@xmachines/docs 2.0.0-alpha.1 → 2.1.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 +16 -17
- package/api/@xmachines/play/README.md +58 -66
- package/api/@xmachines/play/classes/NonNullableError.md +14 -14
- package/api/@xmachines/play/classes/PlayError.md +32 -34
- package/api/@xmachines/play/functions/assertNonNullable.md +17 -17
- package/api/@xmachines/play/type-aliases/PlayEvent.md +28 -27
- package/api/@xmachines/play-actor/README.md +114 -50
- package/api/@xmachines/play-actor/classes/AbstractActor.md +45 -30
- package/api/@xmachines/play-actor/functions/attachRenderErrorHandler.md +19 -18
- package/api/@xmachines/play-actor/functions/composePlayState.md +27 -0
- package/api/@xmachines/play-actor/functions/createViewStoreLifecycle.md +21 -0
- package/api/@xmachines/play-actor/functions/guardContextWrites.md +43 -0
- package/api/@xmachines/play-actor/functions/refreshContextSubtree.md +28 -0
- package/api/@xmachines/play-actor/functions/reuseComposedState.md +42 -0
- package/api/@xmachines/play-actor/functions/shallowEqualExcept.md +29 -0
- package/api/@xmachines/play-actor/functions/toAtomState.md +16 -14
- package/api/@xmachines/play-actor/functions/typedSpec.md +25 -27
- package/api/@xmachines/play-actor/interfaces/BaseActorProviderProps.md +17 -15
- package/api/@xmachines/play-actor/interfaces/BaseViewContextValue.md +15 -14
- package/api/@xmachines/play-actor/interfaces/PlaySpec.md +13 -15
- package/api/@xmachines/play-actor/interfaces/ResolveViewStoreOptions.md +11 -0
- package/api/@xmachines/play-actor/interfaces/Routable.md +6 -6
- 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 +9 -9
- package/api/@xmachines/play-actor/variables/CONTEXT_STATE_KEY.md +15 -0
- package/api/@xmachines/play-dom/README.md +123 -86
- package/api/@xmachines/play-dom/classes/PlayRenderer.md +34 -32
- package/api/@xmachines/play-dom/functions/createPlayUI.md +10 -10
- package/api/@xmachines/play-dom/functions/createRenderer.md +21 -17
- 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 +16 -16
- 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 +9 -9
- package/api/@xmachines/play-dom/interfaces/PlayDomOptions.md +17 -17
- 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 +5 -5
- package/api/@xmachines/play-dom/variables/schema.md +35 -45
- package/api/@xmachines/play-dom-router/README.md +68 -51
- package/api/@xmachines/play-dom-router/classes/DomRouterBridge.md +116 -0
- package/api/@xmachines/play-dom-router/functions/connectRouter.md +4 -3
- package/api/@xmachines/play-dom-router/functions/createBrowserHistory.md +16 -14
- package/api/@xmachines/play-dom-router/functions/createRouteMap.md +12 -11
- package/api/@xmachines/play-dom-router/functions/createRouter.md +14 -14
- package/api/@xmachines/play-dom-router/interfaces/BrowserHistory.md +25 -26
- package/api/@xmachines/play-dom-router/interfaces/BrowserWindow.md +21 -20
- package/api/@xmachines/play-dom-router/interfaces/ConnectRouterOptions.md +7 -7
- package/api/@xmachines/play-dom-router/interfaces/PlayRouteEvent.md +41 -35
- package/api/@xmachines/play-dom-router/interfaces/RoutableActor.md +18 -17
- package/api/@xmachines/play-dom-router/interfaces/RouteLookupContract.md +9 -9
- package/api/@xmachines/play-dom-router/interfaces/RouteMap.md +39 -38
- package/api/@xmachines/play-dom-router/interfaces/RouteMapOptions.md +5 -5
- package/api/@xmachines/play-dom-router/interfaces/RouteMapping.md +11 -10
- package/api/@xmachines/play-dom-router/interfaces/RouterBridge.md +27 -24
- package/api/@xmachines/play-dom-router/interfaces/VanillaRouter.md +7 -7
- package/api/@xmachines/play-react/README.md +65 -55
- package/api/@xmachines/play-react/classes/PlayErrorBoundary.md +14 -13
- 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 +4 -4
- package/api/@xmachines/play-react/functions/useSignalEffect.md +39 -39
- package/api/@xmachines/play-react/interfaces/ActorProviderProps.md +11 -11
- package/api/@xmachines/play-react/interfaces/ComponentContext.md +9 -8
- package/api/@xmachines/play-react/interfaces/PlayErrorBoundaryProps.md +7 -7
- package/api/@xmachines/play-react/interfaces/PlayErrorBoundaryState.md +6 -6
- package/api/@xmachines/play-react/interfaces/PlayUIProviderProps.md +14 -14
- package/api/@xmachines/play-react/interfaces/ViewContextValue.md +8 -8
- package/api/@xmachines/play-react/type-aliases/AnyPlayActor.md +2 -2
- package/api/@xmachines/play-react/type-aliases/PlayRendererProps.md +13 -0
- package/api/@xmachines/play-react/variables/ActorProvider.md +9 -8
- package/api/@xmachines/play-react/variables/PlayRenderer.md +5 -4
- package/api/@xmachines/play-react/variables/PlayUIProvider.md +6 -6
- package/api/@xmachines/play-react-router/README.md +38 -31
- package/api/@xmachines/play-react-router/classes/ReactRouterBridge.md +22 -19
- package/api/@xmachines/play-react-router/classes/RouteMap.md +50 -48
- package/api/@xmachines/play-react-router/functions/createPlayRouterProvider.md +16 -14
- package/api/@xmachines/play-react-router/functions/createRouteMap.md +12 -11
- package/api/@xmachines/play-react-router/functions/createRouteMapFromTree.md +18 -18
- package/api/@xmachines/play-react-router/interfaces/PlayActor.md +22 -20
- package/api/@xmachines/play-react-router/interfaces/PlayRouteEvent.md +41 -35
- package/api/@xmachines/play-react-router/interfaces/PlayRouterProviderBaseProps.md +12 -12
- package/api/@xmachines/play-react-router/interfaces/PlayRouterProviderProps.md +11 -11
- package/api/@xmachines/play-react-router/interfaces/RouteMapOptions.md +5 -5
- package/api/@xmachines/play-react-router/interfaces/RouteMapping.md +11 -10
- package/api/@xmachines/play-react-router/interfaces/RouterBridge.md +27 -24
- package/api/@xmachines/play-react-router/type-aliases/PlayRouterBridgeConstructor.md +2 -2
- package/api/@xmachines/play-react-router/variables/PlayRouterProvider.md +7 -6
- package/api/@xmachines/play-router/README.md +99 -95
- package/api/@xmachines/play-router/classes/RouteMap.md +50 -48
- package/api/@xmachines/play-router/classes/RouterBridgeBase.md +29 -23
- package/api/@xmachines/play-router/functions/buildPlayRouteEvent.md +6 -5
- package/api/@xmachines/play-router/functions/buildRouteTree.md +16 -15
- package/api/@xmachines/play-router/functions/createRouteMap.md +12 -11
- package/api/@xmachines/play-router/functions/createRouteMapFromTree.md +18 -18
- package/api/@xmachines/play-router/functions/detectDuplicateRoutes.md +18 -17
- package/api/@xmachines/play-router/functions/extractMachineRoutes.md +11 -10
- package/api/@xmachines/play-router/functions/extractQuery.md +3 -3
- package/api/@xmachines/play-router/functions/extractRouteParams.md +22 -19
- package/api/@xmachines/play-router/functions/findRouteById.md +10 -9
- package/api/@xmachines/play-router/functions/findRouteByPath.md +14 -12
- package/api/@xmachines/play-router/functions/getNavigableRoutes.md +9 -9
- package/api/@xmachines/play-router/functions/getRoutableRoutes.md +9 -9
- package/api/@xmachines/play-router/functions/getTransitionReachableRoutes.md +16 -15
- package/api/@xmachines/play-router/functions/isRouteReachable.md +12 -11
- package/api/@xmachines/play-router/functions/machineToGraph.md +1 -1
- package/api/@xmachines/play-router/functions/routeExists.md +8 -8
- package/api/@xmachines/play-router/functions/sanitizePathname.md +15 -13
- package/api/@xmachines/play-router/functions/validateRouteFormat.md +10 -10
- package/api/@xmachines/play-router/functions/validateStateExists.md +9 -9
- package/api/@xmachines/play-router/interfaces/BuildPlayRouteEventOptions.md +6 -6
- package/api/@xmachines/play-router/interfaces/LocationLike.md +11 -11
- package/api/@xmachines/play-router/interfaces/MachineEdgeData.md +7 -9
- package/api/@xmachines/play-router/interfaces/MachineNodeData.md +9 -9
- package/api/@xmachines/play-router/interfaces/PlayActor.md +22 -20
- package/api/@xmachines/play-router/interfaces/PlayRouteEvent.md +41 -35
- package/api/@xmachines/play-router/interfaces/ResolvedRoutePath.md +7 -7
- package/api/@xmachines/play-router/interfaces/RoutableActor.md +18 -17
- package/api/@xmachines/play-router/interfaces/RouteInfo.md +11 -11
- package/api/@xmachines/play-router/interfaces/RouteMapOptions.md +5 -5
- package/api/@xmachines/play-router/interfaces/RouteMapping.md +11 -10
- package/api/@xmachines/play-router/interfaces/RouteMatch.md +5 -5
- package/api/@xmachines/play-router/interfaces/RouteNode.md +13 -13
- package/api/@xmachines/play-router/interfaces/RouteObject.md +6 -6
- package/api/@xmachines/play-router/interfaces/RouteTree.md +11 -11
- package/api/@xmachines/play-router/interfaces/RouteWatcherHandle.md +13 -13
- package/api/@xmachines/play-router/interfaces/RouterBridge.md +27 -24
- package/api/@xmachines/play-router/interfaces/WindowLike.md +10 -10
- package/api/@xmachines/play-router/type-aliases/BaseRouteMapping.md +13 -0
- package/api/@xmachines/play-router/type-aliases/MachineGraph.md +4 -3
- package/api/@xmachines/play-router/type-aliases/RouteMetadata.md +2 -2
- package/api/@xmachines/play-signals/README.md +38 -36
- package/api/@xmachines/play-signals/functions/watchSignal.md +15 -15
- package/api/@xmachines/play-signals/interfaces/ComputedOptions.md +6 -6
- package/api/@xmachines/play-signals/interfaces/SignalComputed.md +10 -10
- package/api/@xmachines/play-signals/interfaces/SignalOptions.md +6 -6
- package/api/@xmachines/play-signals/interfaces/SignalState.md +13 -13
- package/api/@xmachines/play-signals/interfaces/SignalWatcher.md +18 -18
- package/api/@xmachines/play-signals/type-aliases/WatcherNotify.md +6 -5
- package/api/@xmachines/play-solid/README.md +46 -42
- package/api/@xmachines/play-solid/functions/useActor.md +1 -1
- package/api/@xmachines/play-solid/functions/usePlayView.md +3 -3
- package/api/@xmachines/play-solid/interfaces/ActorProviderProps.md +13 -13
- package/api/@xmachines/play-solid/interfaces/PlayUIProviderProps.md +14 -14
- package/api/@xmachines/play-solid/interfaces/ViewContextValue.md +9 -9
- package/api/@xmachines/play-solid/type-aliases/AnyPlayActor.md +2 -2
- package/api/@xmachines/play-solid/variables/ActorContext.md +5 -4
- package/api/@xmachines/play-solid/variables/ActorProvider.md +8 -7
- package/api/@xmachines/play-solid/variables/PlayRenderer.md +6 -4
- package/api/@xmachines/play-solid/variables/PlayUIProvider.md +7 -7
- package/api/@xmachines/play-solid-router/README.md +39 -34
- package/api/@xmachines/play-solid-router/classes/RouteMap.md +50 -48
- package/api/@xmachines/play-solid-router/classes/SolidRouterBridge.md +43 -34
- package/api/@xmachines/play-solid-router/functions/createPlayRouterProvider.md +15 -13
- package/api/@xmachines/play-solid-router/functions/createRouteMap.md +12 -11
- package/api/@xmachines/play-solid-router/interfaces/AbstractActor.md +45 -30
- package/api/@xmachines/play-solid-router/interfaces/PlayActor.md +22 -20
- package/api/@xmachines/play-solid-router/interfaces/PlayRouteEvent.md +41 -35
- package/api/@xmachines/play-solid-router/interfaces/PlayRouterProviderBaseProps.md +10 -10
- package/api/@xmachines/play-solid-router/interfaces/PlayRouterProviderProps.md +11 -11
- package/api/@xmachines/play-solid-router/interfaces/RouteMapOptions.md +5 -5
- package/api/@xmachines/play-solid-router/interfaces/RouteMapping.md +11 -10
- package/api/@xmachines/play-solid-router/interfaces/RouterBridge.md +27 -24
- package/api/@xmachines/play-solid-router/type-aliases/PlayRouterBridgeConstructor.md +5 -5
- package/api/@xmachines/play-solid-router/type-aliases/RoutableActor.md +2 -2
- package/api/@xmachines/play-solid-router/type-aliases/SolidRouterHooks.md +11 -11
- package/api/@xmachines/play-solid-router/variables/PlayRouterProvider.md +9 -8
- package/api/@xmachines/play-svelte/README.md +60 -33
- package/api/@xmachines/play-svelte/functions/defineRegistry.md +9 -8
- package/api/@xmachines/play-svelte/functions/getActorContext.md +5 -4
- package/api/@xmachines/play-svelte/functions/getPlayViewContext.md +3 -3
- package/api/@xmachines/play-svelte/functions/setActorContext.md +1 -1
- package/api/@xmachines/play-svelte/interfaces/ActorProviderProps.md +17 -15
- package/api/@xmachines/play-svelte/interfaces/DefineRegistryOptions.md +9 -9
- package/api/@xmachines/play-svelte/interfaces/PlayUIProviderProps.md +20 -18
- package/api/@xmachines/play-svelte/interfaces/ViewContextValue.md +12 -11
- package/api/@xmachines/play-svelte/type-aliases/AnyPlayActor.md +2 -2
- package/api/@xmachines/play-svelte-spa-router/README.md +43 -52
- package/api/@xmachines/play-svelte-spa-router/classes/RouteMap.md +50 -48
- package/api/@xmachines/play-svelte-spa-router/classes/SvelteSpaRouterBridge.md +133 -0
- package/api/@xmachines/play-svelte-spa-router/functions/connectRouter.md +3 -3
- package/api/@xmachines/play-svelte-spa-router/functions/createRouteMap.md +12 -11
- package/api/@xmachines/play-svelte-spa-router/interfaces/ConnectRouterOptions.md +7 -7
- package/api/@xmachines/play-svelte-spa-router/interfaces/PlayRouteEvent.md +41 -35
- package/api/@xmachines/play-svelte-spa-router/interfaces/RouteMapOptions.md +5 -5
- package/api/@xmachines/play-svelte-spa-router/interfaces/RouteMapping.md +11 -10
- package/api/@xmachines/play-svelte-spa-router/interfaces/RouterBridge.md +27 -24
- package/api/@xmachines/play-svelte-spa-router/interfaces/WindowLike.md +10 -10
- package/api/@xmachines/play-svelte-spa-router/type-aliases/RoutableActor.md +1 -1
- package/api/@xmachines/play-sveltekit-router/README.md +43 -39
- package/api/@xmachines/play-sveltekit-router/classes/RouteMap.md +50 -48
- package/api/@xmachines/play-sveltekit-router/classes/SvelteKitRouterBridge.md +132 -0
- package/api/@xmachines/play-sveltekit-router/functions/connectRouter.md +3 -3
- package/api/@xmachines/play-sveltekit-router/functions/createRouteMap.md +12 -11
- package/api/@xmachines/play-sveltekit-router/interfaces/ConnectRouterOptions.md +6 -6
- package/api/@xmachines/play-sveltekit-router/interfaces/LocationLike.md +11 -11
- package/api/@xmachines/play-sveltekit-router/interfaces/PlayRouteEvent.md +41 -35
- package/api/@xmachines/play-sveltekit-router/interfaces/RouteMapOptions.md +5 -5
- package/api/@xmachines/play-sveltekit-router/interfaces/RouteMapping.md +11 -10
- package/api/@xmachines/play-sveltekit-router/interfaces/RouterBridge.md +27 -24
- package/api/@xmachines/play-sveltekit-router/type-aliases/RoutableActor.md +1 -1
- package/api/@xmachines/play-tanstack-react-router/README.md +67 -49
- package/api/@xmachines/play-tanstack-react-router/classes/RouteMap.md +50 -48
- package/api/@xmachines/play-tanstack-react-router/classes/TanStackReactRouterBridge.md +43 -38
- package/api/@xmachines/play-tanstack-react-router/functions/createPlayRouterProvider.md +16 -14
- package/api/@xmachines/play-tanstack-react-router/functions/createRouteMap.md +12 -11
- package/api/@xmachines/play-tanstack-react-router/functions/createRouteMapFromTree.md +18 -18
- package/api/@xmachines/play-tanstack-react-router/functions/extractMachineRoutes.md +11 -10
- package/api/@xmachines/play-tanstack-react-router/interfaces/PlayActor.md +22 -20
- package/api/@xmachines/play-tanstack-react-router/interfaces/PlayRouteEvent.md +41 -35
- package/api/@xmachines/play-tanstack-react-router/interfaces/PlayRouterProviderBaseProps.md +12 -12
- package/api/@xmachines/play-tanstack-react-router/interfaces/PlayRouterProviderProps.md +11 -11
- package/api/@xmachines/play-tanstack-react-router/interfaces/RouteMapOptions.md +5 -5
- package/api/@xmachines/play-tanstack-react-router/interfaces/RouteMapping.md +11 -10
- package/api/@xmachines/play-tanstack-react-router/interfaces/RouteNavigateEvent.md +16 -11
- package/api/@xmachines/play-tanstack-react-router/interfaces/RouterBridge.md +27 -24
- package/api/@xmachines/play-tanstack-react-router/type-aliases/PlayRouterBridgeConstructor.md +2 -2
- package/api/@xmachines/play-tanstack-react-router/type-aliases/TanStackRouterInstance.md +1 -1
- package/api/@xmachines/play-tanstack-react-router/type-aliases/TanStackRouterLike.md +15 -13
- package/api/@xmachines/play-tanstack-react-router/variables/PlayRouterProvider.md +9 -8
- package/api/@xmachines/play-tanstack-router/README.md +38 -16
- package/api/@xmachines/play-tanstack-router/classes/TanStackRouterBridgeBase.md +43 -38
- package/api/@xmachines/play-tanstack-router/type-aliases/TanStackRouteMapLike.md +9 -9
- package/api/@xmachines/play-tanstack-router/type-aliases/TanStackRouterLike.md +15 -13
- package/api/@xmachines/play-tanstack-solid-router/README.md +76 -50
- package/api/@xmachines/play-tanstack-solid-router/classes/RouteMap.md +50 -48
- package/api/@xmachines/play-tanstack-solid-router/classes/TanStackSolidRouterBridge.md +38 -30
- package/api/@xmachines/play-tanstack-solid-router/functions/createPlayRouterProvider.md +15 -13
- package/api/@xmachines/play-tanstack-solid-router/functions/createRouteMap.md +12 -11
- package/api/@xmachines/play-tanstack-solid-router/interfaces/PlayActor.md +22 -20
- package/api/@xmachines/play-tanstack-solid-router/interfaces/PlayRouteEvent.md +41 -35
- package/api/@xmachines/play-tanstack-solid-router/interfaces/PlayRouterProviderBaseProps.md +11 -11
- package/api/@xmachines/play-tanstack-solid-router/interfaces/PlayRouterProviderProps.md +9 -9
- package/api/@xmachines/play-tanstack-solid-router/interfaces/RouteMapOptions.md +5 -5
- package/api/@xmachines/play-tanstack-solid-router/interfaces/RouteMapping.md +11 -10
- package/api/@xmachines/play-tanstack-solid-router/interfaces/RouterBridge.md +27 -24
- package/api/@xmachines/play-tanstack-solid-router/type-aliases/PlayRouterBridgeConstructor.md +2 -2
- package/api/@xmachines/play-tanstack-solid-router/type-aliases/RoutableActor.md +2 -2
- package/api/@xmachines/play-tanstack-solid-router/type-aliases/TanStackRouterInstance.md +1 -1
- package/api/@xmachines/play-tanstack-solid-router/type-aliases/TanStackRouterLike.md +15 -13
- package/api/@xmachines/play-tanstack-solid-router/variables/PlayRouterProvider.md +7 -7
- package/api/@xmachines/play-vue/README.md +39 -39
- package/api/@xmachines/play-vue/functions/defineRegistry.md +10 -9
- 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/functions/usePlayView.md +28 -0
- package/api/@xmachines/play-vue/interfaces/ActorProviderProps.md +10 -9
- package/api/@xmachines/play-vue/interfaces/PlayUIProviderProps.md +13 -12
- package/api/@xmachines/play-vue/interfaces/ViewContextValue.md +10 -9
- package/api/@xmachines/play-vue/interfaces/VisibilityProviderProps.md +6 -2
- package/api/@xmachines/play-vue/type-aliases/AnyPlayActor.md +2 -2
- 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/variables/getPlayViewContext.md +34 -0
- package/api/@xmachines/play-vue-router/README.md +66 -57
- package/api/@xmachines/play-vue-router/classes/RouteMap.md +50 -48
- package/api/@xmachines/play-vue-router/classes/VueRouterBridge.md +26 -19
- package/api/@xmachines/play-vue-router/functions/createRouteMap.md +12 -11
- package/api/@xmachines/play-vue-router/interfaces/PlayActor.md +22 -20
- package/api/@xmachines/play-vue-router/interfaces/PlayRouteEvent.md +41 -35
- package/api/@xmachines/play-vue-router/interfaces/RouteMapOptions.md +5 -5
- package/api/@xmachines/play-vue-router/interfaces/RouteMapping.md +11 -10
- package/api/@xmachines/play-vue-router/interfaces/RouterBridge.md +27 -24
- package/api/@xmachines/play-vue-router/type-aliases/RoutableActor.md +2 -2
- package/api/@xmachines/play-vue-router/type-aliases/VueRouteMap.md +13 -0
- package/api/@xmachines/play-vue-router/variables/PlayRouterProvider.md +5 -5
- package/api/@xmachines/play-vue-router/variables/VueRouteMap.md +13 -0
- package/api/@xmachines/play-xstate/README.md +129 -138
- package/api/@xmachines/play-xstate/classes/PlayerActor.md +148 -114
- package/api/@xmachines/play-xstate/functions/buildRouteUrl.md +19 -23
- package/api/@xmachines/play-xstate/functions/composeGuards.md +34 -33
- package/api/@xmachines/play-xstate/functions/composeGuardsOr.md +27 -22
- package/api/@xmachines/play-xstate/functions/contextFieldMatches.md +19 -14
- package/api/@xmachines/play-xstate/functions/definePlayer.md +19 -19
- package/api/@xmachines/play-xstate/functions/deriveRoute.md +26 -25
- package/api/@xmachines/play-xstate/functions/eventMatches.md +12 -7
- package/api/@xmachines/play-xstate/functions/formatPlayRouteTransitions.md +17 -48
- package/api/@xmachines/play-xstate/functions/hasContext.md +12 -9
- package/api/@xmachines/play-xstate/functions/isAbsoluteRoute.md +10 -10
- package/api/@xmachines/play-xstate/functions/negateGuard.md +26 -20
- package/api/@xmachines/play-xstate/interfaces/PlayerConfig.md +6 -6
- package/api/@xmachines/play-xstate/interfaces/PlayerFactoryResumeOptions.md +7 -7
- package/api/@xmachines/play-xstate/interfaces/PlayerOptions.md +10 -11
- package/api/@xmachines/play-xstate/interfaces/RouteContext.md +15 -14
- 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 +13 -11
- package/api/@xmachines/play-xstate/type-aliases/GuardArray.md +8 -5
- package/api/@xmachines/play-xstate/type-aliases/PlayerFactory.md +11 -15
- package/api/@xmachines/play-xstate/type-aliases/RouteMachineConfig.md +12 -19
- package/api/@xmachines/play-xstate/type-aliases/RouteMetadata.md +1 -1
- package/api/@xmachines/play-xstate/type-aliases/RouteStateNode.md +15 -26
- package/api/@xmachines/shared/README.md +12 -14
- 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 +90 -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-vue/functions/getPlayViewContext.md +0 -28
- 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
|
@@ -1,29 +1,21 @@
|
|
|
1
|
-
<!-- generated-by: gsd-doc-writer -->
|
|
2
|
-
|
|
3
1
|
# Form Validation with Typed Context
|
|
4
2
|
|
|
5
|
-
Managing login form state using `setup({
|
|
3
|
+
Managing login form state using `setup({ types })`, typed `assign`, guards, and `meta.view` with `$bindState`.
|
|
6
4
|
|
|
7
5
|
## Use Case
|
|
8
6
|
|
|
9
7
|
This example mirrors the `authMachine` login pattern: a form state with a local state store (`$bindState` two-way binding), a guard on the submit action, and a `meta.view` spec describing the component tree. It covers:
|
|
10
8
|
|
|
11
|
-
- Typed context
|
|
12
|
-
-
|
|
9
|
+
- Typed context mutations with `setup.assign`
|
|
10
|
+
- Guards as inline functions checking context
|
|
13
11
|
- `meta.view` spec with `$bindState` for two-way form binding
|
|
14
12
|
- Sending typed domain events from the view layer
|
|
15
13
|
|
|
16
14
|
## Complete Code
|
|
17
15
|
|
|
18
16
|
```typescript
|
|
19
|
-
import { setup
|
|
20
|
-
import {
|
|
21
|
-
createRoutedMachine,
|
|
22
|
-
definePlayer,
|
|
23
|
-
emptyEventSchema,
|
|
24
|
-
playMetaSchema,
|
|
25
|
-
playRouteEventSchema,
|
|
26
|
-
} from "@xmachines/play-xstate";
|
|
17
|
+
import { setup } from "xstate";
|
|
18
|
+
import { definePlayer, formatPlayRouteTransitions } from "@xmachines/play-xstate";
|
|
27
19
|
|
|
28
20
|
// Context shape
|
|
29
21
|
interface LoginContext {
|
|
@@ -34,136 +26,133 @@ interface LoginContext {
|
|
|
34
26
|
query: Record<string, string>;
|
|
35
27
|
}
|
|
36
28
|
|
|
37
|
-
//
|
|
38
|
-
|
|
39
|
-
|
|
29
|
+
// Event union — lowercase dot-separated names
|
|
30
|
+
type LoginEvent =
|
|
31
|
+
| {
|
|
32
|
+
type: "play.route";
|
|
33
|
+
to: string;
|
|
34
|
+
params?: Record<string, string>;
|
|
35
|
+
query?: Record<string, string>;
|
|
36
|
+
}
|
|
37
|
+
| { type: "auth.login"; username: string }
|
|
38
|
+
| { type: "auth.logout" };
|
|
39
|
+
|
|
40
|
+
// 1. Typed setup — always use setup() before createMachine()
|
|
40
41
|
const loginSetup = setup({
|
|
41
|
-
|
|
42
|
-
context:
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
"play.route": playRouteEventSchema,
|
|
46
|
-
"auth.login": types<{ username: string }>(),
|
|
47
|
-
"auth.logout": emptyEventSchema,
|
|
48
|
-
},
|
|
49
|
-
// State meta carries route templates (meta.route) and typed PlaySpec
|
|
50
|
-
// view specs (meta.view)
|
|
51
|
-
meta: playMetaSchema,
|
|
42
|
+
types: {
|
|
43
|
+
context: {} as LoginContext,
|
|
44
|
+
events: {} as LoginEvent,
|
|
45
|
+
input: {} as Partial<LoginContext> | undefined,
|
|
52
46
|
},
|
|
53
47
|
});
|
|
54
48
|
|
|
55
|
-
// 2. Machine —
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
on: {
|
|
72
|
-
"auth.login": ({ context, event }) => {
|
|
73
|
-
// Guard: allow login only when not already authenticated
|
|
74
|
-
if (context.isAuthenticated) return;
|
|
75
|
-
return {
|
|
49
|
+
// 2. Machine — wraps config in formatPlayRouteTransitions for play.route support
|
|
50
|
+
const loginMachine = loginSetup.createMachine(
|
|
51
|
+
formatPlayRouteTransitions({
|
|
52
|
+
id: "login",
|
|
53
|
+
initial: "idle",
|
|
54
|
+
context: ({ input }) => ({
|
|
55
|
+
isAuthenticated: input?.isAuthenticated ?? false,
|
|
56
|
+
username: input?.username ?? null,
|
|
57
|
+
errorMessage: null,
|
|
58
|
+
params: input?.params ?? {},
|
|
59
|
+
query: input?.query ?? {},
|
|
60
|
+
}),
|
|
61
|
+
|
|
62
|
+
// Root-level event handlers — accessible from any state
|
|
63
|
+
on: {
|
|
64
|
+
"auth.login": {
|
|
76
65
|
target: ".dashboard",
|
|
77
|
-
|
|
66
|
+
// Guard: allow login only when not already authenticated
|
|
67
|
+
guard: ({ context }) => !context.isAuthenticated,
|
|
68
|
+
actions: loginSetup.assign({
|
|
78
69
|
isAuthenticated: true,
|
|
79
70
|
errorMessage: null,
|
|
80
|
-
// Typed by the event
|
|
81
|
-
username: event.username,
|
|
82
|
-
},
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
"auth.logout": ({ context }) => {
|
|
86
|
-
if (!context.isAuthenticated) return;
|
|
87
|
-
return {
|
|
71
|
+
// Typed by the event union — TypeScript narrows event.username safely
|
|
72
|
+
username: ({ event }) => (event.type === "auth.login" ? event.username : null),
|
|
73
|
+
}),
|
|
74
|
+
},
|
|
75
|
+
"auth.logout": {
|
|
88
76
|
target: ".idle",
|
|
89
|
-
|
|
77
|
+
guard: ({ context }) => context.isAuthenticated,
|
|
78
|
+
actions: loginSetup.assign({
|
|
90
79
|
isAuthenticated: false,
|
|
91
80
|
username: null,
|
|
92
|
-
},
|
|
93
|
-
}
|
|
81
|
+
}),
|
|
82
|
+
},
|
|
94
83
|
},
|
|
95
|
-
},
|
|
96
84
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
85
|
+
states: {
|
|
86
|
+
idle: {
|
|
87
|
+
id: "idle",
|
|
88
|
+
meta: {
|
|
89
|
+
route: "/",
|
|
90
|
+
view: {
|
|
91
|
+
root: "root",
|
|
92
|
+
elements: {
|
|
93
|
+
root: { type: "Home", props: { title: "Welcome" }, children: [] },
|
|
94
|
+
},
|
|
106
95
|
},
|
|
107
96
|
},
|
|
108
97
|
},
|
|
109
|
-
},
|
|
110
98
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
99
|
+
login: {
|
|
100
|
+
id: "login",
|
|
101
|
+
meta: {
|
|
102
|
+
route: "/login",
|
|
103
|
+
view: {
|
|
104
|
+
root: "root",
|
|
105
|
+
// Local state store — initial value shown in the form field
|
|
106
|
+
state: { username: "" },
|
|
107
|
+
elements: {
|
|
108
|
+
root: {
|
|
109
|
+
type: "Login",
|
|
110
|
+
props: {
|
|
111
|
+
title: "Sign In",
|
|
112
|
+
// $bindState wires the prop to the local state store (two-way)
|
|
113
|
+
username: { $bindState: "/username" },
|
|
114
|
+
},
|
|
115
|
+
children: [],
|
|
116
|
+
on: {
|
|
117
|
+
// emit("submit") → resolves username from $state, calls login action
|
|
118
|
+
submit: {
|
|
119
|
+
action: "login",
|
|
120
|
+
params: { username: { $state: "/username" } },
|
|
121
|
+
},
|
|
133
122
|
},
|
|
134
123
|
},
|
|
135
124
|
},
|
|
136
125
|
},
|
|
137
126
|
},
|
|
138
127
|
},
|
|
139
|
-
},
|
|
140
128
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
129
|
+
dashboard: {
|
|
130
|
+
id: "dashboard",
|
|
131
|
+
meta: {
|
|
132
|
+
route: "/dashboard",
|
|
133
|
+
view: {
|
|
134
|
+
root: "root",
|
|
135
|
+
elements: {
|
|
136
|
+
root: {
|
|
137
|
+
type: "Dashboard",
|
|
138
|
+
props: { title: "Dashboard" },
|
|
139
|
+
children: [],
|
|
140
|
+
on: {
|
|
141
|
+
logout: { action: "logout" },
|
|
142
|
+
},
|
|
154
143
|
},
|
|
155
144
|
},
|
|
156
145
|
},
|
|
157
146
|
},
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
147
|
+
// always-guard: redirect to login if not authenticated
|
|
148
|
+
always: {
|
|
149
|
+
guard: ({ context }) => !context.isAuthenticated,
|
|
150
|
+
target: "login",
|
|
151
|
+
},
|
|
163
152
|
},
|
|
164
153
|
},
|
|
165
|
-
},
|
|
166
|
-
|
|
154
|
+
}),
|
|
155
|
+
);
|
|
167
156
|
|
|
168
157
|
// 3. Factory and actor
|
|
169
158
|
const createPlayer = definePlayer({ machine: loginMachine });
|
|
@@ -180,7 +169,7 @@ console.log(actor.getSnapshot().value); // "dashboard"
|
|
|
180
169
|
console.log(actor.getSnapshot().context.username); // "alice"
|
|
181
170
|
|
|
182
171
|
// 6. Guard prevents re-login while authenticated
|
|
183
|
-
actor.send({ type: "auth.login", username: "bob" }); //
|
|
172
|
+
actor.send({ type: "auth.login", username: "bob" }); // guard fires, transition rejected
|
|
184
173
|
console.log(actor.getSnapshot().context.username); // still "alice"
|
|
185
174
|
|
|
186
175
|
// 7. Logout
|
|
@@ -226,10 +215,10 @@ view: {
|
|
|
226
215
|
|
|
227
216
|
## Key Concepts
|
|
228
217
|
|
|
229
|
-
- **`setup({
|
|
230
|
-
-
|
|
231
|
-
- **Guards as
|
|
232
|
-
- **`always` transitions**:
|
|
218
|
+
- **`setup({ types })`**: Always declare context, events, and input types before `createMachine`.
|
|
219
|
+
- **`setup.assign(...)`**: Use the scoped `assign` from your `setup` instance, not the bare one from `xstate`. This provides full type inference.
|
|
220
|
+
- **Guards as inline functions**: `({ context }) => !context.isAuthenticated` — guards check state invariants ("can I BE in this state?"), not event details.
|
|
221
|
+
- **`always` transitions**: Entry guards on states. Used for protected routes — if the guard fires, the machine redirects before the state is fully entered.
|
|
233
222
|
- **Lowercase dot-separated event types**: `"auth.login"`, `"auth.logout"`, `"play.route"` — not `SCREAMING_SNAKE_CASE`.
|
|
234
223
|
|
|
235
224
|
## Connecting the Renderer
|
|
@@ -314,6 +303,6 @@ window.addEventListener("beforeunload", () => {
|
|
|
314
303
|
## Next Steps
|
|
315
304
|
|
|
316
305
|
- **[Basic State Machine](basic-state-machine.md)** — Foundational concepts without a view layer
|
|
317
|
-
- **[Routing Patterns](routing-patterns.md)** — Parameter routes, relative routes, and `always` auth
|
|
318
|
-
- **[`PlaySpec`](../api/@xmachines/play-actor/interfaces/PlaySpec.md)** — Spec type governing `meta.view`, `$bindState`, `$state
|
|
306
|
+
- **[Routing Patterns](routing-patterns.md)** — Parameter routes, relative routes, and `always` auth guards
|
|
307
|
+
- **[`PlaySpec`](../api/@xmachines/play-actor/interfaces/PlaySpec.md)** — Spec type governing `meta.view`, `$bindState`, and `$state`
|
|
319
308
|
- **[`@xmachines/play-router`](../api/@xmachines/play-router/README.md)** — Route extraction and tree building
|
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
<!-- generated-by: gsd-doc-writer -->
|
|
2
|
-
|
|
3
1
|
# Routing Patterns
|
|
4
2
|
|
|
5
|
-
How the `authMachine` uses `meta.route`, `play.route` events, `formatPlayRouteTransitions`, and `always`
|
|
3
|
+
How the `authMachine` uses `meta.route`, `play.route` events, `formatPlayRouteTransitions`, and `always` guards to implement actor-authoritative URL routing.
|
|
6
4
|
|
|
7
5
|
## Overview
|
|
8
6
|
|
|
@@ -62,17 +60,12 @@ states: {
|
|
|
62
60
|
|
|
63
61
|
### `formatPlayRouteTransitions` — Auto-Generating Route Handlers
|
|
64
62
|
|
|
65
|
-
Instead of hand-writing `play.route` event handlers for every routable state,
|
|
63
|
+
Instead of hand-writing `play.route` event handlers for every routable state, wrap your machine config with `formatPlayRouteTransitions`:
|
|
66
64
|
|
|
67
65
|
```typescript
|
|
68
|
-
import { setup
|
|
69
|
-
import {
|
|
70
|
-
|
|
71
|
-
definePlayer,
|
|
72
|
-
emptyEventSchema,
|
|
73
|
-
playMetaSchema,
|
|
74
|
-
playRouteEventSchema,
|
|
75
|
-
} from "@xmachines/play-xstate";
|
|
66
|
+
import { setup } from "xstate";
|
|
67
|
+
import { definePlayer, formatPlayRouteTransitions } from "@xmachines/play-xstate";
|
|
68
|
+
import type { PlayRouteEvent } from "@xmachines/play-router";
|
|
76
69
|
|
|
77
70
|
interface AuthContext {
|
|
78
71
|
isAuthenticated: boolean;
|
|
@@ -82,72 +75,47 @@ interface AuthContext {
|
|
|
82
75
|
}
|
|
83
76
|
|
|
84
77
|
const authSetup = setup({
|
|
85
|
-
|
|
86
|
-
context:
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
"auth.login": types<{ username: string }>(),
|
|
91
|
-
"auth.logout": emptyEventSchema,
|
|
92
|
-
},
|
|
93
|
-
meta: playMetaSchema,
|
|
78
|
+
types: {
|
|
79
|
+
context: {} as AuthContext,
|
|
80
|
+
events: {} as
|
|
81
|
+
PlayRouteEvent | { type: "auth.login"; username: string } | { type: "auth.logout" },
|
|
82
|
+
input: {} as Partial<AuthContext> | undefined,
|
|
94
83
|
},
|
|
95
84
|
});
|
|
96
85
|
|
|
97
|
-
const authMachine =
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
86
|
+
const authMachine = authSetup.createMachine(
|
|
87
|
+
formatPlayRouteTransitions({
|
|
88
|
+
id: "auth",
|
|
89
|
+
initial: "home",
|
|
90
|
+
context: ({ input }) => ({
|
|
91
|
+
isAuthenticated: input?.isAuthenticated ?? false,
|
|
92
|
+
username: input?.username ?? null,
|
|
93
|
+
params: input?.params ?? {},
|
|
94
|
+
query: input?.query ?? {},
|
|
95
|
+
}),
|
|
96
|
+
states: {
|
|
97
|
+
home: { id: "home", meta: { route: "/" } },
|
|
98
|
+
about: { id: "about", meta: { route: "/about" } },
|
|
99
|
+
login: { id: "login", meta: { route: "/login" } },
|
|
100
|
+
profile: { id: "profile", meta: { route: "/profile/:username" } },
|
|
101
|
+
},
|
|
105
102
|
}),
|
|
106
|
-
|
|
107
|
-
home: { id: "home", meta: { route: "/" } },
|
|
108
|
-
about: { id: "about", meta: { route: "/about" } },
|
|
109
|
-
login: { id: "login", meta: { route: "/login" } },
|
|
110
|
-
profile: { id: "profile", meta: { route: "/profile/:username" } },
|
|
111
|
-
},
|
|
112
|
-
});
|
|
103
|
+
);
|
|
113
104
|
```
|
|
114
105
|
|
|
115
|
-
|
|
106
|
+
`formatPlayRouteTransitions` generates root-level handlers equivalent to:
|
|
116
107
|
|
|
117
108
|
```typescript
|
|
118
|
-
// Equivalent of what formatPlayRouteTransitions produces:
|
|
119
|
-
states: {
|
|
120
|
-
home: { id: "home", meta: { route: "/" }, route: {} },
|
|
121
|
-
about: { id: "about", meta: { route: "/about" }, route: {} },
|
|
122
|
-
login: { id: "login", meta: { route: "/login" }, route: {} },
|
|
123
|
-
profile: { id: "profile", meta: { route: "/profile/:username" }, route: {} },
|
|
124
|
-
},
|
|
125
109
|
on: {
|
|
126
110
|
"play.route": [
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
({ event }
|
|
130
|
-
|
|
131
|
-
if (target === undefined) return undefined; // fall through to your fallbacks
|
|
132
|
-
if (target === null) {
|
|
133
|
-
// user-declared route config: its resolver decides (and owns any patch)
|
|
134
|
-
enq.raise({ ...event, type: "xstate.route" });
|
|
135
|
-
return {};
|
|
136
|
-
}
|
|
137
|
-
// one atomic transition: navigation + params/query patch together
|
|
138
|
-
return {
|
|
139
|
-
target,
|
|
140
|
-
reenter: true,
|
|
141
|
-
context: { params: event.params ?? {}, query: event.query ?? {} },
|
|
142
|
-
};
|
|
143
|
-
},
|
|
144
|
-
// ...your own play.route fallbacks (e.g. a 404 route) run for unknown targets
|
|
111
|
+
{ target: ".home", guard: ({ event }) => event.to === "#home", reenter: true, actions: assign({ params, query }) },
|
|
112
|
+
{ target: ".about", guard: ({ event }) => event.to === "#about", reenter: true, actions: assign({ params, query }) },
|
|
113
|
+
{ target: ".login", guard: ({ event }) => event.to === "#login", reenter: true, actions: assign({ params, query }) },
|
|
114
|
+
{ target: ".profile", guard: ({ event }) => event.to === "#profile", reenter: true, actions: assign({ params, query }) },
|
|
145
115
|
],
|
|
146
116
|
}
|
|
147
117
|
```
|
|
148
118
|
|
|
149
|
-
For injected routes the forwarder navigates directly — navigation and the `params`/`query` patch are one atomic transition, so exit actions see the old params and no `always` transition can observe a half-navigated state. The injected `route: {}` configs keep statically-targeted `xstate.route` edges in the graph for tooling. States that declare their **own** `route` config are re-raised as `xstate.route` instead, so the user's resolver decides (including blocking — in which case context stays untouched). Unknown targets return `undefined`, falling through to any `play.route` fallbacks you define yourself.
|
|
150
|
-
|
|
151
119
|
### `play.route` Events — Navigation
|
|
152
120
|
|
|
153
121
|
To navigate, send a `play.route` event with `to: "#stateId"`:
|
|
@@ -176,63 +144,61 @@ actor.send({
|
|
|
176
144
|
|
|
177
145
|
**`to` always uses `"#stateId"` format** — the state's `id` field prefixed with `#`. Do not pass URL paths here.
|
|
178
146
|
|
|
179
|
-
### `always`
|
|
147
|
+
### `always` Guards — Protected Routes
|
|
180
148
|
|
|
181
|
-
Use XState `always` transitions to protect states.
|
|
149
|
+
Use XState `always` transitions to protect states. If the guard fires, the machine redirects _before_ the state is fully entered:
|
|
182
150
|
|
|
183
151
|
```typescript
|
|
184
152
|
dashboard: {
|
|
185
153
|
id: "dashboard",
|
|
186
154
|
meta: { route: "/dashboard" },
|
|
187
|
-
always:
|
|
155
|
+
always: {
|
|
188
156
|
// If not authenticated, redirect to login immediately
|
|
189
|
-
|
|
190
|
-
|
|
157
|
+
guard: ({ context }) => !context.isAuthenticated,
|
|
158
|
+
target: "login",
|
|
191
159
|
},
|
|
192
160
|
},
|
|
193
161
|
profile: {
|
|
194
162
|
id: "profile",
|
|
195
163
|
meta: { route: "/profile/:username" },
|
|
196
|
-
always:
|
|
197
|
-
|
|
198
|
-
|
|
164
|
+
always: {
|
|
165
|
+
guard: ({ context }) => !context.isAuthenticated,
|
|
166
|
+
target: "login",
|
|
199
167
|
},
|
|
200
168
|
},
|
|
201
169
|
```
|
|
202
170
|
|
|
203
|
-
**Why `always` and not guards on events
|
|
171
|
+
**Why `always` and not event guards?** Guards on events check "can I TAKE this transition?". `always` guards check "can I BE in this state?" — the correct invariant for authentication. The actor enforces the guard even on direct URL access (browser back/forward or deep link), because the router sends a `play.route` event which triggers the `always` guard.
|
|
204
172
|
|
|
205
173
|
### Root-Level Event Handlers
|
|
206
174
|
|
|
207
175
|
Domain events placed at the root `on:` level are handled from any state:
|
|
208
176
|
|
|
209
177
|
```typescript
|
|
210
|
-
const authMachine =
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
return {
|
|
178
|
+
const authMachine = authSetup.createMachine(
|
|
179
|
+
formatPlayRouteTransitions({
|
|
180
|
+
// ...
|
|
181
|
+
on: {
|
|
182
|
+
"auth.login": {
|
|
216
183
|
target: ".dashboard",
|
|
217
|
-
|
|
184
|
+
guard: ({ context }) => !context.isAuthenticated,
|
|
185
|
+
actions: authSetup.assign({
|
|
218
186
|
isAuthenticated: true,
|
|
219
|
-
username: event.username,
|
|
220
|
-
},
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
"auth.logout": ({ context }) => {
|
|
224
|
-
if (!context.isAuthenticated) return;
|
|
225
|
-
return {
|
|
187
|
+
username: ({ event }) => (event.type === "auth.login" ? event.username : null),
|
|
188
|
+
}),
|
|
189
|
+
},
|
|
190
|
+
"auth.logout": {
|
|
226
191
|
target: ".home",
|
|
227
|
-
|
|
192
|
+
guard: ({ context }) => context.isAuthenticated,
|
|
193
|
+
actions: authSetup.assign({
|
|
228
194
|
isAuthenticated: false,
|
|
229
195
|
username: null,
|
|
230
|
-
},
|
|
231
|
-
}
|
|
196
|
+
}),
|
|
197
|
+
},
|
|
232
198
|
},
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
199
|
+
states: {/* ... */},
|
|
200
|
+
}),
|
|
201
|
+
);
|
|
236
202
|
```
|
|
237
203
|
|
|
238
204
|
## Complete Actor Usage
|
|
@@ -319,7 +285,7 @@ function App() {
|
|
|
319
285
|
| **Actor Authority (INV-01)** | Guards on the machine validate every navigation. The router cannot change state directly. |
|
|
320
286
|
| **Passive Infrastructure (INV-04)** | The router observes `actor.currentRoute` — it never decides where to go. |
|
|
321
287
|
| **State-Driven Reset (INV-03)** | Browser back/forward sends `play.route` events to the actor. History is driven by actor state. |
|
|
322
|
-
| **Strict Separation (INV-02)** | The machine has zero framework imports. Guards,
|
|
288
|
+
| **Strict Separation (INV-02)** | The machine has zero framework imports. Guards, actions, and context are pure TypeScript. |
|
|
323
289
|
|
|
324
290
|
## Next Steps
|
|
325
291
|
|