@xmachines/docs 6.0.0 → 7.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 +9 -8
- package/api/@xmachines/core/README.md +7 -2
- package/api/@xmachines/core/cache/functions/createLruCache.md +1 -1
- package/api/@xmachines/core/cache/interfaces/KeyValueCache.md +3 -3
- package/api/@xmachines/core/errors/classes/BaseError.md +4 -4
- package/api/@xmachines/core/errors/classes/DisposeConflictError.md +4 -4
- package/api/@xmachines/core/utils/functions/asDisposable.md +2 -2
- package/api/@xmachines/core/utils/functions/createNullRecord.md +1 -1
- package/api/@xmachines/core/utils/functions/createWarnOnce.md +1 -1
- package/api/@xmachines/core/utils/functions/describeValue.md +1 -1
- package/api/@xmachines/core/utils/functions/isError.md +1 -1
- package/api/@xmachines/core/utils/functions/isThenable.md +1 -1
- package/api/@xmachines/core/utils/functions/releaseQuietly.md +1 -1
- package/api/@xmachines/core/utils/functions/rethrowLater.md +1 -1
- package/api/@xmachines/core/utils/functions/safeString.md +1 -1
- package/api/@xmachines/core/utils/functions/shallowEqualExcept.md +1 -1
- package/api/@xmachines/core/utils/type-aliases/DisposeKey.md +1 -1
- package/api/@xmachines/core/utils/type-aliases/DisposeMember.md +1 -1
- package/api/@xmachines/core/utils/variables/DISPOSE.md +1 -1
- package/api/@xmachines/play/README.md +10 -5
- package/api/@xmachines/play/errors/classes/NonNullableError.md +4 -4
- package/api/@xmachines/play/errors/classes/PlayError.md +6 -4
- package/api/@xmachines/play/index/functions/assertNonNullable.md +1 -1
- package/api/@xmachines/play/index/type-aliases/PlayEvent.md +2 -2
- package/api/@xmachines/play-actor/README.md +9 -1
- package/api/@xmachines/play-actor/interfaces/ActorEvent.md +2 -2
- package/api/@xmachines/play-actor/interfaces/PlayActor.md +3 -3
- package/api/@xmachines/play-atom/README.md +17 -5
- package/api/@xmachines/play-atom/functions/watchAtom.md +1 -1
- package/api/@xmachines/play-atom/interfaces/AsyncAtomOptions.md +2 -2
- package/api/@xmachines/play-atom/interfaces/Atom.md +6 -6
- package/api/@xmachines/play-atom/interfaces/AtomObserver.md +4 -4
- package/api/@xmachines/play-atom/interfaces/AtomOptions.md +2 -2
- package/api/@xmachines/play-atom/interfaces/AtomSubscription.md +2 -2
- package/api/@xmachines/play-atom/interfaces/BaseAtom.md +4 -4
- package/api/@xmachines/play-atom/interfaces/CreateAtom.md +3 -3
- package/api/@xmachines/play-atom/interfaces/Readable.md +4 -4
- package/api/@xmachines/play-atom/interfaces/ReadonlyAtom.md +4 -4
- package/api/@xmachines/play-atom/type-aliases/AnyAtom.md +1 -1
- package/api/@xmachines/play-atom/type-aliases/AsyncAtomState.md +1 -1
- package/api/@xmachines/play-atom/variables/createAsyncAtom.md +1 -1
- package/api/@xmachines/play-atom/variables/createAtom.md +1 -1
- package/api/@xmachines/play-atom/variables/createWritableAtom.md +1 -1
- package/api/@xmachines/play-dom/README.md +138 -60
- package/api/@xmachines/play-dom/classes/PlayRenderer.md +12 -12
- package/api/@xmachines/play-dom/functions/createPlayUI.md +5 -5
- package/api/@xmachines/play-dom/functions/createRenderer.md +1 -1
- package/api/@xmachines/play-dom/functions/renderSpec.md +3 -2
- package/api/@xmachines/play-dom/interfaces/ComponentContext.md +9 -9
- package/api/@xmachines/play-dom/interfaces/CreatePlayUIOptions.md +15 -14
- package/api/@xmachines/play-dom/interfaces/DomRenderContext.md +26 -20
- package/api/@xmachines/play-dom/interfaces/MountOptions.md +3 -3
- package/api/@xmachines/play-dom/interfaces/PassOptions.md +14 -0
- package/api/@xmachines/play-dom/interfaces/PlayDomOptions.md +18 -17
- package/api/@xmachines/play-dom/interfaces/RenderErrorInfo.md +16 -0
- package/api/@xmachines/play-dom/interfaces/RenderSpecOptions.md +17 -15
- package/api/@xmachines/play-dom/interfaces/UIProviderOptions.md +9 -8
- package/api/@xmachines/play-dom/interfaces/ValidationRegistry.md +14 -11
- package/api/@xmachines/play-dom/type-aliases/ConfirmHandler.md +9 -10
- package/api/@xmachines/play-dom/type-aliases/DefineRegistryOptions.md +4 -3
- package/api/@xmachines/play-dom/type-aliases/MountFn.md +1 -1
- package/api/@xmachines/play-dom/type-aliases/OnRenderError.md +27 -0
- package/api/@xmachines/play-dom/type-aliases/RenderErrorKind.md +21 -0
- package/api/@xmachines/play-dom-router/README.md +41 -5
- package/api/@xmachines/play-dom-router/classes/DomRouterBridge.md +7 -7
- package/api/@xmachines/play-dom-router/classes/RouteMap.md +4 -4
- 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 -3
- package/api/@xmachines/play-dom-router/interfaces/BrowserHistory.md +14 -14
- package/api/@xmachines/play-dom-router/interfaces/BrowserWindow.md +14 -14
- package/api/@xmachines/play-dom-router/interfaces/ConnectRouterOptions.md +8 -8
- package/api/@xmachines/play-dom-router/interfaces/PlayRouteEvent.md +7 -7
- package/api/@xmachines/play-dom-router/interfaces/RoutableActor.md +4 -4
- 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 +6 -6
- package/api/@xmachines/play-dom-router/interfaces/VanillaRouter.md +4 -4
- package/api/@xmachines/play-pattern/README.md +1 -1
- package/api/@xmachines/play-pattern/functions/buildPath.md +1 -1
- package/api/@xmachines/play-pattern/functions/createLruCache.md +1 -1
- package/api/@xmachines/play-pattern/functions/getIndexKey.md +1 -1
- package/api/@xmachines/play-pattern/functions/isDotSegment.md +1 -1
- package/api/@xmachines/play-pattern/functions/parsePattern.md +1 -1
- package/api/@xmachines/play-pattern/interfaces/GroupPart.md +4 -4
- package/api/@xmachines/play-pattern/interfaces/KeyValueCache.md +3 -3
- package/api/@xmachines/play-pattern/interfaces/LiteralPart.md +3 -3
- package/api/@xmachines/play-pattern/interfaces/ParamPart.md +7 -7
- package/api/@xmachines/play-pattern/interfaces/ParseOptions.md +2 -2
- package/api/@xmachines/play-pattern/interfaces/ParsedPattern.md +12 -12
- package/api/@xmachines/play-pattern/interfaces/PatternParam.md +4 -4
- package/api/@xmachines/play-pattern/type-aliases/PathBuildResult.md +1 -1
- package/api/@xmachines/play-pattern/type-aliases/PathParams.md +1 -1
- package/api/@xmachines/play-pattern/type-aliases/PatternModifier.md +1 -1
- package/api/@xmachines/play-pattern/type-aliases/PatternPart.md +1 -1
- package/api/@xmachines/play-react/README.md +57 -18
- package/api/@xmachines/play-react/classes/PlayErrorBoundary.md +6 -6
- package/api/@xmachines/play-react/functions/defineRegistry.md +1 -1
- package/api/@xmachines/play-react/functions/useActor.md +1 -1
- package/api/@xmachines/play-react/functions/useAtomEffect.md +1 -1
- package/api/@xmachines/play-react/functions/usePlayView.md +1 -1
- package/api/@xmachines/play-react/interfaces/ActionProviderProps.md +5 -5
- package/api/@xmachines/play-react/interfaces/ActorProviderProps.md +11 -11
- package/api/@xmachines/play-react/interfaces/DefineRegistryResult.md +15 -0
- package/api/@xmachines/play-react/interfaces/PlayErrorBoundaryProps.md +6 -6
- package/api/@xmachines/play-react/interfaces/PlayErrorBoundaryState.md +4 -4
- package/api/@xmachines/play-react/interfaces/PlayUIProviderProps.md +13 -13
- package/api/@xmachines/play-react/interfaces/RenderErrorInfo.md +16 -0
- package/api/@xmachines/play-react/interfaces/RendererProps.md +7 -7
- 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/type-aliases/OnRenderError.md +27 -0
- package/api/@xmachines/play-react/type-aliases/RenderErrorKind.md +21 -0
- package/api/@xmachines/play-react/variables/ActorProvider.md +14 -4
- 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 +26 -5
- package/api/@xmachines/play-react-router/classes/ReactRouterBridge.md +7 -7
- package/api/@xmachines/play-react-router/classes/RouteMap.md +4 -4
- package/api/@xmachines/play-react-router/functions/createPlayRouterProvider.md +1 -1
- package/api/@xmachines/play-react-router/functions/createRouteMapFromTree.md +1 -1
- package/api/@xmachines/play-react-router/interfaces/PlayRouteEvent.md +7 -7
- package/api/@xmachines/play-react-router/interfaces/PlayRouterProviderProps.md +9 -9
- package/api/@xmachines/play-react-router/interfaces/RoutableActor.md +4 -4
- 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 +1 -1
- 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 +79 -23
- 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/classes/RouteMap.md +4 -4
- package/api/@xmachines/play-router/index/classes/RouterBridgeBase.md +7 -7
- 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/createLruCache.md +1 -1
- package/api/@xmachines/play-router/index/functions/createRouteMapFromTree.md +1 -1
- 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 +1 -1
- package/api/@xmachines/play-router/index/functions/findRouteById.md +1 -1
- package/api/@xmachines/play-router/index/functions/findRouteByPath.md +1 -1
- package/api/@xmachines/play-router/index/functions/isMountableBridge.md +1 -1
- package/api/@xmachines/play-router/index/functions/joinBasePath.md +1 -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 +1 -1
- 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 +1 -1
- package/api/@xmachines/play-router/index/functions/sanitizePathname.md +1 -1
- package/api/@xmachines/play-router/index/functions/splitLocation.md +1 -1
- 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 +3 -3
- package/api/@xmachines/play-router/index/interfaces/BuildPlayRouteEventOptions.md +4 -4
- package/api/@xmachines/play-router/index/interfaces/CompileOptions.md +3 -3
- package/api/@xmachines/play-router/index/interfaces/FrameworkParamsSource.md +7 -7
- package/api/@xmachines/play-router/index/interfaces/KeyValueCache.md +3 -3
- package/api/@xmachines/play-router/index/interfaces/LocationLike.md +3 -3
- package/api/@xmachines/play-router/index/interfaces/MountableRouterBridge.md +6 -6
- package/api/@xmachines/play-router/index/interfaces/OpenProviderBridgeArgs.md +8 -8
- package/api/@xmachines/play-router/index/interfaces/ParseOptions.md +2 -2
- package/api/@xmachines/play-router/index/interfaces/ParsedPattern.md +12 -12
- package/api/@xmachines/play-router/index/interfaces/PlayRouteEvent.md +7 -7
- package/api/@xmachines/play-router/index/interfaces/PlayRouterProviderBaseProps.md +9 -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 +3 -3
- package/api/@xmachines/play-router/index/interfaces/RoutableActor.md +4 -4
- package/api/@xmachines/play-router/index/interfaces/RouteInfo.md +8 -8
- package/api/@xmachines/play-router/index/interfaces/RouteMapOptions.md +4 -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 +12 -15
- package/api/@xmachines/play-router/index/interfaces/RouteTree.md +5 -5
- package/api/@xmachines/play-router/index/interfaces/RouteWatcherHandle.md +3 -3
- package/api/@xmachines/play-router/index/interfaces/RouterBridge.md +3 -3
- package/api/@xmachines/play-router/index/interfaces/RouterBridgeOptions.md +6 -6
- package/api/@xmachines/play-router/index/interfaces/RouterConnection.md +6 -6
- package/api/@xmachines/play-router/index/interfaces/SplitLocation.md +5 -5
- package/api/@xmachines/play-router/index/interfaces/WindowLike.md +3 -3
- package/api/@xmachines/play-router/index/type-aliases/PlayRouterBridgeConstructor.md +1 -1
- 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 +3 -3
- 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 +1 -1
- package/api/@xmachines/play-router/xstate/functions/extractMachineRoutes.md +1 -1
- 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 +35 -14
- package/api/@xmachines/play-solid/functions/defineRegistry.md +5 -5
- package/api/@xmachines/play-solid/functions/useActor.md +1 -1
- package/api/@xmachines/play-solid/functions/useBoundProp.md +8 -5
- package/api/@xmachines/play-solid/functions/useFieldValidation.md +6 -4
- package/api/@xmachines/play-solid/functions/usePlayView.md +1 -1
- package/api/@xmachines/play-solid/functions/useStateBinding.md +5 -3
- package/api/@xmachines/play-solid/functions/useStateValue.md +5 -3
- package/api/@xmachines/play-solid/interfaces/ActorProviderProps.md +10 -10
- package/api/@xmachines/play-solid/interfaces/ComponentContext.md +9 -8
- package/api/@xmachines/play-solid/interfaces/PlayUIProviderProps.md +13 -13
- package/api/@xmachines/play-solid/interfaces/RenderErrorInfo.md +16 -0
- package/api/@xmachines/play-solid/interfaces/RendererProps.md +7 -7
- 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/type-aliases/OnRenderError.md +27 -0
- package/api/@xmachines/play-solid/type-aliases/RenderErrorKind.md +21 -0
- package/api/@xmachines/play-solid/variables/ActorContext.md +1 -1
- package/api/@xmachines/play-solid/variables/ActorProvider.md +17 -3
- 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 +35 -54
- package/api/@xmachines/play-solid-router/README.md +22 -6
- package/api/@xmachines/play-solid-router/classes/RouteMap.md +4 -4
- package/api/@xmachines/play-solid-router/classes/SolidRouterBridge.md +8 -8
- package/api/@xmachines/play-solid-router/functions/createPlayRouterProvider.md +1 -1
- package/api/@xmachines/play-solid-router/interfaces/PlayActor.md +3 -3
- package/api/@xmachines/play-solid-router/interfaces/PlayRouteEvent.md +7 -7
- package/api/@xmachines/play-solid-router/interfaces/PlayRouterProviderProps.md +9 -9
- package/api/@xmachines/play-solid-router/interfaces/RoutableActor.md +4 -4
- package/api/@xmachines/play-solid-router/interfaces/RouteMapOptions.md +4 -4
- package/api/@xmachines/play-solid-router/interfaces/RouteMapping.md +3 -3
- package/api/@xmachines/play-solid-router/interfaces/RouterBridge.md +3 -3
- package/api/@xmachines/play-solid-router/type-aliases/PlayRouterBridgeConstructor.md +1 -1
- 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 +18 -10
- package/api/@xmachines/play-svelte/functions/defineRegistry.md +3 -4
- package/api/@xmachines/play-svelte/functions/getActorContext.md +1 -1
- package/api/@xmachines/play-svelte/functions/getPlayViewContext.md +1 -1
- package/api/@xmachines/play-svelte/functions/setActorContext.md +1 -1
- package/api/@xmachines/play-svelte/interfaces/ActorProviderProps.md +12 -12
- package/api/@xmachines/play-svelte/interfaces/BaseComponentProps.md +10 -8
- package/api/@xmachines/play-svelte/interfaces/ComponentContext.md +10 -8
- package/api/@xmachines/play-svelte/interfaces/DefineRegistryOptions.md +8 -8
- package/api/@xmachines/play-svelte/interfaces/DefineRegistryResult.md +15 -0
- package/api/@xmachines/play-svelte/interfaces/PlayUIProviderProps.md +14 -14
- package/api/@xmachines/play-svelte/interfaces/RenderErrorInfo.md +16 -0
- 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/type-aliases/OnRenderError.md +27 -0
- package/api/@xmachines/play-svelte/type-aliases/RenderErrorKind.md +21 -0
- package/api/@xmachines/play-svelte-spa-router/README.md +9 -5
- package/api/@xmachines/play-svelte-spa-router/classes/RouteMap.md +4 -4
- package/api/@xmachines/play-svelte-spa-router/classes/SvelteSpaRouterBridge.md +7 -7
- package/api/@xmachines/play-svelte-spa-router/functions/connectRouter.md +1 -1
- package/api/@xmachines/play-svelte-spa-router/interfaces/BasePathOptions.md +3 -3
- package/api/@xmachines/play-svelte-spa-router/interfaces/ConnectRouterOptions.md +8 -8
- package/api/@xmachines/play-svelte-spa-router/interfaces/PlayRouteEvent.md +7 -7
- package/api/@xmachines/play-svelte-spa-router/interfaces/RoutableActor.md +4 -4
- 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 +6 -6
- package/api/@xmachines/play-svelte-spa-router/interfaces/WindowLike.md +3 -3
- package/api/@xmachines/play-sveltekit-router/README.md +65 -13
- package/api/@xmachines/play-sveltekit-router/classes/RouteMap.md +4 -4
- package/api/@xmachines/play-sveltekit-router/classes/SvelteKitRouterBridge.md +29 -19
- package/api/@xmachines/play-sveltekit-router/functions/connectRouter.md +1 -1
- package/api/@xmachines/play-sveltekit-router/interfaces/BasePathOptions.md +3 -3
- package/api/@xmachines/play-sveltekit-router/interfaces/ConnectRouterOptions.md +13 -16
- 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 +4 -4
- 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 +6 -6
- package/api/@xmachines/play-sveltekit-router/interfaces/SvelteKitRouterBridgeOptions.md +25 -0
- package/api/@xmachines/play-sveltekit-router/type-aliases/ShallowNavigation.md +21 -0
- package/api/@xmachines/play-tanstack-react-router/README.md +34 -16
- package/api/@xmachines/play-tanstack-react-router/classes/RouteMap.md +4 -4
- package/api/@xmachines/play-tanstack-react-router/classes/TanStackReactRouterBridge.md +7 -7
- package/api/@xmachines/play-tanstack-react-router/functions/createPlayRouterProvider.md +1 -1
- package/api/@xmachines/play-tanstack-react-router/functions/createRouteMapFromTree.md +1 -1
- package/api/@xmachines/play-tanstack-react-router/interfaces/PlayRouteEvent.md +7 -7
- package/api/@xmachines/play-tanstack-react-router/interfaces/PlayRouterProviderProps.md +9 -9
- package/api/@xmachines/play-tanstack-react-router/interfaces/RoutableActor.md +4 -4
- 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 +1 -1
- 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 +5 -3
- package/api/@xmachines/play-tanstack-router/classes/TanStackRouterBridgeBase.md +7 -7
- 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 +45 -11
- package/api/@xmachines/play-tanstack-solid-router/classes/RouteMap.md +4 -4
- package/api/@xmachines/play-tanstack-solid-router/classes/TanStackSolidRouterBridge.md +7 -7
- 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 +9 -9
- package/api/@xmachines/play-tanstack-solid-router/interfaces/RoutableActor.md +4 -4
- 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 +1 -1
- 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 +1 -1
- 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/functions/buildPath.md +1 -1
- package/api/@xmachines/play-url/index/functions/cleanFrameworkParams.md +1 -1
- package/api/@xmachines/play-url/index/functions/createLruCache.md +1 -1
- package/api/@xmachines/play-url/index/functions/getCandidates.md +1 -1
- package/api/@xmachines/play-url/index/functions/getCompiledPattern.md +1 -1
- package/api/@xmachines/play-url/index/functions/getIndexKey.md +1 -1
- package/api/@xmachines/play-url/index/functions/holdsUnsubstitutedParam.md +1 -1
- package/api/@xmachines/play-url/index/functions/isDotSegment.md +1 -1
- package/api/@xmachines/play-url/index/functions/joinBasePath.md +1 -1
- package/api/@xmachines/play-url/index/functions/normalizeBasePath.md +1 -1
- package/api/@xmachines/play-url/index/functions/parsePattern.md +1 -1
- 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 +1 -1
- package/api/@xmachines/play-url/index/functions/sanitizePathname.md +1 -1
- package/api/@xmachines/play-url/index/functions/splitLocation.md +1 -1
- 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 +3 -3
- package/api/@xmachines/play-url/index/interfaces/FrameworkParamsSource.md +7 -7
- package/api/@xmachines/play-url/index/interfaces/GroupPart.md +4 -4
- package/api/@xmachines/play-url/index/interfaces/KeyValueCache.md +3 -3
- package/api/@xmachines/play-url/index/interfaces/LiteralPart.md +3 -3
- package/api/@xmachines/play-url/index/interfaces/ParamPart.md +7 -7
- package/api/@xmachines/play-url/index/interfaces/ParseOptions.md +2 -2
- package/api/@xmachines/play-url/index/interfaces/ParsedPattern.md +12 -12
- package/api/@xmachines/play-url/index/interfaces/PatternParam.md +4 -4
- package/api/@xmachines/play-url/index/interfaces/ResolvedBasePath.md +3 -3
- package/api/@xmachines/play-url/index/interfaces/SplitLocation.md +5 -5
- package/api/@xmachines/play-url/index/type-aliases/PathBuildResult.md +1 -1
- package/api/@xmachines/play-url/index/type-aliases/PathParams.md +1 -1
- 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 +92 -35
- package/api/@xmachines/play-view/errors/README.md +2 -0
- package/api/@xmachines/play-view/errors/classes/InvalidViewOutletError.md +204 -0
- package/api/@xmachines/play-view/errors/classes/ReadOnlyContextError.md +5 -5
- package/api/@xmachines/play-view/errors/classes/ViewElementKeyCollisionError.md +181 -0
- package/api/@xmachines/play-view/index/README.md +16 -4
- package/api/@xmachines/play-view/index/functions/attachRenderErrorHandler.md +10 -9
- package/api/@xmachines/play-view/index/functions/bindStoreHandlers.md +34 -0
- package/api/@xmachines/play-view/index/functions/composePlayState.md +1 -1
- package/api/@xmachines/play-view/index/functions/composeViews.md +41 -0
- package/api/@xmachines/play-view/index/functions/createActorProxy.md +39 -0
- package/api/@xmachines/play-view/index/functions/createRenderErrorBinding.md +35 -0
- package/api/@xmachines/play-view/index/functions/createReportGuard.md +1 -1
- package/api/@xmachines/play-view/index/functions/createViewSession.md +29 -0
- package/api/@xmachines/play-view/index/functions/createViewStoreLifecycle.md +1 -1
- package/api/@xmachines/play-view/index/functions/forwardRenderError.md +45 -0
- package/api/@xmachines/play-view/index/functions/guardContextWrites.md +1 -1
- 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/toAtomState.md +1 -1
- package/api/@xmachines/play-view/index/functions/typedSpec.md +11 -11
- package/api/@xmachines/play-view/index/interfaces/BaseActorProviderProps.md +8 -8
- package/api/@xmachines/play-view/index/interfaces/BaseViewContextValue.md +5 -5
- package/api/@xmachines/play-view/index/interfaces/ComposedView.md +16 -0
- package/api/@xmachines/play-view/index/interfaces/HandlerFactory.md +19 -0
- package/api/@xmachines/play-view/index/interfaces/PlaySpec.md +12 -8
- package/api/@xmachines/play-view/index/interfaces/ReportGuard.md +5 -5
- package/api/@xmachines/play-view/index/interfaces/ReportGuardMessages.md +5 -5
- package/api/@xmachines/play-view/index/interfaces/ResolveViewStoreOptions.md +2 -2
- package/api/@xmachines/play-view/index/interfaces/ViewMeta.md +25 -0
- package/api/@xmachines/play-view/index/interfaces/ViewOutlet.md +23 -0
- package/api/@xmachines/play-view/index/interfaces/ViewSession.md +155 -0
- package/api/@xmachines/play-view/index/interfaces/ViewSessionOptions.md +12 -0
- package/api/@xmachines/play-view/index/interfaces/ViewSessionSnapshot.md +23 -0
- package/api/@xmachines/play-view/index/interfaces/ViewStoreLifecycle.md +22 -3
- package/api/@xmachines/play-view/index/interfaces/ViewStoreResolution.md +7 -6
- package/api/@xmachines/play-view/index/interfaces/ViewTree.md +15 -0
- package/api/@xmachines/play-view/index/interfaces/ViewTreeChild.md +14 -0
- package/api/@xmachines/play-view/index/interfaces/Viewable.md +4 -4
- package/api/@xmachines/play-view/index/type-aliases/StateUpdater.md +21 -0
- 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 +21 -18
- 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/useBoundProp.md +10 -4
- package/api/@xmachines/play-vue/functions/useFieldValidation.md +12 -5
- package/api/@xmachines/play-vue/functions/usePlayView.md +1 -1
- package/api/@xmachines/play-vue/interfaces/ActorProviderProps.md +8 -8
- package/api/@xmachines/play-vue/interfaces/PlayUIProviderProps.md +11 -11
- package/api/@xmachines/play-vue/interfaces/RenderErrorInfo.md +16 -0
- package/api/@xmachines/play-vue/interfaces/RendererProps.md +7 -7
- 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/type-aliases/OnRenderError.md +27 -0
- package/api/@xmachines/play-vue/type-aliases/RenderErrorKind.md +21 -0
- package/api/@xmachines/play-vue/variables/PlayRenderer.md +1 -1
- package/api/@xmachines/play-vue/variables/Renderer.md +3 -3
- package/api/@xmachines/play-vue-router/README.md +18 -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 +4 -4
- package/api/@xmachines/play-vue-router/index/classes/VueRouterBridge.md +7 -7
- package/api/@xmachines/play-vue-router/index/interfaces/PlayRouteEvent.md +7 -7
- package/api/@xmachines/play-vue-router/index/interfaces/RoutableActor.md +4 -4
- package/api/@xmachines/play-vue-router/index/interfaces/RouteMapOptions.md +4 -4
- package/api/@xmachines/play-vue-router/index/interfaces/RouteMapping.md +3 -3
- package/api/@xmachines/play-vue-router/index/interfaces/RouterBridge.md +3 -3
- package/api/@xmachines/play-vue-router/index/variables/PlayRouterProvider.md +1 -1
- package/api/@xmachines/play-xstate/README.md +87 -28
- 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 +7 -7
- 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/classes/PlayerActor.md +10 -10
- 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 +7 -7
- 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/with-routing/functions/buildRouteUrl.md +1 -1
- 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 +12 -15
- 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 +2 -4
- package/api/@xmachines/shared/README.md +1 -0
- package/api/@xmachines/shared/vite-aliases/README.md +7 -0
- package/api/@xmachines/shared/vite-aliases/functions/xmAliases.md +11 -5
- package/api/@xmachines/shared/vite-aliases/functions/xmBuildOutput.md +37 -0
- package/api/@xmachines/shared/vite-aliases/functions/xmBuildOutputFile.md +28 -0
- 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/vite-aliases/functions/xmTestTarget.md +26 -0
- package/api/@xmachines/shared/vite-aliases/type-aliases/XmTestTarget.md +15 -0
- package/api/@xmachines/shared/vitest/functions/defineXmBrowserConfig.md +1 -1
- package/api/@xmachines/shared/vitest/functions/defineXmVitestConfig.md +5 -1
- package/api/@xmachines/shared/vitest/interfaces/XmBrowserConfigOptions.md +4 -4
- package/api/llms.txt +8 -4
- package/contributing/architecture.md +96 -51
- package/contributing/configuration.md +55 -14
- package/contributing/deployment.md +3 -3
- package/contributing/development.md +31 -4
- package/contributing/migrating-to-play-atom.md +11 -5
- package/contributing/testing.md +93 -33
- package/examples/@xmachines/play-dom-demo/README.md +2 -2
- package/examples/@xmachines/play-dom-demo/functions/createAuthActionHandlers.md +9 -9
- package/examples/@xmachines/play-dom-demo/functions/createConfirmDialog.md +1 -1
- package/examples/@xmachines/play-dom-demo/functions/createNavBar.md +1 -1
- package/examples/@xmachines/play-dom-demo/functions/initShell.md +1 -1
- package/examples/@xmachines/play-dom-demo/type-aliases/AuthCatalog.md +1 -1
- package/examples/@xmachines/play-dom-demo/variables/About.md +1 -1
- package/examples/@xmachines/play-dom-demo/variables/Button.md +1 -1
- package/examples/@xmachines/play-dom-demo/variables/Contact.md +1 -1
- package/examples/@xmachines/play-dom-demo/variables/Dashboard.md +1 -1
- package/examples/@xmachines/play-dom-demo/variables/Field.md +1 -1
- package/examples/@xmachines/play-dom-demo/variables/Home.md +1 -1
- package/examples/@xmachines/play-dom-demo/variables/Login.md +1 -1
- package/examples/@xmachines/play-dom-demo/variables/NavBarView.md +1 -1
- package/examples/@xmachines/play-dom-demo/variables/Navigation.md +1 -1
- package/examples/@xmachines/play-dom-demo/variables/Overview.md +1 -1
- package/examples/@xmachines/play-dom-demo/variables/Panel.md +1 -1
- package/examples/@xmachines/play-dom-demo/variables/Profile.md +1 -1
- package/examples/@xmachines/play-dom-demo/variables/Settings.md +1 -1
- package/examples/@xmachines/play-dom-demo/variables/Stats.md +1 -1
- package/examples/@xmachines/play-dom-demo/variables/authCatalog.md +1 -1
- package/examples/@xmachines/play-dom-demo/variables/demoComponents.md +15 -15
- package/examples/@xmachines/play-dom-router-demo/README.md +4 -3
- package/examples/@xmachines/play-react-demo/README.md +2 -2
- package/examples/@xmachines/play-react-demo/functions/createAuthActionHandlers.md +9 -9
- package/examples/@xmachines/play-react-demo/type-aliases/AuthCatalog.md +1 -1
- package/examples/@xmachines/play-react-demo/variables/About.md +1 -1
- package/examples/@xmachines/play-react-demo/variables/Button.md +1 -1
- package/examples/@xmachines/play-react-demo/variables/Contact.md +1 -1
- package/examples/@xmachines/play-react-demo/variables/Dashboard.md +1 -1
- package/examples/@xmachines/play-react-demo/variables/DebugPanel.md +1 -1
- package/examples/@xmachines/play-react-demo/variables/Field.md +1 -1
- package/examples/@xmachines/play-react-demo/variables/Home.md +1 -1
- package/examples/@xmachines/play-react-demo/variables/Login.md +1 -1
- package/examples/@xmachines/play-react-demo/variables/NavBar.md +1 -1
- package/examples/@xmachines/play-react-demo/variables/NavBarView.md +1 -1
- package/examples/@xmachines/play-react-demo/variables/Navigation.md +1 -1
- package/examples/@xmachines/play-react-demo/variables/Overview.md +1 -1
- package/examples/@xmachines/play-react-demo/variables/Panel.md +1 -1
- package/examples/@xmachines/play-react-demo/variables/Profile.md +1 -1
- package/examples/@xmachines/play-react-demo/variables/Settings.md +1 -1
- package/examples/@xmachines/play-react-demo/variables/Shell.md +1 -1
- package/examples/@xmachines/play-react-demo/variables/Stats.md +1 -1
- package/examples/@xmachines/play-react-demo/variables/authCatalog.md +1 -1
- package/examples/@xmachines/play-react-demo/variables/demoComponents.md +15 -15
- package/examples/@xmachines/play-react-router-demo/README.md +4 -3
- package/examples/@xmachines/play-solid-demo/README.md +3 -3
- package/examples/@xmachines/play-solid-demo/functions/createAuthActionHandlers.md +9 -9
- package/examples/@xmachines/play-solid-demo/type-aliases/AuthCatalog.md +1 -1
- package/examples/@xmachines/play-solid-demo/variables/About.md +1 -1
- package/examples/@xmachines/play-solid-demo/variables/Button.md +1 -1
- package/examples/@xmachines/play-solid-demo/variables/Contact.md +1 -1
- package/examples/@xmachines/play-solid-demo/variables/Dashboard.md +1 -1
- package/examples/@xmachines/play-solid-demo/variables/DebugPanel.md +1 -1
- package/examples/@xmachines/play-solid-demo/variables/Field.md +1 -1
- package/examples/@xmachines/play-solid-demo/variables/Home.md +1 -1
- package/examples/@xmachines/play-solid-demo/variables/Login.md +1 -1
- package/examples/@xmachines/play-solid-demo/variables/NavBar.md +1 -1
- package/examples/@xmachines/play-solid-demo/variables/NavBarView.md +1 -1
- package/examples/@xmachines/play-solid-demo/variables/Navigation.md +1 -1
- package/examples/@xmachines/play-solid-demo/variables/Overview.md +1 -1
- package/examples/@xmachines/play-solid-demo/variables/Panel.md +1 -1
- package/examples/@xmachines/play-solid-demo/variables/Profile.md +1 -1
- package/examples/@xmachines/play-solid-demo/variables/Settings.md +1 -1
- package/examples/@xmachines/play-solid-demo/variables/Shell.md +1 -1
- package/examples/@xmachines/play-solid-demo/variables/Stats.md +1 -1
- package/examples/@xmachines/play-solid-demo/variables/authCatalog.md +190 -277
- package/examples/@xmachines/play-solid-demo/variables/demoComponents.md +17 -17
- package/examples/@xmachines/play-solid-router-demo/README.md +9 -3
- package/examples/@xmachines/play-svelte-demo/README.md +1 -1
- package/examples/@xmachines/play-svelte-demo/functions/createAuthActionHandlers.md +9 -9
- package/examples/@xmachines/play-svelte-demo/type-aliases/AuthCatalog.md +1 -1
- package/examples/@xmachines/play-svelte-demo/variables/authCatalog.md +190 -277
- package/examples/@xmachines/play-svelte-demo/variables/demoComponents.md +15 -15
- package/examples/@xmachines/play-svelte-spa-router-demo/README.md +1 -1
- package/examples/@xmachines/play-sveltekit-router-demo/README.md +1 -1
- package/examples/@xmachines/play-tanstack-react-router-demo/README.md +3 -2
- package/examples/@xmachines/play-tanstack-solid-router-demo/README.md +9 -8
- package/examples/@xmachines/play-vue-demo/README.md +2 -2
- package/examples/@xmachines/play-vue-demo/functions/createAuthActionHandlers.md +9 -9
- package/examples/@xmachines/play-vue-demo/type-aliases/AuthCatalog.md +1 -1
- package/examples/@xmachines/play-vue-demo/variables/App.md +1 -1
- package/examples/@xmachines/play-vue-demo/variables/authCatalog.md +1 -1
- package/examples/@xmachines/play-vue-demo/variables/demoComponents.md +1 -1
- package/examples/@xmachines/play-vue-router-demo/README.md +3 -3
- package/examples/README.md +1 -1
- package/examples/form-validation.md +17 -13
- package/examples/multi-router-integration.md +269 -148
- package/examples/routing-patterns.md +44 -9
- package/examples/traffic-light.md +7 -3
- package/guides/README.md +5 -4
- package/guides/actor-model.md +41 -23
- package/guides/atoms.md +52 -12
- package/guides/getting-started.md +65 -19
- package/guides/inspector.md +72 -12
- package/guides/routing.md +44 -45
- package/guides/state-machines.md +102 -15
- package/guides/views.md +367 -0
- package/package.json +6 -6
- package/rfc/play.md +55 -21
- package/api/@xmachines/play-view/index/functions/createFailureLatch.md +0 -20
- package/api/@xmachines/play-view/index/functions/sameViewInputs.md +0 -25
- package/api/@xmachines/play-view/index/interfaces/FailureLatch.md +0 -60
- package/api/@xmachines/play-view/index/interfaces/ViewInputs.md +0 -19
package/guides/state-machines.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#
|
|
1
|
+
# State Machines in XMachines
|
|
2
2
|
|
|
3
3
|
XMachines uses XState v5 as its state machine engine. This page explains what finite state machines are, how XMachines extends them with routing and view metadata, and why this design eliminates an entire category of bugs common in traditional frontend architecture.
|
|
4
4
|
|
|
@@ -33,7 +33,6 @@ const authSetup = setup({
|
|
|
33
33
|
types: {
|
|
34
34
|
context: {} as { username: string | null },
|
|
35
35
|
events: {} as { type: "auth.login"; username: string } | { type: "auth.logout" },
|
|
36
|
-
input: {} as undefined,
|
|
37
36
|
},
|
|
38
37
|
});
|
|
39
38
|
|
|
@@ -47,7 +46,8 @@ const authMachine = authSetup.createMachine({
|
|
|
47
46
|
"auth.login": {
|
|
48
47
|
target: "authenticated",
|
|
49
48
|
actions: authSetup.assign({
|
|
50
|
-
username: ({ event }) =>
|
|
49
|
+
username: ({ event }) =>
|
|
50
|
+
event.type === "auth.login" ? event.username : null,
|
|
51
51
|
}),
|
|
52
52
|
},
|
|
53
53
|
},
|
|
@@ -78,6 +78,7 @@ XMachines extends XState's `meta` field on each state node. This is where routin
|
|
|
78
78
|
|
|
79
79
|
```typescript
|
|
80
80
|
import { typedSpec } from "@xmachines/play-view";
|
|
81
|
+
import { setup } from "xstate";
|
|
81
82
|
|
|
82
83
|
const appMachine = setup({/* ... */}).createMachine({
|
|
83
84
|
id: "app",
|
|
@@ -122,19 +123,90 @@ const appMachine = setup({/* ... */}).createMachine({
|
|
|
122
123
|
|
|
123
124
|
`meta.route` is a string path. When the machine enters a state, `actor.currentRoute` (a `ReadonlyAtom`) derives this path and emits it. The router bridge reads it and updates the URL.
|
|
124
125
|
|
|
125
|
-
`meta.view` is a [`
|
|
126
|
+
`meta.view` is a [`ViewMeta`](../api/@xmachines/play-view/index/interfaces/ViewMeta.md) — a `@xmachines/json-render-core` spec object describing what to render. The actor derives a [`PlaySpec`](../api/@xmachines/play-view/index/interfaces/PlaySpec.md) from it, and that derived spec is what a renderer receives. Use `typedSpec(...)` from [`@xmachines/play-view`](../api/@xmachines/play-view/README.md) to type-check the spec literal at the definition site (XState's `meta` is untyped). When the machine enters a state, `actor.currentView` is updated with the derived spec. The renderer reads it and projects it through framework components.
|
|
126
127
|
|
|
127
128
|
The machine's whole context is available to every view through the **`/context` projection**: the derived spec's `state` carries `context: <machine context>`. Specs read it with ordinary state expressions — `{ $state: "/context/username" }` in props, `visible` conditions, or `repeat.statePath`. The subtree is **read-only**: context changes only through machine events, and a `$bindState`/`setState` write under `/context` throws. URL data lives at its own paths (`/context/params/…`, `/context/query/…`, written into context by `formatPlayRouteTransitions`), so a URL param can never shadow a machine-owned field. When validating specs with tools like `validateSpec`, validate the **derived** view (`actor.currentView.get()`) — its `state` honestly describes the store contents — not the raw `meta.view`. A context change re-emits the view with the same `viewKey`; providers respond by refreshing `/context` in the live store, not by remounting the UI.
|
|
128
129
|
|
|
130
|
+
**Give each state its own id, and do not use an array index as an id.** XState does not check that the ids of the states are unique, and a repeated id makes a `#id` target name two states. XMachines keys the route, the view and its store on the id of a state, so two states that share an id share one route entry, one store, and one key. An array index is a whole number from 0 to 2³² − 2 with no leading zero, such as `"42"`. JavaScript lists such a key first in every object that is keyed on ids, so the route of its state loses its place in the branch. [`@xmachines/play-xstate`](../api/@xmachines/play-xstate/README.md) writes one warning for each machine that breaks these rules.
|
|
131
|
+
|
|
129
132
|
**The machine is the single source of truth for both routing and views.** There is no separate route configuration file. There is no switch statement in a component deciding what to render based on the URL. The state machine encodes all of that.
|
|
130
133
|
|
|
134
|
+
### A layout and its pages: `outlets`
|
|
135
|
+
|
|
136
|
+
Without outlets, the deepest active state that declares a view wins, and a view on a parent state stays off the screen. Declare `outlets` in the view of the parent to show the parent view AND the view of its active child. Each outlet names an element of the parent view, and the view of the child goes into that element:
|
|
137
|
+
|
|
138
|
+
```typescript
|
|
139
|
+
import { typedSpec, type ViewMeta } from "@xmachines/play-view";
|
|
140
|
+
import { setup } from "xstate";
|
|
141
|
+
|
|
142
|
+
declare const menuView: ViewMeta, homeView: ViewMeta, searchView: ViewMeta; // your views
|
|
143
|
+
|
|
144
|
+
const shell = typedSpec({
|
|
145
|
+
root: "shell",
|
|
146
|
+
state: { collapsed: false },
|
|
147
|
+
elements: {
|
|
148
|
+
shell: { type: "Shell", props: {}, children: ["title"], slots: { sidebar: [] } },
|
|
149
|
+
title: { type: "Heading", props: { text: "App" }, children: [] },
|
|
150
|
+
},
|
|
151
|
+
outlets: {
|
|
152
|
+
menu: { element: "shell", slot: "sidebar" }, // the region "menu"
|
|
153
|
+
"*": { element: "shell" }, // every other child
|
|
154
|
+
},
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
const appMachine = setup({/* ... */}).createMachine({
|
|
158
|
+
id: "app",
|
|
159
|
+
type: "parallel",
|
|
160
|
+
meta: { view: shell },
|
|
161
|
+
states: {
|
|
162
|
+
menu: { initial: "open", states: { open: { meta: { view: menuView } } } },
|
|
163
|
+
page: {
|
|
164
|
+
initial: "home",
|
|
165
|
+
states: {
|
|
166
|
+
home: { meta: { route: "/", view: homeView } },
|
|
167
|
+
search: { meta: { route: "/search", view: searchView } },
|
|
168
|
+
},
|
|
169
|
+
},
|
|
170
|
+
},
|
|
171
|
+
});
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
- **The key of an outlet** is the key of a child state in `states`, or `"*"` for each active child that has no outlet of its own. A child with neither stays off the screen.
|
|
175
|
+
- **A compound state** fills one outlet with its active child. **A parallel state** fills one outlet for each region, in the order of `states`.
|
|
176
|
+
- **`slot`** names a named slot of the element. Omit it to append the child view to the `children` of the element. The component of the element renders the slot, as the renderer of your framework describes.
|
|
177
|
+
- **The view of a child** is the deepest view in its active subtree, and a child view can declare `outlets` of its own for a nested layout. A parallel state without outlets shows the region of the routes when that region has a view, and its first region that has a view otherwise. The region of the routes keeps the screen while it sits in a state without a route of its own.
|
|
178
|
+
|
|
179
|
+
The derived spec holds the elements of every composed view. The keys of the outer view stay as you wrote them, and each key of a child view gets the id of its state as a prefix, for example `app.page.search/root`, so two views never collide.
|
|
180
|
+
|
|
181
|
+
The `viewKey` of a composed view is the id of the outermost state that declares `outlets`. A change of the page therefore keeps the store of the layout: the `collapsed` value in the example above does not change. The first time that a page shows, the provider writes the keys of its authored `state` that the store does not hold. A page that comes back finds the values that it left. All the pages of one layout share one store, so two pages that declare the same key share one value: give each page its own keys. When two composed views declare the same state key, the outer view wins. The library writes one warning for each layout that names every key that two of its views declare, also for two pages that are never on the screen together.
|
|
182
|
+
|
|
183
|
+
An outlet that names an element that its view does not hold throws `InvalidViewOutletError`. The actor reports it through its `onError` option, and it keeps the last good view.
|
|
184
|
+
|
|
185
|
+
**`handler` decides whether the layout survives a navigation.** Under the default `handler: "root"`, a navigation exits and enters every active state below the root, and a parallel state then puts its other regions back in their `initial` state. Declare `handler: "local"` or `"both"` on a routed state inside a region, as [Re-entry on a navigation](routing.md#re-entry-on-a-navigation) describes.
|
|
186
|
+
|
|
187
|
+
**The URL comes from the routed region.** In a parallel machine, the URL comes from the first region whose active states declare a `meta.route`, so the `menu` region can come before the `page` region. Keep the routes of one layout in one region. The URL shows the route of the first routed region only, so a navigation to a route of a second routed region never shows in the address bar.
|
|
188
|
+
|
|
189
|
+
CAUTION: a second routed region moves without its URL. Take a `page` region with `/` and `/search`, and a `drawer` region after it with `/drawer` and `/drawer/settings`:
|
|
190
|
+
|
|
191
|
+
| Step | `page` | `drawer` | URL |
|
|
192
|
+
| --------------------------- | -------- | ---------- | --------- |
|
|
193
|
+
| start | `home` | `closed` | `/` |
|
|
194
|
+
| a navigation to `#settings` | `home` | `settings` | `/` |
|
|
195
|
+
| a navigation to `#search` | `search` | `closed` | `/search` |
|
|
196
|
+
|
|
197
|
+
- The navigation to `#settings` moves the drawer, and the URL stays `/`. The browser adds no history entry, BACK does not close the drawer, and a reload or a shared link loses the drawer.
|
|
198
|
+
- A deep link to `/drawer/settings` moves the drawer too, but the actor derives the URL `/` from the `page` region, so the address bar does not keep the path of the drawer.
|
|
199
|
+
- The navigation to `#search` puts the drawer back to `closed`, because the default `handler: "root"` exits and enters every region. `handler: "local"` keeps it.
|
|
200
|
+
|
|
201
|
+
A URL path has one hierarchy, and it cannot hold the branches of two regions. Keep the other regions unrouted. When the position of such a region must survive a reload or a shared link, write it as a query value of the routed region, for example `/search?drawer=settings`. The generated `play.route` transition assigns the query to `context.query`, the URL carries `context.query`, and your machine moves the region to match the value.
|
|
202
|
+
|
|
131
203
|
---
|
|
132
204
|
|
|
133
205
|
## [`formatPlayRouteTransitions`](../api/@xmachines/play-xstate/with-routing/functions/formatPlayRouteTransitions.md) — automatic route event wiring
|
|
134
206
|
|
|
135
207
|
For routing to work, the machine must respond to `play.route` events (sent by router bridges when the user navigates). Writing these transitions by hand is mechanical:
|
|
136
208
|
|
|
137
|
-
```typescript
|
|
209
|
+
```typescript fragment
|
|
138
210
|
// Without formatPlayRouteTransitions — verbose and repetitive
|
|
139
211
|
states: {
|
|
140
212
|
home: {
|
|
@@ -154,6 +226,7 @@ states: {
|
|
|
154
226
|
|
|
155
227
|
```typescript
|
|
156
228
|
import { formatPlayRouteTransitions } from "@xmachines/play-xstate/routing";
|
|
229
|
+
import { setup } from "xstate";
|
|
157
230
|
|
|
158
231
|
const appMachine = setup({/* ... */}).createMachine(
|
|
159
232
|
formatPlayRouteTransitions({
|
|
@@ -170,7 +243,7 @@ const appMachine = setup({/* ... */}).createMachine(
|
|
|
170
243
|
|
|
171
244
|
[`formatPlayRouteTransitions`](../api/@xmachines/play-xstate/with-routing/functions/formatPlayRouteTransitions.md) inspects all state nodes with a `meta.route` and generates the corresponding `play.route` guard transitions. The machine's context must include `params` and `query` fields (populated by the router bridge when params or query strings are present):
|
|
172
245
|
|
|
173
|
-
```typescript
|
|
246
|
+
```typescript fragment
|
|
174
247
|
types: {
|
|
175
248
|
context: {} as {
|
|
176
249
|
params: Record<string, string>;
|
|
@@ -188,7 +261,12 @@ types: {
|
|
|
188
261
|
Guards are the mechanism by which the actor controls whether a transition occurs. They are pure functions of `{ context, event }` that return a boolean.
|
|
189
262
|
|
|
190
263
|
```typescript
|
|
264
|
+
import { setup } from "xstate";
|
|
265
|
+
|
|
191
266
|
const authSetup = setup({
|
|
267
|
+
types: {
|
|
268
|
+
context: {} as { isAuthenticated: boolean; role: "user" | "admin" },
|
|
269
|
+
},
|
|
192
270
|
guards: {
|
|
193
271
|
isAuthenticated: ({ context }) => context.isAuthenticated,
|
|
194
272
|
isAdmin: ({ context }) => context.role === "admin",
|
|
@@ -216,7 +294,7 @@ Each combinator resolves a guard NAME against the `guards` of `setup()`, so a na
|
|
|
216
294
|
|
|
217
295
|
Context is the machine's persistent data store. It survives transitions and can be read and updated by actions:
|
|
218
296
|
|
|
219
|
-
```typescript
|
|
297
|
+
```typescript fragment
|
|
220
298
|
// Context is defined in setup({ types })
|
|
221
299
|
types: {
|
|
222
300
|
context: {} as {
|
|
@@ -243,22 +321,30 @@ Context is accessed in guards, actions, and when computing routes or views. It i
|
|
|
243
321
|
A snapshot is a point-in-time serialisation of the machine's current state and context. XState produces snapshots in a JSON-compatible format:
|
|
244
322
|
|
|
245
323
|
```typescript
|
|
324
|
+
import { definePlayer } from "@xmachines/play-xstate";
|
|
325
|
+
import type { AnyStateMachine } from "xstate";
|
|
326
|
+
|
|
327
|
+
declare const machine: AnyStateMachine; // your machine
|
|
328
|
+
|
|
329
|
+
const createPlayer = definePlayer({ machine });
|
|
330
|
+
const actor = createPlayer();
|
|
331
|
+
actor.start();
|
|
332
|
+
|
|
246
333
|
const snapshot = actor.getSnapshot();
|
|
247
334
|
// snapshot.value → current state node name, e.g. "dashboard"
|
|
248
335
|
// snapshot.context → current context object
|
|
249
336
|
|
|
250
|
-
//
|
|
337
|
+
// Serialize and stop
|
|
338
|
+
const saved = JSON.stringify(actor.getPersistedSnapshot());
|
|
251
339
|
actor.stop();
|
|
252
|
-
const saved = JSON.stringify(snapshot);
|
|
253
340
|
|
|
254
341
|
// Restore
|
|
255
|
-
const restored = JSON.parse(saved);
|
|
256
|
-
|
|
257
|
-
actor.start();
|
|
342
|
+
const restored = createPlayer(undefined, { snapshot: JSON.parse(saved) });
|
|
343
|
+
restored.start();
|
|
258
344
|
// Actor resumes from where it left off
|
|
259
345
|
```
|
|
260
346
|
|
|
261
|
-
[`definePlayer`](../api/@xmachines/play-xstate/index/functions/definePlayer.md) accepts an optional
|
|
347
|
+
The factory that [`definePlayer`](../api/@xmachines/play-xstate/index/functions/definePlayer.md) returns accepts an optional second argument, `{ snapshot }`, for this purpose. Serialize the result of `getPersistedSnapshot()`, and not of `getSnapshot()`: XState restores from the persisted form. Restoration is useful for server-side rendering (hydrate with the server's snapshot), session persistence (resume after page reload), and testing (start from a known mid-flow state).
|
|
262
348
|
|
|
263
349
|
---
|
|
264
350
|
|
|
@@ -276,9 +362,10 @@ actor.start();
|
|
|
276
362
|
|
|
277
363
|
## See also
|
|
278
364
|
|
|
279
|
-
- [
|
|
280
|
-
- [
|
|
365
|
+
- [The Actor Model](actor-model.md) — how the machine definition becomes a live actor
|
|
366
|
+
- [Atoms](atoms.md) — how the actor's state is observed by infrastructure
|
|
281
367
|
- [Getting Started](getting-started.md) — step-by-step walkthrough building your first machine and actor
|
|
368
|
+
- [Views](views.md) — which state supplies the view, how a layout holds its pages, and when a renderer keeps the UI
|
|
282
369
|
- [Routing Patterns](../examples/routing-patterns.md) — worked examples of `meta.route` and guards
|
|
283
370
|
- [@xmachines/play-xstate](../api/@xmachines/play-xstate/README.md) — full API reference for [`definePlayer`](../api/@xmachines/play-xstate/index/functions/definePlayer.md), [`PlayerActor`](../api/@xmachines/play-xstate/index/classes/PlayerActor.md), and the routing utilities
|
|
284
371
|
- [XState v5 documentation](https://stately.ai/docs/xstate) — upstream state machine library documentation
|
package/guides/views.md
ADDED
|
@@ -0,0 +1,367 @@
|
|
|
1
|
+
# Views in XMachines
|
|
2
|
+
|
|
3
|
+
A view of XMachines is a fact about a STATE, and not a fact about a component tree. A state node declares `meta.view`, the actor derives the current view from the active states, and a renderer turns that description into the UI of one framework.
|
|
4
|
+
|
|
5
|
+
This guide tells which state supplies the view, how a parent view holds the views of its substates, how a view reads the machine context, and when a renderer keeps the UI and when it builds the UI again. It also names the four rules that every one of the five renderers follows.
|
|
6
|
+
|
|
7
|
+
After you read it, you know where to put a value that the screen shows, why a write to `/context` throws, and why a draft in a form survives one event and not another.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## What problem a view spec solves
|
|
12
|
+
|
|
13
|
+
An application without a machine decides the screen inside its components: `if (user && !loading) return <Dashboard />`. Each such condition is a second copy of a decision, and the copies disagree when one of them changes.
|
|
14
|
+
|
|
15
|
+
The machine knows the state already. XMachines therefore puts the view ON the state, as data. The component tree holds no condition that selects a screen, and the machine holds no import of a framework.
|
|
16
|
+
|
|
17
|
+
The data is a spec of `@xmachines/json-render-core`: a flat map of elements, each with a component type, props and children. One spec renders in React, in Vue, in SolidJS, in Svelte and in the plain DOM, because each renderer reads the same grammar.
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## The three parts of a view
|
|
22
|
+
|
|
23
|
+
| Part | Where it lives | What it says |
|
|
24
|
+
| -------- | ---------------------------------------------- | ----------------------------------------------------- |
|
|
25
|
+
| catalog | `defineCatalog(schema, …)`, one for each app | the component types and the actions that exist |
|
|
26
|
+
| spec | `meta.view` of a state node | WHICH components show in that state, with which data |
|
|
27
|
+
| registry | `defineRegistry(catalog, …)`, one per renderer | HOW each component renders, and what each action does |
|
|
28
|
+
|
|
29
|
+
The catalog is the vocabulary. It holds Zod schemas and no framework code. The spec uses the vocabulary. The registry binds each word to a component of one framework and to a handler of each action.
|
|
30
|
+
|
|
31
|
+
A machine and its specs therefore change never when you change the framework. You write a second registry.
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Declaring a view
|
|
36
|
+
|
|
37
|
+
A `meta.view` is a [`ViewMeta`](../api/@xmachines/play-view/index/interfaces/ViewMeta.md). `root` names the first element, and `elements` holds every element by its key:
|
|
38
|
+
|
|
39
|
+
```ts
|
|
40
|
+
import { setup } from "xstate";
|
|
41
|
+
import { typedSpec } from "@xmachines/play-view";
|
|
42
|
+
|
|
43
|
+
const machine = setup({}).createMachine({
|
|
44
|
+
id: "app",
|
|
45
|
+
initial: "home",
|
|
46
|
+
states: {
|
|
47
|
+
home: {
|
|
48
|
+
meta: {
|
|
49
|
+
view: typedSpec({
|
|
50
|
+
root: "page",
|
|
51
|
+
elements: {
|
|
52
|
+
page: { type: "Page", props: { title: "Welcome" }, children: ["intro"] },
|
|
53
|
+
intro: { type: "Text", props: { text: "Choose a task." }, children: [] },
|
|
54
|
+
},
|
|
55
|
+
}),
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
});
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
XState types `meta` as `Record<string, unknown>`, so TypeScript checks nothing that you write there. `typedSpec` of [`@xmachines/play-view`](../api/@xmachines/play-view/README.md) gives the literal the type `ViewMeta` where you write it, and it does nothing at run time. The check of an excess property works on an inline literal only. For a spec in a variable, write `satisfies ViewMeta` at the literal.
|
|
63
|
+
|
|
64
|
+
A `ViewMeta` is what you WRITE. A [`PlaySpec`](../api/@xmachines/play-view/index/interfaces/PlaySpec.md) is what the actor DERIVES from it, and what a renderer receives. The derivation consumes `outlets`, it adds the machine context, and it stamps `viewKey` and `viewParts`.
|
|
65
|
+
|
|
66
|
+
The view is an OPTIONAL capability of the actor. Compose it with `withView` of [`@xmachines/play-xstate`](../api/@xmachines/play-xstate/README.md), from its `view` subpath:
|
|
67
|
+
|
|
68
|
+
```ts
|
|
69
|
+
import { definePlayer, compose, PlayerActor } from "@xmachines/play-xstate";
|
|
70
|
+
import { withView } from "@xmachines/play-xstate/view";
|
|
71
|
+
import type { AnyStateMachine } from "xstate";
|
|
72
|
+
|
|
73
|
+
declare const machine: AnyStateMachine; // your machine
|
|
74
|
+
|
|
75
|
+
const actor = definePlayer({ machine, actor: compose(PlayerActor, withView) })();
|
|
76
|
+
actor.start();
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
The actor then holds `currentView`, a `ReadonlyAtom<PlaySpec | null>`. An application that renders no view composes no `withView`, and it installs no json-render.
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## Which state supplies the view
|
|
84
|
+
|
|
85
|
+
**The deepest active state that declares a view supplies it**, unless a parent composes it. A state that declares no view shows the view of its nearest ancestor that declares one. An ancestor view without `outlets` does not show, because the view of its descendant replaces it:
|
|
86
|
+
|
|
87
|
+
```ts fragment
|
|
88
|
+
states: {
|
|
89
|
+
dashboard: {
|
|
90
|
+
meta: { view: dashboardView }, // shows in dashboard.overview
|
|
91
|
+
initial: "overview",
|
|
92
|
+
states: {
|
|
93
|
+
overview: {},
|
|
94
|
+
settings: { meta: { view: settingsView } }, // replaces dashboardView
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
When no active state declares a view, `currentView` holds `null`, and the renderer shows its `fallback` content.
|
|
101
|
+
|
|
102
|
+
A **parallel** state follows the same region as the route derivation: the first region whose active states declare a `meta.route`, else the first region that declares a route in any state, else the first region. A region that owns the routes therefore keeps the screen while it sits in a state without a route, such as a load. The view on the screen therefore belongs to the region of the URL. When that region holds no view, the view comes from another active region, so one region can own the URL and another region can own the view. Keep the routes in one region: the [State Machines](state-machines.md#a-layout-and-its-pages-outlets) guide shows what a second routed region does to the URL.
|
|
103
|
+
|
|
104
|
+
### A layout and its pages: `outlets`
|
|
105
|
+
|
|
106
|
+
A parent view that declares `outlets` shows itself AND the view of its active child. Each outlet names an element of the parent view, and the view of the child goes into that element:
|
|
107
|
+
|
|
108
|
+
```ts fragment
|
|
109
|
+
const shell = typedSpec({
|
|
110
|
+
root: "shell",
|
|
111
|
+
state: { collapsed: false },
|
|
112
|
+
elements: {
|
|
113
|
+
shell: { type: "Shell", props: {}, children: ["title"] },
|
|
114
|
+
title: { type: "Heading", props: { text: "App" }, children: [] },
|
|
115
|
+
},
|
|
116
|
+
outlets: { "*": { element: "shell" } },
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
states: {
|
|
120
|
+
app: {
|
|
121
|
+
meta: { view: shell },
|
|
122
|
+
initial: "home",
|
|
123
|
+
states: {
|
|
124
|
+
home: { meta: { route: "/", view: homeView } },
|
|
125
|
+
search: { meta: { route: "/search", view: searchView } },
|
|
126
|
+
},
|
|
127
|
+
},
|
|
128
|
+
},
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
- The key of an outlet is the key of a child in `states`, or `"*"` for each active child that has no outlet of its own. A child with neither stays off the screen.
|
|
132
|
+
- A compound state fills one outlet with its active child. A parallel state fills one outlet for each region, in the order of `states`.
|
|
133
|
+
- `slot` names a named slot of the element. Omit it, and the renderer appends the child view to the `children` of the element.
|
|
134
|
+
- The view of a child is the deepest view below it. A child view can declare `outlets` of its own, for a nested layout.
|
|
135
|
+
- An outlet that names an element that its view does not hold throws `InvalidViewOutletError`. The actor reports it through `onError`, and it keeps the last valid view.
|
|
136
|
+
- The keys of the outer view carry no prefix, and each key of a child view gets the id of its state and a `/` as a prefix. A key of the outer view such as `"page/root"` equals the key of the element `root` of the child state `page`, and the composition throws `ViewElementKeyCollisionError`. Do not start a key of the outer view with the id of a state and a `/`.
|
|
137
|
+
|
|
138
|
+
The derived spec is ONE flat spec. The keys of the outer view stay as you wrote them. Each key of a child view gets the id of its state as a prefix: the `root` element of the view of the state `app.search` becomes `app.search/root`. Two views therefore never collide. The [State Machines](state-machines.md#a-layout-and-its-pages-outlets) guide shows a parallel layout with a named slot.
|
|
139
|
+
|
|
140
|
+
### The view key
|
|
141
|
+
|
|
142
|
+
The derivation stamps the identity of the view on the spec, as `viewKey`. For a view without outlets, it is the id of the state that declares the view. For a composed view, it is the id of the outermost state that declares `outlets`, and `viewParts` lists the id of each composed state. The [renderer section](#when-the-renderer-keeps-the-ui) tells why the key matters. Never write `viewKey` or `viewParts` yourself: `typedSpec` refuses both, and the derivation overwrites them.
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
## Reading the machine context
|
|
147
|
+
|
|
148
|
+
Each derived view carries the whole machine context in its `state`, under the key `context`:
|
|
149
|
+
|
|
150
|
+
```
|
|
151
|
+
derived state = { ...meta.view.state, context: <the machine context> }
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
A spec reads the context through the ordinary state grammar of json-render. The same path works in a prop, in a `visible` condition, and in `repeat.statePath`:
|
|
155
|
+
|
|
156
|
+
```ts fragment
|
|
157
|
+
elements: {
|
|
158
|
+
greeting: { type: "Text", props: { text: { $state: "/context/username" } }, children: [] },
|
|
159
|
+
tasks: {
|
|
160
|
+
type: "List",
|
|
161
|
+
props: {},
|
|
162
|
+
repeat: { statePath: "/context/tasks", key: "id" },
|
|
163
|
+
children: ["task"],
|
|
164
|
+
},
|
|
165
|
+
task: { type: "Text", props: { text: { $item: "title" } }, children: [] },
|
|
166
|
+
},
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
The routing capability writes the URL into the context: the params go to `context.params`, and the query goes to `context.query`. A spec therefore reads `/context/params/userId` for a value of the URL and `/context/username` for a value of the machine. The path tells the origin of each value, and a param can hide no field of the machine.
|
|
170
|
+
|
|
171
|
+
**The `/context` subtree is read-only to the spec.** A `$bindState` write or a `setState` write under `/context` throws `ReadOnlyContextError`, and the message names the path. The context changes through a machine event only. A handler that writes the whole snapshot back, with the `context` key unchanged, does not throw: the store ignores a write of an identical value.
|
|
172
|
+
|
|
173
|
+
`context` is a reserved key. When `meta.view.state` declares a top-level `context` key of its own, the derivation skips the projection for that view, the authored value wins, and a warning in development names the conflict. Rename the field.
|
|
174
|
+
|
|
175
|
+
CAUTION: the projection shows the WHOLE context to the client. A debug panel, an inspector and a validator read the view store, and each one is a client-side tool. Keep a secret out of the context.
|
|
176
|
+
|
|
177
|
+
Validate the DERIVED view, `actor.currentView.get()`, and not the raw `meta.view`. The `state` of the derived view describes the store as it is, so a tool such as `validateSpec` sees a spec that agrees with itself.
|
|
178
|
+
|
|
179
|
+
---
|
|
180
|
+
|
|
181
|
+
## Two kinds of state
|
|
182
|
+
|
|
183
|
+
A view store holds two kinds of state, at two places, with two owners.
|
|
184
|
+
|
|
185
|
+
| Kind | Where in the store | Written by | Lives for |
|
|
186
|
+
| --------------- | --------------------- | ------------------------------------------------------------ | ------------- |
|
|
187
|
+
| ephemeral state | the root: `/username` | `spec.state` seeds it; `$bindState` and `setState` change it | one `viewKey` |
|
|
188
|
+
| domain state | `/context/…` | the machine, through an event | the actor |
|
|
189
|
+
|
|
190
|
+
Ephemeral state is the state of the screen: a draft in a field, an open panel, a selected tab. The machine does not need it until the user commits it.
|
|
191
|
+
|
|
192
|
+
Domain state is the state of the application. Each change of it is an event, so the inspector shows each change with its cause.
|
|
193
|
+
|
|
194
|
+
This login form uses both. The field binds to `/username`, and the submit sends the value to the machine:
|
|
195
|
+
|
|
196
|
+
```ts fragment
|
|
197
|
+
view: typedSpec({
|
|
198
|
+
root: "form",
|
|
199
|
+
state: { username: "" },
|
|
200
|
+
elements: {
|
|
201
|
+
form: {
|
|
202
|
+
type: "Login",
|
|
203
|
+
props: { username: { $bindState: "/username" } },
|
|
204
|
+
children: [],
|
|
205
|
+
on: {
|
|
206
|
+
submit: { action: "login", params: { username: { $state: "/username" } } },
|
|
207
|
+
},
|
|
208
|
+
},
|
|
209
|
+
},
|
|
210
|
+
}),
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
Keep high-frequency data in the ephemeral state or in a child actor, and not in the context. Each change of a top-level field of the context emits the view again. A keystroke is not a fact of the domain.
|
|
214
|
+
|
|
215
|
+
---
|
|
216
|
+
|
|
217
|
+
## How an interaction becomes an event
|
|
218
|
+
|
|
219
|
+
A component emits a named event of json-render, such as `submit` or `press`. The `on` field of its element maps that name to an ACTION, with params that the renderer resolves from the store. The registry holds the handler of each action, and a handler of a domain action sends a machine event:
|
|
220
|
+
|
|
221
|
+
```ts
|
|
222
|
+
import { defineCatalog } from "@xmachines/json-render-core";
|
|
223
|
+
import { defineRegistry, schema, type ComponentFn } from "@xmachines/play-dom";
|
|
224
|
+
import type { ViewActor } from "@xmachines/play-view";
|
|
225
|
+
import { z } from "zod";
|
|
226
|
+
|
|
227
|
+
declare const actor: ViewActor<unknown, { type: "auth.login"; username: string }>;
|
|
228
|
+
|
|
229
|
+
const catalog = defineCatalog(schema, {
|
|
230
|
+
components: { Login: { props: z.object({ username: z.string() }) } },
|
|
231
|
+
actions: { login: { params: z.object({ username: z.string() }) } },
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
declare const Login: ComponentFn<typeof catalog, "Login">; // your component
|
|
235
|
+
|
|
236
|
+
const registryResult = defineRegistry(catalog, {
|
|
237
|
+
components: { Login },
|
|
238
|
+
actions: {
|
|
239
|
+
login: async (params) => {
|
|
240
|
+
if (params) actor.send({ type: "auth.login", username: params.username });
|
|
241
|
+
},
|
|
242
|
+
},
|
|
243
|
+
});
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
The guards of the machine then decide. The renderer changes no state of the machine, and it selects no view. It sends, and it shows what the actor derives next.
|
|
247
|
+
|
|
248
|
+
The renderer implements four built-in actions over the ephemeral state: `setState`, `pushState`, `removeState` and `validateForm`. They need no handler in the registry. An `on` entry can hold an array of bindings, and the renderer runs them in order. For example, it sends the event, and then it clears the draft:
|
|
249
|
+
|
|
250
|
+
```ts fragment
|
|
251
|
+
on: {
|
|
252
|
+
press: [
|
|
253
|
+
{ action: "addTask", params: { title: { $state: "/newTaskTitle" } } },
|
|
254
|
+
{ action: "setState", params: { statePath: "/newTaskTitle", value: "" } },
|
|
255
|
+
],
|
|
256
|
+
},
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
In an action param, `{ $item: "id" }` resolves to the JSON pointer of the item field, such as `/context/tasks/0/id`, and not to its value. The built-ins need the pointer to address the entry. A handler that needs the value reads it from the state that it receives as its third argument.
|
|
260
|
+
|
|
261
|
+
---
|
|
262
|
+
|
|
263
|
+
## When the renderer keeps the UI
|
|
264
|
+
|
|
265
|
+
A renderer holds one view store for each view, and the `viewKey` decides its lifetime.
|
|
266
|
+
|
|
267
|
+
| The emission | What the renderer does |
|
|
268
|
+
| ------------------------------------- | --------------------------------------------------------------- |
|
|
269
|
+
| a new `viewKey` | it seeds a NEW store from `spec.state` |
|
|
270
|
+
| the same `viewKey` | it replaces `/context` in the live store, and it keeps the rest |
|
|
271
|
+
| the same `viewKey`, new `viewParts` | as above, and it writes each authored key that the store lacks |
|
|
272
|
+
| no `viewKey`, from a hand-built actor | it seeds a new store for each emission |
|
|
273
|
+
| a different actor | it discards the store with the actor |
|
|
274
|
+
| `null` | it shows the fallback, and it resolves no store |
|
|
275
|
+
|
|
276
|
+
With the same `viewKey`, every renderer keeps the DOM nodes, the focus and the ephemeral state. A context change therefore updates a list under a field that has the focus, and the draft in the field stays.
|
|
277
|
+
|
|
278
|
+
With a new `viewKey`, the ephemeral state starts again from `spec.state`, and every renderer builds the view again. The state that a component keeps for itself, such as the text of an unbound input, goes with the old view. Two sibling states that each declare a view therefore reset a draft on each transition between them, also when their two specs are equal.
|
|
279
|
+
|
|
280
|
+
A parent keeps the ephemeral state across a move between its children in one of two ways:
|
|
281
|
+
|
|
282
|
+
- **Declare the view on the parent**, and no view on the children. The `viewKey` stays the id of the parent.
|
|
283
|
+
- **Declare `outlets` on the parent.** The `viewKey` stays the id of the parent, and each child still shows its own view. A change of the page keeps the store of the layout, so the `collapsed` value of the [layout above](#a-layout-and-its-pages-outlets) does not change.
|
|
284
|
+
|
|
285
|
+
In a composed view, all the views of one layout share ONE store. The first time that a page shows, the renderer writes each key of its authored `state` that the store does not hold. A page that comes back finds the values that it left. Two pages that declare the same key therefore share one value: give each page its own keys. When two composed views declare the same key, the outer view wins. play-xstate reads the states of the machine one time, and it writes one warning for each layout that names every key that two of its views declare.
|
|
286
|
+
|
|
287
|
+
`currentView` also emits only on a real change of the view on the screen. An event that changes no context field and moves to no other view keeps the previous reference, and no subscriber runs. The gate compares the top-level fields of the context. It does not enter a value, so a new object in a field emits again, also when its contents are equal.
|
|
288
|
+
|
|
289
|
+
In the **controlled mode**, you give the provider a `store`. The provider then ignores `spec.state`, and you own the seed and the lifetime of that store. The renderer still owns `/context`, and it refreshes the subtree in your store on each emission. The tree lives as long as its store, so a new `viewKey` keeps the tree in the controlled mode, and a new store builds it again.
|
|
290
|
+
|
|
291
|
+
---
|
|
292
|
+
|
|
293
|
+
## When a view fails
|
|
294
|
+
|
|
295
|
+
A failure of the DERIVATION stays inside the actor. `currentView` catches it, it keeps the last valid view, and it reports the error to the `onError` hook of the actor in a microtask. The transition continues for every other observer.
|
|
296
|
+
|
|
297
|
+
A failure of the RENDER stays inside the provider. When a component throws, when the store does not resolve, or when the root of the view fails, the provider shows its `fallback` and it calls its own `onError` prop:
|
|
298
|
+
|
|
299
|
+
| Renderer | The `onError` prop of the provider |
|
|
300
|
+
| ----------------------------------------------------------------- | ---------------------------------- |
|
|
301
|
+
| [`@xmachines/play-react`](../api/@xmachines/play-react/README.md) | `(error, reset, info) => void` |
|
|
302
|
+
| the four other renderers | `(error, reset) => void` |
|
|
303
|
+
|
|
304
|
+
The provider reports one failure one time for one set of inputs — the actor, the view and the store — and not one time for each render. A new emission, or a call of `reset`, makes the next failure report again. Without `onError`, the provider writes the failure to `console.error`, so that no failure is silent. A handler that throws does not break the containment: the provider writes that failure to `console.error` too.
|
|
305
|
+
|
|
306
|
+
`onRenderError` receives each failure that json-render reports, with `(error, name, info)`, and it replaces every handler of `defineRegistry`. `info.kind` names the failure: a catalog component that throws (`"element"`), a prop or a `visible` condition of a child (`"props"`, `"visible"`), an action chain or a watch chain (`"action"`, `"watch"`), or the root (`"root"`). A failure of the ROOT — its component, a prop, or its `visible` condition — leaves no view on the screen. json-render gives it to no error boundary of the host, so each of the five providers contains it as a failure of the view: it shows its `fallback`, it calls `onError` one time, and the next view renders again. `onRenderError` also receives it, with the kind `"root"`. A failure below the root reaches `onRenderError` alone, and the rest of the view stays. Without a handler of the host, the provider writes one console line for a failure of the root, and not two.
|
|
307
|
+
|
|
308
|
+
---
|
|
309
|
+
|
|
310
|
+
## The view invariants
|
|
311
|
+
|
|
312
|
+
### 1. The machine selects the view. The renderer never does
|
|
313
|
+
|
|
314
|
+
The renderer reads `currentView` and shows it. No component decides which screen shows. A condition that selects a screen belongs in a state and its guards.
|
|
315
|
+
|
|
316
|
+
### 2. `/context` is read-only to the spec
|
|
317
|
+
|
|
318
|
+
A spec reads the machine context, and it writes it never. The store throws `ReadOnlyContextError` for a write, and the machine changes the context through an event. The renderer refreshes the subtree through a store below the guard, so the rule binds the spec and not the machinery.
|
|
319
|
+
|
|
320
|
+
### 3. The `viewKey` decides the life of the ephemeral state
|
|
321
|
+
|
|
322
|
+
The same key keeps the store, and a new key seeds a new one. Put a view, or a layout with `outlets`, on the state whose lifetime the ephemeral state must have.
|
|
323
|
+
|
|
324
|
+
### 4. A renderer reads `currentView` and `send`, and nothing else
|
|
325
|
+
|
|
326
|
+
A provider takes a `ViewActor`: the actor contract and the `Viewable` capability. It names no engine and no router. The five renderers read no router package, and the routers read no view package. The two halves meet in the application only.
|
|
327
|
+
|
|
328
|
+
---
|
|
329
|
+
|
|
330
|
+
## Which renderer to use
|
|
331
|
+
|
|
332
|
+
| Renderer | Mount |
|
|
333
|
+
| ------------------------------------------------------------------- | ---------------------------------------------- |
|
|
334
|
+
| [`@xmachines/play-react`](../api/@xmachines/play-react/README.md) | `<PlayUIProvider>` around `<PlayRenderer />` |
|
|
335
|
+
| [`@xmachines/play-vue`](../api/@xmachines/play-vue/README.md) | `<PlayUIProvider>` around `<PlayRenderer />` |
|
|
336
|
+
| [`@xmachines/play-solid`](../api/@xmachines/play-solid/README.md) | `<PlayUIProvider>` around `<PlayRenderer />` |
|
|
337
|
+
| [`@xmachines/play-svelte`](../api/@xmachines/play-svelte/README.md) | `<PlayUIProvider>` around `<PlayRenderer />` |
|
|
338
|
+
| [`@xmachines/play-dom`](../api/@xmachines/play-dom/README.md) | `createPlayUI(registryResult)(actor, element)` |
|
|
339
|
+
|
|
340
|
+
Each one exports `schema` for `defineCatalog`, and `defineRegistry` for its own components. `PlayUIProvider` takes the `actor`, the `registryResult`, and the optional `store`, `fallback`, `onError` and `onRenderError`. The [Getting Started](getting-started.md#connecting-a-view-renderer) guide shows a complete mount for each framework.
|
|
341
|
+
|
|
342
|
+
[`@xmachines/play-view`](../api/@xmachines/play-view/README.md) holds the part that the five share: the view session, which resolves the store of each view outside a render, the `/context` guard and the report guard. A shared contract suite runs the same scenarios against each renderer, so the five agree on what a viewer sees.
|
|
343
|
+
|
|
344
|
+
---
|
|
345
|
+
|
|
346
|
+
## Summary
|
|
347
|
+
|
|
348
|
+
| Question | Answer |
|
|
349
|
+
| ----------------------------------------- | ------------------------------------------------------------------- |
|
|
350
|
+
| Where does a view come from? | `meta.view` of the deepest active state that declares one |
|
|
351
|
+
| How does a layout show its page? | The layout declares `outlets`, and the page view goes into one |
|
|
352
|
+
| What shows when no state declares a view? | The `fallback` of the provider |
|
|
353
|
+
| How does a spec read the machine context? | `{ $state: "/context/…" }`, in a prop, a condition or a repeat |
|
|
354
|
+
| Can a spec write the context? | No. Send the actor an event |
|
|
355
|
+
| Where does a draft go? | In `spec.state`, at the root of the store, with `$bindState` |
|
|
356
|
+
| When does a draft reset? | When the `viewKey` changes: the outermost state of the view changes |
|
|
357
|
+
| Which side selects the screen? | The machine, in every renderer |
|
|
358
|
+
| Who reports a failure of a render? | The provider, one time, through its `onError` |
|
|
359
|
+
|
|
360
|
+
## See also
|
|
361
|
+
|
|
362
|
+
- [State Machines](state-machines.md) — how `meta.route` and `meta.view` sit on a state node
|
|
363
|
+
- [Routing](routing.md) — the other half, and the same rule of a single active branch
|
|
364
|
+
- [Atoms](atoms.md) — the primitive under `currentView`
|
|
365
|
+
- [The Actor Model](actor-model.md) — why the machine holds no framework import
|
|
366
|
+
- [Form validation](../examples/form-validation.md) — a worked login form, with `$bindState` and a guard
|
|
367
|
+
- [@xmachines/play-view](../api/@xmachines/play-view/README.md) — API reference
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xmachines/docs",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "7.0.0",
|
|
4
4
|
"description": "Documentation for XMachines",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"documentation",
|
|
@@ -56,13 +56,13 @@
|
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {
|
|
58
58
|
"@testing-library/jest-dom": "^7.0.1",
|
|
59
|
-
"@types/node": "^26.6.
|
|
60
|
-
"oxfmt": "^0.
|
|
61
|
-
"oxlint": "^1.
|
|
59
|
+
"@types/node": "^26.6.4",
|
|
60
|
+
"oxfmt": "^0.71.0",
|
|
61
|
+
"oxlint": "^1.86.0",
|
|
62
62
|
"typedoc": "^0.28.20",
|
|
63
63
|
"typedoc-plugin-llms-txt": "^0.1.2",
|
|
64
|
-
"typedoc-plugin-markdown": "^4.13.
|
|
65
|
-
"vitest": "^5.0.
|
|
64
|
+
"typedoc-plugin-markdown": "^4.13.1",
|
|
65
|
+
"vitest": "^5.0.3"
|
|
66
66
|
},
|
|
67
67
|
"engines": {
|
|
68
68
|
"node": ">=24.0.0"
|