@xmachines/play-router 1.0.0-beta.25 → 1.0.0-beta.26
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 +30 -4
- package/dist/base-route-map.d.ts +11 -2
- package/dist/base-route-map.d.ts.map +1 -1
- package/dist/base-route-map.js +10 -3
- package/dist/base-route-map.js.map +1 -1
- package/dist/create-route-map-from-machine.d.ts +24 -0
- package/dist/create-route-map-from-machine.d.ts.map +1 -0
- package/dist/create-route-map-from-machine.js +32 -0
- package/dist/create-route-map-from-machine.js.map +1 -0
- package/dist/create-route-map-from-tree.d.ts +31 -0
- package/dist/create-route-map-from-tree.d.ts.map +1 -0
- package/dist/create-route-map-from-tree.js +42 -0
- package/dist/create-route-map-from-tree.js.map +1 -0
- package/dist/index.d.ts +5 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -4
- package/dist/index.js.map +1 -1
- package/dist/router-bridge-base.d.ts +46 -4
- package/dist/router-bridge-base.d.ts.map +1 -1
- package/dist/router-bridge-base.js +85 -40
- package/dist/router-bridge-base.js.map +1 -1
- package/dist/router-sync.d.ts +26 -0
- package/dist/router-sync.d.ts.map +1 -1
- package/dist/router-sync.js +47 -2
- package/dist/router-sync.js.map +1 -1
- package/dist/types.d.ts +52 -4
- package/dist/types.d.ts.map +1 -1
- package/package.json +11 -6
package/README.md
CHANGED
|
@@ -237,9 +237,16 @@ import { extractMachineRoutes } from "@xmachines/play-router";
|
|
|
237
237
|
|
|
238
238
|
const tree = extractMachineRoutes(authMachine);
|
|
239
239
|
|
|
240
|
-
// Query routes
|
|
240
|
+
// Query routes — use fullPath for URL matching (path is the raw meta.route segment)
|
|
241
241
|
const loginRoute = tree.byStateId.get("login");
|
|
242
|
-
console.log(loginRoute?.
|
|
242
|
+
console.log(loginRoute?.fullPath); // "/login"
|
|
243
|
+
console.log(loginRoute?.path); // "/login" (same for absolute routes)
|
|
244
|
+
|
|
245
|
+
// For nested relative routes the distinction matters:
|
|
246
|
+
// meta.route: "overview" under "/dashboard" → path: "overview", fullPath: "/dashboard/overview"
|
|
247
|
+
const overviewRoute = tree.byStateId.get("overview");
|
|
248
|
+
console.log(overviewRoute?.path); // "overview" (raw segment — relative)
|
|
249
|
+
console.log(overviewRoute?.fullPath); // "/dashboard/overview" (resolved — use this)
|
|
243
250
|
|
|
244
251
|
const dashboardRoute = tree.byPath.get("/dashboard");
|
|
245
252
|
console.log(dashboardRoute?.id); // "dashboard"
|
|
@@ -284,6 +291,25 @@ const successors = getSuccessors(tree.graph!, "myMachine.home");
|
|
|
284
291
|
- `eventType: string` — event type triggering this transition
|
|
285
292
|
- `guardType?: string` — guard name/description (if transition is guarded)
|
|
286
293
|
|
|
294
|
+
### createRouteMapFromMachine() / createRouteMapFromTree()
|
|
295
|
+
|
|
296
|
+
Both build a `BaseRouteMap` using `node.fullPath` (absolute resolved paths) for browser URL matching.
|
|
297
|
+
|
|
298
|
+
```typescript
|
|
299
|
+
// Single-call form — preferred for XState machines:
|
|
300
|
+
import { createRouteMapFromMachine } from "@xmachines/play-router";
|
|
301
|
+
const routeMap = createRouteMapFromMachine(machine);
|
|
302
|
+
|
|
303
|
+
// Two-step form — used by framework adapter packages:
|
|
304
|
+
import { extractMachineRoutes, createRouteMapFromTree } from "@xmachines/play-router";
|
|
305
|
+
const routeTree = extractMachineRoutes(machine);
|
|
306
|
+
const routeMap = createRouteMapFromTree(routeTree);
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
Both forms produce identical results. `createRouteMapFromTree` is exposed for framework adapters (React Router, TanStack Router) that need to hold the `RouteTree` separately for other purposes (e.g. graph queries).
|
|
310
|
+
|
|
311
|
+
**`node.path` vs `node.fullPath`:** Every `RouteNode` carries both fields. `path` is the raw `meta.route` segment as declared in the machine — it may be relative (e.g. `"overview"`). `fullPath` is the resolved absolute path (e.g. `"/dashboard/overview"`). Route maps always use `fullPath`. Only use `path` if you specifically need the declared segment.
|
|
312
|
+
|
|
287
313
|
### Query Utilities
|
|
288
314
|
|
|
289
315
|
```typescript
|
|
@@ -339,9 +365,9 @@ const machine = createMachine({
|
|
|
339
365
|
|
|
340
366
|
const tree = extractMachineRoutes(machine);
|
|
341
367
|
|
|
342
|
-
// Bidirectional mapping
|
|
368
|
+
// Bidirectional mapping — use fullPath for URLs; path is the raw meta.route segment
|
|
343
369
|
const profileById = tree.byStateId.get("profile");
|
|
344
|
-
console.log(profileById?.
|
|
370
|
+
console.log(profileById?.fullPath); // "/profile/:userId"
|
|
345
371
|
|
|
346
372
|
const profileByPath = findRouteByPath(tree, "/profile/user123");
|
|
347
373
|
console.log(profileByPath?.id); // "profile"
|
package/dist/base-route-map.d.ts
CHANGED
|
@@ -39,7 +39,8 @@ export interface RouteMapping {
|
|
|
39
39
|
* - Static paths (no `:param`) → O(1) `Map` lookup
|
|
40
40
|
* - Dynamic paths → O(k) bucket-indexed scan using `URLPattern`, where `k` is the number
|
|
41
41
|
* of routes sharing the same first path segment
|
|
42
|
-
* - Results are cached after the first match
|
|
42
|
+
* - Results are cached after the first match in an LRU cache (default 500 entries,
|
|
43
|
+
* configurable via the `cacheSize` constructor option)
|
|
43
44
|
*
|
|
44
45
|
* **Pattern syntax** (`:param` / `:param?`):
|
|
45
46
|
* - `:param` — required segment, matches exactly one non-`/` segment
|
|
@@ -78,8 +79,16 @@ export declare class BaseRouteMap {
|
|
|
78
79
|
*
|
|
79
80
|
* @param mappings - Array of `{ stateId, path }` entries. Order determines
|
|
80
81
|
* priority when multiple patterns could match the same path.
|
|
82
|
+
* @param options - Optional configuration.
|
|
83
|
+
* `options.cacheSize`: Maximum number of resolved parameterized path lookups
|
|
84
|
+
* to cache. Defaults to `500`. Increase for applications with many unique
|
|
85
|
+
* parameterized URL values (e.g. user profile pages with thousands of distinct IDs).
|
|
86
|
+
* After eviction the path falls back to the O(k) bucket pattern scan — correct
|
|
87
|
+
* but slower. Minimum effective value is `1` (QuickLRU constraint).
|
|
81
88
|
*/
|
|
82
|
-
constructor(mappings: RouteMapping[]
|
|
89
|
+
constructor(mappings: RouteMapping[], { cacheSize }?: {
|
|
90
|
+
cacheSize?: number;
|
|
91
|
+
});
|
|
83
92
|
/**
|
|
84
93
|
* Resolve a URL path to its mapped state ID.
|
|
85
94
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base-route-map.d.ts","sourceRoot":"","sources":["../src/base-route-map.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAgCH;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,YAAY;IAC5B,4DAA4D;IAC5D,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,oFAAoF;IACpF,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACtB;AAED
|
|
1
|
+
{"version":3,"file":"base-route-map.d.ts","sourceRoot":"","sources":["../src/base-route-map.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAgCH;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,YAAY;IAC5B,4DAA4D;IAC5D,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,oFAAoF;IACpF,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,qBAAa,YAAY;IACxB,OAAO,CAAC,aAAa,CAAsB;IAC3C,OAAO,CAAC,aAAa,CAAsB;IAC3C,OAAO,CAAC,cAAc,CAGpB;IACF,OAAO,CAAC,cAAc,CAAkC;IAExD;;;;;;;;;;;;;;;OAeG;gBACS,QAAQ,EAAE,YAAY,EAAE,EAAE,EAAE,SAAe,EAAE,GAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAO;IAiCtF;;;;;;;;;;;;;;;OAeG;IACH,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAuB7C;;;;;;;;;;;OAWG;IACH,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;CAGhD"}
|
package/dist/base-route-map.js
CHANGED
|
@@ -38,7 +38,8 @@ function normalizeParamNames(path) {
|
|
|
38
38
|
* - Static paths (no `:param`) → O(1) `Map` lookup
|
|
39
39
|
* - Dynamic paths → O(k) bucket-indexed scan using `URLPattern`, where `k` is the number
|
|
40
40
|
* of routes sharing the same first path segment
|
|
41
|
-
* - Results are cached after the first match
|
|
41
|
+
* - Results are cached after the first match in an LRU cache (default 500 entries,
|
|
42
|
+
* configurable via the `cacheSize` constructor option)
|
|
42
43
|
*
|
|
43
44
|
* **Pattern syntax** (`:param` / `:param?`):
|
|
44
45
|
* - `:param` — required segment, matches exactly one non-`/` segment
|
|
@@ -77,12 +78,18 @@ export class BaseRouteMap {
|
|
|
77
78
|
*
|
|
78
79
|
* @param mappings - Array of `{ stateId, path }` entries. Order determines
|
|
79
80
|
* priority when multiple patterns could match the same path.
|
|
81
|
+
* @param options - Optional configuration.
|
|
82
|
+
* `options.cacheSize`: Maximum number of resolved parameterized path lookups
|
|
83
|
+
* to cache. Defaults to `500`. Increase for applications with many unique
|
|
84
|
+
* parameterized URL values (e.g. user profile pages with thousands of distinct IDs).
|
|
85
|
+
* After eviction the path falls back to the O(k) bucket pattern scan — correct
|
|
86
|
+
* but slower. Minimum effective value is `1` (QuickLRU constraint).
|
|
80
87
|
*/
|
|
81
|
-
constructor(mappings) {
|
|
88
|
+
constructor(mappings, { cacheSize = 500 } = {}) {
|
|
82
89
|
this.stateIdToPath = new Map();
|
|
83
90
|
this.pathToStateId = new Map();
|
|
84
91
|
this.patternBuckets = new Map();
|
|
85
|
-
this.pathMatchCache = new QuickLRU({ maxSize:
|
|
92
|
+
this.pathMatchCache = new QuickLRU({ maxSize: Math.max(1, cacheSize) });
|
|
86
93
|
let patternOrder = 0;
|
|
87
94
|
for (const { stateId, path } of mappings) {
|
|
88
95
|
this.stateIdToPath.set(stateId, path);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base-route-map.js","sourceRoot":"","sources":["../src/base-route-map.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,QAAQ,MAAM,WAAW,CAAC;AACjC,OAAO,EAEN,iBAAiB,EACjB,WAAW,EACX,aAAa,GACb,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,0BAA0B,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAEnF;;;;;;;;;;;GAWG;AACH,SAAS,mBAAmB,CAAC,IAAY;IACxC,OAAO,IAAI,CAAC,OAAO,CAClB,iDAAiD,EACjD,CAAC,EAAE,EAAE,IAAY,EAAE,QAAgB,EAAE,EAAE;QACtC,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,GAAG,QAAQ,EAAE,CAAC;IACjD,CAAC,CACD,CAAC;AACH,CAAC;AAwBD
|
|
1
|
+
{"version":3,"file":"base-route-map.js","sourceRoot":"","sources":["../src/base-route-map.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,QAAQ,MAAM,WAAW,CAAC;AACjC,OAAO,EAEN,iBAAiB,EACjB,WAAW,EACX,aAAa,GACb,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,0BAA0B,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAEnF;;;;;;;;;;;GAWG;AACH,SAAS,mBAAmB,CAAC,IAAY;IACxC,OAAO,IAAI,CAAC,OAAO,CAClB,iDAAiD,EACjD,CAAC,EAAE,EAAE,IAAY,EAAE,QAAgB,EAAE,EAAE;QACtC,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,GAAG,QAAQ,EAAE,CAAC;IACjD,CAAC,CACD,CAAC;AACH,CAAC;AAwBD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,MAAM,OAAO,YAAY;IAChB,aAAa,CAAsB;IACnC,aAAa,CAAsB;IACnC,cAAc,CAGpB;IACM,cAAc,CAAkC;IAExD;;;;;;;;;;;;;;;OAeG;IACH,YAAY,QAAwB,EAAE,EAAE,SAAS,GAAG,GAAG,KAA6B,EAAE;QACrF,IAAI,CAAC,aAAa,GAAG,IAAI,GAAG,EAAE,CAAC;QAC/B,IAAI,CAAC,aAAa,GAAG,IAAI,GAAG,EAAE,CAAC;QAC/B,IAAI,CAAC,cAAc,GAAG,IAAI,GAAG,EAAE,CAAC;QAChC,IAAI,CAAC,cAAc,GAAG,IAAI,QAAQ,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,CAAC,EAAE,CAAC,CAAC;QACxE,IAAI,YAAY,GAAG,CAAC,CAAC;QAErB,KAAK,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,QAAQ,EAAE,CAAC;YAC1C,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;YAEtC,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;gBACxB,MAAM,gBAAgB,GAAG,iBAAiB,EAAE,CAAC;gBAC7C,IAAI,CAAC,gBAAgB,EAAE,CAAC;oBACvB,MAAM,IAAI,0BAA0B,EAAE,CAAC;gBACxC,CAAC;gBACD,MAAM,SAAS,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;gBACpC,MAAM,MAAM,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;gBACxD,IAAI,CAAC;oBACJ,MAAM,CAAC,IAAI,CAAC;wBACX,OAAO,EAAE,IAAI,gBAAgB,CAAC,EAAE,QAAQ,EAAE,mBAAmB,CAAC,IAAI,CAAC,EAAE,CAAC;wBACtE,OAAO;wBACP,KAAK,EAAE,YAAY,EAAE;qBACrB,CAAC,CAAC;gBACJ,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACd,MAAM,IAAI,wBAAwB,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;gBAC1D,CAAC;gBACD,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;YAC5C,CAAC;iBAAM,CAAC;gBACP,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;YACvC,CAAC;QACF,CAAC;IACF,CAAC;IAED;;;;;;;;;;;;;;;OAeG;IACH,gBAAgB,CAAC,IAAY;QAC5B,oDAAoD;QACpD,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAEnD,MAAM,UAAU,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACrD,IAAI,UAAU,KAAK,SAAS;YAAE,OAAO,UAAU,CAAC;QAEhD,MAAM,WAAW,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACvD,IAAI,WAAW,KAAK,SAAS;YAAE,OAAO,WAAW,CAAC;QAElD,MAAM,UAAU,GAAG,aAAa,CAAC,IAAI,CAAC,cAAc,EAAE,WAAW,CAAC,SAAS,CAAC,CAAC,CAAC;QAC9E,KAAK,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,UAAU,EAAE,CAAC;YAC/C,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC,CAAC;YACpD,IAAI,KAAK,EAAE,CAAC;gBACX,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;gBAC5C,OAAO,OAAO,CAAC;YAChB,CAAC;QACF,CAAC;QAED,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;QACzC,OAAO,IAAI,CAAC;IACb,CAAC;IAED;;;;;;;;;;;OAWG;IACH,gBAAgB,CAAC,OAAe;QAC/B,OAAO,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC;IAChD,CAAC;CACD"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { AnyStateMachine } from "xstate";
|
|
2
|
+
import { BaseRouteMap } from "./base-route-map.js";
|
|
3
|
+
/**
|
|
4
|
+
* Create a `BaseRouteMap` from an XState state machine.
|
|
5
|
+
*
|
|
6
|
+
* Extracts all routable states (those with `meta.route`) and builds a bidirectional
|
|
7
|
+
* path ↔ stateId lookup structure. The returned map is used by `RouterBridgeBase`
|
|
8
|
+
* subclasses to translate browser URL changes into `play.route` actor events and
|
|
9
|
+
* vice-versa.
|
|
10
|
+
*
|
|
11
|
+
* @param machine - XState v5 state machine with `meta.route` annotations on states.
|
|
12
|
+
* @returns A `BaseRouteMap` for passing to any `RouterBridgeBase`-based adapter.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```typescript
|
|
16
|
+
* import { createRouteMapFromMachine } from '@xmachines/play-router';
|
|
17
|
+
* import { connectRouter } from '@xmachines/play-dom-router';
|
|
18
|
+
*
|
|
19
|
+
* const routeMap = createRouteMapFromMachine(myMachine);
|
|
20
|
+
* const disconnect = connectRouter({ actor, router, routeMap });
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export declare function createRouteMapFromMachine(machine: AnyStateMachine): BaseRouteMap;
|
|
24
|
+
//# sourceMappingURL=create-route-map-from-machine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-route-map-from-machine.d.ts","sourceRoot":"","sources":["../src/create-route-map-from-machine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,QAAQ,CAAC;AAG9C,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAEnD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,eAAe,GAAG,YAAY,CAShF"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { extractMachineRoutes } from "./extract-routes.js";
|
|
2
|
+
import { getRoutableRoutes } from "./query.js";
|
|
3
|
+
import { BaseRouteMap } from "./base-route-map.js";
|
|
4
|
+
/**
|
|
5
|
+
* Create a `BaseRouteMap` from an XState state machine.
|
|
6
|
+
*
|
|
7
|
+
* Extracts all routable states (those with `meta.route`) and builds a bidirectional
|
|
8
|
+
* path ↔ stateId lookup structure. The returned map is used by `RouterBridgeBase`
|
|
9
|
+
* subclasses to translate browser URL changes into `play.route` actor events and
|
|
10
|
+
* vice-versa.
|
|
11
|
+
*
|
|
12
|
+
* @param machine - XState v5 state machine with `meta.route` annotations on states.
|
|
13
|
+
* @returns A `BaseRouteMap` for passing to any `RouterBridgeBase`-based adapter.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```typescript
|
|
17
|
+
* import { createRouteMapFromMachine } from '@xmachines/play-router';
|
|
18
|
+
* import { connectRouter } from '@xmachines/play-dom-router';
|
|
19
|
+
*
|
|
20
|
+
* const routeMap = createRouteMapFromMachine(myMachine);
|
|
21
|
+
* const disconnect = connectRouter({ actor, router, routeMap });
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
export function createRouteMapFromMachine(machine) {
|
|
25
|
+
const routeTree = extractMachineRoutes(machine);
|
|
26
|
+
const routes = getRoutableRoutes(routeTree);
|
|
27
|
+
return new BaseRouteMap(routes.map((node) => ({
|
|
28
|
+
stateId: node.stateId,
|
|
29
|
+
path: node.fullPath,
|
|
30
|
+
})));
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=create-route-map-from-machine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-route-map-from-machine.js","sourceRoot":"","sources":["../src/create-route-map-from-machine.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAEnD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,yBAAyB,CAAC,OAAwB;IACjE,MAAM,SAAS,GAAG,oBAAoB,CAAC,OAAO,CAAC,CAAC;IAChD,MAAM,MAAM,GAAG,iBAAiB,CAAC,SAAS,CAAC,CAAC;IAC5C,OAAO,IAAI,YAAY,CACtB,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,CACH,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { RouteTree } from "./types.js";
|
|
2
|
+
import { BaseRouteMap } from "./base-route-map.js";
|
|
3
|
+
/**
|
|
4
|
+
* Create a `BaseRouteMap` from a `RouteTree` node structure.
|
|
5
|
+
*
|
|
6
|
+
* Used by framework-router adapters (React Router, TanStack Router) that pass a
|
|
7
|
+
* `RouteTree` produced by `extractMachineRoutes()` rather than calling
|
|
8
|
+
* `createRouteMapFromMachine()` directly.
|
|
9
|
+
*
|
|
10
|
+
* Traverses all nodes collecting `{ stateId: node.id, path: node.fullPath }` pairs.
|
|
11
|
+
* `node.fullPath` is always the absolute resolved path (e.g. `"/dashboard/overview"`),
|
|
12
|
+
* which is what `BaseRouteMap` needs for browser URL matching. This matches the
|
|
13
|
+
* behaviour of `createRouteMapFromMachine`, which also uses `node.fullPath`.
|
|
14
|
+
*
|
|
15
|
+
* @param routeTree - A `RouteTree` as returned by `extractMachineRoutes()`.
|
|
16
|
+
* @returns A `BaseRouteMap` for use with any `RouterBridgeBase`-based adapter.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```typescript
|
|
20
|
+
* // Preferred — single call for XState machines:
|
|
21
|
+
* import { createRouteMapFromMachine } from '@xmachines/play-router';
|
|
22
|
+
* const routeMap = createRouteMapFromMachine(machine);
|
|
23
|
+
*
|
|
24
|
+
* // Equivalent two-step form used by framework adapters:
|
|
25
|
+
* import { extractMachineRoutes, createRouteMapFromTree } from '@xmachines/play-router';
|
|
26
|
+
* const routeTree = extractMachineRoutes(machine);
|
|
27
|
+
* const routeMap = createRouteMapFromTree(routeTree); // uses node.fullPath (absolute)
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
export declare function createRouteMapFromTree(routeTree: RouteTree): BaseRouteMap;
|
|
31
|
+
//# sourceMappingURL=create-route-map-from-tree.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-route-map-from-tree.d.ts","sourceRoot":"","sources":["../src/create-route-map-from-tree.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAa,MAAM,YAAY,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAEnD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,SAAS,GAAG,YAAY,CAczE"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { BaseRouteMap } from "./base-route-map.js";
|
|
2
|
+
/**
|
|
3
|
+
* Create a `BaseRouteMap` from a `RouteTree` node structure.
|
|
4
|
+
*
|
|
5
|
+
* Used by framework-router adapters (React Router, TanStack Router) that pass a
|
|
6
|
+
* `RouteTree` produced by `extractMachineRoutes()` rather than calling
|
|
7
|
+
* `createRouteMapFromMachine()` directly.
|
|
8
|
+
*
|
|
9
|
+
* Traverses all nodes collecting `{ stateId: node.id, path: node.fullPath }` pairs.
|
|
10
|
+
* `node.fullPath` is always the absolute resolved path (e.g. `"/dashboard/overview"`),
|
|
11
|
+
* which is what `BaseRouteMap` needs for browser URL matching. This matches the
|
|
12
|
+
* behaviour of `createRouteMapFromMachine`, which also uses `node.fullPath`.
|
|
13
|
+
*
|
|
14
|
+
* @param routeTree - A `RouteTree` as returned by `extractMachineRoutes()`.
|
|
15
|
+
* @returns A `BaseRouteMap` for use with any `RouterBridgeBase`-based adapter.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```typescript
|
|
19
|
+
* // Preferred — single call for XState machines:
|
|
20
|
+
* import { createRouteMapFromMachine } from '@xmachines/play-router';
|
|
21
|
+
* const routeMap = createRouteMapFromMachine(machine);
|
|
22
|
+
*
|
|
23
|
+
* // Equivalent two-step form used by framework adapters:
|
|
24
|
+
* import { extractMachineRoutes, createRouteMapFromTree } from '@xmachines/play-router';
|
|
25
|
+
* const routeTree = extractMachineRoutes(machine);
|
|
26
|
+
* const routeMap = createRouteMapFromTree(routeTree); // uses node.fullPath (absolute)
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
export function createRouteMapFromTree(routeTree) {
|
|
30
|
+
const routes = [];
|
|
31
|
+
function traverse(node) {
|
|
32
|
+
if (node.id && node.fullPath) {
|
|
33
|
+
routes.push({ stateId: node.id, path: node.fullPath });
|
|
34
|
+
}
|
|
35
|
+
if (node.children) {
|
|
36
|
+
node.children.forEach(traverse);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
traverse(routeTree.root);
|
|
40
|
+
return new BaseRouteMap(routes);
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=create-route-map-from-tree.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-route-map-from-tree.js","sourceRoot":"","sources":["../src/create-route-map-from-tree.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAEnD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,UAAU,sBAAsB,CAAC,SAAoB;IAC1D,MAAM,MAAM,GAA6C,EAAE,CAAC;IAE5D,SAAS,QAAQ,CAAC,IAAe;QAChC,IAAI,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC9B,MAAM,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;QACxD,CAAC;QACD,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YACnB,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QACjC,CAAC;IACF,CAAC;IAED,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IACzB,OAAO,IAAI,YAAY,CAAC,MAAM,CAAC,CAAC;AACjC,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { RouterBridgeBase } from "./router-bridge-base.js";
|
|
2
2
|
export type { RouteWatcherHandle } from "./router-bridge-base.js";
|
|
3
|
-
export { sanitizePathname, buildPlayRouteEvent, extractQuery } from "./router-sync.js";
|
|
3
|
+
export { sanitizePathname, buildPlayRouteEvent, extractQuery, extractRouteParams, } from "./router-sync.js";
|
|
4
4
|
export type { RouteMatch, BuildPlayRouteEventOptions } from "./router-sync.js";
|
|
5
5
|
export { validateRouteFormat, validateStateExists, detectDuplicateRoutes, } from "./validate-routes.js";
|
|
6
6
|
export { buildRouteTree } from "./build-tree.js";
|
|
@@ -8,8 +8,10 @@ export { extractMachineRoutes } from "./extract-routes.js";
|
|
|
8
8
|
export { getNavigableRoutes, getRoutableRoutes, routeExists, getTransitionReachableRoutes, isRouteReachable, } from "./query.js";
|
|
9
9
|
export { machineToGraph } from "./machine-to-graph.js";
|
|
10
10
|
export type { MachineGraph } from "./machine-to-graph.js";
|
|
11
|
-
export type { RouteInfo, RouteNode, RouteTree, RouteObject, RouteMetadata, PlayRouteEvent, RouterBridge, MachineNodeData, MachineEdgeData, } from "./types.js";
|
|
11
|
+
export type { RouteInfo, RouteNode, RouteTree, RouteObject, RouteMetadata, PlayRouteEvent, RouterBridge, MachineNodeData, MachineEdgeData, WindowLike, LocationLike, } from "./types.js";
|
|
12
12
|
export { createRouteMap, type RouteMap } from "./create-route-map.js";
|
|
13
|
-
export { BaseRouteMap, type RouteMapping as BaseRouteMapping } from "./base-route-map.js";
|
|
13
|
+
export { BaseRouteMap, type RouteMapping, type RouteMapping as BaseRouteMapping, } from "./base-route-map.js";
|
|
14
|
+
export { createRouteMapFromMachine } from "./create-route-map-from-machine.js";
|
|
15
|
+
export { createRouteMapFromTree } from "./create-route-map-from-tree.js";
|
|
14
16
|
export { findRouteById, findRouteByPath } from "./find-route.js";
|
|
15
17
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,YAAY,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAGlE,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,YAAY,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAGlE,OAAO,EACN,gBAAgB,EAChB,mBAAmB,EACnB,YAAY,EACZ,kBAAkB,GAClB,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EAAE,UAAU,EAAE,0BAA0B,EAAE,MAAM,kBAAkB,CAAC;AAG/E,OAAO,EACN,mBAAmB,EACnB,mBAAmB,EACnB,qBAAqB,GACrB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EACN,kBAAkB,EAClB,iBAAiB,EACjB,WAAW,EACX,4BAA4B,EAC5B,gBAAgB,GAChB,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,YAAY,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAE1D,YAAY,EACX,SAAS,EACT,SAAS,EACT,SAAS,EACT,WAAW,EACX,aAAa,EACb,cAAc,EACd,YAAY,EACZ,eAAe,EACf,eAAe,EACf,UAAU,EACV,YAAY,GACZ,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,cAAc,EAAE,KAAK,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAItE,OAAO,EACN,YAAY,EACZ,KAAK,YAAY,EACjB,KAAK,YAAY,IAAI,gBAAgB,GACrC,MAAM,qBAAqB,CAAC;AAI7B,OAAO,EAAE,yBAAyB,EAAE,MAAM,oCAAoC,CAAC;AAC/E,OAAO,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AAGzE,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// RouterBridgeBase — public API for community adapters
|
|
2
2
|
export { RouterBridgeBase } from "./router-bridge-base.js";
|
|
3
3
|
// Router sync utilities — used by play-dom-router and adapters that bypass syncActorFromRouter()
|
|
4
|
-
export { sanitizePathname, buildPlayRouteEvent, extractQuery } from "./router-sync.js";
|
|
4
|
+
export { sanitizePathname, buildPlayRouteEvent, extractQuery, extractRouteParams, } from "./router-sync.js";
|
|
5
5
|
// Route utilities (existing)
|
|
6
6
|
export { validateRouteFormat, validateStateExists, detectDuplicateRoutes, } from "./validate-routes.js";
|
|
7
7
|
export { buildRouteTree } from "./build-tree.js";
|
|
@@ -12,9 +12,12 @@ export { machineToGraph } from "./machine-to-graph.js";
|
|
|
12
12
|
// Route map for path → state ID resolution (createRouteMap / RouteMap interface)
|
|
13
13
|
export { createRouteMap } from "./create-route-map.js";
|
|
14
14
|
// Shared bidirectional route mapping base class.
|
|
15
|
-
//
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
// RouteMapping is exported directly; BaseRouteMapping kept as alias for compatibility.
|
|
16
|
+
export { BaseRouteMap, } from "./base-route-map.js";
|
|
17
|
+
// Factories: create a BaseRouteMap from a machine or a route tree.
|
|
18
|
+
// All RouterBridgeBase adapters use these instead of rolling their own factories.
|
|
19
|
+
export { createRouteMapFromMachine } from "./create-route-map-from-machine.js";
|
|
20
|
+
export { createRouteMapFromTree } from "./create-route-map-from-tree.js";
|
|
18
21
|
// Route lookup helpers — matchesPattern is private within find-route.ts
|
|
19
22
|
export { findRouteById, findRouteByPath } from "./find-route.js";
|
|
20
23
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,uDAAuD;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAG3D,iGAAiG;AACjG,OAAO,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,uDAAuD;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAG3D,iGAAiG;AACjG,OAAO,EACN,gBAAgB,EAChB,mBAAmB,EACnB,YAAY,EACZ,kBAAkB,GAClB,MAAM,kBAAkB,CAAC;AAG1B,6BAA6B;AAC7B,OAAO,EACN,mBAAmB,EACnB,mBAAmB,EACnB,qBAAqB,GACrB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EACN,kBAAkB,EAClB,iBAAiB,EACjB,WAAW,EACX,4BAA4B,EAC5B,gBAAgB,GAChB,MAAM,YAAY,CAAC;AAEpB,qEAAqE;AACrE,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAiBvD,iFAAiF;AACjF,OAAO,EAAE,cAAc,EAAiB,MAAM,uBAAuB,CAAC;AAEtE,iDAAiD;AACjD,uFAAuF;AACvF,OAAO,EACN,YAAY,GAGZ,MAAM,qBAAqB,CAAC;AAE7B,mEAAmE;AACnE,kFAAkF;AAClF,OAAO,EAAE,yBAAyB,EAAE,MAAM,oCAAoC,CAAC;AAC/E,OAAO,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AAEzE,wEAAwE;AACxE,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC"}
|
|
@@ -133,15 +133,33 @@ export declare abstract class RouterBridgeBase implements RouterBridge {
|
|
|
133
133
|
* Extract path parameters from URL using the URLPattern API.
|
|
134
134
|
*
|
|
135
135
|
* Accesses `globalThis.URLPattern` at runtime — no polyfill is imported by this
|
|
136
|
-
* library. If `URLPattern` is unavailable
|
|
137
|
-
*
|
|
138
|
-
*
|
|
136
|
+
* library. If `URLPattern` is unavailable and the matched route has parameterized
|
|
137
|
+
* segments, a `URLPatternUnavailableError` is thrown — callers must provide a polyfill
|
|
138
|
+
* for environments without native URLPattern support (Node.js < 24, older browsers).
|
|
139
139
|
*
|
|
140
140
|
* @param pathname - The actual URL path (e.g., '/profile/john')
|
|
141
141
|
* @param stateId - The matched state ID for looking up the route pattern
|
|
142
|
-
* @returns Extracted path parameters, or empty object if
|
|
142
|
+
* @returns Extracted path parameters, or empty object if no match
|
|
143
|
+
* @throws {URLPatternUnavailableError} When URLPattern is absent and the route is parameterized
|
|
143
144
|
*/
|
|
144
145
|
protected extractParams(pathname: string, stateId: string): Record<string, string>;
|
|
146
|
+
/**
|
|
147
|
+
* Resolve an actor route value to a concrete URL path for navigation.
|
|
148
|
+
*
|
|
149
|
+
* Bridges that receive raw `actor.currentRoute` values in `navigateRouter`
|
|
150
|
+
* can call this to normalize stateIds (with or without `#` prefix) to paths.
|
|
151
|
+
* Returns `null` when navigation is not possible:
|
|
152
|
+
* - unknown stateId with no route map entry
|
|
153
|
+
* - parameterized pattern (e.g. `/profile/:id`) — no concrete values available
|
|
154
|
+
* - non-path string that isn't a known stateId
|
|
155
|
+
*
|
|
156
|
+
* Route maps may store stateIds with or without the `#` prefix; both forms
|
|
157
|
+
* are tried automatically.
|
|
158
|
+
*
|
|
159
|
+
* @param route - Raw actor route value (stateId, `#`-stateId, or concrete path)
|
|
160
|
+
* @returns Concrete URL path, or `null` if navigation should be skipped
|
|
161
|
+
*/
|
|
162
|
+
protected resolveNavigationPath(route: string): string | null;
|
|
145
163
|
/**
|
|
146
164
|
* Extract query parameters from URL search string.
|
|
147
165
|
*
|
|
@@ -161,6 +179,16 @@ export declare abstract class RouterBridgeBase implements RouterBridge {
|
|
|
161
179
|
*
|
|
162
180
|
* Called by connect(). Should set up the framework-specific subscription
|
|
163
181
|
* for location changes and call syncActorFromRouter() on each change.
|
|
182
|
+
*
|
|
183
|
+
* **Implementations that call `syncActorFromRouter`** get `sanitizePathname`
|
|
184
|
+
* applied automatically — no extra work needed.
|
|
185
|
+
*
|
|
186
|
+
* **Implementations that bypass `syncActorFromRouter`** (e.g. `VueRouterBridge`,
|
|
187
|
+
* which builds the `play.route` event directly from `afterEach` params) MUST
|
|
188
|
+
* apply `sanitizePathname(path)` manually before processing the path. Skipping
|
|
189
|
+
* this allows oversized or malformed paths through without the length/content
|
|
190
|
+
* guards that protect the route-map lookup. Import `sanitizePathname` from
|
|
191
|
+
* `@xmachines/play-router`.
|
|
164
192
|
*/
|
|
165
193
|
protected abstract watchRouterChanges(): void;
|
|
166
194
|
/**
|
|
@@ -188,5 +216,19 @@ export declare abstract class RouterBridgeBase implements RouterBridge {
|
|
|
188
216
|
* bridges that have not yet implemented this hook.
|
|
189
217
|
*/
|
|
190
218
|
protected getInitialRouterPath(): string | null | undefined;
|
|
219
|
+
/**
|
|
220
|
+
* Return the router's current search string at connect() time.
|
|
221
|
+
*
|
|
222
|
+
* Paired with `getInitialRouterPath()` — called once during connect() to pass
|
|
223
|
+
* the initial URL query string to `syncActorFromRouter()`. If the router's current
|
|
224
|
+
* URL has no search (or the subclass doesn't override this), returns `undefined`
|
|
225
|
+
* and `syncActorFromRouter` will produce an empty `query: {}` in the event.
|
|
226
|
+
*
|
|
227
|
+
* Subclasses that override `getInitialRouterPath()` and have a query string
|
|
228
|
+
* available should also override this method.
|
|
229
|
+
*
|
|
230
|
+
* @returns URL search string (e.g. `"?tab=security"`), or `undefined` if not available.
|
|
231
|
+
*/
|
|
232
|
+
protected getInitialRouterSearch(): string | undefined;
|
|
191
233
|
}
|
|
192
234
|
//# sourceMappingURL=router-bridge-base.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"router-bridge-base.d.ts","sourceRoot":"","sources":["../src/router-bridge-base.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AAEH,OAAO,EAAE,MAAM,EAAe,MAAM,yBAAyB,CAAC;AAE9D,OAAO,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACrE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"router-bridge-base.d.ts","sourceRoot":"","sources":["../src/router-bridge-base.ts"],"names":[],"mappings":"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"}
|
|
@@ -42,8 +42,8 @@
|
|
|
42
42
|
*/
|
|
43
43
|
import { Signal, watchSignal } from "@xmachines/play-signals";
|
|
44
44
|
import { RouterSyncError } from "./errors.js";
|
|
45
|
-
import {
|
|
46
|
-
import {
|
|
45
|
+
import { buildPlayRouteEvent, extractQuery, extractRouteParams, resolveRouteMapMatch, sanitizePathname, } from "./router-sync.js";
|
|
46
|
+
import { URLPatternUnavailableError } from "./errors.js";
|
|
47
47
|
/**
|
|
48
48
|
* Abstract base class for all `@xmachines` router adapter bridges.
|
|
49
49
|
*
|
|
@@ -112,27 +112,38 @@ export class RouterBridgeBase {
|
|
|
112
112
|
// fire for the already-loaded location. Subclasses that can read the router's
|
|
113
113
|
// current location synchronously should override getInitialRouterPath().
|
|
114
114
|
const initialRouterPath = this.getInitialRouterPath();
|
|
115
|
+
const initialRouterSearch = this.getInitialRouterSearch();
|
|
115
116
|
const initialActorRoute = this.actor.currentRoute.get();
|
|
116
|
-
if (typeof initialRouterPath === "string"
|
|
117
|
-
//
|
|
118
|
-
//
|
|
119
|
-
//
|
|
120
|
-
//
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
117
|
+
if (typeof initialRouterPath === "string") {
|
|
118
|
+
// Check if actor is already at the router's current location.
|
|
119
|
+
// Actor currentRoute may be a stateId (e.g. "#app.home") while initialRouterPath
|
|
120
|
+
// is a URL path (e.g. "/home"). Resolve the path to a stateId before comparing
|
|
121
|
+
// to avoid a false "they differ" that would trigger an unnecessary initial sync.
|
|
122
|
+
const resolvedStateId = this.routeMap.getStateIdByPath(sanitizePathname(initialRouterPath) ?? initialRouterPath);
|
|
123
|
+
const actorAlreadyAtRouterLocation = resolvedStateId !== null &&
|
|
124
|
+
resolvedStateId !== undefined &&
|
|
125
|
+
(resolvedStateId === initialActorRoute || initialRouterPath === initialActorRoute);
|
|
126
|
+
if (!actorAlreadyAtRouterLocation) {
|
|
127
|
+
// Router path differs from actor route — but is this a deep-link or a restore?
|
|
128
|
+
//
|
|
129
|
+
// Deep-link: router is at a non-initial URL the actor hasn't seen yet.
|
|
130
|
+
// → router wins: syncActorFromRouter (guards then evaluate access).
|
|
131
|
+
//
|
|
132
|
+
// Restore: browser is at the machine's initial URL while the actor was
|
|
133
|
+
// restored to a different route from a snapshot.
|
|
134
|
+
// → actor wins: push actor's restored route to the router.
|
|
135
|
+
//
|
|
136
|
+
// Detection: if the router URL equals the machine's initial route AND the
|
|
137
|
+
// actor is at a different route, this is a restore scenario.
|
|
138
|
+
if (initialActorRoute &&
|
|
139
|
+
initialRouterPath === this.actor.initialRoute &&
|
|
140
|
+
initialActorRoute !== this.actor.initialRoute) {
|
|
141
|
+
this.lastSyncedPath = initialActorRoute;
|
|
142
|
+
this.navigateRouter(initialActorRoute);
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
this.syncActorFromRouter(initialRouterPath, initialRouterSearch);
|
|
146
|
+
}
|
|
136
147
|
}
|
|
137
148
|
}
|
|
138
149
|
else if (initialActorRoute && initialRouterPath === null) {
|
|
@@ -229,6 +240,11 @@ export class RouterBridgeBase {
|
|
|
229
240
|
this.lastSyncedPath = nextRoute.pathname;
|
|
230
241
|
}
|
|
231
242
|
catch (error) {
|
|
243
|
+
// URLPatternUnavailableError is a user-actionable error — propagate as-is
|
|
244
|
+
// so callers can detect it and prompt the user to add a URLPattern polyfill.
|
|
245
|
+
if (error instanceof URLPatternUnavailableError) {
|
|
246
|
+
throw error;
|
|
247
|
+
}
|
|
232
248
|
throw new RouterSyncError("Failed to sync actor state from router location.", {
|
|
233
249
|
cause: error,
|
|
234
250
|
});
|
|
@@ -242,31 +258,44 @@ export class RouterBridgeBase {
|
|
|
242
258
|
* Extract path parameters from URL using the URLPattern API.
|
|
243
259
|
*
|
|
244
260
|
* Accesses `globalThis.URLPattern` at runtime — no polyfill is imported by this
|
|
245
|
-
* library. If `URLPattern` is unavailable
|
|
246
|
-
*
|
|
247
|
-
*
|
|
261
|
+
* library. If `URLPattern` is unavailable and the matched route has parameterized
|
|
262
|
+
* segments, a `URLPatternUnavailableError` is thrown — callers must provide a polyfill
|
|
263
|
+
* for environments without native URLPattern support (Node.js < 24, older browsers).
|
|
248
264
|
*
|
|
249
265
|
* @param pathname - The actual URL path (e.g., '/profile/john')
|
|
250
266
|
* @param stateId - The matched state ID for looking up the route pattern
|
|
251
|
-
* @returns Extracted path parameters, or empty object if
|
|
267
|
+
* @returns Extracted path parameters, or empty object if no match
|
|
268
|
+
* @throws {URLPatternUnavailableError} When URLPattern is absent and the route is parameterized
|
|
252
269
|
*/
|
|
253
270
|
extractParams(pathname, stateId) {
|
|
254
271
|
const pattern = this.routeMap.getPathByStateId(stateId);
|
|
255
|
-
if (!pattern
|
|
256
|
-
return {};
|
|
257
|
-
try {
|
|
258
|
-
const Ctor = getURLPatternCtor();
|
|
259
|
-
if (!Ctor)
|
|
260
|
-
return {};
|
|
261
|
-
const urlPattern = new Ctor({ pathname: pattern });
|
|
262
|
-
const result = urlPattern.exec({ pathname });
|
|
263
|
-
if (!result)
|
|
264
|
-
return {};
|
|
265
|
-
return result.pathname.groups || {};
|
|
266
|
-
}
|
|
267
|
-
catch {
|
|
272
|
+
if (!pattern)
|
|
268
273
|
return {};
|
|
269
|
-
|
|
274
|
+
return extractRouteParams(pathname, pattern);
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Resolve an actor route value to a concrete URL path for navigation.
|
|
278
|
+
*
|
|
279
|
+
* Bridges that receive raw `actor.currentRoute` values in `navigateRouter`
|
|
280
|
+
* can call this to normalize stateIds (with or without `#` prefix) to paths.
|
|
281
|
+
* Returns `null` when navigation is not possible:
|
|
282
|
+
* - unknown stateId with no route map entry
|
|
283
|
+
* - parameterized pattern (e.g. `/profile/:id`) — no concrete values available
|
|
284
|
+
* - non-path string that isn't a known stateId
|
|
285
|
+
*
|
|
286
|
+
* Route maps may store stateIds with or without the `#` prefix; both forms
|
|
287
|
+
* are tried automatically.
|
|
288
|
+
*
|
|
289
|
+
* @param route - Raw actor route value (stateId, `#`-stateId, or concrete path)
|
|
290
|
+
* @returns Concrete URL path, or `null` if navigation should be skipped
|
|
291
|
+
*/
|
|
292
|
+
resolveNavigationPath(route) {
|
|
293
|
+
const withoutHash = route.startsWith("#") ? route.slice(1) : route;
|
|
294
|
+
const mapped = this.routeMap.getPathByStateId(route) ?? this.routeMap.getPathByStateId(withoutHash);
|
|
295
|
+
const path = mapped ?? (route.startsWith("/") ? route : null);
|
|
296
|
+
if (path === null || path.includes(":"))
|
|
297
|
+
return null;
|
|
298
|
+
return path;
|
|
270
299
|
}
|
|
271
300
|
/**
|
|
272
301
|
* Extract query parameters from URL search string.
|
|
@@ -298,6 +327,22 @@ export class RouterBridgeBase {
|
|
|
298
327
|
getInitialRouterPath() {
|
|
299
328
|
return undefined;
|
|
300
329
|
}
|
|
330
|
+
/**
|
|
331
|
+
* Return the router's current search string at connect() time.
|
|
332
|
+
*
|
|
333
|
+
* Paired with `getInitialRouterPath()` — called once during connect() to pass
|
|
334
|
+
* the initial URL query string to `syncActorFromRouter()`. If the router's current
|
|
335
|
+
* URL has no search (or the subclass doesn't override this), returns `undefined`
|
|
336
|
+
* and `syncActorFromRouter` will produce an empty `query: {}` in the event.
|
|
337
|
+
*
|
|
338
|
+
* Subclasses that override `getInitialRouterPath()` and have a query string
|
|
339
|
+
* available should also override this method.
|
|
340
|
+
*
|
|
341
|
+
* @returns URL search string (e.g. `"?tab=security"`), or `undefined` if not available.
|
|
342
|
+
*/
|
|
343
|
+
getInitialRouterSearch() {
|
|
344
|
+
return undefined;
|
|
345
|
+
}
|
|
301
346
|
}
|
|
302
347
|
function createRouteWatcher(signal, onRoute) {
|
|
303
348
|
let cleanup = () => { };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"router-bridge-base.js","sourceRoot":"","sources":["../src/router-bridge-base.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AAEH,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAG9C,OAAO,
|
|
1
|
+
{"version":3,"file":"router-bridge-base.js","sourceRoot":"","sources":["../src/router-bridge-base.ts"],"names":[],"mappings":"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"}
|
package/dist/router-sync.d.ts
CHANGED
|
@@ -42,6 +42,32 @@ export declare function resolveRouteMapMatch(pathname: string, routeMap: RouterS
|
|
|
42
42
|
* ```
|
|
43
43
|
*/
|
|
44
44
|
export declare function sanitizePathname(pathname: string): string | null;
|
|
45
|
+
/**
|
|
46
|
+
* Extract named path parameters from a URL using the URLPattern API.
|
|
47
|
+
*
|
|
48
|
+
* Takes the pattern string directly — use this when the pattern is already known.
|
|
49
|
+
* For extraction via a state ID lookup, see `RouterBridgeBase.extractParams`.
|
|
50
|
+
*
|
|
51
|
+
* Undefined values (unmatched optional segments, e.g. `/settings` against
|
|
52
|
+
* `/settings/:section?`) are omitted from the returned object.
|
|
53
|
+
*
|
|
54
|
+
* @param pathname - The concrete URL pathname (e.g. `/profile/alice`)
|
|
55
|
+
* @param pattern - The URL pattern template (e.g. `/profile/:username`)
|
|
56
|
+
* @returns A record of extracted parameter values, or `{}` for static patterns.
|
|
57
|
+
* @throws {URLPatternUnavailableError} When `URLPattern` is absent and the pattern is parameterized.
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* ```typescript
|
|
61
|
+
* import { extractRouteParams } from "@xmachines/play-router";
|
|
62
|
+
*
|
|
63
|
+
* extractRouteParams("/profile/alice", "/profile/:username")
|
|
64
|
+
* // → { username: "alice" }
|
|
65
|
+
*
|
|
66
|
+
* extractRouteParams("/settings", "/settings/:section?")
|
|
67
|
+
* // → {} (optional param absent — not included)
|
|
68
|
+
* ```
|
|
69
|
+
*/
|
|
70
|
+
export declare function extractRouteParams(pathname: string, pattern: string): Record<string, string>;
|
|
45
71
|
/**
|
|
46
72
|
* Parse a URL search string into the plain object shape expected by
|
|
47
73
|
* `play.route` events.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"router-sync.d.ts","sourceRoot":"","sources":["../src/router-sync.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"router-sync.d.ts","sourceRoot":"","sources":["../src/router-sync.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAQjD,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,OAAO,EAAE,CAAC,iBAAiB,EAAE,MAAM,KAAK,UAAU,CAAC;CACnD;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,oBAAoB,CACnC,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;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAKhE;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAc5F;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAUnE;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAClC,OAAO,EAAE,0BAA0B,GACjC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,cAAc,CAAA;CAAE,GAAG,IAAI,CAiBpD"}
|
package/dist/router-sync.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { getURLPatternCtor, } from "./url-pattern-utils.js";
|
|
2
|
+
import { URLPatternUnavailableError } from "./errors.js";
|
|
1
3
|
/**
|
|
2
4
|
* Resolve a sanitized pathname against a route map and extract any matched params.
|
|
3
5
|
*
|
|
@@ -43,6 +45,49 @@ export function sanitizePathname(pathname) {
|
|
|
43
45
|
const withoutHash = withoutQuery.split("#")[0];
|
|
44
46
|
return withoutHash.replace(/\/+/g, "/");
|
|
45
47
|
}
|
|
48
|
+
/**
|
|
49
|
+
* Extract named path parameters from a URL using the URLPattern API.
|
|
50
|
+
*
|
|
51
|
+
* Takes the pattern string directly — use this when the pattern is already known.
|
|
52
|
+
* For extraction via a state ID lookup, see `RouterBridgeBase.extractParams`.
|
|
53
|
+
*
|
|
54
|
+
* Undefined values (unmatched optional segments, e.g. `/settings` against
|
|
55
|
+
* `/settings/:section?`) are omitted from the returned object.
|
|
56
|
+
*
|
|
57
|
+
* @param pathname - The concrete URL pathname (e.g. `/profile/alice`)
|
|
58
|
+
* @param pattern - The URL pattern template (e.g. `/profile/:username`)
|
|
59
|
+
* @returns A record of extracted parameter values, or `{}` for static patterns.
|
|
60
|
+
* @throws {URLPatternUnavailableError} When `URLPattern` is absent and the pattern is parameterized.
|
|
61
|
+
*
|
|
62
|
+
* @example
|
|
63
|
+
* ```typescript
|
|
64
|
+
* import { extractRouteParams } from "@xmachines/play-router";
|
|
65
|
+
*
|
|
66
|
+
* extractRouteParams("/profile/alice", "/profile/:username")
|
|
67
|
+
* // → { username: "alice" }
|
|
68
|
+
*
|
|
69
|
+
* extractRouteParams("/settings", "/settings/:section?")
|
|
70
|
+
* // → {} (optional param absent — not included)
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
73
|
+
export function extractRouteParams(pathname, pattern) {
|
|
74
|
+
const Ctor = getURLPatternCtor();
|
|
75
|
+
if (!Ctor)
|
|
76
|
+
throw new URLPatternUnavailableError();
|
|
77
|
+
if (!pattern.includes(":"))
|
|
78
|
+
return {};
|
|
79
|
+
const urlPattern = new Ctor({ pathname: pattern });
|
|
80
|
+
const match = urlPattern.exec({ pathname });
|
|
81
|
+
if (!match?.pathname.groups)
|
|
82
|
+
return {};
|
|
83
|
+
const params = {};
|
|
84
|
+
for (const [key, value] of Object.entries(match.pathname.groups)) {
|
|
85
|
+
if (value !== undefined) {
|
|
86
|
+
params[key] = value;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return params;
|
|
90
|
+
}
|
|
46
91
|
/**
|
|
47
92
|
* Parse a URL search string into the plain object shape expected by
|
|
48
93
|
* `play.route` events.
|
|
@@ -50,9 +95,9 @@ export function sanitizePathname(pathname) {
|
|
|
50
95
|
export function extractQuery(search) {
|
|
51
96
|
try {
|
|
52
97
|
const params = {};
|
|
53
|
-
|
|
98
|
+
new URLSearchParams(search).forEach((value, key) => {
|
|
54
99
|
params[key] = value;
|
|
55
|
-
}
|
|
100
|
+
});
|
|
56
101
|
return params;
|
|
57
102
|
}
|
|
58
103
|
catch {
|
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
|
@@ -70,9 +70,16 @@ export interface RouteInfo {
|
|
|
70
70
|
export interface RouteNode {
|
|
71
71
|
/** Unique identifier (state ID) */
|
|
72
72
|
id: string;
|
|
73
|
-
/**
|
|
73
|
+
/**
|
|
74
|
+
* The raw route path segment as declared in `meta.route` — may be relative (e.g. `"overview"`)
|
|
75
|
+
* or absolute (e.g. `"/dashboard"`). Do not use this for URL matching; use `fullPath` instead.
|
|
76
|
+
*/
|
|
74
77
|
path: string;
|
|
75
|
-
/**
|
|
78
|
+
/**
|
|
79
|
+
* The fully resolved absolute path from the root (e.g. `"/dashboard/overview"`).
|
|
80
|
+
* Always use `fullPath` for browser URL matching and route map construction.
|
|
81
|
+
* `createRouteMapFromTree` and `createRouteMapFromMachine` both use this field.
|
|
82
|
+
*/
|
|
76
83
|
fullPath: string;
|
|
77
84
|
/** Route pattern with parameters (e.g., /profile/:userId) if path contains params */
|
|
78
85
|
pattern?: string;
|
|
@@ -141,7 +148,7 @@ export interface RouteTree {
|
|
|
141
148
|
*
|
|
142
149
|
* @param type - Event discriminator (always "play.route")
|
|
143
150
|
* @param to - Target state ID with # prefix (e.g., '#home', '#profile')
|
|
144
|
-
* @param params -
|
|
151
|
+
* @param params - Path-only route parameters extracted from the URL path (e.g., `{ userId: '123' }` from `/profile/123`). Query parameters are kept separate in `query`.
|
|
145
152
|
* @param query - Query parameters only (isolated from path params)
|
|
146
153
|
* @param match - Full URLPattern match result for debugging/observability (optional)
|
|
147
154
|
*
|
|
@@ -190,7 +197,7 @@ export interface RouteTree {
|
|
|
190
197
|
* const event: PlayRouteEvent = {
|
|
191
198
|
* type: 'play.route',
|
|
192
199
|
* to: '#settings',
|
|
193
|
-
* params: { section: 'profile' }, //
|
|
200
|
+
* params: { section: 'profile' }, // Path-only route parameter
|
|
194
201
|
* query: { tab: 'security' } // Query-only
|
|
195
202
|
* };
|
|
196
203
|
* actor.send(event);
|
|
@@ -284,4 +291,45 @@ export interface RouterBridge {
|
|
|
284
291
|
*/
|
|
285
292
|
disconnect(): void | Promise<void>;
|
|
286
293
|
}
|
|
294
|
+
/**
|
|
295
|
+
* Minimal window interface required by adapters that subscribe to DOM events
|
|
296
|
+
* (e.g. `hashchange`). Injectable for SSR and testing — pass a mock instead of
|
|
297
|
+
* the global `window` when the DOM is unavailable.
|
|
298
|
+
*
|
|
299
|
+
* Defined structurally (no `Window` reference) so this package compiles without
|
|
300
|
+
* the DOM lib.
|
|
301
|
+
*
|
|
302
|
+
* @example
|
|
303
|
+
* ```typescript
|
|
304
|
+
* // Normal usage — global window (default)
|
|
305
|
+
* connectRouter({ actor, routeMap });
|
|
306
|
+
*
|
|
307
|
+
* // SSR / test — injected mock
|
|
308
|
+
* const mockWin: WindowLike = { addEventListener: vi.fn(), removeEventListener: vi.fn() };
|
|
309
|
+
* connectRouter({ actor, routeMap, window: mockWin });
|
|
310
|
+
* ```
|
|
311
|
+
*/
|
|
312
|
+
export interface WindowLike {
|
|
313
|
+
addEventListener(type: string, listener: (event: Event) => void): void;
|
|
314
|
+
removeEventListener(type: string, listener: (event: Event) => void): void;
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* Minimal location interface required by adapters that read the current URL at
|
|
318
|
+
* `connect()` time. Injectable for SSR and testing — pass a mock instead of the
|
|
319
|
+
* global `location` when the DOM is unavailable.
|
|
320
|
+
*
|
|
321
|
+
* Defined structurally (no `Location` reference) so this package compiles without
|
|
322
|
+
* the DOM lib.
|
|
323
|
+
*
|
|
324
|
+
* @example
|
|
325
|
+
* ```typescript
|
|
326
|
+
* // SSR / test — injected mock
|
|
327
|
+
* const mockLoc: LocationLike = { pathname: "/dashboard", search: "?tab=posts" };
|
|
328
|
+
* connectRouter({ actor, routeMap, location: mockLoc });
|
|
329
|
+
* ```
|
|
330
|
+
*/
|
|
331
|
+
export interface LocationLike {
|
|
332
|
+
readonly pathname: string;
|
|
333
|
+
readonly search: string;
|
|
334
|
+
}
|
|
287
335
|
//# 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,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAE9C;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC/B,wDAAwD;IACxD,OAAO,EAAE,MAAM,CAAC;IAChB,6BAA6B;IAC7B,IAAI,EAAE,QAAQ,GAAG,UAAU,GAAG,UAAU,GAAG,OAAO,GAAG,SAAS,CAAC;IAC/D,iCAAiC;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,yDAAyD;IACzD,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC/B,mDAAmD;IACnD,SAAS,EAAE,MAAM,CAAC;IAClB,8CAA8C;IAC9C,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;GAKG;AAEH;;GAEG;AACH,MAAM,WAAW,WAAW;IAC3B,8CAA8C;IAC9C,IAAI,EAAE,MAAM,CAAC;IACb,0DAA0D;IAC1D,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,WAAW,CAAC;AAEjD;;GAEG;AACH,MAAM,WAAW,SAAS;IACzB,mDAAmD;IACnD,OAAO,EAAE,MAAM,CAAC;IAChB,oCAAoC;IACpC,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,2CAA2C;IAC3C,SAAS,EAAE,MAAM,CAAC;IAClB,0FAA0F;IAC1F,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,qDAAqD;IACrD,UAAU,EAAE,OAAO,CAAC;IACpB;;;OAGG;IACH,QAAQ,EAAE,OAAO,CAAC;IAClB,8BAA8B;IAC9B,QAAQ,EAAE,aAAa,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,SAAS;IACzB,mCAAmC;IACnC,EAAE,EAAE,MAAM,CAAC;IACX
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xmachines/play-router",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.26",
|
|
4
4
|
"description": "Route tree extraction from XState v5 state machines. Part of @xmachines/play Universal Player Architecture.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"routing",
|
|
@@ -28,6 +28,11 @@
|
|
|
28
28
|
"types": "./test/demo-browser-suite.ts",
|
|
29
29
|
"import": "./test/demo-browser-suite.ts"
|
|
30
30
|
},
|
|
31
|
+
"./test/contract.js": {
|
|
32
|
+
"source": "./test/router-bridge-contract.ts",
|
|
33
|
+
"types": "./test/router-bridge-contract.ts",
|
|
34
|
+
"import": "./test/router-bridge-contract.ts"
|
|
35
|
+
},
|
|
31
36
|
"./errors": {
|
|
32
37
|
"source": "./src/errors.ts",
|
|
33
38
|
"types": "./dist/errors.d.ts",
|
|
@@ -47,15 +52,15 @@
|
|
|
47
52
|
},
|
|
48
53
|
"dependencies": {
|
|
49
54
|
"@statelyai/graph": "^0.10.0",
|
|
50
|
-
"@xmachines/play": "1.0.0-beta.
|
|
51
|
-
"@xmachines/play-actor": "1.0.0-beta.
|
|
52
|
-
"@xmachines/play-signals": "1.0.0-beta.
|
|
55
|
+
"@xmachines/play": "1.0.0-beta.26",
|
|
56
|
+
"@xmachines/play-actor": "1.0.0-beta.26",
|
|
57
|
+
"@xmachines/play-signals": "1.0.0-beta.26",
|
|
53
58
|
"quick-lru": "^7.0.0"
|
|
54
59
|
},
|
|
55
60
|
"devDependencies": {
|
|
56
61
|
"@types/node": "^25.5.0",
|
|
57
|
-
"@xmachines/play-xstate": "1.0.0-beta.
|
|
58
|
-
"@xmachines/shared": "1.0.0-beta.
|
|
62
|
+
"@xmachines/play-xstate": "1.0.0-beta.26",
|
|
63
|
+
"@xmachines/shared": "1.0.0-beta.26",
|
|
59
64
|
"oxfmt": "^0.43.0",
|
|
60
65
|
"oxlint": "^1.57.0",
|
|
61
66
|
"typescript": "^5.9.3 || ^6.0.2",
|