@xmachines/docs 2.2.0 → 4.0.0

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 (483) hide show
  1. package/README.md +8 -16
  2. package/api/@xmachines/play/README.md +75 -97
  3. package/api/@xmachines/play/errors/README.md +8 -0
  4. package/api/@xmachines/play/{classes → errors/classes}/NonNullableError.md +6 -6
  5. package/api/@xmachines/play/{classes → errors/classes}/PlayError.md +35 -10
  6. package/api/@xmachines/play/index/README.md +75 -0
  7. package/api/@xmachines/play/index/functions/asCleanup.md +78 -0
  8. package/api/@xmachines/play/{functions → index/functions}/assertNonNullable.md +2 -2
  9. package/api/@xmachines/{play-actor → play/index}/functions/shallowEqualExcept.md +3 -3
  10. package/api/@xmachines/play/index/type-aliases/Cleanup.md +38 -0
  11. package/api/@xmachines/play/index/type-aliases/DisposeKey.md +32 -0
  12. package/api/@xmachines/play/{type-aliases → index/type-aliases}/PlayEvent.md +4 -4
  13. package/api/@xmachines/play/index/variables/DISPOSE.md +34 -0
  14. package/api/@xmachines/play-actor/README.md +78 -222
  15. package/api/@xmachines/play-actor/interfaces/ActorEvent.md +18 -0
  16. package/api/@xmachines/play-actor/interfaces/PlayActor.md +73 -0
  17. package/api/@xmachines/play-dom/README.md +99 -43
  18. package/api/@xmachines/play-dom/classes/PlayRenderer.md +12 -11
  19. package/api/@xmachines/play-dom/functions/asCleanup.md +78 -0
  20. package/api/@xmachines/play-dom/functions/createPlayUI.md +6 -6
  21. package/api/@xmachines/play-dom/functions/createRenderer.md +3 -3
  22. package/api/@xmachines/play-dom/interfaces/CreatePlayUIOptions.md +17 -11
  23. package/api/@xmachines/play-dom/interfaces/MountOptions.md +5 -4
  24. package/api/@xmachines/play-dom/interfaces/PlayDomOptions.md +14 -12
  25. package/api/@xmachines/play-dom/type-aliases/Cleanup.md +38 -0
  26. package/api/@xmachines/play-dom/type-aliases/MountFn.md +30 -8
  27. package/api/@xmachines/play-dom-router/README.md +99 -73
  28. package/api/@xmachines/play-dom-router/classes/DomRouterBridge.md +22 -21
  29. package/api/@xmachines/{play-vue-router → play-dom-router}/classes/RouteMap.md +12 -6
  30. package/api/@xmachines/play-dom-router/functions/asCleanup.md +78 -0
  31. package/api/@xmachines/play-dom-router/functions/connectRouter.md +3 -8
  32. package/api/@xmachines/play-dom-router/functions/createBrowserHistory.md +7 -1
  33. package/api/@xmachines/play-dom-router/functions/createRouter.md +12 -6
  34. package/api/@xmachines/play-dom-router/interfaces/BasePathOptions.md +5 -5
  35. package/api/@xmachines/play-dom-router/interfaces/BrowserHistory.md +73 -19
  36. package/api/@xmachines/play-dom-router/interfaces/BrowserWindow.md +16 -16
  37. package/api/@xmachines/play-dom-router/interfaces/ConnectRouterOptions.md +8 -8
  38. package/api/@xmachines/play-dom-router/interfaces/PlayRouteEvent.md +9 -14
  39. package/api/@xmachines/play-dom-router/interfaces/RoutableActor.md +24 -21
  40. package/api/@xmachines/play-dom-router/interfaces/RouteLookupContract.md +3 -3
  41. package/api/@xmachines/play-dom-router/interfaces/RouteMapOptions.md +4 -4
  42. package/api/@xmachines/play-dom-router/interfaces/RouteMapping.md +3 -3
  43. package/api/@xmachines/play-dom-router/interfaces/RouterBridge.md +3 -3
  44. package/api/@xmachines/play-dom-router/interfaces/RouterConnection.md +36 -7
  45. package/api/@xmachines/play-dom-router/interfaces/VanillaRouter.md +40 -6
  46. package/api/@xmachines/play-dom-router/type-aliases/Cleanup.md +38 -0
  47. package/api/@xmachines/play-dom-router/variables/DISPOSE.md +34 -0
  48. package/api/@xmachines/play-react/README.md +18 -40
  49. package/api/@xmachines/play-react/classes/PlayErrorBoundary.md +50 -11
  50. package/api/@xmachines/play-react/functions/useActor.md +1 -1
  51. package/api/@xmachines/play-react/functions/usePlayView.md +1 -1
  52. package/api/@xmachines/play-react/functions/useSignalEffect.md +1 -1
  53. package/api/@xmachines/play-react/interfaces/ActorProviderProps.md +11 -11
  54. package/api/@xmachines/play-react/interfaces/PlayErrorBoundaryProps.md +8 -6
  55. package/api/@xmachines/play-react/interfaces/PlayErrorBoundaryState.md +6 -5
  56. package/api/@xmachines/play-react/interfaces/PlayUIProviderProps.md +13 -13
  57. package/api/@xmachines/play-react/interfaces/ViewContextValue.md +8 -8
  58. package/api/@xmachines/play-react/type-aliases/AnyPlayActor.md +11 -3
  59. package/api/@xmachines/play-react/variables/ActorProvider.md +1 -1
  60. package/api/@xmachines/play-react/variables/PlayRenderer.md +1 -1
  61. package/api/@xmachines/play-react/variables/PlayUIProvider.md +1 -1
  62. package/api/@xmachines/play-react/variables/schema.md +52 -0
  63. package/api/@xmachines/play-react-router/README.md +22 -50
  64. package/api/@xmachines/play-react-router/classes/ReactRouterBridge.md +17 -16
  65. package/api/@xmachines/play-react-router/classes/RouteMap.md +11 -5
  66. package/api/@xmachines/play-react-router/functions/createPlayRouterProvider.md +11 -8
  67. package/api/@xmachines/play-react-router/functions/createRouteMapFromTree.md +16 -9
  68. package/api/@xmachines/play-react-router/interfaces/PlayRouteEvent.md +9 -14
  69. package/api/@xmachines/play-react-router/interfaces/PlayRouterProviderProps.md +10 -10
  70. package/api/@xmachines/play-react-router/interfaces/RoutableActor.md +72 -0
  71. package/api/@xmachines/play-react-router/interfaces/RouteMapOptions.md +4 -4
  72. package/api/@xmachines/play-react-router/interfaces/RouteMapping.md +3 -3
  73. package/api/@xmachines/play-react-router/interfaces/RouterBridge.md +3 -3
  74. package/api/@xmachines/play-react-router/type-aliases/PlayRouterBridgeConstructor.md +17 -7
  75. package/api/@xmachines/play-react-router/type-aliases/PlayRouterProviderBaseProps.md +5 -5
  76. package/api/@xmachines/play-react-router/variables/PlayRouterProvider.md +4 -4
  77. package/api/@xmachines/play-router/README.md +108 -189
  78. package/api/@xmachines/play-router/errors/README.md +15 -0
  79. package/api/@xmachines/play-router/errors/classes/DuplicateBridgeError.md +191 -0
  80. package/api/@xmachines/play-router/errors/classes/DuplicateRoutePathError.md +175 -0
  81. package/api/@xmachines/play-router/errors/classes/EmptyRoutePathError.md +175 -0
  82. package/api/@xmachines/play-router/errors/classes/InvalidBasePathError.md +200 -0
  83. package/api/@xmachines/play-router/errors/classes/InvalidRoutePatternError.md +203 -0
  84. package/api/@xmachines/play-router/errors/classes/InvalidStateIdError.md +175 -0
  85. package/api/@xmachines/play-router/errors/classes/MissingBasePathParamError.md +199 -0
  86. package/api/@xmachines/play-router/errors/classes/RouterSyncError.md +192 -0
  87. package/api/@xmachines/play-router/errors/classes/UnknownStateTypeError.md +182 -0
  88. package/api/@xmachines/play-router/index/README.md +75 -0
  89. package/api/@xmachines/play-router/{classes → index/classes}/RouteMap.md +12 -6
  90. package/api/@xmachines/play-router/{classes → index/classes}/RouterBridgeBase.md +19 -17
  91. package/api/@xmachines/play-router/{functions → index/functions}/buildPlayRouteEvent.md +2 -2
  92. package/api/@xmachines/play-router/{functions → index/functions}/buildRouteTree.md +14 -4
  93. package/api/@xmachines/play-router/{functions → index/functions}/cleanFrameworkParams.md +3 -4
  94. package/api/@xmachines/play-router/{functions → index/functions}/createRouteMapFromTree.md +13 -6
  95. package/api/@xmachines/play-router/{functions → index/functions}/createRouterConnection.md +2 -2
  96. package/api/@xmachines/play-router/{functions → index/functions}/detectDuplicateRoutes.md +2 -2
  97. package/api/@xmachines/play-router/{functions → index/functions}/extractQuery.md +2 -2
  98. package/api/@xmachines/play-router/{functions → index/functions}/extractRouteParams.md +3 -3
  99. package/api/@xmachines/play-router/{functions → index/functions}/findRouteById.md +2 -2
  100. package/api/@xmachines/play-router/{functions → index/functions}/findRouteByPath.md +2 -2
  101. package/api/@xmachines/play-router/index/functions/getPatternParamNames.md +29 -0
  102. package/api/@xmachines/play-router/index/functions/getRequiredPatternParamNames.md +39 -0
  103. package/api/@xmachines/play-router/{functions → index/functions}/isMountableBridge.md +2 -2
  104. package/api/@xmachines/play-router/index/functions/joinBasePath.md +37 -0
  105. package/api/@xmachines/play-router/{functions → index/functions}/mountKey.md +2 -2
  106. package/api/@xmachines/play-router/index/functions/normalizeBasePath.md +43 -0
  107. package/api/@xmachines/play-router/{functions → index/functions}/openProviderBridge.md +14 -14
  108. package/api/@xmachines/play-router/index/functions/pickOwnParams.md +41 -0
  109. package/api/@xmachines/play-router/{functions → index/functions}/repointProviderBridge.md +2 -2
  110. package/api/@xmachines/play-router/index/functions/resolveBasePath.md +51 -0
  111. package/api/@xmachines/play-router/{functions → index/functions}/resolveFrameworkParams.md +11 -13
  112. package/api/@xmachines/play-router/{functions → index/functions}/sanitizePathname.md +2 -2
  113. package/api/@xmachines/play-router/index/functions/stripBasePath.md +44 -0
  114. package/api/@xmachines/play-router/{functions → index/functions}/validateRouteFormat.md +2 -2
  115. package/api/@xmachines/play-router/{functions → index/functions}/validateStateExists.md +2 -2
  116. package/api/@xmachines/play-router/{interfaces → index/interfaces}/BasePathOptions.md +6 -6
  117. package/api/@xmachines/play-router/index/interfaces/BuildPlayRouteEventOptions.md +13 -0
  118. package/api/@xmachines/play-router/index/interfaces/FrameworkParamsSource.md +47 -0
  119. package/api/@xmachines/play-router/{interfaces → index/interfaces}/LocationLike.md +6 -6
  120. package/api/@xmachines/play-router/{interfaces → index/interfaces}/MountableRouterBridge.md +9 -9
  121. package/api/@xmachines/play-router/{interfaces → index/interfaces}/OpenProviderBridgeArgs.md +13 -13
  122. package/api/@xmachines/play-router/index/interfaces/PlayRouteEvent.md +130 -0
  123. package/api/@xmachines/play-router/{interfaces → index/interfaces}/PlayRouterProviderBaseProps.md +15 -15
  124. package/api/@xmachines/play-router/index/interfaces/ResolvedBasePath.md +14 -0
  125. package/api/@xmachines/play-router/{interfaces → index/interfaces}/ResolvedRoutePath.md +6 -6
  126. package/api/@xmachines/play-router/index/interfaces/Routable.md +26 -0
  127. package/api/@xmachines/play-router/index/interfaces/RoutableActor.md +72 -0
  128. package/api/@xmachines/play-router/{interfaces → index/interfaces}/RouteInfo.md +11 -11
  129. package/api/@xmachines/play-router/{interfaces → index/interfaces}/RouteMapOptions.md +5 -5
  130. package/api/@xmachines/play-router/{interfaces → index/interfaces}/RouteMapping.md +6 -6
  131. package/api/@xmachines/play-router/index/interfaces/RouteMatch.md +12 -0
  132. package/api/@xmachines/play-router/{interfaces → index/interfaces}/RouteNode.md +13 -13
  133. package/api/@xmachines/play-router/index/interfaces/RouteObject.md +34 -0
  134. package/api/@xmachines/play-router/index/interfaces/RouteTree.md +27 -0
  135. package/api/@xmachines/play-router/{interfaces → index/interfaces}/RouteWatcherHandle.md +7 -7
  136. package/api/@xmachines/play-router/{interfaces → index/interfaces}/RouterBridge.md +5 -5
  137. package/api/@xmachines/play-router/{interfaces → index/interfaces}/RouterConnection.md +38 -9
  138. package/api/@xmachines/play-router/{interfaces → index/interfaces}/WindowLike.md +4 -4
  139. package/api/@xmachines/play-router/index/type-aliases/PlayRouterBridgeConstructor.md +46 -0
  140. package/api/@xmachines/play-router/index/type-aliases/RouteData.md +12 -0
  141. package/api/@xmachines/play-router/index/type-aliases/RouteDataResolver.md +31 -0
  142. package/api/@xmachines/play-router/index/type-aliases/RouteMetadata.md +11 -0
  143. package/api/@xmachines/play-router/index/variables/DISPOSE.md +34 -0
  144. package/api/@xmachines/play-router/index/variables/NO_BASE_PATH.md +18 -0
  145. package/api/@xmachines/play-router/index/variables/ROOT_NODE_ID.md +18 -0
  146. package/api/@xmachines/play-router/xstate/README.md +53 -0
  147. package/api/@xmachines/{play-dom-router → play-router/xstate}/functions/createRouteMap.md +8 -6
  148. package/api/@xmachines/play-router/{functions → xstate/functions}/extractMachineRoutes.md +4 -4
  149. package/api/@xmachines/play-router/xstate/functions/getNavigableRoutes.md +35 -0
  150. package/api/@xmachines/play-router/{functions → xstate/functions}/getRoutableRoutes.md +6 -6
  151. package/api/@xmachines/play-router/{functions → xstate/functions}/getRouteMappings.md +7 -7
  152. package/api/@xmachines/play-router/{functions → xstate/functions}/getTransitionReachableRoutes.md +2 -2
  153. package/api/@xmachines/play-router/{functions → xstate/functions}/isRouteReachable.md +2 -2
  154. package/api/@xmachines/play-router/{functions → xstate/functions}/machineToGraph.md +2 -2
  155. package/api/@xmachines/play-router/xstate/functions/routeExists.md +26 -0
  156. package/api/@xmachines/play-router/xstate/interfaces/MachineEdgeData.md +15 -0
  157. package/api/@xmachines/play-router/xstate/interfaces/MachineNodeData.md +17 -0
  158. package/api/@xmachines/play-router/{type-aliases → xstate/type-aliases}/MachineGraph.md +2 -2
  159. package/api/@xmachines/play-signals/README.md +5 -25
  160. package/api/@xmachines/play-signals/functions/watchSignal.md +27 -4
  161. package/api/@xmachines/play-signals/interfaces/ComputedOptions.md +2 -2
  162. package/api/@xmachines/play-signals/interfaces/SignalComputed.md +2 -2
  163. package/api/@xmachines/play-signals/interfaces/SignalOptions.md +2 -2
  164. package/api/@xmachines/play-signals/interfaces/SignalState.md +3 -3
  165. package/api/@xmachines/play-signals/interfaces/SignalWatcher.md +4 -4
  166. package/api/@xmachines/play-signals/type-aliases/Cleanup.md +38 -0
  167. package/api/@xmachines/play-signals/type-aliases/WatcherNotify.md +1 -1
  168. package/api/@xmachines/play-solid/README.md +36 -35
  169. package/api/@xmachines/play-solid/functions/useActor.md +1 -1
  170. package/api/@xmachines/play-solid/functions/usePlayView.md +14 -1
  171. package/api/@xmachines/play-solid/interfaces/ActorProviderProps.md +11 -11
  172. package/api/@xmachines/play-solid/interfaces/PlayUIProviderProps.md +13 -13
  173. package/api/@xmachines/play-solid/interfaces/ViewContextValue.md +16 -8
  174. package/api/@xmachines/play-solid/type-aliases/AnyPlayActor.md +11 -3
  175. package/api/@xmachines/play-solid/variables/ActorContext.md +1 -1
  176. package/api/@xmachines/play-solid/variables/ActorProvider.md +1 -1
  177. package/api/@xmachines/play-solid/variables/PlayRenderer.md +1 -1
  178. package/api/@xmachines/play-solid/variables/PlayUIProvider.md +1 -1
  179. package/api/@xmachines/play-solid/variables/schema.md +71 -0
  180. package/api/@xmachines/play-solid-router/README.md +31 -52
  181. package/api/@xmachines/play-solid-router/classes/RouteMap.md +11 -5
  182. package/api/@xmachines/play-solid-router/classes/SolidRouterBridge.md +30 -53
  183. package/api/@xmachines/play-solid-router/functions/createPlayRouterProvider.md +9 -8
  184. package/api/@xmachines/play-solid-router/interfaces/PlayActor.md +38 -35
  185. package/api/@xmachines/play-solid-router/interfaces/PlayRouteEvent.md +9 -14
  186. package/api/@xmachines/play-solid-router/interfaces/PlayRouterProviderProps.md +12 -12
  187. package/api/@xmachines/play-solid-router/interfaces/RoutableActor.md +72 -0
  188. package/api/@xmachines/play-solid-router/interfaces/RouteMapOptions.md +4 -4
  189. package/api/@xmachines/play-solid-router/interfaces/RouteMapping.md +5 -5
  190. package/api/@xmachines/play-solid-router/interfaces/RouterBridge.md +3 -3
  191. package/api/@xmachines/play-solid-router/type-aliases/PlayRouterBridgeConstructor.md +17 -7
  192. package/api/@xmachines/play-solid-router/type-aliases/PlayRouterProviderBaseProps.md +5 -5
  193. package/api/@xmachines/play-solid-router/type-aliases/SolidRouterHooks.md +4 -4
  194. package/api/@xmachines/play-solid-router/variables/PlayRouterProvider.md +4 -4
  195. package/api/@xmachines/play-svelte/README.md +13 -28
  196. package/api/@xmachines/play-svelte/functions/defineRegistry.md +1 -1
  197. package/api/@xmachines/play-svelte/functions/getActorContext.md +1 -1
  198. package/api/@xmachines/play-svelte/functions/getPlayViewContext.md +7 -1
  199. package/api/@xmachines/play-svelte/functions/setActorContext.md +1 -1
  200. package/api/@xmachines/play-svelte/interfaces/ActorProviderProps.md +12 -12
  201. package/api/@xmachines/play-svelte/interfaces/DefineRegistryOptions.md +4 -4
  202. package/api/@xmachines/play-svelte/interfaces/PlayUIProviderProps.md +14 -14
  203. package/api/@xmachines/play-svelte/interfaces/ViewContextValue.md +8 -8
  204. package/api/@xmachines/play-svelte/type-aliases/AnyPlayActor.md +11 -3
  205. package/api/@xmachines/play-svelte/variables/schema.md +16 -0
  206. package/api/@xmachines/play-svelte-spa-router/README.md +22 -41
  207. package/api/@xmachines/play-svelte-spa-router/classes/RouteMap.md +11 -5
  208. package/api/@xmachines/play-svelte-spa-router/classes/SvelteSpaRouterBridge.md +22 -21
  209. package/api/@xmachines/play-svelte-spa-router/functions/connectRouter.md +3 -2
  210. package/api/@xmachines/play-svelte-spa-router/interfaces/BasePathOptions.md +5 -5
  211. package/api/@xmachines/play-svelte-spa-router/interfaces/ConnectRouterOptions.md +8 -8
  212. package/api/@xmachines/play-svelte-spa-router/interfaces/PlayRouteEvent.md +9 -14
  213. package/api/@xmachines/play-svelte-spa-router/interfaces/RoutableActor.md +72 -0
  214. package/api/@xmachines/play-svelte-spa-router/interfaces/RouteMapOptions.md +4 -4
  215. package/api/@xmachines/play-svelte-spa-router/interfaces/RouteMapping.md +3 -3
  216. package/api/@xmachines/play-svelte-spa-router/interfaces/RouterBridge.md +3 -3
  217. package/api/@xmachines/play-svelte-spa-router/interfaces/RouterConnection.md +36 -7
  218. package/api/@xmachines/play-svelte-spa-router/interfaces/WindowLike.md +3 -3
  219. package/api/@xmachines/play-sveltekit-router/README.md +17 -35
  220. package/api/@xmachines/play-sveltekit-router/classes/RouteMap.md +11 -5
  221. package/api/@xmachines/play-sveltekit-router/classes/SvelteKitRouterBridge.md +22 -21
  222. package/api/@xmachines/play-sveltekit-router/functions/connectRouter.md +3 -2
  223. package/api/@xmachines/play-sveltekit-router/interfaces/BasePathOptions.md +5 -5
  224. package/api/@xmachines/play-sveltekit-router/interfaces/ConnectRouterOptions.md +8 -8
  225. package/api/@xmachines/play-sveltekit-router/interfaces/LocationLike.md +3 -3
  226. package/api/@xmachines/play-sveltekit-router/interfaces/PlayRouteEvent.md +9 -14
  227. package/api/@xmachines/play-sveltekit-router/interfaces/RoutableActor.md +72 -0
  228. package/api/@xmachines/play-sveltekit-router/interfaces/RouteMapOptions.md +4 -4
  229. package/api/@xmachines/play-sveltekit-router/interfaces/RouteMapping.md +3 -3
  230. package/api/@xmachines/play-sveltekit-router/interfaces/RouterBridge.md +3 -3
  231. package/api/@xmachines/play-sveltekit-router/interfaces/RouterConnection.md +36 -7
  232. package/api/@xmachines/play-tanstack-react-router/README.md +19 -43
  233. package/api/@xmachines/play-tanstack-react-router/classes/RouteMap.md +11 -5
  234. package/api/@xmachines/play-tanstack-react-router/classes/TanStackReactRouterBridge.md +18 -17
  235. package/api/@xmachines/play-tanstack-react-router/functions/createPlayRouterProvider.md +11 -8
  236. package/api/@xmachines/play-tanstack-react-router/functions/createRouteMapFromTree.md +16 -9
  237. package/api/@xmachines/play-tanstack-react-router/interfaces/PlayRouteEvent.md +9 -14
  238. package/api/@xmachines/play-tanstack-react-router/interfaces/PlayRouterProviderProps.md +10 -10
  239. package/api/@xmachines/play-tanstack-react-router/interfaces/RoutableActor.md +72 -0
  240. package/api/@xmachines/play-tanstack-react-router/interfaces/RouteMapOptions.md +4 -4
  241. package/api/@xmachines/play-tanstack-react-router/interfaces/RouteMapping.md +3 -3
  242. package/api/@xmachines/play-tanstack-react-router/interfaces/RouterBridge.md +3 -3
  243. package/api/@xmachines/play-tanstack-react-router/type-aliases/PlayRouterBridgeConstructor.md +17 -7
  244. package/api/@xmachines/play-tanstack-react-router/type-aliases/PlayRouterProviderBaseProps.md +5 -5
  245. package/api/@xmachines/play-tanstack-react-router/type-aliases/TanStackRouterInstance.md +1 -1
  246. package/api/@xmachines/play-tanstack-react-router/type-aliases/TanStackRouterLike.md +5 -5
  247. package/api/@xmachines/play-tanstack-react-router/variables/PlayRouterProvider.md +4 -4
  248. package/api/@xmachines/play-tanstack-router/README.md +6 -4
  249. package/api/@xmachines/play-tanstack-router/classes/TanStackRouterBridgeBase.md +17 -20
  250. package/api/@xmachines/play-tanstack-router/type-aliases/TanStackRouteMapLike.md +3 -3
  251. package/api/@xmachines/play-tanstack-router/type-aliases/TanStackRouterLike.md +5 -5
  252. package/api/@xmachines/play-tanstack-solid-router/README.md +26 -52
  253. package/api/@xmachines/play-tanstack-solid-router/classes/RouteMap.md +11 -5
  254. package/api/@xmachines/play-tanstack-solid-router/classes/TanStackSolidRouterBridge.md +49 -45
  255. package/api/@xmachines/play-tanstack-solid-router/functions/createPlayRouterProvider.md +9 -8
  256. package/api/@xmachines/play-tanstack-solid-router/interfaces/PlayRouteEvent.md +9 -14
  257. package/api/@xmachines/play-tanstack-solid-router/interfaces/PlayRouterProviderProps.md +10 -10
  258. package/api/@xmachines/play-tanstack-solid-router/interfaces/RoutableActor.md +72 -0
  259. package/api/@xmachines/play-tanstack-solid-router/interfaces/RouteMapOptions.md +4 -4
  260. package/api/@xmachines/play-tanstack-solid-router/interfaces/RouteMapping.md +3 -3
  261. package/api/@xmachines/play-tanstack-solid-router/interfaces/RouterBridge.md +3 -3
  262. package/api/@xmachines/play-tanstack-solid-router/type-aliases/PlayRouterBridgeConstructor.md +17 -7
  263. package/api/@xmachines/play-tanstack-solid-router/type-aliases/PlayRouterProviderBaseProps.md +5 -5
  264. package/api/@xmachines/play-tanstack-solid-router/type-aliases/TanStackRouterInstance.md +1 -1
  265. package/api/@xmachines/play-tanstack-solid-router/type-aliases/TanStackRouterLike.md +5 -5
  266. package/api/@xmachines/play-tanstack-solid-router/variables/PlayRouterProvider.md +4 -4
  267. package/api/@xmachines/play-url/README.md +69 -0
  268. package/api/@xmachines/play-url/errors/README.md +17 -0
  269. package/api/@xmachines/play-url/errors/classes/InvalidBasePathError.md +200 -0
  270. package/api/@xmachines/play-url/errors/classes/InvalidRoutePatternError.md +203 -0
  271. package/api/@xmachines/play-url/errors/classes/MissingBasePathParamError.md +199 -0
  272. package/api/@xmachines/play-url/index/README.md +65 -0
  273. package/api/@xmachines/play-url/index/functions/cleanFrameworkParams.md +39 -0
  274. package/api/@xmachines/play-url/index/functions/getCandidates.md +29 -0
  275. package/api/@xmachines/play-url/index/functions/getCompiledPattern.md +31 -0
  276. package/api/@xmachines/play-url/index/functions/getIndexKey.md +30 -0
  277. package/api/@xmachines/play-url/index/functions/getNormalizedParamNameMap.md +32 -0
  278. package/api/@xmachines/play-url/index/functions/getPatternParamNames.md +29 -0
  279. package/api/@xmachines/play-url/index/functions/getRequiredPatternParamNames.md +39 -0
  280. package/api/@xmachines/play-url/index/functions/holdsUnsubstitutedParam.md +36 -0
  281. package/api/@xmachines/play-url/index/functions/isParameterizedPattern.md +36 -0
  282. package/api/@xmachines/{play-router → play-url/index}/functions/joinBasePath.md +2 -2
  283. package/api/@xmachines/{play-router → play-url/index}/functions/normalizeBasePath.md +2 -2
  284. package/api/@xmachines/play-url/index/functions/normalizeParamNames.md +36 -0
  285. package/api/@xmachines/play-url/index/functions/parsePattern.md +27 -0
  286. package/api/@xmachines/{play-router → play-url/index}/functions/pickOwnParams.md +4 -4
  287. package/api/@xmachines/{play-router → play-url/index}/functions/resolveBasePath.md +2 -2
  288. package/api/@xmachines/play-url/index/functions/resolveFrameworkParams.md +49 -0
  289. package/api/@xmachines/{play-router → play-url/index}/functions/stripBasePath.md +2 -2
  290. package/api/@xmachines/play-url/index/interfaces/BasePathOptions.md +28 -0
  291. package/api/@xmachines/{play-router → play-url/index}/interfaces/FrameworkParamsSource.md +9 -9
  292. package/api/@xmachines/play-url/index/interfaces/GroupPart.md +15 -0
  293. package/api/@xmachines/play-url/index/interfaces/LiteralPart.md +14 -0
  294. package/api/@xmachines/play-url/index/interfaces/ParamPart.md +21 -0
  295. package/api/@xmachines/play-url/index/interfaces/ParsedPattern.md +23 -0
  296. package/api/@xmachines/play-url/index/interfaces/PatternParam.md +15 -0
  297. package/api/@xmachines/{play-router → play-url/index}/interfaces/ResolvedBasePath.md +6 -6
  298. package/api/@xmachines/play-url/index/type-aliases/PatternModifier.md +11 -0
  299. package/api/@xmachines/play-url/index/type-aliases/PatternPart.md +9 -0
  300. package/api/@xmachines/play-url/index/type-aliases/URLPatternCtor.md +22 -0
  301. package/api/@xmachines/play-url/index/type-aliases/URLPatternLike.md +68 -0
  302. package/api/@xmachines/{play-router → play-url/index}/variables/NO_BASE_PATH.md +2 -2
  303. package/api/@xmachines/play-url/index/variables/URLPattern.md +21 -0
  304. package/api/@xmachines/play-view/README.md +165 -0
  305. package/api/@xmachines/play-view/errors/README.md +17 -0
  306. package/api/@xmachines/play-view/errors/classes/ReadOnlyContextError.md +192 -0
  307. package/api/@xmachines/play-view/index/README.md +55 -0
  308. package/api/@xmachines/{play-actor → play-view/index}/functions/attachRenderErrorHandler.md +6 -6
  309. package/api/@xmachines/{play-actor → play-view/index}/functions/composePlayState.md +2 -2
  310. package/api/@xmachines/play-view/index/functions/createFailureLatch.md +20 -0
  311. package/api/@xmachines/play-view/index/functions/createReportGuard.md +26 -0
  312. package/api/@xmachines/{play-actor → play-view/index}/functions/createViewStoreLifecycle.md +2 -2
  313. package/api/@xmachines/{play-actor → play-view/index}/functions/guardContextWrites.md +2 -2
  314. package/api/@xmachines/{play-actor → play-view/index}/functions/refreshContextSubtree.md +2 -2
  315. package/api/@xmachines/{play-actor → play-view/index}/functions/reuseComposedState.md +3 -3
  316. package/api/@xmachines/play-view/index/functions/sameViewInputs.md +25 -0
  317. package/api/@xmachines/{play-actor → play-view/index}/functions/toAtomState.md +2 -2
  318. package/api/@xmachines/{play-actor → play-view/index}/functions/typedSpec.md +2 -2
  319. package/api/@xmachines/play-view/index/interfaces/BaseActorProviderProps.md +49 -0
  320. package/api/@xmachines/{play-actor → play-view/index}/interfaces/BaseViewContextValue.md +12 -12
  321. package/api/@xmachines/play-view/index/interfaces/FailureLatch.md +60 -0
  322. package/api/@xmachines/{play-actor → play-view/index}/interfaces/PlaySpec.md +8 -8
  323. package/api/@xmachines/play-view/index/interfaces/ReportGuard.md +92 -0
  324. package/api/@xmachines/play-view/index/interfaces/ReportGuardMessages.md +18 -0
  325. package/api/@xmachines/{play-actor → play-view/index}/interfaces/ResolveViewStoreOptions.md +5 -5
  326. package/api/@xmachines/play-view/index/interfaces/ViewInputs.md +19 -0
  327. package/api/@xmachines/{play-actor → play-view/index}/interfaces/ViewStoreLifecycle.md +6 -5
  328. package/api/@xmachines/{play-actor → play-view/index}/interfaces/ViewStoreResolution.md +7 -7
  329. package/api/@xmachines/{play-actor → play-view/index}/interfaces/Viewable.md +5 -5
  330. package/api/@xmachines/play-view/index/type-aliases/ViewActor.md +26 -0
  331. package/api/@xmachines/{play-actor → play-view/index}/variables/CONTEXT_STATE_KEY.md +2 -2
  332. package/api/@xmachines/play-vue/README.md +46 -42
  333. package/api/@xmachines/play-vue/functions/defineRegistry.md +1 -1
  334. package/api/@xmachines/play-vue/functions/useActor.md +1 -1
  335. package/api/@xmachines/play-vue/functions/usePlayView.md +6 -1
  336. package/api/@xmachines/play-vue/interfaces/ActorProviderProps.md +13 -8
  337. package/api/@xmachines/play-vue/interfaces/PlayUIProviderProps.md +15 -10
  338. package/api/@xmachines/play-vue/interfaces/ViewContextValue.md +8 -8
  339. package/api/@xmachines/play-vue/type-aliases/AnyPlayActor.md +11 -3
  340. package/api/@xmachines/play-vue/type-aliases/ComponentEntry.md +1 -1
  341. package/api/@xmachines/play-vue/type-aliases/ComponentsMap.md +1 -1
  342. package/api/@xmachines/play-vue/type-aliases/DefineRegistryOptions.md +2 -2
  343. package/api/@xmachines/play-vue/variables/PlayRenderer.md +1 -1
  344. package/api/@xmachines/play-vue/variables/schema.md +71 -0
  345. package/api/@xmachines/play-vue-router/README.md +34 -77
  346. package/api/@xmachines/play-vue-router/errors/README.md +8 -0
  347. package/api/@xmachines/play-vue-router/errors/classes/VueRouterNavigationError.md +193 -0
  348. package/api/@xmachines/play-vue-router/errors/classes/VueRouterSendError.md +177 -0
  349. package/api/@xmachines/play-vue-router/index/README.md +20 -0
  350. package/api/@xmachines/play-vue-router/index/classes/RouteMap.md +157 -0
  351. package/api/@xmachines/play-vue-router/{classes → index/classes}/VueRouterBridge.md +24 -43
  352. package/api/@xmachines/play-vue-router/index/interfaces/PlayRouteEvent.md +130 -0
  353. package/api/@xmachines/play-vue-router/index/interfaces/RoutableActor.md +72 -0
  354. package/api/@xmachines/play-vue-router/{interfaces → index/interfaces}/RouteMapOptions.md +5 -5
  355. package/api/@xmachines/play-vue-router/{interfaces → index/interfaces}/RouteMapping.md +6 -6
  356. package/api/@xmachines/play-vue-router/{interfaces → index/interfaces}/RouterBridge.md +5 -5
  357. package/api/@xmachines/play-vue-router/{variables → index/variables}/PlayRouterProvider.md +4 -4
  358. package/api/@xmachines/play-xstate/README.md +163 -98
  359. package/api/@xmachines/play-xstate/errors/README.md +13 -0
  360. package/api/@xmachines/play-xstate/errors/classes/ActorThrewNonErrorError.md +199 -0
  361. package/api/@xmachines/play-xstate/errors/classes/InvalidEventError.md +198 -0
  362. package/api/@xmachines/play-xstate/errors/classes/InvalidMachineError.md +169 -0
  363. package/api/@xmachines/play-xstate/errors/classes/InvalidRouteHandlerError.md +197 -0
  364. package/api/@xmachines/play-xstate/errors/classes/InvalidRouteMetadataError.md +176 -0
  365. package/api/@xmachines/play-xstate/errors/classes/MissingRouteParamError.md +199 -0
  366. package/api/@xmachines/play-xstate/errors/classes/MissingStateIdError.md +203 -0
  367. package/api/@xmachines/play-xstate/index/README.md +38 -0
  368. package/api/@xmachines/play-xstate/index/classes/PlayerActor.md +584 -0
  369. package/api/@xmachines/play-xstate/index/functions/compose.md +224 -0
  370. package/api/@xmachines/play-xstate/index/functions/definePlayer.md +158 -0
  371. package/api/@xmachines/play-xstate/index/interfaces/PlayerConfig.md +22 -0
  372. package/api/@xmachines/play-xstate/{interfaces → index/interfaces}/PlayerFactoryResumeOptions.md +3 -3
  373. package/api/@xmachines/play-xstate/{interfaces → index/interfaces}/PlayerOptions.md +8 -8
  374. package/api/@xmachines/play-xstate/index/type-aliases/Capability.md +33 -0
  375. package/api/@xmachines/play-xstate/index/type-aliases/PlayerConstructor.md +39 -0
  376. package/api/@xmachines/play-xstate/index/type-aliases/PlayerFactory.md +27 -0
  377. package/api/@xmachines/play-xstate/index/variables/DISPOSE.md +34 -0
  378. package/api/@xmachines/play-xstate/with-routing/README.md +46 -0
  379. package/api/@xmachines/play-xstate/{functions → with-routing/functions}/buildRouteUrl.md +2 -2
  380. package/api/@xmachines/play-xstate/{functions → with-routing/functions}/deriveRoute.md +4 -4
  381. package/api/@xmachines/play-xstate/{functions → with-routing/functions}/formatPlayRouteTransitions.md +2 -2
  382. package/api/@xmachines/play-xstate/{functions → with-routing/functions}/isAbsoluteRoute.md +3 -3
  383. package/api/@xmachines/play-xstate/with-routing/functions/withRouting.md +36 -0
  384. package/api/@xmachines/play-xstate/{interfaces → with-routing/interfaces}/RouteContext.md +6 -6
  385. package/api/@xmachines/play-xstate/with-routing/interfaces/RouteObject.md +34 -0
  386. package/api/@xmachines/play-xstate/with-routing/type-aliases/RouteData.md +12 -0
  387. package/api/@xmachines/play-xstate/with-routing/type-aliases/RouteDataResolver.md +31 -0
  388. package/api/@xmachines/play-xstate/{type-aliases → with-routing/type-aliases}/RouteMachineConfig.md +5 -5
  389. package/api/@xmachines/play-xstate/with-routing/type-aliases/RouteMetadata.md +11 -0
  390. package/api/@xmachines/play-xstate/{type-aliases → with-routing/type-aliases}/RouteStateNode.md +21 -7
  391. package/api/@xmachines/play-xstate/with-view/README.md +31 -0
  392. package/api/@xmachines/play-xstate/with-view/functions/withView.md +32 -0
  393. package/api/@xmachines/shared/README.md +10 -32
  394. package/api/@xmachines/shared/vite-aliases/functions/xmAliases.md +1 -1
  395. package/api/@xmachines/shared/vite-aliases/functions/xmCacheDir.md +1 -1
  396. package/api/@xmachines/shared/vite-aliases/functions/xmOptimizeDeps.md +1 -1
  397. package/api/@xmachines/shared/vite-aliases/functions/xmResolve.md +1 -1
  398. package/api/@xmachines/shared/vite-aliases/functions/xmSvelteRunes.md +2 -2
  399. package/api/@xmachines/shared/vitest/functions/defineXmBrowserConfig.md +1 -1
  400. package/api/@xmachines/shared/vitest/functions/defineXmVitestConfig.md +2 -1
  401. package/api/@xmachines/shared/vitest/interfaces/XmBrowserConfigOptions.md +4 -4
  402. package/api/README.md +2 -0
  403. package/api/llms.txt +15 -10
  404. package/contributing/architecture.md +97 -65
  405. package/contributing/configuration.md +142 -41
  406. package/contributing/deployment.md +30 -28
  407. package/contributing/development.md +94 -31
  408. package/contributing/testing.md +90 -31
  409. package/examples/README.md +9 -7
  410. package/examples/form-validation.md +3 -2
  411. package/examples/multi-router-integration.md +61 -39
  412. package/examples/routing-patterns.md +15 -14
  413. package/examples/traffic-light.md +11 -5
  414. package/guides/README.md +1 -0
  415. package/guides/actor-model.md +35 -26
  416. package/guides/getting-started.md +47 -44
  417. package/guides/inspector.md +4 -4
  418. package/guides/routing.md +245 -0
  419. package/guides/signals.md +43 -0
  420. package/guides/state-machines.md +16 -17
  421. package/package.json +10 -9
  422. package/rfc/play.md +35 -22
  423. package/api/@xmachines/play-actor/classes/AbstractActor.md +0 -505
  424. package/api/@xmachines/play-actor/interfaces/BaseActorProviderProps.md +0 -48
  425. package/api/@xmachines/play-actor/interfaces/Routable.md +0 -14
  426. package/api/@xmachines/play-dom-router/interfaces/RouteMap.md +0 -122
  427. package/api/@xmachines/play-react/type-aliases/PlayRendererProps.md +0 -13
  428. package/api/@xmachines/play-react-router/functions/createRouteMap.md +0 -40
  429. package/api/@xmachines/play-react-router/interfaces/PlayActor.md +0 -70
  430. package/api/@xmachines/play-router/functions/createRouteMap.md +0 -40
  431. package/api/@xmachines/play-router/functions/getNavigableRoutes.md +0 -35
  432. package/api/@xmachines/play-router/functions/getPatternParamNames.md +0 -24
  433. package/api/@xmachines/play-router/functions/getRequiredPatternParamNames.md +0 -36
  434. package/api/@xmachines/play-router/functions/routeExists.md +0 -26
  435. package/api/@xmachines/play-router/interfaces/BuildPlayRouteEventOptions.md +0 -13
  436. package/api/@xmachines/play-router/interfaces/MachineEdgeData.md +0 -15
  437. package/api/@xmachines/play-router/interfaces/MachineNodeData.md +0 -17
  438. package/api/@xmachines/play-router/interfaces/PlayActor.md +0 -70
  439. package/api/@xmachines/play-router/interfaces/PlayRouteEvent.md +0 -135
  440. package/api/@xmachines/play-router/interfaces/RoutableActor.md +0 -65
  441. package/api/@xmachines/play-router/interfaces/RouteMatch.md +0 -12
  442. package/api/@xmachines/play-router/interfaces/RouteObject.md +0 -21
  443. package/api/@xmachines/play-router/interfaces/RouteTree.md +0 -21
  444. package/api/@xmachines/play-router/type-aliases/BaseRouteMapping.md +0 -13
  445. package/api/@xmachines/play-router/type-aliases/PlayRouterBridgeConstructor.md +0 -36
  446. package/api/@xmachines/play-router/type-aliases/RouteMetadata.md +0 -11
  447. package/api/@xmachines/play-solid-router/functions/createRouteMap.md +0 -40
  448. package/api/@xmachines/play-solid-router/interfaces/AbstractActor.md +0 -471
  449. package/api/@xmachines/play-solid-router/type-aliases/RoutableActor.md +0 -13
  450. package/api/@xmachines/play-svelte-spa-router/functions/createRouteMap.md +0 -40
  451. package/api/@xmachines/play-svelte-spa-router/type-aliases/RoutableActor.md +0 -9
  452. package/api/@xmachines/play-sveltekit-router/functions/createRouteMap.md +0 -40
  453. package/api/@xmachines/play-sveltekit-router/type-aliases/RoutableActor.md +0 -9
  454. package/api/@xmachines/play-tanstack-react-router/functions/createRouteMap.md +0 -40
  455. package/api/@xmachines/play-tanstack-react-router/functions/extractMachineRoutes.md +0 -29
  456. package/api/@xmachines/play-tanstack-react-router/interfaces/PlayActor.md +0 -70
  457. package/api/@xmachines/play-tanstack-react-router/interfaces/RouteNavigateEvent.md +0 -31
  458. package/api/@xmachines/play-tanstack-solid-router/functions/createRouteMap.md +0 -40
  459. package/api/@xmachines/play-tanstack-solid-router/interfaces/PlayActor.md +0 -70
  460. package/api/@xmachines/play-tanstack-solid-router/type-aliases/RoutableActor.md +0 -13
  461. package/api/@xmachines/play-vue/interfaces/VisibilityProviderProps.md +0 -9
  462. package/api/@xmachines/play-vue/variables/getPlayViewContext.md +0 -34
  463. package/api/@xmachines/play-vue-router/functions/createRouteMap.md +0 -40
  464. package/api/@xmachines/play-vue-router/interfaces/PlayActor.md +0 -70
  465. package/api/@xmachines/play-vue-router/interfaces/PlayRouteEvent.md +0 -135
  466. package/api/@xmachines/play-vue-router/type-aliases/RoutableActor.md +0 -13
  467. package/api/@xmachines/play-vue-router/type-aliases/VueRouteMap.md +0 -13
  468. package/api/@xmachines/play-vue-router/variables/VueRouteMap.md +0 -13
  469. package/api/@xmachines/play-xstate/classes/PlayerActor.md +0 -532
  470. package/api/@xmachines/play-xstate/functions/composeGuards.md +0 -86
  471. package/api/@xmachines/play-xstate/functions/composeGuardsOr.md +0 -72
  472. package/api/@xmachines/play-xstate/functions/contextFieldMatches.md +0 -43
  473. package/api/@xmachines/play-xstate/functions/definePlayer.md +0 -78
  474. package/api/@xmachines/play-xstate/functions/eventMatches.md +0 -45
  475. package/api/@xmachines/play-xstate/functions/hasContext.md +0 -45
  476. package/api/@xmachines/play-xstate/functions/negateGuard.md +0 -67
  477. package/api/@xmachines/play-xstate/interfaces/PlayerConfig.md +0 -20
  478. package/api/@xmachines/play-xstate/interfaces/RouteObject.md +0 -17
  479. package/api/@xmachines/play-xstate/type-aliases/ComposedGuard.md +0 -19
  480. package/api/@xmachines/play-xstate/type-aliases/Guard.md +0 -36
  481. package/api/@xmachines/play-xstate/type-aliases/GuardArray.md +0 -23
  482. package/api/@xmachines/play-xstate/type-aliases/PlayerFactory.md +0 -26
  483. package/api/@xmachines/play-xstate/type-aliases/RouteMetadata.md +0 -9
