@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,676 +1,163 @@
|
|
|
1
1
|
[API](../../README.md) / @xmachines/play-solid-router
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
**SolidJS Router adapter for XMachines Universal Player Architecture**
|
|
6
|
-
|
|
7
|
-
SolidJS Router adapter using `RouterBridgeBase` for consistent actor↔router sync.
|
|
8
|
-
|
|
9
|
-
## Overview
|
|
10
|
-
|
|
11
|
-
`@xmachines/play-solid-router` provides seamless integration between SolidJS Router and XMachines state machines. Built on Solid's reactive primitives, it enables zero-adaptation signals synchronization.
|
|
12
|
-
|
|
13
|
-
Per [Play RFC](../../../rfc/play.md), this package implements:
|
|
3
|
+
<!-- generated-by: gsd-doc-writer -->
|
|
14
4
|
|
|
15
|
-
|
|
16
|
-
- **Passive Infrastructure (INV-04):** Router observes `actor.currentRoute` signal
|
|
17
|
-
- **Signal-Only Reactivity (INV-05):** TC39 watcher lifecycle + Solid reactive owner integration
|
|
18
|
-
|
|
19
|
-
**Key Benefits:**
|
|
20
|
-
|
|
21
|
-
- **Bridge-first:** Extends shared `RouterBridgeBase` policy used by other adapters
|
|
22
|
-
- **Automatic tracking:** Uses Solid reactivity for router→actor while base class handles actor→router watcher lifecycle
|
|
23
|
-
- **Fine-grained reactivity:** Updates only affected components
|
|
24
|
-
- **Logic-driven navigation:** Business logic in state machines, not components
|
|
25
|
-
- **Type-safe parameters:** Route params flow through state machine context
|
|
5
|
+
# @xmachines/play-solid-router
|
|
26
6
|
|
|
27
|
-
|
|
7
|
+
SolidJS Router adapter for the XMachines Universal Player Architecture. Provides bidirectional synchronisation between a `PlayerActor`'s state machine routes and the browser URL via `@solidjs/router`.
|
|
28
8
|
|
|
29
|
-
|
|
30
|
-
- @solidjs/router 0.13.0+ (modern routing primitives)
|
|
31
|
-
- TC39 Signals polyfill integration
|
|
9
|
+
Part of the [xmachines-js monorepo](../../README.md).
|
|
32
10
|
|
|
33
11
|
## Installation
|
|
34
12
|
|
|
35
13
|
```bash
|
|
36
|
-
npm install @
|
|
14
|
+
npm install @xmachines/play-solid-router
|
|
37
15
|
```
|
|
38
16
|
|
|
39
|
-
**Peer dependencies
|
|
17
|
+
**Peer dependencies** (must be installed separately):
|
|
40
18
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
- — Actor base
|
|
45
|
-
- — Route extraction
|
|
46
|
-
- — TC39 Signals primitives
|
|
19
|
+
```bash
|
|
20
|
+
npm install solid-js @solidjs/router xstate
|
|
21
|
+
```
|
|
47
22
|
|
|
48
23
|
## Quick Start
|
|
49
24
|
|
|
50
|
-
```
|
|
51
|
-
import { Router, Route, useNavigate, useLocation, useParams } from
|
|
52
|
-
import { onCleanup } from
|
|
53
|
-
import {
|
|
54
|
-
import { definePlayer } from
|
|
55
|
-
|
|
56
|
-
function App() {
|
|
57
|
-
// 1. Get SolidJS Router hooks (MUST be inside component)
|
|
58
|
-
const navigate = useNavigate();
|
|
59
|
-
const location = useLocation();
|
|
60
|
-
const params = useParams();
|
|
61
|
-
|
|
62
|
-
// 2. Create route mapping from machine routes
|
|
63
|
-
const routeMap = createRouteMap(authMachine);
|
|
64
|
-
|
|
65
|
-
// 3. Create player with state machine
|
|
66
|
-
const createPlayer = definePlayer({
|
|
67
|
-
machine: authMachine,
|
|
68
|
-
catalog: componentCatalog
|
|
69
|
-
});
|
|
70
|
-
const actor = createPlayer();
|
|
71
|
-
actor.start();
|
|
72
|
-
|
|
73
|
-
// 4. Create bridge to sync actor and router
|
|
74
|
-
const bridge = new SolidRouterBridge(
|
|
75
|
-
navigate,
|
|
76
|
-
location,
|
|
77
|
-
params,
|
|
78
|
-
actor,
|
|
79
|
-
routeMap
|
|
80
|
-
);
|
|
81
|
-
|
|
82
|
-
// 5. Start synchronization
|
|
83
|
-
bridge.connect();
|
|
84
|
-
|
|
85
|
-
// 6. Cleanup on component disposal
|
|
86
|
-
onCleanup(() => {
|
|
87
|
-
bridge.disconnect();
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
return (
|
|
91
|
-
<Router>
|
|
92
|
-
<Route path="/" component={HomeView} />
|
|
93
|
-
<Route path="/profile/:userId" component={ProfileView} />
|
|
94
|
-
<Route path="/settings/:section?" component={SettingsView} />
|
|
95
|
-
</Router>
|
|
96
|
-
);
|
|
97
|
-
}
|
|
98
|
-
```
|
|
25
|
+
```tsx
|
|
26
|
+
import { Router, Route, useNavigate, useLocation, useParams } from "@solidjs/router";
|
|
27
|
+
import { onCleanup, type ParentComponent } from "solid-js";
|
|
28
|
+
import { PlayRouterProvider, createRouteMap } from "@xmachines/play-solid-router";
|
|
29
|
+
import { definePlayer } from "@xmachines/play-xstate";
|
|
30
|
+
import { myMachine } from "./machine.js";
|
|
99
31
|
|
|
100
|
-
|
|
32
|
+
const actor = definePlayer({ machine: myMachine })();
|
|
33
|
+
actor.start();
|
|
101
34
|
|
|
102
|
-
|
|
35
|
+
const routeMap = createRouteMap(myMachine);
|
|
103
36
|
|
|
104
|
-
|
|
37
|
+
const Layout: ParentComponent = () => {
|
|
38
|
+
const navigate = useNavigate();
|
|
39
|
+
const location = useLocation();
|
|
40
|
+
const params = useParams();
|
|
105
41
|
|
|
106
|
-
|
|
42
|
+
onCleanup(() => actor.stop());
|
|
107
43
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
routeMap: RouteMap,
|
|
44
|
+
return (
|
|
45
|
+
<PlayRouterProvider
|
|
46
|
+
actor={actor}
|
|
47
|
+
routeMap={routeMap}
|
|
48
|
+
router={{ navigate, location, params }}
|
|
49
|
+
renderer={(a) => <MyApp actor={a} />}
|
|
50
|
+
/>
|
|
116
51
|
);
|
|
117
|
-
dispose(): void;
|
|
118
|
-
}
|
|
119
|
-
```
|
|
120
|
-
|
|
121
|
-
**Constructor Parameters:**
|
|
122
|
-
|
|
123
|
-
- `navigate` - Function from `useNavigate()` hook (signals-aware navigation)
|
|
124
|
-
- `location` - Object from `useLocation()` hook (reactive pathname, search, hash)
|
|
125
|
-
- `params` - Object from `useParams()` hook (reactive route parameters)
|
|
126
|
-
- `actor` - XMachines actor instance (from `definePlayer().actor`)
|
|
127
|
-
- `routeMap` - Bidirectional state ID ↔ path mapping
|
|
128
|
-
|
|
129
|
-
**Methods:**
|
|
130
|
-
|
|
131
|
-
- `connect()` - Start bidirectional synchronization. Both `location.pathname` and `location.search` are forwarded to the actor on first connect, so users arriving on `/profile?tab=posts` have `query: { tab: "posts" }` in the initial `play.route` event.
|
|
132
|
-
- `disconnect()` - Stop synchronization and cleanup bridge resources.
|
|
133
|
-
- `dispose()` - Alias of `disconnect()`.
|
|
134
|
-
|
|
135
|
-
`connect()` creates a Solid-owned router watcher, and `disconnect()`/`dispose()` tears it down immediately. Do not rely on owner unmount alone if you need the bridge to stop processing router updates earlier.
|
|
136
|
-
|
|
137
|
-
**Internal Behavior:**
|
|
138
|
-
|
|
139
|
-
- Uses `RouterBridgeBase` TC39 watcher lifecycle for actor→router synchronization
|
|
140
|
-
- Updates SolidJS Router via `navigate(path)` when actor state changes
|
|
141
|
-
- Uses `createEffect(on(...))` to watch `location.pathname` signal
|
|
142
|
-
- Sends `play.route` events to actor when user navigates, using Solid's pre-parsed `useParams()` for path parameter extraction (no URLPattern polyfill required)
|
|
143
|
-
- Prevents circular updates with path tracking and processing flags
|
|
144
|
-
|
|
145
|
-
### `RouteMap`
|
|
146
|
-
|
|
147
|
-
Bidirectional mapping between XMachines state IDs and SolidJS Router paths with pattern matching support.
|
|
148
|
-
|
|
149
|
-
`RouteMap` extends `BaseRouteMap` from, inheriting bucket-indexed
|
|
150
|
-
bidirectional route matching. No routing logic lives in the adapter itself.
|
|
151
|
-
|
|
152
|
-
```typescript
|
|
153
|
-
interface RouteMapping {
|
|
154
|
-
readonly stateId: string;
|
|
155
|
-
readonly path: string;
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
// RouteMap is a thin subclass of BaseRouteMap — no extra methods
|
|
159
|
-
class RouteMap extends BaseRouteMap {}
|
|
160
|
-
|
|
161
|
-
// Inherited API:
|
|
162
|
-
routeMap.getStateIdByPath(path: string): string | null
|
|
163
|
-
routeMap.getPathByStateId(stateId: string): string | null
|
|
164
|
-
```
|
|
165
|
-
|
|
166
|
-
`getStateIdByPath` and `getPathByStateId` both return `null` (not `undefined`) for misses.
|
|
167
|
-
|
|
168
|
-
**Constructor Parameters:**
|
|
169
|
-
|
|
170
|
-
- `mappings` - Array of `{ stateId, path }` entries:
|
|
171
|
-
- `stateId` — State machine state ID (e.g., `'#profile'`)
|
|
172
|
-
- `path` — SolidJS Router path pattern (e.g., `'/profile/:userId'`)
|
|
173
|
-
|
|
174
|
-
**Methods:**
|
|
175
|
-
|
|
176
|
-
- `getPathByStateId(stateId)` — Find path pattern from state ID
|
|
177
|
-
- `getStateIdByPath(path)` — Find state ID from path with pattern matching (supports `:param` and `:param?` syntax)
|
|
178
|
-
|
|
179
|
-
**Pattern Matching:**
|
|
180
|
-
|
|
181
|
-
Uses bucket-indexed RegExp matching for dynamic routes:
|
|
182
|
-
|
|
183
|
-
```typescript
|
|
184
|
-
const routeMap = new RouteMap([{ stateId: "#settings", path: "/settings/:section?" }]);
|
|
185
|
-
|
|
186
|
-
routeMap.getStateIdByPath("/settings"); // '#settings'
|
|
187
|
-
routeMap.getStateIdByPath("/settings/account"); // '#settings'
|
|
188
|
-
routeMap.getStateIdByPath("/settings/privacy"); // '#settings'
|
|
189
|
-
routeMap.getStateIdByPath("/other"); // null
|
|
190
|
-
```
|
|
191
|
-
|
|
192
|
-
## Examples
|
|
193
|
-
|
|
194
|
-
### Basic Usage: Simple 2-3 Route Setup
|
|
195
|
-
|
|
196
|
-
```typescript
|
|
197
|
-
import { Router, Route } from '@solidjs/router';
|
|
198
|
-
import { defineCatalog } from "@json-render/core";
|
|
199
|
-
import { schema } from "@json-render/react/schema";
|
|
200
|
-
import { defineRegistry } from "@xmachines/play-solid";
|
|
201
|
-
import { z } from "zod";
|
|
202
|
-
|
|
203
|
-
// Catalog and registry
|
|
204
|
-
const appCatalog = defineCatalog(schema, {
|
|
205
|
-
components: {
|
|
206
|
-
Home: { props: z.object({}) },
|
|
207
|
-
About: { props: z.object({}) },
|
|
208
|
-
Contact: { props: z.object({}) },
|
|
209
|
-
},
|
|
210
|
-
});
|
|
211
|
-
const registry = defineRegistry(appCatalog, { components: { Home, About, Contact } });
|
|
212
|
-
|
|
213
|
-
// State machine with 3 states
|
|
214
|
-
const appMachine = setup({
|
|
215
|
-
types: {
|
|
216
|
-
events: {} as PlayRouteEvent
|
|
217
|
-
}
|
|
218
|
-
}).createMachine({
|
|
219
|
-
id: 'app',
|
|
220
|
-
initial: 'home',
|
|
221
|
-
states: {
|
|
222
|
-
home: {
|
|
223
|
-
meta: { route: '/', view: { component: 'Home' } }
|
|
224
|
-
},
|
|
225
|
-
about: {
|
|
226
|
-
meta: { route: '/about', view: { component: 'About' } }
|
|
227
|
-
},
|
|
228
|
-
contact: {
|
|
229
|
-
meta: { route: '/contact', view: { component: 'Contact' } }
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
});
|
|
233
|
-
|
|
234
|
-
// Component setup
|
|
235
|
-
function App() {
|
|
236
|
-
const navigate = useNavigate();
|
|
237
|
-
const location = useLocation();
|
|
238
|
-
const params = useParams();
|
|
239
|
-
|
|
240
|
-
const routeMap = createRouteMap(appMachine);
|
|
241
|
-
|
|
242
|
-
const createPlayer = definePlayer({ machine: appMachine, catalog: appCatalog });
|
|
243
|
-
const actor = createPlayer();
|
|
244
|
-
actor.start();
|
|
245
|
-
const bridge = new SolidRouterBridge(navigate, location, params, actor, routeMap);
|
|
246
|
-
|
|
247
|
-
onCleanup(() => bridge.dispose());
|
|
248
|
-
|
|
249
|
-
return (
|
|
250
|
-
<Router>
|
|
251
|
-
<Route path="/" component={Home} />
|
|
252
|
-
<Route path="/about" component={About} />
|
|
253
|
-
<Route path="/contact" component={Contact} />
|
|
254
|
-
</Router>
|
|
255
|
-
);
|
|
256
|
-
}
|
|
257
|
-
```
|
|
258
|
-
|
|
259
|
-
### Parameter Handling: Dynamic Routes with `:param` Syntax
|
|
260
|
-
|
|
261
|
-
```typescript
|
|
262
|
-
// State machine with parameter routes
|
|
263
|
-
import { formatPlayRouteTransitions } from "@xmachines/play-xstate";
|
|
264
|
-
import { defineCatalog } from "@json-render/core";
|
|
265
|
-
import { schema } from "@json-render/react/schema";
|
|
266
|
-
import { defineRegistry } from "@xmachines/play-solid";
|
|
267
|
-
import { z } from "zod";
|
|
268
|
-
|
|
269
|
-
const appCatalog = defineCatalog(schema, {
|
|
270
|
-
components: {
|
|
271
|
-
Profile: { props: z.object({ userId: z.string() }) },
|
|
272
|
-
Settings: { props: z.object({ section: z.string().optional() }) },
|
|
273
|
-
},
|
|
274
|
-
});
|
|
275
|
-
const registry = defineRegistry(appCatalog, { components: { Profile, Settings } });
|
|
276
|
-
|
|
277
|
-
const machineConfig = {
|
|
278
|
-
id: 'app',
|
|
279
|
-
context: {},
|
|
280
|
-
states: {
|
|
281
|
-
profile: {
|
|
282
|
-
meta: {
|
|
283
|
-
route: '/profile/:userId',
|
|
284
|
-
view: { component: 'Profile' },
|
|
285
|
-
},
|
|
286
|
-
},
|
|
287
|
-
settings: {
|
|
288
|
-
meta: {
|
|
289
|
-
route: '/settings/:section?',
|
|
290
|
-
view: { component: 'Settings' },
|
|
291
|
-
},
|
|
292
|
-
}
|
|
293
|
-
}
|
|
294
52
|
};
|
|
295
53
|
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
context: {} as { userId?: string; section?: string },
|
|
299
|
-
events: {} as PlayRouteEvent
|
|
300
|
-
}
|
|
301
|
-
}).createMachine(formatPlayRouteTransitions(machineConfig));
|
|
302
|
-
|
|
303
|
-
// Router with dynamic routes
|
|
304
|
-
function App() {
|
|
305
|
-
const navigate = useNavigate();
|
|
306
|
-
const location = useLocation();
|
|
307
|
-
const params = useParams();
|
|
308
|
-
|
|
309
|
-
const routeMap = createRouteMap(appMachine);
|
|
310
|
-
|
|
311
|
-
const createPlayer = definePlayer({ machine: appMachine, catalog: appCatalog });
|
|
312
|
-
const actor = createPlayer();
|
|
313
|
-
actor.start();
|
|
314
|
-
const bridge = new SolidRouterBridge(navigate, location, params, actor, routeMap);
|
|
315
|
-
|
|
316
|
-
onCleanup(() => bridge.dispose());
|
|
317
|
-
|
|
318
|
-
return (
|
|
319
|
-
<Router>
|
|
320
|
-
<Route path="/profile/:userId" component={Profile} />
|
|
321
|
-
<Route path="/settings/:section?" component={Settings} />
|
|
322
|
-
</Router>
|
|
323
|
-
);
|
|
54
|
+
export default function App() {
|
|
55
|
+
return <Router root={Layout}>{/* one <Route> per routable state */}</Router>;
|
|
324
56
|
}
|
|
325
57
|
```
|
|
326
58
|
|
|
327
|
-
|
|
59
|
+
## API Summary
|
|
328
60
|
|
|
329
|
-
|
|
330
|
-
function ProfileButton(props: { userId: string }) {
|
|
331
|
-
return (
|
|
332
|
-
<button
|
|
333
|
-
onClick={() =>
|
|
334
|
-
props.actor.send({
|
|
335
|
-
type: "play.route",
|
|
336
|
-
to: "#profile",
|
|
337
|
-
params: { userId: props.userId },
|
|
338
|
-
})
|
|
339
|
-
}
|
|
340
|
-
>
|
|
341
|
-
View Profile
|
|
342
|
-
</button>
|
|
343
|
-
);
|
|
344
|
-
}
|
|
345
|
-
```
|
|
61
|
+
### `PlayRouterProvider`
|
|
346
62
|
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
```typescript
|
|
350
|
-
// State machine with query param handling
|
|
351
|
-
import { formatPlayRouteTransitions } from "@xmachines/play-xstate";
|
|
352
|
-
import { defineCatalog } from "@json-render/core";
|
|
353
|
-
import { schema } from "@json-render/react/schema";
|
|
354
|
-
import { defineRegistry } from "@xmachines/play-solid";
|
|
355
|
-
import { z } from "zod";
|
|
356
|
-
|
|
357
|
-
const searchCatalog = defineCatalog(schema, {
|
|
358
|
-
components: {
|
|
359
|
-
Search: { props: z.object({ query: z.string().optional() }) },
|
|
360
|
-
},
|
|
361
|
-
});
|
|
362
|
-
const registry = defineRegistry(searchCatalog, { components: { Search } });
|
|
363
|
-
|
|
364
|
-
const machineConfig = {
|
|
365
|
-
context: { query: '', filters: {} },
|
|
366
|
-
states: {
|
|
367
|
-
search: {
|
|
368
|
-
meta: {
|
|
369
|
-
route: '/search',
|
|
370
|
-
view: { component: 'Search' },
|
|
371
|
-
},
|
|
372
|
-
}
|
|
373
|
-
}
|
|
374
|
-
};
|
|
63
|
+
A SolidJS component that wires a `PlayerActor` to Solid Router. It creates and connects a `SolidRouterBridge` on mount and disconnects it via `onCleanup` on unmount.
|
|
375
64
|
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
props.actor.send({
|
|
391
|
-
type: 'play.route',
|
|
392
|
-
to: '#search',
|
|
393
|
-
query: { q: searchTerm(), tag: 'typescript' }
|
|
394
|
-
});
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
return (
|
|
398
|
-
<div>
|
|
399
|
-
<input
|
|
400
|
-
value={searchTerm()}
|
|
401
|
-
onInput={(e) => setSearchTerm(e.target.value)}
|
|
402
|
-
/>
|
|
403
|
-
<button onClick={handleSearch}>Search</button>
|
|
404
|
-
</div>
|
|
405
|
-
);
|
|
65
|
+
```tsx
|
|
66
|
+
interface PlayRouterProviderProps<TActor extends RoutableActor> {
|
|
67
|
+
/** The actor to sync with Solid Router. */
|
|
68
|
+
actor: TActor;
|
|
69
|
+
/** Bidirectional route map for state ID ↔ URL path lookups. */
|
|
70
|
+
routeMap: RouteMap;
|
|
71
|
+
/**
|
|
72
|
+
* The three Solid Router hook results that drive bidirectional sync.
|
|
73
|
+
* Must be obtained via useNavigate(), useLocation(), and useParams()
|
|
74
|
+
* inside a router context.
|
|
75
|
+
*/
|
|
76
|
+
router: SolidRouterHooks;
|
|
77
|
+
/** Render callback — receives the concrete actor type and router hooks. */
|
|
78
|
+
renderer: (actor: TActor, router: SolidRouterHooks) => JSX.Element;
|
|
406
79
|
}
|
|
407
80
|
```
|
|
408
81
|
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
- `/search?q=xmachines&tag=typescript`
|
|
412
|
-
|
|
413
|
-
### Protected Routes: Authentication Guards
|
|
414
|
-
|
|
415
|
-
```typescript
|
|
416
|
-
// State machine with auth guards
|
|
417
|
-
import { defineCatalog } from "@json-render/core";
|
|
418
|
-
import { schema } from "@json-render/react/schema";
|
|
419
|
-
import { defineRegistry } from "@xmachines/play-solid";
|
|
420
|
-
import { z } from "zod";
|
|
421
|
-
|
|
422
|
-
const authCatalog = defineCatalog(schema, {
|
|
423
|
-
components: {
|
|
424
|
-
Home: { props: z.object({}) },
|
|
425
|
-
Login: { props: z.object({ title: z.string() }) },
|
|
426
|
-
Dashboard: { props: z.object({ username: z.string() }) },
|
|
427
|
-
},
|
|
428
|
-
});
|
|
429
|
-
const registry = defineRegistry(authCatalog, { components: { Home, Login, Dashboard } });
|
|
430
|
-
|
|
431
|
-
const authMachine = setup({
|
|
432
|
-
types: {
|
|
433
|
-
context: {} as { isAuthenticated: boolean },
|
|
434
|
-
events: {} as PlayRouteEvent | { type: "login" } | { type: "logout" },
|
|
435
|
-
},
|
|
436
|
-
}).createMachine({
|
|
437
|
-
context: { isAuthenticated: false },
|
|
438
|
-
initial: "home",
|
|
439
|
-
states: {
|
|
440
|
-
home: {
|
|
441
|
-
meta: { route: "/", view: { component: "Home" } },
|
|
442
|
-
},
|
|
443
|
-
login: {
|
|
444
|
-
meta: { route: "/login", view: { component: "Login" } },
|
|
445
|
-
on: {
|
|
446
|
-
login: {
|
|
447
|
-
target: "dashboard",
|
|
448
|
-
actions: assign({ isAuthenticated: true }),
|
|
449
|
-
},
|
|
450
|
-
},
|
|
451
|
-
},
|
|
452
|
-
dashboard: {
|
|
453
|
-
meta: { route: "/dashboard", view: { component: "Dashboard" } },
|
|
454
|
-
always: {
|
|
455
|
-
guard: ({ context }) => !context.isAuthenticated,
|
|
456
|
-
target: "login",
|
|
457
|
-
},
|
|
458
|
-
},
|
|
459
|
-
},
|
|
460
|
-
});
|
|
461
|
-
|
|
462
|
-
const player = definePlayer({ machine: authMachine, catalog: authCatalog });
|
|
463
|
-
```
|
|
464
|
-
|
|
465
|
-
**Guard behavior:**
|
|
82
|
+
### `SolidRouterBridge`
|
|
466
83
|
|
|
467
|
-
-
|
|
468
|
-
- Bridge sends `play.route` event to actor
|
|
469
|
-
- Actor's `always` guard checks `isAuthenticated`
|
|
470
|
-
- If `false`, actor transitions to `login` state
|
|
471
|
-
- Bridge detects state change via `createEffect`, redirects to `/login`
|
|
472
|
-
- Actor Authority principle enforced
|
|
84
|
+
Low-level class for manual integration. Extends `RouterBridgeBase` from `@xmachines/play-router` and uses Solid's `createEffect` for reactive router→actor sync.
|
|
473
85
|
|
|
474
|
-
|
|
86
|
+
> **Important:** `connect()` must be called inside a Solid reactive owner (component or `createRoot`). Cleanup is not automatic — call `disconnect()` (or `dispose()`) explicitly, typically in `onCleanup()`.
|
|
475
87
|
|
|
476
88
|
```tsx
|
|
477
|
-
import { onCleanup } from "
|
|
478
|
-
import { SolidRouterBridge } from "@xmachines/play-solid-router";
|
|
89
|
+
import { useNavigate, useLocation, useParams, onCleanup } from "@solidjs/router";
|
|
90
|
+
import { SolidRouterBridge, RouteMap } from "@xmachines/play-solid-router";
|
|
479
91
|
|
|
480
92
|
function App() {
|
|
481
93
|
const navigate = useNavigate();
|
|
482
94
|
const location = useLocation();
|
|
483
95
|
const params = useParams();
|
|
484
|
-
const actor = useContext(ActorContext);
|
|
485
|
-
const routeMap = useContext(RouteMapContext);
|
|
486
96
|
|
|
487
|
-
const
|
|
97
|
+
const routeMap = new RouteMap([
|
|
98
|
+
{ stateId: "#home", path: "/" },
|
|
99
|
+
{ stateId: "#profile", path: "/profile/:userId" },
|
|
100
|
+
]);
|
|
488
101
|
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
});
|
|
102
|
+
const bridge = new SolidRouterBridge(navigate, location, params, actor, routeMap);
|
|
103
|
+
bridge.connect();
|
|
104
|
+
onCleanup(() => bridge.disconnect());
|
|
493
105
|
|
|
494
|
-
return <
|
|
106
|
+
return <div>...</div>;
|
|
495
107
|
}
|
|
496
108
|
```
|
|
497
109
|
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
- `createEffect` subscriptions continue after disposal (memory leak)
|
|
501
|
-
- Multiple bridge instances send duplicate events
|
|
502
|
-
- Tests fail with "Cannot send to stopped actor" errors
|
|
503
|
-
- Solid's fine-grained reactivity tracks disposed components
|
|
504
|
-
|
|
505
|
-
## Architecture
|
|
506
|
-
|
|
507
|
-
### Bidirectional Sync (Actor ↔ Router)
|
|
508
|
-
|
|
509
|
-
**Actor → Router (Signal-driven via createEffect):**
|
|
510
|
-
|
|
511
|
-
1. Actor transitions to new state with `meta.route`
|
|
512
|
-
2. `actor.currentRoute` signal updates
|
|
513
|
-
3. `createEffect(on(...))` fires with new route value
|
|
514
|
-
4. Bridge extracts state ID from signal
|
|
515
|
-
5. Bridge looks up path via `routeMap.getPathByStateId(stateId)`
|
|
516
|
-
6. Bridge calls `navigate(path)`
|
|
517
|
-
7. SolidJS Router updates URL and renders component
|
|
518
|
-
|
|
519
|
-
**Router → Actor (Location tracking via createEffect):**
|
|
520
|
-
|
|
521
|
-
1. User clicks link or browser back button
|
|
522
|
-
2. `location.pathname` signal updates
|
|
523
|
-
3. `createEffect(on(...))` fires with new pathname
|
|
524
|
-
4. Bridge looks up state ID via `routeMap.getStateIdByPath(pathname)`
|
|
525
|
-
5. Bridge extracts params from `useParams()` reactive object
|
|
526
|
-
6. Bridge sends `play.route` event to actor
|
|
527
|
-
7. Actor validates navigation (guards, transitions)
|
|
528
|
-
8. If accepted: Actor transitions, signal updates, URL stays
|
|
529
|
-
9. If rejected: Actor redirects, bridge corrects URL via `navigate()`
|
|
530
|
-
|
|
531
|
-
### Circular Update Prevention
|
|
532
|
-
|
|
533
|
-
**Multi-layer guards prevent infinite loops:**
|
|
534
|
-
|
|
535
|
-
1. **`lastSyncedPath` tracking:** Stores last synchronized path, skips if unchanged
|
|
536
|
-
2. **`isProcessingNavigation` flag:** Set during navigation processing, prevents concurrent syncs
|
|
537
|
-
3. **Effect timing:** Solid's batched updates and `defer: true` option prevent rapid cycles
|
|
538
|
-
|
|
539
|
-
**Signals-native pattern:**
|
|
540
|
-
|
|
541
|
-
```typescript
|
|
542
|
-
// Actor → Router
|
|
543
|
-
createEffect(
|
|
544
|
-
on(
|
|
545
|
-
() => this.actor.currentRoute.get(),
|
|
546
|
-
(route) => {
|
|
547
|
-
if (!route || route === this.lastSyncedPath || this.isProcessingNavigation) {
|
|
548
|
-
return;
|
|
549
|
-
}
|
|
550
|
-
this.lastSyncedPath = route;
|
|
551
|
-
this.navigate(route);
|
|
552
|
-
},
|
|
553
|
-
{ defer: true },
|
|
554
|
-
),
|
|
555
|
-
);
|
|
556
|
-
|
|
557
|
-
// Router → Actor
|
|
558
|
-
createEffect(
|
|
559
|
-
on(
|
|
560
|
-
() => this.location.pathname,
|
|
561
|
-
(pathname) => {
|
|
562
|
-
if (pathname === this.lastSyncedPath || this.isProcessingNavigation) {
|
|
563
|
-
return;
|
|
564
|
-
}
|
|
565
|
-
this.isProcessingNavigation = true;
|
|
566
|
-
this.actor.send({ type: "play.route", to: stateId, params });
|
|
567
|
-
this.isProcessingNavigation = false;
|
|
568
|
-
},
|
|
569
|
-
{ defer: true },
|
|
570
|
-
),
|
|
571
|
-
);
|
|
572
|
-
```
|
|
110
|
+
### `createRouteMap(machine)`
|
|
573
111
|
|
|
574
|
-
|
|
112
|
+
Factory that builds a `RouteMap` directly from an XState machine definition. Re-exported from `@xmachines/play-router`.
|
|
575
113
|
|
|
576
|
-
|
|
114
|
+
```ts
|
|
115
|
+
import { createRouteMap } from "@xmachines/play-solid-router";
|
|
577
116
|
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
- - Actor base class with signal protocol
|
|
581
|
-
- - Route extraction and pattern matching
|
|
582
|
-
- - TC39 Signals polyfill for reactivity
|
|
583
|
-
- **Architecture Layers:**
|
|
584
|
-
|
|
585
|
-
```
|
|
586
|
-
┌─────────────────────────────────────┐
|
|
587
|
-
│ Solid Components (View Layer) │
|
|
588
|
-
│ - Props include actor reference │
|
|
589
|
-
│ - Sends play.route events │
|
|
590
|
-
└─────────────────────────────────────┘
|
|
591
|
-
↕
|
|
592
|
-
┌─────────────────────────────────────┐
|
|
593
|
-
│ SolidRouterBridge (Adapter) │
|
|
594
|
-
│ - createEffect(actor.currentRoute) │
|
|
595
|
-
│ - createEffect(location.pathname) │
|
|
596
|
-
└─────────────────────────────────────┘
|
|
597
|
-
↕ ↕
|
|
598
|
-
┌─────────────┐ ┌──────────────────┐
|
|
599
|
-
│ SolidJS │ │ XMachines Actor │
|
|
600
|
-
│ Router │ │ (Business Logic) │
|
|
601
|
-
│ (Infra) │ │ │
|
|
602
|
-
└─────────────┘ └──────────────────┘
|
|
117
|
+
const routeMap = createRouteMap(myMachine);
|
|
603
118
|
```
|
|
604
119
|
|
|
605
|
-
###
|
|
606
|
-
|
|
607
|
-
**Why signals-native matters:**
|
|
608
|
-
|
|
609
|
-
- **Zero adaptation:** Solid signals and TC39 Signals share reactive primitives
|
|
610
|
-
- **Automatic tracking:** `createEffect(on(...))` tracks dependencies without manual Watcher setup
|
|
611
|
-
- **Fine-grained updates:** Only affected components re-render (not full tree)
|
|
612
|
-
- **Batched updates:** Solid batches multiple signal changes in single render cycle
|
|
613
|
-
|
|
614
|
-
**Hook context requirement (Pitfall 2):**
|
|
120
|
+
### `RouteMap` / `RouteMapping`
|
|
615
121
|
|
|
616
|
-
|
|
122
|
+
Bidirectional state ID ↔ URL path mapping. Re-exported from `@xmachines/play-router`.
|
|
617
123
|
|
|
618
|
-
```
|
|
619
|
-
|
|
620
|
-
const navigate = useNavigate(); // ERROR: No reactive context
|
|
621
|
-
const bridge = new SolidRouterBridge(navigate, ...);
|
|
124
|
+
```ts
|
|
125
|
+
import { RouteMap } from "@xmachines/play-solid-router";
|
|
622
126
|
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
const bridge = new SolidRouterBridge(navigate, location, params, actor, routeMap);
|
|
629
|
-
onCleanup(() => bridge.dispose());
|
|
630
|
-
return <Router>...</Router>;
|
|
631
|
-
}
|
|
127
|
+
const routeMap = new RouteMap([
|
|
128
|
+
{ stateId: "#home", path: "/" },
|
|
129
|
+
{ stateId: "#profile", path: "/profile/:userId" },
|
|
130
|
+
{ stateId: "#settings", path: "/settings/:section?" },
|
|
131
|
+
]);
|
|
632
132
|
```
|
|
633
133
|
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
### Pattern Matching for Dynamic Routes
|
|
637
|
-
|
|
638
|
-
**Bucket-indexed matching via `BaseRouteMap`:**
|
|
134
|
+
### Types
|
|
639
135
|
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
136
|
+
| Export | Description |
|
|
137
|
+
| ------------------------- | -------------------------------------------------------------------------------------------- |
|
|
138
|
+
| `RoutableActor` | Minimum actor shape accepted by `PlayRouterProvider` (`AbstractActor & Routable & Viewable`) |
|
|
139
|
+
| `SolidRouterHooks` | Shape of the `router` prop: `{ navigate, location, params }` |
|
|
140
|
+
| `PlayRouterProviderProps` | Full props interface for `PlayRouterProvider` |
|
|
141
|
+
| `PlayRouteEvent` | Event type sent to the actor on URL change (`play.route`) |
|
|
142
|
+
| `RouterBridge` | Interface implemented by `SolidRouterBridge` |
|
|
643
143
|
|
|
644
|
-
|
|
144
|
+
## Testing
|
|
645
145
|
|
|
646
|
-
|
|
647
|
-
- `:param?` - Optional parameter (e.g., `/settings/:section?` matches `/settings` and `/settings/account`)
|
|
648
|
-
- Wildcards via `*` (future enhancement)
|
|
146
|
+
Run tests for this package in isolation:
|
|
649
147
|
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
const routeMap = new RouteMap([
|
|
654
|
-
{ stateId: "#profile", path: "/profile/:userId" },
|
|
655
|
-
{ stateId: "#settings", path: "/settings/:section?" },
|
|
656
|
-
]);
|
|
148
|
+
```bash
|
|
149
|
+
# From the monorepo root
|
|
150
|
+
npm test -w packages/play-solid-router
|
|
657
151
|
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
routeMap.getStateIdByPath("/settings/privacy"); // '#settings'
|
|
152
|
+
# Or from this package directory
|
|
153
|
+
npm test
|
|
661
154
|
```
|
|
662
155
|
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
- [Demo](../../../examples/@xmachines/play-solid-router-demo/README.md)
|
|
666
|
-
- [SolidJS renderer](../play-solid/README.md)
|
|
156
|
+
Coverage thresholds: **80%** lines, functions, branches, and statements.
|
|
667
157
|
|
|
668
158
|
## License
|
|
669
159
|
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
This work is licensed under the terms of the MIT license.
|
|
673
|
-
For a copy, see <https://opensource.org/licenses/MIT>.
|
|
160
|
+
MIT — see [LICENSE](LICENSE).
|
|
674
161
|
|
|
675
162
|
## Classes
|
|
676
163
|
|