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
|
@@ -2,10 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
var dev_dist_xstateDev = require('../dev/dist/xstate-dev.development.cjs.js');
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
/**
|
|
6
|
+
* `T | unknown` reduces to `unknown` and that can be problematic when it comes to contextual typing.
|
|
7
|
+
* It especially is a problem when the union has a function member, like here:
|
|
8
|
+
*
|
|
9
|
+
* ```ts
|
|
10
|
+
* declare function test(cbOrVal: ((arg: number) => unknown) | unknown): void;
|
|
11
|
+
* test((arg) => {}) // oops, implicit any
|
|
12
|
+
* ```
|
|
13
|
+
*
|
|
14
|
+
* This type can be used to avoid this problem. This union represents the same value space as `unknown`.
|
|
15
|
+
*/
|
|
6
16
|
|
|
7
|
-
//
|
|
8
|
-
// export type IndexByType<T extends { type: string }> = { [E in T as E['type']]: E; };
|
|
17
|
+
// https://github.com/microsoft/TypeScript/issues/23182#issuecomment-379091887
|
|
9
18
|
|
|
10
19
|
/**
|
|
11
20
|
* The full definition of an event, with a string `type`.
|
|
@@ -15,8 +24,6 @@ var dev_dist_xstateDev = require('../dev/dist/xstate-dev.development.cjs.js');
|
|
|
15
24
|
// we should also accept a raw machine as actor logic here
|
|
16
25
|
// or just make machine actor logic
|
|
17
26
|
|
|
18
|
-
// TODO: narrow this to logic from machine
|
|
19
|
-
|
|
20
27
|
/**
|
|
21
28
|
* The string or object representing the state value relative to the parent state node.
|
|
22
29
|
*
|
|
@@ -323,7 +330,7 @@ const symbolObservable = (() => typeof Symbol === 'function' && Symbol.observabl
|
|
|
323
330
|
* @returns Actor logic
|
|
324
331
|
*/
|
|
325
332
|
function fromTransition(transition, initialState) {
|
|
326
|
-
|
|
333
|
+
return {
|
|
327
334
|
config: transition,
|
|
328
335
|
transition: (state, event, actorContext) => {
|
|
329
336
|
return transition(state, event, actorContext);
|
|
@@ -337,103 +344,258 @@ function fromTransition(transition, initialState) {
|
|
|
337
344
|
getPersistedState: state => state,
|
|
338
345
|
restoreState: state => state
|
|
339
346
|
};
|
|
340
|
-
return logic;
|
|
341
347
|
}
|
|
342
348
|
|
|
343
|
-
|
|
344
|
-
const
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
349
|
+
function matchesState(parentStateId, childStateId) {
|
|
350
|
+
const parentStateValue = toStateValue(parentStateId);
|
|
351
|
+
const childStateValue = toStateValue(childStateId);
|
|
352
|
+
if (typeof childStateValue === 'string') {
|
|
353
|
+
if (typeof parentStateValue === 'string') {
|
|
354
|
+
return childStateValue === parentStateValue;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
// Parent more specific than child
|
|
358
|
+
return false;
|
|
359
|
+
}
|
|
360
|
+
if (typeof parentStateValue === 'string') {
|
|
361
|
+
return parentStateValue in childStateValue;
|
|
362
|
+
}
|
|
363
|
+
return Object.keys(parentStateValue).every(key => {
|
|
364
|
+
if (!(key in childStateValue)) {
|
|
365
|
+
return false;
|
|
366
|
+
}
|
|
367
|
+
return matchesState(parentStateValue[key], childStateValue[key]);
|
|
368
|
+
});
|
|
369
|
+
}
|
|
370
|
+
function toStatePath(stateId) {
|
|
371
|
+
try {
|
|
372
|
+
if (isArray(stateId)) {
|
|
373
|
+
return stateId;
|
|
374
|
+
}
|
|
375
|
+
return stateId.toString().split(STATE_DELIMITER);
|
|
376
|
+
} catch (e) {
|
|
377
|
+
throw new Error(`'${stateId}' is not a valid state path.`);
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
function isStateLike(state) {
|
|
381
|
+
return typeof state === 'object' && 'value' in state && 'context' in state && 'event' in state;
|
|
382
|
+
}
|
|
383
|
+
function toStateValue(stateValue) {
|
|
384
|
+
if (isStateLike(stateValue)) {
|
|
385
|
+
return stateValue.value;
|
|
386
|
+
}
|
|
387
|
+
if (isArray(stateValue)) {
|
|
388
|
+
return pathToStateValue(stateValue);
|
|
389
|
+
}
|
|
390
|
+
if (typeof stateValue !== 'string') {
|
|
391
|
+
return stateValue;
|
|
392
|
+
}
|
|
393
|
+
const statePath = toStatePath(stateValue);
|
|
394
|
+
return pathToStateValue(statePath);
|
|
395
|
+
}
|
|
396
|
+
function pathToStateValue(statePath) {
|
|
397
|
+
if (statePath.length === 1) {
|
|
398
|
+
return statePath[0];
|
|
399
|
+
}
|
|
400
|
+
const value = {};
|
|
401
|
+
let marker = value;
|
|
402
|
+
for (let i = 0; i < statePath.length - 1; i++) {
|
|
403
|
+
if (i === statePath.length - 2) {
|
|
404
|
+
marker[statePath[i]] = statePath[i + 1];
|
|
405
|
+
} else {
|
|
406
|
+
const previous = marker;
|
|
407
|
+
marker = {};
|
|
408
|
+
previous[statePath[i]] = marker;
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
return value;
|
|
412
|
+
}
|
|
413
|
+
function mapValues(collection, iteratee) {
|
|
414
|
+
const result = {};
|
|
415
|
+
const collectionKeys = Object.keys(collection);
|
|
416
|
+
for (let i = 0; i < collectionKeys.length; i++) {
|
|
417
|
+
const key = collectionKeys[i];
|
|
418
|
+
result[key] = iteratee(collection[key], key, collection, i);
|
|
419
|
+
}
|
|
420
|
+
return result;
|
|
421
|
+
}
|
|
422
|
+
function flatten(array) {
|
|
423
|
+
return [].concat(...array);
|
|
424
|
+
}
|
|
425
|
+
function toArrayStrict(value) {
|
|
426
|
+
if (isArray(value)) {
|
|
427
|
+
return value;
|
|
428
|
+
}
|
|
429
|
+
return [value];
|
|
430
|
+
}
|
|
431
|
+
function toArray(value) {
|
|
432
|
+
if (value === undefined) {
|
|
433
|
+
return [];
|
|
434
|
+
}
|
|
435
|
+
return toArrayStrict(value);
|
|
436
|
+
}
|
|
437
|
+
function mapContext(mapper, context, event, self) {
|
|
438
|
+
if (typeof mapper === 'function') {
|
|
439
|
+
return mapper({
|
|
440
|
+
context,
|
|
441
|
+
event,
|
|
442
|
+
self
|
|
443
|
+
});
|
|
444
|
+
}
|
|
445
|
+
if (typeof mapper === 'object' && Object.values(mapper).some(val => typeof val === 'function')) {
|
|
446
|
+
console.warn(`Dynamically mapping values to individual properties is deprecated. Use a single function that returns the mapped object instead.\nFound object containing properties whose values are possibly mapping functions: ${Object.entries(mapper).filter(([key, value]) => typeof value === 'function').map(([key, value]) => `\n - ${key}: ${value.toString().replace(/\n\s*/g, '')}`).join('')}`);
|
|
447
|
+
}
|
|
448
|
+
return mapper;
|
|
449
|
+
}
|
|
450
|
+
function isPromiseLike(value) {
|
|
451
|
+
if (value instanceof Promise) {
|
|
452
|
+
return true;
|
|
453
|
+
}
|
|
454
|
+
// Check if shape matches the Promise/A+ specification for a "thenable".
|
|
455
|
+
if (value !== null && (typeof value === 'function' || typeof value === 'object') && typeof value.then === 'function') {
|
|
456
|
+
return true;
|
|
457
|
+
}
|
|
458
|
+
return false;
|
|
459
|
+
}
|
|
460
|
+
function isArray(value) {
|
|
461
|
+
return Array.isArray(value);
|
|
462
|
+
}
|
|
463
|
+
function isErrorEvent(event) {
|
|
464
|
+
return typeof event.type === 'string' && (event.type === errorExecution || event.type.startsWith(errorPlatform));
|
|
465
|
+
}
|
|
466
|
+
function toTransitionConfigArray(configLike) {
|
|
467
|
+
return toArrayStrict(configLike).map(transitionLike => {
|
|
468
|
+
if (typeof transitionLike === 'undefined' || typeof transitionLike === 'string') {
|
|
469
|
+
return {
|
|
470
|
+
target: transitionLike
|
|
471
|
+
};
|
|
472
|
+
}
|
|
473
|
+
return transitionLike;
|
|
474
|
+
});
|
|
475
|
+
}
|
|
476
|
+
function normalizeTarget(target) {
|
|
477
|
+
if (target === undefined || target === TARGETLESS_KEY) {
|
|
478
|
+
return undefined;
|
|
479
|
+
}
|
|
480
|
+
return toArray(target);
|
|
481
|
+
}
|
|
482
|
+
function toInvokeConfig(invocable, id) {
|
|
483
|
+
if (typeof invocable === 'object') {
|
|
484
|
+
if ('src' in invocable) {
|
|
485
|
+
return invocable;
|
|
486
|
+
}
|
|
487
|
+
if ('transition' in invocable) {
|
|
488
|
+
return {
|
|
489
|
+
id,
|
|
490
|
+
src: invocable
|
|
491
|
+
};
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
return {
|
|
495
|
+
id,
|
|
496
|
+
src: invocable
|
|
497
|
+
};
|
|
498
|
+
}
|
|
499
|
+
function toObserver(nextHandler, errorHandler, completionHandler) {
|
|
500
|
+
const isObserver = typeof nextHandler === 'object';
|
|
501
|
+
const self = isObserver ? nextHandler : undefined;
|
|
502
|
+
return {
|
|
503
|
+
next: (isObserver ? nextHandler.next : nextHandler)?.bind(self),
|
|
504
|
+
error: (isObserver ? nextHandler.error : errorHandler)?.bind(self),
|
|
505
|
+
complete: (isObserver ? nextHandler.complete : completionHandler)?.bind(self)
|
|
506
|
+
};
|
|
507
|
+
}
|
|
508
|
+
function createInvokeId(stateNodeId, index) {
|
|
509
|
+
return `${stateNodeId}:invocation[${index}]`;
|
|
510
|
+
}
|
|
511
|
+
function resolveReferencedActor(referenced) {
|
|
512
|
+
return referenced ? 'transition' in referenced ? {
|
|
513
|
+
src: referenced,
|
|
514
|
+
input: undefined
|
|
515
|
+
} : referenced : undefined;
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
function fromCallback(invokeCallback) {
|
|
519
|
+
return {
|
|
520
|
+
config: invokeCallback,
|
|
521
|
+
start: (_state, {
|
|
522
|
+
self
|
|
523
|
+
}) => {
|
|
524
|
+
self.send({
|
|
525
|
+
type: startSignalType
|
|
526
|
+
});
|
|
379
527
|
},
|
|
380
|
-
|
|
528
|
+
transition: (state, event, {
|
|
381
529
|
self,
|
|
530
|
+
id,
|
|
382
531
|
system
|
|
383
532
|
}) => {
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
533
|
+
if (event.type === startSignalType) {
|
|
534
|
+
const sendBack = eventForParent => {
|
|
535
|
+
if (state.canceled) {
|
|
536
|
+
return;
|
|
537
|
+
}
|
|
538
|
+
self._parent?.send(eventForParent);
|
|
539
|
+
};
|
|
540
|
+
const receive = newListener => {
|
|
541
|
+
state.receivers.add(newListener);
|
|
542
|
+
};
|
|
543
|
+
state.dispose = invokeCallback({
|
|
544
|
+
input: state.input,
|
|
545
|
+
system,
|
|
546
|
+
self: self,
|
|
547
|
+
sendBack,
|
|
548
|
+
receive
|
|
549
|
+
});
|
|
550
|
+
if (isPromiseLike(state.dispose)) {
|
|
551
|
+
state.dispose.then(resolved => {
|
|
552
|
+
self._parent?.send(doneInvoke(id, resolved));
|
|
553
|
+
state.canceled = true;
|
|
554
|
+
}, errorData => {
|
|
555
|
+
state.canceled = true;
|
|
556
|
+
self._parent?.send(error(id, errorData));
|
|
557
|
+
});
|
|
558
|
+
}
|
|
559
|
+
return state;
|
|
388
560
|
}
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
}));
|
|
394
|
-
resolvedPromise.then(response => {
|
|
395
|
-
// TODO: remove this condition once dead letter queue lands
|
|
396
|
-
if (self._state.status !== 'active') {
|
|
397
|
-
return;
|
|
561
|
+
if (event.type === stopSignalType) {
|
|
562
|
+
state.canceled = true;
|
|
563
|
+
if (typeof state.dispose === 'function') {
|
|
564
|
+
state.dispose();
|
|
398
565
|
}
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
}
|
|
408
|
-
self.send({
|
|
409
|
-
type: rejectEventType,
|
|
410
|
-
data: errorData
|
|
411
|
-
});
|
|
412
|
-
});
|
|
566
|
+
return state;
|
|
567
|
+
}
|
|
568
|
+
if (isSignal(event)) {
|
|
569
|
+
// TODO: unrecognized signal
|
|
570
|
+
return state;
|
|
571
|
+
}
|
|
572
|
+
state.receivers.forEach(receiver => receiver(event));
|
|
573
|
+
return state;
|
|
413
574
|
},
|
|
414
575
|
getInitialState: (_, input) => {
|
|
415
576
|
return {
|
|
416
|
-
|
|
417
|
-
|
|
577
|
+
canceled: false,
|
|
578
|
+
receivers: new Set(),
|
|
579
|
+
dispose: undefined,
|
|
418
580
|
input
|
|
419
581
|
};
|
|
420
582
|
},
|
|
421
|
-
getSnapshot:
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
583
|
+
getSnapshot: () => undefined,
|
|
584
|
+
getPersistedState: ({
|
|
585
|
+
input,
|
|
586
|
+
canceled
|
|
587
|
+
}) => ({
|
|
588
|
+
input,
|
|
589
|
+
canceled
|
|
590
|
+
})
|
|
425
591
|
};
|
|
426
|
-
return logic;
|
|
427
592
|
}
|
|
428
593
|
|
|
429
|
-
// TODO: this likely shouldn't accept TEvent, observable actor doesn't accept external events
|
|
430
594
|
function fromObservable(observableCreator) {
|
|
431
595
|
const nextEventType = '$$xstate.next';
|
|
432
596
|
const errorEventType = '$$xstate.error';
|
|
433
597
|
const completeEventType = '$$xstate.complete';
|
|
434
|
-
|
|
435
|
-
// TODO: add event types
|
|
436
|
-
const logic = {
|
|
598
|
+
return {
|
|
437
599
|
config: observableCreator,
|
|
438
600
|
transition: (state, event, {
|
|
439
601
|
self,
|
|
@@ -463,6 +625,7 @@ function fromObservable(observableCreator) {
|
|
|
463
625
|
status: 'error',
|
|
464
626
|
input: undefined,
|
|
465
627
|
data: event.data,
|
|
628
|
+
// TODO: if we keep this as `data` we should reflect this in the type
|
|
466
629
|
subscription: undefined
|
|
467
630
|
};
|
|
468
631
|
case completeEventType:
|
|
@@ -540,7 +703,6 @@ function fromObservable(observableCreator) {
|
|
|
540
703
|
subscription: undefined
|
|
541
704
|
})
|
|
542
705
|
};
|
|
543
|
-
return logic;
|
|
544
706
|
}
|
|
545
707
|
|
|
546
708
|
/**
|
|
@@ -557,7 +719,7 @@ function fromEventObservable(lazyObservable) {
|
|
|
557
719
|
const completeEventType = '$$xstate.complete';
|
|
558
720
|
|
|
559
721
|
// TODO: event types
|
|
560
|
-
|
|
722
|
+
return {
|
|
561
723
|
config: lazyObservable,
|
|
562
724
|
transition: (state, event) => {
|
|
563
725
|
if (state.status !== 'active') {
|
|
@@ -570,6 +732,7 @@ function fromEventObservable(lazyObservable) {
|
|
|
570
732
|
status: 'error',
|
|
571
733
|
input: undefined,
|
|
572
734
|
data: event.data,
|
|
735
|
+
// TODO: if we keep this as `data` we should reflect this in the type
|
|
573
736
|
subscription: undefined
|
|
574
737
|
};
|
|
575
738
|
case completeEventType:
|
|
@@ -644,255 +807,91 @@ function fromEventObservable(lazyObservable) {
|
|
|
644
807
|
subscription: undefined
|
|
645
808
|
})
|
|
646
809
|
};
|
|
647
|
-
return logic;
|
|
648
|
-
}
|
|
649
|
-
|
|
650
|
-
function matchesState(parentStateId, childStateId) {
|
|
651
|
-
const parentStateValue = toStateValue(parentStateId);
|
|
652
|
-
const childStateValue = toStateValue(childStateId);
|
|
653
|
-
if (typeof childStateValue === 'string') {
|
|
654
|
-
if (typeof parentStateValue === 'string') {
|
|
655
|
-
return childStateValue === parentStateValue;
|
|
656
|
-
}
|
|
657
|
-
|
|
658
|
-
// Parent more specific than child
|
|
659
|
-
return false;
|
|
660
|
-
}
|
|
661
|
-
if (typeof parentStateValue === 'string') {
|
|
662
|
-
return parentStateValue in childStateValue;
|
|
663
|
-
}
|
|
664
|
-
return Object.keys(parentStateValue).every(key => {
|
|
665
|
-
if (!(key in childStateValue)) {
|
|
666
|
-
return false;
|
|
667
|
-
}
|
|
668
|
-
return matchesState(parentStateValue[key], childStateValue[key]);
|
|
669
|
-
});
|
|
670
|
-
}
|
|
671
|
-
function toStatePath(stateId) {
|
|
672
|
-
try {
|
|
673
|
-
if (isArray(stateId)) {
|
|
674
|
-
return stateId;
|
|
675
|
-
}
|
|
676
|
-
return stateId.toString().split(STATE_DELIMITER);
|
|
677
|
-
} catch (e) {
|
|
678
|
-
throw new Error(`'${stateId}' is not a valid state path.`);
|
|
679
|
-
}
|
|
680
|
-
}
|
|
681
|
-
function isStateLike(state) {
|
|
682
|
-
return typeof state === 'object' && 'value' in state && 'context' in state && 'event' in state;
|
|
683
|
-
}
|
|
684
|
-
function toStateValue(stateValue) {
|
|
685
|
-
if (isStateLike(stateValue)) {
|
|
686
|
-
return stateValue.value;
|
|
687
|
-
}
|
|
688
|
-
if (isArray(stateValue)) {
|
|
689
|
-
return pathToStateValue(stateValue);
|
|
690
|
-
}
|
|
691
|
-
if (typeof stateValue !== 'string') {
|
|
692
|
-
return stateValue;
|
|
693
|
-
}
|
|
694
|
-
const statePath = toStatePath(stateValue);
|
|
695
|
-
return pathToStateValue(statePath);
|
|
696
|
-
}
|
|
697
|
-
function pathToStateValue(statePath) {
|
|
698
|
-
if (statePath.length === 1) {
|
|
699
|
-
return statePath[0];
|
|
700
|
-
}
|
|
701
|
-
const value = {};
|
|
702
|
-
let marker = value;
|
|
703
|
-
for (let i = 0; i < statePath.length - 1; i++) {
|
|
704
|
-
if (i === statePath.length - 2) {
|
|
705
|
-
marker[statePath[i]] = statePath[i + 1];
|
|
706
|
-
} else {
|
|
707
|
-
const previous = marker;
|
|
708
|
-
marker = {};
|
|
709
|
-
previous[statePath[i]] = marker;
|
|
710
|
-
}
|
|
711
|
-
}
|
|
712
|
-
return value;
|
|
713
|
-
}
|
|
714
|
-
function mapValues(collection, iteratee) {
|
|
715
|
-
const result = {};
|
|
716
|
-
const collectionKeys = Object.keys(collection);
|
|
717
|
-
for (let i = 0; i < collectionKeys.length; i++) {
|
|
718
|
-
const key = collectionKeys[i];
|
|
719
|
-
result[key] = iteratee(collection[key], key, collection, i);
|
|
720
|
-
}
|
|
721
|
-
return result;
|
|
722
|
-
}
|
|
723
|
-
function flatten(array) {
|
|
724
|
-
return [].concat(...array);
|
|
725
|
-
}
|
|
726
|
-
function toArrayStrict(value) {
|
|
727
|
-
if (isArray(value)) {
|
|
728
|
-
return value;
|
|
729
|
-
}
|
|
730
|
-
return [value];
|
|
731
|
-
}
|
|
732
|
-
function toArray(value) {
|
|
733
|
-
if (value === undefined) {
|
|
734
|
-
return [];
|
|
735
|
-
}
|
|
736
|
-
return toArrayStrict(value);
|
|
737
|
-
}
|
|
738
|
-
function mapContext(mapper, context, event) {
|
|
739
|
-
if (typeof mapper === 'function') {
|
|
740
|
-
return mapper({
|
|
741
|
-
context,
|
|
742
|
-
event
|
|
743
|
-
});
|
|
744
|
-
}
|
|
745
|
-
const result = {};
|
|
746
|
-
const args = {
|
|
747
|
-
context,
|
|
748
|
-
event
|
|
749
|
-
};
|
|
750
|
-
for (const key of Object.keys(mapper)) {
|
|
751
|
-
const subMapper = mapper[key];
|
|
752
|
-
if (typeof subMapper === 'function') {
|
|
753
|
-
result[key] = subMapper(args);
|
|
754
|
-
} else {
|
|
755
|
-
result[key] = subMapper;
|
|
756
|
-
}
|
|
757
|
-
}
|
|
758
|
-
return result;
|
|
759
|
-
}
|
|
760
|
-
function isPromiseLike(value) {
|
|
761
|
-
if (value instanceof Promise) {
|
|
762
|
-
return true;
|
|
763
|
-
}
|
|
764
|
-
// Check if shape matches the Promise/A+ specification for a "thenable".
|
|
765
|
-
if (value !== null && (typeof value === 'function' || typeof value === 'object') && typeof value.then === 'function') {
|
|
766
|
-
return true;
|
|
767
|
-
}
|
|
768
|
-
return false;
|
|
769
|
-
}
|
|
770
|
-
function isArray(value) {
|
|
771
|
-
return Array.isArray(value);
|
|
772
|
-
}
|
|
773
|
-
function isErrorEvent(event) {
|
|
774
|
-
return typeof event.type === 'string' && (event.type === errorExecution || event.type.startsWith(errorPlatform));
|
|
775
|
-
}
|
|
776
|
-
function toTransitionConfigArray(configLike) {
|
|
777
|
-
return toArrayStrict(configLike).map(transitionLike => {
|
|
778
|
-
if (typeof transitionLike === 'undefined' || typeof transitionLike === 'string') {
|
|
779
|
-
return {
|
|
780
|
-
target: transitionLike
|
|
781
|
-
};
|
|
782
|
-
}
|
|
783
|
-
return transitionLike;
|
|
784
|
-
});
|
|
785
|
-
}
|
|
786
|
-
function normalizeTarget(target) {
|
|
787
|
-
if (target === undefined || target === TARGETLESS_KEY) {
|
|
788
|
-
return undefined;
|
|
789
|
-
}
|
|
790
|
-
return toArray(target);
|
|
791
|
-
}
|
|
792
|
-
function toInvokeConfig(invocable, id) {
|
|
793
|
-
if (typeof invocable === 'object') {
|
|
794
|
-
if ('src' in invocable) {
|
|
795
|
-
return invocable;
|
|
796
|
-
}
|
|
797
|
-
if ('transition' in invocable) {
|
|
798
|
-
return {
|
|
799
|
-
id,
|
|
800
|
-
src: invocable
|
|
801
|
-
};
|
|
802
|
-
}
|
|
803
|
-
}
|
|
804
|
-
return {
|
|
805
|
-
id,
|
|
806
|
-
src: invocable
|
|
807
|
-
};
|
|
808
|
-
}
|
|
809
|
-
function toObserver(nextHandler, errorHandler, completionHandler) {
|
|
810
|
-
const noop = () => {};
|
|
811
|
-
const isObserver = typeof nextHandler === 'object';
|
|
812
|
-
const self = isObserver ? nextHandler : null;
|
|
813
|
-
return {
|
|
814
|
-
next: ((isObserver ? nextHandler.next : nextHandler) || noop).bind(self),
|
|
815
|
-
error: ((isObserver ? nextHandler.error : errorHandler) || noop).bind(self),
|
|
816
|
-
complete: ((isObserver ? nextHandler.complete : completionHandler) || noop).bind(self)
|
|
817
|
-
};
|
|
818
|
-
}
|
|
819
|
-
function createInvokeId(stateNodeId, index) {
|
|
820
|
-
return `${stateNodeId}:invocation[${index}]`;
|
|
821
|
-
}
|
|
822
|
-
function resolveReferencedActor(referenced) {
|
|
823
|
-
return referenced ? 'transition' in referenced ? {
|
|
824
|
-
src: referenced,
|
|
825
|
-
input: undefined
|
|
826
|
-
} : referenced : undefined;
|
|
827
810
|
}
|
|
828
811
|
|
|
829
|
-
|
|
812
|
+
const resolveEventType = '$$xstate.resolve';
|
|
813
|
+
const rejectEventType = '$$xstate.reject';
|
|
814
|
+
function fromPromise(
|
|
815
|
+
// TODO: add types
|
|
816
|
+
promiseCreator) {
|
|
817
|
+
// TODO: add event types
|
|
830
818
|
const logic = {
|
|
831
|
-
config:
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
819
|
+
config: promiseCreator,
|
|
820
|
+
transition: (state, event) => {
|
|
821
|
+
if (state.status !== 'active') {
|
|
822
|
+
return state;
|
|
823
|
+
}
|
|
824
|
+
switch (event.type) {
|
|
825
|
+
case resolveEventType:
|
|
826
|
+
return {
|
|
827
|
+
...state,
|
|
828
|
+
status: 'done',
|
|
829
|
+
data: event.data,
|
|
830
|
+
input: undefined
|
|
831
|
+
};
|
|
832
|
+
case rejectEventType:
|
|
833
|
+
return {
|
|
834
|
+
...state,
|
|
835
|
+
status: 'error',
|
|
836
|
+
data: event.data,
|
|
837
|
+
// TODO: if we keep this as `data` we should reflect this in the type
|
|
838
|
+
input: undefined
|
|
839
|
+
};
|
|
840
|
+
case stopSignalType:
|
|
841
|
+
return {
|
|
842
|
+
...state,
|
|
843
|
+
status: 'canceled',
|
|
844
|
+
input: undefined
|
|
845
|
+
};
|
|
846
|
+
default:
|
|
847
|
+
return state;
|
|
848
|
+
}
|
|
838
849
|
},
|
|
839
|
-
|
|
850
|
+
start: (state, {
|
|
840
851
|
self,
|
|
841
|
-
id,
|
|
842
852
|
system
|
|
843
853
|
}) => {
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
}
|
|
849
|
-
self._parent?.send(eventForParent);
|
|
850
|
-
};
|
|
851
|
-
const receiver = newListener => {
|
|
852
|
-
state.receivers.add(newListener);
|
|
853
|
-
};
|
|
854
|
-
state.dispose = invokeCallback(sender, receiver, {
|
|
855
|
-
input: state.input,
|
|
856
|
-
system,
|
|
857
|
-
self: self
|
|
858
|
-
});
|
|
859
|
-
if (isPromiseLike(state.dispose)) {
|
|
860
|
-
state.dispose.then(resolved => {
|
|
861
|
-
self._parent?.send(doneInvoke(id, resolved));
|
|
862
|
-
state.canceled = true;
|
|
863
|
-
}, errorData => {
|
|
864
|
-
state.canceled = true;
|
|
865
|
-
self._parent?.send(error(id, errorData));
|
|
866
|
-
});
|
|
867
|
-
}
|
|
868
|
-
return state;
|
|
854
|
+
// TODO: determine how to allow customizing this so that promises
|
|
855
|
+
// can be restarted if necessary
|
|
856
|
+
if (state.status !== 'active') {
|
|
857
|
+
return;
|
|
869
858
|
}
|
|
870
|
-
|
|
871
|
-
state.
|
|
872
|
-
|
|
873
|
-
|
|
859
|
+
const resolvedPromise = Promise.resolve(promiseCreator({
|
|
860
|
+
input: state.input,
|
|
861
|
+
system,
|
|
862
|
+
self
|
|
863
|
+
}));
|
|
864
|
+
resolvedPromise.then(response => {
|
|
865
|
+
// TODO: remove this condition once dead letter queue lands
|
|
866
|
+
if (self._state.status !== 'active') {
|
|
867
|
+
return;
|
|
874
868
|
}
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
869
|
+
self.send({
|
|
870
|
+
type: resolveEventType,
|
|
871
|
+
data: response
|
|
872
|
+
});
|
|
873
|
+
}, errorData => {
|
|
874
|
+
// TODO: remove this condition once dead letter queue lands
|
|
875
|
+
if (self._state.status !== 'active') {
|
|
876
|
+
return;
|
|
877
|
+
}
|
|
878
|
+
self.send({
|
|
879
|
+
type: rejectEventType,
|
|
880
|
+
data: errorData
|
|
881
|
+
});
|
|
882
|
+
});
|
|
883
883
|
},
|
|
884
884
|
getInitialState: (_, input) => {
|
|
885
885
|
return {
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
dispose: undefined,
|
|
886
|
+
status: 'active',
|
|
887
|
+
data: undefined,
|
|
889
888
|
input
|
|
890
889
|
};
|
|
891
890
|
},
|
|
892
|
-
getSnapshot:
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
891
|
+
getSnapshot: state => state.data,
|
|
892
|
+
getStatus: state => state,
|
|
893
|
+
getPersistedState: state => state,
|
|
894
|
+
restoreState: state => state
|
|
896
895
|
};
|
|
897
896
|
return logic;
|
|
898
897
|
}
|
|
@@ -931,6 +930,7 @@ function toActorRef(actorRefLike) {
|
|
|
931
930
|
id: 'anonymous',
|
|
932
931
|
sessionId: '',
|
|
933
932
|
getSnapshot: () => undefined,
|
|
933
|
+
// TODO: this isn't safe
|
|
934
934
|
[symbolObservable]: function () {
|
|
935
935
|
return this;
|
|
936
936
|
},
|
|
@@ -944,6 +944,19 @@ function createEmptyActor() {
|
|
|
944
944
|
return interpret(emptyLogic);
|
|
945
945
|
}
|
|
946
946
|
|
|
947
|
+
/**
|
|
948
|
+
* This function makes sure that unhandled errors are thrown in a separate macrotask.
|
|
949
|
+
* It allows those errors to be detected by global error handlers and reported to bug tracking services
|
|
950
|
+
* without interrupting our own stack of execution.
|
|
951
|
+
*
|
|
952
|
+
* @param err error to be thrown
|
|
953
|
+
*/
|
|
954
|
+
function reportUnhandledError(err) {
|
|
955
|
+
setTimeout(() => {
|
|
956
|
+
throw err;
|
|
957
|
+
});
|
|
958
|
+
}
|
|
959
|
+
|
|
947
960
|
function createSystem() {
|
|
948
961
|
let sessionIdCounter = 0;
|
|
949
962
|
const children = new Map();
|
|
@@ -1112,29 +1125,38 @@ class Interpreter {
|
|
|
1112
1125
|
deferredFn();
|
|
1113
1126
|
}
|
|
1114
1127
|
for (const observer of this.observers) {
|
|
1115
|
-
|
|
1128
|
+
// TODO: should observers be notified in case of the error?
|
|
1129
|
+
try {
|
|
1130
|
+
observer.next?.(snapshot);
|
|
1131
|
+
} catch (err) {
|
|
1132
|
+
reportUnhandledError(err);
|
|
1133
|
+
}
|
|
1116
1134
|
}
|
|
1117
1135
|
const status = this.logic.getStatus?.(state);
|
|
1118
1136
|
switch (status?.status) {
|
|
1119
1137
|
case 'done':
|
|
1120
1138
|
this._stopProcedure();
|
|
1139
|
+
this._complete();
|
|
1121
1140
|
this._doneEvent = doneInvoke(this.id, status.data);
|
|
1122
1141
|
this._parent?.send(this._doneEvent);
|
|
1123
|
-
this._complete();
|
|
1124
1142
|
break;
|
|
1125
1143
|
case 'error':
|
|
1126
1144
|
this._stopProcedure();
|
|
1127
|
-
this._parent?.send(error(this.id, status.data));
|
|
1128
1145
|
this._error(status.data);
|
|
1146
|
+
this._parent?.send(error(this.id, status.data));
|
|
1129
1147
|
break;
|
|
1130
1148
|
}
|
|
1131
1149
|
}
|
|
1132
1150
|
subscribe(nextListenerOrObserver, errorListener, completeListener) {
|
|
1133
1151
|
const observer = toObserver(nextListenerOrObserver, errorListener, completeListener);
|
|
1134
|
-
this.
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1152
|
+
if (this.status !== ActorStatus.Stopped) {
|
|
1153
|
+
this.observers.add(observer);
|
|
1154
|
+
} else {
|
|
1155
|
+
try {
|
|
1156
|
+
observer.complete?.();
|
|
1157
|
+
} catch (err) {
|
|
1158
|
+
reportUnhandledError(err);
|
|
1159
|
+
}
|
|
1138
1160
|
}
|
|
1139
1161
|
return {
|
|
1140
1162
|
unsubscribe: () => {
|
|
@@ -1156,8 +1178,26 @@ class Interpreter {
|
|
|
1156
1178
|
this.system._set(this._systemId, this);
|
|
1157
1179
|
}
|
|
1158
1180
|
this.status = ActorStatus.Running;
|
|
1181
|
+
const status = this.logic.getStatus?.(this._state);
|
|
1182
|
+
switch (status?.status) {
|
|
1183
|
+
case 'done':
|
|
1184
|
+
// a state machine can be "done" upon intialization (it could reach a final state using initial microsteps)
|
|
1185
|
+
// we still need to complete observers, flush deferreds etc
|
|
1186
|
+
this.update(this._state);
|
|
1187
|
+
// fallthrough
|
|
1188
|
+
case 'error':
|
|
1189
|
+
// TODO: rethink cleanup of observers, mailbox, etc
|
|
1190
|
+
return this;
|
|
1191
|
+
}
|
|
1159
1192
|
if (this.logic.start) {
|
|
1160
|
-
|
|
1193
|
+
try {
|
|
1194
|
+
this.logic.start(this._state, this._actorContext);
|
|
1195
|
+
} catch (err) {
|
|
1196
|
+
this._stopProcedure();
|
|
1197
|
+
this._error(err);
|
|
1198
|
+
this._parent?.send(error(this.id, err));
|
|
1199
|
+
return this;
|
|
1200
|
+
}
|
|
1161
1201
|
}
|
|
1162
1202
|
|
|
1163
1203
|
// TODO: this notifies all subscribers but usually this is redundant
|
|
@@ -1171,23 +1211,30 @@ class Interpreter {
|
|
|
1171
1211
|
return this;
|
|
1172
1212
|
}
|
|
1173
1213
|
_process(event) {
|
|
1214
|
+
// TODO: reexamine what happens when an action (or a guard or smth) throws
|
|
1215
|
+
let nextState;
|
|
1216
|
+
let caughtError;
|
|
1174
1217
|
try {
|
|
1175
|
-
|
|
1176
|
-
this.update(nextState);
|
|
1177
|
-
if (event.type === stopSignalType) {
|
|
1178
|
-
this._stopProcedure();
|
|
1179
|
-
this._complete();
|
|
1180
|
-
}
|
|
1218
|
+
nextState = this.logic.transition(this._state, event, this._actorContext);
|
|
1181
1219
|
} catch (err) {
|
|
1182
|
-
//
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
}
|
|
1220
|
+
// we wrap it in a box so we can rethrow it later even if falsy value gets caught here
|
|
1221
|
+
caughtError = {
|
|
1222
|
+
err
|
|
1223
|
+
};
|
|
1224
|
+
}
|
|
1225
|
+
if (caughtError) {
|
|
1226
|
+
const {
|
|
1227
|
+
err
|
|
1228
|
+
} = caughtError;
|
|
1229
|
+
this._stopProcedure();
|
|
1230
|
+
this._error(err);
|
|
1231
|
+
this._parent?.send(error(this.id, err));
|
|
1232
|
+
return;
|
|
1233
|
+
}
|
|
1234
|
+
this.update(nextState);
|
|
1235
|
+
if (event.type === stopSignalType) {
|
|
1236
|
+
this._stopProcedure();
|
|
1237
|
+
this._complete();
|
|
1191
1238
|
}
|
|
1192
1239
|
}
|
|
1193
1240
|
_stop() {
|
|
@@ -1216,15 +1263,35 @@ class Interpreter {
|
|
|
1216
1263
|
}
|
|
1217
1264
|
_complete() {
|
|
1218
1265
|
for (const observer of this.observers) {
|
|
1219
|
-
|
|
1266
|
+
try {
|
|
1267
|
+
observer.complete?.();
|
|
1268
|
+
} catch (err) {
|
|
1269
|
+
reportUnhandledError(err);
|
|
1270
|
+
}
|
|
1220
1271
|
}
|
|
1221
1272
|
this.observers.clear();
|
|
1222
1273
|
}
|
|
1223
|
-
_error(
|
|
1274
|
+
_error(err) {
|
|
1275
|
+
if (!this.observers.size) {
|
|
1276
|
+
if (!this._parent) {
|
|
1277
|
+
reportUnhandledError(err);
|
|
1278
|
+
}
|
|
1279
|
+
return;
|
|
1280
|
+
}
|
|
1281
|
+
let reportError = false;
|
|
1224
1282
|
for (const observer of this.observers) {
|
|
1225
|
-
observer.error
|
|
1283
|
+
const errorListener = observer.error;
|
|
1284
|
+
reportError ||= !errorListener;
|
|
1285
|
+
try {
|
|
1286
|
+
errorListener?.(err);
|
|
1287
|
+
} catch (err2) {
|
|
1288
|
+
reportUnhandledError(err2);
|
|
1289
|
+
}
|
|
1226
1290
|
}
|
|
1227
1291
|
this.observers.clear();
|
|
1292
|
+
if (reportError) {
|
|
1293
|
+
reportUnhandledError(err);
|
|
1294
|
+
}
|
|
1228
1295
|
}
|
|
1229
1296
|
_stopProcedure() {
|
|
1230
1297
|
if (this.status !== ActorStatus.Running) {
|
|
@@ -1557,10 +1624,10 @@ function toGuardDefinition(guardConfig, getPredicate) {
|
|
|
1557
1624
|
}
|
|
1558
1625
|
}
|
|
1559
1626
|
|
|
1560
|
-
function getOutput(configuration, context, event) {
|
|
1627
|
+
function getOutput(configuration, context, event, self) {
|
|
1561
1628
|
const machine = configuration[0].machine;
|
|
1562
1629
|
const finalChildStateNode = configuration.find(stateNode => stateNode.type === 'final' && stateNode.parent === machine.root);
|
|
1563
|
-
return finalChildStateNode && finalChildStateNode.output ? mapContext(finalChildStateNode.output, context, event) : undefined;
|
|
1630
|
+
return finalChildStateNode && finalChildStateNode.output ? mapContext(finalChildStateNode.output, context, event, self) : undefined;
|
|
1564
1631
|
}
|
|
1565
1632
|
const isAtomicStateNode = stateNode => stateNode.type === 'atomic' || stateNode.type === 'final';
|
|
1566
1633
|
function getChildren(stateNode) {
|
|
@@ -2187,7 +2254,7 @@ function microstepProcedure(transitions, currentState, mutConfiguration, event,
|
|
|
2187
2254
|
actions.push(...filteredTransitions.flatMap(t => t.actions));
|
|
2188
2255
|
|
|
2189
2256
|
// Enter states
|
|
2190
|
-
enterStates(event, filteredTransitions, mutConfiguration, actions, internalQueue, currentState, historyValue, isInitial);
|
|
2257
|
+
enterStates(event, filteredTransitions, mutConfiguration, actions, internalQueue, currentState, historyValue, isInitial, actorCtx);
|
|
2191
2258
|
const nextConfiguration = [...mutConfiguration];
|
|
2192
2259
|
const done = isInFinalState(nextConfiguration);
|
|
2193
2260
|
if (done) {
|
|
@@ -2196,7 +2263,7 @@ function microstepProcedure(transitions, currentState, mutConfiguration, event,
|
|
|
2196
2263
|
}
|
|
2197
2264
|
try {
|
|
2198
2265
|
const nextState = resolveActionsAndContext(actions, event, currentState, actorCtx);
|
|
2199
|
-
const output = done ? getOutput(nextConfiguration, nextState.context, event) : undefined;
|
|
2266
|
+
const output = done ? getOutput(nextConfiguration, nextState.context, event, actorCtx.self) : undefined;
|
|
2200
2267
|
internalQueue.push(...nextState._internalQueue);
|
|
2201
2268
|
return cloneState(currentState, {
|
|
2202
2269
|
configuration: nextConfiguration,
|
|
@@ -2213,7 +2280,7 @@ function microstepProcedure(transitions, currentState, mutConfiguration, event,
|
|
|
2213
2280
|
throw e;
|
|
2214
2281
|
}
|
|
2215
2282
|
}
|
|
2216
|
-
function enterStates(event, filteredTransitions, mutConfiguration, actions, internalQueue, currentState, historyValue, isInitial) {
|
|
2283
|
+
function enterStates(event, filteredTransitions, mutConfiguration, actions, internalQueue, currentState, historyValue, isInitial, actorContext) {
|
|
2217
2284
|
const statesToEnter = new Set();
|
|
2218
2285
|
const statesForDefaultEntry = new Set();
|
|
2219
2286
|
computeEntrySet(filteredTransitions, historyValue, statesForDefaultEntry, statesToEnter);
|
|
@@ -2241,7 +2308,7 @@ function enterStates(event, filteredTransitions, mutConfiguration, actions, inte
|
|
|
2241
2308
|
if (!parent.parent) {
|
|
2242
2309
|
continue;
|
|
2243
2310
|
}
|
|
2244
|
-
internalQueue.push(done(parent.id, stateNodeToEnter.output ? mapContext(stateNodeToEnter.output, currentState.context, event) : undefined));
|
|
2311
|
+
internalQueue.push(done(parent.id, stateNodeToEnter.output ? mapContext(stateNodeToEnter.output, currentState.context, event, actorContext.self) : undefined));
|
|
2245
2312
|
if (parent.parent) {
|
|
2246
2313
|
const grandparent = parent.parent;
|
|
2247
2314
|
if (grandparent.type === 'parallel') {
|
|
@@ -2564,6 +2631,7 @@ class State {
|
|
|
2564
2631
|
this.value = void 0;
|
|
2565
2632
|
this.done = void 0;
|
|
2566
2633
|
this.output = void 0;
|
|
2634
|
+
this.error = void 0;
|
|
2567
2635
|
this.context = void 0;
|
|
2568
2636
|
this.historyValue = {};
|
|
2569
2637
|
this._internalQueue = void 0;
|
|
@@ -2580,6 +2648,7 @@ class State {
|
|
|
2580
2648
|
this.tags = new Set(flatten(this.configuration.map(sn => sn.tags)));
|
|
2581
2649
|
this.done = config.done ?? false;
|
|
2582
2650
|
this.output = config.output;
|
|
2651
|
+
this.error = config.error;
|
|
2583
2652
|
}
|
|
2584
2653
|
|
|
2585
2654
|
/**
|
|
@@ -2824,7 +2893,7 @@ function createSpawner(actorContext, {
|
|
|
2824
2893
|
}
|
|
2825
2894
|
};
|
|
2826
2895
|
return (src, options) => {
|
|
2827
|
-
const actorRef = spawn(src, options);
|
|
2896
|
+
const actorRef = spawn(src, options); // TODO: fix types
|
|
2828
2897
|
spawnedChildren[actorRef.id] = actorRef;
|
|
2829
2898
|
actorContext.defer(() => {
|
|
2830
2899
|
if (actorRef.status === ActorStatus.Stopped) {
|
|
@@ -3062,6 +3131,7 @@ exports.and = and;
|
|
|
3062
3131
|
exports.assign = assign;
|
|
3063
3132
|
exports.cancel = cancel;
|
|
3064
3133
|
exports.choose = choose;
|
|
3134
|
+
exports.cloneState = cloneState;
|
|
3065
3135
|
exports.constantPrefixes = constantPrefixes;
|
|
3066
3136
|
exports.createEmptyActor = createEmptyActor;
|
|
3067
3137
|
exports.createInitEvent = createInitEvent;
|