@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 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?.path); // "/login"
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?.path); // "/profile/:userId"
370
+ console.log(profileById?.fullPath); // "/profile/:userId"
345
371
 
346
372
  const profileByPath = findRouteByPath(tree, "/profile/user123");
347
373
  console.log(profileByPath?.id); // "profile"
@@ -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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,qBAAa,YAAY;IACxB,OAAO,CAAC,aAAa,CAAsB;IAC3C,OAAO,CAAC,aAAa,CAAsB;IAC3C,OAAO,CAAC,cAAc,CAGpB;IACF,OAAO,CAAC,cAAc,CAAkC;IAExD;;;;;;;;;OASG;gBACS,QAAQ,EAAE,YAAY,EAAE;IAiCpC;;;;;;;;;;;;;;;OAeG;IACH,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAuB7C;;;;;;;;;;;OAWG;IACH,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;CAGhD"}
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"}
@@ -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: 500 });
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":"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"}
1
+ {"version":3,"file":"base-route-map.js","sourceRoot":"","sources":["../src/base-route-map.ts"],"names":[],"mappings":"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"}
@@ -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
@@ -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,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACvF,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,GACf,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,cAAc,EAAE,KAAK,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAKtE,OAAO,EAAE,YAAY,EAAE,KAAK,YAAY,IAAI,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAG1F,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC"}
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
- // Re-exported as `BaseRouteMapping` (not `RouteMapping`) so adapter packages can
16
- // define their own local `RouteMapping` type without a name collision.
17
- export { BaseRouteMap } from "./base-route-map.js";
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,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAGvF,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;AAevD,iFAAiF;AACjF,OAAO,EAAE,cAAc,EAAiB,MAAM,uBAAuB,CAAC;AAEtE,iDAAiD;AACjD,iFAAiF;AACjF,uEAAuE;AACvE,OAAO,EAAE,YAAY,EAAyC,MAAM,qBAAqB,CAAC;AAE1F,wEAAwE;AACxE,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC"}
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 (Node.js < 24, older browsers without a
137
- * polyfill), this method returns `{}` silently (graceful degradation routing still
138
- * works, params will be empty).
136
+ * library. If `URLPattern` is unavailable and the matched route has parameterized
137
+ * segments, a `URLPatternUnavailableError` is throwncallers 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 URLPattern is unavailable or no match
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;AAY5C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,kBAAkB;IAClC,mDAAmD;IACnD,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC;IACpD,8CAA8C;IAC9C,OAAO,IAAI,IAAI,CAAC;CAChB;AAED;;;;;;GAMG;AACH,8BAAsB,gBAAiB,YAAW,YAAY;IAe5D,SAAS,CAAC,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC,aAAa,CAAC,GAAG,QAAQ;IACjE,SAAS,CAAC,QAAQ,CAAC,QAAQ,EAAE;QAC5B,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;QAC1D,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;KACxD;IAjBF,SAAS,CAAC,WAAW,EAAE,OAAO,CAAS;IACvC,SAAS,CAAC,gBAAgB,EAAE,OAAO,CAAS;IAC5C,SAAS,CAAC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAQ;IAC/C,SAAS,CAAC,sBAAsB,EAAE,OAAO,CAAS;IAClD,SAAS,CAAC,YAAY,EAAE,kBAAkB,GAAG,IAAI,CAAQ;IAEzD;;;;;OAKG;gBAEiB,KAAK,EAAE,aAAa,CAAC,aAAa,CAAC,GAAG,QAAQ,EAC9C,QAAQ,EAAE;QAC5B,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;QAC1D,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;KACxD;IASF;;;;;;;;;;;;;OAaG;IACH,OAAO,IAAI,IAAI;IA+Df;;;;OAIG;IACH,UAAU,IAAI,IAAI;IAqBlB;;;;;;;;;OASG;IACH,SAAS,CAAC,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,GAAG,IAAI;IAcnE;;;;;OAKG;IACH,SAAS,CAAC,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI;IAwCtE;;;;;;;;;;;OAWG;IACH,SAAS,CAAC,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IAelF;;;;;OAKG;IACH,SAAS,CAAC,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IAM9D;;;;;OAKG;IACH,SAAS,CAAC,QAAQ,CAAC,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAErD;;;;;OAKG;IACH,SAAS,CAAC,QAAQ,CAAC,kBAAkB,IAAI,IAAI;IAE7C;;;;OAIG;IACH,SAAS,CAAC,QAAQ,CAAC,oBAAoB,IAAI,IAAI;IAE/C;;;;;;;;;;;;;;;;;OAiBG;IACH,SAAS,CAAC,oBAAoB,IAAI,MAAM,GAAG,IAAI,GAAG,SAAS;CAG3D"}
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 { getURLPatternCtor, } from "./url-pattern-utils.js";
46
- import { buildPlayRouteEvent, extractQuery, resolveRouteMapMatch, sanitizePathname, } from "./router-sync.js";
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" && initialRouterPath !== initialActorRoute) {
117
- // Router path differs from actor route — but is this a deep-link or a restore?
118
- //
119
- // Deep-link: router is at a non-initial URL the actor hasn't seen yet.
120
- // router wins: syncActorFromRouter (guards then evaluate access).
121
- //
122
- // Restore: browser is at the machine's initial URL while the actor was
123
- // restored to a different route from a snapshot.
124
- // → actor wins: push actor's restored route to the router.
125
- //
126
- // Detection: if the router URL equals the machine's initial route AND the
127
- // actor is at a different route, this is a restore scenario.
128
- if (initialActorRoute &&
129
- initialRouterPath === this.actor.initialRoute &&
130
- initialActorRoute !== this.actor.initialRoute) {
131
- this.lastSyncedPath = initialActorRoute;
132
- this.navigateRouter(initialActorRoute);
133
- }
134
- else {
135
- this.syncActorFromRouter(initialRouterPath);
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 (Node.js < 24, older browsers without a
246
- * polyfill), this method returns `{}` silently (graceful degradation routing still
247
- * works, params will be empty).
261
+ * library. If `URLPattern` is unavailable and the matched route has parameterized
262
+ * segments, a `URLPatternUnavailableError` is throwncallers 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 URLPattern is unavailable or no match
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 || !pattern.includes(":"))
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":"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"}
1
+ {"version":3,"file":"router-bridge-base.js","sourceRoot":"","sources":["../src/router-bridge-base.ts"],"names":[],"mappings":"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"}
@@ -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;AAEjD,MAAM,WAAW,UAAU;IAC1B,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,0BAA0B;IAC1C,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,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;;;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"}
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"}
@@ -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
- for (const [key, value] of Array.from(new URLSearchParams(search))) {
98
+ new URLSearchParams(search).forEach((value, key) => {
54
99
  params[key] = value;
55
- }
100
+ });
56
101
  return params;
