xstate 5.0.0-alpha.6 → 5.0.0-beta.11
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.d.mts +2 -0
- package/actions/dist/xstate-actions.cjs.d.mts.map +1 -0
- package/actions/dist/xstate-actions.cjs.d.ts +1 -0
- package/actions/dist/xstate-actions.cjs.d.ts.map +1 -0
- package/actions/dist/xstate-actions.cjs.js +29 -5
- package/actions/dist/xstate-actions.cjs.mjs +24 -0
- package/actions/dist/{xstate-actions.cjs.dev.js → xstate-actions.development.cjs.js} +3 -3
- package/actions/dist/xstate-actions.development.esm.js +2 -0
- package/actions/dist/xstate-actions.esm.js +2 -2
- package/actions/dist/xstate-actions.umd.min.js +1 -1
- package/actions/dist/xstate-actions.umd.min.js.map +1 -1
- package/actors/dist/xstate-actors.cjs.d.mts +2 -0
- package/actors/dist/xstate-actors.cjs.d.mts.map +1 -0
- package/actors/dist/xstate-actors.cjs.d.ts +1 -0
- package/actors/dist/xstate-actors.cjs.d.ts.map +1 -0
- package/actors/dist/xstate-actors.cjs.js +20 -5
- package/actors/dist/xstate-actors.cjs.mjs +15 -0
- package/actors/dist/{xstate-actors.cjs.dev.js → xstate-actors.development.cjs.js} +3 -2
- package/actors/dist/xstate-actors.development.esm.js +2 -0
- package/actors/dist/xstate-actors.esm.js +2 -2
- package/actors/dist/xstate-actors.umd.min.js +1 -1
- package/actors/dist/xstate-actors.umd.min.js.map +1 -1
- package/dev/dist/xstate-dev.cjs.d.mts +2 -0
- package/dev/dist/xstate-dev.cjs.d.mts.map +1 -0
- package/dev/dist/xstate-dev.cjs.d.ts +1 -0
- package/dev/dist/xstate-dev.cjs.d.ts.map +1 -0
- package/dev/dist/xstate-dev.cjs.js +45 -4
- package/dev/dist/xstate-dev.cjs.mjs +5 -0
- package/{dist/index-ebaab3c9.cjs.dev.js → dev/dist/xstate-dev.development.cjs.js} +6 -7
- package/{dist/index-50bd0aff.esm.js → dev/dist/xstate-dev.development.esm.js} +6 -8
- package/dev/dist/xstate-dev.esm.js +42 -1
- package/dev/dist/xstate-dev.umd.min.js +1 -1
- package/dev/dist/xstate-dev.umd.min.js.map +1 -1
- package/dist/actions-26f9aa9d.cjs.js +3388 -0
- package/dist/actions-acbe7aa1.development.cjs.js +3423 -0
- package/dist/actions-b82e841e.esm.js +3306 -0
- package/dist/actions-cff79077.development.esm.js +3341 -0
- package/dist/declarations/src/State.d.ts +2 -3
- package/dist/declarations/src/StateMachine.d.ts +6 -6
- package/dist/declarations/src/StateNode.d.ts +3 -9
- package/dist/declarations/src/actions/send.d.ts +0 -7
- package/dist/declarations/src/actions.d.ts +9 -8
- package/dist/declarations/src/actors/index.d.ts +2 -1
- package/dist/declarations/src/actors/observable.d.ts +1 -2
- package/dist/declarations/src/actors/promise.d.ts +1 -2
- package/dist/declarations/src/guards.d.ts +2 -2
- package/dist/declarations/src/index.d.ts +13 -29
- package/dist/declarations/src/interpreter.d.ts +5 -4
- package/dist/declarations/src/stateUtils.d.ts +9 -14
- package/dist/declarations/src/typegenTypes.d.ts +7 -1
- package/dist/declarations/src/types.d.ts +18 -92
- package/dist/declarations/src/utils.d.ts +3 -6
- package/dist/declarations/src/waitFor.d.ts +33 -0
- package/dist/xstate.cjs.d.mts +2 -0
- package/dist/xstate.cjs.d.mts.map +1 -0
- package/dist/xstate.cjs.d.ts +1 -0
- package/dist/xstate.cjs.d.ts.map +1 -0
- package/dist/xstate.cjs.js +802 -4
- package/dist/xstate.cjs.mjs +38 -0
- package/dist/xstate.development.cjs.js +808 -0
- package/dist/xstate.development.esm.js +770 -0
- package/dist/xstate.esm.js +594 -706
- package/dist/xstate.umd.min.js +1 -1
- package/dist/xstate.umd.min.js.map +1 -1
- package/guards/dist/xstate-guards.cjs.d.mts +2 -0
- package/guards/dist/xstate-guards.cjs.d.mts.map +1 -0
- package/guards/dist/xstate-guards.cjs.d.ts +1 -0
- package/guards/dist/xstate-guards.cjs.d.ts.map +1 -0
- package/guards/dist/xstate-guards.cjs.js +13 -5
- package/guards/dist/xstate-guards.cjs.mjs +8 -0
- package/guards/dist/{xstate-guards.cjs.dev.js → xstate-guards.development.cjs.js} +2 -2
- package/guards/dist/xstate-guards.development.esm.js +2 -0
- package/guards/dist/xstate-guards.esm.js +2 -2
- package/guards/dist/xstate-guards.umd.min.js +1 -1
- package/guards/dist/xstate-guards.umd.min.js.map +1 -1
- package/package.json +58 -1
- package/actions/dist/xstate-actions.cjs.prod.js +0 -31
- package/actors/dist/xstate-actors.cjs.prod.js +0 -21
- package/dev/dist/xstate-dev.cjs.dev.js +0 -11
- package/dev/dist/xstate-dev.cjs.prod.js +0 -48
- package/dist/actions-41b74cdc.esm.js +0 -4287
- package/dist/actions-bf7bb1c5.cjs.dev.js +0 -4342
- package/dist/actions-c46e4911.cjs.prod.js +0 -4304
- package/dist/declarations/actions/dynamicAction.d.ts +0 -5
- package/dist/declarations/src/Mailbox.d.ts +0 -12
- package/dist/declarations/src/actions/invoke.d.ts +0 -3
- package/dist/declarations/src/environment.d.ts +0 -1
- package/dist/declarations/src/memo.d.ts +0 -2
- package/dist/declarations/src/schema.d.ts +0 -2
- package/dist/declarations/src/spawn.d.ts +0 -2
- package/dist/declarations/src/system.d.ts +0 -2
- package/dist/xstate.cjs.dev.js +0 -921
- package/dist/xstate.cjs.prod.js +0 -921
- package/guards/dist/xstate-guards.cjs.prod.js +0 -15
package/dist/xstate.esm.js
CHANGED
|
@@ -1,31 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export {
|
|
3
|
-
import '
|
|
4
|
-
|
|
5
|
-
function pure(getActions) {
|
|
6
|
-
return createDynamicAction({
|
|
7
|
-
type: pure$1,
|
|
8
|
-
params: {
|
|
9
|
-
get: getActions
|
|
10
|
-
}
|
|
11
|
-
}, function (_event, _ref) {
|
|
12
|
-
var _toArray;
|
|
13
|
-
var state = _ref.state;
|
|
14
|
-
return [state, {
|
|
15
|
-
type: pure$1,
|
|
16
|
-
params: {
|
|
17
|
-
actions: (_toArray = toArray(toActionObjects(getActions({
|
|
18
|
-
context: state.context,
|
|
19
|
-
event: _event.data
|
|
20
|
-
})))) !== null && _toArray !== void 0 ? _toArray : []
|
|
21
|
-
}
|
|
22
|
-
}];
|
|
23
|
-
});
|
|
24
|
-
}
|
|
1
|
+
import { m as mapValues, t as toActionObjects, a as toArray, f as formatTransitions, b as toTransitionConfigArray, N as NULL_EVENT, c as formatTransition, d as memo, e as evaluateGuard, g as flatten, h as createInvokeId, i as isString, j as invoke, k as getDelayedTransitions, l as formatInitialTransition, n as getCandidates, o as toInvokeConfig, p as createSpawner, S as STATE_DELIMITER, q as getConfiguration, r as getStateNodes, s as resolveStateValue, u as isInFinalState, v as State, w as isErrorEvent, x as macrostep, y as transitionNode, z as getInitialConfiguration, A as createInitEvent, B as resolveActionsAndContext, C as microstep, D as error, E as isStateId, F as getStateNodeByPath, G as getPersistedState, H as resolveReferencedActor, I as interpret, J as initEvent, K as matchesState } from './actions-b82e841e.esm.js';
|
|
2
|
+
export { a9 as ActionTypes, P as Interpreter, Q as InterpreterStatus, aa as SpecialTargets, v as State, a7 as and, T as assign, U as cancel, V as choose, R as doneInvoke, O as forwardTo, a2 as fromCallback, a3 as fromEventObservable, a1 as fromObservable, a0 as fromPromise, a4 as fromTransition, r as getStateNodes, I as interpret, W as log, K as matchesState, a6 as not, a8 as or, _ as pathToStateValue, X as pure, Y as raise, M as sendParent, L as sendTo, a5 as stateIn, Z as stop, $ as toObserver } from './actions-b82e841e.esm.js';
|
|
3
|
+
import '../dev/dist/xstate-dev.esm.js';
|
|
25
4
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
var StateNode = /*#__PURE__*/function () {
|
|
5
|
+
const EMPTY_OBJECT = {};
|
|
6
|
+
class StateNode {
|
|
29
7
|
/**
|
|
30
8
|
* The relative key of the state node, which represents its location in the overall state value.
|
|
31
9
|
*/
|
|
@@ -84,53 +62,51 @@ var StateNode = /*#__PURE__*/function () {
|
|
|
84
62
|
*/
|
|
85
63
|
|
|
86
64
|
/**
|
|
87
|
-
* The order this state node appears. Corresponds to the implicit
|
|
65
|
+
* The order this state node appears. Corresponds to the implicit document order.
|
|
88
66
|
*/
|
|
89
67
|
|
|
90
|
-
|
|
68
|
+
constructor(
|
|
91
69
|
/**
|
|
92
70
|
* The raw config used to create the machine.
|
|
93
71
|
*/
|
|
94
72
|
config, options) {
|
|
95
|
-
var _this = this;
|
|
96
|
-
_classCallCheck(this, StateNode);
|
|
97
73
|
this.config = config;
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
74
|
+
this.key = void 0;
|
|
75
|
+
this.id = void 0;
|
|
76
|
+
this.type = void 0;
|
|
77
|
+
this.path = void 0;
|
|
78
|
+
this.states = void 0;
|
|
79
|
+
this.history = void 0;
|
|
80
|
+
this.entry = void 0;
|
|
81
|
+
this.exit = void 0;
|
|
82
|
+
this.parent = void 0;
|
|
83
|
+
this.machine = void 0;
|
|
84
|
+
this.meta = void 0;
|
|
85
|
+
this.output = void 0;
|
|
86
|
+
this.order = -1;
|
|
87
|
+
this.description = void 0;
|
|
88
|
+
this.tags = [];
|
|
89
|
+
this.transitions = void 0;
|
|
90
|
+
this.always = void 0;
|
|
115
91
|
this.parent = options._parent;
|
|
116
92
|
this.key = options._key;
|
|
117
93
|
this.machine = options._machine;
|
|
118
94
|
this.path = this.parent ? this.parent.path.concat(this.key) : [];
|
|
119
|
-
this.id = this.config.id || [this.machine.id
|
|
95
|
+
this.id = this.config.id || [this.machine.id, ...this.path].join(this.machine.delimiter);
|
|
120
96
|
this.type = this.config.type || (this.config.states && Object.keys(this.config.states).length ? 'compound' : this.config.history ? 'history' : 'atomic');
|
|
121
97
|
this.description = this.config.description;
|
|
122
98
|
this.order = this.machine.idMap.size;
|
|
123
99
|
this.machine.idMap.set(this.id, this);
|
|
124
|
-
this.states = this.config.states ? mapValues(this.config.states,
|
|
125
|
-
|
|
126
|
-
_parent:
|
|
100
|
+
this.states = this.config.states ? mapValues(this.config.states, (stateConfig, key) => {
|
|
101
|
+
const stateNode = new StateNode(stateConfig, {
|
|
102
|
+
_parent: this,
|
|
127
103
|
_key: key,
|
|
128
|
-
_machine:
|
|
104
|
+
_machine: this.machine
|
|
129
105
|
});
|
|
130
106
|
return stateNode;
|
|
131
107
|
}) : EMPTY_OBJECT;
|
|
132
108
|
if (this.type === 'compound' && !this.config.initial) {
|
|
133
|
-
throw new Error(
|
|
109
|
+
throw new Error(`No initial state specified for compound state node "#${this.id}". Try adding { initial: "${Object.keys(this.states)[0]}" } to the state config.`);
|
|
134
110
|
}
|
|
135
111
|
|
|
136
112
|
// History config
|
|
@@ -141,273 +117,204 @@ var StateNode = /*#__PURE__*/function () {
|
|
|
141
117
|
this.output = this.type === 'final' ? this.config.output : undefined;
|
|
142
118
|
this.tags = toArray(config.tags);
|
|
143
119
|
}
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
this.transitions = formatTransitions(this);
|
|
149
|
-
if (this.config.always) {
|
|
150
|
-
this.always = toTransitionConfigArray(NULL_EVENT, this.config.always).map(function (t) {
|
|
151
|
-
return formatTransition(_this2, t);
|
|
152
|
-
});
|
|
153
|
-
}
|
|
154
|
-
Object.keys(this.states).forEach(function (key) {
|
|
155
|
-
_this2.states[key]._initialize();
|
|
156
|
-
});
|
|
120
|
+
_initialize() {
|
|
121
|
+
this.transitions = formatTransitions(this);
|
|
122
|
+
if (this.config.always) {
|
|
123
|
+
this.always = toTransitionConfigArray(NULL_EVENT, this.config.always).map(t => formatTransition(this, t));
|
|
157
124
|
}
|
|
125
|
+
Object.keys(this.states).forEach(key => {
|
|
126
|
+
this.states[key]._initialize();
|
|
127
|
+
});
|
|
128
|
+
}
|
|
158
129
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
130
|
+
/**
|
|
131
|
+
* The well-structured state node definition.
|
|
132
|
+
*/
|
|
133
|
+
get definition() {
|
|
134
|
+
return {
|
|
135
|
+
id: this.id,
|
|
136
|
+
key: this.key,
|
|
137
|
+
version: this.machine.version,
|
|
138
|
+
type: this.type,
|
|
139
|
+
initial: this.initial ? {
|
|
140
|
+
target: this.initial.target,
|
|
141
|
+
source: this,
|
|
142
|
+
actions: this.initial.actions,
|
|
143
|
+
eventType: null,
|
|
144
|
+
reenter: false,
|
|
145
|
+
toJSON: () => ({
|
|
146
|
+
target: this.initial.target.map(t => `#${t.id}`),
|
|
147
|
+
source: `#${this.id}`,
|
|
174
148
|
actions: this.initial.actions,
|
|
175
|
-
eventType: null
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
order: this.order || -1,
|
|
198
|
-
output: this.output,
|
|
199
|
-
invoke: this.invoke,
|
|
200
|
-
description: this.description,
|
|
201
|
-
tags: this.tags
|
|
202
|
-
};
|
|
203
|
-
}
|
|
204
|
-
}, {
|
|
205
|
-
key: "toJSON",
|
|
206
|
-
value: function toJSON() {
|
|
207
|
-
return this.definition;
|
|
208
|
-
}
|
|
149
|
+
eventType: null
|
|
150
|
+
})
|
|
151
|
+
} : undefined,
|
|
152
|
+
history: this.history,
|
|
153
|
+
states: mapValues(this.states, state => {
|
|
154
|
+
return state.definition;
|
|
155
|
+
}),
|
|
156
|
+
on: this.on,
|
|
157
|
+
transitions: this.transitions,
|
|
158
|
+
entry: this.entry,
|
|
159
|
+
exit: this.exit,
|
|
160
|
+
meta: this.meta,
|
|
161
|
+
order: this.order || -1,
|
|
162
|
+
output: this.output,
|
|
163
|
+
invoke: this.invoke,
|
|
164
|
+
description: this.description,
|
|
165
|
+
tags: this.tags
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
toJSON() {
|
|
169
|
+
return this.definition;
|
|
170
|
+
}
|
|
209
171
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
172
|
+
/**
|
|
173
|
+
* The behaviors invoked as actors by this state node.
|
|
174
|
+
*/
|
|
175
|
+
get invoke() {
|
|
176
|
+
return memo(this, 'invoke', () => toArray(this.config.invoke).map((invocable, i) => {
|
|
177
|
+
const generatedId = createInvokeId(this.id, i);
|
|
178
|
+
const invokeConfig = toInvokeConfig(invocable, generatedId);
|
|
179
|
+
const resolvedId = invokeConfig.id || generatedId;
|
|
180
|
+
const {
|
|
181
|
+
src,
|
|
182
|
+
systemId
|
|
183
|
+
} = invokeConfig;
|
|
184
|
+
const resolvedSrc = isString(src) ? src : !('type' in src) ? resolvedId : src;
|
|
185
|
+
if (!this.machine.options.actors[resolvedId] && typeof src !== 'string' && !('type' in src)) {
|
|
186
|
+
this.machine.options.actors = {
|
|
187
|
+
...this.machine.options.actors,
|
|
188
|
+
// TODO: this should accept `src` as-is
|
|
189
|
+
[resolvedId]: src
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
return {
|
|
193
|
+
type: invoke,
|
|
194
|
+
...invokeConfig,
|
|
195
|
+
src: resolvedSrc,
|
|
196
|
+
id: resolvedId,
|
|
197
|
+
systemId: systemId,
|
|
198
|
+
toJSON() {
|
|
199
|
+
const {
|
|
200
|
+
onDone,
|
|
201
|
+
onError,
|
|
202
|
+
...invokeDefValues
|
|
203
|
+
} = invokeConfig;
|
|
204
|
+
return {
|
|
205
|
+
...invokeDefValues,
|
|
206
|
+
type: invoke,
|
|
231
207
|
src: resolvedSrc,
|
|
232
|
-
id: resolvedId
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
return _objectSpread2(_objectSpread2({}, invokeDefValues), {}, {
|
|
239
|
-
type: invoke,
|
|
240
|
-
src: resolvedSrc,
|
|
241
|
-
id: resolvedId
|
|
242
|
-
});
|
|
243
|
-
}
|
|
244
|
-
});
|
|
245
|
-
});
|
|
246
|
-
});
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
/**
|
|
250
|
-
* The mapping of events to transitions.
|
|
251
|
-
*/
|
|
252
|
-
}, {
|
|
253
|
-
key: "on",
|
|
254
|
-
get: function get() {
|
|
255
|
-
var _this5 = this;
|
|
256
|
-
return memo(this, 'on', function () {
|
|
257
|
-
var transitions = _this5.transitions;
|
|
258
|
-
return transitions.reduce(function (map, transition) {
|
|
259
|
-
map[transition.eventType] = map[transition.eventType] || [];
|
|
260
|
-
map[transition.eventType].push(transition);
|
|
261
|
-
return map;
|
|
262
|
-
}, {});
|
|
263
|
-
});
|
|
264
|
-
}
|
|
265
|
-
}, {
|
|
266
|
-
key: "after",
|
|
267
|
-
get: function get() {
|
|
268
|
-
var _this6 = this;
|
|
269
|
-
return memo(this, 'delayedTransitions', function () {
|
|
270
|
-
return getDelayedTransitions(_this6);
|
|
271
|
-
});
|
|
272
|
-
}
|
|
273
|
-
}, {
|
|
274
|
-
key: "initial",
|
|
275
|
-
get: function get() {
|
|
276
|
-
var _this7 = this;
|
|
277
|
-
return memo(this, 'initial', function () {
|
|
278
|
-
return formatInitialTransition(_this7, _this7.config.initial || []);
|
|
279
|
-
});
|
|
280
|
-
}
|
|
208
|
+
id: resolvedId
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
};
|
|
212
|
+
}));
|
|
213
|
+
}
|
|
281
214
|
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
215
|
+
/**
|
|
216
|
+
* The mapping of events to transitions.
|
|
217
|
+
*/
|
|
218
|
+
get on() {
|
|
219
|
+
return memo(this, 'on', () => {
|
|
220
|
+
const transitions = this.transitions;
|
|
221
|
+
return transitions.reduce((map, transition) => {
|
|
222
|
+
map[transition.eventType] = map[transition.eventType] || [];
|
|
223
|
+
map[transition.eventType].push(transition);
|
|
224
|
+
return map;
|
|
225
|
+
}, {});
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
get after() {
|
|
229
|
+
return memo(this, 'delayedTransitions', () => getDelayedTransitions(this));
|
|
230
|
+
}
|
|
231
|
+
get initial() {
|
|
232
|
+
return memo(this, 'initial', () => formatInitialTransition(this, this.config.initial || []));
|
|
233
|
+
}
|
|
234
|
+
next(state, event) {
|
|
235
|
+
const eventType = event.type;
|
|
236
|
+
const actions = [];
|
|
237
|
+
let selectedTransition;
|
|
238
|
+
const candidates = memo(this, `candidates-${eventType}`, () => getCandidates(this, eventType));
|
|
239
|
+
for (const candidate of candidates) {
|
|
240
|
+
const {
|
|
241
|
+
guard
|
|
242
|
+
} = candidate;
|
|
243
|
+
const resolvedContext = state.context;
|
|
244
|
+
let guardPassed = false;
|
|
305
245
|
try {
|
|
306
|
-
|
|
307
|
-
var candidate = _step.value;
|
|
308
|
-
var guard = candidate.guard;
|
|
309
|
-
var resolvedContext = state.context;
|
|
310
|
-
var guardPassed = false;
|
|
311
|
-
try {
|
|
312
|
-
guardPassed = !guard || evaluateGuard(guard, resolvedContext, _event, state);
|
|
313
|
-
} catch (err) {
|
|
314
|
-
throw new Error("Unable to evaluate guard '".concat(guard.type, "' in transition for event '").concat(eventName, "' in state node '").concat(this.id, "':\n").concat(err.message));
|
|
315
|
-
}
|
|
316
|
-
if (guardPassed) {
|
|
317
|
-
actions.push.apply(actions, _toConsumableArray(candidate.actions));
|
|
318
|
-
selectedTransition = candidate;
|
|
319
|
-
break;
|
|
320
|
-
}
|
|
321
|
-
}
|
|
246
|
+
guardPassed = !guard || evaluateGuard(guard, resolvedContext, event, state);
|
|
322
247
|
} catch (err) {
|
|
323
|
-
|
|
324
|
-
} finally {
|
|
325
|
-
_iterator.f();
|
|
248
|
+
throw new Error(`Unable to evaluate guard '${guard.type}' in transition for event '${eventType}' in state node '${this.id}':\n${err.message}`);
|
|
326
249
|
}
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
* The target state value of the history state node, if it exists. This represents the
|
|
332
|
-
* default state value to transition to if no history value exists yet.
|
|
333
|
-
*/
|
|
334
|
-
}, {
|
|
335
|
-
key: "target",
|
|
336
|
-
get: function get() {
|
|
337
|
-
if (this.type === 'history') {
|
|
338
|
-
var historyConfig = this.config;
|
|
339
|
-
return historyConfig.target;
|
|
250
|
+
if (guardPassed) {
|
|
251
|
+
actions.push(...candidate.actions);
|
|
252
|
+
selectedTransition = candidate;
|
|
253
|
+
break;
|
|
340
254
|
}
|
|
341
|
-
return undefined;
|
|
342
255
|
}
|
|
256
|
+
return selectedTransition ? [selectedTransition] : undefined;
|
|
257
|
+
}
|
|
343
258
|
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
return _this9.states[stateKey].stateIds;
|
|
353
|
-
}));
|
|
354
|
-
return [this.id].concat(childStateIds);
|
|
259
|
+
/**
|
|
260
|
+
* The target state value of the history state node, if it exists. This represents the
|
|
261
|
+
* default state value to transition to if no history value exists yet.
|
|
262
|
+
*/
|
|
263
|
+
get target() {
|
|
264
|
+
if (this.type === 'history') {
|
|
265
|
+
const historyConfig = this.config;
|
|
266
|
+
return historyConfig.target;
|
|
355
267
|
}
|
|
268
|
+
return undefined;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* All the state node IDs of this state node and its descendant state nodes.
|
|
273
|
+
*/
|
|
274
|
+
get stateIds() {
|
|
275
|
+
const childStateIds = flatten(Object.keys(this.states).map(stateKey => {
|
|
276
|
+
return this.states[stateKey].stateIds;
|
|
277
|
+
}));
|
|
278
|
+
return [this.id].concat(childStateIds);
|
|
279
|
+
}
|
|
356
280
|
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
var _iterator2 = _createForOfIteratorHelper(state.events),
|
|
373
|
-
_step2;
|
|
374
|
-
try {
|
|
375
|
-
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
376
|
-
var event = _step2.value;
|
|
377
|
-
events.add("".concat(event));
|
|
378
|
-
}
|
|
379
|
-
} catch (err) {
|
|
380
|
-
_iterator2.e(err);
|
|
381
|
-
} finally {
|
|
382
|
-
_iterator2.f();
|
|
383
|
-
}
|
|
281
|
+
/**
|
|
282
|
+
* All the event types accepted by this state node and its descendants.
|
|
283
|
+
*/
|
|
284
|
+
get events() {
|
|
285
|
+
return memo(this, 'events', () => {
|
|
286
|
+
const {
|
|
287
|
+
states
|
|
288
|
+
} = this;
|
|
289
|
+
const events = new Set(this.ownEvents);
|
|
290
|
+
if (states) {
|
|
291
|
+
for (const stateId of Object.keys(states)) {
|
|
292
|
+
const state = states[stateId];
|
|
293
|
+
if (state.states) {
|
|
294
|
+
for (const event of state.events) {
|
|
295
|
+
events.add(`${event}`);
|
|
384
296
|
}
|
|
385
297
|
}
|
|
386
298
|
}
|
|
387
|
-
|
|
388
|
-
});
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
/**
|
|
392
|
-
* All the events that have transitions directly from this state node.
|
|
393
|
-
*
|
|
394
|
-
* Excludes any inert events.
|
|
395
|
-
*/
|
|
396
|
-
}, {
|
|
397
|
-
key: "ownEvents",
|
|
398
|
-
get: function get() {
|
|
399
|
-
var events = new Set(this.transitions.filter(function (transition) {
|
|
400
|
-
return !(!transition.target && !transition.actions.length && !transition.external);
|
|
401
|
-
}).map(function (transition) {
|
|
402
|
-
return transition.eventType;
|
|
403
|
-
}));
|
|
299
|
+
}
|
|
404
300
|
return Array.from(events);
|
|
405
|
-
}
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
/**
|
|
305
|
+
* All the events that have transitions directly from this state node.
|
|
306
|
+
*
|
|
307
|
+
* Excludes any inert events.
|
|
308
|
+
*/
|
|
309
|
+
get ownEvents() {
|
|
310
|
+
const events = new Set(this.transitions.filter(transition => {
|
|
311
|
+
return !(!transition.target && !transition.actions.length && !transition.reenter);
|
|
312
|
+
}).map(transition => transition.eventType));
|
|
313
|
+
return Array.from(events);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
409
316
|
|
|
410
|
-
|
|
317
|
+
const STATE_IDENTIFIER = '#';
|
|
411
318
|
function createDefaultOptions() {
|
|
412
319
|
return {
|
|
413
320
|
actions: {},
|
|
@@ -417,35 +324,54 @@ function createDefaultOptions() {
|
|
|
417
324
|
context: {}
|
|
418
325
|
};
|
|
419
326
|
}
|
|
420
|
-
|
|
421
|
-
|
|
327
|
+
class StateMachine {
|
|
328
|
+
// TODO: this getter should be removed
|
|
329
|
+
getContext(input) {
|
|
330
|
+
return this.getContextAndActions(undefined, input)[0];
|
|
331
|
+
}
|
|
332
|
+
getContextAndActions(actorCtx, input) {
|
|
333
|
+
const actions = [];
|
|
334
|
+
const {
|
|
335
|
+
context
|
|
336
|
+
} = this.config;
|
|
337
|
+
const resolvedContext = typeof context === 'function' ? context({
|
|
338
|
+
spawn: createSpawner(actorCtx?.self, this, undefined,
|
|
339
|
+
// TODO: this requires `| undefined` for all referenced dynamic inputs that are spawnable in the context factory,
|
|
340
|
+
createInitEvent(input), actions),
|
|
341
|
+
input
|
|
342
|
+
}) : context;
|
|
343
|
+
return [resolvedContext || {}, actions];
|
|
344
|
+
}
|
|
345
|
+
/**
|
|
346
|
+
* The machine's own version.
|
|
347
|
+
*/
|
|
348
|
+
|
|
349
|
+
constructor(
|
|
422
350
|
/**
|
|
423
351
|
* The raw config used to create the machine.
|
|
424
352
|
*/
|
|
425
353
|
config, options) {
|
|
426
|
-
var _this$config$schema;
|
|
427
|
-
_classCallCheck(this, StateMachine);
|
|
428
354
|
this.config = config;
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
355
|
+
this.version = void 0;
|
|
356
|
+
this.delimiter = void 0;
|
|
357
|
+
this.options = void 0;
|
|
358
|
+
this.types = void 0;
|
|
359
|
+
this.__xstatenode = true;
|
|
360
|
+
this.idMap = new Map();
|
|
361
|
+
this.root = void 0;
|
|
362
|
+
this.id = void 0;
|
|
363
|
+
this.states = void 0;
|
|
364
|
+
this.events = void 0;
|
|
365
|
+
this.__TContext = void 0;
|
|
366
|
+
this.__TEvent = void 0;
|
|
367
|
+
this.__TAction = void 0;
|
|
368
|
+
this.__TActorMap = void 0;
|
|
369
|
+
this.__TResolvedTypesMeta = void 0;
|
|
444
370
|
this.id = config.id || '(machine)';
|
|
445
371
|
this.options = Object.assign(createDefaultOptions(), options);
|
|
446
372
|
this.delimiter = this.config.delimiter || STATE_DELIMITER;
|
|
447
373
|
this.version = this.config.version;
|
|
448
|
-
this.
|
|
374
|
+
this.types = this.config.types ?? {};
|
|
449
375
|
this.transition = this.transition.bind(this);
|
|
450
376
|
this.root = new StateNode(config, {
|
|
451
377
|
_key: this.id,
|
|
@@ -465,311 +391,252 @@ var StateMachine = /*#__PURE__*/function () {
|
|
|
465
391
|
*
|
|
466
392
|
* @returns A new `StateMachine` instance with the provided implementations.
|
|
467
393
|
*/
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
}
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
var _this$options = this.options,
|
|
495
|
-
actions = _this$options.actions,
|
|
496
|
-
guards = _this$options.guards,
|
|
497
|
-
actors = _this$options.actors,
|
|
498
|
-
delays = _this$options.delays;
|
|
499
|
-
return new StateMachine(this.config, {
|
|
500
|
-
actions: _objectSpread2(_objectSpread2({}, actions), implementations.actions),
|
|
501
|
-
guards: _objectSpread2(_objectSpread2({}, guards), implementations.guards),
|
|
502
|
-
actors: _objectSpread2(_objectSpread2({}, actors), implementations.actors),
|
|
503
|
-
delays: _objectSpread2(_objectSpread2({}, delays), implementations.delays)
|
|
504
|
-
});
|
|
505
|
-
}
|
|
394
|
+
provide(implementations) {
|
|
395
|
+
const {
|
|
396
|
+
actions,
|
|
397
|
+
guards,
|
|
398
|
+
actors,
|
|
399
|
+
delays
|
|
400
|
+
} = this.options;
|
|
401
|
+
return new StateMachine(this.config, {
|
|
402
|
+
actions: {
|
|
403
|
+
...actions,
|
|
404
|
+
...implementations.actions
|
|
405
|
+
},
|
|
406
|
+
guards: {
|
|
407
|
+
...guards,
|
|
408
|
+
...implementations.guards
|
|
409
|
+
},
|
|
410
|
+
actors: {
|
|
411
|
+
...actors,
|
|
412
|
+
...implementations.actors
|
|
413
|
+
},
|
|
414
|
+
delays: {
|
|
415
|
+
...delays,
|
|
416
|
+
...implementations.delays
|
|
417
|
+
}
|
|
418
|
+
});
|
|
419
|
+
}
|
|
506
420
|
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
var resolvedContext = this.getContext();
|
|
530
|
-
return this.resolveState(State.from(resolvedStateValue, resolvedContext, this));
|
|
531
|
-
}
|
|
421
|
+
/**
|
|
422
|
+
* Resolves the given `state` to a new `State` instance relative to this machine.
|
|
423
|
+
*
|
|
424
|
+
* This ensures that `.nextEvents` represent the correct values.
|
|
425
|
+
*
|
|
426
|
+
* @param state The state to resolve
|
|
427
|
+
*/
|
|
428
|
+
resolveState(state) {
|
|
429
|
+
const configurationSet = getConfiguration(getStateNodes(this.root, state.value));
|
|
430
|
+
const configuration = Array.from(configurationSet);
|
|
431
|
+
return this.createState({
|
|
432
|
+
...state,
|
|
433
|
+
value: resolveStateValue(this.root, state.value),
|
|
434
|
+
configuration,
|
|
435
|
+
done: isInFinalState(configuration)
|
|
436
|
+
});
|
|
437
|
+
}
|
|
438
|
+
resolveStateValue(stateValue) {
|
|
439
|
+
const resolvedStateValue = resolveStateValue(this.root, stateValue);
|
|
440
|
+
const resolvedContext = this.getContext();
|
|
441
|
+
return this.resolveState(State.from(resolvedStateValue, resolvedContext, this));
|
|
442
|
+
}
|
|
532
443
|
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
})) {
|
|
552
|
-
throw scxmlEvent.data.data;
|
|
553
|
-
}
|
|
554
|
-
var _macrostep = macrostep(currentState, scxmlEvent, actorCtx),
|
|
555
|
-
nextState = _macrostep.state;
|
|
556
|
-
return nextState;
|
|
557
|
-
}
|
|
444
|
+
/**
|
|
445
|
+
* Determines the next state given the current `state` and received `event`.
|
|
446
|
+
* Calculates a full macrostep from all microsteps.
|
|
447
|
+
*
|
|
448
|
+
* @param state The current State instance or state value
|
|
449
|
+
* @param event The received event
|
|
450
|
+
*/
|
|
451
|
+
transition(state = this.initialState, event, actorCtx) {
|
|
452
|
+
const currentState = state instanceof State ? state : this.resolveStateValue(state);
|
|
453
|
+
// TODO: handle error events in a better way
|
|
454
|
+
if (isErrorEvent(event) && !currentState.nextEvents.some(nextEvent => nextEvent === event.type)) {
|
|
455
|
+
throw event.data;
|
|
456
|
+
}
|
|
457
|
+
const {
|
|
458
|
+
state: nextState
|
|
459
|
+
} = macrostep(currentState, event, actorCtx);
|
|
460
|
+
return nextState;
|
|
461
|
+
}
|
|
558
462
|
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
var scxmlEvent = toSCXMLEvent(event);
|
|
573
|
-
var _macrostep2 = macrostep(state, scxmlEvent, actorCtx),
|
|
574
|
-
microstates = _macrostep2.microstates;
|
|
575
|
-
return microstates;
|
|
576
|
-
}
|
|
577
|
-
}, {
|
|
578
|
-
key: "getTransitionData",
|
|
579
|
-
value: function getTransitionData(state, _event) {
|
|
580
|
-
return transitionNode(this.root, state.value, state, _event) || [];
|
|
581
|
-
}
|
|
463
|
+
/**
|
|
464
|
+
* Determines the next state given the current `state` and `event`.
|
|
465
|
+
* Calculates a microstep.
|
|
466
|
+
*
|
|
467
|
+
* @param state The current state
|
|
468
|
+
* @param event The received event
|
|
469
|
+
*/
|
|
470
|
+
microstep(state = this.initialState, event, actorCtx) {
|
|
471
|
+
return macrostep(state, event, actorCtx).microstates;
|
|
472
|
+
}
|
|
473
|
+
getTransitionData(state, event) {
|
|
474
|
+
return transitionNode(this.root, state.value, state, event) || [];
|
|
475
|
+
}
|
|
582
476
|
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
})
|
|
607
|
-
preInitial.
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
preInitial.children = nextState.children;
|
|
613
|
-
preInitial.actions = nextState.actions;
|
|
614
|
-
}
|
|
615
|
-
return preInitial;
|
|
616
|
-
}
|
|
477
|
+
/**
|
|
478
|
+
* The initial state _before_ evaluating any microsteps.
|
|
479
|
+
* This "pre-initial" state is provided to initial actions executed in the initial state.
|
|
480
|
+
*/
|
|
481
|
+
getPreInitialState(actorCtx, input) {
|
|
482
|
+
const [context, actions] = this.getContextAndActions(actorCtx, input);
|
|
483
|
+
const config = getInitialConfiguration(this.root);
|
|
484
|
+
const preInitial = this.resolveState(this.createState({
|
|
485
|
+
value: {},
|
|
486
|
+
// TODO: this is computed in state constructor
|
|
487
|
+
context,
|
|
488
|
+
event: createInitEvent({}),
|
|
489
|
+
actions: [],
|
|
490
|
+
meta: undefined,
|
|
491
|
+
configuration: config,
|
|
492
|
+
transitions: [],
|
|
493
|
+
children: {}
|
|
494
|
+
}));
|
|
495
|
+
preInitial._initial = true;
|
|
496
|
+
preInitial.actions.unshift(...actions);
|
|
497
|
+
if (actorCtx) {
|
|
498
|
+
const {
|
|
499
|
+
nextState
|
|
500
|
+
} = resolveActionsAndContext(actions, initEvent, preInitial, actorCtx);
|
|
501
|
+
preInitial.children = nextState.children;
|
|
502
|
+
preInitial.actions = nextState.actions;
|
|
503
|
+
}
|
|
504
|
+
return preInitial;
|
|
505
|
+
}
|
|
617
506
|
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
return this.getInitialState();
|
|
626
|
-
}
|
|
507
|
+
/**
|
|
508
|
+
* The initial State instance, which includes all actions to be executed from
|
|
509
|
+
* entering the initial state.
|
|
510
|
+
*/
|
|
511
|
+
get initialState() {
|
|
512
|
+
return this.getInitialState();
|
|
513
|
+
}
|
|
627
514
|
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
try {
|
|
654
|
-
var _child$start;
|
|
655
|
-
(_child$start = child.start) === null || _child$start === void 0 ? void 0 : _child$start.call(child);
|
|
656
|
-
} catch (err) {
|
|
657
|
-
// TODO: unify error handling when child starts
|
|
658
|
-
actorCtx.self.send(error(child.id, err));
|
|
659
|
-
}
|
|
515
|
+
/**
|
|
516
|
+
* Returns the initial `State` instance, with reference to `self` as an `ActorRef`.
|
|
517
|
+
*/
|
|
518
|
+
getInitialState(actorCtx, input) {
|
|
519
|
+
const initEvent = createInitEvent(input); // TODO: fix;
|
|
520
|
+
|
|
521
|
+
const preInitialState = this.getPreInitialState(actorCtx, input);
|
|
522
|
+
const nextState = microstep([], preInitialState, actorCtx, initEvent);
|
|
523
|
+
nextState.actions.unshift(...preInitialState.actions);
|
|
524
|
+
const {
|
|
525
|
+
state: macroState
|
|
526
|
+
} = macrostep(nextState, initEvent, actorCtx);
|
|
527
|
+
return macroState;
|
|
528
|
+
}
|
|
529
|
+
start(state, actorCtx) {
|
|
530
|
+
state.actions.forEach(action => {
|
|
531
|
+
action.execute?.(actorCtx);
|
|
532
|
+
});
|
|
533
|
+
Object.values(state.children).forEach(child => {
|
|
534
|
+
if (child.status === 0) {
|
|
535
|
+
try {
|
|
536
|
+
child.start?.();
|
|
537
|
+
} catch (err) {
|
|
538
|
+
// TODO: unify error handling when child starts
|
|
539
|
+
actorCtx.self.send(error(child.id, err));
|
|
660
540
|
}
|
|
661
|
-
});
|
|
662
|
-
}
|
|
663
|
-
}, {
|
|
664
|
-
key: "getStateNodeById",
|
|
665
|
-
value: function getStateNodeById(stateId) {
|
|
666
|
-
var fullPath = stateId.split(this.delimiter);
|
|
667
|
-
var relativePath = fullPath.slice(1);
|
|
668
|
-
var resolvedStateId = isStateId(fullPath[0]) ? fullPath[0].slice(STATE_IDENTIFIER.length) : fullPath[0];
|
|
669
|
-
var stateNode = this.idMap.get(resolvedStateId);
|
|
670
|
-
if (!stateNode) {
|
|
671
|
-
throw new Error("Child state node '#".concat(resolvedStateId, "' does not exist on machine '").concat(this.id, "'"));
|
|
672
541
|
}
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
id: actorId,
|
|
727
|
-
state: actorState
|
|
728
|
-
});
|
|
729
|
-
children[actorId] = actorRef;
|
|
730
|
-
});
|
|
731
|
-
var restoredState = this.createState(new State(_objectSpread2(_objectSpread2({}, state), {}, {
|
|
732
|
-
children: children
|
|
733
|
-
}), this));
|
|
734
|
-
|
|
735
|
-
// TODO: DRY this up
|
|
736
|
-
restoredState.configuration.forEach(function (stateNode) {
|
|
737
|
-
if (stateNode.invoke) {
|
|
738
|
-
stateNode.invoke.forEach(function (invokeConfig) {
|
|
739
|
-
var id = invokeConfig.id,
|
|
740
|
-
src = invokeConfig.src;
|
|
741
|
-
if (children[id]) {
|
|
742
|
-
return;
|
|
743
|
-
}
|
|
744
|
-
var referenced = resolveReferencedActor(_this.options.actors[src]);
|
|
745
|
-
if (referenced) {
|
|
746
|
-
var actorRef = interpret(referenced.src, {
|
|
747
|
-
id: id,
|
|
748
|
-
parent: _actorCtx === null || _actorCtx === void 0 ? void 0 : _actorCtx.self,
|
|
749
|
-
input: 'input' in invokeConfig ? invokeConfig.input : referenced.input
|
|
750
|
-
});
|
|
751
|
-
children[id] = actorRef;
|
|
752
|
-
}
|
|
753
|
-
});
|
|
754
|
-
}
|
|
542
|
+
});
|
|
543
|
+
}
|
|
544
|
+
getStateNodeById(stateId) {
|
|
545
|
+
const fullPath = stateId.split(this.delimiter);
|
|
546
|
+
const relativePath = fullPath.slice(1);
|
|
547
|
+
const resolvedStateId = isStateId(fullPath[0]) ? fullPath[0].slice(STATE_IDENTIFIER.length) : fullPath[0];
|
|
548
|
+
const stateNode = this.idMap.get(resolvedStateId);
|
|
549
|
+
if (!stateNode) {
|
|
550
|
+
throw new Error(`Child state node '#${resolvedStateId}' does not exist on machine '${this.id}'`);
|
|
551
|
+
}
|
|
552
|
+
return getStateNodeByPath(stateNode, relativePath);
|
|
553
|
+
}
|
|
554
|
+
get definition() {
|
|
555
|
+
return {
|
|
556
|
+
context: this.getContext(),
|
|
557
|
+
...this.root.definition
|
|
558
|
+
};
|
|
559
|
+
}
|
|
560
|
+
toJSON() {
|
|
561
|
+
return this.definition;
|
|
562
|
+
}
|
|
563
|
+
getPersistedState(state) {
|
|
564
|
+
return getPersistedState(state);
|
|
565
|
+
}
|
|
566
|
+
createState(stateConfig) {
|
|
567
|
+
const state = stateConfig instanceof State ? stateConfig : new State(stateConfig, this);
|
|
568
|
+
const {
|
|
569
|
+
nextState: resolvedState
|
|
570
|
+
} = resolveActionsAndContext(state.actions, state.event, state, undefined);
|
|
571
|
+
return resolvedState;
|
|
572
|
+
}
|
|
573
|
+
getStatus(state) {
|
|
574
|
+
return state.done ? {
|
|
575
|
+
status: 'done',
|
|
576
|
+
data: state.output
|
|
577
|
+
} : {
|
|
578
|
+
status: 'active'
|
|
579
|
+
};
|
|
580
|
+
}
|
|
581
|
+
restoreState(state, _actorCtx) {
|
|
582
|
+
const children = {};
|
|
583
|
+
Object.keys(state.children).forEach(actorId => {
|
|
584
|
+
const actorData = state.children[actorId];
|
|
585
|
+
const childState = actorData.state;
|
|
586
|
+
const src = actorData.src;
|
|
587
|
+
const behavior = src ? resolveReferencedActor(this.options.actors[src])?.src : undefined;
|
|
588
|
+
if (!behavior) {
|
|
589
|
+
return;
|
|
590
|
+
}
|
|
591
|
+
const actorState = behavior.restoreState?.(childState, _actorCtx);
|
|
592
|
+
const actorRef = interpret(behavior, {
|
|
593
|
+
id: actorId,
|
|
594
|
+
state: actorState
|
|
755
595
|
});
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
596
|
+
children[actorId] = actorRef;
|
|
597
|
+
});
|
|
598
|
+
const restoredState = this.createState(new State({
|
|
599
|
+
...state,
|
|
600
|
+
children
|
|
601
|
+
}, this));
|
|
602
|
+
|
|
603
|
+
// TODO: DRY this up
|
|
604
|
+
restoredState.configuration.forEach(stateNode => {
|
|
605
|
+
if (stateNode.invoke) {
|
|
606
|
+
stateNode.invoke.forEach(invokeConfig => {
|
|
607
|
+
const {
|
|
608
|
+
id,
|
|
609
|
+
src
|
|
610
|
+
} = invokeConfig;
|
|
611
|
+
if (children[id]) {
|
|
612
|
+
return;
|
|
613
|
+
}
|
|
614
|
+
const referenced = resolveReferencedActor(this.options.actors[src]);
|
|
615
|
+
if (referenced) {
|
|
616
|
+
const actorRef = interpret(referenced.src, {
|
|
617
|
+
id,
|
|
618
|
+
parent: _actorCtx?.self,
|
|
619
|
+
input: 'input' in invokeConfig ? invokeConfig.input : referenced.input
|
|
620
|
+
});
|
|
621
|
+
children[id] = actorRef;
|
|
622
|
+
}
|
|
623
|
+
});
|
|
624
|
+
}
|
|
625
|
+
});
|
|
626
|
+
restoredState.actions = [];
|
|
627
|
+
return restoredState;
|
|
628
|
+
}
|
|
759
629
|
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
return StateMachine;
|
|
763
|
-
}();
|
|
630
|
+
/**@deprecated an internal property acting as a "phantom" type, not meant to be used at runtime */
|
|
631
|
+
}
|
|
764
632
|
|
|
765
633
|
function createMachine(config, implementations) {
|
|
766
634
|
return new StateMachine(config, implementations);
|
|
767
635
|
}
|
|
768
636
|
|
|
769
637
|
function mapState(stateMap, stateId) {
|
|
770
|
-
|
|
771
|
-
for (
|
|
772
|
-
var mappedStateId = _Object$keys[_i];
|
|
638
|
+
let foundStateId;
|
|
639
|
+
for (const mappedStateId of Object.keys(stateMap)) {
|
|
773
640
|
if (matchesState(mappedStateId, stateId) && (!foundStateId || stateId.length > foundStateId.length)) {
|
|
774
641
|
foundStateId = mappedStateId;
|
|
775
642
|
}
|
|
@@ -777,103 +644,124 @@ function mapState(stateMap, stateId) {
|
|
|
777
644
|
return stateMap[foundStateId];
|
|
778
645
|
}
|
|
779
646
|
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
}
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
start: this.now(),
|
|
808
|
-
timeout: timeout,
|
|
809
|
-
fn: fn
|
|
810
|
-
});
|
|
811
|
-
return id;
|
|
812
|
-
}
|
|
813
|
-
}, {
|
|
814
|
-
key: "clearTimeout",
|
|
815
|
-
value: function clearTimeout(id) {
|
|
816
|
-
this.timeouts["delete"](id);
|
|
647
|
+
class SimulatedClock {
|
|
648
|
+
constructor() {
|
|
649
|
+
this.timeouts = new Map();
|
|
650
|
+
this._now = 0;
|
|
651
|
+
this._id = 0;
|
|
652
|
+
}
|
|
653
|
+
now() {
|
|
654
|
+
return this._now;
|
|
655
|
+
}
|
|
656
|
+
getId() {
|
|
657
|
+
return this._id++;
|
|
658
|
+
}
|
|
659
|
+
setTimeout(fn, timeout) {
|
|
660
|
+
const id = this.getId();
|
|
661
|
+
this.timeouts.set(id, {
|
|
662
|
+
start: this.now(),
|
|
663
|
+
timeout,
|
|
664
|
+
fn
|
|
665
|
+
});
|
|
666
|
+
return id;
|
|
667
|
+
}
|
|
668
|
+
clearTimeout(id) {
|
|
669
|
+
this.timeouts.delete(id);
|
|
670
|
+
}
|
|
671
|
+
set(time) {
|
|
672
|
+
if (this._now > time) {
|
|
673
|
+
throw new Error('Unable to travel back in time');
|
|
817
674
|
}
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
675
|
+
this._now = time;
|
|
676
|
+
this.flushTimeouts();
|
|
677
|
+
}
|
|
678
|
+
flushTimeouts() {
|
|
679
|
+
[...this.timeouts].sort(([_idA, timeoutA], [_idB, timeoutB]) => {
|
|
680
|
+
const endA = timeoutA.start + timeoutA.timeout;
|
|
681
|
+
const endB = timeoutB.start + timeoutB.timeout;
|
|
682
|
+
return endB > endA ? -1 : 1;
|
|
683
|
+
}).forEach(([id, timeout]) => {
|
|
684
|
+
if (this.now() - timeout.start >= timeout.timeout) {
|
|
685
|
+
this.timeouts.delete(id);
|
|
686
|
+
timeout.fn.call(null);
|
|
687
|
+
}
|
|
688
|
+
});
|
|
689
|
+
}
|
|
690
|
+
increment(ms) {
|
|
691
|
+
this._now += ms;
|
|
692
|
+
this.flushTimeouts();
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
const defaultWaitForOptions = {
|
|
697
|
+
timeout: 10_000 // 10 seconds
|
|
698
|
+
};
|
|
699
|
+
|
|
700
|
+
/**
|
|
701
|
+
* Subscribes to an actor ref and waits for its emitted value to satisfy
|
|
702
|
+
* a predicate, and then resolves with that value.
|
|
703
|
+
* Will throw if the desired state is not reached after a timeout
|
|
704
|
+
* (defaults to 10 seconds).
|
|
705
|
+
*
|
|
706
|
+
* @example
|
|
707
|
+
* ```js
|
|
708
|
+
* const state = await waitFor(someService, state => {
|
|
709
|
+
* return state.hasTag('loaded');
|
|
710
|
+
* });
|
|
711
|
+
*
|
|
712
|
+
* state.hasTag('loaded'); // true
|
|
713
|
+
* ```
|
|
714
|
+
*
|
|
715
|
+
* @param actorRef The actor ref to subscribe to
|
|
716
|
+
* @param predicate Determines if a value matches the condition to wait for
|
|
717
|
+
* @param options
|
|
718
|
+
* @returns A promise that eventually resolves to the emitted value
|
|
719
|
+
* that matches the condition
|
|
720
|
+
*/
|
|
721
|
+
function waitFor(actorRef, predicate, options) {
|
|
722
|
+
const resolvedOptions = {
|
|
723
|
+
...defaultWaitForOptions,
|
|
724
|
+
...options
|
|
725
|
+
};
|
|
726
|
+
return new Promise((res, rej) => {
|
|
727
|
+
let done = false;
|
|
728
|
+
const handle = resolvedOptions.timeout === Infinity ? undefined : setTimeout(() => {
|
|
729
|
+
sub.unsubscribe();
|
|
730
|
+
rej(new Error(`Timeout of ${resolvedOptions.timeout} ms exceeded`));
|
|
731
|
+
}, resolvedOptions.timeout);
|
|
732
|
+
const dispose = () => {
|
|
733
|
+
clearTimeout(handle);
|
|
734
|
+
done = true;
|
|
735
|
+
sub?.unsubscribe();
|
|
736
|
+
};
|
|
737
|
+
function checkEmitted(emitted) {
|
|
738
|
+
if (predicate(emitted)) {
|
|
739
|
+
dispose();
|
|
740
|
+
res(emitted);
|
|
823
741
|
}
|
|
824
|
-
this._now = time;
|
|
825
|
-
this.flushTimeouts();
|
|
826
|
-
}
|
|
827
|
-
}, {
|
|
828
|
-
key: "flushTimeouts",
|
|
829
|
-
value: function flushTimeouts() {
|
|
830
|
-
var _this = this;
|
|
831
|
-
_toConsumableArray(this.timeouts).sort(function (_ref, _ref2) {
|
|
832
|
-
var _ref3 = _slicedToArray(_ref, 2),
|
|
833
|
-
_idA = _ref3[0],
|
|
834
|
-
timeoutA = _ref3[1];
|
|
835
|
-
var _ref4 = _slicedToArray(_ref2, 2),
|
|
836
|
-
_idB = _ref4[0],
|
|
837
|
-
timeoutB = _ref4[1];
|
|
838
|
-
var endA = timeoutA.start + timeoutA.timeout;
|
|
839
|
-
var endB = timeoutB.start + timeoutB.timeout;
|
|
840
|
-
return endB > endA ? -1 : 1;
|
|
841
|
-
}).forEach(function (_ref5) {
|
|
842
|
-
var _ref6 = _slicedToArray(_ref5, 2),
|
|
843
|
-
id = _ref6[0],
|
|
844
|
-
timeout = _ref6[1];
|
|
845
|
-
if (_this.now() - timeout.start >= timeout.timeout) {
|
|
846
|
-
_this.timeouts["delete"](id);
|
|
847
|
-
timeout.fn.call(null);
|
|
848
|
-
}
|
|
849
|
-
});
|
|
850
742
|
}
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
743
|
+
let sub; // avoid TDZ when disposing synchronously
|
|
744
|
+
|
|
745
|
+
// See if the current snapshot already matches the predicate
|
|
746
|
+
checkEmitted(actorRef.getSnapshot());
|
|
747
|
+
if (done) {
|
|
748
|
+
return;
|
|
749
|
+
}
|
|
750
|
+
sub = actorRef.subscribe({
|
|
751
|
+
next: checkEmitted,
|
|
752
|
+
error: err => {
|
|
753
|
+
dispose();
|
|
754
|
+
rej(err);
|
|
755
|
+
},
|
|
756
|
+
complete: () => {
|
|
757
|
+
dispose();
|
|
758
|
+
rej(new Error(`Actor terminated without satisfying predicate`));
|
|
759
|
+
}
|
|
760
|
+
});
|
|
761
|
+
if (done) {
|
|
762
|
+
sub.unsubscribe();
|
|
856
763
|
}
|
|
857
|
-
}
|
|
858
|
-
|
|
859
|
-
}();
|
|
860
|
-
|
|
861
|
-
var actions = {
|
|
862
|
-
raise: raise,
|
|
863
|
-
send: send,
|
|
864
|
-
sendParent: sendParent,
|
|
865
|
-
sendTo: sendTo,
|
|
866
|
-
log: log,
|
|
867
|
-
cancel: cancel,
|
|
868
|
-
stop: stop,
|
|
869
|
-
assign: assign,
|
|
870
|
-
after: after,
|
|
871
|
-
done: done,
|
|
872
|
-
respond: respond,
|
|
873
|
-
forwardTo: forwardTo,
|
|
874
|
-
escalate: escalate,
|
|
875
|
-
choose: choose,
|
|
876
|
-
pure: pure
|
|
877
|
-
};
|
|
764
|
+
});
|
|
765
|
+
}
|
|
878
766
|
|
|
879
|
-
export { SimulatedClock, StateMachine, StateNode,
|
|
767
|
+
export { SimulatedClock, StateMachine, StateNode, createMachine, mapState, waitFor };
|