@xmachines/docs 1.0.0-beta.45 → 1.0.0-beta.48
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +135 -7
- package/api/@xmachines/play/README.md +134 -57
- package/api/@xmachines/play/classes/NonNullableError.md +4 -4
- package/api/@xmachines/play/classes/PlayError.md +4 -4
- package/api/@xmachines/play/functions/assertNonNullable.md +1 -1
- package/api/@xmachines/play/type-aliases/PlayEvent.md +2 -2
- package/api/@xmachines/play-actor/README.md +130 -155
- package/api/@xmachines/play-actor/classes/AbstractActor.md +3 -3
- package/api/@xmachines/play-actor/functions/typedSpec.md +1 -1
- package/api/@xmachines/play-actor/interfaces/BaseActorProviderProps.md +5 -5
- package/api/@xmachines/play-actor/interfaces/BaseViewContextValue.md +5 -5
- package/api/@xmachines/play-actor/interfaces/PlaySpec.md +2 -2
- package/api/@xmachines/play-actor/interfaces/Routable.md +3 -3
- package/api/@xmachines/play-actor/interfaces/Viewable.md +2 -2
- package/api/@xmachines/play-dom/README.md +140 -232
- package/api/@xmachines/play-dom/classes/PlayRenderer.md +4 -4
- package/api/@xmachines/play-dom/functions/connectRenderer.md +1 -1
- package/api/@xmachines/play-dom/functions/createPlayUI.md +1 -1
- package/api/@xmachines/play-dom/functions/createRenderer.md +1 -1
- package/api/@xmachines/play-dom/functions/defineRegistry.md +1 -1
- package/api/@xmachines/play-dom/functions/renderSpec.md +1 -1
- package/api/@xmachines/play-dom/interfaces/ComponentContext.md +7 -7
- package/api/@xmachines/play-dom/interfaces/ConnectRendererOptions.md +13 -13
- package/api/@xmachines/play-dom/interfaces/CreatePlayUIOptions.md +6 -6
- package/api/@xmachines/play-dom/interfaces/DefineRegistryResult.md +4 -4
- package/api/@xmachines/play-dom/interfaces/DomRenderContext.md +12 -12
- package/api/@xmachines/play-dom/interfaces/EventHandle.md +4 -4
- package/api/@xmachines/play-dom/interfaces/MountOptions.md +3 -3
- package/api/@xmachines/play-dom/interfaces/PlayDomOptions.md +5 -5
- package/api/@xmachines/play-dom/interfaces/UIProviderOptions.md +5 -5
- package/api/@xmachines/play-dom/type-aliases/ActionFn.md +1 -1
- package/api/@xmachines/play-dom/type-aliases/Actions.md +1 -1
- package/api/@xmachines/play-dom/type-aliases/BaseComponentProps.md +7 -7
- package/api/@xmachines/play-dom/type-aliases/CatalogHasActions.md +1 -1
- package/api/@xmachines/play-dom/type-aliases/ComponentFn.md +1 -1
- package/api/@xmachines/play-dom/type-aliases/ComponentRegistry.md +1 -1
- package/api/@xmachines/play-dom/type-aliases/DefineRegistryOptions.md +2 -2
- package/api/@xmachines/play-dom/type-aliases/DomComponentRenderer.md +1 -1
- package/api/@xmachines/play-dom/type-aliases/DomRegistry.md +1 -1
- package/api/@xmachines/play-dom/type-aliases/DomSchema.md +1 -1
- package/api/@xmachines/play-dom/type-aliases/MountFn.md +1 -1
- package/api/@xmachines/play-dom/type-aliases/SetState.md +1 -1
- package/api/@xmachines/play-dom/variables/schema.md +1 -1
- package/api/@xmachines/play-dom-router/README.md +160 -158
- package/api/@xmachines/play-dom-router/functions/connectRouter.md +1 -1
- package/api/@xmachines/play-dom-router/functions/createBrowserHistory.md +1 -1
- package/api/@xmachines/play-dom-router/functions/createRouteMap.md +1 -1
- package/api/@xmachines/play-dom-router/functions/createRouter.md +1 -1
- package/api/@xmachines/play-dom-router/interfaces/BrowserHistory.md +14 -14
- package/api/@xmachines/play-dom-router/interfaces/BrowserWindow.md +14 -14
- package/api/@xmachines/play-dom-router/interfaces/ConnectRouterOptions.md +4 -4
- package/api/@xmachines/play-dom-router/interfaces/PlayRouteEvent.md +6 -6
- package/api/@xmachines/play-dom-router/interfaces/RouteLookupContract.md +3 -3
- package/api/@xmachines/play-dom-router/interfaces/RouteMap.md +3 -3
- package/api/@xmachines/play-dom-router/interfaces/RouteMapOptions.md +2 -2
- package/api/@xmachines/play-dom-router/interfaces/RouteMapping.md +3 -3
- package/api/@xmachines/play-dom-router/interfaces/RouterBridge.md +3 -3
- package/api/@xmachines/play-dom-router/interfaces/VanillaRouter.md +4 -4
- package/api/@xmachines/play-dom-router/type-aliases/RoutableActor.md +1 -1
- package/api/@xmachines/play-react/README.md +109 -320
- package/api/@xmachines/play-react/classes/PlayErrorBoundary.md +5 -5
- package/api/@xmachines/play-react/functions/useActor.md +1 -1
- package/api/@xmachines/play-react/functions/usePlayView.md +1 -1
- package/api/@xmachines/play-react/functions/useSignalEffect.md +1 -1
- package/api/@xmachines/play-react/interfaces/ActorProviderProps.md +8 -8
- package/api/@xmachines/play-react/interfaces/PlayErrorBoundaryProps.md +4 -4
- package/api/@xmachines/play-react/interfaces/PlayErrorBoundaryState.md +3 -3
- package/api/@xmachines/play-react/interfaces/PlayUIProviderProps.md +8 -8
- package/api/@xmachines/play-react/interfaces/ViewContextValue.md +5 -5
- package/api/@xmachines/play-react/type-aliases/PlayActor.md +1 -1
- package/api/@xmachines/play-react/variables/ActorProvider.md +1 -1
- package/api/@xmachines/play-react/variables/PlayRenderer.md +1 -1
- package/api/@xmachines/play-react/variables/PlayUIProvider.md +1 -1
- package/api/@xmachines/play-react-router/README.md +107 -124
- package/api/@xmachines/play-react-router/classes/ReactRouterBridge.md +23 -23
- package/api/@xmachines/play-react-router/classes/RouteMap.md +4 -4
- package/api/@xmachines/play-react-router/functions/PlayRouterProvider.md +1 -1
- package/api/@xmachines/play-react-router/functions/createRouteMap.md +1 -1
- package/api/@xmachines/play-react-router/functions/createRouteMapFromTree.md +1 -1
- package/api/@xmachines/play-react-router/interfaces/PlayRouteEvent.md +6 -6
- package/api/@xmachines/play-react-router/interfaces/PlayRouterProviderProps.md +5 -5
- package/api/@xmachines/play-react-router/interfaces/RouteMapOptions.md +2 -2
- package/api/@xmachines/play-react-router/interfaces/RouteMapping.md +3 -3
- package/api/@xmachines/play-react-router/interfaces/RouterBridge.md +3 -3
- package/api/@xmachines/play-router/README.md +235 -475
- package/api/@xmachines/play-router/classes/RouteMap.md +4 -4
- package/api/@xmachines/play-router/classes/RouterBridgeBase.md +23 -23
- package/api/@xmachines/play-router/functions/buildPlayRouteEvent.md +1 -1
- package/api/@xmachines/play-router/functions/buildRouteTree.md +1 -1
- package/api/@xmachines/play-router/functions/createRouteMap.md +1 -1
- package/api/@xmachines/play-router/functions/createRouteMapFromTree.md +1 -1
- package/api/@xmachines/play-router/functions/createRouteMatcher.md +1 -1
- package/api/@xmachines/play-router/functions/detectDuplicateRoutes.md +1 -1
- package/api/@xmachines/play-router/functions/extractMachineRoutes.md +1 -1
- package/api/@xmachines/play-router/functions/extractQuery.md +1 -1
- package/api/@xmachines/play-router/functions/extractRouteParams.md +1 -1
- package/api/@xmachines/play-router/functions/findRouteById.md +1 -1
- package/api/@xmachines/play-router/functions/findRouteByPath.md +1 -1
- package/api/@xmachines/play-router/functions/getNavigableRoutes.md +1 -1
- package/api/@xmachines/play-router/functions/getRoutableRoutes.md +1 -1
- package/api/@xmachines/play-router/functions/getTransitionReachableRoutes.md +1 -1
- package/api/@xmachines/play-router/functions/isRouteReachable.md +1 -1
- package/api/@xmachines/play-router/functions/machineToGraph.md +1 -1
- package/api/@xmachines/play-router/functions/routeExists.md +1 -1
- package/api/@xmachines/play-router/functions/sanitizePathname.md +1 -1
- package/api/@xmachines/play-router/functions/validateRouteFormat.md +1 -1
- package/api/@xmachines/play-router/functions/validateStateExists.md +1 -1
- package/api/@xmachines/play-router/interfaces/BuildPlayRouteEventOptions.md +4 -4
- package/api/@xmachines/play-router/interfaces/LocationLike.md +3 -3
- package/api/@xmachines/play-router/interfaces/MachineEdgeData.md +3 -3
- package/api/@xmachines/play-router/interfaces/MachineNodeData.md +5 -5
- package/api/@xmachines/play-router/interfaces/PlayRouteEvent.md +6 -6
- package/api/@xmachines/play-router/interfaces/RouteInfo.md +8 -8
- package/api/@xmachines/play-router/interfaces/RouteMapOptions.md +2 -2
- package/api/@xmachines/play-router/interfaces/RouteMapping.md +3 -3
- package/api/@xmachines/play-router/interfaces/RouteMatch.md +3 -3
- package/api/@xmachines/play-router/interfaces/RouteMatcher.md +4 -4
- package/api/@xmachines/play-router/interfaces/RouteNode.md +10 -10
- package/api/@xmachines/play-router/interfaces/RouteObject.md +2 -2
- package/api/@xmachines/play-router/interfaces/RouteTree.md +5 -5
- package/api/@xmachines/play-router/interfaces/RouteWatcherHandle.md +3 -3
- package/api/@xmachines/play-router/interfaces/RouterBridge.md +3 -3
- package/api/@xmachines/play-router/interfaces/WindowLike.md +3 -3
- package/api/@xmachines/play-router/type-aliases/MachineGraph.md +1 -1
- package/api/@xmachines/play-router/type-aliases/RouteMetadata.md +1 -1
- package/api/@xmachines/play-signals/README.md +105 -73
- package/api/@xmachines/play-signals/functions/watchSignal.md +1 -1
- package/api/@xmachines/play-signals/interfaces/ComputedOptions.md +2 -2
- package/api/@xmachines/play-signals/interfaces/SignalComputed.md +2 -2
- package/api/@xmachines/play-signals/interfaces/SignalOptions.md +2 -2
- package/api/@xmachines/play-signals/interfaces/SignalState.md +3 -3
- package/api/@xmachines/play-signals/interfaces/SignalWatcher.md +4 -4
- package/api/@xmachines/play-signals/type-aliases/WatcherNotify.md +1 -1
- package/api/@xmachines/play-solid/README.md +117 -263
- package/api/@xmachines/play-solid/functions/useActor.md +1 -1
- package/api/@xmachines/play-solid/functions/usePlayView.md +1 -1
- package/api/@xmachines/play-solid/interfaces/ActorProviderProps.md +8 -8
- package/api/@xmachines/play-solid/interfaces/PlayUIProviderProps.md +8 -8
- package/api/@xmachines/play-solid/interfaces/ViewContextValue.md +5 -5
- package/api/@xmachines/play-solid/type-aliases/PlayActor.md +1 -1
- package/api/@xmachines/play-solid/variables/ActorContext.md +1 -1
- package/api/@xmachines/play-solid/variables/ActorProvider.md +1 -1
- package/api/@xmachines/play-solid/variables/PlayRenderer.md +1 -1
- package/api/@xmachines/play-solid/variables/PlayUIProvider.md +1 -1
- package/api/@xmachines/play-solid-router/README.md +93 -606
- package/api/@xmachines/play-solid-router/classes/RouteMap.md +4 -4
- package/api/@xmachines/play-solid-router/classes/SolidRouterBridge.md +24 -24
- package/api/@xmachines/play-solid-router/functions/PlayRouterProvider.md +1 -1
- package/api/@xmachines/play-solid-router/functions/createRouteMap.md +1 -1
- package/api/@xmachines/play-solid-router/interfaces/AbstractActor.md +3 -3
- package/api/@xmachines/play-solid-router/interfaces/PlayRouteEvent.md +6 -6
- package/api/@xmachines/play-solid-router/interfaces/PlayRouterProviderProps.md +5 -5
- package/api/@xmachines/play-solid-router/interfaces/RouteMapOptions.md +2 -2
- package/api/@xmachines/play-solid-router/interfaces/RouteMapping.md +3 -3
- package/api/@xmachines/play-solid-router/interfaces/RouterBridge.md +3 -3
- package/api/@xmachines/play-solid-router/type-aliases/RoutableActor.md +1 -1
- package/api/@xmachines/play-solid-router/type-aliases/SolidRouterHooks.md +4 -4
- package/api/@xmachines/play-svelte/README.md +111 -103
- package/api/@xmachines/play-svelte/functions/defineRegistry.md +1 -1
- package/api/@xmachines/play-svelte/functions/getActorContext.md +1 -1
- package/api/@xmachines/play-svelte/functions/getPlayViewContext.md +1 -1
- package/api/@xmachines/play-svelte/functions/setActorContext.md +1 -1
- package/api/@xmachines/play-svelte/interfaces/ActorProviderProps.md +8 -8
- package/api/@xmachines/play-svelte/interfaces/DefineRegistryOptions.md +4 -4
- package/api/@xmachines/play-svelte/interfaces/PlayUIProviderProps.md +11 -11
- package/api/@xmachines/play-svelte/interfaces/ViewContextValue.md +5 -5
- package/api/@xmachines/play-svelte/type-aliases/PlayActor.md +1 -1
- package/api/@xmachines/play-svelte-spa-router/README.md +156 -17
- package/api/@xmachines/play-svelte-spa-router/classes/RouteMap.md +4 -4
- package/api/@xmachines/play-svelte-spa-router/functions/connectRouter.md +1 -1
- package/api/@xmachines/play-svelte-spa-router/functions/createRouteMap.md +1 -1
- package/api/@xmachines/play-svelte-spa-router/interfaces/ConnectRouterOptions.md +4 -4
- package/api/@xmachines/play-svelte-spa-router/interfaces/PlayRouteEvent.md +6 -6
- package/api/@xmachines/play-svelte-spa-router/interfaces/RouteMapOptions.md +2 -2
- package/api/@xmachines/play-svelte-spa-router/interfaces/RouteMapping.md +3 -3
- package/api/@xmachines/play-svelte-spa-router/interfaces/RouterBridge.md +3 -3
- package/api/@xmachines/play-svelte-spa-router/interfaces/WindowLike.md +3 -3
- package/api/@xmachines/play-svelte-spa-router/type-aliases/RoutableActor.md +1 -1
- package/api/@xmachines/play-sveltekit-router/README.md +168 -17
- package/api/@xmachines/play-sveltekit-router/classes/RouteMap.md +4 -4
- package/api/@xmachines/play-sveltekit-router/functions/connectRouter.md +1 -1
- package/api/@xmachines/play-sveltekit-router/functions/createRouteMap.md +1 -1
- package/api/@xmachines/play-sveltekit-router/interfaces/ConnectRouterOptions.md +4 -4
- package/api/@xmachines/play-sveltekit-router/interfaces/LocationLike.md +3 -3
- package/api/@xmachines/play-sveltekit-router/interfaces/PlayRouteEvent.md +6 -6
- package/api/@xmachines/play-sveltekit-router/interfaces/RouteMapOptions.md +2 -2
- package/api/@xmachines/play-sveltekit-router/interfaces/RouteMapping.md +3 -3
- package/api/@xmachines/play-sveltekit-router/interfaces/RouterBridge.md +3 -3
- package/api/@xmachines/play-sveltekit-router/type-aliases/RoutableActor.md +1 -1
- package/api/@xmachines/play-tanstack-react-router/README.md +147 -122
- package/api/@xmachines/play-tanstack-react-router/classes/RouteMap.md +4 -4
- package/api/@xmachines/play-tanstack-react-router/classes/TanStackReactRouterBridge.md +23 -23
- package/api/@xmachines/play-tanstack-react-router/functions/PlayRouterProvider.md +1 -1
- package/api/@xmachines/play-tanstack-react-router/functions/createRouteMap.md +1 -1
- package/api/@xmachines/play-tanstack-react-router/functions/createRouteMapFromTree.md +1 -1
- package/api/@xmachines/play-tanstack-react-router/functions/extractMachineRoutes.md +1 -1
- package/api/@xmachines/play-tanstack-react-router/interfaces/PlayRouteEvent.md +6 -6
- package/api/@xmachines/play-tanstack-react-router/interfaces/PlayRouterProviderProps.md +5 -5
- package/api/@xmachines/play-tanstack-react-router/interfaces/RouteMapOptions.md +2 -2
- package/api/@xmachines/play-tanstack-react-router/interfaces/RouteMapping.md +3 -3
- package/api/@xmachines/play-tanstack-react-router/interfaces/RouteNavigateEvent.md +3 -3
- package/api/@xmachines/play-tanstack-react-router/interfaces/RouterBridge.md +3 -3
- package/api/@xmachines/play-tanstack-react-router/type-aliases/TanStackRouterInstance.md +1 -1
- package/api/@xmachines/play-tanstack-react-router/type-aliases/TanStackRouterLike.md +4 -4
- package/api/@xmachines/play-tanstack-solid-router/README.md +195 -173
- package/api/@xmachines/play-tanstack-solid-router/classes/RouteMap.md +4 -4
- package/api/@xmachines/play-tanstack-solid-router/classes/SolidRouterBridge.md +24 -24
- package/api/@xmachines/play-tanstack-solid-router/functions/PlayRouterProvider.md +1 -1
- package/api/@xmachines/play-tanstack-solid-router/functions/createRouteMap.md +1 -1
- package/api/@xmachines/play-tanstack-solid-router/interfaces/PlayRouteEvent.md +6 -6
- package/api/@xmachines/play-tanstack-solid-router/interfaces/PlayRouterProviderProps.md +5 -5
- package/api/@xmachines/play-tanstack-solid-router/interfaces/RouteMapOptions.md +2 -2
- package/api/@xmachines/play-tanstack-solid-router/interfaces/RouteMapping.md +3 -3
- package/api/@xmachines/play-tanstack-solid-router/interfaces/RouterBridge.md +3 -3
- package/api/@xmachines/play-tanstack-solid-router/type-aliases/RoutableActor.md +1 -1
- package/api/@xmachines/play-tanstack-solid-router/type-aliases/TanStackRouterInstance.md +1 -1
- package/api/@xmachines/play-tanstack-solid-router/type-aliases/TanStackRouterLike.md +3 -3
- package/api/@xmachines/play-vue/README.md +126 -271
- package/api/@xmachines/play-vue/functions/defineRegistry.md +1 -1
- package/api/@xmachines/play-vue/functions/getPlayViewContext.md +1 -1
- package/api/@xmachines/play-vue/functions/useActor.md +1 -1
- package/api/@xmachines/play-vue/interfaces/ActorProviderProps.md +5 -5
- package/api/@xmachines/play-vue/interfaces/PlayUIProviderProps.md +8 -8
- package/api/@xmachines/play-vue/interfaces/ViewContextValue.md +5 -5
- package/api/@xmachines/play-vue/interfaces/VisibilityProviderProps.md +1 -1
- package/api/@xmachines/play-vue/type-aliases/ComponentEntry.md +1 -1
- package/api/@xmachines/play-vue/type-aliases/ComponentsMap.md +1 -1
- package/api/@xmachines/play-vue/type-aliases/DefineRegistryOptions.md +2 -2
- package/api/@xmachines/play-vue/type-aliases/PlayActor.md +1 -1
- package/api/@xmachines/play-vue/variables/PlayRenderer.md +1 -1
- package/api/@xmachines/play-vue-router/README.md +148 -528
- package/api/@xmachines/play-vue-router/classes/RouteMap.md +4 -4
- package/api/@xmachines/play-vue-router/classes/VueRouterBridge.md +24 -24
- package/api/@xmachines/play-vue-router/functions/createRouteMap.md +1 -1
- package/api/@xmachines/play-vue-router/interfaces/PlayRouteEvent.md +6 -6
- package/api/@xmachines/play-vue-router/interfaces/RouteMapOptions.md +2 -2
- package/api/@xmachines/play-vue-router/interfaces/RouteMapping.md +3 -3
- package/api/@xmachines/play-vue-router/interfaces/RouterBridge.md +3 -3
- package/api/@xmachines/play-vue-router/type-aliases/RoutableActor.md +1 -1
- package/api/@xmachines/play-vue-router/variables/PlayRouterProvider.md +1 -1
- package/api/@xmachines/play-xstate/README.md +167 -496
- package/api/@xmachines/play-xstate/classes/PlayerActor.md +12 -12
- package/api/@xmachines/play-xstate/functions/buildRouteUrl.md +1 -1
- package/api/@xmachines/play-xstate/functions/composeGuards.md +1 -1
- package/api/@xmachines/play-xstate/functions/composeGuardsOr.md +1 -1
- package/api/@xmachines/play-xstate/functions/contextFieldMatches.md +1 -1
- package/api/@xmachines/play-xstate/functions/definePlayer.md +1 -1
- package/api/@xmachines/play-xstate/functions/deriveRoute.md +1 -1
- package/api/@xmachines/play-xstate/functions/eventMatches.md +1 -1
- package/api/@xmachines/play-xstate/functions/formatPlayRouteTransitions.md +1 -1
- package/api/@xmachines/play-xstate/functions/hasContext.md +1 -1
- package/api/@xmachines/play-xstate/functions/isAbsoluteRoute.md +1 -1
- package/api/@xmachines/play-xstate/functions/negateGuard.md +1 -1
- package/api/@xmachines/play-xstate/interfaces/PlayerConfig.md +3 -3
- package/api/@xmachines/play-xstate/interfaces/PlayerFactoryResumeOptions.md +2 -2
- package/api/@xmachines/play-xstate/interfaces/PlayerOptions.md +6 -6
- package/api/@xmachines/play-xstate/interfaces/RouteContext.md +5 -5
- package/api/@xmachines/play-xstate/type-aliases/ComposedGuard.md +1 -1
- package/api/@xmachines/play-xstate/type-aliases/Guard.md +1 -1
- package/api/@xmachines/play-xstate/type-aliases/GuardArray.md +1 -1
- package/api/@xmachines/play-xstate/type-aliases/PlayerFactory.md +1 -1
- package/api/@xmachines/play-xstate/type-aliases/RouteMachineConfig.md +4 -4
- package/api/@xmachines/play-xstate/type-aliases/RouteStateNode.md +4 -4
- package/api/@xmachines/shared/README.md +81 -294
- package/api/@xmachines/shared/vite-aliases/functions/xmAliases.md +1 -1
- package/api/@xmachines/shared/vite-aliases/functions/xmCacheDir.md +1 -1
- package/api/@xmachines/shared/vite-aliases/functions/xmOptimizeDeps.md +1 -1
- package/api/@xmachines/shared/vite-aliases/functions/xmResolve.md +1 -1
- package/api/@xmachines/shared/vitest/functions/defineXmVitestConfig.md +1 -1
- package/examples/@xmachines/play-dom-demo/README.md +4 -4
- package/examples/@xmachines/play-dom-demo/functions/createNavBar.md +1 -1
- package/examples/@xmachines/play-dom-demo/functions/initShell.md +1 -1
- package/examples/@xmachines/play-dom-demo/type-aliases/AuthCatalog.md +1 -1
- package/examples/@xmachines/play-dom-demo/variables/About.md +1 -1
- package/examples/@xmachines/play-dom-demo/variables/Contact.md +1 -1
- package/examples/@xmachines/play-dom-demo/variables/Dashboard.md +1 -1
- package/examples/@xmachines/play-dom-demo/variables/Home.md +1 -1
- package/examples/@xmachines/play-dom-demo/variables/Login.md +1 -1
- package/examples/@xmachines/play-dom-demo/variables/NavBarView.md +1 -1
- package/examples/@xmachines/play-dom-demo/variables/Navigation.md +1 -1
- package/examples/@xmachines/play-dom-demo/variables/Overview.md +1 -1
- package/examples/@xmachines/play-dom-demo/variables/Profile.md +1 -1
- package/examples/@xmachines/play-dom-demo/variables/Settings.md +1 -1
- package/examples/@xmachines/play-dom-demo/variables/Stats.md +1 -1
- package/examples/@xmachines/play-dom-demo/variables/authCatalog.md +1 -1
- package/examples/@xmachines/play-dom-router-demo/README.md +3 -3
- package/examples/@xmachines/play-react-demo/README.md +2 -2
- package/examples/@xmachines/play-react-demo/functions/App.md +1 -1
- package/examples/@xmachines/play-react-demo/type-aliases/AuthCatalog.md +1 -1
- package/examples/@xmachines/play-react-demo/variables/About.md +1 -1
- package/examples/@xmachines/play-react-demo/variables/Contact.md +1 -1
- package/examples/@xmachines/play-react-demo/variables/Dashboard.md +1 -1
- package/examples/@xmachines/play-react-demo/variables/DebugPanel.md +1 -1
- package/examples/@xmachines/play-react-demo/variables/Home.md +1 -1
- package/examples/@xmachines/play-react-demo/variables/Login.md +1 -1
- package/examples/@xmachines/play-react-demo/variables/NavBar.md +1 -1
- package/examples/@xmachines/play-react-demo/variables/NavBarView.md +1 -1
- package/examples/@xmachines/play-react-demo/variables/Navigation.md +1 -1
- package/examples/@xmachines/play-react-demo/variables/Overview.md +1 -1
- package/examples/@xmachines/play-react-demo/variables/Profile.md +1 -1
- package/examples/@xmachines/play-react-demo/variables/Settings.md +1 -1
- package/examples/@xmachines/play-react-demo/variables/Shell.md +1 -1
- package/examples/@xmachines/play-react-demo/variables/Stats.md +1 -1
- package/examples/@xmachines/play-react-demo/variables/authCatalog.md +1 -1
- package/examples/@xmachines/play-react-router-demo/README.md +2 -2
- package/examples/@xmachines/play-solid-demo/README.md +2 -2
- package/examples/@xmachines/play-solid-demo/functions/App.md +1 -1
- package/examples/@xmachines/play-solid-demo/type-aliases/AuthCatalog.md +1 -1
- package/examples/@xmachines/play-solid-demo/variables/About.md +1 -1
- package/examples/@xmachines/play-solid-demo/variables/Contact.md +1 -1
- package/examples/@xmachines/play-solid-demo/variables/Dashboard.md +1 -1
- package/examples/@xmachines/play-solid-demo/variables/DebugPanel.md +1 -1
- package/examples/@xmachines/play-solid-demo/variables/Home.md +1 -1
- package/examples/@xmachines/play-solid-demo/variables/Login.md +1 -1
- package/examples/@xmachines/play-solid-demo/variables/NavBar.md +1 -1
- package/examples/@xmachines/play-solid-demo/variables/NavBarView.md +1 -1
- package/examples/@xmachines/play-solid-demo/variables/Navigation.md +1 -1
- package/examples/@xmachines/play-solid-demo/variables/Overview.md +1 -1
- package/examples/@xmachines/play-solid-demo/variables/Profile.md +1 -1
- package/examples/@xmachines/play-solid-demo/variables/Settings.md +1 -1
- package/examples/@xmachines/play-solid-demo/variables/Shell.md +1 -1
- package/examples/@xmachines/play-solid-demo/variables/Stats.md +1 -1
- package/examples/@xmachines/play-solid-demo/variables/authCatalog.md +1 -1
- package/examples/@xmachines/play-solid-router-demo/README.md +1 -1
- package/examples/@xmachines/play-svelte-demo/README.md +2 -2
- package/examples/@xmachines/play-svelte-demo/type-aliases/AuthCatalog.md +1 -1
- package/examples/@xmachines/play-svelte-demo/variables/authCatalog.md +1 -1
- package/examples/@xmachines/play-svelte-spa-router-demo/README.md +3 -3
- package/examples/@xmachines/play-sveltekit-router-demo/README.md +3 -3
- package/examples/@xmachines/play-tanstack-react-router-demo/README.md +1 -1
- package/examples/@xmachines/play-tanstack-solid-router-demo/README.md +1 -1
- package/examples/@xmachines/play-vue-demo/README.md +2 -2
- package/examples/@xmachines/play-vue-demo/type-aliases/AuthCatalog.md +1 -1
- package/examples/@xmachines/play-vue-demo/variables/App.md +1 -1
- package/examples/@xmachines/play-vue-demo/variables/authCatalog.md +1 -1
- package/examples/@xmachines/play-vue-router-demo/README.md +1 -1
- package/examples/README.md +24 -25
- package/examples/form-validation.md +2 -2
- package/guides/README.md +7 -7
- package/guides/actor-model.md +18 -18
- package/guides/architecture.md +500 -0
- package/guides/configuration.md +556 -0
- package/guides/deployment.md +336 -0
- package/guides/development.md +617 -0
- package/guides/getting-started.md +351 -142
- package/guides/signals.md +19 -19
- package/guides/state-machines.md +16 -16
- package/guides/testing.md +460 -0
- package/package.json +5 -5
- package/guides/installation.md +0 -257
|
@@ -1,37 +1,25 @@
|
|
|
1
1
|
[API](../../README.md) / @xmachines/play-router
|
|
2
2
|
|
|
3
|
+
<!-- generated-by: gsd-doc-writer -->
|
|
4
|
+
|
|
3
5
|
# @xmachines/play-router
|
|
4
6
|
|
|
5
|
-
|
|
7
|
+
Route tree extraction from XState v5 state machines. Part of [@xmachines/play](../play/README.md) Universal Player Architecture.
|
|
6
8
|
|
|
7
9
|
Graph-based route extraction and bidirectional lookup enabling Actor Authority over navigation.
|
|
8
10
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
`@xmachines/play-router` extracts route trees from XState state machines using `@statelyai/graph` — a typed, JSON-serializable graph library. It converts machines to a directed `Graph` with hierarchy, transition edges, and route metadata, then builds hierarchical `RouteTree` structures with bidirectional state ID ↔ path mapping.
|
|
12
|
-
|
|
13
|
-
It also exports `RouterBridgeBase`, the shared base class used by framework adapters to implement `RouterBridge` with consistent actor↔router synchronization behavior.
|
|
14
|
-
|
|
15
|
-
`RouterBridgeBase` is the policy point; framework adapters are thin ports that implement only framework-specific navigate/subscribe/unsubscribe behavior.
|
|
16
|
-
|
|
17
|
-
The low-level `connectRouter()` from `@xmachines/play-dom-router` uses the same router-to-actor event builder and route-map match helper as `RouterBridgeBase`, so pathname sanitization, state-id normalization, param extraction, and query extraction stay aligned across vanilla and framework adapters.
|
|
18
|
-
|
|
19
|
-
Per [Play RFC](../../../rfc/play.md), this package implements:
|
|
20
|
-
|
|
21
|
-
- **Actor Authority (INV-01):** Routes derive from machine definitions, not external configuration
|
|
22
|
-
|
|
23
|
-
**Routing:** Supports `meta.route` detection, `play.route` event routing, and pattern matching for dynamic parameters.
|
|
11
|
+
Part of the [xmachines-js monorepo](../../README.md).
|
|
24
12
|
|
|
25
13
|
## Installation
|
|
26
14
|
|
|
27
15
|
```bash
|
|
28
|
-
npm install xstate@^5.
|
|
16
|
+
npm install xstate@^5.30.0
|
|
29
17
|
npm install @xmachines/play-router
|
|
30
18
|
```
|
|
31
19
|
|
|
32
20
|
**Peer dependencies:**
|
|
33
21
|
|
|
34
|
-
- `xstate` ^5.
|
|
22
|
+
- `xstate` ^5.30.0 — XState v5 state machine runtime
|
|
35
23
|
|
|
36
24
|
**URLPattern polyfill (Node.js < 24 / older browsers):**
|
|
37
25
|
|
|
@@ -50,555 +38,327 @@ Install the polyfill:
|
|
|
50
38
|
npm install urlpattern-polyfill
|
|
51
39
|
```
|
|
52
40
|
|
|
53
|
-
`urlpattern-polyfill` is declared as an optional peer dependency. Package managers will not install it automatically — consumers must install and load it when their runtime lacks native URLPattern support
|
|
41
|
+
`urlpattern-polyfill` is declared as an optional peer dependency. Package managers will not install it automatically — consumers must install and load it when their runtime lacks native URLPattern support.
|
|
42
|
+
|
|
43
|
+
## Usage
|
|
54
44
|
|
|
55
|
-
|
|
45
|
+
### Extract routes from a machine
|
|
56
46
|
|
|
57
47
|
```typescript
|
|
58
48
|
import { createMachine } from "xstate";
|
|
59
|
-
import { extractMachineRoutes,
|
|
49
|
+
import { extractMachineRoutes, createRouteMap } from "@xmachines/play-router";
|
|
60
50
|
|
|
61
|
-
// Route pattern (recommended)
|
|
62
51
|
const machine = createMachine({
|
|
63
52
|
id: "app",
|
|
64
53
|
initial: "home",
|
|
65
54
|
states: {
|
|
66
55
|
home: {
|
|
67
56
|
id: "home",
|
|
68
|
-
meta: { route: "/"
|
|
57
|
+
meta: { route: "/" },
|
|
69
58
|
},
|
|
70
59
|
dashboard: {
|
|
71
60
|
id: "dashboard",
|
|
72
|
-
meta: { route: "/dashboard"
|
|
61
|
+
meta: { route: "/dashboard" },
|
|
73
62
|
initial: "overview",
|
|
74
63
|
states: {
|
|
75
64
|
overview: {
|
|
76
65
|
id: "overview",
|
|
77
|
-
meta: { route: "/overview"
|
|
66
|
+
meta: { route: "/overview" },
|
|
78
67
|
},
|
|
79
68
|
settings: {
|
|
80
69
|
id: "settings",
|
|
81
|
-
meta: { route: "/settings/:section?"
|
|
70
|
+
meta: { route: "/settings/:section?" }, // optional parameter
|
|
82
71
|
},
|
|
83
72
|
},
|
|
84
73
|
},
|
|
74
|
+
profile: {
|
|
75
|
+
id: "profile",
|
|
76
|
+
meta: { route: "/profile/:userId" }, // required parameter
|
|
77
|
+
},
|
|
85
78
|
},
|
|
86
79
|
});
|
|
87
80
|
|
|
81
|
+
// Build hierarchical route tree with bidirectional maps
|
|
88
82
|
const tree = extractMachineRoutes(machine);
|
|
89
83
|
|
|
90
|
-
//
|
|
91
|
-
|
|
92
|
-
console.log(tree.byStateId.get("overview")); // RouteNode
|
|
84
|
+
// Path → RouteNode
|
|
85
|
+
const node = tree.byPath.get("/dashboard"); // RouteNode for "dashboard"
|
|
93
86
|
|
|
94
|
-
//
|
|
95
|
-
const
|
|
96
|
-
console.log(
|
|
97
|
-
```
|
|
87
|
+
// State ID → RouteNode
|
|
88
|
+
const overview = tree.byStateId.get("overview");
|
|
89
|
+
console.log(overview?.fullPath); // "/overview"
|
|
98
90
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
The demo demonstrates:
|
|
104
|
-
|
|
105
|
-
- **RouteTree extraction** from XState machine meta.route
|
|
106
|
-
- **History API integration** (pushState, popstate)
|
|
107
|
-
- **Bidirectional synchronization** (actor ↔ URL)
|
|
108
|
-
- **Protected route guards** (authentication redirects)
|
|
109
|
-
- **Dynamic route parameters** (/profile/:userId)
|
|
110
|
-
|
|
111
|
-
**Run the demo:**
|
|
112
|
-
|
|
113
|
-
```bash
|
|
114
|
-
npm run dev -w @xmachines/play-dom-router-demo
|
|
91
|
+
// Build a RouteMap for framework adapters
|
|
92
|
+
const routeMap = createRouteMap(machine);
|
|
93
|
+
routeMap.getStateIdByPath("/profile/123"); // "profile"
|
|
94
|
+
routeMap.getPathByStateId("profile"); // "/profile/:userId"
|
|
115
95
|
```
|
|
116
96
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
1. Login with any username
|
|
120
|
-
2. Navigate between home and profile
|
|
121
|
-
3. Use browser back/forward buttons
|
|
122
|
-
4. Try accessing protected routes directly
|
|
123
|
-
|
|
124
|
-
**Key implementation patterns:**
|
|
97
|
+
### Sending `play.route` events
|
|
125
98
|
|
|
126
99
|
```typescript
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
}
|
|
100
|
+
import type { PlayRouteEvent } from "@xmachines/play-router";
|
|
101
|
+
|
|
102
|
+
// Navigate to a state by ID
|
|
103
|
+
const event: PlayRouteEvent = {
|
|
104
|
+
type: "play.route",
|
|
105
|
+
to: "#dashboard",
|
|
106
|
+
};
|
|
107
|
+
actor.send(event);
|
|
108
|
+
|
|
109
|
+
// Navigate with route parameters
|
|
110
|
+
actor.send({
|
|
111
|
+
type: "play.route",
|
|
112
|
+
to: "#profile",
|
|
113
|
+
params: { userId: "123" },
|
|
141
114
|
});
|
|
142
115
|
|
|
143
|
-
//
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
}
|
|
116
|
+
// Navigate with query parameters
|
|
117
|
+
actor.send({
|
|
118
|
+
type: "play.route",
|
|
119
|
+
to: "#settings",
|
|
120
|
+
params: { section: "billing" },
|
|
121
|
+
query: { tab: "invoices" },
|
|
150
122
|
});
|
|
151
|
-
|
|
152
|
-
// Initial URL handling
|
|
153
|
-
const initialPath = window.location.pathname;
|
|
154
|
-
if (initialPath !== "/") {
|
|
155
|
-
const { to, params } = routeMatcher.match(initialPath);
|
|
156
|
-
if (to) {
|
|
157
|
-
actor.send({ type: "play.route", to, params });
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
```
|
|
161
|
-
|
|
162
|
-
This example shows the core routing concepts without framework dependencies, making it ideal for understanding how @xmachines/play-router integrates with browser History API.
|
|
163
|
-
|
|
164
|
-
## Canonical Watcher Lifecycle
|
|
165
|
-
|
|
166
|
-
Bridge implementations should use one watcher flow:
|
|
167
|
-
|
|
168
|
-
1. `notify`
|
|
169
|
-
2. `queueMicrotask`
|
|
170
|
-
3. `getPending()`
|
|
171
|
-
4. read actor route and sync infrastructure state
|
|
172
|
-
5. re-arm with `watch(...)` or `watch()`
|
|
173
|
-
|
|
174
|
-
Watcher notification is one-shot; re-arm is required.
|
|
175
|
-
|
|
176
|
-
## Bridge Cleanup Contract
|
|
177
|
-
|
|
178
|
-
Bridge teardown must be explicit and deterministic:
|
|
179
|
-
|
|
180
|
-
- `disconnect`/`dispose` must unwatch signal subscriptions and unhook router listeners.
|
|
181
|
-
- Do not rely on GC-only cleanup guidance.
|
|
182
|
-
- Infrastructure remains passive: bridges observe and forward intents, actors decide validity.
|
|
183
|
-
- `createBrowserHistory().destroy()` (from `@xmachines/play-dom-router`) is idempotent and restores shared `window.history` patches only after the last wrapper for that window is removed.
|
|
184
|
-
- **Note**: `createBrowserHistory()` mutates global `window.history` methods (`pushState` and `replaceState`) and coordinates wrappers with shared ref-count state. To reduce leakage, create one history wrapper per browser window at the application boundary and always pair it with `destroy()` during teardown.
|
|
185
|
-
|
|
186
|
-
## Bridge Sync Ordering
|
|
187
|
-
|
|
188
|
-
`RouterBridgeBase.connect()` has an intentional ordering contract used by all framework adapters:
|
|
189
|
-
|
|
190
|
-
- seed `lastSyncedPath` from `actor.currentRoute` in the constructor
|
|
191
|
-
- install the actor route watcher
|
|
192
|
-
- install adapter router subscriptions
|
|
193
|
-
- resolve initial sync using `getInitialRouterPath()` and `actor.initialRoute`
|
|
194
|
-
|
|
195
|
-
That final step distinguishes:
|
|
196
|
-
|
|
197
|
-
- **deep-link:** browser URL differs from the machine's initial route, so router wins and the actor receives `play.route`
|
|
198
|
-
- **restore:** browser URL is still at the machine's initial route while the actor was restored elsewhere, so actor wins and the bridge pushes the actor route back into the router
|
|
199
|
-
|
|
200
|
-
Actor-originated router sync suppresses router echoes via `lastSyncedPath`. `syncRouterFromActor` resolves the concrete path and stores it before calling the adapter's navigation method; when the router callback fires with that same path, `syncActorFromRouter` short-circuits at `sanitized === lastSyncedPath` and sends no event.
|
|
201
|
-
|
|
202
|
-
## Diagnostics
|
|
203
|
-
|
|
204
|
-
Router infrastructure reports runtime failures through `PlayDiagnostics` from `@xmachines/play`.
|
|
205
|
-
|
|
206
|
-
- Default behavior uses `consoleDiagnostics`.
|
|
207
|
-
- Messages follow a stable `[scope:code] message` format.
|
|
208
|
-
- Example: `[RouterBridgeBase:PLAY_ROUTER_SYNC_FAILED] Failed to sync actor state from router location.`
|
|
209
|
-
|
|
210
|
-
This keeps router errors observable while letting applications swap in their own diagnostics implementation upstream.
|
|
211
|
-
|
|
212
|
-
## API Reference
|
|
213
|
-
|
|
214
|
-
### extractMachineRoutes()
|
|
215
|
-
|
|
216
|
-
Main entry point — crawls state machine, extracts routes, builds tree:
|
|
217
|
-
|
|
218
|
-
```typescript
|
|
219
|
-
const tree = extractMachineRoutes(machine: AnyStateMachine): RouteTree;
|
|
220
123
|
```
|
|
221
124
|
|
|
222
|
-
|
|
125
|
+
### Implementing a `RouterBridgeBase` adapter
|
|
223
126
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
**Returns:** `RouteTree` with:
|
|
227
|
-
|
|
228
|
-
- `byPath: Map<string, RouteNode>` — URL path → route node
|
|
229
|
-
- `byStateId: Map<string, RouteNode>` — State ID → route node
|
|
230
|
-
- `root: RouteNode` — synthetic root node
|
|
231
|
-
- `graph: MachineGraph` — `@statelyai/graph` Graph for hierarchy queries, reachability checks, and transition-aware navigation
|
|
232
|
-
|
|
233
|
-
**Throws:** Error if routes are invalid (malformed paths, missing state IDs, duplicates)
|
|
234
|
-
|
|
235
|
-
**Example:**
|
|
236
|
-
|
|
237
|
-
```typescript
|
|
238
|
-
import { extractMachineRoutes } from "@xmachines/play-router";
|
|
239
|
-
|
|
240
|
-
const tree = extractMachineRoutes(authMachine);
|
|
241
|
-
|
|
242
|
-
// Query routes — use fullPath for URL matching (path is the raw meta.route segment)
|
|
243
|
-
const loginRoute = tree.byStateId.get("login");
|
|
244
|
-
console.log(loginRoute?.fullPath); // "/login"
|
|
245
|
-
console.log(loginRoute?.path); // "/login" (same for absolute routes)
|
|
246
|
-
|
|
247
|
-
// For nested relative routes the distinction matters:
|
|
248
|
-
// meta.route: "overview" under "/dashboard" → path: "overview", fullPath: "/dashboard/overview"
|
|
249
|
-
const overviewRoute = tree.byStateId.get("overview");
|
|
250
|
-
console.log(overviewRoute?.path); // "overview" (raw segment — relative)
|
|
251
|
-
console.log(overviewRoute?.fullPath); // "/dashboard/overview" (resolved — use this)
|
|
252
|
-
|
|
253
|
-
const dashboardRoute = tree.byPath.get("/dashboard");
|
|
254
|
-
console.log(dashboardRoute?.id); // "dashboard"
|
|
255
|
-
```
|
|
256
|
-
|
|
257
|
-
### machineToGraph()
|
|
258
|
-
|
|
259
|
-
Converts an XState v5 machine to a typed `@statelyai/graph` `Graph`:
|
|
127
|
+
Extend `RouterBridgeBase` and implement the three abstract methods for your framework:
|
|
260
128
|
|
|
261
129
|
```typescript
|
|
262
|
-
import {
|
|
263
|
-
import {
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
```typescript
|
|
278
|
-
const tree = extractMachineRoutes(machine);
|
|
279
|
-
|
|
280
|
-
// Use @statelyai/graph algorithms directly on the graph
|
|
281
|
-
const successors = getSuccessors(tree.graph!, "myMachine.home");
|
|
282
|
-
```
|
|
283
|
-
|
|
284
|
-
**Node data** (`MachineNodeData`):
|
|
285
|
-
|
|
286
|
-
- `stateId: string` — XState state ID (e.g., `"myMachine.dashboard.overview"`)
|
|
287
|
-
- `type` — `"atomic" | "compound" | "parallel" | "final" | "history"`
|
|
288
|
-
- `meta?: Record<string, unknown>` — original state meta object
|
|
289
|
-
- `route?: string` — extracted route path from `meta.route`
|
|
130
|
+
import { RouterBridgeBase } from "@xmachines/play-router";
|
|
131
|
+
import type { AbstractActor, Routable } from "@xmachines/play-actor";
|
|
132
|
+
import type { AnyActorLogic } from "xstate";
|
|
133
|
+
|
|
134
|
+
export class MyRouterBridge extends RouterBridgeBase {
|
|
135
|
+
private unsubscribe: (() => void) | null = null;
|
|
136
|
+
|
|
137
|
+
constructor(
|
|
138
|
+
private readonly myRouter: MyRouter,
|
|
139
|
+
actor: AbstractActor<AnyActorLogic> & Routable,
|
|
140
|
+
routeMap: ReturnType<typeof createRouteMap>,
|
|
141
|
+
) {
|
|
142
|
+
super(actor, routeMap);
|
|
143
|
+
}
|
|
290
144
|
|
|
291
|
-
|
|
145
|
+
// Tell the framework router to navigate to a path
|
|
146
|
+
protected navigateRouter(path: string): void {
|
|
147
|
+
this.myRouter.navigate(path);
|
|
148
|
+
}
|
|
292
149
|
|
|
293
|
-
|
|
294
|
-
|
|
150
|
+
// Subscribe to router location changes, call syncActorFromRouter on each
|
|
151
|
+
protected watchRouterChanges(): void {
|
|
152
|
+
this.unsubscribe = this.myRouter.subscribe((location) => {
|
|
153
|
+
this.syncActorFromRouter(location.pathname, location.search);
|
|
154
|
+
});
|
|
155
|
+
}
|
|
295
156
|
|
|
296
|
-
|
|
157
|
+
// Unsubscribe from router location changes
|
|
158
|
+
protected unwatchRouterChanges(): void {
|
|
159
|
+
this.unsubscribe?.();
|
|
160
|
+
this.unsubscribe = null;
|
|
161
|
+
}
|
|
297
162
|
|
|
298
|
-
|
|
163
|
+
// Provide the router's current path for initial deep-link sync
|
|
164
|
+
protected override getInitialRouterPath(): string {
|
|
165
|
+
return this.myRouter.state.location.pathname;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
299
168
|
|
|
300
|
-
|
|
301
|
-
// Single-call form — preferred for XState machines:
|
|
302
|
-
import { createRouteMap } from "@xmachines/play-router";
|
|
169
|
+
// Usage
|
|
303
170
|
const routeMap = createRouteMap(machine);
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
const routeMap = createRouteMapFromTree(routeTree);
|
|
171
|
+
const bridge = new MyRouterBridge(myRouter, actor, routeMap);
|
|
172
|
+
bridge.connect();
|
|
173
|
+
// ...
|
|
174
|
+
bridge.disconnect();
|
|
309
175
|
```
|
|
310
176
|
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
**`node.path` vs `node.fullPath`:** Every `RouteNode` carries both fields. `path` is the raw `meta.route` segment as declared in the machine — it may be relative (e.g. `"overview"`). `fullPath` is the resolved absolute path (e.g. `"/dashboard/overview"`). Route maps always use `fullPath`. Only use `path` if you specifically need the declared segment.
|
|
314
|
-
|
|
315
|
-
### Query Utilities
|
|
177
|
+
## API Summary
|
|
316
178
|
|
|
317
|
-
|
|
318
|
-
import {
|
|
319
|
-
getNavigableRoutes,
|
|
320
|
-
getRoutableRoutes,
|
|
321
|
-
routeExists,
|
|
322
|
-
getTransitionReachableRoutes,
|
|
323
|
-
isRouteReachable,
|
|
324
|
-
} from "@xmachines/play-router";
|
|
179
|
+
### Route Extraction
|
|
325
180
|
|
|
326
|
-
|
|
327
|
-
|
|
181
|
+
| Export | Description |
|
|
182
|
+
| ---------------------------------------- | ---------------------------------------------------------------------------------- |
|
|
183
|
+
| `extractMachineRoutes(machine)` | Convert an XState machine to a `RouteTree` with bidirectional state ID ↔ path maps |
|
|
184
|
+
| `createRouteMap(machine, options?)` | Build a `RouteMap` directly from a machine (preferred form for adapters) |
|
|
185
|
+
| `createRouteMapFromTree(tree, options?)` | Build a `RouteMap` from an already-extracted `RouteTree` |
|
|
186
|
+
| `buildRouteTree(routes)` | Build a `RouteTree` from an array of `RouteInfo` objects |
|
|
187
|
+
| `machineToGraph(machine)` | Convert a machine to a typed `@statelyai/graph` `Graph` for graph algorithm access |
|
|
328
188
|
|
|
329
|
-
|
|
330
|
-
const allRoutes = getRoutableRoutes(tree);
|
|
189
|
+
### Route Matching
|
|
331
190
|
|
|
332
|
-
|
|
333
|
-
|
|
191
|
+
| Export | Description |
|
|
192
|
+
| ----------------------------- | ------------------------------------------------------------------------------------------ |
|
|
193
|
+
| `createRouteMatcher(tree)` | Create a `RouteMatcher` that matches URL paths to `#stateId` values and extracts params |
|
|
194
|
+
| `RouteMap` | Bidirectional `stateId ↔ path` lookup class; supports O(1) exact and O(k) pattern matching |
|
|
195
|
+
| `findRouteById(tree, id)` | Look up a `RouteNode` by state ID |
|
|
196
|
+
| `findRouteByPath(tree, path)` | Look up a `RouteNode` by URL path (supports dynamic patterns) |
|
|
334
197
|
|
|
335
|
-
|
|
336
|
-
const reachableIds = getTransitionReachableRoutes(tree.graph!, "myMachine.home");
|
|
337
|
-
|
|
338
|
-
// Is there any path from state A to state B via transitions?
|
|
339
|
-
const canReach = isRouteReachable(tree.graph!, "myMachine.home", "myMachine.dashboard");
|
|
340
|
-
```
|
|
341
|
-
|
|
342
|
-
## Examples
|
|
343
|
-
|
|
344
|
-
### Route Detection
|
|
345
|
-
|
|
346
|
-
```typescript
|
|
347
|
-
import { extractMachineRoutes, findRouteByPath } from "@xmachines/play-router";
|
|
348
|
-
import { createMachine } from "xstate";
|
|
349
|
-
|
|
350
|
-
const machine = createMachine({
|
|
351
|
-
initial: "home",
|
|
352
|
-
states: {
|
|
353
|
-
home: {
|
|
354
|
-
id: "home",
|
|
355
|
-
meta: { route: "/", view: { component: "Home" } },
|
|
356
|
-
},
|
|
357
|
-
profile: {
|
|
358
|
-
id: "profile",
|
|
359
|
-
meta: { route: "/profile/:userId", view: { component: "Profile" } }, // Parameter pattern
|
|
360
|
-
},
|
|
361
|
-
settings: {
|
|
362
|
-
id: "settings",
|
|
363
|
-
meta: { route: "/settings/:section?", view: { component: "Settings" } }, // Optional parameter
|
|
364
|
-
},
|
|
365
|
-
},
|
|
366
|
-
});
|
|
367
|
-
|
|
368
|
-
const tree = extractMachineRoutes(machine);
|
|
369
|
-
|
|
370
|
-
// Bidirectional mapping — use fullPath for URLs; path is the raw meta.route segment
|
|
371
|
-
const profileById = tree.byStateId.get("profile");
|
|
372
|
-
console.log(profileById?.fullPath); // "/profile/:userId"
|
|
373
|
-
|
|
374
|
-
const profileByPath = findRouteByPath(tree, "/profile/user123");
|
|
375
|
-
console.log(profileByPath?.id); // "profile"
|
|
376
|
-
```
|
|
377
|
-
|
|
378
|
-
### Hierarchical Route Tree
|
|
379
|
-
|
|
380
|
-
```typescript
|
|
381
|
-
import { extractMachineRoutes, getNavigableRoutes } from "@xmachines/play-router";
|
|
382
|
-
|
|
383
|
-
const machine = createMachine({
|
|
384
|
-
initial: "app",
|
|
385
|
-
states: {
|
|
386
|
-
app: {
|
|
387
|
-
id: "app",
|
|
388
|
-
meta: { route: "/", view: { component: "AppShell" } },
|
|
389
|
-
initial: "dashboard",
|
|
390
|
-
states: {
|
|
391
|
-
dashboard: {
|
|
392
|
-
id: "dashboard",
|
|
393
|
-
meta: { route: "/dashboard", view: { component: "Dashboard" } },
|
|
394
|
-
initial: "overview",
|
|
395
|
-
states: {
|
|
396
|
-
overview: {
|
|
397
|
-
id: "overview",
|
|
398
|
-
meta: { route: "/overview", view: { component: "Overview" } },
|
|
399
|
-
},
|
|
400
|
-
analytics: {
|
|
401
|
-
id: "analytics",
|
|
402
|
-
meta: { route: "/analytics", view: { component: "Analytics" } },
|
|
403
|
-
},
|
|
404
|
-
},
|
|
405
|
-
},
|
|
406
|
-
},
|
|
407
|
-
},
|
|
408
|
-
},
|
|
409
|
-
});
|
|
410
|
-
|
|
411
|
-
const tree = extractMachineRoutes(machine);
|
|
412
|
-
|
|
413
|
-
// Get child routes
|
|
414
|
-
const dashboardChildren = getNavigableRoutes(tree, "dashboard");
|
|
415
|
-
console.log(dashboardChildren.map((r) => r.id)); // ["overview", "analytics"]
|
|
416
|
-
|
|
417
|
-
// Route inheritance
|
|
418
|
-
const analyticsRoute = tree.byStateId.get("analytics");
|
|
419
|
-
console.log(analyticsRoute?.fullPath); // "/analytics" (absolute route)
|
|
420
|
-
```
|
|
198
|
+
### Query Utilities
|
|
421
199
|
|
|
422
|
-
|
|
200
|
+
| Export | Description |
|
|
201
|
+
| ------------------------------------------------- | ------------------------------------------------------------------------- |
|
|
202
|
+
| `getRoutableRoutes(tree)` | All routable `RouteNode`s as a flat array |
|
|
203
|
+
| `getNavigableRoutes(tree, stateId)` | Child routes reachable from a state (hierarchical + transition-reachable) |
|
|
204
|
+
| `routeExists(tree, path)` | Check whether a path is registered in the tree |
|
|
205
|
+
| `getTransitionReachableRoutes(graph, stateId)` | Route paths reachable via XState transitions from a state |
|
|
206
|
+
| `isRouteReachable(graph, fromStateId, toStateId)` | Check whether a transition path exists between two states |
|
|
207
|
+
|
|
208
|
+
### Router Bridge
|
|
209
|
+
|
|
210
|
+
| Export | Description |
|
|
211
|
+
| --------------------------------------- | ------------------------------------------------------------------------------------- |
|
|
212
|
+
| `RouterBridgeBase` | Abstract base class for framework router adapters; implements `RouterBridge` protocol |
|
|
213
|
+
| `sanitizePathname(path)` | Normalize a raw pathname; returns `null` for paths > 2048 chars or malformed input |
|
|
214
|
+
| `buildPlayRouteEvent(options)` | Build a `PlayRouteEvent` from a pathname + route-map match result |
|
|
215
|
+
| `extractRouteParams(pathname, pattern)` | Extract path parameters from a URL using URLPattern |
|
|
216
|
+
| `extractQuery(search)` | Extract query parameters from a URL search string |
|
|
217
|
+
|
|
218
|
+
### Validation
|
|
219
|
+
|
|
220
|
+
| Export | Description |
|
|
221
|
+
| ---------------------------------------- | ------------------------------------------------- |
|
|
222
|
+
| `validateRouteFormat(route, stateId)` | Assert route path is non-empty |
|
|
223
|
+
| `validateStateExists(stateId, stateIds)` | Assert a state ID is present in the machine graph |
|
|
224
|
+
| `detectDuplicateRoutes(routes)` | Throw if any two states share the same URL path |
|
|
225
|
+
|
|
226
|
+
### Key Types
|
|
227
|
+
|
|
228
|
+
| Export | Description |
|
|
229
|
+
| ---------------------------------- | -------------------------------------------------------------------------------------- |
|
|
230
|
+
| `RouterBridge` | Interface for `connect()` / `disconnect()` lifecycle |
|
|
231
|
+
| `RouteTree` | Hierarchical tree with `root`, `byStateId`, `byPath`, and optional `graph` |
|
|
232
|
+
| `RouteNode` | Single node in the tree with `id`, `path`, `fullPath`, `stateId`, `children`, `parent` |
|
|
233
|
+
| `RouteInfo` | Flat route descriptor extracted from a state node |
|
|
234
|
+
| `PlayRouteEvent` | Routing event `{ type: "play.route", to, params?, query? }` |
|
|
235
|
+
| `RouteMapping` | `{ stateId, path }` pair used to build a `RouteMap` |
|
|
236
|
+
| `RouteMapping as BaseRouteMapping` | Alias for `RouteMapping` (backwards-compat re-export) |
|
|
237
|
+
| `MachineGraph` | Typed `@statelyai/graph` Graph with `MachineNodeData` / `MachineEdgeData` |
|
|
238
|
+
| `WindowLike` | Injectable minimal `window` interface for SSR / testing |
|
|
239
|
+
| `LocationLike` | Injectable minimal `location` interface for SSR / testing |
|
|
240
|
+
|
|
241
|
+
### Errors (subpath `@xmachines/play-router/errors`)
|
|
242
|
+
|
|
243
|
+
| Class | Code | When thrown |
|
|
244
|
+
| ---------------------------- | --------------------------------------- | ----------------------------------------------------------------- |
|
|
245
|
+
| `RouterSyncError` | `PLAY_ROUTER_SYNC_FAILED` | `syncActorFromRouter()` fails to send a `play.route` event |
|
|
246
|
+
| `DuplicateBridgeError` | `PLAY_ROUTER_DUPLICATE_BRIDGE` | A second bridge tries to connect to an actor that already has one |
|
|
247
|
+
| `URLPatternUnavailableError` | `PLAY_ROUTE_MAP_URLPATTERN_UNAVAILABLE` | URLPattern API is absent and no polyfill is loaded |
|
|
248
|
+
| `InvalidRoutePatternError` | `PLAY_ROUTE_MAP_INVALID_PATTERN` | A route pattern string is rejected by the URLPattern constructor |
|
|
249
|
+
| `EmptyRoutePathError` | `PLAY_ROUTE_EMPTY_PATH` | A state declares `meta.route: ""` |
|
|
250
|
+
| `InvalidStateIdError` | `PLAY_ROUTE_INVALID_STATE_ID` | A route references a state ID not in the machine graph |
|
|
251
|
+
| `DuplicateRoutePathError` | `PLAY_ROUTE_DUPLICATE_PATH` | Two or more states share the same URL path |
|
|
252
|
+
| `UnknownStateTypeError` | `PLAY_ROUTE_UNKNOWN_STATE_TYPE` | A state node has an unrecognised XState `.type` value |
|
|
423
253
|
|
|
424
254
|
```typescript
|
|
425
|
-
import {
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
id: "user",
|
|
431
|
-
meta: { route: "/user/:userId", view: { component: "User" } }, // Required parameter
|
|
432
|
-
},
|
|
433
|
-
settings: {
|
|
434
|
-
id: "settings",
|
|
435
|
-
meta: { route: "/settings/:section?", view: { component: "Settings" } }, // Optional parameter
|
|
436
|
-
},
|
|
437
|
-
},
|
|
438
|
-
});
|
|
439
|
-
|
|
440
|
-
const tree = extractMachineRoutes(machine);
|
|
441
|
-
|
|
442
|
-
// Pattern matching for actual URLs
|
|
443
|
-
const userRoute = findRouteByPath(tree, "/user/user123");
|
|
444
|
-
console.log(userRoute?.id); // "user"
|
|
445
|
-
|
|
446
|
-
const settingsDefault = findRouteByPath(tree, "/settings");
|
|
447
|
-
console.log(settingsDefault?.id); // "settings" (optional param)
|
|
255
|
+
import {
|
|
256
|
+
RouterSyncError,
|
|
257
|
+
DuplicateBridgeError,
|
|
258
|
+
URLPatternUnavailableError,
|
|
259
|
+
} from "@xmachines/play-router/errors";
|
|
448
260
|
|
|
449
|
-
|
|
450
|
-
|
|
261
|
+
try {
|
|
262
|
+
bridge.connect();
|
|
263
|
+
} catch (err) {
|
|
264
|
+
if (err instanceof DuplicateBridgeError) {
|
|
265
|
+
// Actor already bridged — call disconnect() first
|
|
266
|
+
} else if (err instanceof RouterSyncError) {
|
|
267
|
+
console.error("Router sync failed:", err.message, err.cause);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
451
270
|
```
|
|
452
271
|
|
|
453
272
|
## Route Configuration
|
|
454
273
|
|
|
455
|
-
###
|
|
274
|
+
### `meta.route` patterns
|
|
456
275
|
|
|
457
|
-
|
|
458
|
-
states: {
|
|
459
|
-
dashboard: {
|
|
460
|
-
id: "dashboard", // Required for bidirectional lookup
|
|
461
|
-
meta: {
|
|
462
|
-
route: "/dashboard", // URL path - marks state as routable
|
|
463
|
-
},
|
|
464
|
-
},
|
|
465
|
-
}
|
|
466
|
-
```
|
|
467
|
-
|
|
468
|
-
### Alternative Pattern
|
|
276
|
+
Routes are declared on XState state nodes via the `meta.route` field:
|
|
469
277
|
|
|
470
278
|
```typescript
|
|
471
279
|
states: {
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
280
|
+
home: {
|
|
281
|
+
id: "home",
|
|
282
|
+
meta: { route: "/" }, // static route
|
|
283
|
+
},
|
|
284
|
+
profile: {
|
|
285
|
+
id: "profile",
|
|
286
|
+
meta: { route: "/profile/:userId" }, // required parameter
|
|
287
|
+
},
|
|
288
|
+
settings: {
|
|
289
|
+
id: "settings",
|
|
290
|
+
meta: { route: "/settings/:section?" }, // optional parameter
|
|
291
|
+
},
|
|
292
|
+
docs: {
|
|
293
|
+
id: "docs",
|
|
294
|
+
meta: { route: { path: "/docs", title: "Documentation" } }, // object form
|
|
295
|
+
},
|
|
478
296
|
}
|
|
479
297
|
```
|
|
480
298
|
|
|
481
|
-
###
|
|
299
|
+
### Relative vs absolute paths
|
|
482
300
|
|
|
483
|
-
|
|
484
|
-
states: {
|
|
485
|
-
parent: {
|
|
486
|
-
id: "parent",
|
|
487
|
-
meta: { route: "/parent", view: { component: "Parent" } },
|
|
488
|
-
states: {
|
|
489
|
-
absolute: {
|
|
490
|
-
id: "absolute",
|
|
491
|
-
meta: { route: "/absolute", view: { component: "Absolute" } }, // Starts with / → doesn't inherit
|
|
492
|
-
},
|
|
493
|
-
relative: {
|
|
494
|
-
id: "relative",
|
|
495
|
-
meta: { route: "relative", view: { component: "Relative" } }, // No leading / → inherits parent path prefix
|
|
496
|
-
// Final path: "/parent/relative"
|
|
497
|
-
},
|
|
498
|
-
},
|
|
499
|
-
},
|
|
500
|
-
}
|
|
501
|
-
```
|
|
502
|
-
|
|
503
|
-
### Dynamic Parameters
|
|
301
|
+
Child routes with a leading `/` are absolute (do not inherit the parent path). Without a leading `/`, they resolve relative to their nearest routable ancestor:
|
|
504
302
|
|
|
505
303
|
```typescript
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
304
|
+
states: {
|
|
305
|
+
dashboard: {
|
|
306
|
+
id: "dashboard",
|
|
307
|
+
meta: { route: "/dashboard" },
|
|
308
|
+
states: {
|
|
309
|
+
overview: {
|
|
310
|
+
id: "overview",
|
|
311
|
+
meta: { route: "/overview" }, // absolute → fullPath: "/overview"
|
|
312
|
+
},
|
|
313
|
+
stats: {
|
|
314
|
+
id: "stats",
|
|
315
|
+
meta: { route: "stats" }, // relative → fullPath: "/dashboard/stats"
|
|
316
|
+
},
|
|
317
|
+
},
|
|
318
|
+
},
|
|
511
319
|
}
|
|
512
320
|
```
|
|
513
321
|
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
## Security Utilities
|
|
517
|
-
|
|
518
|
-
### `sanitizePathname()`
|
|
322
|
+
Always use `node.fullPath` (never `node.path`) for browser URL matching and route map construction.
|
|
519
323
|
|
|
520
|
-
|
|
324
|
+
## Testing
|
|
521
325
|
|
|
522
|
-
```
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
// In a custom adapter's route-watch callback:
|
|
526
|
-
const clean = sanitizePathname(rawPath);
|
|
527
|
-
if (clean === null) return; // Reject malformed/oversized paths (> 2048 chars)
|
|
528
|
-
// Proceed with clean normalized path
|
|
529
|
-
```
|
|
530
|
-
|
|
531
|
-
Returns `null` for paths exceeding 2048 characters. Strips query fragments, hash fragments, and collapses duplicate slashes.
|
|
532
|
-
|
|
533
|
-
---
|
|
534
|
-
|
|
535
|
-
## Error Handling
|
|
536
|
-
|
|
537
|
-
All runtime errors thrown by this package extend `PlayError` from `@xmachines/play` and
|
|
538
|
-
are exported from the `./errors` subpath:
|
|
326
|
+
```bash
|
|
327
|
+
# Run tests for this package
|
|
328
|
+
npm test -w @xmachines/play-router
|
|
539
329
|
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
RouterSyncError,
|
|
543
|
-
URLPatternUnavailableError,
|
|
544
|
-
InvalidRoutePatternError,
|
|
545
|
-
} from "@xmachines/play-router/errors";
|
|
330
|
+
# Watch mode
|
|
331
|
+
npm run test:watch -w @xmachines/play-router
|
|
546
332
|
```
|
|
547
333
|
|
|
548
|
-
|
|
549
|
-
| ---------------------------- | --------------------------------------- | -------------------------------------------------------------- |
|
|
550
|
-
| `RouterSyncError` | `PLAY_ROUTER_SYNC_FAILED` | `syncActorFromRouter()` fails to send a `play.route` event |
|
|
551
|
-
| `URLPatternUnavailableError` | `PLAY_ROUTE_MAP_URLPATTERN_UNAVAILABLE` | `createRouteMap()` called before URLPattern polyfill is loaded |
|
|
552
|
-
| `InvalidRoutePatternError` | `PLAY_ROUTE_MAP_INVALID_PATTERN` | A route pattern string is rejected by URLPattern constructor |
|
|
553
|
-
|
|
554
|
-
`InvalidRoutePatternError` carries a `pattern: string` field with the offending pattern.
|
|
334
|
+
The package exports a router bridge contract test suite for adapter authors:
|
|
555
335
|
|
|
556
336
|
```typescript
|
|
557
|
-
import {
|
|
558
|
-
import { RouterSyncError } from "@xmachines/play-router/errors";
|
|
337
|
+
import { runBridgeContractTests } from "@xmachines/play-router/test/contract.js";
|
|
559
338
|
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
} else if (err instanceof PlayError) {
|
|
567
|
-
console.error(`[${err.scope}:${err.code}] ${err.message}`);
|
|
568
|
-
}
|
|
569
|
-
}
|
|
339
|
+
runBridgeContractTests({
|
|
340
|
+
name: "MyRouterBridge",
|
|
341
|
+
createHarness(initialPath) {
|
|
342
|
+
// return ContractHarness with bridge, actor, simulateNavigation, getLastNavigatedPath
|
|
343
|
+
},
|
|
344
|
+
});
|
|
570
345
|
```
|
|
571
346
|
|
|
572
|
-
## Architecture
|
|
573
|
-
|
|
574
|
-
This package enables **Actor Authority (INV-01)**:
|
|
575
|
-
|
|
576
|
-
1. **Routes derive from machine:** Business logic defines routes in state machine, not external config
|
|
577
|
-
2. **Graph-based extraction:** `machineToGraph()` converts machines to typed `@statelyai/graph` `Graph` objects with hierarchy, transition edges, and route metadata
|
|
578
|
-
3. **Bidirectional mapping:** Fast lookup by path (browser URL) or by state ID (state machine)
|
|
579
|
-
4. **Transition-aware queries:** `getTransitionReachableRoutes()` and `isRouteReachable()` use graph algorithms for navigation reachability
|
|
580
|
-
5. **Build-time validation:** Invalid routes throw errors during extraction, not runtime
|
|
581
|
-
|
|
582
|
-
**Enhancements:**
|
|
583
|
-
|
|
584
|
-
- `meta.route` detection via state metadata — extracted into typed graph node data
|
|
585
|
-
- Pattern matching for dynamic routes (`:param` and `:param?`)
|
|
586
|
-
- State ID ↔ path bidirectional maps for `play.route` events
|
|
587
|
-
- `@statelyai/graph` integration — hierarchy queries, reachability checks, transition traversal
|
|
588
|
-
|
|
589
347
|
## Related Packages
|
|
590
348
|
|
|
591
|
-
- **[@xmachines/play
|
|
592
|
-
- **[@xmachines/play-
|
|
593
|
-
- **[@xmachines/play-
|
|
594
|
-
- **[@xmachines/play](../play/README.md)**
|
|
349
|
+
- **[@xmachines/play](../play/README.md)** — Core protocol types (`PlayEvent`, `PlayError`)
|
|
350
|
+
- **[@xmachines/play-actor](../play-actor/README.md)** — Abstract actor base class (`AbstractActor`, `Routable`)
|
|
351
|
+
- **[@xmachines/play-signals](../play-signals/README.md)** — TC39 Signals polyfill used for actor route observation
|
|
352
|
+
- **[@xmachines/play-xstate](../play-xstate/README.md)** — XState v5 logic adapter that integrates with route trees
|
|
353
|
+
- **[@xmachines/play-tanstack-react-router](../play-tanstack-react-router/README.md)** — TanStack Router adapter (React)
|
|
354
|
+
- **[@xmachines/play-tanstack-solid-router](../play-tanstack-solid-router/README.md)** — TanStack Router adapter (SolidJS)
|
|
355
|
+
- **[@xmachines/play-react-router](../play-react-router/README.md)** — React Router v7 adapter
|
|
356
|
+
- **[@xmachines/play-vue-router](../play-vue-router/README.md)** — Vue Router adapter
|
|
357
|
+
- **[@xmachines/play-solid-router](../play-solid-router/README.md)** — SolidJS Router adapter
|
|
595
358
|
|
|
596
359
|
## License
|
|
597
360
|
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
This work is licensed under the terms of the MIT license.
|
|
601
|
-
For a copy, see <https://opensource.org/licenses/MIT>.
|
|
361
|
+
MIT — see [LICENSE](LICENSE).
|
|
602
362
|
|
|
603
363
|
## Classes
|
|
604
364
|
|