57
102
  }
58
103
  catch {
@@ -1 +1 @@
1
- {"version":3,"file":"router-sync.js","sourceRoot":"","sources":["../src/router-sync.ts"],"names":[],"mappings":"AAkBA;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB,CACnC,QAAgB,EAChB,QAA0B,EAC1B,aAA4E;IAE5E,MAAM,OAAO,GAAG,QAAQ,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IACpD,IAAI,CAAC,OAAO,EAAE,CAAC;QACd,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;IACjC,CAAC;IAED,OAAO;QACN,EAAE,EAAE,OAAO;QACX,MAAM,EAAE,aAAa,CAAC,QAAQ,EAAE,OAAO,CAAC;KACxC,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,UAAU,gBAAgB,CAAC,QAAgB;IAChD,IAAI,QAAQ,CAAC,MAAM,GAAG,IAAI;QAAE,OAAO,IAAI,CAAC;IACxC,MAAM,YAAY,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5C,MAAM,WAAW,GAAG,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/C,OAAO,WAAW,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AACzC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,MAAc;IAC1C,IAAI,CAAC;QACJ,MAAM,MAAM,GAA2B,EAAE,CAAC;QAC1C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,eAAe,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;YACpE,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;QACrB,CAAC;QACD,OAAO,MAAM,CAAC;IACf,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,EAAE,CAAC;IACX,CAAC;AACF,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,mBAAmB,CAClC,OAAmC;IAEnC,MAAM,QAAQ,GAAG,gBAAgB,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACpD,IAAI,QAAQ,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAEnC,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACxC,IAAI,CAAC,KAAK,CAAC,EAAE;QAAE,OAAO,IAAI,CAAC;IAE3B,MAAM,EAAE,GAAG,KAAK,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,EAAE,EAAE,CAAC;IAChE,OAAO;QACN,QAAQ;QACR,KAAK,EAAE;YACN,IAAI,EAAE,YAAY;YAClB,EAAE;YACF,MAAM,EAAE,KAAK,CAAC,MAAM,IAAI,EAAE;YAC1B,KAAK,EAAE,YAAY,CAAC,OAAO,CAAC,MAAM,IAAI,EAAE,CAAC;SACzC;KACD,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"router-sync.js","sourceRoot":"","sources":["../src/router-sync.ts"],"names":[],"mappings":"AACA,OAAO,EAGN,iBAAiB,GACjB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,0BAA0B,EAAE,MAAM,aAAa,CAAC;AAkBzD;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB,CACnC,QAAgB,EAChB,QAA0B,EAC1B,aAA4E;IAE5E,MAAM,OAAO,GAAG,QAAQ,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IACpD,IAAI,CAAC,OAAO,EAAE,CAAC;QACd,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;IACjC,CAAC;IAED,OAAO;QACN,EAAE,EAAE,OAAO;QACX,MAAM,EAAE,aAAa,CAAC,QAAQ,EAAE,OAAO,CAAC;KACxC,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,UAAU,gBAAgB,CAAC,QAAgB;IAChD,IAAI,QAAQ,CAAC,MAAM,GAAG,IAAI;QAAE,OAAO,IAAI,CAAC;IACxC,MAAM,YAAY,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5C,MAAM,WAAW,GAAG,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/C,OAAO,WAAW,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AACzC,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,UAAU,kBAAkB,CAAC,QAAgB,EAAE,OAAe;IACnE,MAAM,IAAI,GAA+B,iBAAiB,EAAE,CAAC;IAC7D,IAAI,CAAC,IAAI;QAAE,MAAM,IAAI,0BAA0B,EAAE,CAAC;IAClD,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,EAAE,CAAC;IACtC,MAAM,UAAU,GAAmB,IAAI,IAAI,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC;IACnE,MAAM,KAAK,GAAG,UAAU,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC;IAC5C,IAAI,CAAC,KAAK,EAAE,QAAQ,CAAC,MAAM;QAAE,OAAO,EAAE,CAAC;IACvC,MAAM,MAAM,GAA2B,EAAE,CAAC;IAC1C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QAClE,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACzB,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;QACrB,CAAC;IACF,CAAC;IACD,OAAO,MAAM,CAAC;AACf,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,MAAc;IAC1C,IAAI,CAAC;QACJ,MAAM,MAAM,GAA2B,EAAE,CAAC;QAC1C,IAAI,eAAe,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;YAClD,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;QACrB,CAAC,CAAC,CAAC;QACH,OAAO,MAAM,CAAC;IACf,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,EAAE,CAAC;IACX,CAAC;AACF,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,mBAAmB,CAClC,OAAmC;IAEnC,MAAM,QAAQ,GAAG,gBAAgB,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACpD,IAAI,QAAQ,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAEnC,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACxC,IAAI,CAAC,KAAK,CAAC,EAAE;QAAE,OAAO,IAAI,CAAC;IAE3B,MAAM,EAAE,GAAG,KAAK,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,EAAE,EAAE,CAAC;IAChE,OAAO;QACN,QAAQ;QACR,KAAK,EAAE;YACN,IAAI,EAAE,YAAY;YAClB,EAAE;YACF,MAAM,EAAE,KAAK,CAAC,MAAM,IAAI,EAAE;YAC1B,KAAK,EAAE,YAAY,CAAC,OAAO,CAAC,MAAM,IAAI,EAAE,CAAC;SACzC;KACD,CAAC;AACH,CAAC"}
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
- /** Route path segment (relative or absolute) */
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
- /** Full resolved path from root */
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 - Merged path + query parameters (path parameters win conflicts)
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' }, // Merged: path + query
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
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
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.25",
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.25",
51
- "@xmachines/play-actor": "1.0.0-beta.25",
52
- "@xmachines/play-signals": "1.0.0-beta.25",
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.25",
58
- "@xmachines/shared": "1.0.0-beta.25",
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",