@xmachines/play-router 2.2.0 → 4.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 +103 -109
- package/dist/base-route-map.d.ts +7 -1
- package/dist/base-route-map.d.ts.map +1 -1
- package/dist/base-route-map.js +25 -12
- package/dist/base-route-map.js.map +1 -1
- package/dist/build-tree.d.ts +16 -1
- package/dist/build-tree.d.ts.map +1 -1
- package/dist/build-tree.js +23 -6
- package/dist/build-tree.js.map +1 -1
- package/dist/create-route-map-from-tree.d.ts +12 -6
- package/dist/create-route-map-from-tree.d.ts.map +1 -1
- package/dist/create-route-map-from-tree.js +13 -5
- package/dist/create-route-map-from-tree.js.map +1 -1
- package/dist/errors.d.ts +2 -134
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +11 -151
- package/dist/errors.js.map +1 -1
- package/dist/find-route.d.ts.map +1 -1
- package/dist/find-route.js +14 -19
- package/dist/find-route.js.map +1 -1
- package/dist/index.d.ts +7 -16
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -11
- package/dist/index.js.map +1 -1
- package/dist/provider-lifecycle.d.ts +28 -6
- package/dist/provider-lifecycle.d.ts.map +1 -1
- package/dist/provider-lifecycle.js +16 -2
- package/dist/provider-lifecycle.js.map +1 -1
- package/dist/router-bridge-base.d.ts +42 -23
- package/dist/router-bridge-base.d.ts.map +1 -1
- package/dist/router-bridge-base.js +257 -84
- package/dist/router-bridge-base.js.map +1 -1
- package/dist/router-sync.d.ts +1 -1
- package/dist/router-sync.d.ts.map +1 -1
- package/dist/router-sync.js +28 -13
- package/dist/router-sync.js.map +1 -1
- package/dist/types.d.ts +186 -87
- package/dist/types.d.ts.map +1 -1
- package/dist/{create-route-map.d.ts → xstate/create-route-map.d.ts} +6 -20
- package/dist/xstate/create-route-map.d.ts.map +1 -0
- package/dist/{create-route-map.js → xstate/create-route-map.js} +5 -3
- package/dist/xstate/create-route-map.js.map +1 -0
- package/dist/{extract-routes.d.ts → xstate/extract-routes.d.ts} +3 -2
- package/dist/xstate/extract-routes.d.ts.map +1 -0
- package/dist/{extract-routes.js → xstate/extract-routes.js} +8 -3
- package/dist/xstate/extract-routes.js.map +1 -0
- package/dist/xstate/index.d.ts +35 -0
- package/dist/xstate/index.d.ts.map +1 -0
- package/dist/xstate/index.js +33 -0
- package/dist/xstate/index.js.map +1 -0
- package/dist/{machine-to-graph.d.ts → xstate/machine-to-graph.d.ts} +1 -1
- package/dist/xstate/machine-to-graph.d.ts.map +1 -0
- package/dist/{machine-to-graph.js → xstate/machine-to-graph.js} +2 -2
- package/dist/xstate/machine-to-graph.js.map +1 -0
- package/dist/xstate/machine-types.d.ts +42 -0
- package/dist/xstate/machine-types.d.ts.map +1 -0
- package/dist/xstate/machine-types.js +2 -0
- package/dist/xstate/machine-types.js.map +1 -0
- package/dist/{query.d.ts → xstate/query.d.ts} +6 -4
- package/dist/xstate/query.d.ts.map +1 -0
- package/dist/{query.js → xstate/query.js} +3 -2
- package/dist/xstate/query.js.map +1 -0
- package/package.json +26 -20
- package/dist/base-path.d.ts +0 -209
- package/dist/base-path.d.ts.map +0 -1
- package/dist/base-path.js +0 -418
- package/dist/base-path.js.map +0 -1
- package/dist/create-route-map.d.ts.map +0 -1
- package/dist/create-route-map.js.map +0 -1
- package/dist/extract-routes.d.ts.map +0 -1
- package/dist/extract-routes.js.map +0 -1
- package/dist/framework-params.d.ts +0 -144
- package/dist/framework-params.d.ts.map +0 -1
- package/dist/framework-params.js +0 -291
- package/dist/framework-params.js.map +0 -1
- package/dist/machine-to-graph.d.ts.map +0 -1
- package/dist/machine-to-graph.js.map +0 -1
- package/dist/query.d.ts.map +0 -1
- package/dist/query.js.map +0 -1
- package/dist/url-pattern-utils.d.ts +0 -93
- package/dist/url-pattern-utils.d.ts.map +0 -1
- package/dist/url-pattern-utils.js +0 -233
- package/dist/url-pattern-utils.js.map +0 -1
package/dist/router-sync.d.ts
CHANGED
|
@@ -67,7 +67,7 @@ export declare function sanitizePathname(pathname: string): string | null;
|
|
|
67
67
|
* @param pathname - The concrete URL pathname, for example `/profile/alice`
|
|
68
68
|
* @param pattern - The template of the URL pattern, for example `/profile/:username`
|
|
69
69
|
* @returns The record of the parameter values of the read, or `{}` for a static pattern.
|
|
70
|
-
* @throws {
|
|
70
|
+
* @throws {InvalidRoutePatternError} When URLPattern cannot compile the pattern.
|
|
71
71
|
*
|
|
72
72
|
* @example
|
|
73
73
|
* ```typescript
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"router-sync.d.ts","sourceRoot":"","sources":["../src/router-sync.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"router-sync.d.ts","sourceRoot":"","sources":["../src/router-sync.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,MAAM,WAAW,UAAU;IAC1B,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,0BAA0B;IAC1C,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,KAAK,EAAE,CAAC,iBAAiB,EAAE,MAAM,KAAK,UAAU,CAAC;CACjD;AAED,MAAM,WAAW,gBAAgB;IAChC,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAC1D,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;CACxD;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAC5B,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,gBAAgB,EAC1B,aAAa,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC1E,UAAU,CAUZ;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAUhE;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAyB5F;AAeD;;;GAGG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAgBnE;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAClC,OAAO,EAAE,0BAA0B,GACjC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,cAAc,CAAA;CAAE,GAAG,IAAI,CAsBpD"}
|
package/dist/router-sync.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { URLPatternUnavailableError } from "./errors.js";
|
|
1
|
+
import { getCompiledPattern, getNormalizedParamNameMap, isParameterizedPattern, } from "@xmachines/play-url";
|
|
3
2
|
/**
|
|
4
3
|
* Matches a clean pathname against a route map, and reads each param of the match.
|
|
5
4
|
*
|
|
@@ -43,8 +42,13 @@ export function matchRouteMap(pathname, routeMap, extractParams) {
|
|
|
43
42
|
export function sanitizePathname(pathname) {
|
|
44
43
|
if (pathname.length > 2048)
|
|
45
44
|
return null;
|
|
46
|
-
|
|
47
|
-
|
|
45
|
+
// `slice` to the first separator. `split` allocates an array for a value that the
|
|
46
|
+
// code reads once, and its first element reads `string | undefined` although a split
|
|
47
|
+
// answers one element always.
|
|
48
|
+
const queryAt = pathname.indexOf("?");
|
|
49
|
+
const withoutQuery = queryAt === -1 ? pathname : pathname.slice(0, queryAt);
|
|
50
|
+
const hashAt = withoutQuery.indexOf("#");
|
|
51
|
+
const withoutHash = hashAt === -1 ? withoutQuery : withoutQuery.slice(0, hashAt);
|
|
48
52
|
return withoutHash.replace(/\/+/g, "/");
|
|
49
53
|
}
|
|
50
54
|
/**
|
|
@@ -70,7 +74,7 @@ export function sanitizePathname(pathname) {
|
|
|
70
74
|
* @param pathname - The concrete URL pathname, for example `/profile/alice`
|
|
71
75
|
* @param pattern - The template of the URL pattern, for example `/profile/:username`
|
|
72
76
|
* @returns The record of the parameter values of the read, or `{}` for a static pattern.
|
|
73
|
-
* @throws {
|
|
77
|
+
* @throws {InvalidRoutePatternError} When URLPattern cannot compile the pattern.
|
|
74
78
|
*
|
|
75
79
|
* @example
|
|
76
80
|
* ```typescript
|
|
@@ -84,27 +88,32 @@ export function sanitizePathname(pathname) {
|
|
|
84
88
|
* ```
|
|
85
89
|
*/
|
|
86
90
|
export function extractRouteParams(pathname, pattern) {
|
|
87
|
-
const Ctor = getURLPatternCtor();
|
|
88
|
-
if (!Ctor)
|
|
89
|
-
throw new URLPatternUnavailableError();
|
|
90
91
|
if (!isParameterizedPattern(pattern))
|
|
91
92
|
return {};
|
|
92
93
|
// Compile the pattern with the SAME normalization as the match in RouteMap.
|
|
93
94
|
// Without it, URLPattern reads ":cat-id" as the group ":cat" and the literal "-id",
|
|
94
95
|
// and the read of the params then contradicts the map that matched the path.
|
|
95
|
-
const urlPattern = getCompiledPattern(pattern
|
|
96
|
+
const urlPattern = getCompiledPattern(pattern);
|
|
96
97
|
const match = urlPattern.exec({ pathname });
|
|
97
98
|
if (!match?.pathname.groups)
|
|
98
99
|
return {};
|
|
99
100
|
// Map each normalized group name (":cat_id") back to its original param name ("cat-id").
|
|
100
101
|
const nameMap = getNormalizedParamNameMap(pattern);
|
|
101
|
-
|
|
102
|
+
// A null prototype for the accumulator, exactly as `cleanFrameworkParams` uses: a plain
|
|
103
|
+
// `{}` turns `params["__proto__"] = value` into a write of the PROTOTYPE setter, which
|
|
104
|
+
// drops the value in silence. A machine that declares `/:__proto__` then received `{}`
|
|
105
|
+
// from this extraction while the parse of Vue Router or SolidJS Router carried the
|
|
106
|
+
// value, so the two sources of the same params disagreed.
|
|
107
|
+
const params = Object.create(null);
|
|
102
108
|
for (const [key, value] of Object.entries(match.pathname.groups)) {
|
|
103
109
|
if (value !== undefined) {
|
|
104
110
|
params[nameMap.get(key) ?? key] = decodeParamValue(value); // nosemgrep: gitlab.eslint.detect-object-injection
|
|
105
111
|
}
|
|
106
112
|
}
|
|
107
|
-
|
|
113
|
+
// Spread at the boundary: `event.params` reaches a machine of the user, and a plain
|
|
114
|
+
// object is what it received before. A spread creates OWN properties, so a param named
|
|
115
|
+
// "__proto__" stays a key while the value keeps a prototype.
|
|
116
|
+
return { ...params };
|
|
108
117
|
}
|
|
109
118
|
/**
|
|
110
119
|
* Decodes each percent sequence of a URLPattern group value. It keeps the raw value
|
|
@@ -125,11 +134,17 @@ function decodeParamValue(value) {
|
|
|
125
134
|
*/
|
|
126
135
|
export function extractQuery(search) {
|
|
127
136
|
try {
|
|
128
|
-
|
|
137
|
+
// A null prototype for the accumulator, and a spread at the boundary: the same two
|
|
138
|
+
// steps as `extractRouteParams` above, and for the same reason. A plain `{}` turns
|
|
139
|
+
// `params["__proto__"] = value` into a write of the PROTOTYPE setter, which drops
|
|
140
|
+
// the value in silence — so a location of `?__proto__=nav` reached the machine with
|
|
141
|
+
// an EMPTY query, while the same name in the path reached it as a param. The two
|
|
142
|
+
// halves of one `play.route` event answered one name differently.
|
|
143
|
+
const params = Object.create(null);
|
|
129
144
|
new URLSearchParams(search).forEach((value, key) => {
|
|
130
145
|
params[key] = value; // nosemgrep: gitlab.eslint.detect-object-injection
|
|
131
146
|
});
|
|
132
|
-
return params;
|
|
147
|
+
return { ...params };
|
|
133
148
|
}
|
|
134
149
|
catch {
|
|
135
150
|
return {};
|
package/dist/router-sync.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"router-sync.js","sourceRoot":"","sources":["../src/router-sync.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"router-sync.js","sourceRoot":"","sources":["../src/router-sync.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,48 +1,146 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type { BasePathOptions } from "./base-path.js";
|
|
1
|
+
import type { BasePathOptions } from "@xmachines/play-url";
|
|
3
2
|
import type { Signal } from "@xmachines/play-signals";
|
|
4
|
-
import type { PlaySpec } from "@xmachines/play-actor";
|
|
5
3
|
/**
|
|
6
|
-
* The
|
|
7
|
-
*
|
|
4
|
+
* The type definitions of the routing protocol of @xmachines/play-router
|
|
5
|
+
*
|
|
6
|
+
* PlayRouteEvent, RouterBridge, RouteMetadata, and RouteObject are here. The routing
|
|
7
|
+
* therefore stays separate from the base event protocol of @xmachines/play.
|
|
8
8
|
*/
|
|
9
|
-
export interface MachineNodeData {
|
|
10
|
-
/** The XState state ID, for example "test.dashboard.overview" */
|
|
11
|
-
stateId: string;
|
|
12
|
-
/** The state type of XState */
|
|
13
|
-
type: "atomic" | "compound" | "parallel" | "final" | "history";
|
|
14
|
-
/** The original meta object of the state */
|
|
15
|
-
meta?: Record<string, unknown>;
|
|
16
|
-
/** The route path of meta.route, in its string form */
|
|
17
|
-
route?: string;
|
|
18
|
-
}
|
|
19
9
|
/**
|
|
20
|
-
* The data
|
|
21
|
-
*
|
|
10
|
+
* The resolved extra data of a route. It reaches the consumer on the `data` field of a
|
|
11
|
+
* `play.route` event.
|
|
22
12
|
*/
|
|
23
|
-
export
|
|
24
|
-
/** The event type that starts this transition */
|
|
25
|
-
eventType: string;
|
|
26
|
-
/**
|
|
27
|
-
* The guard as a string, when a guard is present
|
|
28
|
-
*
|
|
29
|
-
* @deprecated Will be removed in the next major.
|
|
30
|
-
*/
|
|
31
|
-
guardType?: string;
|
|
32
|
-
}
|
|
13
|
+
export type RouteData = Record<string, unknown>;
|
|
33
14
|
/**
|
|
34
|
-
* The
|
|
15
|
+
* The function form of {@link RouteObject.data}.
|
|
35
16
|
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
17
|
+
* The signature mirrors `WithDynamicParams` of XState: the resolver reads the context
|
|
18
|
+
* of the machine and the event that asks for the route, and it returns the data.
|
|
19
|
+
*
|
|
20
|
+
* The resolver reads every field of the event, and `event.data` among them: that field
|
|
21
|
+
* carries what the SENDER of the event supplied, and the resolver decides how it
|
|
22
|
+
* combines with what the state declares. The `data` that the resolver RETURNS goes to
|
|
23
|
+
* `context.data`, and it does not go back onto the event.
|
|
38
24
|
*/
|
|
25
|
+
export type RouteDataResolver = (args: {
|
|
26
|
+
context: unknown;
|
|
27
|
+
event: PlayRouteEvent;
|
|
28
|
+
}) => RouteData;
|
|
39
29
|
/**
|
|
40
30
|
* A route object, with more metadata.
|
|
41
31
|
*/
|
|
42
32
|
export interface RouteObject {
|
|
43
|
-
/** The template of the route path, for example
|
|
33
|
+
/** The template of the route path, for example `"/user/:id"`. */
|
|
44
34
|
path: string;
|
|
45
|
-
/**
|
|
35
|
+
/**
|
|
36
|
+
* The `reenter` flag of the generated `play.route` transition.
|
|
37
|
+
*
|
|
38
|
+
* The default is `false`, which is also the default of XState.
|
|
39
|
+
*
|
|
40
|
+
* The flag spares the DOMAIN of the transition, and not every ancestor that stays
|
|
41
|
+
* active. Under the default placement `handler: "root"` the domain is the root of
|
|
42
|
+
* the machine, so `false` spares the root alone: each ancestor BETWEEN the root and
|
|
43
|
+
* the target still runs its `exit` and its `entry` actions, because XState re-enters
|
|
44
|
+
* every descendant of the domain that lies on the path to the target. A move between
|
|
45
|
+
* two siblings therefore still runs the `entry` action of their shared parent.
|
|
46
|
+
*
|
|
47
|
+
* {@link RouteObject.handler} is the field that spares those intermediate ancestors:
|
|
48
|
+
* `"local"` and `"both"` move the domain down to the parent of the state. Use the
|
|
49
|
+
* two fields together where an `entry` action must run one time for each state that
|
|
50
|
+
* the actor really enters.
|
|
51
|
+
*
|
|
52
|
+
* Set the field to `true` where the domain must run its `entry` actions again on
|
|
53
|
+
* every route to a descendant.
|
|
54
|
+
*
|
|
55
|
+
* The flag does not decide the destination. The value of the machine after a route
|
|
56
|
+
* is identical under both settings. A route to a state that has children still
|
|
57
|
+
* enters the `initial` child of that state, because the generated transition targets
|
|
58
|
+
* the state by its id, and XState enters the initial child of an id target under
|
|
59
|
+
* both settings.
|
|
60
|
+
*
|
|
61
|
+
* @see [Play RFC](../../docs/rfc/play.md)
|
|
62
|
+
*/
|
|
63
|
+
reenter?: boolean;
|
|
64
|
+
/**
|
|
65
|
+
* Where the generated `play.route` transition sits.
|
|
66
|
+
*
|
|
67
|
+
* `"root"` is the default, and it is what XState does: `formatRouteTransitions`
|
|
68
|
+
* installs every route transition on the ROOT of the machine, and each one targets
|
|
69
|
+
* its state by the ID. A route from any state therefore reaches this state. The cost
|
|
70
|
+
* is that the root is the domain of the transition, so XState re-enters each
|
|
71
|
+
* ancestor on the path to the target, and those ancestors run their `entry` actions
|
|
72
|
+
* again although they stay active.
|
|
73
|
+
*
|
|
74
|
+
* `"local"` installs the transition on the PARENT of this state instead, and it
|
|
75
|
+
* targets this state relatively. XState offers the transitions of the deepest active
|
|
76
|
+
* state node first, so the parent answers the event itself and runs its `exit` and
|
|
77
|
+
* its `entry` actions NOT again.
|
|
78
|
+
*
|
|
79
|
+
* `"both"` installs one transition in each place. The local one answers while the
|
|
80
|
+
* parent is active, and the root one answers a route that arrives from outside the
|
|
81
|
+
* parent. Use `"both"` where an ancestor holds an `entry` action that must run one
|
|
82
|
+
* time for each real entry, such as an analytics event or an audit record.
|
|
83
|
+
*
|
|
84
|
+
* CAUTION: `"local"` makes this state reachable by a route ONLY while its parent is
|
|
85
|
+
* active. A `play.route` event that arrives from anywhere else matches no transition
|
|
86
|
+
* and the actor does not move. A browser URL for this state therefore leaves the URL
|
|
87
|
+
* and the actor divergent. Choose `"local"` to SCOPE a route on purpose, for example
|
|
88
|
+
* a step that a person reaches only inside its wizard. Choose `"both"` where the
|
|
89
|
+
* state must stay reachable from everywhere.
|
|
90
|
+
*
|
|
91
|
+
* The field has no effect on a state whose parent IS the root: the root transition
|
|
92
|
+
* of such a state is already local to its parent, so all three values agree.
|
|
93
|
+
*/
|
|
94
|
+
handler?: "root" | "local" | "both";
|
|
95
|
+
/**
|
|
96
|
+
* The extra data that the state threads into its `play.route` event.
|
|
97
|
+
*
|
|
98
|
+
* The shape follows `WithDynamicParams` of XState, which is how XState itself
|
|
99
|
+
* parameterizes an action and a guard: the field holds a literal value, OR a
|
|
100
|
+
* function of `{ context, event }` that returns one.
|
|
101
|
+
*
|
|
102
|
+
* ```ts
|
|
103
|
+
* // The literal form. It survives a serialization of the machine.
|
|
104
|
+
* meta: { route: { path: "/doc/:docId", data: { titleKey: "doc.view" } } }
|
|
105
|
+
*
|
|
106
|
+
* // The function form, for a value that depends on the route.
|
|
107
|
+
* meta: {
|
|
108
|
+
* route: {
|
|
109
|
+
* path: "/doc/:docId",
|
|
110
|
+
* data: ({ event }) => ({ title: `Document ${event.params?.docId}` }),
|
|
111
|
+
* },
|
|
112
|
+
* }
|
|
113
|
+
* ```
|
|
114
|
+
*
|
|
115
|
+
* The generated transition resolves the value and assigns it to the `data` field of
|
|
116
|
+
* the context, beside `params` and `query`. The data of a state does NOT merge with
|
|
117
|
+
* the data of its ancestors: each state declares the whole value that its own route
|
|
118
|
+
* carries.
|
|
119
|
+
*
|
|
120
|
+
* This field and {@link PlayRouteEvent.data} are two different things, and they meet
|
|
121
|
+
* in the resolver. This field is what the STATE declares, in its machine.
|
|
122
|
+
* `PlayRouteEvent.data` is what the SENDER of the event supplies, such as a router
|
|
123
|
+
* bridge or the code of an application. A resolver reads `event.data` and returns
|
|
124
|
+
* whatever mix of the two the state needs.
|
|
125
|
+
*
|
|
126
|
+
* CAUTION: the function form holds a function inside `meta`, and a function does not
|
|
127
|
+
* survive `JSON.stringify`. A machine that Stately Studio reads, or that a process
|
|
128
|
+
* sends over a wire, must use the literal form.
|
|
129
|
+
*/
|
|
130
|
+
data?: RouteData | RouteDataResolver;
|
|
131
|
+
/**
|
|
132
|
+
* The additional metadata of the route: a title, a breadcrumb, and so on.
|
|
133
|
+
*
|
|
134
|
+
* CAUTION: `path`, `handler`, `reenter` and `data` are RESERVED. The routing layer
|
|
135
|
+
* reads those four names, and a release before this one read `path` alone. A state
|
|
136
|
+
* that carries its own `handler` value now throws an `InvalidRouteHandlerError` from
|
|
137
|
+
* `formatPlayRouteTransitions`, so the machine builds never; a state that carries its
|
|
138
|
+
* own `data` value now writes that value to `context.data`, where the `/context`
|
|
139
|
+
* projection of every view reads it. A `reenter` value is read as the FLAG of the
|
|
140
|
+
* generated transition, and the literal `true` alone turns the reentry on: the
|
|
141
|
+
* default is `false`, and a release before this one generated every transition with
|
|
142
|
+
* `reenter: true`. Give such a field another name.
|
|
143
|
+
*/
|
|
46
144
|
[key: string]: unknown;
|
|
47
145
|
}
|
|
48
146
|
/**
|
|
@@ -112,7 +210,7 @@ export interface RouteNode {
|
|
|
112
210
|
* - byStateId: it maps each state ID to its route node, for the target of a play.route event
|
|
113
211
|
* - byPath: it maps each URL path to its route node, for the browser navigation
|
|
114
212
|
*/
|
|
115
|
-
export interface RouteTree {
|
|
213
|
+
export interface RouteTree<TGraph = unknown> {
|
|
116
214
|
/** The root node of the routes */
|
|
117
215
|
root: RouteNode;
|
|
118
216
|
/**
|
|
@@ -127,17 +225,20 @@ export interface RouteTree {
|
|
|
127
225
|
byPath: Map<string, RouteNode>;
|
|
128
226
|
/**
|
|
129
227
|
* The graph of the state machine, for an advanced query.
|
|
130
|
-
*
|
|
131
|
-
*
|
|
132
|
-
*
|
|
228
|
+
*
|
|
229
|
+
* `TGraph` carries its type, and this package names none: a route tree is a map from a
|
|
230
|
+
* path to a state, and the graph of a MACHINE belongs to the package that reads a
|
|
231
|
+
* machine. `extractMachineRoutes` of `@xmachines/play-router/xstate` answers
|
|
232
|
+
* `RouteTree<MachineGraph>`, so a consumer of that function loses no type.
|
|
133
233
|
*
|
|
134
234
|
* @example
|
|
135
235
|
* ```typescript
|
|
136
236
|
* import { getSuccessors, hasPath } from "@statelyai/graph";
|
|
237
|
+
* // `tree` comes from `extractMachineRoutes` of `@xmachines/play-router/xstate`
|
|
137
238
|
* const successors = getSuccessors(tree.graph!, "myMachine.home");
|
|
138
239
|
* ```
|
|
139
240
|
*/
|
|
140
|
-
graph?:
|
|
241
|
+
graph?: TGraph;
|
|
141
242
|
}
|
|
142
243
|
/**
|
|
143
244
|
* The routing event, with its parameters and its query
|
|
@@ -231,23 +332,43 @@ export interface PlayRouteEvent {
|
|
|
231
332
|
readonly to: string;
|
|
232
333
|
readonly params?: Record<string, string>;
|
|
233
334
|
readonly query?: Record<string, string>;
|
|
335
|
+
/**
|
|
336
|
+
* The extra data that the SENDER of this event supplies: a router bridge, or the
|
|
337
|
+
* code of an application. It is not what the target state declares — that is
|
|
338
|
+
* {@link RouteObject.data}, and a resolver there reads this field.
|
|
339
|
+
*/
|
|
340
|
+
readonly data?: RouteData;
|
|
234
341
|
readonly match?: unknown;
|
|
235
|
-
|
|
342
|
+
}
|
|
343
|
+
/**
|
|
344
|
+
* An optional capability: the routing support
|
|
345
|
+
*/
|
|
346
|
+
export interface Routable {
|
|
347
|
+
readonly currentRoute: Signal.Computed<string | null>;
|
|
348
|
+
readonly initialRoute: string | null;
|
|
236
349
|
}
|
|
237
350
|
/**
|
|
238
351
|
* The minimal actor interface that `RouterBridgeBase` and every framework router
|
|
239
352
|
* adapter require.
|
|
240
353
|
*
|
|
241
|
-
*
|
|
242
|
-
*
|
|
243
|
-
*
|
|
244
|
-
*
|
|
354
|
+
* It names `send` itself, and it therefore gives `RouterBridgeBase.actor.send` a type that
|
|
355
|
+
* accepts a `PlayRouteEvent` directly. That removes the unsafe cast
|
|
356
|
+
* `(actor.send as (e: PlayRouteEvent) => void)`.
|
|
357
|
+
*
|
|
358
|
+
* It is {@link Routable} with `send`. The two members of the capability are declared once,
|
|
359
|
+
* in `Routable`, and this interface extends it. A copy of them here drifts the day that
|
|
360
|
+
* one of the two files changes.
|
|
245
361
|
*
|
|
246
|
-
*
|
|
247
|
-
*
|
|
248
|
-
*
|
|
249
|
-
*
|
|
250
|
-
*
|
|
362
|
+
* **It names the view NOWHERE. Routing implies no rendering.** No file of this package,
|
|
363
|
+
* and no file of any of the eight router adapters, ever reads `currentView`. A provider
|
|
364
|
+
* whose renderer callback reads the view binds its own `TActor`, and a constraint keeps
|
|
365
|
+
* the concrete type of the actor whole, so that callback still reads the exact spec of
|
|
366
|
+
* that actor.
|
|
367
|
+
*
|
|
368
|
+
* Every `PlayActor` of `@xmachines/play-actor` that also implements `Routable`, and whose
|
|
369
|
+
* event union holds `PlayRouteEvent`, satisfies this interface structurally. A machine
|
|
370
|
+
* that declares no route event does NOT satisfy it, and that refusal is correct: a bridge
|
|
371
|
+
* cannot navigate an actor that receives no route event.
|
|
251
372
|
*
|
|
252
373
|
* @example
|
|
253
374
|
* ```typescript
|
|
@@ -260,49 +381,10 @@ export interface PlayRouteEvent {
|
|
|
260
381
|
* }
|
|
261
382
|
* ```
|
|
262
383
|
*/
|
|
263
|
-
export interface RoutableActor {
|
|
264
|
-
/** The TC39 Signal of the current URL path of the actor, or of its state ID. */
|
|
265
|
-
readonly currentRoute: Signal.Computed<string | null>;
|
|
266
|
-
/**
|
|
267
|
-
* The route of the initial state of the machine. The constructor fixes it.
|
|
268
|
-
* A router bridge compares it with the browser URL. It therefore separates a deep
|
|
269
|
-
* link, where the router wins, from a restore of a session, where the actor wins.
|
|
270
|
-
*/
|
|
271
|
-
readonly initialRoute: string | null;
|
|
384
|
+
export interface RoutableActor extends Routable {
|
|
272
385
|
/** Sends a route navigation event to the actor. */
|
|
273
386
|
send(event: PlayRouteEvent): void;
|
|
274
387
|
}
|
|
275
|
-
/**
|
|
276
|
-
* The complete actor shape of the `PlayRouterProvider` component of each framework
|
|
277
|
-
* adapter: `play-solid-router`, `play-vue-router`, `play-react-router`, and each
|
|
278
|
-
* adapter on the shared framework router bridge bases.
|
|
279
|
-
*
|
|
280
|
-
* The shape extends `RoutableActor` with `currentView`, because the provider renders
|
|
281
|
-
* the current view spec and also keeps the routes in step. It therefore needs both
|
|
282
|
-
* capabilities.
|
|
283
|
-
*
|
|
284
|
-
* - Use `RoutableActor` when you need the routing alone, for example in a
|
|
285
|
-
* `RouterBridgeBase` subclass, or in `connectRouter`.
|
|
286
|
-
* - Use `PlayActor` when the component also renders the current view spec, for
|
|
287
|
-
* example for the renderer callback parameter of `PlayRouterProvider`, and in
|
|
288
|
-
* `PlayRenderer`.
|
|
289
|
-
*
|
|
290
|
-
* Every `AbstractActor` subclass that implements both `Routable` and `Viewable`
|
|
291
|
-
* satisfies this interface structurally.
|
|
292
|
-
*
|
|
293
|
-
* @example
|
|
294
|
-
* ```typescript
|
|
295
|
-
* import type { PlayActor } from "@xmachines/play-router";
|
|
296
|
-
*
|
|
297
|
-
* function MyRouterProvider({ actor }: { actor: PlayActor }) {
|
|
298
|
-
* // it reads actor.currentRoute for the routing, and actor.currentView for the render
|
|
299
|
-
* }
|
|
300
|
-
* ```
|
|
301
|
-
*/
|
|
302
|
-
export interface PlayActor extends RoutableActor {
|
|
303
|
-
/** The TC39 Signal of the current view spec of the actor, or `null` when no view is active. */
|
|
304
|
-
readonly currentView: Signal.State<PlaySpec | null>;
|
|
305
|
-
}
|
|
306
388
|
/**
|
|
307
389
|
* The RouterBridge interface of a runtime infrastructure adapter
|
|
308
390
|
*
|
|
@@ -462,4 +544,21 @@ export interface LocationLike {
|
|
|
462
544
|
readonly pathname: string;
|
|
463
545
|
readonly search: string;
|
|
464
546
|
}
|
|
547
|
+
/**
|
|
548
|
+
* The options of `createRouteMap` and of `createRouteMapFromTree`.
|
|
549
|
+
*/
|
|
550
|
+
export interface RouteMapOptions {
|
|
551
|
+
/**
|
|
552
|
+
* The maximum number of the resolved parameterized path lookups in the cache.
|
|
553
|
+
*
|
|
554
|
+
* `RouteMap.getStateIdByPath()` resolves a parameterized pattern, for example
|
|
555
|
+
* `/profile/:userId`, with URLPattern on each call. The map keeps each path of a
|
|
556
|
+
* frequent visit in an LRU cache, and a later lookup of that path is therefore
|
|
557
|
+
* O(1).
|
|
558
|
+
*
|
|
559
|
+
* Raise this value for an application with a large set of parameterized routes, or
|
|
560
|
+
* with a high frequency of the navigation. The default is `500`.
|
|
561
|
+
*/
|
|
562
|
+
cacheSize?: number;
|
|
563
|
+
}
|
|
465
564
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,27 +1,13 @@
|
|
|
1
1
|
import type { AnyStateMachine } from "xstate";
|
|
2
|
-
import { RouteMap } from "
|
|
3
|
-
|
|
4
|
-
* The options of `createRouteMap` and of `createRouteMapFromTree`.
|
|
5
|
-
*/
|
|
6
|
-
export interface RouteMapOptions {
|
|
7
|
-
/**
|
|
8
|
-
* The maximum number of the resolved parameterized path lookups in the cache.
|
|
9
|
-
*
|
|
10
|
-
* `RouteMap.getStateIdByPath()` resolves a parameterized pattern, for example
|
|
11
|
-
* `/profile/:userId`, with URLPattern on each call. The map keeps each path of a
|
|
12
|
-
* frequent visit in an LRU cache, and a later lookup of that path is therefore
|
|
13
|
-
* O(1).
|
|
14
|
-
*
|
|
15
|
-
* Raise this value for an application with a large set of parameterized routes, or
|
|
16
|
-
* with a high frequency of the navigation. The default is `500`.
|
|
17
|
-
*/
|
|
18
|
-
cacheSize?: number;
|
|
19
|
-
}
|
|
2
|
+
import { RouteMap } from "../base-route-map.js";
|
|
3
|
+
import type { RouteMapOptions } from "../types.js";
|
|
20
4
|
/**
|
|
21
5
|
* Creates a `RouteMap` from an XState state machine.
|
|
22
6
|
*
|
|
23
7
|
* The function reads every state with a route, which means each state with a
|
|
24
|
-
* `meta.route` field. It
|
|
8
|
+
* `meta.route` field. It keeps the routable states alone, and it drops the synthetic
|
|
9
|
+
* root of the tree. `createRouteMapFromTree` of the main entry point drops the same
|
|
10
|
+
* node, and the two functions therefore answer the same map for the same machine. It then builds the lookup structure between a path and a
|
|
25
11
|
* stateId, for both directions. A subclass of `RouterBridgeBase` uses the map: it
|
|
26
12
|
* converts each change of the browser URL into a `play.route` actor event, and each
|
|
27
13
|
* actor route into a URL.
|
|
@@ -33,7 +19,7 @@ export interface RouteMapOptions {
|
|
|
33
19
|
*
|
|
34
20
|
* @example
|
|
35
21
|
* ```typescript
|
|
36
|
-
* import { createRouteMap } from '@xmachines/play-router';
|
|
22
|
+
* import { createRouteMap } from '@xmachines/play-router/xstate';
|
|
37
23
|
* import { connectRouter } from '@xmachines/play-dom-router';
|
|
38
24
|
*
|
|
39
25
|
* const routeMap = createRouteMap(myMachine);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-route-map.d.ts","sourceRoot":"","sources":["../../src/xstate/create-route-map.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,QAAQ,CAAC;AAG9C,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,eAAe,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,QAAQ,CAU5F"}
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { extractMachineRoutes } from "./extract-routes.js";
|
|
2
2
|
import { getRoutableRoutes } from "./query.js";
|
|
3
|
-
import { RouteMap } from "
|
|
3
|
+
import { RouteMap } from "../base-route-map.js";
|
|
4
4
|
/**
|
|
5
5
|
* Creates a `RouteMap` from an XState state machine.
|
|
6
6
|
*
|
|
7
7
|
* The function reads every state with a route, which means each state with a
|
|
8
|
-
* `meta.route` field. It
|
|
8
|
+
* `meta.route` field. It keeps the routable states alone, and it drops the synthetic
|
|
9
|
+
* root of the tree. `createRouteMapFromTree` of the main entry point drops the same
|
|
10
|
+
* node, and the two functions therefore answer the same map for the same machine. It then builds the lookup structure between a path and a
|
|
9
11
|
* stateId, for both directions. A subclass of `RouterBridgeBase` uses the map: it
|
|
10
12
|
* converts each change of the browser URL into a `play.route` actor event, and each
|
|
11
13
|
* actor route into a URL.
|
|
@@ -17,7 +19,7 @@ import { RouteMap } from "./base-route-map.js";
|
|
|
17
19
|
*
|
|
18
20
|
* @example
|
|
19
21
|
* ```typescript
|
|
20
|
-
* import { createRouteMap } from '@xmachines/play-router';
|
|
22
|
+
* import { createRouteMap } from '@xmachines/play-router/xstate';
|
|
21
23
|
* import { connectRouter } from '@xmachines/play-dom-router';
|
|
22
24
|
*
|
|
23
25
|
* const routeMap = createRouteMap(myMachine);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-route-map.js","sourceRoot":"","sources":["../../src/xstate/create-route-map.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAGhD;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,UAAU,cAAc,CAAC,OAAwB,EAAE,OAAyB;IACjF,MAAM,SAAS,GAAG,oBAAoB,CAAC,OAAO,CAAC,CAAC;IAChD,MAAM,MAAM,GAAG,iBAAiB,CAAC,SAAS,CAAC,CAAC;IAC5C,OAAO,IAAI,QAAQ,CAClB,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACrB,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,IAAI,EAAE,IAAI,CAAC,QAAQ;KACnB,CAAC,CAAC,EACH,OAAO,CACP,CAAC;AACH,CAAC"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { AnyStateMachine } from "xstate";
|
|
2
|
-
import type { RouteTree } from "
|
|
2
|
+
import type { RouteTree } from "../types.js";
|
|
3
|
+
import { type MachineGraph } from "./machine-to-graph.js";
|
|
3
4
|
/**
|
|
4
5
|
* Reads the complete route tree from the graph of a state machine
|
|
5
6
|
*
|
|
@@ -12,5 +13,5 @@ import type { RouteTree } from "./types.js";
|
|
|
12
13
|
* @param machine - The XState v5 state machine
|
|
13
14
|
* @returns The route tree, with its root, its byStateId map, its byPath map, and its graph
|
|
14
15
|
*/
|
|
15
|
-
export declare const extractMachineRoutes: (machine: AnyStateMachine) => RouteTree
|
|
16
|
+
export declare const extractMachineRoutes: (machine: AnyStateMachine) => RouteTree<MachineGraph>;
|
|
16
17
|
//# sourceMappingURL=extract-routes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extract-routes.d.ts","sourceRoot":"","sources":["../../src/xstate/extract-routes.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,QAAQ,CAAC;AAE9C,OAAO,KAAK,EAAE,SAAS,EAA4B,MAAM,aAAa,CAAC;AAEvE,OAAO,EAAkB,KAAK,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAgF1E;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,oBAAoB,GAAI,SAAS,eAAe,KAAG,SAAS,CAAC,YAAY,CAoBrF,CAAC"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import { isParameterizedPattern } from "@xmachines/play-url";
|
|
1
2
|
import { machineToGraph } from "./machine-to-graph.js";
|
|
2
|
-
import { validateRouteFormat, validateStateExists } from "
|
|
3
|
-
import { buildRouteTree } from "
|
|
3
|
+
import { validateRouteFormat, validateStateExists } from "../validate-routes.js";
|
|
4
|
+
import { buildRouteTree } from "../build-tree.js";
|
|
4
5
|
/**
|
|
5
6
|
* Builds the statePath of a graph node, and it walks the chain of the parentId
|
|
6
7
|
* values.
|
|
@@ -37,7 +38,11 @@ const extractRouteFromNode = (graphNode, stateIds, graphNodeMap) => {
|
|
|
37
38
|
validateStateExists(stateId, stateIds);
|
|
38
39
|
// Build the statePath from the chain of the parentId values. This works for an explicit ID and also for a generated one
|
|
39
40
|
const statePath = buildStatePath(graphNode, graphNodeMap);
|
|
40
|
-
|
|
41
|
+
// The parse answers this, and not a search for a ":". `route.includes(":")` was the
|
|
42
|
+
// last expression that read the grammar on its own: it reported no pattern for
|
|
43
|
+
// `/docs/*`, for `/books{/:id}?` and for an escaped literal, so a consumer that reads
|
|
44
|
+
// `node.pattern` learned that a parameterized route is a literal path.
|
|
45
|
+
const pattern = isParameterizedPattern(route) ? route : undefined;
|
|
41
46
|
// Build the original shape of the metadata again, from the data of the graph
|
|
42
47
|
const metadata = meta && typeof meta === "object" && "route" in meta
|
|
43
48
|
? meta["route"]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extract-routes.js","sourceRoot":"","sources":["../../src/xstate/extract-routes.ts"],"names":[],"mappings":"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"}
|