xstate 6.0.0-alpha.48 → 6.0.0-alpha.49
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +23 -0
- package/dist/{StateMachine-b09d2b00.cjs.js → StateMachine-0adb3a70.cjs.js} +1 -1
- package/dist/{StateMachine-b3a890bf.development.cjs.js → StateMachine-29450e6d.development.cjs.js} +1 -1
- package/dist/{StateMachine-8329769a.esm.js → StateMachine-2af31c11.esm.js} +1 -1
- package/dist/{StateMachine-88b3c26a.development.esm.js → StateMachine-faf50c5c.development.esm.js} +1 -1
- package/dist/{createActor-27287c65.esm.js → createActor-268165d4.esm.js} +1 -1
- package/dist/{createActor-309d77eb.development.esm.js → createActor-88709f74.development.esm.js} +1 -1
- package/dist/{createActor-cc3d6dde.development.cjs.js → createActor-a1e0dffb.development.cjs.js} +0 -3
- package/dist/{createActor-9b41ade9.cjs.js → createActor-b4dd05ae.cjs.js} +0 -3
- package/dist/declarations/src/fsm/createFSMActor.d.ts +67 -0
- package/dist/declarations/src/fsm/index.d.ts +2 -0
- package/dist/declarations/src/fsm.d.ts +5 -4
- package/dist/{effectDescriptor-b1f5deb6.esm.js → effectDescriptor-30c9a744.esm.js} +1 -1
- package/dist/{effectDescriptor-7707794b.development.esm.js → effectDescriptor-39d22100.development.esm.js} +1 -1
- package/dist/{effectDescriptor-a1678d06.development.cjs.js → effectDescriptor-7ff6802f.development.cjs.js} +1 -1
- package/dist/{effectDescriptor-bd36a33e.cjs.js → effectDescriptor-be348e50.cjs.js} +1 -1
- package/dist/fsm-7a2e9697.cjs.js +777 -0
- package/dist/fsm-b804b3e9.esm.js +775 -0
- package/dist/fsm-c1316948.development.cjs.js +777 -0
- package/dist/fsm-e18a7cb4.development.esm.js +775 -0
- package/dist/{types-81d03bef.esm.js → types-3c3455f7.esm.js} +1 -1
- package/dist/{types-1793b8b6.development.esm.js → types-adda3842.development.esm.js} +1 -1
- package/dist/{types-7e468202.development.cjs.js → types-b3fea5bd.development.cjs.js} +1 -1
- package/dist/{types-9c1bc85f.cjs.js → types-fbabaeee.cjs.js} +1 -1
- package/dist/xstate-actors.cjs.js +1 -1
- package/dist/xstate-actors.development.cjs.js +1 -1
- package/dist/xstate-actors.development.esm.js +2 -2
- package/dist/xstate-actors.esm.js +2 -2
- package/dist/xstate-durable.cjs.js +2 -2
- package/dist/xstate-durable.development.cjs.js +2 -2
- package/dist/xstate-durable.development.esm.js +2 -2
- package/dist/xstate-durable.esm.js +2 -2
- package/dist/xstate-fsm.cjs.d.mts +2 -0
- package/dist/xstate-fsm.cjs.d.ts +2 -0
- package/dist/xstate-fsm.cjs.js +409 -0
- package/dist/xstate-fsm.cjs.mjs +5 -0
- package/dist/xstate-fsm.development.cjs.js +409 -0
- package/dist/xstate-fsm.development.cjs.mjs +5 -0
- package/dist/xstate-fsm.development.esm.js +403 -0
- package/dist/xstate-fsm.esm.js +403 -0
- package/dist/xstate-fsm.umd.min.js +2 -0
- package/dist/xstate-fsm.umd.min.js.map +1 -0
- package/dist/xstate-graph.cjs.js +2 -2
- package/dist/xstate-graph.development.cjs.js +2 -2
- package/dist/xstate-graph.development.esm.js +2 -2
- package/dist/xstate-graph.esm.js +2 -2
- package/dist/xstate-scxml.cjs.js +3 -3
- package/dist/xstate-scxml.development.cjs.js +3 -3
- package/dist/xstate-scxml.development.esm.js +3 -3
- package/dist/xstate-scxml.esm.js +3 -3
- package/dist/xstate-validation.cjs.js +1 -1
- package/dist/xstate-validation.development.cjs.js +1 -1
- package/dist/xstate-validation.development.esm.js +1 -1
- package/dist/xstate-validation.esm.js +1 -1
- package/dist/xstate.cjs.js +6 -380
- package/dist/xstate.development.cjs.js +6 -380
- package/dist/xstate.development.esm.js +10 -384
- package/dist/xstate.esm.js +10 -384
- package/dist/xstate.umd.min.js +1 -1
- package/dist/xstate.umd.min.js.map +1 -1
- package/fsm/package.json +8 -0
- package/package.json +18 -2
|
@@ -0,0 +1,403 @@
|
|
|
1
|
+
export { c as createFSM } from './fsm-b804b3e9.esm.js';
|
|
2
|
+
import './createActor-268165d4.esm.js';
|
|
3
|
+
|
|
4
|
+
var FSMActorStatus = /*#__PURE__*/function (FSMActorStatus) {
|
|
5
|
+
FSMActorStatus[FSMActorStatus["NotStarted"] = 0] = "NotStarted";
|
|
6
|
+
FSMActorStatus[FSMActorStatus["Running"] = 1] = "Running";
|
|
7
|
+
FSMActorStatus[FSMActorStatus["Stopped"] = 2] = "Stopped";
|
|
8
|
+
return FSMActorStatus;
|
|
9
|
+
}(FSMActorStatus || {});
|
|
10
|
+
let nextSessionId = 0;
|
|
11
|
+
function addressSegment(id) {
|
|
12
|
+
return id.replaceAll('%', '%25').replaceAll('/', '%2F');
|
|
13
|
+
}
|
|
14
|
+
const timerMaps = new WeakMap();
|
|
15
|
+
const registryMaps = new WeakMap();
|
|
16
|
+
class FSMSystem {
|
|
17
|
+
constructor(_clock) {
|
|
18
|
+
this._clock = _clock;
|
|
19
|
+
}
|
|
20
|
+
createActorRef(logic, options) {
|
|
21
|
+
return new FSMActor(logic, options);
|
|
22
|
+
}
|
|
23
|
+
spawnActor() {}
|
|
24
|
+
startActor(actor) {
|
|
25
|
+
actor.start();
|
|
26
|
+
}
|
|
27
|
+
stopActor(actor) {
|
|
28
|
+
actor._stop();
|
|
29
|
+
}
|
|
30
|
+
terminateActor(actor, termination) {
|
|
31
|
+
actor._terminate(termination);
|
|
32
|
+
}
|
|
33
|
+
emitEvent(source, event) {
|
|
34
|
+
source._emit(event);
|
|
35
|
+
}
|
|
36
|
+
sendEvent(_, target, event) {
|
|
37
|
+
target._send(event);
|
|
38
|
+
}
|
|
39
|
+
_relay(source, target, event) {
|
|
40
|
+
this.sendEvent(source, target, event);
|
|
41
|
+
}
|
|
42
|
+
scheduleTimer(source, id, delay) {
|
|
43
|
+
let actorTimers = timerMaps.get(source);
|
|
44
|
+
if (!actorTimers) {
|
|
45
|
+
actorTimers = new Map();
|
|
46
|
+
timerMaps.set(source, actorTimers);
|
|
47
|
+
}
|
|
48
|
+
actorTimers.set(id, this._clock.setTimeout(() => {
|
|
49
|
+
actorTimers.delete(id);
|
|
50
|
+
source._send({
|
|
51
|
+
type: 'xstate.timer',
|
|
52
|
+
id
|
|
53
|
+
});
|
|
54
|
+
}, delay));
|
|
55
|
+
}
|
|
56
|
+
cancelTimer(source, id) {
|
|
57
|
+
const actorTimers = timerMaps.get(source);
|
|
58
|
+
const timeout = actorTimers?.get(id);
|
|
59
|
+
if (timeout !== undefined) {
|
|
60
|
+
this._clock.clearTimeout(timeout);
|
|
61
|
+
actorTimers.delete(id);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
cancelAllTimers(source) {
|
|
65
|
+
const actorTimers = timerMaps.get(source);
|
|
66
|
+
for (const timeout of actorTimers?.values() ?? []) {
|
|
67
|
+
this._clock.clearTimeout(timeout);
|
|
68
|
+
}
|
|
69
|
+
actorTimers?.clear();
|
|
70
|
+
}
|
|
71
|
+
_set(key, actor) {
|
|
72
|
+
let registry = registryMaps.get(this);
|
|
73
|
+
if (!registry) {
|
|
74
|
+
registry = new Map();
|
|
75
|
+
registryMaps.set(this, registry);
|
|
76
|
+
}
|
|
77
|
+
registry.set(key, actor);
|
|
78
|
+
}
|
|
79
|
+
get(key) {
|
|
80
|
+
return registryMaps.get(this)?.get(key);
|
|
81
|
+
}
|
|
82
|
+
getAll() {
|
|
83
|
+
return Object.fromEntries(registryMaps.get(this) ?? []);
|
|
84
|
+
}
|
|
85
|
+
_unregister(actor) {
|
|
86
|
+
const registry = registryMaps.get(this);
|
|
87
|
+
for (const [key, value] of registry ?? []) {
|
|
88
|
+
if (value === actor) {
|
|
89
|
+
registry.delete(key);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/** A compact actor runtime for logic returned by `createFSM(...)`. */
|
|
96
|
+
class FSMActor {
|
|
97
|
+
constructor(logic, options = {}) {
|
|
98
|
+
this.logic = logic;
|
|
99
|
+
this.options = options;
|
|
100
|
+
this._snapshot = void 0;
|
|
101
|
+
this._effects = void 0;
|
|
102
|
+
this._queue = void 0;
|
|
103
|
+
this._processing = false;
|
|
104
|
+
this._observers = void 0;
|
|
105
|
+
this._listeners = void 0;
|
|
106
|
+
this._trigger = void 0;
|
|
107
|
+
this._restored = false;
|
|
108
|
+
this._processingStatus = FSMActorStatus.NotStarted;
|
|
109
|
+
this.id = void 0;
|
|
110
|
+
this.sessionId = void 0;
|
|
111
|
+
this.address = void 0;
|
|
112
|
+
this.ref = this;
|
|
113
|
+
this.src = void 0;
|
|
114
|
+
this.system = void 0;
|
|
115
|
+
this._parent = void 0;
|
|
116
|
+
this.id = options.id ?? logic.id ?? '(fsm)';
|
|
117
|
+
this.sessionId = options._sessionId ?? `fsm:${nextSessionId++}`;
|
|
118
|
+
this.src = options.src ?? logic;
|
|
119
|
+
this._parent = options.parent;
|
|
120
|
+
this.address = this._parent ? `${this._parent.address}/${addressSegment(this.id)}` : addressSegment(this.id);
|
|
121
|
+
this.system = this._parent?.system ?? new FSMSystem(options.clock ?? {
|
|
122
|
+
setTimeout,
|
|
123
|
+
clearTimeout
|
|
124
|
+
});
|
|
125
|
+
if (options.registryKey) {
|
|
126
|
+
this.system._set(options.registryKey, this);
|
|
127
|
+
}
|
|
128
|
+
const persisted = options.snapshot ?? options.state;
|
|
129
|
+
try {
|
|
130
|
+
if (persisted !== undefined) {
|
|
131
|
+
this._restored = true;
|
|
132
|
+
this._snapshot = logic.restoreSnapshot?.(persisted, this) ?? persisted;
|
|
133
|
+
this._effects = [];
|
|
134
|
+
} else {
|
|
135
|
+
[this._snapshot, this._effects] = logic.initialTransition(options.input, this);
|
|
136
|
+
}
|
|
137
|
+
} catch (error) {
|
|
138
|
+
this._snapshot = {
|
|
139
|
+
status: 'error',
|
|
140
|
+
output: undefined,
|
|
141
|
+
error
|
|
142
|
+
};
|
|
143
|
+
this._effects = [];
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
get self() {
|
|
147
|
+
return this;
|
|
148
|
+
}
|
|
149
|
+
get logger() {
|
|
150
|
+
return this.options.logger ?? console.log;
|
|
151
|
+
}
|
|
152
|
+
defer(fn) {
|
|
153
|
+
fn();
|
|
154
|
+
}
|
|
155
|
+
get emit() {
|
|
156
|
+
const emit = event => this.system.emitEvent(this, event);
|
|
157
|
+
Object.defineProperty(this, 'emit', {
|
|
158
|
+
value: emit
|
|
159
|
+
});
|
|
160
|
+
return emit;
|
|
161
|
+
}
|
|
162
|
+
stopChild(child) {
|
|
163
|
+
child._stop();
|
|
164
|
+
}
|
|
165
|
+
actionExecutor(effect) {
|
|
166
|
+
effect.exec();
|
|
167
|
+
}
|
|
168
|
+
start() {
|
|
169
|
+
if (this._processingStatus !== FSMActorStatus.NotStarted) {
|
|
170
|
+
return this;
|
|
171
|
+
}
|
|
172
|
+
this._processingStatus = FSMActorStatus.Running;
|
|
173
|
+
try {
|
|
174
|
+
this.runEffects(this._effects);
|
|
175
|
+
} catch (error) {
|
|
176
|
+
this.fail(error);
|
|
177
|
+
return this;
|
|
178
|
+
}
|
|
179
|
+
if (this._snapshot.status === 'error') {
|
|
180
|
+
this.fail(this._snapshot.error);
|
|
181
|
+
return this;
|
|
182
|
+
}
|
|
183
|
+
this._effects = [];
|
|
184
|
+
if (this._processingStatus === FSMActorStatus.Stopped) {
|
|
185
|
+
return this;
|
|
186
|
+
}
|
|
187
|
+
try {
|
|
188
|
+
this.logic.start?.(this._snapshot, this, {
|
|
189
|
+
restored: this._restored
|
|
190
|
+
});
|
|
191
|
+
} catch (error) {
|
|
192
|
+
this.fail(error);
|
|
193
|
+
return this;
|
|
194
|
+
}
|
|
195
|
+
if (this._restored) {
|
|
196
|
+
const timers = this._snapshot.timers ?? {};
|
|
197
|
+
for (const timer of Object.values(timers)) {
|
|
198
|
+
const delay = !this.system._clock.now && timer.startedAt !== undefined ? Math.min(timer.delay, Math.max(0, timer.startedAt + timer.delay - Date.now())) : timer.delay;
|
|
199
|
+
this.system.scheduleTimer(this, timer.id, delay);
|
|
200
|
+
}
|
|
201
|
+
this._restored = false;
|
|
202
|
+
}
|
|
203
|
+
this.notify();
|
|
204
|
+
this.flush();
|
|
205
|
+
return this;
|
|
206
|
+
}
|
|
207
|
+
send(event) {
|
|
208
|
+
if (this._processingStatus === FSMActorStatus.Stopped) {
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
(this._queue ??= []).push(event);
|
|
212
|
+
this.flush();
|
|
213
|
+
}
|
|
214
|
+
_send(event) {
|
|
215
|
+
this.send(event);
|
|
216
|
+
}
|
|
217
|
+
flush() {
|
|
218
|
+
if (this._processing || this._processingStatus !== FSMActorStatus.Running || !this._queue?.length) {
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
this._processing = true;
|
|
222
|
+
let event;
|
|
223
|
+
while (this._processingStatus === FSMActorStatus.Running && (event = this._queue?.shift())) {
|
|
224
|
+
try {
|
|
225
|
+
const [snapshot, effects] = this.logic.transition(this._snapshot, event, this);
|
|
226
|
+
this._snapshot = snapshot;
|
|
227
|
+
this.runEffects(effects);
|
|
228
|
+
if (this._snapshot.status === 'active') {
|
|
229
|
+
this.notify();
|
|
230
|
+
}
|
|
231
|
+
} catch (error) {
|
|
232
|
+
this.fail(error);
|
|
233
|
+
break;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
this._processing = false;
|
|
237
|
+
}
|
|
238
|
+
runEffects(effects) {
|
|
239
|
+
for (const effect of effects) {
|
|
240
|
+
effect.exec();
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
getSnapshot() {
|
|
244
|
+
return this._snapshot;
|
|
245
|
+
}
|
|
246
|
+
getPersistedSnapshot(options) {
|
|
247
|
+
return this.logic.getPersistedSnapshot(this._snapshot, options);
|
|
248
|
+
}
|
|
249
|
+
toJSON() {
|
|
250
|
+
return {
|
|
251
|
+
xstate$type: 'actorRef',
|
|
252
|
+
id: this.id,
|
|
253
|
+
address: this.address,
|
|
254
|
+
src: typeof this.src === 'string' ? this.src : undefined
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
_stop() {
|
|
258
|
+
if (this._processingStatus === FSMActorStatus.Stopped) {
|
|
259
|
+
return this;
|
|
260
|
+
}
|
|
261
|
+
if (this._processingStatus === FSMActorStatus.Running) {
|
|
262
|
+
const [snapshot, effects] = this.logic.transition(this._snapshot, {
|
|
263
|
+
type: '@xstate.stop'
|
|
264
|
+
}, this);
|
|
265
|
+
this._snapshot = snapshot;
|
|
266
|
+
this.runEffects(effects);
|
|
267
|
+
}
|
|
268
|
+
this._processingStatus = FSMActorStatus.Stopped;
|
|
269
|
+
this.system.cancelAllTimers(this);
|
|
270
|
+
this.system._unregister(this);
|
|
271
|
+
this._queue = undefined;
|
|
272
|
+
for (const observer of this._observers ?? []) {
|
|
273
|
+
observer.complete?.();
|
|
274
|
+
}
|
|
275
|
+
this._observers?.clear();
|
|
276
|
+
return this;
|
|
277
|
+
}
|
|
278
|
+
stop() {
|
|
279
|
+
if (this._parent) {
|
|
280
|
+
throw new Error('A non-root actor cannot be stopped directly.');
|
|
281
|
+
}
|
|
282
|
+
return this._stop();
|
|
283
|
+
}
|
|
284
|
+
subscribe(observerOrNext, error, complete) {
|
|
285
|
+
const observer = typeof observerOrNext === 'function' ? {
|
|
286
|
+
next: observerOrNext,
|
|
287
|
+
error,
|
|
288
|
+
complete
|
|
289
|
+
} : observerOrNext ?? {};
|
|
290
|
+
if (this._processingStatus === FSMActorStatus.Stopped) {
|
|
291
|
+
const snapshot = this._snapshot;
|
|
292
|
+
if (snapshot.status === 'done') {
|
|
293
|
+
observer.complete?.();
|
|
294
|
+
} else if (snapshot.status === 'error') {
|
|
295
|
+
observer.error?.(snapshot.error);
|
|
296
|
+
}
|
|
297
|
+
return {
|
|
298
|
+
unsubscribe() {}
|
|
299
|
+
};
|
|
300
|
+
}
|
|
301
|
+
(this._observers ??= new Set()).add(observer);
|
|
302
|
+
return {
|
|
303
|
+
unsubscribe: () => this._observers?.delete(observer)
|
|
304
|
+
};
|
|
305
|
+
}
|
|
306
|
+
on(type, handler) {
|
|
307
|
+
let listeners = this._listeners?.get(type);
|
|
308
|
+
if (!listeners) {
|
|
309
|
+
listeners = new Set();
|
|
310
|
+
(this._listeners ??= new Map()).set(type, listeners);
|
|
311
|
+
}
|
|
312
|
+
listeners.add(handler);
|
|
313
|
+
return {
|
|
314
|
+
unsubscribe: () => listeners.delete(handler)
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
_emit(event) {
|
|
318
|
+
for (const listeners of [this._listeners?.get(event.type), this._listeners?.get('*')]) {
|
|
319
|
+
for (const listener of listeners ?? []) {
|
|
320
|
+
listener(event);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
_terminate(termination) {
|
|
325
|
+
this.notify();
|
|
326
|
+
this._processingStatus = FSMActorStatus.Stopped;
|
|
327
|
+
this.system.cancelAllTimers(this);
|
|
328
|
+
this.system._unregister(this);
|
|
329
|
+
for (const observer of this._observers ?? []) {
|
|
330
|
+
if (termination.status === 'error') {
|
|
331
|
+
observer.error?.(termination.error);
|
|
332
|
+
} else {
|
|
333
|
+
observer.complete?.();
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
this._observers?.clear();
|
|
337
|
+
this._listeners?.clear();
|
|
338
|
+
}
|
|
339
|
+
fail(error) {
|
|
340
|
+
this._snapshot = {
|
|
341
|
+
...this._snapshot,
|
|
342
|
+
status: 'error',
|
|
343
|
+
output: undefined,
|
|
344
|
+
error
|
|
345
|
+
};
|
|
346
|
+
this._processingStatus = FSMActorStatus.Stopped;
|
|
347
|
+
this.system.cancelAllTimers(this);
|
|
348
|
+
this.system._unregister(this);
|
|
349
|
+
this._queue = undefined;
|
|
350
|
+
for (const observer of this._observers ?? []) {
|
|
351
|
+
observer.error?.(error);
|
|
352
|
+
}
|
|
353
|
+
this._observers?.clear();
|
|
354
|
+
this._listeners?.clear();
|
|
355
|
+
}
|
|
356
|
+
notify() {
|
|
357
|
+
for (const observer of this._observers ?? []) {
|
|
358
|
+
observer.next?.(this._snapshot);
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
_isRunning() {
|
|
362
|
+
return this._processingStatus === FSMActorStatus.Running;
|
|
363
|
+
}
|
|
364
|
+
_inspectTransition() {}
|
|
365
|
+
get trigger() {
|
|
366
|
+
return this._trigger ??= new Proxy({}, {
|
|
367
|
+
get: (_, type) => payload => this.send({
|
|
368
|
+
...payload,
|
|
369
|
+
type
|
|
370
|
+
})
|
|
371
|
+
});
|
|
372
|
+
}
|
|
373
|
+
select(selector, equal = Object.is) {
|
|
374
|
+
return {
|
|
375
|
+
get: () => selector(this._snapshot),
|
|
376
|
+
subscribe: observerOrNext => {
|
|
377
|
+
const observer = typeof observerOrNext === 'function' ? {
|
|
378
|
+
next: observerOrNext
|
|
379
|
+
} : observerOrNext;
|
|
380
|
+
let selected = selector(this._snapshot);
|
|
381
|
+
return this.subscribe({
|
|
382
|
+
next: snapshot => {
|
|
383
|
+
const next = selector(snapshot);
|
|
384
|
+
if (!equal(selected, next)) {
|
|
385
|
+
selected = next;
|
|
386
|
+
observer.next?.(next);
|
|
387
|
+
}
|
|
388
|
+
},
|
|
389
|
+
error: observer.error,
|
|
390
|
+
complete: observer.complete
|
|
391
|
+
});
|
|
392
|
+
}
|
|
393
|
+
};
|
|
394
|
+
}
|
|
395
|
+
[Symbol.observable]() {
|
|
396
|
+
return this;
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
function createFSMActor(logic, options) {
|
|
400
|
+
return new FSMActor(logic, options);
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
export { FSMActor, createFSMActor };
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).XStateFSM={})}(this,function(t){"use strict";var e=function(t){return t[t.NotStarted=0]="NotStarted",t[t.Running=1]="Running",t[t.Stopped=2]="Stopped",t}(e||{});let s=0;function n(t){return t.replaceAll("%","%25").replaceAll("/","%2F")}const r=new WeakMap,i=new WeakMap;class o{constructor(t){this._clock=t}createActorRef(t,e){return new c(t,e)}spawnActor(){}startActor(t){t.start()}stopActor(t){t._stop()}terminateActor(t,e){t._terminate(e)}emitEvent(t,e){t._emit(e)}sendEvent(t,e,s){e._send(s)}_relay(t,e,s){this.sendEvent(t,e,s)}scheduleTimer(t,e,s){let n=r.get(t);n||(n=new Map,r.set(t,n)),n.set(e,this._clock.setTimeout(()=>{n.delete(e),t._send({type:"xstate.timer",id:e})},s))}cancelTimer(t,e){const s=r.get(t),n=s?.get(e);void 0!==n&&(this._clock.clearTimeout(n),s.delete(e))}cancelAllTimers(t){const e=r.get(t);for(const t of e?.values()??[])this._clock.clearTimeout(t);e?.clear()}_set(t,e){let s=i.get(this);s||(s=new Map,i.set(this,s)),s.set(t,e)}get(t){return i.get(this)?.get(t)}getAll(){return Object.fromEntries(i.get(this)??[])}_unregister(t){const e=i.get(this);for(const[s,n]of e??[])n===t&&e.delete(s)}}class c{constructor(t,r={}){this.logic=t,this.options=r,this._snapshot=void 0,this._effects=void 0,this._queue=void 0,this._processing=!1,this._observers=void 0,this._listeners=void 0,this._trigger=void 0,this._restored=!1,this._processingStatus=e.NotStarted,this.id=void 0,this.sessionId=void 0,this.address=void 0,this.ref=this,this.src=void 0,this.system=void 0,this._parent=void 0,this.id=r.id??t.id??"(fsm)",this.sessionId=r._sessionId??"fsm:"+s++,this.src=r.src??t,this._parent=r.parent,this.address=this._parent?`${this._parent.address}/${n(this.id)}`:n(this.id),this.system=this._parent?.system??new o(r.clock??{setTimeout:setTimeout,clearTimeout:clearTimeout}),r.registryKey&&this.system._set(r.registryKey,this);const i=r.snapshot??r.state;try{void 0!==i?(this._restored=!0,this._snapshot=t.restoreSnapshot?.(i,this)??i,this._effects=[]):[this._snapshot,this._effects]=t.initialTransition(r.input,this)}catch(t){this._snapshot={status:"error",output:void 0,error:t},this._effects=[]}}get self(){return this}get logger(){return this.options.logger??console.log}defer(t){t()}get emit(){const t=t=>this.system.emitEvent(this,t);return Object.defineProperty(this,"emit",{value:t}),t}stopChild(t){t._stop()}actionExecutor(t){t.exec()}start(){if(this._processingStatus!==e.NotStarted)return this;this._processingStatus=e.Running;try{this.runEffects(this._effects)}catch(t){return this.fail(t),this}if("error"===this._snapshot.status)return this.fail(this._snapshot.error),this;if(this._effects=[],this._processingStatus===e.Stopped)return this;try{this.logic.start?.(this._snapshot,this,{restored:this._restored})}catch(t){return this.fail(t),this}if(this._restored){const t=this._snapshot.timers??{};for(const e of Object.values(t)){const t=this.system._clock.now||void 0===e.startedAt?e.delay:Math.min(e.delay,Math.max(0,e.startedAt+e.delay-Date.now()));this.system.scheduleTimer(this,e.id,t)}this._restored=!1}return this.notify(),this.flush(),this}send(t){this._processingStatus!==e.Stopped&&((this._queue??=[]).push(t),this.flush())}_send(t){this.send(t)}flush(){if(this._processing||this._processingStatus!==e.Running||!this._queue?.length)return;let t;for(this._processing=!0;this._processingStatus===e.Running&&(t=this._queue?.shift());)try{const[e,s]=this.logic.transition(this._snapshot,t,this);this._snapshot=e,this.runEffects(s),"active"===this._snapshot.status&&this.notify()}catch(t){this.fail(t);break}this._processing=!1}runEffects(t){for(const e of t)e.exec()}getSnapshot(){return this._snapshot}getPersistedSnapshot(t){return this.logic.getPersistedSnapshot(this._snapshot,t)}toJSON(){return{xstate$type:"actorRef",id:this.id,address:this.address,src:"string"==typeof this.src?this.src:void 0}}_stop(){if(this._processingStatus===e.Stopped)return this;if(this._processingStatus===e.Running){const[t,e]=this.logic.transition(this._snapshot,{type:"@xstate.stop"},this);this._snapshot=t,this.runEffects(e)}this._processingStatus=e.Stopped,this.system.cancelAllTimers(this),this.system._unregister(this),this._queue=void 0;for(const t of this._observers??[])t.complete?.();return this._observers?.clear(),this}stop(){if(this._parent)throw new Error("A non-root actor cannot be stopped directly.");return this._stop()}subscribe(t,s,n){const r="function"==typeof t?{next:t,error:s,complete:n}:t??{};if(this._processingStatus===e.Stopped){const t=this._snapshot;return"done"===t.status?r.complete?.():"error"===t.status&&r.error?.(t.error),{unsubscribe(){}}}return(this._observers??=new Set).add(r),{unsubscribe:()=>this._observers?.delete(r)}}on(t,e){let s=this._listeners?.get(t);return s||(s=new Set,(this._listeners??=new Map).set(t,s)),s.add(e),{unsubscribe:()=>s.delete(e)}}_emit(t){for(const e of[this._listeners?.get(t.type),this._listeners?.get("*")])for(const s of e??[])s(t)}_terminate(t){this.notify(),this._processingStatus=e.Stopped,this.system.cancelAllTimers(this),this.system._unregister(this);for(const e of this._observers??[])"error"===t.status?e.error?.(t.error):e.complete?.();this._observers?.clear(),this._listeners?.clear()}fail(t){this._snapshot={...this._snapshot,status:"error",output:void 0,error:t},this._processingStatus=e.Stopped,this.system.cancelAllTimers(this),this.system._unregister(this),this._queue=void 0;for(const e of this._observers??[])e.error?.(t);this._observers?.clear(),this._listeners?.clear()}notify(){for(const t of this._observers??[])t.next?.(this._snapshot)}_isRunning(){return this._processingStatus===e.Running}_inspectTransition(){}get trigger(){return this._trigger??=new Proxy({},{get:(t,e)=>t=>this.send({...t,type:e})})}select(t,e=Object.is){return{get:()=>t(this._snapshot),subscribe:s=>{const n="function"==typeof s?{next:s}:s;let r=t(this._snapshot);return this.subscribe({next:s=>{const i=t(s);e(r,i)||(r=i,n.next?.(i))},error:n.error,complete:n.complete})}}}[Symbol.observable](){return this}}const a="@xstate.init",u="@xstate.stop",h=new WeakMap;function p(t,e){const s=(t,e)=>[{status:"active",output:void 0,error:void 0,input:t},[]];return{id:e,start:(e,{self:s,system:n})=>{const r=e.input.actor;if(!r||"stopped"===r.getSnapshot().status)return;const i=t(e.input,{self:s,system:n});if(!i)return;let o,c=!1;const a=()=>{c||(c=!0,i.unsubscribe(),o?.unsubscribe())},u=s._parent;u&&(o=u.subscribe({complete:a,error:a})),h.set(s,{unsubscribe:a})},transition:(t,e,{self:s})=>e.type===u?(h.get(s)?.unsubscribe(),h.delete(s),[{...t,status:"stopped",error:void 0},[]]):[t,[]],initialTransition:s,getInitialSnapshot:(t,e)=>s(e)[0],getPersistedSnapshot:t=>t,restoreSnapshot:t=>t}}function d(t,e,s){"stopped"!==t.getSnapshot().status&&t._parent&&e._relay(t,t._parent,s())}function l(){return p(({actor:t,mappers:e},{self:s,system:n})=>{const{done:r,error:i,snapshot:o}=e;return t.subscribe({next:t=>{"done"===t.status&&r?d(s,n,()=>r(t.output)):"error"===t.status&&i?d(s,n,()=>i(t.error)):"active"===t.status&&o&&d(s,n,()=>o(t))},error:t=>{i&&d(s,n,()=>i(t))},complete:()=>{}})},"xstate.subscription")}const f=l(),y=Symbol();function _(t){return!!t[y]}function g(t,e){if(!_(e)){const s=t,n=e.self;return s.self=n,s.system=e.system,s.parent=n._parent,s}return Object.defineProperties(t,{self:{enumerable:!0,get:()=>e.self},system:{enumerable:!0,get:()=>e.system},parent:{enumerable:!0,get:()=>function(t){return _(t)?t._parent:t.self._parent}(e)}}),t}function m(){return p(({actor:t,eventType:e,mapper:s},{self:n,system:r})=>{const i="*"!==e&&e.endsWith(".*");return t.on(i?"*":e,t=>{i&&!function(t,e){if(e===t)return!0;if("*"===e)return!0;if(!e.endsWith(".*"))return!1;const s=e.split("."),n=t.split(".");for(let t=0;t<s.length;t++){const e=s[t],r=n[t];if("*"===e)return t===s.length-1;if(e!==r)return!1}return!0}(t.type,e)||d(n,r,()=>s(t))})},"xstate.listener")}const v=m(),x=new WeakMap;function b(t,e){x.set(t,{ids:new Set(Object.keys(e.children)),counters:{...e._nextActorIds}})}function w(t=this.source?.system??this.actor?.system){switch(this.type){case"@xstate.spawn":return t.spawnActor(this.source,this.actor);case"@xstate.start":return t.startActor(this.actor);case"@xstate.stop":return t.stopActor(this.actor);case"@xstate.terminate":return t.terminateActor(this.actor,this);case"@xstate.raise":case"@xstate.sendTo":{if(void 0===this.delay)return t.sendEvent(this.source,this.target,this.event);const e=this.source.getSnapshot().timers[this.id];return e&&!t._clock.now&&(e.startedAt=Date.now()),t.scheduleTimer(this.source,this.id,this.delay)}case"@xstate.cancel":return t.cancelTimer(this.source,this.id);case"@xstate.emit":return t.emitEvent(this.source,this.event);default:return this.action?.(...this.args)}}function S(t,e={}){return{kind:"builtin",type:t,params:void 0,args:[],exec:w,...e}}function A(t,e,s){const n=(t,...s)=>{e.push(S(t.name||"(anonymous)",{kind:"action",action:t,args:s}))};n.cancel=s=>{e.push(S("@xstate.cancel",{source:t.self,id:s}))},n.emit=s=>{e.push(S("@xstate.emit",{kind:"emit",type:"@xstate.emit",source:t.self,event:s}))},n.log=(...e)=>{n(t.logger,...e)},n.raise=(n,r)=>{if("string"==typeof n)throw new Error("Only event objects may be used with raise");void 0===r?.delay?s.push(n):e.push(S("@xstate.raise",{source:t.self,event:n,id:r.id,delay:r.delay}))},n.sendTo=(n,r,i)=>{n?e.push(S("@xstate.sendTo",{source:t.self,target:n,event:r,id:i?.id,delay:i?.delay})):s.push({type:"xstate.error.communication",error:{message:"Unable to send event to an undefined actor",event:r}})};n.spawn=(s,n={})=>{if("string"==typeof s)throw new Error(`Actor source "${s}" not found`);const r=x.get(t);let i,o,c=n.id;if(void 0===c){i=s.id??"x","(machine)"===i&&(i="x"),o=r.counters[i]??0;do{c=`${i}:${o++}`}while(r.ids.has(c));r.counters[i]=o}if(r.ids.has(c))throw new Error(`Actor with id "${c}" already exists`);r.ids.add(c);const a=t.system.createActorRef(s,{...n,id:c,parent:t.self});return e.push(S("@xstate.spawn",{source:t.self,actor:a,id:c,logic:s,src:s,input:n.input,childUpdate:{type:"add",actor:a,id:c,prefix:i,next:o}})),a},n.stop=s=>{s&&(x.get(t)?.ids.delete(s.id),e.push(S("@xstate.stop",{source:t.self,actor:s,id:s.id,childUpdate:{type:"remove",actor:s}})))};const r=(s,n)=>{const r=t.system.createActorRef(s,{input:n,parent:t.self});return e.push(S("@xstate.spawn",{source:t.self,actor:r,id:r.id,logic:s,src:s,input:n})),r};return n.listen=(t,e,s)=>r(v,{actor:t,eventType:e,mapper:s}),n.subscribeTo=(t,e)=>r(f,{actor:t,mappers:"function"==typeof e?{snapshot:e}:e}),n}function T(t,e,s){let n=t;for(const t of e){const e=t.childUpdate;if("add"===e?.type)n={...n,children:{...n.children,[e.id]:e.actor},...e.prefix&&{_nextActorIds:{...n._nextActorIds,[e.prefix]:Math.max(n._nextActorIds?.[e.prefix]??0,e.next)}}};else if("remove"===e?.type){const t={...n.children};let r=e.actor._parent===s.self;for(const s of Object.keys(t))t[s]===e.actor&&(r=!0,delete t[s]);if(!r)throw new Error(`Cannot stop non-child actor ${e.actor.id}`);n={...n,children:t}}if("@xstate.cancel"===t.type){if(n.timers[t.id]){const e={...n.timers};delete e[t.id],n={...n,timers:e}}}else if(("@xstate.raise"===t.type||"@xstate.sendTo"===t.type)&&void 0!==t.delay){const e=t,r=void 0===e.id,i=e.id??`xstate.timer.auto.${n._nextTimerId}`;e.id=i,n={...n,timers:{...n.timers,[i]:{id:i,delay:e.delay,type:e.type,event:e.event,target:"@xstate.raise"===e.type||e.target===s.self?"self":e.target}},_nextTimerId:r?n._nextTimerId+1:n._nextTimerId}}}return[n,e]}function I(t){const e=[],s=[],n=[];for(const r of t){if("@xstate.stop"===r.type)for(const t of[s,n]){const s=t.findIndex(t=>t.actor===r.actor);-1!==s&&e.push(t.splice(s,1)[0])}if(e.push(r),"@xstate.spawn"!==r.type)continue;const t=S("@xstate.start",{actor:r.actor,id:r.id,source:r.source});(r.logic===v||r.logic===f?s:n).push(t)}return e.concat(s,n)}function k(t,e,s){return S("@xstate.sendTo",{source:t.self,target:e,event:s})}function E(t,e,s){const[n,r]=s;return"done"!==n.status&&"error"!==n.status||"done"===e?.status||"error"===e?.status||r.push(S("@xstate.terminate",{source:t.self,actor:t.self,id:t.self.id,status:n.status,output:n.output,error:n.error})),[n,r]}const O={actions:{},actors:{},guards:{},delays:{}},j=[],M=[];function $(t,e){if(Object.keys(t).length)throw new Error("FSM child persistence requires registered sources.");for(const t in e)if("self"!==e[t].target)throw new Error(`FSM timer '${t}' must target self to be persisted.`)}function R(t){return void 0===t?[]:Array.isArray(t)?t:[t]}function P(t,e){return"function"==typeof t?t(e):t}function F(t,e,s){return"function"==typeof t?t({context:e,event:s}):t}function q(t,e){for(const s of Object.keys(e))if(!Object.prototype.hasOwnProperty.call(t,s)||!Object.is(t[s],e[s]))return{...t,...e};return t}function W(t,e,s,n){return{status:t.status,output:t.output,error:t.error,value:e,context:s,input:t.input,children:t.children,timers:t.timers,_nextTimerId:t._nextTimerId,_nextActorIds:t._nextActorIds,_stateInput:n,machine:t.machine}}function N(t){return{status:"stopped",output:void 0,error:void 0,value:t.value,context:t.context,input:void 0,children:t.children,timers:t.timers,_nextTimerId:t._nextTimerId,_nextActorIds:t._nextActorIds,_stateInput:t._stateInput,machine:t.machine}}function U(t,e){const s=[],n=A(e,s,[]);for(const e of Object.values(t.children))n.stop(e);for(const e of Object.keys(t.timers))n.cancel(e);return T(t,s,e)}function C(t,e,s,n,r,i){const o={...t,status:"done",output:void 0,error:void 0},[c,a]=i(o,e,s,r[o.value]?.exit,o._stateInput,n),[u,h]=U(c,s);return[u,[...a,...h]]}function D(t,e){throw new Error(`Invalid transition for "${t}": use { target: "${e}" } instead of a string target.`)}t.FSMActor=c,t.createFSM=function(t){const e={id:t.id??"(fsm)",sources:O};!function(t){for(const[e,s]of Object.entries(t.states)){for(const[t,n]of Object.entries(s.on??{}))for(const s of R(n))"string"==typeof s&&D(`${e}.${t}`,s);if(s.always)for(const t of R(s.always))"string"==typeof t&&D(`${e}.always`,t)}}(t);const s=(t,e,s,n,r)=>{if(!n)return[t,j];const i=[],o=A(s,i,r);let c=t.context;for(const r of R(n)){const n=r(g({context:c,event:e,input:t._stateInput,value:t.value,children:t.children},s),o);n?.context&&(c=q(c,n.context))}return T(c===t.context?t:W(t,t.value,c,t._stateInput),i,s)},n=(t,e,s,n,r,i)=>{if(!n)return[t,j];const o=[],c=A(s,o,i);let a;const u=Array.isArray(n)?n.length:1;for(let i=0;i<u;i++){const o=(Array.isArray(n)?n[i]:n)(g({context:a??t.context,event:e,input:r,value:t.value,children:t.children},s),c);if(void 0!==o?.context){const e=a??t.context,s=q(e,o.context);s!==e&&(a=s)}}return T(void 0!==a?W(t,t.value,a,t._stateInput):t,o,s)},r=(e,s,n,r)=>{const i=t.states[e.value],o=""===s.type?i?.always:i?.on?.[s.type];if(!o)return;const c=Array.isArray(o)?o.length:1;for(let t=0;t<c;t++){const i=Array.isArray(o)?o[t]:o,c=g({context:e.context,event:s,input:e.input,value:e.value,children:e.children},n);if("function"==typeof i){const t=[],e=i(c,A(n,t,r));if(!e){if(t.length)return{effects:t};continue}return{target:e.target,context:e.context,input:e.input,effects:t}}if(!("guard"in i)||!i.guard||i.guard(c))return{target:i.target,context:P(i.context,c),input:i.input,actions:"actions"in i&&i.actions?R(i.actions):M}}},i=(e,o,c)=>{if("active"!==e.status)return[e,[]];if(o.type===u){const[t,s]=U(e,c);return[N(t),s]}if("xstate.timer"===o.type){const t=e.timers[o.id];if(!t)return[e,j];const s={...e.timers};delete s[t.id];const n={...e,timers:s};if("@xstate.raise"===t.type)return i(n,t.event,c);return[n,[k(c,"self"===t.target?c.self:t.target,t.event)]]}const a=t.states[e.value],h=""===o.type?a?.always:a?.on?.[o.type];if(!h)return[e,j];if(!(Array.isArray(h)||"function"==typeof h||"guard"in h||"actions"in h&&h.actions||"function"==typeof h.input)){const s=h.target??e.value,n=t.states[s],r=s!==e.value;if(!(n?.always||r&&(a.exit||n?.entry||"final"===n?.type))){const t=void 0!==h.context,n=void 0!==h.input,i=_(c)?"function"==typeof h.context?h.context(g({context:e.context,event:o,input:e.input,value:e.value,children:e.children},c)):h.context:P(h.context,{context:e.context,event:o,input:e.input,value:e.value,self:c.self,system:c.system,parent:c.self._parent,children:e.children}),a=t&&i?q(e.context,i):e.context;return r||a!==e.context||n||void 0!==e._stateInput?[W(e,s,a,n?F(h.input,a,o):void 0),j]:[e,j]}}let p;if("function"==typeof h&&h.length<2&&!a?.exit){const s=h(g({context:e.context,event:o,input:e.input,value:e.value,children:e.children},c),void 0);if(!s)return[e,j];const n=s.target??e.value,r=t.states[n];if(!r?.entry&&!r?.always&&"final"!==r?.type){const t=void 0!==s.context,r=void 0!==s.input,i=t&&s.context?q(e.context,s.context):e.context;return n!==e.value||i!==e.context||r||void 0!==e._stateInput?[W(e,n,i,r?F(s.input,i,o):void 0),j]:[e,j]}p={target:s.target,context:s.context,input:s.input,actions:M}}let d=e;const l=[],f=[o];let y=0;for(;f.length;){if(++y>1e3)throw new Error("FSM microstep count exceeded 1000");const e=f.shift(),i=p??r(d,e,c,f);if(p=void 0,!i)continue;const o=i.target??d.value,a=t.states[o],u=o!==d.value;if(u){const[s,r]=n(d,e,c,t.states[d.value]?.exit,d._stateInput,f);d=s,l.push(...r)}let h=d.context;void 0!==i.context&&(h=q(h,i.context));const _=void 0!==i.input,g=_?F(i.input,h,e):void 0;(u||h!==d.context||_||void 0!==d._stateInput)&&(d=W(d,o,h,g));const m=i.effects?T(d,i.effects,c):s(d,e,c,i.actions,f),[v,x]=m;if(d=v,l.push(...x),u){const[t,s]=n(d,e,c,a?.entry,g,f);d=t,l.push(...s)}if("final"===a?.type){const[s,r]=C(d,e,c,f,t.states,n);d=s,l.push(...r);break}a?.always&&f.unshift({type:""})}return[d,l]},o={id:t.id,config:t,transition:(...t)=>{b(t[2],t[0]);const[e,s]=i(...t);return E(t[2],t[0],[e,I(s)])},initialTransition:(s,r)=>{const o=t.states[t.initial],c=function(t,e){return"function"==typeof t?t({input:e}):t??{}}(t.context,s),u=function(t,e,s,n,r){return{status:"active",output:void 0,error:void 0,value:t,context:e,input:s,children:{},timers:{},_nextTimerId:0,_stateInput:r,machine:n}}(t.initial,c,s,e);b(r,u);const h=[];let[p,d]=n(u,{type:a},r,o?.entry,void 0,h);if(d.length||(d=[]),"final"===o?.type){const[e,s]=C(p,{type:a},r,h,t.states,n);p=e,d.push(...s)}else for(o?.always&&h.unshift({type:""});h.length;){const[t,e]=i(p,h.shift(),r);p=t,d.push(...e)}return E(r,void 0,[p,I(d)])},getInitialSnapshot:(t,e)=>o.initialTransition(e,t)[0],getPersistedSnapshot:t=>{const{machine:e,children:s,...n}=t;return $(s,n.timers),{...n,children:{}}},restoreSnapshot:t=>{const s=t,n=s.children??{},r=s.timers??{};$(n,r);return{...s,children:{},timers:r,machine:e}}};return o},t.createFSMActor=function(t,e){return new c(t,e)},Object.defineProperty(t,"__esModule",{value:!0})});
|
|
2
|
+
//# sourceMappingURL=xstate-fsm.umd.min.js.map
|