xstate 5.0.2 → 5.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/actions/dist/xstate-actions.cjs.js +2 -2
- package/actions/dist/xstate-actions.development.cjs.js +2 -2
- package/actions/dist/xstate-actions.development.esm.js +2 -2
- package/actions/dist/xstate-actions.esm.js +2 -2
- package/actions/dist/xstate-actions.umd.min.js +1 -1
- package/actions/dist/xstate-actions.umd.min.js.map +1 -1
- package/actors/dist/xstate-actors.cjs.js +1 -1
- package/actors/dist/xstate-actors.development.cjs.js +1 -1
- package/actors/dist/xstate-actors.development.esm.js +1 -1
- package/actors/dist/xstate-actors.esm.js +1 -1
- package/actors/dist/xstate-actors.umd.min.js +1 -1
- package/actors/dist/xstate-actors.umd.min.js.map +1 -1
- package/dist/declarations/src/SimulatedClock.d.ts +3 -1
- package/dist/declarations/src/actions/send.d.ts +1 -1
- package/dist/declarations/src/actors/callback.d.ts +3 -2
- package/dist/declarations/src/actors/observable.d.ts +2 -1
- package/dist/declarations/src/actors/promise.d.ts +3 -2
- package/dist/declarations/src/actors/transition.d.ts +3 -2
- package/dist/declarations/src/index.d.ts +6 -5
- package/dist/declarations/src/interpreter.d.ts +4 -8
- package/dist/declarations/src/spawn.d.ts +3 -2
- package/dist/declarations/src/system.d.ts +32 -2
- package/dist/declarations/src/toPromise.d.ts +24 -0
- package/dist/declarations/src/types.d.ts +13 -16
- package/dist/{log-22e678c5.esm.js → log-5409ee89.esm.js} +15 -8
- package/dist/{log-f196f85f.development.esm.js → log-557e5fa3.development.esm.js} +15 -8
- package/dist/{log-5e226275.cjs.js → log-74467f02.cjs.js} +15 -8
- package/dist/{log-641cd926.development.cjs.js → log-a56e34a9.development.cjs.js} +15 -8
- package/dist/{raise-89c581c4.development.esm.js → raise-0ff85b7b.development.esm.js} +109 -43
- package/dist/{raise-8bc422d1.esm.js → raise-5d7ae4b7.esm.js} +109 -43
- package/dist/{raise-62704519.development.cjs.js → raise-6fb30f8b.development.cjs.js} +108 -42
- package/dist/{raise-34e25c2c.cjs.js → raise-746abff7.cjs.js} +108 -42
- package/dist/xstate.cjs.js +57 -5
- package/dist/xstate.cjs.mjs +1 -0
- package/dist/xstate.development.cjs.js +57 -5
- package/dist/xstate.development.cjs.mjs +1 -0
- package/dist/xstate.development.esm.js +59 -8
- package/dist/xstate.esm.js +59 -8
- package/dist/xstate.umd.min.js +1 -1
- package/dist/xstate.umd.min.js.map +1 -1
- package/guards/dist/xstate-guards.cjs.js +1 -1
- package/guards/dist/xstate-guards.development.cjs.js +1 -1
- package/guards/dist/xstate-guards.development.esm.js +1 -1
- package/guards/dist/xstate-guards.esm.js +1 -1
- package/package.json +1 -1
|
@@ -126,13 +126,56 @@ function reportUnhandledError(err) {
|
|
|
126
126
|
|
|
127
127
|
const symbolObservable = (() => typeof Symbol === 'function' && Symbol.observable || '@@observable')();
|
|
128
128
|
|
|
129
|
+
function createScheduledEventId(actorRef, id) {
|
|
130
|
+
return `${actorRef.sessionId}.${id}`;
|
|
131
|
+
}
|
|
129
132
|
let idCounter = 0;
|
|
130
|
-
function createSystem(rootActor) {
|
|
133
|
+
function createSystem(rootActor, options) {
|
|
131
134
|
const children = new Map();
|
|
132
135
|
const keyedActors = new Map();
|
|
133
136
|
const reverseKeyedActors = new WeakMap();
|
|
134
137
|
const observers = new Set();
|
|
138
|
+
const timerMap = {};
|
|
139
|
+
const clock = options.clock;
|
|
140
|
+
const scheduler = {
|
|
141
|
+
schedule: (source, target, event, delay, id = Math.random().toString(36).slice(2)) => {
|
|
142
|
+
const scheduledEvent = {
|
|
143
|
+
source,
|
|
144
|
+
target,
|
|
145
|
+
event,
|
|
146
|
+
delay,
|
|
147
|
+
id,
|
|
148
|
+
startedAt: Date.now()
|
|
149
|
+
};
|
|
150
|
+
const scheduledEventId = createScheduledEventId(source, id);
|
|
151
|
+
system._snapshot._scheduledEvents[scheduledEventId] = scheduledEvent;
|
|
152
|
+
const timeout = clock.setTimeout(() => {
|
|
153
|
+
delete timerMap[scheduledEventId];
|
|
154
|
+
delete system._snapshot._scheduledEvents[scheduledEventId];
|
|
155
|
+
system._relay(source, target, event);
|
|
156
|
+
}, delay);
|
|
157
|
+
timerMap[scheduledEventId] = timeout;
|
|
158
|
+
},
|
|
159
|
+
cancel: (source, id) => {
|
|
160
|
+
const scheduledEventId = createScheduledEventId(source, id);
|
|
161
|
+
const timeout = timerMap[scheduledEventId];
|
|
162
|
+
delete timerMap[scheduledEventId];
|
|
163
|
+
delete system._snapshot._scheduledEvents[scheduledEventId];
|
|
164
|
+
clock.clearTimeout(timeout);
|
|
165
|
+
},
|
|
166
|
+
cancelAll: actorRef => {
|
|
167
|
+
for (const scheduledEventId in system._snapshot._scheduledEvents) {
|
|
168
|
+
const scheduledEvent = system._snapshot._scheduledEvents[scheduledEventId];
|
|
169
|
+
if (scheduledEvent.source === actorRef) {
|
|
170
|
+
scheduler.cancel(actorRef, scheduledEvent.id);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
};
|
|
135
175
|
const system = {
|
|
176
|
+
_snapshot: {
|
|
177
|
+
_scheduledEvents: (options?.snapshot && options.snapshot.scheduler) ?? {}
|
|
178
|
+
},
|
|
136
179
|
_bookId: () => `x:${idCounter++}`,
|
|
137
180
|
_register: (sessionId, actorRef) => {
|
|
138
181
|
children.set(sessionId, actorRef);
|
|
@@ -175,6 +218,28 @@ function createSystem(rootActor) {
|
|
|
175
218
|
event
|
|
176
219
|
});
|
|
177
220
|
target._send(event);
|
|
221
|
+
},
|
|
222
|
+
scheduler,
|
|
223
|
+
getSnapshot: () => {
|
|
224
|
+
return {
|
|
225
|
+
_scheduledEvents: {
|
|
226
|
+
...system._snapshot._scheduledEvents
|
|
227
|
+
}
|
|
228
|
+
};
|
|
229
|
+
},
|
|
230
|
+
start: () => {
|
|
231
|
+
const scheduledEvets = system._snapshot._scheduledEvents;
|
|
232
|
+
system._snapshot._scheduledEvents = {};
|
|
233
|
+
for (const scheduledId in scheduledEvets) {
|
|
234
|
+
const {
|
|
235
|
+
source,
|
|
236
|
+
target,
|
|
237
|
+
event,
|
|
238
|
+
delay,
|
|
239
|
+
id
|
|
240
|
+
} = scheduledEvets[scheduledId];
|
|
241
|
+
scheduler.schedule(source, target, event, delay, id);
|
|
242
|
+
}
|
|
178
243
|
}
|
|
179
244
|
};
|
|
180
245
|
return system;
|
|
@@ -360,7 +425,6 @@ class Actor {
|
|
|
360
425
|
*/
|
|
361
426
|
this.id = void 0;
|
|
362
427
|
this.mailbox = new Mailbox(this._process.bind(this));
|
|
363
|
-
this.delayedEventsMap = {};
|
|
364
428
|
this.observers = new Set();
|
|
365
429
|
this.logger = void 0;
|
|
366
430
|
/** @internal */
|
|
@@ -397,7 +461,9 @@ class Actor {
|
|
|
397
461
|
systemId,
|
|
398
462
|
inspect
|
|
399
463
|
} = resolvedOptions;
|
|
400
|
-
this.system = parent
|
|
464
|
+
this.system = parent ? parent.system : createSystem(this, {
|
|
465
|
+
clock
|
|
466
|
+
});
|
|
401
467
|
if (inspect && !parent) {
|
|
402
468
|
// Always inspect at the system-level
|
|
403
469
|
this.system.inspect(toObserver(inspect));
|
|
@@ -578,10 +644,28 @@ class Actor {
|
|
|
578
644
|
if (this._processingStatus !== ProcessingStatus.Stopped) {
|
|
579
645
|
this.observers.add(observer);
|
|
580
646
|
} else {
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
647
|
+
switch (this._snapshot.status) {
|
|
648
|
+
case 'done':
|
|
649
|
+
try {
|
|
650
|
+
observer.complete?.();
|
|
651
|
+
} catch (err) {
|
|
652
|
+
reportUnhandledError(err);
|
|
653
|
+
}
|
|
654
|
+
break;
|
|
655
|
+
case 'error':
|
|
656
|
+
{
|
|
657
|
+
const err = this._snapshot.error;
|
|
658
|
+
if (!observer.error) {
|
|
659
|
+
reportUnhandledError(err);
|
|
660
|
+
} else {
|
|
661
|
+
try {
|
|
662
|
+
observer.error(err);
|
|
663
|
+
} catch (err) {
|
|
664
|
+
reportUnhandledError(err);
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
break;
|
|
668
|
+
}
|
|
585
669
|
}
|
|
586
670
|
}
|
|
587
671
|
return {
|
|
@@ -638,6 +722,9 @@ class Actor {
|
|
|
638
722
|
this._error(this._snapshot.error);
|
|
639
723
|
return this;
|
|
640
724
|
}
|
|
725
|
+
if (!this._parent) {
|
|
726
|
+
this.system.start();
|
|
727
|
+
}
|
|
641
728
|
if (this.logic.start) {
|
|
642
729
|
try {
|
|
643
730
|
this.logic.start(this._snapshot, this._actorScope);
|
|
@@ -766,9 +853,7 @@ class Actor {
|
|
|
766
853
|
}
|
|
767
854
|
|
|
768
855
|
// Cancel all delayed events
|
|
769
|
-
|
|
770
|
-
this.clock.clearTimeout(this.delayedEventsMap[key]);
|
|
771
|
-
}
|
|
856
|
+
this.system.scheduler.cancelAll(this);
|
|
772
857
|
|
|
773
858
|
// TODO: mailbox.reset
|
|
774
859
|
this.mailbox.clear();
|
|
@@ -800,35 +885,6 @@ class Actor {
|
|
|
800
885
|
send(event) {
|
|
801
886
|
this.system._relay(undefined, this, event);
|
|
802
887
|
}
|
|
803
|
-
|
|
804
|
-
/**
|
|
805
|
-
* TODO: figure out a way to do this within the machine
|
|
806
|
-
* @internal
|
|
807
|
-
*/
|
|
808
|
-
delaySend(params) {
|
|
809
|
-
const {
|
|
810
|
-
event,
|
|
811
|
-
id,
|
|
812
|
-
delay
|
|
813
|
-
} = params;
|
|
814
|
-
const timerId = this.clock.setTimeout(() => {
|
|
815
|
-
this.system._relay(this, params.to ?? this, event);
|
|
816
|
-
}, delay);
|
|
817
|
-
|
|
818
|
-
// TODO: consider the rehydration story here
|
|
819
|
-
if (id) {
|
|
820
|
-
this.delayedEventsMap[id] = timerId;
|
|
821
|
-
}
|
|
822
|
-
}
|
|
823
|
-
|
|
824
|
-
/**
|
|
825
|
-
* TODO: figure out a way to do this within the machine
|
|
826
|
-
* @internal
|
|
827
|
-
*/
|
|
828
|
-
cancel(sendId) {
|
|
829
|
-
this.clock.clearTimeout(this.delayedEventsMap[sendId]);
|
|
830
|
-
delete this.delayedEventsMap[sendId];
|
|
831
|
-
}
|
|
832
888
|
attachDevTools() {
|
|
833
889
|
const {
|
|
834
890
|
devTools
|
|
@@ -940,7 +996,9 @@ function resolveCancel(_, snapshot, actionArgs, actionParams, {
|
|
|
940
996
|
return [snapshot, resolvedSendId];
|
|
941
997
|
}
|
|
942
998
|
function executeCancel(actorScope, resolvedSendId) {
|
|
943
|
-
actorScope.
|
|
999
|
+
actorScope.defer(() => {
|
|
1000
|
+
actorScope.system.scheduler.cancel(actorScope.self, resolvedSendId);
|
|
1001
|
+
});
|
|
944
1002
|
}
|
|
945
1003
|
/**
|
|
946
1004
|
* Cancels an in-flight `send(...)` action. A canceled sent action will not
|
|
@@ -2291,8 +2349,16 @@ function resolveRaise(_, snapshot, args, actionParams, {
|
|
|
2291
2349
|
}];
|
|
2292
2350
|
}
|
|
2293
2351
|
function executeRaise(actorScope, params) {
|
|
2294
|
-
|
|
2295
|
-
|
|
2352
|
+
const {
|
|
2353
|
+
event,
|
|
2354
|
+
delay,
|
|
2355
|
+
id
|
|
2356
|
+
} = params;
|
|
2357
|
+
if (typeof delay === 'number') {
|
|
2358
|
+
actorScope.defer(() => {
|
|
2359
|
+
const self = actorScope.self;
|
|
2360
|
+
actorScope.system.scheduler.schedule(self, self, event, delay, id);
|
|
2361
|
+
});
|
|
2296
2362
|
return;
|
|
2297
2363
|
}
|
|
2298
2364
|
}
|
|
@@ -2314,4 +2380,4 @@ function raise(eventOrExpr, options) {
|
|
|
2314
2380
|
return raise;
|
|
2315
2381
|
}
|
|
2316
2382
|
|
|
2317
|
-
export { $$ACTOR_TYPE as $, Actor as A, interpret as B, isMachineSnapshot as C,
|
|
2383
|
+
export { $$ACTOR_TYPE as $, Actor as A, interpret as B, isMachineSnapshot as C, and as D, not as E, or as F, stateIn as G, getAllOwnEventDescriptors as H, matchesState as I, pathToStateValue as J, toObserver as K, cancel as L, raise as M, NULL_EVENT as N, spawnChild as O, stop as P, stopChild as Q, ProcessingStatus as R, STATE_DELIMITER as S, cloneMachineSnapshot as T, XSTATE_ERROR as U, createErrorActorEvent as V, XSTATE_STOP as X, toTransitionConfigArray as a, formatTransition as b, createInvokeId as c, formatInitialTransition as d, evaluateGuard as e, formatTransitions as f, getDelayedTransitions as g, getCandidates as h, getAllStateNodes as i, getStateNodes as j, createMachineSnapshot as k, isInFinalState as l, mapValues as m, macrostep as n, transitionNode as o, resolveActionsAndContext as p, createInitEvent as q, resolveStateValue as r, microstep as s, toArray as t, getInitialStateNodes as u, isStateId as v, getStateNodeByPath as w, getPersistedSnapshot as x, resolveReferencedActor as y, createActor as z };
|
|
@@ -128,13 +128,56 @@ function reportUnhandledError(err) {
|
|
|
128
128
|
|
|
129
129
|
const symbolObservable = (() => typeof Symbol === 'function' && Symbol.observable || '@@observable')();
|
|
130
130
|
|
|
131
|
+
function createScheduledEventId(actorRef, id) {
|
|
132
|
+
return `${actorRef.sessionId}.${id}`;
|
|
133
|
+
}
|
|
131
134
|
let idCounter = 0;
|
|
132
|
-
function createSystem(rootActor) {
|
|
135
|
+
function createSystem(rootActor, options) {
|
|
133
136
|
const children = new Map();
|
|
134
137
|
const keyedActors = new Map();
|
|
135
138
|
const reverseKeyedActors = new WeakMap();
|
|
136
139
|
const observers = new Set();
|
|
140
|
+
const timerMap = {};
|
|
141
|
+
const clock = options.clock;
|
|
142
|
+
const scheduler = {
|
|
143
|
+
schedule: (source, target, event, delay, id = Math.random().toString(36).slice(2)) => {
|
|
144
|
+
const scheduledEvent = {
|
|
145
|
+
source,
|
|
146
|
+
target,
|
|
147
|
+
event,
|
|
148
|
+
delay,
|
|
149
|
+
id,
|
|
150
|
+
startedAt: Date.now()
|
|
151
|
+
};
|
|
152
|
+
const scheduledEventId = createScheduledEventId(source, id);
|
|
153
|
+
system._snapshot._scheduledEvents[scheduledEventId] = scheduledEvent;
|
|
154
|
+
const timeout = clock.setTimeout(() => {
|
|
155
|
+
delete timerMap[scheduledEventId];
|
|
156
|
+
delete system._snapshot._scheduledEvents[scheduledEventId];
|
|
157
|
+
system._relay(source, target, event);
|
|
158
|
+
}, delay);
|
|
159
|
+
timerMap[scheduledEventId] = timeout;
|
|
160
|
+
},
|
|
161
|
+
cancel: (source, id) => {
|
|
162
|
+
const scheduledEventId = createScheduledEventId(source, id);
|
|
163
|
+
const timeout = timerMap[scheduledEventId];
|
|
164
|
+
delete timerMap[scheduledEventId];
|
|
165
|
+
delete system._snapshot._scheduledEvents[scheduledEventId];
|
|
166
|
+
clock.clearTimeout(timeout);
|
|
167
|
+
},
|
|
168
|
+
cancelAll: actorRef => {
|
|
169
|
+
for (const scheduledEventId in system._snapshot._scheduledEvents) {
|
|
170
|
+
const scheduledEvent = system._snapshot._scheduledEvents[scheduledEventId];
|
|
171
|
+
if (scheduledEvent.source === actorRef) {
|
|
172
|
+
scheduler.cancel(actorRef, scheduledEvent.id);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
};
|
|
137
177
|
const system = {
|
|
178
|
+
_snapshot: {
|
|
179
|
+
_scheduledEvents: (options?.snapshot && options.snapshot.scheduler) ?? {}
|
|
180
|
+
},
|
|
138
181
|
_bookId: () => `x:${idCounter++}`,
|
|
139
182
|
_register: (sessionId, actorRef) => {
|
|
140
183
|
children.set(sessionId, actorRef);
|
|
@@ -177,6 +220,28 @@ function createSystem(rootActor) {
|
|
|
177
220
|
event
|
|
178
221
|
});
|
|
179
222
|
target._send(event);
|
|
223
|
+
},
|
|
224
|
+
scheduler,
|
|
225
|
+
getSnapshot: () => {
|
|
226
|
+
return {
|
|
227
|
+
_scheduledEvents: {
|
|
228
|
+
...system._snapshot._scheduledEvents
|
|
229
|
+
}
|
|
230
|
+
};
|
|
231
|
+
},
|
|
232
|
+
start: () => {
|
|
233
|
+
const scheduledEvets = system._snapshot._scheduledEvents;
|
|
234
|
+
system._snapshot._scheduledEvents = {};
|
|
235
|
+
for (const scheduledId in scheduledEvets) {
|
|
236
|
+
const {
|
|
237
|
+
source,
|
|
238
|
+
target,
|
|
239
|
+
event,
|
|
240
|
+
delay,
|
|
241
|
+
id
|
|
242
|
+
} = scheduledEvets[scheduledId];
|
|
243
|
+
scheduler.schedule(source, target, event, delay, id);
|
|
244
|
+
}
|
|
180
245
|
}
|
|
181
246
|
};
|
|
182
247
|
return system;
|
|
@@ -365,7 +430,6 @@ class Actor {
|
|
|
365
430
|
*/
|
|
366
431
|
this.id = void 0;
|
|
367
432
|
this.mailbox = new Mailbox(this._process.bind(this));
|
|
368
|
-
this.delayedEventsMap = {};
|
|
369
433
|
this.observers = new Set();
|
|
370
434
|
this.logger = void 0;
|
|
371
435
|
/** @internal */
|
|
@@ -402,7 +466,9 @@ class Actor {
|
|
|
402
466
|
systemId,
|
|
403
467
|
inspect
|
|
404
468
|
} = resolvedOptions;
|
|
405
|
-
this.system = parent
|
|
469
|
+
this.system = parent ? parent.system : createSystem(this, {
|
|
470
|
+
clock
|
|
471
|
+
});
|
|
406
472
|
if (inspect && !parent) {
|
|
407
473
|
// Always inspect at the system-level
|
|
408
474
|
this.system.inspect(toObserver(inspect));
|
|
@@ -583,10 +649,28 @@ class Actor {
|
|
|
583
649
|
if (this._processingStatus !== ProcessingStatus.Stopped) {
|
|
584
650
|
this.observers.add(observer);
|
|
585
651
|
} else {
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
652
|
+
switch (this._snapshot.status) {
|
|
653
|
+
case 'done':
|
|
654
|
+
try {
|
|
655
|
+
observer.complete?.();
|
|
656
|
+
} catch (err) {
|
|
657
|
+
reportUnhandledError(err);
|
|
658
|
+
}
|
|
659
|
+
break;
|
|
660
|
+
case 'error':
|
|
661
|
+
{
|
|
662
|
+
const err = this._snapshot.error;
|
|
663
|
+
if (!observer.error) {
|
|
664
|
+
reportUnhandledError(err);
|
|
665
|
+
} else {
|
|
666
|
+
try {
|
|
667
|
+
observer.error(err);
|
|
668
|
+
} catch (err) {
|
|
669
|
+
reportUnhandledError(err);
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
break;
|
|
673
|
+
}
|
|
590
674
|
}
|
|
591
675
|
}
|
|
592
676
|
return {
|
|
@@ -643,6 +727,9 @@ class Actor {
|
|
|
643
727
|
this._error(this._snapshot.error);
|
|
644
728
|
return this;
|
|
645
729
|
}
|
|
730
|
+
if (!this._parent) {
|
|
731
|
+
this.system.start();
|
|
732
|
+
}
|
|
646
733
|
if (this.logic.start) {
|
|
647
734
|
try {
|
|
648
735
|
this.logic.start(this._snapshot, this._actorScope);
|
|
@@ -771,9 +858,7 @@ class Actor {
|
|
|
771
858
|
}
|
|
772
859
|
|
|
773
860
|
// Cancel all delayed events
|
|
774
|
-
|
|
775
|
-
this.clock.clearTimeout(this.delayedEventsMap[key]);
|
|
776
|
-
}
|
|
861
|
+
this.system.scheduler.cancelAll(this);
|
|
777
862
|
|
|
778
863
|
// TODO: mailbox.reset
|
|
779
864
|
this.mailbox.clear();
|
|
@@ -813,35 +898,6 @@ class Actor {
|
|
|
813
898
|
}
|
|
814
899
|
this.system._relay(undefined, this, event);
|
|
815
900
|
}
|
|
816
|
-
|
|
817
|
-
/**
|
|
818
|
-
* TODO: figure out a way to do this within the machine
|
|
819
|
-
* @internal
|
|
820
|
-
*/
|
|
821
|
-
delaySend(params) {
|
|
822
|
-
const {
|
|
823
|
-
event,
|
|
824
|
-
id,
|
|
825
|
-
delay
|
|
826
|
-
} = params;
|
|
827
|
-
const timerId = this.clock.setTimeout(() => {
|
|
828
|
-
this.system._relay(this, params.to ?? this, event);
|
|
829
|
-
}, delay);
|
|
830
|
-
|
|
831
|
-
// TODO: consider the rehydration story here
|
|
832
|
-
if (id) {
|
|
833
|
-
this.delayedEventsMap[id] = timerId;
|
|
834
|
-
}
|
|
835
|
-
}
|
|
836
|
-
|
|
837
|
-
/**
|
|
838
|
-
* TODO: figure out a way to do this within the machine
|
|
839
|
-
* @internal
|
|
840
|
-
*/
|
|
841
|
-
cancel(sendId) {
|
|
842
|
-
this.clock.clearTimeout(this.delayedEventsMap[sendId]);
|
|
843
|
-
delete this.delayedEventsMap[sendId];
|
|
844
|
-
}
|
|
845
901
|
attachDevTools() {
|
|
846
902
|
const {
|
|
847
903
|
devTools
|
|
@@ -953,7 +1009,9 @@ function resolveCancel(_, snapshot, actionArgs, actionParams, {
|
|
|
953
1009
|
return [snapshot, resolvedSendId];
|
|
954
1010
|
}
|
|
955
1011
|
function executeCancel(actorScope, resolvedSendId) {
|
|
956
|
-
actorScope.
|
|
1012
|
+
actorScope.defer(() => {
|
|
1013
|
+
actorScope.system.scheduler.cancel(actorScope.self, resolvedSendId);
|
|
1014
|
+
});
|
|
957
1015
|
}
|
|
958
1016
|
/**
|
|
959
1017
|
* Cancels an in-flight `send(...)` action. A canceled sent action will not
|
|
@@ -2344,8 +2402,16 @@ function resolveRaise(_, snapshot, args, actionParams, {
|
|
|
2344
2402
|
}];
|
|
2345
2403
|
}
|
|
2346
2404
|
function executeRaise(actorScope, params) {
|
|
2347
|
-
|
|
2348
|
-
|
|
2405
|
+
const {
|
|
2406
|
+
event,
|
|
2407
|
+
delay,
|
|
2408
|
+
id
|
|
2409
|
+
} = params;
|
|
2410
|
+
if (typeof delay === 'number') {
|
|
2411
|
+
actorScope.defer(() => {
|
|
2412
|
+
const self = actorScope.self;
|
|
2413
|
+
actorScope.system.scheduler.schedule(self, self, event, delay, id);
|
|
2414
|
+
});
|
|
2349
2415
|
return;
|
|
2350
2416
|
}
|
|
2351
2417
|
}
|
|
@@ -128,13 +128,56 @@ function reportUnhandledError(err) {
|
|
|
128
128
|
|
|
129
129
|
const symbolObservable = (() => typeof Symbol === 'function' && Symbol.observable || '@@observable')();
|
|
130
130
|
|
|
131
|
+
function createScheduledEventId(actorRef, id) {
|
|
132
|
+
return `${actorRef.sessionId}.${id}`;
|
|
133
|
+
}
|
|
131
134
|
let idCounter = 0;
|
|
132
|
-
function createSystem(rootActor) {
|
|
135
|
+
function createSystem(rootActor, options) {
|
|
133
136
|
const children = new Map();
|
|
134
137
|
const keyedActors = new Map();
|
|
135
138
|
const reverseKeyedActors = new WeakMap();
|
|
136
139
|
const observers = new Set();
|
|
140
|
+
const timerMap = {};
|
|
141
|
+
const clock = options.clock;
|
|
142
|
+
const scheduler = {
|
|
143
|
+
schedule: (source, target, event, delay, id = Math.random().toString(36).slice(2)) => {
|
|
144
|
+
const scheduledEvent = {
|
|
145
|
+
source,
|
|
146
|
+
target,
|
|
147
|
+
event,
|
|
148
|
+
delay,
|
|
149
|
+
id,
|
|
150
|
+
startedAt: Date.now()
|
|
151
|
+
};
|
|
152
|
+
const scheduledEventId = createScheduledEventId(source, id);
|
|
153
|
+
system._snapshot._scheduledEvents[scheduledEventId] = scheduledEvent;
|
|
154
|
+
const timeout = clock.setTimeout(() => {
|
|
155
|
+
delete timerMap[scheduledEventId];
|
|
156
|
+
delete system._snapshot._scheduledEvents[scheduledEventId];
|
|
157
|
+
system._relay(source, target, event);
|
|
158
|
+
}, delay);
|
|
159
|
+
timerMap[scheduledEventId] = timeout;
|
|
160
|
+
},
|
|
161
|
+
cancel: (source, id) => {
|
|
162
|
+
const scheduledEventId = createScheduledEventId(source, id);
|
|
163
|
+
const timeout = timerMap[scheduledEventId];
|
|
164
|
+
delete timerMap[scheduledEventId];
|
|
165
|
+
delete system._snapshot._scheduledEvents[scheduledEventId];
|
|
166
|
+
clock.clearTimeout(timeout);
|
|
167
|
+
},
|
|
168
|
+
cancelAll: actorRef => {
|
|
169
|
+
for (const scheduledEventId in system._snapshot._scheduledEvents) {
|
|
170
|
+
const scheduledEvent = system._snapshot._scheduledEvents[scheduledEventId];
|
|
171
|
+
if (scheduledEvent.source === actorRef) {
|
|
172
|
+
scheduler.cancel(actorRef, scheduledEvent.id);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
};
|
|
137
177
|
const system = {
|
|
178
|
+
_snapshot: {
|
|
179
|
+
_scheduledEvents: (options?.snapshot && options.snapshot.scheduler) ?? {}
|
|
180
|
+
},
|
|
138
181
|
_bookId: () => `x:${idCounter++}`,
|
|
139
182
|
_register: (sessionId, actorRef) => {
|
|
140
183
|
children.set(sessionId, actorRef);
|
|
@@ -177,6 +220,28 @@ function createSystem(rootActor) {
|
|
|
177
220
|
event
|
|
178
221
|
});
|
|
179
222
|
target._send(event);
|
|
223
|
+
},
|
|
224
|
+
scheduler,
|
|
225
|
+
getSnapshot: () => {
|
|
226
|
+
return {
|
|
227
|
+
_scheduledEvents: {
|
|
228
|
+
...system._snapshot._scheduledEvents
|
|
229
|
+
}
|
|
230
|
+
};
|
|
231
|
+
},
|
|
232
|
+
start: () => {
|
|
233
|
+
const scheduledEvets = system._snapshot._scheduledEvents;
|
|
234
|
+
system._snapshot._scheduledEvents = {};
|
|
235
|
+
for (const scheduledId in scheduledEvets) {
|
|
236
|
+
const {
|
|
237
|
+
source,
|
|
238
|
+
target,
|
|
239
|
+
event,
|
|
240
|
+
delay,
|
|
241
|
+
id
|
|
242
|
+
} = scheduledEvets[scheduledId];
|
|
243
|
+
scheduler.schedule(source, target, event, delay, id);
|
|
244
|
+
}
|
|
180
245
|
}
|
|
181
246
|
};
|
|
182
247
|
return system;
|
|
@@ -362,7 +427,6 @@ class Actor {
|
|
|
362
427
|
*/
|
|
363
428
|
this.id = void 0;
|
|
364
429
|
this.mailbox = new Mailbox(this._process.bind(this));
|
|
365
|
-
this.delayedEventsMap = {};
|
|
366
430
|
this.observers = new Set();
|
|
367
431
|
this.logger = void 0;
|
|
368
432
|
/** @internal */
|
|
@@ -399,7 +463,9 @@ class Actor {
|
|
|
399
463
|
systemId,
|
|
400
464
|
inspect
|
|
401
465
|
} = resolvedOptions;
|
|
402
|
-
this.system = parent
|
|
466
|
+
this.system = parent ? parent.system : createSystem(this, {
|
|
467
|
+
clock
|
|
468
|
+
});
|
|
403
469
|
if (inspect && !parent) {
|
|
404
470
|
// Always inspect at the system-level
|
|
405
471
|
this.system.inspect(toObserver(inspect));
|
|
@@ -580,10 +646,28 @@ class Actor {
|
|
|
580
646
|
if (this._processingStatus !== ProcessingStatus.Stopped) {
|
|
581
647
|
this.observers.add(observer);
|
|
582
648
|
} else {
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
649
|
+
switch (this._snapshot.status) {
|
|
650
|
+
case 'done':
|
|
651
|
+
try {
|
|
652
|
+
observer.complete?.();
|
|
653
|
+
} catch (err) {
|
|
654
|
+
reportUnhandledError(err);
|
|
655
|
+
}
|
|
656
|
+
break;
|
|
657
|
+
case 'error':
|
|
658
|
+
{
|
|
659
|
+
const err = this._snapshot.error;
|
|
660
|
+
if (!observer.error) {
|
|
661
|
+
reportUnhandledError(err);
|
|
662
|
+
} else {
|
|
663
|
+
try {
|
|
664
|
+
observer.error(err);
|
|
665
|
+
} catch (err) {
|
|
666
|
+
reportUnhandledError(err);
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
break;
|
|
670
|
+
}
|
|
587
671
|
}
|
|
588
672
|
}
|
|
589
673
|
return {
|
|
@@ -640,6 +724,9 @@ class Actor {
|
|
|
640
724
|
this._error(this._snapshot.error);
|
|
641
725
|
return this;
|
|
642
726
|
}
|
|
727
|
+
if (!this._parent) {
|
|
728
|
+
this.system.start();
|
|
729
|
+
}
|
|
643
730
|
if (this.logic.start) {
|
|
644
731
|
try {
|
|
645
732
|
this.logic.start(this._snapshot, this._actorScope);
|
|
@@ -768,9 +855,7 @@ class Actor {
|
|
|
768
855
|
}
|
|
769
856
|
|
|
770
857
|
// Cancel all delayed events
|
|
771
|
-
|
|
772
|
-
this.clock.clearTimeout(this.delayedEventsMap[key]);
|
|
773
|
-
}
|
|
858
|
+
this.system.scheduler.cancelAll(this);
|
|
774
859
|
|
|
775
860
|
// TODO: mailbox.reset
|
|
776
861
|
this.mailbox.clear();
|
|
@@ -802,35 +887,6 @@ class Actor {
|
|
|
802
887
|
send(event) {
|
|
803
888
|
this.system._relay(undefined, this, event);
|
|
804
889
|
}
|
|
805
|
-
|
|
806
|
-
/**
|
|
807
|
-
* TODO: figure out a way to do this within the machine
|
|
808
|
-
* @internal
|
|
809
|
-
*/
|
|
810
|
-
delaySend(params) {
|
|
811
|
-
const {
|
|
812
|
-
event,
|
|
813
|
-
id,
|
|
814
|
-
delay
|
|
815
|
-
} = params;
|
|
816
|
-
const timerId = this.clock.setTimeout(() => {
|
|
817
|
-
this.system._relay(this, params.to ?? this, event);
|
|
818
|
-
}, delay);
|
|
819
|
-
|
|
820
|
-
// TODO: consider the rehydration story here
|
|
821
|
-
if (id) {
|
|
822
|
-
this.delayedEventsMap[id] = timerId;
|
|
823
|
-
}
|
|
824
|
-
}
|
|
825
|
-
|
|
826
|
-
/**
|
|
827
|
-
* TODO: figure out a way to do this within the machine
|
|
828
|
-
* @internal
|
|
829
|
-
*/
|
|
830
|
-
cancel(sendId) {
|
|
831
|
-
this.clock.clearTimeout(this.delayedEventsMap[sendId]);
|
|
832
|
-
delete this.delayedEventsMap[sendId];
|
|
833
|
-
}
|
|
834
890
|
attachDevTools() {
|
|
835
891
|
const {
|
|
836
892
|
devTools
|
|
@@ -942,7 +998,9 @@ function resolveCancel(_, snapshot, actionArgs, actionParams, {
|
|
|
942
998
|
return [snapshot, resolvedSendId];
|
|
943
999
|
}
|
|
944
1000
|
function executeCancel(actorScope, resolvedSendId) {
|
|
945
|
-
actorScope.
|
|
1001
|
+
actorScope.defer(() => {
|
|
1002
|
+
actorScope.system.scheduler.cancel(actorScope.self, resolvedSendId);
|
|
1003
|
+
});
|
|
946
1004
|
}
|
|
947
1005
|
/**
|
|
948
1006
|
* Cancels an in-flight `send(...)` action. A canceled sent action will not
|
|
@@ -2293,8 +2351,16 @@ function resolveRaise(_, snapshot, args, actionParams, {
|
|
|
2293
2351
|
}];
|
|
2294
2352
|
}
|
|
2295
2353
|
function executeRaise(actorScope, params) {
|
|
2296
|
-
|
|
2297
|
-
|
|
2354
|
+
const {
|
|
2355
|
+
event,
|
|
2356
|
+
delay,
|
|
2357
|
+
id
|
|
2358
|
+
} = params;
|
|
2359
|
+
if (typeof delay === 'number') {
|
|
2360
|
+
actorScope.defer(() => {
|
|
2361
|
+
const self = actorScope.self;
|
|
2362
|
+
actorScope.system.scheduler.schedule(self, self, event, delay, id);
|
|
2363
|
+
});
|
|
2298
2364
|
return;
|
|
2299
2365
|
}
|
|
2300
2366
|
}
|