@xmachines/play-react 1.0.0-beta.9 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/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,395 +1,194 @@
1
1
  # @xmachines/play-react
2
2
 
3
- **React renderer consuming signals and UI schema with provider pattern**
3
+ React renderer for XMachines Play architecture with signal-driven rendering.
4
4
 
5
- Signal-driven React rendering layer observing actor state with zero React state for business logic.
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
6
+ [![Version](https://img.shields.io/badge/version-1.1.0-blue)](https://www.npmjs.com/package/@xmachines/play-react)
6
7
 
7
- ## Overview
8
+ Part of the [xmachines-js monorepo](../../README.md).
8
9
 
9
- `@xmachines/play-react` provides `PlayRenderer` and `useSignalEffect` for building React UIs that passively observe actor signals. This package enables framework-swappable architecture where React 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:
12
-
13
- - **Signal-Only Reactivity (INV-05):** No useState/useReducer for business logic, signals only
14
- - **Passive Infrastructure (INV-04):** Components observe signals, send events to actor
10
+ ## Installation
15
11
 
16
- **Key Principle:** React state is never used for business logic. Signals are the source of truth.
12
+ ```bash
13
+ pnpm add @xmachines/play-react
14
+ ```
17
15
 
18
- Renderer receives actor via props (provider pattern), not children.
19
-
20
- ## Installation
16
+ **Peer dependencies** (must be installed separately):
21
17
 
22
18
  ```bash
23
- npm install react@^18.0.0 react-dom@^18.0.0
24
- npm install @xmachines/play-react
19
+ pnpm add react react-dom xstate @xstate/store @xmachines/json-render-react @xmachines/json-render-core @xmachines/json-render-xstate
25
20
  ```
26
21
 
27
- ## Current Exports
22
+ Supported versions:
28
23
 
29
- - `PlayRenderer`
30
- - `useSignalEffect`
31
- - `PlayErrorBoundary`
32
- - `PlayRendererProps` (type)
33
- - `PlayErrorBoundaryProps` (type)
24
+ - `react` / `react-dom`: `^18.0.0 || ^19.0.0`
25
+ - `xstate`: `^5.31.0`
26
+ - `@xstate/store`: `^3.17.0`
27
+ - `@xmachines/json-render-*`: `^0.18.0`
34
28
 
35
- **Peer dependencies:**
29
+ ## Usage
36
30
 
37
- - `react` ^18.0.0 || ^19.0.0 React runtime
38
- - `react-dom` ^18.0.0 || ^19.0.0 — React DOM renderer
31
+ ### Standard usage `PlayUIProvider` + `PlayRenderer`
39
32
 
40
- ## Quick Start
33
+ The recommended pattern for actor-driven React rendering:
41
34
 
42
- ```typescript
43
- import { createRoot } from "react-dom/client";
35
+ ```tsx
36
+ import { PlayUIProvider, PlayRenderer, defineRegistry } from "@xmachines/play-react";
44
37
  import { definePlayer } from "@xmachines/play-xstate";
45
- import { defineCatalog } from "@xmachines/play-catalog";
46
- import { PlayRenderer } from "@xmachines/play-react";
47
- import { z } from "zod";
48
-
49
- // 1. Define catalog (business logic layer)
50
- const catalog = defineCatalog({
51
- LoginForm: z.object({ error: z.string().optional() }),
52
- Dashboard: z.object({
53
- userId: z.string(),
54
- username: z.string(),
55
- }),
56
- });
57
38
 
58
- // 2. Create React components (view layer)
59
- const components = {
60
- LoginForm: ({ error, send }) => (
61
- <form
62
- onSubmit={(e) => {
63
- e.preventDefault();
64
- const data = new FormData(e.currentTarget);
65
- send({
66
- type: "auth.login",
67
- username: data.get("username"),
68
- });
69
- }}
70
- >
71
- {error && <p style={{ color: "red" }}>{error}</p>}
72
- <input name="username" required placeholder="Username" />
73
- <button type="submit">Log In</button>
74
- </form>
75
- ),
76
- Dashboard: ({ userId, username, send }) => (
77
- <div>
78
- <h1>Welcome, {username}!</h1>
79
- <p>User ID: {userId}</p>
80
- <button onClick={() => send({ type: "auth.logout" })}>Log Out</button>
81
- </div>
82
- ),
83
- };
84
-
85
- // 3. Create player actor (business logic runtime)
86
- const createPlayer = definePlayer({ machine: authMachine, catalog });
87
- const actor = createPlayer();
39
+ // 1. Create and start the actor
40
+ const actor = definePlayer({ machine: myMachine })();
88
41
  actor.start();
89
42
 
90
- // 4. Render UI (actor via props)
91
- const root = createRoot(document.getElementById("app")!);
92
- root.render(<PlayRenderer actor={actor} components={components} />);
93
- ```
94
-
95
- ## API Reference
96
-
97
- ### PlayRenderer
98
-
99
- Main renderer component subscribing to actor signals and dynamically rendering catalog components:
43
+ // 2. Define the component registry with action handlers
44
+ const registryResult = defineRegistry(myCatalog, {
45
+ components: { Login, Dashboard },
46
+ actions: {
47
+ login: async ({ username }) => actor.send({ type: "auth.login", username }),
48
+ logout: async () => actor.send({ type: "auth.logout" }),
49
+ },
50
+ });
100
51
 
101
- ```typescript
102
- interface PlayRendererProps {
103
- actor: AbstractActor<AnyActorLogic> & Viewable;
104
- components: Record<string, React.ElementType>;
105
- fallback?: React.ReactNode;
52
+ // 3. Render — signals drive view transitions automatically
53
+ function App() {
54
+ return (
55
+ <PlayUIProvider actor={actor} registryResult={registryResult}>
56
+ <PlayRenderer />
57
+ </PlayUIProvider>
58
+ );
106
59
  }
107
60
  ```
108
61
 
109
- **Props:**
110
-
111
- - `actor` - Actor instance with `currentView` signal
112
- - `components` - Map of component names to React components
113
- - `fallback` - Component shown when `currentView` is null (default: `null`)
114
-
115
- **Behavior:**
62
+ ### With optional `JSONUIProvider` props
116
63
 
117
- 1. Subscribes to `actor.currentView` signal via `useSignalEffect`
118
- 2. Looks up component from `components` map using `view.component` string
119
- 3. Renders component with props from `view.props` + `send` function
64
+ Pass navigation and validation helpers through `PlayUIProvider`:
120
65
 
121
- **Example:**
122
-
123
- ```typescript
124
- <PlayRenderer
66
+ ```tsx
67
+ <PlayUIProvider
125
68
  actor={actor}
126
- components={{
127
- HomePage: ({ send }) => <div>Home</div>,
128
- AboutPage: ({ send }) => <div>About</div>,
129
- }}
130
- fallback={<div>Loading...</div>}
131
- />
132
- ```
133
-
134
- ### useSignalEffect()
135
-
136
- Hook for subscribing to signal changes with automatic cleanup:
137
-
138
- ```typescript
139
- useSignalEffect(() => {
140
- const value = signal.get();
141
- // React re-renders when signal changes
142
- });
69
+ registryResult={registryResult}
70
+ navigate={(path) => router.push(path)}
71
+ validationFunctions={{ isEmail: (v) => /^.+@.+$/.test(String(v)) }}
72
+ >
73
+ <PlayRenderer />
74
+ </PlayUIProvider>
143
75
  ```
144
76
 
145
- **Behavior:**
146
-
147
- - Tracks signal dependencies automatically via `Signal.Computed` wrapper
148
- - Uses `Signal.subtle.Watcher` with microtask batching
149
- - Triggers React state update to force re-render
150
- - Cleans up watcher on unmount with explicit `unwatch`
151
-
152
- **Canonical watcher lifecycle:**
153
-
154
- 1. `notify`
155
- 2. `queueMicrotask`
156
- 3. drain pending work (`getPending` and/or `Computed.get`)
157
- 4. run effect + trigger render
158
- 5. re-arm watcher via `watch()`
159
-
160
- Watcher notification is one-shot, so re-arm and explicit cleanup are both required.
77
+ ### Escape hatch — custom provider composition
161
78
 
162
- **Example:**
79
+ Use `ActorProvider` directly when you need to compose providers manually:
163
80
 
164
- ```typescript
165
- import { useSignalEffect } from "@xmachines/play-react";
166
- import { useState } from "react";
167
-
168
- function RouteDisplay({ actor }: { actor: AbstractActor<any> }) {
169
- const [route, setRoute] = useState<string | null>(null);
170
-
171
- useSignalEffect(() => {
172
- const currentRoute = actor.currentRoute.get();
173
- setRoute(currentRoute);
174
- });
81
+ ```tsx
82
+ import { ActorProvider, JSONUIProvider, PlayRenderer } from "@xmachines/play-react";
175
83
 
176
- return <div>Current Route: {route ?? "None"}</div>;
177
- }
84
+ <ActorProvider actor={actor} registryResult={registryResult}>
85
+ <JSONUIProvider registry={registryResult.registry}>
86
+ <PlayRenderer />
87
+ </JSONUIProvider>
88
+ </ActorProvider>;
178
89
  ```
179
90
 
180
- ### PlayErrorBoundary
181
-
182
- React class component error boundary for catching catalog component render errors.
91
+ ### Accessing the actor from inside the tree
183
92
 
184
- `PlayRenderer` wraps its render output in `PlayErrorBoundary` automatically. You can also use it directly to wrap any component that may throw during render.
93
+ ```tsx
94
+ import { useActor } from "@xmachines/play-react";
185
95
 
186
- ```typescript
187
- interface PlayErrorBoundaryProps {
188
- fallback?: React.ReactNode; // UI shown when a child throws (default: null)
189
- children: React.ReactNode;
190
- onError?: (error: Error, info: React.ErrorInfo) => void; // Forward to Sentry, Datadog, etc.
96
+ function SubmitButton() {
97
+ const actor = useActor();
98
+ return <button onClick={() => actor.send({ type: "SUBMIT" })}>Submit</button>;
191
99
  }
192
100
  ```
193
101
 
194
- **Props:**
195
-
196
- - `fallback` — ReactNode rendered when a child component throws. Defaults to `null`.
197
- - `onError` — Optional callback forwarded on every caught error. Use for production observability (Sentry, Datadog, custom logging).
198
-
199
- **Example:**
102
+ ### Subscribing to signals directly
200
103
 
201
104
  ```tsx
202
- import { PlayErrorBoundary } from "@xmachines/play-react";
203
-
204
- <PlayErrorBoundary
205
- fallback={<div className="error">Something went wrong.</div>}
206
- onError={(error) => Sentry.captureException(error)}
207
- >
208
- <YourCatalogComponent />
209
- </PlayErrorBoundary>;
210
- ```
211
-
212
- Works with React 18 and React 19. Uses the standard class component `componentDidCatch` + `getDerivedStateFromError` pattern.
213
-
214
- **Complete API:** See [API Documentation](../../docs/api/@xmachines/play-react)
215
-
216
- ## Examples
217
-
218
- ### Component Receiving Props from Catalog
219
-
220
- ```typescript
221
- import { PlayRenderer } from "@xmachines/play-react";
222
- import { defineCatalog } from "@xmachines/play-catalog";
223
- import { z } from "zod";
224
-
225
- // Define schema in catalog
226
- const catalog = defineCatalog({
227
- UserProfile: z.object({
228
- userId: z.string(),
229
- name: z.string(),
230
- avatar: z.string().url().optional(),
231
- stats: z.object({
232
- posts: z.number(),
233
- followers: z.number(),
234
- }),
235
- }),
236
- });
237
-
238
- // Component receives type-safe props + send
239
- const components = {
240
- UserProfile: ({ userId, name, avatar, stats, send }) => (
241
- <div>
242
- {avatar && <img src={avatar} alt={name} />}
243
- <h1>{name}</h1>
244
- <p>ID: {userId}</p>
245
- <div>
246
- <span>{stats.posts} posts</span>
247
- <span>{stats.followers} followers</span>
248
- </div>
249
- <button
250
- onClick={() =>
251
- send({
252
- type: "profile.edit",
253
- userId,
254
- })
255
- }
256
- >
257
- Edit Profile
258
- </button>
259
- </div>
260
- ),
261
- };
262
-
263
- <PlayRenderer actor={actor} components={components} />;
264
- ```
265
-
266
- ### useSignalEffect for Custom Rendering
267
-
268
- ```typescript
269
105
  import { useSignalEffect } from "@xmachines/play-react";
270
- import { AbstractActor } from "@xmachines/play-actor";
271
106
 
272
- function CustomRenderer({ actor }: { actor: AbstractActor<any> }) {
107
+ function MyComponent({ actor }) {
273
108
  const [view, setView] = useState(null);
274
109
 
275
- // Subscribe to currentView signal
276
110
  useSignalEffect(() => {
277
- const currentView = actor.currentView.get();
278
- setView(currentView);
279
- });
280
-
281
- if (!view) return <div>No view</div>;
282
-
283
- // Custom rendering logic
284
- if (view.component === "SpecialCase") {
285
- return <SpecialCaseComponent {...view.props} actor={actor} />;
286
- }
111
+ setView(actor.currentView.get());
112
+ }, [actor]); // deps: re-subscribe when the actor prop swaps
287
113
 
288
- // Fallback to standard rendering
289
- return <DefaultComponent view={view} actor={actor} />;
114
+ return <div>{view?.component}</div>;
290
115
  }
291
116
  ```
292
117
 
293
- ### Provider Pattern
294
-
295
- ```typescript
296
- import { PlayTanStackRouterProvider } from "@xmachines/play-tanstack-react-router";
297
- import { PlayRenderer } from "@xmachines/play-react";
298
-
299
- // Renderer receives actor via props (not children)
300
- function App() {
301
- return (
302
- <PlayTanStackRouterProvider
303
- actor={actor}
304
- router={router}
305
- renderer={(currentActor, currentRouter) => {
306
- void currentRouter;
307
- return (
308
- <div>
309
- <Header actor={currentActor} />
310
- <PlayRenderer actor={currentActor} components={components} />
311
- <Footer />
312
- </div>
313
- );
314
- }}
315
- />
316
- );
317
- }
318
-
319
- // Header component also receives actor
320
- function Header({ actor }: { actor: AbstractActor<any> }) {
321
- const [route, setRoute] = useState<string | null>(null);
322
-
323
- useSignalEffect(() => {
324
- setRoute(actor.currentRoute.get());
325
- });
326
-
327
- return (
328
- <header>
329
- <nav>Current: {route}</nav>
330
- </header>
331
- );
332
- }
118
+ ## API Summary
119
+
120
+ ### Components
121
+
122
+ | Export | Description |
123
+ | --------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
124
+ | `<PlayUIProvider>` | Batteries-included provider: wraps `ActorProvider` + `JSONUIProvider`. Standard entry point. |
125
+ | `<PlayRenderer>` | Zero-prop leaf component. Reads the current actor view from context and renders it. Must be inside `PlayUIProvider` or `ActorProvider`. |
126
+ | `<ActorProvider>` | Escape-hatch primitive. Owns actor bridging, signal subscription, and per-view `StateStore` lifecycle. |
127
+ | `<PlayErrorBoundary>` | React class error boundary for catching catalog component render errors. |
128
+
129
+ ### Hooks
130
+
131
+ | Export | Description |
132
+ | ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
133
+ | `useSignalEffect(callback, deps?)` | Subscribes to TC39 signal changes; re-runs the callback when any accessed signal changes (re-render via the callback's own setState). Optional `deps` recreates the subscription, like `useEffect`. Cleanup is automatic on unmount. |
134
+ | `useActor()` | Returns the raw actor instance. Must be called inside an `ActorProvider`/`PlayUIProvider` tree. |
135
+ | `usePlayView()` | Returns `{ spec, handlers, registry, store }` for the current view. Must be called inside an `ActorProvider`/`PlayUIProvider` tree. |
136
+
137
+ ### Types
138
+
139
+ | Export | Description |
140
+ | ------------------------ | ---------------------------------------------------------------------------------------------- |
141
+ | `PlayUIProviderProps` | Props for `<PlayUIProvider>` |
142
+ | `ActorProviderProps` | Props for `<ActorProvider>` (also exported as `PlayRendererProps` for migration compatibility) |
143
+ | `PlayErrorBoundaryProps` | Props for `<PlayErrorBoundary>` |
144
+ | `PlayErrorBoundaryState` | State shape for `<PlayErrorBoundary>` |
145
+ | `AnyPlayActor` | Type alias for `AbstractActor<AnyActorLogic>` the bare actor type used by context providers |
146
+ | `ViewContextValue` | Value shape returned by `usePlayView()` |
147
+ | `RenderErrorHandler` | Error handler callback type for render errors |
148
+
149
+ ### Re-exports from `@xmachines/json-render-react`
150
+
151
+ `@xmachines/play-react` re-exports the full `@xmachines/json-render-react` surface so consumers only need one import:
152
+
153
+ ```ts
154
+ import {
155
+ defineRegistry,
156
+ useBoundProp,
157
+ JSONUIProvider,
158
+ StateProvider,
159
+ ActionProvider,
160
+ VisibilityProvider,
161
+ ValidationProvider,
162
+ Renderer,
163
+ } from "@xmachines/play-react";
333
164
  ```
334
165
 
335
- ## Architecture
336
-
337
- This package implements **Signal-Only Reactivity (INV-05)** and **Passive Infrastructure (INV-04)**:
338
-
339
- 1. **No Business Logic in React:**
340
- - No useState/useReducer for business state
341
- - No useEffect for side effects
342
- - React only triggers renders, doesn't control state
166
+ ## Key Principle
343
167
 
344
- 2. **Signals as Source of Truth:**
345
- - `actor.currentView.get()` provides UI structure
346
- - `actor.currentRoute.get()` provides navigation state
347
- - Components observe signals via `useSignalEffect`
168
+ React state is **never** used for business logic — only for triggering React's render cycle. Signals (`@xmachines/play-signals`) are the source of truth. `PlayUIProvider` passively observes actor signals via `useSignalEffect` and re-renders when the current view changes. Rapid signal updates are batched via microtasks to prevent unnecessary React renders.
348
169
 
349
- 3. **Event Forwarding:**
350
- - Components receive `send` function via props
351
- - User actions send events to actor (e.g., `{ type: "auth.login" }`)
352
- - Actor guards validate and process events
170
+ ## Testing
353
171
 
354
- 4. **Microtask Batching:**
355
- - `Signal.subtle.Watcher` coalesces rapid signal changes
356
- - Prevents React thrashing from multiple signal updates
357
- - Single React render per microtask batch
172
+ Run unit tests (jsdom environment):
358
173
 
359
- 5. **Explicit Disposal Contract:**
360
- - Component teardown must call watcher `unwatch` in cleanup
361
- - Do not rely on GC-only cleanup
362
-
363
- **Pattern:**
364
-
365
- - Renderer receives actor via props (provider pattern)
366
- - Enables composition with navigation, headers, footers
367
- - Supports multiple renderers in same app
368
-
369
- **Architectural Invariants:**
174
+ ```bash
175
+ pnpm --filter @xmachines/play-react test
176
+ ```
370
177
 
371
- - **Signal-Only Reactivity (INV-05):** No React state for business logic
372
- - **Passive Infrastructure (INV-04):** Components reflect, never decide
178
+ Run tests with coverage:
373
179
 
374
- ## Benefits
180
+ ```bash
181
+ pnpm --filter @xmachines/play-react run test:coverage
182
+ ```
375
183
 
376
- - **Framework Swappable:** Business logic has zero React imports
377
- - **Type Safety:** Props validated against catalog schemas
378
- - **Simple Testing:** Test actors without React renderer
379
- - **Performance:** Microtask batching reduces unnecessary renders
380
- - **Composability:** Renderer prop enables complex layouts ()
184
+ Run browser integration tests (requires Chromium):
381
185
 
382
- ## Related Packages
186
+ ```bash
187
+ pnpm --filter @xmachines/play-react run test:browser
188
+ ```
383
189
 
384
- - **[@xmachines/play-xstate](../play-xstate)** - XState adapter providing actors
385
- - **[@xmachines/play-catalog](../play-catalog)** - UI schema validation
386
- - **[@xmachines/play-tanstack-react-router](../play-tanstack-react-router)** - TanStack Router integration
387
- - **[@xmachines/play-actor](../play-actor)** - Actor base
388
- - **[@xmachines/play-signals](../play-signals)** - TC39 Signals primitives
190
+ Coverage thresholds: 80% lines, functions, branches, and statements.
389
191
 
390
192
  ## License
391
193
 
392
- Copyright (c) 2016 [Mikael Karon](mailto:mikael@karon.se). All rights reserved.
393
-
394
- This work is licensed under the terms of the MIT license.
395
- For a copy, see <https://opensource.org/licenses/MIT>.
194
+ MIT see [LICENSE](./LICENSE).
@@ -0,0 +1,82 @@
1
+ /**
2
+ * ActorProvider — escape hatch primitive for actor lifecycle management.
3
+ *
4
+ * Owns: actor bridging, signal subscription (useSignalEffect), per-view StateStore
5
+ * lifecycle (controlled/uncontrolled), handler resolution via inner component pattern
6
+ * (uses useStateStore()), StateProvider wrap, PlayErrorBoundary wrap, onRenderError injection.
7
+ *
8
+ * Standard usage: prefer <PlayUIProvider> unless you need to compose providers manually.
9
+ *
10
+ * @packageDocumentation
11
+ */
12
+ import React from "react";
13
+ import type { DefineRegistryResult, ComponentRegistry } from "@xmachines/json-render-react";
14
+ import { type BaseActorProviderProps, type BaseViewContextValue } from "@xmachines/play-actor";
15
+ /**
16
+ * Props for the ActorProvider component.
17
+ *
18
+ * @public
19
+ */
20
+ export interface ActorProviderProps extends BaseActorProviderProps<DefineRegistryResult> {
21
+ /** Optional component shown when currentView is null or a catalog component throws */
22
+ fallback?: React.ReactNode;
23
+ /** Optional error handler callback invoked when a catalog component throws during render */
24
+ onError?: (error: Error, info: React.ErrorInfo) => void;
25
+ /** Child components to render inside the provider tree */
26
+ children: React.ReactNode;
27
+ }
28
+ /**
29
+ * Value provided by ViewContext (accessible via usePlayView()).
30
+ *
31
+ * @public
32
+ */
33
+ export interface ViewContextValue extends BaseViewContextValue<ComponentRegistry> {
34
+ }
35
+ /**
36
+ * Hook to access the current view spec, handlers, and registry.
37
+ *
38
+ * Must be called inside <ActorProvider> or <PlayUIProvider>.
39
+ *
40
+ * @throws {Error} If called outside an ActorProvider/PlayUIProvider tree
41
+ *
42
+ * @example
43
+ * ```typescript
44
+ * import { usePlayView } from "@xmachines/play-react";
45
+ *
46
+ * function MyRenderer() {
47
+ * const view = usePlayView();
48
+ * return <Renderer spec={view.spec} registry={view.registry} />;
49
+ * }
50
+ * ```
51
+ *
52
+ * @public
53
+ */
54
+ export declare function usePlayView(): ViewContextValue;
55
+ /**
56
+ * ActorProvider — escape hatch primitive for composing actor lifecycle with custom providers.
57
+ *
58
+ * Subscribes to actor.currentView signal, manages the per-view StateStore lifecycle,
59
+ * wraps children in StateProvider and PlayErrorBoundary, and injects onRenderError
60
+ * into the component registry.
61
+ *
62
+ * Standard usage: prefer <PlayUIProvider> unless you need to compose providers manually.
63
+ *
64
+ * @example
65
+ * ```tsx
66
+ * // Custom composition (escape hatch):
67
+ * <ActorProvider actor={actor} registryResult={registryResult}>
68
+ * <JSONUIProvider registry={registryResult.registry}>
69
+ * <PlayRenderer />
70
+ * </JSONUIProvider>
71
+ * </ActorProvider>
72
+ *
73
+ * // Standard usage: prefer PlayUIProvider
74
+ * <PlayUIProvider actor={actor} registryResult={registryResult}>
75
+ * <PlayRenderer />
76
+ * </PlayUIProvider>
77
+ * ```
78
+ *
79
+ * @public
80
+ */
81
+ export declare const ActorProvider: React.FC<ActorProviderProps>;
82
+ //# sourceMappingURL=ActorProvider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ActorProvider.d.ts","sourceRoot":"","sources":["../src/ActorProvider.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAA+D,MAAM,OAAO,CAAC;AAEpF,OAAO,KAAK,EACX,oBAAoB,EAEpB,iBAAiB,EACjB,MAAM,8BAA8B,CAAC;AAOtC,OAAO,EAIN,KAAK,sBAAsB,EAC3B,KAAK,oBAAoB,EACzB,MAAM,uBAAuB,CAAC;AAI/B;;;;GAIG;AACH,MAAM,WAAW,kBAAmB,SAAQ,sBAAsB,CAAC,oBAAoB,CAAC;IACvF,sFAAsF;IACtF,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,4FAA4F;IAC5F,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC,SAAS,KAAK,IAAI,CAAC;IACxD,0DAA0D;IAC1D,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC1B;AAED;;;;GAIG;AACH,MAAM,WAAW,gBAAiB,SAAQ,oBAAoB,CAAC,iBAAiB,CAAC;CAAG;AAQpF;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,WAAW,IAAI,gBAAgB,CAE9C;AA0ED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CAqFtD,CAAC"}