@xmachines/play-router 1.0.0-beta.2 → 1.0.0-beta.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/README.md +169 -47
  2. package/dist/base-route-map.d.ts +116 -0
  3. package/dist/base-route-map.d.ts.map +1 -0
  4. package/dist/base-route-map.js +206 -0
  5. package/dist/base-route-map.js.map +1 -0
  6. package/dist/build-tree.d.ts.map +1 -1
  7. package/dist/build-tree.js +6 -5
  8. package/dist/build-tree.js.map +1 -1
  9. package/dist/connect-router.d.ts.map +1 -1
  10. package/dist/connect-router.js +35 -45
  11. package/dist/connect-router.js.map +1 -1
  12. package/dist/create-browser-history.d.ts +38 -5
  13. package/dist/create-browser-history.d.ts.map +1 -1
  14. package/dist/create-browser-history.js +43 -17
  15. package/dist/create-browser-history.js.map +1 -1
  16. package/dist/create-route-map.d.ts +21 -1
  17. package/dist/create-route-map.d.ts.map +1 -1
  18. package/dist/create-route-map.js +73 -22
  19. package/dist/create-route-map.js.map +1 -1
  20. package/dist/errors.d.ts +75 -0
  21. package/dist/errors.d.ts.map +1 -0
  22. package/dist/errors.js +85 -0
  23. package/dist/errors.js.map +1 -0
  24. package/dist/extract-routes.d.ts +5 -31
  25. package/dist/extract-routes.d.ts.map +1 -1
  26. package/dist/extract-routes.js +70 -49
  27. package/dist/extract-routes.js.map +1 -1
  28. package/dist/find-route.d.ts +44 -0
  29. package/dist/find-route.d.ts.map +1 -0
  30. package/dist/find-route.js +126 -0
  31. package/dist/find-route.js.map +1 -0
  32. package/dist/index.d.ts +9 -48
  33. package/dist/index.d.ts.map +1 -1
  34. package/dist/index.js +16 -131
  35. package/dist/index.js.map +1 -1
  36. package/dist/machine-to-graph.d.ts +17 -0
  37. package/dist/machine-to-graph.d.ts.map +1 -0
  38. package/dist/machine-to-graph.js +115 -0
  39. package/dist/machine-to-graph.js.map +1 -0
  40. package/dist/query.d.ts +44 -1
  41. package/dist/query.d.ts.map +1 -1
  42. package/dist/query.js +80 -3
  43. package/dist/query.js.map +1 -1
  44. package/dist/router-bridge-base.d.ts +49 -19
  45. package/dist/router-bridge-base.d.ts.map +1 -1
  46. package/dist/router-bridge-base.js +120 -56
  47. package/dist/router-bridge-base.js.map +1 -1
  48. package/dist/router-sync.d.ts +62 -0
  49. package/dist/router-sync.d.ts.map +1 -0
  50. package/dist/router-sync.js +87 -0
  51. package/dist/router-sync.js.map +1 -0
  52. package/dist/types.d.ts +73 -14
  53. package/dist/types.d.ts.map +1 -1
  54. package/dist/validate-routes.d.ts +9 -9
  55. package/dist/validate-routes.d.ts.map +1 -1
  56. package/dist/validate-routes.js +12 -11
  57. package/dist/validate-routes.js.map +1 -1
  58. package/package.json +36 -18
  59. package/dist/crawl-machine.d.ts +0 -74
  60. package/dist/crawl-machine.d.ts.map +0 -1
  61. package/dist/crawl-machine.js +0 -95
  62. package/dist/crawl-machine.js.map +0 -1
  63. package/dist/extract-route.d.ts +0 -25
  64. package/dist/extract-route.d.ts.map +0 -1
  65. package/dist/extract-route.js +0 -63
  66. package/dist/extract-route.js.map +0 -1
