@xmachines/docs 1.0.0 → 2.0.0-alpha.1
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 +1 -1
- package/api/@xmachines/play/classes/NonNullableError.md +11 -11
- package/api/@xmachines/play/classes/PlayError.md +11 -11
- package/api/@xmachines/play/functions/assertNonNullable.md +1 -1
- package/api/@xmachines/play/type-aliases/PlayEvent.md +4 -4
- package/api/@xmachines/play-actor/classes/AbstractActor.md +20 -19
- package/api/@xmachines/play-actor/functions/attachRenderErrorHandler.md +1 -1
- package/api/@xmachines/play-actor/functions/toAtomState.md +1 -1
- package/api/@xmachines/play-actor/functions/typedSpec.md +1 -1
- package/api/@xmachines/play-actor/interfaces/BaseActorProviderProps.md +7 -7
- package/api/@xmachines/play-actor/interfaces/BaseViewContextValue.md +7 -7
- package/api/@xmachines/play-actor/interfaces/PlaySpec.md +7 -7
- package/api/@xmachines/play-actor/interfaces/Routable.md +5 -5
- package/api/@xmachines/play-actor/interfaces/Viewable.md +4 -4
- package/api/@xmachines/play-dom/classes/PlayRenderer.md +4 -4
- 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/interfaces/CreatePlayUIOptions.md +10 -10
- package/api/@xmachines/play-dom/interfaces/MountOptions.md +5 -5
- package/api/@xmachines/play-dom/interfaces/PlayDomOptions.md +12 -12
- package/api/@xmachines/play-dom/type-aliases/MountFn.md +1 -1
- package/api/@xmachines/play-dom-router/README.md +1 -1
- 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 +2 -2
- package/api/@xmachines/play-dom-router/functions/createRouter.md +1 -1
- package/api/@xmachines/play-dom-router/interfaces/BrowserHistory.md +16 -16
- package/api/@xmachines/play-dom-router/interfaces/BrowserWindow.md +16 -16
- package/api/@xmachines/play-dom-router/interfaces/ConnectRouterOptions.md +6 -6
- package/api/@xmachines/play-dom-router/interfaces/PlayRouteEvent.md +8 -8
- package/api/@xmachines/play-dom-router/interfaces/RoutableActor.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 +4 -4
- package/api/@xmachines/play-dom-router/interfaces/RouteMapping.md +5 -5
- package/api/@xmachines/play-dom-router/interfaces/RouterBridge.md +3 -3
- package/api/@xmachines/play-dom-router/interfaces/VanillaRouter.md +6 -6
- package/api/@xmachines/play-react/README.md +1 -1
- 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 +10 -10
- package/api/@xmachines/play-react/interfaces/PlayErrorBoundaryProps.md +6 -6
- package/api/@xmachines/play-react/interfaces/PlayErrorBoundaryState.md +5 -5
- package/api/@xmachines/play-react/interfaces/PlayUIProviderProps.md +13 -13
- package/api/@xmachines/play-react/interfaces/ViewContextValue.md +7 -7
- package/api/@xmachines/play-react/type-aliases/AnyPlayActor.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 +1 -1
- package/api/@xmachines/play-react-router/classes/ReactRouterBridge.md +4 -4
- package/api/@xmachines/play-react-router/classes/RouteMap.md +4 -4
- package/api/@xmachines/play-react-router/functions/createPlayRouterProvider.md +1 -1
- package/api/@xmachines/play-react-router/functions/createRouteMap.md +2 -2
- package/api/@xmachines/play-react-router/functions/createRouteMapFromTree.md +1 -1
- package/api/@xmachines/play-react-router/interfaces/PlayActor.md +7 -7
- package/api/@xmachines/play-react-router/interfaces/PlayRouteEvent.md +8 -8
- package/api/@xmachines/play-react-router/interfaces/PlayRouterProviderBaseProps.md +7 -7
- package/api/@xmachines/play-react-router/interfaces/PlayRouterProviderProps.md +7 -7
- package/api/@xmachines/play-react-router/interfaces/RouteMapOptions.md +4 -4
- package/api/@xmachines/play-react-router/interfaces/RouteMapping.md +5 -5
- package/api/@xmachines/play-react-router/interfaces/RouterBridge.md +3 -3
- package/api/@xmachines/play-react-router/type-aliases/PlayRouterBridgeConstructor.md +1 -1
- package/api/@xmachines/play-react-router/variables/PlayRouterProvider.md +1 -1
- package/api/@xmachines/play-router/README.md +15 -7
- package/api/@xmachines/play-router/classes/RouteMap.md +4 -4
- package/api/@xmachines/play-router/classes/RouterBridgeBase.md +4 -4
- 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 +2 -2
- package/api/@xmachines/play-router/functions/createRouteMapFromTree.md +1 -1
- package/api/@xmachines/play-router/functions/detectDuplicateRoutes.md +1 -1
- package/api/@xmachines/play-router/functions/extractMachineRoutes.md +2 -2
- 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 +6 -6
- package/api/@xmachines/play-router/interfaces/LocationLike.md +5 -5
- package/api/@xmachines/play-router/interfaces/MachineEdgeData.md +7 -5
- package/api/@xmachines/play-router/interfaces/MachineNodeData.md +7 -7
- package/api/@xmachines/play-router/interfaces/PlayActor.md +7 -7
- package/api/@xmachines/play-router/interfaces/PlayRouteEvent.md +8 -8
- package/api/@xmachines/play-router/interfaces/ResolvedRoutePath.md +5 -5
- package/api/@xmachines/play-router/interfaces/RoutableActor.md +6 -6
- package/api/@xmachines/play-router/interfaces/RouteInfo.md +10 -10
- package/api/@xmachines/play-router/interfaces/RouteMapOptions.md +4 -4
- package/api/@xmachines/play-router/interfaces/RouteMapping.md +5 -5
- package/api/@xmachines/play-router/interfaces/RouteMatch.md +5 -5
- package/api/@xmachines/play-router/interfaces/RouteNode.md +12 -12
- package/api/@xmachines/play-router/interfaces/RouteObject.md +4 -4
- package/api/@xmachines/play-router/interfaces/RouteTree.md +7 -7
- 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/functions/watchSignal.md +1 -1
- package/api/@xmachines/play-signals/interfaces/ComputedOptions.md +4 -4
- package/api/@xmachines/play-signals/interfaces/SignalComputed.md +2 -2
- package/api/@xmachines/play-signals/interfaces/SignalOptions.md +4 -4
- 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/functions/useActor.md +1 -1
- package/api/@xmachines/play-solid/functions/usePlayView.md +1 -1
- package/api/@xmachines/play-solid/interfaces/ActorProviderProps.md +10 -10
- package/api/@xmachines/play-solid/interfaces/PlayUIProviderProps.md +13 -13
- package/api/@xmachines/play-solid/interfaces/ViewContextValue.md +7 -7
- package/api/@xmachines/play-solid/type-aliases/AnyPlayActor.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 +5 -5
- package/api/@xmachines/play-solid-router/classes/RouteMap.md +4 -4
- package/api/@xmachines/play-solid-router/classes/SolidRouterBridge.md +5 -5
- package/api/@xmachines/play-solid-router/functions/createPlayRouterProvider.md +1 -1
- package/api/@xmachines/play-solid-router/functions/createRouteMap.md +2 -2
- package/api/@xmachines/play-solid-router/interfaces/AbstractActor.md +20 -19
- package/api/@xmachines/play-solid-router/interfaces/PlayActor.md +7 -7
- package/api/@xmachines/play-solid-router/interfaces/PlayRouteEvent.md +8 -8
- package/api/@xmachines/play-solid-router/interfaces/PlayRouterProviderBaseProps.md +7 -7
- package/api/@xmachines/play-solid-router/interfaces/PlayRouterProviderProps.md +7 -7
- package/api/@xmachines/play-solid-router/interfaces/RouteMapOptions.md +4 -4
- package/api/@xmachines/play-solid-router/interfaces/RouteMapping.md +5 -5
- package/api/@xmachines/play-solid-router/interfaces/RouterBridge.md +3 -3
- package/api/@xmachines/play-solid-router/type-aliases/PlayRouterBridgeConstructor.md +1 -1
- 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-solid-router/variables/PlayRouterProvider.md +1 -1
- package/api/@xmachines/play-svelte/README.md +1 -1
- 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 +10 -10
- package/api/@xmachines/play-svelte/interfaces/DefineRegistryOptions.md +6 -6
- package/api/@xmachines/play-svelte/interfaces/PlayUIProviderProps.md +13 -13
- package/api/@xmachines/play-svelte/interfaces/ViewContextValue.md +7 -7
- package/api/@xmachines/play-svelte/type-aliases/AnyPlayActor.md +1 -1
- package/api/@xmachines/play-svelte-spa-router/README.md +24 -18
- 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 +2 -2
- package/api/@xmachines/play-svelte-spa-router/interfaces/ConnectRouterOptions.md +6 -6
- package/api/@xmachines/play-svelte-spa-router/interfaces/PlayRouteEvent.md +8 -8
- package/api/@xmachines/play-svelte-spa-router/interfaces/RouteMapOptions.md +4 -4
- package/api/@xmachines/play-svelte-spa-router/interfaces/RouteMapping.md +5 -5
- 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 +5 -5
- 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 +2 -2
- package/api/@xmachines/play-sveltekit-router/interfaces/ConnectRouterOptions.md +6 -6
- package/api/@xmachines/play-sveltekit-router/interfaces/LocationLike.md +5 -5
- package/api/@xmachines/play-sveltekit-router/interfaces/PlayRouteEvent.md +8 -8
- package/api/@xmachines/play-sveltekit-router/interfaces/RouteMapOptions.md +4 -4
- package/api/@xmachines/play-sveltekit-router/interfaces/RouteMapping.md +5 -5
- 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 +1 -1
- package/api/@xmachines/play-tanstack-react-router/classes/RouteMap.md +4 -4
- package/api/@xmachines/play-tanstack-react-router/classes/TanStackReactRouterBridge.md +4 -4
- package/api/@xmachines/play-tanstack-react-router/functions/createPlayRouterProvider.md +1 -1
- package/api/@xmachines/play-tanstack-react-router/functions/createRouteMap.md +2 -2
- package/api/@xmachines/play-tanstack-react-router/functions/createRouteMapFromTree.md +1 -1
- package/api/@xmachines/play-tanstack-react-router/functions/extractMachineRoutes.md +2 -2
- package/api/@xmachines/play-tanstack-react-router/interfaces/PlayActor.md +7 -7
- package/api/@xmachines/play-tanstack-react-router/interfaces/PlayRouteEvent.md +8 -8
- package/api/@xmachines/play-tanstack-react-router/interfaces/PlayRouterProviderBaseProps.md +7 -7
- package/api/@xmachines/play-tanstack-react-router/interfaces/PlayRouterProviderProps.md +7 -7
- package/api/@xmachines/play-tanstack-react-router/interfaces/RouteMapOptions.md +4 -4
- package/api/@xmachines/play-tanstack-react-router/interfaces/RouteMapping.md +5 -5
- package/api/@xmachines/play-tanstack-react-router/interfaces/RouteNavigateEvent.md +5 -5
- package/api/@xmachines/play-tanstack-react-router/interfaces/RouterBridge.md +3 -3
- package/api/@xmachines/play-tanstack-react-router/type-aliases/PlayRouterBridgeConstructor.md +1 -1
- 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-react-router/variables/PlayRouterProvider.md +1 -1
- package/api/@xmachines/play-tanstack-router/classes/TanStackRouterBridgeBase.md +2 -2
- package/api/@xmachines/play-tanstack-router/type-aliases/TanStackRouteMapLike.md +3 -3
- package/api/@xmachines/play-tanstack-router/type-aliases/TanStackRouterLike.md +4 -4
- package/api/@xmachines/play-tanstack-solid-router/README.md +5 -5
- package/api/@xmachines/play-tanstack-solid-router/classes/RouteMap.md +4 -4
- package/api/@xmachines/play-tanstack-solid-router/classes/TanStackSolidRouterBridge.md +5 -5
- package/api/@xmachines/play-tanstack-solid-router/functions/createPlayRouterProvider.md +1 -1
- package/api/@xmachines/play-tanstack-solid-router/functions/createRouteMap.md +2 -2
- package/api/@xmachines/play-tanstack-solid-router/interfaces/PlayActor.md +7 -7
- package/api/@xmachines/play-tanstack-solid-router/interfaces/PlayRouteEvent.md +8 -8
- package/api/@xmachines/play-tanstack-solid-router/interfaces/PlayRouterProviderBaseProps.md +7 -7
- package/api/@xmachines/play-tanstack-solid-router/interfaces/PlayRouterProviderProps.md +7 -7
- package/api/@xmachines/play-tanstack-solid-router/interfaces/RouteMapOptions.md +4 -4
- package/api/@xmachines/play-tanstack-solid-router/interfaces/RouteMapping.md +5 -5
- package/api/@xmachines/play-tanstack-solid-router/interfaces/RouterBridge.md +3 -3
- package/api/@xmachines/play-tanstack-solid-router/type-aliases/PlayRouterBridgeConstructor.md +1 -1
- 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 +4 -4
- package/api/@xmachines/play-tanstack-solid-router/variables/PlayRouterProvider.md +1 -1
- package/api/@xmachines/play-vue/README.md +1 -1
- 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 +7 -7
- package/api/@xmachines/play-vue/interfaces/PlayUIProviderProps.md +10 -10
- package/api/@xmachines/play-vue/interfaces/ViewContextValue.md +7 -7
- package/api/@xmachines/play-vue/interfaces/VisibilityProviderProps.md +1 -1
- package/api/@xmachines/play-vue/type-aliases/AnyPlayActor.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 +4 -4
- package/api/@xmachines/play-vue/variables/PlayRenderer.md +1 -1
- package/api/@xmachines/play-vue-router/README.md +1 -1
- package/api/@xmachines/play-vue-router/classes/RouteMap.md +4 -4
- package/api/@xmachines/play-vue-router/classes/VueRouterBridge.md +5 -5
- package/api/@xmachines/play-vue-router/functions/createRouteMap.md +2 -2
- package/api/@xmachines/play-vue-router/interfaces/PlayActor.md +7 -7
- package/api/@xmachines/play-vue-router/interfaces/PlayRouteEvent.md +8 -8
- package/api/@xmachines/play-vue-router/interfaces/RouteMapOptions.md +4 -4
- package/api/@xmachines/play-vue-router/interfaces/RouteMapping.md +5 -5
- 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 +88 -25
- package/api/@xmachines/play-xstate/classes/PlayerActor.md +34 -33
- package/api/@xmachines/play-xstate/functions/buildRouteUrl.md +1 -1
- package/api/@xmachines/play-xstate/functions/composeGuards.md +23 -17
- package/api/@xmachines/play-xstate/functions/composeGuardsOr.md +16 -16
- package/api/@xmachines/play-xstate/functions/contextFieldMatches.md +1 -1
- package/api/@xmachines/play-xstate/functions/createRoutedMachine.md +87 -0
- package/api/@xmachines/play-xstate/functions/definePlayer.md +3 -3
- 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 +45 -11
- 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 +15 -15
- package/api/@xmachines/play-xstate/interfaces/PlayerConfig.md +5 -5
- package/api/@xmachines/play-xstate/interfaces/PlayerFactoryResumeOptions.md +4 -4
- package/api/@xmachines/play-xstate/interfaces/PlayerOptions.md +8 -8
- package/api/@xmachines/play-xstate/interfaces/RouteContext.md +7 -7
- package/api/@xmachines/play-xstate/interfaces/RouteObject.md +4 -4
- package/api/@xmachines/play-xstate/type-aliases/ComposedGuard.md +26 -5
- 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/PlayRoutePayload.md +30 -0
- package/api/@xmachines/play-xstate/type-aliases/PlayerFactory.md +1 -1
- package/api/@xmachines/play-xstate/type-aliases/RouteMachineConfig.md +13 -6
- package/api/@xmachines/play-xstate/type-aliases/RouteMetadata.md +1 -1
- package/api/@xmachines/play-xstate/type-aliases/RouteStateNode.md +16 -4
- package/api/@xmachines/play-xstate/type-aliases/SetupLike.md +33 -0
- package/api/@xmachines/play-xstate/type-aliases/WithOptional.md +31 -0
- package/api/@xmachines/play-xstate/variables/emptyEventSchema.md +37 -0
- package/api/@xmachines/play-xstate/variables/playMetaSchema.md +40 -0
- package/api/@xmachines/play-xstate/variables/playRouteEventSchema.md +9 -0
- 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/vite-aliases/functions/xmSvelteRunes.md +4 -4
- package/api/@xmachines/shared/vitest/functions/defineXmBrowserConfig.md +1 -1
- package/api/@xmachines/shared/vitest/functions/defineXmVitestConfig.md +1 -1
- package/api/@xmachines/shared/vitest/interfaces/XmBrowserConfigOptions.md +6 -6
- package/contributing/architecture.md +9 -6
- package/contributing/development.md +1 -1
- 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-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-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-svelte-demo/type-aliases/AuthCatalog.md +1 -1
- package/examples/@xmachines/play-svelte-demo/variables/authCatalog.md +1 -1
- 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/README.md +1 -1
- package/examples/basic-state-machine.md +22 -24
- package/examples/form-validation.md +118 -109
- package/examples/routing-patterns.md +92 -60
- package/examples/traffic-light.md +46 -57
- package/guides/getting-started.md +79 -68
- package/guides/state-machines.md +68 -52
- package/package.json +2 -2
- package/rfc/play.md +4 -4
|
@@ -18,58 +18,58 @@ Applicable patterns:
|
|
|
18
18
|
## Complete Code
|
|
19
19
|
|
|
20
20
|
```typescript
|
|
21
|
-
import { setup } from "xstate";
|
|
22
|
-
import {
|
|
21
|
+
import { setup, types } from "xstate";
|
|
22
|
+
import {
|
|
23
|
+
createRoutedMachine,
|
|
24
|
+
definePlayer,
|
|
25
|
+
emptyEventSchema,
|
|
26
|
+
playMetaSchema,
|
|
27
|
+
playRouteEventSchema,
|
|
28
|
+
} from "@xmachines/play-xstate";
|
|
23
29
|
|
|
24
30
|
// 1. Typed setup
|
|
25
31
|
const trafficSetup = setup({
|
|
26
|
-
|
|
27
|
-
context: {
|
|
32
|
+
schemas: {
|
|
33
|
+
context: types<{
|
|
28
34
|
params: Record<string, string>;
|
|
29
35
|
query: Record<string, string>;
|
|
36
|
+
}>(),
|
|
37
|
+
events: {
|
|
38
|
+
timer: emptyEventSchema,
|
|
39
|
+
"play.route": playRouteEventSchema,
|
|
30
40
|
},
|
|
31
|
-
|
|
32
|
-
| { type: "timer" }
|
|
33
|
-
| {
|
|
34
|
-
type: "play.route";
|
|
35
|
-
to: string;
|
|
36
|
-
params?: Record<string, string>;
|
|
37
|
-
query?: Record<string, string>;
|
|
38
|
-
},
|
|
39
|
-
input: {} as undefined,
|
|
41
|
+
meta: playMetaSchema,
|
|
40
42
|
},
|
|
41
43
|
});
|
|
42
44
|
|
|
43
|
-
// 2. Machine with meta.route on every state
|
|
44
|
-
//
|
|
45
|
-
//
|
|
46
|
-
const trafficMachine = trafficSetup
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
45
|
+
// 2. Machine with meta.route on every state.
|
|
46
|
+
// createRoutedMachine wires routing up from each state's id + meta.route,
|
|
47
|
+
// with the same config typing as trafficSetup.createMachine itself.
|
|
48
|
+
const trafficMachine = createRoutedMachine(trafficSetup)({
|
|
49
|
+
id: "traffic",
|
|
50
|
+
initial: "red",
|
|
51
|
+
context: {
|
|
52
|
+
params: {},
|
|
53
|
+
query: {},
|
|
54
|
+
},
|
|
55
|
+
states: {
|
|
56
|
+
red: {
|
|
57
|
+
id: "red",
|
|
58
|
+
meta: { route: "/red" },
|
|
59
|
+
on: { timer: { target: "green" } },
|
|
60
|
+
},
|
|
61
|
+
green: {
|
|
62
|
+
id: "green",
|
|
63
|
+
meta: { route: "/green" },
|
|
64
|
+
on: { timer: { target: "yellow" } },
|
|
53
65
|
},
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
on: { timer: "green" },
|
|
59
|
-
},
|
|
60
|
-
green: {
|
|
61
|
-
id: "green",
|
|
62
|
-
meta: { route: "/green" },
|
|
63
|
-
on: { timer: "yellow" },
|
|
64
|
-
},
|
|
65
|
-
yellow: {
|
|
66
|
-
id: "yellow",
|
|
67
|
-
meta: { route: "/yellow" },
|
|
68
|
-
on: { timer: "red" },
|
|
69
|
-
},
|
|
66
|
+
yellow: {
|
|
67
|
+
id: "yellow",
|
|
68
|
+
meta: { route: "/yellow" },
|
|
69
|
+
on: { timer: { target: "red" } },
|
|
70
70
|
},
|
|
71
|
-
}
|
|
72
|
-
);
|
|
71
|
+
},
|
|
72
|
+
});
|
|
73
73
|
|
|
74
74
|
// 3. Player factory
|
|
75
75
|
const createPlayer = definePlayer({ machine: trafficMachine });
|
|
@@ -101,23 +101,12 @@ actor.stop();
|
|
|
101
101
|
|
|
102
102
|
## How `formatPlayRouteTransitions` Works
|
|
103
103
|
|
|
104
|
-
`formatPlayRouteTransitions` crawls every state that has **both** an `id` and a `meta.route
|
|
105
|
-
|
|
106
|
-
```typescript
|
|
107
|
-
// Auto-generated by formatPlayRouteTransitions — you don't write this manually:
|
|
108
|
-
on: {
|
|
109
|
-
"play.route": [
|
|
110
|
-
{ target: ".red", guard: ({ event }) => event.to === "#red", reenter: true, actions: assign({ params, query }) },
|
|
111
|
-
{ target: ".green", guard: ({ event }) => event.to === "#green", reenter: true, actions: assign({ params, query }) },
|
|
112
|
-
{ target: ".yellow", guard: ({ event }) => event.to === "#yellow", reenter: true, actions: assign({ params, query }) },
|
|
113
|
-
],
|
|
114
|
-
}
|
|
115
|
-
```
|
|
104
|
+
`formatPlayRouteTransitions` (applied by `createRoutedMachine`) crawls every state that has **both** an `id` and a `meta.route` and wires them to XState v6's native routing: each routed state gets a static `route: {}` config, and one root `play.route` forwarder navigates those targets in a single atomic transition while patching `params`/`query` into context. See the [routing patterns example](./routing-patterns.md) for the full mechanism, including user-declared route configs and fallback handling for unknown targets.
|
|
116
105
|
|
|
117
106
|
**Requirements:**
|
|
118
107
|
|
|
119
108
|
- Every routable state must have both `id` (the `#id` navigation target) and `meta.route` (the URL template).
|
|
120
|
-
- The machine's context must include `params` and `query` fields (both `Record<string, string>`), because `formatPlayRouteTransitions`
|
|
109
|
+
- The machine's context must include `params` and `query` fields (both `Record<string, string>`), because `formatPlayRouteTransitions` patches them into context on every `play.route` transition.
|
|
121
110
|
|
|
122
111
|
## `actor.currentRoute` Signal
|
|
123
112
|
|
|
@@ -137,12 +126,12 @@ unwatch();
|
|
|
137
126
|
## Key Concepts
|
|
138
127
|
|
|
139
128
|
- **`meta.route`**: Marks a state as routable. The value is a URL template (e.g. `"/profile/:username"`).
|
|
140
|
-
- **`
|
|
129
|
+
- **`createRoutedMachine`**: Setup-typed entry point that applies `formatPlayRouteTransitions` — wiring `id` + `meta.route` pairs to XState v6's native routing (`route` configs + an `xstate.route` forwarder).
|
|
141
130
|
- **`actor.currentRoute`**: TC39 `Signal.Computed` containing the resolved URL for the active state.
|
|
142
131
|
- **`play.route` events**: Navigation events with a `to: "#stateId"` target. Use `to: "#red"` (state ID), not `to: "/red"` (URL path).
|
|
143
132
|
|
|
144
133
|
## Next Steps
|
|
145
134
|
|
|
146
|
-
- **[Form Validation Example](form-validation.md)** — Context
|
|
147
|
-
- **[Routing Patterns](routing-patterns.md)** — Parameter routes, relative routes, and `always` auth
|
|
135
|
+
- **[Form Validation Example](form-validation.md)** — Context patches and guard logic in transition functions
|
|
136
|
+
- **[Routing Patterns](routing-patterns.md)** — Parameter routes, relative routes, and `always` auth redirects
|
|
148
137
|
- **[Play RFC](../rfc/play.md)** — Complete architectural specification
|
|
@@ -145,7 +145,7 @@ This section covers installing XMachines packages into your own application and
|
|
|
145
145
|
- **Node.js** `>= 22.0.0`
|
|
146
146
|
- **pnpm** via corepack (`corepack enable`)
|
|
147
147
|
- **TypeScript** `>= 5.7` (strict mode recommended)
|
|
148
|
-
- **XState** `
|
|
148
|
+
- **XState** `v6` (required peer dependency for [`@xmachines/play-xstate`](../api/@xmachines/play-xstate/README.md))
|
|
149
149
|
|
|
150
150
|
All packages are ES modules (`"type": "module"`). Use `.js` extensions in all TypeScript imports.
|
|
151
151
|
|
|
@@ -161,7 +161,7 @@ pnpm add xstate @xmachines/play-xstate @xmachines/play-actor @xmachines/play-sig
|
|
|
161
161
|
|
|
162
162
|
| Package | Role |
|
|
163
163
|
| --------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
164
|
-
| `xstate` | XState
|
|
164
|
+
| `xstate` | XState v6 state machine engine (peer dependency) |
|
|
165
165
|
| [`@xmachines/play-xstate`](../api/@xmachines/play-xstate/README.md) | [`definePlayer()`](../api/@xmachines/play-xstate/functions/definePlayer.md), [`PlayerActor`](../api/@xmachines/play-xstate/classes/PlayerActor.md), routing helpers |
|
|
166
166
|
| [`@xmachines/play-actor`](../api/@xmachines/play-actor/README.md) | Abstract actor base class and interface types |
|
|
167
167
|
| [`@xmachines/play-signals`](../api/@xmachines/play-signals/README.md) | TC39 Signals polyfill (`Signal.State`, `Signal.Computed`, [`watchSignal`](../api/@xmachines/play-signals/functions/watchSignal.md)) |
|
|
@@ -199,15 +199,16 @@ pnpm add @xmachines/play-dom # Vanilla DOM
|
|
|
199
199
|
The minimum viable XMachines actor — no framework dependencies:
|
|
200
200
|
|
|
201
201
|
```typescript
|
|
202
|
-
import { setup } from "xstate";
|
|
203
|
-
import { definePlayer } from "@xmachines/play-xstate";
|
|
202
|
+
import { setup, types } from "xstate";
|
|
203
|
+
import { definePlayer, emptyEventSchema } from "@xmachines/play-xstate";
|
|
204
204
|
|
|
205
|
-
// 1. Declare
|
|
205
|
+
// 1. Declare schemas with setup() — the XState v6 typed entry point
|
|
206
206
|
const appSetup = setup({
|
|
207
|
-
|
|
208
|
-
context: {
|
|
209
|
-
events: {
|
|
210
|
-
|
|
207
|
+
schemas: {
|
|
208
|
+
context: types<{ count: number }>(),
|
|
209
|
+
events: {
|
|
210
|
+
toggle: emptyEventSchema,
|
|
211
|
+
},
|
|
211
212
|
},
|
|
212
213
|
});
|
|
213
214
|
|
|
@@ -219,18 +220,18 @@ const machine = appSetup.createMachine({
|
|
|
219
220
|
states: {
|
|
220
221
|
off: {
|
|
221
222
|
on: {
|
|
222
|
-
toggle: {
|
|
223
|
+
toggle: ({ context }) => ({
|
|
223
224
|
target: "on",
|
|
224
|
-
|
|
225
|
-
},
|
|
225
|
+
context: { count: context.count + 1 },
|
|
226
|
+
}),
|
|
226
227
|
},
|
|
227
228
|
},
|
|
228
229
|
on: {
|
|
229
230
|
on: {
|
|
230
|
-
toggle: {
|
|
231
|
+
toggle: ({ context }) => ({
|
|
231
232
|
target: "off",
|
|
232
|
-
|
|
233
|
-
},
|
|
233
|
+
context: { count: context.count + 1 },
|
|
234
|
+
}),
|
|
234
235
|
},
|
|
235
236
|
},
|
|
236
237
|
},
|
|
@@ -257,8 +258,8 @@ actor.stop();
|
|
|
257
258
|
|
|
258
259
|
**Key rules:**
|
|
259
260
|
|
|
260
|
-
- Always use `setup({
|
|
261
|
-
-
|
|
261
|
+
- Always use `setup({ schemas })` before `createMachine` — never bare `createMachine` from xstate.
|
|
262
|
+
- Update context by returning a shallow `context` patch from the transition function — there is no `assign` action.
|
|
262
263
|
- Call `actor.start()` before sending events.
|
|
263
264
|
- Call `actor.stop()` when done to clean up signal subscriptions.
|
|
264
265
|
|
|
@@ -270,64 +271,73 @@ State machines control navigation through `meta.route` on states and `play.route
|
|
|
270
271
|
|
|
271
272
|
#### Define a routable machine with `formatPlayRouteTransitions`
|
|
272
273
|
|
|
273
|
-
[`formatPlayRouteTransitions`](../api/@xmachines/play-xstate/functions/formatPlayRouteTransitions.md)
|
|
274
|
+
`createRoutedMachine` wires routing up from `id` + `meta.route` state pairs (via [`formatPlayRouteTransitions`](../api/@xmachines/play-xstate/functions/formatPlayRouteTransitions.md)): each routed state gets a native XState v6 `route: {}` config, and one root `play.route` forwarder navigates those targets in a single atomic transition, patching `params`/`query` into context:
|
|
274
275
|
|
|
275
276
|
```typescript
|
|
276
|
-
import { setup } from "xstate";
|
|
277
|
-
import {
|
|
278
|
-
|
|
277
|
+
import { setup, types } from "xstate";
|
|
278
|
+
import {
|
|
279
|
+
createRoutedMachine,
|
|
280
|
+
definePlayer,
|
|
281
|
+
emptyEventSchema,
|
|
282
|
+
playMetaSchema,
|
|
283
|
+
playRouteEventSchema,
|
|
284
|
+
} from "@xmachines/play-xstate";
|
|
279
285
|
|
|
280
286
|
const appSetup = setup({
|
|
281
|
-
|
|
282
|
-
// params and query are REQUIRED for
|
|
283
|
-
context: {
|
|
287
|
+
schemas: {
|
|
288
|
+
// params and query are REQUIRED for routed machines
|
|
289
|
+
context: types<{
|
|
284
290
|
isAuthenticated: boolean;
|
|
285
291
|
params: Record<string, string>;
|
|
286
292
|
query: Record<string, string>;
|
|
293
|
+
}>(),
|
|
294
|
+
events: {
|
|
295
|
+
"play.route": playRouteEventSchema,
|
|
296
|
+
"auth.login": types<{ username: string }>(),
|
|
297
|
+
"auth.logout": emptyEventSchema,
|
|
287
298
|
},
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
input: {} as undefined,
|
|
299
|
+
// meta.route on state nodes needs a declared meta schema
|
|
300
|
+
meta: playMetaSchema,
|
|
291
301
|
},
|
|
292
302
|
});
|
|
293
303
|
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
target: "login",
|
|
311
|
-
},
|
|
304
|
+
// createRoutedMachine(appSetup) has the same signature as appSetup.createMachine
|
|
305
|
+
const appMachine = createRoutedMachine(appSetup)({
|
|
306
|
+
id: "app",
|
|
307
|
+
initial: "home",
|
|
308
|
+
context: { isAuthenticated: false, params: {}, query: {} },
|
|
309
|
+
states: {
|
|
310
|
+
home: { id: "home", meta: { route: "/" } },
|
|
311
|
+
about: { id: "about", meta: { route: "/about" } },
|
|
312
|
+
login: { id: "login", meta: { route: "/login" } },
|
|
313
|
+
dashboard: {
|
|
314
|
+
id: "dashboard",
|
|
315
|
+
meta: { route: "/dashboard" },
|
|
316
|
+
// always transition: redirect to /login if not authenticated
|
|
317
|
+
always: ({ context }) => {
|
|
318
|
+
if (context.isAuthenticated) return;
|
|
319
|
+
return { target: "login" };
|
|
312
320
|
},
|
|
313
|
-
profile: { id: "profile", meta: { route: "/profile/:username" } },
|
|
314
321
|
},
|
|
315
|
-
|
|
316
|
-
|
|
322
|
+
profile: { id: "profile", meta: { route: "/profile/:username" } },
|
|
323
|
+
},
|
|
324
|
+
on: {
|
|
325
|
+
"auth.login": ({ context }) => {
|
|
326
|
+
if (context.isAuthenticated) return;
|
|
327
|
+
return {
|
|
317
328
|
target: ".dashboard",
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
329
|
+
context: { isAuthenticated: true },
|
|
330
|
+
};
|
|
331
|
+
},
|
|
332
|
+
"auth.logout": ({ context }) => {
|
|
333
|
+
if (!context.isAuthenticated) return;
|
|
334
|
+
return {
|
|
324
335
|
target: ".home",
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
},
|
|
336
|
+
context: { isAuthenticated: false },
|
|
337
|
+
};
|
|
328
338
|
},
|
|
329
|
-
}
|
|
330
|
-
);
|
|
339
|
+
},
|
|
340
|
+
});
|
|
331
341
|
|
|
332
342
|
const createPlayer = definePlayer({ machine: appMachine });
|
|
333
343
|
const actor = createPlayer();
|
|
@@ -340,9 +350,9 @@ console.log(actor.currentRoute.get()); // "/"
|
|
|
340
350
|
actor.send({ type: "play.route", to: "#about" });
|
|
341
351
|
console.log(actor.currentRoute.get()); // "/about"
|
|
342
352
|
|
|
343
|
-
// Attempt a protected route — always
|
|
353
|
+
// Attempt a protected route — always transition redirects to login
|
|
344
354
|
actor.send({ type: "play.route", to: "#dashboard" });
|
|
345
|
-
console.log(actor.getSnapshot().value); // "login" (
|
|
355
|
+
console.log(actor.getSnapshot().value); // "login" (redirect fired)
|
|
346
356
|
|
|
347
357
|
// Navigate with params
|
|
348
358
|
actor.send({ type: "auth.login", username: "alice" });
|
|
@@ -357,7 +367,7 @@ actor.stop();
|
|
|
357
367
|
- Every routable state **must** have an `id` — [`formatPlayRouteTransitions`](../api/@xmachines/play-xstate/functions/formatPlayRouteTransitions.md) throws `MissingStateIdError` if absent.
|
|
358
368
|
- Send `play.route` events with `to: "#stateId"` — always use the `id` field prefixed with `#`, never raw URL paths.
|
|
359
369
|
- The machine context **must** include `params: Record<string, string>` and `query: Record<string, string>`.
|
|
360
|
-
- Use `always`
|
|
370
|
+
- Use `always` transitions (function form, with an early-return guard) to protect states from direct URL access — these fire even on browser back/forward.
|
|
361
371
|
|
|
362
372
|
---
|
|
363
373
|
|
|
@@ -609,14 +619,14 @@ window.addEventListener("beforeunload", () => disconnect());
|
|
|
609
619
|
|
|
610
620
|
**Error:** `MissingQueryContextError` at runtime when using [`formatPlayRouteTransitions`](../api/@xmachines/play-xstate/functions/formatPlayRouteTransitions.md).
|
|
611
621
|
|
|
612
|
-
**Fix:** Add `params` and `query` fields to your machine context
|
|
622
|
+
**Fix:** Add `params` and `query` fields to your machine context schema and initial value:
|
|
613
623
|
|
|
614
624
|
```typescript
|
|
615
|
-
context: {
|
|
625
|
+
context: types<{
|
|
616
626
|
params: Record<string, string>;
|
|
617
627
|
query: Record<string, string>;
|
|
618
628
|
// ...other fields
|
|
619
|
-
}
|
|
629
|
+
}>()
|
|
620
630
|
// and initialize them:
|
|
621
631
|
context: { params: {}, query: {}, /* ...other fields */ }
|
|
622
632
|
```
|
|
@@ -678,7 +688,7 @@ node --version
|
|
|
678
688
|
|
|
679
689
|
| Term | Description |
|
|
680
690
|
| ----------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- |
|
|
681
|
-
| `setup({
|
|
691
|
+
| `setup({ schemas })` | XState v6 entry point — declares schemas (via `types<T>()`) for context, events, input, and state meta |
|
|
682
692
|
| [`definePlayer({ machine })`](../api/@xmachines/play-xstate/functions/definePlayer.md) | Creates a factory that produces [`PlayerActor`](../api/@xmachines/play-xstate/classes/PlayerActor.md) instances |
|
|
683
693
|
| `actor.start()` | Activates the machine — always call before sending events |
|
|
684
694
|
| `actor.send({ type })` | Sends an event; machine guards decide whether a transition occurs |
|
|
@@ -686,9 +696,10 @@ node --version
|
|
|
686
696
|
| `actor.state` | `Signal.State<Snapshot>` — TC39 Signal for reactive state observation |
|
|
687
697
|
| `actor.currentRoute` | `Signal.Computed<string \| null>` — resolved URL from active state's `meta.route` |
|
|
688
698
|
| `actor.currentView` | `Signal.State<PlaySpec \| null>` — view spec from active state's `meta.view` |
|
|
689
|
-
|
|
|
699
|
+
| `createRoutedMachine(setup)` | Setup-typed `createMachine` that wires `id` + `meta.route` state pairs to native routing |
|
|
700
|
+
| [`formatPlayRouteTransitions`](../api/@xmachines/play-xstate/functions/formatPlayRouteTransitions.md) | Underlying transform — native `route: {}` configs plus one root `play.route` forwarder |
|
|
690
701
|
| `play.route` event | Navigation event — `to: "#stateId"`, optional `params`, `query` |
|
|
691
|
-
| `always`
|
|
702
|
+
| `always` transition | Protects states — fires on entry before any event, even on direct URL access |
|
|
692
703
|
| [`extractMachineRoutes`](../api/@xmachines/play-router/functions/extractMachineRoutes.md) | Extracts a `RouteTree` from a state machine — used by framework-integrated router adapters |
|
|
693
704
|
| [`createRouteMapFromTree`](../api/@xmachines/play-router/functions/createRouteMapFromTree.md) | Builds a `RouteMap` from a `RouteTree` for bidirectional state ID ↔ URL lookups |
|
|
694
705
|
| [`connectRouter`](../api/@xmachines/play-dom-router/functions/connectRouter.md) | Connects a vanilla DOM router to an actor — returns a disconnect cleanup function |
|
package/guides/state-machines.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Understanding State Machines in XMachines
|
|
2
2
|
|
|
3
|
-
XMachines uses XState
|
|
3
|
+
XMachines uses XState v6 as its state machine engine. This page explains what finite state machines are, how XMachines extends them with routing and view metadata, and why this design eliminates an entire category of bugs common in traditional frontend architecture.
|
|
4
4
|
|
|
5
5
|
After reading this, you will understand what a machine definition actually encodes — and why state machines are a better unit of business logic than component-level state or ad-hoc if/else trees.
|
|
6
6
|
|
|
@@ -22,18 +22,21 @@ In traditional component-level state (e.g., boolean flags, `useState` combinatio
|
|
|
22
22
|
|
|
23
23
|
---
|
|
24
24
|
|
|
25
|
-
## How XMachines uses XState
|
|
25
|
+
## How XMachines uses XState v6
|
|
26
26
|
|
|
27
|
-
XMachines wraps XState
|
|
27
|
+
XMachines wraps XState v6 via [`@xmachines/play-xstate`](../api/@xmachines/play-xstate/README.md). You define machines using XState's `setup().createMachine()` API:
|
|
28
28
|
|
|
29
29
|
```typescript
|
|
30
|
-
import { setup } from "xstate";
|
|
30
|
+
import { setup, types } from "xstate";
|
|
31
|
+
import { emptyEventSchema } from "@xmachines/play-xstate";
|
|
31
32
|
|
|
32
33
|
const authSetup = setup({
|
|
33
|
-
|
|
34
|
-
context: {
|
|
35
|
-
events: {
|
|
36
|
-
|
|
34
|
+
schemas: {
|
|
35
|
+
context: types<{ username: string | null }>(),
|
|
36
|
+
events: {
|
|
37
|
+
"auth.login": types<{ username: string }>(),
|
|
38
|
+
"auth.logout": emptyEventSchema,
|
|
39
|
+
},
|
|
37
40
|
},
|
|
38
41
|
});
|
|
39
42
|
|
|
@@ -44,20 +47,18 @@ const authMachine = authSetup.createMachine({
|
|
|
44
47
|
states: {
|
|
45
48
|
unauthenticated: {
|
|
46
49
|
on: {
|
|
47
|
-
"auth.login": {
|
|
50
|
+
"auth.login": ({ event }) => ({
|
|
48
51
|
target: "authenticated",
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
}),
|
|
52
|
-
},
|
|
52
|
+
context: { username: event.username },
|
|
53
|
+
}),
|
|
53
54
|
},
|
|
54
55
|
},
|
|
55
56
|
authenticated: {
|
|
56
57
|
on: {
|
|
57
|
-
"auth.logout": {
|
|
58
|
+
"auth.logout": () => ({
|
|
58
59
|
target: "unauthenticated",
|
|
59
|
-
|
|
60
|
-
},
|
|
60
|
+
context: { username: null },
|
|
61
|
+
}),
|
|
61
62
|
},
|
|
62
63
|
},
|
|
63
64
|
},
|
|
@@ -66,8 +67,8 @@ const authMachine = authSetup.createMachine({
|
|
|
66
67
|
|
|
67
68
|
Key patterns:
|
|
68
69
|
|
|
69
|
-
- **Always use `setup({
|
|
70
|
-
- **
|
|
70
|
+
- **Always use `setup({ schemas })`** before `createMachine`. The `types<T>()` helper declares type-only schemas so TypeScript can check that your events, context fields, and transitions are consistent throughout the machine. The `events` schema is a map from event type to payload shape — the payload excludes the `type` field itself.
|
|
71
|
+
- **Transitions are plain functions** that return `{ target, context }`. Context updates are shallow patches returned from the transition function — there is no separate `assign` action.
|
|
71
72
|
- **Event names use lowercase dot-separated namespaces**: `"auth.login"`, `"play.route"`, `"form.submit"`. This convention makes the event log readable and avoids collisions.
|
|
72
73
|
|
|
73
74
|
---
|
|
@@ -138,8 +139,8 @@ states: {
|
|
|
138
139
|
home: {
|
|
139
140
|
on: {
|
|
140
141
|
"play.route": [
|
|
141
|
-
|
|
142
|
-
|
|
142
|
+
({ event }) => (event.to === "#login" ? { target: "login" } : undefined),
|
|
143
|
+
({ event }) => (event.to === "#dashboard" ? { target: "dashboard" } : undefined),
|
|
143
144
|
],
|
|
144
145
|
},
|
|
145
146
|
meta: { route: "/" },
|
|
@@ -148,34 +149,38 @@ states: {
|
|
|
148
149
|
}
|
|
149
150
|
```
|
|
150
151
|
|
|
151
|
-
[`formatPlayRouteTransitions`](../api/@xmachines/play-xstate/functions/formatPlayRouteTransitions.md) from [`@xmachines/play-xstate`](../api/@xmachines/play-xstate/README.md)
|
|
152
|
+
[`formatPlayRouteTransitions`](../api/@xmachines/play-xstate/functions/formatPlayRouteTransitions.md) from [`@xmachines/play-xstate`](../api/@xmachines/play-xstate/README.md) wires this up automatically from the `id` and `meta.route` fields you already have — each routed state gets a native XState v6 `route: {}` config (for `xstate.route` interop and graph tooling), and one root `play.route` forwarder navigates those targets in a single atomic transition, patching `params`/`query` into context:
|
|
152
153
|
|
|
153
154
|
```typescript
|
|
154
|
-
import {
|
|
155
|
-
|
|
156
|
-
const
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
},
|
|
165
|
-
}
|
|
166
|
-
);
|
|
155
|
+
import { createRoutedMachine, emptyEventSchema } from "@xmachines/play-xstate";
|
|
156
|
+
|
|
157
|
+
const appSetup = setup({/* ... */});
|
|
158
|
+
|
|
159
|
+
const appMachine = createRoutedMachine(appSetup)({
|
|
160
|
+
id: "app",
|
|
161
|
+
initial: "home",
|
|
162
|
+
states: {
|
|
163
|
+
home: { id: "home", meta: { route: "/" } },
|
|
164
|
+
login: { id: "login", meta: { route: "/login" } },
|
|
165
|
+
dashboard: { id: "dashboard", meta: { route: "/dashboard" } },
|
|
166
|
+
},
|
|
167
|
+
});
|
|
167
168
|
```
|
|
168
169
|
|
|
169
|
-
[`formatPlayRouteTransitions`](../api/@xmachines/play-xstate/functions/formatPlayRouteTransitions.md)
|
|
170
|
+
`createRoutedMachine` has the same signature as the setup's own `createMachine`, so the config keeps full contextual typing. (The underlying transform, [`formatPlayRouteTransitions`](../api/@xmachines/play-xstate/functions/formatPlayRouteTransitions.md), can also be called directly on a config before `createMachine`.) The machine's context must include `params` and `query` fields (populated by the router bridge when params or query strings are present):
|
|
170
171
|
|
|
171
172
|
```typescript
|
|
172
|
-
|
|
173
|
-
context: {
|
|
173
|
+
schemas: {
|
|
174
|
+
context: types<{
|
|
174
175
|
params: Record<string, string>;
|
|
175
176
|
query: Record<string, string>;
|
|
176
177
|
// ... other context fields
|
|
178
|
+
}>(),
|
|
179
|
+
events: {
|
|
180
|
+
"play.route": playRouteEventSchema, // exported by @xmachines/play-xstate
|
|
181
|
+
// ... other event schemas
|
|
177
182
|
},
|
|
178
|
-
|
|
183
|
+
meta: playMetaSchema, // exported by @xmachines/play-xstate — types meta.route / meta.view
|
|
179
184
|
}
|
|
180
185
|
```
|
|
181
186
|
|
|
@@ -183,7 +188,7 @@ types: {
|
|
|
183
188
|
|
|
184
189
|
## Guards — the actor's authority
|
|
185
190
|
|
|
186
|
-
Guards are the mechanism by which the actor controls whether a transition occurs. They are pure functions of `{ context, event }` that return a boolean.
|
|
191
|
+
Guards are the mechanism by which the actor controls whether a transition occurs. They are pure functions of transition arguments (`{ context, event, ... }`) that return a boolean. Named guards declared in `setup({ guards })` are passed to every transition function via `args.guards`:
|
|
187
192
|
|
|
188
193
|
```typescript
|
|
189
194
|
const authSetup = setup({
|
|
@@ -194,11 +199,22 @@ const authSetup = setup({
|
|
|
194
199
|
});
|
|
195
200
|
```
|
|
196
201
|
|
|
197
|
-
|
|
202
|
+
A transition function evaluates its guard condition and returns early to reject the transition:
|
|
203
|
+
|
|
204
|
+
```typescript
|
|
205
|
+
on: {
|
|
206
|
+
"admin.open": (args) => {
|
|
207
|
+
if (!args.guards.isAdmin(args)) return;
|
|
208
|
+
return { target: "adminPanel" };
|
|
209
|
+
},
|
|
210
|
+
},
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
When the guard fails, the transition function returns `undefined`, the transition does not occur — the machine stays in its current state and the `play.route` event is discarded. The router bridge then sees that `actor.currentRoute` has not changed and corrects the URL back to the current valid route.
|
|
198
214
|
|
|
199
215
|
This is the **Actor Authority** invariant in practice: the machine decides, infrastructure adjusts.
|
|
200
216
|
|
|
201
|
-
XMachines provides guard combinators in [`@xmachines/play-xstate`](../api/@xmachines/play-xstate/README.md) for composing complex conditions:
|
|
217
|
+
XMachines provides guard combinators in [`@xmachines/play-xstate`](../api/@xmachines/play-xstate/README.md) for composing complex conditions. Each combinator returns a plain predicate — call it inside a transition function with the transition arguments:
|
|
202
218
|
|
|
203
219
|
| Function | What it does |
|
|
204
220
|
| --------------------------------------------------------------------------------------------------- | --------------------------------------- |
|
|
@@ -213,27 +229,27 @@ XMachines provides guard combinators in [`@xmachines/play-xstate`](../api/@xmach
|
|
|
213
229
|
|
|
214
230
|
## Context — persistent state across transitions
|
|
215
231
|
|
|
216
|
-
Context is the machine's persistent data store. It survives transitions and
|
|
232
|
+
Context is the machine's persistent data store. It survives transitions and is updated by the shallow patches transition functions return:
|
|
217
233
|
|
|
218
234
|
```typescript
|
|
219
|
-
// Context is defined in setup({
|
|
220
|
-
|
|
221
|
-
context: {
|
|
235
|
+
// Context is defined in setup({ schemas })
|
|
236
|
+
schemas: {
|
|
237
|
+
context: types<{
|
|
222
238
|
isAuthenticated: boolean;
|
|
223
239
|
username: string | null;
|
|
224
240
|
loginAttempts: number;
|
|
225
|
-
},
|
|
241
|
+
}>(),
|
|
226
242
|
},
|
|
227
243
|
|
|
228
|
-
//
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
244
|
+
// Transitions update context by returning a patch
|
|
245
|
+
on: {
|
|
246
|
+
"login.failure": ({ context }) => ({
|
|
247
|
+
context: { loginAttempts: context.loginAttempts + 1 },
|
|
232
248
|
}),
|
|
233
249
|
},
|
|
234
250
|
```
|
|
235
251
|
|
|
236
|
-
Context is accessed in guards,
|
|
252
|
+
Context is accessed in guards, transition functions, and when computing routes or views. It is not directly observable from outside the actor via signals — only the derived signals (`state`, `currentRoute`, `currentView`) are public. If you need to expose a context field reactively, add a `Signal.Computed` to the actor that derives from `actor.state`.
|
|
237
253
|
|
|
238
254
|
---
|
|
239
255
|
|
|
@@ -280,5 +296,5 @@ actor.start();
|
|
|
280
296
|
- [Getting Started](getting-started.md) — step-by-step walkthrough building your first machine and actor
|
|
281
297
|
- [Routing Patterns](../examples/routing-patterns.md) — worked examples of `meta.route` and guards
|
|
282
298
|
- [@xmachines/play-xstate](../api/@xmachines/play-xstate/README.md) — full API reference for [`definePlayer`](../api/@xmachines/play-xstate/functions/definePlayer.md), [`PlayerActor`](../api/@xmachines/play-xstate/classes/PlayerActor.md), guard combinators
|
|
283
|
-
- [XState
|
|
299
|
+
- [XState documentation](https://stately.ai/docs/xstate) — upstream state machine library documentation
|
|
284
300
|
- [Play RFC](../rfc/play.md) — complete architectural specification
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xmachines/docs",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0-alpha.1",
|
|
4
4
|
"description": "Documentation for XMachines",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"documentation",
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
"devDependencies": {
|
|
55
55
|
"@testing-library/jest-dom": "^6.9.1",
|
|
56
56
|
"@types/node": "^26.1.1",
|
|
57
|
-
"@xmachines/shared": "
|
|
57
|
+
"@xmachines/shared": "2.0.0-alpha.1",
|
|
58
58
|
"oxfmt": "^0.58.0",
|
|
59
59
|
"oxlint": "^1.73.0",
|
|
60
60
|
"typedoc": "^0.28.19",
|