xstate 3.3.2 → 3.3.3
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/README.md +21 -1
- package/dist/xstate.js +1 -1
- package/dist/xstate.utils.js +1 -1
- package/es/State.d.ts +8 -7
- package/es/State.js +3 -2
- package/es/StateNode.d.ts +35 -20
- package/es/StateNode.js +119 -46
- package/es/graph.d.ts +4 -1
- package/es/graph.js +5 -4
- package/es/patterns.js +1 -1
- package/es/scxml.d.ts +2 -1
- package/es/scxml.js +9 -8
- package/es/types.d.ts +4 -7
- package/es/utils.d.ts +6 -1
- package/es/utils.js +17 -1
- package/lib/State.d.ts +8 -7
- package/lib/State.js +3 -2
- package/lib/StateNode.d.ts +35 -20
- package/lib/StateNode.js +118 -45
- package/lib/graph.d.ts +4 -1
- package/lib/graph.js +5 -3
- package/lib/patterns.js +1 -1
- package/lib/scxml.d.ts +2 -1
- package/lib/scxml.js +9 -8
- package/lib/types.d.ts +4 -7
- package/lib/utils.d.ts +6 -1
- package/lib/utils.js +18 -1
- package/package.json +3 -3
- package/src/State.ts +4 -1
- package/src/StateNode.ts +221 -89
- package/src/graph.ts +14 -12
- package/src/scxml.ts +52 -49
- package/src/types.ts +6 -9
- package/src/utils.ts +25 -4
- package/test/activities.test.ts +28 -1
- package/test/deterministic.test.ts +1 -1
- package/test/history.test.ts +139 -0
- package/test/invalid.test.ts +48 -0
- package/test/parallel.test.ts +229 -1
package/lib/StateNode.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { Event, StateValue, Action, StandardMachine, ParallelMachine, SimpleOrCompoundStateNodeConfig,
|
|
1
|
+
import { Event, StateValue, Action, StandardMachine, ParallelMachine, SimpleOrCompoundStateNodeConfig, ParallelMachineConfig, EventType, StandardMachineConfig, Activity, ConditionalTransitionConfig, StateTransition, MachineOptions, HistoryValue } from './types';
|
|
2
2
|
import { State } from './State';
|
|
3
|
-
declare class StateNode
|
|
3
|
+
declare class StateNode {
|
|
4
4
|
config: SimpleOrCompoundStateNodeConfig | StandardMachineConfig | ParallelMachineConfig;
|
|
5
5
|
options: MachineOptions;
|
|
6
6
|
key: string;
|
|
@@ -25,22 +25,23 @@ declare class StateNode implements StateNode {
|
|
|
25
25
|
constructor(config: SimpleOrCompoundStateNodeConfig | StandardMachineConfig | ParallelMachineConfig, options?: MachineOptions);
|
|
26
26
|
getStateNodes(state: StateValue | State): StateNode[];
|
|
27
27
|
handles(event: Event): boolean;
|
|
28
|
-
_transitionLeafNode
|
|
29
|
-
_transitionHierarchicalNode
|
|
30
|
-
_transitionOrthogonalNode
|
|
31
|
-
_transition(stateValue: StateValue, state: State, event: Event, extendedState?: any):
|
|
32
|
-
_next
|
|
33
|
-
_getEntryExitStates
|
|
34
|
-
private _evaluateCond
|
|
35
|
-
private _getActions
|
|
36
|
-
private _getActivities
|
|
28
|
+
private _transitionLeafNode;
|
|
29
|
+
private _transitionHierarchicalNode;
|
|
30
|
+
private _transitionOrthogonalNode;
|
|
31
|
+
_transition(stateValue: StateValue, state: State, event: Event, extendedState?: any): StateTransition;
|
|
32
|
+
private _next;
|
|
33
|
+
private _getEntryExitStates;
|
|
34
|
+
private _evaluateCond;
|
|
35
|
+
private _getActions;
|
|
36
|
+
private _getActivities;
|
|
37
37
|
transition(state: StateValue | State, event: Event, extendedState?: any): State;
|
|
38
|
-
private ensureValidPaths
|
|
38
|
+
private ensureValidPaths;
|
|
39
39
|
getStateNode(stateKey: string): StateNode;
|
|
40
40
|
getStateNodeById(stateId: string): StateNode;
|
|
41
|
-
|
|
41
|
+
getStateNodeByPath(statePath: string | string[]): StateNode;
|
|
42
|
+
private resolve;
|
|
42
43
|
private readonly resolvedStateValue;
|
|
43
|
-
private getResolvedPath
|
|
44
|
+
private getResolvedPath;
|
|
44
45
|
private readonly initialStateValue;
|
|
45
46
|
readonly initialState: State;
|
|
46
47
|
readonly target: StateValue | undefined;
|
|
@@ -52,13 +53,27 @@ declare class StateNode implements StateNode {
|
|
|
52
53
|
* @param history The previous state to retrieve history
|
|
53
54
|
* @param resolve Whether state nodes should resolve to initial child state nodes
|
|
54
55
|
*/
|
|
55
|
-
getRelativeStateNodes(relativeStateId: string | string[],
|
|
56
|
+
getRelativeStateNodes(relativeStateId: string | string[], historyValue?: HistoryValue, resolve?: boolean): StateNode[];
|
|
56
57
|
readonly initialStateNodes: StateNode[];
|
|
57
|
-
|
|
58
|
-
|
|
58
|
+
/**
|
|
59
|
+
* Retrieves state nodes from a relative path to this state node.
|
|
60
|
+
*
|
|
61
|
+
* @param relativePath The relative path from this state node
|
|
62
|
+
* @param historyValue
|
|
63
|
+
*/
|
|
64
|
+
getFromRelativePath(relativePath: string[], historyValue?: HistoryValue): StateNode[];
|
|
65
|
+
static updateHistoryValue(hist: HistoryValue, stateValue: StateValue): HistoryValue;
|
|
66
|
+
historyValue(relativeStateValue?: StateValue | undefined): HistoryValue | undefined;
|
|
67
|
+
/**
|
|
68
|
+
* Resolves to the historical value(s) of the parent state node,
|
|
69
|
+
* represented by state nodes.
|
|
70
|
+
*
|
|
71
|
+
* @param historyValue
|
|
72
|
+
*/
|
|
73
|
+
private resolveHistory;
|
|
59
74
|
readonly events: EventType[];
|
|
60
|
-
private formatTransition
|
|
61
|
-
private formatTransitions
|
|
75
|
+
private formatTransition;
|
|
76
|
+
private formatTransitions;
|
|
62
77
|
}
|
|
63
|
-
export declare function Machine
|
|
78
|
+
export declare function Machine<T extends StandardMachineConfig | ParallelMachineConfig>(config: T, options?: MachineOptions): T extends ParallelMachineConfig ? ParallelMachine : T extends StandardMachineConfig ? StandardMachine : never;
|
|
64
79
|
export { StateNode };
|
package/lib/StateNode.js
CHANGED
|
@@ -17,11 +17,6 @@ var HISTORY_KEY = '$history';
|
|
|
17
17
|
var NULL_EVENT = '';
|
|
18
18
|
var STATE_IDENTIFIER = '#';
|
|
19
19
|
var isStateId = function (str) { return str[0] === STATE_IDENTIFIER; };
|
|
20
|
-
// const emptyActions: ActionMap = Object.freeze({
|
|
21
|
-
// onEntry: [],
|
|
22
|
-
// onExit: [],
|
|
23
|
-
// actions: []
|
|
24
|
-
// });
|
|
25
20
|
var defaultOptions = {
|
|
26
21
|
guards: {}
|
|
27
22
|
};
|
|
@@ -53,10 +48,10 @@ var StateNode = /** @class */ (function () {
|
|
|
53
48
|
this.parallel = !!config.parallel;
|
|
54
49
|
this.states = (config.states
|
|
55
50
|
? utils_1.mapValues(config.states, function (stateConfig, key) {
|
|
51
|
+
var _a;
|
|
56
52
|
var stateNode = new StateNode(__assign({}, stateConfig, { key: key, parent: _this }));
|
|
57
53
|
Object.assign(_this.idMap, __assign((_a = {}, _a[stateNode.id] = stateNode, _a), stateNode.idMap));
|
|
58
54
|
return stateNode;
|
|
59
|
-
var _a;
|
|
60
55
|
})
|
|
61
56
|
: {});
|
|
62
57
|
// History config
|
|
@@ -74,6 +69,7 @@ var StateNode = /** @class */ (function () {
|
|
|
74
69
|
}
|
|
75
70
|
StateNode.prototype.getStateNodes = function (state) {
|
|
76
71
|
var _this = this;
|
|
72
|
+
var _a;
|
|
77
73
|
if (!state) {
|
|
78
74
|
return [];
|
|
79
75
|
}
|
|
@@ -94,7 +90,6 @@ var StateNode = /** @class */ (function () {
|
|
|
94
90
|
var subStateNode = _this.getStateNode(subStateKey).getStateNodes(stateValue[subStateKey]);
|
|
95
91
|
return allSubStateNodes.concat(subStateNode);
|
|
96
92
|
}, []));
|
|
97
|
-
var _a;
|
|
98
93
|
};
|
|
99
94
|
StateNode.prototype.handles = function (event) {
|
|
100
95
|
var eventType = utils_1.getEventType(event);
|
|
@@ -196,10 +191,10 @@ var StateNode = /** @class */ (function () {
|
|
|
196
191
|
}
|
|
197
192
|
var allResolvedPaths = utils_1.flatMap(Object.keys(transitionMap).map(function (key) {
|
|
198
193
|
var transition = transitionMap[key];
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
194
|
+
var value = transition.value || state.value;
|
|
195
|
+
return utils_1.toStatePaths(utils_1.path(_this.path)(value)[key]).map(function (statePath) {
|
|
196
|
+
return _this.path.concat(key, statePath);
|
|
197
|
+
});
|
|
203
198
|
}));
|
|
204
199
|
var nextStateValue = this.machine.resolve(utils_1.pathsToStateValue(allResolvedPaths));
|
|
205
200
|
return {
|
|
@@ -282,7 +277,7 @@ var StateNode = /** @class */ (function () {
|
|
|
282
277
|
};
|
|
283
278
|
}
|
|
284
279
|
var nextStateNodes = utils_1.flatMap(nextStateStrings.map(function (str) {
|
|
285
|
-
return _this.getRelativeStateNodes(str, state.
|
|
280
|
+
return _this.getRelativeStateNodes(str, state.historyValue);
|
|
286
281
|
}));
|
|
287
282
|
var nextStatePaths = nextStateNodes.map(function (stateNode) { return stateNode.path; });
|
|
288
283
|
var entryExitStates = nextStateNodes.reduce(function (allEntryExitStates, nextStateNode) {
|
|
@@ -294,7 +289,7 @@ var StateNode = /** @class */ (function () {
|
|
|
294
289
|
}, { entry: new Set(), exit: new Set() });
|
|
295
290
|
return {
|
|
296
291
|
value: this.machine.resolve(utils_1.pathsToStateValue(utils_1.flatMap(nextStateStrings.map(function (str) {
|
|
297
|
-
return _this.getRelativeStateNodes(str, state.
|
|
292
|
+
return _this.getRelativeStateNodes(str, state.historyValue).map(function (s) { return s.path; });
|
|
298
293
|
})))),
|
|
299
294
|
entryExitStates: entryExitStates,
|
|
300
295
|
actions: actions,
|
|
@@ -348,8 +343,7 @@ var StateNode = /** @class */ (function () {
|
|
|
348
343
|
var condFn;
|
|
349
344
|
if (typeof condition === 'string') {
|
|
350
345
|
if (!this.machine.options.guards[condition]) {
|
|
351
|
-
throw new Error("String condition '" + condition + "' is not defined on machine '" + this
|
|
352
|
-
.machine.id + "'");
|
|
346
|
+
throw new Error("String condition '" + condition + "' is not defined on machine '" + this.machine.id + "'");
|
|
353
347
|
}
|
|
354
348
|
condFn = this.machine.options.guards[condition];
|
|
355
349
|
}
|
|
@@ -381,28 +375,31 @@ var StateNode = /** @class */ (function () {
|
|
|
381
375
|
return {};
|
|
382
376
|
}
|
|
383
377
|
var activityMap = __assign({}, state.activities);
|
|
384
|
-
Array.from(transition.entryExitStates.
|
|
378
|
+
Array.from(transition.entryExitStates.exit).forEach(function (stateNode) {
|
|
385
379
|
if (!stateNode.activities) {
|
|
386
380
|
return; // TODO: fixme
|
|
387
381
|
}
|
|
388
382
|
stateNode.activities.forEach(function (activity) {
|
|
389
|
-
activityMap[utils_1.getActionType(activity)] =
|
|
383
|
+
activityMap[utils_1.getActionType(activity)] = false;
|
|
390
384
|
});
|
|
391
385
|
});
|
|
392
|
-
Array.from(transition.entryExitStates.
|
|
386
|
+
Array.from(transition.entryExitStates.entry).forEach(function (stateNode) {
|
|
393
387
|
if (!stateNode.activities) {
|
|
394
388
|
return; // TODO: fixme
|
|
395
389
|
}
|
|
396
390
|
stateNode.activities.forEach(function (activity) {
|
|
397
|
-
activityMap[utils_1.getActionType(activity)] =
|
|
391
|
+
activityMap[utils_1.getActionType(activity)] = true;
|
|
398
392
|
});
|
|
399
393
|
});
|
|
400
394
|
return activityMap;
|
|
401
395
|
};
|
|
402
396
|
StateNode.prototype.transition = function (state, event, extendedState) {
|
|
397
|
+
var _a;
|
|
403
398
|
var resolvedStateValue = typeof state === 'string'
|
|
404
399
|
? this.resolve(utils_1.pathToStateValue(this.getResolvedPath(state)))
|
|
405
|
-
: state instanceof State_1.State
|
|
400
|
+
: state instanceof State_1.State
|
|
401
|
+
? state
|
|
402
|
+
: this.resolve(state);
|
|
406
403
|
var eventType = utils_1.getEventType(event);
|
|
407
404
|
if (this.strict) {
|
|
408
405
|
if (this.events.indexOf(eventType) === -1) {
|
|
@@ -410,6 +407,11 @@ var StateNode = /** @class */ (function () {
|
|
|
410
407
|
}
|
|
411
408
|
}
|
|
412
409
|
var currentState = State_1.State.from(resolvedStateValue);
|
|
410
|
+
var historyValue = resolvedStateValue instanceof State_1.State
|
|
411
|
+
? resolvedStateValue.historyValue
|
|
412
|
+
? resolvedStateValue.historyValue
|
|
413
|
+
: this.machine.historyValue(resolvedStateValue.value)
|
|
414
|
+
: this.machine.historyValue(resolvedStateValue);
|
|
413
415
|
var stateTransition = this._transition(currentState.value, currentState, event, extendedState);
|
|
414
416
|
try {
|
|
415
417
|
this.ensureValidPaths(stateTransition.paths);
|
|
@@ -438,15 +440,15 @@ var StateNode = /** @class */ (function () {
|
|
|
438
440
|
stateNodes.forEach(function (stateNode) {
|
|
439
441
|
data[stateNode.id] = stateNode.data;
|
|
440
442
|
});
|
|
441
|
-
// Dispose of previous histories to prevent memory leaks
|
|
442
|
-
delete currentState.history;
|
|
443
443
|
var nextState = stateTransition.value
|
|
444
|
-
? new State_1.State(stateTransition.value, currentState, nonEventActions, activities, data, raisedEvents)
|
|
444
|
+
? new State_1.State(stateTransition.value, StateNode.updateHistoryValue(historyValue, stateTransition.value), currentState, nonEventActions, activities, data, raisedEvents)
|
|
445
445
|
: undefined;
|
|
446
446
|
if (!nextState) {
|
|
447
447
|
// Unchanged state should be returned with no actions
|
|
448
448
|
return State_1.State.inert(currentState);
|
|
449
449
|
}
|
|
450
|
+
// Dispose of previous histories to prevent memory leaks
|
|
451
|
+
delete currentState.history;
|
|
450
452
|
var maybeNextState = nextState;
|
|
451
453
|
while (raisedEvents.length) {
|
|
452
454
|
var currentActions = maybeNextState.actions;
|
|
@@ -455,7 +457,6 @@ var StateNode = /** @class */ (function () {
|
|
|
455
457
|
(_a = maybeNextState.actions).unshift.apply(_a, currentActions);
|
|
456
458
|
}
|
|
457
459
|
return maybeNextState;
|
|
458
|
-
var _a;
|
|
459
460
|
};
|
|
460
461
|
StateNode.prototype.ensureValidPaths = function (paths) {
|
|
461
462
|
var _this = this;
|
|
@@ -469,8 +470,9 @@ var StateNode = /** @class */ (function () {
|
|
|
469
470
|
if (marker.parent.parallel) {
|
|
470
471
|
continue outer;
|
|
471
472
|
}
|
|
472
|
-
throw new Error("State node '" + stateNode.id + "' shares parent '" + marker.parent
|
|
473
|
-
.
|
|
473
|
+
throw new Error("State node '" + stateNode.id + "' shares parent '" + marker.parent.id + "' with state node '" + visitedParents
|
|
474
|
+
.get(marker.parent)
|
|
475
|
+
.map(function (a) { return a.id; }) + "'");
|
|
474
476
|
}
|
|
475
477
|
if (!visitedParents.get(marker.parent)) {
|
|
476
478
|
visitedParents.set(marker.parent, [stateNode]);
|
|
@@ -487,8 +489,7 @@ var StateNode = /** @class */ (function () {
|
|
|
487
489
|
return this.machine.getStateNodeById(stateKey);
|
|
488
490
|
}
|
|
489
491
|
if (!this.states) {
|
|
490
|
-
throw new Error("Unable to retrieve child state '" + stateKey + "' from '" + this
|
|
491
|
-
.id + "'; no child states exist.");
|
|
492
|
+
throw new Error("Unable to retrieve child state '" + stateKey + "' from '" + this.id + "'; no child states exist.");
|
|
492
493
|
}
|
|
493
494
|
var result = this.states[stateKey];
|
|
494
495
|
if (!result) {
|
|
@@ -506,8 +507,18 @@ var StateNode = /** @class */ (function () {
|
|
|
506
507
|
}
|
|
507
508
|
return stateNode;
|
|
508
509
|
};
|
|
510
|
+
StateNode.prototype.getStateNodeByPath = function (statePath) {
|
|
511
|
+
var arrayStatePath = utils_1.toStatePath(statePath, this.delimiter);
|
|
512
|
+
var currentStateNode = this;
|
|
513
|
+
while (arrayStatePath.length) {
|
|
514
|
+
var key = arrayStatePath.shift();
|
|
515
|
+
currentStateNode = currentStateNode.getStateNode(key);
|
|
516
|
+
}
|
|
517
|
+
return currentStateNode;
|
|
518
|
+
};
|
|
509
519
|
StateNode.prototype.resolve = function (stateValue) {
|
|
510
520
|
var _this = this;
|
|
521
|
+
var _a;
|
|
511
522
|
if (typeof stateValue === 'string') {
|
|
512
523
|
var subStateNode = this.getStateNode(stateValue);
|
|
513
524
|
return subStateNode.initial
|
|
@@ -525,10 +536,10 @@ var StateNode = /** @class */ (function () {
|
|
|
525
536
|
? _this.getStateNode(subStateKey).resolve(subStateValue)
|
|
526
537
|
: {};
|
|
527
538
|
});
|
|
528
|
-
var _a;
|
|
529
539
|
};
|
|
530
540
|
Object.defineProperty(StateNode.prototype, "resolvedStateValue", {
|
|
531
541
|
get: function () {
|
|
542
|
+
var _a, _b;
|
|
532
543
|
var key = this.key;
|
|
533
544
|
if (this.parallel) {
|
|
534
545
|
return _a = {},
|
|
@@ -542,7 +553,6 @@ var StateNode = /** @class */ (function () {
|
|
|
542
553
|
return _b = {},
|
|
543
554
|
_b[key] = this.states[this.initial].resolvedStateValue,
|
|
544
555
|
_b;
|
|
545
|
-
var _a, _b;
|
|
546
556
|
},
|
|
547
557
|
enumerable: true,
|
|
548
558
|
configurable: true
|
|
@@ -575,6 +585,7 @@ var StateNode = /** @class */ (function () {
|
|
|
575
585
|
});
|
|
576
586
|
Object.defineProperty(StateNode.prototype, "initialState", {
|
|
577
587
|
get: function () {
|
|
588
|
+
var _a;
|
|
578
589
|
var initialStateValue = this.initialStateValue;
|
|
579
590
|
if (!initialStateValue) {
|
|
580
591
|
throw new Error("Cannot retrieve initial state from simple state '" + this.id + ".'");
|
|
@@ -592,7 +603,21 @@ var StateNode = /** @class */ (function () {
|
|
|
592
603
|
});
|
|
593
604
|
}
|
|
594
605
|
});
|
|
595
|
-
|
|
606
|
+
// TODO: deduplicate - DRY (from this.transition())
|
|
607
|
+
var raisedEvents = actions.filter(function (action) {
|
|
608
|
+
return typeof action === 'object' &&
|
|
609
|
+
(action.type === actions_1.actionTypes.raise || action.type === actions_1.actionTypes.null);
|
|
610
|
+
});
|
|
611
|
+
var initialState = new State_1.State(initialStateValue, undefined, undefined, actions, activityMap);
|
|
612
|
+
var maybeNextState = initialState;
|
|
613
|
+
while (raisedEvents.length) {
|
|
614
|
+
var currentActions = maybeNextState.actions;
|
|
615
|
+
var raisedEvent = raisedEvents.shift();
|
|
616
|
+
maybeNextState = this.transition(maybeNextState, raisedEvent.type === actions_1.actionTypes.null ? NULL_EVENT : raisedEvent.event, undefined // TODO: consider initial state given external state
|
|
617
|
+
);
|
|
618
|
+
(_a = maybeNextState.actions).unshift.apply(_a, currentActions);
|
|
619
|
+
}
|
|
620
|
+
return maybeNextState;
|
|
596
621
|
},
|
|
597
622
|
enumerable: true,
|
|
598
623
|
configurable: true
|
|
@@ -636,9 +661,8 @@ var StateNode = /** @class */ (function () {
|
|
|
636
661
|
* @param history The previous state to retrieve history
|
|
637
662
|
* @param resolve Whether state nodes should resolve to initial child state nodes
|
|
638
663
|
*/
|
|
639
|
-
StateNode.prototype.getRelativeStateNodes = function (relativeStateId,
|
|
664
|
+
StateNode.prototype.getRelativeStateNodes = function (relativeStateId, historyValue, resolve) {
|
|
640
665
|
if (resolve === void 0) { resolve = true; }
|
|
641
|
-
var historyValue = history ? history.value : undefined;
|
|
642
666
|
if (typeof relativeStateId === 'string' && isStateId(relativeStateId)) {
|
|
643
667
|
var unresolvedStateNode = this.getStateNodeById(relativeStateId);
|
|
644
668
|
return resolve
|
|
@@ -671,6 +695,12 @@ var StateNode = /** @class */ (function () {
|
|
|
671
695
|
enumerable: true,
|
|
672
696
|
configurable: true
|
|
673
697
|
});
|
|
698
|
+
/**
|
|
699
|
+
* Retrieves state nodes from a relative path to this state node.
|
|
700
|
+
*
|
|
701
|
+
* @param relativePath The relative path from this state node
|
|
702
|
+
* @param historyValue
|
|
703
|
+
*/
|
|
674
704
|
StateNode.prototype.getFromRelativePath = function (relativePath, historyValue) {
|
|
675
705
|
var _this = this;
|
|
676
706
|
if (!relativePath.length) {
|
|
@@ -685,7 +715,7 @@ var StateNode = /** @class */ (function () {
|
|
|
685
715
|
if (!historyValue) {
|
|
686
716
|
return [this];
|
|
687
717
|
}
|
|
688
|
-
var subHistoryValue = utils_1.
|
|
718
|
+
var subHistoryValue = utils_1.nestedPath(this.path, 'states')(historyValue).current;
|
|
689
719
|
if (typeof subHistoryValue === 'string') {
|
|
690
720
|
return this.states[subHistoryValue].getFromRelativePath(xs, historyValue);
|
|
691
721
|
}
|
|
@@ -702,6 +732,51 @@ var StateNode = /** @class */ (function () {
|
|
|
702
732
|
}
|
|
703
733
|
return this.states[x].getFromRelativePath(xs, historyValue);
|
|
704
734
|
};
|
|
735
|
+
StateNode.updateHistoryValue = function (hist, stateValue) {
|
|
736
|
+
function update(_hist, _sv) {
|
|
737
|
+
return utils_1.mapValues(_hist.states, function (subHist, key) {
|
|
738
|
+
if (!subHist) {
|
|
739
|
+
return undefined;
|
|
740
|
+
}
|
|
741
|
+
var subStateValue = (typeof _sv === 'string' ? undefined : _sv[key]) ||
|
|
742
|
+
(subHist ? subHist.current : undefined);
|
|
743
|
+
if (!subStateValue) {
|
|
744
|
+
return undefined;
|
|
745
|
+
}
|
|
746
|
+
return {
|
|
747
|
+
current: subStateValue,
|
|
748
|
+
states: update(subHist, subStateValue)
|
|
749
|
+
};
|
|
750
|
+
});
|
|
751
|
+
}
|
|
752
|
+
return {
|
|
753
|
+
current: stateValue,
|
|
754
|
+
states: update(hist, stateValue)
|
|
755
|
+
};
|
|
756
|
+
};
|
|
757
|
+
StateNode.prototype.historyValue = function (relativeStateValue) {
|
|
758
|
+
if (!Object.keys(this.states).length) {
|
|
759
|
+
return undefined;
|
|
760
|
+
}
|
|
761
|
+
return {
|
|
762
|
+
current: relativeStateValue || this.initialStateValue,
|
|
763
|
+
states: utils_1.mapFilterValues(this.states, function (stateNode, key) {
|
|
764
|
+
if (!relativeStateValue) {
|
|
765
|
+
return stateNode.historyValue();
|
|
766
|
+
}
|
|
767
|
+
var subStateValue = typeof relativeStateValue === 'string'
|
|
768
|
+
? undefined
|
|
769
|
+
: relativeStateValue[key];
|
|
770
|
+
return stateNode.historyValue(subStateValue || stateNode.initialStateValue);
|
|
771
|
+
}, function (stateNode) { return !stateNode.history; })
|
|
772
|
+
};
|
|
773
|
+
};
|
|
774
|
+
/**
|
|
775
|
+
* Resolves to the historical value(s) of the parent state node,
|
|
776
|
+
* represented by state nodes.
|
|
777
|
+
*
|
|
778
|
+
* @param historyValue
|
|
779
|
+
*/
|
|
705
780
|
StateNode.prototype.resolveHistory = function (historyValue) {
|
|
706
781
|
var _this = this;
|
|
707
782
|
if (!this.history) {
|
|
@@ -711,21 +786,19 @@ var StateNode = /** @class */ (function () {
|
|
|
711
786
|
if (!historyValue) {
|
|
712
787
|
return this.target
|
|
713
788
|
? utils_1.flatMap(utils_1.toStatePaths(this.target).map(function (relativeChildPath) {
|
|
714
|
-
return parent.getFromRelativePath(relativeChildPath
|
|
789
|
+
return parent.getFromRelativePath(relativeChildPath);
|
|
715
790
|
}))
|
|
716
791
|
: this.parent.initialStateNodes;
|
|
717
792
|
}
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
return [parent.getStateNode(subHistoryValue)];
|
|
722
|
-
}
|
|
723
|
-
return utils_1.flatMap(utils_1.toStatePaths(subHistoryValue).map(function (subStatePath) {
|
|
724
|
-
return _this.history === 'deep'
|
|
725
|
-
? parent.getFromRelativePath(subStatePath)
|
|
726
|
-
: [parent.states[subStatePath[0]]];
|
|
727
|
-
}));
|
|
793
|
+
var subHistoryValue = utils_1.nestedPath(parent.path, 'states')(historyValue).current;
|
|
794
|
+
if (typeof subHistoryValue === 'string') {
|
|
795
|
+
return [parent.getStateNode(subHistoryValue)];
|
|
728
796
|
}
|
|
797
|
+
return utils_1.flatMap(utils_1.toStatePaths(subHistoryValue).map(function (subStatePath) {
|
|
798
|
+
return _this.history === 'deep'
|
|
799
|
+
? parent.getFromRelativePath(subStatePath)
|
|
800
|
+
: [parent.states[subStatePath[0]]];
|
|
801
|
+
}));
|
|
729
802
|
};
|
|
730
803
|
Object.defineProperty(StateNode.prototype, "events", {
|
|
731
804
|
get: function () {
|
package/lib/graph.d.ts
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { StateNode } from './index';
|
|
2
2
|
import { Machine, Edge, PathMap, PathItem, PathsItem, PathsMap, AdjacencyMap } from './types';
|
|
3
3
|
export declare function getNodes(node: StateNode): StateNode[];
|
|
4
|
-
export declare function
|
|
4
|
+
export declare function getEventEdges(node: StateNode, event: string): Edge[];
|
|
5
|
+
export declare function getEdges(node: StateNode, options?: {
|
|
6
|
+
deep: boolean;
|
|
7
|
+
}): Edge[];
|
|
5
8
|
export declare function getAdjacencyMap(node: Machine, extendedState?: any): AdjacencyMap;
|
|
6
9
|
export declare function getShortestPaths(machine: Machine, extendedState?: any): PathMap;
|
|
7
10
|
export declare function getShortestPathsAsArray(machine: Machine, extendedState?: any): PathItem[];
|
package/lib/graph.js
CHANGED
|
@@ -31,9 +31,11 @@ function getEventEdges(node, event) {
|
|
|
31
31
|
});
|
|
32
32
|
}));
|
|
33
33
|
}
|
|
34
|
-
|
|
34
|
+
exports.getEventEdges = getEventEdges;
|
|
35
|
+
function getEdges(node, options) {
|
|
36
|
+
var _a = (options || {}).deep, deep = _a === void 0 ? true : _a;
|
|
35
37
|
var edges = [];
|
|
36
|
-
if (node.states) {
|
|
38
|
+
if (node.states && deep) {
|
|
37
39
|
Object.keys(node.states).forEach(function (stateKey) {
|
|
38
40
|
edges.push.apply(edges, getEdges(node.states[stateKey]));
|
|
39
41
|
});
|
|
@@ -65,6 +67,7 @@ function getAdjacencyMap(node, extendedState) {
|
|
|
65
67
|
}
|
|
66
68
|
exports.getAdjacencyMap = getAdjacencyMap;
|
|
67
69
|
function getShortestPaths(machine, extendedState) {
|
|
70
|
+
var _a;
|
|
68
71
|
if (!machine.states) {
|
|
69
72
|
return EMPTY_MAP;
|
|
70
73
|
}
|
|
@@ -108,7 +111,6 @@ function getShortestPaths(machine, extendedState) {
|
|
|
108
111
|
}
|
|
109
112
|
util(machine.initialState.value);
|
|
110
113
|
return pathMap;
|
|
111
|
-
var _a;
|
|
112
114
|
}
|
|
113
115
|
exports.getShortestPaths = getShortestPaths;
|
|
114
116
|
function getShortestPathsAsArray(machine, extendedState) {
|
package/lib/patterns.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
function toggle(onState, offState, eventType) {
|
|
4
|
+
var _a, _b, _c;
|
|
4
5
|
return _a = {},
|
|
5
6
|
_a[onState] = {
|
|
6
7
|
on: (_b = {}, _b[eventType] = offState, _b)
|
|
@@ -9,6 +10,5 @@ function toggle(onState, offState, eventType) {
|
|
|
9
10
|
on: (_c = {}, _c[eventType] = onState, _c)
|
|
10
11
|
},
|
|
11
12
|
_a;
|
|
12
|
-
var _a, _b, _c;
|
|
13
13
|
}
|
|
14
14
|
exports.toggle = toggle;
|
package/lib/scxml.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { Machine, EventObject } from './types';
|
|
2
2
|
export declare function fromMachine(machine: Machine): string;
|
|
3
3
|
export interface ScxmlToMachineOptions {
|
|
4
|
-
evalCond: (expr: string) =>
|
|
4
|
+
evalCond: (expr: string) => // tslint:disable-next-line:ban-types
|
|
5
|
+
((extState: any, event: EventObject) => boolean) | Function;
|
|
5
6
|
delimiter?: string;
|
|
6
7
|
}
|
|
7
8
|
export declare function toMachine(xml: string, options: ScxmlToMachineOptions): any;
|
package/lib/scxml.js
CHANGED
|
@@ -75,9 +75,9 @@ function stateNodeToSCXML(stateNode) {
|
|
|
75
75
|
return {
|
|
76
76
|
type: 'element',
|
|
77
77
|
name: 'transition',
|
|
78
|
-
attributes: __assign({}, event ? { event: event } : undefined, { target: stateNode.parent.getRelativeStateNodes(targetTransition.target)[0].id }, targetTransition.cond
|
|
78
|
+
attributes: __assign({}, (event ? { event: event } : undefined), { target: stateNode.parent.getRelativeStateNodes(targetTransition.target)[0].id }, (targetTransition.cond
|
|
79
79
|
? { cond: targetTransition.cond.toString() }
|
|
80
|
-
: undefined),
|
|
80
|
+
: undefined)),
|
|
81
81
|
elements: targetTransition.actions
|
|
82
82
|
? targetTransition.actions.map(function (action) { return ({
|
|
83
83
|
type: 'element',
|
|
@@ -95,9 +95,10 @@ function stateNodeToSCXML(stateNode) {
|
|
|
95
95
|
return {
|
|
96
96
|
type: 'element',
|
|
97
97
|
name: 'transition',
|
|
98
|
-
attributes: __assign({}, event ? { event: event } : undefined, { target: stateNode.parent.getRelativeStateNodes(target)[0]
|
|
98
|
+
attributes: __assign({}, (event ? { event: event } : undefined), { target: stateNode.parent.getRelativeStateNodes(target)[0]
|
|
99
|
+
.id }, (targetTransition.cond
|
|
99
100
|
? { cond: targetTransition.cond.toString() }
|
|
100
|
-
: undefined),
|
|
101
|
+
: undefined)),
|
|
101
102
|
elements: targetTransition.actions
|
|
102
103
|
? targetTransition.actions.map(function (action) { return ({
|
|
103
104
|
type: 'element',
|
|
@@ -207,11 +208,11 @@ function toConfig(nodeJson, id, options) {
|
|
|
207
208
|
}
|
|
208
209
|
states = indexedRecord(stateElements, function (item) { return "" + item.attributes.id; });
|
|
209
210
|
on = utils_1.mapValues(indexedAggregateRecord(transitionElements, function (item) { return item.attributes.event || ''; }), function (values) {
|
|
210
|
-
return values.map(function (value) { return (__assign({ target: "#" + value.attributes.target }, value.elements ? executableContent(value.elements) : undefined, value.attributes.cond
|
|
211
|
+
return values.map(function (value) { return (__assign({ target: "#" + value.attributes.target }, (value.elements ? executableContent(value.elements) : undefined), (value.attributes.cond
|
|
211
212
|
? {
|
|
212
213
|
cond: evalCond(value.attributes.cond)
|
|
213
214
|
}
|
|
214
|
-
: undefined)); });
|
|
215
|
+
: undefined))); });
|
|
215
216
|
});
|
|
216
217
|
var onEntry = onEntryElement
|
|
217
218
|
? onEntryElement.elements.map(function (element) {
|
|
@@ -233,13 +234,13 @@ function toConfig(nodeJson, id, options) {
|
|
|
233
234
|
}
|
|
234
235
|
})
|
|
235
236
|
: undefined;
|
|
236
|
-
return __assign({ id: id, delimiter: options.delimiter }, initial ? { initial: initial } : undefined, parallel ? { parallel: parallel } : undefined, stateElements.length
|
|
237
|
+
return __assign({ id: id, delimiter: options.delimiter }, (initial ? { initial: initial } : undefined), (parallel ? { parallel: parallel } : undefined), (stateElements.length
|
|
237
238
|
? {
|
|
238
239
|
states: utils_1.mapValues(states, function (state, key) {
|
|
239
240
|
return toConfig(state, key, options);
|
|
240
241
|
})
|
|
241
242
|
}
|
|
242
|
-
: undefined, transitionElements.length ? { on: on } : undefined, onEntry ? { onEntry: onEntry } : undefined, onExit ? { onExit: onExit } : undefined);
|
|
243
|
+
: undefined), (transitionElements.length ? { on: on } : undefined), (onEntry ? { onEntry: onEntry } : undefined), (onExit ? { onExit: onExit } : undefined));
|
|
243
244
|
}
|
|
244
245
|
return { id: id };
|
|
245
246
|
}
|
package/lib/types.d.ts
CHANGED
|
@@ -19,6 +19,10 @@ export interface StateValueMap {
|
|
|
19
19
|
[key: string]: StateValue;
|
|
20
20
|
}
|
|
21
21
|
export declare type StateValue = string | StateValueMap;
|
|
22
|
+
export interface HistoryValue {
|
|
23
|
+
states: Record<string, HistoryValue | undefined>;
|
|
24
|
+
current: StateValue | undefined;
|
|
25
|
+
}
|
|
22
26
|
export declare type ConditionPredicate = (extendedState: any, event: EventObject, microstepState: StateValue) => boolean;
|
|
23
27
|
export declare type Condition = string | ConditionPredicate;
|
|
24
28
|
export interface TransitionConfig {
|
|
@@ -85,7 +89,6 @@ export interface StandardMachineConfig extends MachineConfig {
|
|
|
85
89
|
export interface ParallelMachineConfig extends MachineConfig {
|
|
86
90
|
initial?: undefined;
|
|
87
91
|
parallel: true;
|
|
88
|
-
states: Record<string, CompoundStateNodeConfig>;
|
|
89
92
|
}
|
|
90
93
|
export interface EntryExitEffectMap {
|
|
91
94
|
entry: Action[];
|
|
@@ -149,12 +152,6 @@ export interface ActivityMap {
|
|
|
149
152
|
}
|
|
150
153
|
export declare type MaybeStateValueActionsTuple = [StateValue | undefined, ActionMap, ActivityMap | undefined];
|
|
151
154
|
export interface StateTransition {
|
|
152
|
-
statePaths: string[][];
|
|
153
|
-
actions: ActionMap;
|
|
154
|
-
activities: ActivityMap | undefined;
|
|
155
|
-
events: EventObject[];
|
|
156
|
-
}
|
|
157
|
-
export interface _StateTransition {
|
|
158
155
|
value: StateValue | undefined;
|
|
159
156
|
entryExitStates: EntryExitStates | undefined;
|
|
160
157
|
actions: Action[];
|
package/lib/utils.d.ts
CHANGED
|
@@ -23,7 +23,12 @@ export declare function mapFilterValues<T, P>(collection: {
|
|
|
23
23
|
* Retrieves a value at the given path.
|
|
24
24
|
* @param props The deep path to the prop of the desired value
|
|
25
25
|
*/
|
|
26
|
-
export declare const path: (props: string[]) => any;
|
|
26
|
+
export declare const path: <T extends Record<string, any>>(props: string[]) => any;
|
|
27
|
+
/**
|
|
28
|
+
* Retrieves a value at the given path via the nested accessor prop.
|
|
29
|
+
* @param props The deep path to the prop of the desired value
|
|
30
|
+
*/
|
|
31
|
+
export declare function nestedPath<T extends Record<string, any>>(props: string[], accessorProp: keyof T): (object: T) => T;
|
|
27
32
|
export declare const toStatePaths: (stateValue: StateValue) => string[][];
|
|
28
33
|
export declare const pathsToStateValue: (paths: string[][]) => StateValue;
|
|
29
34
|
export declare const flatMap: <T>(array: T[][]) => T[];
|
package/lib/utils.js
CHANGED
|
@@ -16,7 +16,9 @@ function getActionType(action) {
|
|
|
16
16
|
try {
|
|
17
17
|
return typeof action === 'string' || typeof action === 'number'
|
|
18
18
|
? "" + action
|
|
19
|
-
: typeof action === 'function'
|
|
19
|
+
: typeof action === 'function'
|
|
20
|
+
? action.name
|
|
21
|
+
: action.type;
|
|
20
22
|
}
|
|
21
23
|
catch (e) {
|
|
22
24
|
throw new Error('Events must be strings or objects with a string event.type property.');
|
|
@@ -96,6 +98,21 @@ exports.path = function (props) { return function (object) {
|
|
|
96
98
|
}
|
|
97
99
|
return result;
|
|
98
100
|
}; };
|
|
101
|
+
/**
|
|
102
|
+
* Retrieves a value at the given path via the nested accessor prop.
|
|
103
|
+
* @param props The deep path to the prop of the desired value
|
|
104
|
+
*/
|
|
105
|
+
function nestedPath(props, accessorProp) {
|
|
106
|
+
return function (object) {
|
|
107
|
+
var result = object;
|
|
108
|
+
for (var _i = 0, props_2 = props; _i < props_2.length; _i++) {
|
|
109
|
+
var prop = props_2[_i];
|
|
110
|
+
result = result[accessorProp][prop];
|
|
111
|
+
}
|
|
112
|
+
return result;
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
exports.nestedPath = nestedPath;
|
|
99
116
|
exports.toStatePaths = function (stateValue) {
|
|
100
117
|
if (typeof stateValue === 'string') {
|
|
101
118
|
return [[stateValue]];
|