@xmachines/play-xstate 2.0.0-alpha.1 → 2.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.
Files changed (89) hide show
  1. package/README.md +114 -114
  2. package/dist/define-player.d.ts +16 -16
  3. package/dist/define-player.js +16 -16
  4. package/dist/errors.d.ts +84 -101
  5. package/dist/errors.d.ts.map +1 -1
  6. package/dist/errors.js +108 -108
  7. package/dist/errors.js.map +1 -1
  8. package/dist/guards/compose.d.ts +70 -77
  9. package/dist/guards/compose.d.ts.map +1 -1
  10. package/dist/guards/compose.js +90 -113
  11. package/dist/guards/compose.js.map +1 -1
  12. package/dist/guards/helpers.d.ts +22 -18
  13. package/dist/guards/helpers.d.ts.map +1 -1
  14. package/dist/guards/helpers.js +23 -19
  15. package/dist/guards/helpers.js.map +1 -1
  16. package/dist/guards/index.d.ts +10 -3
  17. package/dist/guards/index.d.ts.map +1 -1
  18. package/dist/guards/index.js +10 -3
  19. package/dist/guards/index.js.map +1 -1
  20. package/dist/guards/types.d.ts +9 -9
  21. package/dist/guards/types.d.ts.map +1 -1
  22. package/dist/index.d.ts +8 -8
  23. package/dist/index.d.ts.map +1 -1
  24. package/dist/index.js +9 -10
  25. package/dist/index.js.map +1 -1
  26. package/dist/player-actor.d.ts +197 -113
  27. package/dist/player-actor.d.ts.map +1 -1
  28. package/dist/player-actor.js +413 -401
  29. package/dist/player-actor.js.map +1 -1
  30. package/dist/routing/build-url.d.ts +19 -21
  31. package/dist/routing/build-url.d.ts.map +1 -1
  32. package/dist/routing/build-url.js +70 -71
  33. package/dist/routing/build-url.js.map +1 -1
  34. package/dist/routing/derive-current-route.d.ts +51 -13
  35. package/dist/routing/derive-current-route.d.ts.map +1 -1
  36. package/dist/routing/derive-current-route.js +69 -60
  37. package/dist/routing/derive-current-route.js.map +1 -1
  38. package/dist/routing/derive-initial-route.d.ts +23 -23
  39. package/dist/routing/derive-initial-route.js +27 -27
  40. package/dist/routing/derive-initial-route.js.map +1 -1
  41. package/dist/routing/derive-route.d.ts +38 -37
  42. package/dist/routing/derive-route.d.ts.map +1 -1
  43. package/dist/routing/derive-route.js +45 -42
  44. package/dist/routing/derive-route.js.map +1 -1
  45. package/dist/routing/format-play-route-transitions.d.ts +34 -71
  46. package/dist/routing/format-play-route-transitions.d.ts.map +1 -1
  47. package/dist/routing/format-play-route-transitions.js +74 -130
  48. package/dist/routing/format-play-route-transitions.js.map +1 -1
  49. package/dist/routing/index.d.ts +4 -8
  50. package/dist/routing/index.d.ts.map +1 -1
  51. package/dist/routing/index.js +4 -6
  52. package/dist/routing/index.js.map +1 -1
  53. package/dist/routing/types.d.ts +12 -11
  54. package/dist/routing/types.d.ts.map +1 -1
  55. package/dist/types.d.ts +97 -20
  56. package/dist/types.d.ts.map +1 -1
  57. package/dist/view/derive-current-view.d.ts +51 -0
  58. package/dist/view/derive-current-view.d.ts.map +1 -0
  59. package/dist/view/derive-current-view.js +119 -0
  60. package/dist/view/derive-current-view.js.map +1 -0
  61. package/package.json +22 -21
  62. package/dist/define-player.typecheck.d.ts +0 -2
  63. package/dist/define-player.typecheck.d.ts.map +0 -1
  64. package/dist/define-player.typecheck.js +0 -48
  65. package/dist/define-player.typecheck.js.map +0 -1
  66. package/dist/guards/compose.typecheck.d.ts +0 -2
  67. package/dist/guards/compose.typecheck.d.ts.map +0 -1
  68. package/dist/guards/compose.typecheck.js +0 -22
  69. package/dist/guards/compose.typecheck.js.map +0 -1
  70. package/dist/player-actor.typecheck.d.ts +0 -2
  71. package/dist/player-actor.typecheck.d.ts.map +0 -1
  72. package/dist/player-actor.typecheck.js +0 -30
  73. package/dist/player-actor.typecheck.js.map +0 -1
  74. package/dist/routing/create-routed-machine.d.ts +0 -71
  75. package/dist/routing/create-routed-machine.d.ts.map +0 -1
  76. package/dist/routing/create-routed-machine.js +0 -71
  77. package/dist/routing/create-routed-machine.js.map +0 -1
  78. package/dist/routing/play-route-event.typecheck.d.ts +0 -2
  79. package/dist/routing/play-route-event.typecheck.d.ts.map +0 -1
  80. package/dist/routing/play-route-event.typecheck.js +0 -43
  81. package/dist/routing/play-route-event.typecheck.js.map +0 -1
  82. package/dist/routing/schemas.d.ts +0 -99
  83. package/dist/routing/schemas.d.ts.map +0 -1
  84. package/dist/routing/schemas.js +0 -30
  85. package/dist/routing/schemas.js.map +0 -1
  86. package/dist/schemas.d.ts +0 -28
  87. package/dist/schemas.d.ts.map +0 -1
  88. package/dist/schemas.js +0 -29
  89. package/dist/schemas.js.map +0 -1
