@xmachines/play-tanstack-react-router 1.0.0-beta.1 → 1.0.0-beta.10

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 (179) hide show
  1. package/README.md +35 -23
  2. package/dist/route-map.d.ts +26 -56
  3. package/dist/route-map.d.ts.map +1 -1
  4. package/dist/route-map.js +18 -87
  5. package/dist/route-map.js.map +1 -1
  6. package/package.json +25 -17
  7. package/.oxfmtrc.json +0 -3
  8. package/.oxlintrc.json +0 -3
  9. package/examples/demo/README.md +0 -100
  10. package/examples/demo/docs/ARCHITECTURE.md +0 -643
  11. package/examples/demo/docs/INVARIANTS.md +0 -461
  12. package/examples/demo/docs/SWAP-REACT.md +0 -635
  13. package/examples/demo/index.html +0 -16
  14. package/examples/demo/package.json +0 -39
  15. package/examples/demo/src/App.tsx +0 -148
  16. package/examples/demo/src/components/About.tsx +0 -49
  17. package/examples/demo/src/components/Contact.tsx +0 -43
  18. package/examples/demo/src/components/Dashboard.tsx +0 -46
  19. package/examples/demo/src/components/DebugPanel.tsx +0 -68
  20. package/examples/demo/src/components/HeaderNav.tsx +0 -103
  21. package/examples/demo/src/components/Home.tsx +0 -41
  22. package/examples/demo/src/components/Login.tsx +0 -82
  23. package/examples/demo/src/components/Navigation.tsx +0 -262
  24. package/examples/demo/src/components/Profile.tsx +0 -46
  25. package/examples/demo/src/components/Register.tsx +0 -109
  26. package/examples/demo/src/components/Settings.tsx +0 -92
  27. package/examples/demo/src/components/index.ts +0 -16
  28. package/examples/demo/src/main.tsx +0 -20
  29. package/examples/demo/test/actor-authority.test.ts +0 -50
  30. package/examples/demo/test/browser/__screenshots__/back-button-duplicate.browser.test.tsx/Browser-back-button-navigates-through-unique-history--no-duplicates--1.png +0 -0
  31. package/examples/demo/test/browser/__screenshots__/back-button-duplicate.browser.test.tsx/GAP-12--navigation-via-goto---events-creates-single-history-entries-1.png +0 -0
  32. package/examples/demo/test/browser/__screenshots__/back-button-duplicate.browser.test.tsx/GAP-12--navigation-via-goto---events-creates-single-history-entries-2.png +0 -0
  33. package/examples/demo/test/browser/__screenshots__/back-forward-sync.browser.test.tsx/Back-Forward--After-authentication-flow-1.png +0 -0
  34. package/examples/demo/test/browser/__screenshots__/back-forward-sync.browser.test.tsx/Back-Forward--Multiple-rapid-navigations-1.png +0 -0
  35. package/examples/demo/test/browser/__screenshots__/back-forward-sync.browser.test.tsx/Back-Forward--Multiple-rapid-navigations-2.png +0 -0
  36. package/examples/demo/test/browser/__screenshots__/back-forward-sync.browser.test.tsx/Back-Forward--URL-stays-in-sync-with-actor-state-1.png +0 -0
  37. package/examples/demo/test/browser/__screenshots__/back-forward-sync.browser.test.tsx/Back-Forward--URL-stays-in-sync-with-actor-state-2.png +0 -0
  38. package/examples/demo/test/browser/__screenshots__/back-forward-sync.browser.test.tsx/Back-Forward--Works-correctly-1.png +0 -0
  39. package/examples/demo/test/browser/__screenshots__/back-forward-sync.browser.test.tsx/Back-Forward--Works-correctly-2.png +0 -0
  40. package/examples/demo/test/browser/__screenshots__/direct-navigation.browser.test.ts/Direct-navigation-to--about-loads-about-page-1.png +0 -0
  41. package/examples/demo/test/browser/__screenshots__/direct-navigation.browser.test.ts/Direct-navigation-to--contact-loads-contact-page-1.png +0 -0
  42. package/examples/demo/test/browser/__screenshots__/direct-navigation.browser.test.ts/Direct-navigation-to--home-loads-home-page-1.png +0 -0
  43. package/examples/demo/test/browser/__screenshots__/direct-navigation.browser.test.ts/Direct-navigation-to-protected-route-while-authenticated-loads-dashboard-1.png +0 -0
  44. package/examples/demo/test/browser/__screenshots__/direct-navigation.browser.test.ts/Direct-navigation-to-protected-route-while-unauthenticated-redirects-to-login-1.png +0 -0
  45. package/examples/demo/test/browser/__screenshots__/exact-user-scenario.browser.test.tsx/Debug--Print-history-after-each-navigation-1.png +0 -0
  46. package/examples/demo/test/browser/__screenshots__/exact-user-scenario.browser.test.tsx/Debug--Print-history-after-each-navigation-2.png +0 -0
  47. package/examples/demo/test/browser/__screenshots__/exact-user-scenario.browser.test.tsx/EXACT-USER-SCENARIO--home---about---home---contact---home--then-back-3x-should-land-on-about-1.png +0 -0
  48. package/examples/demo/test/browser/__screenshots__/exact-user-scenario.browser.test.tsx/EXACT-USER-SCENARIO--home---about---home---contact---home--then-back-3x-should-land-on-about-2.png +0 -0
  49. package/examples/demo/test/browser/__screenshots__/guard-rejection.browser.test.tsx/E2E--Actor-Authority---infrastructure-cannot-override-guards-1.png +0 -0
  50. package/examples/demo/test/browser/__screenshots__/guard-rejection.browser.test.tsx/E2E--Actor-Authority---infrastructure-cannot-override-guards-2.png +0 -0
  51. package/examples/demo/test/browser/__screenshots__/guard-rejection.browser.test.tsx/E2E--Guards-reject-invalid-navigation-1.png +0 -0
  52. package/examples/demo/test/browser/__screenshots__/guard-rejection.browser.test.tsx/E2E--Guards-reject-invalid-navigation-2.png +0 -0
  53. package/examples/demo/test/browser/__screenshots__/history-investigation.browser.test.tsx/baseHistory-back---navigation--avoiding-window-history--1.png +0 -0
  54. package/examples/demo/test/browser/__screenshots__/history-investigation.browser.test.tsx/baseHistory-back---navigation--avoiding-window-history--2.png +0 -0
  55. package/examples/demo/test/browser/__screenshots__/history-navigation.browser.test.ts/GAP-12--Back-forward-with-guard-transitions---authenticated-user-1.png +0 -0
  56. package/examples/demo/test/browser/__screenshots__/history-navigation.browser.test.ts/GAP-12--Back-forward-with-guard-transitions---authenticated-user-2.png +0 -0
  57. package/examples/demo/test/browser/__screenshots__/history-navigation.browser.test.ts/GAP-12--Back-forward-with-guard-transitions---unauthenticated-user-1.png +0 -0
  58. package/examples/demo/test/browser/__screenshots__/history-navigation.browser.test.ts/GAP-12--Back-forward-with-guard-transitions---unauthenticated-user-2.png +0 -0
  59. package/examples/demo/test/browser/__screenshots__/history-navigation.browser.test.ts/GAP-12--Back-with-guard---authenticated-user-navigates-back-1.png +0 -0
  60. package/examples/demo/test/browser/__screenshots__/history-navigation.browser.test.ts/GAP-12--Back-with-guard---authenticated-user-navigates-back-2.png +0 -0
  61. package/examples/demo/test/browser/__screenshots__/history-navigation.browser.test.ts/GAP-12--Back-with-guard---unauthenticated-user-stays-on-public-routes-1.png +0 -0
  62. package/examples/demo/test/browser/__screenshots__/history-navigation.browser.test.ts/GAP-12--Back-with-guard---unauthenticated-user-stays-on-public-routes-2.png +0 -0
  63. package/examples/demo/test/browser/__screenshots__/history-navigation.browser.test.ts/GAP-12--Forward-button-after-back---unique-history-1.png +0 -0
  64. package/examples/demo/test/browser/__screenshots__/history-navigation.browser.test.ts/GAP-12--Forward-button-after-back---unique-history-2.png +0 -0
  65. package/examples/demo/test/browser/__screenshots__/history-navigation.browser.test.ts/GAP-12--Forward-button-after-back-1.png +0 -0
  66. package/examples/demo/test/browser/__screenshots__/history-navigation.browser.test.ts/GAP-12--Forward-button-after-back-2.png +0 -0
  67. package/examples/demo/test/browser/__screenshots__/history-navigation.browser.test.ts/GAP-12--Navigate-forward-then-back---unique-history-entries-1.png +0 -0
  68. package/examples/demo/test/browser/__screenshots__/history-navigation.browser.test.ts/GAP-12--Navigate-forward-then-back---unique-history-entries-2.png +0 -0
  69. package/examples/demo/test/browser/__screenshots__/history-navigation.browser.test.ts/GAP-12--Rapid-back-forward-navigation-doesn-t-cause-duplicate-entries-1.png +0 -0
  70. package/examples/demo/test/browser/__screenshots__/history-navigation.browser.test.ts/GAP-12--Rapid-back-forward-navigation-doesn-t-cause-duplicate-entries-2.png +0 -0
  71. package/examples/demo/test/browser/__screenshots__/history-navigation.browser.test.ts/GAP-12--Single-back-navigation---about-to-home-1.png +0 -0
  72. package/examples/demo/test/browser/__screenshots__/history-navigation.browser.test.ts/GAP-12--Single-back-navigation---about-to-home-2.png +0 -0
  73. package/examples/demo/test/browser/__screenshots__/history-navigation.browser.test.ts/GAP-12--Single-back-navigation---contact-to-about-1.png +0 -0
  74. package/examples/demo/test/browser/__screenshots__/history-navigation.browser.test.ts/GAP-12--Single-back-navigation---contact-to-about-2.png +0 -0
  75. package/examples/demo/test/browser/__screenshots__/history-navigation.browser.test.ts/GAP-12--View-syncs-with-URL-after-back-forward-1.png +0 -0
  76. package/examples/demo/test/browser/__screenshots__/history-navigation.browser.test.ts/GAP-12--View-syncs-with-URL-after-back-forward-2.png +0 -0
  77. package/examples/demo/test/browser/__screenshots__/history-navigation.browser.test.ts/GAP-12--View-syncs-with-URL-after-back-navigation-1.png +0 -0
  78. package/examples/demo/test/browser/__screenshots__/history-navigation.browser.test.ts/GAP-12--View-syncs-with-URL-after-back-navigation-2.png +0 -0
  79. package/examples/demo/test/browser/__screenshots__/login-flow.browser.test.tsx/E2E--User-can-log-in-and-see-dashboard-1.png +0 -0
  80. package/examples/demo/test/browser/__screenshots__/login-flow.browser.test.tsx/E2E--User-can-log-in-and-see-dashboard-2.png +0 -0
  81. package/examples/demo/test/browser/__screenshots__/navigation.browser.test.tsx/E2E--Navigation-reflects-actor-state-transitions-1.png +0 -0
  82. package/examples/demo/test/browser/__screenshots__/navigation.browser.test.tsx/E2E--Navigation-reflects-actor-state-transitions-2.png +0 -0
  83. package/examples/demo/test/browser/__screenshots__/protected-route-navigation.browser.test.tsx/Browser-back-forward-through-multiple-protected-routes-1.png +0 -0
  84. package/examples/demo/test/browser/__screenshots__/protected-route-navigation.browser.test.tsx/Browser-back-forward-through-multiple-protected-routes-2.png +0 -0
  85. package/examples/demo/test/browser/__screenshots__/protected-route-navigation.browser.test.tsx/Browser-back-navigates-from-dashboard-to-settings--protected-route--1.png +0 -0
  86. package/examples/demo/test/browser/__screenshots__/protected-route-navigation.browser.test.tsx/Browser-back-navigates-from-dashboard-to-settings--protected-route--2.png +0 -0
  87. package/examples/demo/test/browser/__screenshots__/protected-route-navigation.browser.test.tsx/RED--Browser-back-forward-through-multiple-protected-routes-1.png +0 -0
  88. package/examples/demo/test/browser/__screenshots__/protected-route-navigation.browser.test.tsx/RED--Browser-back-from-dashboard-to-settings--protected-route--1.png +0 -0
  89. package/examples/demo/test/browser/__screenshots__/protected-route-navigation.browser.test.tsx/RED--Browser-back-navigates-from-dashboard-to-settings--protected-route--1.png +0 -0
  90. package/examples/demo/test/browser/__screenshots__/settings-parameter.browser.test.tsx/Settings-Parameter-Display-should-display--account--section-when-navigating-to--settings-account-1.png +0 -0
  91. package/examples/demo/test/browser/__screenshots__/settings-parameter.browser.test.tsx/Settings-Parameter-Display-should-display--account--section-when-navigating-to--settings-account-2.png +0 -0
  92. package/examples/demo/test/browser/__screenshots__/settings-parameter.browser.test.tsx/Settings-Parameter-Display-should-display--general--section-when-navigating-to--settings--no-parameter--1.png +0 -0
  93. package/examples/demo/test/browser/__screenshots__/settings-parameter.browser.test.tsx/Settings-Parameter-Display-should-display--general--section-when-navigating-to--settings--no-parameter--2.png +0 -0
  94. package/examples/demo/test/browser/__screenshots__/settings-parameter.browser.test.tsx/Settings-Parameter-Display-should-display--profile--section-when-navigating-to--settings-profile-1.png +0 -0
  95. package/examples/demo/test/browser/__screenshots__/settings-parameter.browser.test.tsx/Settings-Parameter-Display-should-display--profile--section-when-navigating-to--settings-profile-2.png +0 -0
  96. package/examples/demo/test/browser/__screenshots__/settings-parameter.browser.test.tsx/Settings-Parameter-Display-should-update-section-display-when-clicking-section-navigation-buttons-1.png +0 -0
  97. package/examples/demo/test/browser/__screenshots__/settings-parameter.browser.test.tsx/Settings-Parameter-Display-should-update-section-display-when-clicking-section-navigation-buttons-2.png +0 -0
  98. package/examples/demo/test/browser/__screenshots__/settings-query-freeze.browser.test.ts/Settings-with-query-parameters-works-correctly-1.png +0 -0
  99. package/examples/demo/test/browser/__screenshots__/settings-query-freeze.browser.test.ts/Settings-with-section-parameter-works-correctly-1.png +0 -0
  100. package/examples/demo/test/browser/__screenshots__/state-driven.browser.test.ts/DEMO-04--State-Driven-Reset---Browser-back-sends-event-to-actor-1.png +0 -0
  101. package/examples/demo/test/browser/__screenshots__/state-driven.browser.test.ts/DEMO-04--State-Driven-Reset---Browser-back-sends-event-to-actor-2.png +0 -0
  102. package/examples/demo/test/browser/__screenshots__/state-driven.browser.test.ts/DEMO-04b--Browser-navigation-with-SignalSyncedHistory-integration-1.png +0 -0
  103. package/examples/demo/test/browser/__screenshots__/state-driven.browser.test.ts/DEMO-04b--Browser-navigation-with-SignalSyncedHistory-integration-2.png +0 -0
  104. package/examples/demo/test/browser/__screenshots__/tanstack-integration.browser.test.tsx/TanStack-Router-Integration-renders-with-RouterProvider-context-1.png +0 -0
  105. package/examples/demo/test/browser/__screenshots__/tanstack-integration.browser.test.tsx/TanStack-Router-Integration-renders-with-RouterProvider-context-2.png +0 -0
  106. package/examples/demo/test/browser/__screenshots__/test-multiple-back.browser.test.tsx/Multiple-back--Navigate-forward-3x-then-back-3x-1.png +0 -0
  107. package/examples/demo/test/browser/__screenshots__/uat-xstate-route-regression.browser.test.ts/UAT-1--Opening-with--someinvalidstate-stays-at-current-state-1.png +0 -0
  108. package/examples/demo/test/browser/__screenshots__/uat-xstate-route-regression.browser.test.ts/UAT-2--Opening-with--about-renders-About-component--not-Login-1.png +0 -0
  109. package/examples/demo/test/browser/__screenshots__/uat-xstate-route-regression.browser.test.ts/UAT-2b--Opening-with--home-renders-Home-component--not-Login-1.png +0 -0
  110. package/examples/demo/test/browser/__screenshots__/uat-xstate-route-regression.browser.test.ts/UAT-2c--Opening-with--contact-renders-Contact-component--not-Login-1.png +0 -0
  111. package/examples/demo/test/browser/__screenshots__/uat-xstate-route-regression.browser.test.ts/UAT-3--Back-forward-navigation---rendering-syncs-with-URL-1.png +0 -0
  112. package/examples/demo/test/browser/__screenshots__/uat-xstate-route-regression.browser.test.ts/UAT-3--Back-forward-navigation---rendering-syncs-with-URL-2.png +0 -0
  113. package/examples/demo/test/browser/__screenshots__/uat-xstate-route-regression.browser.test.ts/UAT-4--Auth-state-preserved-when-navigating-between-authenticated-anonymous-states-1.png +0 -0
  114. package/examples/demo/test/browser/__screenshots__/uat-xstate-route-regression.browser.test.ts/UAT-4--Auth-state-preserved-when-navigating-between-authenticated-anonymous-states-2.png +0 -0
  115. package/examples/demo/test/browser/__screenshots__/uat-xstate-route-regression.browser.test.ts/UAT-4b--Browser-back-forward-preserves-auth-state-1.png +0 -0
  116. package/examples/demo/test/browser/__screenshots__/uat-xstate-route-regression.browser.test.ts/UAT-4b--Browser-back-forward-preserves-auth-state-2.png +0 -0
  117. package/examples/demo/test/browser/__screenshots__/uat-xstate-route-regression.browser.test.ts/UAT-5--Protected-route-with-play-route-respects-authentication-guard-1.png +0 -0
  118. package/examples/demo/test/browser/__screenshots__/uat-xstate-route-regression.browser.test.ts/UAT-5--Protected-route-with-play-route-respects-authentication-guard-2.png +0 -0
  119. package/examples/demo/test/browser/__screenshots__/user-reported-scenario.browser.test.tsx/User-scenario--home---about---home---contact---home--then-back-3x-1.png +0 -0
  120. package/examples/demo/test/browser/__screenshots__/user-reported-scenario.browser.test.tsx/User-scenario--login---home---about---home---contact---home--then-back-3x-1.png +0 -0
  121. package/examples/demo/test/browser/__screenshots__/xstate-route-events.browser.test.ts/Browser-back-button-sends-play-route-event-with-correct-state-ID-1.png +0 -0
  122. package/examples/demo/test/browser/__screenshots__/xstate-route-events.browser.test.ts/Browser-back-button-sends-play-route-event-with-correct-state-ID-2.png +0 -0
  123. package/examples/demo/test/browser/__screenshots__/xstate-route-events.browser.test.ts/Browser-back-button-sends-xstate-route-event-with-correct-state-ID-1.png +0 -0
  124. package/examples/demo/test/browser/__screenshots__/xstate-route-events.browser.test.ts/Direct-URL-navigation-sends-play-route-event-1.png +0 -0
  125. package/examples/demo/test/browser/__screenshots__/xstate-route-events.browser.test.ts/Direct-URL-navigation-sends-xstate-route-event-1.png +0 -0
  126. package/examples/demo/test/browser/__screenshots__/xstate-route-events.browser.test.ts/Forward-button-sends-play-route-event-1.png +0 -0
  127. package/examples/demo/test/browser/__screenshots__/xstate-route-events.browser.test.ts/Forward-button-sends-play-route-event-2.png +0 -0
  128. package/examples/demo/test/browser/__screenshots__/xstate-route-events.browser.test.ts/Forward-button-sends-xstate-route-event-1.png +0 -0
  129. package/examples/demo/test/browser/__screenshots__/xstate-route-events.browser.test.ts/GAP-12-fix-preserved--No-duplicate-history-entries-with-play-route-1.png +0 -0
  130. package/examples/demo/test/browser/__screenshots__/xstate-route-events.browser.test.ts/GAP-12-fix-preserved--No-duplicate-history-entries-with-play-route-2.png +0 -0
  131. package/examples/demo/test/browser/__screenshots__/xstate-route-events.browser.test.ts/Protected-route-sends-xstate-route-with-authentication-guard-1.png +0 -0
  132. package/examples/demo/test/browser/back-button-duplicate.browser.test.tsx +0 -148
  133. package/examples/demo/test/browser/back-forward-sync.browser.test.tsx +0 -149
  134. package/examples/demo/test/browser/direct-navigation.browser.test.ts +0 -146
  135. package/examples/demo/test/browser/exact-user-scenario.browser.test.tsx +0 -207
  136. package/examples/demo/test/browser/guard-rejection.browser.test.tsx +0 -52
  137. package/examples/demo/test/browser/history-investigation.browser.test.tsx +0 -82
  138. package/examples/demo/test/browser/history-navigation.browser.test.ts +0 -351
  139. package/examples/demo/test/browser/login-flow.browser.test.tsx +0 -34
  140. package/examples/demo/test/browser/navigation.browser.test.tsx +0 -34
  141. package/examples/demo/test/browser/protected-route-navigation.browser.test.tsx +0 -161
  142. package/examples/demo/test/browser/redirect-url-update.browser.test.tsx +0 -140
  143. package/examples/demo/test/browser/settings-parameter.browser.test.tsx +0 -164
  144. package/examples/demo/test/browser/settings-query-freeze.browser.test.ts +0 -141
  145. package/examples/demo/test/browser/state-driven.browser.test.ts +0 -112
  146. package/examples/demo/test/browser/tanstack-integration.browser.test.tsx +0 -61
  147. package/examples/demo/test/browser/uat-xstate-route-regression.browser.test.ts +0 -58
  148. package/examples/demo/test/browser/xstate-route-events.browser.test.ts +0 -293
  149. package/examples/demo/test/browser-back-view-rendering.test.ts +0 -104
  150. package/examples/demo/test/browser-e2e/auth-flow.browser.test.tsx +0 -49
  151. package/examples/demo/test/invalid-route-redirect.test.ts +0 -40
  152. package/examples/demo/test/passive-infra.test.ts +0 -35
  153. package/examples/demo/test/route-parameters.test.ts +0 -539
  154. package/examples/demo/test/signal-only.test.ts +0 -54
  155. package/examples/demo/test/strict-separation.test.ts +0 -37
  156. package/examples/demo/test/test-utils.ts +0 -49
  157. package/examples/demo/tsconfig.json +0 -21
  158. package/examples/demo/tsconfig.tsbuildinfo +0 -1
  159. package/examples/demo/vite.config.ts +0 -13
  160. package/examples/demo/vitest.browser.config.ts +0 -72
  161. package/examples/demo/vitest.config.e2e.browser.ts +0 -28
  162. package/examples/demo/vitest.config.ts +0 -35
  163. package/src/extract-params.ts +0 -75
  164. package/src/index.ts +0 -31
  165. package/src/play-router-provider.tsx +0 -46
  166. package/src/route-map.ts +0 -158
  167. package/src/tanstack-router-bridge.ts +0 -135
  168. package/src/types.ts +0 -26
  169. package/src/utils.ts +0 -12
  170. package/test/browser/__screenshots__/signal-synced-history.browser.test.ts/Browser-back-button-sends-route-navigate-event-to-actor-1.png +0 -0
  171. package/test/browser/__screenshots__/signal-synced-history.browser.test.ts/SignalSyncedHistory-prevents-circular-updates-1.png +0 -0
  172. package/test/browser/__screenshots__/signal-synced-history.browser.test.ts/SignalSyncedHistory-syncs-actor-route-to-browser-URL-1.png +0 -0
  173. package/test/browser/signal-synced-history.browser.test.ts +0 -95
  174. package/test/route-map.test.ts +0 -107
  175. package/test/tanstack-router-bridge.test.ts +0 -318
  176. package/test/urlpattern-integration.test.ts +0 -145
  177. package/tsconfig.json +0 -16
  178. package/tsconfig.tsbuildinfo +0 -1
  179. package/vitest.config.ts +0 -35
