xstate 5.0.0-beta.10 → 5.0.0-beta.12
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 +29 -5
- package/actions/dist/{xstate-actions.cjs.dev.js → xstate-actions.development.cjs.js} +2 -2
- 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.js +20 -5
- package/actors/dist/{xstate-actors.cjs.dev.js → xstate-actors.development.cjs.js} +2 -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.js +45 -4
- package/{dist/index-0f3fdf0c.cjs.prod.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-b34f6ce7.esm.js +3292 -0
- package/dist/actions-c8b9504d.development.esm.js +3327 -0
- package/dist/actions-d9c19f35.development.cjs.js +3409 -0
- package/dist/actions-e4c704f3.cjs.js +3374 -0
- package/dist/declarations/src/interpreter.d.ts +1 -6
- package/dist/declarations/src/types.d.ts +1 -0
- package/dist/declarations/src/utils.d.ts +0 -1
- package/dist/declarations/src/waitFor.d.ts +1 -1
- package/dist/xstate.cjs.js +802 -4
- package/dist/xstate.development.cjs.js +808 -0
- package/dist/xstate.development.esm.js +770 -0
- package/dist/xstate.esm.js +543 -662
- package/dist/xstate.umd.min.js +1 -1
- package/dist/xstate.umd.min.js.map +1 -1
- package/guards/dist/xstate-guards.cjs.js +13 -5
- package/guards/dist/{xstate-guards.cjs.prod.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 +52 -1
- package/actions/dist/xstate-actions.cjs.prod.js +0 -31
- package/actors/dist/xstate-actors.cjs.prod.js +0 -22
- package/dev/dist/xstate-dev.cjs.dev.js +0 -11
- package/dev/dist/xstate-dev.cjs.prod.js +0 -11
- package/dist/actions-109712d3.cjs.dev.js +0 -4357
- package/dist/actions-67f1d04e.esm.js +0 -4270
- package/dist/actions-d0262a43.cjs.prod.js +0 -4333
- 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/spawn.d.ts +0 -2
- package/dist/declarations/src/system.d.ts +0 -2
- package/dist/index-ebaab3c9.cjs.dev.js +0 -52
- package/dist/xstate.cjs.dev.js +0 -933
- package/dist/xstate.cjs.prod.js +0 -930
- package/guards/dist/xstate-guards.cjs.dev.js +0 -15
package/dist/xstate.esm.js
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export {
|
|
3
|
-
import '
|
|
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-b34f6ce7.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-b34f6ce7.esm.js';
|
|
3
|
+
import '../dev/dist/xstate-dev.esm.js';
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
var StateNode = /*#__PURE__*/function () {
|
|
5
|
+
const EMPTY_OBJECT = {};
|
|
6
|
+
class StateNode {
|
|
8
7
|
/**
|
|
9
8
|
* The relative key of the state node, which represents its location in the overall state value.
|
|
10
9
|
*/
|
|
@@ -66,50 +65,48 @@ var StateNode = /*#__PURE__*/function () {
|
|
|
66
65
|
* The order this state node appears. Corresponds to the implicit document order.
|
|
67
66
|
*/
|
|
68
67
|
|
|
69
|
-
|
|
68
|
+
constructor(
|
|
70
69
|
/**
|
|
71
70
|
* The raw config used to create the machine.
|
|
72
71
|
*/
|
|
73
72
|
config, options) {
|
|
74
|
-
var _this = this;
|
|
75
|
-
_classCallCheck(this, StateNode);
|
|
76
73
|
this.config = config;
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
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;
|
|
94
91
|
this.parent = options._parent;
|
|
95
92
|
this.key = options._key;
|
|
96
93
|
this.machine = options._machine;
|
|
97
94
|
this.path = this.parent ? this.parent.path.concat(this.key) : [];
|
|
98
|
-
this.id = this.config.id || [this.machine.id
|
|
95
|
+
this.id = this.config.id || [this.machine.id, ...this.path].join(this.machine.delimiter);
|
|
99
96
|
this.type = this.config.type || (this.config.states && Object.keys(this.config.states).length ? 'compound' : this.config.history ? 'history' : 'atomic');
|
|
100
97
|
this.description = this.config.description;
|
|
101
98
|
this.order = this.machine.idMap.size;
|
|
102
99
|
this.machine.idMap.set(this.id, this);
|
|
103
|
-
this.states = this.config.states ? mapValues(this.config.states,
|
|
104
|
-
|
|
105
|
-
_parent:
|
|
100
|
+
this.states = this.config.states ? mapValues(this.config.states, (stateConfig, key) => {
|
|
101
|
+
const stateNode = new StateNode(stateConfig, {
|
|
102
|
+
_parent: this,
|
|
106
103
|
_key: key,
|
|
107
|
-
_machine:
|
|
104
|
+
_machine: this.machine
|
|
108
105
|
});
|
|
109
106
|
return stateNode;
|
|
110
107
|
}) : EMPTY_OBJECT;
|
|
111
108
|
if (this.type === 'compound' && !this.config.initial) {
|
|
112
|
-
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.`);
|
|
113
110
|
}
|
|
114
111
|
|
|
115
112
|
// History config
|
|
@@ -120,261 +117,204 @@ var StateNode = /*#__PURE__*/function () {
|
|
|
120
117
|
this.output = this.type === 'final' ? this.config.output : undefined;
|
|
121
118
|
this.tags = toArray(config.tags);
|
|
122
119
|
}
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
this.transitions = formatTransitions(this);
|
|
128
|
-
if (this.config.always) {
|
|
129
|
-
this.always = toTransitionConfigArray(NULL_EVENT, this.config.always).map(function (t) {
|
|
130
|
-
return formatTransition(_this2, t);
|
|
131
|
-
});
|
|
132
|
-
}
|
|
133
|
-
Object.keys(this.states).forEach(function (key) {
|
|
134
|
-
_this2.states[key]._initialize();
|
|
135
|
-
});
|
|
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));
|
|
136
124
|
}
|
|
125
|
+
Object.keys(this.states).forEach(key => {
|
|
126
|
+
this.states[key]._initialize();
|
|
127
|
+
});
|
|
128
|
+
}
|
|
137
129
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
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}`,
|
|
153
148
|
actions: this.initial.actions,
|
|
154
|
-
eventType: null
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
order: this.order || -1,
|
|
177
|
-
output: this.output,
|
|
178
|
-
invoke: this.invoke,
|
|
179
|
-
description: this.description,
|
|
180
|
-
tags: this.tags
|
|
181
|
-
};
|
|
182
|
-
}
|
|
183
|
-
}, {
|
|
184
|
-
key: "toJSON",
|
|
185
|
-
value: function toJSON() {
|
|
186
|
-
return this.definition;
|
|
187
|
-
}
|
|
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
|
+
}
|
|
188
171
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
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,
|
|
210
207
|
src: resolvedSrc,
|
|
211
|
-
id: resolvedId
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
return _objectSpread2(_objectSpread2({}, invokeDefValues), {}, {
|
|
218
|
-
type: invoke,
|
|
219
|
-
src: resolvedSrc,
|
|
220
|
-
id: resolvedId
|
|
221
|
-
});
|
|
222
|
-
}
|
|
223
|
-
});
|
|
224
|
-
});
|
|
225
|
-
});
|
|
226
|
-
}
|
|
208
|
+
id: resolvedId
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
};
|
|
212
|
+
}));
|
|
213
|
+
}
|
|
227
214
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
return
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
});
|
|
259
|
-
}
|
|
260
|
-
}, {
|
|
261
|
-
key: "next",
|
|
262
|
-
value: function next(state, event) {
|
|
263
|
-
var _this8 = this;
|
|
264
|
-
var eventType = event.type;
|
|
265
|
-
var actions = [];
|
|
266
|
-
var selectedTransition;
|
|
267
|
-
var candidates = memo(this, "candidates-".concat(eventType), function () {
|
|
268
|
-
return getCandidates(_this8, eventType);
|
|
269
|
-
});
|
|
270
|
-
var _iterator = _createForOfIteratorHelper(candidates),
|
|
271
|
-
_step;
|
|
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;
|
|
272
245
|
try {
|
|
273
|
-
|
|
274
|
-
var candidate = _step.value;
|
|
275
|
-
var guard = candidate.guard;
|
|
276
|
-
var resolvedContext = state.context;
|
|
277
|
-
var guardPassed = false;
|
|
278
|
-
try {
|
|
279
|
-
guardPassed = !guard || evaluateGuard(guard, resolvedContext, event, state);
|
|
280
|
-
} catch (err) {
|
|
281
|
-
throw new Error("Unable to evaluate guard '".concat(guard.type, "' in transition for event '").concat(eventType, "' in state node '").concat(this.id, "':\n").concat(err.message));
|
|
282
|
-
}
|
|
283
|
-
if (guardPassed) {
|
|
284
|
-
actions.push.apply(actions, _toConsumableArray(candidate.actions));
|
|
285
|
-
selectedTransition = candidate;
|
|
286
|
-
break;
|
|
287
|
-
}
|
|
288
|
-
}
|
|
246
|
+
guardPassed = !guard || evaluateGuard(guard, resolvedContext, event, state);
|
|
289
247
|
} catch (err) {
|
|
290
|
-
|
|
291
|
-
} finally {
|
|
292
|
-
_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}`);
|
|
293
249
|
}
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
* The target state value of the history state node, if it exists. This represents the
|
|
299
|
-
* default state value to transition to if no history value exists yet.
|
|
300
|
-
*/
|
|
301
|
-
}, {
|
|
302
|
-
key: "target",
|
|
303
|
-
get: function get() {
|
|
304
|
-
if (this.type === 'history') {
|
|
305
|
-
var historyConfig = this.config;
|
|
306
|
-
return historyConfig.target;
|
|
250
|
+
if (guardPassed) {
|
|
251
|
+
actions.push(...candidate.actions);
|
|
252
|
+
selectedTransition = candidate;
|
|
253
|
+
break;
|
|
307
254
|
}
|
|
308
|
-
return undefined;
|
|
309
255
|
}
|
|
256
|
+
return selectedTransition ? [selectedTransition] : undefined;
|
|
257
|
+
}
|
|
310
258
|
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
return _this9.states[stateKey].stateIds;
|
|
320
|
-
}));
|
|
321
|
-
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;
|
|
322
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
|
+
}
|
|
323
280
|
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
var _iterator2 = _createForOfIteratorHelper(state.events),
|
|
340
|
-
_step2;
|
|
341
|
-
try {
|
|
342
|
-
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
343
|
-
var event = _step2.value;
|
|
344
|
-
events.add("".concat(event));
|
|
345
|
-
}
|
|
346
|
-
} catch (err) {
|
|
347
|
-
_iterator2.e(err);
|
|
348
|
-
} finally {
|
|
349
|
-
_iterator2.f();
|
|
350
|
-
}
|
|
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}`);
|
|
351
296
|
}
|
|
352
297
|
}
|
|
353
298
|
}
|
|
354
|
-
|
|
355
|
-
});
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
/**
|
|
359
|
-
* All the events that have transitions directly from this state node.
|
|
360
|
-
*
|
|
361
|
-
* Excludes any inert events.
|
|
362
|
-
*/
|
|
363
|
-
}, {
|
|
364
|
-
key: "ownEvents",
|
|
365
|
-
get: function get() {
|
|
366
|
-
var events = new Set(this.transitions.filter(function (transition) {
|
|
367
|
-
return !(!transition.target && !transition.actions.length && !transition.reenter);
|
|
368
|
-
}).map(function (transition) {
|
|
369
|
-
return transition.eventType;
|
|
370
|
-
}));
|
|
299
|
+
}
|
|
371
300
|
return Array.from(events);
|
|
372
|
-
}
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
|
|
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
|
+
}
|
|
376
316
|
|
|
377
|
-
|
|
317
|
+
const STATE_IDENTIFIER = '#';
|
|
378
318
|
function createDefaultOptions() {
|
|
379
319
|
return {
|
|
380
320
|
actions: {},
|
|
@@ -384,35 +324,54 @@ function createDefaultOptions() {
|
|
|
384
324
|
context: {}
|
|
385
325
|
};
|
|
386
326
|
}
|
|
387
|
-
|
|
388
|
-
|
|
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(
|
|
389
350
|
/**
|
|
390
351
|
* The raw config used to create the machine.
|
|
391
352
|
*/
|
|
392
353
|
config, options) {
|
|
393
|
-
var _this$config$types;
|
|
394
|
-
_classCallCheck(this, StateMachine);
|
|
395
354
|
this.config = config;
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
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;
|
|
411
370
|
this.id = config.id || '(machine)';
|
|
412
371
|
this.options = Object.assign(createDefaultOptions(), options);
|
|
413
372
|
this.delimiter = this.config.delimiter || STATE_DELIMITER;
|
|
414
373
|
this.version = this.config.version;
|
|
415
|
-
this.types =
|
|
374
|
+
this.types = this.config.types ?? {};
|
|
416
375
|
this.transition = this.transition.bind(this);
|
|
417
376
|
this.root = new StateNode(config, {
|
|
418
377
|
_key: this.id,
|
|
@@ -432,307 +391,252 @@ var StateMachine = /*#__PURE__*/function () {
|
|
|
432
391
|
*
|
|
433
392
|
* @returns A new `StateMachine` instance with the provided implementations.
|
|
434
393
|
*/
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
}
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
var _this$options = this.options,
|
|
462
|
-
actions = _this$options.actions,
|
|
463
|
-
guards = _this$options.guards,
|
|
464
|
-
actors = _this$options.actors,
|
|
465
|
-
delays = _this$options.delays;
|
|
466
|
-
return new StateMachine(this.config, {
|
|
467
|
-
actions: _objectSpread2(_objectSpread2({}, actions), implementations.actions),
|
|
468
|
-
guards: _objectSpread2(_objectSpread2({}, guards), implementations.guards),
|
|
469
|
-
actors: _objectSpread2(_objectSpread2({}, actors), implementations.actors),
|
|
470
|
-
delays: _objectSpread2(_objectSpread2({}, delays), implementations.delays)
|
|
471
|
-
});
|
|
472
|
-
}
|
|
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
|
+
}
|
|
473
420
|
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
var resolvedContext = this.getContext();
|
|
497
|
-
return this.resolveState(State.from(resolvedStateValue, resolvedContext, this));
|
|
498
|
-
}
|
|
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
|
+
}
|
|
499
443
|
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
throw event.data;
|
|
519
|
-
}
|
|
520
|
-
var _macrostep = macrostep(currentState, event, actorCtx),
|
|
521
|
-
nextState = _macrostep.state;
|
|
522
|
-
return nextState;
|
|
523
|
-
}
|
|
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
|
+
}
|
|
524
462
|
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
return macrostep(state, event, actorCtx).microstates;
|
|
539
|
-
}
|
|
540
|
-
}, {
|
|
541
|
-
key: "getTransitionData",
|
|
542
|
-
value: function getTransitionData(state, event) {
|
|
543
|
-
return transitionNode(this.root, state.value, state, event) || [];
|
|
544
|
-
}
|
|
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
|
+
}
|
|
545
476
|
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
})
|
|
570
|
-
preInitial.
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
preInitial.children = nextState.children;
|
|
576
|
-
preInitial.actions = nextState.actions;
|
|
577
|
-
}
|
|
578
|
-
return preInitial;
|
|
579
|
-
}
|
|
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
|
+
}
|
|
580
506
|
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
return this.getInitialState();
|
|
589
|
-
}
|
|
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
|
+
}
|
|
590
514
|
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
try {
|
|
617
|
-
var _child$start;
|
|
618
|
-
(_child$start = child.start) === null || _child$start === void 0 ? void 0 : _child$start.call(child);
|
|
619
|
-
} catch (err) {
|
|
620
|
-
// TODO: unify error handling when child starts
|
|
621
|
-
actorCtx.self.send(error(child.id, err));
|
|
622
|
-
}
|
|
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));
|
|
623
540
|
}
|
|
624
|
-
});
|
|
625
|
-
}
|
|
626
|
-
}, {
|
|
627
|
-
key: "getStateNodeById",
|
|
628
|
-
value: function getStateNodeById(stateId) {
|
|
629
|
-
var fullPath = stateId.split(this.delimiter);
|
|
630
|
-
var relativePath = fullPath.slice(1);
|
|
631
|
-
var resolvedStateId = isStateId(fullPath[0]) ? fullPath[0].slice(STATE_IDENTIFIER.length) : fullPath[0];
|
|
632
|
-
var stateNode = this.idMap.get(resolvedStateId);
|
|
633
|
-
if (!stateNode) {
|
|
634
|
-
throw new Error("Child state node '#".concat(resolvedStateId, "' does not exist on machine '").concat(this.id, "'"));
|
|
635
541
|
}
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
id: actorId,
|
|
690
|
-
state: actorState
|
|
691
|
-
});
|
|
692
|
-
children[actorId] = actorRef;
|
|
693
|
-
});
|
|
694
|
-
var restoredState = this.createState(new State(_objectSpread2(_objectSpread2({}, state), {}, {
|
|
695
|
-
children: children
|
|
696
|
-
}), this));
|
|
697
|
-
|
|
698
|
-
// TODO: DRY this up
|
|
699
|
-
restoredState.configuration.forEach(function (stateNode) {
|
|
700
|
-
if (stateNode.invoke) {
|
|
701
|
-
stateNode.invoke.forEach(function (invokeConfig) {
|
|
702
|
-
var id = invokeConfig.id,
|
|
703
|
-
src = invokeConfig.src;
|
|
704
|
-
if (children[id]) {
|
|
705
|
-
return;
|
|
706
|
-
}
|
|
707
|
-
var referenced = resolveReferencedActor(_this.options.actors[src]);
|
|
708
|
-
if (referenced) {
|
|
709
|
-
var actorRef = interpret(referenced.src, {
|
|
710
|
-
id: id,
|
|
711
|
-
parent: _actorCtx === null || _actorCtx === void 0 ? void 0 : _actorCtx.self,
|
|
712
|
-
input: 'input' in invokeConfig ? invokeConfig.input : referenced.input
|
|
713
|
-
});
|
|
714
|
-
children[id] = actorRef;
|
|
715
|
-
}
|
|
716
|
-
});
|
|
717
|
-
}
|
|
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
|
|
718
595
|
});
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
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
|
+
}
|
|
722
629
|
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
return StateMachine;
|
|
726
|
-
}();
|
|
630
|
+
/**@deprecated an internal property acting as a "phantom" type, not meant to be used at runtime */
|
|
631
|
+
}
|
|
727
632
|
|
|
728
633
|
function createMachine(config, implementations) {
|
|
729
634
|
return new StateMachine(config, implementations);
|
|
730
635
|
}
|
|
731
636
|
|
|
732
637
|
function mapState(stateMap, stateId) {
|
|
733
|
-
|
|
734
|
-
for (
|
|
735
|
-
var mappedStateId = _Object$keys[_i];
|
|
638
|
+
let foundStateId;
|
|
639
|
+
for (const mappedStateId of Object.keys(stateMap)) {
|
|
736
640
|
if (matchesState(mappedStateId, stateId) && (!foundStateId || stateId.length > foundStateId.length)) {
|
|
737
641
|
foundStateId = mappedStateId;
|
|
738
642
|
}
|
|
@@ -740,84 +644,57 @@ function mapState(stateMap, stateId) {
|
|
|
740
644
|
return stateMap[foundStateId];
|
|
741
645
|
}
|
|
742
646
|
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
}
|
|
771
|
-
}, {
|
|
772
|
-
key: "clearTimeout",
|
|
773
|
-
value: function clearTimeout(id) {
|
|
774
|
-
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');
|
|
775
674
|
}
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
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);
|
|
781
687
|
}
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
_toConsumableArray(this.timeouts).sort(function (_ref, _ref2) {
|
|
790
|
-
var _ref3 = _slicedToArray(_ref, 2);
|
|
791
|
-
_ref3[0];
|
|
792
|
-
var timeoutA = _ref3[1];
|
|
793
|
-
var _ref4 = _slicedToArray(_ref2, 2);
|
|
794
|
-
_ref4[0];
|
|
795
|
-
var timeoutB = _ref4[1];
|
|
796
|
-
var endA = timeoutA.start + timeoutA.timeout;
|
|
797
|
-
var endB = timeoutB.start + timeoutB.timeout;
|
|
798
|
-
return endB > endA ? -1 : 1;
|
|
799
|
-
}).forEach(function (_ref5) {
|
|
800
|
-
var _ref6 = _slicedToArray(_ref5, 2),
|
|
801
|
-
id = _ref6[0],
|
|
802
|
-
timeout = _ref6[1];
|
|
803
|
-
if (_this.now() - timeout.start >= timeout.timeout) {
|
|
804
|
-
_this.timeouts["delete"](id);
|
|
805
|
-
timeout.fn.call(null);
|
|
806
|
-
}
|
|
807
|
-
});
|
|
808
|
-
}
|
|
809
|
-
}, {
|
|
810
|
-
key: "increment",
|
|
811
|
-
value: function increment(ms) {
|
|
812
|
-
this._now += ms;
|
|
813
|
-
this.flushTimeouts();
|
|
814
|
-
}
|
|
815
|
-
}]);
|
|
816
|
-
return SimulatedClock;
|
|
817
|
-
}();
|
|
688
|
+
});
|
|
689
|
+
}
|
|
690
|
+
increment(ms) {
|
|
691
|
+
this._now += ms;
|
|
692
|
+
this.flushTimeouts();
|
|
693
|
+
}
|
|
694
|
+
}
|
|
818
695
|
|
|
819
|
-
|
|
820
|
-
timeout:
|
|
696
|
+
const defaultWaitForOptions = {
|
|
697
|
+
timeout: 10_000 // 10 seconds
|
|
821
698
|
};
|
|
822
699
|
|
|
823
700
|
/**
|
|
@@ -842,20 +719,20 @@ var defaultWaitForOptions = {
|
|
|
842
719
|
* that matches the condition
|
|
843
720
|
*/
|
|
844
721
|
function waitFor(actorRef, predicate, options) {
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
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(() => {
|
|
852
729
|
sub.unsubscribe();
|
|
853
|
-
rej(new Error(
|
|
730
|
+
rej(new Error(`Timeout of ${resolvedOptions.timeout} ms exceeded`));
|
|
854
731
|
}, resolvedOptions.timeout);
|
|
855
|
-
|
|
732
|
+
const dispose = () => {
|
|
856
733
|
clearTimeout(handle);
|
|
857
734
|
done = true;
|
|
858
|
-
sub
|
|
735
|
+
sub?.unsubscribe();
|
|
859
736
|
};
|
|
860
737
|
function checkEmitted(emitted) {
|
|
861
738
|
if (predicate(emitted)) {
|
|
@@ -863,18 +740,22 @@ function waitFor(actorRef, predicate, options) {
|
|
|
863
740
|
res(emitted);
|
|
864
741
|
}
|
|
865
742
|
}
|
|
743
|
+
let sub; // avoid TDZ when disposing synchronously
|
|
866
744
|
|
|
867
745
|
// See if the current snapshot already matches the predicate
|
|
868
746
|
checkEmitted(actorRef.getSnapshot());
|
|
869
|
-
|
|
747
|
+
if (done) {
|
|
748
|
+
return;
|
|
749
|
+
}
|
|
750
|
+
sub = actorRef.subscribe({
|
|
870
751
|
next: checkEmitted,
|
|
871
|
-
error:
|
|
752
|
+
error: err => {
|
|
872
753
|
dispose();
|
|
873
754
|
rej(err);
|
|
874
755
|
},
|
|
875
|
-
complete:
|
|
756
|
+
complete: () => {
|
|
876
757
|
dispose();
|
|
877
|
-
rej(new Error(
|
|
758
|
+
rej(new Error(`Actor terminated without satisfying predicate`));
|
|
878
759
|
}
|
|
879
760
|
});
|
|
880
761
|
if (done) {
|