@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.
Files changed (83) hide show
  1. package/README.md +103 -109
  2. package/dist/base-route-map.d.ts +7 -1
  3. package/dist/base-route-map.d.ts.map +1 -1
  4. package/dist/base-route-map.js +25 -12
  5. package/dist/base-route-map.js.map +1 -1
  6. package/dist/build-tree.d.ts +16 -1
  7. package/dist/build-tree.d.ts.map +1 -1
  8. package/dist/build-tree.js +23 -6
  9. package/dist/build-tree.js.map +1 -1
  10. package/dist/create-route-map-from-tree.d.ts +12 -6
  11. package/dist/create-route-map-from-tree.d.ts.map +1 -1
  12. package/dist/create-route-map-from-tree.js +13 -5
  13. package/dist/create-route-map-from-tree.js.map +1 -1
  14. package/dist/errors.d.ts +2 -134
  15. package/dist/errors.d.ts.map +1 -1
  16. package/dist/errors.js +11 -151
  17. package/dist/errors.js.map +1 -1
  18. package/dist/find-route.d.ts.map +1 -1
  19. package/dist/find-route.js +14 -19
  20. package/dist/find-route.js.map +1 -1
  21. package/dist/index.d.ts +7 -16
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/index.js +10 -11
  24. package/dist/index.js.map +1 -1
  25. package/dist/provider-lifecycle.d.ts +28 -6
  26. package/dist/provider-lifecycle.d.ts.map +1 -1
  27. package/dist/provider-lifecycle.js +16 -2
  28. package/dist/provider-lifecycle.js.map +1 -1
  29. package/dist/router-bridge-base.d.ts +42 -23
  30. package/dist/router-bridge-base.d.ts.map +1 -1
  31. package/dist/router-bridge-base.js +257 -84
  32. package/dist/router-bridge-base.js.map +1 -1
  33. package/dist/router-sync.d.ts +1 -1
  34. package/dist/router-sync.d.ts.map +1 -1
  35. package/dist/router-sync.js +28 -13
  36. package/dist/router-sync.js.map +1 -1
  37. package/dist/types.d.ts +186 -87
  38. package/dist/types.d.ts.map +1 -1
  39. package/dist/{create-route-map.d.ts → xstate/create-route-map.d.ts} +6 -20
  40. package/dist/xstate/create-route-map.d.ts.map +1 -0
  41. package/dist/{create-route-map.js → xstate/create-route-map.js} +5 -3
  42. package/dist/xstate/create-route-map.js.map +1 -0
  43. package/dist/{extract-routes.d.ts → xstate/extract-routes.d.ts} +3 -2
  44. package/dist/xstate/extract-routes.d.ts.map +1 -0
  45. package/dist/{extract-routes.js → xstate/extract-routes.js} +8 -3
  46. package/dist/xstate/extract-routes.js.map +1 -0
  47. package/dist/xstate/index.d.ts +35 -0
  48. package/dist/xstate/index.d.ts.map +1 -0
  49. package/dist/xstate/index.js +33 -0
  50. package/dist/xstate/index.js.map +1 -0
  51. package/dist/{machine-to-graph.d.ts → xstate/machine-to-graph.d.ts} +1 -1
  52. package/dist/xstate/machine-to-graph.d.ts.map +1 -0
  53. package/dist/{machine-to-graph.js → xstate/machine-to-graph.js} +2 -2
  54. package/dist/xstate/machine-to-graph.js.map +1 -0
  55. package/dist/xstate/machine-types.d.ts +42 -0
  56. package/dist/xstate/machine-types.d.ts.map +1 -0
  57. package/dist/xstate/machine-types.js +2 -0
  58. package/dist/xstate/machine-types.js.map +1 -0
  59. package/dist/{query.d.ts → xstate/query.d.ts} +6 -4
  60. package/dist/xstate/query.d.ts.map +1 -0
  61. package/dist/{query.js → xstate/query.js} +3 -2
  62. package/dist/xstate/query.js.map +1 -0
  63. package/package.json +26 -20
  64. package/dist/base-path.d.ts +0 -209
  65. package/dist/base-path.d.ts.map +0 -1
  66. package/dist/base-path.js +0 -418
  67. package/dist/base-path.js.map +0 -1
  68. package/dist/create-route-map.d.ts.map +0 -1
  69. package/dist/create-route-map.js.map +0 -1
  70. package/dist/extract-routes.d.ts.map +0 -1
  71. package/dist/extract-routes.js.map +0 -1
  72. package/dist/framework-params.d.ts +0 -144
  73. package/dist/framework-params.d.ts.map +0 -1
  74. package/dist/framework-params.js +0 -291
  75. package/dist/framework-params.js.map +0 -1
  76. package/dist/machine-to-graph.d.ts.map +0 -1
  77. package/dist/machine-to-graph.js.map +0 -1
  78. package/dist/query.d.ts.map +0 -1
  79. package/dist/query.js.map +0 -1
  80. package/dist/url-pattern-utils.d.ts +0 -93
  81. package/dist/url-pattern-utils.d.ts.map +0 -1
  82. package/dist/url-pattern-utils.js +0 -233
  83. package/dist/url-pattern-utils.js.map +0 -1