package/README.md CHANGED
@@ -29,25 +29,15 @@ npm install @xmachines/play-tanstack-react-router @xmachines/play-router @xmachi
29
29
 
30
30
  Peer dependencies:
31
31
 
32
- - `@tanstack/react-router` `^1.0.0`
32
+ - `@tanstack/react-router` `^1.166.7`
33
33
  - `react` `^18 || ^19`
34
+ - `xstate` `^5.0.0`
34
35
 
35
- ## Browser Support
36
+ ## URLPattern Support
36
37
 
37
- This package uses the [URLPattern API](https://developer.mozilla.org/en-US/docs/Web/API/URLPattern) for route pattern matching.
38
+ This package uses the [URLPattern API](https://developer.mozilla.org/en-US/docs/Web/API/URLPattern) for route pattern matching via `@xmachines/play-router`.
38
39
 
39
- Native support includes current Chrome, Firefox, and Safari 17.4+.
40
- For Node.js test environments or older browsers, install `urlpattern-polyfill`.
41
-
42
- ```bash
43
- npm install urlpattern-polyfill
44
- ```
45
-
46
- ```ts
47
- if (!globalThis.URLPattern) {
48
- await import("urlpattern-polyfill");
49
- }
50
- ```
40
+ URLPattern is available natively on Node.js 24+ and modern browsers (Chrome 95+, Firefox 117+, Safari 16.4+). On older environments, load a polyfill **before** importing this package — see [`@xmachines/play-router` installation](../play-router/README.md#installation) for details.
51
41
 
52
42
  ## Quick Start
53
43
 
@@ -112,16 +102,35 @@ class TanStackReactRouterBridge implements RouterBridge {
112
102
 
113
103
  ### `RouteMap` and `createRouteMapFromTree`
114
104
 
115
- Map state IDs to URL paths and resolve URLs back to state IDs:
105
+ Map state IDs to URL paths and resolve URLs back to state IDs.
106
+
107
+ `RouteMap` extends `BaseRouteMap` from `@xmachines/play-router`, inheriting bucket-indexed
108
+ bidirectional route matching. No routing logic lives in the adapter itself.
116
109
 
117
110
  ```ts
118
- class RouteMap {
119
- constructor(routes: Array<{ stateId: string; path: string }>);
120
- getStateIdByPath(path: string): string | undefined;
121
- getPathByStateId(stateId: string): string | undefined;
122
- }
111
+ // RouteMap is a thin subclass of BaseRouteMap — no extra methods
112
+ class RouteMap extends BaseRouteMap {}
113
+
114
+ // Inherited API:
115
+ routeMap.getStateIdByPath(path: string): string | null
116
+ routeMap.getPathByStateId(stateId: string): string | null
123
117
 
124
- function createRouteMapFromTree(routeTree: RouteTree): RouteMap;
118
+ // Factory from a machine route tree:
119
+ function createRouteMapFromTree(routeTree: RouteTree): RouteMap
120
+ ```
121
+
122
+ `getStateIdByPath` returns `null` (not `undefined`) for unmatched paths.
123
+
124
+ ```ts
125
+ const routeMap = new RouteMap([
126
+ { stateId: "home", path: "/" },
127
+ { stateId: "profile", path: "/profile/:userId" },
128
+ { stateId: "settings", path: "/settings/:section?" },
129
+ ]);
130
+
131
+ routeMap.getStateIdByPath("/profile/123"); // "profile"
132
+ routeMap.getPathByStateId("home"); // "/"
133
+ routeMap.getStateIdByPath("/unknown"); // null
125
134
  ```
126
135
 
127
136
  ### `PlayRouterProvider`
@@ -174,4 +183,7 @@ This keeps routing infrastructure passive while preserving business-logic contro
174
183
 
175
184
  ## License
176
185
 
177
- MIT
186
+ Copyright (c) 2016 [Mikael Karon](mailto:mikael@karon.se). All rights reserved.
187
+
188
+ This work is licensed under the terms of the MIT license.
189
+ For a copy, see <https://opensource.org/licenses/MIT>.
@@ -10,75 +10,45 @@
10
10
  * @packageDocumentation
11
11
  */
12
12
  import type { RouteTree } from "@xmachines/play-router";
13
+ import { BaseRouteMap } from "@xmachines/play-router";
13
14
  /**
14
- * Mapping between state machine state ID and router path
15
+ * Mapping between state machine state ID and router path.
16
+ *
17
+ * Structurally compatible with `BaseRouteMapping` from `@xmachines/play-router`.
18
+ * Fields are `readonly` — entries are immutable once passed to `RouteMap`.
15
19
  */
16
20
  export interface RouteMapping {
17
- /** State ID from state machine (e.g., "settings.profile") */
18
- stateId: string;
19
- /** Router path with optional parameters (e.g., "/settings/:section?") */
20
- path: string;
21
+ /** State ID from state machine (e.g., `"home"`, `"settings.profile"`) */
22
+ readonly stateId: string;
23
+ /** Router path with optional parameters (e.g., `"/settings/:section?"`) */
24
+ readonly path: string;
21
25
  }
22
26
  /**
23
- * Bidirectional route mapper with pattern matching support
27
+ * Bidirectional route mapper for TanStack React Router.
28
+ *
29
+ * Extends {@link BaseRouteMap} — all matching logic lives there.
30
+ * This class exists to provide a TanStack React Router-specific type name and to
31
+ * allow future adapter-specific extensions without breaking the shared base.
24
32
  *
25
- * Maps between state IDs (XMachines actor) and paths (router).
26
- * Handles both exact matches (static paths) and pattern matches (parameterized paths).
33
+ * **Inherited API:**
34
+ * - `getStateIdByPath(path): string | null` path state ID
35
+ * - `getPathByStateId(stateId): string | null` — state ID → path pattern
36
+ *
37
+ * @extends BaseRouteMap
27
38
  *
28
39
  * @example
29
40
  * ```typescript
30
- * const routes: RouteMapping[] = [
31
- * { stateId: "home", path: "/" },
32
- * { stateId: "profile", path: "/profile/:userId" },
33
- * { stateId: "settings", path: "/settings/:section?" }
34
- * ];
35
- *
36
- * const routeMap = new RouteMap(routes);
41
+ * const routeMap = new RouteMap([
42
+ * { stateId: "home", path: "/" },
43
+ * { stateId: "profile", path: "/profile/:userId" },
44
+ * { stateId: "settings", path: "/settings/:section?" },
45
+ * ]);
37
46
  *
38
47
  * routeMap.getStateIdByPath("/profile/123"); // "profile"
39
- * routeMap.getPathByStateId("home"); // "/"
48
+ * routeMap.getPathByStateId("home"); // "/"
40
49
  * ```
41
50
  */
42
- export declare class RouteMap {
43
- private stateIdToPath;
44
- private pathToStateId;
45
- private patterns;
46
- /**
47
- * Create RouteMap from route mappings
48
- *
49
- * @param routes - Array of state ID → path mappings
50
- */
51
- constructor(routes: RouteMapping[]);
52
- /**
53
- * Get state ID from router path
54
- *
55
- * Tries exact match first, then pattern match for parameterized paths.
56
- *
57
- * @param path - Router path (e.g., "/profile/123")
58
- * @returns State ID or null if no match
59
- *
60
- * @example
61
- * ```typescript
62
- * routeMap.getStateIdByPath("/"); // "home" (exact match)
63
- * routeMap.getStateIdByPath("/profile/123"); // "profile" (pattern match)
64
- * ```
65
- */
66
- getStateIdByPath(path: string): string | null;
67
- /**
68
- * Get router path from state ID
69
- *
70
- * Returns the route pattern with parameter placeholders (not substituted).
71
- *
72
- * @param stateId - State machine state ID
73
- * @returns Router path or null if no match
74
- *
75
- * @example
76
- * ```typescript
77
- * routeMap.getPathByStateId("home"); // "/"
78
- * routeMap.getPathByStateId("profile"); // "/profile/:userId"
79
- * ```
80
- */
81
- getPathByStateId(stateId: string): string | null;
51
+ export declare class RouteMap extends BaseRouteMap {
82
52
  }
83
53
  /**
84
54
  * Create RouteMap from RouteTree
@@ -1 +1 @@
1
- {"version":3,"file":"route-map.d.ts","sourceRoot":"","sources":["../src/route-map.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAa,MAAM,wBAAwB,CAAC;AAEnE;;GAEG;AACH,MAAM,WAAW,YAAY;IAC5B,6DAA6D;IAC7D,OAAO,EAAE,MAAM,CAAC;IAChB,yEAAyE;IACzE,IAAI,EAAE,MAAM,CAAC;CACb;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBAAa,QAAQ;IACpB,OAAO,CAAC,aAAa,CAAsB;IAC3C,OAAO,CAAC,aAAa,CAAsB;IAC3C,OAAO,CAAC,QAAQ,CAA4D;IAE5E;;;;OAIG;gBACS,MAAM,EAAE,YAAY,EAAE;IA0BlC;;;;;;;;;;;;;OAaG;IACH,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAa7C;;;;;;;;;;;;;OAaG;IACH,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;CAGhD;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,SAAS,GAAG,QAAQ,CAcrE"}
1
+ {"version":3,"file":"route-map.d.ts","sourceRoot":"","sources":["../src/route-map.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAa,MAAM,wBAAwB,CAAC;AACnE,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAEtD;;;;;GAKG;AACH,MAAM,WAAW,YAAY;IAC5B,yEAAyE;IACzE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,2EAA2E;IAC3E,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,qBAAa,QAAS,SAAQ,YAAY;CAAG;AAE7C;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,SAAS,GAAG,QAAQ,CAcrE"}
package/dist/route-map.js CHANGED
@@ -9,102 +9,33 @@
9
9
  *
10
10
  * @packageDocumentation
11
11
  */
12
+ import { BaseRouteMap } from "@xmachines/play-router";
12
13
  /**
13
- * Bidirectional route mapper with pattern matching support
14
+ * Bidirectional route mapper for TanStack React Router.
14
15
  *
15
- * Maps between state IDs (XMachines actor) and paths (router).
16
- * Handles both exact matches (static paths) and pattern matches (parameterized paths).
16
+ * Extends {@link BaseRouteMap} all matching logic lives there.
17
+ * This class exists to provide a TanStack React Router-specific type name and to
18
+ * allow future adapter-specific extensions without breaking the shared base.
19
+ *
20
+ * **Inherited API:**
21
+ * - `getStateIdByPath(path): string | null` — path → state ID
22
+ * - `getPathByStateId(stateId): string | null` — state ID → path pattern
23
+ *
24
+ * @extends BaseRouteMap
17
25
  *
18
26
  * @example
19
27
  * ```typescript
20
- * const routes: RouteMapping[] = [
21
- * { stateId: "home", path: "/" },
22
- * { stateId: "profile", path: "/profile/:userId" },
23
- * { stateId: "settings", path: "/settings/:section?" }
24
- * ];
25
- *
26
- * const routeMap = new RouteMap(routes);
28
+ * const routeMap = new RouteMap([
29
+ * { stateId: "home", path: "/" },
30
+ * { stateId: "profile", path: "/profile/:userId" },
31
+ * { stateId: "settings", path: "/settings/:section?" },
32
+ * ]);
27
33
  *
28
34
  * routeMap.getStateIdByPath("/profile/123"); // "profile"
29
- * routeMap.getPathByStateId("home"); // "/"
35
+ * routeMap.getPathByStateId("home"); // "/"
30
36
  * ```
31
37
  */
32
- export class RouteMap {
33
- stateIdToPath;
34
- pathToStateId;
35
- patterns;
36
- /**
37
- * Create RouteMap from route mappings
38
- *
39
- * @param routes - Array of state ID → path mappings
40
- */
41
- constructor(routes) {
42
- this.stateIdToPath = new Map();
43
- this.pathToStateId = new Map();
44
- this.patterns = [];
45
- for (const { stateId, path } of routes) {
46
- this.stateIdToPath.set(stateId, path);
47
- // Check if path has parameters
48
- if (path.includes(":")) {
49
- // Convert :param and :param? to regex
50
- const pattern = path
51
- .replace(/\/:[^/]+\?/g, "(?:/([^/]+))?") // Optional params with optional slash
52
- .replace(/:[^/]+/g, "([^/]+)"); // Required params
53
- this.patterns.push({
54
- pattern: new RegExp(`^${pattern}$`),
55
- stateId,
56
- path,
57
- });
58
- }
59
- else {
60
- // Exact match for static paths
61
- this.pathToStateId.set(path, stateId);
62
- }
63
- }
64
- }
65
- /**
66
- * Get state ID from router path
67
- *
68
- * Tries exact match first, then pattern match for parameterized paths.
69
- *
70
- * @param path - Router path (e.g., "/profile/123")
71
- * @returns State ID or null if no match
72
- *
73
- * @example
74
- * ```typescript
75
- * routeMap.getStateIdByPath("/"); // "home" (exact match)
76
- * routeMap.getStateIdByPath("/profile/123"); // "profile" (pattern match)
77
- * ```
78
- */
79
- getStateIdByPath(path) {
80
- // Try exact match first
81
- const exactMatch = this.pathToStateId.get(path);
82
- if (exactMatch)
83
- return exactMatch;
84
- // Try pattern match
85
- for (const { pattern, stateId } of this.patterns) {
86
- if (pattern.test(path))
87
- return stateId;
88
- }
89
- return null;
90
- }
91
- /**
92
- * Get router path from state ID
93
- *
94
- * Returns the route pattern with parameter placeholders (not substituted).
95
- *
96
- * @param stateId - State machine state ID
97
- * @returns Router path or null if no match
98
- *
99
- * @example
100
- * ```typescript
101
- * routeMap.getPathByStateId("home"); // "/"
102
- * routeMap.getPathByStateId("profile"); // "/profile/:userId"
103
- * ```
104
- */
105
- getPathByStateId(stateId) {
106
- return this.stateIdToPath.get(stateId) || null;
107
- }
38
+ export class RouteMap extends BaseRouteMap {
108
39
  }
109
40
  /**
110
41
  * Create RouteMap from RouteTree
@@ -1 +1 @@
1
- {"version":3,"file":"route-map.js","sourceRoot":"","sources":["../src/route-map.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAcH;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,OAAO,QAAQ;IACZ,aAAa,CAAsB;IACnC,aAAa,CAAsB;IACnC,QAAQ,CAA4D;IAE5E;;;;OAIG;IACH,YAAY,MAAsB;QACjC,IAAI,CAAC,aAAa,GAAG,IAAI,GAAG,EAAE,CAAC;QAC/B,IAAI,CAAC,aAAa,GAAG,IAAI,GAAG,EAAE,CAAC;QAC/B,IAAI,CAAC,QAAQ,GAAG,EAAE,CAAC;QAEnB,KAAK,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,MAAM,EAAE,CAAC;YACxC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;YAEtC,+BAA+B;YAC/B,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;gBACxB,sCAAsC;gBACtC,MAAM,OAAO,GAAG,IAAI;qBAClB,OAAO,CAAC,aAAa,EAAE,eAAe,CAAC,CAAC,sCAAsC;qBAC9E,OAAO,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC,kBAAkB;gBACnD,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;oBAClB,OAAO,EAAE,IAAI,MAAM,CAAC,IAAI,OAAO,GAAG,CAAC;oBACnC,OAAO;oBACP,IAAI;iBACJ,CAAC,CAAC;YACJ,CAAC;iBAAM,CAAC;gBACP,+BAA+B;gBAC/B,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;YACvC,CAAC;QACF,CAAC;IACF,CAAC;IAED;;;;;;;;;;;;;OAaG;IACH,gBAAgB,CAAC,IAAY;QAC5B,wBAAwB;QACxB,MAAM,UAAU,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAChD,IAAI,UAAU;YAAE,OAAO,UAAU,CAAC;QAElC,oBAAoB;QACpB,KAAK,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAClD,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC;gBAAE,OAAO,OAAO,CAAC;QACxC,CAAC;QAED,OAAO,IAAI,CAAC;IACb,CAAC;IAED;;;;;;;;;;;;;OAaG;IACH,gBAAgB,CAAC,OAAe;QAC/B,OAAO,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC;IAChD,CAAC;CACD;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,sBAAsB,CAAC,SAAoB;IAC1D,MAAM,MAAM,GAAmB,EAAE,CAAC;IAElC,SAAS,QAAQ,CAAC,IAAe;QAChC,IAAI,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YAC1B,MAAM,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QACpD,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,QAAQ,CAAC,MAAM,CAAC,CAAC;AAC7B,CAAC"}
1
+ {"version":3,"file":"route-map.js","sourceRoot":"","sources":["../src/route-map.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAetD;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,OAAO,QAAS,SAAQ,YAAY;CAAG;AAE7C;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,sBAAsB,CAAC,SAAoB;IAC1D,MAAM,MAAM,GAAmB,EAAE,CAAC;IAElC,SAAS,QAAQ,CAAC,IAAe;QAChC,IAAI,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YAC1B,MAAM,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QACpD,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,QAAQ,CAAC,MAAM,CAAC,CAAC;AAC7B,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xmachines/play-tanstack-react-router",
3
- "version": "1.0.0-beta.1",
3
+ "version": "1.0.0-beta.10",
4
4
  "description": "TanStack React Router adapter for XMachines Play - synchronizes browser URL with actor state through passive infrastructure",
5
5
  "keywords": [
6
6
  "routing",
@@ -12,6 +12,11 @@
12
12
  ],
13
13
  "license": "MIT",
14
14
  "author": "XMachines",
15
+ "files": [
16
+ "dist",
17
+ "README.md",
18
+ "LICENSE"
19
+ ],
15
20
  "type": "module",
16
21
  "exports": {
17
22
  ".": {
@@ -20,32 +25,35 @@
20
25
  },
21
26
  "./package.json": "./package.json"
22
27
  },
28
+ "publishConfig": {
29
+ "access": "public"
30
+ },
23
31
  "scripts": {
24
32
  "build": "tsc --build",
25
- "clean": "rm -rf dist *.tsbuildinfo",
33
+ "clean": "rm -rf dist *.tsbuildinfo node_modules/.vite node_modules/.vite-temp",
26
34
  "typecheck": "tsc --noEmit",
27
- "test": "vitest run",
28
- "test:browser": "vitest run",
35
+ "test": "vitest",
36
+ "test:browser": "vitest",
29
37
  "prepublishOnly": "npm run build"
30
38
  },
31
39
  "dependencies": {
32
- "@tanstack/react-router": "^1.166.7",
33
- "@xmachines/play-actor": "1.0.0-beta.1",
34
- "@xmachines/play-router": "1.0.0-beta.1",
35
- "@xmachines/play-signals": "1.0.0-beta.1",
36
- "xstate": "^5.28.0"
40
+ "@xmachines/play-actor": "1.0.0-beta.10",
41
+ "@xmachines/play-router": "1.0.0-beta.10",
42
+ "@xmachines/play-signals": "1.0.0-beta.10",
43
+ "xstate": "^5.0.0"
37
44
  },
38
45
  "devDependencies": {
39
- "@types/node": "^25.3.3",
40
- "typescript": "^5.7.0"
46
+ "@tanstack/react-router": "^1.167.5",
47
+ "@types/node": "^25.5.0",
48
+ "@xmachines/shared": "1.0.0-beta.10",
49
+ "jsdom": "^29.0.1",
50
+ "typescript": "^5.9.3",
51
+ "vitest": "^4.1.0"
41
52
  },
42
53
  "peerDependencies": {
43
54
  "@tanstack/react-router": "^1.166.7",
44
- "react": "^18.2.0 || ^19.0.0",
45
- "react-dom": "^18.2.0 || ^19.0.0",
46
- "xstate": "^5.28.0"
47
- },
48
- "publishConfig": {
49
- "access": "public"
55
+ "react": "^18.0.0 || ^19.0.0",
56
+ "react-dom": "^18.0.0 || ^19.0.0",
57
+ "xstate": "^5.0.0"
50
58
  }
51
59
  }
package/.oxfmtrc.json DELETED
@@ -1,3 +0,0 @@
1
- {
2
- "extends": ["@xmachines/shared/oxfmt"]
3
- }
package/.oxlintrc.json DELETED
@@ -1,3 +0,0 @@
1
- {
2
- "extends": ["@xmachines/shared/oxlint"]
3
- }
@@ -1,100 +0,0 @@
1
- # TanStack React Router Demo
2
-
3
- React + TanStack Router demonstration of Play's actor-authoritative routing and rendering model.
4
-
5
- ## What This Demonstrates
6
-
7
- - Shared auth machine reused without framework-specific business logic
8
- - `PlayRouterProvider` renderer-based integration with TanStack Router
9
- - Shell-driven rendering via `PlayRenderer` with actor-authoritative navigation
10
- - Non-browser invariant tests plus browser E2E coverage
11
-
12
- ## Running the Demo
13
-
14
- From this directory (`packages/play-tanstack-react-router/examples/demo`):
15
-
16
- ```bash
17
- npm install
18
- npm run dev
19
- ```
20
-
21
- Open `http://localhost:3000`.
22
-
23
- ## Step-by-Step Code Flow
24
-
25
- This demo uses provider-based integration centered on `PlayRouterProvider` and a route map generated from the machine:
26
-
27
- 1. `src/main.tsx` mounts `<App />`.
28
- 2. `src/App.tsx` creates/starts the actor from shared machine + catalog.
29
- 3. `src/App.tsx` builds `routeMap` from `extractMachineRoutes(authMachine)` + `createRouteMapFromTree(routeTree)`.
30
- 4. `PlayRouterProvider` bridges TanStack Router to the actor and renders `Shell` via `renderer(actor, router)`.
31
- 5. `Shell` renders `PlayRenderer`, header/nav, and debug panel from actor state.
32
- 6. Tests in `test/` and `test/browser*/` validate invariant and runtime behavior.
33
-
34
- ```tsx
35
- // src/App.tsx (shape)
36
- const routeTree = extractMachineRoutes(authMachine);
37
- const routeMap = createRouteMapFromTree(routeTree);
38
-
39
- return (
40
- <PlayRouterProvider
41
- actor={actor}
42
- router={router}
43
- routeMap={routeMap}
44
- renderer={(currentActor, currentRouter) => (
45
- <Shell actor={currentActor} router={currentRouter} />
46
- )}
47
- />
48
- );
49
- ```
50
-
51
- ```tsx
52
- // src/components/Login.tsx (shape)
53
- <button onClick={() => actor.send({ type: "auth.login", username, password })}>Login</button>
54
- ```
55
-
56
- Shared business logic comes from the common demo machine/catalog module (`authMachine` and `catalog`), so routing decisions remain machine-driven and framework-independent.
57
-
58
- ## Key Files
59
-
60
- - `src/main.tsx` - React entry point that mounts `<App />`
61
- - `src/App.tsx` - actor lifecycle, route-map creation, provider wiring, and `Shell` rendering
62
- - `src/components/` - UI components that send actor events and render state-driven views
63
- - `test/actor-authority.test.ts` - actor authority and guarded navigation behavior
64
- - `test/strict-separation.test.ts` - machine/view infrastructure separation contracts
65
- - `test/browser-e2e/auth-flow.browser.test.tsx` - canonical browser auth flow
66
- - `test/browser/` - extended browser checks for URL sync, history behavior, and route event flow
67
-
68
- ## Available Scripts
69
-
70
- ```bash
71
- npm run dev # Start Vite dev server (http://localhost:3000)
72
- npm run build # Build production assets
73
- npm run preview # Preview production build locally
74
- npm run test # Run Vitest suite
75
- npm run test:vitest # Explicit Vitest command alias
76
- npm run test:browser # Browser-focused test run (e2e browser config)
77
- npm run test:browser:full # Full browser test config run
78
- npm run test:e2e # Alias to test:browser
79
- ```
80
-
81
- ## Verification
82
-
83
- Run the core invariant checks referenced by this demo docs:
84
-
85
- ```bash
86
- npm run test:vitest -- test/actor-authority.test.ts test/strict-separation.test.ts
87
- npm run test:browser
88
- ```
89
-
90
- Manual sanity flow:
91
-
92
- 1. Run `npm run dev` and open `http://localhost:3000`.
93
- 2. Attempt protected navigation while logged out and confirm guard-driven behavior.
94
- 3. Log in, then confirm route and view updates stay in sync.
95
-
96
- ## Learn More
97
-
98
- - [TanStack React Router package README](../../README.md)
99
- - [Solid Router demo README](../../../play-solid-router/examples/demo/README.md)
100
- - [TanStack Solid Router demo README](../../../play-tanstack-solid-router/examples/demo/README.md)