@xmachines/docs 1.0.0-beta.26 → 1.0.0-beta.27
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/api/@xmachines/play/classes/PlayError.md +4 -4
- package/api/@xmachines/play/type-aliases/PlayEvent.md +2 -2
- package/api/@xmachines/play-actor/classes/AbstractActor.md +3 -3
- package/api/@xmachines/play-actor/functions/typedSpec.md +1 -1
- package/api/@xmachines/play-actor/interfaces/PlaySpec.md +2 -2
- package/api/@xmachines/play-actor/interfaces/Routable.md +3 -3
- package/api/@xmachines/play-actor/interfaces/ViewMetadata.md +3 -3
- package/api/@xmachines/play-actor/interfaces/Viewable.md +2 -2
- package/api/@xmachines/play-dom/README.md +24 -8
- package/api/@xmachines/play-dom/classes/PlayRenderer.md +4 -4
- package/api/@xmachines/play-dom/functions/connectRenderer.md +1 -1
- package/api/@xmachines/play-dom/functions/defineRegistry.md +61 -0
- package/api/@xmachines/play-dom/functions/renderSpec.md +29 -12
- package/api/@xmachines/play-dom/interfaces/ComponentContext.md +62 -0
- package/api/@xmachines/play-dom/interfaces/ConnectRendererOptions.md +9 -9
- package/api/@xmachines/play-dom/interfaces/DefineRegistryOptions.md +25 -0
- package/api/@xmachines/play-dom/interfaces/DefineRegistryResult.md +18 -0
- package/api/@xmachines/play-dom/interfaces/DomRenderContext.md +13 -10
- package/api/@xmachines/play-dom/interfaces/EventHandle.md +29 -0
- package/api/@xmachines/play-dom/interfaces/PlayDomOptions.md +5 -5
- package/api/@xmachines/play-dom/type-aliases/ComponentFn.md +53 -0
- package/api/@xmachines/play-dom/type-aliases/ComponentRegistry.md +21 -0
- package/api/@xmachines/play-dom/type-aliases/DomComponentRenderer.md +16 -3
- package/api/@xmachines/play-dom/type-aliases/DomRegistry.md +5 -2
- 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/createRouteMap.md +1 -1
- package/api/@xmachines/play-dom-router/functions/createRouter.md +1 -1
- 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 +4 -4
- package/api/@xmachines/play-dom-router/interfaces/PlayRouteEvent.md +6 -6
- package/api/@xmachines/play-dom-router/interfaces/RouteMap.md +3 -3
- package/api/@xmachines/play-dom-router/interfaces/RouteMapLike.md +3 -3
- 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/VanillaRouter.md +4 -4
- package/api/@xmachines/play-dom-router/type-aliases/RoutableActor.md +1 -1
- package/api/@xmachines/play-dom-router-demo/README.md +46 -51
- package/api/@xmachines/play-react/classes/PlayErrorBoundary.md +5 -5
- package/api/@xmachines/play-react/functions/useActor.md +1 -1
- package/api/@xmachines/play-react/functions/useSignalEffect.md +1 -1
- package/api/@xmachines/play-react/interfaces/PlayErrorBoundaryProps.md +4 -4
- package/api/@xmachines/play-react/interfaces/PlayErrorBoundaryState.md +3 -3
- package/api/@xmachines/play-react/interfaces/PlayRendererProps.md +7 -7
- package/api/@xmachines/play-react/type-aliases/PlayActor.md +1 -1
- package/api/@xmachines/play-react/variables/PlayRenderer.md +1 -1
- package/api/@xmachines/play-react-router/classes/ReactRouterBridge.md +23 -23
- package/api/@xmachines/play-react-router/classes/RouteMap.md +4 -4
- package/api/@xmachines/play-react-router/functions/PlayRouterProvider.md +1 -1
- package/api/@xmachines/play-react-router/functions/createRouteMapFromTree.md +1 -1
- package/api/@xmachines/play-react-router/interfaces/PlayRouteEvent.md +6 -6
- package/api/@xmachines/play-react-router/interfaces/PlayRouterProviderProps.md +5 -5
- 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-router/classes/BaseRouteMap.md +4 -4
- package/api/@xmachines/play-router/classes/RouterBridgeBase.md +23 -23
- package/api/@xmachines/play-router/functions/buildPlayRouteEvent.md +1 -1
- package/api/@xmachines/play-router/functions/buildRouteTree.md +1 -1
- package/api/@xmachines/play-router/functions/createRouteMap.md +1 -1
- package/api/@xmachines/play-router/functions/createRouteMapFromMachine.md +1 -1
- package/api/@xmachines/play-router/functions/createRouteMapFromTree.md +1 -1
- package/api/@xmachines/play-router/functions/detectDuplicateRoutes.md +1 -1
- package/api/@xmachines/play-router/functions/extractMachineRoutes.md +1 -1
- package/api/@xmachines/play-router/functions/extractQuery.md +1 -1
- package/api/@xmachines/play-router/functions/extractRouteParams.md +1 -1
- package/api/@xmachines/play-router/functions/findRouteById.md +1 -1
- package/api/@xmachines/play-router/functions/findRouteByPath.md +1 -1
- package/api/@xmachines/play-router/functions/getNavigableRoutes.md +1 -1
- package/api/@xmachines/play-router/functions/getRoutableRoutes.md +1 -1
- package/api/@xmachines/play-router/functions/getTransitionReachableRoutes.md +1 -1
- package/api/@xmachines/play-router/functions/isRouteReachable.md +1 -1
- package/api/@xmachines/play-router/functions/machineToGraph.md +1 -1
- package/api/@xmachines/play-router/functions/routeExists.md +1 -1
- package/api/@xmachines/play-router/functions/sanitizePathname.md +1 -1
- package/api/@xmachines/play-router/functions/validateRouteFormat.md +1 -1
- package/api/@xmachines/play-router/functions/validateStateExists.md +1 -1
- package/api/@xmachines/play-router/interfaces/BuildPlayRouteEventOptions.md +4 -4
- package/api/@xmachines/play-router/interfaces/LocationLike.md +3 -3
- package/api/@xmachines/play-router/interfaces/MachineEdgeData.md +3 -3
- package/api/@xmachines/play-router/interfaces/MachineNodeData.md +5 -5
- package/api/@xmachines/play-router/interfaces/PlayRouteEvent.md +6 -6
- package/api/@xmachines/play-router/interfaces/RouteInfo.md +8 -8
- package/api/@xmachines/play-router/interfaces/RouteMap.md +4 -4
- package/api/@xmachines/play-router/interfaces/RouteMapping.md +3 -3
- package/api/@xmachines/play-router/interfaces/RouteMatch.md +3 -3
- package/api/@xmachines/play-router/interfaces/RouteNode.md +10 -10
- package/api/@xmachines/play-router/interfaces/RouteObject.md +2 -2
- package/api/@xmachines/play-router/interfaces/RouteTree.md +5 -5
- package/api/@xmachines/play-router/interfaces/RouteWatcherHandle.md +3 -3
- package/api/@xmachines/play-router/interfaces/RouterBridge.md +3 -3
- package/api/@xmachines/play-router/interfaces/WindowLike.md +3 -3
- package/api/@xmachines/play-router/type-aliases/MachineGraph.md +1 -1
- package/api/@xmachines/play-router/type-aliases/RouteMetadata.md +1 -1
- package/api/@xmachines/play-signals/functions/watchSignal.md +1 -1
- package/api/@xmachines/play-signals/interfaces/ComputedOptions.md +2 -2
- package/api/@xmachines/play-signals/interfaces/SignalComputed.md +2 -2
- package/api/@xmachines/play-signals/interfaces/SignalOptions.md +2 -2
- package/api/@xmachines/play-signals/interfaces/SignalState.md +3 -3
- package/api/@xmachines/play-signals/interfaces/SignalWatcher.md +4 -4
- package/api/@xmachines/play-signals/type-aliases/WatcherNotify.md +1 -1
- package/api/@xmachines/play-solid/functions/useActor.md +1 -1
- package/api/@xmachines/play-solid/interfaces/PlayRendererProps.md +7 -7
- package/api/@xmachines/play-solid/type-aliases/PlayActor.md +1 -1
- package/api/@xmachines/play-solid/variables/PlayRenderer.md +1 -1
- package/api/@xmachines/play-solid-router/classes/RouteMap.md +4 -4
- package/api/@xmachines/play-solid-router/classes/SolidRouterBridge.md +24 -24
- package/api/@xmachines/play-solid-router/functions/PlayRouterProvider.md +1 -1
- package/api/@xmachines/play-solid-router/functions/createRouteMap.md +1 -1
- package/api/@xmachines/play-solid-router/interfaces/AbstractActor.md +3 -3
- package/api/@xmachines/play-solid-router/interfaces/PlayRouteEvent.md +6 -6
- package/api/@xmachines/play-solid-router/interfaces/PlayRouterProviderProps.md +5 -5
- 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/RoutableActor.md +1 -1
- package/api/@xmachines/play-solid-router/type-aliases/SolidRouterHooks.md +4 -4
- package/api/@xmachines/play-solid-router-demo/README.md +25 -28
- package/api/@xmachines/play-svelte/interfaces/PlayRendererProps.md +7 -7
- package/api/@xmachines/play-svelte-spa-router/classes/RouteMap.md +4 -4
- package/api/@xmachines/play-svelte-spa-router/functions/connectRouter.md +1 -1
- package/api/@xmachines/play-svelte-spa-router/functions/createRouteMap.md +1 -1
- package/api/@xmachines/play-svelte-spa-router/interfaces/ConnectRouterOptions.md +4 -4
- package/api/@xmachines/play-svelte-spa-router/interfaces/PlayRouteEvent.md +6 -6
- 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/WindowLike.md +3 -3
- package/api/@xmachines/play-svelte-spa-router/type-aliases/RoutableActor.md +1 -1
- package/api/@xmachines/play-svelte-spa-router-demo/README.md +119 -12
- package/api/@xmachines/play-sveltekit-router/classes/RouteMap.md +4 -4
- package/api/@xmachines/play-sveltekit-router/functions/connectRouter.md +1 -1
- package/api/@xmachines/play-sveltekit-router/functions/createRouteMap.md +1 -1
- package/api/@xmachines/play-sveltekit-router/interfaces/ConnectRouterOptions.md +4 -4
- package/api/@xmachines/play-sveltekit-router/interfaces/LocationLike.md +3 -3
- package/api/@xmachines/play-sveltekit-router/interfaces/PlayRouteEvent.md +6 -6
- 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/type-aliases/RoutableActor.md +1 -1
- package/api/@xmachines/play-sveltekit-router-demo/README.md +120 -12
- package/api/@xmachines/play-tanstack-react-router/classes/RouteMap.md +4 -4
- package/api/@xmachines/play-tanstack-react-router/classes/TanStackReactRouterBridge.md +23 -23
- package/api/@xmachines/play-tanstack-react-router/functions/PlayRouterProvider.md +1 -1
- package/api/@xmachines/play-tanstack-react-router/functions/createRouteMap.md +1 -1
- package/api/@xmachines/play-tanstack-react-router/functions/createRouteMapFromTree.md +1 -1
- package/api/@xmachines/play-tanstack-react-router/functions/extractMachineRoutes.md +1 -1
- package/api/@xmachines/play-tanstack-react-router/interfaces/PlayRouteEvent.md +6 -6
- package/api/@xmachines/play-tanstack-react-router/interfaces/PlayRouterProviderProps.md +5 -5
- package/api/@xmachines/play-tanstack-react-router/interfaces/RouteMapping.md +3 -3
- package/api/@xmachines/play-tanstack-react-router/interfaces/RouteNavigateEvent.md +3 -3
- package/api/@xmachines/play-tanstack-react-router/interfaces/RouterBridge.md +3 -3
- package/api/@xmachines/play-tanstack-react-router/type-aliases/TanStackRouterInstance.md +1 -1
- package/api/@xmachines/play-tanstack-react-router/type-aliases/TanStackRouterLike.md +17 -3
- package/api/@xmachines/play-tanstack-react-router-demo/README.md +23 -29
- package/api/@xmachines/play-tanstack-solid-router/classes/RouteMap.md +4 -4
- package/api/@xmachines/play-tanstack-solid-router/classes/SolidRouterBridge.md +24 -24
- package/api/@xmachines/play-tanstack-solid-router/functions/PlayRouterProvider.md +1 -1
- package/api/@xmachines/play-tanstack-solid-router/functions/createRouteMap.md +1 -1
- package/api/@xmachines/play-tanstack-solid-router/interfaces/PlayRouteEvent.md +6 -6
- package/api/@xmachines/play-tanstack-solid-router/interfaces/PlayRouterProviderProps.md +5 -5
- 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/RoutableActor.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 +3 -3
- package/api/@xmachines/play-tanstack-solid-router-demo/README.md +25 -26
- 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/interfaces/PlayRendererProps.md +5 -5
- 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 +4 -3
- package/api/@xmachines/play-vue/type-aliases/PlayActor.md +1 -1
- package/api/@xmachines/play-vue/variables/PlayRenderer.md +1 -1
- package/api/@xmachines/play-vue-router/classes/RouteMap.md +4 -4
- package/api/@xmachines/play-vue-router/classes/VueBaseRouteMap.md +4 -4
- package/api/@xmachines/play-vue-router/classes/VueRouterBridge.md +24 -24
- package/api/@xmachines/play-vue-router/functions/createRouteMap.md +1 -1
- package/api/@xmachines/play-vue-router/interfaces/PlayRouteEvent.md +6 -6
- package/api/@xmachines/play-vue-router/interfaces/RouteMapping.md +3 -3
- package/api/@xmachines/play-vue-router/interfaces/RouterBridge.md +3 -3
- package/api/@xmachines/play-vue-router/type-aliases/RoutableActor.md +1 -1
- package/api/@xmachines/play-vue-router/variables/PlayRouterProvider.md +1 -1
- package/api/@xmachines/play-vue-router-demo/README.md +47 -40
- package/api/@xmachines/play-xstate/classes/PlayerActor.md +11 -11
- package/api/@xmachines/play-xstate/functions/buildRouteUrl.md +1 -1
- package/api/@xmachines/play-xstate/functions/composeGuards.md +1 -1
- package/api/@xmachines/play-xstate/functions/composeGuardsOr.md +1 -1
- package/api/@xmachines/play-xstate/functions/contextFieldMatches.md +1 -1
- package/api/@xmachines/play-xstate/functions/definePlayer.md +1 -1
- package/api/@xmachines/play-xstate/functions/deriveRoute.md +1 -1
- package/api/@xmachines/play-xstate/functions/eventMatches.md +1 -1
- package/api/@xmachines/play-xstate/functions/formatPlayRouteTransitions.md +1 -1
- package/api/@xmachines/play-xstate/functions/hasContext.md +1 -1
- package/api/@xmachines/play-xstate/functions/isAbsoluteRoute.md +1 -1
- package/api/@xmachines/play-xstate/functions/negateGuard.md +1 -1
- package/api/@xmachines/play-xstate/interfaces/PlayerConfig.md +3 -3
- package/api/@xmachines/play-xstate/interfaces/PlayerFactoryResumeOptions.md +2 -2
- package/api/@xmachines/play-xstate/interfaces/PlayerOptions.md +6 -6
- package/api/@xmachines/play-xstate/interfaces/RouteContext.md +5 -5
- package/api/@xmachines/play-xstate/type-aliases/ComposedGuard.md +1 -1
- package/api/@xmachines/play-xstate/type-aliases/Guard.md +1 -1
- package/api/@xmachines/play-xstate/type-aliases/GuardArray.md +1 -1
- package/api/@xmachines/play-xstate/type-aliases/PlayerFactory.md +1 -1
- package/api/@xmachines/play-xstate/type-aliases/RouteMachineConfig.md +4 -4
- package/api/@xmachines/play-xstate/type-aliases/RouteStateNode.md +4 -4
- package/api/@xmachines/shared/functions/defineXmVitestConfig.md +3 -7
- package/api/@xmachines/shared/functions/xmAliases.md +1 -1
- package/examples/README.md +48 -35
- package/examples/basic-state-machine.md +75 -31
- package/examples/form-validation.md +199 -127
- package/examples/multi-router-integration.md +312 -230
- package/examples/routing-patterns.md +243 -189
- package/examples/traffic-light.md +114 -65
- package/guides/README.md +29 -15
- package/guides/getting-started.md +224 -144
- package/guides/installation.md +153 -213
- package/package.json +2 -2
|
@@ -1,215 +1,295 @@
|
|
|
1
|
+
<!-- generated-by: gsd-doc-writer -->
|
|
2
|
+
|
|
1
3
|
# Getting Started
|
|
2
4
|
|
|
3
|
-
Welcome to XMachines! This guide
|
|
5
|
+
Welcome to XMachines! This guide gets you from zero to a running actor using the current XState v5 + XMachines API.
|
|
4
6
|
|
|
5
7
|
## What is XMachines?
|
|
6
8
|
|
|
7
|
-
XMachines is a TypeScript implementation of the Universal Player Architecture—a state machine
|
|
8
|
-
|
|
9
|
-
At its core, XMachines is built on the actor model, following the principle that **business logic must be the single source of truth** for navigation, state, and UI structure. Infrastructure reflects actor state—it never decides.
|
|
10
|
-
|
|
11
|
-
Unlike traditional frameworks where your logic adapts to the framework, XMachines inverts this relationship. Your state machines own the application behavior, and the infrastructure (routers, view renderers, React components) passively observes and reflects the current state through signals. This results in complete runtime agnosticism—your logic has zero framework dependencies.
|
|
12
|
-
|
|
13
|
-
## Why XMachines?
|
|
14
|
-
|
|
15
|
-
**Type Safety with TypeScript**
|
|
16
|
-
|
|
17
|
-
- Full type inference from state machine catalog through to components
|
|
18
|
-
- Catch navigation errors and state bugs at compile time
|
|
19
|
-
- Zod validation for UI schemas and state structures
|
|
20
|
-
|
|
21
|
-
**Predictable State Management**
|
|
22
|
-
|
|
23
|
-
- State machines make application behavior explicit and testable
|
|
24
|
-
- Actor model ensures clear message passing patterns
|
|
25
|
-
- Guard enforcement prevents invalid state transitions
|
|
26
|
-
|
|
27
|
-
**Platform Flexibility**
|
|
9
|
+
XMachines is a TypeScript implementation of the Universal Player Architecture — a state machine system that strictly separates business logic from infrastructure. State machines (actors) control routing, views, and navigation through TC39 Signals. Infrastructure (routers, renderers, React components) passively observes and reflects actor state.
|
|
28
10
|
|
|
29
|
-
|
|
30
|
-
- Choose only the packages you need for your platform
|
|
31
|
-
- Framework integrations (React, TanStack Router) are optional adapters
|
|
11
|
+
Your state machines have **zero framework dependencies**. Routers and renderers are optional adapters.
|
|
32
12
|
|
|
33
|
-
|
|
13
|
+
## Installation
|
|
34
14
|
|
|
35
|
-
|
|
36
|
-
- `@xmachines/play` foundation works with any infrastructure
|
|
37
|
-
- Mix and match adapters based on your stack
|
|
38
|
-
|
|
39
|
-
## Quick Start
|
|
40
|
-
|
|
41
|
-
### Installation
|
|
42
|
-
|
|
43
|
-
First, install XMachines packages. See the complete [Installation →](installation.md) guide for all package managers and environments.
|
|
15
|
+
Install the core packages (see [Installation →](installation.md) for the full package guide):
|
|
44
16
|
|
|
45
17
|
```bash
|
|
46
|
-
npm install @xmachines/play @xmachines/play-xstate
|
|
18
|
+
npm install @xmachines/play-xstate @xmachines/play-actor @xmachines/play-signals xstate
|
|
47
19
|
```
|
|
48
20
|
|
|
49
|
-
|
|
21
|
+
## Step 1: Define a Machine
|
|
22
|
+
|
|
23
|
+
Use `setup({ types })` from XState v5 to declare types, then call `setup.createMachine()`:
|
|
50
24
|
|
|
51
25
|
```typescript
|
|
52
|
-
import {
|
|
26
|
+
import { setup } from "xstate";
|
|
53
27
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
28
|
+
const toggleSetup = setup({
|
|
29
|
+
types: {
|
|
30
|
+
context: {} as { count: number },
|
|
31
|
+
events: {} as { type: "toggle" },
|
|
32
|
+
input: {} as { count?: number } | undefined,
|
|
33
|
+
},
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
const toggleMachine = toggleSetup.createMachine({
|
|
37
|
+
id: "toggle",
|
|
38
|
+
initial: "off",
|
|
39
|
+
context: ({ input }) => ({
|
|
40
|
+
count: input?.count ?? 0,
|
|
41
|
+
}),
|
|
58
42
|
states: {
|
|
59
|
-
|
|
60
|
-
on: {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
43
|
+
off: {
|
|
44
|
+
on: {
|
|
45
|
+
toggle: {
|
|
46
|
+
target: "on",
|
|
47
|
+
actions: toggleSetup.assign({ count: ({ context }) => context.count + 1 }),
|
|
48
|
+
},
|
|
49
|
+
},
|
|
64
50
|
},
|
|
65
|
-
|
|
66
|
-
on: {
|
|
51
|
+
on: {
|
|
52
|
+
on: {
|
|
53
|
+
toggle: {
|
|
54
|
+
target: "off",
|
|
55
|
+
actions: toggleSetup.assign({ count: ({ context }) => context.count + 1 }),
|
|
56
|
+
},
|
|
57
|
+
},
|
|
67
58
|
},
|
|
68
59
|
},
|
|
69
60
|
});
|
|
70
61
|
```
|
|
71
62
|
|
|
72
|
-
|
|
63
|
+
**Key rules:**
|
|
64
|
+
|
|
65
|
+
- Always use `setup({ types })` before `createMachine` — not the bare `createMachine` from xstate.
|
|
66
|
+
- Use `setup.assign(...)` (not the bare `assign` from xstate) for context mutations.
|
|
67
|
+
- Event types use lowercase dot-separated names: `"toggle"`, `"auth.login"`, `"play.route"`.
|
|
68
|
+
|
|
69
|
+
## Step 2: Define a Player
|
|
70
|
+
|
|
71
|
+
`definePlayer` wraps the machine in a factory. Each call to the factory creates an independent `PlayerActor` instance:
|
|
73
72
|
|
|
74
73
|
```typescript
|
|
75
|
-
import {
|
|
74
|
+
import { definePlayer } from "@xmachines/play-xstate";
|
|
75
|
+
|
|
76
|
+
const createPlayer = definePlayer({ machine: toggleMachine });
|
|
77
|
+
```
|
|
76
78
|
|
|
77
|
-
|
|
78
|
-
const actor = createActor(trafficLightMachine);
|
|
79
|
+
## Step 3: Create and Start an Actor
|
|
79
80
|
|
|
80
|
-
|
|
81
|
+
```typescript
|
|
82
|
+
const actor = createPlayer();
|
|
81
83
|
actor.start();
|
|
82
84
|
|
|
83
|
-
//
|
|
84
|
-
console.log(actor.getSnapshot().value); // "
|
|
85
|
+
// Read initial state
|
|
86
|
+
console.log(actor.getSnapshot().value); // "off"
|
|
87
|
+
console.log(actor.getSnapshot().context); // { count: 0 }
|
|
85
88
|
|
|
86
|
-
// Send events
|
|
87
|
-
actor.send({ type: "
|
|
88
|
-
console.log(actor.getSnapshot().value); // "
|
|
89
|
+
// Send events
|
|
90
|
+
actor.send({ type: "toggle" });
|
|
91
|
+
console.log(actor.getSnapshot().value); // "on"
|
|
92
|
+
console.log(actor.getSnapshot().context.count); // 1
|
|
89
93
|
|
|
90
|
-
|
|
91
|
-
|
|
94
|
+
// Cleanup
|
|
95
|
+
actor.stop();
|
|
92
96
|
```
|
|
93
97
|
|
|
94
|
-
|
|
98
|
+
## Step 4: Read State via TC39 Signals
|
|
95
99
|
|
|
96
|
-
|
|
97
|
-
import { signal, computed } from "@xmachines/play-signals";
|
|
100
|
+
`actor.state` is a `Signal.State<Snapshot>`. Use it when wiring infrastructure that needs to react to state changes:
|
|
98
101
|
|
|
99
|
-
|
|
100
|
-
|
|
102
|
+
```typescript
|
|
103
|
+
import { watchSignal } from "@xmachines/play-signals";
|
|
101
104
|
|
|
102
|
-
//
|
|
103
|
-
actor.
|
|
104
|
-
|
|
105
|
+
// Watch the state signal — callback fires on every transition
|
|
106
|
+
const unwatch = watchSignal(actor.state, () => {
|
|
107
|
+
console.log("State changed to:", actor.state.get().value);
|
|
105
108
|
});
|
|
106
109
|
|
|
107
|
-
//
|
|
108
|
-
const canProceed = computed(() => currentState.value === "green");
|
|
110
|
+
actor.send({ type: "toggle" }); // logs "State changed to: on"
|
|
109
111
|
|
|
110
|
-
|
|
112
|
+
// Stop watching
|
|
113
|
+
unwatch();
|
|
111
114
|
```
|
|
112
115
|
|
|
113
|
-
##
|
|
116
|
+
## Step 5: Add Routing (Optional)
|
|
114
117
|
|
|
115
|
-
|
|
118
|
+
Add `meta.route` to states and wrap the config with `formatPlayRouteTransitions`. The machine's context must include `params` and `query` fields:
|
|
116
119
|
|
|
117
120
|
```typescript
|
|
118
|
-
import {
|
|
119
|
-
import {
|
|
120
|
-
import {
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
count: 0,
|
|
129
|
-
},
|
|
130
|
-
states: {
|
|
131
|
-
inactive: {
|
|
132
|
-
on: {
|
|
133
|
-
TOGGLE: {
|
|
134
|
-
target: "active",
|
|
135
|
-
actions: "incrementCount",
|
|
136
|
-
},
|
|
137
|
-
},
|
|
138
|
-
},
|
|
139
|
-
active: {
|
|
140
|
-
on: {
|
|
141
|
-
TOGGLE: {
|
|
142
|
-
target: "inactive",
|
|
143
|
-
actions: "incrementCount",
|
|
144
|
-
},
|
|
145
|
-
},
|
|
146
|
-
},
|
|
121
|
+
import { setup } from "xstate";
|
|
122
|
+
import { definePlayer, formatPlayRouteTransitions } from "@xmachines/play-xstate";
|
|
123
|
+
import type { PlayRouteEvent } from "@xmachines/play-router";
|
|
124
|
+
|
|
125
|
+
const appSetup = setup({
|
|
126
|
+
types: {
|
|
127
|
+
context: {} as {
|
|
128
|
+
isAuthenticated: boolean;
|
|
129
|
+
params: Record<string, string>;
|
|
130
|
+
query: Record<string, string>;
|
|
147
131
|
},
|
|
132
|
+
events: {} as PlayRouteEvent | { type: "auth.login"; username: string },
|
|
133
|
+
input: {} as undefined,
|
|
148
134
|
},
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
const appMachine = appSetup.createMachine(
|
|
138
|
+
formatPlayRouteTransitions({
|
|
139
|
+
id: "app",
|
|
140
|
+
initial: "home",
|
|
141
|
+
context: { isAuthenticated: false, params: {}, query: {} },
|
|
142
|
+
states: {
|
|
143
|
+
home: { id: "home", meta: { route: "/" } },
|
|
144
|
+
login: { id: "login", meta: { route: "/login" } },
|
|
154
145
|
},
|
|
155
|
-
},
|
|
146
|
+
}),
|
|
156
147
|
);
|
|
157
148
|
|
|
158
|
-
|
|
159
|
-
const
|
|
160
|
-
|
|
149
|
+
const createPlayer = definePlayer({ machine: appMachine });
|
|
150
|
+
const actor = createPlayer();
|
|
151
|
+
actor.start();
|
|
152
|
+
|
|
153
|
+
console.log(actor.currentRoute.get()); // "/"
|
|
154
|
+
|
|
155
|
+
actor.send({ type: "play.route", to: "#login" });
|
|
156
|
+
console.log(actor.currentRoute.get()); // "/login"
|
|
157
|
+
|
|
158
|
+
actor.stop();
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
## Step 6: Add a View Registry (Optional)
|
|
162
|
+
|
|
163
|
+
Connect a renderer to map `meta.view` specs to real components. The vanilla DOM renderer uses `connectRenderer` + `defineRegistry`:
|
|
161
164
|
|
|
162
|
-
|
|
163
|
-
|
|
165
|
+
```typescript
|
|
166
|
+
import { connectRenderer, defineRegistry } from "@xmachines/play-dom";
|
|
167
|
+
import { authCatalog } from "@xmachines/play-actor-shared";
|
|
168
|
+
import { Home, Login } from "./components/index.js";
|
|
164
169
|
|
|
165
|
-
|
|
166
|
-
|
|
170
|
+
const { registry } = defineRegistry(authCatalog, {
|
|
171
|
+
components: { Home, Login },
|
|
167
172
|
});
|
|
168
173
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
174
|
+
const disconnectRenderer = connectRenderer({
|
|
175
|
+
actor,
|
|
176
|
+
registry,
|
|
177
|
+
container: document.getElementById("app")!,
|
|
178
|
+
});
|
|
173
179
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
180
|
+
// cleanup
|
|
181
|
+
window.addEventListener("beforeunload", () => {
|
|
182
|
+
disconnectRenderer();
|
|
183
|
+
actor.stop();
|
|
184
|
+
});
|
|
177
185
|
```
|
|
178
186
|
|
|
179
|
-
|
|
187
|
+
For React, use `PlayRenderer` from `@xmachines/play-react`:
|
|
180
188
|
|
|
181
|
-
|
|
189
|
+
```tsx
|
|
190
|
+
import { PlayRenderer, defineRegistry } from "@xmachines/play-react";
|
|
191
|
+
import { authCatalog } from "@xmachines/play-actor-shared";
|
|
192
|
+
import { Home, Login } from "./components/index.js";
|
|
182
193
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
194
|
+
const { registry } = defineRegistry(authCatalog, {
|
|
195
|
+
components: { Home, Login },
|
|
196
|
+
actions: {
|
|
197
|
+
login: async () => {},
|
|
198
|
+
logout: async () => {},
|
|
199
|
+
},
|
|
200
|
+
});
|
|
186
201
|
|
|
187
|
-
|
|
202
|
+
function App() {
|
|
203
|
+
return (
|
|
204
|
+
<PlayRenderer
|
|
205
|
+
actor={actor}
|
|
206
|
+
registry={registry}
|
|
207
|
+
actions={{
|
|
208
|
+
login: "auth.login",
|
|
209
|
+
logout: "auth.logout",
|
|
210
|
+
}}
|
|
211
|
+
/>
|
|
212
|
+
);
|
|
213
|
+
}
|
|
214
|
+
```
|
|
188
215
|
|
|
189
|
-
|
|
216
|
+
## Complete Toggle Example
|
|
190
217
|
|
|
191
|
-
|
|
218
|
+
```typescript
|
|
219
|
+
import { setup } from "xstate";
|
|
220
|
+
import { definePlayer } from "@xmachines/play-xstate";
|
|
221
|
+
import { watchSignal } from "@xmachines/play-signals";
|
|
222
|
+
|
|
223
|
+
const toggleSetup = setup({
|
|
224
|
+
types: {
|
|
225
|
+
context: {} as { count: number },
|
|
226
|
+
events: {} as { type: "toggle" },
|
|
227
|
+
input: {} as undefined,
|
|
228
|
+
},
|
|
229
|
+
});
|
|
192
230
|
|
|
193
|
-
|
|
231
|
+
const toggleMachine = toggleSetup.createMachine({
|
|
232
|
+
id: "toggle",
|
|
233
|
+
initial: "off",
|
|
234
|
+
context: { count: 0 },
|
|
235
|
+
states: {
|
|
236
|
+
off: {
|
|
237
|
+
on: {
|
|
238
|
+
toggle: {
|
|
239
|
+
target: "on",
|
|
240
|
+
actions: toggleSetup.assign({ count: ({ context }) => context.count + 1 }),
|
|
241
|
+
},
|
|
242
|
+
},
|
|
243
|
+
},
|
|
244
|
+
on: {
|
|
245
|
+
on: {
|
|
246
|
+
toggle: {
|
|
247
|
+
target: "off",
|
|
248
|
+
actions: toggleSetup.assign({ count: ({ context }) => context.count + 1 }),
|
|
249
|
+
},
|
|
250
|
+
},
|
|
251
|
+
},
|
|
252
|
+
},
|
|
253
|
+
});
|
|
194
254
|
|
|
195
|
-
|
|
255
|
+
const createPlayer = definePlayer({ machine: toggleMachine });
|
|
256
|
+
const actor = createPlayer();
|
|
196
257
|
|
|
197
|
-
|
|
258
|
+
const unwatch = watchSignal(actor.state, () => {
|
|
259
|
+
const snap = actor.state.get();
|
|
260
|
+
console.log(`State: ${String(snap.value)}, Count: ${snap.context.count}`);
|
|
261
|
+
});
|
|
198
262
|
|
|
199
|
-
|
|
263
|
+
actor.start();
|
|
264
|
+
// logs: State: off, Count: 0
|
|
200
265
|
|
|
201
|
-
|
|
266
|
+
actor.send({ type: "toggle" });
|
|
267
|
+
// logs: State: on, Count: 1
|
|
202
268
|
|
|
203
|
-
|
|
269
|
+
actor.send({ type: "toggle" });
|
|
270
|
+
// logs: State: off, Count: 2
|
|
204
271
|
|
|
205
|
-
|
|
206
|
-
|
|
272
|
+
unwatch();
|
|
273
|
+
actor.stop();
|
|
274
|
+
```
|
|
207
275
|
|
|
208
|
-
|
|
276
|
+
## Glossary
|
|
209
277
|
|
|
210
|
-
|
|
211
|
-
|
|
278
|
+
| Term | Description |
|
|
279
|
+
| ---------------------------- | -------------------------------------------------------------------------------------------- |
|
|
280
|
+
| `setup({ types })` | XState v5 entry point — declares TypeScript types for context, events, and input |
|
|
281
|
+
| `definePlayer({ machine })` | Creates a factory that produces `PlayerActor` instances from the machine |
|
|
282
|
+
| `actor.start()` | Activates the machine — always call before sending events |
|
|
283
|
+
| `actor.send({ type })` | Sends an event to the machine |
|
|
284
|
+
| `actor.getSnapshot()` | Synchronous snapshot of the current state and context |
|
|
285
|
+
| `actor.state` | `Signal.State<Snapshot>` — TC39 Signal for reactive state observation |
|
|
286
|
+
| `actor.currentRoute` | `Signal.Computed<string \| null>` — resolved URL from the active state's `meta.route` |
|
|
287
|
+
| `actor.currentView` | `Signal.State<ViewMetadata \| null>` — current view spec from the active state's `meta.view` |
|
|
288
|
+
| `formatPlayRouteTransitions` | Utility that generates `play.route` handlers from `id` + `meta.route` state pairs |
|
|
212
289
|
|
|
213
|
-
|
|
290
|
+
## Next Steps
|
|
214
291
|
|
|
215
|
-
**
|
|
292
|
+
- **[Installation Guide](installation.md)** — Framework-specific packages, TypeScript config
|
|
293
|
+
- **[Examples](../examples/README.md)** — Routing patterns, form validation, multi-router demos
|
|
294
|
+
- **[API Reference](../api/README.md)** — Generated API docs for all packages
|
|
295
|
+
- **[Play RFC](../rfc/play.md)** — Complete architectural specification
|