@xmachines/docs 1.0.0-beta.18 → 1.0.0-beta.20

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.
Files changed (189) hide show
  1. package/api/@xmachines/play/README.md +1 -1
  2. package/api/@xmachines/play/classes/PlayError.md +4 -4
  3. package/api/@xmachines/play/type-aliases/PlayEvent.md +3 -3
  4. package/api/@xmachines/play-actor/README.md +2 -2
  5. package/api/@xmachines/play-actor/classes/AbstractActor.md +4 -4
  6. package/api/@xmachines/play-actor/interfaces/PlaySpec.md +2 -2
  7. package/api/@xmachines/play-actor/interfaces/Routable.md +3 -3
  8. package/api/@xmachines/play-actor/interfaces/ViewMetadata.md +3 -3
  9. package/api/@xmachines/play-actor/interfaces/Viewable.md +2 -2
  10. package/api/@xmachines/play-dom/classes/PlayRenderer.md +4 -4
  11. package/api/@xmachines/play-dom/functions/connectRenderer.md +1 -1
  12. package/api/@xmachines/play-dom/functions/renderSpec.md +1 -1
  13. package/api/@xmachines/play-dom/interfaces/ConnectRendererOptions.md +7 -7
  14. package/api/@xmachines/play-dom/interfaces/DomRenderContext.md +7 -7
  15. package/api/@xmachines/play-dom/interfaces/PlayDomOptions.md +3 -3
  16. package/api/@xmachines/play-dom/type-aliases/DomComponentRenderer.md +1 -1
  17. package/api/@xmachines/play-dom/type-aliases/DomRegistry.md +1 -1
  18. package/api/@xmachines/play-react/README.md +7 -2
  19. package/api/@xmachines/play-react/classes/PlayErrorBoundary.md +9 -5
  20. package/api/@xmachines/play-react/functions/useActor.md +1 -1
  21. package/api/@xmachines/play-react/functions/useSignalEffect.md +1 -1
  22. package/api/@xmachines/play-react/interfaces/PlayErrorBoundaryProps.md +4 -4
  23. package/api/@xmachines/play-react/interfaces/PlayErrorBoundaryState.md +3 -3
  24. package/api/@xmachines/play-react/interfaces/PlayRendererProps.md +6 -6
  25. package/api/@xmachines/play-react/type-aliases/PlayActor.md +1 -1
  26. package/api/@xmachines/play-react/variables/PlayRenderer.md +1 -1
  27. package/api/@xmachines/play-react-router/classes/ReactRouterBridge.md +23 -23
  28. package/api/@xmachines/play-react-router/classes/RouteMap.md +4 -4
  29. package/api/@xmachines/play-react-router/functions/PlayRouterProvider.md +1 -1
  30. package/api/@xmachines/play-react-router/functions/createRouteMapFromTree.md +1 -1
  31. package/api/@xmachines/play-react-router/interfaces/PlayRouteEvent.md +9 -9
  32. package/api/@xmachines/play-react-router/interfaces/PlayRouterProviderProps.md +5 -5
  33. package/api/@xmachines/play-react-router/interfaces/RouteMapping.md +3 -3
  34. package/api/@xmachines/play-react-router/interfaces/RouterBridge.md +4 -4
  35. package/api/@xmachines/play-router/README.md +103 -47
  36. package/api/@xmachines/play-router/classes/BaseRouteMap.md +4 -4
  37. package/api/@xmachines/play-router/classes/RouterBridgeBase.md +21 -21
  38. package/api/@xmachines/play-router/functions/buildRouteTree.md +1 -1
  39. package/api/@xmachines/play-router/functions/connectRouter.md +1 -1
  40. package/api/@xmachines/play-router/functions/createBrowserHistory.md +1 -1
  41. package/api/@xmachines/play-router/functions/createRouteMap.md +1 -1
  42. package/api/@xmachines/play-router/functions/createRouter.md +1 -1
  43. package/api/@xmachines/play-router/functions/detectDuplicateRoutes.md +1 -1
  44. package/api/@xmachines/play-router/functions/extractMachineRoutes.md +6 -42
  45. package/api/@xmachines/play-router/functions/findRouteById.md +1 -1
  46. package/api/@xmachines/play-router/functions/findRouteByPath.md +1 -1
  47. package/api/@xmachines/play-router/functions/getNavigableRoutes.md +1 -1
  48. package/api/@xmachines/play-router/functions/getRoutableRoutes.md +1 -1
  49. package/api/@xmachines/play-router/functions/getTransitionReachableRoutes.md +38 -0
  50. package/api/@xmachines/play-router/functions/isRouteReachable.md +38 -0
  51. package/api/@xmachines/play-router/functions/machineToGraph.md +19 -0
  52. package/api/@xmachines/play-router/functions/routeExists.md +1 -1
  53. package/api/@xmachines/play-router/functions/sanitizePathname.md +40 -0
  54. package/api/@xmachines/play-router/functions/validateRouteFormat.md +9 -8
  55. package/api/@xmachines/play-router/functions/validateStateExists.md +8 -8
  56. package/api/@xmachines/play-router/interfaces/BaseRouteMapping.md +3 -3
  57. package/api/@xmachines/play-router/interfaces/BrowserHistory.md +14 -14
  58. package/api/@xmachines/play-router/interfaces/BrowserWindow.md +14 -14
  59. package/api/@xmachines/play-router/interfaces/ConnectRouterOptions.md +4 -4
  60. package/api/@xmachines/play-router/interfaces/MachineEdgeData.md +15 -0
  61. package/api/@xmachines/play-router/interfaces/MachineNodeData.md +17 -0
  62. package/api/@xmachines/play-router/interfaces/PlayRouteEvent.md +7 -7
  63. package/api/@xmachines/play-router/interfaces/RouteInfo.md +8 -8
  64. package/api/@xmachines/play-router/interfaces/RouteMap.md +4 -4
  65. package/api/@xmachines/play-router/interfaces/RouteNode.md +12 -12
  66. package/api/@xmachines/play-router/interfaces/RouteObject.md +2 -2
  67. package/api/@xmachines/play-router/interfaces/RouteTree.md +7 -6
  68. package/api/@xmachines/play-router/interfaces/RouteWatcherHandle.md +3 -3
  69. package/api/@xmachines/play-router/interfaces/RouterBridge.md +4 -4
  70. package/api/@xmachines/play-router/interfaces/VanillaRouter.md +4 -4
  71. package/api/@xmachines/play-router/type-aliases/MachineGraph.md +20 -0
  72. package/api/@xmachines/play-router/type-aliases/RouteMetadata.md +1 -1
  73. package/api/@xmachines/play-signals/README.md +8 -2
  74. package/api/@xmachines/play-signals/functions/watchSignal.md +8 -1
  75. package/api/@xmachines/play-signals/interfaces/ComputedOptions.md +2 -2
  76. package/api/@xmachines/play-signals/interfaces/SignalComputed.md +2 -2
  77. package/api/@xmachines/play-signals/interfaces/SignalOptions.md +2 -2
  78. package/api/@xmachines/play-signals/interfaces/SignalState.md +3 -3
  79. package/api/@xmachines/play-signals/interfaces/SignalWatcher.md +4 -4
  80. package/api/@xmachines/play-signals/type-aliases/WatcherNotify.md +1 -1
  81. package/api/@xmachines/play-solid/README.md +1 -1
  82. package/api/@xmachines/play-solid/functions/useActor.md +1 -1
  83. package/api/@xmachines/play-solid/interfaces/PlayRendererProps.md +6 -6
  84. package/api/@xmachines/play-solid/type-aliases/PlayActor.md +1 -1
  85. package/api/@xmachines/play-solid/variables/PlayRenderer.md +1 -1
  86. package/api/@xmachines/play-solid-router/README.md +1 -1
  87. package/api/@xmachines/play-solid-router/classes/RouteMap.md +4 -4
  88. package/api/@xmachines/play-solid-router/classes/SolidRouterBridge.md +24 -24
  89. package/api/@xmachines/play-solid-router/functions/PlayRouterProvider.md +1 -1
  90. package/api/@xmachines/play-solid-router/functions/createRouteMap.md +1 -1
  91. package/api/@xmachines/play-solid-router/interfaces/AbstractActor.md +16 -16
  92. package/api/@xmachines/play-solid-router/interfaces/PlayRouteEvent.md +9 -9
  93. package/api/@xmachines/play-solid-router/interfaces/PlayRouterProviderProps.md +5 -5
  94. package/api/@xmachines/play-solid-router/interfaces/RouteMapping.md +3 -3
  95. package/api/@xmachines/play-solid-router/interfaces/RouterBridge.md +4 -4
  96. package/api/@xmachines/play-solid-router/type-aliases/RoutableActor.md +1 -1
  97. package/api/@xmachines/play-solid-router/type-aliases/SolidRouterHooks.md +4 -4
  98. package/api/@xmachines/play-tanstack-react-router/README.md +1 -4
  99. package/api/@xmachines/play-tanstack-react-router/classes/RouteMap.md +4 -4
  100. package/api/@xmachines/play-tanstack-react-router/classes/TanStackReactRouterBridge.md +23 -23
  101. package/api/@xmachines/play-tanstack-react-router/functions/PlayRouterProvider.md +1 -1
  102. package/api/@xmachines/play-tanstack-react-router/functions/createRouteMap.md +1 -1
  103. package/api/@xmachines/play-tanstack-react-router/functions/createRouteMapFromTree.md +1 -1
  104. package/api/@xmachines/play-tanstack-react-router/functions/extractMachineRoutes.md +28 -0
  105. package/api/@xmachines/play-tanstack-react-router/functions/extractParams.md +1 -1
  106. package/api/@xmachines/play-tanstack-react-router/functions/extractQueryParams.md +1 -1
  107. package/api/@xmachines/play-tanstack-react-router/interfaces/PlayRouteEvent.md +9 -9
  108. package/api/@xmachines/play-tanstack-react-router/interfaces/PlayRouterProviderProps.md +5 -5
  109. package/api/@xmachines/play-tanstack-react-router/interfaces/RouteMapping.md +3 -3
  110. package/api/@xmachines/play-tanstack-react-router/interfaces/RouteNavigateEvent.md +3 -3
  111. package/api/@xmachines/play-tanstack-react-router/interfaces/RouterBridge.md +4 -4
  112. package/api/@xmachines/play-tanstack-react-router/type-aliases/TanStackRouterInstance.md +1 -1
  113. package/api/@xmachines/play-tanstack-react-router/type-aliases/TanStackRouterLike.md +4 -4
  114. package/api/@xmachines/play-tanstack-solid-router/README.md +1 -1
  115. package/api/@xmachines/play-tanstack-solid-router/classes/RouteMap.md +4 -4
  116. package/api/@xmachines/play-tanstack-solid-router/classes/SolidRouterBridge.md +26 -25
  117. package/api/@xmachines/play-tanstack-solid-router/functions/PlayRouterProvider.md +1 -1
  118. package/api/@xmachines/play-tanstack-solid-router/functions/createRouteMap.md +1 -1
  119. package/api/@xmachines/play-tanstack-solid-router/interfaces/PlayRouteEvent.md +9 -9
  120. package/api/@xmachines/play-tanstack-solid-router/interfaces/PlayRouterProviderProps.md +5 -5
  121. package/api/@xmachines/play-tanstack-solid-router/interfaces/RouteMapping.md +3 -3
  122. package/api/@xmachines/play-tanstack-solid-router/interfaces/RouterBridge.md +4 -4
  123. package/api/@xmachines/play-tanstack-solid-router/type-aliases/RoutableActor.md +1 -1
  124. package/api/@xmachines/play-tanstack-solid-router/type-aliases/TanStackRouterInstance.md +1 -1
  125. package/api/@xmachines/play-tanstack-solid-router/type-aliases/TanStackRouterLike.md +4 -4
  126. package/api/@xmachines/play-vue/README.md +1 -1
  127. package/api/@xmachines/play-vue/functions/defineRegistry.md +1 -1
  128. package/api/@xmachines/play-vue/functions/useActor.md +1 -1
  129. package/api/@xmachines/play-vue/interfaces/PlayRendererProps.md +5 -5
  130. package/api/@xmachines/play-vue/type-aliases/ComponentEntry.md +1 -1
  131. package/api/@xmachines/play-vue/type-aliases/ComponentsMap.md +1 -1
  132. package/api/@xmachines/play-vue/type-aliases/DefineRegistryOptions.md +2 -2
  133. package/api/@xmachines/play-vue/type-aliases/PlayActor.md +1 -1
  134. package/api/@xmachines/play-vue/variables/PlayRenderer.md +1 -1
  135. package/api/@xmachines/play-vue-router/README.md +2 -1
  136. package/api/@xmachines/play-vue-router/classes/RouteMap.md +7 -7
  137. package/api/@xmachines/play-vue-router/classes/VueBaseRouteMap.md +7 -7
  138. package/api/@xmachines/play-vue-router/classes/VueRouterBridge.md +27 -32
  139. package/api/@xmachines/play-vue-router/functions/createRouteMap.md +1 -1
  140. package/api/@xmachines/play-vue-router/interfaces/PlayRouteEvent.md +9 -9
  141. package/api/@xmachines/play-vue-router/interfaces/RouteMapping.md +4 -4
  142. package/api/@xmachines/play-vue-router/interfaces/RouterBridge.md +4 -4
  143. package/api/@xmachines/play-vue-router/type-aliases/RoutableActor.md +1 -1
  144. package/api/@xmachines/play-vue-router/variables/PlayRouterProvider.md +1 -1
  145. package/api/@xmachines/play-xstate/README.md +6 -6
  146. package/api/@xmachines/play-xstate/classes/PlayerActor.md +12 -12
  147. package/api/@xmachines/play-xstate/functions/buildRouteUrl.md +1 -1
  148. package/api/@xmachines/play-xstate/functions/composeGuards.md +1 -1
  149. package/api/@xmachines/play-xstate/functions/composeGuardsOr.md +1 -1
  150. package/api/@xmachines/play-xstate/functions/contextFieldMatches.md +36 -0
  151. package/api/@xmachines/play-xstate/functions/definePlayer.md +2 -2
  152. package/api/@xmachines/play-xstate/functions/deriveRoute.md +2 -2
  153. package/api/@xmachines/play-xstate/functions/eventMatches.md +1 -1
  154. package/api/@xmachines/play-xstate/functions/formatPlayRouteTransitions.md +1 -1
  155. package/api/@xmachines/play-xstate/functions/hasContext.md +1 -1
  156. package/api/@xmachines/play-xstate/functions/isAbsoluteRoute.md +1 -1
  157. package/api/@xmachines/play-xstate/functions/negateGuard.md +1 -1
  158. package/api/@xmachines/play-xstate/interfaces/PlayerConfig.md +3 -3
  159. package/api/@xmachines/play-xstate/interfaces/PlayerFactoryResumeOptions.md +2 -2
  160. package/api/@xmachines/play-xstate/interfaces/PlayerOptions.md +6 -6
  161. package/api/@xmachines/play-xstate/interfaces/RouteContext.md +5 -5
  162. package/api/@xmachines/play-xstate/type-aliases/ComposedGuard.md +1 -1
  163. package/api/@xmachines/play-xstate/type-aliases/Guard.md +1 -1
  164. package/api/@xmachines/play-xstate/type-aliases/GuardArray.md +1 -1
  165. package/api/@xmachines/play-xstate/type-aliases/PlayerFactory.md +1 -1
  166. package/api/@xmachines/play-xstate/type-aliases/RouteMachineConfig.md +4 -4
  167. package/api/@xmachines/play-xstate/type-aliases/RouteStateNode.md +4 -4
  168. package/api/@xmachines/shared/functions/defineXmVitestConfig.md +2 -2
  169. package/api/@xmachines/shared/functions/xmAliases.md +1 -1
  170. package/api/_media/play.md +447 -0
  171. package/examples/multi-router-integration.md +1 -1
  172. package/examples/routing-patterns.md +1 -1
  173. package/guides/installation.md +30 -30
  174. package/package.json +5 -3
  175. package/rfc/broker.md +100 -0
  176. package/rfc/browser.md +44 -0
  177. package/rfc/cli.md +118 -0
  178. package/rfc/git.md +61 -0
  179. package/rfc/mcp.md +43 -0
  180. package/rfc/node.md +36 -0
  181. package/rfc/play.md +447 -0
  182. package/rfc/rest.md +102 -0
  183. package/rfc/run.md +159 -0
  184. package/rfc/streams.md +168 -0
  185. package/api/@xmachines/play-router/functions/crawlMachine.md +0 -92
  186. package/api/@xmachines/play-router/functions/extractRoute.md +0 -45
  187. package/api/@xmachines/play-router/interfaces/StateVisit.md +0 -15
  188. package/api/@xmachines/play-tanstack-react-router/variables/extractMachineRoutes.md +0 -64
  189. package/api/@xmachines/play-xstate/functions/stateMatches.md +0 -25
