@xmachines/play-xstate 3.0.0 → 5.0.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 +190 -68
- package/dist/capabilities.d.ts +93 -0
- package/dist/capabilities.d.ts.map +1 -0
- package/dist/capabilities.js +4 -0
- package/dist/capabilities.js.map +1 -0
- package/dist/define-player.d.ts +7 -1
- package/dist/define-player.d.ts.map +1 -1
- package/dist/define-player.js +9 -60
- package/dist/define-player.js.map +1 -1
- package/dist/errors.d.ts +64 -23
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +93 -31
- package/dist/errors.js.map +1 -1
- package/dist/index.d.ts +4 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -6
- package/dist/index.js.map +1 -1
- package/dist/player-actor.d.ts +73 -137
- package/dist/player-actor.d.ts.map +1 -1
- package/dist/player-actor.js +108 -254
- package/dist/player-actor.js.map +1 -1
- package/dist/routing/build-url.d.ts +8 -1
- package/dist/routing/build-url.d.ts.map +1 -1
- package/dist/routing/build-url.js +34 -54
- package/dist/routing/build-url.js.map +1 -1
- package/dist/routing/derive-current-route.d.ts +12 -38
- package/dist/routing/derive-current-route.d.ts.map +1 -1
- package/dist/routing/derive-current-route.js +24 -82
- package/dist/routing/derive-current-route.js.map +1 -1
- package/dist/routing/derive-initial-route.d.ts +2 -1
- package/dist/routing/derive-initial-route.d.ts.map +1 -1
- package/dist/routing/derive-initial-route.js +13 -2
- package/dist/routing/derive-initial-route.js.map +1 -1
- package/dist/routing/derive-route.d.ts +81 -2
- package/dist/routing/derive-route.d.ts.map +1 -1
- package/dist/routing/derive-route.js +97 -3
- package/dist/routing/derive-route.js.map +1 -1
- package/dist/routing/format-play-route-transitions.d.ts +8 -2
- package/dist/routing/format-play-route-transitions.d.ts.map +1 -1
- package/dist/routing/format-play-route-transitions.js +175 -43
- package/dist/routing/format-play-route-transitions.js.map +1 -1
- package/dist/routing/index.d.ts +1 -1
- package/dist/routing/index.d.ts.map +1 -1
- package/dist/routing/types.d.ts +9 -5
- package/dist/routing/types.d.ts.map +1 -1
- package/dist/state-meta.d.ts +52 -0
- package/dist/state-meta.d.ts.map +1 -0
- package/dist/state-meta.js +77 -0
- package/dist/state-meta.js.map +1 -0
- package/dist/types.d.ts +20 -5
- package/dist/types.d.ts.map +1 -1
- package/dist/view/derive-current-view.d.ts +7 -6
- package/dist/view/derive-current-view.d.ts.map +1 -1
- package/dist/view/derive-current-view.js +7 -6
- package/dist/view/derive-current-view.js.map +1 -1
- package/dist/with-routing.d.ts +45 -0
- package/dist/with-routing.d.ts.map +1 -0
- package/dist/with-routing.js +140 -0
- package/dist/with-routing.js.map +1 -0
- package/dist/with-view.d.ts +57 -0
- package/dist/with-view.d.ts.map +1 -0
- package/dist/with-view.js +158 -0
- package/dist/with-view.js.map +1 -0
- package/package.json +40 -18
- package/dist/guards/compose.d.ts +0 -158
- package/dist/guards/compose.d.ts.map +0 -1
- package/dist/guards/compose.js +0 -188
- package/dist/guards/compose.js.map +0 -1
- package/dist/guards/helpers.d.ts +0 -62
- package/dist/guards/helpers.d.ts.map +0 -1
- package/dist/guards/helpers.js +0 -85
- package/dist/guards/helpers.js.map +0 -1
- package/dist/guards/index.d.ts +0 -20
- package/dist/guards/index.d.ts.map +0 -1
- package/dist/guards/index.js +0 -18
- package/dist/guards/index.js.map +0 -1
- package/dist/guards/types.d.ts +0 -22
- package/dist/guards/types.d.ts.map +0 -1
- package/dist/guards/types.js +0 -2
- package/dist/guards/types.js.map +0 -1
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { buildPath } from "@xmachines/play-pattern";
|
|
1
2
|
import { isAbsoluteRoute } from "./derive-route.js";
|
|
2
|
-
import { MissingRouteParamError } from "../errors.js";
|
|
3
|
+
import { InvalidRouteParamError, MissingRouteParamError } from "../errors.js";
|
|
3
4
|
/**
|
|
4
5
|
* Builds a complete URL from a route template and the context of the actor.
|
|
5
6
|
*
|
|
@@ -17,12 +18,18 @@ import { MissingRouteParamError } from "../errors.js";
|
|
|
17
18
|
* @param context - The context object of the actor. Each route parameter must be in
|
|
18
19
|
* `context.params`, because the function reads no flat context field. An absent
|
|
19
20
|
* `query` field builds a URL without a query, exactly like `query: {}`.
|
|
21
|
+
* @param options - The caches to read, as {@link ParseOptions}. The default is the cache
|
|
22
|
+
* that `@xmachines/play-pattern` shares with every caller of the process. A parse is
|
|
23
|
+
* deterministic, so this changes how often the parser runs and it changes no answer.
|
|
20
24
|
* @returns The complete URL string.
|
|
21
25
|
*
|
|
22
26
|
* @throws {MissingRouteParamError} When a **necessary** `:param` placeholder has no
|
|
23
27
|
* value in the context. The function omits an optional parameter (`:param?`) in
|
|
24
28
|
* silence when its value is absent. Import the class from
|
|
25
29
|
* `@xmachines/play-xstate/errors`.
|
|
30
|
+
* @throws {InvalidRouteParamError} When a `:param` placeholder carries a dot segment,
|
|
31
|
+
* which a URL resolves away. The template matches the built URL back never, so the
|
|
32
|
+
* actor and the address bar would stay out of step.
|
|
26
33
|
*
|
|
27
34
|
* @example
|
|
28
35
|
* ```typescript
|
|
@@ -33,7 +40,7 @@ import { MissingRouteParamError } from "../errors.js";
|
|
|
33
40
|
* // → "/settings" (the optional param is absent, and there is no query string)
|
|
34
41
|
* ```
|
|
35
42
|
*/
|
|
36
|
-
export const buildRouteUrl = (routeTemplate, context = { query: {} }) => {
|
|
43
|
+
export const buildRouteUrl = (routeTemplate, context = { query: {} }, options) => {
|
|
37
44
|
// A context without a `query` field builds a URL without a query, in the same way
|
|
38
45
|
// as an absent context. The generated play.route transitions assign `query` on
|
|
39
46
|
// every navigation, and the shape of the initial context has no effect on that.
|
|
@@ -43,10 +50,31 @@ export const buildRouteUrl = (routeTemplate, context = { query: {} }) => {
|
|
|
43
50
|
// Handle a relative path and an absolute path
|
|
44
51
|
const basePath = context.basePath || "";
|
|
45
52
|
const isAbsolute = isAbsoluteRoute(routeTemplate);
|
|
46
|
-
// Build the base URL
|
|
47
|
-
|
|
48
|
-
//
|
|
49
|
-
|
|
53
|
+
// Build the base URL. Join every run of separators into one, exactly as
|
|
54
|
+
// `buildRouteTree` of `@xmachines/play-router` does for the `fullPath` that the route
|
|
55
|
+
// map holds: `deriveRoute` writes `${parent}/${child}`, so a parent route that ends
|
|
56
|
+
// with a `/` gives `/app//sub` while the map holds `/app/sub`. A bridge pushed that
|
|
57
|
+
// location, the router reported `/app/sub` back — `sanitizePathname` collapses it —
|
|
58
|
+
// and the echo test then read its OWN push as a move of the user and sent a
|
|
59
|
+
// `play.route` for the state the actor was in already.
|
|
60
|
+
//
|
|
61
|
+
// The collapse runs on the TEMPLATE, and not on the built path, so a `:path*` value
|
|
62
|
+
// keeps every separator that it carries.
|
|
63
|
+
let url = (isAbsolute ? routeTemplate : joinPaths(basePath, routeTemplate)).replace(/\/+/g, "/");
|
|
64
|
+
// Replace each param with a context value. `buildPath` of `@xmachines/play-pattern`
|
|
65
|
+
// reads the WHOLE pattern grammar, which is the same parse that the match reads, so a
|
|
66
|
+
// route that the router matches derives a URL that the router matches back. That
|
|
67
|
+
// package carries the language alone: no URLPattern, and no polyfill for it.
|
|
68
|
+
const built = buildPath(url, context.params ?? {}, options);
|
|
69
|
+
if (!built.ok) {
|
|
70
|
+
if (built.reason === "unresolvable") {
|
|
71
|
+
throw new InvalidRouteParamError(built.param, built.value, routeTemplate);
|
|
72
|
+
}
|
|
73
|
+
throw new MissingRouteParamError(built.missing, routeTemplate);
|
|
74
|
+
}
|
|
75
|
+
// A template of the root level with optional params only, for example `/:section?`,
|
|
76
|
+
// builds `""`. That value makes an invalid URL, such as `""` or `"?tab=x"`.
|
|
77
|
+
url = built.path === "" ? "/" : built.path;
|
|
50
78
|
// Append the query params of the context. The frequent empty `query: {}` passes the
|
|
51
79
|
// key check first. Therefore each recomputation allocates a URLSearchParams object
|
|
52
80
|
// only when it has something to write.
|
|
@@ -66,54 +94,6 @@ export const buildRouteUrl = (routeTemplate, context = { query: {} }) => {
|
|
|
66
94
|
}
|
|
67
95
|
return url;
|
|
68
96
|
};
|
|
69
|
-
/**
|
|
70
|
-
* Replaces each `:param` placeholder with a context value, and it escapes that
|
|
71
|
-
* value with `encodeURIComponent`.
|
|
72
|
-
*
|
|
73
|
-
* The function supports an optional parameter, in the form :param?.
|
|
74
|
-
* - It removes an optional parameter without a value completely, and it also removes the /
|
|
75
|
-
* - It writes a warning for a necessary parameter without a value
|
|
76
|
-
*
|
|
77
|
-
* The lookup of a parameter:
|
|
78
|
-
* - The function reads context.params[param] only. It reads no flat context field.
|
|
79
|
-
*
|
|
80
|
-
* @param template - The URL template, with the :param or :param? syntax
|
|
81
|
-
* @param context - The context with the parameter values. It can have a params field
|
|
82
|
-
* @returns The URL with the parameters in place, and without a double slash
|
|
83
|
-
* @throws {MissingRouteParamError} When a necessary route parameter is absent
|
|
84
|
-
*/
|
|
85
|
-
const substituteParams = (template, context) => {
|
|
86
|
-
// Replace each parameter, and handle the optional syntax
|
|
87
|
-
let hasOptionalRemoval = false;
|
|
88
|
-
const result = template.replace(/:(\w+)(\?)?/g, (_match, param, optional) => {
|
|
89
|
-
const value = context.params?.[param]; // nosemgrep: gitlab.eslint.detect-object-injection
|
|
90
|
-
// The parameter has a value that is not empty: put it in place.
|
|
91
|
-
// For an optional param, an empty string means "no value".
|
|
92
|
-
if (value !== undefined && value !== null && value !== "") {
|
|
93
|
-
return encodeURIComponent(String(value));
|
|
94
|
-
}
|
|
95
|
-
// An optional parameter without a value, or with an empty string: remove the segment
|
|
96
|
-
if (optional === "?") {
|
|
97
|
-
hasOptionalRemoval = true;
|
|
98
|
-
return ""; // This leaves // in the path. The code below removes it
|
|
99
|
-
}
|
|
100
|
-
throw new MissingRouteParamError(param, template);
|
|
101
|
-
});
|
|
102
|
-
// Remove each double slash
|
|
103
|
-
let cleaned = result.replace(/\/+/g, "/");
|
|
104
|
-
// Remove a trailing slash only after the code removed an optional parameter.
|
|
105
|
-
// A trailing slash of a necessary param stays, because it shows an error.
|
|
106
|
-
if (hasOptionalRemoval && cleaned.endsWith("/")) {
|
|
107
|
-
cleaned = cleaned.slice(0, -1);
|
|
108
|
-
}
|
|
109
|
-
// Return an empty path never: a template of the root level with optional params
|
|
110
|
-
// only, for example "/:section?", becomes "" after the trim of the trailing slash.
|
|
111
|
-
// That value makes an invalid URL, such as "" or "?tab=x". Normalize it to "/".
|
|
112
|
-
if (cleaned === "") {
|
|
113
|
-
cleaned = "/";
|
|
114
|
-
}
|
|
115
|
-
return cleaned;
|
|
116
|
-
};
|
|
117
97
|
/**
|
|
118
98
|
* Joins a base path and a relative path
|
|
119
99
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build-url.js","sourceRoot":"","sources":["../../src/routing/build-url.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"build-url.js","sourceRoot":"","sources":["../../src/routing/build-url.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,40 +1,6 @@
|
|
|
1
1
|
import type { AnyMachineSnapshot } from "xstate";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
* root to a leaf. The key of each entry is the state id, and the order is the
|
|
5
|
-
* ancestors first. {@link deriveRoute} folds this shape.
|
|
6
|
-
*
|
|
7
|
-
* `snapshot.getMeta()` returns a FLAT record of the meta object of every active
|
|
8
|
-
* state. For a machine that is not parallel, that record is one chain of ancestors
|
|
9
|
-
* already. For a PARALLEL machine, it mixes the entries of every active region. A
|
|
10
|
-
* blind fold therefore joins a relative route of one region to an absolute route of
|
|
11
|
-
* a sibling region, and the URL belongs to the tree of neither region. The flat
|
|
12
|
-
* record also cannot go back into a hierarchy: when a state declares an explicit
|
|
13
|
-
* `id`, for example a child with `id: "dashboard-overview"` under `id: "dashboard"`,
|
|
14
|
-
* the meta keys are those ids, and they carry no information about the ancestry.
|
|
15
|
-
*
|
|
16
|
-
* Therefore this function walks `snapshot.value`, which holds the real hierarchy of
|
|
17
|
-
* the active states by the state key, against the node tree of the machine. It
|
|
18
|
-
* follows the FIRST active child at each level. This gives one deterministic branch,
|
|
19
|
-
* which matches the historical behavior of "the first that it finds" for a parallel
|
|
20
|
-
* machine. It also works with an explicit id, because each node carries its own `id`
|
|
21
|
-
* and its own `meta`.
|
|
22
|
-
*
|
|
23
|
-
* The function returns `null` when the snapshot exposes no machine and no value to
|
|
24
|
-
* walk. This is a defensive measure, because a real XState snapshot always exposes
|
|
25
|
-
* them. The caller then uses `getMeta()`, as before.
|
|
26
|
-
*/
|
|
27
|
-
export declare const firstActiveBranchMeta: (snapshot: AnyMachineSnapshot) => Record<string, unknown> | null;
|
|
28
|
-
/**
|
|
29
|
-
* Resolves the meta record that the route derivation and the view derivation fold:
|
|
30
|
-
* the single active branch that {@link firstActiveBranchMeta} walks, which is
|
|
31
|
-
* correct for a parallel machine and for an explicit id, or the flat `getMeta()`
|
|
32
|
-
* record when the snapshot has no machine tree to walk. `deriveCurrentRoute` and
|
|
33
|
-
* `deriveCurrentView` share this function. Therefore the two sides cannot move apart
|
|
34
|
-
* on the selection of the branch, and they cannot move apart on their tolerance of a
|
|
35
|
-
* degenerate snapshot.
|
|
36
|
-
*/
|
|
37
|
-
export declare const activeStateMeta: (snapshot: AnyMachineSnapshot) => Record<string, unknown> | null;
|
|
2
|
+
import type { ParseOptions } from "@xmachines/play-pattern";
|
|
3
|
+
export { activeStateMeta, firstActiveBranchMeta } from "../state-meta.js";
|
|
38
4
|
/**
|
|
39
5
|
* Derives the current URL of the actor from the state metadata and the context.
|
|
40
6
|
*
|
|
@@ -46,7 +12,7 @@ export declare const activeStateMeta: (snapshot: AnyMachineSnapshot) => Record<s
|
|
|
46
12
|
* - The snapshot has no route metadata, which means a state without a route
|
|
47
13
|
* - The context does not hold a necessary route parameter (`MissingRouteParamError`)
|
|
48
14
|
*
|
|
49
|
-
* The `null` value for an absent param is deliberate: the computed
|
|
15
|
+
* The `null` value for an absent param is deliberate: the computed atom therefore
|
|
50
16
|
* stays stable during a temporary state. Such a state appears during a transition,
|
|
51
17
|
* before the context is complete, and also after a logout, when `context.username`
|
|
52
18
|
* is `null` and the router bridge did not reach the new state yet. The router bridge
|
|
@@ -54,7 +20,15 @@ export declare const activeStateMeta: (snapshot: AnyMachineSnapshot) => Record<s
|
|
|
54
20
|
* context is complete.
|
|
55
21
|
*
|
|
56
22
|
* @param snapshot - The current snapshot of the XState machine.
|
|
23
|
+
* @param options - The caches that the parse of the route TEMPLATE reads. The default is
|
|
24
|
+
* the cache that `@xmachines/play-pattern` shares with every caller of the process.
|
|
25
|
+
*
|
|
26
|
+
* `withRouting` calls this function with no options, and that is deliberate: it parses
|
|
27
|
+
* the `meta.route` template of a state, and a machine declares a small and static set of
|
|
28
|
+
* those. The unbounded key space that a cache of the caller answers is the one of
|
|
29
|
+
* `RouterBridgeBase`, which parses a CONCRETE location — one for each value that an
|
|
30
|
+
* application puts in a param — and a bridge takes its caches already.
|
|
57
31
|
* @returns The resolved URL string, or `null` when the function cannot resolve the route.
|
|
58
32
|
*/
|
|
59
|
-
export declare const deriveCurrentRoute: (snapshot: AnyMachineSnapshot) => string | null;
|
|
33
|
+
export declare const deriveCurrentRoute: (snapshot: AnyMachineSnapshot, options?: ParseOptions) => string | null;
|
|
60
34
|
//# sourceMappingURL=derive-current-route.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"derive-current-route.d.ts","sourceRoot":"","sources":["../../src/routing/derive-current-route.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"derive-current-route.d.ts","sourceRoot":"","sources":["../../src/routing/derive-current-route.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,QAAQ,CAAC;AAMjD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAG5D,OAAO,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAE1E;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,eAAO,MAAM,kBAAkB,GAC9B,UAAU,kBAAkB,EAC5B,UAAU,YAAY,KACpB,MAAM,GAAG,IAsCX,CAAC"}
|
|
@@ -1,82 +1,8 @@
|
|
|
1
1
|
import { MissingRouteParamError } from "../errors.js";
|
|
2
2
|
import { deriveRoute } from "./derive-route.js";
|
|
3
3
|
import { buildRouteUrl } from "./build-url.js";
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
* root to a leaf. The key of each entry is the state id, and the order is the
|
|
7
|
-
* ancestors first. {@link deriveRoute} folds this shape.
|
|
8
|
-
*
|
|
9
|
-
* `snapshot.getMeta()` returns a FLAT record of the meta object of every active
|
|
10
|
-
* state. For a machine that is not parallel, that record is one chain of ancestors
|
|
11
|
-
* already. For a PARALLEL machine, it mixes the entries of every active region. A
|
|
12
|
-
* blind fold therefore joins a relative route of one region to an absolute route of
|
|
13
|
-
* a sibling region, and the URL belongs to the tree of neither region. The flat
|
|
14
|
-
* record also cannot go back into a hierarchy: when a state declares an explicit
|
|
15
|
-
* `id`, for example a child with `id: "dashboard-overview"` under `id: "dashboard"`,
|
|
16
|
-
* the meta keys are those ids, and they carry no information about the ancestry.
|
|
17
|
-
*
|
|
18
|
-
* Therefore this function walks `snapshot.value`, which holds the real hierarchy of
|
|
19
|
-
* the active states by the state key, against the node tree of the machine. It
|
|
20
|
-
* follows the FIRST active child at each level. This gives one deterministic branch,
|
|
21
|
-
* which matches the historical behavior of "the first that it finds" for a parallel
|
|
22
|
-
* machine. It also works with an explicit id, because each node carries its own `id`
|
|
23
|
-
* and its own `meta`.
|
|
24
|
-
*
|
|
25
|
-
* The function returns `null` when the snapshot exposes no machine and no value to
|
|
26
|
-
* walk. This is a defensive measure, because a real XState snapshot always exposes
|
|
27
|
-
* them. The caller then uses `getMeta()`, as before.
|
|
28
|
-
*/
|
|
29
|
-
export const firstActiveBranchMeta = (snapshot) => {
|
|
30
|
-
const root = snapshot.machine?.root;
|
|
31
|
-
if (!root)
|
|
32
|
-
return null;
|
|
33
|
-
const ordered = {};
|
|
34
|
-
let node = root;
|
|
35
|
-
let value = snapshot.value;
|
|
36
|
-
while (node) {
|
|
37
|
-
if (node.meta && typeof node.meta === "object") {
|
|
38
|
-
ordered[node.id] = node.meta; // nosemgrep: gitlab.eslint.detect-object-injection
|
|
39
|
-
}
|
|
40
|
-
// Find the key of the active child at this level. A string value is the name of an
|
|
41
|
-
// atomic active leaf. An object value is a compound node, with one key, or a
|
|
42
|
-
// parallel node, with many keys: take the first key, for one deterministic
|
|
43
|
-
// branch.
|
|
44
|
-
let key;
|
|
45
|
-
if (typeof value === "string") {
|
|
46
|
-
key = value;
|
|
47
|
-
}
|
|
48
|
-
else if (value && typeof value === "object") {
|
|
49
|
-
key = Object.keys(value)[0];
|
|
50
|
-
}
|
|
51
|
-
if (key === undefined)
|
|
52
|
-
break;
|
|
53
|
-
const child = node.states?.[key]; // nosemgrep: gitlab.eslint.detect-object-injection
|
|
54
|
-
if (!child)
|
|
55
|
-
break;
|
|
56
|
-
value =
|
|
57
|
-
typeof value === "object" && value !== null
|
|
58
|
-
? value[key] // nosemgrep: gitlab.eslint.detect-object-injection
|
|
59
|
-
: {};
|
|
60
|
-
node = child;
|
|
61
|
-
}
|
|
62
|
-
return ordered;
|
|
63
|
-
};
|
|
64
|
-
/**
|
|
65
|
-
* Resolves the meta record that the route derivation and the view derivation fold:
|
|
66
|
-
* the single active branch that {@link firstActiveBranchMeta} walks, which is
|
|
67
|
-
* correct for a parallel machine and for an explicit id, or the flat `getMeta()`
|
|
68
|
-
* record when the snapshot has no machine tree to walk. `deriveCurrentRoute` and
|
|
69
|
-
* `deriveCurrentView` share this function. Therefore the two sides cannot move apart
|
|
70
|
-
* on the selection of the branch, and they cannot move apart on their tolerance of a
|
|
71
|
-
* degenerate snapshot.
|
|
72
|
-
*/
|
|
73
|
-
export const activeStateMeta = (snapshot) => {
|
|
74
|
-
if (!snapshot || typeof snapshot.getMeta !== "function") {
|
|
75
|
-
return null;
|
|
76
|
-
}
|
|
77
|
-
const meta = firstActiveBranchMeta(snapshot) ?? snapshot.getMeta();
|
|
78
|
-
return meta && typeof meta === "object" ? meta : null;
|
|
79
|
-
};
|
|
4
|
+
import { activeStateMeta } from "../state-meta.js";
|
|
5
|
+
export { activeStateMeta, firstActiveBranchMeta } from "../state-meta.js";
|
|
80
6
|
/**
|
|
81
7
|
* Derives the current URL of the actor from the state metadata and the context.
|
|
82
8
|
*
|
|
@@ -88,7 +14,7 @@ export const activeStateMeta = (snapshot) => {
|
|
|
88
14
|
* - The snapshot has no route metadata, which means a state without a route
|
|
89
15
|
* - The context does not hold a necessary route parameter (`MissingRouteParamError`)
|
|
90
16
|
*
|
|
91
|
-
* The `null` value for an absent param is deliberate: the computed
|
|
17
|
+
* The `null` value for an absent param is deliberate: the computed atom therefore
|
|
92
18
|
* stays stable during a temporary state. Such a state appears during a transition,
|
|
93
19
|
* before the context is complete, and also after a logout, when `context.username`
|
|
94
20
|
* is `null` and the router bridge did not reach the new state yet. The router bridge
|
|
@@ -96,9 +22,17 @@ export const activeStateMeta = (snapshot) => {
|
|
|
96
22
|
* context is complete.
|
|
97
23
|
*
|
|
98
24
|
* @param snapshot - The current snapshot of the XState machine.
|
|
25
|
+
* @param options - The caches that the parse of the route TEMPLATE reads. The default is
|
|
26
|
+
* the cache that `@xmachines/play-pattern` shares with every caller of the process.
|
|
27
|
+
*
|
|
28
|
+
* `withRouting` calls this function with no options, and that is deliberate: it parses
|
|
29
|
+
* the `meta.route` template of a state, and a machine declares a small and static set of
|
|
30
|
+
* those. The unbounded key space that a cache of the caller answers is the one of
|
|
31
|
+
* `RouterBridgeBase`, which parses a CONCRETE location — one for each value that an
|
|
32
|
+
* application puts in a param — and a bridge takes its caches already.
|
|
99
33
|
* @returns The resolved URL string, or `null` when the function cannot resolve the route.
|
|
100
34
|
*/
|
|
101
|
-
export const deriveCurrentRoute = (snapshot) => {
|
|
35
|
+
export const deriveCurrentRoute = (snapshot, options) => {
|
|
102
36
|
const meta = activeStateMeta(snapshot);
|
|
103
37
|
if (!meta) {
|
|
104
38
|
return null;
|
|
@@ -108,7 +42,7 @@ export const deriveCurrentRoute = (snapshot) => {
|
|
|
108
42
|
return null;
|
|
109
43
|
}
|
|
110
44
|
try {
|
|
111
|
-
return buildRouteUrl(routeTemplate, (snapshot.context ?? {}));
|
|
45
|
+
return buildRouteUrl(routeTemplate, (snapshot.context ?? {}), options);
|
|
112
46
|
}
|
|
113
47
|
catch (error) {
|
|
114
48
|
// MissingRouteParamError: the condition is temporary, and it resolves itself. A
|
|
@@ -117,14 +51,22 @@ export const deriveCurrentRoute = (snapshot) => {
|
|
|
117
51
|
// context.params, and also after a logout, before the bridge redirects. A `null`
|
|
118
52
|
// value is correct here:
|
|
119
53
|
// - a router bridge reads null and skips the navigation (syncRouterFromActor, line 242)
|
|
120
|
-
// - the
|
|
121
|
-
// - a
|
|
122
|
-
//
|
|
54
|
+
// - the atom computes its value again on the next snapshot, when the params arrive
|
|
55
|
+
// - a report of a condition that resolves itself is worse than a null value for
|
|
56
|
+
// one tick.
|
|
123
57
|
// Do NOT convert this into a throw.
|
|
124
58
|
if (error instanceof MissingRouteParamError) {
|
|
125
59
|
return null;
|
|
126
60
|
}
|
|
127
61
|
// Each unexpected error goes to the caller without a change.
|
|
62
|
+
//
|
|
63
|
+
// This function is PURE, and it stays that way: it has no actor, so it holds no
|
|
64
|
+
// error channel and no previous value. The CALLER decides what an unexpected error
|
|
65
|
+
// means. `currentRoute` of `with-routing.ts` is that caller for the reactive path —
|
|
66
|
+
// it reports through `onError` of the actor and keeps the last route, because a
|
|
67
|
+
// throw from there would unwind into the transition. `initialRoute` is the other
|
|
68
|
+
// caller, and a throw from it fails the construction, which is where a developer
|
|
69
|
+
// wants to see a route template that cannot be built.
|
|
128
70
|
throw error;
|
|
129
71
|
}
|
|
130
72
|
};
|
|
@@ -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":"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,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAEnD,OAAO,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAE1E;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CACjC,QAA4B,EAC5B,OAAsB,EACN,EAAE;IAClB,MAAM,IAAI,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;IACvC,IAAI,CAAC,IAAI,EAAE,CAAC;QACX,OAAO,IAAI,CAAC;IACb,CAAC;IAED,MAAM,aAAa,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;IACxC,IAAI,CAAC,aAAa,EAAE,CAAC;QACpB,OAAO,IAAI,CAAC;IACb,CAAC;IAED,IAAI,CAAC;QACJ,OAAO,aAAa,CAAC,aAAa,EAAE,CAAC,QAAQ,CAAC,OAAO,IAAI,EAAE,CAAiB,EAAE,OAAO,CAAC,CAAC;IACxF,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,gFAAgF;QAChF,oFAAoF;QACpF,gFAAgF;QAChF,iFAAiF;QACjF,yBAAyB;QACzB,0FAA0F;QAC1F,qFAAqF;QACrF,kFAAkF;QAClF,gBAAgB;QAChB,oCAAoC;QACpC,IAAI,KAAK,YAAY,sBAAsB,EAAE,CAAC;YAC7C,OAAO,IAAI,CAAC;QACb,CAAC;QACD,6DAA6D;QAC7D,EAAE;QACF,gFAAgF;QAChF,mFAAmF;QACnF,oFAAoF;QACpF,gFAAgF;QAChF,iFAAiF;QACjF,iFAAiF;QACjF,sDAAsD;QACtD,MAAM,KAAK,CAAC;IACb,CAAC;AACF,CAAC,CAAC"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type AnyStateMachine } from "xstate";
|
|
2
|
+
import type { ParseOptions } from "@xmachines/play-pattern";
|
|
2
3
|
/**
|
|
3
4
|
* Derives the initial route of the machine directly from the machine definition.
|
|
4
5
|
*
|
|
@@ -39,5 +40,5 @@ import { type AnyStateMachine } from "xstate";
|
|
|
39
40
|
* deriveInitialRoute(machine, { username: "alice" }); // "/profile/alice"
|
|
40
41
|
* ```
|
|
41
42
|
*/
|
|
42
|
-
export declare const deriveInitialRoute: (machine: AnyStateMachine, input?: unknown) => string | null;
|
|
43
|
+
export declare const deriveInitialRoute: (machine: AnyStateMachine, input?: unknown, options?: ParseOptions) => string | null;
|
|
43
44
|
//# sourceMappingURL=derive-initial-route.d.ts.map
|
|
@@ -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;
|
|
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;AAG1F,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAE5D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,eAAO,MAAM,kBAAkB,GAC9B,SAAS,eAAe,EACxB,QAAQ,OAAO,EACf,UAAU,YAAY,KACpB,MAAM,GAAG,IAwBX,CAAC"}
|
|
@@ -40,7 +40,7 @@ import { deriveCurrentRoute } from "./derive-current-route.js";
|
|
|
40
40
|
* deriveInitialRoute(machine, { username: "alice" }); // "/profile/alice"
|
|
41
41
|
* ```
|
|
42
42
|
*/
|
|
43
|
-
export const deriveInitialRoute = (machine, input) => {
|
|
43
|
+
export const deriveInitialRoute = (machine, input, options) => {
|
|
44
44
|
let initialSnapshot;
|
|
45
45
|
try {
|
|
46
46
|
[initialSnapshot] = initialTransition(machine, input);
|
|
@@ -52,6 +52,17 @@ export const deriveInitialRoute = (machine, input) => {
|
|
|
52
52
|
// that snapshot also has no route metadata. Report "no initial route to derive".
|
|
53
53
|
return null;
|
|
54
54
|
}
|
|
55
|
-
|
|
55
|
+
// The SAME failure, reported the other way. XState 5.32 threw out of
|
|
56
|
+
// `initialTransition` for a context factory that throws, and 5.33 returns an
|
|
57
|
+
// error-status snapshot instead, with the reason on `snapshot.error`. The catch above
|
|
58
|
+
// therefore stopped firing, and a machine whose context never built derived the route
|
|
59
|
+
// of its initial state — `/login` for a factory that threw — which a bridge then took
|
|
60
|
+
// as the place of the actor.
|
|
61
|
+
//
|
|
62
|
+
// Both shapes mean the same thing, so both answer the same way. The status is the
|
|
63
|
+
// question, and it holds whichever way a later release reports the failure.
|
|
64
|
+
if (initialSnapshot.status === "error")
|
|
65
|
+
return null;
|
|
66
|
+
return deriveCurrentRoute(initialSnapshot, options);
|
|
56
67
|
};
|
|
57
68
|
//# sourceMappingURL=derive-initial-route.js.map
|
|
@@ -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;
|
|
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;AAG/D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CACjC,OAAwB,EACxB,KAAe,EACf,OAAsB,EACN,EAAE;IAClB,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,qEAAqE;IACrE,6EAA6E;IAC7E,sFAAsF;IACtF,sFAAsF;IACtF,sFAAsF;IACtF,6BAA6B;IAC7B,EAAE;IACF,kFAAkF;IAClF,4EAA4E;IAC5E,IAAI,eAAe,CAAC,MAAM,KAAK,OAAO;QAAE,OAAO,IAAI,CAAC;IAEpD,OAAO,kBAAkB,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC;AACrD,CAAC,CAAC"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { PlayRouteEvent, RouteData } from "@xmachines/play-router";
|
|
1
2
|
import type { RouteMetadata } from "./types.js";
|
|
2
3
|
/**
|
|
3
4
|
* Derives the route from the metadata of an XState state
|
|
@@ -18,7 +19,7 @@ import type { RouteMetadata } from "./types.js";
|
|
|
18
19
|
* @example
|
|
19
20
|
* The basic read of a route
|
|
20
21
|
* ```typescript
|
|
21
|
-
* import { deriveRoute } from "@xmachines/play-xstate";
|
|
22
|
+
* import { deriveRoute } from "@xmachines/play-xstate/routing";
|
|
22
23
|
* import { setup } from "xstate";
|
|
23
24
|
*
|
|
24
25
|
* const machine = setup({}).createMachine({
|
|
@@ -101,6 +102,84 @@ export declare const deriveRoute: (stateMeta: Record<string, unknown>) => string
|
|
|
101
102
|
* @throws {InvalidRouteMetadataError} When the form of the route is invalid
|
|
102
103
|
*/
|
|
103
104
|
export declare const normalizeRoute: (route: RouteMetadata, source?: string) => string;
|
|
105
|
+
/**
|
|
106
|
+
* Reads the `reenter` flag of the route metadata.
|
|
107
|
+
*
|
|
108
|
+
* The string form of the metadata declares no flag, and the object form declares the
|
|
109
|
+
* flag only when it wants one. Both therefore give `false`, which is the default of
|
|
110
|
+
* XState for a transition. A state without a route gives `false` too, so the caller
|
|
111
|
+
* needs no test of its own for that case.
|
|
112
|
+
*
|
|
113
|
+
* The function does NOT check the form of the metadata. `normalizeRoute` runs first at
|
|
114
|
+
* every call site and throws `InvalidRouteMetadataError` on a malformed value.
|
|
115
|
+
*
|
|
116
|
+
* @param route - The route metadata: a string, an object with a `path` property, or
|
|
117
|
+
* `undefined` for a state that declares no route
|
|
118
|
+
* @returns The declared flag, or `false` where the metadata declares none
|
|
119
|
+
*
|
|
120
|
+
* @example
|
|
121
|
+
* ```typescript
|
|
122
|
+
* routeReenter("/dashboard"); // false
|
|
123
|
+
* routeReenter({ path: "/dashboard" }); // false
|
|
124
|
+
* routeReenter({ path: "/dashboard", reenter: true }); // true
|
|
125
|
+
* routeReenter(undefined); // false
|
|
126
|
+
* ```
|
|
127
|
+
*/
|
|
128
|
+
export declare const routeReenter: (route: RouteMetadata | undefined) => boolean;
|
|
129
|
+
/**
|
|
130
|
+
* Reads the extra data that a route declares, resolved for one event.
|
|
131
|
+
*
|
|
132
|
+
* The field holds a literal value or a function of `{ context, event }`, which is the
|
|
133
|
+
* `WithDynamicParams` shape of XState. This function collapses the two into the value.
|
|
134
|
+
*
|
|
135
|
+
* The function does NOT check the form of the metadata. `normalizeRoute` runs first at
|
|
136
|
+
* every call site and throws `InvalidRouteMetadataError` on a malformed value.
|
|
137
|
+
*
|
|
138
|
+
* @param route - The route metadata: a string, an object with a `path` property, or
|
|
139
|
+
* `undefined` for a state that declares no route
|
|
140
|
+
* @param args - The context of the machine and the `play.route` event that asks for the
|
|
141
|
+
* route. The resolver reads them.
|
|
142
|
+
* @returns The data, or `undefined` where the route declares none
|
|
143
|
+
*
|
|
144
|
+
* @example
|
|
145
|
+
* ```typescript
|
|
146
|
+
* routeData({ path: "/a", data: { titleKey: "a" } }, args); // { titleKey: "a" }
|
|
147
|
+
* routeData({ path: "/a", data: ({ event }) => ({ to: event.to }) }, args);
|
|
148
|
+
* routeData("/a", args); // undefined
|
|
149
|
+
* ```
|
|
150
|
+
*/
|
|
151
|
+
export declare const routeData: (route: RouteMetadata | undefined, args: {
|
|
152
|
+
context: unknown;
|
|
153
|
+
event: PlayRouteEvent;
|
|
154
|
+
}) => RouteData | undefined;
|
|
155
|
+
/**
|
|
156
|
+
* Reads the placement of the generated `play.route` transition.
|
|
157
|
+
*
|
|
158
|
+
* `"root"` is the default, and it is the placement of XState: every route transition
|
|
159
|
+
* sits on the root of the machine. `"local"` moves the transition to the parent of the
|
|
160
|
+
* state, and `"both"` puts one transition in each place.
|
|
161
|
+
*
|
|
162
|
+
* The function does NOT check the form of the metadata. `normalizeRoute` runs first at
|
|
163
|
+
* every call site and throws `InvalidRouteMetadataError` on a malformed value.
|
|
164
|
+
*
|
|
165
|
+
* @param route - The route metadata: a string, an object with a `path` property, or
|
|
166
|
+
* `undefined` for a state that declares no route
|
|
167
|
+
* @param source - The `PlayError.scope` value to report for an unknown placement
|
|
168
|
+
* @returns The declared placement, and `"root"` where the metadata declares none
|
|
169
|
+
* @throws {InvalidRouteHandlerError} When the object declares a `handler` that is not
|
|
170
|
+
* `"root"`, `"local"`, or `"both"`. A typo would otherwise fall back to a placement
|
|
171
|
+
* that the author did not ask for, and it would change which states a route reaches.
|
|
172
|
+
*
|
|
173
|
+
* @example
|
|
174
|
+
* ```typescript
|
|
175
|
+
* routeHandler("/dashboard"); // "root"
|
|
176
|
+
* routeHandler({ path: "/dashboard" }); // "root"
|
|
177
|
+
* routeHandler({ path: "/dashboard", handler: "local" }); // "local"
|
|
178
|
+
* routeHandler({ path: "/dashboard", handler: "both" }); // "both"
|
|
179
|
+
* routeHandler({ path: "/dashboard", handler: "locale" }); // throws
|
|
180
|
+
* ```
|
|
181
|
+
*/
|
|
182
|
+
export declare const routeHandler: (route: RouteMetadata | undefined, source?: string) => "root" | "local" | "both";
|
|
104
183
|
/**
|
|
105
184
|
* Tells you if the route path is absolute
|
|
106
185
|
*
|
|
@@ -113,7 +192,7 @@ export declare const normalizeRoute: (route: RouteMetadata, source?: string) =>
|
|
|
113
192
|
*
|
|
114
193
|
* @example
|
|
115
194
|
* ```typescript
|
|
116
|
-
* import { isAbsoluteRoute } from "@xmachines/play-xstate";
|
|
195
|
+
* import { isAbsoluteRoute } from "@xmachines/play-xstate/routing";
|
|
117
196
|
*
|
|
118
197
|
* console.log(isAbsoluteRoute("/dashboard")); // true
|
|
119
198
|
* console.log(isAbsoluteRoute("settings")); // false
|
|
@@ -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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;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
|
+
{"version":3,"file":"derive-route.d.ts","sourceRoot":"","sources":["../../src/routing/derive-route.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACxE,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;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,YAAY,GAAI,OAAO,aAAa,GAAG,SAAS,KAAG,OACuB,CAAC;AAExF;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,SAAS,GACrB,OAAO,aAAa,GAAG,SAAS,EAChC,MAAM;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,cAAc,CAAA;CAAE,KAC/C,SAAS,GAAG,SAOd,CAAC;AAKF;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,eAAO,MAAM,YAAY,GACxB,OAAO,aAAa,GAAG,SAAS,EAChC,eAAqC,KACnC,MAAM,GAAG,OAAO,GAAG,MAUrB,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,eAAe,GAAI,MAAM,MAAM,KAAG,OAE9C,CAAC"}
|