@xmachines/play-xstate 2.0.0 → 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 +66 -65
- package/dist/define-player.d.ts +16 -16
- package/dist/define-player.js +16 -16
- package/dist/errors.d.ts +57 -50
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +63 -55
- package/dist/errors.js.map +1 -1
- package/dist/guards/compose.d.ts +53 -50
- package/dist/guards/compose.d.ts.map +1 -1
- package/dist/guards/compose.js +67 -63
- package/dist/guards/compose.js.map +1 -1
- package/dist/guards/helpers.d.ts +22 -22
- package/dist/guards/helpers.js +23 -23
- package/dist/guards/index.d.ts +9 -9
- package/dist/guards/index.js +9 -9
- package/dist/guards/types.d.ts +9 -8
- package/dist/guards/types.d.ts.map +1 -1
- package/dist/index.d.ts +6 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -7
- package/dist/index.js.map +1 -1
- package/dist/player-actor.d.ts +162 -146
- package/dist/player-actor.d.ts.map +1 -1
- package/dist/player-actor.js +269 -241
- package/dist/player-actor.js.map +1 -1
- package/dist/routing/build-url.d.ts +19 -16
- package/dist/routing/build-url.d.ts.map +1 -1
- package/dist/routing/build-url.js +62 -59
- package/dist/routing/build-url.js.map +1 -1
- package/dist/routing/derive-current-route.d.ts +42 -36
- package/dist/routing/derive-current-route.d.ts.map +1 -1
- package/dist/routing/derive-current-route.js +57 -49
- package/dist/routing/derive-current-route.js.map +1 -1
- package/dist/routing/derive-initial-route.d.ts +23 -20
- package/dist/routing/derive-initial-route.d.ts.map +1 -1
- package/dist/routing/derive-initial-route.js +27 -24
- 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 -28
- package/dist/routing/format-play-route-transitions.d.ts.map +1 -1
- package/dist/routing/format-play-route-transitions.js +32 -28
- package/dist/routing/format-play-route-transitions.js.map +1 -1
- package/dist/routing/index.d.ts +3 -3
- package/dist/routing/index.js +3 -3
- package/dist/routing/types.d.ts +12 -11
- package/dist/routing/types.d.ts.map +1 -1
- package/dist/types.d.ts +64 -60
- package/dist/types.d.ts.map +1 -1
- package/dist/view/derive-current-view.d.ts +42 -40
- package/dist/view/derive-current-view.d.ts.map +1 -1
- package/dist/view/derive-current-view.js +51 -47
- package/dist/view/derive-current-view.js.map +1 -1
- package/package.json +7 -6
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"derive-current-route.js","sourceRoot":"","sources":["../../src/routing/derive-current-route.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAG/C
|
|
1
|
+
{"version":3,"file":"derive-current-route.js","sourceRoot":"","sources":["../../src/routing/derive-current-route.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,29 +1,32 @@
|
|
|
1
1
|
import { type AnyStateMachine } from "xstate";
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
3
|
+
* Derives the initial route of the machine directly from the machine definition.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
* snapshot
|
|
7
|
-
* states
|
|
8
|
-
*
|
|
5
|
+
* The function uses the pure `initialTransition` helper of XState to compute the
|
|
6
|
+
* initial snapshot of the machine. That helper resolves the complete chain of the
|
|
7
|
+
* initial states, which includes each nested compound state, and also the real
|
|
8
|
+
* initial context for the given `input`. It makes no actor, and it runs no entry
|
|
9
|
+
* action.
|
|
9
10
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* against
|
|
13
|
-
* `context.params`.
|
|
11
|
+
* The resolution of the route follows the same rules as {@link deriveCurrentRoute}
|
|
12
|
+
* for a live snapshot: the deepest state with a route wins, a relative `meta.route`
|
|
13
|
+
* segment resolves against the ancestors with a route, and each `:param` placeholder
|
|
14
|
+
* receives a value of the initial `context.params`.
|
|
14
15
|
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
16
|
+
* A router bridge compares the result with the browser URL. It therefore separates a
|
|
17
|
+
* deep link (a URL that is not the initial one → the router wins) from a restore
|
|
18
|
+
* (the initial URL, and the actor at a different route from the restore → the actor
|
|
19
|
+
* wins). The derivation reads no snapshot of a restore. Therefore it always gives
|
|
20
|
+
* the **default** initial route of the machine.
|
|
19
21
|
*
|
|
20
|
-
* @param machine - XState v5 state machine
|
|
21
|
-
* @param input -
|
|
22
|
-
* `createActor(machine, { input })
|
|
23
|
-
* @returns
|
|
24
|
-
* `meta.route
|
|
25
|
-
*
|
|
26
|
-
*
|
|
22
|
+
* @param machine - The definition of the XState v5 state machine.
|
|
23
|
+
* @param input - The input of the actor. The function gives it to the context
|
|
24
|
+
* factory of the machine, exactly like `createActor(machine, { input })`.
|
|
25
|
+
* @returns The resolved initial URL string, or `null`. The function returns `null`
|
|
26
|
+
* in three cases: the initial state has no `meta.route` field; the initial context
|
|
27
|
+
* does not hold a necessary `:param`; or the context logic or the initial-transition
|
|
28
|
+
* logic of the machine throws for the given input. The last case matches the
|
|
29
|
+
* error-status snapshot of `createActor`, which also has no route to derive.
|
|
27
30
|
*
|
|
28
31
|
* @example
|
|
29
32
|
* ```typescript
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"derive-initial-route.d.ts","sourceRoot":"","sources":["../../src/routing/derive-initial-route.ts"],"names":[],"mappings":"AAAA,OAAO,EAA8C,KAAK,eAAe,EAAE,MAAM,QAAQ,CAAC;AAI1F
|
|
1
|
+
{"version":3,"file":"derive-initial-route.d.ts","sourceRoot":"","sources":["../../src/routing/derive-initial-route.ts"],"names":[],"mappings":"AAAA,OAAO,EAA8C,KAAK,eAAe,EAAE,MAAM,QAAQ,CAAC;AAI1F;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,eAAO,MAAM,kBAAkB,GAAI,SAAS,eAAe,EAAE,QAAQ,OAAO,KAAG,MAAM,GAAG,IAavF,CAAC"}
|
|
@@ -1,30 +1,33 @@
|
|
|
1
1
|
import { initialTransition } from "xstate";
|
|
2
2
|
import { deriveCurrentRoute } from "./derive-current-route.js";
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
4
|
+
* Derives the initial route of the machine directly from the machine definition.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
* snapshot
|
|
8
|
-
* states
|
|
9
|
-
*
|
|
6
|
+
* The function uses the pure `initialTransition` helper of XState to compute the
|
|
7
|
+
* initial snapshot of the machine. That helper resolves the complete chain of the
|
|
8
|
+
* initial states, which includes each nested compound state, and also the real
|
|
9
|
+
* initial context for the given `input`. It makes no actor, and it runs no entry
|
|
10
|
+
* action.
|
|
10
11
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* against
|
|
14
|
-
* `context.params`.
|
|
12
|
+
* The resolution of the route follows the same rules as {@link deriveCurrentRoute}
|
|
13
|
+
* for a live snapshot: the deepest state with a route wins, a relative `meta.route`
|
|
14
|
+
* segment resolves against the ancestors with a route, and each `:param` placeholder
|
|
15
|
+
* receives a value of the initial `context.params`.
|
|
15
16
|
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
17
|
+
* A router bridge compares the result with the browser URL. It therefore separates a
|
|
18
|
+
* deep link (a URL that is not the initial one → the router wins) from a restore
|
|
19
|
+
* (the initial URL, and the actor at a different route from the restore → the actor
|
|
20
|
+
* wins). The derivation reads no snapshot of a restore. Therefore it always gives
|
|
21
|
+
* the **default** initial route of the machine.
|
|
20
22
|
*
|
|
21
|
-
* @param machine - XState v5 state machine
|
|
22
|
-
* @param input -
|
|
23
|
-
* `createActor(machine, { input })
|
|
24
|
-
* @returns
|
|
25
|
-
* `meta.route
|
|
26
|
-
*
|
|
27
|
-
*
|
|
23
|
+
* @param machine - The definition of the XState v5 state machine.
|
|
24
|
+
* @param input - The input of the actor. The function gives it to the context
|
|
25
|
+
* factory of the machine, exactly like `createActor(machine, { input })`.
|
|
26
|
+
* @returns The resolved initial URL string, or `null`. The function returns `null`
|
|
27
|
+
* in three cases: the initial state has no `meta.route` field; the initial context
|
|
28
|
+
* does not hold a necessary `:param`; or the context logic or the initial-transition
|
|
29
|
+
* logic of the machine throws for the given input. The last case matches the
|
|
30
|
+
* error-status snapshot of `createActor`, which also has no route to derive.
|
|
28
31
|
*
|
|
29
32
|
* @example
|
|
30
33
|
* ```typescript
|
|
@@ -43,10 +46,10 @@ export const deriveInitialRoute = (machine, input) => {
|
|
|
43
46
|
[initialSnapshot] = initialTransition(machine, input);
|
|
44
47
|
}
|
|
45
48
|
catch {
|
|
46
|
-
//
|
|
47
|
-
// factory
|
|
48
|
-
// the
|
|
49
|
-
// has no route metadata
|
|
49
|
+
// The context factory or the initial-transition logic threw for this input, for
|
|
50
|
+
// example a factory that reads a necessary `input` field and receives none. This is
|
|
51
|
+
// the equivalent of the error-status snapshot of createActor in the pure helper, and
|
|
52
|
+
// that snapshot also has no route metadata. Report "no initial route to derive".
|
|
50
53
|
return null;
|
|
51
54
|
}
|
|
52
55
|
return deriveCurrentRoute(initialSnapshot);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"derive-initial-route.js","sourceRoot":"","sources":["../../src/routing/derive-initial-route.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAiD,MAAM,QAAQ,CAAC;AAE1F,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAE/D
|
|
1
|
+
{"version":3,"file":"derive-initial-route.js","sourceRoot":"","sources":["../../src/routing/derive-initial-route.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAiD,MAAM,QAAQ,CAAC;AAE1F,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAE/D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,OAAwB,EAAE,KAAe,EAAiB,EAAE;IAC9F,IAAI,eAAmC,CAAC;IACxC,IAAI,CAAC;QACJ,CAAC,eAAe,CAAC,GAAG,iBAAiB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IACvD,CAAC;IAAC,MAAM,CAAC;QACR,gFAAgF;QAChF,oFAAoF;QACpF,qFAAqF;QACrF,iFAAiF;QACjF,OAAO,IAAI,CAAC;IACb,CAAC;IAED,OAAO,kBAAkB,CAAC,eAAe,CAAC,CAAC;AAC5C,CAAC,CAAC"}
|
|
@@ -1,21 +1,22 @@
|
|
|
1
1
|
import type { RouteMetadata } from "./types.js";
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
3
|
+
* Derives the route from the metadata of an XState state
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* (`{ path: "/about" }`).
|
|
8
|
-
*
|
|
5
|
+
* The function reads the URL template of the route from the `meta.route` field in
|
|
6
|
+
* the metadata of the active state. It supports a string route (`"/about"`) and also
|
|
7
|
+
* an object route with a path property (`{ path: "/about" }`). It returns null for a
|
|
8
|
+
* state without route metadata, because not every state needs a route.
|
|
9
9
|
*
|
|
10
|
-
* **Architectural
|
|
11
|
-
* routing information from state machine
|
|
12
|
-
*
|
|
10
|
+
* **Architectural context:** the function implements **Actor Authority (INV-01)**,
|
|
11
|
+
* because it reads the routing information from the state machine definition, and
|
|
12
|
+
* not from an external configuration. The current state of the Actor decides the
|
|
13
|
+
* route, and no decision of the infrastructure decides it.
|
|
13
14
|
*
|
|
14
|
-
* @param stateMeta -
|
|
15
|
-
* @returns
|
|
15
|
+
* @param stateMeta - The state metadata from snapshot.getMeta()
|
|
16
|
+
* @returns The template of the route path, which can hold a :param, or null when the function finds no route
|
|
16
17
|
*
|
|
17
18
|
* @example
|
|
18
|
-
*
|
|
19
|
+
* The basic read of a route
|
|
19
20
|
* ```typescript
|
|
20
21
|
* import { deriveRoute } from "@xmachines/play-xstate";
|
|
21
22
|
* import { setup } from "xstate";
|
|
@@ -38,7 +39,7 @@ import type { RouteMetadata } from "./types.js";
|
|
|
38
39
|
* ```
|
|
39
40
|
*
|
|
40
41
|
* @example
|
|
41
|
-
*
|
|
42
|
+
* A route with a parameter
|
|
42
43
|
* ```typescript
|
|
43
44
|
* const machine = setup({}).createMachine({
|
|
44
45
|
* states: {
|
|
@@ -52,11 +53,11 @@ import type { RouteMetadata } from "./types.js";
|
|
|
52
53
|
* });
|
|
53
54
|
*
|
|
54
55
|
* const route = deriveRoute(snapshot.getMeta());
|
|
55
|
-
* console.log(route); // "/profile/:userId"
|
|
56
|
+
* console.log(route); // "/profile/:userId" — the template, before the substitution
|
|
56
57
|
* ```
|
|
57
58
|
*
|
|
58
59
|
* @example
|
|
59
|
-
*
|
|
60
|
+
* The object form of a route
|
|
60
61
|
* ```typescript
|
|
61
62
|
* const machine = setup({}).createMachine({
|
|
62
63
|
* states: {
|
|
@@ -74,41 +75,41 @@ import type { RouteMetadata } from "./types.js";
|
|
|
74
75
|
* ```
|
|
75
76
|
*
|
|
76
77
|
* @see [Play RFC](../../../docs/rfc/play.md)
|
|
77
|
-
* @see {@link buildRouteUrl} for
|
|
78
|
-
* @see {@link isAbsoluteRoute} for
|
|
78
|
+
* @see {@link buildRouteUrl} for the construction of a URL, with the substitution of each parameter
|
|
79
|
+
* @see {@link isAbsoluteRoute} for the test of an absolute path
|
|
79
80
|
*
|
|
80
81
|
* @remarks
|
|
81
|
-
* This function
|
|
82
|
-
*
|
|
83
|
-
* function
|
|
82
|
+
* This function reads the route definition from `meta.route`. A state with a
|
|
83
|
+
* `route: {}` config has a route. {@link buildRouteUrl} substitutes each parameter,
|
|
84
|
+
* and this function does not: deriveRoute returns a template.
|
|
84
85
|
*
|
|
85
|
-
* **
|
|
86
|
-
*
|
|
87
|
-
*
|
|
86
|
+
* **A state without a route:** a state without a `meta.route` field gives `null`.
|
|
87
|
+
* This is deliberate, because not every state needs a route. An intermediate loading
|
|
88
|
+
* state and a substate, for example, often have no URL of their own.
|
|
88
89
|
*/
|
|
89
90
|
export declare const deriveRoute: (stateMeta: Record<string, unknown>) => string | null;
|
|
90
91
|
/**
|
|
91
|
-
*
|
|
92
|
+
* Normalizes the route metadata into a string path
|
|
92
93
|
*
|
|
93
|
-
*
|
|
94
|
-
*
|
|
94
|
+
* The function handles the string form and the object form of a route definition.
|
|
95
|
+
* The output is therefore always a string, for the construction of the URL.
|
|
95
96
|
*
|
|
96
|
-
* @param route -
|
|
97
|
-
* @param source - `PlayError.scope` to report
|
|
98
|
-
*
|
|
99
|
-
* @returns
|
|
100
|
-
* @throws {InvalidRouteMetadataError}
|
|
97
|
+
* @param route - The route metadata: a string, or an object with a path property
|
|
98
|
+
* @param source - The `PlayError.scope` value to report for invalid metadata. The
|
|
99
|
+
* default is `"deriveRoute"`
|
|
100
|
+
* @returns The normalized string of the route path
|
|
101
|
+
* @throws {InvalidRouteMetadataError} When the form of the route is invalid
|
|
101
102
|
*/
|
|
102
103
|
export declare const normalizeRoute: (route: RouteMetadata, source?: string) => string;
|
|
103
104
|
/**
|
|
104
|
-
*
|
|
105
|
+
* Tells you if the route path is absolute
|
|
105
106
|
*
|
|
106
|
-
*
|
|
107
|
-
*
|
|
108
|
-
*
|
|
107
|
+
* The function decides if a route path is absolute, which means that it starts with
|
|
108
|
+
* `/`, or relative. An absolute path inherits nothing from a parent route. A
|
|
109
|
+
* relative path joins a parent path, for a nested routing.
|
|
109
110
|
*
|
|
110
|
-
* @param path -
|
|
111
|
-
* @returns true
|
|
111
|
+
* @param path - The route path to test
|
|
112
|
+
* @returns true when the path starts with '/'. In every other case, false
|
|
112
113
|
*
|
|
113
114
|
* @example
|
|
114
115
|
* ```typescript
|
|
@@ -119,7 +120,7 @@ export declare const normalizeRoute: (route: RouteMetadata, source?: string) =>
|
|
|
119
120
|
* console.log(isAbsoluteRoute("./about")); // false
|
|
120
121
|
* ```
|
|
121
122
|
*
|
|
122
|
-
* @see {@link deriveRoute} for route
|
|
123
|
+
* @see {@link deriveRoute} for the read of a route
|
|
123
124
|
*/
|
|
124
125
|
export declare const isAbsoluteRoute: (path: string) => boolean;
|
|
125
126
|
//# sourceMappingURL=derive-route.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"derive-route.d.ts","sourceRoot":"","sources":["../../src/routing/derive-route.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAe,MAAM,YAAY,CAAC;AAG7D
|
|
1
|
+
{"version":3,"file":"derive-route.d.ts","sourceRoot":"","sources":["../../src/routing/derive-route.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAe,MAAM,YAAY,CAAC;AAG7D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuFG;AACH,eAAO,MAAM,WAAW,GAAI,WAAW,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAG,MAAM,GAAG,IAuBzE,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,cAAc,GAAI,OAAO,aAAa,EAAE,eAAsB,KAAG,MAW7E,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,eAAe,GAAI,MAAM,MAAM,KAAG,OAE9C,CAAC"}
|
|
@@ -1,21 +1,22 @@
|
|
|
1
1
|
import { InvalidRouteMetadataError } from "../errors.js";
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
3
|
+
* Derives the route from the metadata of an XState state
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* (`{ path: "/about" }`).
|
|
8
|
-
*
|
|
5
|
+
* The function reads the URL template of the route from the `meta.route` field in
|
|
6
|
+
* the metadata of the active state. It supports a string route (`"/about"`) and also
|
|
7
|
+
* an object route with a path property (`{ path: "/about" }`). It returns null for a
|
|
8
|
+
* state without route metadata, because not every state needs a route.
|
|
9
9
|
*
|
|
10
|
-
* **Architectural
|
|
11
|
-
* routing information from state machine
|
|
12
|
-
*
|
|
10
|
+
* **Architectural context:** the function implements **Actor Authority (INV-01)**,
|
|
11
|
+
* because it reads the routing information from the state machine definition, and
|
|
12
|
+
* not from an external configuration. The current state of the Actor decides the
|
|
13
|
+
* route, and no decision of the infrastructure decides it.
|
|
13
14
|
*
|
|
14
|
-
* @param stateMeta -
|
|
15
|
-
* @returns
|
|
15
|
+
* @param stateMeta - The state metadata from snapshot.getMeta()
|
|
16
|
+
* @returns The template of the route path, which can hold a :param, or null when the function finds no route
|
|
16
17
|
*
|
|
17
18
|
* @example
|
|
18
|
-
*
|
|
19
|
+
* The basic read of a route
|
|
19
20
|
* ```typescript
|
|
20
21
|
* import { deriveRoute } from "@xmachines/play-xstate";
|
|
21
22
|
* import { setup } from "xstate";
|
|
@@ -38,7 +39,7 @@ import { InvalidRouteMetadataError } from "../errors.js";
|
|
|
38
39
|
* ```
|
|
39
40
|
*
|
|
40
41
|
* @example
|
|
41
|
-
*
|
|
42
|
+
* A route with a parameter
|
|
42
43
|
* ```typescript
|
|
43
44
|
* const machine = setup({}).createMachine({
|
|
44
45
|
* states: {
|
|
@@ -52,11 +53,11 @@ import { InvalidRouteMetadataError } from "../errors.js";
|
|
|
52
53
|
* });
|
|
53
54
|
*
|
|
54
55
|
* const route = deriveRoute(snapshot.getMeta());
|
|
55
|
-
* console.log(route); // "/profile/:userId"
|
|
56
|
+
* console.log(route); // "/profile/:userId" — the template, before the substitution
|
|
56
57
|
* ```
|
|
57
58
|
*
|
|
58
59
|
* @example
|
|
59
|
-
*
|
|
60
|
+
* The object form of a route
|
|
60
61
|
* ```typescript
|
|
61
62
|
* const machine = setup({}).createMachine({
|
|
62
63
|
* states: {
|
|
@@ -74,23 +75,25 @@ import { InvalidRouteMetadataError } from "../errors.js";
|
|
|
74
75
|
* ```
|
|
75
76
|
*
|
|
76
77
|
* @see [Play RFC](../../../docs/rfc/play.md)
|
|
77
|
-
* @see {@link buildRouteUrl} for
|
|
78
|
-
* @see {@link isAbsoluteRoute} for
|
|
78
|
+
* @see {@link buildRouteUrl} for the construction of a URL, with the substitution of each parameter
|
|
79
|
+
* @see {@link isAbsoluteRoute} for the test of an absolute path
|
|
79
80
|
*
|
|
80
81
|
* @remarks
|
|
81
|
-
* This function
|
|
82
|
-
*
|
|
83
|
-
* function
|
|
82
|
+
* This function reads the route definition from `meta.route`. A state with a
|
|
83
|
+
* `route: {}` config has a route. {@link buildRouteUrl} substitutes each parameter,
|
|
84
|
+
* and this function does not: deriveRoute returns a template.
|
|
84
85
|
*
|
|
85
|
-
* **
|
|
86
|
-
*
|
|
87
|
-
*
|
|
86
|
+
* **A state without a route:** a state without a `meta.route` field gives `null`.
|
|
87
|
+
* This is deliberate, because not every state needs a route. An intermediate loading
|
|
88
|
+
* state and a substate, for example, often have no URL of their own.
|
|
88
89
|
*/
|
|
89
90
|
export const deriveRoute = (stateMeta) => {
|
|
90
|
-
// snapshot.getMeta()
|
|
91
|
-
//
|
|
92
|
-
//
|
|
93
|
-
//
|
|
91
|
+
// snapshot.getMeta() puts the keys of the ancestors first. Fold each entry with a
|
|
92
|
+
// route from the top to the bottom. The meta.route of the deepest active state
|
|
93
|
+
// therefore wins over the route of an ancestor, and a RELATIVE route resolves
|
|
94
|
+
// against its nearest ancestors with a route. The tree resolution of play-router
|
|
95
|
+
// does the same: the fullPath of a child is the fullPath of its parent, then "/",
|
|
96
|
+
// then its own path.
|
|
94
97
|
let resolved = null;
|
|
95
98
|
for (const meta of Object.values(stateMeta)) {
|
|
96
99
|
if (typeof meta !== "object" || meta === null)
|
|
@@ -111,36 +114,36 @@ export const deriveRoute = (stateMeta) => {
|
|
|
111
114
|
return resolved;
|
|
112
115
|
};
|
|
113
116
|
/**
|
|
114
|
-
*
|
|
117
|
+
* Normalizes the route metadata into a string path
|
|
115
118
|
*
|
|
116
|
-
*
|
|
117
|
-
*
|
|
119
|
+
* The function handles the string form and the object form of a route definition.
|
|
120
|
+
* The output is therefore always a string, for the construction of the URL.
|
|
118
121
|
*
|
|
119
|
-
* @param route -
|
|
120
|
-
* @param source - `PlayError.scope` to report
|
|
121
|
-
*
|
|
122
|
-
* @returns
|
|
123
|
-
* @throws {InvalidRouteMetadataError}
|
|
122
|
+
* @param route - The route metadata: a string, or an object with a path property
|
|
123
|
+
* @param source - The `PlayError.scope` value to report for invalid metadata. The
|
|
124
|
+
* default is `"deriveRoute"`
|
|
125
|
+
* @returns The normalized string of the route path
|
|
126
|
+
* @throws {InvalidRouteMetadataError} When the form of the route is invalid
|
|
124
127
|
*/
|
|
125
128
|
export const normalizeRoute = (route, source = "deriveRoute") => {
|
|
126
129
|
if (typeof route === "string") {
|
|
127
130
|
return route;
|
|
128
131
|
}
|
|
129
|
-
//
|
|
132
|
+
// A route object, with a path property
|
|
130
133
|
if (route && typeof route === "object" && "path" in route) {
|
|
131
134
|
return route.path;
|
|
132
135
|
}
|
|
133
136
|
throw new InvalidRouteMetadataError(route, source);
|
|
134
137
|
};
|
|
135
138
|
/**
|
|
136
|
-
*
|
|
139
|
+
* Tells you if the route path is absolute
|
|
137
140
|
*
|
|
138
|
-
*
|
|
139
|
-
*
|
|
140
|
-
*
|
|
141
|
+
* The function decides if a route path is absolute, which means that it starts with
|
|
142
|
+
* `/`, or relative. An absolute path inherits nothing from a parent route. A
|
|
143
|
+
* relative path joins a parent path, for a nested routing.
|
|
141
144
|
*
|
|
142
|
-
* @param path -
|
|
143
|
-
* @returns true
|
|
145
|
+
* @param path - The route path to test
|
|
146
|
+
* @returns true when the path starts with '/'. In every other case, false
|
|
144
147
|
*
|
|
145
148
|
* @example
|
|
146
149
|
* ```typescript
|
|
@@ -151,7 +154,7 @@ export const normalizeRoute = (route, source = "deriveRoute") => {
|
|
|
151
154
|
* console.log(isAbsoluteRoute("./about")); // false
|
|
152
155
|
* ```
|
|
153
156
|
*
|
|
154
|
-
* @see {@link deriveRoute} for route
|
|
157
|
+
* @see {@link deriveRoute} for the read of a route
|
|
155
158
|
*/
|
|
156
159
|
export const isAbsoluteRoute = (path) => {
|
|
157
160
|
return path.startsWith("/");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"derive-route.js","sourceRoot":"","sources":["../../src/routing/derive-route.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAC;AAEzD
|
|
1
|
+
{"version":3,"file":"derive-route.js","sourceRoot":"","sources":["../../src/routing/derive-route.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAC;AAEzD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuFG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,SAAkC,EAAiB,EAAE;IAChF,kFAAkF;IAClF,+EAA+E;IAC/E,8EAA8E;IAC9E,iFAAiF;IACjF,kFAAkF;IAClF,qBAAqB;IACrB,IAAI,QAAQ,GAAkB,IAAI,CAAC;IACnC,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC;QAC7C,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI;YAAE,SAAS;QACxD,IAAI,CAAC,CAAC,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK;YAAE,SAAS;QAEhD,MAAM,KAAK,GAAG,cAAc,CAAC,IAAI,CAAC,KAAsB,CAAC,CAAC;QAC1D,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,EAAE;YAAE,SAAS;QACxD,IAAI,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC;YAC5B,QAAQ,GAAG,KAAK,CAAC;QAClB,CAAC;aAAM,CAAC;YACP,MAAM,IAAI,GAAW,QAAQ,KAAK,IAAI,IAAI,QAAQ,KAAK,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC;YAC3E,QAAQ,GAAG,GAAG,IAAI,IAAI,KAAK,EAAE,CAAC;QAC/B,CAAC;IACF,CAAC;IAED,OAAO,QAAQ,CAAC;AACjB,CAAC,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,KAAoB,EAAE,MAAM,GAAG,aAAa,EAAU,EAAE;IACtF,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC/B,OAAO,KAAK,CAAC;IACd,CAAC;IAED,uCAAuC;IACvC,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,IAAI,KAAK,EAAE,CAAC;QAC3D,OAAQ,KAAqB,CAAC,IAAI,CAAC;IACpC,CAAC;IAED,MAAM,IAAI,yBAAyB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;AACpD,CAAC,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,IAAY,EAAW,EAAE;IACxD,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;AAC7B,CAAC,CAAC"}
|
|
@@ -1,37 +1,40 @@
|
|
|
1
1
|
import type { RouteMetadata } from "./types.js";
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
* `formatPlayRouteTransitions`
|
|
3
|
+
* The minimal structural shape of one XState state node, as
|
|
4
|
+
* `formatPlayRouteTransitions` reads it during its walk over the machine config.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
* state
|
|
8
|
-
*
|
|
6
|
+
* This type holds only the fields that the function reads. Every other field of a
|
|
7
|
+
* state node, such as `on`, `entry`, and `after`, passes through the index
|
|
8
|
+
* signature without a change.
|
|
9
9
|
*/
|
|
10
10
|
export type RouteStateNode = {
|
|
11
|
-
/**
|
|
11
|
+
/**
|
|
12
|
+
* The optional explicit state ID, for example `"home"` or `"settings"`. It is the `#id` target of a `play.route` event.
|
|
13
|
+
*/
|
|
12
14
|
id?: string;
|
|
13
|
-
/**
|
|
15
|
+
/** The state metadata. A `meta.route` field gives the state a route. */
|
|
14
16
|
meta?: {
|
|
15
17
|
/**
|
|
16
|
-
* URL path
|
|
17
|
-
* form (`{ path, title }`)
|
|
18
|
+
* The template of the URL path: the string form, for example
|
|
19
|
+
* `"/profile/:username"`, or the object form (`{ path, title }`). Both match
|
|
20
|
+
* {@link RouteMetadata}.
|
|
18
21
|
*/
|
|
19
22
|
route?: RouteMetadata;
|
|
20
23
|
};
|
|
21
|
-
/**
|
|
24
|
+
/** The nested child states. The function walks them for each further route declaration. */
|
|
22
25
|
states?: Record<string, RouteStateNode>;
|
|
23
26
|
[key: string]: unknown;
|
|
24
27
|
};
|
|
25
28
|
/**
|
|
26
|
-
*
|
|
27
|
-
* `formatPlayRouteTransitions
|
|
29
|
+
* The minimal structural constraint of a machine config that
|
|
30
|
+
* `formatPlayRouteTransitions` accepts.
|
|
28
31
|
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
* parameter
|
|
33
|
-
*
|
|
34
|
-
* `setup().createMachine()
|
|
32
|
+
* The constraint is loose on purpose. The function therefore accepts the bare config
|
|
33
|
+
* object of `createMachine` and also the stricter config of
|
|
34
|
+
* `setup().createMachine`, and the call site needs no type cast. The generic
|
|
35
|
+
* parameter `T extends RouteMachineConfig` of `formatPlayRouteTransitions` keeps the
|
|
36
|
+
* original concrete type through the transform. Therefore
|
|
37
|
+
* `setup().createMachine()` accepts the return value directly.
|
|
35
38
|
*/
|
|
36
39
|
export type RouteMachineConfig = {
|
|
37
40
|
context?: unknown;
|
|
@@ -40,12 +43,14 @@ export type RouteMachineConfig = {
|
|
|
40
43
|
[key: string]: unknown;
|
|
41
44
|
};
|
|
42
45
|
/**
|
|
43
|
-
*
|
|
46
|
+
* Makes the play.route transitions from the declarative route configs
|
|
44
47
|
*
|
|
45
|
-
*
|
|
46
|
-
* transitions that handle `play.route`
|
|
48
|
+
* The function walks the machine states. It looks for each state with a `meta.route`
|
|
49
|
+
* field, and it generates the transitions that handle a `play.route` event: each
|
|
50
|
+
* transition matches event.to against a state ID.
|
|
47
51
|
*
|
|
48
|
-
*
|
|
52
|
+
* The internal formatRouteTransitions function of XState was the model for this
|
|
53
|
+
* function (stateUtils.ts, line 391).
|
|
49
54
|
*
|
|
50
55
|
* @example
|
|
51
56
|
* ```typescript
|
|
@@ -60,13 +65,14 @@ export type RouteMachineConfig = {
|
|
|
60
65
|
* const machine = createMachine(formatPlayRouteTransitions(machineConfig));
|
|
61
66
|
* ```
|
|
62
67
|
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
* -
|
|
66
|
-
* -
|
|
68
|
+
* The function generates the `play.route` handlers at the root level. Those
|
|
69
|
+
* handlers:
|
|
70
|
+
* - match event.to against a state ID, for example event.to === "#home"
|
|
71
|
+
* - target the correct state
|
|
72
|
+
* - assign the params and the query of the event to the context
|
|
67
73
|
*
|
|
68
|
-
* @param machineConfig - XState machine config
|
|
69
|
-
* @returns The same machine config with
|
|
74
|
+
* @param machineConfig - The XState machine config, before `createMachine`. It must extend `RouteMachineConfig`.
|
|
75
|
+
* @returns The same machine config, with the generated `play.route` handlers in it. The original type `T` stays.
|
|
70
76
|
*/
|
|
71
77
|
export declare function formatPlayRouteTransitions<T extends RouteMachineConfig>(machineConfig: T): T;
|
|
72
78
|
//# sourceMappingURL=format-play-route-transitions.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"format-play-route-transitions.d.ts","sourceRoot":"","sources":["../../src/routing/format-play-route-transitions.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAkBhD;;;;;;;GAOG;AACH,MAAM,MAAM,cAAc,GAAG;IAC5B
|
|
1
|
+
{"version":3,"file":"format-play-route-transitions.d.ts","sourceRoot":"","sources":["../../src/routing/format-play-route-transitions.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAkBhD;;;;;;;GAOG;AACH,MAAM,MAAM,cAAc,GAAG;IAC5B;;OAEG;IACH,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,wEAAwE;IACxE,IAAI,CAAC,EAAE;QACN;;;;WAIG;QACH,KAAK,CAAC,EAAE,aAAa,CAAC;KACtB,CAAC;IACF,2FAA2F;IAC3F,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IACxC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACvB,CAAC;AAaF;;;;;;;;;;GAUG;AACH,MAAM,MAAM,kBAAkB,GAAG;IAChC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;IAC7C,EAAE,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;IACzC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACvB,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAgB,0BAA0B,CAAC,CAAC,SAAS,kBAAkB,EAAE,aAAa,EAAE,CAAC,GAAG,CAAC,CAmF5F"}
|