@@ -0,0 +1,87 @@
1
+ /**
2
+ * Resolve a sanitized pathname against a route map and extract any matched params.
3
+ *
4
+ * Shared by low-level and framework router sync paths to keep route-map matching
5
+ * semantics aligned.
6
+ */
7
+ export function resolveRouteMapMatch(pathname, routeMap, extractParams) {
8
+ const stateId = routeMap.getStateIdByPath(pathname);
9
+ if (!stateId) {
10
+ return { to: null, params: {} };
11
+ }
12
+ return {
13
+ to: stateId,
14
+ params: extractParams(pathname, stateId),
15
+ };
16
+ }
17
+ /**
18
+ * Normalize a pathname before route-map lookup.
19
+ *
20
+ * This strips query/hash fragments, collapses duplicate slashes, and rejects
21
+ * implausibly long paths that should never enter route resolution.
22
+ *
23
+ * Returns `null` for paths exceeding 2048 characters (malformed/adversarial input).
24
+ * Adapters that bypass `RouterBridgeBase.syncActorFromRouter()` (e.g. `VueRouterBridge`)
25
+ * must call this function directly and return early on `null` to apply the same
26
+ * defense-in-depth security guarantee as the shared base class.
27
+ *
28
+ * @param pathname - Raw path string from router navigation event.
29
+ * @returns Normalized path string, or `null` if the path is malformed/too long.
30
+ *
31
+ * @example
32
+ * ```typescript
33
+ * import { sanitizePathname } from "@xmachines/play-router";
34
+ *
35
+ * const clean = sanitizePathname(to.path);
36
+ * if (clean === null) return; // reject malformed path
37
+ * ```
38
+ */
39
+ export function sanitizePathname(pathname) {
40
+ if (pathname.length > 2048)
41
+ return null;
42
+ const withoutQuery = pathname.split("?")[0];
43
+ const withoutHash = withoutQuery.split("#")[0];
44
+ return withoutHash.replace(/\/+/g, "/");
45
+ }
46
+ /**
47
+ * Parse a URL search string into the plain object shape expected by
48
+ * `play.route` events.
49
+ */
50
+ export function extractQuery(search) {
51
+ try {
52
+ const params = {};
53
+ for (const [key, value] of Array.from(new URLSearchParams(search))) {
54
+ params[key] = value;
55
+ }
56
+ return params;
57
+ }
58
+ catch {
59
+ return {};
60
+ }
61
+ }
62
+ /**
63
+ * Build a normalized `play.route` event from raw router/browser input.
64
+ *
65
+ * Both `connectRouter()` and `RouterBridgeBase` use this helper so low-level and
66
+ * framework adapters share the same pathname sanitization, route resolution, and
67
+ * query extraction behavior.
68
+ */
69
+ export function buildPlayRouteEvent(options) {
70
+ const pathname = sanitizePathname(options.pathname);
71
+ if (pathname === null)
72
+ return null;
73
+ const match = options.resolve(pathname);
74
+ if (!match.to)
75
+ return null;
76
+ const to = match.to.startsWith("#") ? match.to : `#${match.to}`;
77
+ return {
78
+ pathname,
79
+ event: {
80
+ type: "play.route",
81
+ to,
82
+ params: match.params ?? {},
83
+ query: extractQuery(options.search ?? ""),
84
+ },
85
+ };
86
+ }
87
+ //# sourceMappingURL=router-sync.js.map
@@ -0,0 +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"}
package/dist/types.d.ts CHANGED
@@ -1,16 +1,47 @@
1
- import type { StateNode } from "xstate";
2
- import type { RouteMetadata } from "@xmachines/play-xstate";
1
+ import type { Graph } from "@statelyai/graph";
3
2
  /**
4
- * Represents a visit to a state node during graph crawling
3
+ * Data attached to each node in the machine graph representation.
4
+ * Captures the essential state metadata needed for route extraction and queries.
5
5
  */
