@xmachines/docs 3.0.0 → 4.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 +8 -16
- package/api/@xmachines/play/README.md +11 -100
- package/api/@xmachines/play/errors/README.md +8 -0
- package/api/@xmachines/play/{classes → errors/classes}/NonNullableError.md +6 -6
- package/api/@xmachines/play/{classes → errors/classes}/PlayError.md +35 -10
- package/api/@xmachines/play/index/README.md +75 -0
- package/api/@xmachines/play/{functions → index/functions}/asCleanup.md +2 -2
- package/api/@xmachines/play/{functions → index/functions}/assertNonNullable.md +2 -2
- package/api/@xmachines/{play-actor → play/index}/functions/shallowEqualExcept.md +3 -3
- package/api/@xmachines/play/{type-aliases → index/type-aliases}/Cleanup.md +3 -3
- package/api/@xmachines/play/{type-aliases → index/type-aliases}/DisposeKey.md +2 -2
- package/api/@xmachines/play/{type-aliases → index/type-aliases}/PlayEvent.md +4 -4
- package/api/@xmachines/play/{variables → index/variables}/DISPOSE.md +2 -2
- package/api/@xmachines/play-actor/README.md +78 -229
- package/api/@xmachines/play-actor/interfaces/ActorEvent.md +18 -0
- package/api/@xmachines/play-actor/interfaces/PlayActor.md +73 -0
- package/api/@xmachines/play-dom/README.md +28 -40
- package/api/@xmachines/play-dom/classes/PlayRenderer.md +12 -11
- package/api/@xmachines/play-dom/functions/asCleanup.md +78 -0
- package/api/@xmachines/play-dom/functions/createPlayUI.md +4 -4
- package/api/@xmachines/play-dom/functions/createRenderer.md +1 -1
- package/api/@xmachines/play-dom/interfaces/CreatePlayUIOptions.md +3 -3
- package/api/@xmachines/play-dom/interfaces/MountOptions.md +3 -3
- package/api/@xmachines/play-dom/interfaces/PlayDomOptions.md +6 -6
- package/api/@xmachines/play-dom/type-aliases/Cleanup.md +2 -2
- package/api/@xmachines/play-dom/type-aliases/MountFn.md +29 -12
- package/api/@xmachines/play-dom-router/README.md +70 -70
- package/api/@xmachines/play-dom-router/classes/DomRouterBridge.md +22 -21
- package/api/@xmachines/{play-vue-router → play-dom-router}/classes/RouteMap.md +12 -6
- package/api/@xmachines/play-dom-router/functions/asCleanup.md +78 -0
- package/api/@xmachines/play-dom-router/functions/connectRouter.md +3 -8
- package/api/@xmachines/play-dom-router/functions/createBrowserHistory.md +9 -3
- package/api/@xmachines/play-dom-router/functions/createRouter.md +8 -14
- package/api/@xmachines/play-dom-router/interfaces/BasePathOptions.md +5 -5
- package/api/@xmachines/play-dom-router/interfaces/BrowserHistory.md +70 -26
- package/api/@xmachines/play-dom-router/interfaces/BrowserWindow.md +14 -14
- package/api/@xmachines/play-dom-router/interfaces/ConnectRouterOptions.md +8 -8
- package/api/@xmachines/play-dom-router/interfaces/PlayRouteEvent.md +9 -14
- package/api/@xmachines/play-dom-router/interfaces/RoutableActor.md +24 -21
- package/api/@xmachines/play-dom-router/interfaces/RouteLookupContract.md +3 -3
- package/api/@xmachines/play-dom-router/interfaces/RouteMapOptions.md +4 -4
- package/api/@xmachines/play-dom-router/interfaces/RouteMapping.md +3 -3
- package/api/@xmachines/play-dom-router/interfaces/RouterBridge.md +3 -3
- package/api/@xmachines/play-dom-router/interfaces/RouterConnection.md +8 -8
- package/api/@xmachines/play-dom-router/interfaces/VanillaRouter.md +36 -23
- package/api/@xmachines/play-dom-router/type-aliases/Cleanup.md +2 -2
- package/api/@xmachines/play-dom-router/variables/DISPOSE.md +2 -2
- package/api/@xmachines/play-react/README.md +17 -39
- package/api/@xmachines/play-react/classes/PlayErrorBoundary.md +14 -10
- package/api/@xmachines/play-react/functions/useActor.md +1 -1
- package/api/@xmachines/play-react/functions/usePlayView.md +1 -1
- package/api/@xmachines/play-react/functions/useSignalEffect.md +1 -1
- package/api/@xmachines/play-react/interfaces/ActorProviderProps.md +11 -11
- package/api/@xmachines/play-react/interfaces/PlayErrorBoundaryProps.md +6 -6
- package/api/@xmachines/play-react/interfaces/PlayErrorBoundaryState.md +4 -4
- package/api/@xmachines/play-react/interfaces/PlayUIProviderProps.md +13 -13
- package/api/@xmachines/play-react/interfaces/ViewContextValue.md +8 -8
- package/api/@xmachines/play-react/type-aliases/AnyPlayActor.md +11 -3
- 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/variables/schema.md +52 -0
- package/api/@xmachines/play-react-router/README.md +22 -50
- package/api/@xmachines/play-react-router/classes/ReactRouterBridge.md +17 -16
- package/api/@xmachines/play-react-router/classes/RouteMap.md +11 -5
- package/api/@xmachines/play-react-router/functions/createPlayRouterProvider.md +11 -8
- package/api/@xmachines/play-react-router/functions/createRouteMapFromTree.md +16 -9
- package/api/@xmachines/play-react-router/interfaces/PlayRouteEvent.md +9 -14
- package/api/@xmachines/play-react-router/interfaces/PlayRouterProviderProps.md +10 -10
- package/api/@xmachines/play-react-router/interfaces/RoutableActor.md +72 -0
- package/api/@xmachines/play-react-router/interfaces/RouteMapOptions.md +4 -4
- package/api/@xmachines/play-react-router/interfaces/RouteMapping.md +3 -3
- package/api/@xmachines/play-react-router/interfaces/RouterBridge.md +3 -3
- package/api/@xmachines/play-react-router/type-aliases/PlayRouterBridgeConstructor.md +17 -7
- package/api/@xmachines/play-react-router/type-aliases/PlayRouterProviderBaseProps.md +5 -5
- package/api/@xmachines/play-react-router/variables/PlayRouterProvider.md +4 -4
- package/api/@xmachines/play-router/README.md +104 -196
- package/api/@xmachines/play-router/errors/README.md +15 -0
- package/api/@xmachines/play-router/errors/classes/DuplicateBridgeError.md +191 -0
- package/api/@xmachines/play-router/errors/classes/DuplicateRoutePathError.md +175 -0
- package/api/@xmachines/play-router/errors/classes/EmptyRoutePathError.md +175 -0
- package/api/@xmachines/play-router/errors/classes/InvalidBasePathError.md +200 -0
- package/api/@xmachines/play-router/errors/classes/InvalidRoutePatternError.md +203 -0
- package/api/@xmachines/play-router/errors/classes/InvalidStateIdError.md +175 -0
- package/api/@xmachines/play-router/errors/classes/MissingBasePathParamError.md +199 -0
- package/api/@xmachines/play-router/errors/classes/RouterSyncError.md +192 -0
- package/api/@xmachines/play-router/errors/classes/UnknownStateTypeError.md +182 -0
- package/api/@xmachines/play-router/index/README.md +75 -0
- package/api/@xmachines/play-router/{classes → index/classes}/RouteMap.md +12 -6
- package/api/@xmachines/play-router/{classes → index/classes}/RouterBridgeBase.md +19 -17
- package/api/@xmachines/play-router/{functions → index/functions}/buildPlayRouteEvent.md +2 -2
- package/api/@xmachines/play-router/{functions → index/functions}/buildRouteTree.md +14 -4
- package/api/@xmachines/play-router/{functions → index/functions}/cleanFrameworkParams.md +3 -4
- package/api/@xmachines/play-router/{functions → index/functions}/createRouteMapFromTree.md +13 -6
- package/api/@xmachines/play-router/{functions → index/functions}/createRouterConnection.md +2 -2
- package/api/@xmachines/play-router/{functions → index/functions}/detectDuplicateRoutes.md +2 -2
- package/api/@xmachines/play-router/{functions → index/functions}/extractQuery.md +2 -2
- package/api/@xmachines/play-router/{functions → index/functions}/extractRouteParams.md +3 -3
- package/api/@xmachines/play-router/{functions → index/functions}/findRouteById.md +2 -2
- package/api/@xmachines/play-router/{functions → index/functions}/findRouteByPath.md +2 -2
- package/api/@xmachines/play-router/index/functions/getPatternParamNames.md +29 -0
- package/api/@xmachines/play-router/index/functions/getRequiredPatternParamNames.md +39 -0
- package/api/@xmachines/play-router/{functions → index/functions}/isMountableBridge.md +2 -2
- package/api/@xmachines/play-router/index/functions/joinBasePath.md +37 -0
- package/api/@xmachines/play-router/{functions → index/functions}/mountKey.md +2 -2
- package/api/@xmachines/play-router/index/functions/normalizeBasePath.md +43 -0
- package/api/@xmachines/play-router/{functions → index/functions}/openProviderBridge.md +14 -14
- package/api/@xmachines/play-router/index/functions/pickOwnParams.md +41 -0
- package/api/@xmachines/play-router/{functions → index/functions}/repointProviderBridge.md +2 -2
- package/api/@xmachines/play-router/index/functions/resolveBasePath.md +51 -0
- package/api/@xmachines/play-router/{functions → index/functions}/resolveFrameworkParams.md +11 -13
- package/api/@xmachines/play-router/{functions → index/functions}/sanitizePathname.md +2 -2
- package/api/@xmachines/play-router/index/functions/stripBasePath.md +44 -0
- package/api/@xmachines/play-router/{functions → index/functions}/validateRouteFormat.md +2 -2
- package/api/@xmachines/play-router/{functions → index/functions}/validateStateExists.md +2 -2
- package/api/@xmachines/play-router/{interfaces → index/interfaces}/BasePathOptions.md +6 -6
- package/api/@xmachines/play-router/index/interfaces/BuildPlayRouteEventOptions.md +13 -0
- package/api/@xmachines/play-router/index/interfaces/FrameworkParamsSource.md +47 -0
- package/api/@xmachines/play-router/{interfaces → index/interfaces}/LocationLike.md +6 -6
- package/api/@xmachines/play-router/{interfaces → index/interfaces}/MountableRouterBridge.md +9 -9
- package/api/@xmachines/play-router/{interfaces → index/interfaces}/OpenProviderBridgeArgs.md +13 -13
- package/api/@xmachines/play-router/index/interfaces/PlayRouteEvent.md +130 -0
- package/api/@xmachines/play-router/{interfaces → index/interfaces}/PlayRouterProviderBaseProps.md +15 -15
- package/api/@xmachines/play-router/index/interfaces/ResolvedBasePath.md +14 -0
- package/api/@xmachines/play-router/{interfaces → index/interfaces}/ResolvedRoutePath.md +6 -6
- package/api/@xmachines/play-router/index/interfaces/Routable.md +26 -0
- package/api/@xmachines/play-router/index/interfaces/RoutableActor.md +72 -0
- package/api/@xmachines/play-router/{interfaces → index/interfaces}/RouteInfo.md +11 -11
- package/api/@xmachines/play-router/{interfaces → index/interfaces}/RouteMapOptions.md +5 -5
- package/api/@xmachines/play-router/{interfaces → index/interfaces}/RouteMapping.md +6 -6
- package/api/@xmachines/play-router/index/interfaces/RouteMatch.md +12 -0
- package/api/@xmachines/play-router/{interfaces → index/interfaces}/RouteNode.md +13 -13
- package/api/@xmachines/play-router/index/interfaces/RouteObject.md +34 -0
- package/api/@xmachines/play-router/index/interfaces/RouteTree.md +27 -0
- package/api/@xmachines/play-router/{interfaces → index/interfaces}/RouteWatcherHandle.md +7 -7
- package/api/@xmachines/play-router/{interfaces → index/interfaces}/RouterBridge.md +5 -5
- package/api/@xmachines/play-router/{interfaces → index/interfaces}/RouterConnection.md +10 -10
- package/api/@xmachines/play-router/{interfaces → index/interfaces}/WindowLike.md +4 -4
- package/api/@xmachines/play-router/index/type-aliases/PlayRouterBridgeConstructor.md +46 -0
- package/api/@xmachines/play-router/index/type-aliases/RouteData.md +12 -0
- package/api/@xmachines/play-router/index/type-aliases/RouteDataResolver.md +31 -0
- package/api/@xmachines/play-router/index/type-aliases/RouteMetadata.md +11 -0
- package/api/@xmachines/{play-xstate → play-router/index}/variables/DISPOSE.md +3 -3
- package/api/@xmachines/play-router/index/variables/NO_BASE_PATH.md +18 -0
- package/api/@xmachines/play-router/index/variables/ROOT_NODE_ID.md +18 -0
- package/api/@xmachines/play-router/xstate/README.md +53 -0
- package/api/@xmachines/play-router/{functions → xstate/functions}/createRouteMap.md +8 -6
- package/api/@xmachines/play-router/{functions → xstate/functions}/extractMachineRoutes.md +4 -4
- package/api/@xmachines/play-router/xstate/functions/getNavigableRoutes.md +35 -0
- package/api/@xmachines/play-router/{functions → xstate/functions}/getRoutableRoutes.md +6 -6
- package/api/@xmachines/play-router/{functions → xstate/functions}/getRouteMappings.md +7 -7
- package/api/@xmachines/play-router/{functions → xstate/functions}/getTransitionReachableRoutes.md +2 -2
- package/api/@xmachines/play-router/{functions → xstate/functions}/isRouteReachable.md +2 -2
- package/api/@xmachines/play-router/{functions → xstate/functions}/machineToGraph.md +2 -2
- package/api/@xmachines/play-router/xstate/functions/routeExists.md +26 -0
- package/api/@xmachines/play-router/xstate/interfaces/MachineEdgeData.md +15 -0
- package/api/@xmachines/play-router/xstate/interfaces/MachineNodeData.md +17 -0
- package/api/@xmachines/play-router/{type-aliases → xstate/type-aliases}/MachineGraph.md +2 -2
- package/api/@xmachines/play-signals/README.md +2 -24
- package/api/@xmachines/play-signals/functions/watchSignal.md +1 -1
- package/api/@xmachines/play-signals/interfaces/ComputedOptions.md +2 -2
- package/api/@xmachines/play-signals/interfaces/SignalComputed.md +2 -2
- package/api/@xmachines/play-signals/interfaces/SignalOptions.md +2 -2
- package/api/@xmachines/play-signals/interfaces/SignalState.md +3 -3
- package/api/@xmachines/play-signals/interfaces/SignalWatcher.md +4 -4
- package/api/@xmachines/play-signals/type-aliases/Cleanup.md +2 -2
- package/api/@xmachines/play-signals/type-aliases/WatcherNotify.md +1 -1
- package/api/@xmachines/play-solid/README.md +14 -31
- 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 +11 -11
- package/api/@xmachines/play-solid/interfaces/PlayUIProviderProps.md +13 -13
- package/api/@xmachines/play-solid/interfaces/ViewContextValue.md +8 -8
- package/api/@xmachines/play-solid/type-aliases/AnyPlayActor.md +11 -3
- 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/variables/schema.md +71 -0
- package/api/@xmachines/play-solid-router/README.md +31 -52
- package/api/@xmachines/play-solid-router/classes/RouteMap.md +11 -5
- package/api/@xmachines/play-solid-router/classes/SolidRouterBridge.md +30 -53
- package/api/@xmachines/play-solid-router/functions/createPlayRouterProvider.md +9 -8
- package/api/@xmachines/play-solid-router/interfaces/PlayActor.md +38 -35
- package/api/@xmachines/play-solid-router/interfaces/PlayRouteEvent.md +9 -14
- package/api/@xmachines/play-solid-router/interfaces/PlayRouterProviderProps.md +12 -12
- package/api/@xmachines/play-solid-router/interfaces/RoutableActor.md +72 -0
- 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 +17 -7
- package/api/@xmachines/play-solid-router/type-aliases/PlayRouterProviderBaseProps.md +5 -5
- package/api/@xmachines/play-solid-router/type-aliases/SolidRouterHooks.md +4 -4
- package/api/@xmachines/play-solid-router/variables/PlayRouterProvider.md +4 -4
- package/api/@xmachines/play-svelte/README.md +11 -26
- 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 +12 -12
- package/api/@xmachines/play-svelte/interfaces/DefineRegistryOptions.md +4 -4
- package/api/@xmachines/play-svelte/interfaces/PlayUIProviderProps.md +14 -14
- package/api/@xmachines/play-svelte/interfaces/ViewContextValue.md +8 -8
- package/api/@xmachines/play-svelte/type-aliases/AnyPlayActor.md +11 -3
- package/api/@xmachines/play-svelte/variables/schema.md +16 -0
- package/api/@xmachines/play-svelte-spa-router/README.md +22 -41
- package/api/@xmachines/play-svelte-spa-router/classes/RouteMap.md +11 -5
- package/api/@xmachines/play-svelte-spa-router/classes/SvelteSpaRouterBridge.md +22 -21
- package/api/@xmachines/play-svelte-spa-router/functions/connectRouter.md +3 -2
- package/api/@xmachines/play-svelte-spa-router/interfaces/BasePathOptions.md +5 -5
- package/api/@xmachines/play-svelte-spa-router/interfaces/ConnectRouterOptions.md +8 -8
- package/api/@xmachines/play-svelte-spa-router/interfaces/PlayRouteEvent.md +9 -14
- package/api/@xmachines/play-svelte-spa-router/interfaces/RoutableActor.md +72 -0
- package/api/@xmachines/play-svelte-spa-router/interfaces/RouteMapOptions.md +4 -4
- package/api/@xmachines/play-svelte-spa-router/interfaces/RouteMapping.md +3 -3
- package/api/@xmachines/play-svelte-spa-router/interfaces/RouterBridge.md +3 -3
- package/api/@xmachines/play-svelte-spa-router/interfaces/RouterConnection.md +8 -8
- package/api/@xmachines/play-svelte-spa-router/interfaces/WindowLike.md +3 -3
- package/api/@xmachines/play-sveltekit-router/README.md +17 -35
- package/api/@xmachines/play-sveltekit-router/classes/RouteMap.md +11 -5
- package/api/@xmachines/play-sveltekit-router/classes/SvelteKitRouterBridge.md +22 -21
- package/api/@xmachines/play-sveltekit-router/functions/connectRouter.md +3 -2
- package/api/@xmachines/play-sveltekit-router/interfaces/BasePathOptions.md +5 -5
- package/api/@xmachines/play-sveltekit-router/interfaces/ConnectRouterOptions.md +8 -8
- package/api/@xmachines/play-sveltekit-router/interfaces/LocationLike.md +3 -3
- package/api/@xmachines/play-sveltekit-router/interfaces/PlayRouteEvent.md +9 -14
- package/api/@xmachines/play-sveltekit-router/interfaces/RoutableActor.md +72 -0
- package/api/@xmachines/play-sveltekit-router/interfaces/RouteMapOptions.md +4 -4
- package/api/@xmachines/play-sveltekit-router/interfaces/RouteMapping.md +3 -3
- package/api/@xmachines/play-sveltekit-router/interfaces/RouterBridge.md +3 -3
- package/api/@xmachines/play-sveltekit-router/interfaces/RouterConnection.md +8 -8
- package/api/@xmachines/play-tanstack-react-router/README.md +19 -43
- package/api/@xmachines/play-tanstack-react-router/classes/RouteMap.md +11 -5
- package/api/@xmachines/play-tanstack-react-router/classes/TanStackReactRouterBridge.md +18 -17
- package/api/@xmachines/play-tanstack-react-router/functions/createPlayRouterProvider.md +11 -8
- package/api/@xmachines/play-tanstack-react-router/functions/createRouteMapFromTree.md +16 -9
- package/api/@xmachines/play-tanstack-react-router/interfaces/PlayRouteEvent.md +9 -14
- package/api/@xmachines/play-tanstack-react-router/interfaces/PlayRouterProviderProps.md +10 -10
- package/api/@xmachines/play-tanstack-react-router/interfaces/RoutableActor.md +72 -0
- package/api/@xmachines/play-tanstack-react-router/interfaces/RouteMapOptions.md +4 -4
- package/api/@xmachines/play-tanstack-react-router/interfaces/RouteMapping.md +3 -3
- package/api/@xmachines/play-tanstack-react-router/interfaces/RouterBridge.md +3 -3
- package/api/@xmachines/play-tanstack-react-router/type-aliases/PlayRouterBridgeConstructor.md +17 -7
- package/api/@xmachines/play-tanstack-react-router/type-aliases/PlayRouterProviderBaseProps.md +5 -5
- package/api/@xmachines/play-tanstack-react-router/type-aliases/TanStackRouterInstance.md +1 -1
- package/api/@xmachines/play-tanstack-react-router/type-aliases/TanStackRouterLike.md +5 -5
- package/api/@xmachines/play-tanstack-react-router/variables/PlayRouterProvider.md +4 -4
- package/api/@xmachines/play-tanstack-router/README.md +6 -4
- package/api/@xmachines/play-tanstack-router/classes/TanStackRouterBridgeBase.md +17 -20
- package/api/@xmachines/play-tanstack-router/type-aliases/TanStackRouteMapLike.md +3 -3
- package/api/@xmachines/play-tanstack-router/type-aliases/TanStackRouterLike.md +5 -5
- package/api/@xmachines/play-tanstack-solid-router/README.md +26 -52
- package/api/@xmachines/play-tanstack-solid-router/classes/RouteMap.md +11 -5
- package/api/@xmachines/play-tanstack-solid-router/classes/TanStackSolidRouterBridge.md +49 -45
- package/api/@xmachines/play-tanstack-solid-router/functions/createPlayRouterProvider.md +9 -8
- package/api/@xmachines/play-tanstack-solid-router/interfaces/PlayRouteEvent.md +9 -14
- package/api/@xmachines/play-tanstack-solid-router/interfaces/PlayRouterProviderProps.md +10 -10
- package/api/@xmachines/play-tanstack-solid-router/interfaces/RoutableActor.md +72 -0
- package/api/@xmachines/play-tanstack-solid-router/interfaces/RouteMapOptions.md +4 -4
- package/api/@xmachines/play-tanstack-solid-router/interfaces/RouteMapping.md +3 -3
- package/api/@xmachines/play-tanstack-solid-router/interfaces/RouterBridge.md +3 -3
- package/api/@xmachines/play-tanstack-solid-router/type-aliases/PlayRouterBridgeConstructor.md +17 -7
- package/api/@xmachines/play-tanstack-solid-router/type-aliases/PlayRouterProviderBaseProps.md +5 -5
- package/api/@xmachines/play-tanstack-solid-router/type-aliases/TanStackRouterInstance.md +1 -1
- package/api/@xmachines/play-tanstack-solid-router/type-aliases/TanStackRouterLike.md +5 -5
- package/api/@xmachines/play-tanstack-solid-router/variables/PlayRouterProvider.md +4 -4
- package/api/@xmachines/play-url/README.md +69 -0
- package/api/@xmachines/play-url/errors/README.md +17 -0
- package/api/@xmachines/play-url/errors/classes/InvalidBasePathError.md +200 -0
- package/api/@xmachines/play-url/errors/classes/InvalidRoutePatternError.md +203 -0
- package/api/@xmachines/play-url/errors/classes/MissingBasePathParamError.md +199 -0
- package/api/@xmachines/play-url/index/README.md +65 -0
- package/api/@xmachines/play-url/index/functions/cleanFrameworkParams.md +39 -0
- package/api/@xmachines/play-url/index/functions/getCandidates.md +29 -0
- package/api/@xmachines/play-url/index/functions/getCompiledPattern.md +31 -0
- package/api/@xmachines/play-url/index/functions/getIndexKey.md +30 -0
- package/api/@xmachines/play-url/index/functions/getNormalizedParamNameMap.md +32 -0
- package/api/@xmachines/play-url/index/functions/getPatternParamNames.md +29 -0
- package/api/@xmachines/play-url/index/functions/getRequiredPatternParamNames.md +39 -0
- package/api/@xmachines/play-url/index/functions/holdsUnsubstitutedParam.md +36 -0
- package/api/@xmachines/play-url/index/functions/isParameterizedPattern.md +36 -0
- package/api/@xmachines/{play-router → play-url/index}/functions/joinBasePath.md +2 -2
- package/api/@xmachines/{play-router → play-url/index}/functions/normalizeBasePath.md +2 -2
- package/api/@xmachines/play-url/index/functions/normalizeParamNames.md +36 -0
- package/api/@xmachines/play-url/index/functions/parsePattern.md +27 -0
- package/api/@xmachines/{play-router → play-url/index}/functions/pickOwnParams.md +4 -4
- package/api/@xmachines/{play-router → play-url/index}/functions/resolveBasePath.md +2 -2
- package/api/@xmachines/play-url/index/functions/resolveFrameworkParams.md +49 -0
- package/api/@xmachines/{play-router → play-url/index}/functions/stripBasePath.md +2 -2
- package/api/@xmachines/play-url/index/interfaces/BasePathOptions.md +28 -0
- package/api/@xmachines/{play-router → play-url/index}/interfaces/FrameworkParamsSource.md +9 -9
- package/api/@xmachines/play-url/index/interfaces/GroupPart.md +15 -0
- package/api/@xmachines/play-url/index/interfaces/LiteralPart.md +14 -0
- package/api/@xmachines/play-url/index/interfaces/ParamPart.md +21 -0
- package/api/@xmachines/play-url/index/interfaces/ParsedPattern.md +23 -0
- package/api/@xmachines/play-url/index/interfaces/PatternParam.md +15 -0
- package/api/@xmachines/{play-router → play-url/index}/interfaces/ResolvedBasePath.md +6 -6
- package/api/@xmachines/play-url/index/type-aliases/PatternModifier.md +11 -0
- package/api/@xmachines/play-url/index/type-aliases/PatternPart.md +9 -0
- package/api/@xmachines/play-url/index/type-aliases/URLPatternCtor.md +22 -0
- package/api/@xmachines/play-url/index/type-aliases/URLPatternLike.md +68 -0
- package/api/@xmachines/{play-router → play-url/index}/variables/NO_BASE_PATH.md +2 -2
- package/api/@xmachines/play-url/index/variables/URLPattern.md +21 -0
- package/api/@xmachines/play-view/README.md +165 -0
- package/api/@xmachines/play-view/errors/README.md +17 -0
- package/api/@xmachines/play-view/errors/classes/ReadOnlyContextError.md +192 -0
- package/api/@xmachines/play-view/index/README.md +55 -0
- package/api/@xmachines/{play-actor → play-view/index}/functions/attachRenderErrorHandler.md +6 -6
- package/api/@xmachines/{play-actor → play-view/index}/functions/composePlayState.md +2 -2
- package/api/@xmachines/{play-actor → play-view/index}/functions/createFailureLatch.md +2 -2
- package/api/@xmachines/{play-actor → play-view/index}/functions/createReportGuard.md +2 -2
- package/api/@xmachines/{play-actor → play-view/index}/functions/createViewStoreLifecycle.md +2 -2
- package/api/@xmachines/{play-actor → play-view/index}/functions/guardContextWrites.md +2 -2
- package/api/@xmachines/{play-actor → play-view/index}/functions/refreshContextSubtree.md +2 -2
- package/api/@xmachines/{play-actor → play-view/index}/functions/reuseComposedState.md +3 -3
- package/api/@xmachines/{play-actor → play-view/index}/functions/sameViewInputs.md +2 -2
- package/api/@xmachines/{play-actor → play-view/index}/functions/toAtomState.md +2 -2
- package/api/@xmachines/{play-actor → play-view/index}/functions/typedSpec.md +2 -2
- package/api/@xmachines/play-view/index/interfaces/BaseActorProviderProps.md +49 -0
- package/api/@xmachines/{play-actor → play-view/index}/interfaces/BaseViewContextValue.md +12 -12
- package/api/@xmachines/{play-actor → play-view/index}/interfaces/FailureLatch.md +6 -5
- package/api/@xmachines/{play-actor → play-view/index}/interfaces/PlaySpec.md +8 -8
- package/api/@xmachines/{play-actor → play-view/index}/interfaces/ReportGuard.md +6 -6
- package/api/@xmachines/{play-actor → play-view/index}/interfaces/ReportGuardMessages.md +6 -6
- package/api/@xmachines/{play-actor → play-view/index}/interfaces/ResolveViewStoreOptions.md +5 -5
- package/api/@xmachines/{play-actor → play-view/index}/interfaces/ViewInputs.md +7 -7
- package/api/@xmachines/{play-actor → play-view/index}/interfaces/ViewStoreLifecycle.md +6 -5
- package/api/@xmachines/{play-actor → play-view/index}/interfaces/ViewStoreResolution.md +7 -7
- package/api/@xmachines/{play-actor → play-view/index}/interfaces/Viewable.md +5 -5
- package/api/@xmachines/play-view/index/type-aliases/ViewActor.md +26 -0
- package/api/@xmachines/{play-actor → play-view/index}/variables/CONTEXT_STATE_KEY.md +2 -2
- package/api/@xmachines/play-vue/README.md +15 -33
- package/api/@xmachines/play-vue/functions/defineRegistry.md +1 -1
- package/api/@xmachines/play-vue/functions/useActor.md +1 -1
- package/api/@xmachines/play-vue/functions/usePlayView.md +1 -1
- package/api/@xmachines/play-vue/interfaces/ActorProviderProps.md +9 -9
- package/api/@xmachines/play-vue/interfaces/PlayUIProviderProps.md +11 -11
- package/api/@xmachines/play-vue/interfaces/ViewContextValue.md +8 -8
- package/api/@xmachines/play-vue/type-aliases/AnyPlayActor.md +11 -3
- package/api/@xmachines/play-vue/type-aliases/ComponentEntry.md +1 -1
- package/api/@xmachines/play-vue/type-aliases/ComponentsMap.md +1 -1
- package/api/@xmachines/play-vue/type-aliases/DefineRegistryOptions.md +2 -2
- package/api/@xmachines/play-vue/variables/PlayRenderer.md +1 -1
- package/api/@xmachines/play-vue/variables/schema.md +71 -0
- package/api/@xmachines/play-vue-router/README.md +34 -77
- package/api/@xmachines/play-vue-router/errors/README.md +8 -0
- package/api/@xmachines/play-vue-router/errors/classes/VueRouterNavigationError.md +193 -0
- package/api/@xmachines/play-vue-router/errors/classes/VueRouterSendError.md +177 -0
- package/api/@xmachines/play-vue-router/index/README.md +20 -0
- package/api/@xmachines/play-vue-router/index/classes/RouteMap.md +157 -0
- package/api/@xmachines/play-vue-router/{classes → index/classes}/VueRouterBridge.md +24 -43
- package/api/@xmachines/play-vue-router/index/interfaces/PlayRouteEvent.md +130 -0
- package/api/@xmachines/play-vue-router/index/interfaces/RoutableActor.md +72 -0
- package/api/@xmachines/play-vue-router/{interfaces → index/interfaces}/RouteMapOptions.md +5 -5
- package/api/@xmachines/play-vue-router/{interfaces → index/interfaces}/RouteMapping.md +6 -6
- package/api/@xmachines/play-vue-router/{interfaces → index/interfaces}/RouterBridge.md +5 -5
- package/api/@xmachines/play-vue-router/{variables → index/variables}/PlayRouterProvider.md +4 -4
- package/api/@xmachines/play-xstate/README.md +153 -105
- package/api/@xmachines/play-xstate/errors/README.md +13 -0
- package/api/@xmachines/play-xstate/errors/classes/ActorThrewNonErrorError.md +199 -0
- package/api/@xmachines/play-xstate/errors/classes/InvalidEventError.md +198 -0
- package/api/@xmachines/play-xstate/errors/classes/InvalidMachineError.md +169 -0
- package/api/@xmachines/play-xstate/errors/classes/InvalidRouteHandlerError.md +197 -0
- package/api/@xmachines/play-xstate/errors/classes/InvalidRouteMetadataError.md +176 -0
- package/api/@xmachines/play-xstate/errors/classes/MissingRouteParamError.md +199 -0
- package/api/@xmachines/play-xstate/errors/classes/MissingStateIdError.md +203 -0
- package/api/@xmachines/play-xstate/index/README.md +38 -0
- package/api/@xmachines/play-xstate/index/classes/PlayerActor.md +584 -0
- package/api/@xmachines/play-xstate/index/functions/compose.md +224 -0
- package/api/@xmachines/play-xstate/index/functions/definePlayer.md +158 -0
- package/api/@xmachines/play-xstate/index/interfaces/PlayerConfig.md +22 -0
- package/api/@xmachines/play-xstate/{interfaces → index/interfaces}/PlayerFactoryResumeOptions.md +3 -3
- package/api/@xmachines/play-xstate/{interfaces → index/interfaces}/PlayerOptions.md +8 -8
- package/api/@xmachines/play-xstate/index/type-aliases/Capability.md +33 -0
- package/api/@xmachines/play-xstate/index/type-aliases/PlayerConstructor.md +39 -0
- package/api/@xmachines/play-xstate/index/type-aliases/PlayerFactory.md +27 -0
- package/api/@xmachines/{play-router → play-xstate/index}/variables/DISPOSE.md +3 -3
- package/api/@xmachines/play-xstate/with-routing/README.md +46 -0
- package/api/@xmachines/play-xstate/{functions → with-routing/functions}/buildRouteUrl.md +2 -2
- package/api/@xmachines/play-xstate/{functions → with-routing/functions}/deriveRoute.md +4 -4
- package/api/@xmachines/play-xstate/{functions → with-routing/functions}/formatPlayRouteTransitions.md +2 -2
- package/api/@xmachines/play-xstate/{functions → with-routing/functions}/isAbsoluteRoute.md +3 -3
- package/api/@xmachines/play-xstate/with-routing/functions/withRouting.md +36 -0
- package/api/@xmachines/play-xstate/{interfaces → with-routing/interfaces}/RouteContext.md +6 -6
- package/api/@xmachines/play-xstate/with-routing/interfaces/RouteObject.md +34 -0
- package/api/@xmachines/play-xstate/with-routing/type-aliases/RouteData.md +12 -0
- package/api/@xmachines/play-xstate/with-routing/type-aliases/RouteDataResolver.md +31 -0
- package/api/@xmachines/play-xstate/{type-aliases → with-routing/type-aliases}/RouteMachineConfig.md +5 -5
- package/api/@xmachines/play-xstate/with-routing/type-aliases/RouteMetadata.md +11 -0
- package/api/@xmachines/play-xstate/{type-aliases → with-routing/type-aliases}/RouteStateNode.md +21 -7
- package/api/@xmachines/play-xstate/with-view/README.md +31 -0
- package/api/@xmachines/play-xstate/with-view/functions/withView.md +32 -0
- package/api/@xmachines/shared/README.md +10 -32
- package/api/@xmachines/shared/vite-aliases/functions/xmAliases.md +1 -1
- package/api/@xmachines/shared/vite-aliases/functions/xmCacheDir.md +1 -1
- package/api/@xmachines/shared/vite-aliases/functions/xmOptimizeDeps.md +1 -1
- package/api/@xmachines/shared/vite-aliases/functions/xmResolve.md +1 -1
- package/api/@xmachines/shared/vite-aliases/functions/xmSvelteRunes.md +2 -2
- package/api/@xmachines/shared/vitest/functions/defineXmBrowserConfig.md +1 -1
- package/api/@xmachines/shared/vitest/functions/defineXmVitestConfig.md +2 -1
- package/api/@xmachines/shared/vitest/interfaces/XmBrowserConfigOptions.md +4 -4
- package/api/README.md +2 -0
- package/api/llms.txt +15 -10
- package/contributing/architecture.md +94 -66
- package/contributing/configuration.md +85 -26
- package/contributing/deployment.md +30 -28
- package/contributing/development.md +51 -10
- package/contributing/testing.md +87 -28
- package/examples/README.md +9 -7
- package/examples/form-validation.md +3 -2
- package/examples/multi-router-integration.md +61 -39
- package/examples/routing-patterns.md +15 -14
- package/examples/traffic-light.md +11 -5
- package/guides/README.md +1 -0
- package/guides/actor-model.md +35 -26
- package/guides/getting-started.md +49 -46
- package/guides/inspector.md +4 -4
- package/guides/routing.md +245 -0
- package/guides/state-machines.md +16 -17
- package/package.json +10 -9
- package/rfc/play.md +35 -22
- package/api/@xmachines/play-actor/classes/AbstractActor.md +0 -505
- package/api/@xmachines/play-actor/interfaces/BaseActorProviderProps.md +0 -48
- package/api/@xmachines/play-actor/interfaces/Routable.md +0 -14
- package/api/@xmachines/play-dom/type-aliases/DisposablePlayUI.md +0 -36
- package/api/@xmachines/play-dom-router/functions/createRouteMap.md +0 -40
- package/api/@xmachines/play-dom-router/interfaces/DisposableBrowserHistory.md +0 -262
- package/api/@xmachines/play-dom-router/interfaces/DisposableVanillaRouter.md +0 -80
- package/api/@xmachines/play-dom-router/interfaces/RouteMap.md +0 -122
- package/api/@xmachines/play-react/type-aliases/PlayRendererProps.md +0 -13
- package/api/@xmachines/play-react-router/functions/createRouteMap.md +0 -40
- package/api/@xmachines/play-react-router/interfaces/PlayActor.md +0 -70
- package/api/@xmachines/play-router/functions/getNavigableRoutes.md +0 -35
- package/api/@xmachines/play-router/functions/getPatternParamNames.md +0 -24
- package/api/@xmachines/play-router/functions/getRequiredPatternParamNames.md +0 -36
- package/api/@xmachines/play-router/functions/routeExists.md +0 -26
- package/api/@xmachines/play-router/interfaces/BuildPlayRouteEventOptions.md +0 -13
- package/api/@xmachines/play-router/interfaces/MachineEdgeData.md +0 -15
- package/api/@xmachines/play-router/interfaces/MachineNodeData.md +0 -17
- package/api/@xmachines/play-router/interfaces/PlayActor.md +0 -70
- package/api/@xmachines/play-router/interfaces/PlayRouteEvent.md +0 -135
- package/api/@xmachines/play-router/interfaces/RoutableActor.md +0 -65
- package/api/@xmachines/play-router/interfaces/RouteMatch.md +0 -12
- package/api/@xmachines/play-router/interfaces/RouteObject.md +0 -21
- package/api/@xmachines/play-router/interfaces/RouteTree.md +0 -21
- package/api/@xmachines/play-router/type-aliases/BaseRouteMapping.md +0 -13
- package/api/@xmachines/play-router/type-aliases/PlayRouterBridgeConstructor.md +0 -36
- package/api/@xmachines/play-router/type-aliases/RouteMetadata.md +0 -11
- package/api/@xmachines/play-solid-router/functions/createRouteMap.md +0 -40
- package/api/@xmachines/play-solid-router/interfaces/AbstractActor.md +0 -471
- package/api/@xmachines/play-solid-router/type-aliases/RoutableActor.md +0 -13
- package/api/@xmachines/play-svelte-spa-router/functions/createRouteMap.md +0 -40
- package/api/@xmachines/play-svelte-spa-router/type-aliases/RoutableActor.md +0 -9
- package/api/@xmachines/play-sveltekit-router/functions/createRouteMap.md +0 -40
- package/api/@xmachines/play-sveltekit-router/type-aliases/RoutableActor.md +0 -9
- package/api/@xmachines/play-tanstack-react-router/functions/createRouteMap.md +0 -40
- package/api/@xmachines/play-tanstack-react-router/functions/extractMachineRoutes.md +0 -29
- package/api/@xmachines/play-tanstack-react-router/interfaces/PlayActor.md +0 -70
- package/api/@xmachines/play-tanstack-react-router/interfaces/RouteNavigateEvent.md +0 -31
- package/api/@xmachines/play-tanstack-solid-router/functions/createRouteMap.md +0 -40
- package/api/@xmachines/play-tanstack-solid-router/interfaces/PlayActor.md +0 -70
- package/api/@xmachines/play-tanstack-solid-router/type-aliases/RoutableActor.md +0 -13
- package/api/@xmachines/play-vue/interfaces/VisibilityProviderProps.md +0 -9
- package/api/@xmachines/play-vue/variables/getPlayViewContext.md +0 -39
- package/api/@xmachines/play-vue-router/functions/createRouteMap.md +0 -40
- package/api/@xmachines/play-vue-router/interfaces/PlayActor.md +0 -70
- package/api/@xmachines/play-vue-router/interfaces/PlayRouteEvent.md +0 -135
- package/api/@xmachines/play-vue-router/type-aliases/RoutableActor.md +0 -13
- package/api/@xmachines/play-vue-router/type-aliases/VueRouteMap.md +0 -13
- package/api/@xmachines/play-vue-router/variables/VueRouteMap.md +0 -13
- package/api/@xmachines/play-xstate/classes/PlayerActor.md +0 -568
- package/api/@xmachines/play-xstate/functions/composeGuards.md +0 -86
- package/api/@xmachines/play-xstate/functions/composeGuardsOr.md +0 -72
- package/api/@xmachines/play-xstate/functions/contextFieldMatches.md +0 -43
- package/api/@xmachines/play-xstate/functions/definePlayer.md +0 -78
- package/api/@xmachines/play-xstate/functions/eventMatches.md +0 -45
- package/api/@xmachines/play-xstate/functions/hasContext.md +0 -45
- package/api/@xmachines/play-xstate/functions/negateGuard.md +0 -67
- package/api/@xmachines/play-xstate/interfaces/PlayerConfig.md +0 -20
- package/api/@xmachines/play-xstate/interfaces/RouteObject.md +0 -17
- package/api/@xmachines/play-xstate/type-aliases/ComposedGuard.md +0 -19
- package/api/@xmachines/play-xstate/type-aliases/Guard.md +0 -36
- package/api/@xmachines/play-xstate/type-aliases/GuardArray.md +0 -23
- package/api/@xmachines/play-xstate/type-aliases/PlayerFactory.md +0 -26
- package/api/@xmachines/play-xstate/type-aliases/RouteMetadata.md +0 -9
|
@@ -18,11 +18,11 @@ Jump to the section that applies to you:
|
|
|
18
18
|
|
|
19
19
|
You need the following installed before cloning the repository:
|
|
20
20
|
|
|
21
|
-
| Requirement | Version | Notes
|
|
22
|
-
| ----------- | ------------------ |
|
|
23
|
-
| Node.js | `>= 24.0.0` | The floor to
|
|
24
|
-
| pnpm | via corepack | Enable with `corepack enable`; the version is pinned by the `packageManager` field. The project uses pnpm workspaces.
|
|
25
|
-
| Git | any recent version | Conventional commit format is enforced by CI
|
|
21
|
+
| Requirement | Version | Notes |
|
|
22
|
+
| ----------- | ------------------ | --------------------------------------------------------------------------------------------------------------------- |
|
|
23
|
+
| Node.js | `>= 24.0.0` | The floor to develop AND to consume. Every `package.json` `engines` field declares it. |
|
|
24
|
+
| pnpm | via corepack | Enable with `corepack enable`; the version is pinned by the `packageManager` field. The project uses pnpm workspaces. |
|
|
25
|
+
| Git | any recent version | Conventional commit format is enforced by CI |
|
|
26
26
|
|
|
27
27
|
No global TypeScript install is needed — it is installed as a dev dependency via `pnpm install --frozen-lockfile`.
|
|
28
28
|
|
|
@@ -140,7 +140,7 @@ This section covers installing XMachines packages into your own application and
|
|
|
140
140
|
|
|
141
141
|
### Prerequisites
|
|
142
142
|
|
|
143
|
-
- **Node.js** `>=
|
|
143
|
+
- **Node.js** `>= 24.0.0`
|
|
144
144
|
- **pnpm** via corepack (`corepack enable`)
|
|
145
145
|
- **TypeScript** `>= 5.7` (strict mode recommended)
|
|
146
146
|
- **XState** `v5` (required peer dependency for [`@xmachines/play-xstate`](../api/@xmachines/play-xstate/README.md))
|
|
@@ -157,13 +157,13 @@ Every XMachines application needs these four packages plus XState:
|
|
|
157
157
|
pnpm add xstate @xmachines/play-xstate @xmachines/play-actor @xmachines/play-signals @xmachines/json-render-core
|
|
158
158
|
```
|
|
159
159
|
|
|
160
|
-
| Package | Role
|
|
161
|
-
| --------------------------------------------------------------------- |
|
|
162
|
-
| `xstate` | XState v5 state machine engine (peer dependency)
|
|
163
|
-
| [`@xmachines/play-xstate`](../api/@xmachines/play-xstate/README.md) | [`definePlayer()`](../api/@xmachines/play-xstate/functions/definePlayer.md), [`PlayerActor`](../api/@xmachines/play-xstate/classes/PlayerActor.md), routing helpers |
|
|
164
|
-
| [`@xmachines/play-actor`](../api/@xmachines/play-actor/README.md) |
|
|
165
|
-
| [`@xmachines/play-signals`](../api/@xmachines/play-signals/README.md) | TC39 Signals polyfill (`Signal.State`, `Signal.Computed`, [`watchSignal`](../api/@xmachines/play-signals/functions/watchSignal.md))
|
|
166
|
-
| `@xmachines/json-render-core` | Spec and store types the actor layer builds on — a peer of `@xmachines/play-actor`, and of every renderer package
|
|
160
|
+
| Package | Role |
|
|
161
|
+
| --------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
162
|
+
| `xstate` | XState v5 state machine engine (peer dependency) |
|
|
163
|
+
| [`@xmachines/play-xstate`](../api/@xmachines/play-xstate/README.md) | [`definePlayer()`](../api/@xmachines/play-xstate/index/functions/definePlayer.md), [`PlayerActor`](../api/@xmachines/play-xstate/index/classes/PlayerActor.md), routing helpers |
|
|
164
|
+
| [`@xmachines/play-actor`](../api/@xmachines/play-actor/README.md) | The actor contract: `PlayActor`, which names no state machine library |
|
|
165
|
+
| [`@xmachines/play-signals`](../api/@xmachines/play-signals/README.md) | TC39 Signals polyfill (`Signal.State`, `Signal.Computed`, [`watchSignal`](../api/@xmachines/play-signals/functions/watchSignal.md)) |
|
|
166
|
+
| `@xmachines/json-render-core` | Spec and store types the actor layer builds on — a peer of `@xmachines/play-actor`, and of every renderer package |
|
|
167
167
|
|
|
168
168
|
#### Step 2: Install a router adapter (pick one)
|
|
169
169
|
|
|
@@ -171,7 +171,7 @@ pnpm add xstate @xmachines/play-xstate @xmachines/play-actor @xmachines/play-sig
|
|
|
171
171
|
# Provider pattern (framework-integrated routers)
|
|
172
172
|
pnpm add @xmachines/play-tanstack-react-router # TanStack Router (React)
|
|
173
173
|
pnpm add @xmachines/play-tanstack-solid-router # TanStack Router (SolidJS)
|
|
174
|
-
pnpm add @xmachines/play-react-router # React Router
|
|
174
|
+
pnpm add @xmachines/play-react-router # React Router 7/8
|
|
175
175
|
pnpm add @xmachines/play-vue-router # Vue Router 4.x/5.x
|
|
176
176
|
pnpm add @xmachines/play-solid-router # SolidJS Router
|
|
177
177
|
|
|
@@ -269,11 +269,13 @@ State machines control navigation through `meta.route` on states and `play.route
|
|
|
269
269
|
|
|
270
270
|
#### Define a routable machine with `formatPlayRouteTransitions`
|
|
271
271
|
|
|
272
|
-
[`formatPlayRouteTransitions`](../api/@xmachines/play-xstate/functions/formatPlayRouteTransitions.md) auto-generates `play.route` handlers from `id` + `meta.route` state pairs:
|
|
272
|
+
[`formatPlayRouteTransitions`](../api/@xmachines/play-xstate/with-routing/functions/formatPlayRouteTransitions.md) auto-generates `play.route` handlers from `id` + `meta.route` state pairs:
|
|
273
273
|
|
|
274
274
|
```typescript
|
|
275
275
|
import { setup } from "xstate";
|
|
276
|
-
import { definePlayer,
|
|
276
|
+
import { definePlayer, compose, PlayerActor } from "@xmachines/play-xstate";
|
|
277
|
+
import { formatPlayRouteTransitions } from "@xmachines/play-xstate/routing";
|
|
278
|
+
import { withRouting } from "@xmachines/play-xstate/routing";
|
|
277
279
|
import type { PlayRouteEvent } from "@xmachines/play-router";
|
|
278
280
|
|
|
279
281
|
const appSetup = setup({
|
|
@@ -328,7 +330,10 @@ const appMachine = appSetup.createMachine(
|
|
|
328
330
|
}),
|
|
329
331
|
);
|
|
330
332
|
|
|
331
|
-
const createPlayer = definePlayer({
|
|
333
|
+
const createPlayer = definePlayer({
|
|
334
|
+
machine: appMachine,
|
|
335
|
+
actor: compose(PlayerActor, withRouting),
|
|
336
|
+
});
|
|
332
337
|
const actor = createPlayer();
|
|
333
338
|
actor.start();
|
|
334
339
|
|
|
@@ -353,7 +358,7 @@ actor.stop();
|
|
|
353
358
|
|
|
354
359
|
**Routing rules:**
|
|
355
360
|
|
|
356
|
-
- Every routable state **must** have an `id` — [`formatPlayRouteTransitions`](../api/@xmachines/play-xstate/functions/formatPlayRouteTransitions.md) throws `MissingStateIdError` if absent.
|
|
361
|
+
- Every routable state **must** have an `id` — [`formatPlayRouteTransitions`](../api/@xmachines/play-xstate/with-routing/functions/formatPlayRouteTransitions.md) throws `MissingStateIdError` if absent.
|
|
357
362
|
- Send `play.route` events with `to: "#stateId"` — always use the `id` field prefixed with `#`, never raw URL paths.
|
|
358
363
|
- The machine context **must** include `params: Record<string, string>` and `query: Record<string, string>`.
|
|
359
364
|
- Use `always` guards to protect states from direct URL access — these fire even on browser back/forward.
|
|
@@ -372,12 +377,8 @@ Used with framework-integrated routers like TanStack Router. All three props (`a
|
|
|
372
377
|
// React + TanStack Router example
|
|
373
378
|
import { useMemo, useEffect } from "react";
|
|
374
379
|
import { createRouter, createRootRoute } from "@tanstack/react-router";
|
|
375
|
-
import {
|
|
376
|
-
|
|
377
|
-
extractMachineRoutes,
|
|
378
|
-
createRouteMapFromTree,
|
|
379
|
-
} from "@xmachines/play-tanstack-react-router";
|
|
380
|
-
|
|
380
|
+
import { PlayRouterProvider, createRouteMapFromTree } from "@xmachines/play-tanstack-react-router";
|
|
381
|
+
import { extractMachineRoutes } from "@xmachines/play-router/xstate";
|
|
381
382
|
// Build OUTSIDE of JSX — must be stable references
|
|
382
383
|
const routeTree = extractMachineRoutes(appMachine);
|
|
383
384
|
const routeMap = createRouteMapFromTree(routeTree);
|
|
@@ -408,7 +409,8 @@ Used with framework-agnostic or server-rendered routers. `connectRouter` handles
|
|
|
408
409
|
|
|
409
410
|
```typescript
|
|
410
411
|
import { createBrowserHistory, createRouter, connectRouter } from "@xmachines/play-dom-router";
|
|
411
|
-
import {
|
|
412
|
+
import { createRouteMapFromTree } from "@xmachines/play-router";
|
|
413
|
+
import { extractMachineRoutes } from "@xmachines/play-router/xstate";
|
|
412
414
|
|
|
413
415
|
const routeTree = extractMachineRoutes(appMachine);
|
|
414
416
|
const routeMap = createRouteMapFromTree(routeTree);
|
|
@@ -610,7 +612,7 @@ window.addEventListener("beforeunload", () => disconnect());
|
|
|
610
612
|
`play.route` event never appears. No error is raised — a context without a
|
|
611
613
|
`query` field builds a query-less URL, exactly like `query: {}`.
|
|
612
614
|
|
|
613
|
-
**Fix:** With [`formatPlayRouteTransitions`](../api/@xmachines/play-xstate/functions/formatPlayRouteTransitions.md)
|
|
615
|
+
**Fix:** With [`formatPlayRouteTransitions`](../api/@xmachines/play-xstate/with-routing/functions/formatPlayRouteTransitions.md)
|
|
614
616
|
nothing is needed — the generated transitions assign `event.query` to context
|
|
615
617
|
on every navigation. A machine that handles `play.route` by hand must do that
|
|
616
618
|
assignment itself:
|
|
@@ -627,8 +629,9 @@ on: {
|
|
|
627
629
|
```
|
|
628
630
|
|
|
629
631
|
(Older releases threw `MissingQueryContextError` at construction for a
|
|
630
|
-
routing-aware context without a `query` field
|
|
631
|
-
|
|
632
|
+
routing-aware context without a `query` field. That class is gone: the generated
|
|
633
|
+
`play.route` transitions assign `query` on every navigation, so the loss it
|
|
634
|
+
guarded against cannot happen.)
|
|
632
635
|
|
|
633
636
|
#### Missing `id` on routable states
|
|
634
637
|
|
|
@@ -675,7 +678,7 @@ const routeMap = useMemo(() => createRouteMapFromTree(routeTree), [routeTree]);
|
|
|
675
678
|
|
|
676
679
|
**Error:** `SyntaxError: Cannot use import statement in a module` or TC39 Signals not available.
|
|
677
680
|
|
|
678
|
-
**Fix:** Use Node.js `>=
|
|
681
|
+
**Fix:** Use Node.js `>= 24.0.0`. Check with:
|
|
679
682
|
|
|
680
683
|
```bash
|
|
681
684
|
node --version
|
|
@@ -685,23 +688,23 @@ node --version
|
|
|
685
688
|
|
|
686
689
|
## Key Concepts Reference
|
|
687
690
|
|
|
688
|
-
| Term
|
|
689
|
-
|
|
|
690
|
-
| `setup({ types })`
|
|
691
|
-
| [`definePlayer({ machine })`](../api/@xmachines/play-xstate/functions/definePlayer.md)
|
|
692
|
-
| `actor.start()`
|
|
693
|
-
| `actor.send({ type })`
|
|
694
|
-
| `actor.getSnapshot()`
|
|
695
|
-
| `actor.state`
|
|
696
|
-
| `actor.currentRoute`
|
|
697
|
-
| `actor.currentView`
|
|
698
|
-
| [`formatPlayRouteTransitions`](../api/@xmachines/play-xstate/functions/formatPlayRouteTransitions.md) | Generates `play.route` handlers from `id` + `meta.route` state pairs
|
|
699
|
-
| `play.route` event
|
|
700
|
-
| `always` guard
|
|
701
|
-
| [`extractMachineRoutes`](../api/@xmachines/play-router/functions/extractMachineRoutes.md)
|
|
702
|
-
| [`createRouteMapFromTree`](../api/@xmachines/play-router/functions/createRouteMapFromTree.md)
|
|
703
|
-
| [`connectRouter`](../api/@xmachines/play-dom-router/functions/connectRouter.md)
|
|
704
|
-
| [`PlayRouterProvider`](../api/@xmachines/play-tanstack-react-router/variables/PlayRouterProvider.md)
|
|
691
|
+
| Term | Description |
|
|
692
|
+
| ------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------- |
|
|
693
|
+
| `setup({ types })` | XState v5 entry point — declares TypeScript types for context, events, and input |
|
|
694
|
+
| [`definePlayer({ machine })`](../api/@xmachines/play-xstate/index/functions/definePlayer.md) | Creates a factory that produces [`PlayerActor`](../api/@xmachines/play-xstate/index/classes/PlayerActor.md) instances |
|
|
695
|
+
| `actor.start()` | Activates the machine — always call before sending events |
|
|
696
|
+
| `actor.send({ type })` | Sends an event; machine guards decide whether a transition occurs |
|
|
697
|
+
| `actor.getSnapshot()` | Synchronous read of current state and context |
|
|
698
|
+
| `actor.state` | `Signal.State<Snapshot>` — TC39 Signal for reactive state observation |
|
|
699
|
+
| `actor.currentRoute` | `Signal.Computed<string \| null>` — resolved URL from active state's `meta.route` |
|
|
700
|
+
| `actor.currentView` | `Signal.State<PlaySpec \| null>` — view spec from active state's `meta.view` |
|
|
701
|
+
| [`formatPlayRouteTransitions`](../api/@xmachines/play-xstate/with-routing/functions/formatPlayRouteTransitions.md) | Generates `play.route` handlers from `id` + `meta.route` state pairs |
|
|
702
|
+
| `play.route` event | Navigation event — `to: "#stateId"`, optional `params`, `query` |
|
|
703
|
+
| `always` guard | Protects states — fires on entry before any event, even on direct URL access |
|
|
704
|
+
| [`extractMachineRoutes`](../api/@xmachines/play-router/xstate/functions/extractMachineRoutes.md) | Extracts a `RouteTree` from a state machine — used by framework-integrated router adapters |
|
|
705
|
+
| [`createRouteMapFromTree`](../api/@xmachines/play-router/index/functions/createRouteMapFromTree.md) | Builds a `RouteMap` from a `RouteTree` for bidirectional state ID ↔ URL lookups |
|
|
706
|
+
| [`connectRouter`](../api/@xmachines/play-dom-router/functions/connectRouter.md) | Connects a vanilla DOM router to an actor — returns a disconnect cleanup function |
|
|
707
|
+
| [`PlayRouterProvider`](../api/@xmachines/play-tanstack-react-router/variables/PlayRouterProvider.md) | React component that connects a `PlayerActor` to TanStack React Router |
|
|
705
708
|
|
|
706
709
|
---
|
|
707
710
|
|
package/guides/inspector.md
CHANGED
|
@@ -22,7 +22,7 @@ Install the inspect client alongside your existing XState dependency:
|
|
|
22
22
|
pnpm add -D @statelyai/inspect
|
|
23
23
|
```
|
|
24
24
|
|
|
25
|
-
Create an inspector and hand its `inspect` observer to [`definePlayer`](../api/@xmachines/play-xstate/functions/definePlayer.md):
|
|
25
|
+
Create an inspector and hand its `inspect` observer to [`definePlayer`](../api/@xmachines/play-xstate/index/functions/definePlayer.md):
|
|
26
26
|
|
|
27
27
|
```typescript
|
|
28
28
|
import { createBrowserInspector } from "@statelyai/inspect";
|
|
@@ -42,7 +42,7 @@ actor.start();
|
|
|
42
42
|
|
|
43
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
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:
|
|
45
|
+
That is the whole integration. [`PlayerOptions.inspect`](../api/@xmachines/play-xstate/index/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
46
|
|
|
47
47
|
```typescript
|
|
48
48
|
// Function form — the common case
|
|
@@ -190,8 +190,8 @@ const createPlayer = definePlayer({ machine: appMachine, options });
|
|
|
190
190
|
|
|
191
191
|
## Related documentation
|
|
192
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
|
|
193
|
+
- **[`PlayerOptions`](../api/@xmachines/play-xstate/index/interfaces/PlayerOptions.md)** — the full options bag, `inspect` included
|
|
194
|
+
- **[`PlayerActor`](../api/@xmachines/play-xstate/index/classes/PlayerActor.md)** — the actor an inspector observes
|
|
195
195
|
- **[Understanding the Actor Model](actor-model.md)** — why the actor is the actor, and what that buys
|
|
196
196
|
- **[Getting Started](getting-started.md)** — installing packages and creating your first actor
|
|
197
197
|
- **[Stately inspect docs](https://stately.ai/docs/inspector)** — the inspector itself, its transports and options
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
# Understanding Routing in XMachines
|
|
2
|
+
|
|
3
|
+
A route of XMachines is a fact about a STATE, and not a fact about a component tree. A state node declares `meta.route`, and the library carries that declaration in both directions: a URL becomes a state, and a state becomes a URL.
|
|
4
|
+
|
|
5
|
+
This guide states the pattern language one time, and it names the three rules that every one of the nine router adapters follows.
|
|
6
|
+
|
|
7
|
+
After you read it, you know which patterns a route can declare, which side resolves a location, and why a bridge comes in a `connect()` and `disconnect()` pair.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## What problem URLPattern solves
|
|
12
|
+
|
|
13
|
+
A route pattern has to say two different things.
|
|
14
|
+
|
|
15
|
+
- A URL must become a **state id**. `/profile/alice` is the state `profile`, and `alice` is a param of it.
|
|
16
|
+
- A state must become a **URL**. The state `profile` with `{ userId: "alice" }` is the path `/profile/alice`.
|
|
17
|
+
|
|
18
|
+
The first direction needs a matcher, and every router writes its own. Express uses `path-to-regexp`, svelte-spa-router uses `regexparam`, and Vue Router, React Router, SolidJS Router, TanStack Router and SvelteKit each wrote a parser of their own. A library that spans nine of them cannot adopt one of those parsers, because each one carries a different set of features, and a machine that declares a pattern one router refuses is a machine that runs on eight of the nine.
|
|
19
|
+
|
|
20
|
+
`URLPattern` is the WHATWG standard for this, its syntax comes from `path-to-regexp`, and it is a superset of it. XMachines takes it as the pattern language, and it reads the whole of it.
|
|
21
|
+
|
|
22
|
+
This is the same decision that [`@xmachines/play-signals`](signals.md) makes for reactivity: one standard, isolated behind one module, present on every runtime. There is no `SignalsUnavailableError`, because the polyfill makes the question impossible to ask, and there is no URLPattern availability error for the same reason.
|
|
23
|
+
|
|
24
|
+
### The API is always present
|
|
25
|
+
|
|
26
|
+
`@xmachines/play-router` carries [`urlpattern-polyfill`](https://github.com/kenchris/urlpattern-polyfill) as an ordinary dependency. It uses the native `URLPattern` when the runtime has one, and the polyfill when it does not. **Install nothing, and load nothing.**
|
|
27
|
+
|
|
28
|
+
The native API arrived in Chrome 95, in Firefox 142 and in Safari 26. The browser floor of this workspace is Chrome 110, Firefox 115 and Safari 16.4. Chrome carries the API at that floor, and Firefox and Safari carry it far above it, so a Firefox or a Safari at the floor runs the polyfill. `test/url-pattern-parity.test.ts` measures the two implementations against each other, form by form. They agree on every form of the grammar, and they disagree about one shape that no bridge can produce — see the prefix rule below.
|
|
29
|
+
|
|
30
|
+
The cost is 18 kB, minified and with no dependency of its own, and a consumer whose runtime has the native API pays it too. A conditional load would save those bytes and it would make the module asynchronous: `RouteMap` compiles in its constructor, and a navigation matches inside an event handler. Neither can await.
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## The pattern grammar
|
|
35
|
+
|
|
36
|
+
A `meta.route` path is a URLPattern **pathname** pattern. These are the forms:
|
|
37
|
+
|
|
38
|
+
| Form | Name | Matches |
|
|
39
|
+
| ------------ | ------------ | ---------------------------------------------------------- |
|
|
40
|
+
| `/users` | a literal | that path, and nothing else |
|
|
41
|
+
| `:name` | a param | one path segment, reported to the machine as `name` |
|
|
42
|
+
| `:name(\d+)` | a constraint | one segment that the regular expression accepts |
|
|
43
|
+
| `(\d+)` | anonymous | one segment, reported under a NUMBER and not a name |
|
|
44
|
+
| `*` | a wildcard | every remaining character, reported under a number |
|
|
45
|
+
| `{…}` | a group | the forms inside it, as one unit that a modifier can carry |
|
|
46
|
+
| `\:` | an escape | the next character, as a literal |
|
|
47
|
+
|
|
48
|
+
A **modifier** follows a param, a wildcard or a group:
|
|
49
|
+
|
|
50
|
+
| Modifier | Meaning | A path that fills it not |
|
|
51
|
+
| -------- | ------------ | ------------------------ |
|
|
52
|
+
| none | exactly one | does not match |
|
|
53
|
+
| `?` | zero or one | matches |
|
|
54
|
+
| `+` | one or more | does not match |
|
|
55
|
+
| `*` | zero or more | matches |
|
|
56
|
+
|
|
57
|
+
```ts
|
|
58
|
+
const machine = createMachine({
|
|
59
|
+
id: "app",
|
|
60
|
+
states: {
|
|
61
|
+
home: { meta: { route: "/" } },
|
|
62
|
+
profile: { meta: { route: "/profile/:userId" } },
|
|
63
|
+
settings: { meta: { route: "/settings/:section?" } },
|
|
64
|
+
},
|
|
65
|
+
});
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Which forms work in which direction
|
|
69
|
+
|
|
70
|
+
The table above is what the route map MATCHES. The two directions are not the same size
|
|
71
|
+
today, and a route that uses only the inbound half stops the URL silently.
|
|
72
|
+
|
|
73
|
+
| Form | URL to state | state to URL |
|
|
74
|
+
| ----------------------------- | ------------ | ---------------------------------------------------------------------- |
|
|
75
|
+
| a literal, `:name`, `:name?` | yes | yes |
|
|
76
|
+
| `:name*` | yes | **no** — the `*` stops the push, and the URL does not move |
|
|
77
|
+
| `:name+` | yes | **no** — the `+` reaches the URL, and a value with a `/` is encoded |
|
|
78
|
+
| `{…}` | yes | **no** — the braces reach the URL |
|
|
79
|
+
| `:name(\d+)`, `(\d+)` | yes | **no** — the constraint reaches the URL, or it stops the push |
|
|
80
|
+
| `*` | yes | **no** — the `*` stops the push, and the URL does not move |
|
|
81
|
+
| `:cat-id`, a hyphen in a name | yes | **no** — the substitution throws, and the URL stops |
|
|
82
|
+
| an escape, `\+` and `\(` | yes | yes — the bridge resolves the escape before it pushes |
|
|
83
|
+
| an escape, `\:` | yes | **no** — the substitution reads the escaped `:` as a param, and throws |
|
|
84
|
+
|
|
85
|
+
`buildRouteUrl` of `@xmachines/play-xstate` performs the outbound half, and it reads
|
|
86
|
+
`:name` and `:name?` alone. A state whose route uses another form derives a URL that its
|
|
87
|
+
own route matches never — or no URL at all, because `deriveCurrentRoute` catches the
|
|
88
|
+
`MissingRouteParamError` and answers `null`.
|
|
89
|
+
|
|
90
|
+
**Declare a route with a literal, `:name`, `:name?` and an escape until the outbound half
|
|
91
|
+
reads the whole grammar.** The remaining forms are safe for a route that the machine never
|
|
92
|
+
navigates TO, such as a catch-all that only receives a deep link. Issue #16 closes the
|
|
93
|
+
difference.
|
|
94
|
+
|
|
95
|
+
A constraint fails in one of two ways, and which one depends on a single character. The
|
|
96
|
+
derived path carries the constraint whole — `/v/:major(\d+)` with `{ major: "2" }` gives
|
|
97
|
+
`/v/2(\d+)` — and the bridge reads a path that holds a BACKSLASH through the grammar. It
|
|
98
|
+
reads `(\d+)` as a param there, so the route resolves to no one path and the push stops.
|
|
99
|
+
A constraint with no backslash, such as `([0-9]+)`, reaches the address bar as it stands.
|
|
100
|
+
|
|
101
|
+
`buildRouteUrl` leaves an escape as the template writes it, and the bridge resolves it
|
|
102
|
+
before the push. The actor route carries `/tags/c\+\+`, and the address bar receives
|
|
103
|
+
`/tags/c++`, which is the path that the route matches.
|
|
104
|
+
|
|
105
|
+
### A literal that the grammar would read
|
|
106
|
+
|
|
107
|
+
`:`, `+`, `?`, `(` and `{` are characters of the grammar, so a route that writes one of them raw does not mean the literal. The two halves fail differently.
|
|
108
|
+
|
|
109
|
+
URLPattern **refuses** `:`, `+` and `?`: `/tags/c++` reads `+` as a modifier of the literal before it, and a modifier needs a part; `/time/10:30` reads `:` as the start of a param name, and `30` is no name. A route map throws `InvalidRoutePatternError` for each of them, and the error names the pattern.
|
|
110
|
+
|
|
111
|
+
URLPattern **accepts** `(` and `{`, and it reads them as grammar: `/docs/rfc(2119)` is the literal `/docs/rfc` and an anonymous param that the expression `2119` constrains, so it matches `/docs/rfc2119`; `/i18n/{en}` is a group, so it matches `/i18n/en`. Neither route reports a fault, and neither one matches the path that its author wrote.
|
|
112
|
+
|
|
113
|
+
Escape the character when you mean it literally. A `:` and a `?` are the two exceptions,
|
|
114
|
+
and the paragraphs below give the form to write for each.
|
|
115
|
+
|
|
116
|
+
```
|
|
117
|
+
/tags/c\+\+ matches /tags/c++
|
|
118
|
+
/docs/rfc\(2119\) matches /docs/rfc(2119)
|
|
119
|
+
/time/10%3A30 matches /time/10:30
|
|
120
|
+
/a%3Fb matches /a?b
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
**An escaped `:` matches, and it derives no URL.** `substituteParams` of `buildRouteUrl` reads `:30` of `/time/10\:30` as a param placeholder, finds no value for the name `30`, and throws `MissingRouteParamError` — which `deriveCurrentRoute` answers with `null`, so the address bar follows that state never. `\+` and `\(` carry no such risk, because neither character starts a param name. Write `%3A` instead: `/time/10%3A30` is an ordinary literal path, and both halves read it. Issue #16 closes the difference.
|
|
124
|
+
|
|
125
|
+
A `?` has no literal form, and the escape does not give it one. A URL pathname ends at its first `?`, so `getStateIdByPath` cuts every location there. The route `/a\?b` compiles with no fault, and no location reaches it. Write `%3F` instead: `/a%3Fb` is an ordinary literal path, and it resolves.
|
|
126
|
+
|
|
127
|
+
This rule is about the PATTERN that a state declares. A param VALUE needs no escape, because `buildRouteUrl` percent-encodes each value: `/search/:q` with `{ q: "a+b" }` becomes the location `/search/a%2Bb`, and `extractRouteParams` reads `a+b` back from it.
|
|
128
|
+
|
|
129
|
+
`encodeURIComponent` leaves `*` as it stands, and that is the one exception. A bridge refuses a path that still holds a `:` or a `*`, because such a character marks a param that nothing substituted. A value of `a*b` therefore stops the push, and the URL stays where it is.
|
|
130
|
+
|
|
131
|
+
**This is a change of behaviour, and a route of yours can hold one of these characters today.** An earlier release read a route as a pattern only when the route held a `:` or a `*`. `/tags/c++`, `/docs/rfc(2119)` and `/i18n/{en}` therefore went to the exact-match map, and each one matched the path that its author wrote. The route map reads the whole grammar now. `/tags/c++` throws `InvalidRoutePatternError` in the constructor of `RouteMap`, and the other two compile and match another path in silence. Add the escape to each route that writes one of these characters raw.
|
|
132
|
+
|
|
133
|
+
A route that carries a QUERY STRING is the same case, and it is the form a machine writes most often. `meta: { route: "/dates?trip=one-way" }` reached the exact-match map before, and the bridge pushed it to the address bar with its query. The grammar reads that `?` as a modifier that follows no part, so `RouteMap` throws `InvalidRoutePatternError` in its constructor now and the application starts never. A route declares a PATHNAME: put the default in `context.query`, which the generated `play.route` transition assigns and `buildRouteUrl` writes to the URL.
|
|
134
|
+
|
|
135
|
+
### Upgrading from 3.x: the `reenter` default changed
|
|
136
|
+
|
|
137
|
+
An earlier release wrote `reenter: true` on every transition that `formatPlayRouteTransitions` generated, so every routed state re-entered its own domain on each navigation and ran its `entry` actions again. The flag now comes from `meta.route`, and the default is `false`, which is the default of XState.
|
|
138
|
+
|
|
139
|
+
**Nothing throws, and the `entry` action simply stops running.** A state that needs it declares the flag for itself:
|
|
140
|
+
|
|
141
|
+
```ts
|
|
142
|
+
states: {
|
|
143
|
+
dashboard: { meta: { route: { path: "/dashboard", reenter: true } } },
|
|
144
|
+
},
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
`reenter` spares the DOMAIN of the transition and not every ancestor that stays active. Under the default `handler: "root"` the domain is the root of the machine, so `false` spares the root alone and each ancestor between the root and the target still runs its `exit` and `entry` actions. `handler: "local"` and `handler: "both"` move the domain down to the parent, which is the field that spares those intermediate ancestors.
|
|
148
|
+
|
|
149
|
+
CAUTION: `"local"` also SCOPES the route. The generated transition then sits on the parent alone, so a `play.route` event that arrives while the parent is inactive matches nothing and the actor does not move — a deep link or a press on BACK therefore leaves the URL and the actor divergent. Choose `"local"` where that scope is the intent, such as a step that a person reaches only inside its wizard. Choose `"both"` where the state must stay reachable from everywhere.
|
|
150
|
+
|
|
151
|
+
### The prefix rule
|
|
152
|
+
|
|
153
|
+
A `/` directly before a **param** belongs TO that param. A `/` directly before a **group** does not.
|
|
154
|
+
|
|
155
|
+
```
|
|
156
|
+
/settings/:section? matches /settings — the modifier removed the separator too
|
|
157
|
+
/a/:b?/c matches /a/c
|
|
158
|
+
/a/{b}?/c matches /a//c, and NOT /a/c
|
|
159
|
+
/books{/:id}? matches /books
|
|
160
|
+
/books/{:id}? matches /books/, and NOT /books
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
This one rule decides every optional route in this library. Write `{/:id}?` and not `/{:id}?` when you want the bare path to work.
|
|
164
|
+
|
|
165
|
+
**A bare path of a doubled slash is unreachable.** `sanitizePathname` joins every run of separators into one, and every bridge calls it before the match, so the location `/a//c` arrives as `/a/c` — which `/a/{b}?/c` matches never. Put the separator INSIDE the group, and the bare path is an ordinary one.
|
|
166
|
+
|
|
167
|
+
The two URLPattern implementations also disagree about a path of a doubled slash, and about nothing else: the native API matches `/{/v2}` against `//v2`, and `urlpattern-polyfill` does not. The collapse above is what keeps that difference away from your routes.
|
|
168
|
+
|
|
169
|
+
### The one divergence from URLPattern
|
|
170
|
+
|
|
171
|
+
A param name of URLPattern is a JavaScript identifier, and it carries no hyphen: `/docs/:cat-id` is the param `cat` followed by the literal `-id` for the standard.
|
|
172
|
+
|
|
173
|
+
**XMachines reads `cat-id` as one name.** It compiles the pattern as `:cat_id` and it maps the group back, so the machine receives `{ "cat-id": "intro" }`. A route names its params the way the application does.
|
|
174
|
+
|
|
175
|
+
The cost is that you cannot write URLPattern's own reading of `:cat-id`. Use `:cat` followed by a separate literal segment when you need it.
|
|
176
|
+
|
|
177
|
+
---
|
|
178
|
+
|
|
179
|
+
## The routing invariants
|
|
180
|
+
|
|
181
|
+
### 1. XMachines resolves the state id. The router never does
|
|
182
|
+
|
|
183
|
+
The router is a **source of locations** and a **sink for navigations**. It resolves a state id never, because a state id is a concept of the machine that the router knows nothing about.
|
|
184
|
+
|
|
185
|
+
| Direction | Who does the work |
|
|
186
|
+
| ----------------- | --------------------------------------------------------------------------------------- |
|
|
187
|
+
| URL → state id | XMachines. `RouteMap.getStateIdByPath` runs the URLPattern match, in all nine adapters |
|
|
188
|
+
| actor route → URL | XMachines, and it touches URLPattern never: a map lookup, then a substitution of params |
|
|
189
|
+
| params | the URLPattern extraction, except where the framework already parsed them |
|
|
190
|
+
|
|
191
|
+
That follows from the architecture: a host registers ONE catch-all route — `/:pathMatch(.*)*` in the Vue demo — so the framework matches nothing that belongs to the machine.
|
|
192
|
+
|
|
193
|
+
Vue Router and SolidJS Router parse their own params, and their bridges keep that parse when it covers every **required** name of the pattern. That is an optimization, and never a second source of truth: a bridge under a mount ignores the framework entirely, because the framework matched a route of the HOST there and a name that collides carries the value of the host.
|
|
194
|
+
|
|
195
|
+
### 2. A `basePath` divides the two sides
|
|
196
|
+
|
|
197
|
+
A machine can own the whole router, or it can sit under a mount. `basePath` is the prefix that belongs to the host, and the machine owns the suffix alone. Every path that reaches the machine has the prefix removed already, and every path that the machine pushes gets it back.
|
|
198
|
+
|
|
199
|
+
### 3. `connect()` and `disconnect()` come in a pair, and one actor takes one bridge
|
|
200
|
+
|
|
201
|
+
A bridge installs a signal watcher on the actor and a subscription on the router. Neither releases itself.
|
|
202
|
+
|
|
203
|
+
- Call `disconnect()` from the teardown of your component: `useEffect` cleanup in React, `onUnmounted` in Vue, `onCleanup` in Solid.
|
|
204
|
+
- A second `connect()` on an actor that already has a bridge throws `DuplicateBridgeError`. The actor takes one bridge, so that two bridges cannot drive it in opposite directions.
|
|
205
|
+
- `connect()` gives all or nothing. It installs the watcher and the subscription BEFORE the first synchronization, because that synchronization drives both directions — and when the synchronization throws, `connect()` removes everything it installed and frees the actor again.
|
|
206
|
+
|
|
207
|
+
---
|
|
208
|
+
|
|
209
|
+
## Which patterns cost what
|
|
210
|
+
|
|
211
|
+
- A **static** route costs nothing. `RouteMap` splits at construction: a literal path goes into an exact-match `Map`, and only a pattern compiles a `URLPattern`. A route map of literal paths alone reaches the API never.
|
|
212
|
+
- A **parameterized** route pays one compilation in the constructor, and one match for each distinct path, behind an LRU cache.
|
|
213
|
+
- A route that a **framework** already parsed pays neither, for as long as its parse covers every required name.
|
|
214
|
+
|
|
215
|
+
---
|
|
216
|
+
|
|
217
|
+
## Why not a matcher of our own
|
|
218
|
+
|
|
219
|
+
The 2.2.0 review asked whether a hand-written segment matcher could drop the `URLPattern` requirement. The answer is no, and the reason is not the size of the code.
|
|
220
|
+
|
|
221
|
+
A pattern language has to carry the largest set of features that the nine target routers can express, and not the subset that this repository happens to use today. A count of the patterns HERE — 85 of 88 are a literal plus `:name` — measures our own habits, and it is the wrong basis for the decision. `URLPattern` is the most expressive engine available, and a matcher of our own would carry less.
|
|
222
|
+
|
|
223
|
+
Two matchers that disagree is also a worse failure than one dependency. The match and the extraction of the params would then read the same pattern differently, and a route would resolve while its params came back empty.
|
|
224
|
+
|
|
225
|
+
---
|
|
226
|
+
|
|
227
|
+
## Summary
|
|
228
|
+
|
|
229
|
+
| Question | Answer |
|
|
230
|
+
| ----------------------------------------- | --------------------------------------------------------------- |
|
|
231
|
+
| What is the pattern language? | The `URLPattern` pathname grammar, plus hyphenated param names |
|
|
232
|
+
| Do I install a polyfill? | No. `@xmachines/play-router` carries one |
|
|
233
|
+
| Which side turns a URL into a state? | XMachines, in every adapter |
|
|
234
|
+
| Which side turns a state into a URL? | XMachines, with no URLPattern at all |
|
|
235
|
+
| When does the framework parse the params? | Vue Router and SolidJS Router, when the parse covers every name |
|
|
236
|
+
| Who releases the bridge? | You, through `disconnect()` in the teardown of your component |
|
|
237
|
+
|
|
238
|
+
## See also
|
|
239
|
+
|
|
240
|
+
- [Understanding State Machines](state-machines.md) — how `meta.route` reaches the route map
|
|
241
|
+
- [Understanding TC39 Signals](signals.md) — the same decision, made for reactivity
|
|
242
|
+
- [Multi-router integration](../examples/multi-router-integration.md) — the provider pattern and `basePath`, end to end
|
|
243
|
+
- [Routing patterns](../examples/routing-patterns.md) — worked route maps
|
|
244
|
+
- [@xmachines/play-router](../api/@xmachines/play-router/README.md) — API reference
|
|
245
|
+
- [URLPattern on MDN](https://developer.mozilla.org/en-US/docs/Web/API/URLPattern) — the standard
|
package/guides/state-machines.md
CHANGED
|
@@ -77,7 +77,7 @@ Key patterns:
|
|
|
77
77
|
XMachines extends XState's `meta` field on each state node. This is where routing intent and view structure live:
|
|
78
78
|
|
|
79
79
|
```typescript
|
|
80
|
-
import { typedSpec } from "@xmachines/play-
|
|
80
|
+
import { typedSpec } from "@xmachines/play-view";
|
|
81
81
|
|
|
82
82
|
const appMachine = setup({/* ... */}).createMachine({
|
|
83
83
|
id: "app",
|
|
@@ -122,7 +122,7 @@ const appMachine = setup({/* ... */}).createMachine({
|
|
|
122
122
|
|
|
123
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.
|
|
124
124
|
|
|
125
|
-
`meta.view` is a [`PlaySpec`](../api/@xmachines/play-
|
|
125
|
+
`meta.view` is a [`PlaySpec`](../api/@xmachines/play-view/index/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
126
|
|
|
127
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.
|
|
128
128
|
|
|
@@ -130,7 +130,7 @@ The machine's whole context is available to every view through the **`/context`
|
|
|
130
130
|
|
|
131
131
|
---
|
|
132
132
|
|
|
133
|
-
## [`formatPlayRouteTransitions`](../api/@xmachines/play-xstate/functions/formatPlayRouteTransitions.md) — automatic route event wiring
|
|
133
|
+
## [`formatPlayRouteTransitions`](../api/@xmachines/play-xstate/with-routing/functions/formatPlayRouteTransitions.md) — automatic route event wiring
|
|
134
134
|
|
|
135
135
|
For routing to work, the machine must respond to `play.route` events (sent by router bridges when the user navigates). Writing these transitions by hand is mechanical:
|
|
136
136
|
|
|
@@ -150,10 +150,10 @@ states: {
|
|
|
150
150
|
}
|
|
151
151
|
```
|
|
152
152
|
|
|
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
|
+
[`formatPlayRouteTransitions`](../api/@xmachines/play-xstate/with-routing/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:
|
|
154
154
|
|
|
155
155
|
```typescript
|
|
156
|
-
import { formatPlayRouteTransitions } from "@xmachines/play-xstate";
|
|
156
|
+
import { formatPlayRouteTransitions } from "@xmachines/play-xstate/routing";
|
|
157
157
|
|
|
158
158
|
const appMachine = setup({/* ... */}).createMachine(
|
|
159
159
|
formatPlayRouteTransitions({
|
|
@@ -168,7 +168,7 @@ const appMachine = setup({/* ... */}).createMachine(
|
|
|
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
|
+
[`formatPlayRouteTransitions`](../api/@xmachines/play-xstate/with-routing/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):
|
|
172
172
|
|
|
173
173
|
```typescript
|
|
174
174
|
types: {
|
|
@@ -200,16 +200,15 @@ Guards are evaluated by XState before a transition fires. If the guard returns `
|
|
|
200
200
|
|
|
201
201
|
This is the **Actor Authority** invariant in practice: the machine decides, infrastructure adjusts.
|
|
202
202
|
|
|
203
|
-
|
|
203
|
+
Compose a condition with the combinators of XState:
|
|
204
204
|
|
|
205
|
-
| Function
|
|
206
|
-
|
|
|
207
|
-
|
|
|
208
|
-
|
|
|
209
|
-
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
| [`eventMatches(type)`](../api/@xmachines/play-xstate/functions/eventMatches.md) | Checks the event type |
|
|
205
|
+
| Function | What it does |
|
|
206
|
+
| --------------- | --------------------------- |
|
|
207
|
+
| `and([g1, g2])` | AND — every guard must pass |
|
|
208
|
+
| `or([g1, g2])` | OR — one guard must pass |
|
|
209
|
+
| `not(g)` | NOT — it inverts the guard |
|
|
210
|
+
|
|
211
|
+
Each combinator resolves a guard NAME against the `guards` of `setup()`, so a name that the map does not hold fails to compile.
|
|
213
212
|
|
|
214
213
|
---
|
|
215
214
|
|
|
@@ -259,7 +258,7 @@ actor.start();
|
|
|
259
258
|
// Actor resumes from where it left off
|
|
260
259
|
```
|
|
261
260
|
|
|
262
|
-
[`definePlayer`](../api/@xmachines/play-xstate/functions/definePlayer.md) accepts an optional `restore` argument for this purpose. Restoration is useful for server-side rendering (hydrate with the server's snapshot), session persistence (resume after page reload), and testing (start from a known mid-flow state).
|
|
261
|
+
[`definePlayer`](../api/@xmachines/play-xstate/index/functions/definePlayer.md) accepts an optional `restore` argument for this purpose. Restoration is useful for server-side rendering (hydrate with the server's snapshot), session persistence (resume after page reload), and testing (start from a known mid-flow state).
|
|
263
262
|
|
|
264
263
|
---
|
|
265
264
|
|
|
@@ -281,6 +280,6 @@ actor.start();
|
|
|
281
280
|
- [Understanding TC39 Signals](signals.md) — how the actor's state is observed by infrastructure
|
|
282
281
|
- [Getting Started](getting-started.md) — step-by-step walkthrough building your first machine and actor
|
|
283
282
|
- [Routing Patterns](../examples/routing-patterns.md) — worked examples of `meta.route` and guards
|
|
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),
|
|
283
|
+
- [@xmachines/play-xstate](../api/@xmachines/play-xstate/README.md) — full API reference for [`definePlayer`](../api/@xmachines/play-xstate/index/functions/definePlayer.md), [`PlayerActor`](../api/@xmachines/play-xstate/index/classes/PlayerActor.md), and the routing utilities
|
|
285
284
|
- [XState v5 documentation](https://stately.ai/docs/xstate) — upstream state machine library documentation
|
|
286
285
|
- [Play RFC](../rfc/play.md) — complete architectural specification
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xmachines/docs",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.0",
|
|
4
4
|
"description": "Documentation for XMachines",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"documentation",
|
|
@@ -45,6 +45,7 @@
|
|
|
45
45
|
},
|
|
46
46
|
"scripts": {
|
|
47
47
|
"lint": "oxlint .",
|
|
48
|
+
"lint:security": "node ../../scripts/semgrep-scan.mjs",
|
|
48
49
|
"lint:fix": "oxlint --fix .",
|
|
49
50
|
"format": "oxfmt .",
|
|
50
51
|
"format:check": "oxfmt --check .",
|
|
@@ -53,16 +54,16 @@
|
|
|
53
54
|
"clean": "rm -rf coverage node_modules/.vite*"
|
|
54
55
|
},
|
|
55
56
|
"devDependencies": {
|
|
56
|
-
"@testing-library/jest-dom": "^
|
|
57
|
-
"@types/node": "^26.2
|
|
58
|
-
"oxfmt": "^0.
|
|
59
|
-
"oxlint": "^1.
|
|
60
|
-
"typedoc": "^0.28.
|
|
57
|
+
"@testing-library/jest-dom": "^7.0.1",
|
|
58
|
+
"@types/node": "^26.6.2",
|
|
59
|
+
"oxfmt": "^0.68.0",
|
|
60
|
+
"oxlint": "^1.83.0",
|
|
61
|
+
"typedoc": "^0.28.20",
|
|
61
62
|
"typedoc-plugin-llms-txt": "^0.1.2",
|
|
62
|
-
"typedoc-plugin-markdown": "^4.
|
|
63
|
-
"vitest": "^
|
|
63
|
+
"typedoc-plugin-markdown": "^4.13.0",
|
|
64
|
+
"vitest": "^5.0.1"
|
|
64
65
|
},
|
|
65
66
|
"engines": {
|
|
66
|
-
"node": ">=
|
|
67
|
+
"node": ">=24.0.0"
|
|
67
68
|
}
|
|
68
69
|
}
|