@xmachines/play-router 1.0.0-beta.22 → 1.0.0-beta.23

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
@@ -12,7 +12,7 @@ It also exports `RouterBridgeBase`, the shared base class used by framework adap
12
12
 
13
13
  `RouterBridgeBase` is the policy point; framework adapters are thin ports that implement only framework-specific navigate/subscribe/unsubscribe behavior.
14
14
 
15
- The low-level `connectRouter()` path now uses the same router-to-actor event builder and route-map match helper as `RouterBridgeBase`, so pathname sanitization, state-id normalization, param extraction, and query extraction stay aligned across vanilla and framework adapters.
15
+ The low-level `connectRouter()` from `@xmachines/play-dom-router` uses the same router-to-actor event builder and route-map match helper as `RouterBridgeBase`, so pathname sanitization, state-id normalization, param extraction, and query extraction stay aligned across vanilla and framework adapters.
16
16
 
17
17
  Per [Play RFC](../docs/rfc/play.md), this package implements:
18
18
 
@@ -109,9 +109,7 @@ The demo demonstrates:
109
109
  **Run the demo:**
110
110
 
111
111
  ```bash
112
- cd packages/play-router/examples/demo
113
- npm install
114
- npm run dev
112
+ npm run dev -w packages/play-dom-router/examples/demo
115
113
  ```
116
114
 
117
115
  Open http://localhost:5174/ and explore:
@@ -180,7 +178,7 @@ Bridge teardown must be explicit and deterministic:
180
178
  - `disconnect`/`dispose` must unwatch signal subscriptions and unhook router listeners.
181
179
  - Do not rely on GC-only cleanup guidance.
182
180
  - Infrastructure remains passive: bridges observe and forward intents, actors decide validity.
183
- - `createBrowserHistory().destroy()` is idempotent and restores shared `window.history` patches only after the last wrapper for that window is removed.
181
+ - `createBrowserHistory().destroy()` (from `@xmachines/play-dom-router`) is idempotent and restores shared `window.history` patches only after the last wrapper for that window is removed.
184
182
  - **Note**: `createBrowserHistory()` mutates global `window.history` methods (`pushState` and `replaceState`) and coordinates wrappers with shared ref-count state. To reduce leakage, create one history wrapper per browser window at the application boundary and always pair it with `destroy()` during teardown.
185
183
 
186
184
  ## Bridge Sync Ordering
package/dist/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  export { RouterBridgeBase } from "./router-bridge-base.js";
2
2
  export type { RouteWatcherHandle } from "./router-bridge-base.js";
3
- export { sanitizePathname } from "./router-sync.js";
3
+ export { sanitizePathname, buildPlayRouteEvent, extractQuery } from "./router-sync.js";
4
+ export type { RouteMatch, BuildPlayRouteEventOptions } from "./router-sync.js";
4
5
  export { validateRouteFormat, validateStateExists, detectDuplicateRoutes, } from "./validate-routes.js";
5
6
  export { buildRouteTree } from "./build-tree.js";
6
7
  export { extractMachineRoutes } from "./extract-routes.js";
@@ -10,8 +11,5 @@ export type { MachineGraph } from "./machine-to-graph.js";
10
11
  export type { RouteInfo, RouteNode, RouteTree, RouteObject, RouteMetadata, PlayRouteEvent, RouterBridge, MachineNodeData, MachineEdgeData, } from "./types.js";
11
12
  export { createRouteMap, type RouteMap } from "./create-route-map.js";
12
13
  export { BaseRouteMap, type RouteMapping as BaseRouteMapping } from "./base-route-map.js";
13
- export { createBrowserHistory, type BrowserHistory, type BrowserWindow, } from "./create-browser-history.js";
14
- export { createRouter, type VanillaRouter } from "./create-router.js";
15
- export { connectRouter, type ConnectRouterOptions } from "./connect-router.js";
16
14
  export { findRouteById, findRouteByPath } from "./find-route.js";
17
15
  //# 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,MAAM,kBAAkB,CAAC;AAGpD,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,EACN,oBAAoB,EACpB,KAAK,cAAc,EACnB,KAAK,aAAa,GAClB,MAAM,6BAA6B,CAAC;AAGrC,OAAO,EAAE,YAAY,EAAE,KAAK,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAGtE,OAAO,EAAE,aAAa,EAAE,KAAK,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAG/E,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,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"}
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
- // Router sync utilities — sanitizePathname is used by adapters that bypass syncActorFromRouter()
4
- export { sanitizePathname } from "./router-sync.js";
3
+ // Router sync utilities — used by play-dom-router and adapters that bypass syncActorFromRouter()
4
+ export { sanitizePathname, buildPlayRouteEvent, extractQuery } 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";
@@ -15,12 +15,6 @@ export { createRouteMap } from "./create-route-map.js";
15
15
  // Re-exported as `BaseRouteMapping` (not `RouteMapping`) so adapter packages can