@@ -19,7 +19,7 @@ The boundary between them is enforced by the signal protocol: the actor exposes
19
19
  ```
20
20
  Actor (business logic)
21
21
 
22
- │ emits signals: state, currentRoute, currentView
22
+ │ emits signals: state, and currentRoute / currentView from its capabilities
23
23
 
24
24
  Infrastructure (runtime adapters)
25
25
  ├── Router Bridge — reflects currentRoute into the URL bar
@@ -33,20 +33,20 @@ Infrastructure → actor: only via actor.send({ type: "..." })
33
33
 
34
34
  ## What the actor owns
35
35
 
36
- An actor in XMachines is a [`PlayerActor`](../api/@xmachines/play-xstate/classes/PlayerActor.md) — a concrete class that extends XState's `Actor` class via [`AbstractActor`](../api/@xmachines/play-actor/classes/AbstractActor.md). It implements three reactive properties:
36
+ An actor in XMachines is a [`PlayerActor`](../api/@xmachines/play-xstate/index/classes/PlayerActor.md) — a concrete class that extends XState's `Actor` class via [`PlayActor`](../api/@xmachines/play-actor/interfaces/PlayActor.md). It implements three reactive properties:
37
37
 
38
- | Property | Type | What it is |
39
- | -------------------- | --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
40
- | `actor.state` | `Signal.State<Snapshot>` | Updated on every XState transition. The full machine snapshot. |
41
- | `actor.currentRoute` | `Signal.Computed<string \| null>` | Derived from the active state node's `meta.route`. |
42
- | `actor.currentView` | `Signal.State<PlaySpec \| null>` | Updated on each transition. Holds the [`PlaySpec`](../api/@xmachines/play-actor/interfaces/PlaySpec.md) that drives renderers. |
38
+ | Property | Type | What it is |
39
+ | -------------------- | --------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
40
+ | `actor.state` | `Signal.State<Snapshot>` | Updated on every XState transition. The full machine snapshot. |
41
+ | `actor.currentRoute` | `Signal.Computed<string \| null>` | Derived from the active state node's `meta.route`. Needs the routing capability. |
42
+ | `actor.currentView` | `Signal.State<PlaySpec \| null>` | Updated on each transition. Holds the [`PlaySpec`](../api/@xmachines/play-view/index/interfaces/PlaySpec.md) that drives renderers. Needs the view capability. |
43
43
 
44
44
  All three are set by the actor, never by infrastructure. Infrastructure reads them via signals.
45
45
 
46
46
  The actor also owns:
47
47
 
48
48
  - **Guards** — it decides whether a transition is valid. If a router sends a `play.route` event for a path the actor's guards reject, the actor does not transition. It then emits its current valid route back through `currentRoute`, and the router bridge overwrites the URL to match.
49
- - **Error states** — structured errors ([`PlayError`](../api/@xmachines/play/classes/PlayError.md)) are part of the actor's state graph, not thrown into the environment.
49
+ - **Error states** — structured errors ([`PlayError`](../api/@xmachines/play/errors/classes/PlayError.md)) are part of the actor's state graph, not thrown into the environment.
50
50
  - **Initial route** — `actor.initialRoute` is the route the actor starts in. Router adapters use this for initial navigation, not the browser's current URL.
51
51
 
52
52
  ---
@@ -87,17 +87,19 @@ This is why the invariant is called **State-Driven Reset** in the Play RFC.
87
87
 
88
88
  ---
89
89
 
90
- ## [`AbstractActor`](../api/@xmachines/play-actor/classes/AbstractActor.md) — the enforced contract
90
+ ## [`PlayActor`](../api/@xmachines/play-actor/interfaces/PlayActor.md) — the enforced contract
91
91
 
92
- [`AbstractActor`](../api/@xmachines/play-actor/classes/AbstractActor.md) (from [`@xmachines/play-actor`](../api/@xmachines/play-actor/README.md)) is the abstract base class that all actor implementations must extend. It extends XState's `Actor`, which means:
92
+ [`PlayActor`](../api/@xmachines/play-actor/interfaces/PlayActor.md) (from [`@xmachines/play-actor`](../api/@xmachines/play-actor/README.md)) is the contract that all actor implementations satisfy. It is an INTERFACE, and it names no state machine library.
93
+
94
+ An adapter extends the actor class of its own engine. [`PlayerActor`](../api/@xmachines/play-xstate/index/classes/PlayerActor.md) of [`@xmachines/play-xstate`](../api/@xmachines/play-xstate/README.md) extends `Actor` of XState, which means:
93
95
 
94
96
  - XState's inspection API works ([`@statelyai/inspect`](https://stately.ai/docs/inspector) — see [Inspecting a Running Actor](inspector.md))
95
97
  - XState DevTools attach to actors normally
96
98
  - The full XState ecosystem (testing utilities, visualization) is compatible
97
99
 
98
- [`AbstractActor`](../api/@xmachines/play-actor/classes/AbstractActor.md) adds one abstract requirement: a reactive `state` property of type `Signal.State<unknown>`. This is the single point where XState's pull-based snapshot API is bridged to TC39's push-based signal system.
100
+ [`PlayActor`](../api/@xmachines/play-actor/interfaces/PlayActor.md) asks for two members: a reactive `state` property of type `Signal.State<TSnapshot>`, and a typed `send`. `state` is the single point where the pull-based snapshot API of an engine is bridged to the push-based signal system of TC39.
99
101
 
100
- The two optional capability interfaces — [`Routable`](../api/@xmachines/play-actor/interfaces/Routable.md) and [`Viewable`](../api/@xmachines/play-actor/interfaces/Viewable.md) — are deliberately separate:
102
+ The two optional capability interfaces — [`Routable`](../api/@xmachines/play-router/index/interfaces/Routable.md) and [`Viewable`](../api/@xmachines/play-view/index/interfaces/Viewable.md) — are deliberately separate:
101
103
 
102
104
  - Not every actor needs routing (e.g., a background data-sync actor).
103
105
  - Not every actor drives a view (e.g., a sub-actor composed inside a parent).
@@ -105,26 +107,33 @@ The two optional capability interfaces — [`Routable`](../api/@xmachines/play-a
105
107
  An actor implements only the capabilities it actually uses:
106
108
 
107
109
  ```typescript
