@xmachines/play-xstate 1.0.0 → 1.1.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/README.md +32 -14
- package/dist/errors.d.ts +46 -32
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +69 -32
- package/dist/errors.js.map +1 -1
- package/dist/guards/compose.d.ts +8 -0
- package/dist/guards/compose.d.ts.map +1 -1
- package/dist/guards/compose.js +7 -2
- package/dist/guards/compose.js.map +1 -1
- package/dist/guards/helpers.d.ts +6 -2
- package/dist/guards/helpers.d.ts.map +1 -1
- package/dist/guards/helpers.js +6 -2
- package/dist/guards/helpers.js.map +1 -1
- package/dist/guards/index.d.ts +7 -0
- package/dist/guards/index.d.ts.map +1 -1
- package/dist/guards/index.js +7 -0
- package/dist/guards/index.js.map +1 -1
- package/dist/guards/types.d.ts +4 -5
- package/dist/guards/types.d.ts.map +1 -1
- package/dist/player-actor.d.ts +105 -39
- package/dist/player-actor.d.ts.map +1 -1
- package/dist/player-actor.js +312 -318
- package/dist/player-actor.js.map +1 -1
- package/dist/routing/build-url.d.ts +2 -7
- package/dist/routing/build-url.d.ts.map +1 -1
- package/dist/routing/build-url.js +21 -25
- package/dist/routing/build-url.js.map +1 -1
- package/dist/routing/derive-current-route.d.ts +32 -0
- package/dist/routing/derive-current-route.d.ts.map +1 -1
- package/dist/routing/derive-current-route.js +20 -19
- package/dist/routing/derive-current-route.js.map +1 -1
- package/dist/routing/derive-initial-route.d.ts +0 -3
- package/dist/routing/derive-initial-route.d.ts.map +1 -1
- package/dist/routing/derive-initial-route.js +0 -3
- package/dist/routing/derive-initial-route.js.map +1 -1
- package/dist/routing/index.d.ts +1 -1
- package/dist/routing/index.d.ts.map +1 -1
- package/dist/routing/index.js +1 -1
- package/dist/routing/index.js.map +1 -1
- package/dist/types.d.ts +86 -13
- package/dist/types.d.ts.map +1 -1
- package/dist/view/derive-current-view.d.ts +54 -0
- package/dist/view/derive-current-view.d.ts.map +1 -0
- package/dist/view/derive-current-view.js +167 -0
- package/dist/view/derive-current-view.js.map +1 -0
- package/package.json +11 -14
- package/dist/define-player.typecheck.d.ts +0 -2
- package/dist/define-player.typecheck.d.ts.map +0 -1
- package/dist/define-player.typecheck.js +0 -48
- package/dist/define-player.typecheck.js.map +0 -1
- package/dist/player-actor.typecheck.d.ts +0 -2
- package/dist/player-actor.typecheck.d.ts.map +0 -1
- package/dist/player-actor.typecheck.js +0 -27
- package/dist/player-actor.typecheck.js.map +0 -1
package/dist/player-actor.d.ts
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Actor, type AnyStateMachine, type AnyActorLogic, type EmittedFrom, type InputFrom, type ActorOptions, type Observer, type Snapshot, type SnapshotFrom, type Subscription, type EventFromLogic } from "xstate";
|
|
2
2
|
import { AbstractActor, type Routable, type Viewable, type PlaySpec } from "@xmachines/play-actor";
|
|
3
3
|
import { Signal } from "@xmachines/play-signals";
|
|
4
4
|
import type { PlayerOptions } from "./types.js";
|
|
5
5
|
/**
|
|
6
6
|
* Concrete XState actor implementing Play Architecture signal protocol
|
|
7
7
|
*
|
|
8
|
-
* Extends {@link @xmachines/play-actor!AbstractActor}
|
|
9
|
-
* while maintaining ecosystem compatibility (XState
|
|
10
|
-
*
|
|
11
|
-
*
|
|
8
|
+
* Extends {@link @xmachines/play-actor!AbstractActor} — and so XState's own `Actor` —
|
|
9
|
+
* to provide XState v5 integration while maintaining ecosystem compatibility (XState
|
|
10
|
+
* inspection, devtools). The machine is handed to the base constructor, so a
|
|
11
|
+
* `PlayerActor` **is** the XState actor rather than a wrapper around one: everything
|
|
12
|
+
* XState's `Actor` exposes operates on this instance's own state, and the class adds
|
|
13
|
+
* TC39 Signal-based reactive state for Infrastructure observation on top.
|
|
12
14
|
*
|
|
13
15
|
* **Capabilities:** Implements both {@link @xmachines/play-actor!Routable} and
|
|
14
16
|
* {@link @xmachines/play-actor!Viewable} interfaces, providing routing and view
|
|
@@ -31,7 +33,14 @@ import type { PlayerOptions } from "./types.js";
|
|
|
31
33
|
* initial: 'idle',
|
|
32
34
|
* states: {
|
|
33
35
|
* idle: {
|
|
34
|
-
* meta: {
|
|
36
|
+
* meta: {
|
|
37
|
+
* route: '/',
|
|
38
|
+
* // A view spec needs `root` and `elements` — other shapes derive null.
|
|
39
|
+
* view: {
|
|
40
|
+
* root: 'home',
|
|
41
|
+
* elements: { home: { type: 'HomePage', props: {}, children: [] } },
|
|
42
|
+
* },
|
|
43
|
+
* },
|
|
35
44
|
* }
|
|
36
45
|
* }
|
|
37
46
|
* });
|
|
@@ -41,8 +50,8 @@ import type { PlayerOptions } from "./types.js";
|
|
|
41
50
|
* actor.start();
|
|
42
51
|
*
|
|
43
52
|
* // Observe signals
|
|
44
|
-
* console.log(actor.currentRoute.get());
|
|
45
|
-
* console.log(actor.currentView.get());
|
|
53
|
+
* console.log(actor.currentRoute.get()); // '/'
|
|
54
|
+
* console.log(actor.currentView.get()?.root); // 'home'
|
|
46
55
|
* ```
|
|
47
56
|
*
|
|
48
57
|
* @example
|
|
@@ -78,17 +87,63 @@ import type { PlayerOptions } from "./types.js";
|
|
|
78
87
|
* cached and updated at state entry, not computed on every read.
|
|
79
88
|
*/
|
|
80
89
|
export declare class PlayerActor<TMachine extends AnyStateMachine> extends AbstractActor<AnyActorLogic, EventFromLogic<TMachine>> implements Routable, Viewable {
|
|
81
|
-
private
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
90
|
+
private playerOptions?;
|
|
91
|
+
/**
|
|
92
|
+
* Whether this constructor has returned.
|
|
93
|
+
*
|
|
94
|
+
* XState hands the actor to a context factory as `self`, and to an
|
|
95
|
+
* `inspect` observer as `actorRef`, from inside its own constructor — where
|
|
96
|
+
* none of this class's fields exist yet and XState itself refuses to read
|
|
97
|
+
* the snapshot ("Snapshot can't be read while the actor initializes
|
|
98
|
+
* itself"). Anything reachable from that window has to check this first.
|
|
99
|
+
*/
|
|
100
|
+
private constructed?;
|
|
101
|
+
/**
|
|
102
|
+
* The caller's live options bag, or an empty one during construction.
|
|
103
|
+
*
|
|
104
|
+
* XState hands this actor to a context factory as `self` and to an
|
|
105
|
+
* `inspect` observer as `actorRef` from inside its own constructor, before
|
|
106
|
+
* any field here is assigned. Reading hooks through this accessor keeps
|
|
107
|
+
* that window from throwing — a throw would be caught by XState's
|
|
108
|
+
* initialization and parked as an error snapshot — while preserving the
|
|
109
|
+
* read-at-delivery-time behaviour the bag's own docs promise.
|
|
110
|
+
*
|
|
111
|
+
* The window-sensitive fields below are `declare`d for the same reason.
|
|
112
|
+
* This target compiles class fields to `Object.defineProperty`, which runs
|
|
113
|
+
* after `super()` returns: a plain declaration — initializer or not — would
|
|
114
|
+
* reset anything the window had written back to `undefined`. `declare`
|
|
115
|
+
* emits nothing, so those writes survive.
|
|
116
|
+
*/
|
|
117
|
+
private get hooks();
|
|
118
|
+
/**
|
|
119
|
+
* Real lifecycle transitions, so onStart/onStop fire once each. XState's
|
|
120
|
+
* own status is internal, and a machine snapshot already reads "active"
|
|
121
|
+
* before start(), so neither can distinguish not-yet-started from running.
|
|
122
|
+
*/
|
|
123
|
+
private lifecycle?;
|
|
124
|
+
/**
|
|
125
|
+
* Userland subscriptions without an error listener. XState's dispatch
|
|
126
|
+
* rethrows an actor error globally on their behalf (once per delivery, a
|
|
127
|
+
* shared flag), so while one is active the internal error listener's own
|
|
128
|
+
* loud-default rethrow must stand down — or the same error is reported
|
|
129
|
+
* twice.
|
|
130
|
+
*/
|
|
131
|
+
private nextOnlySubscriptions?;
|
|
132
|
+
/**
|
|
133
|
+
* The last snapshot the view pipeline processed. XState notifies observers
|
|
134
|
+
* on EVERY processed event — an ignored event redelivers the identical
|
|
135
|
+
* snapshot — and deriveCurrentView is pure in the snapshot, so an identical
|
|
136
|
+
* reference cannot change the outcome. Seeded with undefined (never a
|
|
137
|
+
* snapshot): the construction-time snapshot is reference-identical to the
|
|
138
|
+
* one start() replays, and seeding with it would suppress the initial view.
|
|
139
|
+
*/
|
|
140
|
+
private lastViewSnapshot;
|
|
86
141
|
state: Signal.State<ReturnType<TMachine["transition"]>>;
|
|
87
142
|
/**
|
|
88
143
|
* Returns whether the actor's current state can accept the given event.
|
|
89
144
|
*
|
|
90
145
|
* Typed to the machine's event union — passing an unknown event type is a
|
|
91
|
-
* compile error.
|
|
146
|
+
* compile error. Evaluated against the current snapshot signal.
|
|
92
147
|
*
|
|
93
148
|
* @example
|
|
94
149
|
* ```typescript
|
|
@@ -101,16 +156,15 @@ export declare class PlayerActor<TMachine extends AnyStateMachine> extends Abstr
|
|
|
101
156
|
* machine state's `meta.route` template and the actor's context.
|
|
102
157
|
*
|
|
103
158
|
* Returns `null` when the current state has no `meta.route`, or when the route
|
|
104
|
-
* template cannot be fully resolved
|
|
105
|
-
*
|
|
106
|
-
*
|
|
107
|
-
*
|
|
108
|
-
* route template has no matching value in the actor's context. Import the class
|
|
109
|
-
* from `@xmachines/play-xstate/errors`.
|
|
159
|
+
* template cannot be fully resolved — a required `:param` absent from context
|
|
160
|
+
* is caught internally (`MissingRouteParamError` never escapes `get()`): the
|
|
161
|
+
* condition is transient mid-transition and the signal recomputes on the next
|
|
162
|
+
* snapshot.
|
|
110
163
|
*
|
|
111
164
|
* @example
|
|
112
165
|
* ```typescript
|
|
113
|
-
* // Returns "/profile/alice" when context.userId === "alice"
|
|
166
|
+
* // Returns "/profile/alice" when context.params.userId === "alice",
|
|
167
|
+
* // and null while the param is still missing.
|
|
114
168
|
* const route = actor.currentRoute.get();
|
|
115
169
|
* ```
|
|
116
170
|
*/
|
|
@@ -147,6 +201,11 @@ export declare class PlayerActor<TMachine extends AnyStateMachine> extends Abstr
|
|
|
147
201
|
*
|
|
148
202
|
* Returns `null` when the current state has no `meta.view` metadata.
|
|
149
203
|
*
|
|
204
|
+
* Two states declaring separate but structurally identical `meta.view`
|
|
205
|
+
* literals emit distinct references on a transition between them (a
|
|
206
|
+
* provider remount); hoist the shared literal into one `typedSpec` constant
|
|
207
|
+
* to deduplicate by identity.
|
|
208
|
+
*
|
|
150
209
|
* @example
|
|
151
210
|
* ```typescript
|
|
152
211
|
* const view = actor.currentView.get();
|
|
@@ -156,20 +215,31 @@ export declare class PlayerActor<TMachine extends AnyStateMachine> extends Abstr
|
|
|
156
215
|
* }
|
|
157
216
|
* ```
|
|
158
217
|
*/
|
|
159
|
-
currentView: Signal.State<PlaySpec | null>;
|
|
160
|
-
constructor(machine: TMachine, options: PlayerOptions<TMachine>, input?: InputFrom<TMachine>, restoredSnapshot?:
|
|
218
|
+
readonly currentView: Signal.State<PlaySpec | null>;
|
|
219
|
+
constructor(machine: TMachine, options: PlayerOptions<TMachine>, input?: InputFrom<TMachine>, restoredSnapshot?: ActorOptions<TMachine>["snapshot"]);
|
|
161
220
|
/**
|
|
162
|
-
* Start the actor
|
|
221
|
+
* Start the actor.
|
|
163
222
|
*
|
|
164
|
-
*
|
|
223
|
+
* Fires `onStart` on each real start — every transition from not-running to
|
|
224
|
+
* running, including a start after a stop, which XState allows (its own
|
|
225
|
+
* `start()` bails only while the actor is already RUNNING). A repeated call
|
|
226
|
+
* while running does not re-fire it, so a defensive double mount does not
|
|
227
|
+
* re-run `onStart` side effects for one actual start.
|
|
165
228
|
*/
|
|
166
229
|
start(): this;
|
|
167
230
|
/**
|
|
168
|
-
* Stop the actor and
|
|
231
|
+
* Stop the actor and clean up.
|
|
232
|
+
*
|
|
233
|
+
* Fires `onStop` only when the actor was actually running — mirroring
|
|
234
|
+
* XState, where stopping a never-started or already-stopped actor is a
|
|
235
|
+
* no-op with zero teardown — so paired cleanup never runs twice, nor
|
|
236
|
+
* against resources `onStart` never acquired. Stopping does not close the
|
|
237
|
+
* actor for good: a later `start()` is a fresh lifecycle and fires
|
|
238
|
+
* `onStart` again.
|
|
169
239
|
*/
|
|
170
240
|
stop(): this;
|
|
171
241
|
/**
|
|
172
|
-
* Send an event to
|
|
242
|
+
* Send an event to this actor.
|
|
173
243
|
*
|
|
174
244
|
* The actor's state machine guards decide whether the event causes a transition.
|
|
175
245
|
* Pass any event from the machine's event union — domain events, routing events, etc.
|
|
@@ -194,7 +264,7 @@ export declare class PlayerActor<TMachine extends AnyStateMachine> extends Abstr
|
|
|
194
264
|
*/
|
|
195
265
|
getSnapshot(): ReturnType<Actor<TMachine>["getSnapshot"]>;
|
|
196
266
|
/**
|
|
197
|
-
* Subscribe to snapshot updates
|
|
267
|
+
* Subscribe to this actor's snapshot updates.
|
|
198
268
|
*
|
|
199
269
|
* Accepts an observer object, exactly like XState's `Actor.subscribe`.
|
|
200
270
|
*
|
|
@@ -203,7 +273,7 @@ export declare class PlayerActor<TMachine extends AnyStateMachine> extends Abstr
|
|
|
203
273
|
*/
|
|
204
274
|
subscribe(observer: Observer<SnapshotFrom<TMachine>>): Subscription;
|
|
205
275
|
/**
|
|
206
|
-
* Subscribe to snapshot updates
|
|
276
|
+
* Subscribe to this actor's snapshot updates.
|
|
207
277
|
*
|
|
208
278
|
* Accepts listener functions, exactly like XState's `Actor.subscribe`.
|
|
209
279
|
*
|
|
@@ -214,7 +284,7 @@ export declare class PlayerActor<TMachine extends AnyStateMachine> extends Abstr
|
|
|
214
284
|
*/
|
|
215
285
|
subscribe(nextListener?: (snapshot: SnapshotFrom<TMachine>) => void, errorListener?: (error: unknown) => void, completeListener?: () => void): Subscription;
|
|
216
286
|
/**
|
|
217
|
-
* Listen for events
|
|
287
|
+
* Listen for events this actor emits via the `emit` action.
|
|
218
288
|
*
|
|
219
289
|
* @param type - Emitted event type to listen for, or `"*"` for all.
|
|
220
290
|
* @param handler - Called with each matching emitted event.
|
|
@@ -224,25 +294,21 @@ export declare class PlayerActor<TMachine extends AnyStateMachine> extends Abstr
|
|
|
224
294
|
type: TType;
|
|
225
295
|
})) => void): Subscription;
|
|
226
296
|
/**
|
|
227
|
-
* Get
|
|
297
|
+
* Get this actor's persisted snapshot.
|
|
228
298
|
*
|
|
229
299
|
* Suitable for serialization and later restoration via the factory's
|
|
230
300
|
* `restore.snapshot` option.
|
|
231
301
|
*/
|
|
232
|
-
getPersistedSnapshot(): Snapshot<unknown>;
|
|
302
|
+
getPersistedSnapshot(options?: unknown): Snapshot<unknown>;
|
|
233
303
|
/**
|
|
234
|
-
*
|
|
235
|
-
*
|
|
236
|
-
* Per CONTEXT.md: "Prop validation: At state entry (when state becomes active)"
|
|
237
|
-
* Validates once per transition and stores result in signal.
|
|
304
|
+
* Derive and cache the view at state entry — once per transition, stored in
|
|
305
|
+
* the signal rather than recomputed per read.
|
|
238
306
|
*
|
|
239
307
|
* @param snapshot - Current XState snapshot
|
|
240
308
|
*/
|
|
241
309
|
private validateAndCacheView;
|
|
242
310
|
/**
|
|
243
|
-
* Convenience dispose method for cleanup
|
|
244
|
-
*
|
|
245
|
-
* Per CONTEXT.md: "Both .dispose() convenience method and manual machine.stop()"
|
|
311
|
+
* Convenience dispose method for cleanup — an alias for {@link stop}.
|
|
246
312
|
*/
|
|
247
313
|
dispose(): void;
|
|
248
314
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"player-actor.d.ts","sourceRoot":"","sources":["../src/player-actor.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"player-actor.d.ts","sourceRoot":"","sources":["../src/player-actor.ts"],"names":[],"mappings":"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"}
|