16
16
  // define their own local `RouteMapping` type without a name collision.
17
17
  export { BaseRouteMap } from "./base-route-map.js";
18
- // Browser history abstraction (aligned with TanStack Router)
19
- export { createBrowserHistory, } from "./create-browser-history.js";
20
- // Vanilla router (framework-agnostic)
21
- export { createRouter } from "./create-router.js";
22
- // Pure browser integration (low-level API)
23
- export { connectRouter } from "./connect-router.js";
24
18
  // Route lookup helpers — matchesPattern is private within find-route.ts
25
19
  export { findRouteById, findRouteByPath } from "./find-route.js";
26
20
  //# 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,MAAM,kBAAkB,CAAC;AAEpD,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,6DAA6D;AAC7D,OAAO,EACN,oBAAoB,GAGpB,MAAM,6BAA6B,CAAC;AAErC,sCAAsC;AACtC,OAAO,EAAE,YAAY,EAAsB,MAAM,oBAAoB,CAAC;AAEtE,2CAA2C;AAC3C,OAAO,EAAE,aAAa,EAA6B,MAAM,qBAAqB,CAAC;AAE/E,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,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,9 +1,9 @@
1
1
  import type { PlayRouteEvent } from "./types.js";
2
- interface RouteMatch {
2
+ export interface RouteMatch {
3
3
  to: string | null | undefined;
4
4
  params?: Record<string, string>;
5
5
  }
6
- interface BuildPlayRouteEventOptions {
6
+ export interface BuildPlayRouteEventOptions {
7
7
  pathname: string;
8
8
  search?: string | undefined;
9
9
  resolve: (sanitizedPathname: string) => RouteMatch;
@@ -50,13 +50,12 @@ export declare function extractQuery(search: string): Record<string, string>;
50
50
  /**
51
51
  * Build a normalized `play.route` event from raw router/browser input.
52
52
  *
53
- * Both `connectRouter()` and `RouterBridgeBase` use this helper so low-level and
54
- * framework adapters share the same pathname sanitization, route resolution, and
55
- * query extraction behavior.
53
+ * Both `connectRouter()` (from `@xmachines/play-dom-router`) and `RouterBridgeBase`
54
+ * use this helper so low-level and framework adapters share the same pathname
55
+ * sanitization, route resolution, and query extraction behavior.
56
56
  */
57
57
  export declare function buildPlayRouteEvent(options: BuildPlayRouteEventOptions): {
58
58
  pathname: string;
59
59
  event: PlayRouteEvent;
60
60
  } | null;
61
- export {};
62
61
  //# sourceMappingURL=router-sync.d.ts.map
@@ -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,UAAU,UAAU;IACnB,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC;AAED,UAAU,0BAA0B;IACnC,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;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"}
@@ -62,9 +62,9 @@ export function extractQuery(search) {
62
62
  /**
63
63
  * Build a normalized `play.route` event from raw router/browser input.
64
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.
65
+ * Both `connectRouter()` (from `@xmachines/play-dom-router`) and `RouterBridgeBase`
66
+ * use this helper so low-level and framework adapters share the same pathname
67
+ * sanitization, route resolution, and query extraction behavior.
68
68
  */
69
69
  export function buildPlayRouteEvent(options) {
70
70
  const pathname = sanitizePathname(options.pathname);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xmachines/play-router",
3
- "version": "1.0.0-beta.22",
3
+ "version": "1.0.0-beta.23",
4
4
  "description": "Route tree extraction from XState v5 state machines. Part of @xmachines/play Universal Player Architecture.",
5
5
  "keywords": [
6
6
  "routing",
@@ -34,23 +34,25 @@
34
34
  },
35
35
  "scripts": {
36
36
  "build": "tsc --build",
37
- "clean": "rm -rf dist *.tsbuildinfo coverage .vitest-attachments test/browser/__screenshots__ node_modules/.vite-temp",
37
+ "clean": "rm -rf dist *.tsbuildinfo coverage .vitest-attachments test/browser/__screenshots__ node_modules/.vite*",
38
38
  "lint": "oxlint .",
39
39
  "format": "oxfmt .",
40
40
  "test": "vitest",
41
41
  "prepublishOnly": "npm run build"
42
42
  },
43
43
  "dependencies": {
44
- "@statelyai/graph": "^0.9.0",
45
- "@xmachines/play": "1.0.0-beta.22",
46
- "@xmachines/play-actor": "1.0.0-beta.22",
47
- "@xmachines/play-signals": "1.0.0-beta.22",
44
+ "@statelyai/graph": "^0.10.0",
45
+ "@xmachines/play": "1.0.0-beta.23",
46
+ "@xmachines/play-actor": "1.0.0-beta.23",
47
+ "@xmachines/play-signals": "1.0.0-beta.23",
48
48
  "quick-lru": "^7.0.0"
49
49
  },
50
50
  "devDependencies": {
51
51
  "@types/node": "^25.5.0",
52
- "@xmachines/play-xstate": "1.0.0-beta.22",
53
- "@xmachines/shared": "1.0.0-beta.22",
52
+ "@xmachines/play-xstate": "1.0.0-beta.23",
53
+ "@xmachines/shared": "1.0.0-beta.23",
54
+ "oxfmt": "^0.43.0",
55
+ "oxlint": "^1.57.0",
54
56
  "typescript": "^5.9.3 || ^6.0.2",
55
57
  "urlpattern-polyfill": "^10.1.0",
56
58
  "vitest": "^4.1.2",
@@ -1,56 +0,0 @@
1
- import type { AbstractActor, Routable } from "@xmachines/play-actor";
2
- import type { AnyActorLogic } from "xstate";
3
- import type { VanillaRouter } from "./create-router.js";
4
- import type { RouteMap } from "./create-route-map.js";
5
- export interface ConnectRouterOptions {
6
- actor: AbstractActor<AnyActorLogic> & Routable;
7
- router: VanillaRouter;
8
- routeMap: RouteMap;
9
- }
10
- /**
11
- * Connect vanilla router to actor (pure browser integration).
12
- *
13
- * This is the LOW-LEVEL API for maximum control. No JSX, no rendering,
14
- * just actor ↔ router synchronization.
15
- *
16
- * Use this when:
17
- * - You want manual control over rendering
18
- * - Using non-JSX framework (jQuery, Alpine, HTMX, etc.)
19
- * - Building custom integration
20
- *
21
- * For JSX frameworks, use framework adapters instead:
22
- * - @xmachines/play-react (React components)
23
- * - Future: @xmachines/play-preact, @xmachines/play-solid, @xmachines/play-vue
24
- *
25
- * Architecture:
26
- * - Subscribes to history changes → sends play.route to actor
27
- * - Watches actor.currentRoute signal → updates browser URL
28
- * - Prevents circular updates (history change triggers actor, actor triggers history)
29
- * - Returns cleanup function
30
- *
31
- * Usage:
32
- * ```typescript
33
- * import { createBrowserHistory, createRouter, connectRouter } from '@xmachines/play-router';
34
- *
35
- * const history = createBrowserHistory({ window });
36
- * const router = createRouter({ routeTree, history });
37
- *
38
- * // Connect router to actor
39
- * const disconnect = connectRouter({ actor, router, routeMap });
40
- *
41
- * // User handles rendering (vanilla JS)
42
- * const watcher = new Signal.subtle.Watcher(() => {
43
- * queueMicrotask(() => {
44
- * const view = actor.currentView.get();
45
- * document.getElementById('app').innerHTML = render(view);
46
- * });
47
- * });
48
- * watcher.watch(actor.currentView);
49
- *
50
- * // Later: cleanup
51
- * disconnect();
52
- * watcher.unwatch(actor.currentView);
53
- * ```
54
- */
55
- export declare function connectRouter(options: ConnectRouterOptions): () => void;
56
- //# sourceMappingURL=connect-router.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"connect-router.d.ts","sourceRoot":"","sources":["../src/connect-router.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACrE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAC5C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAGtD,MAAM,WAAW,oBAAoB;IACpC,KAAK,EAAE,aAAa,CAAC,aAAa,CAAC,GAAG,QAAQ,CAAC;IAC/C,MAAM,EAAE,aAAa,CAAC;IACtB,QAAQ,EAAE,QAAQ,CAAC;CACnB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,MAAM,IAAI,CAqEvE"}
@@ -1,109 +0,0 @@
1
- import { watchSignal } from "@xmachines/play-signals";
2
- import { buildPlayRouteEvent } from "./router-sync.js";
3
- /**
4
- * Connect vanilla router to actor (pure browser integration).
5
- *
6
- * This is the LOW-LEVEL API for maximum control. No JSX, no rendering,
7
- * just actor ↔ router synchronization.
8
- *
9
- * Use this when:
10
- * - You want manual control over rendering
11
- * - Using non-JSX framework (jQuery, Alpine, HTMX, etc.)
12
- * - Building custom integration
13
- *
14
- * For JSX frameworks, use framework adapters instead:
15
- * - @xmachines/play-react (React components)
16
- * - Future: @xmachines/play-preact, @xmachines/play-solid, @xmachines/play-vue
17
- *
18
- * Architecture:
19
- * - Subscribes to history changes → sends play.route to actor
20
- * - Watches actor.currentRoute signal → updates browser URL
21
- * - Prevents circular updates (history change triggers actor, actor triggers history)
22
- * - Returns cleanup function
23
- *
24
- * Usage:
25
- * ```typescript
26
- * import { createBrowserHistory, createRouter, connectRouter } from '@xmachines/play-router';
27
- *
28
- * const history = createBrowserHistory({ window });
29
- * const router = createRouter({ routeTree, history });
30
- *
31
- * // Connect router to actor
32
- * const disconnect = connectRouter({ actor, router, routeMap });
33
- *
34
- * // User handles rendering (vanilla JS)
35
- * const watcher = new Signal.subtle.Watcher(() => {
36
- * queueMicrotask(() => {
37
- * const view = actor.currentView.get();
38
- * document.getElementById('app').innerHTML = render(view);
39
- * });
40
- * });
41
- * watcher.watch(actor.currentView);
42
- *
43
- * // Later: cleanup
44
- * disconnect();
45
- * watcher.unwatch(actor.currentView);
46
- * ```
47
- */
48
- export function connectRouter(options) {
49
- const { actor, router, routeMap } = options;
50
- const { history } = router;
51
- // Prevent circular updates — single navigation-processing guard.
52
- // Matches RouterBridgeBase.isProcessingNavigation pattern.
53
- // Reduces race-condition surface from 2³=8 flag combinations to 2.
54
- let isProcessingNavigation = false;
55
- // Subscribe to history changes (browser navigation)
56
- const unsubscribeHistory = history.subscribe((location) => {
57
- if (isProcessingNavigation)
58
- return;
59
- const nextRoute = buildPlayRouteEvent({
60
- pathname: location.pathname,
61
- search: location.search,
62
- resolve: (pathname) => routeMap.resolve(pathname),
63
- });
64
- if (nextRoute) {
65
- isProcessingNavigation = true;
66
- actor.send(nextRoute.event);
67
- // Check immediately if actor redirected (always-guard)
68
- // XState processes events synchronously, so snapshot is already updated
69
- const newActorRoute = actor.currentRoute.get();
70
- if (newActorRoute && newActorRoute !== nextRoute.pathname) {
71
- // Actor redirected - update URL
72
- history.replace(newActorRoute);
73
- }
74
- // Clear flag synchronously to prevent race conditions
75
- isProcessingNavigation = false;
76
- }
77
- });
78
- // Watch actor's currentRoute signal (actor-driven navigation)
79
- const unwatchRoute = watchSignal(actor.currentRoute, (route) => {
80
- if (isProcessingNavigation)
81
- return;
82
- const currentPath = history.location.pathname;
83
- if (route && route !== currentPath) {
84
- isProcessingNavigation = true;
85
- history.push(route);
86
- isProcessingNavigation = false;
87
- }
88
- });
89
- // Sync initial URL to actor
90
- // ONLY send route event if URL doesn't match actor's initial state
91
- const initialPath = history.location.pathname;
92
- const initialActorRoute = actor.currentRoute.get();
93
- if (initialPath !== initialActorRoute) {
94
- const nextRoute = buildPlayRouteEvent({
95
- pathname: initialPath,
96
- search: history.location.search,
97
- resolve: (pathname) => routeMap.resolve(pathname),
98
- });
99
- if (nextRoute) {
100
- actor.send(nextRoute.event);
101
- }
102
- }
103
- // Return cleanup
104
- return () => {
105
- unsubscribeHistory();
106
- unwatchRoute();
107
- };
108
- }
109
- //# sourceMappingURL=connect-router.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"connect-router.js","sourceRoot":"","sources":["../src/connect-router.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAKtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAQvD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AACH,MAAM,UAAU,aAAa,CAAC,OAA6B;IAC1D,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC;IAC5C,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC;IAE3B,iEAAiE;IACjE,2DAA2D;IAC3D,mEAAmE;IACnE,IAAI,sBAAsB,GAAG,KAAK,CAAC;IAEnC,oDAAoD;IACpD,MAAM,kBAAkB,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,QAAQ,EAAE,EAAE;QACzD,IAAI,sBAAsB;YAAE,OAAO;QAEnC,MAAM,SAAS,GAAG,mBAAmB,CAAC;YACrC,QAAQ,EAAE,QAAQ,CAAC,QAAQ;YAC3B,MAAM,EAAE,QAAQ,CAAC,MAAM;YACvB,OAAO,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC;SACjD,CAAC,CAAC;QACH,IAAI,SAAS,EAAE,CAAC;YACf,sBAAsB,GAAG,IAAI,CAAC;YAE9B,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;YAE5B,uDAAuD;YACvD,wEAAwE;YACxE,MAAM,aAAa,GAAG,KAAK,CAAC,YAAY,CAAC,GAAG,EAAE,CAAC;YAC/C,IAAI,aAAa,IAAI,aAAa,KAAK,SAAS,CAAC,QAAQ,EAAE,CAAC;gBAC3D,gCAAgC;gBAChC,OAAO,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;YAChC,CAAC;YAED,sDAAsD;YACtD,sBAAsB,GAAG,KAAK,CAAC;QAChC,CAAC;IACF,CAAC,CAAC,CAAC;IAEH,8DAA8D;IAC9D,MAAM,YAAY,GAAG,WAAW,CAAC,KAAK,CAAC,YAAY,EAAE,CAAC,KAAK,EAAE,EAAE;QAC9D,IAAI,sBAAsB;YAAE,OAAO;QAEnC,MAAM,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAC9C,IAAI,KAAK,IAAI,KAAK,KAAK,WAAW,EAAE,CAAC;YACpC,sBAAsB,GAAG,IAAI,CAAC;YAC9B,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACpB,sBAAsB,GAAG,KAAK,CAAC;QAChC,CAAC;IACF,CAAC,CAAC,CAAC;IAEH,4BAA4B;IAC5B,mEAAmE;IACnE,MAAM,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC;IAC9C,MAAM,iBAAiB,GAAG,KAAK,CAAC,YAAY,CAAC,GAAG,EAAE,CAAC;IAEnD,IAAI,WAAW,KAAK,iBAAiB,EAAE,CAAC;QACvC,MAAM,SAAS,GAAG,mBAAmB,CAAC;YACrC,QAAQ,EAAE,WAAW;YACrB,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,MAAM;YAC/B,OAAO,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC;SACjD,CAAC,CAAC;QACH,IAAI,SAAS,EAAE,CAAC;YACf,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QAC7B,CAAC;IACF,CAAC;IAED,iBAAiB;IACjB,OAAO,GAAG,EAAE;QACX,kBAAkB,EAAE,CAAC;QACrB,YAAY,EAAE,CAAC;IAChB,CAAC,CAAC;AACH,CAAC"}
@@ -1,106 +0,0 @@
1
- export interface BrowserHistory {
2
- /**
3
- * Get current location state
4
- */
5
- readonly location: {
6
- pathname: string;
7
- search: string;
8
- hash: string;
9
- state: unknown;
10
- };
11
- /**
12
- * Push new URL to history
13
- */
14
- push(path: string, state?: unknown): void;
15
- /**
16
- * Replace current URL in history
17
- */
18
- replace(path: string, state?: unknown): void;
19
- /**
20
- * Go back/forward
21
- */
22
- go(delta: number): void;
23
- back(): void;
24
- forward(): void;
25
- /**
26
- * Subscribe to history changes
27
- * Returns unsubscribe function
28
- */
29
- subscribe(listener: (location: BrowserHistory["location"]) => void): () => void;
30
- /**
31
- * Create href from path
32
- */
33
- createHref(path: string): string;
34
- /**
35
- * Cleanup.
36
- *
37
- * Safe to call more than once. When multiple wrappers share the same
38
- * `window.history`, the original methods are restored only after the last
39
- * wrapper is destroyed.
40
- */
41
- destroy(): void;
42
- }
43
- /**
44
- * Minimal window interface for createBrowserHistory
45
- *
46
- * Structural interface covering only the properties actually used.
47
- * Accepts Window, JSDOM window, or any compatible test double.
48
- * Avoids coupling to `Window & typeof globalThis` which varies across environments.
49
- *
50
- * @public
51
- */
52
- export interface BrowserWindow {
53
- history: {
54
- readonly state: unknown;
55
- pushState(state: unknown, title: string, url?: string | null): void;
56
- replaceState(state: unknown, title: string, url?: string | null): void;
57
- go(delta: number): void;
58
- back(): void;
59
- forward(): void;
60
- };
61
- location: {
62
- readonly pathname: string;
63
- readonly search: string;
64
- readonly hash: string;
65
- };
66
- addEventListener(type: "popstate", listener: () => void): void;
67
- removeEventListener(type: "popstate", listener: () => void): void;
68
- }
69
- /**
70
- * Create browser history that wraps window.history
71
- *
72
- * Aligned with TanStack Router's history interface for API parallelism.
73
- *
74
- * Architecture:
75
- * - Patches window.history.pushState/replaceState to detect changes
76
- * - Listens to popstate for browser back/forward
77
- * - Provides subscribe() for listeners (like PlayRouterProvider)
78
- * - Testable (accepts window object)
79
- *
80
- * Usage:
81
- * ```typescript
82
- * const history = createBrowserHistory({ window });
83
- *
84
- * const unsubscribe = history.subscribe((location) => {
85
- * console.log('URL changed:', location.pathname);
86
- * });
87
- *
88
- * history.push('/new-path');
89
- *
90
- * // Later:
91
- * unsubscribe();
92
- * history.destroy();
93
- * ```
94
- *
95
- * `destroy()` is idempotent and cooperates with other wrappers created for the
96
- * same `window` instance.
97
- *
98
- * **Warning**: `createBrowserHistory()` mutates global `window.history` methods
99
- * (`pushState` and `replaceState`) and coordinates wrappers with shared ref-count state.
100
- * To mitigate leakage, create one history wrapper per browser window at the application
101
- * boundary and always pair it with `destroy()` during teardown.
102
- */
103
- export declare function createBrowserHistory(options: {
104
- window: BrowserWindow;
105
- }): BrowserHistory;
106
- //# sourceMappingURL=create-browser-history.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"create-browser-history.d.ts","sourceRoot":"","sources":["../src/create-browser-history.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,cAAc;IAC9B;;OAEG;IACH,QAAQ,CAAC,QAAQ,EAAE;QAClB,QAAQ,EAAE,MAAM,CAAC;QACjB,MAAM,EAAE,MAAM,CAAC;QACf,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,OAAO,CAAC;KACf,CAAC;IAEF;;OAEG;IACH,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAE1C;;OAEG;IACH,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAE7C;;OAEG;IACH,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,IAAI,IAAI,IAAI,CAAC;IACb,OAAO,IAAI,IAAI,CAAC;IAEhB;;;OAGG;IACH,SAAS,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,cAAc,CAAC,UAAU,CAAC,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;IAEhF;;OAEG;IACH,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IAEjC;;;;;;OAMG;IACH,OAAO,IAAI,IAAI,CAAC;CAChB;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,aAAa;IAC7B,OAAO,EAAE;QACR,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;QACxB,SAAS,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAAC;QACpE,YAAY,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAAC;QACvE,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;QACxB,IAAI,IAAI,IAAI,CAAC;QACb,OAAO,IAAI,IAAI,CAAC;KAChB,CAAC;IACF,QAAQ,EAAE;QACT,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;QAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;KACtB,CAAC;IACF,gBAAgB,CAAC,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;IAC/D,mBAAmB,CAAC,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;CAClE;AAWD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE;IAAE,MAAM,EAAE,aAAa,CAAA;CAAE,GAAG,cAAc,CA8EvF"}
@@ -1,125 +0,0 @@
1
- const historyPatchStates = new WeakMap();
2
- /**
3
- * Create browser history that wraps window.history
4
- *
5
- * Aligned with TanStack Router's history interface for API parallelism.
6
- *
7
- * Architecture:
8
- * - Patches window.history.pushState/replaceState to detect changes
9
- * - Listens to popstate for browser back/forward
10
- * - Provides subscribe() for listeners (like PlayRouterProvider)
11
- * - Testable (accepts window object)
12
- *
13
- * Usage:
14
- * ```typescript
15
- * const history = createBrowserHistory({ window });
16
- *
17
- * const unsubscribe = history.subscribe((location) => {
18
- * console.log('URL changed:', location.pathname);
19
- * });
20
- *
21
- * history.push('/new-path');
22
- *
23
- * // Later:
24
- * unsubscribe();
25
- * history.destroy();
26
- * ```
27
- *
28
- * `destroy()` is idempotent and cooperates with other wrappers created for the
29
- * same `window` instance.
30
- *
31
- * **Warning**: `createBrowserHistory()` mutates global `window.history` methods
32
- * (`pushState` and `replaceState`) and coordinates wrappers with shared ref-count state.
33
- * To mitigate leakage, create one history wrapper per browser window at the application
34
- * boundary and always pair it with `destroy()` during teardown.
35
- */
36
- export function createBrowserHistory(options) {
37
- const win = options.window;
38
- const listeners = new Set();
39
- const patchState = getOrCreatePatchState(win);
40
- let destroyed = false;
41
- function getLocation() {
42
- return {
43
- pathname: win.location.pathname,
44
- search: win.location.search,
45
- hash: win.location.hash,
46
- state: win.history.state,
47
- };
48
- }
49
- function notify() {
50
- const location = getLocation();
51
- listeners.forEach((listener) => listener(location));
52
- }
53
- patchState.wrappers.add(notify);
54
- // Listen to popstate
55
- const popstateHandler = () => notify();
56
- win.addEventListener("popstate", popstateHandler);
57
- return {
58
- get location() {
59
- return getLocation();
60
- },
61
- push(path, state) {
62
- win.history.pushState(state, "", path);
63
- },
64
- replace(path, state) {
65
- win.history.replaceState(state, "", path);
66
- },
67
- go(delta) {
68
- win.history.go(delta);
69
- },
70
- back() {
71
- win.history.back();
72
- },
73
- forward() {
74
- win.history.forward();
75
- },
76
- subscribe(listener) {
77
- listeners.add(listener);
78
- return () => listeners.delete(listener);
79
- },
80
- createHref(path) {
81
- return path;
82
- },
83
- destroy() {
84
- if (destroyed) {
85
- return;
86
- }
87
- destroyed = true;
88
- patchState.wrappers.delete(notify);
89
- patchState.refCount -= 1;
90
- win.removeEventListener("popstate", popstateHandler);
91
- listeners.clear();
92
- if (patchState.refCount === 0) {
93
- win.history.pushState = patchState.originalPushState;
94
- win.history.replaceState = patchState.originalReplaceState;
95
- historyPatchStates.delete(win.history);
96
- }
97
- },
98
- };
99
- }
100
- function getOrCreatePatchState(win) {
101
- const existing = historyPatchStates.get(win.history);
102
- if (existing) {
103
- existing.refCount += 1;
104
- return existing;
105
- }
106
- const originalPushState = win.history.pushState;
107
- const originalReplaceState = win.history.replaceState;
108
- const patchState = {
109
- originalPushState,
110
- originalReplaceState,
111
- wrappers: new Set(),
112
- refCount: 1,
113
- };
114
- win.history.pushState = function (state, title, url) {
115
- patchState.originalPushState.call(win.history, state, title, url);
116
- patchState.wrappers.forEach((notify) => notify());
117
- };
118
- win.history.replaceState = function (state, title, url) {
119
- patchState.originalReplaceState.call(win.history, state, title, url);
120
- patchState.wrappers.forEach((notify) => notify());
121
- };
122
- historyPatchStates.set(win.history, patchState);
123
- return patchState;
124
- }
125
- //# sourceMappingURL=create-browser-history.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"create-browser-history.js","sourceRoot":"","sources":["../src/create-browser-history.ts"],"names":[],"mappings":"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"}
@@ -1,73 +0,0 @@
1
- import type { RouteTree } from "./types.js";
2
- import type { BrowserHistory } from "./create-browser-history.js";
3
- export interface VanillaRouter {
4
- /**
5
- * History instance
6
- */
7
- readonly history: BrowserHistory;
8
- /**
9
- * Route tree (for structure reference)
10
- */
11
- readonly routeTree: RouteTree;
12
- /**
13
- * Cleanup
14
- */
15
- destroy(): void;
16
- }
17
- /**
18
- * Create vanilla router for framework-agnostic routing.
19
- *
20
- * Architecture:
21
- * - Just wraps history and routeTree
22
- * - Does NOT embed routeMap (providers need it as prop)
23
- * - Framework-agnostic history management only
24
- *
25
- * Why no routeMap:
26
- * - Router doesn't know about state IDs (that's Play-specific)
27
- * - RouteMap is the bridge between router and actor
28
- * - Provider receives routeMap as prop to do path → state ID resolution
29
- *
30
- * Usage (parallel to TanStack mode):
31
- * ```typescript
32
- * // Both modes: identical setup
33
- * const routeTree = extractMachineRoutes(machine);
34
- * const routeMap = createRouteMap(routeTree);
35
- * const history = createBrowserHistory({ window });
36
- *
37
- * // Vanilla router
38
- * const router = createRouter({ routeTree, history });
39
- *
40
- * // Provider needs routeMap as prop (router doesn't have it)
41
- * <PlayRouterProvider
42
- * actor={actor}
43
- * router={router}
44
- * routeMap={routeMap} // ← Must pass separately
45
- * renderer={(currentActor, currentRouter) => {
46
- * void currentRouter;
47
- * return <Renderer actor={currentActor} components={components} />;
48
- * }}
49
- * />
50
- * ```
51
- *
52
- * Compare to TanStack mode:
53
- * ```typescript
54
- * // TanStack router (external library)
55
- * const router = TanStackCreateRouter({ routeTree, history });
56
- *
57
- * // Provider needs routeMap as prop (same as vanilla!)
58
- * <PlayRouterProvider
59
- * actor={actor}
60
- * router={router}
61
- * routeMap={routeMap} // ← Must pass separately
62
- * renderer={(currentActor, currentRouter) => {
63
- * void currentRouter;
64
- * return <Renderer actor={currentActor} components={components} />;
65
- * }}
66
- * />
67
- * ```
68
- */
69
- export declare function createRouter(options: {
70
- routeTree: RouteTree;
71
- history: BrowserHistory;
72
- }): VanillaRouter;
73
- //# sourceMappingURL=create-router.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"create-router.d.ts","sourceRoot":"","sources":["../src/create-router.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAElE,MAAM,WAAW,aAAa;IAC7B;;OAEG;IACH,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAC;IAEjC;;OAEG;IACH,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAE9B;;OAEG;IACH,OAAO,IAAI,IAAI,CAAC;CAChB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmDG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE;IACrC,SAAS,EAAE,SAAS,CAAC;IACrB,OAAO,EAAE,cAAc,CAAC;CACxB,GAAG,aAAa,CAWhB"}
@@ -1,63 +0,0 @@
1
- /**
2
- * Create vanilla router for framework-agnostic routing.
3
- *
4
- * Architecture:
5
- * - Just wraps history and routeTree
6
- * - Does NOT embed routeMap (providers need it as prop)
7
- * - Framework-agnostic history management only
8
- *
9
- * Why no routeMap:
10
- * - Router doesn't know about state IDs (that's Play-specific)
11
- * - RouteMap is the bridge between router and actor
12
- * - Provider receives routeMap as prop to do path → state ID resolution
13
- *
14
- * Usage (parallel to TanStack mode):
15
- * ```typescript
16
- * // Both modes: identical setup
17
- * const routeTree = extractMachineRoutes(machine);
18
- * const routeMap = createRouteMap(routeTree);
19
- * const history = createBrowserHistory({ window });
20
- *
21
- * // Vanilla router
22
- * const router = createRouter({ routeTree, history });
23
- *
24
- * // Provider needs routeMap as prop (router doesn't have it)
25
- * <PlayRouterProvider
26
- * actor={actor}
27
- * router={router}
28
- * routeMap={routeMap} // ← Must pass separately
29
- * renderer={(currentActor, currentRouter) => {
30
- * void currentRouter;
31
- * return <Renderer actor={currentActor} components={components} />;
32
- * }}
33
- * />
34
- * ```
35
- *
36
- * Compare to TanStack mode:
37
- * ```typescript
38
- * // TanStack router (external library)
39
- * const router = TanStackCreateRouter({ routeTree, history });
40
- *
41
- * // Provider needs routeMap as prop (same as vanilla!)
42
- * <PlayRouterProvider
43
- * actor={actor}
44
- * router={router}
45
- * routeMap={routeMap} // ← Must pass separately
46
- * renderer={(currentActor, currentRouter) => {
47
- * void currentRouter;
48
- * return <Renderer actor={currentActor} components={components} />;
49
- * }}
50
- * />
51
- * ```
52
- */
53
- export function createRouter(options) {
54
- const { routeTree, history } = options;
55
- return {
56
- routeTree,
57
- history,
58
- destroy() {
59
- history.destroy();
60
- },
61
- };
62
- }
63
- //# sourceMappingURL=create-router.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"create-router.js","sourceRoot":"","sources":["../src/create-router.ts"],"names":[],"mappings":"AAoBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmDG;AACH,MAAM,UAAU,YAAY,CAAC,OAG5B;IACA,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;IAEvC,OAAO;QACN,SAAS;QACT,OAAO;QAEP,OAAO;YACN,OAAO,CAAC,OAAO,EAAE,CAAC;QACnB,CAAC;KACD,CAAC;AACH,CAAC"}