108
- // Minimal actor: just reactive state
109
- class MinimalActor extends AbstractActor<SomeLogic> {
110
- state = new Signal.State(this.getSnapshot());
110
+ // Minimal actor: the contract alone, which is reactive state and send
111
+ class MinimalActor implements PlayActor<SomeSnapshot, SomeEvent> {
112
+ readonly state = new Signal.State<SomeSnapshot>(initial);
113
+ send(event: SomeEvent): void {
114
+ /* dispatch */
115
+ }
111
116
  }
112
117
 
113
- // Full actor: state + routing + view
114
- class PlayerActor extends AbstractActor<SomeMachine> implements Routable, Viewable {
115
- state = new Signal.State(this.getSnapshot());
116
- currentRoute = new Signal.Computed(() => deriveRoute(this.state.get()));
117
- currentView = new Signal.State<PlaySpec | null>(null);
118
+ // Full actor: the contract, the routing and the view. It extends the actor class of
119
+ // its own engine, and `PlayActor` stays out of the inheritance.
120
+ class PlayerActor
121
+ extends Actor<SomeMachine>
122
+ implements PlayActor<SomeSnapshot, SomeEvent>, Routable, Viewable
123
+ {
124
+ readonly state = new Signal.State(this.getSnapshot());
125
+ readonly currentRoute = new Signal.Computed(() => deriveRoute(this.state.get()));
126
+ readonly currentView = new Signal.State<PlaySpec | null>(null);
118
127
  }
119
128
  ```
120
129
 
121
- In practice you never write [`PlayerActor`](../api/@xmachines/play-xstate/classes/PlayerActor.md) yourself — [`definePlayer`](../api/@xmachines/play-xstate/functions/definePlayer.md) from [`@xmachines/play-xstate`](../api/@xmachines/play-xstate/README.md) creates one from your machine definition.
130
+ In practice you never write [`PlayerActor`](../api/@xmachines/play-xstate/index/classes/PlayerActor.md) yourself — [`definePlayer`](../api/@xmachines/play-xstate/index/functions/definePlayer.md) from [`@xmachines/play-xstate`](../api/@xmachines/play-xstate/README.md) creates one from your machine definition.
122
131
 
123
132
  ---
124
133
 
125
- ## [`definePlayer`](../api/@xmachines/play-xstate/functions/definePlayer.md) — the factory builder
134
+ ## [`definePlayer`](../api/@xmachines/play-xstate/index/functions/definePlayer.md) — the factory builder
126
135
 
127
- [`definePlayer({ machine })`](../api/@xmachines/play-xstate/functions/definePlayer.md) is the primary entry point for creating actors:
136
+ [`definePlayer({ machine })`](../api/@xmachines/play-xstate/index/functions/definePlayer.md) is the primary entry point for creating actors:
128
137
 
129
138
  ```typescript
130
139
  import { definePlayer } from "@xmachines/play-xstate";
@@ -137,7 +146,7 @@ const actor = createPlayer();
137
146
  actor.start();
138
147
  ```
139
148
 
140
- [`definePlayer`](../api/@xmachines/play-xstate/functions/definePlayer.md) returns a **factory function**, not an actor. This is intentional: it lets you create multiple independent instances (e.g., one per test, one per user session) without re-processing the machine definition each time.
149
+ [`definePlayer`](../api/@xmachines/play-xstate/index/functions/definePlayer.md) returns a **factory function**, not an actor. This is intentional: it lets you create multiple independent instances (e.g., one per test, one per user session) without re-processing the machine definition each time.
141
150
 
142
151
  The factory accepts optional `input` (initial context overrides) and a `restore` snapshot (for resumable sessions):
143
152
 
@@ -175,6 +184,6 @@ The Play RFC captures the actor/infrastructure split in a single statement:
175
184
  - [Understanding TC39 Signals](signals.md) — how the actor communicates with infrastructure
176
185
  - [Understanding State Machines](state-machines.md) — how the machine definition drives actor behavior
177
186
  - [Getting Started](getting-started.md) — hands-on walkthrough creating and starting an actor
178
- - [@xmachines/play-actor](../api/@xmachines/play-actor/README.md) — API reference for [`AbstractActor`](../api/@xmachines/play-actor/classes/AbstractActor.md)
179
- - [@xmachines/play-xstate](../api/@xmachines/play-xstate/README.md) — API reference for [`definePlayer`](../api/@xmachines/play-xstate/functions/definePlayer.md) and [`PlayerActor`](../api/@xmachines/play-xstate/classes/PlayerActor.md)
187
+ - [@xmachines/play-actor](../api/@xmachines/play-actor/README.md) — API reference for [`PlayActor`](../api/@xmachines/play-actor/interfaces/PlayActor.md)
188
+ - [@xmachines/play-xstate](../api/@xmachines/play-xstate/README.md) — API reference for [`definePlayer`](../api/@xmachines/play-xstate/index/functions/definePlayer.md) and [`PlayerActor`](../api/@xmachines/play-xstate/index/classes/PlayerActor.md)
180
189
  - [Play RFC](../rfc/play.md) — complete architectural specification
@@ -20,13 +20,13 @@ You need the following installed before cloning the repository:
20
20
 
21
21
  | Requirement | Version | Notes |
22
22
  | ----------- | ------------------ | --------------------------------------------------------------------------------------------------------------------- |
23
- | Node.js | `>= 22.0.0` | Specified in all `package.json` `engines` fields |
23
+ | Node.js | `>= 24.0.0` | The floor to develop AND to consume. Every `package.json` `engines` field declares it. |
24
24
  | pnpm | via corepack | Enable with `corepack enable`; the version is pinned by the `packageManager` field. The project uses pnpm workspaces. |
25
25
  | Git | any recent version | Conventional commit format is enforced by CI |
26
26
 
27
27
  No global TypeScript install is needed — it is installed as a dev dependency via `pnpm install --frozen-lockfile`.
28
28
 
29
- > **Node.js version manager tip:** If you manage multiple Node versions with `nvm` or `fnm`, install and activate Node 22 before proceeding.
29
+ > **Node.js version manager tip:** If you manage multiple Node versions with `nvm` or `fnm`, install and activate Node 24 before proceeding.
30
30
 
31
31
  ### Installation Steps
32
32
 
@@ -68,7 +68,7 @@ All tests should pass on a freshly cloned and built repository. If they do, your
68
68
 
69
69
  ### Dev Container (Optional)
70
70
 
71
- A fully configured dev container is provided at `.devcontainer/`. It uses Docker Compose with a Node 22 Bookworm base image and includes Docker-outside-of-Docker, Claude Code, and OpenCode pre-installed.
71
+ A fully configured dev container is provided at `.devcontainer/`. It uses Docker Compose with a Node 24 Bookworm base image and includes Docker-outside-of-Docker, Claude Code, and OpenCode pre-installed.
72
72
 
73
73
  **VS Code:** Open the repository and choose **Reopen in Container** when prompted.
74
74
 
@@ -140,7 +140,7 @@ This section covers installing XMachines packages into your own application and
140
140
 
141
141
  ### Prerequisites
142
142
 
143
- - **Node.js** `>= 22.0.0`
143
+ - **Node.js** `>= 24.0.0`
144
144
  - **pnpm** via corepack (`corepack enable`)
145
145
  - **TypeScript** `>= 5.7` (strict mode recommended)
146
146
  - **XState** `v5` (required peer dependency for [`@xmachines/play-xstate`](../api/@xmachines/play-xstate/README.md))
@@ -157,13 +157,13 @@ Every XMachines application needs these four packages plus XState:
157
157
  pnpm add xstate @xmachines/play-xstate @xmachines/play-actor @xmachines/play-signals @xmachines/json-render-core
158
158
  ```
159
159
 
160
- | Package | Role |
161
- | --------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
162
- | `xstate` | XState v5 state machine engine (peer dependency) |
163
- | [`@xmachines/play-xstate`](../api/@xmachines/play-xstate/README.md) | [`definePlayer()`](../api/@xmachines/play-xstate/functions/definePlayer.md), [`PlayerActor`](../api/@xmachines/play-xstate/classes/PlayerActor.md), routing helpers |
164
- | [`@xmachines/play-actor`](../api/@xmachines/play-actor/README.md) | Abstract actor base class and interface types |
165
- | [`@xmachines/play-signals`](../api/@xmachines/play-signals/README.md) | TC39 Signals polyfill (`Signal.State`, `Signal.Computed`, [`watchSignal`](../api/@xmachines/play-signals/functions/watchSignal.md)) |
166
- | `@xmachines/json-render-core` | Spec and store types the actor layer builds on — a peer of `@xmachines/play-actor`, and of every renderer package |
160
+ | Package | Role |
161
+ | --------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
162
+ | `xstate` | XState v5 state machine engine (peer dependency) |
163
+ | [`@xmachines/play-xstate`](../api/@xmachines/play-xstate/README.md) | [`definePlayer()`](../api/@xmachines/play-xstate/index/functions/definePlayer.md), [`PlayerActor`](../api/@xmachines/play-xstate/index/classes/PlayerActor.md), routing helpers |
164
+ | [`@xmachines/play-actor`](../api/@xmachines/play-actor/README.md) | The actor contract: `PlayActor`, which names no state machine library |
165
+ | [`@xmachines/play-signals`](../api/@xmachines/play-signals/README.md) | TC39 Signals polyfill (`Signal.State`, `Signal.Computed`, [`watchSignal`](../api/@xmachines/play-signals/functions/watchSignal.md)) |
166
+ | `@xmachines/json-render-core` | Spec and store types the actor layer builds on — a peer of `@xmachines/play-actor`, and of every renderer package |
167
167
 
168
168
  #### Step 2: Install a router adapter (pick one)
169
169
 
@@ -171,7 +171,7 @@ pnpm add xstate @xmachines/play-xstate @xmachines/play-actor @xmachines/play-sig
171
171
  # Provider pattern (framework-integrated routers)
172
172
  pnpm add @xmachines/play-tanstack-react-router # TanStack Router (React)
173
173
  pnpm add @xmachines/play-tanstack-solid-router # TanStack Router (SolidJS)
174
- pnpm add @xmachines/play-react-router # React Router v7
174
+ pnpm add @xmachines/play-react-router # React Router 7/8
175
175
  pnpm add @xmachines/play-vue-router # Vue Router 4.x/5.x
176
176
  pnpm add @xmachines/play-solid-router # SolidJS Router
177
177
 
@@ -269,11 +269,13 @@ State machines control navigation through `meta.route` on states and `play.route
269
269
 
270
270
  #### Define a routable machine with `formatPlayRouteTransitions`
271
271
 
272
- [`formatPlayRouteTransitions`](../api/@xmachines/play-xstate/functions/formatPlayRouteTransitions.md) auto-generates `play.route` handlers from `id` + `meta.route` state pairs:
272
+ [`formatPlayRouteTransitions`](../api/@xmachines/play-xstate/with-routing/functions/formatPlayRouteTransitions.md) auto-generates `play.route` handlers from `id` + `meta.route` state pairs:
273
273
 
274
274
  ```typescript
275
275
  import { setup } from "xstate";
276
- import { definePlayer, formatPlayRouteTransitions } from "@xmachines/play-xstate";
276
+ import { definePlayer, compose, PlayerActor } from "@xmachines/play-xstate";
277
+ import { formatPlayRouteTransitions } from "@xmachines/play-xstate/routing";
278
+ import { withRouting } from "@xmachines/play-xstate/routing";
277
279
  import type { PlayRouteEvent } from "@xmachines/play-router";
278
280
 
279
281
  const appSetup = setup({
@@ -328,7 +330,10 @@ const appMachine = appSetup.createMachine(
328
330
  }),
329
331
  );
330
332
 
331
- const createPlayer = definePlayer({ machine: appMachine });
333
+ const createPlayer = definePlayer({
334
+ machine: appMachine,
335
+ actor: compose(PlayerActor, withRouting),
336
+ });
332
337
  const actor = createPlayer();
333
338
  actor.start();
334
339
 
@@ -353,7 +358,7 @@ actor.stop();
353
358
 
354
359
  **Routing rules:**
355
360
 
356
- - Every routable state **must** have an `id` — [`formatPlayRouteTransitions`](../api/@xmachines/play-xstate/functions/formatPlayRouteTransitions.md) throws `MissingStateIdError` if absent.
361
+ - Every routable state **must** have an `id` — [`formatPlayRouteTransitions`](../api/@xmachines/play-xstate/with-routing/functions/formatPlayRouteTransitions.md) throws `MissingStateIdError` if absent.
357
362
  - Send `play.route` events with `to: "#stateId"` — always use the `id` field prefixed with `#`, never raw URL paths.
358
363
  - The machine context **must** include `params: Record<string, string>` and `query: Record<string, string>`.
359
364
  - Use `always` guards to protect states from direct URL access — these fire even on browser back/forward.
@@ -372,12 +377,8 @@ Used with framework-integrated routers like TanStack Router. All three props (`a
372
377
  // React + TanStack Router example
373
378
  import { useMemo, useEffect } from "react";
374
379
  import { createRouter, createRootRoute } from "@tanstack/react-router";
375
- import {
376
- PlayRouterProvider,
377
- extractMachineRoutes,
378
- createRouteMapFromTree,
379
- } from "@xmachines/play-tanstack-react-router";
380
-
380
+ import { PlayRouterProvider, createRouteMapFromTree } from "@xmachines/play-tanstack-react-router";
381
+ import { extractMachineRoutes } from "@xmachines/play-router/xstate";
381
382
  // Build OUTSIDE of JSX — must be stable references
382
383
  const routeTree = extractMachineRoutes(appMachine);
383
384
  const routeMap = createRouteMapFromTree(routeTree);
@@ -408,7 +409,8 @@ Used with framework-agnostic or server-rendered routers. `connectRouter` handles
408
409
 
409
410
  ```typescript
410
411
  import { createBrowserHistory, createRouter, connectRouter } from "@xmachines/play-dom-router";
411
- import { extractMachineRoutes, createRouteMapFromTree } from "@xmachines/play-router";
412
+ import { createRouteMapFromTree } from "@xmachines/play-router";
413
+ import { extractMachineRoutes } from "@xmachines/play-router/xstate";
412
414
 
413
415
  const routeTree = extractMachineRoutes(appMachine);
414
416
  const routeMap = createRouteMapFromTree(routeTree);
@@ -610,7 +612,7 @@ window.addEventListener("beforeunload", () => disconnect());
610
612
  `play.route` event never appears. No error is raised — a context without a
611
613
  `query` field builds a query-less URL, exactly like `query: {}`.
612
614
 
613
- **Fix:** With [`formatPlayRouteTransitions`](../api/@xmachines/play-xstate/functions/formatPlayRouteTransitions.md)
615
+ **Fix:** With [`formatPlayRouteTransitions`](../api/@xmachines/play-xstate/with-routing/functions/formatPlayRouteTransitions.md)
614
616
  nothing is needed — the generated transitions assign `event.query` to context
615
617
  on every navigation. A machine that handles `play.route` by hand must do that
616
618
  assignment itself:
@@ -627,8 +629,9 @@ on: {
627
629
  ```
628
630
 
629
631
  (Older releases threw `MissingQueryContextError` at construction for a
630
- routing-aware context without a `query` field; the error class remains
631
- exported for `instanceof` compatibility but is never thrown.)
632
+ routing-aware context without a `query` field. That class is gone: the generated
633
+ `play.route` transitions assign `query` on every navigation, so the loss it
634
+ guarded against cannot happen.)
632
635
 
633
636
  #### Missing `id` on routable states
634
637
 
@@ -675,7 +678,7 @@ const routeMap = useMemo(() => createRouteMapFromTree(routeTree), [routeTree]);
675
678
 
676
679
  **Error:** `SyntaxError: Cannot use import statement in a module` or TC39 Signals not available.
677
680
 
678
- **Fix:** Use Node.js `>= 22.0.0`. Check with:
681
+ **Fix:** Use Node.js `>= 24.0.0`. Check with:
679
682
 
680
683
  ```bash
681
684
  node --version
@@ -685,23 +688,23 @@ node --version
685
688
 
686
689
  ## Key Concepts Reference
687
690
 
688
- | Term | Description |
689
- | ----------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- |
690
- | `setup({ types })` | XState v5 entry point — declares TypeScript types for context, events, and input |
691
- | [`definePlayer({ machine })`](../api/@xmachines/play-xstate/functions/definePlayer.md) | Creates a factory that produces [`PlayerActor`](../api/@xmachines/play-xstate/classes/PlayerActor.md) instances |
692
- | `actor.start()` | Activates the machine — always call before sending events |
693
- | `actor.send({ type })` | Sends an event; machine guards decide whether a transition occurs |
694
- | `actor.getSnapshot()` | Synchronous read of current state and context |
695
- | `actor.state` | `Signal.State<Snapshot>` — TC39 Signal for reactive state observation |
696
- | `actor.currentRoute` | `Signal.Computed<string \| null>` — resolved URL from active state's `meta.route` |
697
- | `actor.currentView` | `Signal.State<PlaySpec \| null>` — view spec from active state's `meta.view` |
698
- | [`formatPlayRouteTransitions`](../api/@xmachines/play-xstate/functions/formatPlayRouteTransitions.md) | Generates `play.route` handlers from `id` + `meta.route` state pairs |
699
- | `play.route` event | Navigation event — `to: "#stateId"`, optional `params`, `query` |
700
- | `always` guard | Protects states — fires on entry before any event, even on direct URL access |
701
- | [`extractMachineRoutes`](../api/@xmachines/play-router/functions/extractMachineRoutes.md) | Extracts a `RouteTree` from a state machine — used by framework-integrated router adapters |
702
- | [`createRouteMapFromTree`](../api/@xmachines/play-router/functions/createRouteMapFromTree.md) | Builds a `RouteMap` from a `RouteTree` for bidirectional state ID ↔ URL lookups |
703
- | [`connectRouter`](../api/@xmachines/play-dom-router/functions/connectRouter.md) | Connects a vanilla DOM router to an actor — returns a disconnect cleanup function |
704
- | [`PlayRouterProvider`](../api/@xmachines/play-tanstack-react-router/variables/PlayRouterProvider.md) | React component that connects a `PlayerActor` to TanStack React Router |
691
+ | Term | Description |
692
+ | ------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------- |
693
+ | `setup({ types })` | XState v5 entry point — declares TypeScript types for context, events, and input |
694
+ | [`definePlayer({ machine })`](../api/@xmachines/play-xstate/index/functions/definePlayer.md) | Creates a factory that produces [`PlayerActor`](../api/@xmachines/play-xstate/index/classes/PlayerActor.md) instances |
695
+ | `actor.start()` | Activates the machine — always call before sending events |
696
+ | `actor.send({ type })` | Sends an event; machine guards decide whether a transition occurs |
697
+ | `actor.getSnapshot()` | Synchronous read of current state and context |
698
+ | `actor.state` | `Signal.State<Snapshot>` — TC39 Signal for reactive state observation |
699
+ | `actor.currentRoute` | `Signal.Computed<string \| null>` — resolved URL from active state's `meta.route` |
700
+ | `actor.currentView` | `Signal.State<PlaySpec \| null>` — view spec from active state's `meta.view` |
701
+ | [`formatPlayRouteTransitions`](../api/@xmachines/play-xstate/with-routing/functions/formatPlayRouteTransitions.md) | Generates `play.route` handlers from `id` + `meta.route` state pairs |
702
+ | `play.route` event | Navigation event — `to: "#stateId"`, optional `params`, `query` |
703
+ | `always` guard | Protects states — fires on entry before any event, even on direct URL access |
704
+ | [`extractMachineRoutes`](../api/@xmachines/play-router/xstate/functions/extractMachineRoutes.md) | Extracts a `RouteTree` from a state machine — used by framework-integrated router adapters |
705
+ | [`createRouteMapFromTree`](../api/@xmachines/play-router/index/functions/createRouteMapFromTree.md) | Builds a `RouteMap` from a `RouteTree` for bidirectional state ID ↔ URL lookups |
706
+ | [`connectRouter`](../api/@xmachines/play-dom-router/functions/connectRouter.md) | Connects a vanilla DOM router to an actor — returns a disconnect cleanup function |
707
+ | [`PlayRouterProvider`](../api/@xmachines/play-tanstack-react-router/variables/PlayRouterProvider.md) | React component that connects a `PlayerActor` to TanStack React Router |
705
708
 
706
709
  ---
707
710
 
@@ -22,7 +22,7 @@ Install the inspect client alongside your existing XState dependency:
22
22
  pnpm add -D @statelyai/inspect
23
23
  ```
24
24
 
25
- Create an inspector and hand its `inspect` observer to [`definePlayer`](../api/@xmachines/play-xstate/functions/definePlayer.md):
25
+ Create an inspector and hand its `inspect` observer to [`definePlayer`](../api/@xmachines/play-xstate/index/functions/definePlayer.md):
26
26
 
27
27
  ```typescript
28
28
  import { createBrowserInspector } from "@statelyai/inspect";
@@ -42,7 +42,7 @@ actor.start();
42
42
 
43
43
  `createBrowserInspector()` opens Stately's hosted inspector in a new tab and streams the actor's events to it. From there the machine draws itself, every transition animates, and the context is readable at each step.
44
44
 
45
- That is the whole integration. [`PlayerOptions.inspect`](../api/@xmachines/play-xstate/interfaces/PlayerOptions.md) is forwarded verbatim to XState's `createActor`, so anything XState accepts there is accepted here — a function, or an observer object with a `next` method:
45
+ That is the whole integration. [`PlayerOptions.inspect`](../api/@xmachines/play-xstate/index/interfaces/PlayerOptions.md) is forwarded verbatim to XState's `createActor`, so anything XState accepts there is accepted here — a function, or an observer object with a `next` method:
46
46
 
47
47
  ```typescript
48
48
  // Function form — the common case
@@ -190,8 +190,8 @@ const createPlayer = definePlayer({ machine: appMachine, options });
190
190
 
191
191
  ## Related documentation
192
192
 
193
- - **[`PlayerOptions`](../api/@xmachines/play-xstate/interfaces/PlayerOptions.md)** — the full options bag, `inspect` included
194
- - **[`PlayerActor`](../api/@xmachines/play-xstate/classes/PlayerActor.md)** — the actor an inspector observes
193
+ - **[`PlayerOptions`](../api/@xmachines/play-xstate/index/interfaces/PlayerOptions.md)** — the full options bag, `inspect` included
194
+ - **[`PlayerActor`](../api/@xmachines/play-xstate/index/classes/PlayerActor.md)** — the actor an inspector observes
195
195
  - **[Understanding the Actor Model](actor-model.md)** — why the actor is the actor, and what that buys
196
196
  - **[Getting Started](getting-started.md)** — installing packages and creating your first actor
197
197
  - **[Stately inspect docs](https://stately.ai/docs/inspector)** — the inspector itself, its transports and options
@@ -0,0 +1,245 @@
1
+ # Understanding Routing in XMachines
2
+
3
+ A route of XMachines is a fact about a STATE, and not a fact about a component tree. A state node declares `meta.route`, and the library carries that declaration in both directions: a URL becomes a state, and a state becomes a URL.
4
+
5
+ This guide states the pattern language one time, and it names the three rules that every one of the nine router adapters follows.
6
+
7
+ After you read it, you know which patterns a route can declare, which side resolves a location, and why a bridge comes in a `connect()` and `disconnect()` pair.
8
+
9
+ ---
10
+
11
+ ## What problem URLPattern solves
12
+
13
+ A route pattern has to say two different things.
14
+
15
+ - A URL must become a **state id**. `/profile/alice` is the state `profile`, and `alice` is a param of it.
16
+ - A state must become a **URL**. The state `profile` with `{ userId: "alice" }` is the path `/profile/alice`.
17
+
18
+ The first direction needs a matcher, and every router writes its own. Express uses `path-to-regexp`, svelte-spa-router uses `regexparam`, and Vue Router, React Router, SolidJS Router, TanStack Router and SvelteKit each wrote a parser of their own. A library that spans nine of them cannot adopt one of those parsers, because each one carries a different set of features, and a machine that declares a pattern one router refuses is a machine that runs on eight of the nine.
19
+
20
+ `URLPattern` is the WHATWG standard for this, its syntax comes from `path-to-regexp`, and it is a superset of it. XMachines takes it as the pattern language, and it reads the whole of it.
21
+
22
+ This is the same decision that [`@xmachines/play-signals`](signals.md) makes for reactivity: one standard, isolated behind one module, present on every runtime. There is no `SignalsUnavailableError`, because the polyfill makes the question impossible to ask, and there is no URLPattern availability error for the same reason.
23
+
24
+ ### The API is always present
25
+
26
+ `@xmachines/play-router` carries [`urlpattern-polyfill`](https://github.com/kenchris/urlpattern-polyfill) as an ordinary dependency. It uses the native `URLPattern` when the runtime has one, and the polyfill when it does not. **Install nothing, and load nothing.**
27
+
28
+ The native API arrived in Chrome 95, in Firefox 142 and in Safari 26. The browser floor of this workspace is Chrome 110, Firefox 115 and Safari 16.4. Chrome carries the API at that floor, and Firefox and Safari carry it far above it, so a Firefox or a Safari at the floor runs the polyfill. `test/url-pattern-parity.test.ts` measures the two implementations against each other, form by form. They agree on every form of the grammar, and they disagree about one shape that no bridge can produce — see the prefix rule below.
29
+
30
+ The cost is 18 kB, minified and with no dependency of its own, and a consumer whose runtime has the native API pays it too. A conditional load would save those bytes and it would make the module asynchronous: `RouteMap` compiles in its constructor, and a navigation matches inside an event handler. Neither can await.
31
+
32
+ ---
33
+
34
+ ## The pattern grammar
35
+
36
+ A `meta.route` path is a URLPattern **pathname** pattern. These are the forms:
37
+
38
+ | Form | Name | Matches |
39
+ | ------------ | ------------ | ---------------------------------------------------------- |
40
+ | `/users` | a literal | that path, and nothing else |
41
+ | `:name` | a param | one path segment, reported to the machine as `name` |
42
+ | `:name(\d+)` | a constraint | one segment that the regular expression accepts |
43
+ | `(\d+)` | anonymous | one segment, reported under a NUMBER and not a name |
44
+ | `*` | a wildcard | every remaining character, reported under a number |
45
+ | `{…}` | a group | the forms inside it, as one unit that a modifier can carry |
46
+ | `\:` | an escape | the next character, as a literal |
47
+
48
+ A **modifier** follows a param, a wildcard or a group:
49
+
50
+ | Modifier | Meaning | A path that fills it not |
51
+ | -------- | ------------ | ------------------------ |
52
+ | none | exactly one | does not match |
53
+ | `?` | zero or one | matches |
54
+ | `+` | one or more | does not match |
55
+ | `*` | zero or more | matches |
56
+
57
+ ```ts
58
+ const machine = createMachine({
59
+ id: "app",
60
+ states: {
61
+ home: { meta: { route: "/" } },
62
+ profile: { meta: { route: "/profile/:userId" } },
63
+ settings: { meta: { route: "/settings/:section?" } },
64
+ },
65
+ });
66
+ ```
67
+
68
+ ### Which forms work in which direction
69
+
70
+ The table above is what the route map MATCHES. The two directions are not the same size
71
+ today, and a route that uses only the inbound half stops the URL silently.
72
+
73
+ | Form | URL to state | state to URL |
74
+ | ----------------------------- | ------------ | ---------------------------------------------------------------------- |
75
+ | a literal, `:name`, `:name?` | yes | yes |
76
+ | `:name*` | yes | **no** — the `*` stops the push, and the URL does not move |
77
+ | `:name+` | yes | **no** — the `+` reaches the URL, and a value with a `/` is encoded |
78
+ | `{…}` | yes | **no** — the braces reach the URL |
79
+ | `:name(\d+)`, `(\d+)` | yes | **no** — the constraint reaches the URL, or it stops the push |
80
+ | `*` | yes | **no** — the `*` stops the push, and the URL does not move |
81
+ | `:cat-id`, a hyphen in a name | yes | **no** — the substitution throws, and the URL stops |
82
+ | an escape, `\+` and `\(` | yes | yes — the bridge resolves the escape before it pushes |
83
+ | an escape, `\:` | yes | **no** — the substitution reads the escaped `:` as a param, and throws |
84
+
85
+ `buildRouteUrl` of `@xmachines/play-xstate` performs the outbound half, and it reads
86
+ `:name` and `:name?` alone. A state whose route uses another form derives a URL that its
87
+ own route matches never — or no URL at all, because `deriveCurrentRoute` catches the
88
+ `MissingRouteParamError` and answers `null`.
89
+
90
+ **Declare a route with a literal, `:name`, `:name?` and an escape until the outbound half
91
+ reads the whole grammar.** The remaining forms are safe for a route that the machine never
92
+ navigates TO, such as a catch-all that only receives a deep link. Issue #16 closes the
93
+ difference.
94
+
95
+ A constraint fails in one of two ways, and which one depends on a single character. The
96
+ derived path carries the constraint whole — `/v/:major(\d+)` with `{ major: "2" }` gives
97
+ `/v/2(\d+)` — and the bridge reads a path that holds a BACKSLASH through the grammar. It
98
+ reads `(\d+)` as a param there, so the route resolves to no one path and the push stops.
99
+ A constraint with no backslash, such as `([0-9]+)`, reaches the address bar as it stands.
100
+
101
+ `buildRouteUrl` leaves an escape as the template writes it, and the bridge resolves it
102
+ before the push. The actor route carries `/tags/c\+\+`, and the address bar receives
103
+ `/tags/c++`, which is the path that the route matches.
104
+
105
+ ### A literal that the grammar would read
106
+
107
+ `:`, `+`, `?`, `(` and `{` are characters of the grammar, so a route that writes one of them raw does not mean the literal. The two halves fail differently.
108
+
109
+ URLPattern **refuses** `:`, `+` and `?`: `/tags/c++` reads `+` as a modifier of the literal before it, and a modifier needs a part; `/time/10:30` reads `:` as the start of a param name, and `30` is no name. A route map throws `InvalidRoutePatternError` for each of them, and the error names the pattern.
110
+
111
+ URLPattern **accepts** `(` and `{`, and it reads them as grammar: `/docs/rfc(2119)` is the literal `/docs/rfc` and an anonymous param that the expression `2119` constrains, so it matches `/docs/rfc2119`; `/i18n/{en}` is a group, so it matches `/i18n/en`. Neither route reports a fault, and neither one matches the path that its author wrote.
112
+
113
+ Escape the character when you mean it literally. A `:` and a `?` are the two exceptions,
114
+ and the paragraphs below give the form to write for each.
115
+
116
+ ```
117
+ /tags/c\+\+ matches /tags/c++
118
+ /docs/rfc\(2119\) matches /docs/rfc(2119)
119
+ /time/10%3A30 matches /time/10:30
120
+ /a%3Fb matches /a?b
121
+ ```
122
+
123
+ **An escaped `:` matches, and it derives no URL.** `substituteParams` of `buildRouteUrl` reads `:30` of `/time/10\:30` as a param placeholder, finds no value for the name `30`, and throws `MissingRouteParamError` — which `deriveCurrentRoute` answers with `null`, so the address bar follows that state never. `\+` and `\(` carry no such risk, because neither character starts a param name. Write `%3A` instead: `/time/10%3A30` is an ordinary literal path, and both halves read it. Issue #16 closes the difference.
124
+
125
+ A `?` has no literal form, and the escape does not give it one. A URL pathname ends at its first `?`, so `getStateIdByPath` cuts every location there. The route `/a\?b` compiles with no fault, and no location reaches it. Write `%3F` instead: `/a%3Fb` is an ordinary literal path, and it resolves.
126
+
127
+ This rule is about the PATTERN that a state declares. A param VALUE needs no escape, because `buildRouteUrl` percent-encodes each value: `/search/:q` with `{ q: "a+b" }` becomes the location `/search/a%2Bb`, and `extractRouteParams` reads `a+b` back from it.
128
+
129
+ `encodeURIComponent` leaves `*` as it stands, and that is the one exception. A bridge refuses a path that still holds a `:` or a `*`, because such a character marks a param that nothing substituted. A value of `a*b` therefore stops the push, and the URL stays where it is.
130
+
131
+ **This is a change of behaviour, and a route of yours can hold one of these characters today.** An earlier release read a route as a pattern only when the route held a `:` or a `*`. `/tags/c++`, `/docs/rfc(2119)` and `/i18n/{en}` therefore went to the exact-match map, and each one matched the path that its author wrote. The route map reads the whole grammar now. `/tags/c++` throws `InvalidRoutePatternError` in the constructor of `RouteMap`, and the other two compile and match another path in silence. Add the escape to each route that writes one of these characters raw.
132
+
133
+ A route that carries a QUERY STRING is the same case, and it is the form a machine writes most often. `meta: { route: "/dates?trip=one-way" }` reached the exact-match map before, and the bridge pushed it to the address bar with its query. The grammar reads that `?` as a modifier that follows no part, so `RouteMap` throws `InvalidRoutePatternError` in its constructor now and the application starts never. A route declares a PATHNAME: put the default in `context.query`, which the generated `play.route` transition assigns and `buildRouteUrl` writes to the URL.
134
+
135
+ ### Upgrading from 3.x: the `reenter` default changed
136
+
137
+ An earlier release wrote `reenter: true` on every transition that `formatPlayRouteTransitions` generated, so every routed state re-entered its own domain on each navigation and ran its `entry` actions again. The flag now comes from `meta.route`, and the default is `false`, which is the default of XState.
138
+
139
+ **Nothing throws, and the `entry` action simply stops running.** A state that needs it declares the flag for itself:
140
+
141
+ ```ts
142
+ states: {
143
+ dashboard: { meta: { route: { path: "/dashboard", reenter: true } } },
144
+ },
145
+ ```
146
+
147
+ `reenter` spares the DOMAIN of the transition and not every ancestor that stays active. Under the default `handler: "root"` the domain is the root of the machine, so `false` spares the root alone and each ancestor between the root and the target still runs its `exit` and `entry` actions. `handler: "local"` and `handler: "both"` move the domain down to the parent, which is the field that spares those intermediate ancestors.
148
+
149
+ CAUTION: `"local"` also SCOPES the route. The generated transition then sits on the parent alone, so a `play.route` event that arrives while the parent is inactive matches nothing and the actor does not move — a deep link or a press on BACK therefore leaves the URL and the actor divergent. Choose `"local"` where that scope is the intent, such as a step that a person reaches only inside its wizard. Choose `"both"` where the state must stay reachable from everywhere.
150
+
151
+ ### The prefix rule
152
+
153
+ A `/` directly before a **param** belongs TO that param. A `/` directly before a **group** does not.
154
+
155
+ ```
156
+ /settings/:section? matches /settings — the modifier removed the separator too
157
+ /a/:b?/c matches /a/c
158
+ /a/{b}?/c matches /a//c, and NOT /a/c
159
+ /books{/:id}? matches /books
160
+ /books/{:id}? matches /books/, and NOT /books
161
+ ```
162
+
163
+ This one rule decides every optional route in this library. Write `{/:id}?` and not `/{:id}?` when you want the bare path to work.
164
+
165
+ **A bare path of a doubled slash is unreachable.** `sanitizePathname` joins every run of separators into one, and every bridge calls it before the match, so the location `/a//c` arrives as `/a/c` — which `/a/{b}?/c` matches never. Put the separator INSIDE the group, and the bare path is an ordinary one.
166
+
167
+ The two URLPattern implementations also disagree about a path of a doubled slash, and about nothing else: the native API matches `/{/v2}` against `//v2`, and `urlpattern-polyfill` does not. The collapse above is what keeps that difference away from your routes.
168
+
169
+ ### The one divergence from URLPattern
170
+
171
+ A param name of URLPattern is a JavaScript identifier, and it carries no hyphen: `/docs/:cat-id` is the param `cat` followed by the literal `-id` for the standard.
172
+
173
+ **XMachines reads `cat-id` as one name.** It compiles the pattern as `:cat_id` and it maps the group back, so the machine receives `{ "cat-id": "intro" }`. A route names its params the way the application does.
174
+
175
+ The cost is that you cannot write URLPattern's own reading of `:cat-id`. Use `:cat` followed by a separate literal segment when you need it.
176
+
177
+ ---
178
+
179
+ ## The routing invariants
180
+
181
+ ### 1. XMachines resolves the state id. The router never does
182
+
183
+ The router is a **source of locations** and a **sink for navigations**. It resolves a state id never, because a state id is a concept of the machine that the router knows nothing about.
184
+
185
+ | Direction | Who does the work |
186
+ | ----------------- | --------------------------------------------------------------------------------------- |
187
+ | URL → state id | XMachines. `RouteMap.getStateIdByPath` runs the URLPattern match, in all nine adapters |
188
+ | actor route → URL | XMachines, and it touches URLPattern never: a map lookup, then a substitution of params |
189
+ | params | the URLPattern extraction, except where the framework already parsed them |
190
+
191
+ That follows from the architecture: a host registers ONE catch-all route — `/:pathMatch(.*)*` in the Vue demo — so the framework matches nothing that belongs to the machine.
192
+
193
+ Vue Router and SolidJS Router parse their own params, and their bridges keep that parse when it covers every **required** name of the pattern. That is an optimization, and never a second source of truth: a bridge under a mount ignores the framework entirely, because the framework matched a route of the HOST there and a name that collides carries the value of the host.
194
+
195
+ ### 2. A `basePath` divides the two sides
196
+
197
+ A machine can own the whole router, or it can sit under a mount. `basePath` is the prefix that belongs to the host, and the machine owns the suffix alone. Every path that reaches the machine has the prefix removed already, and every path that the machine pushes gets it back.
198
+
199
+ ### 3. `connect()` and `disconnect()` come in a pair, and one actor takes one bridge
200
+
201
+ A bridge installs a signal watcher on the actor and a subscription on the router. Neither releases itself.
202
+
203
+ - Call `disconnect()` from the teardown of your component: `useEffect` cleanup in React, `onUnmounted` in Vue, `onCleanup` in Solid.
204
+ - A second `connect()` on an actor that already has a bridge throws `DuplicateBridgeError`. The actor takes one bridge, so that two bridges cannot drive it in opposite directions.
205
+ - `connect()` gives all or nothing. It installs the watcher and the subscription BEFORE the first synchronization, because that synchronization drives both directions — and when the synchronization throws, `connect()` removes everything it installed and frees the actor again.
206
+
207
+ ---
208
+
209
+ ## Which patterns cost what
210
+
211
+ - A **static** route costs nothing. `RouteMap` splits at construction: a literal path goes into an exact-match `Map`, and only a pattern compiles a `URLPattern`. A route map of literal paths alone reaches the API never.
212
+ - A **parameterized** route pays one compilation in the constructor, and one match for each distinct path, behind an LRU cache.
213
+ - A route that a **framework** already parsed pays neither, for as long as its parse covers every required name.
214
+
215
+ ---
216
+
217
+ ## Why not a matcher of our own
218
+
219
+ The 2.2.0 review asked whether a hand-written segment matcher could drop the `URLPattern` requirement. The answer is no, and the reason is not the size of the code.
220
+
221
+ A pattern language has to carry the largest set of features that the nine target routers can express, and not the subset that this repository happens to use today. A count of the patterns HERE — 85 of 88 are a literal plus `:name` — measures our own habits, and it is the wrong basis for the decision. `URLPattern` is the most expressive engine available, and a matcher of our own would carry less.
222
+
223
+ Two matchers that disagree is also a worse failure than one dependency. The match and the extraction of the params would then read the same pattern differently, and a route would resolve while its params came back empty.
224
+
225
+ ---
226
+
227
+ ## Summary
228
+
229
+ | Question | Answer |
230
+ | ----------------------------------------- | --------------------------------------------------------------- |
231
+ | What is the pattern language? | The `URLPattern` pathname grammar, plus hyphenated param names |
232
+ | Do I install a polyfill? | No. `@xmachines/play-router` carries one |
233
+ | Which side turns a URL into a state? | XMachines, in every adapter |
234
+ | Which side turns a state into a URL? | XMachines, with no URLPattern at all |
235
+ | When does the framework parse the params? | Vue Router and SolidJS Router, when the parse covers every name |
236
+ | Who releases the bridge? | You, through `disconnect()` in the teardown of your component |
237
+
238
+ ## See also
239
+
240
+ - [Understanding State Machines](state-machines.md) — how `meta.route` reaches the route map
241
+ - [Understanding TC39 Signals](signals.md) — the same decision, made for reactivity
242
+ - [Multi-router integration](../examples/multi-router-integration.md) — the provider pattern and `basePath`, end to end
243
+ - [Routing patterns](../examples/routing-patterns.md) — worked route maps
244
+ - [@xmachines/play-router](../api/@xmachines/play-router/README.md) — API reference
245
+ - [URLPattern on MDN](https://developer.mozilla.org/en-US/docs/Web/API/URLPattern) — the standard