@@ -0,0 +1,447 @@
1
+ # RFC: Play
2
+
3
+ **Status:** Living
4
+ **Version:** 1.1
5
+ **Scope:** Universal runtime interoperability and reference implementation
6
+ **Non-goals:** Persistence, transport protocols, alternative state engines, non-signal reactivity
7
+
8
+ ---
9
+
10
+ ## 1. Purpose
11
+
12
+ This RFC defines the **Universal Player Architecture** and its reference implementation. The architecture establishes a design pattern that strictly separates **Business Logic (The Actor)** from **Infrastructure (The Runtime Adapter and View)**.
13
+
14
+ The reference implementation provides a modular monorepo that satisfies the architectural constraints of **Runtime Agnosticism** and **Logic-Driven Guarding**. It leverages **Standardized Signals (TC39)** to glue a specific **State Engine (XState v5)** to multiple **Runtime Adapters** (TanStack Router, React Router, Vue Router, SolidJS Router) and **View Layers** (React, Vue, SolidJS, Vanilla DOM — all via JSON-Render), while ensuring that **business logic remains the single source of truth** for navigation, state, and UI structure.
15
+
16
+ ---
17
+
18
+ ## 2. Architecture Model
19
+
20
+ ### 2.1 Roles
21
+
22
+ - **The Actor (Logic Engine)**
23
+ - Pure, environment-agnostic logic runtime
24
+ - Owns state, guards, errors, and route validity
25
+ - Emits _Virtual Routes_ as derived intent
26
+
27
+ - **The Runtime Adapter (Infrastructure Layer)**
28
+ - Environment-specific adapter (Browser, Native, Server, Test Runner)
29
+ - Reflects Actor output into the environment
30
+ - Forwards environment events to the Actor without interpretation
31
+
32
+ - **The View**
33
+ - Passive consumer of Actor state
34
+ - No business rules or routing authority
35
+
36
+ ### 2.2 Communication Medium
37
+
38
+ - **Signals (TC39 Proposal)**
39
+ - Used exclusively for Actor ↔ Adapter communication
40
+ - Enables synchronous, glitch-free propagation
41
+
42
+ ---
43
+
44
+ ## 3. Invariants
45
+
46
+ 1. **Actor Authority**
47
+ The Actor is the final authority on state and route validity.
48
+
49
+ 2. **Strict Separation**
50
+ Business logic never depends on runtime APIs or routing libraries.
51
+
52
+ 3. **Signal-Only Reactivity**
53
+ All cross-boundary communication uses standardized Signals.
54
+
55
+ 4. **Passive Infrastructure**
56
+ Runtime Adapters do not enforce guards, validation, or business rules.
57
+
58
+ 5. **State-Driven Reset**
59
+ Invalid external navigation is always overwritten by Actor-derived state.
60
+
61
+ ---
62
+
63
+ ## 4. Core Mechanisms
64
+
65
+ ### 4.1 Reactive Substrate (Signals)
66
+
67
+ - **Push–Pull Model**
68
+ The Actor pushes state updates; Adapters and Views pull computed values lazily.
69
+
70
+ - **Glitch-Free Execution**
71
+ Updates are synchronous and atomic, preventing intermediate invalid states from leaking into the environment.
72
+
73
+ ### 4.2 Logic Engine (The Actor)
74
+
75
+ - Defines **Virtual Routes** as metadata on state nodes
76
+ - Validates all incoming navigation intents
77
+ - On invalid intent:
78
+ 1. Transitions to an error or fallback state
79
+ 2. Emits a corresponding Virtual Route (e.g. `/error`, `/login`)
80
+ 3. Forces the environment to realign with Actor state
81
+
82
+ The Actor has zero knowledge of:
83
+
84
+ - Browser APIs
85
+ - Routing libraries
86
+ - History mechanisms
87
+ - View frameworks
88
+
89
+ ### 4.3 Infrastructure Layer (Runtime Adapter)
90
+
91
+ - **Watcher (Output)**
92
+ Observes the Actor's _Intended Route_ signal and updates the environment accordingly.
93
+
94
+ - **Reflector (Input)**
95
+ Listens to environment events (e.g. back/forward navigation) and forwards them as intents to the Actor.
96
+
97
+ If an intent is rejected:
98
+
99
+ - The Actor emits a new valid state
100
+ - The Adapter overwrites the external environment to match Actor reality
101
+
102
+ ---
103
+
104
+ ## 5. Package Model
105
+
106
+ ### 5.1 Core Layer
107
+
108
+ #### 5.1.1 `@xmachines/play-signals`
109
+
110
+ **Role:** Reactive Substrate
111
+
112
+ Wraps the TC39 Signals (Stage 1) polyfill. By isolating the reactive primitive within this package, the ecosystem is protected from specification churn while providing the ergonomic API surface required by the rest of the architecture.
113
+
114
+ **Exports:**
115
+
116
+ - `Signal` — Re-exported namespace from `signal-polyfill`:
117
+ - `Signal.State` — Actor output snapshot
118
+ - `Signal.Computed` — Lazy, pull-based derivation of routes and views
119
+ - `Signal.subtle.Watcher` — Synchronous observation for Runtime Adapters
120
+ - `watchSignal` — Convenience function: subscribes to a single signal with a one-shot watcher lifecycle and microtask batching; returns a cleanup function
121
+
122
+ #### 5.1.2 `@xmachines/play`
123
+
124
+ **Role:** Core Protocols
125
+
126
+ Exports the minimal shared contracts that allow the Logic Engine and Infrastructure to communicate without direct dependencies. This package is intentionally narrow — it defines only the base event contract and structured error type.
127
+
128
+ **Exports:**
129
+
130
+ - `PlayEvent<TPayload>` — Generic intent event dispatched from Infrastructure to Actor. Any object with `{ readonly type: string }` plus optional typed payload fields.
131
+ - `PlayError` — Structured error base with `scope` and `code` fields for consistent error handling across all `@xmachines/*` packages.
132
+
133
+ > **Note:** Routing contracts (`RouterBridge`, `PlayRouteEvent`) live in `@xmachines/play-router`, not here. This keeps the core protocol package dependency-free.
134
+
135
+ #### 5.1.3 `@xmachines/play-actor`
136
+
137
+ **Role:** Abstract Logic Engine
138
+
139
+ Defines the minimal base class that all logic adapters must implement. By extending the XState `Actor` class, the `AbstractActor` remains fully compatible with the XState ecosystem (inspection, system registration, message passing) while enforcing the Play Architecture's **push–pull signal contract**.
140
+
141
+ The base class requires only two abstract members: **reactive state** and **typed event dispatch**. Routing and view rendering are opt-in via separate interfaces, allowing actors to compose only the capabilities they need.
142
+
143
+ ```ts
144
+ import { Actor, type AnyActorLogic, type EventObject } from "xstate";
145
+ import type { Signal } from "@xmachines/play-signals";
146
+ import type { Spec } from "@json-render/core";
147
+
148
+ // Optional capability: Routing
149
+ export interface Routable {
150
+ readonly currentRoute: Signal.Computed<string | null>;
151
+ readonly initialRoute: string | null;
152
+ }
153
+
154
+ // Optional capability: View rendering
155
+ export interface PlaySpec extends Spec {
156
+ contextProps?: string[];
157
+ }
158
+
159
+ export interface ViewMetadata {
160
+ component: string;
161
+ spec: PlaySpec;
162
+ }
163
+
164
+ export interface Viewable {
165
+ readonly currentView: Signal.State<ViewMetadata | null>;
166
+ }
167
+
168
+ // The Base Protocol — minimal contract
169
+ export abstract class AbstractActor<
170
+ TLogic extends AnyActorLogic,
171
+ TEvent extends EventObject = EventObject,
172
+ > extends Actor<TLogic> {
173
+ // Reactive Output (Snapshot)
174
+ public abstract state: Signal.State<unknown>;
175
+
176
+ // Input Channel (typed for specific event shapes)
177
+ public abstract override send(event: TEvent): void;
178
+ }
179
+ ```
180
+
181
+ **Design Rationale:** The original design placed `currentRoute`, `currentView`, and `catalog` directly on `AbstractActor`. The implementation extracted these into `Routable` and `Viewable` interfaces because:
182
+
183
+ 1. Not all actors need routing (e.g. embedded sub-actors)
184
+ 2. Not all actors need view rendering (e.g. background logic actors)
185
+ 3. Catalog/schema concerns are handled by the renderer layer (`@json-render/core`), not the actor
186
+
187
+ ### 5.2 Logic Layer
188
+
189
+ #### 5.2.1 `@xmachines/play-xstate`
190
+
191
+ **Role:** Concrete Logic Adapter (XState v5)
192
+
193
+ Wraps XState v5 to satisfy the `AbstractActor` contract. Provides the primary API for creating actors from state machine definitions.
194
+
195
+ **Primary Exports:**
196
+
197
+ - `definePlayer` — Factory builder: accepts a machine config, returns a factory function that creates `PlayerActor` instances
198
+ - `PlayerActor` — Concrete class extending `AbstractActor` and implementing both `Routable` and `Viewable`
199
+
200
+ **Utility Exports:**
201
+
202
+ - Guard combinators: `composeGuards`, `composeGuardsOr`, `negateGuard`, `hasContext`, `eventMatches`, `stateMatches`
203
+ - Route derivation: `deriveRoute`, `isAbsoluteRoute`, `buildRouteUrl`, `formatPlayRouteTransitions`
204
+
205
+ **Responsibilities:**
206
+
207
+ - Derive `currentRoute` and `currentView` from active state node metadata
208
+ - Manage signal lifecycle (create on start, dispose on stop)
209
+ - Support snapshot restore for resumable sessions
210
+ - Provide XState DevTools compatibility
211
+
212
+ ```ts
213
+ import type { AnyStateMachine, InputFrom } from "xstate";
214
+
215
+ interface PlayerConfig<TMachine extends AnyStateMachine> {
216
+ machine: TMachine;
217
+ options?: PlayerOptions<TMachine>;
218
+ }
219
+
220
+ // definePlayer returns a factory function, not an object
221
+ const definePlayer = <TMachine extends AnyStateMachine>(
222
+ config: PlayerConfig<TMachine>,
223
+ ): PlayerFactory<TMachine> => {
224
+ return (input?, restore?) => new PlayerActor(machine, options, input, restore?.snapshot);
225
+ };
226
+
227
+ // PlayerActor composes all capabilities
228
+ class PlayerActor<TMachine extends AnyStateMachine>
229
+ extends AbstractActor<AnyActorLogic, EventFromLogic<TMachine>>
230
+ implements Routable, Viewable
231
+ {
232
+ public state: Signal.State<AnyMachineSnapshot>;
233
+ public currentRoute: Signal.Computed<string | null>;
234
+ public currentView: Signal.State<ViewMetadata | null>;
235
+ public readonly initialRoute: string | null;
236
+ }
237
+ ```
238
+
239
+ **Design Rationale:** The original design passed a `catalog` to `definePlayer` and returned `{ create, catalog }`. The implementation decoupled catalogs entirely — component schemas are defined via `@json-render/core`'s `defineCatalog` and bound to renderers via `defineRegistry`, not to actors. This means a single actor can be rendered by different component libraries without change.
240
+
241
+ ### 5.3 Router Layer
242
+
243
+ #### 5.3.1 `@xmachines/play-router`
244
+
245
+ **Role:** Route Infrastructure
246
+
247
+ Provides the complete routing infrastructure: route extraction from state machines, bidirectional route mapping, and the abstract `RouterBridgeBase` that all framework-specific router adapters extend.
248
+
249
+ **Protocol Exports:**
250
+
251
+ - `RouterBridge` — Interface: `{ connect(): void; disconnect(): void }`
252
+ - `PlayRouteEvent` — Routing event: `{ type: 'play.route'; to: string; params?; query?; match? }`
253
+ - `RouterBridgeBase` — Abstract base class that encapsulates common bridge logic (signal watching, route synchronization, param/query extraction). Subclasses implement only three methods:
254
+ - `navigateRouter(path)` — Push a path into the framework router
255
+ - `watchRouterChanges()` — Subscribe to framework router navigation events
256
+ - `unwatchRouterChanges()` — Unsubscribe from framework router events
257
+
258
+ **Route Extraction Exports:**
259
+
260
+ - `RouteNode`, `RouteTree`, `RouteInfo` — Recursive route tree types
261
+ - `crawlMachine` — BFS traversal of state machine graph
262
+ - `extractMachineRoutes` — Build complete route tree from a machine definition
263
+ - `buildRouteTree` — Construct hierarchical tree from flat route info
264
+ - `createRouteMap` / `RouteMap` — Bidirectional path ↔ state ID resolution
265
+ - `BaseRouteMap` / `BaseRouteMapping` — Shared base for adapter-specific route maps
266
+
267
+ **Validation & Query Exports:**
268
+
269
+ - `validateRouteFormat`, `validateStateExists`, `detectDuplicateRoutes`
270
+ - `getNavigableRoutes`, `getRoutableRoutes`, `routeExists`
271
+ - `findRouteById`, `findRouteByPath`
272
+
273
+ **Browser Primitives:**
274
+
275
+ - `createBrowserHistory` / `BrowserHistory` — Browser history abstraction
276
+ - `createRouter` / `VanillaRouter` — Framework-agnostic vanilla router
277
+ - `connectRouter` — Low-level pure browser integration
278
+
279
+ #### 5.3.2 Framework Router Adapters
280
+
281
+ Each adapter extends `RouterBridgeBase` and implements the three abstract methods for its target router. All share the same architectural pattern:
282
+
283
+ | Package | Router | Framework |
284
+ | --------------------------------------- | --------------- | --------- |
285
+ | `@xmachines/play-tanstack-react-router` | TanStack Router | React |
286
+ | `@xmachines/play-tanstack-solid-router` | TanStack Router | SolidJS |
287
+ | `@xmachines/play-react-router` | React Router v7 | React |
288
+ | `@xmachines/play-vue-router` | Vue Router 4/5 | Vue |
289
+ | `@xmachines/play-solid-router` | SolidJS Router | SolidJS |
290
+
291
+ **Runtime Adapter Responsibilities (all adapters):**
292
+
293
+ - **Input (Reflector):** Listen to router navigation events, extract params/query, send `PlayRouteEvent` to Actor
294
+ - **Output (Watcher):** Observe Actor's `currentRoute` signal, call `navigateRouter()` when it changes
295
+ - **Reset:** If Actor rejects a navigation (guard failure), the adapter overwrites the URL bar to match Actor state
296
+
297
+ ### 5.4 View Layer
298
+
299
+ #### 5.4.1 View Renderers
300
+
301
+ Each view renderer provides a `PlayRenderer` component that passively observes the actor's `currentView` signal and projects the JSON spec into framework-native components via `@json-render`.
302
+
303
+ | Package | Framework | JSON-Render Backend |
304
+ | ----------------------- | ----------- | -------------------- |
305
+ | `@xmachines/play-react` | React | `@json-render/react` |
306
+ | `@xmachines/play-vue` | Vue 3 | `@json-render/vue` |
307
+ | `@xmachines/play-solid` | SolidJS | `@json-render/solid` |
308
+ | `@xmachines/play-dom` | Vanilla DOM | `@json-render/core` |
309
+
310
+ **Shared Architecture (all renderers):**
311
+
312
+ 1. Subscribe to `actor.currentView` signal
313
+ 2. Resolve a `StateStore` (external or auto-created per view transition via `@xstate/store`)
314
+ 3. Wire `actions` prop to `actor.send()` via `ActionProvider`
315
+ 4. Render `spec` through the framework's `Renderer` with a `registry` (defined via `defineRegistry`)
316
+
317
+ **`@xmachines/play-react` exports (representative):**
318
+
319
+ ```ts
320
+ // Main component
321
+ export const PlayRenderer: React.FC<PlayRendererProps> = ({
322
+ actor, // AbstractActor & Viewable
323
+ registry, // ComponentRegistry from defineRegistry()
324
+ store?, // Optional external StateStore (controlled mode)
325
+ fallback?, // Shown when currentView is null
326
+ actions?, // Map of action names → XState event type strings
327
+ }) => { /* ... */ };
328
+
329
+ // Hooks
330
+ export { useSignalEffect } from './useSignalEffect';
331
+ export { useActor } from './useActor';
332
+
333
+ // Error handling
334
+ export { PlayErrorBoundary } from './PlayErrorBoundary';
335
+
336
+ // Re-exports from @json-render/react
337
+ export { defineRegistry, useStateBinding, useBoundProp } from '@json-render/react';
338
+ ```
339
+
340
+ **Design Rationale:** The original design passed `components: ComponentMap<TCatalog>` and `catalog: Catalog` directly to `PlayRenderer`. The implementation replaced these with a single `registry` (from `defineRegistry`), which bakes catalog validation into the registry at definition time. This eliminates runtime catalog lookups and provides better TypeScript inference.
341
+
342
+ ### 5.5 Schema Layer (External)
343
+
344
+ Component schemas and UI vocabularies are defined via `@json-render/core`, an external package not in the `@xmachines` scope.
345
+
346
+ - `defineCatalog` — Defines available components and prop schemas (via Zod)
347
+ - `defineRegistry` — Binds a catalog to framework-specific component implementations (available from each `@json-render/*` framework package)
348
+
349
+ The original RFC proposed an `@xmachines/play-ui` package for this purpose. The implementation delegates to `@json-render/core` instead, which provides the same functionality with broader ecosystem support.
350
+
351
+ ---
352
+
353
+ ## 6. Usage Model
354
+
355
+ ### 6.1 Schema Definition (`catalog.ts`)
356
+
357
+ Defines the **UI vocabulary** — available components and their prop schemas. No framework code.
358
+
359
+ ```ts
360
+ import { defineCatalog, z } from "@json-render/core";
361
+
362
+ export const catalog = defineCatalog({
363
+ components: {
364
+ Dashboard: { props: z.object({ title: z.string() }) },
365
+ Metric: { props: z.object({ value: z.number(), label: z.string() }) },
366
+ },
367
+ });
368
+ ```
369
+
370
+ ### 6.2 Feature Definition (`dashboard.player.ts`)
371
+
372
+ Defines **Logic**. No framework code. No routing library imports.
373
+
374
+ ```ts
375
+ import { setup } from "xstate";
376
+ import { definePlayer } from "@xmachines/play-xstate";
377
+
378
+ export const machine = setup({
379
+ /* types, guards, actions */
380
+ }).createMachine({
381
+ initial: "overview",
382
+ states: {
383
+ overview: {
384
+ meta: {
385
+ route: "/dashboard",
386
+ view: {
387
+ type: "Dashboard",
388
+ props: { title: "Q4 Performance" },
389
+ children: [{ type: "Metric", props: { value: 100, label: "Sales" } }],
390
+ },
391
+ },
392
+ },
393
+ },
394
+ });
395
+
396
+ // definePlayer returns a factory function
397
+ export const createDashboard = definePlayer({ machine });
398
+ ```
399
+
400
+ ### 6.3 Application (`App.tsx`)
401
+
402
+ Binds Logic to a View Renderer and Router Adapter.
403
+
404
+ ```tsx
405
+ import { createDashboard, machine } from "./features/dashboard/player";
406
+ import { catalog } from "./catalog";
407
+ import { PlayRenderer, defineRegistry } from "@xmachines/play-react";
408
+ import { TanStackReactRouterBridge } from "@xmachines/play-tanstack-react-router";
409
+ import { extractMachineRoutes, createRouteMap } from "@xmachines/play-router";
410
+
411
+ // 1. Create the actor
412
+ const actor = createDashboard();
413
+
414
+ // 2. Define component implementations (type-checked against catalog)
415
+ const registry = defineRegistry(catalog, {
416
+ Dashboard: ({ props, children }) => <div className="p-4">{children}</div>,
417
+ Metric: ({ props }) => (
418
+ <span>
419
+ {props.label}: {props.value}
420
+ </span>
421
+ ),
422
+ });
423
+
424
+ // 3. Build route map from machine definition
425
+ const routeTree = extractMachineRoutes(machine);
426
+ const routeMap = createRouteMap(routeTree);
427
+
428
+ // 4. Connect router adapter (router, actor, routeMap)
429
+ const bridge = new TanStackReactRouterBridge(tanstackRouter, actor, routeMap);
430
+ bridge.connect();
431
+
432
+ // 5. Render
433
+ function App() {
434
+ return <PlayRenderer actor={actor} registry={registry} actions={{ submit: "form.submit" }} />;
435
+ }
436
+ ```
437
+
438
+ ---
439
+
440
+ ## 7. Lock Statement
441
+
442
+ > Logic is sovereign.
443
+ > Infrastructure reflects, never decides.
444
+ > Capabilities compose, never prescribe.
445
+ > Logic owns structure and flow.
446
+ > Adapters project, never decide.
447
+ > This is Universal Player.
@@ -283,4 +283,4 @@ All three modes preserve the 5 architectural invariants:
283
283
  - [play-tanstack-router README](../api/@xmachines/play-tanstack-react-router/README.md) - TanStack integration details
