Skip to content

Commit 77e5316

Browse files
committed
chore: remove pipe
Backing down on the idea
1 parent aee101b commit 77e5316

File tree

7 files changed

+101
-186
lines changed

7 files changed

+101
-186
lines changed

packages/gurx/src/AsyncQuery.ts

Lines changed: 0 additions & 43 deletions
This file was deleted.

packages/gurx/src/hooks.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import * as React from 'react'
22

3-
import type { Inp, NodeRef, Out, PipeRef } from './realm'
3+
import type { Inp, NodeRef, Out } from './realm'
44

55
import { RealmContext } from './react'
66

@@ -159,7 +159,7 @@ export function usePublisher<T>(node: Inp<T>) {
159159
* @returns A tuple of the current value of the cell and a publisher function.
160160
* @category Hooks
161161
*/
162-
export function useCell<O, I = O>(cell: NodeRef<O> | PipeRef<I, O>): [O, (value: I) => void] {
162+
export function useCell<T>(cell: NodeRef<T>): [T, (value: T) => void] {
163163
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
164-
return [useCellValue<O>(cell), usePublisher<I>(cell as any)]
164+
return [useCellValue<T>(cell), usePublisher<T>(cell as any)]
165165
}

packages/gurx/src/index.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
export * from './AsyncQuery'
21
export * from './hooks'
32
export * from './operators'
43
export { RealmContext, RealmProvider } from './react'

packages/gurx/src/realm.ts

Lines changed: 39 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ import { CC, Tracer, TracerConsole } from './Tracer'
66
import { noop, tap } from './utils'
77

88
const CELL_TYPE = 'cell'
9+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
910
const SIGNAL_TYPE = 'signal'
10-
const PIPE_TYPE = 'pipe'
1111

1212
/**
1313
* A typed reference to a node.
@@ -20,12 +20,10 @@ export type NodeRef<T = unknown> = symbol & { valType: T }
2020
* A function that is called when a node emits a value.
2121
* @typeParam T - The type of values that the node emits.
2222
*/
23-
export type Subscription<T> = (value: T) => unknown
23+
export type Subscription<T> = (value: T, realm: Realm) => unknown
2424

25-
export type PipeRef<I = unknown, O = unknown> = symbol & { inputType: I; outputType: O }
26-
27-
export type Inp<T = unknown> = NodeRef<T> | PipeRef<T>
28-
export type Out<T = unknown> = NodeRef<T> | PipeRef<unknown, T>
25+
export type Inp<T = unknown> = NodeRef<T>
26+
export type Out<T = unknown> = NodeRef<T>
2927

3028
/**
3129
* The resulting type of a subscription to a node. Can be used to cancel the subscription.
@@ -79,8 +77,6 @@ export type Distinct<T> = boolean | Comparator<T>
7977
*/
8078
export type NodeInit<T> = (r: Realm, node$: NodeRef<T>) => void
8179

82-
export type PipeInit<I, O> = (r: Realm, inputRef$: NodeRef<I>, outputRef$: NodeRef<O>) => void
83-
8480
interface CellDefinition<T> {
8581
distinct: Distinct<T>
8682
init: NodeInit<T>
@@ -94,21 +90,27 @@ interface SignalDefinition<T> {
9490
type: typeof SIGNAL_TYPE
9591
}
9692

97-
interface PipeDefinition<I, O> {
98-
distinct: Distinct<I>
99-
init: PipeInit<I, O>
100-
initial: O
101-
type: typeof PIPE_TYPE
102-
}
103-
10493
// eslint-disable-next-line @typescript-eslint/no-explicit-any
105-
const nodeDefs$$ = new Map<symbol, CellDefinition<any> | PipeDefinition<any, any> | SignalDefinition<any>>()
94+
const nodeDefs$$ = new Map<symbol, CellDefinition<any> | SignalDefinition<any>>()
10695
const nodeLabels$$ = new Map<symbol, string>()
96+
const nodeInits$$ = new SetMap<NodeInit<unknown>>()
10797

10898
export const getNodeLabel = (node: symbol): string => {
10999
return nodeLabels$$.get(node) ?? '<anonymous>'
110100
}
111101

102+
function addNodeInit<T>(node: NodeRef<T>, init: NodeInit<T>) {
103+
nodeInits$$.getOrCreate(node).add(init as NodeInit<unknown>)
104+
}
105+
106+
export const R = {
107+
link<T>(source: Out<T>, sink: Inp<T>) {
108+
addNodeInit(source, (r) => {
109+
r.link(source, sink)
110+
})
111+
},
112+
}
113+
112114
let currentRealm$$: Realm | undefined = undefined
113115

114116
/**
@@ -125,7 +127,6 @@ export class Realm {
125127
private readonly distinctNodes = new Map<symbol, Comparator<unknown>>()
126128
private readonly executionMaps = new Map<symbol | symbol[], ExecutionMap>()
127129
private readonly graph = new SetMap<RealmProjection>()
128-
private readonly pipeMap = new Map<symbol, symbol>()
129130
private readonly singletonSubscriptions = new Map<symbol, Subscription<unknown>>()
130131
private readonly state = new Map<symbol, unknown>()
131132

@@ -514,20 +515,9 @@ export class Realm {
514515
* ```
515516
*/
516517
pubIn(values: Record<symbol, unknown>) {
517-
// if we have pipe nodes, we need to use their input symbols for publishing instead
518-
const ids = (Reflect.ownKeys(values) as symbol[]).map((id) => {
519-
return this.pipeMap.get(id) ?? id
520-
})
521-
522-
const mappedValues = Reflect.ownKeys(values).reduce<Record<symbol, unknown>>((acc, key) => {
523-
const symbolKey = key as symbol
524-
const value = values[symbolKey]
525-
const pipeMappedKey: symbol = this.pipeMap.get(symbolKey) ?? symbolKey
526-
acc[pipeMappedKey] = value
527-
return acc
528-
}, {})
518+
const ids = Reflect.ownKeys(values) as symbol[]
529519

530-
const tracePayload = Reflect.ownKeys(mappedValues).map((key) => {
520+
const tracePayload = Reflect.ownKeys(values).map((key) => {
531521
return { [getNodeLabel(key as symbol)]: values[key as symbol] }
532522
})
533523

@@ -553,8 +543,7 @@ export class Realm {
553543
})
554544
}
555545

556-
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
557-
while (true) {
546+
for (;;) {
558547
const nextId = participatingNodeKeys.shift()
559548
if (nextId === undefined) {
560549
break
@@ -578,9 +567,9 @@ export class Realm {
578567
this.state.set(id, value)
579568
}
580569
}
581-
if (Object.hasOwn(mappedValues, id)) {
570+
if (Object.hasOwn(values, id)) {
582571
this.tracer.log(CC.blue(`${getNodeLabel(id)}: `), 'value found in direct payload')
583-
done(mappedValues[id])
572+
done(values[id])
584573
} else {
585574
map.projections.use(id, (nodeProjections) => {
586575
for (const projection of nodeProjections) {
@@ -602,11 +591,11 @@ export class Realm {
602591
this.subscriptions.use(id, (nodeSubscriptions) => {
603592
for (const subscription of nodeSubscriptions) {
604593
this.tracer.log(CC.blue('Calling subscription: '), subscription.name || '<anonymous>', value)
605-
subscription(value)
594+
subscription(value, this)
606595
}
607596
})
608597
})
609-
this.singletonSubscriptions.get(id)?.(value)
598+
this.singletonSubscriptions.get(id)?.(value, this)
610599
} else {
611600
nodeWillNotEmit(id)
612601
}
@@ -619,7 +608,7 @@ export class Realm {
619608
* Most of the time you don't need to do that, since any interaction with the node through a realm will register it.
620609
* The only exception of that rule should be when the interaction is conditional, and the node definition includes an init function that needs to be eagerly evaluated.
621610
*/
622-
register(node$: NodeRef | PipeRef) {
611+
register(node$: NodeRef) {
623612
const definition = nodeDefs$$.get(node$)
624613
// local node
625614
if (definition === undefined) {
@@ -628,30 +617,22 @@ export class Realm {
628617

629618
if (!this.definitionRegistry.has(node$)) {
630619
this.definitionRegistry.add(node$)
631-
if (definition.type === CELL_TYPE) {
632-
return tap(this.cellInstance(definition.initial, definition.distinct, node$), (node$) => {
620+
621+
return tap(
622+
definition.type === CELL_TYPE
623+
? this.cellInstance(definition.initial, definition.distinct, node$)
624+
: this.signalInstance(definition.distinct, node$),
625+
(theNode$) => {
633626
this.inContext(() => {
634-
definition.init(this, node$)
627+
definition.init(this, theNode$)
635628
})
636-
})
637-
}
638-
if (definition.type === SIGNAL_TYPE) {
639-
return tap(this.signalInstance(definition.distinct, node$), (node$) => {
640-
this.inContext(() => {
641-
definition.init(this, node$)
629+
nodeInits$$.use(node$, (inits) => {
630+
for (const init of inits) {
631+
init(this, node$)
632+
}
642633
})
643-
})
644-
}
645-
// PipeRef
646-
const input$ = this.signalInstance(definition.distinct)
647-
const output$ = this.cellInstance(definition.initial, true)
648-
const pipe$ = this.cellInstance(definition.initial, definition.distinct, node$)
649-
this.link(output$, pipe$)
650-
this.pipeMap.set(pipe$, input$)
651-
this.inContext(() => {
652-
definition.init(this, input$, output$)
653-
})
654-
return pipe$
634+
}
635+
)
655636
}
656637
return node$
657638
}
@@ -930,16 +911,6 @@ export function Cell<T>(value: T, init: (r: Realm) => void = noop, distinct: Dis
930911
}) as NodeRef<T>
931912
}
932913

933-
export function Pipe<I, O>(
934-
value: O,
935-
init: (r: Realm, input$: Out<I>, output$: Out<O>) => void,
936-
distinct: Distinct<I> = true
937-
): PipeRef<I, O> {
938-
return tap(Symbol(), (id) => {
939-
nodeDefs$$.set(id, { distinct, init, initial: value, type: PIPE_TYPE })
940-
}) as PipeRef<I, O>
941-
}
942-
943914
/**
944915
* Defines a new **stateful node**, links it to an existing node transform and returns a reference to it.
945916
* Once a realm instance publishes or subscribes to the node, an instance of that node it will be registered in the realm.

packages/gurx/src/test/node/AsyncQuery.test.ts

Lines changed: 0 additions & 28 deletions
This file was deleted.

0 commit comments

Comments
 (0)