@xmachines/play-solid 1.0.0-beta.9 → 2.0.0-alpha.1

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Mikael Karon
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,299 +1,202 @@
1
- # @xmachines/play-solid
2
-
3
- **SolidJS renderer consuming signals and UI schema with provider pattern**
4
-
5
- Signal-driven SolidJS rendering layer observing actor state with zero SolidJS state for business logic.
1
+ <!-- generated-by: gsd-doc-writer -->
6
2
 
7
- ## Overview
8
-
9
- `@xmachines/play-solid` provides `PlayRenderer` for building SolidJS UIs that passively observe actor signals. This package enables framework-swappable architecture where SolidJS is just a rendering target subscribing to signal changes — business logic lives entirely in the actor.
10
-
11
- Per [RFC Play v1](https://gitlab.com/xmachin-es/rfc/-/blob/main/src/play-v1.md), this package implements:
3
+ # @xmachines/play-solid
12
4
 
13
- - **Signal-Only Reactivity (INV-05):** No createSignal/createStore for business logic, TC39 signals only
14
- - **Passive Infrastructure (INV-04):** Components observe signals, send events to actor
5
+ > Solid renderer for XMachines Play architecture
15
6
 
16
- **Key Principle:** SolidJS state is never used for business logic. Signals are the source of truth.
7
+ SolidJS rendering layer that passively observes actor signals and renders UI components via `@xmachines/json-render-solid`. SolidJS reactivity is used solely to trigger re-renders — TC39 Signals are the source of truth.
17
8
 
18
- Renderer receives actor via props (provider pattern), not children.
9
+ Part of the [xmachines-js monorepo](../../README.md).
19
10
 
20
11
  ## Installation
21
12
 
22
13
  ```bash
23
- npm install solid-js@^1.8.0
24
- npm install @xmachines/play-solid
14
+ pnpm add @xmachines/play-solid
25
15
  ```
26
16
 
27
- ## Current Exports
17
+ **Peer dependencies** — install alongside the package:
28
18
 
29
- - `PlayRenderer`
30
- - `PlayRendererProps` (type)
31
-
32
- **Peer dependencies:**
33
-
34
- - `solid-js` ^1.8.0 - SolidJS runtime
19
+ ```bash
20
+ pnpm add solid-js xstate @xstate/store @xmachines/json-render-solid @xmachines/json-render-core @xmachines/json-render-xstate
21
+ ```
35
22
 
36
23
  ## Quick Start
37
24
 
38
25
  ```tsx
39
- import { render } from "solid-js/web";
26
+ import { PlayUIProvider, PlayRenderer, defineRegistry } from "@xmachines/play-solid";
40
27
  import { definePlayer } from "@xmachines/play-xstate";
41
- import { defineCatalog } from "@xmachines/play-catalog";
42
- import { PlayRenderer } from "@xmachines/play-solid";
43
- import { z } from "zod";
44
-
45
- // 1. Define catalog (business logic layer)
46
- const catalog = defineCatalog({
47
- LoginForm: z.object({ error: z.string().optional() }),
48
- Dashboard: z.object({
49
- userId: z.string(),
50
- username: z.string(),
51
- }),
28
+ import { defineCatalog } from "@xmachines/json-render-core";
29
+ import { schema } from "@xmachines/json-render-solid/schema";
30
+
31
+ // 1. Define a catalog (authCatalogDef is a plain object describing components/actions)
32
+ const catalog = defineCatalog(schema, authCatalogDef);
33
+
34
+ // 2. Build a component registry
35
+ const registryResult = defineRegistry(catalog, {
36
+ components: {
37
+ Home: () => <div>Welcome home!</div>,
38
+ Login: (ctx) => <div>Login {ctx.props.error && <span>{ctx.props.error}</span>}</div>,
39
+ },
40
+ actions: {
41
+ login: async (args) => actor.send({ type: "auth.login", username: args.username }),
42
+ logout: async () => actor.send({ type: "auth.logout" }),
43
+ },
52
44
  });
53
45
 
54
- // 2. Create SolidJS components (view layer)
55
- const components = {
56
- LoginForm: (props) => (
57
- <form
58
- onSubmit={(e) => {
59
- e.preventDefault();
60
- const data = new FormData(e.currentTarget);
61
- props.send({
62
- type: "auth.login",
63
- username: data.get("username"),
64
- });
65
- }}
66
- >
67
- {props.error && <p style={{ color: "red" }}>{props.error}</p>}
68
- <input name="username" required placeholder="Username" />
69
- <button type="submit">Log In</button>
70
- </form>
71
- ),
72
- Dashboard: (props) => (
73
- <div>
74
- <h1>Welcome, {props.username}!</h1>
75
- <p>User ID: {props.userId}</p>
76
- <button onClick={() => props.send({ type: "auth.logout" })}>Log Out</button>
77
- </div>
78
- ),
79
- };
80
-
81
- // 3. Create player actor (business logic runtime)
82
- const createPlayer = definePlayer({ machine: authMachine, catalog });
46
+ // 3. Create and start an actor
47
+ const createPlayer = definePlayer({ machine: myMachine });
83
48
  const actor = createPlayer();
84
49
  actor.start();
85
50
 
86
- // 4. Render UI (actor via props)
87
- render(
88
- () => <PlayRenderer actor={actor} components={components} />,
89
- document.getElementById("app")!,
90
- );
91
- ```
92
-
93
- ## API Reference
94
-
95
- ### PlayRenderer
96
-
97
- Main renderer component subscribing to actor signals and dynamically rendering catalog components:
98
-
99
- ```typescript
100
- interface PlayRendererProps {
101
- actor: AbstractActor<any>;
102
- components: Record<string, Component<any>>;
103
- fallback?: JSX.Element;
51
+ // 4. Render
52
+ function App() {
53
+ return (
54
+ <PlayUIProvider actor={actor} registryResult={registryResult}>
55
+ <PlayRenderer />
56
+ </PlayUIProvider>
57
+ );
104
58
  }
105
59
  ```
106
60
 
107
- **Props:**
108
-
109
- - `actor` - Actor instance with `currentView` signal
110
- - `components` - Map of component names to SolidJS components
111
- - `fallback` - Component shown when `currentView` is null
112
-
113
- **Behavior:**
61
+ ## Usage
114
62
 
115
- 1. Subscribes to `actor.currentView` signal using a `Signal.subtle.Watcher` inside the component
116
- 2. Looks up component from `components` map using `view.component` string
117
- 3. Renders component with props from `view.props` + `send` function using Solid's `<Dynamic />`
63
+ ### `PlayUIProvider` + `PlayRenderer` (recommended)
118
64
 
119
- **Example:**
65
+ `PlayUIProvider` is the batteries-included entry point. It wraps `ActorProvider` and `JSONUIProvider` into a single composite provider. `PlayRenderer` is a zero-prop leaf component that reads view context and renders the current spec.
120
66
 
121
67
  ```tsx
122
- <PlayRenderer
68
+ import { PlayUIProvider, PlayRenderer, defineRegistry } from "@xmachines/play-solid";
69
+
70
+ <PlayUIProvider
123
71
  actor={actor}
124
- components={{
125
- HomePage: (props) => <div>Home</div>,
126
- AboutPage: (props) => <div>About</div>,
127
- }}
128
- fallback={<div>Loading...</div>}
129
- />
72
+ registryResult={registryResult}
73
+ fallback={<div>Loading…</div>}
74
+ onError={(err) => console.error(err)}
75
+ navigate={navigateFn} // optional: passed to JSONUIProvider
76
+ validationFunctions={valFns} // optional: form validation helpers
77
+ >
78
+ <PlayRenderer />
79
+ </PlayUIProvider>;
130
80
  ```
131
81
 
132
- ## Examples
82
+ ### `ActorProvider` (escape hatch)
133
83
 
134
- ### Component Receiving Props from Catalog
84
+ For library authors who need direct control over provider composition:
135
85
 
136
86
  ```tsx
137
- import { PlayRenderer } from "@xmachines/play-solid";
138
- import { defineCatalog } from "@xmachines/play-catalog";
139
- import { z } from "zod";
140
-
141
- // Define schema in catalog
142
- const catalog = defineCatalog({
143
- UserProfile: z.object({
144
- userId: z.string(),
145
- name: z.string(),
146
- avatar: z.string().url().optional(),
147
- stats: z.object({
148
- posts: z.number(),
149
- followers: z.number(),
150
- }),
151
- }),
152
- });
153
-
154
- // Component receives type-safe props + send
155
- const components = {
156
- UserProfile: (props) => (
157
- <div>
158
- {props.avatar && <img src={props.avatar} alt={props.name} />}
159
- <h1>{props.name}</h1>
160
- <p>ID: {props.userId}</p>
161
- <div>
162
- <span>{props.stats.posts} posts</span>
163
- <span>{props.stats.followers} followers</span>
164
- </div>
165
- <button
166
- onClick={() =>
167
- props.send({
168
- type: "profile.edit",
169
- userId: props.userId,
170
- })
171
- }
172
- >
173
- Edit Profile
174
- </button>
175
- </div>
176
- ),
177
- };
87
+ import { ActorProvider, PlayRenderer } from "@xmachines/play-solid";
178
88
 
179
- <PlayRenderer actor={actor} components={components} />;
89
+ <ActorProvider actor={actor} registryResult={registryResult}>
90
+ <PlayRenderer />
91
+ </ActorProvider>;
180
92
  ```
181
93
 
182
- ### Provider Pattern
94
+ ### `useActor` hook
95
+
96
+ Access the raw actor instance anywhere inside an `ActorProvider` or `PlayUIProvider` tree:
183
97
 
184
98
  ```tsx
185
- import { PlayTanStackRouterProvider } from "@xmachines/play-tanstack-solid-router";
186
- import { PlayRenderer } from "@xmachines/play-solid";
187
- import { createSignal, onCleanup } from "solid-js";
99
+ import { useActor } from "@xmachines/play-solid";
188
100
 
189
- // Renderer receives actor via props (not children)
190
- function App() {
191
- return (
192
- <PlayTanStackRouterProvider
193
- actor={actor}
194
- router={router}
195
- routeMap={routeMap}
196
- renderer={(currentActor, currentRouter) => {
197
- return (
198
- <div>
199
- <Header actor={currentActor} />
200
- <PlayRenderer actor={currentActor} components={components} />
201
- <Footer />
202
- </div>
203
- );
204
- }}
205
- />
206
- );
101
+ function SubmitButton() {
102
+ const actor = useActor();
103
+ return <button onClick={() => actor.send({ type: "SUBMIT" })}>Submit</button>;
207
104
  }
105
+ ```
208
106
 
209
- // Header component also receives actor
210
- function Header(props) {
211
- const [route, setRoute] = createSignal<string | null>(null);
107
+ ### `usePlayView` hook
212
108
 
213
- // Manual watcher setup for custom component reading signals
214
- let watcher: Signal.subtle.Watcher;
109
+ Access the resolved view context (spec, handlers, registry, store) from within the provider tree:
215
110
 
216
- // ... setup watcher to update route signal ...
111
+ ```tsx
112
+ import { usePlayView } from "@xmachines/play-solid";
113
+ import { Renderer } from "@xmachines/json-render-solid";
217
114
 
218
- return (
219
- <header>
220
- <nav>Current: {route()}</nav>
221
- </header>
222
- );
223
- }
115
+ const MyRenderer = () => {
116
+ const view = usePlayView();
117
+ return <Renderer spec={view.spec} registry={view.registry} />;
118
+ };
224
119
  ```
225
120
 
226
- ## Architecture
121
+ ## API Summary
227
122
 
228
- This package implements **Signal-Only Reactivity (INV-05)** and **Passive Infrastructure (INV-04)**:
123
+ ### Components
229
124
 
230
- 1. **No Business Logic in SolidJS:**
231
- - No createSignal/createStore for business state
232
- - No createEffect for business side effects
233
- - SolidJS only triggers renders, doesn't control state
125
+ | Export | Description |
126
+ | ---------------- | ------------------------------------------------------------------------------ |
127
+ | `PlayUIProvider` | Batteries-included composite provider (recommended entry point) |
128
+ | `PlayRenderer` | Zero-prop leaf component; renders the current view spec inside a provider tree |
129
+ | `ActorProvider` | Lower-level smart provider for escape-hatch composition |
234
130
 
235
- 2. **Signals as Source of Truth:**
236
- - `actor.currentView.get()` provides UI structure
237
- - `actor.currentRoute.get()` provides navigation state
238
- - Components observe signals via explicit watcher patterns
131
+ ### Hooks
239
132
 
240
- 3. **Event Forwarding:**
241
- - Components receive `send` function via props
242
- - User actions send events to actor (e.g., `{ type: "auth.login" }`)
243
- - Actor guards validate and process events
133
+ | Export | Description |
134
+ | --------------- | --------------------------------------------------------------------------------------------- |
135
+ | `useActor()` | Returns the raw `AnyPlayActor` instance from context; throws outside a provider tree |
136
+ | `usePlayView()` | Returns the current `ViewContextValue` (spec, handlers, registry, store); throws outside tree |
244
137
 
245
- 4. **Microtask Batching:**
246
- - `Signal.subtle.Watcher` coalesces rapid signal changes
247
- - Prevents SolidJS thrashing from multiple signal updates
248
- - Single SolidJS render per microtask batch
138
+ ### Context
249
139
 
250
- 5. **Explicit Disposal Contract:**
251
- - Component teardown calls watcher `unwatch` in `onCleanup`
252
- - Do not rely on GC-only cleanup
140
+ | Export | Description |
141
+ | -------------- | -------------------------------------------------------------------------------------- |
142
+ | `ActorContext` | SolidJS context for the actor; use `ActorContext.Provider` directly as an escape hatch |
253
143
 
254
- **Pattern:**
144
+ ### Re-exports from `@xmachines/json-render-solid`
255
145
 
256
- - Renderer receives actor via props (provider pattern)
257
- - Enables composition with navigation, headers, footers
258
- - Supports multiple renderers in same app
146
+ This package re-exports the full `@xmachines/json-render-solid` public API so consumers do not need a direct dependency:
259
147
 
260
- **Architectural Invariants:**
261
-
262
- - **Signal-Only Reactivity (INV-05):** No SolidJS state for business logic
263
- - **Passive Infrastructure (INV-04):** Components reflect, never decide
148
+ ```tsx
149
+ import {
150
+ // Providers
151
+ JSONUIProvider,
152
+ StateProvider,
153
+ ActionProvider,
154
+ VisibilityProvider,
155
+ ValidationProvider,
156
+ // Renderer
157
+ Renderer,
158
+ // Registry factory + hooks
159
+ defineRegistry,
160
+ useBoundProp,
161
+ useStateBinding,
162
+ useStateValue,
163
+ useStateStore,
164
+ useActions,
165
+ useAction,
166
+ useIsVisible,
167
+ useFieldValidation,
168
+ useOptionalValidation,
169
+ useVisibility,
170
+ } from "@xmachines/play-solid";
171
+ ```
264
172
 
265
- ## Canonical Watcher Lifecycle
173
+ ### Key Types
266
174
 
267
- If you write your own custom integration, use the same watcher flow as `PlayRenderer`:
175
+ | Type | Description |
176
+ | --------------------- | ------------------------------------------------------------------------------ |
177
+ | `PlayUIProviderProps` | Props for `PlayUIProvider` |
178
+ | `ActorProviderProps` | Props for `ActorProvider` |
179
+ | `ViewContextValue` | Shape of the context value from `usePlayView()` |
180
+ | `AnyPlayActor` | `AbstractActor<AnyActorLogic>` — bare actor type accepted by context providers |
268
181
 
269
- 1. `notify` callback runs
270
- 2. Schedule work with `queueMicrotask`
271
- 3. Drain `watcher.getPending()`
272
- 4. Read actor signals and update SolidJS-local signal state (`setSignal()`)
273
- 5. Re-arm with `watch(...)` or `watch()`
182
+ ## Testing
274
183
 
275
- Watcher notify is one-shot. Re-arm is required for continuous observation.
184
+ Run tests for this package in isolation:
276
185
 
277
- ## Benefits
186
+ ```bash
187
+ pnpm --filter @xmachines/play-solid test
188
+ ```
278
189
 
279
- - **Framework Swappable:** Business logic has zero SolidJS imports
280
- - **Type Safety:** Props validated against catalog schemas
281
- - **Simple Testing:** Test actors without SolidJS renderer
282
- - **Performance:** Microtask batching reduces unnecessary renders
283
- - **Composability:** Renderer prop enables complex layouts
190
+ Or from within the package directory:
284
191
 
285
- ## Related Packages
192
+ ```bash
193
+ pnpm test # single run (jsdom environment)
194
+ pnpm run test:watch # watch mode
195
+ pnpm run test:ui # interactive Vitest UI
196
+ ```
286
197
 
287
- - **[@xmachines/play-xstate](../play-xstate)** - XState adapter providing actors
288
- - **[@xmachines/play-catalog](../play-catalog)** - UI schema validation
289
- - **[@xmachines/play-solid-router](../play-solid-router)** - Solid Router integration
290
- - **[@xmachines/play-tanstack-solid-router](../play-tanstack-solid-router)** - TanStack Solid Router integration
291
- - **[@xmachines/play-actor](../play-actor)** - Actor base
292
- - **[@xmachines/play-signals](../play-signals)** - TC39 Signals primitives
198
+ Coverage is collected with v8 (80% threshold for lines, functions, branches, and statements). Browser-specific tests live in `test/browser/` and are excluded from the default jsdom run.
293
199
 
294
200
  ## License
295
201
 
296
- Copyright (c) 2016 [Mikael Karon](mailto:mikael@karon.se). All rights reserved.
297
-
298
- This work is licensed under the terms of the MIT license.
299
- For a copy, see <https://opensource.org/licenses/MIT>.
202
+ MIT
@@ -0,0 +1,85 @@
1
+ import { ActorContext as e } from "./useActor.js";
2
+ import { createComponent as t } from "solid-js/web";
3
+ import { StateProvider as n, useStateStore as r } from "@xmachines/json-render-solid";
4
+ import { ErrorBoundary as i, createContext as a, createEffect as o, createMemo as s, createSignal as c, onCleanup as l, useContext as u } from "solid-js";
5
+ import { createAtom as d } from "@xstate/store";
6
+ import { xstateStoreStateStore as f } from "@xmachines/json-render-xstate";
7
+ import { watchSignal as p } from "@xmachines/play-signals";
8
+ import { assertNonNullable as m } from "@xmachines/play";
9
+ import { attachRenderErrorHandler as h, toAtomState as g } from "@xmachines/play-actor";
10
+ //#region src/ActorProvider.tsx
11
+ var _ = a(null);
12
+ function v() {
13
+ return m(u(_), "ViewContext");
14
+ }
15
+ var y = (e) => {
16
+ let n = r(), i = (e) => {
17
+ let t = n.getSnapshot();
18
+ n.update(e(t));
19
+ }, a = e.registryResult.handlers(() => i, () => n.getSnapshot()), o = {
20
+ spec: e.spec,
21
+ handlers: a,
22
+ registry: e.registryResult.registry,
23
+ store: e.store
24
+ };
25
+ return t(_.Provider, {
26
+ value: o,
27
+ get children() {
28
+ return e.children;
29
+ }
30
+ });
31
+ }, b = (r) => {
32
+ let [a, u] = c(null), m = new Proxy({}, {
33
+ get(e, t) {
34
+ let n = r.actor, i = Reflect.get(n, t, n);
35
+ return typeof i == "function" ? i.bind(n) : i;
36
+ },
37
+ has(e, t) {
38
+ return t in r.actor;
39
+ }
40
+ }), _ = s(() => r.onRenderError ? {
41
+ ...r.registryResult,
42
+ registry: h(r.registryResult.registry, r.onRenderError)
43
+ } : r.registryResult), v = null, b = null;
44
+ return o(() => {
45
+ let e = (e) => u(e);
46
+ e(r.actor.currentView.get());
47
+ let t = p(r.actor.currentView, (t) => {
48
+ e(t);
49
+ });
50
+ l(() => t());
51
+ }), t(e.Provider, {
52
+ value: m,
53
+ get children() {
54
+ return t(i, {
55
+ fallback: (e) => (r.onError?.(e), r.fallback ?? null),
56
+ get children() {
57
+ return (() => {
58
+ let e = a();
59
+ if (!e) return r.fallback ?? null;
60
+ let i;
61
+ return r.store ? i = r.store : ((v === null || b !== e) && (v = f({ atom: d(g(e.state)) }), b = e), i = v), t(n, {
62
+ store: i,
63
+ get children() {
64
+ return t(y, {
65
+ get registryResult() {
66
+ return _();
67
+ },
68
+ spec: e,
69
+ store: i,
70
+ get children() {
71
+ return r.children;
72
+ }
73
+ });
74
+ }
75
+ });
76
+ })();
77
+ }
78
+ });
79
+ }
80
+ });
81
+ };
82
+ //#endregion
83
+ export { b as ActorProvider, v as usePlayView };
84
+
85
+ //# sourceMappingURL=ActorProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ActorProvider.js","names":["createSignal","createEffect","createMemo","onCleanup","createContext","useContext","ErrorBoundary","Component","JSX","StateProvider","useStateStore","DefineRegistryResult","SetState","StateStore","ComponentRegistry","createAtom","xstateStoreStateStore","watchSignal","assertNonNullable","toAtomState","attachRenderErrorHandler","PlaySpec","BaseActorProviderProps","BaseViewContextValue","ActorContext","AnyPlayActor","ViewContextValue","ViewContext","usePlayView","ActorProviderProps","fallback","Element","onError","error","children","ActorProviderInner","registryResult","spec","store","innerProps","stateCtx","setStateAdapter","updater","prev","getSnapshot","update","handlers","viewValue","registry","_$createComponent","Provider","value","ActorProvider","props","view","setView","actorProxy","Proxy","get","_target","prop","current","actor","Reflect","bind","has","resolvedRegistryResult","onRenderError","internalStore","lastView","nextView","currentView","unwatch","err","atom","state"],"sources":["../src/ActorProvider.tsx"],"sourcesContent":["/**\n * ActorProvider — Smart SolidJS provider component for the XMachines Play actor lifecycle.\n *\n * Escape hatch primitive for library authors who need direct control. Most users should\n * use PlayUIProvider (batteries-included composite) instead.\n *\n * This component:\n * - Subscribes to actor.currentView signal via watchSignal (in component body per Phase 29)\n * - Manages per-view StateStore lifecycle (controlled/uncontrolled)\n * - Resolves action handlers via inner component pattern (inside StateProvider)\n * - Injects onRenderError into registry if provided\n * - Provides ActorContext (actor) and ViewContext (spec + handlers + registry) to children\n * - Wraps render path in SolidJS ErrorBoundary\n *\n * Per D-11: The old `ActorProvider = ActorContext.Provider` alias is removed. This new smart\n * component takes the name. Use `ActorContext.Provider` directly for escape-hatch access.\n *\n * @packageDocumentation\n */\n\nimport {\n\tcreateSignal,\n\tcreateEffect,\n\tcreateMemo,\n\tonCleanup,\n\tcreateContext,\n\tuseContext,\n\tErrorBoundary,\n} from \"solid-js\";\nimport type { Component, JSX } from \"solid-js\";\nimport { StateProvider, useStateStore } from \"@xmachines/json-render-solid\";\nimport type { DefineRegistryResult, SetState } from \"@xmachines/json-render-solid\";\nimport type { StateStore } from \"@xmachines/json-render-core\";\nimport type { ComponentRegistry } from \"@xmachines/json-render-solid\";\nimport { createAtom } from \"@xstate/store\";\nimport { xstateStoreStateStore } from \"@xmachines/json-render-xstate\";\nimport { watchSignal } from \"@xmachines/play-signals\";\nimport { assertNonNullable } from \"@xmachines/play\";\nimport {\n\ttoAtomState,\n\tattachRenderErrorHandler,\n\ttype PlaySpec,\n\ttype BaseActorProviderProps,\n\ttype BaseViewContextValue,\n} from \"@xmachines/play-actor\";\nimport { ActorContext, type AnyPlayActor } from \"./useActor.js\";\n\n// ---------------------------------------------------------------------------\n// ViewContextValue — shape of the context value provided by ActorProvider\n// ---------------------------------------------------------------------------\n\n/**\n * Value provided by ActorProvider's ViewContext.\n * Access via usePlayView() inside the ActorProvider tree.\n */\nexport interface ViewContextValue extends BaseViewContextValue<ComponentRegistry> {}\n\nconst ViewContext = createContext<ViewContextValue | null>(null);\n\n/**\n * Hook to access the current view context inside an ActorProvider tree.\n *\n * @throws {Error} If called outside an ActorProvider (or PlayUIProvider) tree\n *\n * @example\n * ```tsx\n * import { usePlayView } from \"@xmachines/play-solid\";\n *\n * const MyRenderer: Component = () => {\n * const view = usePlayView();\n * return <Renderer spec={view.spec} registry={view.registry} />;\n * };\n * ```\n */\nexport function usePlayView(): ViewContextValue {\n\treturn assertNonNullable(useContext(ViewContext), \"ViewContext\");\n}\n\n// ---------------------------------------------------------------------------\n// ActorProviderProps\n// ---------------------------------------------------------------------------\n\n/**\n * Props for ActorProvider — the escape hatch primitive.\n *\n * For batteries-included usage, prefer PlayUIProvider which wraps ActorProvider\n * with JSONUIProvider and all required sub-providers.\n */\nexport interface ActorProviderProps extends BaseActorProviderProps<DefineRegistryResult> {\n\t/** Optional fallback element shown when currentView is null or ErrorBoundary catches */\n\tfallback?: JSX.Element;\n\n\t/** Optional callback invoked when SolidJS ErrorBoundary catches an error */\n\tonError?: (error: unknown) => void;\n\n\t/** Children — required; must include <PlayRenderer /> (or use PlayUIProvider shorthand) */\n\tchildren: JSX.Element;\n}\n\n// ---------------------------------------------------------------------------\n// ActorProviderInner — resolves handlers inside StateProvider tree\n// ---------------------------------------------------------------------------\n\n/**\n * Inner component that runs inside StateProvider so it can call useStateStore()\n * to get live set/getSnapshot for handler resolution.\n */\nconst ActorProviderInner: Component<{\n\tregistryResult: DefineRegistryResult;\n\tspec: PlaySpec;\n\tstore: StateStore;\n\tchildren: JSX.Element;\n}> = (innerProps) => {\n\tconst stateCtx = useStateStore();\n\n\t// Build SetState adapter bridging stateCtx.update/getSnapshot\n\tconst setStateAdapter: SetState = (updater) => {\n\t\tconst prev = stateCtx.getSnapshot();\n\t\tstateCtx.update(updater(prev));\n\t};\n\n\tconst handlers = innerProps.registryResult.handlers(\n\t\t() => setStateAdapter,\n\t\t() => stateCtx.getSnapshot(),\n\t);\n\n\tconst viewValue: ViewContextValue = {\n\t\tspec: innerProps.spec,\n\t\thandlers,\n\t\tregistry: innerProps.registryResult.registry,\n\t\tstore: innerProps.store,\n\t};\n\n\treturn <ViewContext.Provider value={viewValue}>{innerProps.children}</ViewContext.Provider>;\n};\n\n// ---------------------------------------------------------------------------\n// ActorProvider — the smart component (per D-11 takes the ActorProvider name)\n// ---------------------------------------------------------------------------\n\n/**\n * Smart ActorProvider component — owns actor bridging, signal subscription,\n * StateStore lifecycle, handler resolution, and error boundary.\n *\n * Per D-11: Replaces the old raw alias `ActorProvider = ActorContext.Provider`.\n * Consumers who previously used `<ActorProvider value={actor}>` should now use\n * `<ActorContext.Provider value={actor}>` for raw provider access, or migrate to\n * this smart component / PlayUIProvider.\n *\n * @example\n * ```tsx\n * import { ActorProvider, PlayRenderer } from \"@xmachines/play-solid\";\n *\n * <ActorProvider actor={myActor} registryResult={registryResult}>\n * <PlayRenderer />\n * </ActorProvider>\n * ```\n */\nexport const ActorProvider: Component<ActorProviderProps> = (props) => {\n\t// SolidJS signal for current view (PlaySpec | null)\n\tconst [view, setView] = createSignal<PlaySpec | null>(null);\n\n\t// A stable Proxy is provided as the ActorContext value instead of the raw\n\t// actor: Solid's Context.Provider reads `value` once at creation, so passing\n\t// `props.actor` directly would snapshot the FIRST actor and useActor()\n\t// consumers would never see a prop swap. With the proxy, consumers keep the\n\t// reference obtained at creation time, yet every property access (send,\n\t// currentView, …) resolves against the latest actor. Reading `props.actor`\n\t// inside the traps is a reactive read, so consumers accessing properties in\n\t// tracking scopes (createEffect, createMemo, JSX) re-run on swap. Methods\n\t// are bound to the current actor so `this` (including private fields) works\n\t// exactly as with a direct call. Mirrors play-vue's ActorProvider proxy.\n\tconst actorProxy = new Proxy({} as AnyPlayActor, {\n\t\tget(_target, prop) {\n\t\t\tconst current = props.actor as AnyPlayActor;\n\t\t\tconst value = Reflect.get(current, prop, current) as unknown;\n\t\t\treturn typeof value === \"function\" ? value.bind(current) : value;\n\t\t},\n\t\thas(_target, prop) {\n\t\t\treturn prop in (props.actor as AnyPlayActor);\n\t\t},\n\t});\n\n\t// Inject onRenderError into registry if provided (non-enumerable override).\n\t// Memoized so that creating a new object on every reactive evaluation does not\n\t// cause unnecessary re-renders of child components that receive this as a prop.\n\tconst resolvedRegistryResult = createMemo(() => {\n\t\tif (!props.onRenderError) return props.registryResult;\n\t\treturn {\n\t\t\t...props.registryResult,\n\t\t\tregistry: attachRenderErrorHandler(props.registryResult.registry, props.onRenderError),\n\t\t};\n\t});\n\n\t// Per-view internal store — recreated on each view transition (uncontrolled mode)\n\tlet internalStore: StateStore | null = null;\n\tlet lastView: PlaySpec | null = null;\n\n\t// Bridge TC39 Signal to SolidJS signal — seed AND watch atomically inside a single\n\t// createEffect to eliminate the race window between .get() and watcher registration.\n\t// If the TC39 signal changes between the initial .get() and first watcher notification,\n\t// the update function captures the latest value without missing it.\n\tcreateEffect(() => {\n\t\tconst update = (nextView: PlaySpec | null) => setView(nextView);\n\t\tupdate(props.actor.currentView.get() as PlaySpec | null);\n\t\tconst unwatch = watchSignal(props.actor.currentView, (nextView) => {\n\t\t\tupdate(nextView as PlaySpec | null);\n\t\t});\n\t\tonCleanup(() => unwatch());\n\t});\n\n\treturn (\n\t\t<ActorContext.Provider value={actorProxy}>\n\t\t\t<ErrorBoundary\n\t\t\t\tfallback={(err: unknown) => {\n\t\t\t\t\tprops.onError?.(err);\n\t\t\t\t\treturn props.fallback ?? null;\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t{(() => {\n\t\t\t\t\tconst currentView = view();\n\t\t\t\t\tif (!currentView) return props.fallback ?? null;\n\n\t\t\t\t\t// Resolve store: external (controlled) or internal per-view atom\n\t\t\t\t\tlet store: StateStore;\n\t\t\t\t\tif (props.store) {\n\t\t\t\t\t\tstore = props.store;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif (internalStore === null || lastView !== currentView) {\n\t\t\t\t\t\t\t// Proto-safe guard: spec.state must be a plain object (T-37-05-02)\n\t\t\t\t\t\t\tinternalStore = xstateStoreStateStore({\n\t\t\t\t\t\t\t\tatom: createAtom(toAtomState(currentView.state)),\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tlastView = currentView;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tstore = internalStore;\n\t\t\t\t\t}\n\n\t\t\t\t\treturn (\n\t\t\t\t\t\t<StateProvider store={store}>\n\t\t\t\t\t\t\t<ActorProviderInner\n\t\t\t\t\t\t\t\tregistryResult={resolvedRegistryResult()}\n\t\t\t\t\t\t\t\tspec={currentView}\n\t\t\t\t\t\t\t\tstore={store}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{props.children}\n\t\t\t\t\t\t\t</ActorProviderInner>\n\t\t\t\t\t\t</StateProvider>\n\t\t\t\t\t);\n\t\t\t\t})()}\n\t\t\t</ErrorBoundary>\n\t\t</ActorContext.Provider>\n\t);\n};\n"],"mappings":";;;;;;;;;;AAyDA,IAAM2B,IAAcvB,EAAuC,IAAI;AAiB/D,SAAgBwB,IAAgC;CAC/C,OAAOV,EAAkBb,EAAWsB,CAAW,GAAG,aAAa;AAChE;AA+BA,IAAMQ,KAKAI,MAAe;CACpB,IAAMC,IAAW9B,EAAc,GAGzB+B,KAA6BC,MAAY;EAC9C,IAAMC,IAAOH,EAASI,YAAY;EAClCJ,EAASK,OAAOH,EAAQC,CAAI,CAAC;CAC9B,GAEMG,IAAWP,EAAWH,eAAeU,eACpCL,SACAD,EAASI,YAAY,CAC5B,GAEMG,IAA8B;EACnCV,MAAME,EAAWF;EACjBS;EACAE,UAAUT,EAAWH,eAAeY;EACpCV,OAAOC,EAAWD;CACnB;CAEA,OAAAW,EAAQtB,EAAYuB,UAAQ;EAACC,OAAOJ;EAAS,IAAAb,WAAA;GAAA,OAAGK,EAAWL;EAAQ;CAAA,CAAA;AACpE,GAwBakB,KAAgDC,MAAU;CAEtE,IAAM,CAACC,GAAMC,KAAWvD,EAA8B,IAAI,GAYpDwD,IAAa,IAAIC,MAAM,CAAC,GAAmB;EAChDC,IAAIC,GAASC,GAAM;GAClB,IAAMC,IAAUR,EAAMS,OAChBX,IAAQY,QAAQL,IAAIG,GAASD,GAAMC,CAAO;GAChD,OAAO,OAAOV,KAAU,aAAaA,EAAMa,KAAKH,CAAO,IAAIV;EAC5D;EACAc,IAAIN,GAASC,GAAM;GAClB,OAAOA,KAASP,EAAMS;EACvB;CACD,CAAC,GAKKI,IAAyBhE,QACzBmD,EAAMc,gBACJ;EACN,GAAGd,EAAMjB;EACTY,UAAU5B,EAAyBiC,EAAMjB,eAAeY,UAAUK,EAAMc,aAAa;CACtF,IAJiCd,EAAMjB,cAKvC,GAGGgC,IAAmC,MACnCC,IAA4B;CAehC,OATApE,QAAmB;EAClB,IAAM4C,KAAUyB,MAA8Bf,EAAQe,CAAQ;EAC9DzB,EAAOQ,EAAMS,MAAMS,YAAYb,IAAI,CAAoB;EACvD,IAAMc,IAAUvD,EAAYoC,EAAMS,MAAMS,cAAcD,MAAa;GAClEzB,EAAOyB,CAA2B;EACnC,CAAC;EACDnE,QAAgBqE,EAAQ,CAAC;CAC1B,CAAC,GAEDvB,EACEzB,EAAa0B,UAAQ;EAACC,OAAOK;EAAU,IAAAtB,WAAA;GAAA,OAAAe,EACtC3C,GAAa;IACbwB,WAAW2C,OACVpB,EAAMrB,UAAUyC,CAAG,GACZpB,EAAMvB,YAAY;IACzB,IAAAI,WAAA;KAAA,cAEO;MACP,IAAMqC,IAAcjB,EAAK;MACzB,IAAI,CAACiB,GAAa,OAAOlB,EAAMvB,YAAY;MAG3C,IAAIQ;MAcJ,OAbIe,EAAMf,QACTA,IAAQe,EAAMf,UAEV8B,MAAkB,QAAQC,MAAaE,OAE1CH,IAAgBpD,EAAsB,EACrC0D,MAAM3D,EAAWI,EAAYoD,EAAYI,KAAK,CAAC,EAChD,CAAC,GACDN,IAAWE,IAEZjC,IAAQ8B,IAGTnB,EACExC,GAAa;OAAQ6B;OAAK,IAAAJ,WAAA;QAAA,OAAAe,EACzBd,GAAkB;SAAA,IAClBC,iBAAc;UAAA,OAAE8B,EAAuB;SAAC;SACxC7B,MAAMkC;SACCjC;SAAK,IAAAJ,WAAA;UAAA,OAEXmB,EAAMnB;SAAQ;QAAA,CAAA;OAAA;MAAA,CAAA;KAInB,EAAA,CAAG;IAAC;GAAA,CAAA;EAAA;CAAA,CAAA;AAIR"}
@@ -1,31 +1,19 @@
1
- import { Dynamic as e, createComponent as t, insert as n, memo as r, mergeProps as i, template as a } from "solid-js/web";
2
- import { createSignal as o, onMount as s } from "solid-js";
3
- import { Signal as c } from "@xmachines/play-signals";
1
+ import { usePlayView as e } from "./ActorProvider.js";
2
+ import { createComponent as t } from "solid-js/web";
3
+ import { Renderer as n } from "@xmachines/json-render-solid";
4
4
  //#region src/PlayRenderer.tsx
5
- var l = /* @__PURE__ */ a("<div class=play-renderer-error>Component \"<!>\" not found in catalog. Available: "), u = (a) => {
6
- let [u, d] = o(a.actor.currentView.get());
7
- s(() => {
8
- let e = new c.subtle.Watcher(() => {
9
- queueMicrotask(() => {
10
- e.getPending(), d(a.actor.currentView.get()), e.watch(a.actor.currentView);
11
- });
12
- });
13
- e.watch(a.actor.currentView);
5
+ var r = () => {
6
+ let r = e();
7
+ return t(n, {
8
+ get spec() {
9
+ return r.spec;
10
+ },
11
+ get registry() {
12
+ return r.registry;
13
+ }
14
14
  });
15
- let f = a.actor.send.bind(a.actor);
16
- return [
17
- r(() => r(() => !u())() && (a.fallback || null)),
18
- r(() => r(() => !!(u() && !a.components))() && (console.error(`Components catalog is ${a.components === null ? "null" : "undefined"}. Cannot render component "${u().component}".`), a.fallback || null)),
19
- r(() => r(() => !!(u() && a.components && !a.components[u().component]))() && (console.error(`Component "${u().component}" not found in catalog. Available components: ${Object.keys(a.components).join(", ")}`), (() => {
20
- var e = l(), t = e.firstChild.nextSibling;
21
- return t.nextSibling, n(e, () => u().component, t), n(e, () => Object.keys(a.components).join(", "), null), e;
22
- })())),
23
- r(() => r(() => !!(u() && a.components && a.components[u().component]))() && t(e, i({ get component() {
24
- return a.components[u().component];
25
- } }, () => u().props, { send: f })))
26
- ];
27
15
  };
28
16
  //#endregion
29
- export { u as PlayRenderer };
17
+ export { r as PlayRenderer };
30
18
 
31
19
  //# sourceMappingURL=PlayRenderer.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"PlayRenderer.js","names":["createSignal","onMount","Component","Dynamic","Signal","PlayRendererProps","SolidView","PlayRenderer","props","view","setView","actor","currentView","get","watcher","subtle","Watcher","queueMicrotask","getPending","watch","sendBound","send","bind","_$memo","fallback","components","console","error","component","Object","keys","join","_el$","_tmpl$","_el$2","firstChild","_el$5","nextSibling","_el$3","_$insert","_$createComponent","_$mergeProps"],"sources":["../src/PlayRenderer.tsx"],"sourcesContent":["/**\n * PlayRenderer - Main SolidJS renderer component for XMachines Play architecture\n *\n * @packageDocumentation\n */\n\nimport { createSignal, onMount, type Component } from \"solid-js\";\nimport { Dynamic } from \"solid-js/web\";\nimport { Signal } from \"@xmachines/play-signals\";\nimport type { PlayRendererProps, SolidView } from \"./types.js\";\n\n/**\n * Main renderer component that subscribes to actor signals and renders UI\n *\n * Architecture (per XMachines Play patterns):\n * - Subscribes to actor.currentView signal via TC39 Signal.subtle.Watcher\n * - Dynamically renders catalog components based on view.component string\n * - Forwards user events to actor via actor.send()\n * - SolidJS signal only for triggering renders, NOT business logic\n *\n * Invariant: Actor Authority - Actor decides all state transitions via guards.\n * Invariant: Passive Infrastructure - Component observes signals and sends events.\n * Invariant: Signal-Only Reactivity - Business logic state lives in actor signals.\n *\n * @example\n * ```typescript\n * import { PlayRenderer } from \"@xmachines/play-solidjs\";\n * import { definePlayer } from \"@xmachines/play-xstate\";\n *\n * const actor = definePlayer({ machine, catalog })();\n * actor.start();\n *\n * const components = {\n * Dashboard: (props) => <div>User: {props.userId}</div>,\n * LoginForm: (props) => (\n * <form onSubmit={(e) => {\n * e.preventDefault();\n * props.send({ type: \"auth.login\", payload: {...} });\n * }}>...</form>\n * )\n * };\n *\n * <PlayRenderer actor={actor} components={components} />\n * ```\n *\n * @param props - Component props\n * @returns SolidJS element rendering current view from actor\n *\n * @remarks\n * **Component lookup:** Dynamically looks up component from `components` map\n * using `view.component` string from actor.currentView signal.\n *\n * **Event forwarding:** Injects `send` function as prop to components. Components\n * call `send(event)` to forward intents to actor. Actor guards decide validity.\n *\n * **Error handling:** If component not found in catalog, logs error and shows\n * fallback. This indicates missing component registration, not runtime error.\n *\n * **Signal bridge:** Uses one-shot re-watch pattern. TC39 Signal watchers stop\n * watching after notification, so watcher.watch() must be called in microtask\n * after getPending() to re-arm for next notification.\n *\n * **CRITICAL:** Never call actor.send() during render - only in event handlers.\n * Calling send during render causes infinite render loops.\n */\nexport const PlayRenderer: Component<PlayRendererProps> = (props) => {\n\t// Create SolidJS signal for view\n\t// Signal is NOT business logic state - it's just SolidJS's render trigger\n\tconst [view, setView] = createSignal<SolidView>(props.actor.currentView.get() as SolidView);\n\n\t// Bridge TC39 Signal to SolidJS signal\n\t// Uses one-shot re-watch pattern (must re-watch after each notification)\n\tonMount(() => {\n\t\tconst watcher = new Signal.subtle.Watcher(() => {\n\t\t\tqueueMicrotask(() => {\n\t\t\t\t// Acknowledge the notification\n\t\t\t\twatcher.getPending();\n\n\t\t\t\t// Update SolidJS signal (triggers SolidJS reactivity)\n\t\t\t\tsetView(props.actor.currentView.get() as SolidView);\n\n\t\t\t\t// Re-watch for next notification (one-shot pattern)\n\t\t\t\t// TC39 Signal watchers stop watching after notification\n\t\t\t\twatcher.watch(props.actor.currentView);\n\t\t\t});\n\t\t});\n\n\t\t// Watch actor.currentView for changes\n\t\twatcher.watch(props.actor.currentView);\n\n\t\t// Note: TC39 Signal watchers don't have explicit disposal\n\t\t// The watcher will be garbage collected when the component unmounts\n\t});\n\n\t// Bind send function (ensures correct 'this' context)\n\tconst sendBound = props.actor.send.bind(props.actor);\n\n\treturn (\n\t\t<>\n\t\t\t{/* No view - show fallback */}\n\t\t\t{!view() && (props.fallback || null)}\n\n\t\t\t{/* Handle null/undefined components catalog gracefully */}\n\t\t\t{view() &&\n\t\t\t\t!props.components &&\n\t\t\t\t(() => {\n\t\t\t\t\tconsole.error(\n\t\t\t\t\t\t`Components catalog is ${props.components === null ? \"null\" : \"undefined\"}. ` +\n\t\t\t\t\t\t\t`Cannot render component \"${view()!.component}\".`,\n\t\t\t\t\t);\n\t\t\t\t\treturn props.fallback || null;\n\t\t\t\t})()}\n\n\t\t\t{/* View exists but component not found */}\n\t\t\t{view() &&\n\t\t\t\tprops.components &&\n\t\t\t\t!props.components[view()!.component] &&\n\t\t\t\t(() => {\n\t\t\t\t\tconsole.error(\n\t\t\t\t\t\t`Component \"${view()!.component}\" not found in catalog. ` +\n\t\t\t\t\t\t\t`Available components: ${Object.keys(props.components).join(\", \")}`,\n\t\t\t\t\t);\n\t\t\t\t\treturn (\n\t\t\t\t\t\t<div class=\"play-renderer-error\">\n\t\t\t\t\t\t\tComponent \"{view()!.component}\" not found in catalog. Available:{\" \"}\n\t\t\t\t\t\t\t{Object.keys(props.components).join(\", \")}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t);\n\t\t\t\t})()}\n\n\t\t\t{/* Render matched component dynamically */}\n\t\t\t{view() && props.components && props.components[view()!.component] && (\n\t\t\t\t<Dynamic\n\t\t\t\t\tcomponent={props.components[view()!.component]}\n\t\t\t\t\t{...view()!.props}\n\t\t\t\t\tsend={sendBound}\n\t\t\t\t/>\n\t\t\t)}\n\t\t</>\n\t);\n};\n"],"mappings":";;;;iHAiEaO,KAA8CC,MAAU;CAGpE,IAAM,CAACC,GAAMC,KAAWV,EAAwBQ,EAAMG,MAAMC,YAAYC,KAAK,CAAc;AAI3FZ,SAAc;EACb,IAAMa,IAAU,IAAIV,EAAOW,OAAOC,cAAc;AAC/CC,wBAAqB;AASpBH,IAPAA,EAAQI,YAAY,EAGpBR,EAAQF,EAAMG,MAAMC,YAAYC,KAAK,CAAc,EAInDC,EAAQK,MAAMX,EAAMG,MAAMC,YAAY;KACrC;IACD;AAGFE,IAAQK,MAAMX,EAAMG,MAAMC,YAAY;GAIrC;CAGF,IAAMQ,IAAYZ,EAAMG,MAAMU,KAAKC,KAAKd,EAAMG,MAAM;AAEpD,QAAA;EAAAY,QAGGA,QAAA,CAACd,GAAM,CAAA,EAAA,KAAKD,EAAMgB,YAAY,MAAK;EAAAD,QAGnCA,QAAA,CAAA,EAAAd,GAAM,IACN,CAACD,EAAMiB,YAAU,EAAA,KAEhBC,QAAQC,MACP,yBAAyBnB,EAAMiB,eAAe,OAAO,SAAS,YAAW,6BAC5ChB,GAAM,CAAEmB,UAAS,IAC9C,EACMpB,EAAMgB,YAAY,MACtB;EAAAD,QAGJA,QAAA,CAAA,EAAAd,GAAM,IACND,EAAMiB,cACN,CAACjB,EAAMiB,WAAWhB,GAAM,CAAEmB,YAAU,EAAA,KAEnCF,QAAQC,MACP,cAAclB,GAAM,CAAEmB,UAAS,gDACLC,OAAOC,KAAKtB,EAAMiB,WAAW,CAACM,KAAK,KAAK,GAClE,SACD;GAAA,IAAAC,IAAAC,GAAA,EAAAG,IAAAJ,EAAAG,WAAAE;AAG2C,UAH3CD,EAAAC,aAAAE,EAAAP,SAEcvB,GAAM,CAAEmB,WAASQ,EAAA,EAAAG,EAAAP,SAC5BH,OAAOC,KAAKtB,EAAMiB,WAAW,CAACM,KAAK,KAAK,EAAA,KAAA,EAAAC;MAAA,EAGxC;EAAAT,QAGJA,QAAA,CAAA,EAAAd,GAAM,IAAID,EAAMiB,cAAcjB,EAAMiB,WAAWhB,GAAM,CAAEmB,YAAU,EAAA,IAAAY,EAChErC,GAAOsC,EAAA,EAAA,IACPb,YAAS;AAAA,UAAEpB,EAAMiB,WAAWhB,GAAM,CAAEmB;KAAU,QAC1CnB,GAAM,CAAED,OAAK,EACjBa,MAAMD,GAAS,CAAA,CAEhB,CAAA;EAAA"}
1
+ {"version":3,"file":"PlayRenderer.js","names":["Component","Renderer","usePlayView","PlayRenderer","view","_$createComponent","spec","registry"],"sources":["../src/PlayRenderer.tsx"],"sourcesContent":["/**\n * PlayRenderer - Zero-prop leaf component for XMachines Play SolidJS architecture.\n *\n * Reads view context from the enclosing ActorProvider (or PlayUIProvider) via\n * usePlayView() and renders the spec using @xmachines/json-render-solid's Renderer.\n *\n * Standard usage:\n * ```tsx\n * <PlayUIProvider actor={myActor} registryResult={registryResult}>\n * <PlayRenderer />\n * </PlayUIProvider>\n * ```\n *\n * @packageDocumentation\n */\n\nimport type { Component } from \"solid-js\";\nimport { Renderer } from \"@xmachines/json-render-solid\";\nimport { usePlayView } from \"./ActorProvider.js\";\n\n/**\n * Zero-prop leaf renderer. Must be placed inside an ActorProvider or PlayUIProvider tree.\n *\n * Reads ViewContextValue (spec, handlers, registry) from the enclosing provider\n * via usePlayView() and renders the spec via @xmachines/json-render-solid's Renderer.\n */\nexport const PlayRenderer: Component = () => {\n\tconst view = usePlayView();\n\treturn <Renderer spec={view.spec} registry={view.registry} />;\n};\n"],"mappings":";;;;AA0BA,IAAaG,UAAgC;CAC5C,IAAMC,IAAOF,EAAY;CACzB,OAAAG,EAAQJ,GAAQ;EAAA,IAACK,OAAI;GAAA,OAAEF,EAAKE;EAAI;EAAA,IAAEC,WAAQ;GAAA,OAAEH,EAAKG;EAAQ;CAAA,CAAA;AAC1D"}
@@ -0,0 +1,35 @@
1
+ import { ActorProvider as e, usePlayView as t } from "./ActorProvider.js";
2
+ import { createComponent as n, mergeProps as r } from "solid-js/web";
3
+ import { JSONUIProvider as i } from "@xmachines/json-render-solid";
4
+ //#region src/PlayUIProvider.tsx
5
+ var a = (e) => {
6
+ let a = t();
7
+ return n(i, r({
8
+ get registry() {
9
+ return a.registry;
10
+ },
11
+ get handlers() {
12
+ return a.handlers;
13
+ },
14
+ get store() {
15
+ return a.store;
16
+ }
17
+ }, () => e.validationFunctions !== void 0 && { validationFunctions: e.validationFunctions }, () => e.navigate !== void 0 && { navigate: e.navigate }, () => e.functions !== void 0 && { functions: e.functions }, { get children() {
18
+ return e.children;
19
+ } }));
20
+ }, o = (t) => n(e, r({
21
+ get actor() {
22
+ return t.actor;
23
+ },
24
+ get registryResult() {
25
+ return t.registryResult;
26
+ }
27
+ }, () => t.store !== void 0 && { store: t.store }, () => t.fallback !== void 0 && { fallback: t.fallback }, () => t.onError !== void 0 && { onError: t.onError }, () => t.onRenderError !== void 0 && { onRenderError: t.onRenderError }, { get children() {
28
+ return n(a, r(() => t.validationFunctions !== void 0 && { validationFunctions: t.validationFunctions }, () => t.navigate !== void 0 && { navigate: t.navigate }, () => t.functions !== void 0 && { functions: t.functions }, { get children() {
29
+ return t.children;
30
+ } }));
31
+ } }));
32
+ //#endregion
33
+ export { o as PlayUIProvider };
34
+
35
+ //# sourceMappingURL=PlayUIProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PlayUIProvider.js","names":["Component","JSX","JSONUIProvider","JSONUIProviderProps","ActorProvider","usePlayView","ActorProviderProps","JSONUIForwardedProps","Pick","PlayUIProviderProps","Partial","JSONUIBridge","children","Element","bridgeProps","view","_$createComponent","_$mergeProps","registry","handlers","store","validationFunctions","undefined","navigate","functions","PlayUIProvider","props","actor","registryResult","fallback","onError","onRenderError"],"sources":["../src/PlayUIProvider.tsx"],"sourcesContent":["/**\n * PlayUIProvider — Batteries-included SolidJS provider for XMachines Play.\n *\n * Wraps ActorProvider + JSONUIProvider into a single composite provider.\n * This is the recommended entry point for most users.\n *\n * Standard usage:\n * ```tsx\n * import { PlayUIProvider, PlayRenderer, defineRegistry } from \"@xmachines/play-solid\";\n *\n * const registryResult = defineRegistry(myCatalog, { components, actions });\n *\n * <PlayUIProvider actor={myActor} registryResult={registryResult}>\n * <PlayRenderer />\n * </PlayUIProvider>\n * ```\n *\n * For full control (library authors), use ActorProvider directly.\n *\n * @packageDocumentation\n */\n\nimport type { Component, JSX } from \"solid-js\";\nimport { JSONUIProvider, type JSONUIProviderProps } from \"@xmachines/json-render-solid\";\nimport { ActorProvider, usePlayView, type ActorProviderProps } from \"./ActorProvider.js\";\n\n// Pick only the forwarded props from JSONUIProviderProps (per D-16)\ntype JSONUIForwardedProps = Pick<\n\tJSONUIProviderProps,\n\t\"validationFunctions\" | \"navigate\" | \"functions\"\n>;\n\n/**\n * Props for PlayUIProvider — all ActorProvider props plus JSONUIProvider's forwarded props.\n */\nexport interface PlayUIProviderProps extends ActorProviderProps, Partial<JSONUIForwardedProps> {}\n\n/**\n * Inner bridge component — must be inside ActorProvider's tree so usePlayView() has\n * access to the resolved ViewContextValue. Reads handlers and registry from the view\n * context and passes them to JSONUIProvider.\n *\n * This bridge pattern mirrors the React implementation (JSONUIBridge in play-react).\n */\nconst JSONUIBridge: Component<Partial<JSONUIForwardedProps> & { children: JSX.Element }> = (\n\tbridgeProps,\n) => {\n\tconst view = usePlayView();\n\n\treturn (\n\t\t<JSONUIProvider\n\t\t\tregistry={view.registry}\n\t\t\thandlers={view.handlers}\n\t\t\tstore={view.store}\n\t\t\t{...(bridgeProps.validationFunctions !== undefined && {\n\t\t\t\tvalidationFunctions: bridgeProps.validationFunctions,\n\t\t\t})}\n\t\t\t{...(bridgeProps.navigate !== undefined && { navigate: bridgeProps.navigate })}\n\t\t\t{...(bridgeProps.functions !== undefined && { functions: bridgeProps.functions })}\n\t\t>\n\t\t\t{bridgeProps.children}\n\t\t</JSONUIProvider>\n\t);\n};\n\n/**\n * Batteries-included composite provider: ActorProvider + JSONUIProvider.\n *\n * Provides the full JSON render context stack:\n * - ActorContext (actor instance via ActorProvider)\n * - ViewContext (spec, handlers, registry via ActorProvider)\n * - StateProvider + ActionProvider + VisibilityProvider + ValidationProvider (via JSONUIProvider)\n * - ConfirmDialogManager (via JSONUIProvider)\n *\n * @example\n * ```tsx\n * <PlayUIProvider actor={myActor} registryResult={registryResult} navigate={navigate}>\n * <PlayRenderer />\n * </PlayUIProvider>\n * ```\n */\nexport const PlayUIProvider: Component<PlayUIProviderProps> = (props) => {\n\treturn (\n\t\t<ActorProvider\n\t\t\tactor={props.actor}\n\t\t\tregistryResult={props.registryResult}\n\t\t\t{...(props.store !== undefined && { store: props.store })}\n\t\t\t{...(props.fallback !== undefined && { fallback: props.fallback })}\n\t\t\t{...(props.onError !== undefined && { onError: props.onError })}\n\t\t\t{...(props.onRenderError !== undefined && { onRenderError: props.onRenderError })}\n\t\t>\n\t\t\t<JSONUIBridge\n\t\t\t\t{...(props.validationFunctions !== undefined && {\n\t\t\t\t\tvalidationFunctions: props.validationFunctions,\n\t\t\t\t})}\n\t\t\t\t{...(props.navigate !== undefined && { navigate: props.navigate })}\n\t\t\t\t{...(props.functions !== undefined && { functions: props.functions })}\n\t\t\t>\n\t\t\t\t{props.children}\n\t\t\t</JSONUIBridge>\n\t\t</ActorProvider>\n\t);\n};\n"],"mappings":";;;;AA4CA,IAAMW,KACLG,MACI;CACJ,IAAMC,IAAOV,EAAY;CAEzB,OAAAW,EACEd,GAAce,EAAA;EAAA,IACdC,WAAQ;GAAA,OAAEH,EAAKG;EAAQ;EAAA,IACvBC,WAAQ;GAAA,OAAEJ,EAAKI;EAAQ;EAAA,IACvBC,QAAK;GAAA,OAAEL,EAAKK;EAAK;CAAA,SACZN,EAAYO,wBAAwBC,KAAAA,KAAa,EACrDD,qBAAqBP,EAAYO,oBAClC,SACKP,EAAYS,aAAaD,KAAAA,KAAa,EAAEC,UAAUT,EAAYS,SAAS,SACvET,EAAYU,cAAcF,KAAAA,KAAa,EAAEE,WAAWV,EAAYU,UAAU,GAAC,EAAA,IAAAZ,WAAA;EAAA,OAE/EE,EAAYF;CAAQ,EAAA,CAAA,CAAA;AAGxB,GAkBaa,KAAkDC,MAC9DV,EACEZ,GAAaa,EAAA;CAAA,IACbU,QAAK;EAAA,OAAED,EAAMC;CAAK;CAAA,IAClBC,iBAAc;EAAA,OAAEF,EAAME;CAAc;AAAA,SAC/BF,EAAMN,UAAUE,KAAAA,KAAa,EAAEF,OAAOM,EAAMN,MAAM,SAClDM,EAAMG,aAAaP,KAAAA,KAAa,EAAEO,UAAUH,EAAMG,SAAS,SAC3DH,EAAMI,YAAYR,KAAAA,KAAa,EAAEQ,SAASJ,EAAMI,QAAQ,SACxDJ,EAAMK,kBAAkBT,KAAAA,KAAa,EAAES,eAAeL,EAAMK,cAAc,GAAC,EAAA,IAAAnB,WAAA;CAAA,OAAAI,EAE/EL,GAAYM,QACPS,EAAML,wBAAwBC,KAAAA,KAAa,EAC/CD,qBAAqBK,EAAML,oBAC5B,SACKK,EAAMH,aAAaD,KAAAA,KAAa,EAAEC,UAAUG,EAAMH,SAAS,SAC3DG,EAAMF,cAAcF,KAAAA,KAAa,EAAEE,WAAWE,EAAMF,UAAU,GAAC,EAAA,IAAAZ,WAAA;EAAA,OAEnEc,EAAMd;CAAQ,EAAA,CAAA,CAAA;AAAA,EAAA,CAAA,CAAA"}
package/dist/index.js CHANGED
@@ -1,2 +1,6 @@
1
- import { PlayRenderer as e } from "./PlayRenderer.js";
2
- export { e as PlayRenderer };
1
+ import { ActorContext as e, useActor as t } from "./useActor.js";
2
+ import { ActorProvider as n, usePlayView as r } from "./ActorProvider.js";
3
+ import { PlayRenderer as i } from "./PlayRenderer.js";
4
+ import { PlayUIProvider as a } from "./PlayUIProvider.js";
5
+ import { ActionProvider as o, JSONUIProvider as s, Renderer as c, StateProvider as l, ValidationProvider as u, VisibilityProvider as d, defineRegistry as f, useAction as p, useActions as m, useBoundProp as h, useFieldValidation as g, useIsVisible as _, useOptionalValidation as v, useStateBinding as y, useStateStore as b, useStateValue as x, useVisibility as S } from "@xmachines/json-render-solid";
6
+ export { o as ActionProvider, e as ActorContext, n as ActorProvider, s as JSONUIProvider, i as PlayRenderer, a as PlayUIProvider, c as Renderer, l as StateProvider, u as ValidationProvider, d as VisibilityProvider, f as defineRegistry, p as useAction, m as useActions, t as useActor, h as useBoundProp, g as useFieldValidation, _ as useIsVisible, v as useOptionalValidation, r as usePlayView, y as useStateBinding, b as useStateStore, x as useStateValue, S as useVisibility };
@@ -0,0 +1,11 @@
1
+ import { createContext as e, useContext as t } from "solid-js";
2
+ import { assertNonNullable as n } from "@xmachines/play";
3
+ //#region src/useActor.ts
4
+ var r = e(null);
5
+ function i() {
6
+ return n(t(r), "ActorContext");
7
+ }
8
+ //#endregion
9
+ export { r as ActorContext, i as useActor };
10
+
11
+ //# sourceMappingURL=useActor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useActor.js","names":[],"sources":["../src/useActor.ts"],"sourcesContent":["/**\n * useActor — SolidJS hook for accessing the raw actor inside an ActorProvider tree.\n *\n * Components rendered inside ActorProvider (or PlayUIProvider) can call useActor()\n * to get direct access to the actor instance without prop drilling.\n *\n * @throws {Error} If called outside an ActorProvider tree\n *\n * @example\n * ```typescript\n * import { useActor } from \"@xmachines/play-solid\";\n *\n * function MyComponent() {\n * const actor = useActor();\n * return <button onClick={() => actor.send({ type: \"SUBMIT\" })}>Submit</button>;\n * }\n * ```\n *\n * @packageDocumentation\n */\n\nimport { createContext, useContext } from \"solid-js\";\nimport { assertNonNullable } from \"@xmachines/play\";\nimport type { AbstractActor } from \"@xmachines/play-actor\";\nimport type { AnyActorLogic } from \"xstate\";\n\n/** Bare actor type accepted by Solid context providers. For the full routing + view shape, use `PlayActor` from `@xmachines/play-router`. */\nexport type AnyPlayActor = AbstractActor<AnyActorLogic>;\n\n/**\n * SolidJS context for the actor — exported so consumers can use ActorContext.Provider\n * directly as an escape hatch (per D-11). The smart ActorProvider component takes\n * the name \"ActorProvider\" and is the recommended entry point.\n */\nexport const ActorContext = createContext<AnyPlayActor | null>(null);\n\nexport function useActor(): AnyPlayActor {\n\treturn assertNonNullable(useContext(ActorContext), \"ActorContext\");\n}\n"],"mappings":";;;AAkCA,IAAa,IAAe,EAAmC,IAAI;AAEnE,SAAgB,IAAyB;CACxC,OAAO,EAAkB,EAAW,CAAY,GAAG,cAAc;AAClE"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@xmachines/play-solid",
3
- "version": "1.0.0-beta.9",
4
- "description": "SolidJS renderer for XMachines Play architecture",
3
+ "version": "2.0.0-alpha.1",
4
+ "description": "Solid renderer for XMachines Play architecture",
5
5
  "keywords": [
6
6
  "catalog",
7
7
  "play",
@@ -12,6 +12,11 @@
12
12
  ],
13
13
  "license": "MIT",
14
14
  "author": "XMachines Contributors",
15
+ "repository": {
16
+ "type": "git",
17
+ "url": "git+ssh://git@gitlab.com/xmachin-es/xmachines-js.git",
18
+ "directory": "packages/play-solid"
19
+ },
15
20
  "files": [
16
21
  "dist",
17
22
  "README.md",
@@ -20,6 +25,7 @@
20
25
  "type": "module",
21
26
  "exports": {
22
27
  ".": {
28
+ "source": "./src/index.ts",
23
29
  "types": "./dist/index.d.ts",
24
30
  "default": "./dist/index.js"
25
31
  }
@@ -29,29 +35,49 @@
29
35
  },
30
36
  "scripts": {
31
37
  "build": "vite build && tsc --build",
32
- "clean": "rm -rf dist tsconfig.tsbuildinfo node_modules/.vite node_modules/.vite-temp",
33
- "typecheck": "tsc --noEmit",
38
+ "clean": "rm -rf dist *.tsbuildinfo coverage .vitest-attachments test/browser/__screenshots__ node_modules/.svelte2tsx-* node_modules/.vite*",
39
+ "lint": "oxlint .",
40
+ "format": "oxfmt .",
34
41
  "test": "vitest",
35
42
  "test:watch": "vitest",
36
43
  "test:ui": "vitest --ui",
37
44
  "prepublishOnly": "npm run build"
38
45
  },
39
46
  "dependencies": {
40
- "@xmachines/play-actor": "1.0.0-beta.9",
41
- "@xmachines/play-catalog": "1.0.0-beta.9",
42
- "@xmachines/play-signals": "1.0.0-beta.9"
47
+ "@xmachines/play": "2.0.0-alpha.1",
48
+ "@xmachines/play-actor": "2.0.0-alpha.1",
49
+ "@xmachines/play-signals": "2.0.0-alpha.1"
43
50
  },
44
51
  "devDependencies": {
45
52
  "@solidjs/testing-library": "^0.8.10",
46
- "@types/node": "^25.5.0",
47
- "@xmachines/shared": "1.0.0-beta.9",
48
- "solid-js": "^1.9.11",
49
- "typescript": "^5.9.3",
50
- "vite": "^8.0.0",
53
+ "@testing-library/jest-dom": "^6.9.1",
54
+ "@types/node": "^26.1.1",
55
+ "@vitest/browser-playwright": "^4.1.10",
56
+ "@xmachines/json-render-core": "^0.19.0-xm.2",
57
+ "@xmachines/json-render-solid": "^0.19.0-xm.2",
58
+ "@xmachines/json-render-xstate": "^0.19.0-xm.2",
59
+ "@xmachines/shared": "2.0.0-alpha.1",
60
+ "@xstate/store": "^3.17.0",
61
+ "jsdom": "^29.1.0",
62
+ "oxfmt": "^0.58.0",
63
+ "oxlint": "^1.73.0",
64
+ "solid-js": "^1.9.12",
65
+ "typescript": "^5.9.3 || ^6.0.3",
66
+ "vite": "^8.0.10",
51
67
  "vite-plugin-solid": "^2.11.11",
52
- "vitest": "^4.1.0"
68
+ "vitest": "^4.1.10",
69
+ "xstate": "^6.0.0-alpha.20",
70
+ "zod": "^4.4.1"
53
71
  },
54
72
  "peerDependencies": {
55
- "solid-js": "^1.8.0"
73
+ "@xmachines/json-render-core": "^0.19.0-xm.2",
74
+ "@xmachines/json-render-solid": "^0.19.0-xm.2",
75
+ "@xmachines/json-render-xstate": "^0.19.0-xm.2",
76
+ "@xstate/store": "^3.17.0",
77
+ "solid-js": "^1.8.0",
78
+ "xstate": "^6.0.0-alpha.20"
79
+ },
80
+ "engines": {
81
+ "node": ">=22.0.0"
56
82
  }
57
83
  }
@@ -1,63 +0,0 @@
1
- /**
2
- * PlayRenderer - Main SolidJS renderer component for XMachines Play architecture
3
- *
4
- * @packageDocumentation
5
- */
6
- import { type Component } from "solid-js";
7
- import type { PlayRendererProps } from "./types.js";
8
- /**
9
- * Main renderer component that subscribes to actor signals and renders UI
10
- *
11
- * Architecture (per XMachines Play patterns):
12
- * - Subscribes to actor.currentView signal via TC39 Signal.subtle.Watcher
13
- * - Dynamically renders catalog components based on view.component string
14
- * - Forwards user events to actor via actor.send()
15
- * - SolidJS signal only for triggering renders, NOT business logic
16
- *
17
- * Invariant: Actor Authority - Actor decides all state transitions via guards.
18
- * Invariant: Passive Infrastructure - Component observes signals and sends events.
19
- * Invariant: Signal-Only Reactivity - Business logic state lives in actor signals.
20
- *
21
- * @example
22
- * ```typescript
23
- * import { PlayRenderer } from "@xmachines/play-solidjs";
24
- * import { definePlayer } from "@xmachines/play-xstate";
25
- *
26
- * const actor = definePlayer({ machine, catalog })();
27
- * actor.start();
28
- *
29
- * const components = {
30
- * Dashboard: (props) => <div>User: {props.userId}</div>,
31
- * LoginForm: (props) => (
32
- * <form onSubmit={(e) => {
33
- * e.preventDefault();
34
- * props.send({ type: "auth.login", payload: {...} });
35
- * }}>...</form>
36
- * )
37
- * };
38
- *
39
- * <PlayRenderer actor={actor} components={components} />
40
- * ```
41
- *
42
- * @param props - Component props
43
- * @returns SolidJS element rendering current view from actor
44
- *
45
- * @remarks
46
- * **Component lookup:** Dynamically looks up component from `components` map
47
- * using `view.component` string from actor.currentView signal.
48
- *
49
- * **Event forwarding:** Injects `send` function as prop to components. Components
50
- * call `send(event)` to forward intents to actor. Actor guards decide validity.
51
- *
52
- * **Error handling:** If component not found in catalog, logs error and shows
53
- * fallback. This indicates missing component registration, not runtime error.
54
- *
55
- * **Signal bridge:** Uses one-shot re-watch pattern. TC39 Signal watchers stop
56
- * watching after notification, so watcher.watch() must be called in microtask
57
- * after getPending() to re-arm for next notification.
58
- *
59
- * **CRITICAL:** Never call actor.send() during render - only in event handlers.
60
- * Calling send during render causes infinite render loops.
61
- */
62
- export declare const PlayRenderer: Component<PlayRendererProps>;
63
- //# sourceMappingURL=PlayRenderer.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"PlayRenderer.d.ts","sourceRoot":"","sources":["../src/PlayRenderer.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAyB,KAAK,SAAS,EAAE,MAAM,UAAU,CAAC;AAGjE,OAAO,KAAK,EAAE,iBAAiB,EAAa,MAAM,YAAY,CAAC;AAE/D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDG;AACH,eAAO,MAAM,YAAY,EAAE,SAAS,CAAC,iBAAiB,CA2ErD,CAAC"}
package/dist/index.d.ts DELETED
@@ -1,8 +0,0 @@
1
- /**
2
- * SolidJS renderer for XMachines Play architecture
3
- *
4
- * @packageDocumentation
5
- */
6
- export { PlayRenderer } from "./PlayRenderer.js";
7
- export type { PlayRendererProps } from "./types.js";
8
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,YAAY,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC"}
package/dist/types.d.ts DELETED
@@ -1,28 +0,0 @@
1
- /**
2
- * TypeScript type definitions for play-solidjs
3
- *
4
- * @packageDocumentation
5
- */
6
- import type { AbstractActor, Viewable } from "@xmachines/play-actor";
7
- import type { JSX, ValidComponent } from "solid-js";
8
- import type { AnyActorLogic } from "xstate";
9
- export type SolidView = {
10
- component: string;
11
- props: Record<string, unknown>;
12
- } | null;
13
- /**
14
- * Props for PlayRenderer component
15
- *
16
- * @property actor - Actor instance with currentView signal (requires Viewable capability)
17
- * @property components - Map of component names to SolidJS components
18
- * @property fallback - Optional element shown when currentView is null
19
- */
20
- export interface PlayRendererProps {
21
- /** Actor instance with currentView signal (requires Viewable capability) */
22
- actor: AbstractActor<AnyActorLogic> & Viewable;
23
- /** Map of component names to SolidJS components */
24
- components: Record<string, ValidComponent>;
25
- /** Optional element shown when currentView is null */
26
- fallback?: JSX.Element;
27
- }
28
- //# sourceMappingURL=types.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACrE,OAAO,KAAK,EAAE,GAAG,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AACpD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAE5C,MAAM,MAAM,SAAS,GAAG;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,GAAG,IAAI,CAAC;AAErF;;;;;;GAMG;AACH,MAAM,WAAW,iBAAiB;IACjC,4EAA4E;IAC5E,KAAK,EAAE,aAAa,CAAC,aAAa,CAAC,GAAG,QAAQ,CAAC;IAE/C,mDAAmD;IACnD,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAE3C,sDAAsD;IACtD,QAAQ,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC;CACvB"}