@@ -54,7 +54,13 @@ export interface Send<Method extends string | symbol, Arguments extends any[]> {
5454 args : Arguments ;
5555}
5656
57- export type Yielded = On | Always | Cond | EntryAction | ExitAction | ListenTo | Call < any > ;
57+ export interface Accumulate {
58+ type : "accumulate" ;
59+ eventName : string | symbol ;
60+ resultKey : symbol ;
61+ }
62+
63+ export type Yielded = On | Always | Cond | EntryAction | ExitAction | ListenTo | Accumulate | Call < any > ;
5864
5965export function on < Event extends string | symbol > ( event : Event , target : Target ) : On {
6066 return { type : "on" , on : event , target } ;
@@ -99,10 +105,15 @@ export function compound(...targets: Array<StateDefinition>): Compound {
99105 return { type : "compound" , targets } ;
100106}
101107
108+ export function accumulate ( eventName : string | symbol , resultKey : symbol ) : Accumulate {
109+ return { type : "accumulate" , eventName, resultKey } ;
110+ }
111+
102112export interface MachineInstance extends Iterator < null | string | Record < string , string > , void , string | symbol > {
103113 changeCount : number ;
104114 current : null | string | Record < string , string > ;
105115 results : null | Promise < unknown > ;
116+ accumulations : Map < symbol | string , Array < symbol | string | Event > > ;
106117 done : boolean ;
107118 next ( arg : string | symbol ) : IteratorResult < null | string | Record < string , string > > &
108119 PromiseLike < any > & {
@@ -120,6 +131,7 @@ class Handlers {
120131 private actionResults = new Map < string | symbol , unknown > ( ) ;
121132 private promise : null | Promise < Array < unknown > > = null ;
122133 public readonly eventsToListenTo = new Array < [ string , EventTarget ] > ( ) ;
134+ public readonly eventsToAccumulate = new Array < [ string | symbol , symbol ] > ( ) ;
123135
124136 * actions ( ) : Generator < EntryAction , void , undefined > {
125137 yield * this . entryActions ;
@@ -171,6 +183,8 @@ class Handlers {
171183 this . alwaysArray . push ( value ) ;
172184 } else if ( value . type === 'listenTo' ) {
173185 this . eventsToListenTo . push ( [ value . eventName , value . sender ] ) ;
186+ } else if ( value . type === 'accumulate' ) {
187+ this . eventsToAccumulate . push ( [ value . eventName , value . resultKey ] ) ;
174188 }
175189 }
176190
@@ -207,6 +221,7 @@ class InternalInstance {
207221 private parent : null | InternalInstance
208222 private globalHandlers = new Handlers ( )
209223 private resolved = null as Promise < Record < string , any > > | null
224+ private accumulations : Map < symbol | string , Array < symbol | string | Event > > = new Map ( ) ;
210225 private eventAborter = new AbortController ( ) ;
211226 child : null | InternalInstance = null
212227
@@ -266,8 +281,19 @@ class InternalInstance {
266281 // return build().then(pairs => Object.fromEntries(pairs as any));
267282 }
268283
284+ * allAccumulations ( ) : Generator < [ symbol | string , Array < string | symbol | Event > ] > /*: Generator<{ key: symbol | string, events: Array<string | symbol | Event> }>*/ {
285+ for ( const [ key , events ] of this . accumulations ) {
286+ // yield { key, events };
287+ yield [ key , events ] ;
288+ }
289+
290+ if ( this . child !== null ) {
291+ yield * this . child . allAccumulations ( ) ;
292+ }
293+ }
294+
269295 handleEvent ( event : Event ) {
270- this . receive ( event . type ) ;
296+ this . receive ( event ) ;
271297 }
272298
273299 cleanup ( ) {
@@ -393,13 +419,23 @@ class InternalInstance {
393419 return false ;
394420 }
395421
396- receive ( event : string | symbol ) {
422+ receive ( event : string | symbol | Event ) {
397423 this . child ?. receive ( event ) ;
398424
399- const target = this . globalHandlers . targetForEvent ( event ) ;
425+ const eventName = typeof event === 'string' || typeof event === 'symbol' ? event : event . type ;
426+
427+ const target = this . globalHandlers . targetForEvent ( eventName ) ;
400428 if ( target !== undefined ) {
401429 this . processTarget ( target ) ;
402430 }
431+
432+ for ( const [ iteratedEventName , resultKey ] of this . globalHandlers . eventsToAccumulate ) {
433+ if ( iteratedEventName === eventName ) {
434+ const current = this . accumulations . get ( resultKey ) ?? [ ] ;
435+ console . log ( "accumulating event" , eventName ) ;
436+ this . accumulations . set ( resultKey , current . concat ( event ) ) ;
437+ }
438+ }
403439 }
404440}
405441
@@ -436,6 +472,9 @@ export function start(
436472 get results ( ) {
437473 return instance . results ;
438474 } ,
475+ get accumulations ( ) {
476+ return new Map ( instance . allAccumulations ( ) ) ;
477+ } ,
439478 next ( event : string | symbol ) {
440479 instance . receive ( event ) ;
441480 const promise = instance . results ;
0 commit comments