284
284
  - [play-react README](../api/@xmachines/play-react/README.md) - React renderer documentation
285
285
  - [play-router README](../api/@xmachines/play-router/README.md) - Framework-agnostic routing
286
- - [RFC Play v1](https://gitlab.com/xmachin-es/rfc/-/blob/main/src/play-v1.md) - Complete specification
286
+ - [Play RFC](../rfc/play.md) - Complete specification
@@ -255,5 +255,5 @@ This demonstrates **Actor Authority (INV-01)** — the state machine controls na
255
255
  ## Learn More
256
256
 
257
257
  - [XState Routes Documentation](https://stately.ai/docs/routes) - Official Stately routing patterns
258
- - [RFC Play v1](https://gitlab.com/xmachin-es/rfc/-/blob/main/src/play-v1.md) - Complete architectural specification
258
+ - [Play RFC](../rfc/play.md) - Complete architectural specification
259
259
  - [play-router README](../api/@xmachines/play-router/README.md) - Route extraction and tree building
@@ -34,7 +34,7 @@ yarn add @xmachines/play @xmachines/play-xstate @xmachines/play-actor @xmachines
34
34
 
35
35
  ## Package Selection Guide
36
36
 
37
- XMachines consists of 8 modular packages. Choose the packages based on your needs:
37
+ XMachines is a modular system of packages. Choose the packages based on your needs:
38
38
 
39
39
  ### Core Packages (Required)
40
40
 
@@ -66,9 +66,9 @@ npm install @xmachines/play @xmachines/play-xstate @xmachines/play-actor @xmachi
66
66
 
67
67
  ### UI and Routing (Optional)
68
68
 
69
- **@xmachines/play-ui**
69
+ **@json-render/core** (external)
70
70
 
71
- - UI schema protocol with Zod validation
71
+ - Component catalog and schema definition with Zod validation
72
72
  - Install if: Building declarative UI structures from state
73
73
 
74
74
  **@xmachines/play-router**
@@ -79,13 +79,15 @@ npm install @xmachines/play @xmachines/play-xstate @xmachines/play-actor @xmachi
79
79
  **@xmachines/play-tanstack-react-router**
80
80
 
81
81
  - TanStack Router adapter with signal observation
82
- - Install if: Using TanStack Router for navigation
82
+ - Install if: Using TanStack Router for navigation (React)
83
83
 
84
84
  **@xmachines/play-react**
85
85
 
86
86
  - React view renderer with JSON-Render
87
87
  - Install if: Building React applications
88
88
 
89
+ > **Other frameworks:** Vue (`@xmachines/play-vue`, `@xmachines/play-vue-router`), SolidJS (`@xmachines/play-solid`, `@xmachines/play-solid-router`, `@xmachines/play-tanstack-solid-router`), and Vanilla DOM (`@xmachines/play-dom`) adapters are also available.
90
+
89
91
  ### Complete Installation
90
92
 
91
93
  For full-featured development with React and routing:
@@ -103,9 +105,9 @@ npm install @xmachines/play @xmachines/play-xstate @xmachines/play-actor @xmachi
103
105
  No special configuration needed. ESM imports work out of the box:
104
106
 
105
107
  ```typescript
106
- import { createMachine } from "@xmachines/play-xstate";
107
- import { createActor } from "@xmachines/play-actor";
108
- import { signal } from "@xmachines/play-signals";
108
+ import { setup } from "xstate";
109
+ import { definePlayer } from "@xmachines/play-xstate";
110
+ import { Signal } from "@xmachines/play-signals";
109
111
  ```
110
112
 
111
113
  Most modern bundlers (Vite, Webpack 5+, Rollup) handle ESM packages automatically.
@@ -136,10 +138,10 @@ node my-app.mjs
136
138
  **Import example:**
137
139
 
138
140
  ```typescript
139
- import { createMachine } from "@xmachines/play-xstate";
140
- import { createActor } from "@xmachines/play-actor";
141
+ import { setup } from "xstate";
142
+ import { definePlayer } from "@xmachines/play-xstate";
141
143
 
142
- const machine = createMachine({
144
+ const machine = setup({}).createMachine({
143
145
  id: "example",
144
146
  initial: "idle",
145
147
  states: {
@@ -148,7 +150,8 @@ const machine = createMachine({
148
150
  },
149
151
  });
150
152
 
151
- const actor = createActor(machine);
153
+ const createExample = definePlayer({ machine });
154
+ const actor = createExample();
152
155
  actor.start();
153
156
  ```
154
157
 
@@ -157,15 +160,9 @@ actor.start();
157
160
  XMachines works with Deno via npm specifiers:
158
161
 
159
162
  ```typescript
160
- import { createMachine } from "npm:@xmachines/play-xstate";
161
- import { createActor } from "npm:@xmachines/play-actor";
162
- import { signal } from "npm:@xmachines/play-signals";
163
- ```
164
-
165
- Alternatively, use a CDN like esm.sh:
166
-
167
- ```typescript
168
- import { createMachine } from "https://esm.sh/@xmachines/play-xstate";
163
+ import { setup } from "npm:xstate";
164
+ import { definePlayer } from "npm:@xmachines/play-xstate";
165
+ import { Signal } from "npm:@xmachines/play-signals";
169
166
  ```
170
167
 
171
168
  ### TypeScript
@@ -196,12 +193,13 @@ XMachines is written in TypeScript and includes built-in type definitions. No se
196
193
 
197
194
  **Type inference:**
198
195
 
199
- XMachines provides full type inference from machine catalog through to components:
196
+ XMachines provides full type inference from machine definition through to components:
200
197
 
201
198
  ```typescript
202
- import { createMachine } from "@xmachines/play-xstate";
199
+ import { setup } from "xstate";
200
+ import { definePlayer } from "@xmachines/play-xstate";
203
201
 
204
- const machine = createMachine({
202
+ const machine = setup({}).createMachine({
205
203
  id: "typed",
206
204
  initial: "idle",
207
205
  context: { count: 0 },
@@ -211,8 +209,9 @@ const machine = createMachine({
211
209
  },
212
210
  });
213
211
 
214
- // TypeScript infers exact state types
215
- type States = typeof machine.states; // "idle" | "running"
212
+ const createTyped = definePlayer({ machine });
213
+ const actor = createTyped();
214
+ // Actor signals provide reactive type-safe state access
216
215
  ```
217
216
 
218
217
  ## Verifying Installation
@@ -222,10 +221,10 @@ Test your installation with this simple script:
222
221
  **test.ts** (or test.js with `"type": "module"`):
223
222
 
224
223
  ```typescript
225
- import { createMachine } from "@xmachines/play-xstate";
226
- import { createActor } from "@xmachines/play-actor";
224
+ import { setup } from "xstate";
225
+ import { definePlayer } from "@xmachines/play-xstate";
227
226
 
228
- const machine = createMachine({
227
+ const machine = setup({}).createMachine({
229
228
  id: "test",
230
229
  initial: "ready",
231
230
  states: {
@@ -233,7 +232,8 @@ const machine = createMachine({
233
232
  },
234
233
  });
235
234
 
236
- const actor = createActor(machine);
235
+ const createTest = definePlayer({ machine });
236
+ const actor = createTest();
237
237
  actor.start();
238
238
 
239
239
  console.log("✓ XMachines installed successfully");
@@ -280,7 +280,7 @@ Current state: ready
280
280
 
281
281
  - Add `"type": "module"` to package.json
282
282
  - Or rename files to `.mjs` extension
283
- - Or use dynamic import: `const { createMachine } = await import('@xmachines/play-xstate')`
283
+ - Or use dynamic import: `const { definePlayer } = await import('@xmachines/play-xstate')`
284
284
 
285
285
  ### Type Errors
286
286
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xmachines/docs",
3
- "version": "1.0.0-beta.18",
3
+ "version": "1.0.0-beta.20",
4
4
  "description": "Documentation for XMachines",
5
5
  "keywords": [
6
6
  "documentation",
@@ -22,6 +22,7 @@
22
22
  "api",
23
23
  "examples",
24
24
  "guides",
25
+ "rfc",
25
26
  "index.js",
26
27
  "index.d.ts"
27
28
  ],
@@ -33,7 +34,8 @@
33
34
  },
34
35
  "./api/*": "./api/*",
35
36
  "./examples/*": "./examples/*",
36
- "./guides/*": "./guides/*"
37
+ "./guides/*": "./guides/*",
38
+ "./rfc/*": "./rfc/*"
37
39
  },
38
40
  "publishConfig": {
39
41
  "access": "public"
@@ -46,7 +48,7 @@
46
48
  "typedoc": "typedoc"
47
49
  },
48
50
  "devDependencies": {
49
- "@xmachines/shared": "1.0.0-beta.18",
51
+ "@xmachines/shared": "1.0.0-beta.20",
50
52
  "typedoc": "^0.28.18",
51
53
  "typedoc-plugin-llms-txt": "^0.1.2",
52
54
  "typedoc-plugin-markdown": "^4.11.0"