6
- export interface StateVisit {
7
- /** The state node being visited */
8
- node: StateNode;
9
- /** Path from root to this state (e.g., ['dashboard', 'overview']) */
10
- path: string[];
11
- /** Parent state node (null for root) */
12
- parent: StateNode | null;
6
+ export interface MachineNodeData {
7
+ /** XState state ID (e.g., "test.dashboard.overview") */
8
+ stateId: string;
9
+ /** State type from XState */
10
+ type: "atomic" | "compound" | "parallel" | "final" | "history";
11
+ /** Original state meta object */
12
+ meta?: Record<string, unknown>;
13
+ /** Extracted route path from meta.route (string form) */
14
+ route?: string;
15
+ }
16
+ /**
17
+ * Data attached to each edge in the machine graph representation.
18
+ * Captures transition event and guard information.
19
+ */
20
+ export interface MachineEdgeData {
21
+ /** The event type that triggers this transition */
22
+ eventType: string;
23
+ /** String representation of guard (if any) */
24
+ guardType?: string;
25
+ }
26
+ /**
27
+ * Routing protocol type definitions for @xmachines/play-router
28
+ *
29
+ * PlayRouteEvent, RouterBridge, RouteMetadata, and RouteObject live here to keep
30
+ * routing concerns separate from the base event protocol in @xmachines/play.
31
+ */
32
+ /**
33
+ * Route object with additional metadata.
34
+ */
35
+ export interface RouteObject {
36
+ /** Route path template (e.g., '/user/:id') */
37
+ path: string;
38
+ /** Additional route metadata (title, breadcrumb, etc.) */
39
+ [key: string]: unknown;
13
40
  }
41
+ /**
42
+ * Route metadata from state machine `meta.route` field.
43
+ */
44
+ export type RouteMetadata = string | RouteObject;
14
45
  /**
15
46
  * Extracted route information from a state node
16
47
  */
@@ -57,7 +88,7 @@ export interface RouteNode {
57
88
  /** Parent route (null for root) */
58
89
  parent: RouteNode | null;
59
90
  /** Original meta.route metadata */
60
- metadata: unknown;
91
+ metadata: RouteMetadata;
61
92
  }
62
93
  /**
63
94
  * Complete route tree with lookup maps
@@ -79,6 +110,18 @@ export interface RouteTree {
79
110
  * Used to look up state ID from URL path for play.route event targeting
80
111
  */
81
112
  byPath: Map<string, RouteNode>;
113
+ /**
114
+ * Graph representation of the state machine for advanced queries.
115
+ * Populated by extractMachineRoutes() — use for hierarchy queries, reachability checks,
116
+ * and transition-aware navigation via @statelyai/graph algorithms.
117
+ *
118
+ * @example
119
+ * ```typescript
120
+ * import { getSuccessors, hasPath } from "@statelyai/graph";
121
+ * const successors = getSuccessors(tree.graph!, "myMachine.home");
122
+ * ```
123
+ */
124
+ graph?: Graph<MachineNodeData, MachineEdgeData>;
82
125
  }
83
126
  /**
84
127
  * Enhanced routing event with parameter and query support
@@ -90,6 +133,12 @@ export interface RouteTree {
90
133
  * user navigation intent that the Actor evaluates through guards. Infrastructure proposes
91
134
  * via `play.route` events, Actor decides via state machine transitions.
92
135
  *
136
+ * **Browser Navigation Flow:**
137
+ * 1. Browser fires `popstate`
138
+ * 2. Router adapter resolves URL to route target
139
+ * 3. Adapter sends `PlayRouteEvent` to Actor
140
+ * 4. Actor validates transition via state machine guards
141
+ *
93
142
  * @param type - Event discriminator (always "play.route")
94
143
  * @param to - Target state ID with # prefix (e.g., '#home', '#profile')
95
144
  * @param params - Merged path + query parameters (path parameters win conflicts)
@@ -99,6 +148,15 @@ export interface RouteTree {
99
148
  * @returns N/A - Interface defines event shape only
100
149
  *
101
150
  * @example
151
+ * Combining base and routing events
152
+ * ```typescript
153
+ * import type { PlayEvent } from "@xmachines/play";
154
+ * import type { PlayRouteEvent } from "@xmachines/play-router";
155
+ *
156
+ * type AppEvent = PlayEvent | PlayRouteEvent;
157
+ * ```
158
+ *
159
+ * @example
102
160
  * Basic navigation to a route
103
161
  * ```typescript
104
162
  * import type { PlayRouteEvent } from "@xmachines/play-router";
@@ -139,7 +197,7 @@ export interface RouteTree {
139
197
  * // Resolves to route: /settings/profile?tab=security
140
198
  * ```
141
199
  *
142
- * @see {@link https://gitlab.com/xmachin-es/rfc/-/blob/main/src/play-v1.md | RFC Play v1}
200
+ * @see [Play RFC](../../docs/rfc/play.md)
143
201
  *
144
202
  * @remarks
145
203
  * Use `play.route` when you need parameter-aware navigation with the `route: {}`
@@ -151,7 +209,8 @@ export interface PlayRouteEvent {
151
209
  readonly to: string;
152
210
  readonly params?: Record<string, string>;
153
211
  readonly query?: Record<string, string>;
154
- readonly match?: any;
212
+ readonly match?: unknown;
213
+ [key: string]: unknown;
155
214
  }
156
215
  /**
157
216
  * RouterBridge interface for runtime infrastructure adapters
@@ -190,7 +249,7 @@ export interface PlayRouteEvent {
190
249
  * }
191
250
  * ```
192
251
  *
193
- * @see {@link https://gitlab.com/xmachin-es/rfc/-/blob/main/src/play-v1.md | RFC Play v1 - Invariant INV-04}
252
+ * @see [Play RFC](../../docs/rfc/play.md) - Invariant INV-04
194
253
  */
