xstate 5.13.2 → 5.15.0
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 +2 -2
- package/actions/dist/xstate-actions.development.cjs.js +2 -2
- package/actions/dist/xstate-actions.development.esm.js +2 -2
- 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 +289 -79
- package/actors/dist/xstate-actors.development.cjs.js +289 -79
- package/actors/dist/xstate-actors.development.esm.js +289 -79
- package/actors/dist/xstate-actors.esm.js +289 -79
- package/actors/dist/xstate-actors.umd.min.js +1 -1
- package/actors/dist/xstate-actors.umd.min.js.map +1 -1
- package/dist/declarations/src/State.d.ts +21 -25
- package/dist/declarations/src/StateMachine.d.ts +18 -30
- package/dist/declarations/src/StateNode.d.ts +29 -51
- package/dist/declarations/src/actions/assign.d.ts +29 -27
- package/dist/declarations/src/actions/cancel.d.ts +28 -22
- package/dist/declarations/src/actions/emit.d.ts +33 -33
- package/dist/declarations/src/actions/enqueueActions.d.ts +18 -16
- package/dist/declarations/src/actions/log.d.ts +5 -4
- package/dist/declarations/src/actions/send.d.ts +5 -3
- package/dist/declarations/src/actors/callback.d.ts +69 -29
- package/dist/declarations/src/actors/index.d.ts +4 -4
- package/dist/declarations/src/actors/observable.d.ts +74 -29
- package/dist/declarations/src/actors/promise.d.ts +91 -13
- package/dist/declarations/src/actors/transition.d.ts +90 -16
- package/dist/declarations/src/assert.d.ts +21 -20
- package/dist/declarations/src/createActor.d.ts +51 -42
- package/dist/declarations/src/createMachine.d.ts +40 -54
- package/dist/declarations/src/getNextSnapshot.d.ts +27 -24
- package/dist/declarations/src/guards.d.ts +67 -66
- package/dist/declarations/src/index.d.ts +0 -1
- package/dist/declarations/src/inspection.d.ts +1 -0
- package/dist/declarations/src/setup.d.ts +1 -2
- package/dist/declarations/src/spawn.d.ts +2 -5
- package/dist/declarations/src/stateUtils.d.ts +5 -10
- package/dist/declarations/src/system.d.ts +2 -2
- package/dist/declarations/src/toPromise.d.ts +1 -0
- package/dist/declarations/src/types.d.ts +169 -192
- package/dist/declarations/src/waitFor.d.ts +9 -9
- package/dist/{log-c447a931.esm.js → log-63de2429.esm.js} +112 -117
- package/dist/{log-5b14d850.cjs.js → log-b8c93ee3.cjs.js} +112 -117
- package/dist/{log-d06dd00b.development.cjs.js → log-d2c282d6.development.cjs.js} +112 -117
- package/dist/{log-b3b03961.development.esm.js → log-e9953143.development.esm.js} +112 -117
- package/dist/{raise-f406edbd.esm.js → raise-2cfe6b8f.esm.js} +302 -284
- package/dist/{raise-150d5679.development.esm.js → raise-7d030497.development.esm.js} +302 -284
- package/dist/{raise-ff8990f7.cjs.js → raise-a6298350.cjs.js} +302 -284
- package/dist/{raise-bf7a8462.development.cjs.js → raise-bad6a97b.development.cjs.js} +302 -284
- package/dist/xstate.cjs.js +134 -157
- package/dist/xstate.development.cjs.js +134 -157
- package/dist/xstate.development.esm.js +136 -159
- package/dist/xstate.esm.js +136 -159
- package/dist/xstate.umd.min.js +1 -1
- package/dist/xstate.umd.min.js.map +1 -1
- package/guards/dist/xstate-guards.cjs.js +1 -1
- package/guards/dist/xstate-guards.development.cjs.js +1 -1
- package/guards/dist/xstate-guards.development.esm.js +1 -1
- package/guards/dist/xstate-guards.esm.js +1 -1
- package/guards/dist/xstate-guards.umd.min.js.map +1 -1
- package/package.json +1 -1
- package/dist/declarations/src/typegenTypes.d.ts +0 -168
|
@@ -1,43 +1,98 @@
|
|
|
1
|
-
import { X as XSTATE_STOP, A as createActor } from '../../dist/raise-
|
|
1
|
+
import { X as XSTATE_STOP, A as createActor } from '../../dist/raise-2cfe6b8f.esm.js';
|
|
2
2
|
import '../../dev/dist/xstate-dev.esm.js';
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* Represents an actor created by `fromTransition`.
|
|
6
|
+
*
|
|
7
|
+
* The type of `self` within the actor's logic.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
*
|
|
11
|
+
* ```ts
|
|
12
|
+
* import {
|
|
13
|
+
* fromTransition,
|
|
14
|
+
* createActor,
|
|
15
|
+
* type AnyActorSystem
|
|
16
|
+
* } from 'xstate';
|
|
17
|
+
*
|
|
18
|
+
* //* The actor's stored context.
|
|
19
|
+
* type Context = {
|
|
20
|
+
* // The current count.
|
|
21
|
+
* count: number;
|
|
22
|
+
* // The amount to increase `count` by.
|
|
23
|
+
* step: number;
|
|
24
|
+
* };
|
|
25
|
+
* // The events the actor receives.
|
|
26
|
+
* type Event = { type: 'increment' };
|
|
27
|
+
* // The actor's input.
|
|
28
|
+
* type Input = { step?: number };
|
|
29
|
+
*
|
|
30
|
+
* // Actor logic that increments `count` by `step` when it receives an event of
|
|
31
|
+
* // type `increment`.
|
|
32
|
+
* const logic = fromTransition<Context, Event, AnyActorSystem, Input>(
|
|
33
|
+
* (state, event, actorScope) => {
|
|
34
|
+
* actorScope.self;
|
|
35
|
+
* // ^? TransitionActorRef<Context, Event>
|
|
36
|
+
*
|
|
37
|
+
* if (event.type === 'increment') {
|
|
38
|
+
* return {
|
|
39
|
+
* ...state,
|
|
40
|
+
* count: state.count + state.step
|
|
41
|
+
* };
|
|
42
|
+
* }
|
|
43
|
+
* return state;
|
|
44
|
+
* },
|
|
45
|
+
* ({ input, self }) => {
|
|
46
|
+
* self;
|
|
47
|
+
* // ^? TransitionActorRef<Context, Event>
|
|
48
|
+
*
|
|
49
|
+
* return {
|
|
50
|
+
* count: 0,
|
|
51
|
+
* step: input.step ?? 1
|
|
52
|
+
* };
|
|
53
|
+
* }
|
|
54
|
+
* );
|
|
55
|
+
*
|
|
56
|
+
* const actor = createActor(logic, { input: { step: 10 } });
|
|
57
|
+
* // ^? TransitionActorRef<Context, Event>
|
|
58
|
+
* ```
|
|
59
|
+
*
|
|
60
|
+
* @see {@link fromTransition}
|
|
61
|
+
*/
|
|
62
|
+
|
|
4
63
|
/**
|
|
5
64
|
* Returns actor logic given a transition function and its initial state.
|
|
6
65
|
*
|
|
7
|
-
* A “transition function” is a function that takes the current `state` and
|
|
66
|
+
* A “transition function” is a function that takes the current `state` and
|
|
67
|
+
* received `event` object as arguments, and returns the next state, similar to
|
|
68
|
+
* a reducer.
|
|
8
69
|
*
|
|
9
70
|
* Actors created from transition logic (“transition actors”) can:
|
|
10
71
|
*
|
|
11
72
|
* - Receive events
|
|
12
73
|
* - Emit snapshots of its state
|
|
13
74
|
*
|
|
14
|
-
* The transition function’s `state` is used as its transition actor’s
|
|
75
|
+
* The transition function’s `state` is used as its transition actor’s
|
|
76
|
+
* `context`.
|
|
15
77
|
*
|
|
16
|
-
* Note that the "state" for a transition function is provided by the initial
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
* - `state` - the current state.
|
|
20
|
-
* - `event` - the received event.
|
|
21
|
-
* - `actorScope` - the actor scope object, with properties like `self` and `system`.
|
|
22
|
-
* @param initialContext The initial state of the transition function, either an object representing the state, or a function which returns a state object. If a function, it will receive as its only argument an object with the following properties:
|
|
23
|
-
* - `input` - the `input` provided to its parent transition actor.
|
|
24
|
-
* - `self` - a reference to its parent transition actor.
|
|
25
|
-
* @see {@link https://stately.ai/docs/input | Input docs} for more information about how input is passed
|
|
26
|
-
* @returns Actor logic
|
|
78
|
+
* Note that the "state" for a transition function is provided by the initial
|
|
79
|
+
* state argument, and is not the same as the State object of an actor or a
|
|
80
|
+
* state within a machine configuration.
|
|
27
81
|
*
|
|
28
82
|
* @example
|
|
83
|
+
*
|
|
29
84
|
* ```ts
|
|
30
85
|
* const transitionLogic = fromTransition(
|
|
31
86
|
* (state, event) => {
|
|
32
87
|
* if (event.type === 'increment') {
|
|
33
88
|
* return {
|
|
34
89
|
* ...state,
|
|
35
|
-
* count: state.count + 1
|
|
90
|
+
* count: state.count + 1
|
|
36
91
|
* };
|
|
37
92
|
* }
|
|
38
93
|
* return state;
|
|
39
94
|
* },
|
|
40
|
-
* { count: 0 }
|
|
95
|
+
* { count: 0 }
|
|
41
96
|
* );
|
|
42
97
|
*
|
|
43
98
|
* const transitionActor = createActor(transitionLogic);
|
|
@@ -58,6 +113,26 @@ import '../../dev/dist/xstate-dev.esm.js';
|
|
|
58
113
|
* // ...
|
|
59
114
|
* // }
|
|
60
115
|
* ```
|
|
116
|
+
*
|
|
117
|
+
* @param transition The transition function used to describe the transition
|
|
118
|
+
* logic. It should return the next state given the current state and event.
|
|
119
|
+
* It receives the following arguments:
|
|
120
|
+
*
|
|
121
|
+
* - `state` - the current state.
|
|
122
|
+
* - `event` - the received event.
|
|
123
|
+
* - `actorScope` - the actor scope object, with properties like `self` and
|
|
124
|
+
* `system`.
|
|
125
|
+
*
|
|
126
|
+
* @param initialContext The initial state of the transition function, either an
|
|
127
|
+
* object representing the state, or a function which returns a state object.
|
|
128
|
+
* If a function, it will receive as its only argument an object with the
|
|
129
|
+
* following properties:
|
|
130
|
+
*
|
|
131
|
+
* - `input` - the `input` provided to its parent transition actor.
|
|
132
|
+
* - `self` - a reference to its parent transition actor.
|
|
133
|
+
*
|
|
134
|
+
* @returns Actor logic
|
|
135
|
+
* @see {@link https://stately.ai/docs/input | Input docs} for more information about how input is passed
|
|
61
136
|
*/
|
|
62
137
|
function fromTransition(transition, initialContext) {
|
|
63
138
|
return {
|
|
@@ -84,36 +159,64 @@ function fromTransition(transition, initialContext) {
|
|
|
84
159
|
}
|
|
85
160
|
|
|
86
161
|
const instanceStates = /* #__PURE__ */new WeakMap();
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Represents an actor created by `fromCallback`.
|
|
165
|
+
*
|
|
166
|
+
* The type of `self` within the actor's logic.
|
|
167
|
+
*
|
|
168
|
+
* @example
|
|
169
|
+
*
|
|
170
|
+
* ```ts
|
|
171
|
+
* import { fromCallback, createActor } from 'xstate';
|
|
172
|
+
*
|
|
173
|
+
* // The events the actor receives.
|
|
174
|
+
* type Event = { type: 'someEvent' };
|
|
175
|
+
* // The actor's input.
|
|
176
|
+
* type Input = { name: string };
|
|
177
|
+
*
|
|
178
|
+
* // Actor logic that logs whenever it receives an event of type `someEvent`.
|
|
179
|
+
* const logic = fromCallback<Event, Input>(({ self, input, receive }) => {
|
|
180
|
+
* self;
|
|
181
|
+
* // ^? CallbackActorRef<Event, Input>
|
|
182
|
+
*
|
|
183
|
+
* receive((event) => {
|
|
184
|
+
* if (event.type === 'someEvent') {
|
|
185
|
+
* console.log(`${input.name}: received "someEvent" event`);
|
|
186
|
+
* // logs 'myActor: received "someEvent" event'
|
|
187
|
+
* }
|
|
188
|
+
* });
|
|
189
|
+
* });
|
|
190
|
+
*
|
|
191
|
+
* const actor = createActor(logic, { input: { name: 'myActor' } });
|
|
192
|
+
* // ^? CallbackActorRef<Event, Input>
|
|
193
|
+
* ```
|
|
194
|
+
*
|
|
195
|
+
* @see {@link fromCallback}
|
|
196
|
+
*/
|
|
197
|
+
|
|
87
198
|
/**
|
|
88
|
-
* An actor logic creator which returns callback logic as defined by a callback
|
|
199
|
+
* An actor logic creator which returns callback logic as defined by a callback
|
|
200
|
+
* function.
|
|
89
201
|
*
|
|
90
202
|
* @remarks
|
|
91
|
-
* Useful for subscription-based or other free-form logic that can send events
|
|
203
|
+
* Useful for subscription-based or other free-form logic that can send events
|
|
204
|
+
* back to the parent actor.
|
|
92
205
|
*
|
|
93
206
|
* Actors created from callback logic (“callback actors”) can:
|
|
207
|
+
*
|
|
94
208
|
* - Receive events via the `receive` function
|
|
95
209
|
* - Send events to the parent actor via the `sendBack` function
|
|
96
210
|
*
|
|
97
211
|
* Callback actors are a bit different from other actors in that they:
|
|
212
|
+
*
|
|
98
213
|
* - Do not work with `onDone`
|
|
99
214
|
* - Do not produce a snapshot using `.getSnapshot()`
|
|
100
215
|
* - Do not emit values when used with `.subscribe()`
|
|
101
216
|
* - Can not be stopped with `.stop()`
|
|
102
217
|
*
|
|
103
|
-
* @param invokeCallback - The callback function used to describe the callback logic
|
|
104
|
-
* The callback function is passed an object with the following properties:
|
|
105
|
-
* - `receive` - A function that can send events back to the parent actor; the listener is then called whenever events are received by the callback actor
|
|
106
|
-
* - `sendBack` - A function that can send events back to the parent actor
|
|
107
|
-
* - `input` - Data that was provided to the callback actor
|
|
108
|
-
* - `self` - The parent actor of the callback actor
|
|
109
|
-
* - `system` - The actor system to which the callback actor belongs
|
|
110
|
-
* The callback function can (optionally) return a cleanup function, which is called when the actor is stopped.
|
|
111
|
-
* @see {@link InvokeCallback} for more information about the callback function and its object argument
|
|
112
|
-
* @see {@link https://stately.ai/docs/input | Input docs} for more information about how input is passed
|
|
113
|
-
|
|
114
|
-
* @returns Callback logic
|
|
115
|
-
*
|
|
116
218
|
* @example
|
|
219
|
+
*
|
|
117
220
|
* ```typescript
|
|
118
221
|
* const callbackLogic = fromCallback(({ sendBack, receive }) => {
|
|
119
222
|
* let lockStatus = 'unlocked';
|
|
@@ -140,6 +243,24 @@ const instanceStates = /* #__PURE__ */new WeakMap();
|
|
|
140
243
|
* };
|
|
141
244
|
* });
|
|
142
245
|
* ```
|
|
246
|
+
*
|
|
247
|
+
* @param invokeCallback - The callback function used to describe the callback
|
|
248
|
+
* logic The callback function is passed an object with the following
|
|
249
|
+
* properties:
|
|
250
|
+
*
|
|
251
|
+
* - `receive` - A function that can send events back to the parent actor; the
|
|
252
|
+
* listener is then called whenever events are received by the callback
|
|
253
|
+
* actor
|
|
254
|
+
* - `sendBack` - A function that can send events back to the parent actor
|
|
255
|
+
* - `input` - Data that was provided to the callback actor
|
|
256
|
+
* - `self` - The parent actor of the callback actor
|
|
257
|
+
* - `system` - The actor system to which the callback actor belongs The callback
|
|
258
|
+
* function can (optionally) return a cleanup function, which is called
|
|
259
|
+
* when the actor is stopped.
|
|
260
|
+
*
|
|
261
|
+
* @returns Callback logic
|
|
262
|
+
* @see {@link InvokeCallback} for more information about the callback function and its object argument
|
|
263
|
+
* @see {@link https://stately.ai/docs/input | Input docs} for more information about how input is passed
|
|
143
264
|
*/
|
|
144
265
|
function fromCallback(invokeCallback) {
|
|
145
266
|
const logic = {
|
|
@@ -147,7 +268,8 @@ function fromCallback(invokeCallback) {
|
|
|
147
268
|
start: (state, actorScope) => {
|
|
148
269
|
const {
|
|
149
270
|
self,
|
|
150
|
-
system
|
|
271
|
+
system,
|
|
272
|
+
emit
|
|
151
273
|
} = actorScope;
|
|
152
274
|
const callbackState = {
|
|
153
275
|
receivers: undefined,
|
|
@@ -169,7 +291,8 @@ function fromCallback(invokeCallback) {
|
|
|
169
291
|
receive: listener => {
|
|
170
292
|
callbackState.receivers ??= new Set();
|
|
171
293
|
callbackState.receivers.add(listener);
|
|
172
|
-
}
|
|
294
|
+
},
|
|
295
|
+
emit
|
|
173
296
|
});
|
|
174
297
|
},
|
|
175
298
|
transition: (state, event, actorScope) => {
|
|
@@ -203,8 +326,43 @@ function fromCallback(invokeCallback) {
|
|
|
203
326
|
const XSTATE_OBSERVABLE_NEXT = 'xstate.observable.next';
|
|
204
327
|
const XSTATE_OBSERVABLE_ERROR = 'xstate.observable.error';
|
|
205
328
|
const XSTATE_OBSERVABLE_COMPLETE = 'xstate.observable.complete';
|
|
329
|
+
|
|
330
|
+
/**
|
|
331
|
+
* Represents an actor created by `fromObservable` or `fromEventObservable`.
|
|
332
|
+
*
|
|
333
|
+
* The type of `self` within the actor's logic.
|
|
334
|
+
*
|
|
335
|
+
* @example
|
|
336
|
+
*
|
|
337
|
+
* ```ts
|
|
338
|
+
* import { fromObservable, createActor } from 'xstate';
|
|
339
|
+
* import { interval } from 'rxjs';
|
|
340
|
+
*
|
|
341
|
+
* // The type of the value observed by the actor's logic.
|
|
342
|
+
* type Context = number;
|
|
343
|
+
* // The actor's input.
|
|
344
|
+
* type Input = { period?: number };
|
|
345
|
+
*
|
|
346
|
+
* // Actor logic that observes a number incremented every `input.period`
|
|
347
|
+
* // milliseconds (default: 1_000).
|
|
348
|
+
* const logic = fromObservable<Context, Input>(({ input, self }) => {
|
|
349
|
+
* self;
|
|
350
|
+
* // ^? ObservableActorRef<Event, Input>
|
|
351
|
+
*
|
|
352
|
+
* return interval(input.period ?? 1_000);
|
|
353
|
+
* });
|
|
354
|
+
*
|
|
355
|
+
* const actor = createActor(logic, { input: { period: 2_000 } });
|
|
356
|
+
* // ^? ObservableActorRef<Event, Input>
|
|
357
|
+
* ```
|
|
358
|
+
*
|
|
359
|
+
* @see {@link fromObservable}
|
|
360
|
+
* @see {@link fromEventObservable}
|
|
361
|
+
*/
|
|
362
|
+
|
|
206
363
|
/**
|
|
207
|
-
* Observable actor logic is described by an observable stream of values. Actors
|
|
364
|
+
* Observable actor logic is described by an observable stream of values. Actors
|
|
365
|
+
* created from observable logic (“observable actors”) can:
|
|
208
366
|
*
|
|
209
367
|
* - Emit snapshots of the observable’s emitted value
|
|
210
368
|
*
|
|
@@ -212,16 +370,10 @@ const XSTATE_OBSERVABLE_COMPLETE = 'xstate.observable.complete';
|
|
|
212
370
|
*
|
|
213
371
|
* Sending events to observable actors will have no effect.
|
|
214
372
|
*
|
|
215
|
-
* @param observableCreator A function that creates an observable. It receives one argument, an object with the following properties:
|
|
216
|
-
* - `input` - Data that was provided to the observable actor
|
|
217
|
-
* - `self` - The parent actor
|
|
218
|
-
* - `system` - The actor system to which the observable actor belongs
|
|
219
|
-
*
|
|
220
|
-
* It should return a {@link Subscribable}, which is compatible with an RxJS Observable, although RxJS is not required to create them.
|
|
221
|
-
*
|
|
222
373
|
* @example
|
|
374
|
+
*
|
|
223
375
|
* ```ts
|
|
224
|
-
* import { fromObservable, createActor } from 'xstate'
|
|
376
|
+
* import { fromObservable, createActor } from 'xstate';
|
|
225
377
|
* import { interval } from 'rxjs';
|
|
226
378
|
*
|
|
227
379
|
* const logic = fromObservable((obj) => interval(1000));
|
|
@@ -240,6 +392,15 @@ const XSTATE_OBSERVABLE_COMPLETE = 'xstate.observable.complete';
|
|
|
240
392
|
* // ...
|
|
241
393
|
* ```
|
|
242
394
|
*
|
|
395
|
+
* @param observableCreator A function that creates an observable. It receives
|
|
396
|
+
* one argument, an object with the following properties:
|
|
397
|
+
*
|
|
398
|
+
* - `input` - Data that was provided to the observable actor
|
|
399
|
+
* - `self` - The parent actor
|
|
400
|
+
* - `system` - The actor system to which the observable actor belongs
|
|
401
|
+
*
|
|
402
|
+
* It should return a {@link Subscribable}, which is compatible with an RxJS
|
|
403
|
+
* Observable, although RxJS is not required to create them.
|
|
243
404
|
* @see {@link https://rxjs.dev} for documentation on RxJS Observable and observable creators.
|
|
244
405
|
* @see {@link Subscribable} interface in XState, which is based on and compatible with RxJS Observable.
|
|
245
406
|
*/
|
|
@@ -247,12 +408,7 @@ function fromObservable(observableCreator) {
|
|
|
247
408
|
// TODO: add event types
|
|
248
409
|
const logic = {
|
|
249
410
|
config: observableCreator,
|
|
250
|
-
transition: (snapshot, event
|
|
251
|
-
self,
|
|
252
|
-
id,
|
|
253
|
-
defer,
|
|
254
|
-
system
|
|
255
|
-
}) => {
|
|
411
|
+
transition: (snapshot, event) => {
|
|
256
412
|
if (snapshot.status !== 'active') {
|
|
257
413
|
return snapshot;
|
|
258
414
|
}
|
|
@@ -304,7 +460,8 @@ function fromObservable(observableCreator) {
|
|
|
304
460
|
},
|
|
305
461
|
start: (state, {
|
|
306
462
|
self,
|
|
307
|
-
system
|
|
463
|
+
system,
|
|
464
|
+
emit
|
|
308
465
|
}) => {
|
|
309
466
|
if (state.status === 'done') {
|
|
310
467
|
// Do not restart a completed observable
|
|
@@ -313,7 +470,8 @@ function fromObservable(observableCreator) {
|
|
|
313
470
|
state._subscription = observableCreator({
|
|
314
471
|
input: state.input,
|
|
315
472
|
system,
|
|
316
|
-
self
|
|
473
|
+
self,
|
|
474
|
+
emit
|
|
317
475
|
}).subscribe({
|
|
318
476
|
next: value => {
|
|
319
477
|
system._relay(self, self, {
|
|
@@ -347,24 +505,20 @@ function fromObservable(observableCreator) {
|
|
|
347
505
|
}
|
|
348
506
|
|
|
349
507
|
/**
|
|
350
|
-
* Creates event observable logic that listens to an observable that delivers
|
|
508
|
+
* Creates event observable logic that listens to an observable that delivers
|
|
509
|
+
* event objects.
|
|
351
510
|
*
|
|
352
|
-
* Event observable actor logic is described by an observable stream of
|
|
511
|
+
* Event observable actor logic is described by an observable stream of
|
|
512
|
+
* {@link https://stately.ai/docs/transitions#event-objects | event objects}.
|
|
513
|
+
* Actors created from event observable logic (“event observable actors”) can:
|
|
353
514
|
*
|
|
354
515
|
* - Implicitly send events to its parent actor
|
|
355
516
|
* - Emit snapshots of its emitted event objects
|
|
356
517
|
*
|
|
357
518
|
* Sending events to event observable actors will have no effect.
|
|
358
519
|
*
|
|
359
|
-
* @param lazyObservable A function that creates an observable that delivers event objects. It receives one argument, an object with the following properties:
|
|
360
|
-
*
|
|
361
|
-
* - `input` - Data that was provided to the event observable actor
|
|
362
|
-
* - `self` - The parent actor
|
|
363
|
-
* - `system` - The actor system to which the event observable actor belongs.
|
|
364
|
-
*
|
|
365
|
-
* It should return a {@link Subscribable}, which is compatible with an RxJS Observable, although RxJS is not required to create them.
|
|
366
|
-
*
|
|
367
520
|
* @example
|
|
521
|
+
*
|
|
368
522
|
* ```ts
|
|
369
523
|
* import {
|
|
370
524
|
* fromEventObservable,
|
|
@@ -375,20 +529,31 @@ function fromObservable(observableCreator) {
|
|
|
375
529
|
* } from 'xstate';
|
|
376
530
|
* import { fromEvent } from 'rxjs';
|
|
377
531
|
*
|
|
378
|
-
* const mouseClickLogic = fromEventObservable(
|
|
379
|
-
* fromEvent(document.body, 'click') as Subscribable<EventObject>
|
|
532
|
+
* const mouseClickLogic = fromEventObservable(
|
|
533
|
+
* () => fromEvent(document.body, 'click') as Subscribable<EventObject>
|
|
380
534
|
* );
|
|
381
535
|
*
|
|
382
536
|
* const canvasMachine = createMachine({
|
|
383
537
|
* invoke: {
|
|
384
538
|
* // Will send mouse `click` events to the canvas actor
|
|
385
|
-
* src: mouseClickLogic
|
|
539
|
+
* src: mouseClickLogic
|
|
386
540
|
* }
|
|
387
541
|
* });
|
|
388
542
|
*
|
|
389
543
|
* const canvasActor = createActor(canvasMachine);
|
|
390
544
|
* canvasActor.start();
|
|
391
545
|
* ```
|
|
546
|
+
*
|
|
547
|
+
* @param lazyObservable A function that creates an observable that delivers
|
|
548
|
+
* event objects. It receives one argument, an object with the following
|
|
549
|
+
* properties:
|
|
550
|
+
*
|
|
551
|
+
* - `input` - Data that was provided to the event observable actor
|
|
552
|
+
* - `self` - The parent actor
|
|
553
|
+
* - `system` - The actor system to which the event observable actor belongs.
|
|
554
|
+
*
|
|
555
|
+
* It should return a {@link Subscribable}, which is compatible with an RxJS
|
|
556
|
+
* Observable, although RxJS is not required to create them.
|
|
392
557
|
*/
|
|
393
558
|
function fromEventObservable(lazyObservable) {
|
|
394
559
|
// TODO: event types
|
|
@@ -438,7 +603,8 @@ function fromEventObservable(lazyObservable) {
|
|
|
438
603
|
},
|
|
439
604
|
start: (state, {
|
|
440
605
|
self,
|
|
441
|
-
system
|
|
606
|
+
system,
|
|
607
|
+
emit
|
|
442
608
|
}) => {
|
|
443
609
|
if (state.status === 'done') {
|
|
444
610
|
// Do not restart a completed observable
|
|
@@ -447,7 +613,8 @@ function fromEventObservable(lazyObservable) {
|
|
|
447
613
|
state._subscription = lazyObservable({
|
|
448
614
|
input: state.input,
|
|
449
615
|
system,
|
|
450
|
-
self
|
|
616
|
+
self,
|
|
617
|
+
emit
|
|
451
618
|
}).subscribe({
|
|
452
619
|
next: value => {
|
|
453
620
|
if (self._parent) {
|
|
@@ -481,27 +648,61 @@ function fromEventObservable(lazyObservable) {
|
|
|
481
648
|
|
|
482
649
|
const XSTATE_PROMISE_RESOLVE = 'xstate.promise.resolve';
|
|
483
650
|
const XSTATE_PROMISE_REJECT = 'xstate.promise.reject';
|
|
651
|
+
|
|
652
|
+
/**
|
|
653
|
+
* Represents an actor created by `fromPromise`.
|
|
654
|
+
*
|
|
655
|
+
* The type of `self` within the actor's logic.
|
|
656
|
+
*
|
|
657
|
+
* @example
|
|
658
|
+
*
|
|
659
|
+
* ```ts
|
|
660
|
+
* import { fromPromise, createActor } from 'xstate';
|
|
661
|
+
*
|
|
662
|
+
* // The actor's resolved output
|
|
663
|
+
* type Output = string;
|
|
664
|
+
* // The actor's input.
|
|
665
|
+
* type Input = { message: string };
|
|
666
|
+
*
|
|
667
|
+
* // Actor logic that fetches the url of an image of a cat saying `input.message`.
|
|
668
|
+
* const logic = fromPromise<Output, Input>(async ({ input, self }) => {
|
|
669
|
+
* self;
|
|
670
|
+
* // ^? PromiseActorRef<Output, Input>
|
|
671
|
+
*
|
|
672
|
+
* const data = await fetch(
|
|
673
|
+
* `https://cataas.com/cat/says/${input.message}`
|
|
674
|
+
* );
|
|
675
|
+
* const url = await data.json();
|
|
676
|
+
* return url;
|
|
677
|
+
* });
|
|
678
|
+
*
|
|
679
|
+
* const actor = createActor(logic, { input: { message: 'hello world' } });
|
|
680
|
+
* // ^? PromiseActorRef<Output, Input>
|
|
681
|
+
* ```
|
|
682
|
+
*
|
|
683
|
+
* @see {@link fromPromise}
|
|
684
|
+
*/
|
|
685
|
+
|
|
686
|
+
const controllerMap = new WeakMap();
|
|
687
|
+
|
|
484
688
|
/**
|
|
485
|
-
* An actor logic creator which returns promise logic as defined by an async
|
|
689
|
+
* An actor logic creator which returns promise logic as defined by an async
|
|
690
|
+
* process that resolves or rejects after some time.
|
|
486
691
|
*
|
|
487
692
|
* Actors created from promise actor logic (“promise actors”) can:
|
|
693
|
+
*
|
|
488
694
|
* - Emit the resolved value of the promise
|
|
489
695
|
* - Output the resolved value of the promise
|
|
490
696
|
*
|
|
491
697
|
* Sending events to promise actors will have no effect.
|
|
492
698
|
*
|
|
493
|
-
* @param promiseCreator
|
|
494
|
-
* A function which returns a Promise, and accepts an object with the following properties:
|
|
495
|
-
* - `input` - Data that was provided to the promise actor
|
|
496
|
-
* - `self` - The parent actor of the promise actor
|
|
497
|
-
* - `system` - The actor system to which the promise actor belongs
|
|
498
|
-
* @see {@link https://stately.ai/docs/input | Input docs} for more information about how input is passed
|
|
499
|
-
*
|
|
500
699
|
* @example
|
|
700
|
+
*
|
|
501
701
|
* ```ts
|
|
502
702
|
* const promiseLogic = fromPromise(async () => {
|
|
503
|
-
* const result = await fetch('https://example.com/...')
|
|
504
|
-
*
|
|
703
|
+
* const result = await fetch('https://example.com/...').then((data) =>
|
|
704
|
+
* data.json()
|
|
705
|
+
* );
|
|
505
706
|
*
|
|
506
707
|
* return result;
|
|
507
708
|
* });
|
|
@@ -524,9 +725,16 @@ const XSTATE_PROMISE_REJECT = 'xstate.promise.reject';
|
|
|
524
725
|
* // ...
|
|
525
726
|
* // }
|
|
526
727
|
* ```
|
|
728
|
+
*
|
|
729
|
+
* @param promiseCreator A function which returns a Promise, and accepts an
|
|
730
|
+
* object with the following properties:
|
|
731
|
+
*
|
|
732
|
+
* - `input` - Data that was provided to the promise actor
|
|
733
|
+
* - `self` - The parent actor of the promise actor
|
|
734
|
+
* - `system` - The actor system to which the promise actor belongs
|
|
735
|
+
*
|
|
736
|
+
* @see {@link https://stately.ai/docs/input | Input docs} for more information about how input is passed
|
|
527
737
|
*/
|
|
528
|
-
|
|
529
|
-
const controllerMap = new WeakMap();
|
|
530
738
|
function fromPromise(promiseCreator) {
|
|
531
739
|
const logic = {
|
|
532
740
|
config: promiseCreator,
|
|
@@ -567,7 +775,8 @@ function fromPromise(promiseCreator) {
|
|
|
567
775
|
},
|
|
568
776
|
start: (state, {
|
|
569
777
|
self,
|
|
570
|
-
system
|
|
778
|
+
system,
|
|
779
|
+
emit
|
|
571
780
|
}) => {
|
|
572
781
|
// TODO: determine how to allow customizing this so that promises
|
|
573
782
|
// can be restarted if necessary
|
|
@@ -580,7 +789,8 @@ function fromPromise(promiseCreator) {
|
|
|
580
789
|
input: state.input,
|
|
581
790
|
system,
|
|
582
791
|
self,
|
|
583
|
-
signal: controller.signal
|
|
792
|
+
signal: controller.signal,
|
|
793
|
+
emit
|
|
584
794
|
}));
|
|
585
795
|
resolvedPromise.then(response => {
|
|
586
796
|
if (self.getSnapshot().status !== 'active') {
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
!function(t,s){"object"==typeof exports&&"undefined"!=typeof module?s(exports):"function"==typeof define&&define.amd?define(["exports"],s):s((t="undefined"!=typeof globalThis?globalThis:t||self).XStateActors={})}(this,(function(t){"use strict";class s{constructor(t){this._process=t,this._active=!1,this._current=null,this._last=null}start(){this._active=!0,this.flush()}clear(){this._current&&(this._current.next=null,this._last=this._current)}enqueue(t){const s={value:t,next:null};if(this._current)return this._last.next=s,void(this._last=s);this._current=s,this._last=s,this._active&&this.flush()}flush(){for(;this._current;){const t=this._current;this._process(t.value),this._current=t.next}this._last=null}}const e="xstate.stop";function i(){const t="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:window;if(t.__xstate__)return t.__xstate__}const o=t=>{const s=i();s&&s.register(t)};function r(t){setTimeout((()=>{throw t}))}const n="function"==typeof Symbol&&Symbol.observable||"@@observable";function a(t,s){return`${t.sessionId}.${s}`}let h=0;function c(t,s,e){const i="object"==typeof t,o=i?t:void 0;return{next:(i?t.next:t)?.bind(o),error:(i?t.error:s)?.bind(o),complete:(i?t.complete:e)?.bind(o)}}let p=function(t){return t[t.NotStarted=0]="NotStarted",t[t.Running=1]="Running",t[t.Stopped=2]="Stopped",t}({});const u={clock:{setTimeout:(t,s)=>setTimeout(t,s),clearTimeout:t=>clearTimeout(t)},logger:console.log.bind(console),devTools:!1};class d{constructor(t,e){this.logic=t,this._snapshot=void 0,this.clock=void 0,this.options=void 0,this.id=void 0,this.mailbox=new s(this._process.bind(this)),this.observers=new Set,this.eventListeners=new Map,this.logger=void 0,this._processingStatus=p.NotStarted,this._parent=void 0,this._syncSnapshot=void 0,this.ref=void 0,this._actorScope=void 0,this._systemId=void 0,this.sessionId=void 0,this.system=void 0,this._doneEvent=void 0,this.src=void 0,this._deferred=[];const i={...u,...e},{clock:o,logger:r,parent:n,syncSnapshot:d,id:l,systemId:_,inspect:v}=i;this.system=n?n.system:function(t,s){const e=new Map,i=new Map,o=new WeakMap,r=new Set,n={},{clock:c,logger:p}=s,u={schedule:(t,s,e,i,o=Math.random().toString(36).slice(2))=>{const r={source:t,target:s,event:e,delay:i,id:o,startedAt:Date.now()},h=a(t,o);d._snapshot._scheduledEvents[h]=r;const p=c.setTimeout((()=>{delete n[h],delete d._snapshot._scheduledEvents[h],d._relay(t,s,e)}),i);n[h]=p},cancel:(t,s)=>{const e=a(t,s),i=n[e];delete n[e],delete d._snapshot._scheduledEvents[e],c.clearTimeout(i)},cancelAll:t=>{for(const s in d._snapshot._scheduledEvents){const e=d._snapshot._scheduledEvents[s];e.source===t&&u.cancel(t,e.id)}}},d={_snapshot:{_scheduledEvents:(s?.snapshot&&s.snapshot.scheduler)??{}},_bookId:()=>"x:"+h++,_register:(t,s)=>(e.set(t,s),t),_unregister:t=>{e.delete(t.sessionId);const s=o.get(t);void 0!==s&&(i.delete(s),o.delete(t))},get:t=>i.get(t),_set:(t,s)=>{const e=i.get(t);if(e&&e!==s)throw new Error(`Actor with system ID '${t}' already exists.`);i.set(t,s),o.set(s,t)},inspect:t=>{r.add(t)},_sendInspectionEvent:s=>{if(!r.size)return;const e={...s,rootId:t.sessionId};r.forEach((t=>t.next?.(e)))},_relay:(t,s,e)=>{d._sendInspectionEvent({type:"@xstate.event",sourceRef:t,actorRef:s,event:e}),s._send(e)},scheduler:u,getSnapshot:()=>({_scheduledEvents:{...d._snapshot._scheduledEvents}}),start:()=>{const t=d._snapshot._scheduledEvents;d._snapshot._scheduledEvents={};for(const s in t){const{source:e,target:i,event:o,delay:r,id:n}=t[s];u.schedule(e,i,o,r,n)}},_clock:c,_logger:p};return d}(this,{clock:o,logger:r}),v&&!n&&this.system.inspect(c(v)),this.sessionId=this.system._bookId(),this.id=l??this.sessionId,this.logger=e?.logger??this.system._logger,this.clock=e?.clock??this.system._clock,this._parent=n,this._syncSnapshot=d,this.options=i,this.src=i.src??t,this.ref=this,this._actorScope={self:this,id:this.id,sessionId:this.sessionId,logger:this.logger,defer:t=>{this._deferred.push(t)},system:this.system,stopChild:t=>{if(t._parent!==this)throw new Error(`Cannot stop child actor ${t.id} of ${this.id} because it is not a child`);t._stop()},emit:t=>{const s=this.eventListeners.get(t.type),e=this.eventListeners.get("*");if(!s&&!e)return;const i=new Set([...s?s.values():[],...e?e.values():[]]);for(const s of Array.from(i))s(t)}},this.send=this.send.bind(this),this.system._sendInspectionEvent({type:"@xstate.actor",actorRef:this}),_&&(this._systemId=_,this.system._set(_,this)),this._initState(e?.snapshot??e?.state),_&&"active"!==this._snapshot.status&&this.system._unregister(this)}_initState(t){try{this._snapshot=t?this.logic.restoreSnapshot?this.logic.restoreSnapshot(t,this._actorScope):t:this.logic.getInitialSnapshot(this._actorScope,this.options?.input)}catch(t){this._snapshot={status:"error",output:void 0,error:t}}}update(t,s){let e;for(this._snapshot=t;e=this._deferred.shift();)try{e()}catch(s){this._deferred.length=0,this._snapshot={...t,status:"error",error:s}}switch(this._snapshot.status){case"active":for(const s of this.observers)try{s.next?.(t)}catch(t){r(t)}break;case"done":for(const s of this.observers)try{s.next?.(t)}catch(t){r(t)}this._stopProcedure(),this._complete(),this._doneEvent=(i=this.id,o=this._snapshot.output,{type:`xstate.done.actor.${i}`,output:o}),this._parent&&this.system._relay(this,this._parent,this._doneEvent);break;case"error":this._error(this._snapshot.error)}var i,o;this.system._sendInspectionEvent({type:"@xstate.snapshot",actorRef:this,event:s,snapshot:t})}subscribe(t,s,e){const i=c(t,s,e);if(this._processingStatus!==p.Stopped)this.observers.add(i);else switch(this._snapshot.status){case"done":try{i.complete?.()}catch(t){r(t)}break;case"error":{const t=this._snapshot.error;if(i.error)try{i.error(t)}catch(t){r(t)}else r(t);break}}return{unsubscribe:()=>{this.observers.delete(i)}}}on(t,s){let e=this.eventListeners.get(t);e||(e=new Set,this.eventListeners.set(t,e));const i=s.bind(void 0);return e.add(i),{unsubscribe:()=>{e.delete(i)}}}start(){if(this._processingStatus===p.Running)return this;this._syncSnapshot&&this.subscribe({next:t=>{"active"===t.status&&this.system._relay(this,this._parent,{type:`xstate.snapshot.${this.id}`,snapshot:t})},error:()=>{}}),this.system._register(this.sessionId,this),this._systemId&&this.system._set(this._systemId,this),this._processingStatus=p.Running;const t={type:"xstate.init",input:this.options.input};this.system._sendInspectionEvent({type:"@xstate.event",sourceRef:this._parent,actorRef:this,event:t});switch(this._snapshot.status){case"done":return this.update(this._snapshot,t),this;case"error":return this._error(this._snapshot.error),this}if(this._parent||this.system.start(),this.logic.start)try{this.logic.start(this._snapshot,this._actorScope)}catch(t){return this._snapshot={...this._snapshot,status:"error",error:t},this._error(t),this}return this.update(this._snapshot,t),this.options.devTools&&this.attachDevTools(),this.mailbox.start(),this}_process(t){let s,i;try{s=this.logic.transition(this._snapshot,t,this._actorScope)}catch(t){i={err:t}}if(i){const{err:t}=i;return this._snapshot={...this._snapshot,status:"error",error:t},void this._error(t)}this.update(s,t),t.type===e&&(this._stopProcedure(),this._complete())}_stop(){return this._processingStatus===p.Stopped?this:(this.mailbox.clear(),this._processingStatus===p.NotStarted?(this._processingStatus=p.Stopped,this):(this.mailbox.enqueue({type:e}),this))}stop(){if(this._parent)throw new Error("A non-root actor cannot be stopped directly.");return this._stop()}_complete(){for(const t of this.observers)try{t.complete?.()}catch(t){r(t)}this.observers.clear()}_reportError(t){if(!this.observers.size)return void(this._parent||r(t));let s=!1;for(const e of this.observers){const i=e.error;s||=!i;try{i?.(t)}catch(t){r(t)}}this.observers.clear(),s&&r(t)}_error(t){this._stopProcedure(),this._reportError(t),this._parent&&this.system._relay(this,this._parent,{type:`xstate.error.actor.${this.id}`,error:t})}_stopProcedure(){return this._processingStatus!==p.Running||(this.system.scheduler.cancelAll(this),this.mailbox.clear(),this.mailbox=new s(this._process.bind(this)),this._processingStatus=p.Stopped,this.system._unregister(this)),this}_send(t){this._processingStatus!==p.Stopped&&this.mailbox.enqueue(t)}send(t){this.system._relay(void 0,this,t)}attachDevTools(){const{devTools:t}=this.options;if(t){("function"==typeof t?t:o)(this)}}toJSON(){return{xstate$$type:1,id:this.id}}getPersistedSnapshot(t){return this.logic.getPersistedSnapshot(this._snapshot,t)}[n](){return this}getSnapshot(){return this._snapshot}}function l(t,s){return{config:t,transition:(s,e,i)=>({...s,context:t(s.context,e,i)}),getInitialSnapshot:(t,e)=>({status:"active",output:void 0,error:void 0,context:"function"==typeof s?s({input:e}):s}),getPersistedSnapshot:t=>t,restoreSnapshot:t=>t}}const _=new WeakMap;const v="xstate.observable.next",f="xstate.observable.error",y="xstate.observable.complete";const g="xstate.promise.resolve",b="xstate.promise.reject",m=new WeakMap;const S=l((t=>{}),void 0);t.createEmptyActor=function(){return function(t,...[s]){return new d(t,s)}(S)},t.fromCallback=function(t){return{config:t,start:(s,e)=>{const{self:i,system:o}=e,r={receivers:void 0,dispose:void 0};_.set(i,r),r.dispose=t({input:s.input,system:o,self:i,sendBack:t=>{"stopped"!==i.getSnapshot().status&&i._parent&&o._relay(i,i._parent,t)},receive:t=>{r.receivers??=new Set,r.receivers.add(t)}})},transition:(t,s,i)=>{const o=_.get(i.self);return s.type===e?(t={...t,status:"stopped",error:void 0},o.dispose?.(),t):(o.receivers?.forEach((t=>t(s))),t)},getInitialSnapshot:(t,s)=>({status:"active",output:void 0,error:void 0,input:s}),getPersistedSnapshot:t=>t,restoreSnapshot:t=>t}},t.fromEventObservable=function(t){return{config:t,transition:(t,s)=>{if("active"!==t.status)return t;switch(s.type){case f:return{...t,status:"error",error:s.data,input:void 0,_subscription:void 0};case y:return{...t,status:"done",input:void 0,_subscription:void 0};case e:return t._subscription.unsubscribe(),{...t,status:"stopped",input:void 0,_subscription:void 0};default:return t}},getInitialSnapshot:(t,s)=>({status:"active",output:void 0,error:void 0,context:void 0,input:s,_subscription:void 0}),start:(s,{self:e,system:i})=>{"done"!==s.status&&(s._subscription=t({input:s.input,system:i,self:e}).subscribe({next:t=>{e._parent&&i._relay(e,e._parent,t)},error:t=>{i._relay(e,e,{type:f,data:t})},complete:()=>{i._relay(e,e,{type:y})}}))},getPersistedSnapshot:({_subscription:t,...s})=>s,restoreSnapshot:t=>({...t,_subscription:void 0})}},t.fromObservable=function(t){return{config:t,transition:(t,s,{self:i,id:o,defer:r,system:n})=>{if("active"!==t.status)return t;switch(s.type){case v:return{...t,context:s.data};case f:return{...t,status:"error",error:s.data,input:void 0,_subscription:void 0};case y:return{...t,status:"done",input:void 0,_subscription:void 0};case e:return t._subscription.unsubscribe(),{...t,status:"stopped",input:void 0,_subscription:void 0};default:return t}},getInitialSnapshot:(t,s)=>({status:"active",output:void 0,error:void 0,context:void 0,input:s,_subscription:void 0}),start:(s,{self:e,system:i})=>{"done"!==s.status&&(s._subscription=t({input:s.input,system:i,self:e}).subscribe({next:t=>{i._relay(e,e,{type:v,data:t})},error:t=>{i._relay(e,e,{type:f,data:t})},complete:()=>{i._relay(e,e,{type:y})}}))},getPersistedSnapshot:({_subscription:t,...s})=>s,restoreSnapshot:t=>({...t,_subscription:void 0})}},t.fromPromise=function(t){return{config:t,transition:(t,s,i)=>{if("active"!==t.status)return t;switch(s.type){case g:{const e=s.data;return{...t,status:"done",output:e,input:void 0}}case b:return{...t,status:"error",error:s.data,input:void 0};case e:return m.get(i.self)?.abort(),{...t,status:"stopped",input:void 0};default:return t}},start:(s,{self:e,system:i})=>{if("active"!==s.status)return;const o=new AbortController;m.set(e,o);Promise.resolve(t({input:s.input,system:i,self:e,signal:o.signal})).then((t=>{"active"===e.getSnapshot().status&&(m.delete(e),i._relay(e,e,{type:g,data:t}))}),(t=>{"active"===e.getSnapshot().status&&(m.delete(e),i._relay(e,e,{type:b,data:t}))}))},getInitialSnapshot:(t,s)=>({status:"active",output:void 0,error:void 0,input:s}),getPersistedSnapshot:t=>t,restoreSnapshot:t=>t}},t.fromTransition=l,Object.defineProperty(t,"__esModule",{value:!0})}));
|
|
1
|
+
!function(t,s){"object"==typeof exports&&"undefined"!=typeof module?s(exports):"function"==typeof define&&define.amd?define(["exports"],s):s((t="undefined"!=typeof globalThis?globalThis:t||self).XStateActors={})}(this,(function(t){"use strict";class s{constructor(t){this._process=t,this._active=!1,this._current=null,this._last=null}start(){this._active=!0,this.flush()}clear(){this._current&&(this._current.next=null,this._last=this._current)}enqueue(t){const s={value:t,next:null};if(this._current)return this._last.next=s,void(this._last=s);this._current=s,this._last=s,this._active&&this.flush()}flush(){for(;this._current;){const t=this._current;this._process(t.value),this._current=t.next}this._last=null}}const e="xstate.stop";function i(){const t="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:window;if(t.__xstate__)return t.__xstate__}const r=t=>{const s=i();s&&s.register(t)};function o(t){setTimeout((()=>{throw t}))}const n="function"==typeof Symbol&&Symbol.observable||"@@observable";function a(t,s,e){const i="object"==typeof t,r=i?t:void 0;return{next:(i?t.next:t)?.bind(r),error:(i?t.error:s)?.bind(r),complete:(i?t.complete:e)?.bind(r)}}function h(t,s){return`${t.sessionId}.${s}`}let c=0;let p=function(t){return t[t.NotStarted=0]="NotStarted",t[t.Running=1]="Running",t[t.Stopped=2]="Stopped",t}({});const u={clock:{setTimeout:(t,s)=>setTimeout(t,s),clearTimeout:t=>clearTimeout(t)},logger:console.log.bind(console),devTools:!1};class d{constructor(t,e){this.logic=t,this._snapshot=void 0,this.clock=void 0,this.options=void 0,this.id=void 0,this.mailbox=new s(this._process.bind(this)),this.observers=new Set,this.eventListeners=new Map,this.logger=void 0,this._processingStatus=p.NotStarted,this._parent=void 0,this._syncSnapshot=void 0,this.ref=void 0,this._actorScope=void 0,this._systemId=void 0,this.sessionId=void 0,this.system=void 0,this._doneEvent=void 0,this.src=void 0,this._deferred=[];const i={...u,...e},{clock:r,logger:o,parent:n,syncSnapshot:d,id:l,systemId:_,inspect:v}=i;this.system=n?n.system:function(t,s){const e=new Map,i=new Map,r=new WeakMap,o=new Set,n={},{clock:p,logger:u}=s,d={schedule:(t,s,e,i,r=Math.random().toString(36).slice(2))=>{const o={source:t,target:s,event:e,delay:i,id:r,startedAt:Date.now()},a=h(t,r);l._snapshot._scheduledEvents[a]=o;const c=p.setTimeout((()=>{delete n[a],delete l._snapshot._scheduledEvents[a],l._relay(t,s,e)}),i);n[a]=c},cancel:(t,s)=>{const e=h(t,s),i=n[e];delete n[e],delete l._snapshot._scheduledEvents[e],p.clearTimeout(i)},cancelAll:t=>{for(const s in l._snapshot._scheduledEvents){const e=l._snapshot._scheduledEvents[s];e.source===t&&d.cancel(t,e.id)}}},l={_snapshot:{_scheduledEvents:(s?.snapshot&&s.snapshot.scheduler)??{}},_bookId:()=>"x:"+c++,_register:(t,s)=>(e.set(t,s),t),_unregister:t=>{e.delete(t.sessionId);const s=r.get(t);void 0!==s&&(i.delete(s),r.delete(t))},get:t=>i.get(t),_set:(t,s)=>{const e=i.get(t);if(e&&e!==s)throw new Error(`Actor with system ID '${t}' already exists.`);i.set(t,s),r.set(s,t)},inspect:t=>{const s=a(t);return o.add(s),{unsubscribe(){o.delete(s)}}},_sendInspectionEvent:s=>{if(!o.size)return;const e={...s,rootId:t.sessionId};o.forEach((t=>t.next?.(e)))},_relay:(t,s,e)=>{l._sendInspectionEvent({type:"@xstate.event",sourceRef:t,actorRef:s,event:e}),s._send(e)},scheduler:d,getSnapshot:()=>({_scheduledEvents:{...l._snapshot._scheduledEvents}}),start:()=>{const t=l._snapshot._scheduledEvents;l._snapshot._scheduledEvents={};for(const s in t){const{source:e,target:i,event:r,delay:o,id:n}=t[s];d.schedule(e,i,r,o,n)}},_clock:p,_logger:u};return l}(this,{clock:r,logger:o}),v&&!n&&this.system.inspect(a(v)),this.sessionId=this.system._bookId(),this.id=l??this.sessionId,this.logger=e?.logger??this.system._logger,this.clock=e?.clock??this.system._clock,this._parent=n,this._syncSnapshot=d,this.options=i,this.src=i.src??t,this.ref=this,this._actorScope={self:this,id:this.id,sessionId:this.sessionId,logger:this.logger,defer:t=>{this._deferred.push(t)},system:this.system,stopChild:t=>{if(t._parent!==this)throw new Error(`Cannot stop child actor ${t.id} of ${this.id} because it is not a child`);t._stop()},emit:t=>{const s=this.eventListeners.get(t.type),e=this.eventListeners.get("*");if(!s&&!e)return;const i=new Set([...s?s.values():[],...e?e.values():[]]);for(const s of Array.from(i))s(t)}},this.send=this.send.bind(this),this.system._sendInspectionEvent({type:"@xstate.actor",actorRef:this}),_&&(this._systemId=_,this.system._set(_,this)),this._initState(e?.snapshot??e?.state),_&&"active"!==this._snapshot.status&&this.system._unregister(this)}_initState(t){try{this._snapshot=t?this.logic.restoreSnapshot?this.logic.restoreSnapshot(t,this._actorScope):t:this.logic.getInitialSnapshot(this._actorScope,this.options?.input)}catch(t){this._snapshot={status:"error",output:void 0,error:t}}}update(t,s){let e;for(this._snapshot=t;e=this._deferred.shift();)try{e()}catch(s){this._deferred.length=0,this._snapshot={...t,status:"error",error:s}}switch(this._snapshot.status){case"active":for(const s of this.observers)try{s.next?.(t)}catch(t){o(t)}break;case"done":for(const s of this.observers)try{s.next?.(t)}catch(t){o(t)}this._stopProcedure(),this._complete(),this._doneEvent=(i=this.id,r=this._snapshot.output,{type:`xstate.done.actor.${i}`,output:r,actorId:i}),this._parent&&this.system._relay(this,this._parent,this._doneEvent);break;case"error":this._error(this._snapshot.error)}var i,r;this.system._sendInspectionEvent({type:"@xstate.snapshot",actorRef:this,event:s,snapshot:t})}subscribe(t,s,e){const i=a(t,s,e);if(this._processingStatus!==p.Stopped)this.observers.add(i);else switch(this._snapshot.status){case"done":try{i.complete?.()}catch(t){o(t)}break;case"error":{const t=this._snapshot.error;if(i.error)try{i.error(t)}catch(t){o(t)}else o(t);break}}return{unsubscribe:()=>{this.observers.delete(i)}}}on(t,s){let e=this.eventListeners.get(t);e||(e=new Set,this.eventListeners.set(t,e));const i=s.bind(void 0);return e.add(i),{unsubscribe:()=>{e.delete(i)}}}start(){if(this._processingStatus===p.Running)return this;this._syncSnapshot&&this.subscribe({next:t=>{"active"===t.status&&this.system._relay(this,this._parent,{type:`xstate.snapshot.${this.id}`,snapshot:t})},error:()=>{}}),this.system._register(this.sessionId,this),this._systemId&&this.system._set(this._systemId,this),this._processingStatus=p.Running;const t={type:"xstate.init",input:this.options.input};this.system._sendInspectionEvent({type:"@xstate.event",sourceRef:this._parent,actorRef:this,event:t});switch(this._snapshot.status){case"done":return this.update(this._snapshot,t),this;case"error":return this._error(this._snapshot.error),this}if(this._parent||this.system.start(),this.logic.start)try{this.logic.start(this._snapshot,this._actorScope)}catch(t){return this._snapshot={...this._snapshot,status:"error",error:t},this._error(t),this}return this.update(this._snapshot,t),this.options.devTools&&this.attachDevTools(),this.mailbox.start(),this}_process(t){let s,i;try{s=this.logic.transition(this._snapshot,t,this._actorScope)}catch(t){i={err:t}}if(i){const{err:t}=i;return this._snapshot={...this._snapshot,status:"error",error:t},void this._error(t)}this.update(s,t),t.type===e&&(this._stopProcedure(),this._complete())}_stop(){return this._processingStatus===p.Stopped?this:(this.mailbox.clear(),this._processingStatus===p.NotStarted?(this._processingStatus=p.Stopped,this):(this.mailbox.enqueue({type:e}),this))}stop(){if(this._parent)throw new Error("A non-root actor cannot be stopped directly.");return this._stop()}_complete(){for(const t of this.observers)try{t.complete?.()}catch(t){o(t)}this.observers.clear()}_reportError(t){if(!this.observers.size)return void(this._parent||o(t));let s=!1;for(const e of this.observers){const i=e.error;s||=!i;try{i?.(t)}catch(t){o(t)}}this.observers.clear(),s&&o(t)}_error(t){var s;this._stopProcedure(),this._reportError(t),this._parent&&this.system._relay(this,this._parent,{type:`xstate.error.actor.${s=this.id}`,error:t,actorId:s})}_stopProcedure(){return this._processingStatus!==p.Running||(this.system.scheduler.cancelAll(this),this.mailbox.clear(),this.mailbox=new s(this._process.bind(this)),this._processingStatus=p.Stopped,this.system._unregister(this)),this}_send(t){this._processingStatus!==p.Stopped&&this.mailbox.enqueue(t)}send(t){this.system._relay(void 0,this,t)}attachDevTools(){const{devTools:t}=this.options;if(t){("function"==typeof t?t:r)(this)}}toJSON(){return{xstate$$type:1,id:this.id}}getPersistedSnapshot(t){return this.logic.getPersistedSnapshot(this._snapshot,t)}[n](){return this}getSnapshot(){return this._snapshot}}function l(t,s){return{config:t,transition:(s,e,i)=>({...s,context:t(s.context,e,i)}),getInitialSnapshot:(t,e)=>({status:"active",output:void 0,error:void 0,context:"function"==typeof s?s({input:e}):s}),getPersistedSnapshot:t=>t,restoreSnapshot:t=>t}}const _=new WeakMap;const v="xstate.observable.next",f="xstate.observable.error",y="xstate.observable.complete";const g="xstate.promise.resolve",b="xstate.promise.reject",m=new WeakMap;const S=l((t=>{}),void 0);t.createEmptyActor=function(){return function(t,...[s]){return new d(t,s)}(S)},t.fromCallback=function(t){return{config:t,start:(s,e)=>{const{self:i,system:r,emit:o}=e,n={receivers:void 0,dispose:void 0};_.set(i,n),n.dispose=t({input:s.input,system:r,self:i,sendBack:t=>{"stopped"!==i.getSnapshot().status&&i._parent&&r._relay(i,i._parent,t)},receive:t=>{n.receivers??=new Set,n.receivers.add(t)},emit:o})},transition:(t,s,i)=>{const r=_.get(i.self);return s.type===e?(t={...t,status:"stopped",error:void 0},r.dispose?.(),t):(r.receivers?.forEach((t=>t(s))),t)},getInitialSnapshot:(t,s)=>({status:"active",output:void 0,error:void 0,input:s}),getPersistedSnapshot:t=>t,restoreSnapshot:t=>t}},t.fromEventObservable=function(t){return{config:t,transition:(t,s)=>{if("active"!==t.status)return t;switch(s.type){case f:return{...t,status:"error",error:s.data,input:void 0,_subscription:void 0};case y:return{...t,status:"done",input:void 0,_subscription:void 0};case e:return t._subscription.unsubscribe(),{...t,status:"stopped",input:void 0,_subscription:void 0};default:return t}},getInitialSnapshot:(t,s)=>({status:"active",output:void 0,error:void 0,context:void 0,input:s,_subscription:void 0}),start:(s,{self:e,system:i,emit:r})=>{"done"!==s.status&&(s._subscription=t({input:s.input,system:i,self:e,emit:r}).subscribe({next:t=>{e._parent&&i._relay(e,e._parent,t)},error:t=>{i._relay(e,e,{type:f,data:t})},complete:()=>{i._relay(e,e,{type:y})}}))},getPersistedSnapshot:({_subscription:t,...s})=>s,restoreSnapshot:t=>({...t,_subscription:void 0})}},t.fromObservable=function(t){return{config:t,transition:(t,s)=>{if("active"!==t.status)return t;switch(s.type){case v:return{...t,context:s.data};case f:return{...t,status:"error",error:s.data,input:void 0,_subscription:void 0};case y:return{...t,status:"done",input:void 0,_subscription:void 0};case e:return t._subscription.unsubscribe(),{...t,status:"stopped",input:void 0,_subscription:void 0};default:return t}},getInitialSnapshot:(t,s)=>({status:"active",output:void 0,error:void 0,context:void 0,input:s,_subscription:void 0}),start:(s,{self:e,system:i,emit:r})=>{"done"!==s.status&&(s._subscription=t({input:s.input,system:i,self:e,emit:r}).subscribe({next:t=>{i._relay(e,e,{type:v,data:t})},error:t=>{i._relay(e,e,{type:f,data:t})},complete:()=>{i._relay(e,e,{type:y})}}))},getPersistedSnapshot:({_subscription:t,...s})=>s,restoreSnapshot:t=>({...t,_subscription:void 0})}},t.fromPromise=function(t){return{config:t,transition:(t,s,i)=>{if("active"!==t.status)return t;switch(s.type){case g:{const e=s.data;return{...t,status:"done",output:e,input:void 0}}case b:return{...t,status:"error",error:s.data,input:void 0};case e:return m.get(i.self)?.abort(),{...t,status:"stopped",input:void 0};default:return t}},start:(s,{self:e,system:i,emit:r})=>{if("active"!==s.status)return;const o=new AbortController;m.set(e,o);Promise.resolve(t({input:s.input,system:i,self:e,signal:o.signal,emit:r})).then((t=>{"active"===e.getSnapshot().status&&(m.delete(e),i._relay(e,e,{type:g,data:t}))}),(t=>{"active"===e.getSnapshot().status&&(m.delete(e),i._relay(e,e,{type:b,data:t}))}))},getInitialSnapshot:(t,s)=>({status:"active",output:void 0,error:void 0,input:s}),getPersistedSnapshot:t=>t,restoreSnapshot:t=>t}},t.fromTransition=l,Object.defineProperty(t,"__esModule",{value:!0})}));
|
|
2
2
|
//# sourceMappingURL=xstate-actors.umd.min.js.map
|