@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.
- package/README.md +114 -114
- package/dist/define-player.d.ts +16 -16
- package/dist/define-player.js +16 -16
- package/dist/errors.d.ts +84 -101
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +108 -108
- package/dist/errors.js.map +1 -1
- package/dist/guards/compose.d.ts +70 -77
- package/dist/guards/compose.d.ts.map +1 -1
- package/dist/guards/compose.js +90 -113
- package/dist/guards/compose.js.map +1 -1
- package/dist/guards/helpers.d.ts +22 -18
- package/dist/guards/helpers.d.ts.map +1 -1
- package/dist/guards/helpers.js +23 -19
- package/dist/guards/helpers.js.map +1 -1
- package/dist/guards/index.d.ts +10 -3
- package/dist/guards/index.d.ts.map +1 -1
- package/dist/guards/index.js +10 -3
- package/dist/guards/index.js.map +1 -1
- package/dist/guards/types.d.ts +9 -9
- package/dist/guards/types.d.ts.map +1 -1
- package/dist/index.d.ts +8 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -10
- package/dist/index.js.map +1 -1
- package/dist/player-actor.d.ts +197 -113
- package/dist/player-actor.d.ts.map +1 -1
- package/dist/player-actor.js +413 -401
- package/dist/player-actor.js.map +1 -1
- package/dist/routing/build-url.d.ts +19 -21
- package/dist/routing/build-url.d.ts.map +1 -1
- package/dist/routing/build-url.js +70 -71
- package/dist/routing/build-url.js.map +1 -1
- package/dist/routing/derive-current-route.d.ts +51 -13
- package/dist/routing/derive-current-route.d.ts.map +1 -1
- package/dist/routing/derive-current-route.js +69 -60
- package/dist/routing/derive-current-route.js.map +1 -1
- package/dist/routing/derive-initial-route.d.ts +23 -23
- package/dist/routing/derive-initial-route.js +27 -27
- package/dist/routing/derive-initial-route.js.map +1 -1
- package/dist/routing/derive-route.d.ts +38 -37
- package/dist/routing/derive-route.d.ts.map +1 -1
- package/dist/routing/derive-route.js +45 -42
- package/dist/routing/derive-route.js.map +1 -1
- package/dist/routing/format-play-route-transitions.d.ts +34 -71
- package/dist/routing/format-play-route-transitions.d.ts.map +1 -1
- package/dist/routing/format-play-route-transitions.js +74 -130
- package/dist/routing/format-play-route-transitions.js.map +1 -1
- package/dist/routing/index.d.ts +4 -8
- package/dist/routing/index.d.ts.map +1 -1
- package/dist/routing/index.js +4 -6
- package/dist/routing/index.js.map +1 -1
- package/dist/routing/types.d.ts +12 -11
- package/dist/routing/types.d.ts.map +1 -1
- package/dist/types.d.ts +97 -20
- package/dist/types.d.ts.map +1 -1
- package/dist/view/derive-current-view.d.ts +51 -0
- package/dist/view/derive-current-view.d.ts.map +1 -0
- package/dist/view/derive-current-view.js +119 -0
- package/dist/view/derive-current-view.js.map +1 -0
- package/package.json +22 -21
- 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/guards/compose.typecheck.d.ts +0 -2
- package/dist/guards/compose.typecheck.d.ts.map +0 -1
- package/dist/guards/compose.typecheck.js +0 -22
- package/dist/guards/compose.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 -30
- package/dist/player-actor.typecheck.js.map +0 -1
- package/dist/routing/create-routed-machine.d.ts +0 -71
- package/dist/routing/create-routed-machine.d.ts.map +0 -1
- package/dist/routing/create-routed-machine.js +0 -71
- package/dist/routing/create-routed-machine.js.map +0 -1
- package/dist/routing/play-route-event.typecheck.d.ts +0 -2
- package/dist/routing/play-route-event.typecheck.d.ts.map +0 -1
- package/dist/routing/play-route-event.typecheck.js +0 -43
- package/dist/routing/play-route-event.typecheck.js.map +0 -1
- package/dist/routing/schemas.d.ts +0 -99
- package/dist/routing/schemas.d.ts.map +0 -1
- package/dist/routing/schemas.js +0 -30
- package/dist/routing/schemas.js.map +0 -1
- package/dist/schemas.d.ts +0 -28
- package/dist/schemas.d.ts.map +0 -1
- package/dist/schemas.js +0 -29
- package/dist/schemas.js.map +0 -1
package/dist/errors.d.ts
CHANGED
|
@@ -1,23 +1,24 @@
|
|
|
1
1
|
import { PlayError } from "@xmachines/play";
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
3
|
+
* `buildRouteUrl()` throws this error when the context of the actor does not hold a
|
|
4
|
+
* necessary route parameter.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
6
|
+
* Read the `param` field and the `template` field to identify the parameter that is
|
|
7
|
+
* absent. Your code therefore parses no `.message` string.
|
|
8
8
|
*
|
|
9
9
|
* **Error code:** `PLAY_XSTATE_ROUTE_PARAM_MISSING`
|
|
10
10
|
*
|
|
11
|
+
* Note: `actor.currentRoute.get()` shows this error never. The route derivation
|
|
12
|
+
* catches it, and it returns `null` for the temporary case during a transition. The
|
|
13
|
+
* error leaves a direct `buildRouteUrl()` call only.
|
|
14
|
+
*
|
|
11
15
|
* @example
|
|
12
16
|
* ```typescript
|
|
17
|
+
* import { buildRouteUrl } from "@xmachines/play-xstate";
|
|
13
18
|
* import { MissingRouteParamError } from "@xmachines/play-xstate/errors";
|
|
14
19
|
*
|
|
15
|
-
* // The route template "/profile/:userId" requires "userId" in context.
|
|
16
|
-
* // If userId is absent, MissingRouteParamError is thrown when the
|
|
17
|
-
* // actor.currentRoute signal is read.
|
|
18
|
-
*
|
|
19
20
|
* try {
|
|
20
|
-
*
|
|
21
|
+
* buildRouteUrl("/profile/:userId", { params: {}, query: {} });
|
|
21
22
|
* } catch (err) {
|
|
22
23
|
* if (err instanceof MissingRouteParamError) {
|
|
23
24
|
* console.error(
|
|
@@ -28,65 +29,48 @@ import { PlayError } from "@xmachines/play";
|
|
|
28
29
|
* ```
|
|
29
30
|
*/
|
|
30
31
|
export declare class MissingRouteParamError extends PlayError {
|
|
31
|
-
/** The name of the route parameter that was
|
|
32
|
+
/** The name of the route parameter that was absent, for example `"userId"`. */
|
|
32
33
|
readonly param: string;
|
|
33
|
-
/** The route template that
|
|
34
|
+
/** The route template that needs the absent parameter, for example `"/profile/:userId"`. */
|
|
34
35
|
readonly template: string;
|
|
35
36
|
constructor(param: string, template: string);
|
|
36
37
|
}
|
|
37
38
|
/**
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
39
|
+
* @deprecated Nothing throws this error now. `buildRouteUrl` reads an absent `query`
|
|
40
|
+
* field as `query: {}`. The generated `play.route` transitions assign `query` on
|
|
41
|
+
* every navigation, and the loss that this error guarded against therefore cannot
|
|
42
|
+
* happen through the route derivation. A machine that handles `play.route` itself
|
|
43
|
+
* and wants the query must assign `event.query` to its context itself. This class
|
|
44
|
+
* stays in the exports, so that an `instanceof` handler that exists now still
|
|
45
|
+
* compiles. Remove such a handler when you have the time.
|
|
44
46
|
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
* If using `formatPlayRouteTransitions`, the field is assigned automatically on each
|
|
48
|
-
* `play.route` event — but the machine's initial context must still declare it.
|
|
47
|
+
* `buildRouteUrl()` threw this error before, when the context had a `params` field,
|
|
48
|
+
* which means a context that knows the routing, but no `query` field.
|
|
49
49
|
*
|
|
50
50
|
* **Error code:** `PLAY_XSTATE_MISSING_QUERY_CONTEXT`
|
|
51
|
-
*
|
|
52
|
-
* @example
|
|
53
|
-
* ```typescript
|
|
54
|
-
* import { MissingQueryContextError } from "@xmachines/play-xstate/errors";
|
|
55
|
-
*
|
|
56
|
-
* try {
|
|
57
|
-
* // params present but no query field — throws
|
|
58
|
-
* buildRouteUrl("/profile/:userId", { params: { userId: "42" } });
|
|
59
|
-
* } catch (err) {
|
|
60
|
-
* if (err instanceof MissingQueryContextError) {
|
|
61
|
-
* console.error("Machine context missing query field");
|
|
62
|
-
* }
|
|
63
|
-
* }
|
|
64
|
-
*
|
|
65
|
-
* // Correct — both params and query declared
|
|
66
|
-
* buildRouteUrl("/profile/:userId", { params: { userId: "42" }, query: {} });
|
|
67
|
-
* ```
|
|
68
51
|
*/
|
|
69
52
|
export declare class MissingQueryContextError extends PlayError {
|
|
70
53
|
constructor();
|
|
71
54
|
}
|
|
72
55
|
/**
|
|
73
|
-
*
|
|
74
|
-
* but
|
|
56
|
+
* `formatPlayRouteTransitions()` throws this error when a state node declares a
|
|
57
|
+
* `meta.route` field but no explicit `id` field.
|
|
75
58
|
*
|
|
76
|
-
* Without `id`, the function
|
|
77
|
-
* state
|
|
78
|
-
* the state
|
|
79
|
-
*
|
|
59
|
+
* Without an `id`, the function can generate no `play.route` guard that targets the
|
|
60
|
+
* state: the guard compares `event.to` with `#<id>`. An absent `id` therefore makes
|
|
61
|
+
* the state unreachable through the routing, and nothing says so. This error shows
|
|
62
|
+
* the fault of the configuration at the moment of the machine definition, and the
|
|
63
|
+
* function skips no state in silence.
|
|
80
64
|
*
|
|
81
65
|
* **Error code:** `PLAY_XSTATE_MISSING_STATE_ID`
|
|
82
66
|
*
|
|
83
67
|
* @example
|
|
84
68
|
* ```typescript
|
|
85
|
-
* // Bad — meta.route without id:
|
|
69
|
+
* // Bad — a meta.route field without an id field:
|
|
86
70
|
* states: {
|
|
87
71
|
* profile: {
|
|
88
72
|
* meta: { route: "/profile/:username" },
|
|
89
|
-
* // ←
|
|
73
|
+
* // ← the id: "profile" field is absent
|
|
90
74
|
* }
|
|
91
75
|
* }
|
|
92
76
|
*
|
|
@@ -100,15 +84,16 @@ export declare class MissingQueryContextError extends PlayError {
|
|
|
100
84
|
* ```
|
|
101
85
|
*/
|
|
102
86
|
export declare class MissingStateIdError extends PlayError {
|
|
103
|
-
/** The state key
|
|
87
|
+
/** The state key, which is the position in the tree of the states, without an explicit `id` field. */
|
|
104
88
|
readonly stateKey: string;
|
|
105
|
-
/** The route template
|
|
89
|
+
/** The route template of the state, for example `"/profile/:username"`. */
|
|
106
90
|
readonly route: string;
|
|
107
91
|
constructor(stateKey: string, route: string);
|
|
108
92
|
}
|
|
109
93
|
/**
|
|
110
|
-
*
|
|
111
|
-
* valid XState machine object
|
|
94
|
+
* The `PlayerActor` constructor throws this error when the `machine` argument is not
|
|
95
|
+
* a valid XState machine object, which means that it is null, undefined, or not an
|
|
96
|
+
* object.
|
|
112
97
|
*
|
|
113
98
|
* **Error code:** `PLAY_XSTATE_INVALID_MACHINE`
|
|
114
99
|
*/
|
|
@@ -116,73 +101,38 @@ export declare class InvalidMachineError extends PlayError {
|
|
|
116
101
|
constructor();
|
|
117
102
|
}
|
|
118
103
|
/**
|
|
119
|
-
*
|
|
120
|
-
* string
|
|
104
|
+
* `normalizeRoute()` throws this error when the `meta.route` value of a state is not
|
|
105
|
+
* a string and not an object with a `path` property.
|
|
121
106
|
*
|
|
122
107
|
* **Error code:** `PLAY_XSTATE_INVALID_ROUTE_METADATA`
|
|
123
108
|
*/
|
|
124
109
|
export declare class InvalidRouteMetadataError extends PlayError {
|
|
125
|
-
/** The
|
|
110
|
+
/** The invalid route value, as a string, for the debug work. */
|
|
126
111
|
readonly detail: string;
|
|
127
112
|
constructor(route: unknown, source?: string);
|
|
128
113
|
}
|
|
129
114
|
/**
|
|
130
|
-
*
|
|
131
|
-
* guards
|
|
115
|
+
* `composeGuards()` and `composeGuardsOr()` throw this error for an empty array of
|
|
116
|
+
* guards. A composition of zero guards has no meaning.
|
|
132
117
|
*
|
|
133
118
|
* **Error code:** `PLAY_XSTATE_EMPTY_GUARD_ARRAY`
|
|
134
119
|
*/
|
|
135
120
|
export declare class EmptyGuardArrayError extends PlayError {
|
|
136
|
-
/** The combinator
|
|
121
|
+
/** The combinator of the call with the empty array: `"and"` or `"or"`. */
|
|
137
122
|
readonly combinator: "and" | "or";
|
|
138
123
|
constructor(combinator: "and" | "or");
|
|
139
124
|
}
|
|
140
125
|
/**
|
|
141
|
-
*
|
|
142
|
-
*
|
|
143
|
-
*/
|
|
144
|
-
export type GuardCombinator = "composeGuards" | "composeGuardsOr" | "negateGuard";
|
|
145
|
-
/**
|
|
146
|
-
* Thrown when a composed guard cannot resolve a string guard name at call time.
|
|
147
|
-
*
|
|
148
|
-
* String names in `composeGuards`/`composeGuardsOr`/`negateGuard` resolve
|
|
149
|
-
* against `args.guards` — the named guards from `setup({ guards })` that
|
|
150
|
-
* XState v6 provides to transition functions, `always`, entry/exit actions
|
|
151
|
-
* (since 6.0.0-alpha.20), and function-form route resolvers. Resolution fails
|
|
152
|
-
* when the name was never declared or when the composed guard is called
|
|
153
|
-
* without transition arguments.
|
|
154
|
-
*
|
|
155
|
-
* **Error code:** `PLAY_XSTATE_UNRESOLVABLE_GUARD_NAME`
|
|
156
|
-
*/
|
|
157
|
-
export declare class UnresolvableGuardNameError extends PlayError {
|
|
158
|
-
/** The guard name that could not be resolved. */
|
|
159
|
-
readonly guardName: string;
|
|
160
|
-
constructor(guardName: string, origin: GuardCombinator);
|
|
161
|
-
}
|
|
162
|
-
/**
|
|
163
|
-
* Thrown when a composed guard evaluates an entry that is neither a predicate
|
|
164
|
-
* function nor a guard name — typically `null`/`undefined` from a typo'd
|
|
165
|
-
* import or an optional lookup.
|
|
126
|
+
* `PlayerActor.send()` throws this error when the event argument is not a plain
|
|
127
|
+
* object.
|
|
166
128
|
*
|
|
167
|
-
*
|
|
168
|
-
*
|
|
169
|
-
*
|
|
129
|
+
* A `PlayEvent` needs the shape `{ type: string, ...fields }`. A `null` value, an
|
|
130
|
+
* `undefined` value, a string, and every other value that is not an object are an
|
|
131
|
+
* error of the programmer.
|
|
170
132
|
*
|
|
171
|
-
*
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
/** `typeof` of the invalid entry (e.g. `"undefined"`, `"object"` for null). */
|
|
175
|
-
readonly entryType: string;
|
|
176
|
-
constructor(entryType: string, origin: GuardCombinator);
|
|
177
|
-
}
|
|
178
|
-
/**
|
|
179
|
-
* Thrown by `PlayerActor.send()` when the event argument is not a plain object.
|
|
180
|
-
*
|
|
181
|
-
* `PlayEvent` requires `{ type: string, ...fields }`. Passing `null`, `undefined`,
|
|
182
|
-
* a string, or any other non-object value is a programmer error.
|
|
183
|
-
*
|
|
184
|
-
* The offending value is attached as the `detail` readonly class field for debugging.
|
|
185
|
-
* TypeScript consumers can access `err.detail` directly without any unsafe cast.
|
|
133
|
+
* The error holds the value in question in its readonly class field `detail`, for
|
|
134
|
+
* the debug work. A TypeScript consumer reads `err.detail` directly, with no unsafe
|
|
135
|
+
* cast.
|
|
186
136
|
*
|
|
187
137
|
* **Error code:** `PLAY_XSTATE_INVALID_EVENT`
|
|
188
138
|
*
|
|
@@ -194,15 +144,48 @@ export declare class InvalidGuardEntryError extends PlayError {
|
|
|
194
144
|
* actor.send(null as any);
|
|
195
145
|
* } catch (err) {
|
|
196
146
|
* if (err instanceof InvalidEventError) {
|
|
197
|
-
* // err.detail
|
|
147
|
+
* // err.detail has the type `unknown`, and it needs no cast
|
|
198
148
|
* console.error("Invalid event passed to actor.send():", err.detail);
|
|
199
149
|
* }
|
|
200
150
|
* }
|
|
201
151
|
* ```
|
|
202
152
|
*/
|
|
203
153
|
export declare class InvalidEventError extends PlayError {
|
|
204
|
-
/** The
|
|
154
|
+
/** The value in question, from the `send()` call. */
|
|
205
155
|
readonly detail: unknown;
|
|
206
156
|
constructor(detail: unknown);
|
|
207
157
|
}
|
|
158
|
+
/**
|
|
159
|
+
* The actor gives this error to `PlayerOptions.onError` when it failed with a value
|
|
160
|
+
* that is not an `Error`, for example after a machine action ran
|
|
161
|
+
* `throw { code: 42 }`.
|
|
162
|
+
*
|
|
163
|
+
* An actor error that *is* an `Error` reaches `onError` without a change, and it
|
|
164
|
+
* keeps the identity of the machine. This case alone builds a new error. The new
|
|
165
|
+
* error therefore carries a code that your code can match, and not a
|
|
166
|
+
* `String(value)` message such as `"[object Object]"`. The `cause` field holds the
|
|
167
|
+
* value from the throw.
|
|
168
|
+
*
|
|
169
|
+
* **Error code:** `PLAY_XSTATE_NON_ERROR_THROWN`
|
|
170
|
+
*
|
|
171
|
+
* @example
|
|
172
|
+
* ```typescript
|
|
173
|
+
* import { ActorThrewNonErrorError } from "@xmachines/play-xstate/errors";
|
|
174
|
+
*
|
|
175
|
+
* definePlayer({
|
|
176
|
+
* machine,
|
|
177
|
+
* options: {
|
|
178
|
+
* onError: (actor, err) => {
|
|
179
|
+
* if (err instanceof ActorThrewNonErrorError) {
|
|
180
|
+
* // err.cause is the value that the machine threw
|
|
181
|
+
* console.error("Machine threw a non-Error:", err.cause);
|
|
182
|
+
* }
|
|
183
|
+
* },
|
|
184
|
+
* },
|
|
185
|
+
* });
|
|
186
|
+
* ```
|
|
187
|
+
*/
|
|
188
|
+
export declare class ActorThrewNonErrorError extends PlayError {
|
|
189
|
+
constructor(value: unknown);
|
|
190
|
+
}
|
|
208
191
|
//# sourceMappingURL=errors.d.ts.map
|
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;
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAsB5C;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,qBAAa,sBAAuB,SAAQ,SAAS;IACpD,+EAA+E;IAC/E,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAEvB,4FAA4F;IAC5F,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;gBAEd,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;CAU3C;AAED;;;;;;;;;;;;;GAaG;AACH,qBAAa,wBAAyB,SAAQ,SAAS;;CAWtD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,qBAAa,mBAAoB,SAAQ,SAAS;IACjD,sGAAsG;IACtG,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,2EAA2E;IAC3E,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;gBAEX,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM;CAW3C;AAED;;;;;;GAMG;AACH,qBAAa,mBAAoB,SAAQ,SAAS;;CASjD;AAED;;;;;GAKG;AACH,qBAAa,yBAA0B,SAAQ,SAAS;IACvD,gEAAgE;IAChE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;gBAEZ,KAAK,EAAE,OAAO,EAAE,MAAM,SAAgB;CAUlD;AAED;;;;;GAKG;AACH,qBAAa,oBAAqB,SAAQ,SAAS;IAClD,0EAA0E;IAC1E,QAAQ,CAAC,UAAU,EAAE,KAAK,GAAG,IAAI,CAAC;gBAEtB,UAAU,EAAE,KAAK,GAAG,IAAI;CASpC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,qBAAa,iBAAkB,SAAQ,SAAS;IAC/C,qDAAqD;IACrD,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;gBAEb,MAAM,EAAE,OAAO;CAS3B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,qBAAa,uBAAwB,SAAQ,SAAS;gBACzC,KAAK,EAAE,OAAO;CAS1B"}
|
package/dist/errors.js
CHANGED
|
@@ -1,23 +1,45 @@
|
|
|
1
1
|
import { PlayError } from "@xmachines/play";
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
3
|
+
* Converts a value from a throw into a string, and it trusts that value not:
|
|
4
|
+
* `String()` itself throws for an object with a null prototype, and also for a value
|
|
5
|
+
* whose `toString` or `Symbol.toPrimitive` throws. This function runs inside the
|
|
6
|
+
* error path. A second throw here therefore replaces the real failure of the machine
|
|
7
|
+
* with a `TypeError`, and it passes around `onError`.
|
|
8
|
+
*/
|
|
9
|
+
const safeString = (value) => {
|
|
10
|
+
try {
|
|
11
|
+
return String(value);
|
|
12
|
+
}
|
|
13
|
+
catch {
|
|
14
|
+
try {
|
|
15
|
+
return Object.prototype.toString.call(value);
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
// A revoked Proxy throws also on an inspection of the brand.
|
|
19
|
+
return "[unrepresentable value]";
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* `buildRouteUrl()` throws this error when the context of the actor does not hold a
|
|
25
|
+
* necessary route parameter.
|
|
5
26
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
27
|
+
* Read the `param` field and the `template` field to identify the parameter that is
|
|
28
|
+
* absent. Your code therefore parses no `.message` string.
|
|
8
29
|
*
|
|
9
30
|
* **Error code:** `PLAY_XSTATE_ROUTE_PARAM_MISSING`
|
|
10
31
|
*
|
|
32
|
+
* Note: `actor.currentRoute.get()` shows this error never. The route derivation
|
|
33
|
+
* catches it, and it returns `null` for the temporary case during a transition. The
|
|
34
|
+
* error leaves a direct `buildRouteUrl()` call only.
|
|
35
|
+
*
|
|
11
36
|
* @example
|
|
12
37
|
* ```typescript
|
|
38
|
+
* import { buildRouteUrl } from "@xmachines/play-xstate";
|
|
13
39
|
* import { MissingRouteParamError } from "@xmachines/play-xstate/errors";
|
|
14
40
|
*
|
|
15
|
-
* // The route template "/profile/:userId" requires "userId" in context.
|
|
16
|
-
* // If userId is absent, MissingRouteParamError is thrown when the
|
|
17
|
-
* // actor.currentRoute signal is read.
|
|
18
|
-
*
|
|
19
41
|
* try {
|
|
20
|
-
*
|
|
42
|
+
* buildRouteUrl("/profile/:userId", { params: {}, query: {} });
|
|
21
43
|
* } catch (err) {
|
|
22
44
|
* if (err instanceof MissingRouteParamError) {
|
|
23
45
|
* console.error(
|
|
@@ -28,9 +50,9 @@ import { PlayError } from "@xmachines/play";
|
|
|
28
50
|
* ```
|
|
29
51
|
*/
|
|
30
52
|
export class MissingRouteParamError extends PlayError {
|
|
31
|
-
/** The name of the route parameter that was
|
|
53
|
+
/** The name of the route parameter that was absent, for example `"userId"`. */
|
|
32
54
|
param;
|
|
33
|
-
/** The route template that
|
|
55
|
+
/** The route template that needs the absent parameter, for example `"/profile/:userId"`. */
|
|
34
56
|
template;
|
|
35
57
|
constructor(param, template) {
|
|
36
58
|
super("buildRouteUrl", "PLAY_XSTATE_ROUTE_PARAM_MISSING", `Route parameter '${param}' is required by template '${template}' but was not found in context.`);
|
|
@@ -40,36 +62,18 @@ export class MissingRouteParamError extends PlayError {
|
|
|
40
62
|
}
|
|
41
63
|
}
|
|
42
64
|
/**
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
65
|
+
* @deprecated Nothing throws this error now. `buildRouteUrl` reads an absent `query`
|
|
66
|
+
* field as `query: {}`. The generated `play.route` transitions assign `query` on
|
|
67
|
+
* every navigation, and the loss that this error guarded against therefore cannot
|
|
68
|
+
* happen through the route derivation. A machine that handles `play.route` itself
|
|
69
|
+
* and wants the query must assign `event.query` to its context itself. This class
|
|
70
|
+
* stays in the exports, so that an `instanceof` handler that exists now still
|
|
71
|
+
* compiles. Remove such a handler when you have the time.
|
|
49
72
|
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
* If using `formatPlayRouteTransitions`, the field is assigned automatically on each
|
|
53
|
-
* `play.route` event — but the machine's initial context must still declare it.
|
|
73
|
+
* `buildRouteUrl()` threw this error before, when the context had a `params` field,
|
|
74
|
+
* which means a context that knows the routing, but no `query` field.
|
|
54
75
|
*
|
|
55
76
|
* **Error code:** `PLAY_XSTATE_MISSING_QUERY_CONTEXT`
|
|
56
|
-
*
|
|
57
|
-
* @example
|
|
58
|
-
* ```typescript
|
|
59
|
-
* import { MissingQueryContextError } from "@xmachines/play-xstate/errors";
|
|
60
|
-
*
|
|
61
|
-
* try {
|
|
62
|
-
* // params present but no query field — throws
|
|
63
|
-
* buildRouteUrl("/profile/:userId", { params: { userId: "42" } });
|
|
64
|
-
* } catch (err) {
|
|
65
|
-
* if (err instanceof MissingQueryContextError) {
|
|
66
|
-
* console.error("Machine context missing query field");
|
|
67
|
-
* }
|
|
68
|
-
* }
|
|
69
|
-
*
|
|
70
|
-
* // Correct — both params and query declared
|
|
71
|
-
* buildRouteUrl("/profile/:userId", { params: { userId: "42" }, query: {} });
|
|
72
|
-
* ```
|
|
73
77
|
*/
|
|
74
78
|
export class MissingQueryContextError extends PlayError {
|
|
75
79
|
constructor() {
|
|
@@ -80,23 +84,24 @@ export class MissingQueryContextError extends PlayError {
|
|
|
80
84
|
}
|
|
81
85
|
}
|
|
82
86
|
/**
|
|
83
|
-
*
|
|
84
|
-
* but
|
|
87
|
+
* `formatPlayRouteTransitions()` throws this error when a state node declares a
|
|
88
|
+
* `meta.route` field but no explicit `id` field.
|
|
85
89
|
*
|
|
86
|
-
* Without `id`, the function
|
|
87
|
-
* state
|
|
88
|
-
* the state
|
|
89
|
-
*
|
|
90
|
+
* Without an `id`, the function can generate no `play.route` guard that targets the
|
|
91
|
+
* state: the guard compares `event.to` with `#<id>`. An absent `id` therefore makes
|
|
92
|
+
* the state unreachable through the routing, and nothing says so. This error shows
|
|
93
|
+
* the fault of the configuration at the moment of the machine definition, and the
|
|
94
|
+
* function skips no state in silence.
|
|
90
95
|
*
|
|
91
96
|
* **Error code:** `PLAY_XSTATE_MISSING_STATE_ID`
|
|
92
97
|
*
|
|
93
98
|
* @example
|
|
94
99
|
* ```typescript
|
|
95
|
-
* // Bad — meta.route without id:
|
|
100
|
+
* // Bad — a meta.route field without an id field:
|
|
96
101
|
* states: {
|
|
97
102
|
* profile: {
|
|
98
103
|
* meta: { route: "/profile/:username" },
|
|
99
|
-
* // ←
|
|
104
|
+
* // ← the id: "profile" field is absent
|
|
100
105
|
* }
|
|
101
106
|
* }
|
|
102
107
|
*
|
|
@@ -110,9 +115,9 @@ export class MissingQueryContextError extends PlayError {
|
|
|
110
115
|
* ```
|
|
111
116
|
*/
|
|
112
117
|
export class MissingStateIdError extends PlayError {
|
|
113
|
-
/** The state key
|
|
118
|
+
/** The state key, which is the position in the tree of the states, without an explicit `id` field. */
|
|
114
119
|
stateKey;
|
|
115
|
-
/** The route template
|
|
120
|
+
/** The route template of the state, for example `"/profile/:username"`. */
|
|
116
121
|
route;
|
|
117
122
|
constructor(stateKey, route) {
|
|
118
123
|
super("formatPlayRouteTransitions", "PLAY_XSTATE_MISSING_STATE_ID", `State "${stateKey}" declares meta.route "${route}" but has no explicit id. ` +
|
|
@@ -123,8 +128,9 @@ export class MissingStateIdError extends PlayError {
|
|
|
123
128
|
}
|
|
124
129
|
}
|
|
125
130
|
/**
|
|
126
|
-
*
|
|
127
|
-
* valid XState machine object
|
|
131
|
+
* The `PlayerActor` constructor throws this error when the `machine` argument is not
|
|
132
|
+
* a valid XState machine object, which means that it is null, undefined, or not an
|
|
133
|
+
* object.
|
|
128
134
|
*
|
|
129
135
|
* **Error code:** `PLAY_XSTATE_INVALID_MACHINE`
|
|
130
136
|
*/
|
|
@@ -135,13 +141,13 @@ export class InvalidMachineError extends PlayError {
|
|
|
135
141
|
}
|
|
136
142
|
}
|
|
137
143
|
/**
|
|
138
|
-
*
|
|
139
|
-
* string
|
|
144
|
+
* `normalizeRoute()` throws this error when the `meta.route` value of a state is not
|
|
145
|
+
* a string and not an object with a `path` property.
|
|
140
146
|
*
|
|
141
147
|
* **Error code:** `PLAY_XSTATE_INVALID_ROUTE_METADATA`
|
|
142
148
|
*/
|
|
143
149
|
export class InvalidRouteMetadataError extends PlayError {
|
|
144
|
-
/** The
|
|
150
|
+
/** The invalid route value, as a string, for the debug work. */
|
|
145
151
|
detail;
|
|
146
152
|
constructor(route, source = "deriveRoute") {
|
|
147
153
|
const detail = JSON.stringify(route);
|
|
@@ -151,13 +157,13 @@ export class InvalidRouteMetadataError extends PlayError {
|
|
|
151
157
|
}
|
|
152
158
|
}
|
|
153
159
|
/**
|
|
154
|
-
*
|
|
155
|
-
* guards
|
|
160
|
+
* `composeGuards()` and `composeGuardsOr()` throw this error for an empty array of
|
|
161
|
+
* guards. A composition of zero guards has no meaning.
|
|
156
162
|
*
|
|
157
163
|
* **Error code:** `PLAY_XSTATE_EMPTY_GUARD_ARRAY`
|
|
158
164
|
*/
|
|
159
165
|
export class EmptyGuardArrayError extends PlayError {
|
|
160
|
-
/** The combinator
|
|
166
|
+
/** The combinator of the call with the empty array: `"and"` or `"or"`. */
|
|
161
167
|
combinator;
|
|
162
168
|
constructor(combinator) {
|
|
163
169
|
super(combinator === "and" ? "composeGuards" : "composeGuardsOr", "PLAY_XSTATE_EMPTY_GUARD_ARRAY", `${combinator === "and" ? "composeGuards" : "composeGuardsOr"} requires at least one guard`);
|
|
@@ -166,58 +172,16 @@ export class EmptyGuardArrayError extends PlayError {
|
|
|
166
172
|
}
|
|
167
173
|
}
|
|
168
174
|
/**
|
|
169
|
-
*
|
|
175
|
+
* `PlayerActor.send()` throws this error when the event argument is not a plain
|
|
176
|
+
* object.
|
|
170
177
|
*
|
|
171
|
-
*
|
|
172
|
-
*
|
|
173
|
-
*
|
|
174
|
-
* (since 6.0.0-alpha.20), and function-form route resolvers. Resolution fails
|
|
175
|
-
* when the name was never declared or when the composed guard is called
|
|
176
|
-
* without transition arguments.
|
|
178
|
+
* A `PlayEvent` needs the shape `{ type: string, ...fields }`. A `null` value, an
|
|
179
|
+
* `undefined` value, a string, and every other value that is not an object are an
|
|
180
|
+
* error of the programmer.
|
|
177
181
|
*
|
|
178
|
-
*
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
/** The guard name that could not be resolved. */
|
|
182
|
-
guardName;
|
|
183
|
-
constructor(guardName, origin) {
|
|
184
|
-
super(origin, "PLAY_XSTATE_UNRESOLVABLE_GUARD_NAME", `Guard "${guardName}" is not a function. Either the name was never declared ` +
|
|
185
|
-
`in setup({ guards }) or the composed guard was called without ` +
|
|
186
|
-
`transition arguments.`);
|
|
187
|
-
this.name = "UnresolvableGuardNameError";
|
|
188
|
-
this.guardName = guardName;
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
/**
|
|
192
|
-
* Thrown when a composed guard evaluates an entry that is neither a predicate
|
|
193
|
-
* function nor a guard name — typically `null`/`undefined` from a typo'd
|
|
194
|
-
* import or an optional lookup.
|
|
195
|
-
*
|
|
196
|
-
* XState v5 failed loudly when evaluating such entries; silently treating them
|
|
197
|
-
* as never-passing would turn `negateGuard(undefined)` into an always-allow.
|
|
198
|
-
* Composition stays lazy (no throw at compose time); evaluation throws.
|
|
199
|
-
*
|
|
200
|
-
* **Error code:** `PLAY_XSTATE_INVALID_GUARD_ENTRY`
|
|
201
|
-
*/
|
|
202
|
-
export class InvalidGuardEntryError extends PlayError {
|
|
203
|
-
/** `typeof` of the invalid entry (e.g. `"undefined"`, `"object"` for null). */
|
|
204
|
-
entryType;
|
|
205
|
-
constructor(entryType, origin) {
|
|
206
|
-
super(origin, "PLAY_XSTATE_INVALID_GUARD_ENTRY", `Guard entry of type "${entryType}" is neither a predicate function nor a ` +
|
|
207
|
-
`guard name. Check for typo'd imports or optional lookups that resolved ` +
|
|
208
|
-
`to null/undefined.`);
|
|
209
|
-
this.name = "InvalidGuardEntryError";
|
|
210
|
-
this.entryType = entryType;
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
/**
|
|
214
|
-
* Thrown by `PlayerActor.send()` when the event argument is not a plain object.
|
|
215
|
-
*
|
|
216
|
-
* `PlayEvent` requires `{ type: string, ...fields }`. Passing `null`, `undefined`,
|
|
217
|
-
* a string, or any other non-object value is a programmer error.
|
|
218
|
-
*
|
|
219
|
-
* The offending value is attached as the `detail` readonly class field for debugging.
|
|
220
|
-
* TypeScript consumers can access `err.detail` directly without any unsafe cast.
|
|
182
|
+
* The error holds the value in question in its readonly class field `detail`, for
|
|
183
|
+
* the debug work. A TypeScript consumer reads `err.detail` directly, with no unsafe
|
|
184
|
+
* cast.
|
|
221
185
|
*
|
|
222
186
|
* **Error code:** `PLAY_XSTATE_INVALID_EVENT`
|
|
223
187
|
*
|
|
@@ -229,14 +193,14 @@ export class InvalidGuardEntryError extends PlayError {
|
|
|
229
193
|
* actor.send(null as any);
|
|
230
194
|
* } catch (err) {
|
|
231
195
|
* if (err instanceof InvalidEventError) {
|
|
232
|
-
* // err.detail
|
|
196
|
+
* // err.detail has the type `unknown`, and it needs no cast
|
|
233
197
|
* console.error("Invalid event passed to actor.send():", err.detail);
|
|
234
198
|
* }
|
|
235
199
|
* }
|
|
236
200
|
* ```
|
|
237
201
|
*/
|
|
238
202
|
export class InvalidEventError extends PlayError {
|
|
239
|
-
/** The
|
|
203
|
+
/** The value in question, from the `send()` call. */
|
|
240
204
|
detail;
|
|
241
205
|
constructor(detail) {
|
|
242
206
|
super("PlayerActor", "PLAY_XSTATE_INVALID_EVENT", "PlayerActor.send() received a non-object event.");
|
|
@@ -244,4 +208,40 @@ export class InvalidEventError extends PlayError {
|
|
|
244
208
|
this.detail = detail;
|
|
245
209
|
}
|
|
246
210
|
}
|
|
211
|
+
/**
|
|
212
|
+
* The actor gives this error to `PlayerOptions.onError` when it failed with a value
|
|
213
|
+
* that is not an `Error`, for example after a machine action ran
|
|
214
|
+
* `throw { code: 42 }`.
|
|
215
|
+
*
|
|
216
|
+
* An actor error that *is* an `Error` reaches `onError` without a change, and it
|
|
217
|
+
* keeps the identity of the machine. This case alone builds a new error. The new
|
|
218
|
+
* error therefore carries a code that your code can match, and not a
|
|
219
|
+
* `String(value)` message such as `"[object Object]"`. The `cause` field holds the
|
|
220
|
+
* value from the throw.
|
|
221
|
+
*
|
|
222
|
+
* **Error code:** `PLAY_XSTATE_NON_ERROR_THROWN`
|
|
223
|
+
*
|
|
224
|
+
* @example
|
|
225
|
+
* ```typescript
|
|
226
|
+
* import { ActorThrewNonErrorError } from "@xmachines/play-xstate/errors";
|
|
227
|
+
*
|
|
228
|
+
* definePlayer({
|
|
229
|
+
* machine,
|
|
230
|
+
* options: {
|
|
231
|
+
* onError: (actor, err) => {
|
|
232
|
+
* if (err instanceof ActorThrewNonErrorError) {
|
|
233
|
+
* // err.cause is the value that the machine threw
|
|
234
|
+
* console.error("Machine threw a non-Error:", err.cause);
|
|
235
|
+
* }
|
|
236
|
+
* },
|
|
237
|
+
* },
|
|
238
|
+
* });
|
|
239
|
+
* ```
|
|
240
|
+
*/
|
|
241
|
+
export class ActorThrewNonErrorError extends PlayError {
|
|
242
|
+
constructor(value) {
|
|
243
|
+
super("PlayerActor", "PLAY_XSTATE_NON_ERROR_THROWN", `PlayerActor failed with a non-Error value: ${safeString(value)}.`, { cause: value });
|
|
244
|
+
this.name = "ActorThrewNonErrorError";
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
247
|
//# sourceMappingURL=errors.js.map
|
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
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
|