@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/contributing/testing.md
CHANGED
|
@@ -4,21 +4,45 @@ This document describes the test framework, conventions, and CI integration for
|
|
|
4
4
|
|
|
5
5
|
## Test Framework and Setup
|
|
6
6
|
|
|
7
|
-
The monorepo uses **[Vitest](https://vitest.dev/) `^
|
|
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
9
|
All packages extend the shared Vitest configuration helper `defineXmVitestConfig` (from `@xmachines/shared/vitest`) which automatically applies:
|
|
10
10
|
|
|
11
11
|
- `@xmachines/*` source aliases so imports resolve to source during test runs
|
|
12
12
|
- `@xmachines/shared/vitest-setup` — extends Vitest matchers with `@testing-library/jest-dom`
|
|
13
|
-
- `@xmachines/shared/vitest-node-setup` — enforces Node.js ≥
|
|
13
|
+
- `@xmachines/shared/vitest-node-setup` — enforces Node.js ≥ 24 on non-browser projects
|
|
14
14
|
|
|
15
15
|
**Auto-injected setup files:**
|
|
16
16
|
|
|
17
17
|
| File | When injected | Purpose |
|
|
18
18
|
| --------------------------------------------- | ------------------------ | ------------------------------------------------------- |
|
|
19
|
-
| `packages/shared/config/vitest.node.setup.ts` | All non-browser projects | Validates Node.js ≥
|
|
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.
|
|
23
|
+
|
|
24
|
+
### The jest-dom patch
|
|
25
|
+
|
|
26
|
+
`patches/@testing-library__jest-dom@7.0.1.patch` moves the matcher declaration of the library from `Assertion` to `Matchers`. The library declares this:
|
|
27
|
+
|
|
28
|
+
```ts
|
|
29
|
+
declare module "vitest" {
|
|
30
|
+
interface Assertion<T = any> extends TestingLibraryMatchers<any, T> {}
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Vitest 5 declares `interface Assertion<R extends void | Promise<void> = void, T = unknown>`. A module augmentation merges only when the type parameters are IDENTICAL, and TypeScript reports nothing when they differ — it simply does not apply. Every matcher therefore left the type of `expect(...)` while the runtime kept working. `Matchers` is the interface that vitest publishes for an extension, and `Assertion` extends it, so the patched declaration reaches every assertion and restates no interface whose shape vitest owns.
|
|
35
|
+
|
|
36
|
+
Delete the patch, its `patchedDependencies` entry in `pnpm-workspace.yaml`, and `tests/jest-dom-augmentation.test.ts` on the day the library ships a declaration that vitest 5 accepts. See [testing-library/jest-dom#738](https://github.com/testing-library/jest-dom/issues/738).
|
|
37
|
+
|
|
38
|
+
### The vitest mocker patch
|
|
39
|
+
|
|
40
|
+
`patches/@vitest__mocker@5.0.1.patch` takes the `configureServer` hook off `vitest:mocks:interceptor` when the caller passes `registerWebSocketEvents: false`, which is how `@vitest/browser` calls it.
|
|
41
|
+
|
|
42
|
+
Vitest returns that plugin from the `applyToEnvironment` of another plugin, and Vite 8 ignores a `configureServer` that it finds there. Vite reports the fact one time for each environment, so a run of 29 projects wrote 29 lines, in the `test` job and in the `test:browser` job both. The hook returns at once for `registerWebSocketEvents: false`, so the omission changes no behaviour.
|
|
43
|
+
|
|
44
|
+
Delete the patch and its `patchedDependencies` entry when vitest ships the fix. See [vitest-dev/vitest#11276](https://github.com/vitest-dev/vitest/issues/11276).
|
|
45
|
+
|
|
22
46
|
Before running any tests, ensure all dependencies are installed:
|
|
23
47
|
|
|
24
48
|
```bash
|
|
@@ -33,7 +57,7 @@ pnpm install --frozen-lockfile
|
|
|
33
57
|
pnpm test
|
|
34
58
|
```
|
|
35
59
|
|
|
36
|
-
Runs `vitest run` across every project that the root `vitest.config.ts` collects —
|
|
60
|
+
Runs `vitest run` across every project that the root `vitest.config.ts` collects — 38 of them today: one for each package, one for each demo that holds node tests, and `infrastructure` for the repository tests in `tests/`. A node project uses the `forks` pool (up to 4 workers) and reuses a worker across test files — see [Isolation](#isolation). A jsdom project uses the `vmThreads` pool — see [Test environments](#test-environments).
|
|
37
61
|
|
|
38
62
|
The root config finds those projects by glob, so a new package or demo joins the run with no edit. Each test file must belong to **one** project: a package config that reaches into its own `examples/` collects the demo tests that the demo config collects already, and the run then executes them two times, under two different environments. `tests/project-collection-overlap.test.ts` asks Vitest for the whole collection and fails on any file that two projects claim.
|
|
39
63
|
|
|
@@ -82,7 +106,7 @@ Individual packages may enforce higher per-package thresholds in their own `vite
|
|
|
82
106
|
pnpm run test:build
|
|
83
107
|
```
|
|
84
108
|
|
|
85
|
-
Runs `tsc --build tsconfig.test.json --force`. This validates that all test TypeScript files across the monorepo type-check correctly without running the tests themselves. Also compiles `.typecheck.ts` files
|
|
109
|
+
Runs `tsc --build tsconfig.test.json --force`. This validates that all test TypeScript files across the monorepo type-check correctly without running the tests themselves. Also compiles the `.typecheck.ts` files of the `test/` directories.
|
|
86
110
|
|
|
87
111
|
This is the command that answers "does this tree type-check?". Use it rather than `pnpm run build` for that question. `tsc --build` skips a project whose dependencies have unchanged `.d.ts` files, so an error inside the source of a library that changes no exported declaration can leave every consumer of that library up to date and never be reported — and consumers here compile library **source**, through the `source` export condition. `--force` costs about a second and takes that decision away from tsc; `tests/typecheck-staleness.test.ts` holds it, and the two other properties the complete check rests on, in place: no project of the gate is `composite`, and the CI job starts with no build state on disk. The job gets that second property by DELETING every `*.tsbuildinfo` before it runs the gate. It does not inherit it: most of the caching of the pipeline arrives through the included node component, and no test in this repository can read that component's cache paths, so a claim about them would be prose that nothing verifies.
|
|
88
112
|
|
|
@@ -133,11 +157,38 @@ packages/<name>/
|
|
|
133
157
|
| `jsdom` | UI renderers: `@xmachines/play-react`, `play-vue`, `play-solid`, `play-svelte`, `play-dom` |
|
|
134
158
|
| Browser (Playwright/Chromium) | Browser-specific and E2E demo tests |
|
|
135
159
|
|
|
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
|
+
|
|
162
|
+
A project that declares its own `pool` keeps it.
|
|
163
|
+
|
|
164
|
+
### Isolation
|
|
165
|
+
|
|
166
|
+
`defineXmVitestConfig` gives a node project `isolate: false`, and it keeps isolation for a jsdom project, for a browser project, and for a project that declares `environmentMatchGlobs`.
|
|
167
|
+
|
|
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
|
+
|
|
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.
|
|
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.
|
|
173
|
+
|
|
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
|
+
|
|
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
|
+
|
|
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.
|
|
179
|
+
|
|
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
|
+
|
|
182
|
+
To check a project that you move off isolation, run the suite with a shuffled file order — the same check that `vitest doctor` applies:
|
|
183
|
+
|
|
184
|
+
```bash
|
|
185
|
+
pnpm exec vitest run --sequence.shuffle.files
|
|
186
|
+
```
|
|
187
|
+
|
|
136
188
|
### Test helpers and shared setup
|
|
137
189
|
|
|
138
190
|
- **`@xmachines/shared/vitest-setup`** — Injects `@testing-library/jest-dom` matchers. Applied automatically by `defineXmVitestConfig`.
|
|
139
|
-
- **`@xmachines/shared/vitest-node-setup`** — Enforces Node ≥
|
|
140
|
-
- **`@xmachines/shared/vitest-urlpattern-setup`** — Polyfills `URLPattern` for packages that need it (e.g. `@xmachines/play-router`). Must be declared explicitly in `setupFiles`.
|
|
191
|
+
- **`@xmachines/shared/vitest-node-setup`** — Enforces Node ≥ 24 at runtime. Auto-injected for non-browser configs.
|
|
141
192
|
- **`packages/play-react/test/test-utils.ts`** — React-specific test utilities for the `play-react` package.
|
|
142
193
|
- **`packages/play-router/examples/shared/`** and **`packages/play-actor/examples/shared/`** — Shared test fixtures for router and actor integration tests.
|
|
143
194
|
|
|
@@ -211,7 +262,7 @@ describe("ClassName or functionName()", () => {
|
|
|
211
262
|
**Import style:** Always use `.js` extensions in imports (ESM requirement):
|
|
212
263
|
|
|
213
264
|
```typescript
|
|
214
|
-
import {
|
|
265
|
+
import { PlayActor } from "../src/abstract-actor.js";
|
|
215
266
|
import { Signal } from "@xmachines/play-signals";
|
|
216
267
|
```
|
|
217
268
|
|
|
@@ -235,16 +286,13 @@ afterEach(() => {
|
|
|
235
286
|
- **Framework router objects** (TanStack Router, Vue Router, React Router, SolidJS Router) — mock with typed `vi.fn()` interfaces because they are external framework dependencies and carry significant setup complexity:
|
|
236
287
|
|
|
237
288
|
```typescript
|
|
238
|
-
const mocks = vi.hoisted(() => ({
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
}));
|
|
242
|
-
|
|
243
|
-
vi.mock("../src/machine-to-graph.js", () => ({
|
|
244
|
-
machineToGraph: mocks.machineToGraph,
|
|
245
|
-
}));
|
|
289
|
+
const mocks = vi.hoisted(() => ({ goto: vi.fn() }));
|
|
290
|
+
|
|
291
|
+
vi.mock("$app/navigation", () => ({ goto: mocks.goto }));
|
|
246
292
|
```
|
|
247
293
|
|
|
294
|
+
A mock of a module costs the WHOLE project its isolation — see [Isolation](#isolation). Mock the framework module, and not a module of the package under test: a test that builds the real collaborator is both cheaper and stronger.
|
|
295
|
+
|
|
248
296
|
- **`console.warn` / `console.error`** when testing code that legitimately emits warnings — mock to suppress noise and assert call counts:
|
|
249
297
|
|
|
250
298
|
```typescript
|
|
@@ -264,22 +312,20 @@ afterEach(() => {
|
|
|
264
312
|
|
|
265
313
|
### Test actor patterns
|
|
266
314
|
|
|
267
|
-
**Preferred: extend `
|
|
315
|
+
**Preferred: extend `PlayActor` for full type safety:**
|
|
268
316
|
|
|
269
317
|
```typescript
|
|
270
|
-
import {
|
|
271
|
-
import type { Routable } from "@xmachines/play-
|
|
318
|
+
import { PlayActor } from "@xmachines/play-actor";
|
|
319
|
+
import type { Routable } from "@xmachines/play-router";
|
|
272
320
|
import { Signal } from "@xmachines/play-signals";
|
|
273
|
-
import type { AnyActorLogic } from "xstate";
|
|
274
321
|
|
|
275
|
-
class MockActor
|
|
276
|
-
|
|
322
|
+
class MockActor implements PlayActor, Routable {
|
|
323
|
+
readonly state = new Signal.State({} as unknown);
|
|
277
324
|
private _routeState: Signal.State<string | null>;
|
|
278
325
|
readonly currentRoute: Signal.Computed<string | null>;
|
|
279
326
|
readonly initialRoute: string | null;
|
|
280
327
|
|
|
281
328
|
constructor(startRoute: string | null = "/") {
|
|
282
|
-
super({} as AnyActorLogic, {}); // {} as AnyActorLogic is the standard stub
|
|
283
329
|
this._routeState = new Signal.State<string | null>(startRoute);
|
|
284
330
|
this.currentRoute = new Signal.Computed(() => this._routeState.get());
|
|
285
331
|
this.initialRoute = startRoute;
|
|
@@ -297,7 +343,7 @@ class MockActor extends AbstractActor<AnyActorLogic> implements Routable {
|
|
|
297
343
|
import { stubOf } from "@xmachines/shared/test-support";
|
|
298
344
|
|
|
299
345
|
function createMockActor(initialView: PlaySpec | null = null) {
|
|
300
|
-
return stubOf<
|
|
346
|
+
return stubOf<ViewActor>({
|
|
301
347
|
currentView: new Signal.State<PlaySpec | null>(initialView),
|
|
302
348
|
send: vi.fn(),
|
|
303
349
|
start: vi.fn(),
|
|
@@ -365,10 +411,10 @@ const bad: PlaySpec = typedSpec({
|
|
|
365
411
|
expect(bad.root).toBe("root");
|
|
366
412
|
```
|
|
367
413
|
|
|
368
|
-
For purely structural type assertions with no runtime test needed, use `.typecheck.ts` files in `
|
|
414
|
+
For purely structural type assertions with no runtime test needed, use `.typecheck.ts` files in `test/`:
|
|
369
415
|
|
|
370
416
|
```typescript
|
|
371
|
-
// packages/play-xstate/
|
|
417
|
+
// packages/play-xstate/test/define-player.typecheck.ts
|
|
372
418
|
type IsAny<T> = 0 extends 1 & T ? true : false;
|
|
373
419
|
type AssertFalse<T extends false> = T;
|
|
374
420
|
|
|
@@ -400,6 +446,17 @@ try {
|
|
|
400
446
|
}
|
|
401
447
|
```
|
|
402
448
|
|
|
449
|
+
### An expected report in the log
|
|
450
|
+
|
|
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
|
+
|
|
453
|
+
Claim the report in the test that expects it, and assert it:
|
|
454
|
+
|
|
455
|
+
- **React.** Take `render` from `test/test-utils.js` of `@xmachines/play-react`, 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
|
+
- **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
|
+
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
|
+
|
|
403
460
|
## Contract Tests
|
|
404
461
|
|
|
405
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:
|
|
@@ -448,11 +505,13 @@ Coverage is collected using the **v8** provider. The root `vitest.config.ts` def
|
|
|
448
505
|
|
|
449
506
|
Individual packages enforce their own (typically stricter) thresholds inside their `vitest.config.ts`:
|
|
450
507
|
|
|
451
|
-
| Package tier
|
|
452
|
-
|
|
|
453
|
-
| Core packages (`@xmachines/play`, `@xmachines/play-actor`)
|
|
454
|
-
| Complex logic (`@xmachines/play-xstate`, `@xmachines/play-router`)
|
|
455
|
-
| Integration packages (e.g. `@xmachines/play-react`, `@xmachines/play-dom`)
|
|
508
|
+
| Package tier | Lines | Functions | Branches | Statements |
|
|
509
|
+
| ---------------------------------------------------------------------------------- | ----- | --------- | -------- | ---------- |
|
|
510
|
+
| Core packages (`@xmachines/play`, `@xmachines/play-actor`, `@xmachines/play-view`) | 90% | 90% | 85% | 90% |
|
|
511
|
+
| Complex logic (`@xmachines/play-xstate`, `@xmachines/play-router`) | 85% | 85% | 80% | 85% |
|
|
512
|
+
| Integration packages (e.g. `@xmachines/play-react`, `@xmachines/play-dom`) | 80% | 80% | 80% | 80% |
|
|
513
|
+
|
|
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.
|
|
456
515
|
|
|
457
516
|
Coverage includes: `src/**/*.ts`, `src/**/*.tsx`, `src/**/*.vue`, `src/**/*.svelte`
|
|
458
517
|
|
package/examples/README.md
CHANGED
|
@@ -76,12 +76,14 @@ pnpm --filter @xmachines/play-dom-router-demo run dev
|
|
|
76
76
|
|
|
77
77
|
### Core
|
|
78
78
|
|
|
79
|
-
| Package
|
|
80
|
-
|
|
|
81
|
-
| [`@xmachines/play-xstate`](../api/@xmachines/play-xstate/README.md)
|
|
82
|
-
| [`@xmachines/play-actor`](../api/@xmachines/play-actor/README.md)
|
|
83
|
-
| [`@xmachines/play-
|
|
84
|
-
| [`@xmachines/play-
|
|
79
|
+
| Package | Role |
|
|
80
|
+
| -------------------------------------------------------------------------- | ----------------------------------------------------------- |
|
|
81
|
+
| [`@xmachines/play-xstate`](../api/@xmachines/play-xstate/README.md) | `definePlayer`, `formatPlayRouteTransitions`, `PlayerActor` |
|
|
82
|
+
| [`@xmachines/play-actor`](../api/@xmachines/play-actor/README.md) | `PlayActor` |
|
|
83
|
+
| [`@xmachines/play-view`](../api/@xmachines/play-view/README.md) | `Viewable`, `PlaySpec`, `typedSpec` |
|
|
84
|
+
| [`@xmachines/play-signals`](../api/@xmachines/play-signals/README.md) | TC39 Signals polyfill, `watchSignal` |
|
|
85
|
+
| [`@xmachines/play-router`](../api/@xmachines/play-router/README.md) | `RouterBridgeBase`, `RouteMap`, `Routable` |
|
|
86
|
+
| [`@xmachines/play-router/xstate`](../api/@xmachines/play-router/README.md) | `extractMachineRoutes`, `getRoutableRoutes` |
|
|
85
87
|
|
|
86
88
|
### Renderers
|
|
87
89
|
|
|
@@ -98,7 +100,7 @@ pnpm --filter @xmachines/play-dom-router-demo run dev
|
|
|
98
100
|
| Package | Router |
|
|
99
101
|
| ------------------------------------------------------------------------------------------------- | ----------------------- |
|
|
100
102
|
| [`@xmachines/play-dom-router`](../api/@xmachines/play-dom-router/README.md) | Vanilla browser history |
|
|
101
|
-
| [`@xmachines/play-react-router`](../api/@xmachines/play-react-router/README.md) | React Router
|
|
103
|
+
| [`@xmachines/play-react-router`](../api/@xmachines/play-react-router/README.md) | React Router 7/8 |
|
|
102
104
|
| [`@xmachines/play-tanstack-react-router`](../api/@xmachines/play-tanstack-react-router/README.md) | TanStack Router (React) |
|
|
103
105
|
| [`@xmachines/play-solid-router`](../api/@xmachines/play-solid-router/README.md) | SolidJS Router |
|
|
104
106
|
| [`@xmachines/play-tanstack-solid-router`](../api/@xmachines/play-tanstack-solid-router/README.md) | TanStack Router (Solid) |
|
|
@@ -15,7 +15,8 @@ This example mirrors the `authMachine` login pattern: a form state with a local
|
|
|
15
15
|
|
|
16
16
|
```typescript
|
|
17
17
|
import { setup } from "xstate";
|
|
18
|
-
import { definePlayer
|
|
18
|
+
import { definePlayer } from "@xmachines/play-xstate";
|
|
19
|
+
import { formatPlayRouteTransitions } from "@xmachines/play-xstate/routing";
|
|
19
20
|
|
|
20
21
|
// Context shape
|
|
21
22
|
interface LoginContext {
|
|
@@ -304,5 +305,5 @@ window.addEventListener("beforeunload", () => {
|
|
|
304
305
|
|
|
305
306
|
- **[Basic State Machine](basic-state-machine.md)** — Foundational concepts without a view layer
|
|
306
307
|
- **[Routing Patterns](routing-patterns.md)** — Parameter routes, relative routes, and `always` auth guards
|
|
307
|
-
- **[`PlaySpec`](../api/@xmachines/play-
|
|
308
|
+
- **[`PlaySpec`](../api/@xmachines/play-view/index/interfaces/PlaySpec.md)** — Spec type governing `meta.view`, `$bindState`, and `$state`
|
|
308
309
|
- **[`@xmachines/play-router`](../api/@xmachines/play-router/README.md)** — Route extraction and tree building
|
|
@@ -25,12 +25,13 @@ Used by framework adapters that have a React/Solid/Vue provider context. The `Pl
|
|
|
25
25
|
import { useEffect, useMemo } from "react";
|
|
26
26
|
import { createRouter, createRootRoute } from "@tanstack/react-router";
|
|
27
27
|
import { PlayRouterProvider, createRouteMapFromTree } from "@xmachines/play-tanstack-react-router";
|
|
28
|
-
import { extractMachineRoutes } from "@xmachines/play-router";
|
|
29
|
-
import { definePlayer } from "@xmachines/play-xstate";
|
|
28
|
+
import { extractMachineRoutes } from "@xmachines/play-router/xstate";
|
|
29
|
+
import { definePlayer, compose, PlayerActor } from "@xmachines/play-xstate";
|
|
30
|
+
import { withRouting } from "@xmachines/play-xstate/routing";
|
|
30
31
|
import { defineRegistry } from "@xmachines/play-react";
|
|
31
32
|
import { authMachine, authCatalog } from "@xmachines/play-actor-shared";
|
|
32
33
|
|
|
33
|
-
const createPlayer = definePlayer({ machine: authMachine });
|
|
34
|
+
const createPlayer = definePlayer({ machine: authMachine, actor: compose(PlayerActor, withRouting) });
|
|
34
35
|
|
|
35
36
|
const { registry } = defineRegistry(authCatalog, {
|
|
36
37
|
components: { /* ...your components */ },
|
|
@@ -66,15 +67,16 @@ export function App() {
|
|
|
66
67
|
}
|
|
67
68
|
```
|
|
68
69
|
|
|
69
|
-
### React + React Router
|
|
70
|
+
### React + React Router 7/8 (`@xmachines/play-react-router`)
|
|
70
71
|
|
|
71
72
|
```typescript
|
|
72
73
|
import { createBrowserRouter, RouterProvider } from "react-router";
|
|
73
74
|
import { PlayRouterProvider, createRouteMapFromTree } from "@xmachines/play-react-router";
|
|
74
|
-
import { extractMachineRoutes } from "@xmachines/play-router";
|
|
75
|
-
import { definePlayer } from "@xmachines/play-xstate";
|
|
75
|
+
import { extractMachineRoutes } from "@xmachines/play-router/xstate";
|
|
76
|
+
import { definePlayer, compose, PlayerActor } from "@xmachines/play-xstate";
|
|
77
|
+
import { withRouting } from "@xmachines/play-xstate/routing";
|
|
76
78
|
|
|
77
|
-
const createPlayer = definePlayer({ machine: authMachine });
|
|
79
|
+
const createPlayer = definePlayer({ machine: authMachine, actor: compose(PlayerActor, withRouting) });
|
|
78
80
|
|
|
79
81
|
function createAppRuntime() {
|
|
80
82
|
const actor = createPlayer();
|
|
@@ -116,11 +118,13 @@ export default function App() {
|
|
|
116
118
|
```typescript
|
|
117
119
|
import { Router, Route } from "@solidjs/router";
|
|
118
120
|
import { onCleanup } from "solid-js";
|
|
119
|
-
import { PlayRouterProvider
|
|
120
|
-
import {
|
|
121
|
-
import {
|
|
121
|
+
import { PlayRouterProvider } from "@xmachines/play-solid-router";
|
|
122
|
+
import { createRouteMap } from "@xmachines/play-router/xstate";
|
|
123
|
+
import { extractMachineRoutes, getRoutableRoutes } from "@xmachines/play-router/xstate";
|
|
124
|
+
import { definePlayer, compose, PlayerActor } from "@xmachines/play-xstate";
|
|
125
|
+
import { withRouting } from "@xmachines/play-xstate/routing";
|
|
122
126
|
|
|
123
|
-
const createPlayer = definePlayer({ machine: authMachine });
|
|
127
|
+
const createPlayer = definePlayer({ machine: authMachine, actor: compose(PlayerActor, withRouting) });
|
|
124
128
|
const actor = createPlayer();
|
|
125
129
|
actor.start();
|
|
126
130
|
|
|
@@ -164,11 +168,13 @@ export default function App() {
|
|
|
164
168
|
```typescript
|
|
165
169
|
import { createRouter, createRootRoute, createRoute, RouterProvider } from "@tanstack/solid-router";
|
|
166
170
|
import { onCleanup } from "solid-js";
|
|
167
|
-
import { PlayRouterProvider
|
|
168
|
-
import {
|
|
169
|
-
import {
|
|
171
|
+
import { PlayRouterProvider } from "@xmachines/play-tanstack-solid-router";
|
|
172
|
+
import { createRouteMap } from "@xmachines/play-router/xstate";
|
|
173
|
+
import { extractMachineRoutes, getRoutableRoutes } from "@xmachines/play-router/xstate";
|
|
174
|
+
import { definePlayer, compose, PlayerActor } from "@xmachines/play-xstate";
|
|
175
|
+
import { withRouting } from "@xmachines/play-xstate/routing";
|
|
170
176
|
|
|
171
|
-
const createPlayer = definePlayer({ machine: authMachine });
|
|
177
|
+
const createPlayer = definePlayer({ machine: authMachine, actor: compose(PlayerActor, withRouting) });
|
|
172
178
|
const actor = createPlayer();
|
|
173
179
|
actor.start();
|
|
174
180
|
|
|
@@ -222,7 +228,8 @@ export default function App() {
|
|
|
222
228
|
<script setup lang="ts">
|
|
223
229
|
import { h, inject } from "vue";
|
|
224
230
|
import { createRouter, createWebHistory } from "vue-router";
|
|
225
|
-
import { PlayRouterProvider
|
|
231
|
+
import { PlayRouterProvider } from "@xmachines/play-vue-router";
|
|
232
|
+
import { createRouteMap } from "@xmachines/play-router/xstate";
|
|
226
233
|
import { defineRegistry } from "@xmachines/play-vue";
|
|
227
234
|
import { authMachine, authCatalog } from "@xmachines/play-actor-shared";
|
|
228
235
|
|
|
@@ -258,18 +265,20 @@ Used by vanilla DOM and Svelte adapters. Call `connectRouter` directly after cre
|
|
|
258
265
|
### Vanilla DOM (`@xmachines/play-dom-router`)
|
|
259
266
|
|
|
260
267
|
```typescript
|
|
261
|
-
import {
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
} from "@xmachines/play-
|
|
267
|
-
import { extractMachineRoutes } from "@xmachines/play-router";
|
|
268
|
-
import { definePlayer } from "@xmachines/play-xstate";
|
|
268
|
+
import { createBrowserHistory, createRouter, connectRouter } from "@xmachines/play-dom-router";
|
|
269
|
+
import { createRouteMap } from "@xmachines/play-router/xstate";
|
|
270
|
+
import { extractMachineRoutes } from "@xmachines/play-router/xstate";
|
|
271
|
+
import { definePlayer, compose, PlayerActor } from "@xmachines/play-xstate";
|
|
272
|
+
import { withRouting } from "@xmachines/play-xstate/routing";
|
|
273
|
+
import { withView } from "@xmachines/play-xstate/view";
|
|
269
274
|
import { createPlayUI, defineRegistry } from "@xmachines/play-dom";
|
|
270
275
|
import { authMachine, authCatalog } from "@xmachines/play-actor-shared";
|
|
271
276
|
|
|
272
|
-
|
|
277
|
+
// The router needs `withRouting`, and the renderer below needs `withView`.
|
|
278
|
+
const createPlayer = definePlayer({
|
|
279
|
+
machine: authMachine,
|
|
280
|
+
actor: compose(PlayerActor, withRouting, withView),
|
|
281
|
+
});
|
|
273
282
|
const actor = createPlayer();
|
|
274
283
|
actor.start();
|
|
275
284
|
|
|
@@ -306,10 +315,15 @@ window.addEventListener("beforeunload", () => {
|
|
|
306
315
|
// lib/router.ts
|
|
307
316
|
import { defineRegistry } from "@xmachines/play-svelte";
|
|
308
317
|
import { authCatalog, authMachine } from "@xmachines/play-actor-shared";
|
|
309
|
-
import { definePlayer } from "@xmachines/play-xstate";
|
|
310
|
-
import {
|
|
311
|
-
|
|
312
|
-
|
|
318
|
+
import { definePlayer, compose, PlayerActor } from "@xmachines/play-xstate";
|
|
319
|
+
import { withRouting } from "@xmachines/play-xstate/routing";
|
|
320
|
+
import { withView } from "@xmachines/play-xstate/view";
|
|
321
|
+
import { connectRouter } from "@xmachines/play-sveltekit-router";
|
|
322
|
+
import { createRouteMap } from "@xmachines/play-router/xstate";
|
|
323
|
+
const createDemoPlayer = definePlayer({
|
|
324
|
+
machine: authMachine,
|
|
325
|
+
actor: compose(PlayerActor, withRouting, withView),
|
|
326
|
+
});
|
|
313
327
|
|
|
314
328
|
const { registry } = defineRegistry(authCatalog, {
|
|
315
329
|
components: {/* ...your Svelte components */},
|
|
@@ -337,11 +351,17 @@ export const disconnectRouter = connectRouter({ actor, routeMap });
|
|
|
337
351
|
|
|
338
352
|
```typescript
|
|
339
353
|
// lib/router.ts — identical pattern to SvelteKit, different import
|
|
340
|
-
import { connectRouter
|
|
341
|
-
import {
|
|
354
|
+
import { connectRouter } from "@xmachines/play-svelte-spa-router";
|
|
355
|
+
import { createRouteMap } from "@xmachines/play-router/xstate";
|
|
356
|
+
import { definePlayer, compose, PlayerActor } from "@xmachines/play-xstate";
|
|
357
|
+
import { withRouting } from "@xmachines/play-xstate/routing";
|
|
358
|
+
import { withView } from "@xmachines/play-xstate/view";
|
|
342
359
|
import { authMachine } from "@xmachines/play-actor-shared";
|
|
343
360
|
|
|
344
|
-
const createDemoPlayer = definePlayer({
|
|
361
|
+
const createDemoPlayer = definePlayer({
|
|
362
|
+
machine: authMachine,
|
|
363
|
+
actor: compose(PlayerActor, withRouting, withView),
|
|
364
|
+
});
|
|
345
365
|
|
|
346
366
|
export const actor = createDemoPlayer();
|
|
347
367
|
actor.start();
|
|
@@ -446,7 +466,7 @@ An actor never changes identity, so a segment of the prefix that _identifies_ th
|
|
|
446
466
|
For a host router that declares real route objects, ask for the list — and drop it again when the machine unloads:
|
|
447
467
|
|
|
448
468
|
```typescript
|
|
449
|
-
import { extractMachineRoutes, getRouteMappings } from "@xmachines/play-router";
|
|
469
|
+
import { extractMachineRoutes, getRouteMappings } from "@xmachines/play-router/xstate";
|
|
450
470
|
|
|
451
471
|
const tree = extractMachineRoutes(authMachine);
|
|
452
472
|
|
|
@@ -460,7 +480,7 @@ getRouteMappings(tree, { basePath: "/:machineId/play" });
|
|
|
460
480
|
// [{ stateId: "home", path: "/:machineId/play" }, ...]
|
|
461
481
|
```
|
|
462
482
|
|
|
463
|
-
> **
|
|
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
|
|
464
484
|
> param the pattern declares, and every required one. A pattern whose params are ALL
|
|
465
485
|
> optional and a framework that reports none — `/settings/:section?` under a catch-all of
|
|
466
486
|
> the host — is settled by the PATH: `/settings` is the bare form of that pattern, so
|
|
@@ -468,17 +488,19 @@ getRouteMappings(tree, { basePath: "/:machineId/play" });
|
|
|
468
488
|
> value, such as `/settings/security`, still reaches the extraction, because only the
|
|
469
489
|
> extraction reads that value.
|
|
470
490
|
>
|
|
471
|
-
> These branches decide the CALLS of a navigation, and
|
|
472
|
-
>
|
|
473
|
-
>
|
|
474
|
-
> a
|
|
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
|
|
493
|
+
> uses the native `URLPattern` when the runtime has one, so you install no polyfill and
|
|
494
|
+
> you load none. A BAD pattern is a question of the route map: `RouteMap` compiles each
|
|
495
|
+
> parameterized route in its constructor and throws an `InvalidRoutePatternError` there.
|
|
496
|
+
> The [routing guide](../guides/routing.md) states the pattern language.
|
|
475
497
|
|
|
476
498
|
## Adapter Summary
|
|
477
499
|
|
|
478
500
|
| Package | Framework | Pattern | Key Import |
|
|
479
501
|
| --------------------------------------- | --------------------- | --------------- | ------------------------------------------------------------------------- |
|
|
480
502
|
| `@xmachines/play-dom-router` | Vanilla DOM | `connectRouter` | `connectRouter`, `createRouteMap`, `createBrowserHistory`, `createRouter` |
|
|
481
|
-
| `@xmachines/play-react-router` | React Router
|
|
503
|
+
| `@xmachines/play-react-router` | React Router 7/8 | Provider | `PlayRouterProvider`, `createRouteMapFromTree` |
|
|
482
504
|
| `@xmachines/play-tanstack-react-router` | TanStack React Router | Provider | `PlayRouterProvider`, `createRouteMapFromTree` |
|
|
483
505
|
| `@xmachines/play-solid-router` | SolidJS Router | Provider | `PlayRouterProvider`, `createRouteMap` |
|
|
484
506
|
| `@xmachines/play-tanstack-solid-router` | TanStack Solid Router | Provider | `PlayRouterProvider`, `createRouteMap` |
|
|
@@ -64,7 +64,8 @@ Instead of hand-writing `play.route` event handlers for every routable state, wr
|
|
|
64
64
|
|
|
65
65
|
```typescript
|
|
66
66
|
import { setup } from "xstate";
|
|
67
|
-
import { definePlayer
|
|
67
|
+
import { definePlayer } from "@xmachines/play-xstate";
|
|
68
|
+
import { formatPlayRouteTransitions } from "@xmachines/play-xstate/routing";
|
|
68
69
|
import type { PlayRouteEvent } from "@xmachines/play-router";
|
|
69
70
|
|
|
70
71
|
interface AuthContext {
|
|
@@ -108,14 +109,16 @@ const authMachine = authSetup.createMachine(
|
|
|
108
109
|
```typescript
|
|
109
110
|
on: {
|
|
110
111
|
"play.route": [
|
|
111
|
-
{ target: ".home", guard: ({ event }) => event.to === "#home", reenter:
|
|
112
|
-
{ target: ".about", guard: ({ event }) => event.to === "#about", reenter:
|
|
113
|
-
{ target: ".login", guard: ({ event }) => event.to === "#login", reenter:
|
|
114
|
-
{ target: ".profile", guard: ({ event }) => event.to === "#profile", reenter:
|
|
112
|
+
{ target: ".home", guard: ({ event }) => event.to === "#home", reenter: false, actions: assign({ params, query }) },
|
|
113
|
+
{ target: ".about", guard: ({ event }) => event.to === "#about", reenter: false, actions: assign({ params, query }) },
|
|
114
|
+
{ target: ".login", guard: ({ event }) => event.to === "#login", reenter: false, actions: assign({ params, query }) },
|
|
115
|
+
{ target: ".profile", guard: ({ event }) => event.to === "#profile", reenter: false, actions: assign({ params, query }) },
|
|
115
116
|
],
|
|
116
117
|
}
|
|
117
118
|
```
|
|
118
119
|
|
|
120
|
+
`reenter` comes from the object form of `meta.route`, and the default is `false`. Declare `meta: { route: { path: "/about", reenter: true } }` for a state that must re-enter its own domain.
|
|
121
|
+
|
|
119
122
|
### `play.route` Events — Navigation
|
|
120
123
|
|
|
121
124
|
To navigate, send a `play.route` event with `to: "#stateId"`:
|
|
@@ -204,7 +207,10 @@ const authMachine = authSetup.createMachine(
|
|
|
204
207
|
## Complete Actor Usage
|
|
205
208
|
|
|
206
209
|
```typescript
|
|
207
|
-
const createPlayer = definePlayer({
|
|
210
|
+
const createPlayer = definePlayer({
|
|
211
|
+
machine: authMachine,
|
|
212
|
+
actor: compose(PlayerActor, withRouting),
|
|
213
|
+
});
|
|
208
214
|
const actor = createPlayer();
|
|
209
215
|
actor.start();
|
|
210
216
|
|
|
@@ -237,13 +243,8 @@ actor.stop();
|
|
|
237
243
|
To sync the browser URL with `actor.currentRoute`, use `@xmachines/play-dom-router`:
|
|
238
244
|
|
|
239
245
|
```typescript
|
|
240
|
-
import {
|
|
241
|
-
|
|
242
|
-
createRouter,
|
|
243
|
-
connectRouter,
|
|
244
|
-
createRouteMap,
|
|
245
|
-
} from "@xmachines/play-dom-router";
|
|
246
|
-
|
|
246
|
+
import { createBrowserHistory, createRouter, connectRouter } from "@xmachines/play-dom-router";
|
|
247
|
+
import { createRouteMap } from "@xmachines/play-router/xstate";
|
|
247
248
|
// createRouteMap extracts meta.route declarations from the machine
|
|
248
249
|
const routeMap = createRouteMap(authMachine);
|
|
249
250
|
|
|
@@ -268,7 +269,7 @@ For React, use `@xmachines/play-react-router` or `@xmachines/play-tanstack-react
|
|
|
268
269
|
|
|
269
270
|
```tsx
|
|
270
271
|
import { PlayRouterProvider, createRouteMapFromTree } from "@xmachines/play-tanstack-react-router";
|
|
271
|
-
import { extractMachineRoutes } from "@xmachines/play-router";
|
|
272
|
+
import { extractMachineRoutes } from "@xmachines/play-router/xstate";
|
|
272
273
|
|
|
273
274
|
const routeTree = extractMachineRoutes(authMachine);
|
|
274
275
|
const routeMap = createRouteMapFromTree(routeTree);
|
|
@@ -17,7 +17,9 @@ Applicable patterns:
|
|
|
17
17
|
|
|
18
18
|
```typescript
|
|
19
19
|
import { setup } from "xstate";
|
|
20
|
-
import { definePlayer,
|
|
20
|
+
import { definePlayer, compose, PlayerActor } from "@xmachines/play-xstate";
|
|
21
|
+
import { formatPlayRouteTransitions } from "@xmachines/play-xstate/routing";
|
|
22
|
+
import { withRouting } from "@xmachines/play-xstate/routing";
|
|
21
23
|
|
|
22
24
|
// 1. Typed setup
|
|
23
25
|
const trafficSetup = setup({
|
|
@@ -70,7 +72,10 @@ const trafficMachine = trafficSetup.createMachine(
|
|
|
70
72
|
);
|
|
71
73
|
|
|
72
74
|
// 3. Player factory
|
|
73
|
-
const createPlayer = definePlayer({
|
|
75
|
+
const createPlayer = definePlayer({
|
|
76
|
+
machine: trafficMachine,
|
|
77
|
+
actor: compose(PlayerActor, withRouting),
|
|
78
|
+
});
|
|
74
79
|
|
|
75
80
|
// 4. Create and start actor
|
|
76
81
|
const actor = createPlayer();
|
|
@@ -105,9 +110,9 @@ actor.stop();
|
|
|
105
110
|
// Auto-generated by formatPlayRouteTransitions — you don't write this manually:
|
|
106
111
|
on: {
|
|
107
112
|
"play.route": [
|
|
108
|
-
{ target: ".red", guard: ({ event }) => event.to === "#red", reenter:
|
|
109
|
-
{ target: ".green", guard: ({ event }) => event.to === "#green", reenter:
|
|
110
|
-
{ target: ".yellow", guard: ({ event }) => event.to === "#yellow", reenter:
|
|
113
|
+
{ target: ".red", guard: ({ event }) => event.to === "#red", reenter: false, actions: assign({ params, query }) },
|
|
114
|
+
{ target: ".green", guard: ({ event }) => event.to === "#green", reenter: false, actions: assign({ params, query }) },
|
|
115
|
+
{ target: ".yellow", guard: ({ event }) => event.to === "#yellow", reenter: false, actions: assign({ params, query }) },
|
|
111
116
|
],
|
|
112
117
|
}
|
|
113
118
|
```
|
|
@@ -116,6 +121,7 @@ on: {
|
|
|
116
121
|
|
|
117
122
|
- Every routable state must have both `id` (the `#id` navigation target) and `meta.route` (the URL template).
|
|
118
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
|
+
- `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.
|
|
119
125
|
|
|
120
126
|
## `actor.currentRoute` Signal
|
|
121
127
|
|
package/guides/README.md
CHANGED
|
@@ -12,6 +12,7 @@ Background reading that explains the _why_ behind XMachines design decisions.
|
|
|
12
12
|
|
|
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
|
+
- **[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
|
|
15
16
|
- **[Understanding TC39 Signals](signals.md)** — The three signal primitives (`Signal.State`, `Signal.Computed`, `Signal.subtle.Watcher`), why XMachines uses them instead of observables, and the architectural invariants they enforce
|
|
16
17
|
|
|
17
18
|
## Tooling
|