195
254
  export interface RouterBridge {
196
255
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACxC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAE5D;;GAEG;AACH,MAAM,WAAW,UAAU;IAC1B,mCAAmC;IACnC,IAAI,EAAE,SAAS,CAAC;IAChB,qEAAqE;IACrE,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,wCAAwC;IACxC,MAAM,EAAE,SAAS,GAAG,IAAI,CAAC;CACzB;AAED;;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,gDAAgD;IAChD,IAAI,EAAE,MAAM,CAAC;IACb,mCAAmC;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,qFAAqF;IACrF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,yCAAyC;IACzC,OAAO,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,QAAQ,EAAE,OAAO,CAAC;IAClB,mBAAmB;IACnB,QAAQ,EAAE,SAAS,EAAE,CAAC;IACtB,mCAAmC;IACnC,MAAM,EAAE,SAAS,GAAG,IAAI,CAAC;IACzB,mCAAmC;IACnC,QAAQ,EAAE,OAAO,CAAC;CAClB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,SAAS;IACzB,sBAAsB;IACtB,IAAI,EAAE,SAAS,CAAC;IAChB;;;OAGG;IACH,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAClC;;;OAGG;IACH,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;CAC/B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiEG;AACH,MAAM,WAAW,cAAc;IAC9B,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAC5B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC,QAAQ,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC;CACrB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,MAAM,WAAW,YAAY;IAC5B;;;;;;;;;;;;;;OAcG;IACH,OAAO,IAAI,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEhC;;;;;;;;;;;;;OAaG;IACH,UAAU,IAAI,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACnC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
@@ -1,27 +1,27 @@
1
- import type { StateNode } from "xstate";
2
1
  import type { RouteInfo } from "./types.js";
3
2
  /**
4
3
  * Validate route path format
5
4
  *
6
- * Ensures route paths start with "/" (absolute or relative).
7
- * Per Route Protocol spec, all routes must have explicit path structure.
5
+ * Ensures route paths are non-empty strings. Both absolute paths ("/foo")
6
+ * and relative paths ("foo", "child/nested") are accepted. Relative routes
7
+ * inherit their parent state's path prefix when the tree is built.
8
8
  *
9
- * @param routePath - Route path to validate
9
+ * @param routePath - Route path to validate (absolute or relative)
10
10
  * @param stateId - State identifier for error messages
11
- * @throws {Error} If route path doesn't start with /
11
+ * @throws {Error} If route path is empty
12
12
  */
13
13
  export declare const validateRouteFormat: (routePath: string, stateId: string) => void;
14
14
  /**
15
- * Validate state exists in state map
15
+ * Validate state exists in state ID set
16
16
  *
17
17
  * Ensures referenced state IDs exist in the machine graph.
18
18
  * Build-time validation prevents broken route references.
19
19
  *
20
20
  * @param stateId - State identifier to validate
21
- * @param stateMap - Map of all state IDs to StateNodes
22
- * @throws {Error} If state ID doesn't exist in map
21
+ * @param stateIds - Set of all known state IDs from the machine graph
22
+ * @throws {Error} If state ID doesn't exist in set
23
23
  */
24
- export declare const validateStateExists: (stateId: string, stateMap: Map<string, StateNode>) => void;
24
+ export declare const validateStateExists: (stateId: string, stateIds: Set<string>) => void;
25
25
  /**
26
26
  * Detect duplicate route paths
27
27
  *
@@ -1 +1 @@
1
- {"version":3,"file":"validate-routes.d.ts","sourceRoot":"","sources":["../src/validate-routes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACxC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C;;;;;;;;;GASG;AACH,eAAO,MAAM,mBAAmB,GAAI,WAAW,MAAM,EAAE,SAAS,MAAM,KAAG,IAMxE,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,mBAAmB,GAAI,SAAS,MAAM,EAAE,UAAU,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,KAAG,IAIvF,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,qBAAqB,GAAI,QAAQ,SAAS,EAAE,KAAG,IAyB3D,CAAC"}
1
+ {"version":3,"file":"validate-routes.d.ts","sourceRoot":"","sources":["../src/validate-routes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C;;;;;;;;;;GAUG;AACH,eAAO,MAAM,mBAAmB,GAAI,WAAW,MAAM,EAAE,SAAS,MAAM,KAAG,IAMxE,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,mBAAmB,GAAI,SAAS,MAAM,EAAE,UAAU,GAAG,CAAC,MAAM,CAAC,KAAG,IAI5E,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,qBAAqB,GAAI,QAAQ,SAAS,EAAE,KAAG,IAyB3D,CAAC"}
@@ -1,30 +1,31 @@
1
1
  /**
2
2
  * Validate route path format
3
3
  *
4
- * Ensures route paths start with "/" (absolute or relative).
5
- * Per Route Protocol spec, all routes must have explicit path structure.
4
+ * Ensures route paths are non-empty strings. Both absolute paths ("/foo")
5
+ * and relative paths ("foo", "child/nested") are accepted. Relative routes
6
+ * inherit their parent state's path prefix when the tree is built.
6
7
  *
7
- * @param routePath - Route path to validate
8
+ * @param routePath - Route path to validate (absolute or relative)
8
9
  * @param stateId - State identifier for error messages
9
- * @throws {Error} If route path doesn't start with /
10
+ * @throws {Error} If route path is empty
10
11
  */
11
12
  export const validateRouteFormat = (routePath, stateId) => {
12
- if (!routePath.startsWith("/")) {
13
- throw new Error(`Invalid route path "${routePath}" in state "${stateId}": routes must start with /`);
13
+ if (!routePath) {
14
+ throw new Error(`Empty route path in state "${stateId}": routes must have a non-empty path`);
14
15
  }
15
16
  };
16
17
  /**
17
- * Validate state exists in state map
18
+ * Validate state exists in state ID set
18
19
  *
19
20
  * Ensures referenced state IDs exist in the machine graph.
20
21
  * Build-time validation prevents broken route references.
21
22
  *
22
23
  * @param stateId - State identifier to validate
23
- * @param stateMap - Map of all state IDs to StateNodes
24
- * @throws {Error} If state ID doesn't exist in map
24
+ * @param stateIds - Set of all known state IDs from the machine graph
25
+ * @throws {Error} If state ID doesn't exist in set
25
26
  */
26
- export const validateStateExists = (stateId, stateMap) => {
27
- if (!stateMap.has(stateId)) {
27
+ export const validateStateExists = (stateId, stateIds) => {
28
+ if (!stateIds.has(stateId)) {
28
29
  throw new Error(`Route references non-existent state ID: ${stateId}`);
29
30
  }
30
31
  };
@@ -1 +1 @@
1
- {"version":3,"file":"validate-routes.js","sourceRoot":"","sources":["../src/validate-routes.ts"],"names":[],"mappings":"AAGA;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,SAAiB,EAAE,OAAe,EAAQ,EAAE;IAC/E,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAChC,MAAM,IAAI,KAAK,CACd,uBAAuB,SAAS,eAAe,OAAO,6BAA6B,CACnF,CAAC;IACH,CAAC;AACF,CAAC,CAAC;AAEF;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,OAAe,EAAE,QAAgC,EAAQ,EAAE;IAC9F,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CAAC,2CAA2C,OAAO,EAAE,CAAC,CAAC;IACvE,CAAC;AACF,CAAC,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,MAAmB,EAAQ,EAAE;IAClE,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAoB,CAAC;IAE7C,wCAAwC;IACxC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC5B,MAAM,QAAQ,GAAG,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;QACrD,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC7B,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IACzC,CAAC;IAED,uCAAuC;IACvC,MAAM,UAAU,GAAa,EAAE,CAAC;IAChC,KAAK,MAAM,CAAC,SAAS,EAAE,QAAQ,CAAC,IAAI,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC;QACxD,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACzB,UAAU,CAAC,IAAI,CAAC,KAAK,SAAS,MAAM,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC7D,CAAC;IACF,CAAC;IAED,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3B,MAAM,IAAI,KAAK,CACd,oCAAoC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM;YAC9D,kDAAkD;YAClD,6FAA6F,CAC9F,CAAC;IACH,CAAC;AACF,CAAC,CAAC"}
1
+ {"version":3,"file":"validate-routes.js","sourceRoot":"","sources":["../src/validate-routes.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,SAAiB,EAAE,OAAe,EAAQ,EAAE;IAC/E,IAAI,CAAC,SAAS,EAAE,CAAC;QAChB,MAAM,IAAI,KAAK,CACd,8BAA8B,OAAO,sCAAsC,CAC3E,CAAC;IACH,CAAC;AACF,CAAC,CAAC;AAEF;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,OAAe,EAAE,QAAqB,EAAQ,EAAE;IACnF,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CAAC,2CAA2C,OAAO,EAAE,CAAC,CAAC;IACvE,CAAC;AACF,CAAC,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,MAAmB,EAAQ,EAAE;IAClE,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAoB,CAAC;IAE7C,wCAAwC;IACxC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC5B,MAAM,QAAQ,GAAG,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;QACrD,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC7B,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IACzC,CAAC;IAED,uCAAuC;IACvC,MAAM,UAAU,GAAa,EAAE,CAAC;IAChC,KAAK,MAAM,CAAC,SAAS,EAAE,QAAQ,CAAC,IAAI,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC;QACxD,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACzB,UAAU,CAAC,IAAI,CAAC,KAAK,SAAS,MAAM,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC7D,CAAC;IACF,CAAC;IAED,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3B,MAAM,IAAI,KAAK,CACd,oCAAoC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM;YAC9D,kDAAkD;YAClD,6FAA6F,CAC9F,CAAC;IACH,CAAC;AACF,CAAC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xmachines/play-router",
3
- "version": "1.0.0-beta.2",
3
+ "version": "1.0.0-beta.21",
4
4
  "description": "Route tree extraction from XState v5 state machines. Part of @xmachines/play Universal Player Architecture.",
5
5
  "keywords": [
6
6
  "routing",
@@ -11,39 +11,57 @@
11
11
  ],
12
12
  "license": "MIT",
13
13
  "author": "XMachines",
14
+ "files": [
15
+ "dist",
16
+ "README.md",
17
+ "LICENSE"
18
+ ],
14
19
  "type": "module",
15
20
  "exports": {
16
21
  ".": {
22
+ "source": "./src/index.ts",
17
23
  "types": "./dist/index.d.ts",
18
24
  "import": "./dist/index.js"
25
+ },
26
+ "./errors": {
27
+ "source": "./src/errors.ts",
28
+ "types": "./dist/errors.d.ts",
29
+ "import": "./dist/errors.js"
19
30
  }
20
31
  },
32
+ "publishConfig": {
33
+ "access": "public"
34
+ },
21
35
  "scripts": {
22
36
  "build": "tsc --build",
23
- "clean": "rm -rf dist *.tsbuildinfo",
24
- "typecheck": "tsc --noEmit",
25
- "test": "vitest run",
37
+ "clean": "rm -rf dist *.tsbuildinfo coverage .vitest-attachments test/browser/__screenshots__",
38
+ "test": "vitest",
26
39
  "prepublishOnly": "npm run build"
27
40
  },
28
41
  "dependencies": {
29
- "@xmachines/play-actor": "1.0.0-beta.2",
30
- "@xmachines/play-signals": "1.0.0-beta.2",
31
- "urlpattern-polyfill": "^10.1.0"
42
+ "@statelyai/graph": "^0.9.0",
43
+ "@xmachines/play": "1.0.0-beta.21",
44
+ "@xmachines/play-actor": "1.0.0-beta.21",
45
+ "@xmachines/play-signals": "1.0.0-beta.21",
46
+ "quick-lru": "^7.0.0"
32
47
  },
33
48
  "devDependencies": {
34
- "@types/node": "^25.4.0",
35
- "typescript": "^5.7.0",
36
- "xstate": "^5.28.0"
49
+ "@types/node": "^25.5.0",
50
+ "@xmachines/play-xstate": "1.0.0-beta.21",
51
+ "@xmachines/shared": "1.0.0-beta.21",
52
+ "typescript": "^5.9.3 || ^6.0.2",
53
+ "urlpattern-polyfill": "^10.1.0",
54
+ "vitest": "^4.1.2",
55
+ "xstate": "^5.30.0"
37
56
  },
38
57
  "peerDependencies": {
39
- "xstate": "^5.28.0"
58
+ "urlpattern-polyfill": "^10.1.0",
59
+ "xstate": "^5.30.0"
40
60
  },
41
- "publishConfig": {
42
- "access": "public"
61
+ "peerDependenciesMeta": {
62
+ "urlpattern-polyfill": {
63
+ "optional": true
64
+ }
43
65
  },
44
- "files": [
45
- "dist",
46
- "README.md",
47
- "LICENSE"
48
- ]
66
+ "_devDependencies_note": "xstate appears in both peerDependencies and devDependencies intentionally. devDependencies provides workspace resolution for local builds and tests. peerDependencies declares the consumer version constraint. Both are pinned to ^5.30.0 to prevent drift. urlpattern-polyfill is an optional peer dependency — consumers on Node < 24 or older browsers install it themselves. devDependencies entry ensures workspace test resolution."
49
67
  }
@@ -1,74 +0,0 @@
1
- import type { AnyStateMachine } from "xstate";
2
- import type { StateVisit } from "./types.js";
3
- /**
4
- * Crawl state machine graph using breadth-first traversal
5
- *
6
- * Visits all state nodes in the machine, including deeply nested states, and returns
7
- * complete list of visits with path and parent information. This enables systematic
8
- * discovery of all states for route extraction and tree building.
9
- *
10
- * **Architectural Context:** Implements **Actor Authority (INV-01)** by extracting
11
- * routing information from the state machine definition rather than external configuration.
12
- * The BFS traversal ensures all nested states are discovered, enabling the Actor to
13
- * define the complete navigation structure through its machine definition.
14
- *
15
- * @param machine - XState v5 state machine to crawl
16
- * @returns Array of state visits in breadth-first order
17
- *
18
- * @example
19
- * Basic machine crawl
20
- * ```typescript
21
- * import { createMachine } from "xstate";
22
- * import { crawlMachine } from "@xmachines/play-router";
23
- *
24
- * const machine = createMachine({
25
- * initial: 'home',
26
- * states: {
27
- * home: {},
28
- * dashboard: {
29
- * initial: 'overview',
30
- * states: {
31
- * overview: {},
32
- * settings: {}
33
- * }
34
- * }
35
- * }
36
- * });
37
- *
38
- * const visits = crawlMachine(machine);
39
- * // Returns visits for: root, home, dashboard, dashboard.overview, dashboard.settings
40
- * console.log(visits.map(v => v.path.join('.')));
41
- * // ['', 'home', 'dashboard', 'dashboard.overview', 'dashboard.settings']
42
- * ```
43
- *
44
- * @example
45
- * Extract state paths and parents
46
- * ```typescript
47
- * import { crawlMachine } from "@xmachines/play-router";
48
- *
49
- * const visits = crawlMachine(machine);
50
- * visits.forEach(visit => {
51
- * console.log({
52
- * path: visit.path.join('.') || 'root',
53
- * hasParent: !!visit.parent,
54
- * hasChildren: Object.keys(visit.node.states).length > 0
55
- * });
56
- * });
57
- * ```
58
- *
59
- * @see {@link https://gitlab.com/xmachin-es/rfc/-/blob/main/src/play-v1.md | RFC Play v1}
60
- * @see {@link extractRoute} for extracting route from individual states
61
- * @see {@link extractMachineRoutes} for complete route extraction
62
- * @see {@link StateVisit} for visit structure
63
- *
64
- * @remarks
65
- * **BFS Traversal:** Breadth-first search ensures systematic discovery of all states
66
- * at each nesting level before descending deeper. This produces a predictable ordering
67
- * useful for route tree construction and debugging.
68
- *
69
- * **Path Format:** Paths use array notation (`['dashboard', 'settings']`) which can be
70
- * joined with dots for state IDs (`'dashboard.settings'`) matching XState's hierarchical
71
- * state naming convention.
72
- */
73
- export declare const crawlMachine: (machine: AnyStateMachine) => StateVisit[];
74
- //# sourceMappingURL=crawl-machine.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"crawl-machine.d.ts","sourceRoot":"","sources":["../src/crawl-machine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqEG;AACH,eAAO,MAAM,YAAY,GAAI,SAAS,eAAe,KAAG,UAAU,EA0BjE,CAAC"}
@@ -1,95 +0,0 @@
1
- /**
2
- * Crawl state machine graph using breadth-first traversal
3
- *
4
- * Visits all state nodes in the machine, including deeply nested states, and returns
5
- * complete list of visits with path and parent information. This enables systematic
6
- * discovery of all states for route extraction and tree building.
7
- *
8
- * **Architectural Context:** Implements **Actor Authority (INV-01)** by extracting
9
- * routing information from the state machine definition rather than external configuration.
10
- * The BFS traversal ensures all nested states are discovered, enabling the Actor to
11
- * define the complete navigation structure through its machine definition.
12
- *
13
- * @param machine - XState v5 state machine to crawl
14
- * @returns Array of state visits in breadth-first order
15
- *
16
- * @example
17
- * Basic machine crawl
18
- * ```typescript
19
- * import { createMachine } from "xstate";
20
- * import { crawlMachine } from "@xmachines/play-router";
21
- *
22
- * const machine = createMachine({
23
- * initial: 'home',
24
- * states: {
25
- * home: {},
26
- * dashboard: {
27
- * initial: 'overview',
28
- * states: {
29
- * overview: {},
30
- * settings: {}
31
- * }
32
- * }
33
- * }
34
- * });
35
- *
36
- * const visits = crawlMachine(machine);
37
- * // Returns visits for: root, home, dashboard, dashboard.overview, dashboard.settings
38
- * console.log(visits.map(v => v.path.join('.')));
39
- * // ['', 'home', 'dashboard', 'dashboard.overview', 'dashboard.settings']
40
- * ```
41
- *
42
- * @example
43
- * Extract state paths and parents
44
- * ```typescript
45
- * import { crawlMachine } from "@xmachines/play-router";
46
- *
47
- * const visits = crawlMachine(machine);
48
- * visits.forEach(visit => {
49
- * console.log({
50
- * path: visit.path.join('.') || 'root',
51
- * hasParent: !!visit.parent,
52
- * hasChildren: Object.keys(visit.node.states).length > 0
53
- * });
54
- * });
55
- * ```
56
- *
57
- * @see {@link https://gitlab.com/xmachin-es/rfc/-/blob/main/src/play-v1.md | RFC Play v1}
58
- * @see {@link extractRoute} for extracting route from individual states
59
- * @see {@link extractMachineRoutes} for complete route extraction
60
- * @see {@link StateVisit} for visit structure
61
- *
62
- * @remarks
63
- * **BFS Traversal:** Breadth-first search ensures systematic discovery of all states
64
- * at each nesting level before descending deeper. This produces a predictable ordering
65
- * useful for route tree construction and debugging.
66
- *
67
- * **Path Format:** Paths use array notation (`['dashboard', 'settings']`) which can be
68
- * joined with dots for state IDs (`'dashboard.settings'`) matching XState's hierarchical
69
- * state naming convention.
70
- */
71
- export const crawlMachine = (machine) => {
72
- const visits = [];
73
- const queue = [
74
- {
75
- node: machine.root,
76
- path: [],
77
- parent: null,
78
- },
79
- ];
80
- while (queue.length > 0) {
81
- const visit = queue.shift();
82
- visits.push(visit);
83
- // Traverse child states
84
- const childStates = Object.entries(visit.node.states);
85
- for (const [key, childNode] of childStates) {
86
- queue.push({
87
- node: childNode,
88
- path: [...visit.path, key],
89
- parent: visit.node,
90
- });
91
- }
92
- }
93
- return visits;
94
- };
95
- //# sourceMappingURL=crawl-machine.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"crawl-machine.js","sourceRoot":"","sources":["../src/crawl-machine.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqEG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,OAAwB,EAAgB,EAAE;IACtE,MAAM,MAAM,GAAiB,EAAE,CAAC;IAChC,MAAM,KAAK,GAAiB;QAC3B;YACC,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,IAAI,EAAE,EAAE;YACR,MAAM,EAAE,IAAI;SACZ;KACD,CAAC;IAEF,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACzB,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,EAAG,CAAC;QAC7B,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAEnB,wBAAwB;QACxB,MAAM,WAAW,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACtD,KAAK,MAAM,CAAC,GAAG,EAAE,SAAS,CAAC,IAAI,WAAW,EAAE,CAAC;YAC5C,KAAK,CAAC,IAAI,CAAC;gBACV,IAAI,EAAE,SAAS;gBACf,IAAI,EAAE,CAAC,GAAG,KAAK,CAAC,IAAI,EAAE,GAAG,CAAC;gBAC1B,MAAM,EAAE,KAAK,CAAC,IAAI;aAClB,CAAC,CAAC;QACJ,CAAC;IACF,CAAC;IAED,OAAO,MAAM,CAAC;AACf,CAAC,CAAC"}
@@ -1,25 +0,0 @@
1
- import type { StateNode } from "xstate";
2
- import type { RouteInfo } from "./types.js";
3
- /**
4
- * Extract route information from state node with validation
5
- *
6
- * States with meta.route are "routable" - they can receive play.route events
7
- * (when machine is wrapped with formatPlayRouteTransitions).
8
- *
9
- * @param node - XState StateNode to extract route from
10
- * @param path - State path segments from root
11
- * @param stateMap - Map of all state IDs to StateNodes for validation
12
- * @returns RouteInfo if state has meta.route, null otherwise
13
- * @throws {Error} If route path is malformed (missing leading /)
14
- * @throws {Error} If route references non-existent state
15
- *
16
- * @example
17
- * ```typescript
18
- * const node = {
19
- * id: 'dashboard',
20
- * meta: { route: '/dashboard' }
21
- * };
22
- * ```
23
- */
24
- export declare const extractRoute: (node: StateNode, path: string[], stateMap: Map<string, StateNode>) => RouteInfo | null;
25
- //# sourceMappingURL=extract-route.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"extract-route.d.ts","sourceRoot":"","sources":["../src/extract-route.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACxC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAG5C;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,YAAY,GACxB,MAAM,SAAS,EACf,MAAM,MAAM,EAAE,EACd,UAAU,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,KAC9B,SAAS,GAAG,IAiDd,CAAC"}