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.
Files changed (62) hide show
  1. package/README.md +23 -0
  2. package/dist/{StateMachine-b09d2b00.cjs.js → StateMachine-0adb3a70.cjs.js} +1 -1
  3. package/dist/{StateMachine-b3a890bf.development.cjs.js → StateMachine-29450e6d.development.cjs.js} +1 -1
  4. package/dist/{StateMachine-8329769a.esm.js → StateMachine-2af31c11.esm.js} +1 -1
  5. package/dist/{StateMachine-88b3c26a.development.esm.js → StateMachine-faf50c5c.development.esm.js} +1 -1
  6. package/dist/{createActor-27287c65.esm.js → createActor-268165d4.esm.js} +1 -1
  7. package/dist/{createActor-309d77eb.development.esm.js → createActor-88709f74.development.esm.js} +1 -1
  8. package/dist/{createActor-cc3d6dde.development.cjs.js → createActor-a1e0dffb.development.cjs.js} +0 -3
  9. package/dist/{createActor-9b41ade9.cjs.js → createActor-b4dd05ae.cjs.js} +0 -3
  10. package/dist/declarations/src/fsm/createFSMActor.d.ts +67 -0
  11. package/dist/declarations/src/fsm/index.d.ts +2 -0
  12. package/dist/declarations/src/fsm.d.ts +5 -4
  13. package/dist/{effectDescriptor-b1f5deb6.esm.js → effectDescriptor-30c9a744.esm.js} +1 -1
  14. package/dist/{effectDescriptor-7707794b.development.esm.js → effectDescriptor-39d22100.development.esm.js} +1 -1
  15. package/dist/{effectDescriptor-a1678d06.development.cjs.js → effectDescriptor-7ff6802f.development.cjs.js} +1 -1
  16. package/dist/{effectDescriptor-bd36a33e.cjs.js → effectDescriptor-be348e50.cjs.js} +1 -1
  17. package/dist/fsm-7a2e9697.cjs.js +777 -0
  18. package/dist/fsm-b804b3e9.esm.js +775 -0
  19. package/dist/fsm-c1316948.development.cjs.js +777 -0
  20. package/dist/fsm-e18a7cb4.development.esm.js +775 -0
  21. package/dist/{types-81d03bef.esm.js → types-3c3455f7.esm.js} +1 -1
  22. package/dist/{types-1793b8b6.development.esm.js → types-adda3842.development.esm.js} +1 -1
  23. package/dist/{types-7e468202.development.cjs.js → types-b3fea5bd.development.cjs.js} +1 -1
  24. package/dist/{types-9c1bc85f.cjs.js → types-fbabaeee.cjs.js} +1 -1
  25. package/dist/xstate-actors.cjs.js +1 -1
  26. package/dist/xstate-actors.development.cjs.js +1 -1
  27. package/dist/xstate-actors.development.esm.js +2 -2
  28. package/dist/xstate-actors.esm.js +2 -2
  29. package/dist/xstate-durable.cjs.js +2 -2
  30. package/dist/xstate-durable.development.cjs.js +2 -2
  31. package/dist/xstate-durable.development.esm.js +2 -2
  32. package/dist/xstate-durable.esm.js +2 -2
  33. package/dist/xstate-fsm.cjs.d.mts +2 -0
  34. package/dist/xstate-fsm.cjs.d.ts +2 -0
  35. package/dist/xstate-fsm.cjs.js +409 -0
  36. package/dist/xstate-fsm.cjs.mjs +5 -0
  37. package/dist/xstate-fsm.development.cjs.js +409 -0
  38. package/dist/xstate-fsm.development.cjs.mjs +5 -0
  39. package/dist/xstate-fsm.development.esm.js +403 -0
  40. package/dist/xstate-fsm.esm.js +403 -0
  41. package/dist/xstate-fsm.umd.min.js +2 -0
  42. package/dist/xstate-fsm.umd.min.js.map +1 -0
  43. package/dist/xstate-graph.cjs.js +2 -2
  44. package/dist/xstate-graph.development.cjs.js +2 -2
  45. package/dist/xstate-graph.development.esm.js +2 -2
  46. package/dist/xstate-graph.esm.js +2 -2
  47. package/dist/xstate-scxml.cjs.js +3 -3
  48. package/dist/xstate-scxml.development.cjs.js +3 -3
  49. package/dist/xstate-scxml.development.esm.js +3 -3
  50. package/dist/xstate-scxml.esm.js +3 -3
  51. package/dist/xstate-validation.cjs.js +1 -1
  52. package/dist/xstate-validation.development.cjs.js +1 -1
  53. package/dist/xstate-validation.development.esm.js +1 -1
  54. package/dist/xstate-validation.esm.js +1 -1
  55. package/dist/xstate.cjs.js +6 -380
  56. package/dist/xstate.development.cjs.js +6 -380
  57. package/dist/xstate.development.esm.js +10 -384
  58. package/dist/xstate.esm.js +10 -384
  59. package/dist/xstate.umd.min.js +1 -1
  60. package/dist/xstate.umd.min.js.map +1 -1
  61. package/fsm/package.json +8 -0
  62. package/package.json +18 -2
@@ -0,0 +1,403 @@
1
+ export { c as createFSM } from './fsm-e18a7cb4.development.esm.js';
2
+ import './createActor-88709f74.development.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 };