@xmachines/play-xstate 1.0.0-beta.53 → 1.0.0-beta.55
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/dist/define-player.d.ts +1 -1
- package/dist/define-player.d.ts.map +1 -1
- package/dist/define-player.js +2 -12
- package/dist/define-player.js.map +1 -1
- package/dist/errors.d.ts +32 -31
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +39 -38
- package/dist/errors.js.map +1 -1
- package/dist/player-actor.d.ts +52 -46
- package/dist/player-actor.d.ts.map +1 -1
- package/dist/player-actor.js +153 -128
- package/dist/player-actor.js.map +1 -1
- package/dist/routing/build-url.js +6 -0
- package/dist/routing/build-url.js.map +1 -1
- package/dist/routing/derive-current-route.d.ts +22 -0
- package/dist/routing/derive-current-route.d.ts.map +1 -0
- package/dist/routing/derive-current-route.js +122 -0
- package/dist/routing/derive-current-route.js.map +1 -0
- package/dist/routing/derive-initial-route.d.ts +43 -0
- package/dist/routing/derive-initial-route.d.ts.map +1 -0
- package/dist/routing/derive-initial-route.js +57 -0
- package/dist/routing/derive-initial-route.js.map +1 -0
- package/dist/routing/derive-route.d.ts.map +1 -1
- package/dist/routing/derive-route.js +18 -6
- package/dist/routing/derive-route.js.map +1 -1
- package/dist/routing/format-play-route-transitions.d.ts.map +1 -1
- package/dist/routing/format-play-route-transitions.js +11 -1
- package/dist/routing/format-play-route-transitions.js.map +1 -1
- package/dist/routing/index.d.ts +2 -0
- package/dist/routing/index.d.ts.map +1 -1
- package/dist/routing/index.js +2 -0
- package/dist/routing/index.js.map +1 -1
- package/package.json +14 -6
- package/dist/signals/index.d.ts +0 -2
- package/dist/signals/index.d.ts.map +0 -1
- package/dist/signals/index.js +0 -2
- package/dist/signals/index.js.map +0 -1
- package/dist/signals/state-signal.d.ts +0 -35
- package/dist/signals/state-signal.d.ts.map +0 -1
- package/dist/signals/state-signal.js +0 -44
- package/dist/signals/state-signal.js.map +0 -1
package/dist/define-player.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"define-player.d.ts","sourceRoot":"","sources":["../src/define-player.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"define-player.d.ts","sourceRoot":"","sources":["../src/define-player.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAa,MAAM,QAAQ,CAAC;AACzD,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAA8B,MAAM,YAAY,CAAC;AAG1F;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuDG;AACH,eAAO,MAAM,YAAY,GAAI,QAAQ,SAAS,eAAe,EAC5D,QAAQ,YAAY,CAAC,QAAQ,CAAC,KAC5B,aAAa,CAAC,QAAQ,CAKxB,CAAC"}
|
package/dist/define-player.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { PlayerActor, deriveCurrentRoute } from "./player-actor.js";
|
|
1
|
+
import { PlayerActor } from "./player-actor.js";
|
|
3
2
|
/**
|
|
4
3
|
* Create a player factory from an XState machine
|
|
5
4
|
*
|
|
@@ -58,15 +57,6 @@ import { PlayerActor, deriveCurrentRoute } from "./player-actor.js";
|
|
|
58
57
|
*/
|
|
59
58
|
export const definePlayer = (config) => {
|
|
60
59
|
const { machine, options } = config;
|
|
61
|
-
|
|
62
|
-
// initialRoute is determined by the machine's initial state node and meta.route
|
|
63
|
-
// template — both fixed at definition time, independent of input or snapshot.
|
|
64
|
-
// Passed to every PlayerActor constructed from this factory, eliminating a
|
|
65
|
-
// redundant createActor() call per actor construction.
|
|
66
|
-
// The actor is never started — getSnapshot() is synchronous and free.
|
|
67
|
-
const cachedInitialRoute = deriveCurrentRoute(createActor(machine).getSnapshot());
|
|
68
|
-
return (input, restore) => {
|
|
69
|
-
return new PlayerActor(machine, options ?? {}, input, restore?.snapshot, cachedInitialRoute);
|
|
70
|
-
};
|
|
60
|
+
return (input, restore) => new PlayerActor(machine, options ?? {}, input, restore?.snapshot);
|
|
71
61
|
};
|
|
72
62
|
//# sourceMappingURL=define-player.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"define-player.js","sourceRoot":"","sources":["../src/define-player.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"define-player.js","sourceRoot":"","sources":["../src/define-player.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuDG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAC3B,MAA8B,EACJ,EAAE;IAC5B,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC;IAEpC,OAAO,CAAC,KAA2B,EAAE,OAA8C,EAAE,EAAE,CACtF,IAAI,WAAW,CAAC,OAAO,EAAE,OAAO,IAAI,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;AACpE,CAAC,CAAC"}
|
package/dist/errors.d.ts
CHANGED
|
@@ -6,7 +6,7 @@ import { PlayError } from "@xmachines/play";
|
|
|
6
6
|
* Use the `param` and `template` fields to identify the missing parameter without
|
|
7
7
|
* parsing the `.message` string.
|
|
8
8
|
*
|
|
9
|
-
* **Error code:** `
|
|
9
|
+
* **Error code:** `PLAY_XSTATE_ROUTE_PARAM_MISSING`
|
|
10
10
|
*
|
|
11
11
|
* @example
|
|
12
12
|
* ```typescript
|
|
@@ -34,31 +34,6 @@ export declare class MissingRouteParamError extends PlayError {
|
|
|
34
34
|
readonly template: string;
|
|
35
35
|
constructor(param: string, template: string);
|
|
36
36
|
}
|
|
37
|
-
/**
|
|
38
|
-
* Thrown by `PlayerActor.send()` when the event argument is not a plain object.
|
|
39
|
-
*
|
|
40
|
-
* `PlayEvent` requires `{ type: string, ...fields }`. Passing `null`, `undefined`,
|
|
41
|
-
* a string, or any other non-object value is a programmer error.
|
|
42
|
-
*
|
|
43
|
-
* The offending value is attached as the `detail` readonly class field for debugging.
|
|
44
|
-
* TypeScript consumers can access `err.detail` directly without any unsafe cast.
|
|
45
|
-
*
|
|
46
|
-
* **Error code:** `PLAY_INVALID_EVENT`
|
|
47
|
-
*
|
|
48
|
-
* @example
|
|
49
|
-
* ```typescript
|
|
50
|
-
* import { InvalidEventError } from "@xmachines/play-xstate/errors";
|
|
51
|
-
*
|
|
52
|
-
* try {
|
|
53
|
-
* actor.send(null as any);
|
|
54
|
-
* } catch (err) {
|
|
55
|
-
* if (err instanceof InvalidEventError) {
|
|
56
|
-
* // err.detail is typed as `unknown` — no cast needed
|
|
57
|
-
* console.error("Invalid event passed to actor.send():", err.detail);
|
|
58
|
-
* }
|
|
59
|
-
* }
|
|
60
|
-
* ```
|
|
61
|
-
*/
|
|
62
37
|
/**
|
|
63
38
|
* Thrown by `buildRouteUrl()` when the context has a `params` field (indicating a
|
|
64
39
|
* routing-aware machine context) but no `query` field.
|
|
@@ -72,7 +47,7 @@ export declare class MissingRouteParamError extends PlayError {
|
|
|
72
47
|
* If using `formatPlayRouteTransitions`, the field is assigned automatically on each
|
|
73
48
|
* `play.route` event — but the machine's initial context must still declare it.
|
|
74
49
|
*
|
|
75
|
-
* **Error code:** `
|
|
50
|
+
* **Error code:** `PLAY_XSTATE_MISSING_QUERY_CONTEXT`
|
|
76
51
|
*
|
|
77
52
|
* @example
|
|
78
53
|
* ```typescript
|
|
@@ -103,7 +78,7 @@ export declare class MissingQueryContextError extends PlayError {
|
|
|
103
78
|
* the state is silently unreachable via routing. This error surfaces the
|
|
104
79
|
* misconfiguration at machine-definition time rather than silently skipping the state.
|
|
105
80
|
*
|
|
106
|
-
* **Error code:** `
|
|
81
|
+
* **Error code:** `PLAY_XSTATE_MISSING_STATE_ID`
|
|
107
82
|
*
|
|
108
83
|
* @example
|
|
109
84
|
* ```typescript
|
|
@@ -135,7 +110,7 @@ export declare class MissingStateIdError extends PlayError {
|
|
|
135
110
|
* Thrown by the `PlayerActor` constructor when the `machine` argument is not a
|
|
136
111
|
* valid XState machine object (null, undefined, or a non-object).
|
|
137
112
|
*
|
|
138
|
-
* **Error code:** `
|
|
113
|
+
* **Error code:** `PLAY_XSTATE_INVALID_MACHINE`
|
|
139
114
|
*/
|
|
140
115
|
export declare class InvalidMachineError extends PlayError {
|
|
141
116
|
constructor();
|
|
@@ -144,7 +119,7 @@ export declare class InvalidMachineError extends PlayError {
|
|
|
144
119
|
* Thrown by `normalizeRoute()` when a state's `meta.route` value is neither a
|
|
145
120
|
* string nor an object with a `path` property.
|
|
146
121
|
*
|
|
147
|
-
* **Error code:** `
|
|
122
|
+
* **Error code:** `PLAY_XSTATE_INVALID_ROUTE_METADATA`
|
|
148
123
|
*/
|
|
149
124
|
export declare class InvalidRouteMetadataError extends PlayError {
|
|
150
125
|
/** The serialised form of the invalid route value for debugging. */
|
|
@@ -155,14 +130,40 @@ export declare class InvalidRouteMetadataError extends PlayError {
|
|
|
155
130
|
* Thrown by `composeGuards()` or `composeGuardsOr()` when called with an empty
|
|
156
131
|
* guards array. A composition of zero guards has no meaningful semantics.
|
|
157
132
|
*
|
|
158
|
-
* **Error code:** `
|
|
133
|
+
* **Error code:** `PLAY_XSTATE_EMPTY_GUARD_ARRAY`
|
|
159
134
|
*/
|
|
160
135
|
export declare class EmptyGuardArrayError extends PlayError {
|
|
161
136
|
/** The combinator that was called with an empty array (`"and"` or `"or"`). */
|
|
162
137
|
readonly combinator: "and" | "or";
|
|
163
138
|
constructor(combinator: "and" | "or");
|
|
164
139
|
}
|
|
140
|
+
/**
|
|
141
|
+
* Thrown by `PlayerActor.send()` when the event argument is not a plain object.
|
|
142
|
+
*
|
|
143
|
+
* `PlayEvent` requires `{ type: string, ...fields }`. Passing `null`, `undefined`,
|
|
144
|
+
* a string, or any other non-object value is a programmer error.
|
|
145
|
+
*
|
|
146
|
+
* The offending value is attached as the `detail` readonly class field for debugging.
|
|
147
|
+
* TypeScript consumers can access `err.detail` directly without any unsafe cast.
|
|
148
|
+
*
|
|
149
|
+
* **Error code:** `PLAY_XSTATE_INVALID_EVENT`
|
|
150
|
+
*
|
|
151
|
+
* @example
|
|
152
|
+
* ```typescript
|
|
153
|
+
* import { InvalidEventError } from "@xmachines/play-xstate/errors";
|
|
154
|
+
*
|
|
155
|
+
* try {
|
|
156
|
+
* actor.send(null as any);
|
|
157
|
+
* } catch (err) {
|
|
158
|
+
* if (err instanceof InvalidEventError) {
|
|
159
|
+
* // err.detail is typed as `unknown` — no cast needed
|
|
160
|
+
* console.error("Invalid event passed to actor.send():", err.detail);
|
|
161
|
+
* }
|
|
162
|
+
* }
|
|
163
|
+
* ```
|
|
164
|
+
*/
|
|
165
165
|
export declare class InvalidEventError extends PlayError {
|
|
166
|
+
/** The offending value passed to `send()`. */
|
|
166
167
|
readonly detail: unknown;
|
|
167
168
|
constructor(detail: unknown);
|
|
168
169
|
}
|
package/dist/errors.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,qBAAa,sBAAuB,SAAQ,SAAS;IACpD,0EAA0E;IAC1E,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAEvB,0FAA0F;IAC1F,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;gBAEd,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;CAU3C;AAED
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,qBAAa,sBAAuB,SAAQ,SAAS;IACpD,0EAA0E;IAC1E,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAEvB,0FAA0F;IAC1F,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;gBAEd,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;CAU3C;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,qBAAa,wBAAyB,SAAQ,SAAS;;CAWtD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,qBAAa,mBAAoB,SAAQ,SAAS;IACjD,oFAAoF;IACpF,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,8EAA8E;IAC9E,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;gBAEX,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM;CAW3C;AAED;;;;;GAKG;AACH,qBAAa,mBAAoB,SAAQ,SAAS;;CASjD;AAED;;;;;GAKG;AACH,qBAAa,yBAA0B,SAAQ,SAAS;IACvD,oEAAoE;IACpE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;gBAEZ,KAAK,EAAE,OAAO;CAU1B;AAED;;;;;GAKG;AACH,qBAAa,oBAAqB,SAAQ,SAAS;IAClD,8EAA8E;IAC9E,QAAQ,CAAC,UAAU,EAAE,KAAK,GAAG,IAAI,CAAC;gBAEtB,UAAU,EAAE,KAAK,GAAG,IAAI;CASpC;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,qBAAa,iBAAkB,SAAQ,SAAS;IAC/C,8CAA8C;IAC9C,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;gBAEb,MAAM,EAAE,OAAO;CAS3B"}
|
package/dist/errors.js
CHANGED
|
@@ -6,7 +6,7 @@ import { PlayError } from "@xmachines/play";
|
|
|
6
6
|
* Use the `param` and `template` fields to identify the missing parameter without
|
|
7
7
|
* parsing the `.message` string.
|
|
8
8
|
*
|
|
9
|
-
* **Error code:** `
|
|
9
|
+
* **Error code:** `PLAY_XSTATE_ROUTE_PARAM_MISSING`
|
|
10
10
|
*
|
|
11
11
|
* @example
|
|
12
12
|
* ```typescript
|
|
@@ -33,37 +33,12 @@ export class MissingRouteParamError extends PlayError {
|
|
|
33
33
|
/** The route template that required the missing parameter (e.g. `"/profile/:userId"`). */
|
|
34
34
|
template;
|
|
35
35
|
constructor(param, template) {
|
|
36
|
-
super("buildRouteUrl", "
|
|
36
|
+
super("buildRouteUrl", "PLAY_XSTATE_ROUTE_PARAM_MISSING", `Route parameter '${param}' is required by template '${template}' but was not found in context.`);
|
|
37
37
|
this.name = "MissingRouteParamError";
|
|
38
38
|
this.param = param;
|
|
39
39
|
this.template = template;
|
|
40
40
|
}
|
|
41
41
|
}
|
|
42
|
-
/**
|
|
43
|
-
* Thrown by `PlayerActor.send()` when the event argument is not a plain object.
|
|
44
|
-
*
|
|
45
|
-
* `PlayEvent` requires `{ type: string, ...fields }`. Passing `null`, `undefined`,
|
|
46
|
-
* a string, or any other non-object value is a programmer error.
|
|
47
|
-
*
|
|
48
|
-
* The offending value is attached as the `detail` readonly class field for debugging.
|
|
49
|
-
* TypeScript consumers can access `err.detail` directly without any unsafe cast.
|
|
50
|
-
*
|
|
51
|
-
* **Error code:** `PLAY_INVALID_EVENT`
|
|
52
|
-
*
|
|
53
|
-
* @example
|
|
54
|
-
* ```typescript
|
|
55
|
-
* import { InvalidEventError } from "@xmachines/play-xstate/errors";
|
|
56
|
-
*
|
|
57
|
-
* try {
|
|
58
|
-
* actor.send(null as any);
|
|
59
|
-
* } catch (err) {
|
|
60
|
-
* if (err instanceof InvalidEventError) {
|
|
61
|
-
* // err.detail is typed as `unknown` — no cast needed
|
|
62
|
-
* console.error("Invalid event passed to actor.send():", err.detail);
|
|
63
|
-
* }
|
|
64
|
-
* }
|
|
65
|
-
* ```
|
|
66
|
-
*/
|
|
67
42
|
/**
|
|
68
43
|
* Thrown by `buildRouteUrl()` when the context has a `params` field (indicating a
|
|
69
44
|
* routing-aware machine context) but no `query` field.
|
|
@@ -77,7 +52,7 @@ export class MissingRouteParamError extends PlayError {
|
|
|
77
52
|
* If using `formatPlayRouteTransitions`, the field is assigned automatically on each
|
|
78
53
|
* `play.route` event — but the machine's initial context must still declare it.
|
|
79
54
|
*
|
|
80
|
-
* **Error code:** `
|
|
55
|
+
* **Error code:** `PLAY_XSTATE_MISSING_QUERY_CONTEXT`
|
|
81
56
|
*
|
|
82
57
|
* @example
|
|
83
58
|
* ```typescript
|
|
@@ -98,7 +73,7 @@ export class MissingRouteParamError extends PlayError {
|
|
|
98
73
|
*/
|
|
99
74
|
export class MissingQueryContextError extends PlayError {
|
|
100
75
|
constructor() {
|
|
101
|
-
super("buildRouteUrl", "
|
|
76
|
+
super("buildRouteUrl", "PLAY_XSTATE_MISSING_QUERY_CONTEXT", "buildRouteUrl() received a context without a 'query' field. " +
|
|
102
77
|
"Declare 'query: Record<string, string>' in the machine context type and " +
|
|
103
78
|
"initialise it to {} so query parameters from play.route events are not silently dropped.");
|
|
104
79
|
this.name = "MissingQueryContextError";
|
|
@@ -113,7 +88,7 @@ export class MissingQueryContextError extends PlayError {
|
|
|
113
88
|
* the state is silently unreachable via routing. This error surfaces the
|
|
114
89
|
* misconfiguration at machine-definition time rather than silently skipping the state.
|
|
115
90
|
*
|
|
116
|
-
* **Error code:** `
|
|
91
|
+
* **Error code:** `PLAY_XSTATE_MISSING_STATE_ID`
|
|
117
92
|
*
|
|
118
93
|
* @example
|
|
119
94
|
* ```typescript
|
|
@@ -140,7 +115,7 @@ export class MissingStateIdError extends PlayError {
|
|
|
140
115
|
/** The route template declared on the state (e.g. `"/profile/:username"`). */
|
|
141
116
|
route;
|
|
142
117
|
constructor(stateKey, route) {
|
|
143
|
-
super("formatPlayRouteTransitions", "
|
|
118
|
+
super("formatPlayRouteTransitions", "PLAY_XSTATE_MISSING_STATE_ID", `State "${stateKey}" declares meta.route "${route}" but has no explicit id. ` +
|
|
144
119
|
`Add id: "${stateKey}" to the state config so play.route events can target it.`);
|
|
145
120
|
this.name = "MissingStateIdError";
|
|
146
121
|
this.stateKey = stateKey;
|
|
@@ -151,11 +126,11 @@ export class MissingStateIdError extends PlayError {
|
|
|
151
126
|
* Thrown by the `PlayerActor` constructor when the `machine` argument is not a
|
|
152
127
|
* valid XState machine object (null, undefined, or a non-object).
|
|
153
128
|
*
|
|
154
|
-
* **Error code:** `
|
|
129
|
+
* **Error code:** `PLAY_XSTATE_INVALID_MACHINE`
|
|
155
130
|
*/
|
|
156
131
|
export class InvalidMachineError extends PlayError {
|
|
157
132
|
constructor() {
|
|
158
|
-
super("PlayerActor", "
|
|
133
|
+
super("PlayerActor", "PLAY_XSTATE_INVALID_MACHINE", "PlayerActor requires a valid XState machine");
|
|
159
134
|
this.name = "InvalidMachineError";
|
|
160
135
|
}
|
|
161
136
|
}
|
|
@@ -163,14 +138,14 @@ export class InvalidMachineError extends PlayError {
|
|
|
163
138
|
* Thrown by `normalizeRoute()` when a state's `meta.route` value is neither a
|
|
164
139
|
* string nor an object with a `path` property.
|
|
165
140
|
*
|
|
166
|
-
* **Error code:** `
|
|
141
|
+
* **Error code:** `PLAY_XSTATE_INVALID_ROUTE_METADATA`
|
|
167
142
|
*/
|
|
168
143
|
export class InvalidRouteMetadataError extends PlayError {
|
|
169
144
|
/** The serialised form of the invalid route value for debugging. */
|
|
170
145
|
detail;
|
|
171
146
|
constructor(route) {
|
|
172
147
|
const detail = JSON.stringify(route);
|
|
173
|
-
super("deriveRoute", "
|
|
148
|
+
super("deriveRoute", "PLAY_XSTATE_INVALID_ROUTE_METADATA", `Invalid route metadata: ${detail}. Expected string or { path: string }`);
|
|
174
149
|
this.name = "InvalidRouteMetadataError";
|
|
175
150
|
this.detail = detail;
|
|
176
151
|
}
|
|
@@ -179,21 +154,47 @@ export class InvalidRouteMetadataError extends PlayError {
|
|
|
179
154
|
* Thrown by `composeGuards()` or `composeGuardsOr()` when called with an empty
|
|
180
155
|
* guards array. A composition of zero guards has no meaningful semantics.
|
|
181
156
|
*
|
|
182
|
-
* **Error code:** `
|
|
157
|
+
* **Error code:** `PLAY_XSTATE_EMPTY_GUARD_ARRAY`
|
|
183
158
|
*/
|
|
184
159
|
export class EmptyGuardArrayError extends PlayError {
|
|
185
160
|
/** The combinator that was called with an empty array (`"and"` or `"or"`). */
|
|
186
161
|
combinator;
|
|
187
162
|
constructor(combinator) {
|
|
188
|
-
super(combinator === "and" ? "composeGuards" : "composeGuardsOr", "
|
|
163
|
+
super(combinator === "and" ? "composeGuards" : "composeGuardsOr", "PLAY_XSTATE_EMPTY_GUARD_ARRAY", `${combinator === "and" ? "composeGuards" : "composeGuardsOr"} requires at least one guard`);
|
|
189
164
|
this.name = "EmptyGuardArrayError";
|
|
190
165
|
this.combinator = combinator;
|
|
191
166
|
}
|
|
192
167
|
}
|
|
168
|
+
/**
|
|
169
|
+
* Thrown by `PlayerActor.send()` when the event argument is not a plain object.
|
|
170
|
+
*
|
|
171
|
+
* `PlayEvent` requires `{ type: string, ...fields }`. Passing `null`, `undefined`,
|
|
172
|
+
* a string, or any other non-object value is a programmer error.
|
|
173
|
+
*
|
|
174
|
+
* The offending value is attached as the `detail` readonly class field for debugging.
|
|
175
|
+
* TypeScript consumers can access `err.detail` directly without any unsafe cast.
|
|
176
|
+
*
|
|
177
|
+
* **Error code:** `PLAY_XSTATE_INVALID_EVENT`
|
|
178
|
+
*
|
|
179
|
+
* @example
|
|
180
|
+
* ```typescript
|
|
181
|
+
* import { InvalidEventError } from "@xmachines/play-xstate/errors";
|
|
182
|
+
*
|
|
183
|
+
* try {
|
|
184
|
+
* actor.send(null as any);
|
|
185
|
+
* } catch (err) {
|
|
186
|
+
* if (err instanceof InvalidEventError) {
|
|
187
|
+
* // err.detail is typed as `unknown` — no cast needed
|
|
188
|
+
* console.error("Invalid event passed to actor.send():", err.detail);
|
|
189
|
+
* }
|
|
190
|
+
* }
|
|
191
|
+
* ```
|
|
192
|
+
*/
|
|
193
193
|
export class InvalidEventError extends PlayError {
|
|
194
|
+
/** The offending value passed to `send()`. */
|
|
194
195
|
detail;
|
|
195
196
|
constructor(detail) {
|
|
196
|
-
super("PlayerActor", "
|
|
197
|
+
super("PlayerActor", "PLAY_XSTATE_INVALID_EVENT", "PlayerActor.send() received a non-object event.");
|
|
197
198
|
this.name = "InvalidEventError";
|
|
198
199
|
this.detail = detail;
|
|
199
200
|
}
|
package/dist/errors.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,MAAM,OAAO,sBAAuB,SAAQ,SAAS;IACpD,0EAA0E;IACjE,KAAK,CAAS;IAEvB,0FAA0F;IACjF,QAAQ,CAAS;IAE1B,YAAY,KAAa,EAAE,QAAgB;QAC1C,KAAK,CACJ,eAAe,EACf,
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
|
package/dist/player-actor.d.ts
CHANGED
|
@@ -1,28 +1,7 @@
|
|
|
1
|
-
import { type AnyStateMachine, type Actor, type AnyActorLogic, type
|
|
1
|
+
import { type AnyStateMachine, type Actor, type AnyActorLogic, type EmittedFrom, type InputFrom, 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
|
-
/**
|
|
6
|
-
* Derive the actor's current URL from state metadata and context.
|
|
7
|
-
*
|
|
8
|
-
* Resolves the route template from the current state's `meta.route` and substitutes
|
|
9
|
-
* any `:param` placeholders from `context.params` (preferred) or flat `context`.
|
|
10
|
-
*
|
|
11
|
-
* Returns `null` — rather than throwing — when:
|
|
12
|
-
* - The snapshot has no route metadata (non-routable state)
|
|
13
|
-
* - A required route parameter is absent from context (`MissingRouteParamError`)
|
|
14
|
-
*
|
|
15
|
-
* The `null` return on missing params is intentional: it keeps the computed signal
|
|
16
|
-
* stable during transient states (e.g. mid-transition before context is fully updated,
|
|
17
|
-
* or after logout when `context.username` is `null` but the router bridge has not yet
|
|
18
|
-
* synced to the new state). The router bridge and URL bar are updated on the next
|
|
19
|
-
* stable snapshot once context is complete.
|
|
20
|
-
*
|
|
21
|
-
* @param snapshot - Current XState machine snapshot.
|
|
22
|
-
* @returns Resolved URL string, or `null` if the route cannot be resolved.
|
|
23
|
-
*/
|
|
24
|
-
/** @internal — exported for `definePlayer` pre-computation only. */
|
|
25
|
-
export declare const deriveCurrentRoute: (snapshot: AnyMachineSnapshot) => string | null;
|
|
26
5
|
/**
|
|
27
6
|
* Concrete XState actor implementing Play Architecture signal protocol
|
|
28
7
|
*
|
|
@@ -100,9 +79,10 @@ export declare const deriveCurrentRoute: (snapshot: AnyMachineSnapshot) => strin
|
|
|
100
79
|
*/
|
|
101
80
|
export declare class PlayerActor<TMachine extends AnyStateMachine> extends AbstractActor<AnyActorLogic, EventFromLogic<TMachine>> implements Routable, Viewable {
|
|
102
81
|
private xstateActor;
|
|
103
|
-
private stateManager;
|
|
104
82
|
private playerOptions;
|
|
105
83
|
private viewSignal;
|
|
84
|
+
/** Last spec emitted on the view signal — used to skip no-change re-emissions. */
|
|
85
|
+
private lastEmittedView;
|
|
106
86
|
state: Signal.State<ReturnType<TMachine["transition"]>>;
|
|
107
87
|
/**
|
|
108
88
|
* Returns whether the actor's current state can accept the given event.
|
|
@@ -143,24 +123,23 @@ export declare class PlayerActor<TMachine extends AnyStateMachine> extends Abstr
|
|
|
143
123
|
* (non-initial URL → router wins) from a restore (initial URL + actor at a
|
|
144
124
|
* different restored route → actor wins).
|
|
145
125
|
*
|
|
146
|
-
*
|
|
147
|
-
*
|
|
148
|
-
*
|
|
149
|
-
*
|
|
150
|
-
*
|
|
151
|
-
*
|
|
152
|
-
* derived from `xstateActor.getSnapshot()` (normal path) or a transient
|
|
153
|
-
* `createActor(machine, { input })` call (restore path, to avoid using the
|
|
154
|
-
* snapshot's state instead of the machine's default).
|
|
126
|
+
* Derived statically from the machine definition via `deriveInitialRoute`
|
|
127
|
+
* (XState's pure `initialTransition` helper): the initial state chain and its
|
|
128
|
+
* `meta.route` templates are fixed at machine definition time, while `:param`
|
|
129
|
+
* substitution uses the machine's real initial context for this actor's `input`.
|
|
130
|
+
* No extra actor is ever created, and a restored snapshot never influences the
|
|
131
|
+
* value — it is always the machine's **default** initial route.
|
|
155
132
|
*/
|
|
156
133
|
readonly initialRoute: string | null;
|
|
157
134
|
/**
|
|
158
135
|
* Reactive signal containing the current view spec derived from the active state's
|
|
159
136
|
* `meta.view` metadata.
|
|
160
137
|
*
|
|
161
|
-
*
|
|
162
|
-
*
|
|
163
|
-
*
|
|
138
|
+
* Emits a **fresh object reference** whenever the rendered view actually changes —
|
|
139
|
+
* a different state's view, or a param/context change that alters the resolved
|
|
140
|
+
* spec (including `reenter: true` re-entries with new params). Snapshots that do
|
|
141
|
+
* not change the rendered view (e.g. context-only assigns) keep the previous
|
|
142
|
+
* reference so downstream providers do not remount the UI on every event.
|
|
164
143
|
*
|
|
165
144
|
* The emitted `PlaySpec` has its element `props` enriched with `context.params`
|
|
166
145
|
* before emission — URL path parameters (e.g. `:section?`) flow into component props
|
|
@@ -178,17 +157,7 @@ export declare class PlayerActor<TMachine extends AnyStateMachine> extends Abstr
|
|
|
178
157
|
* ```
|
|
179
158
|
*/
|
|
180
159
|
currentView: Signal.State<PlaySpec | null>;
|
|
181
|
-
constructor(machine: TMachine, options: PlayerOptions<TMachine>, input?: InputFrom<TMachine>, restoredSnapshot?: SnapshotFrom<TMachine
|
|
182
|
-
/**
|
|
183
|
-
* Pre-computed initial route from `definePlayer`.
|
|
184
|
-
* `initialRoute` is determined by the machine's initial state node and its
|
|
185
|
-
* `meta.route` template — both fixed at machine definition time regardless
|
|
186
|
-
* of `input` or `snapshot`. When provided, used directly on every construction,
|
|
187
|
-
* eliminating a redundant `createActor()` call per actor instance.
|
|
188
|
-
*
|
|
189
|
-
* @internal — set by `definePlayer`; callers should not pass this directly.
|
|
190
|
-
*/
|
|
191
|
-
_cachedInitialRoute?: string | null);
|
|
160
|
+
constructor(machine: TMachine, options: PlayerOptions<TMachine>, input?: InputFrom<TMachine>, restoredSnapshot?: SnapshotFrom<TMachine>);
|
|
192
161
|
/**
|
|
193
162
|
* Start the actor
|
|
194
163
|
*
|
|
@@ -224,6 +193,43 @@ export declare class PlayerActor<TMachine extends AnyStateMachine> extends Abstr
|
|
|
224
193
|
* Get current snapshot
|
|
225
194
|
*/
|
|
226
195
|
getSnapshot(): ReturnType<Actor<TMachine>["getSnapshot"]>;
|
|
196
|
+
/**
|
|
197
|
+
* Subscribe to snapshot updates from the wrapped XState actor.
|
|
198
|
+
*
|
|
199
|
+
* Accepts an observer object, exactly like XState's `Actor.subscribe`.
|
|
200
|
+
*
|
|
201
|
+
* @param observer - Observer with `next`/`error`/`complete` handlers.
|
|
202
|
+
* @returns Subscription with an `unsubscribe()` method.
|
|
203
|
+
*/
|
|
204
|
+
subscribe(observer: Observer<SnapshotFrom<TMachine>>): Subscription;
|
|
205
|
+
/**
|
|
206
|
+
* Subscribe to snapshot updates from the wrapped XState actor.
|
|
207
|
+
*
|
|
208
|
+
* Accepts listener functions, exactly like XState's `Actor.subscribe`.
|
|
209
|
+
*
|
|
210
|
+
* @param nextListener - Snapshot listener function.
|
|
211
|
+
* @param errorListener - Called when the actor errors.
|
|
212
|
+
* @param completeListener - Called when the actor completes (reaches a final state).
|
|
213
|
+
* @returns Subscription with an `unsubscribe()` method.
|
|
214
|
+
*/
|
|
215
|
+
subscribe(nextListener?: (snapshot: SnapshotFrom<TMachine>) => void, errorListener?: (error: unknown) => void, completeListener?: () => void): Subscription;
|
|
216
|
+
/**
|
|
217
|
+
* Listen for events emitted by the wrapped XState actor via the `emit` action.
|
|
218
|
+
*
|
|
219
|
+
* @param type - Emitted event type to listen for, or `"*"` for all.
|
|
220
|
+
* @param handler - Called with each matching emitted event.
|
|
221
|
+
* @returns Subscription with an `unsubscribe()` method.
|
|
222
|
+
*/
|
|
223
|
+
on<TType extends EmittedFrom<TMachine>["type"] | "*">(type: TType, handler: (emitted: EmittedFrom<TMachine> & (TType extends "*" ? unknown : {
|
|
224
|
+
type: TType;
|
|
225
|
+
})) => void): Subscription;
|
|
226
|
+
/**
|
|
227
|
+
* Get the persisted snapshot of the wrapped XState actor.
|
|
228
|
+
*
|
|
229
|
+
* Suitable for serialization and later restoration via the factory's
|
|
230
|
+
* `restore.snapshot` option.
|
|
231
|
+
*/
|
|
232
|
+
getPersistedSnapshot(): Snapshot<unknown>;
|
|
227
233
|
/**
|
|
228
234
|
* Validate view at state entry and cache result
|
|
229
235
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"player-actor.d.ts","sourceRoot":"","sources":["../src/player-actor.ts"],"names":[],"mappings":"AAAA,OAAO,EAEN,KAAK,eAAe,EACpB,KAAK,KAAK,EACV,KAAK,aAAa,
|
|
1
|
+
{"version":3,"file":"player-actor.d.ts","sourceRoot":"","sources":["../src/player-actor.ts"],"names":[],"mappings":"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"}
|