@@ -6,8 +6,8 @@ import { CC, Tracer, TracerConsole } from './Tracer'
6
6
import { noop , tap } from './utils'
7
7
8
8
const CELL_TYPE = 'cell'
9
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
9
10
const SIGNAL_TYPE = 'signal'
10
- const PIPE_TYPE = 'pipe'
11
11
12
12
/**
13
13
* A typed reference to a node.
@@ -20,12 +20,10 @@ export type NodeRef<T = unknown> = symbol & { valType: T }
20
20
* A function that is called when a node emits a value.
21
21
* @typeParam T - The type of values that the node emits.
22
22
*/
23
- export type Subscription < T > = ( value : T ) => unknown
23
+ export type Subscription < T > = ( value : T , realm : Realm ) => unknown
24
24
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 >
29
27
30
28
/**
31
29
* 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>
79
77
*/
80
78
export type NodeInit < T > = ( r : Realm , node$ : NodeRef < T > ) => void
81
79
82
- export type PipeInit < I , O > = ( r : Realm , inputRef$ : NodeRef < I > , outputRef$ : NodeRef < O > ) => void
83
-
84
80
interface CellDefinition < T > {
85
81
distinct : Distinct < T >
86
82
init : NodeInit < T >
@@ -94,21 +90,27 @@ interface SignalDefinition<T> {
94
90
type : typeof SIGNAL_TYPE
95
91
}
96
92
97
- interface PipeDefinition < I , O > {
98
- distinct : Distinct < I >
99
- init : PipeInit < I , O >
100
- initial : O
101
- type : typeof PIPE_TYPE
102
- }
103
-
104
93
// 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 > > ( )
106
95
const nodeLabels$$ = new Map < symbol , string > ( )
96
+ const nodeInits$$ = new SetMap < NodeInit < unknown > > ( )
107
97
108
98
export const getNodeLabel = ( node : symbol ) : string => {
109
99
return nodeLabels$$ . get ( node ) ?? '<anonymous>'
110
100
}
111
101
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
+
112
114
let currentRealm$$ : Realm | undefined = undefined
113
115
114
116
/**
@@ -125,7 +127,6 @@ export class Realm {
125
127
private readonly distinctNodes = new Map < symbol , Comparator < unknown > > ( )
126
128
private readonly executionMaps = new Map < symbol | symbol [ ] , ExecutionMap > ( )
127
129
private readonly graph = new SetMap < RealmProjection > ( )
128
- private readonly pipeMap = new Map < symbol , symbol > ( )
129
130
private readonly singletonSubscriptions = new Map < symbol , Subscription < unknown > > ( )
130
131
private readonly state = new Map < symbol , unknown > ( )
131
132
@@ -514,20 +515,9 @@ export class Realm {
514
515
* ```
515
516
*/
516
517
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 [ ]
529
519
530
- const tracePayload = Reflect . ownKeys ( mappedValues ) . map ( ( key ) => {
520
+ const tracePayload = Reflect . ownKeys ( values ) . map ( ( key ) => {
531
521
return { [ getNodeLabel ( key as symbol ) ] : values [ key as symbol ] }
532
522
} )
533
523
@@ -553,8 +543,7 @@ export class Realm {
553
543
} )
554
544
}
555
545
556
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
557
- while ( true ) {
546
+ for ( ; ; ) {
558
547
const nextId = participatingNodeKeys . shift ( )
559
548
if ( nextId === undefined ) {
560
549
break
@@ -578,9 +567,9 @@ export class Realm {
578
567
this . state . set ( id , value )
579
568
}
580
569
}
581
- if ( Object . hasOwn ( mappedValues , id ) ) {
570
+ if ( Object . hasOwn ( values , id ) ) {
582
571
this . tracer . log ( CC . blue ( `${ getNodeLabel ( id ) } : ` ) , 'value found in direct payload' )
583
- done ( mappedValues [ id ] )
572
+ done ( values [ id ] )
584
573
} else {
585
574
map . projections . use ( id , ( nodeProjections ) => {
586
575
for ( const projection of nodeProjections ) {
@@ -602,11 +591,11 @@ export class Realm {
602
591
this . subscriptions . use ( id , ( nodeSubscriptions ) => {
603
592
for ( const subscription of nodeSubscriptions ) {
604
593
this . tracer . log ( CC . blue ( 'Calling subscription: ' ) , subscription . name || '<anonymous>' , value )
605
- subscription ( value )
594
+ subscription ( value , this )
606
595
}
607
596
} )
608
597
} )
609
- this . singletonSubscriptions . get ( id ) ?.( value )
598
+ this . singletonSubscriptions . get ( id ) ?.( value , this )
610
599
} else {
611
600
nodeWillNotEmit ( id )
612
601
}
@@ -619,7 +608,7 @@ export class Realm {
619
608
* Most of the time you don't need to do that, since any interaction with the node through a realm will register it.
620
609
* 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.
621
610
*/
622
- register ( node$ : NodeRef | PipeRef ) {
611
+ register ( node$ : NodeRef ) {
623
612
const definition = nodeDefs$$ . get ( node$ )
624
613
// local node
625
614
if ( definition === undefined ) {
@@ -628,30 +617,22 @@ export class Realm {
628
617
629
618
if ( ! this . definitionRegistry . has ( node$ ) ) {
630
619
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$ ) => {
633
626
this . inContext ( ( ) => {
634
- definition . init ( this , node $)
627
+ definition . init ( this , theNode $)
635
628
} )
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
+ }
642
633
} )
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
+ )
655
636
}
656
637
return node$
657
638
}
@@ -930,16 +911,6 @@ export function Cell<T>(value: T, init: (r: Realm) => void = noop, distinct: Dis
930
911
} ) as NodeRef < T >
931
912
}
932
913
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
-
943
914
/**
944
915
* Defines a new **stateful node**, links it to an existing node transform and returns a reference to it.
945
916
* Once a realm instance publishes or subscribes to the node, an instance of that node it will be registered in the realm.
0 commit comments