@xmachines/docs 2.0.0-alpha.1 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -5
- package/api/@xmachines/play/README.md +1 -4
- 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/README.md +81 -26
- package/api/@xmachines/play-actor/classes/AbstractActor.md +35 -20
- package/api/@xmachines/play-actor/functions/attachRenderErrorHandler.md +1 -1
- package/api/@xmachines/play-actor/functions/composePlayState.md +26 -0
- package/api/@xmachines/play-actor/functions/createViewStoreLifecycle.md +21 -0
- package/api/@xmachines/play-actor/functions/guardContextWrites.md +41 -0
- package/api/@xmachines/play-actor/functions/refreshContextSubtree.md +27 -0
- package/api/@xmachines/play-actor/functions/reuseComposedState.md +41 -0
- package/api/@xmachines/play-actor/functions/shallowEqualExcept.md +28 -0
- package/api/@xmachines/play-actor/functions/toAtomState.md +1 -1
- package/api/@xmachines/play-actor/functions/typedSpec.md +23 -26
- 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 +12 -14
- package/api/@xmachines/play-actor/interfaces/ResolveViewStoreOptions.md +11 -0
- package/api/@xmachines/play-actor/interfaces/Routable.md +5 -5
- package/api/@xmachines/play-actor/interfaces/ViewStoreLifecycle.md +50 -0
- package/api/@xmachines/play-actor/interfaces/ViewStoreResolution.md +15 -0
- package/api/@xmachines/play-actor/interfaces/Viewable.md +4 -4
- package/api/@xmachines/play-actor/variables/CONTEXT_STATE_KEY.md +15 -0
- package/api/@xmachines/play-dom/README.md +6 -3
- 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/functions/createValidationRegistry.md +22 -0
- package/api/@xmachines/play-dom/functions/defineRegistry.md +5 -5
- package/api/@xmachines/play-dom/interfaces/ComponentContext.md +9 -8
- package/api/@xmachines/play-dom/interfaces/CreatePlayUIOptions.md +10 -10
- package/api/@xmachines/play-dom/interfaces/DomRenderContext.md +2 -0
- package/api/@xmachines/play-dom/interfaces/FieldValidationState.md +16 -0
- 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/interfaces/RenderSpecOptions.md +2 -0
- package/api/@xmachines/play-dom/interfaces/ValidationRegistry.md +21 -0
- package/api/@xmachines/play-dom/type-aliases/BaseComponentProps.md +10 -0
- package/api/@xmachines/play-dom/type-aliases/MountFn.md +1 -1
- package/api/@xmachines/play-dom/variables/schema.md +35 -45
- package/api/@xmachines/play-dom-router/README.md +3 -3
- 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 +4 -3
- package/api/@xmachines/play-react/classes/PlayErrorBoundary.md +5 -5
- package/api/@xmachines/play-react/functions/defineRegistry.md +5 -5
- package/api/@xmachines/play-react/functions/useActor.md +1 -1
- package/api/@xmachines/play-react/functions/useFieldValidation.md +31 -0
- 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/ComponentContext.md +9 -8
- 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 +2 -4
- 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 +9 -17
- 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 +5 -7
- 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/README.md +2 -2
- 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/README.md +2 -2
- 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 +7 -7
- 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 +35 -20
- 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 +22 -4
- 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 +19 -28
- 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 +7 -7
- 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 +3 -3
- 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/README.md +2 -0
- 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 +7 -7
- 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 +3 -5
- 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/functions/useFieldValidation.md +31 -0
- 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 +3 -3
- 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 +100 -111
- package/api/@xmachines/play-xstate/classes/PlayerActor.md +81 -58
- package/api/@xmachines/play-xstate/functions/buildRouteUrl.md +5 -12
- package/api/@xmachines/play-xstate/functions/composeGuards.md +23 -24
- package/api/@xmachines/play-xstate/functions/composeGuardsOr.md +22 -17
- package/api/@xmachines/play-xstate/functions/contextFieldMatches.md +7 -2
- 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 +7 -2
- package/api/@xmachines/play-xstate/functions/formatPlayRouteTransitions.md +11 -45
- package/api/@xmachines/play-xstate/functions/hasContext.md +7 -4
- package/api/@xmachines/play-xstate/functions/isAbsoluteRoute.md +1 -1
- package/api/@xmachines/play-xstate/functions/negateGuard.md +21 -16
- 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 +10 -11
- 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 +9 -25
- package/api/@xmachines/play-xstate/type-aliases/Guard.md +7 -5
- package/api/@xmachines/play-xstate/type-aliases/GuardArray.md +7 -5
- package/api/@xmachines/play-xstate/type-aliases/PlayerFactory.md +11 -15
- package/api/@xmachines/play-xstate/type-aliases/RouteMachineConfig.md +6 -13
- package/api/@xmachines/play-xstate/type-aliases/RouteMetadata.md +1 -1
- package/api/@xmachines/play-xstate/type-aliases/RouteStateNode.md +4 -16
- package/api/@xmachines/shared/README.md +2 -2
- 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 +12 -7
- package/api/@xmachines/shared/vite-aliases/functions/xmResolve.md +1 -1
- package/api/@xmachines/shared/vite-aliases/functions/xmSvelteRunes.md +9 -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 +27 -28
- package/contributing/configuration.md +10 -10
- package/contributing/deployment.md +51 -30
- package/contributing/development.md +62 -21
- package/contributing/testing.md +36 -14
- 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 +4 -1
- package/examples/basic-state-machine.md +24 -24
- package/examples/form-validation.md +110 -121
- package/examples/multi-router-integration.md +0 -2
- package/examples/routing-patterns.md +60 -94
- package/examples/traffic-light.md +57 -48
- package/guides/README.md +6 -2
- package/guides/actor-model.md +1 -1
- package/guides/getting-started.md +89 -90
- package/guides/inspector.md +197 -0
- package/guides/state-machines.md +55 -69
- package/package.json +10 -7
- package/rfc/play.md +15 -6
- package/api/@xmachines/play-xstate/functions/createRoutedMachine.md +0 -87
- package/api/@xmachines/play-xstate/type-aliases/PlayRoutePayload.md +0 -30
- package/api/@xmachines/play-xstate/type-aliases/SetupLike.md +0 -33
- package/api/@xmachines/play-xstate/type-aliases/WithOptional.md +0 -31
- package/api/@xmachines/play-xstate/variables/emptyEventSchema.md +0 -37
- package/api/@xmachines/play-xstate/variables/playMetaSchema.md +0 -40
- package/api/@xmachines/play-xstate/variables/playRouteEventSchema.md +0 -9
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
# Inspecting a Running Actor
|
|
2
|
+
|
|
3
|
+
A `PlayerActor` is an XState actor, so every XState inspection tool works on it unchanged. This guide covers how to attach an inspector, what the events look like once they arrive, and the two things that are specific to XMachines: the actor _is_ the actor an inspector sees, and the observer is configured on the factory rather than on each instance.
|
|
4
|
+
|
|
5
|
+
After reading this you will be able to open the [Stately inspector](https://stately.ai/docs/inspector) against a running demo or your own app, inspect an actor that has no browser around it, and wire an inspector that can be turned on after the actor has already started.
|
|
6
|
+
|
|
7
|
+
- [Quick start](#quick-start) — three lines to a live inspector
|
|
8
|
+
- [Where the observer attaches](#where-the-observer-attaches) — factory-level, creation-time
|
|
9
|
+
- [Reading the events](#reading-the-events) — identity, `rootId`, the construction caveat
|
|
10
|
+
- [Turning the inspector on later](#turning-the-inspector-on-later) — dev-tools toggles and replay
|
|
11
|
+
- [Inspecting without a browser](#inspecting-without-a-browser) — WebSocket transport, Node and SSR
|
|
12
|
+
- [Trying it in the demos](#trying-it-in-the-demos) — the shared demo controller
|
|
13
|
+
- [Production considerations](#production-considerations) — cost and data exposure
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Quick start
|
|
18
|
+
|
|
19
|
+
Install the inspect client alongside your existing XState dependency:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
pnpm add -D @statelyai/inspect
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Create an inspector and hand its `inspect` observer to [`definePlayer`](../api/@xmachines/play-xstate/functions/definePlayer.md):
|
|
26
|
+
|
|
27
|
+
```typescript
|
|
28
|
+
import { createBrowserInspector } from "@statelyai/inspect";
|
|
29
|
+
import { definePlayer } from "@xmachines/play-xstate";
|
|
30
|
+
import { appMachine } from "./machine.js";
|
|
31
|
+
|
|
32
|
+
const { inspect } = createBrowserInspector();
|
|
33
|
+
|
|
34
|
+
const createPlayer = definePlayer({
|
|
35
|
+
machine: appMachine,
|
|
36
|
+
options: { inspect },
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
const actor = createPlayer();
|
|
40
|
+
actor.start();
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
`createBrowserInspector()` opens Stately's hosted inspector in a new tab and streams the actor's events to it. From there the machine draws itself, every transition animates, and the context is readable at each step.
|
|
44
|
+
|
|
45
|
+
That is the whole integration. [`PlayerOptions.inspect`](../api/@xmachines/play-xstate/interfaces/PlayerOptions.md) is forwarded verbatim to XState's `createActor`, so anything XState accepts there is accepted here — a function, or an observer object with a `next` method:
|
|
46
|
+
|
|
47
|
+
```typescript
|
|
48
|
+
// Function form — the common case
|
|
49
|
+
definePlayer({ machine, options: { inspect: (event) => console.log(event.type) } });
|
|
50
|
+
|
|
51
|
+
// Observer form — also forwarded as-is
|
|
52
|
+
definePlayer({ machine, options: { inspect: { next: (event) => sink.write(event) } } });
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## Where the observer attaches
|
|
58
|
+
|
|
59
|
+
Two properties of the attachment point matter in practice.
|
|
60
|
+
|
|
61
|
+
**It is configured on the factory, not on the instance.** `definePlayer({ machine, options })` returns a factory; `options.inspect` belongs to that configuration, and every actor the factory creates reports to the same observer. The factory's per-call options bag carries `snapshot` for restoring persisted state and nothing else — there is no per-instance `inspect` override. When one factory produces several live actors (multi-user scenarios, SSR, tests), demultiplex the stream by root instead:
|
|
62
|
+
|
|
63
|
+
```typescript
|
|
64
|
+
const createPlayer = definePlayer({ machine, options: { inspect } });
|
|
65
|
+
|
|
66
|
+
const alice = createPlayer({ userId: "alice" });
|
|
67
|
+
const bob = createPlayer({ userId: "bob" });
|
|
68
|
+
|
|
69
|
+
// Events from alice's tree, children included
|
|
70
|
+
const forAlice = (event: InspectionEvent) => event.rootId === alice.sessionId;
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
**It is the only route that sees construction.** Attaching after the fact with `actor.system.inspect(fn)` works and needs no factory changes, but it only receives events from the moment it subscribes — the `@xstate.actor` registration event has already fired by then, and an inspector that never receives it has no machine to draw. Use `options.inspect` when you want the full history; use `actor.system.inspect(fn)` when you only care about what happens next.
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
## Reading the events
|
|
78
|
+
|
|
79
|
+
Because a `PlayerActor` _is_ the XState actor rather than a wrapper around a hidden one, the events name it directly:
|
|
80
|
+
|
|
81
|
+
- `event.actorRef === actor` for the player's own events — recognise a player by identity, no bookkeeping required.
|
|
82
|
+
- `event.rootId === actor.sessionId` for the whole tree, including invoked and spawned children, whose `actorRef` is the child rather than the player.
|
|
83
|
+
|
|
84
|
+
The event types are XState's: `@xstate.actor` when an actor registers, `@xstate.event` when an event is sent, `@xstate.snapshot` after a transition, `@xstate.action` for executed actions, and `@xstate.microstep` for intermediate steps.
|
|
85
|
+
|
|
86
|
+
### The construction caveat
|
|
87
|
+
|
|
88
|
+
`@xstate.actor` fires from _inside_ the actor's constructor. The `actorRef` it carries is a real `PlayerActor`, but a mid-construction one: `state`, `currentRoute`, `currentView` and `initialRoute` do not exist yet, and reading them there throws — XState itself refuses to read a snapshot in that window.
|
|
89
|
+
|
|
90
|
+
```typescript
|
|
91
|
+
const inspect = (event: InspectionEvent) => {
|
|
92
|
+
if (event.type === "@xstate.actor") {
|
|
93
|
+
// ❌ throws — the signals are not assigned yet
|
|
94
|
+
console.log(event.actorRef.currentRoute.get());
|
|
95
|
+
}
|
|
96
|
+
if (event.type === "@xstate.snapshot") {
|
|
97
|
+
// ✅ construction has returned; signals are live
|
|
98
|
+
console.log(event.actorRef.getSnapshot().value);
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Capture the reference during construction if you need it, and read the signals from a later event or from outside the observer entirely.
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## Turning the inspector on later
|
|
108
|
+
|
|
109
|
+
An inspector that is only created when the user asks for it — a dev-tools toggle, a keyboard shortcut, a debug panel button — cannot be passed to `definePlayer`, which ran at module scope long before the click. Pass a forwarding function instead, so the attachment point is fixed at factory time while the destination stays swappable:
|
|
110
|
+
|
|
111
|
+
```typescript
|
|
112
|
+
let current: ((event: InspectionEvent) => void) | undefined;
|
|
113
|
+
|
|
114
|
+
const createPlayer = definePlayer({
|
|
115
|
+
machine: appMachine,
|
|
116
|
+
options: { inspect: (event) => current?.(event) },
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
// Later, from a click handler
|
|
120
|
+
export function enableInspector() {
|
|
121
|
+
const { inspect } = createBrowserInspector();
|
|
122
|
+
current = inspect;
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
This attaches at creation time (so nothing is missed structurally) while forwarding to nothing until the toggle flips.
|
|
127
|
+
|
|
128
|
+
There is a catch worth knowing before you ship it: events that arrive while `current` is undefined are dropped, so an inspector enabled after startup opens on a machine with no registration event and no history — it has nothing to draw until the next transition. If late opening should show the machine as it stands, buffer the events from creation and replay the buffer when the inspector connects. The demo controller described below does exactly that, and is worth reading as a worked example.
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
## Inspecting without a browser
|
|
133
|
+
|
|
134
|
+
`createBrowserInspector` is one transport, not the only one. `@statelyai/inspect` also exports `createWebSocketInspector`, which pairs with `createInspectorServer` from `@statelyai/inspect/server` to stream the same events over a socket — the route to an actor with no browser around it at all, such as one running in a Node process or on the server half of an SSR render:
|
|
135
|
+
|
|
136
|
+
```typescript
|
|
137
|
+
import { createWebSocketInspector } from "@statelyai/inspect";
|
|
138
|
+
|
|
139
|
+
const { inspect } = createWebSocketInspector({ url: "ws://localhost:8080" });
|
|
140
|
+
|
|
141
|
+
const createPlayer = definePlayer({ machine: appMachine, options: { inspect } });
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
Both transports consume the identical `options.inspect` observer, so switching between them touches only the line that creates the inspector. The same is true of an observer you write yourself: a `console.log`, a test spy asserting a transition sequence, or a writer that appends events to a log are all valid `inspect` values, and none of them require the inspect client at all.
|
|
145
|
+
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
## Trying it in the demos
|
|
149
|
+
|
|
150
|
+
Every demo in this repository — all five renderer demos and all eight router demos — wires the inspector the same way, so any of them can be used to see the flow end to end:
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
pnpm --filter @xmachines/play-react-demo run dev
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
Click **Show Inspector** in the debug panel at the bottom of the page. The inspector opens in its own window with the machine already drawn and the session's history replayed, and it keeps updating as you log in, navigate, and log out.
|
|
157
|
+
|
|
158
|
+
The demos share one controller, `createDemoInspector()` from `@xmachines/play-actor-shared`, which each demo passes straight through to `definePlayer`:
|
|
159
|
+
|
|
160
|
+
```typescript
|
|
161
|
+
const inspector = createDemoInspector();
|
|
162
|
+
|
|
163
|
+
const actor = definePlayer({
|
|
164
|
+
machine: authMachine,
|
|
165
|
+
options: { inspect: inspector.inspect },
|
|
166
|
+
})();
|
|
167
|
+
actor.start();
|
|
168
|
+
|
|
169
|
+
// The debug panel's button
|
|
170
|
+
<button onClick={() => inspector.show()}>Show Inspector</button>;
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
The controller answers the late-opening problem from the previous section: it buffers serialized events from actor creation, pins the current root's registration so it can never roll out of the bounded buffer, and flushes the buffer when the inspector window completes its handshake. That is a demo trade-off rather than a general recommendation — every transition pays serialization whether or not anyone ever opens the inspector — but it is what makes the button work at any point in a session. See the [shared demo package README](../../play-actor/examples/shared/README.md) for the design in full.
|
|
174
|
+
|
|
175
|
+
---
|
|
176
|
+
|
|
177
|
+
## Production considerations
|
|
178
|
+
|
|
179
|
+
**Cost.** Inspection serializes events. A `console.log` observer is cheap; a browser inspector posting every transition, and any buffering scheme layered on top, is not. Gate the inspector behind a development-only branch, and prefer letting the bundler drop it entirely:
|
|
180
|
+
|
|
181
|
+
```typescript
|
|
182
|
+
const options = import.meta.env.DEV ? { inspect: createBrowserInspector().inspect } : {};
|
|
183
|
+
|
|
184
|
+
const createPlayer = definePlayer({ machine: appMachine, options });
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
**Data exposure.** Inspection events carry the machine's definition and its context — which in a real application may include user identifiers, tokens, or form input. The browser transport posts that data to the inspector's origin over `postMessage`, and the WebSocket transport sends it to whatever server is listening. Treat an inspector connection as a data egress path: keep it out of production builds, and when inspecting a shared environment, know where the events are going.
|
|
188
|
+
|
|
189
|
+
---
|
|
190
|
+
|
|
191
|
+
## Related documentation
|
|
192
|
+
|
|
193
|
+
- **[`PlayerOptions`](../api/@xmachines/play-xstate/interfaces/PlayerOptions.md)** — the full options bag, `inspect` included
|
|
194
|
+
- **[`PlayerActor`](../api/@xmachines/play-xstate/classes/PlayerActor.md)** — the actor an inspector observes
|
|
195
|
+
- **[Understanding the Actor Model](actor-model.md)** — why the actor is the actor, and what that buys
|
|
196
|
+
- **[Getting Started](getting-started.md)** — installing packages and creating your first actor
|
|
197
|
+
- **[Stately inspect docs](https://stately.ai/docs/inspector)** — the inspector itself, its transports and options
|
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 v5 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,21 +22,18 @@ 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 v5
|
|
26
26
|
|
|
27
|
-
XMachines wraps XState
|
|
27
|
+
XMachines wraps XState v5 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
|
|
31
|
-
import { emptyEventSchema } from "@xmachines/play-xstate";
|
|
30
|
+
import { setup } from "xstate";
|
|
32
31
|
|
|
33
32
|
const authSetup = setup({
|
|
34
|
-
|
|
35
|
-
context:
|
|
36
|
-
events: {
|
|
37
|
-
|
|
38
|
-
"auth.logout": emptyEventSchema,
|
|
39
|
-
},
|
|
33
|
+
types: {
|
|
34
|
+
context: {} as { username: string | null },
|
|
35
|
+
events: {} as { type: "auth.login"; username: string } | { type: "auth.logout" },
|
|
36
|
+
input: {} as undefined,
|
|
40
37
|
},
|
|
41
38
|
});
|
|
42
39
|
|
|
@@ -47,18 +44,20 @@ const authMachine = authSetup.createMachine({
|
|
|
47
44
|
states: {
|
|
48
45
|
unauthenticated: {
|
|
49
46
|
on: {
|
|
50
|
-
"auth.login":
|
|
47
|
+
"auth.login": {
|
|
51
48
|
target: "authenticated",
|
|
52
|
-
|
|
53
|
-
|
|
49
|
+
actions: authSetup.assign({
|
|
50
|
+
username: ({ event }) => event.username,
|
|
51
|
+
}),
|
|
52
|
+
},
|
|
54
53
|
},
|
|
55
54
|
},
|
|
56
55
|
authenticated: {
|
|
57
56
|
on: {
|
|
58
|
-
"auth.logout":
|
|
57
|
+
"auth.logout": {
|
|
59
58
|
target: "unauthenticated",
|
|
60
|
-
|
|
61
|
-
}
|
|
59
|
+
actions: authSetup.assign({ username: null }),
|
|
60
|
+
},
|
|
62
61
|
},
|
|
63
62
|
},
|
|
64
63
|
},
|
|
@@ -67,8 +66,8 @@ const authMachine = authSetup.createMachine({
|
|
|
67
66
|
|
|
68
67
|
Key patterns:
|
|
69
68
|
|
|
70
|
-
- **Always use `setup({
|
|
71
|
-
- **
|
|
69
|
+
- **Always use `setup({ types })`** before `createMachine`. The type declarations let TypeScript check that your events, context fields, and actions are consistent throughout the machine.
|
|
70
|
+
- **Use `setup.assign()`**, not the bare `assign` from xstate. This keeps the type checker aware of which context fields the action touches.
|
|
72
71
|
- **Event names use lowercase dot-separated namespaces**: `"auth.login"`, `"play.route"`, `"form.submit"`. This convention makes the event log readable and avoids collisions.
|
|
73
72
|
|
|
74
73
|
---
|
|
@@ -123,7 +122,9 @@ const appMachine = setup({/* ... */}).createMachine({
|
|
|
123
122
|
|
|
124
123
|
`meta.route` is a string path. When the machine enters a state, `actor.currentRoute` (a `Signal.Computed`) derives this path and emits it. The router bridge reads it and updates the URL.
|
|
125
124
|
|
|
126
|
-
`meta.view` is a [`PlaySpec`](../api/@xmachines/play-actor/interfaces/PlaySpec.md) — a `@xmachines/json-render-core` spec object describing what to render. Use `typedSpec
|
|
125
|
+
`meta.view` is a [`PlaySpec`](../api/@xmachines/play-actor/interfaces/PlaySpec.md) — a `@xmachines/json-render-core` spec object describing what to render. Use `typedSpec(...)` from [`@xmachines/play-actor`](../api/@xmachines/play-actor/README.md) to type-check the spec literal at the definition site (XState's `meta` is untyped). When the machine enters a state, `actor.currentView` is updated with the derived spec. The renderer reads it and projects it through framework components.
|
|
126
|
+
|
|
127
|
+
The machine's whole context is available to every view through the **`/context` projection**: the derived spec's `state` carries `context: <machine context>`. Specs read it with ordinary state expressions — `{ $state: "/context/username" }` in props, `visible` conditions, or `repeat.statePath`. The subtree is **read-only**: context changes only through machine events, and a `$bindState`/`setState` write under `/context` throws. URL data lives at its own paths (`/context/params/…`, `/context/query/…`, written into context by `formatPlayRouteTransitions`), so a URL param can never shadow a machine-owned field. When validating specs with tools like `validateSpec`, validate the **derived** view (`actor.currentView.get()`) — its `state` honestly describes the store contents — not the raw `meta.view`. A context change re-emits the view with the same `viewKey`; providers respond by refreshing `/context` in the live store, not by remounting the UI.
|
|
127
128
|
|
|
128
129
|
**The machine is the single source of truth for both routing and views.** There is no separate route configuration file. There is no switch statement in a component deciding what to render based on the URL. The state machine encodes all of that.
|
|
129
130
|
|
|
@@ -139,8 +140,8 @@ states: {
|
|
|
139
140
|
home: {
|
|
140
141
|
on: {
|
|
141
142
|
"play.route": [
|
|
142
|
-
({ event }) =>
|
|
143
|
-
({ event }) =>
|
|
143
|
+
{ guard: ({ event }) => event.to === "#login", target: "login" },
|
|
144
|
+
{ guard: ({ event }) => event.to === "#dashboard", target: "dashboard" },
|
|
144
145
|
],
|
|
145
146
|
},
|
|
146
147
|
meta: { route: "/" },
|
|
@@ -149,38 +150,34 @@ states: {
|
|
|
149
150
|
}
|
|
150
151
|
```
|
|
151
152
|
|
|
152
|
-
[`formatPlayRouteTransitions`](../api/@xmachines/play-xstate/functions/formatPlayRouteTransitions.md) from [`@xmachines/play-xstate`](../api/@xmachines/play-xstate/README.md)
|
|
153
|
+
[`formatPlayRouteTransitions`](../api/@xmachines/play-xstate/functions/formatPlayRouteTransitions.md) from [`@xmachines/play-xstate`](../api/@xmachines/play-xstate/README.md) generates these transitions automatically from the `id` and `meta.route` fields you already have:
|
|
153
154
|
|
|
154
155
|
```typescript
|
|
155
|
-
import {
|
|
156
|
-
|
|
157
|
-
const
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
},
|
|
167
|
-
|
|
156
|
+
import { formatPlayRouteTransitions } from "@xmachines/play-xstate";
|
|
157
|
+
|
|
158
|
+
const appMachine = setup({/* ... */}).createMachine(
|
|
159
|
+
formatPlayRouteTransitions({
|
|
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
|
+
}),
|
|
168
|
+
);
|
|
168
169
|
```
|
|
169
170
|
|
|
170
|
-
|
|
171
|
+
[`formatPlayRouteTransitions`](../api/@xmachines/play-xstate/functions/formatPlayRouteTransitions.md) inspects all state nodes with a `meta.route` and generates the corresponding `play.route` guard transitions. The machine's context must include `params` and `query` fields (populated by the router bridge when params or query strings are present):
|
|
171
172
|
|
|
172
173
|
```typescript
|
|
173
|
-
|
|
174
|
-
context:
|
|
174
|
+
types: {
|
|
175
|
+
context: {} as {
|
|
175
176
|
params: Record<string, string>;
|
|
176
177
|
query: Record<string, string>;
|
|
177
178
|
// ... other context fields
|
|
178
|
-
}>(),
|
|
179
|
-
events: {
|
|
180
|
-
"play.route": playRouteEventSchema, // exported by @xmachines/play-xstate
|
|
181
|
-
// ... other event schemas
|
|
182
179
|
},
|
|
183
|
-
|
|
180
|
+
events: {} as PlayRouteEvent | OtherEvents,
|
|
184
181
|
}
|
|
185
182
|
```
|
|
186
183
|
|
|
@@ -188,7 +185,7 @@ schemas: {
|
|
|
188
185
|
|
|
189
186
|
## Guards — the actor's authority
|
|
190
187
|
|
|
191
|
-
Guards are the mechanism by which the actor controls whether a transition occurs. They are pure functions of
|
|
188
|
+
Guards are the mechanism by which the actor controls whether a transition occurs. They are pure functions of `{ context, event }` that return a boolean.
|
|
192
189
|
|
|
193
190
|
```typescript
|
|
194
191
|
const authSetup = setup({
|
|
@@ -199,22 +196,11 @@ const authSetup = setup({
|
|
|
199
196
|
});
|
|
200
197
|
```
|
|
201
198
|
|
|
202
|
-
|
|
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.
|
|
199
|
+
Guards are evaluated by XState before a transition fires. If the guard returns `false`, 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.
|
|
214
200
|
|
|
215
201
|
This is the **Actor Authority** invariant in practice: the machine decides, infrastructure adjusts.
|
|
216
202
|
|
|
217
|
-
XMachines provides guard combinators in [`@xmachines/play-xstate`](../api/@xmachines/play-xstate/README.md) for composing complex conditions
|
|
203
|
+
XMachines provides guard combinators in [`@xmachines/play-xstate`](../api/@xmachines/play-xstate/README.md) for composing complex conditions:
|
|
218
204
|
|
|
219
205
|
| Function | What it does |
|
|
220
206
|
| --------------------------------------------------------------------------------------------------- | --------------------------------------- |
|
|
@@ -229,27 +215,27 @@ XMachines provides guard combinators in [`@xmachines/play-xstate`](../api/@xmach
|
|
|
229
215
|
|
|
230
216
|
## Context — persistent state across transitions
|
|
231
217
|
|
|
232
|
-
Context is the machine's persistent data store. It survives transitions and
|
|
218
|
+
Context is the machine's persistent data store. It survives transitions and can be read and updated by actions:
|
|
233
219
|
|
|
234
220
|
```typescript
|
|
235
|
-
// Context is defined in setup({
|
|
236
|
-
|
|
237
|
-
context:
|
|
221
|
+
// Context is defined in setup({ types })
|
|
222
|
+
types: {
|
|
223
|
+
context: {} as {
|
|
238
224
|
isAuthenticated: boolean;
|
|
239
225
|
username: string | null;
|
|
240
226
|
loginAttempts: number;
|
|
241
|
-
}
|
|
227
|
+
},
|
|
242
228
|
},
|
|
243
229
|
|
|
244
|
-
//
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
230
|
+
// Actions mutate context via assign
|
|
231
|
+
actions: {
|
|
232
|
+
recordLoginFailure: assign({
|
|
233
|
+
loginAttempts: ({ context }) => context.loginAttempts + 1,
|
|
248
234
|
}),
|
|
249
235
|
},
|
|
250
236
|
```
|
|
251
237
|
|
|
252
|
-
Context is accessed in guards,
|
|
238
|
+
Context is accessed in guards, actions, 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`.
|
|
253
239
|
|
|
254
240
|
---
|
|
255
241
|
|
|
@@ -296,5 +282,5 @@ actor.start();
|
|
|
296
282
|
- [Getting Started](getting-started.md) — step-by-step walkthrough building your first machine and actor
|
|
297
283
|
- [Routing Patterns](../examples/routing-patterns.md) — worked examples of `meta.route` and guards
|
|
298
284
|
- [@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
|
|
299
|
-
- [XState documentation](https://stately.ai/docs/xstate) — upstream state machine library documentation
|
|
285
|
+
- [XState v5 documentation](https://stately.ai/docs/xstate) — upstream state machine library documentation
|
|
300
286
|
- [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": "2.0.0
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "Documentation for XMachines",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"documentation",
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"author": "Mikael Karon <mikael@karon.se>",
|
|
16
16
|
"repository": {
|
|
17
17
|
"type": "git",
|
|
18
|
-
"url": "git+
|
|
18
|
+
"url": "git+https://gitlab.com/xmachin-es/xmachines-js.git",
|
|
19
19
|
"directory": "packages/docs"
|
|
20
20
|
},
|
|
21
21
|
"files": [
|
|
@@ -28,6 +28,7 @@
|
|
|
28
28
|
"index.d.ts"
|
|
29
29
|
],
|
|
30
30
|
"type": "module",
|
|
31
|
+
"sideEffects": false,
|
|
31
32
|
"exports": {
|
|
32
33
|
".": {
|
|
33
34
|
"types": "./index.d.ts",
|
|
@@ -53,13 +54,15 @@
|
|
|
53
54
|
},
|
|
54
55
|
"devDependencies": {
|
|
55
56
|
"@testing-library/jest-dom": "^6.9.1",
|
|
56
|
-
"@types/node": "^26.
|
|
57
|
-
"
|
|
58
|
-
"
|
|
59
|
-
"oxlint": "^1.73.0",
|
|
57
|
+
"@types/node": "^26.2.0",
|
|
58
|
+
"oxfmt": "^0.64.0",
|
|
59
|
+
"oxlint": "^1.79.0",
|
|
60
60
|
"typedoc": "^0.28.19",
|
|
61
61
|
"typedoc-plugin-llms-txt": "^0.1.2",
|
|
62
62
|
"typedoc-plugin-markdown": "^4.11.0",
|
|
63
|
-
"vitest": "^4.1.
|
|
63
|
+
"vitest": "^4.1.11"
|
|
64
|
+
},
|
|
65
|
+
"engines": {
|
|
66
|
+
"node": ">=22.0.0"
|
|
64
67
|
}
|
|
65
68
|
}
|
package/rfc/play.md
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
|
|
12
12
|
This RFC defines the **Universal Player Architecture** and its reference implementation. The architecture establishes a design pattern that strictly separates **Business Logic (The Actor)** from **Infrastructure (The Runtime Adapter and View)**.
|
|
13
13
|
|
|
14
|
-
The reference implementation provides a modular monorepo that satisfies the architectural constraints of **Runtime Agnosticism** and **Logic-Driven Guarding**. It leverages **Standardized Signals (TC39)** to glue a specific **State Engine (XState
|
|
14
|
+
The reference implementation provides a modular monorepo that satisfies the architectural constraints of **Runtime Agnosticism** and **Logic-Driven Guarding**. It leverages **Standardized Signals (TC39)** to glue a specific **State Engine (XState v5)** to multiple **Runtime Adapters** (TanStack Router, React Router, Vue Router, SolidJS Router) and **View Layers** (React, Vue, SolidJS, Vanilla DOM — all via JSON-Render), while ensuring that **business logic remains the single source of truth** for navigation, state, and UI structure.
|
|
15
15
|
|
|
16
16
|
---
|
|
17
17
|
|
|
@@ -153,7 +153,16 @@ export interface Routable {
|
|
|
153
153
|
|
|
154
154
|
// Optional capability: View rendering
|
|
155
155
|
export interface PlaySpec extends Spec {
|
|
156
|
-
|
|
156
|
+
// The machine's whole context is projected into the derived view's state
|
|
157
|
+
// under the read-only /context subtree; specs read it via
|
|
158
|
+
// { $state: "/context/…" } in props, visible conditions, and
|
|
159
|
+
// repeat.statePath. /context never accepts writes — machine context
|
|
160
|
+
// changes only through events.
|
|
161
|
+
//
|
|
162
|
+
// Stamped by view derivation from the selected meta entry (never
|
|
163
|
+
// authored): providers key their store lifecycle on it — changed key
|
|
164
|
+
// reseeds the store, unchanged key refreshes /context in place.
|
|
165
|
+
viewKey?: string;
|
|
157
166
|
}
|
|
158
167
|
|
|
159
168
|
export interface Viewable {
|
|
@@ -183,9 +192,9 @@ export abstract class AbstractActor<
|
|
|
183
192
|
|
|
184
193
|
#### 5.2.1 `@xmachines/play-xstate`
|
|
185
194
|
|
|
186
|
-
**Role:** Concrete Logic Adapter (XState
|
|
195
|
+
**Role:** Concrete Logic Adapter (XState v5)
|
|
187
196
|
|
|
188
|
-
Wraps XState
|
|
197
|
+
Wraps XState v5 to satisfy the `AbstractActor` contract. Provides the primary API for creating actors from state machine definitions.
|
|
189
198
|
|
|
190
199
|
**Primary Exports:**
|
|
191
200
|
|
|
@@ -387,13 +396,13 @@ Defines **Logic**. No framework code. No routing library imports.
|
|
|
387
396
|
import { setup } from "xstate";
|
|
388
397
|
import { definePlayer } from "@xmachines/play-xstate";
|
|
389
398
|
|
|
390
|
-
export const machine = setup({/*
|
|
399
|
+
export const machine = setup({/* types, guards, actions */}).createMachine({
|
|
391
400
|
initial: "overview",
|
|
392
401
|
states: {
|
|
393
402
|
overview: {
|
|
394
403
|
meta: {
|
|
395
404
|
route: "/dashboard",
|
|
396
|
-
view: typedSpec
|
|
405
|
+
view: typedSpec({
|
|
397
406
|
root: "root",
|
|
398
407
|
elements: {
|
|
399
408
|
root: {
|
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
[API](../../../README.md) / [@xmachines/play-xstate](../README.md) / createRoutedMachine
|
|
2
|
-
|
|
3
|
-
# Function: createRoutedMachine()
|
|
4
|
-
|
|
5
|
-
```ts
|
|
6
|
-
function createRoutedMachine<TSetup>(s): TSetup["createMachine"];
|
|
7
|
-
```
|
|
8
|
-
|
|
9
|
-
Defined in: [packages/play-xstate/src/routing/create-routed-machine.ts:78](https://gitlab.com/xmachin-es/xmachines-js/-/blob/v2.0.0-alpha.1/packages/play-xstate/src/routing/create-routed-machine.ts#L78)
|
|
10
|
-
|
|
11
|
-
Returns a `createMachine` that routes: identical signature to the setup's
|
|
12
|
-
own `createMachine`, with [formatPlayRouteTransitions](formatPlayRouteTransitions.md) applied to the
|
|
13
|
-
config at runtime.
|
|
14
|
-
|
|
15
|
-
### Why this exists
|
|
16
|
-
|
|
17
|
-
`formatPlayRouteTransitions(config)` accepts a loosely-typed config. A config
|
|
18
|
-
authored as a standalone value loses inline transition-function parameter
|
|
19
|
-
inference entirely (implicit-any under strict mode), and even the inline
|
|
20
|
-
`setup().createMachine(formatPlayRouteTransitions({ ... }))` form depends on
|
|
21
|
-
TypeScript threading contextual typing through two generic calls.
|
|
22
|
-
|
|
23
|
-
This wrapper removes the question: it is typed as the setup's own
|
|
24
|
-
`createMachine`, so the config is contextually typed exactly as if passed to
|
|
25
|
-
`setup().createMachine(...)` directly — transition-function args infer from
|
|
26
|
-
the setup's schemas, sibling targets are validated, and the returned machine
|
|
27
|
-
keeps its full literal state-value typing.
|
|
28
|
-
|
|
29
|
-
Typing is _identical to native_ — including its current gaps: as of xstate
|
|
30
|
-
6.0.0-alpha.20, `event` and `context` reads in transition args are fully
|
|
31
|
-
typed, while returned context patches are property-typed but still carry a
|
|
32
|
-
loose index signature in the alpha itself. Expect that to tighten upstream
|
|
33
|
-
without changes here.
|
|
34
|
-
|
|
35
|
-
## Type Parameters
|
|
36
|
-
|
|
37
|
-
| Type Parameter |
|
|
38
|
-
| -------------------------------------------------------------- |
|
|
39
|
-
| `TSetup` _extends_ [`SetupLike`](../type-aliases/SetupLike.md) |
|
|
40
|
-
|
|
41
|
-
## Parameters
|
|
42
|
-
|
|
43
|
-
| Parameter | Type | Description |
|
|
44
|
-
| --------- | -------- | ------------------------------------------------------------ |
|
|
45
|
-
| `s` | `TSetup` | A `setup(...)` return value (anything with `createMachine`). |
|
|
46
|
-
|
|
47
|
-
## Returns
|
|
48
|
-
|
|
49
|
-
`TSetup`\[`"createMachine"`\]
|
|
50
|
-
|
|
51
|
-
A function with the same signature as `s.createMachine` that
|
|
52
|
-
applies [formatPlayRouteTransitions](formatPlayRouteTransitions.md) before creating the machine.
|
|
53
|
-
|
|
54
|
-
## Example
|
|
55
|
-
|
|
56
|
-
```typescript
|
|
57
|
-
import { setup, types } from "xstate";
|
|
58
|
-
import { createRoutedMachine, playMetaSchema, playRouteEventSchema } from "@xmachines/play-xstate";
|
|
59
|
-
|
|
60
|
-
const authSetup = setup({
|
|
61
|
-
schemas: {
|
|
62
|
-
context: types<{ isAuthenticated: boolean }>(),
|
|
63
|
-
events: { "play.route": playRouteEventSchema },
|
|
64
|
-
meta: playMetaSchema,
|
|
65
|
-
},
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
const machine = createRoutedMachine(authSetup)({
|
|
69
|
-
initial: "home",
|
|
70
|
-
context: { isAuthenticated: false },
|
|
71
|
-
states: {
|
|
72
|
-
home: { id: "home", meta: { route: "/" } },
|
|
73
|
-
login: { id: "login", meta: { route: "/login" } },
|
|
74
|
-
},
|
|
75
|
-
});
|
|
76
|
-
// ({ context }) params in transitions infer from the setup schemas —
|
|
77
|
-
// no explicit annotations needed.
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
Note: routes are injected at runtime, so the machine's static type does not
|
|
81
|
-
gain an `xstate.route` event for them — `play.route` (declared in the
|
|
82
|
-
setup's event schemas) remains the typed public API; native `xstate.route`
|
|
83
|
-
interop is runtime-only.
|
|
84
|
-
|
|
85
|
-
## See
|
|
86
|
-
|
|
87
|
-
[formatPlayRouteTransitions](formatPlayRouteTransitions.md) for the routing transform itself
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
[API](../../../README.md) / [@xmachines/play-xstate](../README.md) / PlayRoutePayload
|
|
2
|
-
|
|
3
|
-
# Type Alias: PlayRoutePayload
|
|
4
|
-
|
|
5
|
-
```ts
|
|
6
|
-
type PlayRoutePayload = WithOptional<
|
|
7
|
-
WithOptional<
|
|
8
|
-
WithOptional<
|
|
9
|
-
{
|
|
10
|
-
to: PlayRouteEvent["to"];
|
|
11
|
-
},
|
|
12
|
-
{
|
|
13
|
-
params: Record<string, string>;
|
|
14
|
-
}
|
|
15
|
-
>,
|
|
16
|
-
{
|
|
17
|
-
query: Record<string, string>;
|
|
18
|
-
}
|
|
19
|
-
>,
|
|
20
|
-
{
|
|
21
|
-
match: unknown;
|
|
22
|
-
}
|
|
23
|
-
>;
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
Defined in: [packages/play-xstate/src/routing/schemas.ts:62](https://gitlab.com/xmachin-es/xmachines-js/-/blob/v2.0.0-alpha.1/packages/play-xstate/src/routing/schemas.ts#L62)
|
|
27
|
-
|
|
28
|
-
The `play.route` event payload as machines receive it: `to` required;
|
|
29
|
-
`params`/`query`/`match` encoded as optional-by-union so they stay omittable
|
|
30
|
-
through XState v6's `Required<>` event inference.
|