@xmachines/docs 2.2.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 +75 -97
- 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/index/functions/asCleanup.md +78 -0
- 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/index/type-aliases/Cleanup.md +38 -0
- package/api/@xmachines/play/index/type-aliases/DisposeKey.md +32 -0
- package/api/@xmachines/play/{type-aliases → index/type-aliases}/PlayEvent.md +4 -4
- package/api/@xmachines/play/index/variables/DISPOSE.md +34 -0
- package/api/@xmachines/play-actor/README.md +78 -222
- 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 +99 -43
- 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 +6 -6
- package/api/@xmachines/play-dom/functions/createRenderer.md +3 -3
- package/api/@xmachines/play-dom/interfaces/CreatePlayUIOptions.md +17 -11
- package/api/@xmachines/play-dom/interfaces/MountOptions.md +5 -4
- package/api/@xmachines/play-dom/interfaces/PlayDomOptions.md +14 -12
- package/api/@xmachines/play-dom/type-aliases/Cleanup.md +38 -0
- package/api/@xmachines/play-dom/type-aliases/MountFn.md +30 -8
- package/api/@xmachines/play-dom-router/README.md +99 -73
- 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 +7 -1
- package/api/@xmachines/play-dom-router/functions/createRouter.md +12 -6
- package/api/@xmachines/play-dom-router/interfaces/BasePathOptions.md +5 -5
- package/api/@xmachines/play-dom-router/interfaces/BrowserHistory.md +73 -19
- package/api/@xmachines/play-dom-router/interfaces/BrowserWindow.md +16 -16
- 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 +36 -7
- package/api/@xmachines/play-dom-router/interfaces/VanillaRouter.md +40 -6
- package/api/@xmachines/play-dom-router/type-aliases/Cleanup.md +38 -0
- package/api/@xmachines/play-dom-router/variables/DISPOSE.md +34 -0
- package/api/@xmachines/play-react/README.md +18 -40
- package/api/@xmachines/play-react/classes/PlayErrorBoundary.md +50 -11
- 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 +8 -6
- package/api/@xmachines/play-react/interfaces/PlayErrorBoundaryState.md +6 -5
- 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 +108 -189
- 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 +38 -9
- 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-router/index/variables/DISPOSE.md +34 -0
- 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-dom-router → play-router/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 +5 -25
- package/api/@xmachines/play-signals/functions/watchSignal.md +27 -4
- 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 +38 -0
- package/api/@xmachines/play-signals/type-aliases/WatcherNotify.md +1 -1
- package/api/@xmachines/play-solid/README.md +36 -35
- package/api/@xmachines/play-solid/functions/useActor.md +1 -1
- package/api/@xmachines/play-solid/functions/usePlayView.md +14 -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 +16 -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 +13 -28
- 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 +7 -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 +36 -7
- 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 +36 -7
- 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-view/index/functions/createFailureLatch.md +20 -0
- package/api/@xmachines/play-view/index/functions/createReportGuard.md +26 -0
- 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-view/index/functions/sameViewInputs.md +25 -0
- 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-view/index/interfaces/FailureLatch.md +60 -0
- package/api/@xmachines/{play-actor → play-view/index}/interfaces/PlaySpec.md +8 -8
- package/api/@xmachines/play-view/index/interfaces/ReportGuard.md +92 -0
- package/api/@xmachines/play-view/index/interfaces/ReportGuardMessages.md +18 -0
- package/api/@xmachines/{play-actor → play-view/index}/interfaces/ResolveViewStoreOptions.md +5 -5
- package/api/@xmachines/play-view/index/interfaces/ViewInputs.md +19 -0
- 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 +46 -42
- 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 +6 -1
- package/api/@xmachines/play-vue/interfaces/ActorProviderProps.md +13 -8
- package/api/@xmachines/play-vue/interfaces/PlayUIProviderProps.md +15 -10
- 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 +163 -98
- 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-xstate/index/variables/DISPOSE.md +34 -0
- 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 +97 -65
- package/contributing/configuration.md +142 -41
- package/contributing/deployment.md +30 -28
- package/contributing/development.md +94 -31
- package/contributing/testing.md +90 -31
- 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 +47 -44
- package/guides/inspector.md +4 -4
- package/guides/routing.md +245 -0
- package/guides/signals.md +43 -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-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/createRouteMap.md +0 -40
- 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 -34
- 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 -532
- 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
package/guides/actor-model.md
CHANGED
|
@@ -19,7 +19,7 @@ The boundary between them is enforced by the signal protocol: the actor exposes
|
|
|
19
19
|
```
|
|
20
20
|
Actor (business logic)
|
|
21
21
|
│
|
|
22
|
-
│ emits signals: state, currentRoute
|
|
22
|
+
│ emits signals: state, and currentRoute / currentView from its capabilities
|
|
23
23
|
▼
|
|
24
24
|
Infrastructure (runtime adapters)
|
|
25
25
|
├── Router Bridge — reflects currentRoute into the URL bar
|
|
@@ -33,20 +33,20 @@ Infrastructure → actor: only via actor.send({ type: "..." })
|
|
|
33
33
|
|
|
34
34
|
## What the actor owns
|
|
35
35
|
|
|
36
|
-
An actor in XMachines is a [`PlayerActor`](../api/@xmachines/play-xstate/classes/PlayerActor.md) — a concrete class that extends XState's `Actor` class via [`
|
|
36
|
+
An actor in XMachines is a [`PlayerActor`](../api/@xmachines/play-xstate/index/classes/PlayerActor.md) — a concrete class that extends XState's `Actor` class via [`PlayActor`](../api/@xmachines/play-actor/interfaces/PlayActor.md). It implements three reactive properties:
|
|
37
37
|
|
|
38
|
-
| Property | Type | What it is
|
|
39
|
-
| -------------------- | --------------------------------- |
|
|
40
|
-
| `actor.state` | `Signal.State<Snapshot>` | Updated on every XState transition. The full machine snapshot.
|
|
41
|
-
| `actor.currentRoute` | `Signal.Computed<string \| null>` | Derived from the active state node's `meta.route`.
|
|
42
|
-
| `actor.currentView` | `Signal.State<PlaySpec \| null>` | Updated on each transition. Holds the [`PlaySpec`](../api/@xmachines/play-
|
|
38
|
+
| Property | Type | What it is |
|
|
39
|
+
| -------------------- | --------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
40
|
+
| `actor.state` | `Signal.State<Snapshot>` | Updated on every XState transition. The full machine snapshot. |
|
|
41
|
+
| `actor.currentRoute` | `Signal.Computed<string \| null>` | Derived from the active state node's `meta.route`. Needs the routing capability. |
|
|
42
|
+
| `actor.currentView` | `Signal.State<PlaySpec \| null>` | Updated on each transition. Holds the [`PlaySpec`](../api/@xmachines/play-view/index/interfaces/PlaySpec.md) that drives renderers. Needs the view capability. |
|
|
43
43
|
|
|
44
44
|
All three are set by the actor, never by infrastructure. Infrastructure reads them via signals.
|
|
45
45
|
|
|
46
46
|
The actor also owns:
|
|
47
47
|
|
|
48
48
|
- **Guards** — it decides whether a transition is valid. If a router sends a `play.route` event for a path the actor's guards reject, the actor does not transition. It then emits its current valid route back through `currentRoute`, and the router bridge overwrites the URL to match.
|
|
49
|
-
- **Error states** — structured errors ([`PlayError`](../api/@xmachines/play/classes/PlayError.md)) are part of the actor's state graph, not thrown into the environment.
|
|
49
|
+
- **Error states** — structured errors ([`PlayError`](../api/@xmachines/play/errors/classes/PlayError.md)) are part of the actor's state graph, not thrown into the environment.
|
|
50
50
|
- **Initial route** — `actor.initialRoute` is the route the actor starts in. Router adapters use this for initial navigation, not the browser's current URL.
|
|
51
51
|
|
|
52
52
|
---
|
|
@@ -87,17 +87,19 @@ This is why the invariant is called **State-Driven Reset** in the Play RFC.
|
|
|
87
87
|
|
|
88
88
|
---
|
|
89
89
|
|
|
90
|
-
## [`
|
|
90
|
+
## [`PlayActor`](../api/@xmachines/play-actor/interfaces/PlayActor.md) — the enforced contract
|
|
91
91
|
|
|
92
|
-
[`
|
|
92
|
+
[`PlayActor`](../api/@xmachines/play-actor/interfaces/PlayActor.md) (from [`@xmachines/play-actor`](../api/@xmachines/play-actor/README.md)) is the contract that all actor implementations satisfy. It is an INTERFACE, and it names no state machine library.
|
|
93
|
+
|
|
94
|
+
An adapter extends the actor class of its own engine. [`PlayerActor`](../api/@xmachines/play-xstate/index/classes/PlayerActor.md) of [`@xmachines/play-xstate`](../api/@xmachines/play-xstate/README.md) extends `Actor` of XState, which means:
|
|
93
95
|
|
|
94
96
|
- XState's inspection API works ([`@statelyai/inspect`](https://stately.ai/docs/inspector) — see [Inspecting a Running Actor](inspector.md))
|
|
95
97
|
- XState DevTools attach to actors normally
|
|
96
98
|
- The full XState ecosystem (testing utilities, visualization) is compatible
|
|
97
99
|
|
|
98
|
-
[`
|
|
100
|
+
[`PlayActor`](../api/@xmachines/play-actor/interfaces/PlayActor.md) asks for two members: a reactive `state` property of type `Signal.State<TSnapshot>`, and a typed `send`. `state` is the single point where the pull-based snapshot API of an engine is bridged to the push-based signal system of TC39.
|
|
99
101
|
|
|
100
|
-
The two optional capability interfaces — [`Routable`](../api/@xmachines/play-
|
|
102
|
+
The two optional capability interfaces — [`Routable`](../api/@xmachines/play-router/index/interfaces/Routable.md) and [`Viewable`](../api/@xmachines/play-view/index/interfaces/Viewable.md) — are deliberately separate:
|
|
101
103
|
|
|
102
104
|
- Not every actor needs routing (e.g., a background data-sync actor).
|
|
103
105
|
- Not every actor drives a view (e.g., a sub-actor composed inside a parent).
|
|
@@ -105,26 +107,33 @@ The two optional capability interfaces — [`Routable`](../api/@xmachines/play-a
|
|
|
105
107
|
An actor implements only the capabilities it actually uses:
|
|
106
108
|
|
|
107
109
|
```typescript
|
|
108
|
-
// Minimal actor:
|
|
109
|
-
class MinimalActor
|
|
110
|
-
state = new Signal.State(
|
|
110
|
+
// Minimal actor: the contract alone, which is reactive state and send
|
|
111
|
+
class MinimalActor implements PlayActor<SomeSnapshot, SomeEvent> {
|
|
112
|
+
readonly state = new Signal.State<SomeSnapshot>(initial);
|
|
113
|
+
send(event: SomeEvent): void {
|
|
114
|
+
/* dispatch */
|
|
115
|
+
}
|
|
111
116
|
}
|
|
112
117
|
|
|
113
|
-
// Full actor:
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
+
// Full actor: the contract, the routing and the view. It extends the actor class of
|
|
119
|
+
// its own engine, and `PlayActor` stays out of the inheritance.
|
|
120
|
+
class PlayerActor
|
|
121
|
+
extends Actor<SomeMachine>
|
|
122
|
+
implements PlayActor<SomeSnapshot, SomeEvent>, Routable, Viewable
|
|
123
|
+
{
|
|
124
|
+
readonly state = new Signal.State(this.getSnapshot());
|
|
125
|
+
readonly currentRoute = new Signal.Computed(() => deriveRoute(this.state.get()));
|
|
126
|
+
readonly currentView = new Signal.State<PlaySpec | null>(null);
|
|
118
127
|
}
|
|
119
128
|
```
|
|
120
129
|
|
|
121
|
-
In practice you never write [`PlayerActor`](../api/@xmachines/play-xstate/classes/PlayerActor.md) yourself — [`definePlayer`](../api/@xmachines/play-xstate/functions/definePlayer.md) from [`@xmachines/play-xstate`](../api/@xmachines/play-xstate/README.md) creates one from your machine definition.
|
|
130
|
+
In practice you never write [`PlayerActor`](../api/@xmachines/play-xstate/index/classes/PlayerActor.md) yourself — [`definePlayer`](../api/@xmachines/play-xstate/index/functions/definePlayer.md) from [`@xmachines/play-xstate`](../api/@xmachines/play-xstate/README.md) creates one from your machine definition.
|
|
122
131
|
|
|
123
132
|
---
|
|
124
133
|
|
|
125
|
-
## [`definePlayer`](../api/@xmachines/play-xstate/functions/definePlayer.md) — the factory builder
|
|
134
|
+
## [`definePlayer`](../api/@xmachines/play-xstate/index/functions/definePlayer.md) — the factory builder
|
|
126
135
|
|
|
127
|
-
[`definePlayer({ machine })`](../api/@xmachines/play-xstate/functions/definePlayer.md) is the primary entry point for creating actors:
|
|
136
|
+
[`definePlayer({ machine })`](../api/@xmachines/play-xstate/index/functions/definePlayer.md) is the primary entry point for creating actors:
|
|
128
137
|
|
|
129
138
|
```typescript
|
|
130
139
|
import { definePlayer } from "@xmachines/play-xstate";
|
|
@@ -137,7 +146,7 @@ const actor = createPlayer();
|
|
|
137
146
|
actor.start();
|
|
138
147
|
```
|
|
139
148
|
|
|
140
|
-
[`definePlayer`](../api/@xmachines/play-xstate/functions/definePlayer.md) returns a **factory function**, not an actor. This is intentional: it lets you create multiple independent instances (e.g., one per test, one per user session) without re-processing the machine definition each time.
|
|
149
|
+
[`definePlayer`](../api/@xmachines/play-xstate/index/functions/definePlayer.md) returns a **factory function**, not an actor. This is intentional: it lets you create multiple independent instances (e.g., one per test, one per user session) without re-processing the machine definition each time.
|
|
141
150
|
|
|
142
151
|
The factory accepts optional `input` (initial context overrides) and a `restore` snapshot (for resumable sessions):
|
|
143
152
|
|
|
@@ -175,6 +184,6 @@ The Play RFC captures the actor/infrastructure split in a single statement:
|
|
|
175
184
|
- [Understanding TC39 Signals](signals.md) — how the actor communicates with infrastructure
|
|
176
185
|
- [Understanding State Machines](state-machines.md) — how the machine definition drives actor behavior
|
|
177
186
|
- [Getting Started](getting-started.md) — hands-on walkthrough creating and starting an actor
|
|
178
|
-
- [@xmachines/play-actor](../api/@xmachines/play-actor/README.md) — API reference for [`
|
|
179
|
-
- [@xmachines/play-xstate](../api/@xmachines/play-xstate/README.md) — API reference for [`definePlayer`](../api/@xmachines/play-xstate/functions/definePlayer.md) and [`PlayerActor`](../api/@xmachines/play-xstate/classes/PlayerActor.md)
|
|
187
|
+
- [@xmachines/play-actor](../api/@xmachines/play-actor/README.md) — API reference for [`PlayActor`](../api/@xmachines/play-actor/interfaces/PlayActor.md)
|
|
188
|
+
- [@xmachines/play-xstate](../api/@xmachines/play-xstate/README.md) — API reference for [`definePlayer`](../api/@xmachines/play-xstate/index/functions/definePlayer.md) and [`PlayerActor`](../api/@xmachines/play-xstate/index/classes/PlayerActor.md)
|
|
180
189
|
- [Play RFC](../rfc/play.md) — complete architectural specification
|
|
@@ -20,13 +20,13 @@ You need the following installed before cloning the repository:
|
|
|
20
20
|
|
|
21
21
|
| Requirement | Version | Notes |
|
|
22
22
|
| ----------- | ------------------ | --------------------------------------------------------------------------------------------------------------------- |
|
|
23
|
-
| Node.js | `>=
|
|
23
|
+
| Node.js | `>= 24.0.0` | The floor to develop AND to consume. Every `package.json` `engines` field declares it. |
|
|
24
24
|
| pnpm | via corepack | Enable with `corepack enable`; the version is pinned by the `packageManager` field. The project uses pnpm workspaces. |
|
|
25
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
|
|
|
29
|
-
> **Node.js version manager tip:** If you manage multiple Node versions with `nvm` or `fnm`, install and activate Node
|
|
29
|
+
> **Node.js version manager tip:** If you manage multiple Node versions with `nvm` or `fnm`, install and activate Node 24 before proceeding.
|
|
30
30
|
|
|
31
31
|
### Installation Steps
|
|
32
32
|
|
|
@@ -68,7 +68,7 @@ All tests should pass on a freshly cloned and built repository. If they do, your
|
|
|
68
68
|
|
|
69
69
|
### Dev Container (Optional)
|
|
70
70
|
|
|
71
|
-
A fully configured dev container is provided at `.devcontainer/`. It uses Docker Compose with a Node
|
|
71
|
+
A fully configured dev container is provided at `.devcontainer/`. It uses Docker Compose with a Node 24 Bookworm base image and includes Docker-outside-of-Docker, Claude Code, and OpenCode pre-installed.
|
|
72
72
|
|
|
73
73
|
**VS Code:** Open the repository and choose **Reopen in Container** when prompted.
|
|
74
74
|
|
|
@@ -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
|