package/README.md CHANGED
@@ -1,13 +1,8 @@
1
- <!-- generated-by: gsd-doc-writer -->
2
-
3
1
  # @xmachines/play-xstate
4
2
 
5
- > XState v6 adapter for the XMachines Play Architecture bind state machines to the actor base with signal-driven reactivity and router integration.
6
-
7
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
8
- [![Version](https://img.shields.io/badge/version-1.0.0--beta.51-blue)](https://www.npmjs.com/package/@xmachines/play-xstate)
3
+ > XState v5 adapter for the XMachines Play Architecture. It binds a state machine to the actor base, with signal-driven reactivity and a router integration.
9
4
 
10
- Part of the [XMachines Play](../../README.md) monorepo.
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![Version](https://img.shields.io/badge/version-2.1.0-blue)](https://www.npmjs.com/package/@xmachines/play-xstate)
11
6
 
12
7
  ---
13
8
 
@@ -17,7 +12,7 @@ Part of the [XMachines Play](../../README.md) monorepo.
17
12
  pnpm add @xmachines/play-xstate xstate
18
13
  ```
19
14
 
20
- `xstate ^6.0.0-alpha.19` is a peer dependency and must be installed alongside this package.
15
+ `xstate ^5.31.0` is a peer dependency. Install it with this package.
21
16
 
22
17
  ---
23
18
 
@@ -25,18 +20,13 @@ pnpm add @xmachines/play-xstate xstate
25
20
 
26
21
  ```typescript
27
22
  import { setup } from "xstate";
28
- import { definePlayer, emptyEventSchema, playMetaSchema } from "@xmachines/play-xstate";
23
+ import { definePlayer } from "@xmachines/play-xstate";
29
24
 
30
- // 1. Define your XState v6 machine
31
- const machine = setup({
32
- schemas: {
33
- events: { activate: emptyEventSchema },
34
- meta: playMetaSchema, // types meta.route / meta.view on state nodes
35
- },
36
- }).createMachine({
25
+ // 1. Define your XState v5 machine
26
+ const machine = setup({}).createMachine({
37
27
  initial: "idle",
38
28
  states: {
39
- idle: { meta: { route: "/" }, on: { activate: { target: "active" } } },
29
+ idle: { meta: { route: "/" }, on: { activate: "active" } },
40
30
  active: { meta: { route: "/active" } },
41
31
  },
42
32
  });
@@ -64,16 +54,16 @@ actor.stop();
64
54
 
65
55
  ### `definePlayer(config)`
66
56
 
67
- Creates a `PlayerFactory` from an XState v6 machine. The factory pattern enables multiple independent actor instances from a single configuration useful for multi-user scenarios, SSR, or testing.
57
+ This function creates a `PlayerFactory` from an XState v5 machine. One configuration can therefore make more than one independent actor instance. This helps with a multi-user application, with SSR, and with a test.
68
58
 
69
59
  ```typescript
70
- import { setup, types } from "xstate";
60
+ import { setup } from "xstate";
71
61
  import { definePlayer } from "@xmachines/play-xstate";
72
62
 
73
63
  const machine = setup({
74
- schemas: {
75
- context: types<{ userId: string }>(),
76
- input: types<{ userId: string }>(),
64
+ types: {
65
+ context: {} as { userId: string },
66
+ input: {} as { userId: string },
77
67
  },
78
68
  }).createMachine({
79
69
  context: ({ input }) => ({ userId: input.userId }),
@@ -89,6 +79,7 @@ const createPlayer = definePlayer({
89
79
  onTransition: (actor, prev, next) => console.log("transitioned"),
90
80
  onStateChange: (actor, state) => console.log("state changed"),
91
81
  onError: (actor, err) => console.error(err),
82
+ inspect: (event) => console.log(event.type), // handed to XState's actor constructor — enables @statelyai/inspect
92
83
  },
93
84
  });
94
85
 
@@ -99,17 +90,27 @@ const bob = createPlayer({ userId: "bob" });
99
90
 
100
91
  #### `PlayerFactory` signature
101
92
 
93
+ The `input` argument follows the rule of `createActor` in XState. If the input type of a
94
+ machine cannot be `undefined`, the first argument of the factory is necessary. An absent
95
+ input is then a compile error, not an actor that stops in an error status.
96
+
102
97
  ```typescript
103
- type PlayerFactory<TMachine> = (
104
- input?: InputFrom<TMachine>,
105
- options?: PlayerFactoryResumeOptions<TMachine>,
106
- ) => PlayerActor<TMachine>;
98
+ type PlayerFactory<TMachine> =
99
+ undefined extends InputFrom<TMachine>
100
+ ? (
101
+ input?: InputFrom<TMachine>,
102
+ options?: PlayerFactoryResumeOptions<TMachine>,
103
+ ) => PlayerActor<TMachine>
104
+ : (
105
+ input: InputFrom<TMachine>,
106
+ options?: PlayerFactoryResumeOptions<TMachine>,
107
+ ) => PlayerActor<TMachine>;
107
108
  ```
108
109
 
109
110
  #### Restoring from a snapshot
110
111
 
111
112
  ```typescript
112
- const snapshot = actor.getSnapshot();
113
+ const snapshot = actor.getPersistedSnapshot();
113
114
  actor.stop();
114
115
 
115
116
  // Restore to the exact saved state
@@ -118,31 +119,35 @@ restored.start();
118
119
  console.log(restored.currentRoute.get()); // same route as when saved
119
120
  ```
120
121
 
122
+ > **Note:** persist the state with `getPersistedSnapshot()`, not with
123
+ > `getSnapshot()`. `createActor` accepts that form only, and it is the only form
124
+ > that restores a machine with an invoked child or a spawned child.
125
+
121
126
  ---
122
127
 
123
128
  ### `PlayerActor<TMachine>`
124
129
 
125
- Concrete actor class that wraps an XState v6 actor and exposes TC39 Signal-based reactive signals. Implements both `Routable` and `Viewable` interfaces from `@xmachines/play-actor`.
130
+ This concrete actor class is an XState v5 actor that also exposes reactive TC39 Signals. It implements both the `Routable` interface and the `Viewable` interface from `@xmachines/play-actor`.
126
131
 
127
132
  #### Signals
128
133
 
129
- | Signal | Type | Description |
130
- | -------------- | -------------------------------------- | ---------------------------------------------------------------------------------------------------------------- |
131
- | `state` | `Signal.State<SnapshotFrom<TMachine>>` | Current XState snapshot; updated on every active transition |
132
- | `currentRoute` | `Signal.Computed<string \| null>` | Derived URL from active state's `meta.route` template and context |
133
- | `currentView` | `Signal.State<PlaySpec \| null>` | View spec from active state's `meta.view` metadata; enriched with context params |
134
- | `initialRoute` | `readonly string \| null` | Machine's initial-state route (fixed at construction; used by router bridges for deep-link vs restore detection) |
134
+ | Signal | Type | Description |
135
+ | -------------- | -------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
136
+ | `state` | `Signal.State<SnapshotFrom<TMachine>>` | The current XState snapshot. The actor updates it on every active transition |
137
+ | `currentRoute` | `Signal.Computed<string \| null>` | The URL that comes from the `meta.route` template of the active state and from the context |
138
+ | `currentView` | `Signal.State<PlaySpec \| null>` | The view spec from the `meta.view` metadata of the active state, with the context params added |
139
+ | `initialRoute` | `readonly string \| null` | The route of the initial state of the machine. The constructor fixes it, and a router bridge uses it to detect a deep link or a restore |
135
140
 
136
141
  #### Methods
137
142
 
138
- | Method | Description |
139
- | --------------- | -------------------------------------------------------------- |
140
- | `start()` | Start the actor and fire `onStart` hook |
141
- | `stop()` | Stop the actor, clean up subscriptions, fire `onStop` hook |
142
- | `send(event)` | Send a typed event to the machine; fires `onTransition` hook |
143
- | `can(event)` | Returns `true` if the current state can accept the given event |
144
- | `getSnapshot()` | Returns the current XState snapshot |
145
- | `dispose()` | Alias for `stop()` |
143
+ | Method | Description |
144
+ | --------------- | ------------------------------------------------------------------------- |
145
+ | `start()` | Starts the actor and calls the `onStart` hook |
146
+ | `stop()` | Stops the actor, cleans up the subscriptions, and calls the `onStop` hook |
147
+ | `send(event)` | Sends a typed event to the machine and calls the `onTransition` hook |
148
+ | `can(event)` | Returns `true` when the current state accepts the given event |
149
+ | `getSnapshot()` | Returns the current XState snapshot |
150
+ | `dispose()` | The alias of `stop()` |
146
151
 
147
152
  #### Signal usage example
148
153
 
@@ -163,7 +168,12 @@ actor.start();
163
168
 
164
169
  ### Guard utilities
165
170
 
166
- Composable guard helpers that combine predicates with AND, OR, and NOT logic. Each helper returns a plain predicate — call it inside a transition function with the transition arguments and return early to block the transition. String guard names are resolved against the named guards declared in `setup({ guards })`.
171
+ > **Deprecated:** these guard helpers wrap the `and()`, `or()`, and `not()`
172
+ > combinators of XState, but they do not compose with a guard slot that
173
+ > `setup()` types. Use the combinators of XState directly. The next major
174
+ > version removes this module.
175
+
176
+ These composable guard helpers wrap the `and()`, `or()`, and `not()` functions of XState. Use them in a machine `setup({ guards })` definition.
167
177
 
168
178
  ```typescript
169
179
  import { setup } from "xstate";
@@ -176,24 +186,20 @@ import {
176
186
  contextFieldMatches, // guard: context field equals a value
177
187
  } from "@xmachines/play-xstate";
178
188
 
179
- const canAccessAdmin = composeGuards(["isLoggedIn", "hasAdminRole"]);
180
- const isAuthenticated = negateGuard("isGuest");
181
-
182
189
  const machine = setup({
183
190
  guards: {
184
191
  isLoggedIn: ({ context }) => !!context.userId,
185
192
  hasAdminRole: ({ context }) => context.role === "admin",
186
- isGuest: ({ context }) => !context.userId,
187
193
  },
188
194
  }).createMachine({
189
195
  on: {
190
- accessAdmin: (args) => {
191
- if (!canAccessAdmin(args)) return;
192
- return { target: "adminPanel" };
196
+ accessAdmin: {
197
+ guard: composeGuards(["isLoggedIn", "hasAdminRole"]),
198
+ target: "adminPanel",
193
199
  },
194
- accessDashboard: (args) => {
195
- if (!isAuthenticated(args)) return;
196
- return { target: "dashboard" };
200
+ accessLogin: {
201
+ guard: negateGuard("isLoggedIn"),
202
+ target: "login",
197
203
  },
198
204
  },
199
205
  // ...
@@ -204,19 +210,17 @@ const machine = setup({
204
210
 
205
211
  ### Routing utilities
206
212
 
207
- Helper functions for declarative route configuration in XState machines.
213
+ These helper functions configure the routes of an XState machine declaratively.
208
214
 
209
- #### `createRoutedMachine(setup)`
215
+ #### `formatPlayRouteTransitions(machineConfig)`
210
216
 
211
- The recommended entry point: returns a `createMachine` with the same signature as the setup's own full contextual typing for the config that wires routing up at runtime.
217
+ This function reads each machine state that has a `meta.route` field. It then generates the `play.route` event handlers at the root level. You therefore write no repetitive routing transition.
212
218
 
213
219
  ```typescript
214
220
  import { setup } from "xstate";
215
- import { createRoutedMachine } from "@xmachines/play-xstate";
216
-
217
- const appSetup = setup({/* schemas, guards, ... */});
221
+ import { formatPlayRouteTransitions } from "@xmachines/play-xstate";
218
222
 
219
- const machine = createRoutedMachine(appSetup)({
223
+ const config = formatPlayRouteTransitions({
220
224
  id: "app",
221
225
  states: {
222
226
  home: {
@@ -229,61 +233,58 @@ const machine = createRoutedMachine(appSetup)({
229
233
  },
230
234
  },
231
235
  });
236
+
237
+ // config now includes auto-generated play.route handlers:
238
+ // on: { "play.route": [ { target: ".home", guard: e => e.to === "#home" }, ... ] }
239
+ const machine = setup({}).createMachine(config);
232
240
  ```
233
241
 
234
- #### `formatPlayRouteTransitions(machineConfig)`
242
+ > **Note:** every state with a `meta.route` field must also have an explicit `id` field. A state without an `id` field throws `MissingStateIdError` when you define the machine.
235
243
 
236
- The underlying transform. Crawls machine states with `meta.route` and wires them to XState v6's native routing: each routed state gets a native `route: {}` config (targetable via the built-in `xstate.route` event and visible to graph tooling), and one root `play.route` forwarder navigates those targets in a single atomic transition — patching `params`/`query` into context — while re-raising `xstate.route` only for states that declare their own `route` config. Unknown targets fall through to user-defined `play.route` fallbacks (e.g. a 404 route); one `play.route` send is one atomic transition, so exit actions see the old `params` and entry actions the new ones.
244
+ #### Other routing exports
237
245
 
238
- ```typescript
239
- import { setup } from "xstate";
240
- import {
241
- formatPlayRouteTransitions,
242
- playMetaSchema,
243
- playRouteEventSchema,
244
- } from "@xmachines/play-xstate";
246
+ | Export | Description |
247
+ | ---------------------------------- | --------------------------------------------------------------------------- |
248
+ | `deriveRoute(meta)` | Reads the route template string from the metadata object of a state |
249
+ | `isAbsoluteRoute(route)` | Returns `true` when the route string is an absolute URL path |
250
+ | `buildRouteUrl(template, context)` | Replaces each `:param` placeholder of a route template with a context value |
245
251
 
246
- const config = formatPlayRouteTransitions({
247
- id: "app",
248
- states: {
249
- home: {
250
- id: "home",
251
- meta: { route: "/home" },
252
- },
253
- profile: {
254
- id: "profile",
255
- meta: { route: "/users/:userId" },
256
- },
257
- },
258
- });
252
+ ---
259
253
 
260
- // config now carries native route configs plus the play.route forwarder:
261
- // states: { home: { ..., route: {} }, profile: { ..., route: {} } }
262
- // on: { "play.route": [forwarder, ...userFallbacks] }
263
- // The forwarder navigates injected-route targets directly (atomically);
264
- // xstate.route is raised only for states declaring their own route config.
265
- const machine = setup({
266
- schemas: {
267
- events: { "play.route": playRouteEventSchema },
268
- meta: playMetaSchema,
269
- },
270
- }).createMachine(config);
254
+ ## Inspection
255
+
256
+ The factory gives `options.inspect` to `createActor` of XState without a change.
257
+ Therefore every XState inspection tool works with a `PlayerActor`, and this
258
+ includes [`@statelyai/inspect`](https://stately.ai/docs/inspector):
259
+
260
+ ```typescript
261
+ import { createBrowserInspector } from "@statelyai/inspect";
262
+
263
+ const { inspect } = createBrowserInspector();
264
+ const createPlayer = definePlayer({ machine, options: { inspect } });
271
265
  ```
272
266
 
273
- Because the injected `route` configs are static, route transitions keep statically-known targets — `machineToGraph()` sees real edges to every routed state, so reachability queries work.
267
+ Three points are important:
274
268
 
275
- > **Note:** Every state with `meta.route` must also have an explicit `id` field; omitting it throws `MissingStateIdError` at machine-definition time.
269
+ - **`inspect` is an option of the factory, not of one instance.** Every actor of a
270
+ factory reports to the same observer. Separate the actors by root:
271
+ `event.rootId === actor.sessionId` covers the complete tree of an actor, with its
272
+ children.
273
+ - **`inspect` is the only path that sees the construction.** `actor.system.inspect(fn)`
274
+ attaches later, and it sees only the events after that moment. It therefore misses the
275
+ `@xstate.actor` registration, and an inspector needs that registration to draw the
276
+ machine.
277
+ - **A `PlayerActor` is the actor.** Its own events carry `actorRef === playerActor`, so
278
+ you can recognize a player by its identity. Note one point: `@xstate.actor` fires from
279
+ inside the constructor, and `state`, `currentRoute`, `currentView`, and `initialRoute`
280
+ do not exist yet. A read of one of them there throws.
276
281
 
277
- #### Other routing exports
282
+ For an inspector that you create after the factory, such as a dev-tools switch, give the
283
+ factory a function that forwards each event: `inspect: (event) => currentInspector?.(event)`.
278
284
 
279
- | Export | Description |
280
- | ---------------------------------- | ------------------------------------------------------------------------- |
281
- | `playMetaSchema` | Shared `schemas.meta` declaration for `meta.route` / `meta.view` metadata |
282
- | `playRouteEventSchema` | Shared `schemas.events` entry for the `play.route` event payload |
283
- | `emptyEventSchema` | Shared `schemas.events` entry for events that carry no payload |
284
- | `deriveRoute(meta)` | Extract the route template string from a state's metadata object |
285
- | `isAbsoluteRoute(route)` | Returns `true` if the route string is an absolute URL path |
286
- | `buildRouteUrl(template, context)` | Substitute `:param` placeholders in a route template using context values |
285
+ The [inspector guide](../docs/guides/inspector.md) gives the complete procedure: a late
286
+ attachment with a replay, a WebSocket inspection without a browser, and the points to
287
+ consider in production.
287
288
 
288
289
  ---
289
290
 
@@ -292,12 +293,12 @@ Because the injected `route` configs are static, route transitions keep statical
292
293
  ```typescript
293
294
  import type {
294
295
  PlayerConfig, // definePlayer() config argument shape
295
- PlayerOptions, // Lifecycle hooks (onStart, onStop, onTransition, onStateChange, onError)
296
+ PlayerOptions, // Lifecycle hooks (onStart, onStop, onTransition, onStateChange, onError) + inspect
296
297
  PlayerFactory, // Factory function returned by definePlayer()
297
298
  PlayerFactoryResumeOptions, // { snapshot? } for restoring actor state
298
- Guard, // Single XState guard predicate
299
- GuardArray, // Array of guards for compose helpers
300
- ComposedGuard, // Return type of composeGuards / composeGuardsOr / negateGuard
299
+ Guard, // deprecated with the guard utilities — removed in the next major
300
+ GuardArray, // deprecated with the guard utilities — removed in the next major
301
+ ComposedGuard, // deprecated with the guard utilities removed in the next major
301
302
  RouteMachineConfig, // Minimal machine config accepted by formatPlayRouteTransitions
302
303
  RouteStateNode, // Single state node shape used during route crawling
303
304
  RouteContext, // Context shape expected by buildRouteUrl ({ params?, query?, basePath?, hash? })
@@ -310,23 +311,22 @@ import type {
310
311
 
311
312
  ## Error Classes
312
313
 
313
- Error classes are exported from the `@xmachines/play-xstate/errors` sub-path to keep the main bundle lean.
314
+ The `@xmachines/play-xstate/errors` subpath exports the error classes. The main bundle therefore stays small.
314
315
 
315
316
  ```typescript
316
317
  import {
317
318
  MissingRouteParamError, // Required :param absent from context when resolving currentRoute
318
- MissingQueryContextError, // context.params present but context.query missing
319
+ MissingQueryContextError, // deprecated: no longer thrown
319
320
  MissingStateIdError, // meta.route declared without a state id field
320
321
  InvalidMachineError, // PlayerActor constructed with a non-object machine
321
322
  InvalidEventError, // actor.send() called with null/undefined/non-object
323
+ ActorThrewNonErrorError, // actor failed with a thrown value that is not an Error
322
324
  InvalidRouteMetadataError, // meta.route is neither a string nor { path: string }
323
325
  EmptyGuardArrayError, // composeGuards/composeGuardsOr called with empty array
324
- UnresolvableGuardNameError, // string guard name could not be resolved at call time
325
- InvalidGuardEntryError, // guard entry was neither a predicate nor a name (e.g. undefined)
326
326
  } from "@xmachines/play-xstate/errors";
327
327
  ```
328
328
 
329
- All error classes extend `PlayError` from `@xmachines/play` and carry typed detail fields (`param`, `template`, `combinator`, etc.) for programmatic inspection without message parsing.
329
+ Every error class extends `PlayError` from `@xmachines/play`. Each class also carries typed detail fields, such as `param`, `template`, and `combinator`. Your code therefore reads the details of an error, and it does not parse the message.
330
330
 
331
331
  ---
332
332
 
@@ -340,7 +340,7 @@ pnpm --filter @xmachines/play-xstate test
340
340
  pnpm --filter @xmachines/play-xstate run test:watch
341
341
  ```
342
342
 
343
- Tests use [Vitest](https://vitest.dev/) and live in `packages/play-xstate/test/`.
343
+ The tests use [Vitest](https://vitest.dev/). They are in `packages/play-xstate/test/`.
344
344
 
345
345
  ---
346
346
 
@@ -1,23 +1,23 @@
1
1
  import type { AnyStateMachine } from "xstate";
2
2
  import type { PlayerConfig, PlayerFactory } from "./types.js";
3
3
  /**
4
- * Create a player factory from an XState machine
4
+ * Creates a player factory from an XState machine
5
5
  *
6
- * Factory pattern that accepts an XState v6 machine,
7
- * returning a function that creates {@link PlayerActor} instances. This enables
8
- * creating multiple actor instances from a single configuration, useful for
9
- * testing, multi-instance scenarios, or server-side rendering.
6
+ * This factory function accepts an XState v5 machine. It returns a function that
7
+ * makes {@link PlayerActor} instances. One configuration can therefore make more
8
+ * than one actor instance, and this helps with a test, with an application of
9
+ * several instances, and with a render on the server.
10
10
  *
11
- * @typeParam TMachine - XState v6 state machine type
11
+ * @typeParam TMachine - The type of the XState v5 state machine
12
12
  *
13
- * @param config - Player configuration object
14
- * @param config.machine - XState v6 state machine
15
- * @param config.options - Optional lifecycle hooks (onStart, onTransition, etc.)
13
+ * @param config - The configuration object of the player
14
+ * @param config.machine - The XState v5 state machine
15
+ * @param config.options - The optional lifecycle hooks: onStart, onTransition, and the others
16
16
  *
17
- * @returns Factory function that creates actor instances with optional input context
17
+ * @returns The factory function. It makes an actor instance, with an optional input context
18
18
  *
19
19
  * @example
20
- * Basic player factory
20
+ * A basic player factory
21
21
  * ```typescript
22
22
  * import { setup } from "xstate";
23
23
  * import { definePlayer } from "@xmachines/play-xstate";
@@ -36,25 +36,25 @@ import type { PlayerConfig, PlayerFactory } from "./types.js";
36
36
  * ```
37
37
  *
38
38
  * @example
39
- * Multiple actor instances from single factory
39
+ * More than one actor instance from one factory
40
40
  * ```typescript
41
41
  * const createPlayer = definePlayer({ machine });
42
42
  *
43
- * // Create actors for different users
43
+ * // Create an actor for each user
44
44
  * const alice = createPlayer({ userId: 'alice' });
45
45
  * const bob = createPlayer({ userId: 'bob' });
46
46
  *
47
47
  * alice.start();
48
48
  * bob.start();
49
49
  *
50
- * // Independent state machines
50
+ * // The two state machines are independent
51
51
  * console.log(alice.state.get() !== bob.state.get());
52
52
  * ```
53
53
  *
54
54
  * @see [Play RFC](../../docs/rfc/play.md)
55
55
  * @see {@link PlayerActor} for the concrete actor implementation
56
- * @see {@link PlayerConfig} for configuration options
57
- * @see {@link PlayerFactory} for factory function signature
56
+ * @see {@link PlayerConfig} for the configuration options
57
+ * @see {@link PlayerFactory} for the signature of the factory function
58
58
  */
59
59
  export declare const definePlayer: <TMachine extends AnyStateMachine>(config: PlayerConfig<TMachine>) => PlayerFactory<TMachine>;
60
60
  //# sourceMappingURL=define-player.d.ts.map
@@ -1,22 +1,22 @@
1
1
  import { PlayerActor } from "./player-actor.js";
2
2
  /**
3
- * Create a player factory from an XState machine
3
+ * Creates a player factory from an XState machine
4
4
  *
5
- * Factory pattern that accepts an XState v6 machine,
6
- * returning a function that creates {@link PlayerActor} instances. This enables
7
- * creating multiple actor instances from a single configuration, useful for
8
- * testing, multi-instance scenarios, or server-side rendering.
5
+ * This factory function accepts an XState v5 machine. It returns a function that
6
+ * makes {@link PlayerActor} instances. One configuration can therefore make more
7
+ * than one actor instance, and this helps with a test, with an application of
8
+ * several instances, and with a render on the server.
9
9
  *
10
- * @typeParam TMachine - XState v6 state machine type
10
+ * @typeParam TMachine - The type of the XState v5 state machine
11
11
  *
12
- * @param config - Player configuration object
13
- * @param config.machine - XState v6 state machine
14
- * @param config.options - Optional lifecycle hooks (onStart, onTransition, etc.)
12
+ * @param config - The configuration object of the player
13
+ * @param config.machine - The XState v5 state machine
14
+ * @param config.options - The optional lifecycle hooks: onStart, onTransition, and the others
15
15
  *
16
- * @returns Factory function that creates actor instances with optional input context
16
+ * @returns The factory function. It makes an actor instance, with an optional input context
17
17
  *
18
18
  * @example
19
- * Basic player factory
19
+ * A basic player factory
20
20
  * ```typescript
21
21
  * import { setup } from "xstate";
22
22
  * import { definePlayer } from "@xmachines/play-xstate";
@@ -35,25 +35,25 @@ import { PlayerActor } from "./player-actor.js";
35
35
  * ```
36
36
  *
37
37
  * @example
38
- * Multiple actor instances from single factory
38
+ * More than one actor instance from one factory
39
39
  * ```typescript
40
40
  * const createPlayer = definePlayer({ machine });
41
41
  *
42
- * // Create actors for different users
42
+ * // Create an actor for each user
43
43
  * const alice = createPlayer({ userId: 'alice' });
44
44
  * const bob = createPlayer({ userId: 'bob' });
45
45
  *
46
46
  * alice.start();
47
47
  * bob.start();
48
48
  *
49
- * // Independent state machines
49
+ * // The two state machines are independent
50
50
  * console.log(alice.state.get() !== bob.state.get());
51
51
  * ```
52
52
  *
53
53
  * @see [Play RFC](../../docs/rfc/play.md)
54
54
  * @see {@link PlayerActor} for the concrete actor implementation
55
- * @see {@link PlayerConfig} for configuration options
56
- * @see {@link PlayerFactory} for factory function signature
55
+ * @see {@link PlayerConfig} for the configuration options
56
+ * @see {@link PlayerFactory} for the signature of the factory function
57
57
  */
58
58
  export const definePlayer = (config) => {
59
59
  const { machine, options } = config;