@xmachines/docs 4.0.0 → 5.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 -6
- package/api/@xmachines/play/README.md +21 -21
- package/api/@xmachines/play/errors/classes/NonNullableError.md +4 -4
- package/api/@xmachines/play/errors/classes/PlayError.md +5 -4
- package/api/@xmachines/play/index/README.md +2 -2
- package/api/@xmachines/play/index/functions/asCleanup.md +4 -5
- package/api/@xmachines/play/index/functions/assertNonNullable.md +1 -1
- package/api/@xmachines/play/index/functions/shallowEqualExcept.md +1 -1
- package/api/@xmachines/play/index/type-aliases/Cleanup.md +3 -3
- package/api/@xmachines/play/index/type-aliases/DisposeKey.md +1 -1
- package/api/@xmachines/play/index/type-aliases/PlayEvent.md +2 -2
- package/api/@xmachines/play/index/variables/DISPOSE.md +1 -1
- package/api/@xmachines/play-actor/README.md +9 -9
- package/api/@xmachines/play-actor/interfaces/ActorEvent.md +2 -2
- package/api/@xmachines/play-actor/interfaces/PlayActor.md +6 -6
- package/api/@xmachines/play-atom/README.md +281 -0
- package/api/@xmachines/play-atom/functions/watchAtom.md +79 -0
- package/api/@xmachines/play-atom/interfaces/AsyncAtomOptions.md +16 -0
- package/api/@xmachines/play-atom/interfaces/Atom.md +149 -0
- package/api/@xmachines/play-atom/interfaces/AtomObserver.md +25 -0
- package/api/@xmachines/play-atom/interfaces/AtomOptions.md +33 -0
- package/api/@xmachines/play-atom/interfaces/AtomSubscription.md +23 -0
- package/api/@xmachines/play-atom/interfaces/BaseAtom.md +97 -0
- package/api/@xmachines/play-atom/interfaces/CreateAtom.md +91 -0
- package/api/@xmachines/play-atom/interfaces/Readable.md +93 -0
- package/api/@xmachines/play-atom/interfaces/ReadonlyAtom.md +108 -0
- package/api/@xmachines/play-atom/type-aliases/AnyAtom.md +13 -0
- package/api/@xmachines/play-atom/type-aliases/AsyncAtomState.md +32 -0
- package/api/@xmachines/{play-signals → play-atom}/type-aliases/Cleanup.md +4 -4
- package/api/@xmachines/play-atom/variables/createAsyncAtom.md +42 -0
- package/api/@xmachines/play-atom/variables/createAtom.md +18 -0
- package/api/@xmachines/play-atom/variables/createWritableAtom.md +70 -0
- package/api/@xmachines/play-dom/README.md +21 -17
- package/api/@xmachines/play-dom/classes/PlayRenderer.md +10 -10
- package/api/@xmachines/play-dom/functions/asCleanup.md +4 -5
- package/api/@xmachines/play-dom/functions/createPlayUI.md +1 -1
- package/api/@xmachines/play-dom/functions/createRenderer.md +1 -1
- package/api/@xmachines/play-dom/interfaces/CreatePlayUIOptions.md +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 +3 -3
- package/api/@xmachines/play-dom/type-aliases/MountFn.md +1 -1
- package/api/@xmachines/play-dom-router/README.md +24 -24
- package/api/@xmachines/play-dom-router/classes/DomRouterBridge.md +15 -15
- package/api/@xmachines/play-dom-router/classes/RouteMap.md +11 -11
- package/api/@xmachines/play-dom-router/functions/asCleanup.md +4 -5
- package/api/@xmachines/play-dom-router/functions/connectRouter.md +1 -1
- package/api/@xmachines/play-dom-router/functions/createBrowserHistory.md +1 -1
- package/api/@xmachines/play-dom-router/functions/createRouter.md +1 -1
- package/api/@xmachines/play-dom-router/interfaces/BasePathOptions.md +3 -7
- package/api/@xmachines/play-dom-router/interfaces/BrowserHistory.md +15 -15
- package/api/@xmachines/play-dom-router/interfaces/BrowserWindow.md +14 -14
- package/api/@xmachines/play-dom-router/interfaces/ConnectRouterOptions.md +11 -9
- package/api/@xmachines/play-dom-router/interfaces/PlayRouteEvent.md +7 -7
- package/api/@xmachines/play-dom-router/interfaces/RoutableActor.md +6 -6
- package/api/@xmachines/play-dom-router/interfaces/RouteLookupContract.md +3 -3
- package/api/@xmachines/play-dom-router/interfaces/RouteMapOptions.md +10 -4
- package/api/@xmachines/play-dom-router/interfaces/RouteMapping.md +3 -3
- package/api/@xmachines/play-dom-router/interfaces/RouterBridge.md +15 -17
- package/api/@xmachines/play-dom-router/interfaces/RouterConnection.md +7 -7
- package/api/@xmachines/play-dom-router/interfaces/VanillaRouter.md +5 -5
- package/api/@xmachines/play-dom-router/type-aliases/Cleanup.md +3 -3
- package/api/@xmachines/play-dom-router/variables/DISPOSE.md +1 -1
- package/api/@xmachines/play-pattern/README.md +115 -0
- package/api/@xmachines/play-pattern/functions/buildPath.md +46 -0
- package/api/@xmachines/play-pattern/functions/createPatternCache.md +47 -0
- package/api/@xmachines/play-pattern/functions/getIndexKey.md +30 -0
- package/api/@xmachines/play-pattern/functions/isDotSegment.md +40 -0
- package/api/@xmachines/play-pattern/functions/parsePattern.md +28 -0
- package/api/@xmachines/play-pattern/interfaces/GroupPart.md +15 -0
- package/api/@xmachines/play-pattern/interfaces/LiteralPart.md +14 -0
- package/api/@xmachines/play-pattern/interfaces/ParamPart.md +21 -0
- package/api/@xmachines/play-pattern/interfaces/ParseOptions.md +19 -0
- package/api/@xmachines/play-pattern/interfaces/ParsedPattern.md +23 -0
- package/api/@xmachines/play-pattern/interfaces/PatternCache.md +65 -0
- package/api/@xmachines/play-pattern/interfaces/PatternParam.md +15 -0
- package/api/@xmachines/play-pattern/type-aliases/PathBuildResult.md +74 -0
- package/api/@xmachines/play-pattern/type-aliases/PathParams.md +15 -0
- package/api/@xmachines/play-pattern/type-aliases/PatternModifier.md +11 -0
- package/api/@xmachines/play-pattern/type-aliases/PatternPart.md +9 -0
- package/api/@xmachines/play-react/README.md +31 -21
- package/api/@xmachines/play-react/classes/PlayErrorBoundary.md +6 -6
- package/api/@xmachines/play-react/functions/useActor.md +1 -1
- package/api/@xmachines/play-react/functions/useAtomEffect.md +103 -0
- package/api/@xmachines/play-react/functions/usePlayView.md +1 -1
- package/api/@xmachines/play-react/interfaces/ActorProviderProps.md +8 -8
- 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 +8 -8
- package/api/@xmachines/play-react/interfaces/ViewContextValue.md +5 -5
- package/api/@xmachines/play-react/type-aliases/AnyPlayActor.md +1 -1
- package/api/@xmachines/play-react/variables/ActorProvider.md +2 -2
- package/api/@xmachines/play-react/variables/PlayRenderer.md +1 -1
- package/api/@xmachines/play-react/variables/PlayUIProvider.md +1 -1
- package/api/@xmachines/play-react-router/README.md +3 -3
- package/api/@xmachines/play-react-router/classes/ReactRouterBridge.md +15 -15
- package/api/@xmachines/play-react-router/classes/RouteMap.md +11 -11
- package/api/@xmachines/play-react-router/functions/createPlayRouterProvider.md +1 -1
- package/api/@xmachines/play-react-router/functions/createRouteMapFromTree.md +5 -5
- package/api/@xmachines/play-react-router/interfaces/PlayRouteEvent.md +7 -7
- package/api/@xmachines/play-react-router/interfaces/PlayRouterProviderProps.md +11 -9
- package/api/@xmachines/play-react-router/interfaces/RoutableActor.md +6 -6
- package/api/@xmachines/play-react-router/interfaces/RouteMapOptions.md +10 -4
- package/api/@xmachines/play-react-router/interfaces/RouteMapping.md +3 -3
- package/api/@xmachines/play-react-router/interfaces/RouterBridge.md +15 -17
- package/api/@xmachines/play-react-router/type-aliases/PlayRouterBridgeConstructor.md +14 -7
- package/api/@xmachines/play-react-router/type-aliases/PlayRouterProviderBaseProps.md +1 -1
- package/api/@xmachines/play-react-router/variables/PlayRouterProvider.md +1 -1
- package/api/@xmachines/play-router/README.md +25 -14
- package/api/@xmachines/play-router/errors/classes/DuplicateBridgeError.md +4 -4
- package/api/@xmachines/play-router/errors/classes/DuplicateRoutePathError.md +5 -5
- package/api/@xmachines/play-router/errors/classes/EmptyRoutePathError.md +5 -5
- package/api/@xmachines/play-router/errors/classes/InvalidBasePathError.md +5 -5
- package/api/@xmachines/play-router/errors/classes/InvalidRoutePatternError.md +5 -5
- package/api/@xmachines/play-router/errors/classes/InvalidStateIdError.md +5 -5
- package/api/@xmachines/play-router/errors/classes/MissingBasePathParamError.md +6 -6
- package/api/@xmachines/play-router/errors/classes/RouterSyncError.md +4 -4
- package/api/@xmachines/play-router/errors/classes/UnknownStateTypeError.md +6 -6
- package/api/@xmachines/play-router/index/README.md +10 -2
- package/api/@xmachines/play-router/index/classes/RouteMap.md +11 -11
- package/api/@xmachines/play-router/index/classes/RouterBridgeBase.md +10 -10
- package/api/@xmachines/play-router/index/functions/buildPlayRouteEvent.md +1 -1
- package/api/@xmachines/play-router/index/functions/buildRouteTree.md +1 -1
- package/api/@xmachines/play-router/index/functions/cleanFrameworkParams.md +1 -1
- package/api/@xmachines/play-router/index/functions/createPatternCache.md +47 -0
- package/api/@xmachines/play-router/index/functions/createRouteMapFromTree.md +5 -5
- package/api/@xmachines/play-router/index/functions/createRouterConnection.md +1 -1
- package/api/@xmachines/play-router/index/functions/detectDuplicateRoutes.md +1 -1
- package/api/@xmachines/play-router/index/functions/extractQuery.md +1 -1
- package/api/@xmachines/play-router/index/functions/extractRouteParams.md +7 -6
- package/api/@xmachines/play-router/index/functions/findRouteById.md +1 -1
- package/api/@xmachines/play-router/index/functions/findRouteByPath.md +13 -6
- package/api/@xmachines/play-router/index/functions/isMountableBridge.md +1 -1
- package/api/@xmachines/play-router/index/functions/joinBasePath.md +2 -1
- package/api/@xmachines/play-router/index/functions/mountKey.md +1 -1
- package/api/@xmachines/play-router/index/functions/normalizeBasePath.md +1 -1
- package/api/@xmachines/play-router/index/functions/openProviderBridge.md +3 -3
- package/api/@xmachines/play-router/index/functions/parsePattern.md +28 -0
- package/api/@xmachines/play-router/index/functions/pickOwnParams.md +1 -1
- package/api/@xmachines/play-router/index/functions/repointProviderBridge.md +1 -1
- package/api/@xmachines/play-router/index/functions/resolveBasePath.md +1 -1
- package/api/@xmachines/play-router/index/functions/resolveFrameworkParams.md +5 -5
- package/api/@xmachines/play-router/index/functions/sanitizePathname.md +9 -24
- package/api/@xmachines/play-router/index/functions/splitLocation.md +37 -0
- package/api/@xmachines/play-router/index/functions/stripBasePath.md +1 -1
- package/api/@xmachines/play-router/index/functions/validateRouteFormat.md +1 -1
- package/api/@xmachines/play-router/index/functions/validateStateExists.md +1 -1
- package/api/@xmachines/play-router/index/interfaces/BasePathOptions.md +4 -4
- package/api/@xmachines/play-router/index/interfaces/BuildPlayRouteEventOptions.md +4 -4
- package/api/@xmachines/play-router/index/interfaces/CompileOptions.md +35 -0
- package/api/@xmachines/play-router/index/interfaces/FrameworkParamsSource.md +13 -8
- package/api/@xmachines/play-router/index/interfaces/LocationLike.md +3 -3
- package/api/@xmachines/play-router/index/interfaces/MountableRouterBridge.md +9 -9
- package/api/@xmachines/play-router/index/interfaces/OpenProviderBridgeArgs.md +11 -9
- package/api/@xmachines/play-router/index/interfaces/ParseOptions.md +24 -0
- package/api/@xmachines/play-router/index/interfaces/ParsedPattern.md +23 -0
- package/api/@xmachines/play-router/index/interfaces/PatternCache.md +65 -0
- package/api/@xmachines/play-router/index/interfaces/PlayRouteEvent.md +7 -7
- package/api/@xmachines/play-router/index/interfaces/PlayRouterProviderBaseProps.md +15 -9
- package/api/@xmachines/play-router/index/interfaces/ResolvedBasePath.md +3 -3
- package/api/@xmachines/play-router/index/interfaces/ResolvedRoutePath.md +3 -3
- package/api/@xmachines/play-router/index/interfaces/Routable.md +5 -5
- package/api/@xmachines/play-router/index/interfaces/RoutableActor.md +6 -6
- package/api/@xmachines/play-router/index/interfaces/RouteInfo.md +8 -8
- package/api/@xmachines/play-router/index/interfaces/RouteMapOptions.md +10 -4
- package/api/@xmachines/play-router/index/interfaces/RouteMapping.md +3 -3
- package/api/@xmachines/play-router/index/interfaces/RouteMatch.md +3 -3
- package/api/@xmachines/play-router/index/interfaces/RouteNode.md +10 -10
- package/api/@xmachines/play-router/index/interfaces/RouteObject.md +5 -5
- package/api/@xmachines/play-router/index/interfaces/RouteTree.md +5 -5
- package/api/@xmachines/play-router/index/interfaces/RouteWatcherHandle.md +11 -11
- package/api/@xmachines/play-router/index/interfaces/RouterBridge.md +15 -17
- package/api/@xmachines/play-router/index/interfaces/RouterBridgeOptions.md +31 -0
- package/api/@xmachines/play-router/index/interfaces/RouterConnection.md +7 -7
- package/api/@xmachines/play-router/index/interfaces/SplitLocation.md +16 -0
- package/api/@xmachines/play-router/index/interfaces/WindowLike.md +3 -3
- package/api/@xmachines/play-router/index/type-aliases/PlayRouterBridgeConstructor.md +14 -7
- package/api/@xmachines/play-router/index/type-aliases/RouteData.md +1 -1
- package/api/@xmachines/play-router/index/type-aliases/RouteDataResolver.md +1 -1
- package/api/@xmachines/play-router/index/type-aliases/RouteMetadata.md +1 -1
- package/api/@xmachines/play-router/index/type-aliases/URLPatternLike.md +68 -0
- package/api/@xmachines/play-router/index/variables/DISPOSE.md +1 -1
- package/api/@xmachines/play-router/index/variables/NO_BASE_PATH.md +1 -1
- package/api/@xmachines/play-router/index/variables/ROOT_NODE_ID.md +1 -1
- package/api/@xmachines/play-router/xstate/functions/createRouteMap.md +5 -5
- package/api/@xmachines/play-router/xstate/functions/extractMachineRoutes.md +6 -5
- package/api/@xmachines/play-router/xstate/functions/getNavigableRoutes.md +1 -1
- package/api/@xmachines/play-router/xstate/functions/getRoutableRoutes.md +1 -1
- package/api/@xmachines/play-router/xstate/functions/getRouteMappings.md +1 -1
- package/api/@xmachines/play-router/xstate/functions/getTransitionReachableRoutes.md +1 -1
- package/api/@xmachines/play-router/xstate/functions/isRouteReachable.md +1 -1
- package/api/@xmachines/play-router/xstate/functions/machineToGraph.md +1 -1
- package/api/@xmachines/play-router/xstate/functions/routeExists.md +1 -1
- package/api/@xmachines/play-router/xstate/interfaces/MachineEdgeData.md +3 -3
- package/api/@xmachines/play-router/xstate/interfaces/MachineNodeData.md +5 -5
- package/api/@xmachines/play-router/xstate/type-aliases/MachineGraph.md +1 -1
- package/api/@xmachines/play-solid/README.md +9 -5
- 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 +8 -8
- package/api/@xmachines/play-solid/interfaces/PlayUIProviderProps.md +8 -8
- package/api/@xmachines/play-solid/interfaces/ViewContextValue.md +5 -5
- package/api/@xmachines/play-solid/type-aliases/AnyPlayActor.md +1 -1
- package/api/@xmachines/play-solid/variables/ActorContext.md +1 -1
- package/api/@xmachines/play-solid/variables/ActorProvider.md +2 -2
- package/api/@xmachines/play-solid/variables/PlayRenderer.md +1 -1
- package/api/@xmachines/play-solid/variables/PlayUIProvider.md +1 -1
- package/api/@xmachines/play-solid-router/README.md +14 -14
- package/api/@xmachines/play-solid-router/classes/RouteMap.md +11 -11
- package/api/@xmachines/play-solid-router/classes/SolidRouterBridge.md +18 -18
- package/api/@xmachines/play-solid-router/functions/createPlayRouterProvider.md +1 -1
- package/api/@xmachines/play-solid-router/interfaces/PlayActor.md +6 -6
- package/api/@xmachines/play-solid-router/interfaces/PlayRouteEvent.md +7 -7
- package/api/@xmachines/play-solid-router/interfaces/PlayRouterProviderProps.md +11 -9
- package/api/@xmachines/play-solid-router/interfaces/RoutableActor.md +6 -6
- package/api/@xmachines/play-solid-router/interfaces/RouteMapOptions.md +10 -4
- package/api/@xmachines/play-solid-router/interfaces/RouteMapping.md +3 -3
- package/api/@xmachines/play-solid-router/interfaces/RouterBridge.md +15 -17
- package/api/@xmachines/play-solid-router/type-aliases/PlayRouterBridgeConstructor.md +14 -7
- package/api/@xmachines/play-solid-router/type-aliases/PlayRouterProviderBaseProps.md +1 -1
- package/api/@xmachines/play-solid-router/type-aliases/SolidRouterHooks.md +4 -4
- package/api/@xmachines/play-solid-router/variables/PlayRouterProvider.md +1 -1
- package/api/@xmachines/play-svelte/README.md +11 -7
- 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 +8 -8
- package/api/@xmachines/play-svelte/interfaces/DefineRegistryOptions.md +4 -4
- package/api/@xmachines/play-svelte/interfaces/PlayUIProviderProps.md +11 -11
- package/api/@xmachines/play-svelte/interfaces/ViewContextValue.md +5 -5
- package/api/@xmachines/play-svelte/type-aliases/AnyPlayActor.md +1 -1
- package/api/@xmachines/play-svelte-spa-router/README.md +14 -14
- package/api/@xmachines/play-svelte-spa-router/classes/RouteMap.md +11 -11
- package/api/@xmachines/play-svelte-spa-router/classes/SvelteSpaRouterBridge.md +15 -15
- package/api/@xmachines/play-svelte-spa-router/functions/connectRouter.md +1 -1
- package/api/@xmachines/play-svelte-spa-router/interfaces/BasePathOptions.md +3 -7
- package/api/@xmachines/play-svelte-spa-router/interfaces/ConnectRouterOptions.md +11 -9
- package/api/@xmachines/play-svelte-spa-router/interfaces/PlayRouteEvent.md +7 -7
- package/api/@xmachines/play-svelte-spa-router/interfaces/RoutableActor.md +6 -6
- package/api/@xmachines/play-svelte-spa-router/interfaces/RouteMapOptions.md +10 -4
- package/api/@xmachines/play-svelte-spa-router/interfaces/RouteMapping.md +3 -3
- package/api/@xmachines/play-svelte-spa-router/interfaces/RouterBridge.md +15 -17
- package/api/@xmachines/play-svelte-spa-router/interfaces/RouterConnection.md +7 -7
- package/api/@xmachines/play-svelte-spa-router/interfaces/WindowLike.md +3 -3
- package/api/@xmachines/play-sveltekit-router/README.md +17 -17
- package/api/@xmachines/play-sveltekit-router/classes/RouteMap.md +11 -11
- package/api/@xmachines/play-sveltekit-router/classes/SvelteKitRouterBridge.md +15 -15
- package/api/@xmachines/play-sveltekit-router/functions/connectRouter.md +1 -1
- package/api/@xmachines/play-sveltekit-router/interfaces/BasePathOptions.md +3 -7
- package/api/@xmachines/play-sveltekit-router/interfaces/ConnectRouterOptions.md +15 -23
- package/api/@xmachines/play-sveltekit-router/interfaces/LocationLike.md +3 -3
- package/api/@xmachines/play-sveltekit-router/interfaces/PlayRouteEvent.md +7 -7
- package/api/@xmachines/play-sveltekit-router/interfaces/RoutableActor.md +6 -6
- package/api/@xmachines/play-sveltekit-router/interfaces/RouteMapOptions.md +10 -4
- package/api/@xmachines/play-sveltekit-router/interfaces/RouteMapping.md +3 -3
- package/api/@xmachines/play-sveltekit-router/interfaces/RouterBridge.md +15 -17
- package/api/@xmachines/play-sveltekit-router/interfaces/RouterConnection.md +7 -7
- package/api/@xmachines/play-tanstack-react-router/README.md +7 -7
- package/api/@xmachines/play-tanstack-react-router/classes/RouteMap.md +11 -11
- package/api/@xmachines/play-tanstack-react-router/classes/TanStackReactRouterBridge.md +11 -11
- package/api/@xmachines/play-tanstack-react-router/functions/createPlayRouterProvider.md +1 -1
- package/api/@xmachines/play-tanstack-react-router/functions/createRouteMapFromTree.md +5 -5
- package/api/@xmachines/play-tanstack-react-router/interfaces/PlayRouteEvent.md +7 -7
- package/api/@xmachines/play-tanstack-react-router/interfaces/PlayRouterProviderProps.md +11 -9
- package/api/@xmachines/play-tanstack-react-router/interfaces/RoutableActor.md +6 -6
- package/api/@xmachines/play-tanstack-react-router/interfaces/RouteMapOptions.md +10 -4
- package/api/@xmachines/play-tanstack-react-router/interfaces/RouteMapping.md +3 -3
- package/api/@xmachines/play-tanstack-react-router/interfaces/RouterBridge.md +15 -17
- package/api/@xmachines/play-tanstack-react-router/type-aliases/PlayRouterBridgeConstructor.md +14 -7
- package/api/@xmachines/play-tanstack-react-router/type-aliases/PlayRouterProviderBaseProps.md +1 -1
- package/api/@xmachines/play-tanstack-react-router/type-aliases/TanStackRouterInstance.md +1 -1
- package/api/@xmachines/play-tanstack-react-router/type-aliases/TanStackRouterLike.md +5 -5
- package/api/@xmachines/play-tanstack-react-router/variables/PlayRouterProvider.md +1 -1
- package/api/@xmachines/play-tanstack-router/README.md +1 -1
- package/api/@xmachines/play-tanstack-router/classes/TanStackRouterBridgeBase.md +16 -16
- 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 +7 -7
- package/api/@xmachines/play-tanstack-solid-router/classes/RouteMap.md +11 -11
- package/api/@xmachines/play-tanstack-solid-router/classes/TanStackSolidRouterBridge.md +11 -11
- package/api/@xmachines/play-tanstack-solid-router/functions/createPlayRouterProvider.md +1 -1
- package/api/@xmachines/play-tanstack-solid-router/interfaces/PlayRouteEvent.md +7 -7
- package/api/@xmachines/play-tanstack-solid-router/interfaces/PlayRouterProviderProps.md +11 -9
- package/api/@xmachines/play-tanstack-solid-router/interfaces/RoutableActor.md +6 -6
- package/api/@xmachines/play-tanstack-solid-router/interfaces/RouteMapOptions.md +10 -4
- package/api/@xmachines/play-tanstack-solid-router/interfaces/RouteMapping.md +3 -3
- package/api/@xmachines/play-tanstack-solid-router/interfaces/RouterBridge.md +15 -17
- package/api/@xmachines/play-tanstack-solid-router/type-aliases/PlayRouterBridgeConstructor.md +14 -7
- package/api/@xmachines/play-tanstack-solid-router/type-aliases/PlayRouterProviderBaseProps.md +1 -1
- package/api/@xmachines/play-tanstack-solid-router/type-aliases/TanStackRouterInstance.md +1 -1
- package/api/@xmachines/play-tanstack-solid-router/type-aliases/TanStackRouterLike.md +5 -5
- package/api/@xmachines/play-tanstack-solid-router/variables/PlayRouterProvider.md +1 -1
- package/api/@xmachines/play-url/README.md +21 -15
- package/api/@xmachines/play-url/errors/classes/InvalidBasePathError.md +5 -5
- package/api/@xmachines/play-url/errors/classes/InvalidRoutePatternError.md +5 -5
- package/api/@xmachines/play-url/errors/classes/MissingBasePathParamError.md +6 -6
- package/api/@xmachines/play-url/index/README.md +15 -8
- package/api/@xmachines/play-url/index/functions/buildPath.md +46 -0
- package/api/@xmachines/play-url/index/functions/cleanFrameworkParams.md +1 -1
- package/api/@xmachines/play-url/index/functions/createPatternCache.md +47 -0
- package/api/@xmachines/play-url/index/functions/getCandidates.md +1 -1
- package/api/@xmachines/play-url/index/functions/getCompiledPattern.md +8 -7
- package/api/@xmachines/play-url/index/functions/getIndexKey.md +1 -1
- package/api/@xmachines/play-url/index/functions/holdsUnsubstitutedParam.md +2 -2
- package/api/@xmachines/play-url/index/functions/isDotSegment.md +40 -0
- package/api/@xmachines/play-url/index/functions/joinBasePath.md +2 -1
- package/api/@xmachines/play-url/index/functions/normalizeBasePath.md +1 -1
- package/api/@xmachines/play-url/index/functions/parsePattern.md +6 -5
- package/api/@xmachines/play-url/index/functions/pickOwnParams.md +1 -1
- package/api/@xmachines/play-url/index/functions/resolveBasePath.md +1 -1
- package/api/@xmachines/play-url/index/functions/resolveFrameworkParams.md +5 -5
- package/api/@xmachines/play-url/index/functions/sanitizePathname.md +27 -0
- package/api/@xmachines/play-url/index/functions/splitLocation.md +37 -0
- package/api/@xmachines/play-url/index/functions/stripBasePath.md +1 -1
- package/api/@xmachines/play-url/index/interfaces/BasePathOptions.md +3 -3
- package/api/@xmachines/play-url/index/interfaces/CompileOptions.md +21 -0
- package/api/@xmachines/play-url/index/interfaces/FrameworkParamsSource.md +13 -8
- package/api/@xmachines/play-url/index/interfaces/GroupPart.md +6 -6
- package/api/@xmachines/play-url/index/interfaces/LiteralPart.md +5 -5
- package/api/@xmachines/play-url/index/interfaces/ParamPart.md +9 -9
- package/api/@xmachines/play-url/index/interfaces/ParseOptions.md +24 -0
- package/api/@xmachines/play-url/index/interfaces/ParsedPattern.md +14 -14
- package/api/@xmachines/play-url/index/interfaces/PatternCache.md +65 -0
- package/api/@xmachines/play-url/index/interfaces/PatternParam.md +6 -6
- package/api/@xmachines/play-url/index/interfaces/ResolvedBasePath.md +3 -3
- package/api/@xmachines/play-url/index/interfaces/SplitLocation.md +16 -0
- package/api/@xmachines/play-url/index/type-aliases/PathBuildResult.md +74 -0
- package/api/@xmachines/play-url/index/type-aliases/PathParams.md +15 -0
- package/api/@xmachines/play-url/index/type-aliases/PatternModifier.md +1 -1
- package/api/@xmachines/play-url/index/type-aliases/PatternPart.md +1 -1
- package/api/@xmachines/play-url/index/type-aliases/URLPatternCtor.md +1 -1
- package/api/@xmachines/play-url/index/type-aliases/URLPatternLike.md +3 -3
- package/api/@xmachines/play-url/index/variables/NO_BASE_PATH.md +1 -1
- package/api/@xmachines/play-url/index/variables/URLPattern.md +1 -1
- package/api/@xmachines/play-view/README.md +19 -8
- package/api/@xmachines/play-view/errors/classes/ReadOnlyContextError.md +5 -5
- package/api/@xmachines/play-view/index/functions/attachRenderErrorHandler.md +1 -1
- package/api/@xmachines/play-view/index/functions/composePlayState.md +1 -1
- package/api/@xmachines/play-view/index/functions/createFailureLatch.md +1 -1
- package/api/@xmachines/play-view/index/functions/createReportGuard.md +1 -1
- package/api/@xmachines/play-view/index/functions/createViewStoreLifecycle.md +1 -1
- package/api/@xmachines/play-view/index/functions/guardContextWrites.md +4 -28
- package/api/@xmachines/play-view/index/functions/refreshContextSubtree.md +1 -1
- package/api/@xmachines/play-view/index/functions/reuseComposedState.md +1 -1
- package/api/@xmachines/play-view/index/functions/sameViewInputs.md +1 -1
- package/api/@xmachines/play-view/index/functions/toAtomState.md +1 -1
- package/api/@xmachines/play-view/index/functions/typedSpec.md +1 -1
- package/api/@xmachines/play-view/index/interfaces/BaseActorProviderProps.md +5 -5
- package/api/@xmachines/play-view/index/interfaces/BaseViewContextValue.md +5 -5
- package/api/@xmachines/play-view/index/interfaces/FailureLatch.md +3 -3
- package/api/@xmachines/play-view/index/interfaces/PlaySpec.md +2 -2
- package/api/@xmachines/play-view/index/interfaces/ReportGuard.md +5 -5
- package/api/@xmachines/play-view/index/interfaces/ReportGuardMessages.md +3 -3
- package/api/@xmachines/play-view/index/interfaces/ResolveViewStoreOptions.md +2 -2
- package/api/@xmachines/play-view/index/interfaces/ViewInputs.md +4 -4
- package/api/@xmachines/play-view/index/interfaces/ViewStoreLifecycle.md +3 -3
- package/api/@xmachines/play-view/index/interfaces/ViewStoreResolution.md +4 -4
- package/api/@xmachines/play-view/index/interfaces/Viewable.md +5 -5
- package/api/@xmachines/play-view/index/type-aliases/ViewActor.md +1 -1
- package/api/@xmachines/play-view/index/variables/CONTEXT_STATE_KEY.md +1 -1
- package/api/@xmachines/play-vue/README.md +13 -9
- 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 +6 -6
- package/api/@xmachines/play-vue/interfaces/PlayUIProviderProps.md +9 -9
- package/api/@xmachines/play-vue/interfaces/ViewContextValue.md +5 -5
- package/api/@xmachines/play-vue/type-aliases/AnyPlayActor.md +1 -1
- package/api/@xmachines/play-vue/type-aliases/ComponentEntry.md +1 -1
- package/api/@xmachines/play-vue/type-aliases/ComponentsMap.md +1 -1
- package/api/@xmachines/play-vue/type-aliases/DefineRegistryOptions.md +2 -2
- package/api/@xmachines/play-vue/variables/PlayRenderer.md +1 -1
- package/api/@xmachines/play-vue-router/README.md +12 -11
- package/api/@xmachines/play-vue-router/errors/classes/VueRouterNavigationError.md +4 -4
- package/api/@xmachines/play-vue-router/errors/classes/VueRouterSendError.md +4 -4
- package/api/@xmachines/play-vue-router/index/classes/RouteMap.md +11 -11
- package/api/@xmachines/play-vue-router/index/classes/VueRouterBridge.md +15 -15
- package/api/@xmachines/play-vue-router/index/interfaces/PlayRouteEvent.md +7 -7
- package/api/@xmachines/play-vue-router/index/interfaces/RoutableActor.md +6 -6
- package/api/@xmachines/play-vue-router/index/interfaces/RouteMapOptions.md +10 -4
- package/api/@xmachines/play-vue-router/index/interfaces/RouteMapping.md +3 -3
- package/api/@xmachines/play-vue-router/index/interfaces/RouterBridge.md +15 -17
- package/api/@xmachines/play-vue-router/index/variables/PlayRouterProvider.md +23 -1
- package/api/@xmachines/play-xstate/README.md +61 -30
- package/api/@xmachines/play-xstate/errors/README.md +1 -0
- package/api/@xmachines/play-xstate/errors/classes/ActorThrewNonErrorError.md +4 -4
- package/api/@xmachines/play-xstate/errors/classes/InvalidEventError.md +5 -5
- package/api/@xmachines/play-xstate/errors/classes/InvalidMachineError.md +4 -4
- package/api/@xmachines/play-xstate/errors/classes/InvalidRouteHandlerError.md +5 -5
- package/api/@xmachines/play-xstate/errors/classes/InvalidRouteMetadataError.md +5 -5
- package/api/@xmachines/play-xstate/errors/classes/InvalidRouteParamError.md +207 -0
- package/api/@xmachines/play-xstate/errors/classes/MissingRouteParamError.md +6 -6
- package/api/@xmachines/play-xstate/errors/classes/MissingStateIdError.md +6 -6
- package/api/@xmachines/play-xstate/index/README.md +2 -2
- package/api/@xmachines/play-xstate/index/classes/PlayerActor.md +41 -42
- package/api/@xmachines/play-xstate/index/functions/compose.md +4 -4
- package/api/@xmachines/play-xstate/index/functions/definePlayer.md +2 -2
- package/api/@xmachines/play-xstate/index/interfaces/PlayerConfig.md +4 -4
- package/api/@xmachines/play-xstate/index/interfaces/PlayerFactoryResumeOptions.md +2 -2
- package/api/@xmachines/play-xstate/index/interfaces/PlayerOptions.md +9 -9
- package/api/@xmachines/play-xstate/index/type-aliases/Capability.md +1 -1
- package/api/@xmachines/play-xstate/index/type-aliases/PlayerConstructor.md +1 -1
- package/api/@xmachines/play-xstate/index/type-aliases/PlayerFactory.md +1 -1
- package/api/@xmachines/play-xstate/index/variables/DISPOSE.md +1 -1
- package/api/@xmachines/play-xstate/with-routing/functions/buildRouteUrl.md +13 -6
- package/api/@xmachines/play-xstate/with-routing/functions/deriveRoute.md +1 -1
- package/api/@xmachines/play-xstate/with-routing/functions/formatPlayRouteTransitions.md +1 -1
- package/api/@xmachines/play-xstate/with-routing/functions/isAbsoluteRoute.md +1 -1
- package/api/@xmachines/play-xstate/with-routing/functions/withRouting.md +1 -1
- package/api/@xmachines/play-xstate/with-routing/interfaces/RouteContext.md +5 -5
- package/api/@xmachines/play-xstate/with-routing/interfaces/RouteObject.md +5 -5
- package/api/@xmachines/play-xstate/with-routing/type-aliases/RouteData.md +1 -1
- package/api/@xmachines/play-xstate/with-routing/type-aliases/RouteDataResolver.md +1 -1
- package/api/@xmachines/play-xstate/with-routing/type-aliases/RouteMachineConfig.md +4 -4
- package/api/@xmachines/play-xstate/with-routing/type-aliases/RouteMetadata.md +1 -1
- package/api/@xmachines/play-xstate/with-routing/type-aliases/RouteStateNode.md +5 -5
- package/api/@xmachines/play-xstate/with-view/functions/withView.md +6 -5
- 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 +1 -1
- package/api/@xmachines/shared/vitest/interfaces/XmBrowserConfigOptions.md +4 -4
- package/api/README.md +2 -1
- package/api/llms.txt +4 -3
- package/contributing/architecture.md +105 -124
- package/contributing/configuration.md +15 -15
- package/contributing/deployment.md +82 -6
- package/contributing/development.md +58 -30
- package/contributing/migrating-to-play-atom.md +209 -0
- package/contributing/testing.md +61 -64
- package/examples/README.md +3 -3
- package/examples/basic-state-machine.md +4 -4
- package/examples/form-validation.md +1 -1
- package/examples/multi-router-integration.md +23 -23
- package/examples/routing-patterns.md +5 -5
- package/examples/traffic-light.md +6 -6
- package/guides/README.md +1 -1
- package/guides/actor-model.md +26 -17
- package/guides/atoms.md +264 -0
- package/guides/getting-started.md +52 -17
- package/guides/inspector.md +3 -3
- package/guides/routing.md +67 -47
- package/guides/state-machines.md +4 -4
- package/package.json +3 -3
- package/rfc/play.md +83 -52
- package/api/@xmachines/play-react/functions/useSignalEffect.md +0 -77
- package/api/@xmachines/play-router/index/functions/getPatternParamNames.md +0 -29
- package/api/@xmachines/play-router/index/functions/getRequiredPatternParamNames.md +0 -39
- package/api/@xmachines/play-signals/README.md +0 -209
- package/api/@xmachines/play-signals/functions/watchSignal.md +0 -65
- package/api/@xmachines/play-signals/interfaces/ComputedOptions.md +0 -36
- package/api/@xmachines/play-signals/interfaces/SignalComputed.md +0 -49
- package/api/@xmachines/play-signals/interfaces/SignalOptions.md +0 -37
- package/api/@xmachines/play-signals/interfaces/SignalState.md +0 -68
- package/api/@xmachines/play-signals/interfaces/SignalWatcher.md +0 -97
- package/api/@xmachines/play-signals/namespaces/Signal/README.md +0 -22
- package/api/@xmachines/play-signals/namespaces/Signal/classes/Computed.md +0 -52
- package/api/@xmachines/play-signals/namespaces/Signal/classes/State.md +0 -72
- package/api/@xmachines/play-signals/namespaces/Signal/interfaces/Options.md +0 -19
- package/api/@xmachines/play-signals/namespaces/Signal/namespaces/subtle/README.md +0 -21
- package/api/@xmachines/play-signals/namespaces/Signal/namespaces/subtle/classes/Watcher.md +0 -85
- package/api/@xmachines/play-signals/namespaces/Signal/namespaces/subtle/functions/currentComputed.md +0 -13
- package/api/@xmachines/play-signals/namespaces/Signal/namespaces/subtle/functions/hasSinks.md +0 -19
- package/api/@xmachines/play-signals/namespaces/Signal/namespaces/subtle/functions/hasSources.md +0 -19
- package/api/@xmachines/play-signals/namespaces/Signal/namespaces/subtle/functions/introspectSinks.md +0 -19
- package/api/@xmachines/play-signals/namespaces/Signal/namespaces/subtle/functions/introspectSources.md +0 -19
- package/api/@xmachines/play-signals/namespaces/Signal/namespaces/subtle/functions/untrack.md +0 -25
- package/api/@xmachines/play-signals/namespaces/Signal/namespaces/subtle/variables/unwatched.md +0 -9
- package/api/@xmachines/play-signals/namespaces/Signal/namespaces/subtle/variables/watched.md +0 -9
- package/api/@xmachines/play-signals/namespaces/Signal/variables/isComputed.md +0 -19
- package/api/@xmachines/play-signals/namespaces/Signal/variables/isState.md +0 -19
- package/api/@xmachines/play-signals/namespaces/Signal/variables/isWatcher.md +0 -19
- package/api/@xmachines/play-signals/type-aliases/WatcherNotify.md +0 -33
- package/api/@xmachines/play-url/index/functions/getNormalizedParamNameMap.md +0 -32
- package/api/@xmachines/play-url/index/functions/getPatternParamNames.md +0 -29
- package/api/@xmachines/play-url/index/functions/getRequiredPatternParamNames.md +0 -39
- package/api/@xmachines/play-url/index/functions/isParameterizedPattern.md +0 -36
- package/api/@xmachines/play-url/index/functions/normalizeParamNames.md +0 -36
- package/guides/signals.md +0 -209
package/contributing/testing.md
CHANGED
|
@@ -6,11 +6,11 @@ This document describes the test framework, conventions, and CI integration for
|
|
|
6
6
|
|
|
7
7
|
The monorepo uses **[Vitest](https://vitest.dev/) `^5.0.1`** as its test framework, with **@vitest/coverage-v8** for coverage reporting and **@vitest/browser-playwright** (Playwright/Chromium) for browser-mode tests.
|
|
8
8
|
|
|
9
|
-
All packages extend the shared Vitest configuration helper `defineXmVitestConfig` (from `@xmachines/shared/vitest`) which automatically applies:
|
|
9
|
+
All packages extend the shared Vitest configuration helper `defineXmVitestConfig` (from [`@xmachines/shared/vitest`](../api/@xmachines/shared/README.md)) which automatically applies:
|
|
10
10
|
|
|
11
11
|
- `@xmachines/*` source aliases so imports resolve to source during test runs
|
|
12
|
-
- `@xmachines/shared/vitest-setup` — extends Vitest matchers with `@testing-library/jest-dom`
|
|
13
|
-
- `@xmachines/shared/vitest-node-setup` — enforces Node.js ≥ 24 on non-browser projects
|
|
12
|
+
- [`@xmachines/shared/vitest-setup`](../api/@xmachines/shared/README.md) — extends Vitest matchers with `@testing-library/jest-dom`
|
|
13
|
+
- [`@xmachines/shared/vitest-node-setup`](../api/@xmachines/shared/README.md) — enforces Node.js ≥ 24 on non-browser projects
|
|
14
14
|
|
|
15
15
|
**Auto-injected setup files:**
|
|
16
16
|
|
|
@@ -19,7 +19,7 @@ All packages extend the shared Vitest configuration helper `defineXmVitestConfig
|
|
|
19
19
|
| `packages/shared/config/vitest.node.setup.ts` | All non-browser projects | Validates Node.js ≥ 24 runtime; throws if wrong runtime |
|
|
20
20
|
| `packages/shared/config/vitest.setup.ts` | All projects | Imports `@testing-library/jest-dom/vitest` matchers |
|
|
21
21
|
|
|
22
|
-
`vitest.setup.ts` is also the one file that `@xmachines/shared/tsconfig-test` names in `files`, so its import puts the matcher TYPES in every test program. Each package overrides `include`, and `files` survives that.
|
|
22
|
+
`vitest.setup.ts` is also the one file that [`@xmachines/shared/tsconfig-test`](../api/@xmachines/shared/README.md) names in `files`, so its import puts the matcher TYPES in every test program. Each package overrides `include`, and `files` survives that.
|
|
23
23
|
|
|
24
24
|
### The jest-dom patch
|
|
25
25
|
|
|
@@ -141,21 +141,21 @@ packages/<name>/
|
|
|
141
141
|
|
|
142
142
|
### File naming conventions
|
|
143
143
|
|
|
144
|
-
| Extension | Purpose
|
|
145
|
-
| ---------------------------------------- |
|
|
146
|
-
| `.spec.ts` | Protocol enforcement tests; compile-time type safety tests; used in core packages (`play`, `play-actor`, `play-
|
|
147
|
-
| `.test.ts` | Unit, integration, and behavioral tests; used across all packages
|
|
148
|
-
| `.browser.test.ts` / `.browser.test.tsx` | Playwright browser environment tests; excluded from standard `vitest.config.ts`, only run via `vitest.browser.config.ts`
|
|
149
|
-
| `.typecheck.ts` (in `src/`) | Compile-time-only type assertion files; not Vitest test files; validated by `pnpm run test:build`
|
|
150
|
-
| `router-bridge-contract.ts` | Shared contract test runner; not a test file itself; imported by adapter test files
|
|
144
|
+
| Extension | Purpose |
|
|
145
|
+
| ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
|
|
146
|
+
| `.spec.ts` | Protocol enforcement tests; compile-time type safety tests; used in core packages (`play`, `play-actor`, `play-atom`, `play-xstate`) |
|
|
147
|
+
| `.test.ts` | Unit, integration, and behavioral tests; used across all packages |
|
|
148
|
+
| `.browser.test.ts` / `.browser.test.tsx` | Playwright browser environment tests; excluded from standard `vitest.config.ts`, only run via `vitest.browser.config.ts` |
|
|
149
|
+
| `.typecheck.ts` (in `src/`) | Compile-time-only type assertion files; not Vitest test files; validated by `pnpm run test:build` |
|
|
150
|
+
| `router-bridge-contract.ts` | Shared contract test runner; not a test file itself; imported by adapter test files |
|
|
151
151
|
|
|
152
152
|
### Test environments
|
|
153
153
|
|
|
154
|
-
| Environment | Packages
|
|
155
|
-
| ----------------------------- |
|
|
156
|
-
| `node` | Core logic: `@xmachines/play
|
|
157
|
-
| `jsdom` | UI renderers: `@xmachines/play-react
|
|
158
|
-
| Browser (Playwright/Chromium) | Browser-specific and E2E demo tests
|
|
154
|
+
| Environment | Packages |
|
|
155
|
+
| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
156
|
+
| `node` | Core logic: [`@xmachines/play`](../api/@xmachines/play/README.md), `play-actor`, `play-atom`, `play-xstate`, `play-router`, router adapters |
|
|
157
|
+
| `jsdom` | UI renderers: [`@xmachines/play-react`](../api/@xmachines/play-react/README.md), `play-vue`, `play-solid`, `play-svelte`, `play-dom` |
|
|
158
|
+
| Browser (Playwright/Chromium) | Browser-specific and E2E demo tests |
|
|
159
159
|
|
|
160
160
|
`defineXmVitestConfig` gives a jsdom project the `vmThreads` pool. The `forks` pool builds one jsdom for each test file, and a jsdom costs about 0.4 s. The `vmThreads` pool gives each file its own VM context in a worker that keeps the environment, so a worker builds one jsdom for all the files that it runs. Each file still gets a fresh module registry and fresh globals. The full `pnpm test` run takes 94 s with `vmThreads` and 160 s with `forks`, and the environment share of the tracked time drops from 42% to 14%.
|
|
161
161
|
|
|
@@ -167,15 +167,15 @@ A project that declares its own `pool` keeps it.
|
|
|
167
167
|
|
|
168
168
|
Isolation gives each test FILE its own worker: Vitest spawns a process, builds the environment, and evaluates the module graph one more time. That costs about 110 ms for each file, and the full `pnpm test` run takes 90 s with isolation on every project and 62 s with this rule.
|
|
169
169
|
|
|
170
|
-
A jsdom project keeps isolation and loses no time by it, because `vmThreads` above already gives one worker to many files. It also needs isolation: `isolate: false` shares the globals between the files of one worker, and three `@xmachines/play-react` tests fail under it.
|
|
170
|
+
A jsdom project keeps isolation and loses no time by it, because `vmThreads` above already gives one worker to many files. It also needs isolation: `isolate: false` shares the globals between the files of one worker, and three [`@xmachines/play-react`](../api/@xmachines/play-react/README.md) tests fail under it.
|
|
171
171
|
|
|
172
|
-
A worker that runs without isolation keeps ONE module registry for all the files that it runs, so `vi.mock` applies only while the worker has not yet loaded the real module. The order that the pool picks decides the winner, and the suite then fails on some runs and passes on others. `@xmachines/play-router` showed it: one file mocked `machine-to-graph.js` while twenty-five sibling files called the real module, and the package failed three tests on one run of the whole suite and twenty-five on the next. The file now builds a real machine, the package needs no isolation, and it runs in 1.0 s rather than 5.4 s.
|
|
172
|
+
A worker that runs without isolation keeps ONE module registry for all the files that it runs, so `vi.mock` applies only while the worker has not yet loaded the real module. The order that the pool picks decides the winner, and the suite then fails on some runs and passes on others. [`@xmachines/play-router`](../api/@xmachines/play-router/README.md) showed it: one file mocked `machine-to-graph.js` while twenty-five sibling files called the real module, and the package failed three tests on one run of the whole suite and twenty-five on the next. The file now builds a real machine, the package needs no isolation, and it runs in 1.0 s rather than 5.4 s.
|
|
173
173
|
|
|
174
174
|
**A project whose test files call `vi.mock`, `vi.doMock`, `vi.stubGlobal`, or `vi.stubEnv` declares `isolate: true` in its own `vitest.config.ts`, with the reason.** `tests/isolate-policy.test.ts` holds this rule true: it asks `vitest list` which project collects which file, reads `isolate` from the config module, and names the file and the config when the two disagree. The scan follows the relative imports of each test file and reads the setup files of the project, so a fixture that mocks a module cannot hide, and it reads each `@vitest-environment` docblock, which reaches no config. Two projects declare it today: the `play-sveltekit-router` demo, which mocks `$app/navigation`, and the `play-actor` shared example, which stubs `window`.
|
|
175
175
|
|
|
176
176
|
Prefer the other answer where you can reach it. A test that builds the real collaborator needs no isolation, and it costs the whole project nothing.
|
|
177
177
|
|
|
178
|
-
A project that gives SOME of its files another environment isolates for the same reason. Vitest builds and tears down that environment inside a worker that keeps its module registry, so a module evaluated against the jsdom of one file stays cached for the next one and holds a `window` that no longer exists. `@xmachines/play-react-router` runs three React files that way.
|
|
178
|
+
A project that gives SOME of its files another environment isolates for the same reason. Vitest builds and tears down that environment inside a worker that keeps its module registry, so a module evaluated against the jsdom of one file stays cached for the next one and holds a `window` that no longer exists. [`@xmachines/play-react-router`](../api/@xmachines/play-react-router/README.md) runs three React files that way.
|
|
179
179
|
|
|
180
180
|
A spy needs no isolation, and neither do fake timers. Each patches something that the test itself owns and restores, and neither depends on a fresh module registry.
|
|
181
181
|
|
|
@@ -187,8 +187,8 @@ pnpm exec vitest run --sequence.shuffle.files
|
|
|
187
187
|
|
|
188
188
|
### Test helpers and shared setup
|
|
189
189
|
|
|
190
|
-
-
|
|
191
|
-
-
|
|
190
|
+
- **[`@xmachines/shared/vitest-setup`](../api/@xmachines/shared/README.md)** — Injects `@testing-library/jest-dom` matchers. Applied automatically by `defineXmVitestConfig`.
|
|
191
|
+
- **[`@xmachines/shared/vitest-node-setup`](../api/@xmachines/shared/README.md)** — Enforces Node ≥ 24 at runtime. Auto-injected for non-browser configs.
|
|
192
192
|
- **`packages/play-react/test/test-utils.ts`** — React-specific test utilities for the `play-react` package.
|
|
193
193
|
- **`packages/play-router/examples/shared/`** and **`packages/play-actor/examples/shared/`** — Shared test fixtures for router and actor integration tests.
|
|
194
194
|
|
|
@@ -263,7 +263,6 @@ describe("ClassName or functionName()", () => {
|
|
|
263
263
|
|
|
264
264
|
```typescript
|
|
265
265
|
import { PlayActor } from "../src/abstract-actor.js";
|
|
266
|
-
import { Signal } from "@xmachines/play-signals";
|
|
267
266
|
```
|
|
268
267
|
|
|
269
268
|
### Lifecycle hooks
|
|
@@ -306,7 +305,7 @@ afterEach(() => {
|
|
|
306
305
|
|
|
307
306
|
**Never mock these:**
|
|
308
307
|
|
|
309
|
-
- **
|
|
308
|
+
- **Atoms** (`createAtom`, `watchAtom`) — always use real implementations from [`@xmachines/play-atom`](../api/@xmachines/play-atom/README.md). Atoms have precise reactive semantics (synchronous propagation, memoized derivation) that mocks cannot replicate accurately.
|
|
310
309
|
- **Internal `@xmachines/*` packages** — these are resolved directly to source via the `xmAliases` Vite plugin in the Vitest config. Mocking them would hide integration bugs and defeat the purpose of cross-package testing.
|
|
311
310
|
- **XState** — always use real `setup()` / `createMachine()` / `createActor()`. XState's actor lifecycle (start, stop, snapshot, subscription) is a behavioral contract that mocks cannot reliably emulate.
|
|
312
311
|
|
|
@@ -317,17 +316,16 @@ afterEach(() => {
|
|
|
317
316
|
```typescript
|
|
318
317
|
import { PlayActor } from "@xmachines/play-actor";
|
|
319
318
|
import type { Routable } from "@xmachines/play-router";
|
|
320
|
-
import { Signal } from "@xmachines/play-signals";
|
|
321
319
|
|
|
322
320
|
class MockActor implements PlayActor, Routable {
|
|
323
|
-
readonly state =
|
|
324
|
-
private _routeState:
|
|
325
|
-
readonly currentRoute:
|
|
321
|
+
readonly state = createAtom({} as unknown);
|
|
322
|
+
private _routeState: Atom<string | null>;
|
|
323
|
+
readonly currentRoute: ReadonlyAtom<string | null>;
|
|
326
324
|
readonly initialRoute: string | null;
|
|
327
325
|
|
|
328
326
|
constructor(startRoute: string | null = "/") {
|
|
329
|
-
this._routeState =
|
|
330
|
-
this.currentRoute =
|
|
327
|
+
this._routeState = createAtom<string | null>(startRoute);
|
|
328
|
+
this.currentRoute = createAtom(() => this._routeState.get());
|
|
331
329
|
this.initialRoute = startRoute;
|
|
332
330
|
}
|
|
333
331
|
|
|
@@ -344,14 +342,14 @@ import { stubOf } from "@xmachines/shared/test-support";
|
|
|
344
342
|
|
|
345
343
|
function createMockActor(initialView: PlaySpec | null = null) {
|
|
346
344
|
return stubOf<ViewActor>({
|
|
347
|
-
currentView:
|
|
345
|
+
currentView: createAtom<PlaySpec | null>(initialView),
|
|
348
346
|
send: vi.fn(),
|
|
349
347
|
start: vi.fn(),
|
|
350
348
|
stop: vi.fn(),
|
|
351
349
|
getSnapshot: vi.fn(),
|
|
352
350
|
subscribe: vi.fn(),
|
|
353
|
-
state:
|
|
354
|
-
currentRoute:
|
|
351
|
+
state: createAtom<unknown>({}),
|
|
352
|
+
currentRoute: createAtom(() => null),
|
|
355
353
|
});
|
|
356
354
|
}
|
|
357
355
|
```
|
|
@@ -363,9 +361,9 @@ sites. `X as unknown as T` is banned in this repo; if `stubOf` cannot express
|
|
|
363
361
|
the case, `unsafeCast<T>(value)` from the same module is the deliberate,
|
|
364
362
|
greppable escape hatch.
|
|
365
363
|
|
|
366
|
-
### Async and
|
|
364
|
+
### Async and atom patterns
|
|
367
365
|
|
|
368
|
-
**Flushing the microtask queue (required for
|
|
366
|
+
**Flushing the microtask queue (required for `watchAtom` delivery):**
|
|
369
367
|
|
|
370
368
|
```typescript
|
|
371
369
|
function waitForMicrotask(): Promise<void> {
|
|
@@ -377,23 +375,26 @@ await waitForMicrotask();
|
|
|
377
375
|
await vi.waitFor(() => expect(result).toBe(expected), { timeout: 100 });
|
|
378
376
|
```
|
|
379
377
|
|
|
380
|
-
**
|
|
378
|
+
**Atom watch pattern:**
|
|
381
379
|
|
|
382
380
|
```typescript
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
381
|
+
import { createAtom, watchAtom } from "@xmachines/play-atom";
|
|
382
|
+
|
|
383
|
+
let notified: string | null = null;
|
|
384
|
+
const stop = watchAtom(actor.currentRoute, (route) => {
|
|
385
|
+
notified = route;
|
|
386
386
|
});
|
|
387
|
-
watcher.watch(actor.currentRoute);
|
|
388
|
-
actor.currentRoute.get(); // Initial read required to prime computed signals
|
|
389
387
|
|
|
390
388
|
actor.state.set({ path: "/dashboard" });
|
|
391
|
-
|
|
389
|
+
// `watchAtom` coalesces into a microtask, so flush before the assertion.
|
|
390
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
392
391
|
|
|
393
|
-
expect(notified).toBe(
|
|
394
|
-
|
|
392
|
+
expect(notified).toBe("/dashboard");
|
|
393
|
+
stop(); // Always clean up
|
|
395
394
|
```
|
|
396
395
|
|
|
396
|
+
`atom.subscribe` delivers SYNCHRONOUSLY, inside the `set`, and it needs no flush. Use it when a test must observe the notification at the moment of the write. Use `watchAtom` everywhere else, because it is what the renderers and the bridges use.
|
|
397
|
+
|
|
397
398
|
### Compile-time type tests
|
|
398
399
|
|
|
399
400
|
For type-only assertions, use `@ts-expect-error` in `.spec.ts` files:
|
|
@@ -448,18 +449,18 @@ try {
|
|
|
448
449
|
|
|
449
450
|
### An expected report in the log
|
|
450
451
|
|
|
451
|
-
A test that makes a component fail gets a report of the framework for free. React writes the error and a component stack to `console.error` when the root declares no `onCaughtError`, and `@xmachines/play-solid` writes a line of its own when the caller gives no `onError`. Both reports are correct, and both reach the log of the pipeline, where 29 of them once filled more than half of the `test` job.
|
|
452
|
+
A test that makes a component fail gets a report of the framework for free. React writes the error and a component stack to `console.error` when the root declares no `onCaughtError`, and [`@xmachines/play-solid`](../api/@xmachines/play-solid/README.md) writes a line of its own when the caller gives no `onError`. Both reports are correct, and both reach the log of the pipeline, where 29 of them once filled more than half of the `test` job.
|
|
452
453
|
|
|
453
454
|
Claim the report in the test that expects it, and assert it:
|
|
454
455
|
|
|
455
|
-
- **React.** Take `render` from `test/test-utils.js` of `@xmachines/play-react
|
|
456
|
+
- **React.** Take `render` from `test/test-utils.js` of [`@xmachines/play-react`](../api/@xmachines/play-react/README.md), and not from `@testing-library/react`. It gives an `onCaughtError` to the root, which stops the print, and the result carries `caughtErrors` for an assertion. Keep the `render` of the library for a test that holds the DEFAULT report: the print of React IS the report of play-react for a caller that gives no `onError`.
|
|
456
457
|
- **Any framework.** Call `vi.spyOn(console, "error").mockImplementation(() => {})` before the render, and `expect(spy).toHaveBeenCalled()` after it. An `afterEach` with `vi.restoreAllMocks()` returns the console to the next test.
|
|
457
458
|
|
|
458
459
|
A report that a spy swallows and no assertion reads is worse than the noise, because it hides the day that the renderer stops to report.
|
|
459
460
|
|
|
460
461
|
## Contract Tests
|
|
461
462
|
|
|
462
|
-
The `@xmachines/play-router-shared` package exports a shared behavioral contract suite that all router bridge adapters must satisfy. It lives here (rather than in `@xmachines/play-router`) because the suite drives a real actor via `@xmachines/play-xstate` and uses the shared `authMachine` fixture from `@xmachines/play-actor-shared`, so it sits one layer above the router package and keeps `@xmachines/play-router` free of any dependency on the actor runtime:
|
|
463
|
+
The `@xmachines/play-router-shared` package exports a shared behavioral contract suite that all router bridge adapters must satisfy. It lives here (rather than in [`@xmachines/play-router`](../api/@xmachines/play-router/README.md)) because the suite drives a real actor via [`@xmachines/play-xstate`](../api/@xmachines/play-xstate/README.md) and uses the shared `authMachine` fixture from `@xmachines/play-actor-shared`, so it sits one layer above the router package and keeps [`@xmachines/play-router`](../api/@xmachines/play-router/README.md) free of any dependency on the actor runtime:
|
|
463
464
|
|
|
464
465
|
```typescript
|
|
465
466
|
// packages/play-router/examples/shared/test/router-bridge-contract.ts
|
|
@@ -481,7 +482,7 @@ runBridgeContractTests({
|
|
|
481
482
|
|
|
482
483
|
The contract covers: deep-link sync on connect, router→actor navigation sync, actor→router sync, guard redirect flows, duplicate event deduplication, and restore-from-snapshot behavior.
|
|
483
484
|
|
|
484
|
-
**Used by:** `@xmachines/play-router
|
|
485
|
+
**Used by:** [`@xmachines/play-router`](../api/@xmachines/play-router/README.md), `play-tanstack-react-router`, `play-vue-router`, `play-solid-router`, `play-react-router`, and other adapter packages.
|
|
485
486
|
|
|
486
487
|
**Compile-time bridge contract verification:**
|
|
487
488
|
|
|
@@ -505,13 +506,13 @@ Coverage is collected using the **v8** provider. The root `vitest.config.ts` def
|
|
|
505
506
|
|
|
506
507
|
Individual packages enforce their own (typically stricter) thresholds inside their `vitest.config.ts`:
|
|
507
508
|
|
|
508
|
-
| Package tier
|
|
509
|
-
|
|
|
510
|
-
| Core packages (`@xmachines/play
|
|
511
|
-
| Complex logic (`@xmachines/play-xstate
|
|
512
|
-
| Integration packages (e.g. `@xmachines/play-react
|
|
509
|
+
| Package tier | Lines | Functions | Branches | Statements |
|
|
510
|
+
| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----- | --------- | -------- | ---------- |
|
|
511
|
+
| Core packages ([`@xmachines/play`](../api/@xmachines/play/README.md), [`@xmachines/play-actor`](../api/@xmachines/play-actor/README.md), [`@xmachines/play-view`](../api/@xmachines/play-view/README.md)) | 90% | 90% | 85% | 90% |
|
|
512
|
+
| Complex logic ([`@xmachines/play-xstate`](../api/@xmachines/play-xstate/README.md), [`@xmachines/play-router`](../api/@xmachines/play-router/README.md)) | 85% | 85% | 80% | 85% |
|
|
513
|
+
| Integration packages (e.g. [`@xmachines/play-react`](../api/@xmachines/play-react/README.md), [`@xmachines/play-dom`](../api/@xmachines/play-dom/README.md)) | 80% | 80% | 80% | 80% |
|
|
513
514
|
|
|
514
|
-
`@xmachines/play-router` carries the lower numbers for a reason that its `vitest.config.ts` states: the bridge and the provider lifecycle are the mass of that package, and neither is measured by its own project. `@xmachines/play-router-shared` drives them through 3032 lines of contract suite, and each of the nine router adapters drives them again from its own project. The root `pnpm run test:coverage` is what measures the package whole.
|
|
515
|
+
[`@xmachines/play-router`](../api/@xmachines/play-router/README.md) carries the lower numbers for a reason that its `vitest.config.ts` states: the bridge and the provider lifecycle are the mass of that package, and neither is measured by its own project. `@xmachines/play-router-shared` drives them through 3032 lines of contract suite, and each of the nine router adapters drives them again from its own project. The root `pnpm run test:coverage` is what measures the package whole.
|
|
515
516
|
|
|
516
517
|
Coverage includes: `src/**/*.ts`, `src/**/*.tsx`, `src/**/*.vue`, `src/**/*.svelte`
|
|
517
518
|
|
|
@@ -530,23 +531,19 @@ Tests run in GitLab CI using the `to-be-continuous/node` pipeline component (ver
|
|
|
530
531
|
**CI test command** (from `.gitlab-ci.yml`):
|
|
531
532
|
|
|
532
533
|
```bash
|
|
533
|
-
pnpm run test:coverage
|
|
534
|
-
--coverage.reporter=text \
|
|
535
|
-
--coverage.reporter=cobertura \
|
|
536
|
-
--coverage.reportsDirectory=reports/coverage \
|
|
537
|
-
--reporter=default \
|
|
538
|
-
--reporter=junit \
|
|
539
|
-
--outputFile.junit=reports/junit.xml
|
|
534
|
+
pnpm run test:coverage
|
|
540
535
|
```
|
|
541
536
|
|
|
542
|
-
|
|
537
|
+
The job passes no reporter flag. `vitest.config.ts` owns the reporters, the JUnit file and the coverage directory, and it reads `COVERAGE_REPORTS_DIR` — which the `test` job sets to `reports/`. A new package therefore needs no CI change.
|
|
538
|
+
|
|
539
|
+
**Artifacts:** The `test` job publishes:
|
|
543
540
|
|
|
544
|
-
- JUnit XML report at `reports/
|
|
545
|
-
- Cobertura coverage XML at `reports/
|
|
541
|
+
- JUnit XML report at `reports/test-results.xml` (surfaced in GitLab's test results panel)
|
|
542
|
+
- Cobertura coverage XML at `reports/cobertura-coverage.xml` (used for GitLab's coverage percentage badge — extracted from the `All files` line)
|
|
546
543
|
|
|
547
544
|
Coverage and test results are always uploaded (`when: always`) so failures are visible even when the job itself fails.
|
|
548
545
|
|
|
549
|
-
The `pnpm run format:check` and `pnpm run lint` commands enforce code style
|
|
546
|
+
The `pnpm run format:check` and `pnpm run lint` commands enforce code style. They run as the separate `format` and `lint` jobs: the component's own lint job is turned off with `lint-enabled: "false"`, because it runs ESLint.
|
|
550
547
|
|
|
551
548
|
## Test Types Reference
|
|
552
549
|
|
package/examples/README.md
CHANGED
|
@@ -8,7 +8,7 @@ Practical code examples demonstrating current XMachines Play patterns and use ca
|
|
|
8
8
|
|
|
9
9
|
Start with the fundamental machine + actor pattern:
|
|
10
10
|
|
|
11
|
-
- **[Basic State Machine](basic-state-machine.md)** — `setup().createMachine()` + `definePlayer()` +
|
|
11
|
+
- **[Basic State Machine](basic-state-machine.md)** — `setup().createMachine()` + `definePlayer()` + atoms
|
|
12
12
|
- **[Traffic Light](traffic-light.md)** — Multi-state machine with `meta.route` and `formatPlayRouteTransitions`
|
|
13
13
|
- **[Form Validation](form-validation.md)** — Typed context mutations with `setup.assign`, guards, and `$bindState`
|
|
14
14
|
|
|
@@ -60,7 +60,7 @@ The conceptual examples in this directory are TypeScript snippets. To run them:
|
|
|
60
60
|
|
|
61
61
|
```bash
|
|
62
62
|
# Install dependencies (from the monorepo root)
|
|
63
|
-
pnpm add @xmachines/play-xstate @xmachines/play-actor @xmachines/play-
|
|
63
|
+
pnpm add @xmachines/play-xstate @xmachines/play-actor @xmachines/play-atom xstate
|
|
64
64
|
|
|
65
65
|
# Run with tsx
|
|
66
66
|
pnpm dlx tsx my-example.ts
|
|
@@ -81,7 +81,7 @@ pnpm --filter @xmachines/play-dom-router-demo run dev
|
|
|
81
81
|
| [`@xmachines/play-xstate`](../api/@xmachines/play-xstate/README.md) | `definePlayer`, `formatPlayRouteTransitions`, `PlayerActor` |
|
|
82
82
|
| [`@xmachines/play-actor`](../api/@xmachines/play-actor/README.md) | `PlayActor` |
|
|
83
83
|
| [`@xmachines/play-view`](../api/@xmachines/play-view/README.md) | `Viewable`, `PlaySpec`, `typedSpec` |
|
|
84
|
-
| [`@xmachines/play-
|
|
84
|
+
| [`@xmachines/play-atom`](../api/@xmachines/play-atom/README.md) | The atom primitives, `watchAtom` |
|
|
85
85
|
| [`@xmachines/play-router`](../api/@xmachines/play-router/README.md) | `RouterBridgeBase`, `RouteMap`, `Routable` |
|
|
86
86
|
| [`@xmachines/play-router/xstate`](../api/@xmachines/play-router/README.md) | `extractMachineRoutes`, `getRoutableRoutes` |
|
|
87
87
|
|
|
@@ -63,7 +63,7 @@ actor.start();
|
|
|
63
63
|
console.log(actor.getSnapshot().value); // "off"
|
|
64
64
|
console.log(actor.getSnapshot().context.toggleCount); // 0
|
|
65
65
|
|
|
66
|
-
// 6. Read state
|
|
66
|
+
// 6. Read state from the atom
|
|
67
67
|
console.log(actor.state.get().value); // "off"
|
|
68
68
|
|
|
69
69
|
// 7. Send events
|
|
@@ -87,13 +87,13 @@ actor.stop();
|
|
|
87
87
|
|
|
88
88
|
3. **`toggleSetup.assign(...)`** — Assigns context mutations using the typed setup's `assign` helper. This provides full inference from the declared context type — no manual type assertions needed.
|
|
89
89
|
|
|
90
|
-
4. **`definePlayer({ machine })`** — Wraps the machine in a factory. Calling `createPlayer()` returns a `PlayerActor` — XMachines' actor type that extends XState's actor with
|
|
90
|
+
4. **`definePlayer({ machine })`** — Wraps the machine in a factory. Calling `createPlayer()` returns a `PlayerActor` — XMachines' actor type that extends XState's actor with atom reactivity and Play Architecture hooks.
|
|
91
91
|
|
|
92
92
|
5. **`actor.start()`** — Activates the machine. Always call `start()` before sending events.
|
|
93
93
|
|
|
94
94
|
6. **`actor.getSnapshot()`** — Returns the current XState snapshot synchronously. `.value` is the state name; `.context` is the typed context object.
|
|
95
95
|
|
|
96
|
-
7. **`actor.state.get()`** —
|
|
96
|
+
7. **`actor.state.get()`** — atom access to the current snapshot. Useful when wiring infrastructure that observes atoms (renderers, router bridges). Equivalent to `actor.getSnapshot()` for one-time reads.
|
|
97
97
|
|
|
98
98
|
8. **Event types use dot-separated lowercase** — `"toggle"` not `"TOGGLE"`. This matches the XMachines convention used throughout the codebase (e.g. `"auth.login"`, `"auth.logout"`, `"play.route"`).
|
|
99
99
|
|
|
@@ -101,7 +101,7 @@ actor.stop();
|
|
|
101
101
|
|
|
102
102
|
- **`setup({ types })`**: The XState v5 typed entry point. Declares context, event, and input shapes before machine creation.
|
|
103
103
|
- **`definePlayer({ machine })`**: Creates a factory function that returns `PlayerActor` instances.
|
|
104
|
-
- **`actor.state`**:
|
|
104
|
+
- **`actor.state`**: An `Atom<Snapshot>` — an atom-based reactive handle on the machine snapshot.
|
|
105
105
|
- **`actor.getSnapshot()`**: Synchronous snapshot access — use for one-time reads and TypeScript-typed context inspection.
|
|
106
106
|
- **Typed `assign`**: Always call `setup.assign(...)` (not the bare `assign` from xstate) for context mutations.
|
|
107
107
|
|
|
@@ -224,7 +224,7 @@ view: {
|
|
|
224
224
|
|
|
225
225
|
## Connecting the Renderer
|
|
226
226
|
|
|
227
|
-
The machine spec above defines view structure — but nothing renders until you wire a renderer. Use `createRenderer` from `@xmachines/play-dom
|
|
227
|
+
The machine spec above defines view structure — but nothing renders until you wire a renderer. Use `createRenderer` from [`@xmachines/play-dom`](../api/@xmachines/play-dom/README.md):
|
|
228
228
|
|
|
229
229
|
```typescript
|
|
230
230
|
import { createRenderer, schema } from "@xmachines/play-dom";
|
|
@@ -416,8 +416,8 @@ const disconnect = connectRouter({
|
|
|
416
416
|
```
|
|
417
417
|
|
|
418
418
|
The Svelte adapters take the same two prefix options. They need no `router`:
|
|
419
|
-
`@xmachines/play-svelte-spa-router` reads an optional `window`, and
|
|
420
|
-
`@xmachines/play-sveltekit-router` reads an optional `location`.
|
|
419
|
+
[`@xmachines/play-svelte-spa-router`](../api/@xmachines/play-svelte-spa-router/README.md) reads an optional `window`, and
|
|
420
|
+
[`@xmachines/play-sveltekit-router`](../api/@xmachines/play-sveltekit-router/README.md) reads an optional `location`.
|
|
421
421
|
|
|
422
422
|
### What the Prefix Changes
|
|
423
423
|
|
|
@@ -480,7 +480,7 @@ getRouteMappings(tree, { basePath: "/:machineId/play" });
|
|
|
480
480
|
// [{ stateId: "home", path: "/:machineId/play" }, ...]
|
|
481
481
|
```
|
|
482
482
|
|
|
483
|
-
> **Param note.** Under a mount, `@xmachines/play-vue-router` and `@xmachines/play-solid-router` resolve each param from the stripped path with `URLPattern`, and not from the pre-parsed params of their framework: under a prefix the framework matched a route of the **host**, so those params describe the route of the machine never — and a collision of names carries the value of the host. With no prefix, both keep the parse of their framework whenever it reports at least one
|
|
483
|
+
> **Param note.** Under a mount, [`@xmachines/play-vue-router`](../api/@xmachines/play-vue-router/README.md) and [`@xmachines/play-solid-router`](../api/@xmachines/play-solid-router/README.md) resolve each param from the stripped path with `URLPattern`, and not from the pre-parsed params of their framework: under a prefix the framework matched a route of the **host**, so those params describe the route of the machine never — and a collision of names carries the value of the host. With no prefix, both keep the parse of their framework whenever it reports at least one
|
|
484
484
|
> param the pattern declares, and every required one. A pattern whose params are ALL
|
|
485
485
|
> optional and a framework that reports none — `/settings/:section?` under a catch-all of
|
|
486
486
|
> the host — is settled by the PATH: `/settings` is the bare form of that pattern, so
|
|
@@ -489,7 +489,7 @@ getRouteMappings(tree, { basePath: "/:machineId/play" });
|
|
|
489
489
|
> extraction reads that value.
|
|
490
490
|
>
|
|
491
491
|
> These branches decide the CALLS of a navigation, and never the availability of the API.
|
|
492
|
-
> `@xmachines/play-router` carries `urlpattern-polyfill` as an ordinary dependency and it
|
|
492
|
+
> [`@xmachines/play-router`](../api/@xmachines/play-router/README.md) carries `urlpattern-polyfill` as an ordinary dependency and it
|
|
493
493
|
> uses the native `URLPattern` when the runtime has one, so you install no polyfill and
|
|
494
494
|
> you load none. A BAD pattern is a question of the route map: `RouteMap` compiles each
|
|
495
495
|
> parameterized route in its constructor and throws an `InvalidRoutePatternError` there.
|
|
@@ -497,28 +497,28 @@ getRouteMappings(tree, { basePath: "/:machineId/play" });
|
|
|
497
497
|
|
|
498
498
|
## Adapter Summary
|
|
499
499
|
|
|
500
|
-
| Package
|
|
501
|
-
|
|
|
502
|
-
| `@xmachines/play-dom-router`
|
|
503
|
-
| `@xmachines/play-react-router`
|
|
504
|
-
| `@xmachines/play-tanstack-react-router` | TanStack React Router | Provider | `PlayRouterProvider`, `createRouteMapFromTree` |
|
|
505
|
-
| `@xmachines/play-solid-router`
|
|
506
|
-
| `@xmachines/play-tanstack-solid-router` | TanStack Solid Router | Provider | `PlayRouterProvider`, `createRouteMap` |
|
|
507
|
-
| `@xmachines/play-vue-router`
|
|
508
|
-
| `@xmachines/play-sveltekit-router`
|
|
509
|
-
| `@xmachines/play-svelte-spa-router`
|
|
500
|
+
| Package | Framework | Pattern | Key Import |
|
|
501
|
+
| ------------------------------------------------------------------------------------------------- | --------------------- | --------------- | ------------------------------------------------------------------------- |
|
|
502
|
+
| [`@xmachines/play-dom-router`](../api/@xmachines/play-dom-router/README.md) | Vanilla DOM | `connectRouter` | `connectRouter`, `createRouteMap`, `createBrowserHistory`, `createRouter` |
|
|
503
|
+
| [`@xmachines/play-react-router`](../api/@xmachines/play-react-router/README.md) | React Router 7/8 | Provider | `PlayRouterProvider`, `createRouteMapFromTree` |
|
|
504
|
+
| [`@xmachines/play-tanstack-react-router`](../api/@xmachines/play-tanstack-react-router/README.md) | TanStack React Router | Provider | `PlayRouterProvider`, `createRouteMapFromTree` |
|
|
505
|
+
| [`@xmachines/play-solid-router`](../api/@xmachines/play-solid-router/README.md) | SolidJS Router | Provider | `PlayRouterProvider`, `createRouteMap` |
|
|
506
|
+
| [`@xmachines/play-tanstack-solid-router`](../api/@xmachines/play-tanstack-solid-router/README.md) | TanStack Solid Router | Provider | `PlayRouterProvider`, `createRouteMap` |
|
|
507
|
+
| [`@xmachines/play-vue-router`](../api/@xmachines/play-vue-router/README.md) | Vue Router | Provider | `PlayRouterProvider`, `createRouteMap` |
|
|
508
|
+
| [`@xmachines/play-sveltekit-router`](../api/@xmachines/play-sveltekit-router/README.md) | SvelteKit | `connectRouter` | `connectRouter`, `createRouteMap` |
|
|
509
|
+
| [`@xmachines/play-svelte-spa-router`](../api/@xmachines/play-svelte-spa-router/README.md) | Svelte SPA Router | `connectRouter` | `connectRouter`, `createRouteMap` |
|
|
510
510
|
|
|
511
511
|
## Renderer Packages
|
|
512
512
|
|
|
513
513
|
Each framework also has a companion renderer package for the view layer:
|
|
514
514
|
|
|
515
|
-
| Package
|
|
516
|
-
|
|
|
517
|
-
| `@xmachines/play-dom`
|
|
518
|
-
| `@xmachines/play-react`
|
|
519
|
-
| `@xmachines/play-solid`
|
|
520
|
-
| `@xmachines/play-vue`
|
|
521
|
-
| `@xmachines/play-svelte` | Svelte 5 | `PlayRenderer`, `defineRegistry` |
|
|
515
|
+
| Package | Framework | Key API |
|
|
516
|
+
| ------------------------------------------------------------------- | ----------- | -------------------------------------------------- |
|
|
517
|
+
| [`@xmachines/play-dom`](../api/@xmachines/play-dom/README.md) | Vanilla DOM | `createPlayUI`, `createRenderer`, `defineRegistry` |
|
|
518
|
+
| [`@xmachines/play-react`](../api/@xmachines/play-react/README.md) | React | `PlayRenderer`, `defineRegistry` |
|
|
519
|
+
| [`@xmachines/play-solid`](../api/@xmachines/play-solid/README.md) | SolidJS | `PlayRenderer`, `defineRegistry` |
|
|
520
|
+
| [`@xmachines/play-vue`](../api/@xmachines/play-vue/README.md) | Vue 3 | `PlayRenderer`, `defineRegistry` |
|
|
521
|
+
| [`@xmachines/play-svelte`](../api/@xmachines/play-svelte/README.md) | Svelte 5 | `PlayRenderer`, `defineRegistry` |
|
|
522
522
|
|
|
523
523
|
## Architectural Invariants
|
|
524
524
|
|
|
@@ -526,9 +526,9 @@ All adapters preserve the 5 architectural invariants:
|
|
|
526
526
|
|
|
527
527
|
1. **Actor Authority (INV-01):** Machine guards validate all navigation
|
|
528
528
|
2. **Strict Separation (INV-02):** Business logic (machine) has zero framework imports
|
|
529
|
-
3. **
|
|
529
|
+
3. **Atom-Only Reactivity (INV-03):** atoms work identically in all adapters
|
|
530
530
|
4. **Passive Infrastructure (INV-04):** Router observes actor, never decides
|
|
531
|
-
5. **
|
|
531
|
+
5. **State-Driven Reset (INV-05):** Browser back/forward sends `play.route` events to actor
|
|
532
532
|
|
|
533
533
|
## Next Steps
|
|
534
534
|
|
|
@@ -6,7 +6,7 @@ How the `authMachine` uses `meta.route`, `play.route` events, `formatPlayRouteTr
|
|
|
6
6
|
|
|
7
7
|
XMachines inverts the usual routing model. The **actor** owns navigation — its guards decide which states are valid. The **router** is passive infrastructure that observes `actor.currentRoute` and keeps the browser URL in sync. This is **Actor Authority (INV-01)**.
|
|
8
8
|
|
|
9
|
-
Every routing interaction starts with a `play.route` event sent to the actor. If the machine's guards allow the transition, the state changes and `actor.currentRoute` updates. The router bridge sees the new
|
|
9
|
+
Every routing interaction starts with a `play.route` event sent to the actor. If the machine's guards allow the transition, the state changes and `actor.currentRoute` updates. The router bridge sees the new atom value and pushes a history entry. The URL never changes unless the actor approves.
|
|
10
10
|
|
|
11
11
|
## Key Concepts
|
|
12
12
|
|
|
@@ -240,7 +240,7 @@ actor.stop();
|
|
|
240
240
|
|
|
241
241
|
## Vanilla Router Setup
|
|
242
242
|
|
|
243
|
-
To sync the browser URL with `actor.currentRoute`, use `@xmachines/play-dom-router
|
|
243
|
+
To sync the browser URL with `actor.currentRoute`, use [`@xmachines/play-dom-router`](../api/@xmachines/play-dom-router/README.md):
|
|
244
244
|
|
|
245
245
|
```typescript
|
|
246
246
|
import { createBrowserHistory, createRouter, connectRouter } from "@xmachines/play-dom-router";
|
|
@@ -252,7 +252,7 @@ const history = createBrowserHistory({ window });
|
|
|
252
252
|
const router = createRouter({ routeTree: authMachine, history });
|
|
253
253
|
|
|
254
254
|
// connectRouter handles all bidirectional sync:
|
|
255
|
-
// - actor.currentRoute
|
|
255
|
+
// - actor.currentRoute atom → browser URL (history.push)
|
|
256
256
|
// - browser URL changes → play.route event sent to actor
|
|
257
257
|
const disconnect = connectRouter({ actor, router, routeMap });
|
|
258
258
|
|
|
@@ -265,7 +265,7 @@ window.addEventListener("beforeunload", () => {
|
|
|
265
265
|
|
|
266
266
|
## React Router Setup
|
|
267
267
|
|
|
268
|
-
For React, use `@xmachines/play-react-router` or `@xmachines/play-tanstack-react-router
|
|
268
|
+
For React, use [`@xmachines/play-react-router`](../api/@xmachines/play-react-router/README.md) or [`@xmachines/play-tanstack-react-router`](../api/@xmachines/play-tanstack-react-router/README.md):
|
|
269
269
|
|
|
270
270
|
```tsx
|
|
271
271
|
import { PlayRouterProvider, createRouteMapFromTree } from "@xmachines/play-tanstack-react-router";
|
|
@@ -285,7 +285,7 @@ function App() {
|
|
|
285
285
|
| ----------------------------------- | ---------------------------------------------------------------------------------------------- |
|
|
286
286
|
| **Actor Authority (INV-01)** | Guards on the machine validate every navigation. The router cannot change state directly. |
|
|
287
287
|
| **Passive Infrastructure (INV-04)** | The router observes `actor.currentRoute` — it never decides where to go. |
|
|
288
|
-
| **State-Driven Reset (INV-
|
|
288
|
+
| **State-Driven Reset (INV-05)** | Browser back/forward sends `play.route` events to the actor. History is driven by actor state. |
|
|
289
289
|
| **Strict Separation (INV-02)** | The machine has zero framework imports. Guards, actions, and context are pure TypeScript. |
|
|
290
290
|
|
|
291
291
|
## Next Steps
|
|
@@ -81,7 +81,7 @@ const createPlayer = definePlayer({
|
|
|
81
81
|
const actor = createPlayer();
|
|
82
82
|
actor.start();
|
|
83
83
|
|
|
84
|
-
// 5. Read current route
|
|
84
|
+
// 5. Read current route from the atom
|
|
85
85
|
console.log(actor.currentRoute.get()); // "/red"
|
|
86
86
|
|
|
87
87
|
// 6. Advance with domain events
|
|
@@ -123,14 +123,14 @@ on: {
|
|
|
123
123
|
- The machine's context must include `params` and `query` fields (both `Record<string, string>`), because `formatPlayRouteTransitions` assigns them on every `play.route` transition.
|
|
124
124
|
- `reenter` comes from the object form of `meta.route`, and the default is `false`. Declare `meta: { route: { path: "/red", reenter: true } }` for a state that must re-enter its own domain.
|
|
125
125
|
|
|
126
|
-
## `actor.currentRoute`
|
|
126
|
+
## The `actor.currentRoute` atom
|
|
127
127
|
|
|
128
|
-
`actor.currentRoute` is a `
|
|
128
|
+
`actor.currentRoute` is a `ReadonlyAtom<string | null>` derived from the active state's `meta.route` template and `context.params`. A route atom lets a router bridge observe URL changes reactively without polling.
|
|
129
129
|
|
|
130
130
|
```typescript
|
|
131
|
-
import {
|
|
131
|
+
import { watchAtom } from "@xmachines/play-atom";
|
|
132
132
|
|
|
133
|
-
const unwatch =
|
|
133
|
+
const unwatch = watchAtom(actor.currentRoute, () => {
|
|
134
134
|
console.log("URL changed to:", actor.currentRoute.get());
|
|
135
135
|
});
|
|
136
136
|
|
|
@@ -142,7 +142,7 @@ unwatch();
|
|
|
142
142
|
|
|
143
143
|
- **`meta.route`**: Marks a state as routable. The value is a URL template (e.g. `"/profile/:username"`).
|
|
144
144
|
- **`formatPlayRouteTransitions`**: Utility that auto-generates `play.route` handlers from `id` + `meta.route` pairs. Wrap your machine config before passing to `createMachine`.
|
|
145
|
-
- **`actor.currentRoute`**:
|
|
145
|
+
- **`actor.currentRoute`**: a computed atom containing the resolved URL for the active state.
|
|
146
146
|
- **`play.route` events**: Navigation events with a `to: "#stateId"` target. Use `to: "#red"` (state ID), not `to: "/red"` (URL path).
|
|
147
147
|
|
|
148
148
|
## Next Steps
|
package/guides/README.md
CHANGED
|
@@ -13,7 +13,7 @@ Background reading that explains the _why_ behind XMachines design decisions.
|
|
|
13
13
|
- **[Understanding State Machines](state-machines.md)** — What finite state machines are, how `meta.route` and `meta.view` extend them, and why they replace boolean flags and component-level routing logic
|
|
14
14
|
- **[Understanding the Actor Model](actor-model.md)** — The actor/infrastructure split, why the machine has zero framework imports, and how the reset invariant works
|
|
15
15
|
- **[Understanding Routing](routing.md)** — The URLPattern grammar that a `meta.route` path declares, the prefix rule that decides every optional route, and the three invariants that every router adapter follows
|
|
16
|
-
- **[Understanding
|
|
16
|
+
- **[Understanding Atoms](atoms.md)** — The atom primitives (`createAtom`, `createWritableAtom`, `watchAtom`), why XMachines uses them instead of observables, and the architectural invariants they enforce
|
|
17
17
|
|
|
18
18
|
## Tooling
|
|
19
19
|
|