xstate 5.0.0-beta.19 → 5.0.0-beta.21
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 +1 -1
- package/actions/dist/xstate-actions.development.cjs.js +1 -1
- package/actions/dist/xstate-actions.development.esm.js +1 -1
- package/actions/dist/xstate-actions.esm.js +1 -1
- 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/{actions-72105f77.development.esm.js → actions-49f0501e.development.esm.js} +421 -352
- package/dist/{actions-3b74fb92.esm.js → actions-5039c951.esm.js} +489 -423
- package/dist/{actions-bce11b97.development.cjs.js → actions-a95d2e66.development.cjs.js} +421 -351
- package/dist/{actions-2d912781.cjs.js → actions-c619a105.cjs.js} +489 -422
- package/dist/declarations/src/Machine.d.ts +2 -2
- package/dist/declarations/src/State.d.ts +12 -4
- package/dist/declarations/src/StateMachine.d.ts +17 -16
- package/dist/declarations/src/StateNode.d.ts +6 -6
- package/dist/declarations/src/actions/send.d.ts +1 -1
- package/dist/declarations/src/actions.d.ts +2 -2
- package/dist/declarations/src/actors/callback.d.ts +16 -6
- package/dist/declarations/src/actors/index.d.ts +4 -4
- package/dist/declarations/src/actors/observable.d.ts +14 -11
- package/dist/declarations/src/actors/promise.d.ts +14 -8
- package/dist/declarations/src/actors/transition.d.ts +6 -6
- package/dist/declarations/src/guards.d.ts +2 -2
- package/dist/declarations/src/stateUtils.d.ts +8 -8
- package/dist/declarations/src/typegenTypes.d.ts +15 -17
- package/dist/declarations/src/types.d.ts +131 -79
- package/dist/declarations/src/utils.d.ts +3 -3
- package/dist/xstate.cjs.js +12 -12
- package/dist/xstate.development.cjs.js +12 -12
- package/dist/xstate.development.esm.js +13 -13
- package/dist/xstate.esm.js +13 -13
- 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/guards/dist/xstate-guards.umd.min.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,9 +1,18 @@
|
|
|
1
1
|
import { devToolsAdapter } from '../dev/dist/xstate-dev.esm.js';
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
/**
|
|
4
|
+
* `T | unknown` reduces to `unknown` and that can be problematic when it comes to contextual typing.
|
|
5
|
+
* It especially is a problem when the union has a function member, like here:
|
|
6
|
+
*
|
|
7
|
+
* ```ts
|
|
8
|
+
* declare function test(cbOrVal: ((arg: number) => unknown) | unknown): void;
|
|
9
|
+
* test((arg) => {}) // oops, implicit any
|
|
10
|
+
* ```
|
|
11
|
+
*
|
|
12
|
+
* This type can be used to avoid this problem. This union represents the same value space as `unknown`.
|
|
13
|
+
*/
|
|
4
14
|
|
|
5
|
-
//
|
|
6
|
-
// export type IndexByType<T extends { type: string }> = { [E in T as E['type']]: E; };
|
|
15
|
+
// https://github.com/microsoft/TypeScript/issues/23182#issuecomment-379091887
|
|
7
16
|
|
|
8
17
|
/**
|
|
9
18
|
* The full definition of an event, with a string `type`.
|
|
@@ -13,8 +22,6 @@ import { devToolsAdapter } from '../dev/dist/xstate-dev.esm.js';
|
|
|
13
22
|
// we should also accept a raw machine as actor logic here
|
|
14
23
|
// or just make machine actor logic
|
|
15
24
|
|
|
16
|
-
// TODO: narrow this to logic from machine
|
|
17
|
-
|
|
18
25
|
/**
|
|
19
26
|
* The string or object representing the state value relative to the parent state node.
|
|
20
27
|
*
|
|
@@ -305,7 +312,7 @@ const symbolObservable = (() => typeof Symbol === 'function' && Symbol.observabl
|
|
|
305
312
|
* @returns Actor logic
|
|
306
313
|
*/
|
|
307
314
|
function fromTransition(transition, initialState) {
|
|
308
|
-
|
|
315
|
+
return {
|
|
309
316
|
config: transition,
|
|
310
317
|
transition: (state, event, actorContext) => {
|
|
311
318
|
return transition(state, event, actorContext);
|
|
@@ -319,103 +326,255 @@ function fromTransition(transition, initialState) {
|
|
|
319
326
|
getPersistedState: state => state,
|
|
320
327
|
restoreState: state => state
|
|
321
328
|
};
|
|
322
|
-
return logic;
|
|
323
329
|
}
|
|
324
330
|
|
|
325
|
-
|
|
326
|
-
const
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
331
|
+
function matchesState(parentStateId, childStateId) {
|
|
332
|
+
const parentStateValue = toStateValue(parentStateId);
|
|
333
|
+
const childStateValue = toStateValue(childStateId);
|
|
334
|
+
if (typeof childStateValue === 'string') {
|
|
335
|
+
if (typeof parentStateValue === 'string') {
|
|
336
|
+
return childStateValue === parentStateValue;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
// Parent more specific than child
|
|
340
|
+
return false;
|
|
341
|
+
}
|
|
342
|
+
if (typeof parentStateValue === 'string') {
|
|
343
|
+
return parentStateValue in childStateValue;
|
|
344
|
+
}
|
|
345
|
+
return Object.keys(parentStateValue).every(key => {
|
|
346
|
+
if (!(key in childStateValue)) {
|
|
347
|
+
return false;
|
|
348
|
+
}
|
|
349
|
+
return matchesState(parentStateValue[key], childStateValue[key]);
|
|
350
|
+
});
|
|
351
|
+
}
|
|
352
|
+
function toStatePath(stateId) {
|
|
353
|
+
try {
|
|
354
|
+
if (isArray(stateId)) {
|
|
355
|
+
return stateId;
|
|
356
|
+
}
|
|
357
|
+
return stateId.toString().split(STATE_DELIMITER);
|
|
358
|
+
} catch (e) {
|
|
359
|
+
throw new Error(`'${stateId}' is not a valid state path.`);
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
function isStateLike(state) {
|
|
363
|
+
return typeof state === 'object' && 'value' in state && 'context' in state && 'event' in state;
|
|
364
|
+
}
|
|
365
|
+
function toStateValue(stateValue) {
|
|
366
|
+
if (isStateLike(stateValue)) {
|
|
367
|
+
return stateValue.value;
|
|
368
|
+
}
|
|
369
|
+
if (isArray(stateValue)) {
|
|
370
|
+
return pathToStateValue(stateValue);
|
|
371
|
+
}
|
|
372
|
+
if (typeof stateValue !== 'string') {
|
|
373
|
+
return stateValue;
|
|
374
|
+
}
|
|
375
|
+
const statePath = toStatePath(stateValue);
|
|
376
|
+
return pathToStateValue(statePath);
|
|
377
|
+
}
|
|
378
|
+
function pathToStateValue(statePath) {
|
|
379
|
+
if (statePath.length === 1) {
|
|
380
|
+
return statePath[0];
|
|
381
|
+
}
|
|
382
|
+
const value = {};
|
|
383
|
+
let marker = value;
|
|
384
|
+
for (let i = 0; i < statePath.length - 1; i++) {
|
|
385
|
+
if (i === statePath.length - 2) {
|
|
386
|
+
marker[statePath[i]] = statePath[i + 1];
|
|
387
|
+
} else {
|
|
388
|
+
const previous = marker;
|
|
389
|
+
marker = {};
|
|
390
|
+
previous[statePath[i]] = marker;
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
return value;
|
|
394
|
+
}
|
|
395
|
+
function mapValues(collection, iteratee) {
|
|
396
|
+
const result = {};
|
|
397
|
+
const collectionKeys = Object.keys(collection);
|
|
398
|
+
for (let i = 0; i < collectionKeys.length; i++) {
|
|
399
|
+
const key = collectionKeys[i];
|
|
400
|
+
result[key] = iteratee(collection[key], key, collection, i);
|
|
401
|
+
}
|
|
402
|
+
return result;
|
|
403
|
+
}
|
|
404
|
+
function flatten(array) {
|
|
405
|
+
return [].concat(...array);
|
|
406
|
+
}
|
|
407
|
+
function toArrayStrict(value) {
|
|
408
|
+
if (isArray(value)) {
|
|
409
|
+
return value;
|
|
410
|
+
}
|
|
411
|
+
return [value];
|
|
412
|
+
}
|
|
413
|
+
function toArray(value) {
|
|
414
|
+
if (value === undefined) {
|
|
415
|
+
return [];
|
|
416
|
+
}
|
|
417
|
+
return toArrayStrict(value);
|
|
418
|
+
}
|
|
419
|
+
function mapContext(mapper, context, event, self) {
|
|
420
|
+
if (typeof mapper === 'function') {
|
|
421
|
+
return mapper({
|
|
422
|
+
context,
|
|
423
|
+
event,
|
|
424
|
+
self
|
|
425
|
+
});
|
|
426
|
+
}
|
|
427
|
+
return mapper;
|
|
428
|
+
}
|
|
429
|
+
function isPromiseLike(value) {
|
|
430
|
+
if (value instanceof Promise) {
|
|
431
|
+
return true;
|
|
432
|
+
}
|
|
433
|
+
// Check if shape matches the Promise/A+ specification for a "thenable".
|
|
434
|
+
if (value !== null && (typeof value === 'function' || typeof value === 'object') && typeof value.then === 'function') {
|
|
435
|
+
return true;
|
|
436
|
+
}
|
|
437
|
+
return false;
|
|
438
|
+
}
|
|
439
|
+
function isArray(value) {
|
|
440
|
+
return Array.isArray(value);
|
|
441
|
+
}
|
|
442
|
+
function isErrorEvent(event) {
|
|
443
|
+
return typeof event.type === 'string' && (event.type === errorExecution || event.type.startsWith(errorPlatform));
|
|
444
|
+
}
|
|
445
|
+
function toTransitionConfigArray(configLike) {
|
|
446
|
+
return toArrayStrict(configLike).map(transitionLike => {
|
|
447
|
+
if (typeof transitionLike === 'undefined' || typeof transitionLike === 'string') {
|
|
448
|
+
return {
|
|
449
|
+
target: transitionLike
|
|
450
|
+
};
|
|
451
|
+
}
|
|
452
|
+
return transitionLike;
|
|
453
|
+
});
|
|
454
|
+
}
|
|
455
|
+
function normalizeTarget(target) {
|
|
456
|
+
if (target === undefined || target === TARGETLESS_KEY) {
|
|
457
|
+
return undefined;
|
|
458
|
+
}
|
|
459
|
+
return toArray(target);
|
|
460
|
+
}
|
|
461
|
+
function toInvokeConfig(invocable, id) {
|
|
462
|
+
if (typeof invocable === 'object') {
|
|
463
|
+
if ('src' in invocable) {
|
|
464
|
+
return invocable;
|
|
465
|
+
}
|
|
466
|
+
if ('transition' in invocable) {
|
|
467
|
+
return {
|
|
468
|
+
id,
|
|
469
|
+
src: invocable
|
|
470
|
+
};
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
return {
|
|
474
|
+
id,
|
|
475
|
+
src: invocable
|
|
476
|
+
};
|
|
477
|
+
}
|
|
478
|
+
function toObserver(nextHandler, errorHandler, completionHandler) {
|
|
479
|
+
const isObserver = typeof nextHandler === 'object';
|
|
480
|
+
const self = isObserver ? nextHandler : undefined;
|
|
481
|
+
return {
|
|
482
|
+
next: (isObserver ? nextHandler.next : nextHandler)?.bind(self),
|
|
483
|
+
error: (isObserver ? nextHandler.error : errorHandler)?.bind(self),
|
|
484
|
+
complete: (isObserver ? nextHandler.complete : completionHandler)?.bind(self)
|
|
485
|
+
};
|
|
486
|
+
}
|
|
487
|
+
function createInvokeId(stateNodeId, index) {
|
|
488
|
+
return `${stateNodeId}:invocation[${index}]`;
|
|
489
|
+
}
|
|
490
|
+
function resolveReferencedActor(referenced) {
|
|
491
|
+
return referenced ? 'transition' in referenced ? {
|
|
492
|
+
src: referenced,
|
|
493
|
+
input: undefined
|
|
494
|
+
} : referenced : undefined;
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
function fromCallback(invokeCallback) {
|
|
498
|
+
return {
|
|
499
|
+
config: invokeCallback,
|
|
500
|
+
start: (_state, {
|
|
501
|
+
self
|
|
502
|
+
}) => {
|
|
503
|
+
self.send({
|
|
504
|
+
type: startSignalType
|
|
505
|
+
});
|
|
361
506
|
},
|
|
362
|
-
|
|
507
|
+
transition: (state, event, {
|
|
363
508
|
self,
|
|
509
|
+
id,
|
|
364
510
|
system
|
|
365
511
|
}) => {
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
512
|
+
if (event.type === startSignalType) {
|
|
513
|
+
const sendBack = eventForParent => {
|
|
514
|
+
if (state.canceled) {
|
|
515
|
+
return;
|
|
516
|
+
}
|
|
517
|
+
self._parent?.send(eventForParent);
|
|
518
|
+
};
|
|
519
|
+
const receive = newListener => {
|
|
520
|
+
state.receivers.add(newListener);
|
|
521
|
+
};
|
|
522
|
+
state.dispose = invokeCallback({
|
|
523
|
+
input: state.input,
|
|
524
|
+
system,
|
|
525
|
+
self: self,
|
|
526
|
+
sendBack,
|
|
527
|
+
receive
|
|
528
|
+
});
|
|
529
|
+
if (isPromiseLike(state.dispose)) {
|
|
530
|
+
state.dispose.then(resolved => {
|
|
531
|
+
self._parent?.send(doneInvoke(id, resolved));
|
|
532
|
+
state.canceled = true;
|
|
533
|
+
}, errorData => {
|
|
534
|
+
state.canceled = true;
|
|
535
|
+
self._parent?.send(error(id, errorData));
|
|
536
|
+
});
|
|
537
|
+
}
|
|
538
|
+
return state;
|
|
370
539
|
}
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
}));
|
|
376
|
-
resolvedPromise.then(response => {
|
|
377
|
-
// TODO: remove this condition once dead letter queue lands
|
|
378
|
-
if (self._state.status !== 'active') {
|
|
379
|
-
return;
|
|
540
|
+
if (event.type === stopSignalType) {
|
|
541
|
+
state.canceled = true;
|
|
542
|
+
if (typeof state.dispose === 'function') {
|
|
543
|
+
state.dispose();
|
|
380
544
|
}
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
}
|
|
390
|
-
self.send({
|
|
391
|
-
type: rejectEventType,
|
|
392
|
-
data: errorData
|
|
393
|
-
});
|
|
394
|
-
});
|
|
545
|
+
return state;
|
|
546
|
+
}
|
|
547
|
+
if (isSignal(event)) {
|
|
548
|
+
// TODO: unrecognized signal
|
|
549
|
+
return state;
|
|
550
|
+
}
|
|
551
|
+
state.receivers.forEach(receiver => receiver(event));
|
|
552
|
+
return state;
|
|
395
553
|
},
|
|
396
554
|
getInitialState: (_, input) => {
|
|
397
555
|
return {
|
|
398
|
-
|
|
399
|
-
|
|
556
|
+
canceled: false,
|
|
557
|
+
receivers: new Set(),
|
|
558
|
+
dispose: undefined,
|
|
400
559
|
input
|
|
401
560
|
};
|
|
402
561
|
},
|
|
403
|
-
getSnapshot:
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
562
|
+
getSnapshot: () => undefined,
|
|
563
|
+
getPersistedState: ({
|
|
564
|
+
input,
|
|
565
|
+
canceled
|
|
566
|
+
}) => ({
|
|
567
|
+
input,
|
|
568
|
+
canceled
|
|
569
|
+
})
|
|
407
570
|
};
|
|
408
|
-
return logic;
|
|
409
571
|
}
|
|
410
572
|
|
|
411
|
-
// TODO: this likely shouldn't accept TEvent, observable actor doesn't accept external events
|
|
412
573
|
function fromObservable(observableCreator) {
|
|
413
574
|
const nextEventType = '$$xstate.next';
|
|
414
575
|
const errorEventType = '$$xstate.error';
|
|
415
576
|
const completeEventType = '$$xstate.complete';
|
|
416
|
-
|
|
417
|
-
// TODO: add event types
|
|
418
|
-
const logic = {
|
|
577
|
+
return {
|
|
419
578
|
config: observableCreator,
|
|
420
579
|
transition: (state, event, {
|
|
421
580
|
self,
|
|
@@ -445,6 +604,7 @@ function fromObservable(observableCreator) {
|
|
|
445
604
|
status: 'error',
|
|
446
605
|
input: undefined,
|
|
447
606
|
data: event.data,
|
|
607
|
+
// TODO: if we keep this as `data` we should reflect this in the type
|
|
448
608
|
subscription: undefined
|
|
449
609
|
};
|
|
450
610
|
case completeEventType:
|
|
@@ -522,7 +682,6 @@ function fromObservable(observableCreator) {
|
|
|
522
682
|
subscription: undefined
|
|
523
683
|
})
|
|
524
684
|
};
|
|
525
|
-
return logic;
|
|
526
685
|
}
|
|
527
686
|
|
|
528
687
|
/**
|
|
@@ -539,7 +698,7 @@ function fromEventObservable(lazyObservable) {
|
|
|
539
698
|
const completeEventType = '$$xstate.complete';
|
|
540
699
|
|
|
541
700
|
// TODO: event types
|
|
542
|
-
|
|
701
|
+
return {
|
|
543
702
|
config: lazyObservable,
|
|
544
703
|
transition: (state, event) => {
|
|
545
704
|
if (state.status !== 'active') {
|
|
@@ -552,329 +711,166 @@ function fromEventObservable(lazyObservable) {
|
|
|
552
711
|
status: 'error',
|
|
553
712
|
input: undefined,
|
|
554
713
|
data: event.data,
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
subscription: undefined,
|
|
579
|
-
status: 'active',
|
|
580
|
-
data: undefined,
|
|
581
|
-
input
|
|
582
|
-
};
|
|
583
|
-
},
|
|
584
|
-
start: (state, {
|
|
585
|
-
self,
|
|
586
|
-
system
|
|
587
|
-
}) => {
|
|
588
|
-
if (state.status === 'done') {
|
|
589
|
-
// Do not restart a completed observable
|
|
590
|
-
return;
|
|
591
|
-
}
|
|
592
|
-
state.subscription = lazyObservable({
|
|
593
|
-
input: state.input,
|
|
594
|
-
system,
|
|
595
|
-
self
|
|
596
|
-
}).subscribe({
|
|
597
|
-
next: value => {
|
|
598
|
-
self._parent?.send(value);
|
|
599
|
-
},
|
|
600
|
-
error: err => {
|
|
601
|
-
self.send({
|
|
602
|
-
type: errorEventType,
|
|
603
|
-
data: err
|
|
604
|
-
});
|
|
605
|
-
},
|
|
606
|
-
complete: () => {
|
|
607
|
-
self.send({
|
|
608
|
-
type: completeEventType
|
|
609
|
-
});
|
|
610
|
-
}
|
|
611
|
-
});
|
|
612
|
-
},
|
|
613
|
-
getSnapshot: _ => undefined,
|
|
614
|
-
getPersistedState: ({
|
|
615
|
-
status,
|
|
616
|
-
data,
|
|
617
|
-
input
|
|
618
|
-
}) => ({
|
|
619
|
-
status,
|
|
620
|
-
data,
|
|
621
|
-
input
|
|
622
|
-
}),
|
|
623
|
-
getStatus: state => state,
|
|
624
|
-
restoreState: state => ({
|
|
625
|
-
...state,
|
|
626
|
-
subscription: undefined
|
|
627
|
-
})
|
|
628
|
-
};
|
|
629
|
-
return logic;
|
|
630
|
-
}
|
|
631
|
-
|
|
632
|
-
function matchesState(parentStateId, childStateId) {
|
|
633
|
-
const parentStateValue = toStateValue(parentStateId);
|
|
634
|
-
const childStateValue = toStateValue(childStateId);
|
|
635
|
-
if (typeof childStateValue === 'string') {
|
|
636
|
-
if (typeof parentStateValue === 'string') {
|
|
637
|
-
return childStateValue === parentStateValue;
|
|
638
|
-
}
|
|
639
|
-
|
|
640
|
-
// Parent more specific than child
|
|
641
|
-
return false;
|
|
642
|
-
}
|
|
643
|
-
if (typeof parentStateValue === 'string') {
|
|
644
|
-
return parentStateValue in childStateValue;
|
|
645
|
-
}
|
|
646
|
-
return Object.keys(parentStateValue).every(key => {
|
|
647
|
-
if (!(key in childStateValue)) {
|
|
648
|
-
return false;
|
|
649
|
-
}
|
|
650
|
-
return matchesState(parentStateValue[key], childStateValue[key]);
|
|
651
|
-
});
|
|
652
|
-
}
|
|
653
|
-
function toStatePath(stateId) {
|
|
654
|
-
try {
|
|
655
|
-
if (isArray(stateId)) {
|
|
656
|
-
return stateId;
|
|
657
|
-
}
|
|
658
|
-
return stateId.toString().split(STATE_DELIMITER);
|
|
659
|
-
} catch (e) {
|
|
660
|
-
throw new Error(`'${stateId}' is not a valid state path.`);
|
|
661
|
-
}
|
|
662
|
-
}
|
|
663
|
-
function isStateLike(state) {
|
|
664
|
-
return typeof state === 'object' && 'value' in state && 'context' in state && 'event' in state;
|
|
665
|
-
}
|
|
666
|
-
function toStateValue(stateValue) {
|
|
667
|
-
if (isStateLike(stateValue)) {
|
|
668
|
-
return stateValue.value;
|
|
669
|
-
}
|
|
670
|
-
if (isArray(stateValue)) {
|
|
671
|
-
return pathToStateValue(stateValue);
|
|
672
|
-
}
|
|
673
|
-
if (typeof stateValue !== 'string') {
|
|
674
|
-
return stateValue;
|
|
675
|
-
}
|
|
676
|
-
const statePath = toStatePath(stateValue);
|
|
677
|
-
return pathToStateValue(statePath);
|
|
678
|
-
}
|
|
679
|
-
function pathToStateValue(statePath) {
|
|
680
|
-
if (statePath.length === 1) {
|
|
681
|
-
return statePath[0];
|
|
682
|
-
}
|
|
683
|
-
const value = {};
|
|
684
|
-
let marker = value;
|
|
685
|
-
for (let i = 0; i < statePath.length - 1; i++) {
|
|
686
|
-
if (i === statePath.length - 2) {
|
|
687
|
-
marker[statePath[i]] = statePath[i + 1];
|
|
688
|
-
} else {
|
|
689
|
-
const previous = marker;
|
|
690
|
-
marker = {};
|
|
691
|
-
previous[statePath[i]] = marker;
|
|
692
|
-
}
|
|
693
|
-
}
|
|
694
|
-
return value;
|
|
695
|
-
}
|
|
696
|
-
function mapValues(collection, iteratee) {
|
|
697
|
-
const result = {};
|
|
698
|
-
const collectionKeys = Object.keys(collection);
|
|
699
|
-
for (let i = 0; i < collectionKeys.length; i++) {
|
|
700
|
-
const key = collectionKeys[i];
|
|
701
|
-
result[key] = iteratee(collection[key], key, collection, i);
|
|
702
|
-
}
|
|
703
|
-
return result;
|
|
704
|
-
}
|
|
705
|
-
function flatten(array) {
|
|
706
|
-
return [].concat(...array);
|
|
707
|
-
}
|
|
708
|
-
function toArrayStrict(value) {
|
|
709
|
-
if (isArray(value)) {
|
|
710
|
-
return value;
|
|
711
|
-
}
|
|
712
|
-
return [value];
|
|
713
|
-
}
|
|
714
|
-
function toArray(value) {
|
|
715
|
-
if (value === undefined) {
|
|
716
|
-
return [];
|
|
717
|
-
}
|
|
718
|
-
return toArrayStrict(value);
|
|
719
|
-
}
|
|
720
|
-
function mapContext(mapper, context, event) {
|
|
721
|
-
if (typeof mapper === 'function') {
|
|
722
|
-
return mapper({
|
|
723
|
-
context,
|
|
724
|
-
event
|
|
725
|
-
});
|
|
726
|
-
}
|
|
727
|
-
const result = {};
|
|
728
|
-
const args = {
|
|
729
|
-
context,
|
|
730
|
-
event
|
|
731
|
-
};
|
|
732
|
-
for (const key of Object.keys(mapper)) {
|
|
733
|
-
const subMapper = mapper[key];
|
|
734
|
-
if (typeof subMapper === 'function') {
|
|
735
|
-
result[key] = subMapper(args);
|
|
736
|
-
} else {
|
|
737
|
-
result[key] = subMapper;
|
|
738
|
-
}
|
|
739
|
-
}
|
|
740
|
-
return result;
|
|
741
|
-
}
|
|
742
|
-
function isPromiseLike(value) {
|
|
743
|
-
if (value instanceof Promise) {
|
|
744
|
-
return true;
|
|
745
|
-
}
|
|
746
|
-
// Check if shape matches the Promise/A+ specification for a "thenable".
|
|
747
|
-
if (value !== null && (typeof value === 'function' || typeof value === 'object') && typeof value.then === 'function') {
|
|
748
|
-
return true;
|
|
749
|
-
}
|
|
750
|
-
return false;
|
|
751
|
-
}
|
|
752
|
-
function isArray(value) {
|
|
753
|
-
return Array.isArray(value);
|
|
754
|
-
}
|
|
755
|
-
function isErrorEvent(event) {
|
|
756
|
-
return typeof event.type === 'string' && (event.type === errorExecution || event.type.startsWith(errorPlatform));
|
|
757
|
-
}
|
|
758
|
-
function toTransitionConfigArray(configLike) {
|
|
759
|
-
return toArrayStrict(configLike).map(transitionLike => {
|
|
760
|
-
if (typeof transitionLike === 'undefined' || typeof transitionLike === 'string') {
|
|
761
|
-
return {
|
|
762
|
-
target: transitionLike
|
|
763
|
-
};
|
|
764
|
-
}
|
|
765
|
-
return transitionLike;
|
|
766
|
-
});
|
|
767
|
-
}
|
|
768
|
-
function normalizeTarget(target) {
|
|
769
|
-
if (target === undefined || target === TARGETLESS_KEY) {
|
|
770
|
-
return undefined;
|
|
771
|
-
}
|
|
772
|
-
return toArray(target);
|
|
773
|
-
}
|
|
774
|
-
function toInvokeConfig(invocable, id) {
|
|
775
|
-
if (typeof invocable === 'object') {
|
|
776
|
-
if ('src' in invocable) {
|
|
777
|
-
return invocable;
|
|
778
|
-
}
|
|
779
|
-
if ('transition' in invocable) {
|
|
714
|
+
// TODO: if we keep this as `data` we should reflect this in the type
|
|
715
|
+
subscription: undefined
|
|
716
|
+
};
|
|
717
|
+
case completeEventType:
|
|
718
|
+
return {
|
|
719
|
+
...state,
|
|
720
|
+
status: 'done',
|
|
721
|
+
input: undefined,
|
|
722
|
+
subscription: undefined
|
|
723
|
+
};
|
|
724
|
+
case stopSignalType:
|
|
725
|
+
state.subscription.unsubscribe();
|
|
726
|
+
return {
|
|
727
|
+
...state,
|
|
728
|
+
status: 'canceled',
|
|
729
|
+
input: undefined,
|
|
730
|
+
subscription: undefined
|
|
731
|
+
};
|
|
732
|
+
default:
|
|
733
|
+
return state;
|
|
734
|
+
}
|
|
735
|
+
},
|
|
736
|
+
getInitialState: (_, input) => {
|
|
780
737
|
return {
|
|
781
|
-
|
|
782
|
-
|
|
738
|
+
subscription: undefined,
|
|
739
|
+
status: 'active',
|
|
740
|
+
data: undefined,
|
|
741
|
+
input
|
|
783
742
|
};
|
|
784
|
-
}
|
|
785
|
-
}
|
|
786
|
-
return {
|
|
787
|
-
id,
|
|
788
|
-
src: invocable
|
|
789
|
-
};
|
|
790
|
-
}
|
|
791
|
-
function toObserver(nextHandler, errorHandler, completionHandler) {
|
|
792
|
-
const noop = () => {};
|
|
793
|
-
const isObserver = typeof nextHandler === 'object';
|
|
794
|
-
const self = isObserver ? nextHandler : null;
|
|
795
|
-
return {
|
|
796
|
-
next: ((isObserver ? nextHandler.next : nextHandler) || noop).bind(self),
|
|
797
|
-
error: ((isObserver ? nextHandler.error : errorHandler) || noop).bind(self),
|
|
798
|
-
complete: ((isObserver ? nextHandler.complete : completionHandler) || noop).bind(self)
|
|
799
|
-
};
|
|
800
|
-
}
|
|
801
|
-
function createInvokeId(stateNodeId, index) {
|
|
802
|
-
return `${stateNodeId}:invocation[${index}]`;
|
|
803
|
-
}
|
|
804
|
-
function resolveReferencedActor(referenced) {
|
|
805
|
-
return referenced ? 'transition' in referenced ? {
|
|
806
|
-
src: referenced,
|
|
807
|
-
input: undefined
|
|
808
|
-
} : referenced : undefined;
|
|
809
|
-
}
|
|
810
|
-
|
|
811
|
-
function fromCallback(invokeCallback) {
|
|
812
|
-
const logic = {
|
|
813
|
-
config: invokeCallback,
|
|
814
|
-
start: (_state, {
|
|
815
|
-
self
|
|
816
|
-
}) => {
|
|
817
|
-
self.send({
|
|
818
|
-
type: startSignalType
|
|
819
|
-
});
|
|
820
743
|
},
|
|
821
|
-
|
|
744
|
+
start: (state, {
|
|
822
745
|
self,
|
|
823
|
-
id,
|
|
824
746
|
system
|
|
825
747
|
}) => {
|
|
826
|
-
if (
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
self
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
self._parent?.send(error(id, errorData));
|
|
748
|
+
if (state.status === 'done') {
|
|
749
|
+
// Do not restart a completed observable
|
|
750
|
+
return;
|
|
751
|
+
}
|
|
752
|
+
state.subscription = lazyObservable({
|
|
753
|
+
input: state.input,
|
|
754
|
+
system,
|
|
755
|
+
self
|
|
756
|
+
}).subscribe({
|
|
757
|
+
next: value => {
|
|
758
|
+
self._parent?.send(value);
|
|
759
|
+
},
|
|
760
|
+
error: err => {
|
|
761
|
+
self.send({
|
|
762
|
+
type: errorEventType,
|
|
763
|
+
data: err
|
|
764
|
+
});
|
|
765
|
+
},
|
|
766
|
+
complete: () => {
|
|
767
|
+
self.send({
|
|
768
|
+
type: completeEventType
|
|
848
769
|
});
|
|
849
770
|
}
|
|
771
|
+
});
|
|
772
|
+
},
|
|
773
|
+
getSnapshot: _ => undefined,
|
|
774
|
+
getPersistedState: ({
|
|
775
|
+
status,
|
|
776
|
+
data,
|
|
777
|
+
input
|
|
778
|
+
}) => ({
|
|
779
|
+
status,
|
|
780
|
+
data,
|
|
781
|
+
input
|
|
782
|
+
}),
|
|
783
|
+
getStatus: state => state,
|
|
784
|
+
restoreState: state => ({
|
|
785
|
+
...state,
|
|
786
|
+
subscription: undefined
|
|
787
|
+
})
|
|
788
|
+
};
|
|
789
|
+
}
|
|
790
|
+
|
|
791
|
+
const resolveEventType = '$$xstate.resolve';
|
|
792
|
+
const rejectEventType = '$$xstate.reject';
|
|
793
|
+
function fromPromise(
|
|
794
|
+
// TODO: add types
|
|
795
|
+
promiseCreator) {
|
|
796
|
+
// TODO: add event types
|
|
797
|
+
const logic = {
|
|
798
|
+
config: promiseCreator,
|
|
799
|
+
transition: (state, event) => {
|
|
800
|
+
if (state.status !== 'active') {
|
|
850
801
|
return state;
|
|
851
802
|
}
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
803
|
+
switch (event.type) {
|
|
804
|
+
case resolveEventType:
|
|
805
|
+
return {
|
|
806
|
+
...state,
|
|
807
|
+
status: 'done',
|
|
808
|
+
data: event.data,
|
|
809
|
+
input: undefined
|
|
810
|
+
};
|
|
811
|
+
case rejectEventType:
|
|
812
|
+
return {
|
|
813
|
+
...state,
|
|
814
|
+
status: 'error',
|
|
815
|
+
data: event.data,
|
|
816
|
+
// TODO: if we keep this as `data` we should reflect this in the type
|
|
817
|
+
input: undefined
|
|
818
|
+
};
|
|
819
|
+
case stopSignalType:
|
|
820
|
+
return {
|
|
821
|
+
...state,
|
|
822
|
+
status: 'canceled',
|
|
823
|
+
input: undefined
|
|
824
|
+
};
|
|
825
|
+
default:
|
|
826
|
+
return state;
|
|
858
827
|
}
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
828
|
+
},
|
|
829
|
+
start: (state, {
|
|
830
|
+
self,
|
|
831
|
+
system
|
|
832
|
+
}) => {
|
|
833
|
+
// TODO: determine how to allow customizing this so that promises
|
|
834
|
+
// can be restarted if necessary
|
|
835
|
+
if (state.status !== 'active') {
|
|
836
|
+
return;
|
|
862
837
|
}
|
|
863
|
-
|
|
864
|
-
|
|
838
|
+
const resolvedPromise = Promise.resolve(promiseCreator({
|
|
839
|
+
input: state.input,
|
|
840
|
+
system,
|
|
841
|
+
self
|
|
842
|
+
}));
|
|
843
|
+
resolvedPromise.then(response => {
|
|
844
|
+
// TODO: remove this condition once dead letter queue lands
|
|
845
|
+
if (self._state.status !== 'active') {
|
|
846
|
+
return;
|
|
847
|
+
}
|
|
848
|
+
self.send({
|
|
849
|
+
type: resolveEventType,
|
|
850
|
+
data: response
|
|
851
|
+
});
|
|
852
|
+
}, errorData => {
|
|
853
|
+
// TODO: remove this condition once dead letter queue lands
|
|
854
|
+
if (self._state.status !== 'active') {
|
|
855
|
+
return;
|
|
856
|
+
}
|
|
857
|
+
self.send({
|
|
858
|
+
type: rejectEventType,
|
|
859
|
+
data: errorData
|
|
860
|
+
});
|
|
861
|
+
});
|
|
865
862
|
},
|
|
866
863
|
getInitialState: (_, input) => {
|
|
867
864
|
return {
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
dispose: undefined,
|
|
865
|
+
status: 'active',
|
|
866
|
+
data: undefined,
|
|
871
867
|
input
|
|
872
868
|
};
|
|
873
869
|
},
|
|
874
|
-
getSnapshot:
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
870
|
+
getSnapshot: state => state.data,
|
|
871
|
+
getStatus: state => state,
|
|
872
|
+
getPersistedState: state => state,
|
|
873
|
+
restoreState: state => state
|
|
878
874
|
};
|
|
879
875
|
return logic;
|
|
880
876
|
}
|
|
@@ -913,6 +909,7 @@ function toActorRef(actorRefLike) {
|
|
|
913
909
|
id: 'anonymous',
|
|
914
910
|
sessionId: '',
|
|
915
911
|
getSnapshot: () => undefined,
|
|
912
|
+
// TODO: this isn't safe
|
|
916
913
|
[symbolObservable]: function () {
|
|
917
914
|
return this;
|
|
918
915
|
},
|
|
@@ -926,6 +923,19 @@ function createEmptyActor() {
|
|
|
926
923
|
return interpret(emptyLogic);
|
|
927
924
|
}
|
|
928
925
|
|
|
926
|
+
/**
|
|
927
|
+
* This function makes sure that unhandled errors are thrown in a separate macrotask.
|
|
928
|
+
* It allows those errors to be detected by global error handlers and reported to bug tracking services
|
|
929
|
+
* without interrupting our own stack of execution.
|
|
930
|
+
*
|
|
931
|
+
* @param err error to be thrown
|
|
932
|
+
*/
|
|
933
|
+
function reportUnhandledError(err) {
|
|
934
|
+
setTimeout(() => {
|
|
935
|
+
throw err;
|
|
936
|
+
});
|
|
937
|
+
}
|
|
938
|
+
|
|
929
939
|
function createSystem() {
|
|
930
940
|
let sessionIdCounter = 0;
|
|
931
941
|
const children = new Map();
|
|
@@ -1094,29 +1104,38 @@ class Interpreter {
|
|
|
1094
1104
|
deferredFn();
|
|
1095
1105
|
}
|
|
1096
1106
|
for (const observer of this.observers) {
|
|
1097
|
-
|
|
1107
|
+
// TODO: should observers be notified in case of the error?
|
|
1108
|
+
try {
|
|
1109
|
+
observer.next?.(snapshot);
|
|
1110
|
+
} catch (err) {
|
|
1111
|
+
reportUnhandledError(err);
|
|
1112
|
+
}
|
|
1098
1113
|
}
|
|
1099
1114
|
const status = this.logic.getStatus?.(state);
|
|
1100
1115
|
switch (status?.status) {
|
|
1101
1116
|
case 'done':
|
|
1102
1117
|
this._stopProcedure();
|
|
1118
|
+
this._complete();
|
|
1103
1119
|
this._doneEvent = doneInvoke(this.id, status.data);
|
|
1104
1120
|
this._parent?.send(this._doneEvent);
|
|
1105
|
-
this._complete();
|
|
1106
1121
|
break;
|
|
1107
1122
|
case 'error':
|
|
1108
1123
|
this._stopProcedure();
|
|
1109
|
-
this._parent?.send(error(this.id, status.data));
|
|
1110
1124
|
this._error(status.data);
|
|
1125
|
+
this._parent?.send(error(this.id, status.data));
|
|
1111
1126
|
break;
|
|
1112
1127
|
}
|
|
1113
1128
|
}
|
|
1114
1129
|
subscribe(nextListenerOrObserver, errorListener, completeListener) {
|
|
1115
1130
|
const observer = toObserver(nextListenerOrObserver, errorListener, completeListener);
|
|
1116
|
-
this.
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1131
|
+
if (this.status !== ActorStatus.Stopped) {
|
|
1132
|
+
this.observers.add(observer);
|
|
1133
|
+
} else {
|
|
1134
|
+
try {
|
|
1135
|
+
observer.complete?.();
|
|
1136
|
+
} catch (err) {
|
|
1137
|
+
reportUnhandledError(err);
|
|
1138
|
+
}
|
|
1120
1139
|
}
|
|
1121
1140
|
return {
|
|
1122
1141
|
unsubscribe: () => {
|
|
@@ -1138,8 +1157,26 @@ class Interpreter {
|
|
|
1138
1157
|
this.system._set(this._systemId, this);
|
|
1139
1158
|
}
|
|
1140
1159
|
this.status = ActorStatus.Running;
|
|
1160
|
+
const status = this.logic.getStatus?.(this._state);
|
|
1161
|
+
switch (status?.status) {
|
|
1162
|
+
case 'done':
|
|
1163
|
+
// a state machine can be "done" upon intialization (it could reach a final state using initial microsteps)
|
|
1164
|
+
// we still need to complete observers, flush deferreds etc
|
|
1165
|
+
this.update(this._state);
|
|
1166
|
+
// fallthrough
|
|
1167
|
+
case 'error':
|
|
1168
|
+
// TODO: rethink cleanup of observers, mailbox, etc
|
|
1169
|
+
return this;
|
|
1170
|
+
}
|
|
1141
1171
|
if (this.logic.start) {
|
|
1142
|
-
|
|
1172
|
+
try {
|
|
1173
|
+
this.logic.start(this._state, this._actorContext);
|
|
1174
|
+
} catch (err) {
|
|
1175
|
+
this._stopProcedure();
|
|
1176
|
+
this._error(err);
|
|
1177
|
+
this._parent?.send(error(this.id, err));
|
|
1178
|
+
return this;
|
|
1179
|
+
}
|
|
1143
1180
|
}
|
|
1144
1181
|
|
|
1145
1182
|
// TODO: this notifies all subscribers but usually this is redundant
|
|
@@ -1153,23 +1190,30 @@ class Interpreter {
|
|
|
1153
1190
|
return this;
|
|
1154
1191
|
}
|
|
1155
1192
|
_process(event) {
|
|
1193
|
+
// TODO: reexamine what happens when an action (or a guard or smth) throws
|
|
1194
|
+
let nextState;
|
|
1195
|
+
let caughtError;
|
|
1156
1196
|
try {
|
|
1157
|
-
|
|
1158
|
-
this.update(nextState);
|
|
1159
|
-
if (event.type === stopSignalType) {
|
|
1160
|
-
this._stopProcedure();
|
|
1161
|
-
this._complete();
|
|
1162
|
-
}
|
|
1197
|
+
nextState = this.logic.transition(this._state, event, this._actorContext);
|
|
1163
1198
|
} catch (err) {
|
|
1164
|
-
//
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
}
|
|
1199
|
+
// we wrap it in a box so we can rethrow it later even if falsy value gets caught here
|
|
1200
|
+
caughtError = {
|
|
1201
|
+
err
|
|
1202
|
+
};
|
|
1203
|
+
}
|
|
1204
|
+
if (caughtError) {
|
|
1205
|
+
const {
|
|
1206
|
+
err
|
|
1207
|
+
} = caughtError;
|
|
1208
|
+
this._stopProcedure();
|
|
1209
|
+
this._error(err);
|
|
1210
|
+
this._parent?.send(error(this.id, err));
|
|
1211
|
+
return;
|
|
1212
|
+
}
|
|
1213
|
+
this.update(nextState);
|
|
1214
|
+
if (event.type === stopSignalType) {
|
|
1215
|
+
this._stopProcedure();
|
|
1216
|
+
this._complete();
|
|
1173
1217
|
}
|
|
1174
1218
|
}
|
|
1175
1219
|
_stop() {
|
|
@@ -1198,15 +1242,35 @@ class Interpreter {
|
|
|
1198
1242
|
}
|
|
1199
1243
|
_complete() {
|
|
1200
1244
|
for (const observer of this.observers) {
|
|
1201
|
-
|
|
1245
|
+
try {
|
|
1246
|
+
observer.complete?.();
|
|
1247
|
+
} catch (err) {
|
|
1248
|
+
reportUnhandledError(err);
|
|
1249
|
+
}
|
|
1202
1250
|
}
|
|
1203
1251
|
this.observers.clear();
|
|
1204
1252
|
}
|
|
1205
|
-
_error(
|
|
1253
|
+
_error(err) {
|
|
1254
|
+
if (!this.observers.size) {
|
|
1255
|
+
if (!this._parent) {
|
|
1256
|
+
reportUnhandledError(err);
|
|
1257
|
+
}
|
|
1258
|
+
return;
|
|
1259
|
+
}
|
|
1260
|
+
let reportError = false;
|
|
1206
1261
|
for (const observer of this.observers) {
|
|
1207
|
-
observer.error
|
|
1262
|
+
const errorListener = observer.error;
|
|
1263
|
+
reportError ||= !errorListener;
|
|
1264
|
+
try {
|
|
1265
|
+
errorListener?.(err);
|
|
1266
|
+
} catch (err2) {
|
|
1267
|
+
reportUnhandledError(err2);
|
|
1268
|
+
}
|
|
1208
1269
|
}
|
|
1209
1270
|
this.observers.clear();
|
|
1271
|
+
if (reportError) {
|
|
1272
|
+
reportUnhandledError(err);
|
|
1273
|
+
}
|
|
1210
1274
|
}
|
|
1211
1275
|
_stopProcedure() {
|
|
1212
1276
|
if (this.status !== ActorStatus.Running) {
|
|
@@ -1528,10 +1592,10 @@ function toGuardDefinition(guardConfig, getPredicate) {
|
|
|
1528
1592
|
}
|
|
1529
1593
|
}
|
|
1530
1594
|
|
|
1531
|
-
function getOutput(configuration, context, event) {
|
|
1595
|
+
function getOutput(configuration, context, event, self) {
|
|
1532
1596
|
const machine = configuration[0].machine;
|
|
1533
1597
|
const finalChildStateNode = configuration.find(stateNode => stateNode.type === 'final' && stateNode.parent === machine.root);
|
|
1534
|
-
return finalChildStateNode && finalChildStateNode.output ? mapContext(finalChildStateNode.output, context, event) : undefined;
|
|
1598
|
+
return finalChildStateNode && finalChildStateNode.output ? mapContext(finalChildStateNode.output, context, event, self) : undefined;
|
|
1535
1599
|
}
|
|
1536
1600
|
const isAtomicStateNode = stateNode => stateNode.type === 'atomic' || stateNode.type === 'final';
|
|
1537
1601
|
function getChildren(stateNode) {
|
|
@@ -2147,7 +2211,7 @@ function microstepProcedure(transitions, currentState, mutConfiguration, event,
|
|
|
2147
2211
|
actions.push(...filteredTransitions.flatMap(t => t.actions));
|
|
2148
2212
|
|
|
2149
2213
|
// Enter states
|
|
2150
|
-
enterStates(event, filteredTransitions, mutConfiguration, actions, internalQueue, currentState, historyValue, isInitial);
|
|
2214
|
+
enterStates(event, filteredTransitions, mutConfiguration, actions, internalQueue, currentState, historyValue, isInitial, actorCtx);
|
|
2151
2215
|
const nextConfiguration = [...mutConfiguration];
|
|
2152
2216
|
const done = isInFinalState(nextConfiguration);
|
|
2153
2217
|
if (done) {
|
|
@@ -2156,7 +2220,7 @@ function microstepProcedure(transitions, currentState, mutConfiguration, event,
|
|
|
2156
2220
|
}
|
|
2157
2221
|
try {
|
|
2158
2222
|
const nextState = resolveActionsAndContext(actions, event, currentState, actorCtx);
|
|
2159
|
-
const output = done ? getOutput(nextConfiguration, nextState.context, event) : undefined;
|
|
2223
|
+
const output = done ? getOutput(nextConfiguration, nextState.context, event, actorCtx.self) : undefined;
|
|
2160
2224
|
internalQueue.push(...nextState._internalQueue);
|
|
2161
2225
|
return cloneState(currentState, {
|
|
2162
2226
|
configuration: nextConfiguration,
|
|
@@ -2173,7 +2237,7 @@ function microstepProcedure(transitions, currentState, mutConfiguration, event,
|
|
|
2173
2237
|
throw e;
|
|
2174
2238
|
}
|
|
2175
2239
|
}
|
|
2176
|
-
function enterStates(event, filteredTransitions, mutConfiguration, actions, internalQueue, currentState, historyValue, isInitial) {
|
|
2240
|
+
function enterStates(event, filteredTransitions, mutConfiguration, actions, internalQueue, currentState, historyValue, isInitial, actorContext) {
|
|
2177
2241
|
const statesToEnter = new Set();
|
|
2178
2242
|
const statesForDefaultEntry = new Set();
|
|
2179
2243
|
computeEntrySet(filteredTransitions, historyValue, statesForDefaultEntry, statesToEnter);
|
|
@@ -2201,7 +2265,7 @@ function enterStates(event, filteredTransitions, mutConfiguration, actions, inte
|
|
|
2201
2265
|
if (!parent.parent) {
|
|
2202
2266
|
continue;
|
|
2203
2267
|
}
|
|
2204
|
-
internalQueue.push(done(parent.id, stateNodeToEnter.output ? mapContext(stateNodeToEnter.output, currentState.context, event) : undefined));
|
|
2268
|
+
internalQueue.push(done(parent.id, stateNodeToEnter.output ? mapContext(stateNodeToEnter.output, currentState.context, event, actorContext.self) : undefined));
|
|
2205
2269
|
if (parent.parent) {
|
|
2206
2270
|
const grandparent = parent.parent;
|
|
2207
2271
|
if (grandparent.type === 'parallel') {
|
|
@@ -2521,6 +2585,7 @@ class State {
|
|
|
2521
2585
|
this.value = void 0;
|
|
2522
2586
|
this.done = void 0;
|
|
2523
2587
|
this.output = void 0;
|
|
2588
|
+
this.error = void 0;
|
|
2524
2589
|
this.context = void 0;
|
|
2525
2590
|
this.historyValue = {};
|
|
2526
2591
|
this._internalQueue = void 0;
|
|
@@ -2537,6 +2602,7 @@ class State {
|
|
|
2537
2602
|
this.tags = new Set(flatten(this.configuration.map(sn => sn.tags)));
|
|
2538
2603
|
this.done = config.done ?? false;
|
|
2539
2604
|
this.output = config.output;
|
|
2605
|
+
this.error = config.error;
|
|
2540
2606
|
}
|
|
2541
2607
|
|
|
2542
2608
|
/**
|
|
@@ -2772,7 +2838,7 @@ function createSpawner(actorContext, {
|
|
|
2772
2838
|
}
|
|
2773
2839
|
};
|
|
2774
2840
|
return (src, options) => {
|
|
2775
|
-
const actorRef = spawn(src, options);
|
|
2841
|
+
const actorRef = spawn(src, options); // TODO: fix types
|
|
2776
2842
|
spawnedChildren[actorRef.id] = actorRef;
|
|
2777
2843
|
actorContext.defer(() => {
|
|
2778
2844
|
if (actorRef.status === ActorStatus.Stopped) {
|
|
@@ -2986,4 +3052,4 @@ function createInitEvent(input) {
|
|
|
2986
3052
|
};
|
|
2987
3053
|
}
|
|
2988
3054
|
|
|
2989
|
-
export { fromEventObservable as $,
|
|
3055
|
+
export { fromEventObservable as $, microstep as A, isAtomicStateNode as B, isStateId as C, getStateNodeByPath as D, getPersistedState as E, resolveReferencedActor as F, interpret as G, matchesState as H, sendTo as I, sendParent as J, forwardTo as K, Interpreter as L, ActorStatus as M, NULL_EVENT as N, doneInvoke as O, cancel as P, choose as Q, log as R, STATE_DELIMITER as S, pure as T, raise as U, stop as V, pathToStateValue as W, toObserver as X, fromPromise as Y, fromObservable as Z, fromCallback as _, toTransitionConfigArray as a, fromTransition as a0, stateIn as a1, not as a2, and as a3, or as a4, ConstantPrefix as a5, SpecialTargets as a6, startSignalType as a7, stopSignalType as a8, startSignal as a9, stopSignal as aa, isSignal as ab, isActorRef as ac, toActorRef as ad, createEmptyActor as ae, toGuardDefinition as af, constantPrefixes as ag, after as ah, done as ai, error as aj, escalate as ak, formatTransition as b, memo as c, flatten as d, evaluateGuard as e, formatTransitions as f, createInvokeId as g, getDelayedTransitions as h, formatInitialTransition as i, getCandidates as j, toInvokeConfig as k, getConfiguration as l, mapValues as m, getStateNodes as n, isInFinalState as o, State as p, isErrorEvent as q, resolveStateValue as r, cloneState as s, toArray as t, macrostep as u, transitionNode as v, getInitialConfiguration as w, resolveActionsAndContext as x, assign as y, createInitEvent as z };
|