package/dist/base-path.js DELETED
@@ -1,418 +0,0 @@
1
- /**
2
- * The base-path support — it mounts the routes of a machine under a URL prefix.
3
- *
4
- * A host application often owns a part of its own URL space, and it wants a machine
5
- * to own the rest of that space, inside the SAME router. A URL such as
6
- * `/:machineId/play/dashboard` has two halves: `/:machineId/play` belongs to the
7
- * host, which resolves `:machineId` in a loader, and `/dashboard` belongs to the
8
- * `meta.route` tree of the machine.
9
- *
10
- * This module is the boundary between those two halves:
11
- * - {@link resolveBasePath} makes the concrete prefix that the browser URL carries,
12
- * from a base-path pattern and its params.
13
- * - {@link stripBasePath} removes that prefix from an inbound location of the router,
14
- * and it reports a location OUTSIDE the prefix as foreign, so that the bridge stays
15
- * out of it.
16
- * - {@link joinBasePath} adds the prefix again to an outbound path of the machine.
17
- *
18
- * The prefix lives on the BRIDGE, and not on the `RouteMap`. A route map is static,
19
- * it is shared, and it holds an LRU cache inside, while a mount point is dynamic. One
20
- * route map therefore serves every `machineId` without a rebuild.
21
- *
22
- * @internal The package exports these primitives for an adapter and for a host, but
23
- * a consumer normally uses the `basePath` option of a bridge instead.
24
- */
25
- import { InvalidBasePathError, MissingBasePathParamError } from "./errors.js";
26
- /**
27
- * The base path of a bridge that has no `basePath` option.
28
- *
29
- * The object is FROZEN, and both levels of it: {@link resolveBasePath} returns this
30
- * exact instance for every bridge with no mount, and
31
- * `RouterBridgeBase.basePathParams` hands its `params` to the caller.
32
- * `Readonly<Record<string, string>>` is gone at run time, so without the freeze one
33
- * write in consumer code would leak that key into every other unmounted bridge in
34
- * the process.
35
- */
36
- export const NO_BASE_PATH = Object.freeze({
37
- path: "",
38
- params: Object.freeze({}),
39
- });
40
- /**
41
- * Normalizes a base path, and it substitutes no `:param` segment of that path.
42
- *
43
- * Use this function when you want the form of the pattern, for example to declare
44
- * the routes of a machine in a route config of a host that substitutes each param
45
- * itself. {@link resolveBasePath} gives the form that a bridge needs.
46
- *
47
- * @param basePath - The prefix, as a pattern or as a concrete path. An absent value,
48
- * `""`, and `"/"` all give `""`.
49
- * @returns The normalized prefix. It starts with `/`, and it carries no trailing `/`.
50
- * @throws {InvalidBasePathError} For a wildcard segment, for an optional `:param?`
51
- * segment, for a `$param` segment, for a query string or a hash fragment, for a URL
52
- * scheme, for a dot segment (`.`, `..`, and their percent-encoded forms), and for any
53
- * segment that a browser rewrites — one that holds whitespace, a backslash, or a
54
- * character that a URL percent-encodes.
55
- *
56
- * @example
57
- * ```typescript
58
- * normalizeBasePath("/:machineId/play/"); // "/:machineId/play"
59
- * normalizeBasePath("admin"); // "/admin"
60
- * normalizeBasePath("/"); // ""
61
- * ```
62
- */
63
- export function normalizeBasePath(basePath) {
64
- if (basePath === undefined || basePath === null || basePath === "")
65
- return "";
66
- // A base path is a PATHNAME, so refuse a whole URL before the slash collapse hides
67
- // the mistake. "https://host/admin" collapses to "/https:/host/admin", whose every
68
- // segment passes the segment guards below. The bridge would take that mount, then
69
- // strip no real router location under it: the machine would go permanently silent,
70
- // exactly as it does for a query or a hash.
71
- assertNoScheme(basePath);
72
- // Collapse each duplicate slash, add the leading slash, and drop the trailing one.
73
- // The result therefore concatenates cleanly with a machine path, which always
74
- // starts with "/", and it compares cleanly with a sanitized router location, which
75
- // sanitizePathname() has already collapsed.
76
- const collapsed = `/${basePath}`.replace(/\/+/g, "/").replace(/\/$/, "");
77
- if (collapsed === "")
78
- return "";
79
- for (const segment of collapsed.slice(1).split("/")) {
80
- assertBasePathSegment(segment, basePath);
81
- }
82
- return collapsed;
83
- }
84
- /**
85
- * Resolves a base path and its params to the concrete prefix that a browser URL
86
- * carries.
87
- *
88
- * A bridge calls this function one time, and again on each `setBasePath()` call. The
89
- * result is always concrete. {@link stripBasePath} therefore compares a literal
90
- * prefix, and no URLPattern match runs on the hot path of a navigation.
91
- *
92
- * @param basePath - The prefix, as a pattern or as a concrete path.
93
- * @param params - The values of the `:param` segments of `basePath`.
94
- * @returns The concrete prefix, and the values of each param for a `play.route` event.
95
- * @throws {InvalidBasePathError} For a wildcard segment, for an optional `:param?`
96
- * segment, for a `$param` segment, for a query string or a hash fragment, for a URL
97
- * scheme, for a dot segment (`.`, `..`, and their percent-encoded forms), and for any
98
- * segment that a browser rewrites — one that holds whitespace, a backslash, or a
99
- * character that a URL percent-encodes.
100
- * @throws {MissingBasePathParamError} When a `:param` of the prefix has no value.
101
- *
102
- * @example
103
- * ```typescript
104
- * resolveBasePath("/:machineId/play", { machineId: "abc123" });
105
- * // → { path: "/abc123/play", params: { machineId: "abc123" } }
106
- *
107
- * resolveBasePath("/admin");
108
- * // → { path: "/admin", params: {} }
109
- * ```
110
- */
111
- export function resolveBasePath(basePath, params) {
112
- const normalized = normalizeBasePath(basePath);
113
- if (normalized === "")
114
- return NO_BASE_PATH;
115
- if (!normalized.includes(":")) {
116
- return Object.freeze({
117
- path: normalized,
118
- params: Object.freeze({}),
119
- });
120
- }
121
- // A null prototype, for both directions of the lookup. A plain `{}` accumulator
122
- // turns `resolvedParams["__proto__"] = value` into a write of the PROTOTYPE, so a
123
- // param of that name would vanish from the result.
124
- const resolvedParams = Object.create(null);
125
- const segments = normalized
126
- .slice(1)
127
- .split("/")
128
- .map((segment) => {
129
- if (!segment.startsWith(":"))
130
- return segment;
131
- const name = segment.slice(1);
132
- // `Object.hasOwn`, and not a bare read: `params[name]` walks the prototype
133
- // chain, so ":constructor" with no value of its own found
134
- // `Object.prototype.constructor` and resolved the prefix to the source text of
135
- // a function. `stripBasePath` then read EVERY location as foreign, and the
136
- // machine went silent for ever instead of failing loudly here.
137
- const value = params !== undefined && Object.hasOwn(params, name)
138
- ? params[name] // nosemgrep: gitlab.eslint.detect-object-injection
139
- : undefined;
140
- if (value === undefined || value === null || value === "") {
141
- throw new MissingBasePathParamError(name, basePath ?? "");
142
- }
143
- const text = String(value);
144
- const encoded = encodeBasePathValue(text);
145
- // The guards of `assertBasePathSegment` run on the PATTERN, before this
146
- // substitution, so they see ":id" and never the value that replaces it. A value
147
- // of "." or ".." therefore passed every one of them and resolved away in the
148
- // browser: "/m/../play" comes back as "/play", `stripBasePath` reads every
149
- // location as foreign, and the machine goes permanently silent with no error —
150
- // the exact failure the dot-segment guard exists to prevent. Test the RESOLVED
151
- // segment here.
152
- if (!isStableSegment(encoded)) {
153
- throw new InvalidBasePathError(basePath ?? "", `the value "${text}" of ":${name}" resolves to the segment "${encoded}", which a browser rewrites, so the prefix that comes back is not the prefix that went out.`);
154
- }
155
- resolvedParams[name] = text; // nosemgrep: gitlab.eslint.detect-object-injection
156
- return encoded;
157
- });
158
- // FROZEN, both levels, for the same reason NO_BASE_PATH is: `RouterBridgeBase`
159
- // returns `this.mount.params` BY REFERENCE from its accessor, and
160
- // `Readonly<Record<string, string>>` is gone at run time. One write in consumer code
161
- // would change what the bridge reports for the rest of its life, while `basePath`
162
- // still holds the real prefix — the staleness the accessor promises cannot happen.
163
- // Spread, and not the null-prototype record itself: a spread creates OWN properties,
164
- // so a param named "__proto__" stays a key AND the value keeps a normal prototype.
165
- // Handing the bare record out made `bridge.basePathParams.hasOwnProperty(…)` throw,
166
- // on a value the docs describe as a `Readonly<Record<string, string>>`.
167
- return Object.freeze({
168
- path: `/${segments.join("/")}`,
169
- params: Object.freeze({ ...resolvedParams }),
170
- });
171
- }
172
- /**
173
- * Removes the base path from an inbound location of the router.
174
- *
175
- * The return value separates the two cases that make a shared router work:
176
- * - A string is the MACHINE half of the location, for example `"/dashboard"` of
177
- * `"/abc123/play/dashboard"`. The bridge matches it against the route map.
178
- * - `null` means that the location is FOREIGN: it lies outside the mount, so it
179
- * belongs to the host. The bridge sends no `play.route` event, AND it runs no
180
- * corrective navigation. A correction here would drag the user off a page of the
181
- * host.
182
- *
183
- * The match is exact, and it respects each segment boundary. `"/abc/playground"` is
184
- * therefore foreign to the mount `"/abc/play"`.
185
- *
186
- * @param pathname - A sanitized pathname of the router, with no query and no duplicate slash.
187
- * @param basePath - The concrete prefix of {@link resolveBasePath}. `""` removes nothing.
188
- * @returns The machine half of the path, or `null` when the location is foreign.
189
- *
190
- * @example
191
- * ```typescript
192
- * stripBasePath("/abc123/play/dashboard", "/abc123/play"); // "/dashboard"
193
- * stripBasePath("/abc123/play", "/abc123/play"); // "/"
194
- * stripBasePath("/settings", "/abc123/play"); // null — the host owns it
195
- * ```
196
- */
197
- export function stripBasePath(pathname, basePath) {
198
- if (basePath === "")
199
- return pathname;
200
- if (pathname === basePath)
201
- return "/";
202
- if (pathname.startsWith(`${basePath}/`))
203
- return pathname.slice(basePath.length);
204
- return null;
205
- }
206
- /**
207
- * Adds the base path to an outbound path of the machine.
208
- *
209
- * The function joins the PATHNAME only. A query string and a hash fragment of the
210
- * path of the machine stay at the end, because the prefix belongs in front of the
211
- * path.
212
- *
213
- * @param basePath - The concrete prefix of {@link resolveBasePath}. `""` adds nothing.
214
- * @param path - The path of the machine, for example `"/dashboard"` or `"/dates?trip=one-way"`.
215
- * @returns The location for the router of the host.
216
- *
217
- * @example
218
- * ```typescript
219
- * joinBasePath("/abc123/play", "/dashboard"); // "/abc123/play/dashboard"
220
- * joinBasePath("/abc123/play", "/"); // "/abc123/play"
221
- * joinBasePath("/abc123/play", "/x?tab=a"); // "/abc123/play/x?tab=a"
222
- * joinBasePath("", "/dashboard"); // "/dashboard"
223
- * ```
224
- */
225
- export function joinBasePath(basePath, path) {
226
- if (basePath === "")
227
- return path;
228
- const mark = firstMarkIndex(path);
229
- const pathname = mark === -1 ? path : path.slice(0, mark);
230
- const suffix = mark === -1 ? "" : path.slice(mark);
231
- // The root of the machine IS the mount point: "/" must not append a trailing slash,
232
- // because the router callback reports "/abc123/play" and a mismatch there would
233
- // defeat the echo suppression of the bridge.
234
- const joined = pathname === "" || pathname === "/"
235
- ? basePath
236
- : `${basePath}${pathname.startsWith("/") ? "" : "/"}${pathname}`;
237
- return `${joined}${suffix}`;
238
- }
239
- /**
240
- * Gives the index of the first query mark or fragment mark of a path, or `-1`.
241
- *
242
- * The names say `At`, because both values are an INDEX. A name such as `hash` reads
243
- * as a digest to a reader and to a scanner both: `gitlab.eslint.detect-possible-timing-attacks`
244
- * fires on a `===` test against an identifier of that name, and it cannot see that
245
- * the operands here are two numbers.
246
- *
247
- * @internal `RouterBridgeBase` splits a location on the same boundary, to read the
248
- * pathname half of an actor route. One function, so the two sides cannot disagree
249
- * about where a pathname ends.
250
- */
251
- export function firstMarkIndex(path) {
252
- const queryAt = path.indexOf("?");
253
- const fragmentAt = path.indexOf("#");
254
- if (queryAt === -1)
255
- return fragmentAt;
256
- if (fragmentAt === -1)
257
- return queryAt;
258
- return Math.min(queryAt, fragmentAt);
259
- }
260
- /**
261
- * Refuses each segment of a base path that resolves to ONE concrete prefix never.
262
- *
263
- * A bridge writes a real browser URL from its prefix. A wildcard and an optional
264
- * segment each describe a SET of prefixes, so neither of them holds a value to write,
265
- * and a silent pass would put a literal `*` or `:section?` into the address bar.
266
- */
267
- function assertBasePathSegment(segment, basePath) {
268
- if (segment.includes("*")) {
269
- throw new InvalidBasePathError(basePath, 'a wildcard segment cannot resolve to one concrete prefix. Drop the splat segment: mount on the prefix itself, for example "/:machineId/play" for the route "/$machineId/play/$".');
270
- }
271
- if (segment.startsWith("$")) {
272
- throw new InvalidBasePathError(basePath, `"${segment}" looks like a route param of TanStack Router. A base path declares a param as ":${segment.slice(1)}", and its value goes in basePathParams.`);
273
- }
274
- if (segment.startsWith(":") && segment.endsWith("?")) {
275
- throw new InvalidBasePathError(basePath, `the optional segment "${segment}" cannot resolve to one concrete prefix. Give a required ":${segment.slice(1, -1)}" param, or mount on the shorter prefix.`);
276
- }
277
- if (segment === ":") {
278
- throw new InvalidBasePathError(basePath, "a param segment needs a name.");
279
- }
280
- // A browser resolves "." and ".." out of a location, so the prefix that
281
- // `navigateRouter` writes is not the prefix that comes back: "/../admin/about"
282
- // becomes "/admin/about", which no longer starts with the mount. Every later location
283
- // would read as foreign and the machine would go permanently silent.
284
- //
285
- // The PERCENT-ENCODED forms resolve away exactly the same. The WHATWG URL standard
286
- // reads "%2e" as a single-dot segment and ".%2e", "%2e." and "%2e%2e" as double-dot
287
- // segments, each test case-insensitive, so "/a/%2e%2e/admin" also comes back as
288
- // "/admin". A guard on the two literal forms alone let that mount through.
289
- if (isDotSegment(segment)) {
290
- throw new InvalidBasePathError(basePath, `the segment "${segment}" resolves away in a browser, so the prefix that comes back is not the prefix that went out. Give the path that it resolves to.`);
291
- }
292
- // A browser percent-encodes a space, a tab and a newline of a pathname, so the prefix
293
- // that comes back is not the prefix that went out — the same failure as a dot segment,
294
- // and the same silence. `assertNoScheme` also reads the RAW value, and a leading space
295
- // hid a whole URL from it: " https://host/admin" collapsed to "/ https:/host/admin".
296
- if (/\s/.test(segment)) {
297
- throw new InvalidBasePathError(basePath, `the segment "${segment}" holds whitespace, which a browser percent-encodes, so the prefix that comes back is not the prefix that went out. Give the path with no whitespace in it.`);
298
- }
299
- // A base path is a PATHNAME. A query or a hash in it would survive normalization,
300
- // then never match a router location — `sanitizePathname` has already removed both
301
- // by the time `stripBasePath` compares — so every location would read as foreign
302
- // and the machine would go permanently silent. Refuse it here instead.
303
- if (segment.includes("?") || segment.includes("#")) {
304
- throw new InvalidBasePathError(basePath, "a base path is a pathname only: it can carry no query string and no hash fragment. Put a query on the machine's own route instead.");
305
- }
306
- // The general form of the three guards above, and the one that catches the rest. A
307
- // browser reads a "\" as a "/", so "/adm\in" arrives as two segments and "/a\..\x"
308
- // arrives as "/x"; it percent-encodes a non-ASCII character and the characters '"',
309
- // '<', '>', '{', '}', '^' and '`', so "/café" arrives as "/caf%C3%A9". Each one gives
310
- // the same silence as a dot segment: no location matches the mount, and no error says
311
- // so. The guards above stay, because each one names the mistake it found.
312
- if (!isStableSegment(segment)) {
313
- throw new InvalidBasePathError(basePath, `a browser rewrites the segment "${segment}", so the prefix that comes back is not the prefix that went out. Give the segment in the form that a URL carries, for example "caf%C3%A9" for "café".`);
314
- }
315
- }
316
- /** The origin of the probe of {@link isStableSegment}. It reaches no network. */
317
- const PROBE_ORIGIN = "http://probe.invalid";
318
- /**
319
- * Tells you whether a browser writes a path segment back exactly as it went out.
320
- *
321
- * The WHATWG URL parser rewrites a segment in several ways: it resolves "." and ".."
322
- * away, it reads a "\" as a "/", and it percent-encodes whitespace, a non-ASCII
323
- * character, and the characters '"', '<', '>', '{', '}', '^' and '`'. Every one of them
324
- * gives one failure: the prefix that `navigateRouter` writes is not the prefix that
325
- * comes back, so `stripBasePath` reads every location as foreign and the machine goes
326
- * permanently silent, with no error raised.
327
- *
328
- * The function asks the URL parser, and it lists no character, because that list
329
- * belongs to the standard and not to this file.
330
- */
331
- function isStableSegment(segment) {
332
- try {
333
- return new URL(`/${segment}`, PROBE_ORIGIN).pathname === `/${segment}`;
334
- }
335
- catch {
336
- return false;
337
- }
338
- }
339
- /**
340
- * Tells you whether a segment is a single-dot or a double-dot path segment.
341
- *
342
- * The WHATWG URL standard names six forms, and a browser resolves every one of them out
343
- * of a location: "." and "%2e" for the single dot, and "..", ".%2e", "%2e." and "%2e%2e"
344
- * for the double dot. Each percent test is case-insensitive.
345
- */
346
- function isDotSegment(segment) {
347
- const decoded = segment.toLowerCase().replaceAll("%2e", ".");
348
- return decoded === "." || decoded === "..";
349
- }
350
- /**
351
- * Refuses a base path that carries a URL scheme.
352
- *
353
- * The test runs on the RAW value, because the slash collapse of
354
- * {@link normalizeBasePath} turns the form into a path that looks legal. It also runs
355
- * on the TRIMMED value, because a browser drops the leading whitespace of a URL: a
356
- * scheme behind a space is still a scheme. And it runs at every segment boundary,
357
- * because a scheme that a caller joined behind a prefix of its own is still a scheme.
358
- *
359
- * A protocol-relative `//host/path` is NOT refused: it is indistinguishable from a
360
- * sloppy `//a//b`, which the collapse deliberately forgives.
361
- *
362
- * @throws {InvalidBasePathError} For `scheme://host/path`.
363
- */
364
- function assertNoScheme(basePath) {
365
- // RFC 3986: a scheme starts with a letter, then holds letters, digits, "+", "-"
366
- // and ".". A leading "//" with no scheme is the protocol-relative form.
367
- // The test runs at EVERY segment boundary, and not at the start alone. A caller that
368
- // joins a prefix onto a base writes "/https://app.example.com/admin", and also
369
- // "/tenant/https://app.example.com/admin": the collapse then makes
370
- // "/tenant/https:/app.example.com/admin", whose every segment is legal, so the bridge
371
- // mounts where no real location starts and the machine goes permanently silent. A
372
- // guard that stripped the LEADING slashes alone caught the first form and missed the
373
- // second.
374
- if (/(?:^|\/)[a-zA-Z][a-zA-Z\d+\-.]*:\/\//.test(basePath.trim())) {
375
- throw new InvalidBasePathError(basePath, 'a base path is a pathname only: it can carry no scheme and no host. Give the path part alone, for example "/admin" for "https://app.example.com/admin".');
376
- }
377
- }
378
- /**
379
- * Escapes the value of a base-path param for a URL segment.
380
- *
381
- * `encodeURIComponent` leaves a `*` alone, and that is correct here: a `*` is a legal
382
- * path character, and a browser reports it literally. An escape to `%2A` resolved a
383
- * mount that no real location matches, so `stripBasePath` read every location as
384
- * foreign and the machine went permanently silent, with no error raised.
385
- *
386
- * The `*` of "a pattern of no navigation" never reaches this value.
387
- * `resolveNavigationPath` tests the MACHINE half of the route, and `joinBasePath` adds
388
- * the prefix after that test — see the one `navigateRouter` call in
389
- * `pushResolvedRoute`.
390
- */
391
- function encodeBasePathValue(value) {
392
- // `encodeURIComponent` encodes for a QUERY component, so it escapes eight characters
393
- // that RFC 3986 lets a path segment hold raw: the sub-delims "$&+,;=" and ":" and
394
- // "@". Every router reports those raw in a pathname, so an escape resolves a mount
395
- // that no real location matches — `stripBasePath` reads every location as foreign and
396
- // the machine goes permanently silent, with no error raised.
397
- //
398
- // Escape for a segment instead: put those characters back, and keep the escape of
399
- // everything that would change the SHAPE of the path — "/", "?", "#" and "%" among
400
- // them — because a value must forge no path and no query.
401
- return encodeURIComponent(value).replace(/%(?:24|26|2B|2C|3A|3B|3D|40)/g, (escaped) => PATH_SEGMENT_SAFE.get(escaped) ?? escaped);
402
- }
403
- /**
404
- * The escapes that {@link encodeBasePathValue} undoes: the characters a path segment
405
- * holds raw, which `encodeURIComponent` escapes because it encodes for a query.
406
- */
407
- /** A Map, and not an object: a dynamic key reaches no prototype through one. */
408
- const PATH_SEGMENT_SAFE = new Map([
409
- ["%24", "$"],
410
- ["%26", "&"],
411
- ["%2B", "+"],
412
- ["%2C", ","],
413
- ["%3A", ":"],
414
- ["%3B", ";"],
415
- ["%3D", "="],
416
- ["%40", "@"],
417
- ]);
418
- //# sourceMappingURL=base-path.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"base-path.js","sourceRoot":"","sources":["../src/base-path.ts"],"names":[],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"create-route-map.d.ts","sourceRoot":"","sources":["../src/create-route-map.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,QAAQ,CAAC;AAG9C,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAE/C;;GAEG;AACH,MAAM,WAAW,eAAe;IAC/B;;;;;;;;;;OAUG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,eAAe,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,QAAQ,CAU5F"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"create-route-map.js","sourceRoot":"","sources":["../src/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,qBAAqB,CAAC;AAoB/C;;;;;;;;;;;;;;;;;;;;;;GAsBG;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 +0,0 @@
1
- {"version":3,"file":"extract-routes.d.ts","sourceRoot":"","sources":["../src/extract-routes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,QAAQ,CAAC;AAE9C,OAAO,KAAK,EAAE,SAAS,EAA6C,MAAM,YAAY,CAAC;AA6EvF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,oBAAoB,GAAI,SAAS,eAAe,KAAG,SAoB/D,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"extract-routes.js","sourceRoot":"","sources":["../src/extract-routes.ts"],"names":[],"mappings":"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"}
@@ -1,144 +0,0 @@
1
- /**
2
- * The params of a framework router, reconciled with the pattern of the machine.
3
- *
4
- * A framework that parses the params itself — Vue Router and SolidJS Router both do —
5
- * lets a bridge keep that parse instead of running URLPattern again. The decision that
6
- * makes it safe is the same in each of them, and the source of the params is the one
7
- * thing that differs, so the decision lives here and each bridge supplies its source.
8
- *
9
- * @see [Multi-router integration](../../docs/examples/multi-router-integration.md)
10
- */
11
- /**
12
- * Reads the names of every `:param` of a route pattern of the route map.
13
- *
14
- * @param pattern - A route pattern, for example `/profile/:userId`.
15
- * @returns The names, in the order that the pattern declares them. A fresh array, because
16
- * `readPatternParams` caches the one it holds.
17
- */
18
- export declare function getPatternParamNames(pattern: string): string[];
19
- /**
20
- * The names of every param the pattern REQUIRES, so `:name?` is left out.
21
- *
22
- * An optional segment that did not match has no value, and a framework reports none.
23
- * That is a complete answer and not a partial one, so a MIXED pattern such as
24
- * `/profile/:userId/:tab?` keeps the parse of the framework when only `:tab` is absent.
25
- * A caller that counted that absence as a gap would fall back to the URLPattern
26
- * extraction, which THROWS on a runtime with no URLPattern — for a route the framework
27
- * had already answered.
28
- *
29
- * A pattern whose params are ALL optional reports nothing at all, which reads the same
30
- * as "the framework matched another route", so {@link pickOwnParams} falls back for it.
31
- * {@link resolveFrameworkParams} settles that case from the PATH instead, and it needs
32
- * no URLPattern to do it.
33
- *
34
- * @param pattern - A route pattern, for example `/profile/:userId/:tab?`.
35
- * @returns The required names, in the order that the pattern declares them. A fresh
36
- * array, because `readPatternParams` caches the one it holds.
37
- */
38
- export declare function getRequiredPatternParamNames(pattern: string): string[];
39
- /**
40
- * Keeps the entries of `params` whose name the pattern of the machine declares, and
41
- * only when the result covers EVERY name of that pattern.
42
- *
43
- * A complete pick is an answer, and a partial pick is not: a wrapper route of the host
44
- * can declare a subset of the params of the machine — a tenant segment, for example,
45
- * but not the document one — and keeping that subset drops the rest from a route that
46
- * declares them. The caller falls back to its own extraction for `null`.
47
- *
48
- * The result has a null prototype, so a param named `__proto__` stays an own key.
49
- *
50
- * An OPTIONAL name of the pattern (`:name?`) is covered whether the framework reports
51
- * it or not: a segment that did not match has no value, and that is a complete answer.
52
- * At least one declared name must come back, though — a framework that reports none
53
- * matched another route, and the path may still hold a value that only the fallback
54
- * reads. A pattern whose params are ALL optional therefore always answers `null` here
55
- * when the framework reports nothing; {@link resolveFrameworkParams} then reads the PATH,
56
- * which settles the question without the framework and without URLPattern.
57
- *
58
- * @param params - The params of the framework router. {@link cleanFrameworkParams}
59
- * removes each empty value already, and one that reaches here anyway counts as
60
- * absent: an empty value says that the segment did not match, and never that the
61
- * path carries the empty string.
62
- * @param names - The names that the pattern of the machine declares.
63
- * @param requiredNames - The names the pattern REQUIRES. The default treats every name
64
- * as required, so a two-argument call keeps the strict test.
65
- * @returns The params of the machine, or `null` when the framework covers them not.
66
- */
67
- export declare function pickOwnParams(params: Record<string, string>, names: string[], requiredNames?: string[]): Record<string, string> | null;
68
- /**
69
- * The params of a framework router, in the shape that {@link pickOwnParams} reads.
70
- *
71
- * Every framework reports a param that its own route DECLARES and that the location
72
- * did not fill: Vue Router gives `undefined` or `""`, and SolidJS Router does the
73
- * same. Such an entry is not an answer, and a pick that kept it would send an empty
74
- * value to the actor as though the path carried one. Drop it here instead, one time,
75
- * because the rule belongs to the decision of {@link resolveFrameworkParams} and not
76
- * to a bridge: `VueRouterBridge` and `SolidRouterBridge` held one copy each.
77
- *
78
- * A value of an array — the splat of a catch-all route of Vue Router — becomes its
79
- * `String()` form, exactly as a single value does.
80
- *
81
- * The result has a null prototype, for the same reason {@link pickOwnParams} gives: a
82
- * plain `{}` accumulator turns `cleaned["__proto__"] = value` into a write of the
83
- * PROTOTYPE setter, which drops a string value in silence. `pickOwnParams` then read
84
- * `Object.hasOwn(params, "__proto__")` as `false`, called the pick incomplete, and fell
85
- * back to the URLPattern extraction — which THROWS on a runtime with no URLPattern, for
86
- * a route the framework had answered already.
87
- *
88
- * @param params - The raw params of the framework router.
89
- * @returns The params with no absent value, each one a string.
90
- */
91
- export declare function cleanFrameworkParams(params: Record<string, unknown>): Record<string, string>;
92
- /** What {@link resolveFrameworkParams} needs from the bridge that calls it. */
93
- export interface FrameworkParamsSource {
94
- /** The route pattern of the match, from `routeMap.getPathByStateId`. */
95
- pattern: string | null | undefined;
96
- /** The resolved prefix of the mount. `""` means that the machine owns the router. */
97
- basePath: string;
98
- /**
99
- * The machine-side path of the location, with the mount prefix already removed.
100
- *
101
- * The field is OPTIONAL, so a caller that was written before it keeps its behaviour:
102
- * the one branch that reads it falls back without it, exactly as it did.
103
- */
104
- pathname?: string;
105
- /** The params of the framework router, read lazily and cleaned of empty values. */
106
- frameworkParams(): Record<string, string>;
107
- /** The URLPattern extraction of the base class, read lazily. */
108
- fallback(): Record<string, string>;
109
- }
110
- /**
111
- * Decides which params describe the route of the machine.
112
- *
113
- * The three branches, in the order that they apply:
114
- *
115
- * - **The pattern declares no name** — a static path, a bare `*` wildcard, or an
116
- * unknown stateId. The answer is `{}`. The params of the framework must NOT travel
117
- * here: under a catch-all they hold the splat of the host, and that value would reach
118
- * the actor as a param of the machine. This branch also reaches no URLPattern, which
119
- * matters: the extraction needs the constructor even for a pattern with no parameter,
120
- * so a delegation would throw on a runtime without the API.
121
- * - **The bridge sits under a mount** — the framework matched a route of the HOST by
122
- * construction, because the machine owns the suffix of the path only. Its params
123
- * therefore describe this pattern never, whatever they are named, and a name that
124
- * happens to collide carries the value of the host. Read the params of the machine
125
- * from its own pattern instead.
126
- * - **The framework covers every REQUIRED name** — it matched the machine route. Keep
127
- * its parse, together with its decoding. An optional `:name?` that the framework
128
- * reports not is covered too: a segment that did not match has no value. A gap in a
129
- * required name falls back, because keeping it would drop a name the route declares.
130
- * - **The path IS the bare form of the pattern** — every optional segment is absent, so
131
- * `{}` is the complete answer. The branch reads the path and trusts the framework with
132
- * nothing, which is what makes it safe under a catch-all of the host, and it calls
133
- * URLPattern for a location that needs none.
134
- *
135
- * None of this decides whether the APPLICATION needs a URLPattern polyfill. A `RouteMap`
136
- * that holds one parameterized route compiles it in the CONSTRUCTOR, and it throws a
137
- * `URLPatternUnavailableError` there when the runtime has no URLPattern. The polyfill
138
- * question is therefore settled at startup: only a route map of static paths alone
139
- * escapes it. What these branches decide is whether a NAVIGATION calls URLPattern again.
140
- *
141
- * @returns The path parameters of the machine route, or `{}`.
142
- */
143
- export declare function resolveFrameworkParams({ pattern, basePath, pathname, frameworkParams, fallback, }: FrameworkParamsSource): Record<string, string>;
144
- //# sourceMappingURL=framework-params.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"framework-params.d.ts","sourceRoot":"","sources":["../src/framework-params.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAUH;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAE9D;AAqCD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,4BAA4B,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAEtE;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,aAAa,CAC5B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC9B,KAAK,EAAE,MAAM,EAAE,EACf,aAAa,GAAE,MAAM,EAAU,GAC7B,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAoC/B;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAc5F;AAkDD,+EAA+E;AAC/E,MAAM,WAAW,qBAAqB;IACrC,wEAAwE;IACxE,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACnC,qFAAqF;IACrF,QAAQ,EAAE,MAAM,CAAC;IACjB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mFAAmF;IACnF,eAAe,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1C,gEAAgE;IAChE,QAAQ,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACnC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wBAAgB,sBAAsB,CAAC,EACtC,OAAO,EACP,QAAQ,EACR,QAAQ,EACR,eAAe,EACf,QAAQ,GACR,EAAE,qBAAqB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAqBhD"}