xstate 5.0.0-beta.19 → 5.0.0-beta.20
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.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-2d912781.cjs.js → actions-069d9805.cjs.js} +307 -311
- package/dist/{actions-3b74fb92.esm.js → actions-a8a9433c.esm.js} +307 -311
- package/dist/{actions-72105f77.development.esm.js → actions-b299d008.development.esm.js} +307 -311
- package/dist/{actions-bce11b97.development.cjs.js → actions-d1c41ed3.development.cjs.js} +307 -311
- package/dist/declarations/src/Machine.d.ts +2 -2
- package/dist/declarations/src/State.d.ts +15 -4
- package/dist/declarations/src/StateMachine.d.ts +16 -16
- package/dist/declarations/src/StateNode.d.ts +4 -4
- package/dist/declarations/src/actions/send.d.ts +1 -1
- package/dist/declarations/src/actions/stop.d.ts +1 -1
- package/dist/declarations/src/actors/callback.d.ts +13 -3
- package/dist/declarations/src/actors/index.d.ts +4 -4
- package/dist/declarations/src/actors/observable.d.ts +8 -8
- package/dist/declarations/src/actors/promise.d.ts +12 -6
- 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 +99 -59
- package/dist/declarations/src/utils.d.ts +2 -2
- package/dist/xstate.cjs.js +2 -3
- package/dist/xstate.development.cjs.js +2 -3
- package/dist/xstate.development.esm.js +3 -4
- package/dist/xstate.esm.js +3 -4
- 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
|
@@ -2,9 +2,6 @@ import { devToolsAdapter } from '../dev/dist/xstate-dev.development.esm.js';
|
|
|
2
2
|
|
|
3
3
|
// https://github.com/microsoft/TypeScript/issues/23182#issuecomment-379091887
|
|
4
4
|
|
|
5
|
-
// TODO: replace in v5 with:
|
|
6
|
-
// export type IndexByType<T extends { type: string }> = { [E in T as E['type']]: E; };
|
|
7
|
-
|
|
8
5
|
/**
|
|
9
6
|
* The full definition of an event, with a string `type`.
|
|
10
7
|
*/
|
|
@@ -13,8 +10,6 @@ import { devToolsAdapter } from '../dev/dist/xstate-dev.development.esm.js';
|
|
|
13
10
|
// we should also accept a raw machine as actor logic here
|
|
14
11
|
// or just make machine actor logic
|
|
15
12
|
|
|
16
|
-
// TODO: narrow this to logic from machine
|
|
17
|
-
|
|
18
13
|
/**
|
|
19
14
|
* The string or object representing the state value relative to the parent state node.
|
|
20
15
|
*
|
|
@@ -321,7 +316,7 @@ const symbolObservable = (() => typeof Symbol === 'function' && Symbol.observabl
|
|
|
321
316
|
* @returns Actor logic
|
|
322
317
|
*/
|
|
323
318
|
function fromTransition(transition, initialState) {
|
|
324
|
-
|
|
319
|
+
return {
|
|
325
320
|
config: transition,
|
|
326
321
|
transition: (state, event, actorContext) => {
|
|
327
322
|
return transition(state, event, actorContext);
|
|
@@ -335,96 +330,260 @@ function fromTransition(transition, initialState) {
|
|
|
335
330
|
getPersistedState: state => state,
|
|
336
331
|
restoreState: state => state
|
|
337
332
|
};
|
|
338
|
-
return logic;
|
|
339
333
|
}
|
|
340
334
|
|
|
341
|
-
|
|
342
|
-
const
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
335
|
+
function matchesState(parentStateId, childStateId) {
|
|
336
|
+
const parentStateValue = toStateValue(parentStateId);
|
|
337
|
+
const childStateValue = toStateValue(childStateId);
|
|
338
|
+
if (typeof childStateValue === 'string') {
|
|
339
|
+
if (typeof parentStateValue === 'string') {
|
|
340
|
+
return childStateValue === parentStateValue;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
// Parent more specific than child
|
|
344
|
+
return false;
|
|
345
|
+
}
|
|
346
|
+
if (typeof parentStateValue === 'string') {
|
|
347
|
+
return parentStateValue in childStateValue;
|
|
348
|
+
}
|
|
349
|
+
return Object.keys(parentStateValue).every(key => {
|
|
350
|
+
if (!(key in childStateValue)) {
|
|
351
|
+
return false;
|
|
352
|
+
}
|
|
353
|
+
return matchesState(parentStateValue[key], childStateValue[key]);
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
function toStatePath(stateId) {
|
|
357
|
+
try {
|
|
358
|
+
if (isArray(stateId)) {
|
|
359
|
+
return stateId;
|
|
360
|
+
}
|
|
361
|
+
return stateId.toString().split(STATE_DELIMITER);
|
|
362
|
+
} catch (e) {
|
|
363
|
+
throw new Error(`'${stateId}' is not a valid state path.`);
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
function isStateLike(state) {
|
|
367
|
+
return typeof state === 'object' && 'value' in state && 'context' in state && 'event' in state;
|
|
368
|
+
}
|
|
369
|
+
function toStateValue(stateValue) {
|
|
370
|
+
if (isStateLike(stateValue)) {
|
|
371
|
+
return stateValue.value;
|
|
372
|
+
}
|
|
373
|
+
if (isArray(stateValue)) {
|
|
374
|
+
return pathToStateValue(stateValue);
|
|
375
|
+
}
|
|
376
|
+
if (typeof stateValue !== 'string') {
|
|
377
|
+
return stateValue;
|
|
378
|
+
}
|
|
379
|
+
const statePath = toStatePath(stateValue);
|
|
380
|
+
return pathToStateValue(statePath);
|
|
381
|
+
}
|
|
382
|
+
function pathToStateValue(statePath) {
|
|
383
|
+
if (statePath.length === 1) {
|
|
384
|
+
return statePath[0];
|
|
385
|
+
}
|
|
386
|
+
const value = {};
|
|
387
|
+
let marker = value;
|
|
388
|
+
for (let i = 0; i < statePath.length - 1; i++) {
|
|
389
|
+
if (i === statePath.length - 2) {
|
|
390
|
+
marker[statePath[i]] = statePath[i + 1];
|
|
391
|
+
} else {
|
|
392
|
+
const previous = marker;
|
|
393
|
+
marker = {};
|
|
394
|
+
previous[statePath[i]] = marker;
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
return value;
|
|
398
|
+
}
|
|
399
|
+
function mapValues(collection, iteratee) {
|
|
400
|
+
const result = {};
|
|
401
|
+
const collectionKeys = Object.keys(collection);
|
|
402
|
+
for (let i = 0; i < collectionKeys.length; i++) {
|
|
403
|
+
const key = collectionKeys[i];
|
|
404
|
+
result[key] = iteratee(collection[key], key, collection, i);
|
|
405
|
+
}
|
|
406
|
+
return result;
|
|
407
|
+
}
|
|
408
|
+
function flatten(array) {
|
|
409
|
+
return [].concat(...array);
|
|
410
|
+
}
|
|
411
|
+
function toArrayStrict(value) {
|
|
412
|
+
if (isArray(value)) {
|
|
413
|
+
return value;
|
|
414
|
+
}
|
|
415
|
+
return [value];
|
|
416
|
+
}
|
|
417
|
+
function toArray(value) {
|
|
418
|
+
if (value === undefined) {
|
|
419
|
+
return [];
|
|
420
|
+
}
|
|
421
|
+
return toArrayStrict(value);
|
|
422
|
+
}
|
|
423
|
+
function mapContext(mapper, context, event) {
|
|
424
|
+
if (typeof mapper === 'function') {
|
|
425
|
+
return mapper({
|
|
426
|
+
context,
|
|
427
|
+
event
|
|
428
|
+
});
|
|
429
|
+
}
|
|
430
|
+
const result = {};
|
|
431
|
+
const args = {
|
|
432
|
+
context,
|
|
433
|
+
event
|
|
434
|
+
};
|
|
435
|
+
for (const key of Object.keys(mapper)) {
|
|
436
|
+
const subMapper = mapper[key];
|
|
437
|
+
if (typeof subMapper === 'function') {
|
|
438
|
+
result[key] = subMapper(args);
|
|
439
|
+
} else {
|
|
440
|
+
result[key] = subMapper;
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
return result;
|
|
444
|
+
}
|
|
445
|
+
function isPromiseLike(value) {
|
|
446
|
+
if (value instanceof Promise) {
|
|
447
|
+
return true;
|
|
448
|
+
}
|
|
449
|
+
// Check if shape matches the Promise/A+ specification for a "thenable".
|
|
450
|
+
if (value !== null && (typeof value === 'function' || typeof value === 'object') && typeof value.then === 'function') {
|
|
451
|
+
return true;
|
|
452
|
+
}
|
|
453
|
+
return false;
|
|
454
|
+
}
|
|
455
|
+
function isArray(value) {
|
|
456
|
+
return Array.isArray(value);
|
|
457
|
+
}
|
|
458
|
+
function isErrorEvent(event) {
|
|
459
|
+
return typeof event.type === 'string' && (event.type === errorExecution || event.type.startsWith(errorPlatform));
|
|
460
|
+
}
|
|
461
|
+
function toTransitionConfigArray(configLike) {
|
|
462
|
+
return toArrayStrict(configLike).map(transitionLike => {
|
|
463
|
+
if (typeof transitionLike === 'undefined' || typeof transitionLike === 'string') {
|
|
464
|
+
return {
|
|
465
|
+
target: transitionLike
|
|
466
|
+
};
|
|
467
|
+
}
|
|
468
|
+
return transitionLike;
|
|
469
|
+
});
|
|
470
|
+
}
|
|
471
|
+
function normalizeTarget(target) {
|
|
472
|
+
if (target === undefined || target === TARGETLESS_KEY) {
|
|
473
|
+
return undefined;
|
|
474
|
+
}
|
|
475
|
+
return toArray(target);
|
|
476
|
+
}
|
|
477
|
+
function toInvokeConfig(invocable, id) {
|
|
478
|
+
if (typeof invocable === 'object') {
|
|
479
|
+
if ('src' in invocable) {
|
|
480
|
+
return invocable;
|
|
481
|
+
}
|
|
482
|
+
if ('transition' in invocable) {
|
|
483
|
+
return {
|
|
484
|
+
id,
|
|
485
|
+
src: invocable
|
|
486
|
+
};
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
return {
|
|
490
|
+
id,
|
|
491
|
+
src: invocable
|
|
492
|
+
};
|
|
493
|
+
}
|
|
494
|
+
function toObserver(nextHandler, errorHandler, completionHandler) {
|
|
495
|
+
const noop = () => {};
|
|
496
|
+
const isObserver = typeof nextHandler === 'object';
|
|
497
|
+
const self = isObserver ? nextHandler : null;
|
|
498
|
+
return {
|
|
499
|
+
next: ((isObserver ? nextHandler.next : nextHandler) || noop).bind(self),
|
|
500
|
+
error: ((isObserver ? nextHandler.error : errorHandler) || noop).bind(self),
|
|
501
|
+
complete: ((isObserver ? nextHandler.complete : completionHandler) || noop).bind(self)
|
|
502
|
+
};
|
|
503
|
+
}
|
|
504
|
+
function createInvokeId(stateNodeId, index) {
|
|
505
|
+
return `${stateNodeId}:invocation[${index}]`;
|
|
506
|
+
}
|
|
507
|
+
function resolveReferencedActor(referenced) {
|
|
508
|
+
return referenced ? 'transition' in referenced ? {
|
|
509
|
+
src: referenced,
|
|
510
|
+
input: undefined
|
|
511
|
+
} : referenced : undefined;
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
function fromCallback(invokeCallback) {
|
|
347
515
|
const logic = {
|
|
348
|
-
config:
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
return {
|
|
356
|
-
...state,
|
|
357
|
-
status: 'done',
|
|
358
|
-
data: event.data,
|
|
359
|
-
input: undefined
|
|
360
|
-
};
|
|
361
|
-
case rejectEventType:
|
|
362
|
-
return {
|
|
363
|
-
...state,
|
|
364
|
-
status: 'error',
|
|
365
|
-
data: event.data,
|
|
366
|
-
input: undefined
|
|
367
|
-
};
|
|
368
|
-
case stopSignalType:
|
|
369
|
-
return {
|
|
370
|
-
...state,
|
|
371
|
-
status: 'canceled',
|
|
372
|
-
input: undefined
|
|
373
|
-
};
|
|
374
|
-
default:
|
|
375
|
-
return state;
|
|
376
|
-
}
|
|
516
|
+
config: invokeCallback,
|
|
517
|
+
start: (_state, {
|
|
518
|
+
self
|
|
519
|
+
}) => {
|
|
520
|
+
self.send({
|
|
521
|
+
type: startSignalType
|
|
522
|
+
});
|
|
377
523
|
},
|
|
378
|
-
|
|
524
|
+
transition: (state, event, {
|
|
379
525
|
self,
|
|
526
|
+
id,
|
|
380
527
|
system
|
|
381
528
|
}) => {
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
529
|
+
if (event.type === startSignalType) {
|
|
530
|
+
const sendBack = eventForParent => {
|
|
531
|
+
if (state.canceled) {
|
|
532
|
+
return;
|
|
533
|
+
}
|
|
534
|
+
self._parent?.send(eventForParent);
|
|
535
|
+
};
|
|
536
|
+
const receive = newListener => {
|
|
537
|
+
state.receivers.add(newListener);
|
|
538
|
+
};
|
|
539
|
+
state.dispose = invokeCallback({
|
|
540
|
+
input: state.input,
|
|
541
|
+
system,
|
|
542
|
+
self: self,
|
|
543
|
+
sendBack,
|
|
544
|
+
receive
|
|
545
|
+
});
|
|
546
|
+
if (isPromiseLike(state.dispose)) {
|
|
547
|
+
state.dispose.then(resolved => {
|
|
548
|
+
self._parent?.send(doneInvoke(id, resolved));
|
|
549
|
+
state.canceled = true;
|
|
550
|
+
}, errorData => {
|
|
551
|
+
state.canceled = true;
|
|
552
|
+
self._parent?.send(error(id, errorData));
|
|
553
|
+
});
|
|
554
|
+
}
|
|
555
|
+
return state;
|
|
386
556
|
}
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
}));
|
|
392
|
-
resolvedPromise.then(response => {
|
|
393
|
-
// TODO: remove this condition once dead letter queue lands
|
|
394
|
-
if (self._state.status !== 'active') {
|
|
395
|
-
return;
|
|
396
|
-
}
|
|
397
|
-
self.send({
|
|
398
|
-
type: resolveEventType,
|
|
399
|
-
data: response
|
|
400
|
-
});
|
|
401
|
-
}, errorData => {
|
|
402
|
-
// TODO: remove this condition once dead letter queue lands
|
|
403
|
-
if (self._state.status !== 'active') {
|
|
404
|
-
return;
|
|
557
|
+
if (event.type === stopSignalType) {
|
|
558
|
+
state.canceled = true;
|
|
559
|
+
if (typeof state.dispose === 'function') {
|
|
560
|
+
state.dispose();
|
|
405
561
|
}
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
562
|
+
return state;
|
|
563
|
+
}
|
|
564
|
+
if (isSignal(event)) {
|
|
565
|
+
// TODO: unrecognized signal
|
|
566
|
+
return state;
|
|
567
|
+
}
|
|
568
|
+
state.receivers.forEach(receiver => receiver(event));
|
|
569
|
+
return state;
|
|
411
570
|
},
|
|
412
571
|
getInitialState: (_, input) => {
|
|
413
572
|
return {
|
|
414
|
-
|
|
415
|
-
|
|
573
|
+
canceled: false,
|
|
574
|
+
receivers: new Set(),
|
|
575
|
+
dispose: undefined,
|
|
416
576
|
input
|
|
417
577
|
};
|
|
418
578
|
},
|
|
419
|
-
getSnapshot:
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
579
|
+
getSnapshot: () => undefined,
|
|
580
|
+
getPersistedState: ({
|
|
581
|
+
input
|
|
582
|
+
}) => input
|
|
423
583
|
};
|
|
424
584
|
return logic;
|
|
425
585
|
}
|
|
426
586
|
|
|
427
|
-
// TODO: this likely shouldn't accept TEvent, observable actor doesn't accept external events
|
|
428
587
|
function fromObservable(observableCreator) {
|
|
429
588
|
const nextEventType = '$$xstate.next';
|
|
430
589
|
const errorEventType = '$$xstate.error';
|
|
@@ -645,252 +804,88 @@ function fromEventObservable(lazyObservable) {
|
|
|
645
804
|
return logic;
|
|
646
805
|
}
|
|
647
806
|
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
}
|
|
655
|
-
|
|
656
|
-
// Parent more specific than child
|
|
657
|
-
return false;
|
|
658
|
-
}
|
|
659
|
-
if (typeof parentStateValue === 'string') {
|
|
660
|
-
return parentStateValue in childStateValue;
|
|
661
|
-
}
|
|
662
|
-
return Object.keys(parentStateValue).every(key => {
|
|
663
|
-
if (!(key in childStateValue)) {
|
|
664
|
-
return false;
|
|
665
|
-
}
|
|
666
|
-
return matchesState(parentStateValue[key], childStateValue[key]);
|
|
667
|
-
});
|
|
668
|
-
}
|
|
669
|
-
function toStatePath(stateId) {
|
|
670
|
-
try {
|
|
671
|
-
if (isArray(stateId)) {
|
|
672
|
-
return stateId;
|
|
673
|
-
}
|
|
674
|
-
return stateId.toString().split(STATE_DELIMITER);
|
|
675
|
-
} catch (e) {
|
|
676
|
-
throw new Error(`'${stateId}' is not a valid state path.`);
|
|
677
|
-
}
|
|
678
|
-
}
|
|
679
|
-
function isStateLike(state) {
|
|
680
|
-
return typeof state === 'object' && 'value' in state && 'context' in state && 'event' in state;
|
|
681
|
-
}
|
|
682
|
-
function toStateValue(stateValue) {
|
|
683
|
-
if (isStateLike(stateValue)) {
|
|
684
|
-
return stateValue.value;
|
|
685
|
-
}
|
|
686
|
-
if (isArray(stateValue)) {
|
|
687
|
-
return pathToStateValue(stateValue);
|
|
688
|
-
}
|
|
689
|
-
if (typeof stateValue !== 'string') {
|
|
690
|
-
return stateValue;
|
|
691
|
-
}
|
|
692
|
-
const statePath = toStatePath(stateValue);
|
|
693
|
-
return pathToStateValue(statePath);
|
|
694
|
-
}
|
|
695
|
-
function pathToStateValue(statePath) {
|
|
696
|
-
if (statePath.length === 1) {
|
|
697
|
-
return statePath[0];
|
|
698
|
-
}
|
|
699
|
-
const value = {};
|
|
700
|
-
let marker = value;
|
|
701
|
-
for (let i = 0; i < statePath.length - 1; i++) {
|
|
702
|
-
if (i === statePath.length - 2) {
|
|
703
|
-
marker[statePath[i]] = statePath[i + 1];
|
|
704
|
-
} else {
|
|
705
|
-
const previous = marker;
|
|
706
|
-
marker = {};
|
|
707
|
-
previous[statePath[i]] = marker;
|
|
708
|
-
}
|
|
709
|
-
}
|
|
710
|
-
return value;
|
|
711
|
-
}
|
|
712
|
-
function mapValues(collection, iteratee) {
|
|
713
|
-
const result = {};
|
|
714
|
-
const collectionKeys = Object.keys(collection);
|
|
715
|
-
for (let i = 0; i < collectionKeys.length; i++) {
|
|
716
|
-
const key = collectionKeys[i];
|
|
717
|
-
result[key] = iteratee(collection[key], key, collection, i);
|
|
718
|
-
}
|
|
719
|
-
return result;
|
|
720
|
-
}
|
|
721
|
-
function flatten(array) {
|
|
722
|
-
return [].concat(...array);
|
|
723
|
-
}
|
|
724
|
-
function toArrayStrict(value) {
|
|
725
|
-
if (isArray(value)) {
|
|
726
|
-
return value;
|
|
727
|
-
}
|
|
728
|
-
return [value];
|
|
729
|
-
}
|
|
730
|
-
function toArray(value) {
|
|
731
|
-
if (value === undefined) {
|
|
732
|
-
return [];
|
|
733
|
-
}
|
|
734
|
-
return toArrayStrict(value);
|
|
735
|
-
}
|
|
736
|
-
function mapContext(mapper, context, event) {
|
|
737
|
-
if (typeof mapper === 'function') {
|
|
738
|
-
return mapper({
|
|
739
|
-
context,
|
|
740
|
-
event
|
|
741
|
-
});
|
|
742
|
-
}
|
|
743
|
-
const result = {};
|
|
744
|
-
const args = {
|
|
745
|
-
context,
|
|
746
|
-
event
|
|
747
|
-
};
|
|
748
|
-
for (const key of Object.keys(mapper)) {
|
|
749
|
-
const subMapper = mapper[key];
|
|
750
|
-
if (typeof subMapper === 'function') {
|
|
751
|
-
result[key] = subMapper(args);
|
|
752
|
-
} else {
|
|
753
|
-
result[key] = subMapper;
|
|
754
|
-
}
|
|
755
|
-
}
|
|
756
|
-
return result;
|
|
757
|
-
}
|
|
758
|
-
function isPromiseLike(value) {
|
|
759
|
-
if (value instanceof Promise) {
|
|
760
|
-
return true;
|
|
761
|
-
}
|
|
762
|
-
// Check if shape matches the Promise/A+ specification for a "thenable".
|
|
763
|
-
if (value !== null && (typeof value === 'function' || typeof value === 'object') && typeof value.then === 'function') {
|
|
764
|
-
return true;
|
|
765
|
-
}
|
|
766
|
-
return false;
|
|
767
|
-
}
|
|
768
|
-
function isArray(value) {
|
|
769
|
-
return Array.isArray(value);
|
|
770
|
-
}
|
|
771
|
-
function isErrorEvent(event) {
|
|
772
|
-
return typeof event.type === 'string' && (event.type === errorExecution || event.type.startsWith(errorPlatform));
|
|
773
|
-
}
|
|
774
|
-
function toTransitionConfigArray(configLike) {
|
|
775
|
-
return toArrayStrict(configLike).map(transitionLike => {
|
|
776
|
-
if (typeof transitionLike === 'undefined' || typeof transitionLike === 'string') {
|
|
777
|
-
return {
|
|
778
|
-
target: transitionLike
|
|
779
|
-
};
|
|
780
|
-
}
|
|
781
|
-
return transitionLike;
|
|
782
|
-
});
|
|
783
|
-
}
|
|
784
|
-
function normalizeTarget(target) {
|
|
785
|
-
if (target === undefined || target === TARGETLESS_KEY) {
|
|
786
|
-
return undefined;
|
|
787
|
-
}
|
|
788
|
-
return toArray(target);
|
|
789
|
-
}
|
|
790
|
-
function toInvokeConfig(invocable, id) {
|
|
791
|
-
if (typeof invocable === 'object') {
|
|
792
|
-
if ('src' in invocable) {
|
|
793
|
-
return invocable;
|
|
794
|
-
}
|
|
795
|
-
if ('transition' in invocable) {
|
|
796
|
-
return {
|
|
797
|
-
id,
|
|
798
|
-
src: invocable
|
|
799
|
-
};
|
|
800
|
-
}
|
|
801
|
-
}
|
|
802
|
-
return {
|
|
803
|
-
id,
|
|
804
|
-
src: invocable
|
|
805
|
-
};
|
|
806
|
-
}
|
|
807
|
-
function toObserver(nextHandler, errorHandler, completionHandler) {
|
|
808
|
-
const noop = () => {};
|
|
809
|
-
const isObserver = typeof nextHandler === 'object';
|
|
810
|
-
const self = isObserver ? nextHandler : null;
|
|
811
|
-
return {
|
|
812
|
-
next: ((isObserver ? nextHandler.next : nextHandler) || noop).bind(self),
|
|
813
|
-
error: ((isObserver ? nextHandler.error : errorHandler) || noop).bind(self),
|
|
814
|
-
complete: ((isObserver ? nextHandler.complete : completionHandler) || noop).bind(self)
|
|
815
|
-
};
|
|
816
|
-
}
|
|
817
|
-
function createInvokeId(stateNodeId, index) {
|
|
818
|
-
return `${stateNodeId}:invocation[${index}]`;
|
|
819
|
-
}
|
|
820
|
-
function resolveReferencedActor(referenced) {
|
|
821
|
-
return referenced ? 'transition' in referenced ? {
|
|
822
|
-
src: referenced,
|
|
823
|
-
input: undefined
|
|
824
|
-
} : referenced : undefined;
|
|
825
|
-
}
|
|
826
|
-
|
|
827
|
-
function fromCallback(invokeCallback) {
|
|
807
|
+
const resolveEventType = '$$xstate.resolve';
|
|
808
|
+
const rejectEventType = '$$xstate.reject';
|
|
809
|
+
function fromPromise(
|
|
810
|
+
// TODO: add types
|
|
811
|
+
promiseCreator) {
|
|
812
|
+
// TODO: add event types
|
|
828
813
|
const logic = {
|
|
829
|
-
config:
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
814
|
+
config: promiseCreator,
|
|
815
|
+
transition: (state, event) => {
|
|
816
|
+
if (state.status !== 'active') {
|
|
817
|
+
return state;
|
|
818
|
+
}
|
|
819
|
+
switch (event.type) {
|
|
820
|
+
case resolveEventType:
|
|
821
|
+
return {
|
|
822
|
+
...state,
|
|
823
|
+
status: 'done',
|
|
824
|
+
data: event.data,
|
|
825
|
+
input: undefined
|
|
826
|
+
};
|
|
827
|
+
case rejectEventType:
|
|
828
|
+
return {
|
|
829
|
+
...state,
|
|
830
|
+
status: 'error',
|
|
831
|
+
data: event.data,
|
|
832
|
+
input: undefined
|
|
833
|
+
};
|
|
834
|
+
case stopSignalType:
|
|
835
|
+
return {
|
|
836
|
+
...state,
|
|
837
|
+
status: 'canceled',
|
|
838
|
+
input: undefined
|
|
839
|
+
};
|
|
840
|
+
default:
|
|
841
|
+
return state;
|
|
842
|
+
}
|
|
836
843
|
},
|
|
837
|
-
|
|
844
|
+
start: (state, {
|
|
838
845
|
self,
|
|
839
|
-
id,
|
|
840
846
|
system
|
|
841
847
|
}) => {
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
}
|
|
847
|
-
self._parent?.send(eventForParent);
|
|
848
|
-
};
|
|
849
|
-
const receiver = newListener => {
|
|
850
|
-
state.receivers.add(newListener);
|
|
851
|
-
};
|
|
852
|
-
state.dispose = invokeCallback(sender, receiver, {
|
|
853
|
-
input: state.input,
|
|
854
|
-
system,
|
|
855
|
-
self: self
|
|
856
|
-
});
|
|
857
|
-
if (isPromiseLike(state.dispose)) {
|
|
858
|
-
state.dispose.then(resolved => {
|
|
859
|
-
self._parent?.send(doneInvoke(id, resolved));
|
|
860
|
-
state.canceled = true;
|
|
861
|
-
}, errorData => {
|
|
862
|
-
state.canceled = true;
|
|
863
|
-
self._parent?.send(error(id, errorData));
|
|
864
|
-
});
|
|
865
|
-
}
|
|
866
|
-
return state;
|
|
848
|
+
// TODO: determine how to allow customizing this so that promises
|
|
849
|
+
// can be restarted if necessary
|
|
850
|
+
if (state.status !== 'active') {
|
|
851
|
+
return;
|
|
867
852
|
}
|
|
868
|
-
|
|
869
|
-
state.
|
|
870
|
-
|
|
871
|
-
|
|
853
|
+
const resolvedPromise = Promise.resolve(promiseCreator({
|
|
854
|
+
input: state.input,
|
|
855
|
+
system,
|
|
856
|
+
self
|
|
857
|
+
}));
|
|
858
|
+
resolvedPromise.then(response => {
|
|
859
|
+
// TODO: remove this condition once dead letter queue lands
|
|
860
|
+
if (self._state.status !== 'active') {
|
|
861
|
+
return;
|
|
872
862
|
}
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
863
|
+
self.send({
|
|
864
|
+
type: resolveEventType,
|
|
865
|
+
data: response
|
|
866
|
+
});
|
|
867
|
+
}, errorData => {
|
|
868
|
+
// TODO: remove this condition once dead letter queue lands
|
|
869
|
+
if (self._state.status !== 'active') {
|
|
870
|
+
return;
|
|
871
|
+
}
|
|
872
|
+
self.send({
|
|
873
|
+
type: rejectEventType,
|
|
874
|
+
data: errorData
|
|
875
|
+
});
|
|
876
|
+
});
|
|
881
877
|
},
|
|
882
878
|
getInitialState: (_, input) => {
|
|
883
879
|
return {
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
dispose: undefined,
|
|
880
|
+
status: 'active',
|
|
881
|
+
data: undefined,
|
|
887
882
|
input
|
|
888
883
|
};
|
|
889
884
|
},
|
|
890
|
-
getSnapshot:
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
885
|
+
getSnapshot: state => state.data,
|
|
886
|
+
getStatus: state => state,
|
|
887
|
+
getPersistedState: state => state,
|
|
888
|
+
restoreState: state => state
|
|
894
889
|
};
|
|
895
890
|
return logic;
|
|
896
891
|
}
|
|
@@ -929,6 +924,7 @@ function toActorRef(actorRefLike) {
|
|
|
929
924
|
id: 'anonymous',
|
|
930
925
|
sessionId: '',
|
|
931
926
|
getSnapshot: () => undefined,
|
|
927
|
+
// TODO: this isn't safe
|
|
932
928
|
[symbolObservable]: function () {
|
|
933
929
|
return this;
|
|
934
930
|
},
|
|
@@ -2822,7 +2818,7 @@ function createSpawner(actorContext, {
|
|
|
2822
2818
|
}
|
|
2823
2819
|
};
|
|
2824
2820
|
return (src, options) => {
|
|
2825
|
-
const actorRef = spawn(src, options);
|
|
2821
|
+
const actorRef = spawn(src, options); // TODO: fix types
|
|
2826
2822
|
spawnedChildren[actorRef.id] = actorRef;
|
|
2827
2823
|
actorContext.defer(() => {
|
|
2828
2824
|
if (actorRef.status === ActorStatus.Stopped) {
|