@xmachines/play-react 2.0.0 → 2.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/README.md CHANGED
@@ -2,9 +2,7 @@
2
2
 
3
3
  React renderer for XMachines Play architecture with signal-driven rendering.
4
4
 
5
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![Version](https://img.shields.io/badge/version-2.0.0-blue)](https://www.npmjs.com/package/@xmachines/play-react)
6
-
7
- Part of the [xmachines-js monorepo](../../README.md).
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![Version](https://img.shields.io/badge/version-2.1.0-blue)](https://www.npmjs.com/package/@xmachines/play-react)
8
6
 
9
7
  ## Installation
10
8
 
@@ -12,7 +10,7 @@ Part of the [xmachines-js monorepo](../../README.md).
12
10
  pnpm add @xmachines/play-react
13
11
  ```
14
12
 
15
- **Peer dependencies** (must be installed separately):
13
+ **Peer dependencies.** Install them separately:
16
14
 
17
15
  ```bash
18
16
  pnpm add react react-dom xstate @xstate/store @xmachines/json-render-react @xmachines/json-render-core @xmachines/json-render-xstate
@@ -23,7 +21,7 @@ Supported versions:
23
21
  - `react` / `react-dom`: `^18.0.0 || ^19.0.0`
24
22
  - `xstate`: `^5.31.0`
25
23
  - `@xstate/store`: `^3.17.0`
26
- - `@xmachines/json-render-*`: `^0.18.0`
24
+ - `@xmachines/json-render-*`: `^0.20.0-xm.2`
27
25
 
28
26
  ## Usage
29
27
 
@@ -34,6 +32,9 @@ The recommended pattern for actor-driven React rendering:
34
32
  ```tsx
35
33
  import { PlayUIProvider, PlayRenderer, defineRegistry } from "@xmachines/play-react";
36
34
  import { definePlayer } from "@xmachines/play-xstate";
35
+ import { myMachine } from "./machine.js"; // your xstate machine (states carry meta.view specs)
36
+ import { myCatalog } from "./catalog.js"; // defineCatalog(schema, ...) result, using the schema from "@xmachines/json-render-react/schema"
37
+ import { Login, Dashboard } from "./components.js"; // your React components
37
38
 
38
39
  // 1. Create and start the actor
39
40
  const actor = definePlayer({ machine: myMachine })();
@@ -63,27 +64,42 @@ function App() {
63
64
  Pass navigation and validation helpers through `PlayUIProvider`:
64
65
 
65
66
  ```tsx
67
+ // actor, registryResult from the Quick Start above
66
68
  <PlayUIProvider
67
69
  actor={actor}
68
70
  registryResult={registryResult}
69
- navigate={(path) => router.push(path)}
71
+ navigate={(path) => history.pushState(null, "", path)}
70
72
  validationFunctions={{ isEmail: (v) => /^.+@.+$/.test(String(v)) }}
71
73
  >
72
74
  <PlayRenderer />
73
75
  </PlayUIProvider>
74
76
  ```
75
77
 
76
- ### Escape hatch — custom provider composition
78
+ ### Custom provider composition
77
79
 
78
80
  Use `ActorProvider` directly when you need to compose providers manually:
79
81
 
80
82
  ```tsx
81
- import { ActorProvider, JSONUIProvider, PlayRenderer } from "@xmachines/play-react";
83
+ import type { ReactNode } from "react";
84
+ import { ActorProvider, JSONUIProvider, PlayRenderer, usePlayView } from "@xmachines/play-react";
85
+
86
+ // Handlers and store live in ViewContext, so an inner bridge component must
87
+ // read them via usePlayView() and forward all three to JSONUIProvider —
88
+ // passing only `registry` would drop the action handlers and create a fresh store.
89
+ function Bridge({ children }: { children: ReactNode }) {
90
+ const view = usePlayView();
91
+ return (
92
+ <JSONUIProvider registry={view.registry} handlers={view.handlers} store={view.store}>
93
+ {children}
94
+ </JSONUIProvider>
95
+ );
96
+ }
82
97
 
98
+ // actor, registryResult from the Quick Start above
83
99
  <ActorProvider actor={actor} registryResult={registryResult}>
84
- <JSONUIProvider registry={registryResult.registry}>
100
+ <Bridge>
85
101
  <PlayRenderer />
86
- </JSONUIProvider>
102
+ </Bridge>
87
103
  </ActorProvider>;
88
104
  ```
89
105
 
@@ -101,6 +117,7 @@ function SubmitButton() {
101
117
  ### Subscribing to signals directly
102
118
 
103
119
  ```tsx
120
+ import { useState } from "react";
104
121
  import { useSignalEffect } from "@xmachines/play-react";
105
122
 
106
123
  function MyComponent({ actor }) {
@@ -110,7 +127,7 @@ function MyComponent({ actor }) {
110
127
  setView(actor.currentView.get());
111
128
  }, [actor]); // deps: re-subscribe when the actor prop swaps
112
129
 
113
- return <div>{view?.component}</div>;
130
+ return <div>{view?.root}</div>;
114
131
  }
115
132
  ```
116
133
 
@@ -120,34 +137,34 @@ function MyComponent({ actor }) {
120
137
 
121
138
  | Export | Description |
122
139
  | --------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
123
- | `<PlayUIProvider>` | Batteries-included provider: wraps `ActorProvider` + `JSONUIProvider`. Standard entry point. |
140
+ | `<PlayUIProvider>` | Composite provider. It wraps `ActorProvider` and `JSONUIProvider`. Use it as the standard entry point. |
124
141
  | `<PlayRenderer>` | Zero-prop leaf component. Reads the current actor view from context and renders it. Must be inside `PlayUIProvider` or `ActorProvider`. |
125
- | `<ActorProvider>` | Escape-hatch primitive. Owns actor bridging, signal subscription, and per-view `StateStore` lifecycle. |
126
- | `<PlayErrorBoundary>` | React class error boundary for catching catalog component render errors. |
142
+ | `<ActorProvider>` | The low-level provider. It owns the actor bridge, the signal subscription, and the `StateStore` lifecycle of each view. |
143
+ | `<PlayErrorBoundary>` | The React class error boundary that catches a render error of a catalog component. |
127
144
 
128
145
  ### Hooks
129
146
 
130
- | Export | Description |
131
- | ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
132
- | `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. |
133
- | `useActor()` | Returns the raw actor instance. Must be called inside an `ActorProvider`/`PlayUIProvider` tree. |
134
- | `usePlayView()` | Returns `{ spec, handlers, registry, store }` for the current view. Must be called inside an `ActorProvider`/`PlayUIProvider` tree. |
147
+ | Export | Description |
148
+ | ---------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
149
+ | `useSignalEffect(callback, deps?)` | Subscribes to the TC39 signal changes. It runs the callback again when a signal that the callback reads changes, and the callback triggers the re-render with its own setState. The optional `deps` array creates the subscription again, like `useEffect`. The hook removes the subscription on unmount. |
150
+ | `useActor()` | Returns the raw actor instance. Must be called inside an `ActorProvider`/`PlayUIProvider` tree. |
151
+ | `usePlayView()` | Returns `{ spec, handlers, registry, store }` for the current view. Must be called inside an `ActorProvider`/`PlayUIProvider` tree. |
135
152
 
136
153
  ### Types
137
154
 
138
- | Export | Description |
139
- | ------------------------ | ---------------------------------------------------------------------------------------------- |
140
- | `PlayUIProviderProps` | Props for `<PlayUIProvider>` |
141
- | `ActorProviderProps` | Props for `<ActorProvider>` (also exported as `PlayRendererProps` for migration compatibility) |
142
- | `PlayErrorBoundaryProps` | Props for `<PlayErrorBoundary>` |
143
- | `PlayErrorBoundaryState` | State shape for `<PlayErrorBoundary>` |
144
- | `AnyPlayActor` | Type alias for `AbstractActor<AnyActorLogic>` — the bare actor type used by context providers |
145
- | `ViewContextValue` | Value shape returned by `usePlayView()` |
146
- | `RenderErrorHandler` | Error handler callback type for render errors |
155
+ | Export | Description |
156
+ | ------------------------ | -------------------------------------------------------------------------------------------------- |
157
+ | `PlayUIProviderProps` | Props for `<PlayUIProvider>` |
158
+ | `ActorProviderProps` | Props for `<ActorProvider>` (also exported as `PlayRendererProps` for migration compatibility) |
159
+ | `PlayErrorBoundaryProps` | Props for `<PlayErrorBoundary>` |
160
+ | `PlayErrorBoundaryState` | State shape for `<PlayErrorBoundary>` |
161
+ | `AnyPlayActor` | Type alias for `AbstractActor<AnyActorLogic>` — the bare actor type that the context providers use |
162
+ | `ViewContextValue` | The value shape that `usePlayView()` returns |
163
+ | `RenderErrorHandler` | Error handler callback type for render errors |
147
164
 
148
165
  ### Re-exports from `@xmachines/json-render-react`
149
166
 
150
- `@xmachines/play-react` re-exports the full `@xmachines/json-render-react` surface so consumers only need one import:
167
+ `@xmachines/play-react` re-exports the complete `@xmachines/json-render-react` surface, so a consumer needs one import only:
151
168
 
152
169
  ```ts
153
170
  import {
@@ -164,7 +181,7 @@ import {
164
181
 
165
182
  ## Key Principle
166
183
 
167
- 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.
184
+ React state is **never** the place for the business logic. It only triggers the render cycle of React. The signals (`@xmachines/play-signals`) are the source of truth. `PlayUIProvider` observes the actor signals with `useSignalEffect`, and it renders again when the current view changes. It groups rapid signal updates into microtasks, so React does not render more often than necessary.
168
185
 
169
186
  ## Testing
170
187
 
@@ -180,7 +197,7 @@ Run tests with coverage:
180
197
  pnpm --filter @xmachines/play-react run test:coverage
181
198
  ```
182
199
 
183
- Run browser integration tests (requires Chromium):
200
+ Run the browser integration tests. They require Chromium:
184
201
 
185
202
  ```bash
186
203
  pnpm --filter @xmachines/play-react run test:browser
@@ -1,11 +1,14 @@
1
1
  /**
2
- * ActorProvider — escape hatch primitive for actor lifecycle management.
2
+ * ActorProvider — the low-level provider for the actor lifecycle.
3
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.
4
+ * It owns the actor bridge, the signal subscription (useSignalEffect), the
5
+ * StateStore lifecycle of each view (controlled and uncontrolled), the handler
6
+ * resolution through the inner component pattern (it uses useStateStore()), the
7
+ * StateProvider wrapper, the PlayErrorBoundary wrapper, and the injection of
8
+ * onRenderError.
7
9
  *
8
- * Standard usage: prefer <PlayUIProvider> unless you need to compose providers manually.
10
+ * Standard use: prefer <PlayUIProvider>, and use this component only when you
11
+ * compose the providers yourself.
9
12
  *
10
13
  * @packageDocumentation
11
14
  */
@@ -13,31 +16,31 @@ import React from "react";
13
16
  import type { DefineRegistryResult, ComponentRegistry } from "@xmachines/json-render-react";
14
17
  import { type BaseActorProviderProps, type BaseViewContextValue } from "@xmachines/play-actor";
15
18
  /**
16
- * Props for the ActorProvider component.
19
+ * The props of the ActorProvider component.
17
20
  *
18
21
  * @public
19
22
  */
20
23
  export interface ActorProviderProps extends BaseActorProviderProps<DefineRegistryResult> {
21
- /** Optional component shown when currentView is null or a catalog component throws */
24
+ /** The component to show when currentView is null, or when a catalog component throws. This prop is optional */
22
25
  fallback?: React.ReactNode;
23
- /** Optional error handler callback invoked when a catalog component throws during render */
26
+ /** The optional error handler. The provider calls it when a catalog component throws during a render */
24
27
  onError?: (error: Error, info: React.ErrorInfo) => void;
25
- /** Child components to render inside the provider tree */
28
+ /** The child components to render inside the provider tree */
26
29
  children: React.ReactNode;
27
30
  }
28
31
  /**
29
- * Value provided by ViewContext (accessible via usePlayView()).
32
+ * The value that ViewContext provides. usePlayView() reads it.
30
33
  *
31
34
  * @public
32
35
  */
33
36
  export interface ViewContextValue extends BaseViewContextValue<ComponentRegistry> {
34
37
  }
35
38
  /**
36
- * Hook to access the current view spec, handlers, and registry.
39
+ * The hook that gives the current view spec, the handlers, and the registry.
37
40
  *
38
- * Must be called inside <ActorProvider> or <PlayUIProvider>.
41
+ * Call it inside <ActorProvider> or <PlayUIProvider>.
39
42
  *
40
- * @throws {Error} If called outside an ActorProvider/PlayUIProvider tree
43
+ * @throws {Error} When the caller is outside an ActorProvider or PlayUIProvider tree
41
44
  *
42
45
  * @example
43
46
  * ```typescript
@@ -53,24 +56,25 @@ export interface ViewContextValue extends BaseViewContextValue<ComponentRegistry
53
56
  */
54
57
  export declare function usePlayView(): ViewContextValue;
55
58
  /**
56
- * ActorProvider — escape hatch primitive for composing actor lifecycle with custom providers.
59
+ * ActorProvider — the low-level provider that composes the actor lifecycle with your own providers.
57
60
  *
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
+ * It subscribes to the actor.currentView signal. It manages the StateStore
62
+ * lifecycle of each view. It wraps the children in StateProvider and in
63
+ * PlayErrorBoundary. It also puts onRenderError into the component registry.
61
64
  *
62
- * Standard usage: prefer <PlayUIProvider> unless you need to compose providers manually.
65
+ * Standard use: prefer <PlayUIProvider>, and use this component only when you
66
+ * compose the providers yourself.
63
67
  *
64
68
  * @example
65
69
  * ```tsx
66
- * // Custom composition (escape hatch):
70
+ * // A custom composition:
67
71
  * <ActorProvider actor={actor} registryResult={registryResult}>
68
72
  * <JSONUIProvider registry={registryResult.registry}>
69
73
  * <PlayRenderer />
70
74
  * </JSONUIProvider>
71
75
  * </ActorProvider>
72
76
  *
73
- * // Standard usage: prefer PlayUIProvider
77
+ * // Standard use: prefer PlayUIProvider
74
78
  * <PlayUIProvider actor={actor} registryResult={registryResult}>
75
79
  * <PlayRenderer />
76
80
  * </PlayUIProvider>
@@ -1 +1 @@
1
- {"version":3,"file":"ActorProvider.d.ts","sourceRoot":"","sources":["../src/ActorProvider.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAON,MAAM,OAAO,CAAC;AAEf,OAAO,KAAK,EACX,oBAAoB,EAEpB,iBAAiB,EACjB,MAAM,8BAA8B,CAAC;AAOtC,OAAO,EAMN,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,CAgHtD,CAAC"}
1
+ {"version":3,"file":"ActorProvider.d.ts","sourceRoot":"","sources":["../src/ActorProvider.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAON,MAAM,OAAO,CAAC;AAEf,OAAO,KAAK,EACX,oBAAoB,EAEpB,iBAAiB,EACjB,MAAM,8BAA8B,CAAC;AAOtC,OAAO,EAMN,KAAK,sBAAsB,EAC3B,KAAK,oBAAoB,EACzB,MAAM,uBAAuB,CAAC;AAI/B;;;;GAIG;AACH,MAAM,WAAW,kBAAmB,SAAQ,sBAAsB,CAAC,oBAAoB,CAAC;IACvF,gHAAgH;IAChH,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,wGAAwG;IACxG,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC,SAAS,KAAK,IAAI,CAAC;IACxD,8DAA8D;IAC9D,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;AA+ED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CAqHtD,CAAC"}
@@ -1,12 +1,15 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  /**
3
- * ActorProvider — escape hatch primitive for actor lifecycle management.
3
+ * ActorProvider — the low-level provider for the actor lifecycle.
4
4
  *
5
- * Owns: actor bridging, signal subscription (useSignalEffect), per-view StateStore
6
- * lifecycle (controlled/uncontrolled), handler resolution via inner component pattern
7
- * (uses useStateStore()), StateProvider wrap, PlayErrorBoundary wrap, onRenderError injection.
5
+ * It owns the actor bridge, the signal subscription (useSignalEffect), the
6
+ * StateStore lifecycle of each view (controlled and uncontrolled), the handler
7
+ * resolution through the inner component pattern (it uses useStateStore()), the
8
+ * StateProvider wrapper, the PlayErrorBoundary wrapper, and the injection of
9
+ * onRenderError.
8
10
  *
9
- * Standard usage: prefer <PlayUIProvider> unless you need to compose providers manually.
11
+ * Standard use: prefer <PlayUIProvider>, and use this component only when you
12
+ * compose the providers yourself.
10
13
  *
11
14
  * @packageDocumentation
12
15
  */
@@ -20,16 +23,16 @@ import { assertNonNullable } from "@xmachines/play";
20
23
  import { attachRenderErrorHandler, createViewStoreLifecycle, refreshContextSubtree, } from "@xmachines/play-actor";
21
24
  import { ActorContext } from "./useActor.js";
22
25
  /**
23
- * Internal React context for ViewContextValue.
24
- * Accessed via usePlayView() hook.
26
+ * The internal React context of ViewContextValue.
27
+ * The usePlayView() hook reads it.
25
28
  */
26
29
  const ViewContext = createContext(null);
27
30
  /**
28
- * Hook to access the current view spec, handlers, and registry.
31
+ * The hook that gives the current view spec, the handlers, and the registry.
29
32
  *
30
- * Must be called inside <ActorProvider> or <PlayUIProvider>.
33
+ * Call it inside <ActorProvider> or <PlayUIProvider>.
31
34
  *
32
- * @throws {Error} If called outside an ActorProvider/PlayUIProvider tree
35
+ * @throws {Error} When the caller is outside an ActorProvider or PlayUIProvider tree
33
36
  *
34
37
  * @example
35
38
  * ```typescript
@@ -47,42 +50,47 @@ export function usePlayView() {
47
50
  return assertNonNullable(useContext(ViewContext), "ViewContext");
48
51
  }
49
52
  /**
50
- * Create a StateStore backed by a fresh @xstate/store atom seeded from the given state.
51
- * Called internally per view transition when no external store prop is provided.
53
+ * Creates a StateStore on a new @xstate/store atom, with the given state as its
54
+ * first value. The provider calls this function for each view transition, when no
55
+ * external store prop is present.
52
56
  */
53
57
  function createViewStore(initialState) {
54
58
  return xstateStoreStateStore({ atom: createAtom(initialState) });
55
59
  }
56
60
  /**
57
- * Inner component that runs inside StateProvider so it can access StateStore context
58
- * via useStateStore(). Resolves action handlers from registryResult.handlers() using
59
- * the live StateProvider set/getSnapshot functions, then exposes them via ViewContext.
61
+ * The inner component runs inside StateProvider, so that it can read the StateStore
62
+ * context with useStateStore(). It resolves each action handler from
63
+ * registryResult.handlers(), with the live set and getSnapshot functions of
64
+ * StateProvider. It then puts the handlers in ViewContext.
60
65
  */
61
66
  function ActorProviderInner({ registryResult, spec, store, children, }) {
62
67
  const stateCtx = useStateStore();
63
- // Stable refs for stateCtx methods so the useMemo below doesn't need to depend
64
- // on stateCtx identity (useStateStore() may return a new object each render even
65
- // when the underlying store hasn't changed). The handlers factory passes these as
66
- // getter functions and calls them at action-execution time, not at creation time,
67
- // so reading from a ref is always correct.
68
+ // Stable refs of the stateCtx methods. The useMemo below therefore needs no
69
+ // dependency on the identity of stateCtx, because useStateStore() can return a new
70
+ // object on each render, also when the store below it did not change. The factory of
71
+ // the handlers gives these refs as getter functions, and it calls them at the moment
72
+ // of an action, and not at the moment of the creation. A read from a ref is therefore
73
+ // always correct.
68
74
  const stateCtxRef = useRef(stateCtx);
69
75
  stateCtxRef.current = stateCtx;
70
- // Build a SetState adapter: the handlers factory expects an updater-function pattern
71
- // ((prev) => next), while stateCtx provides path-based set/update. This adapter
72
- // bridges the two so action functions can use setState if needed.
73
- // Stable function reference — reads stateCtxRef.current at invocation time.
76
+ // Build a SetState adapter: the factory of the handlers expects the pattern of an
77
+ // updater function, `(prev) => next`, and stateCtx gives a set function and an update
78
+ // function on a path. This adapter joins the two. An action function can therefore
79
+ // use setState.
80
+ // The function reference is stable, and the function reads stateCtxRef.current at the
81
+ // moment of the call.
74
82
  const setStateAdapterRef = useRef((updater) => {
75
83
  const prev = stateCtxRef.current.getSnapshot();
76
84
  stateCtxRef.current.update(updater(prev));
77
85
  });
78
- // Memoize handlers keyed to registryResult identity. The getter functions are
79
- // stable refs so they do not contribute to invalidation. Handlers are only
80
- // recreated when the registry definition itself changes (e.g. a new defineRegistry
81
- // call), not on every render cycle.
86
+ // Keep the handlers, with the identity of registryResult as the key. The getter
87
+ // functions are stable refs, and they therefore cause no new computation. The code
88
+ // makes the handlers again only after a change of the definition of the registry, for
89
+ // example after a new defineRegistry call, and not on each render.
82
90
  const handlers = useMemo(() => registryResult.handlers(() => setStateAdapterRef.current, () => stateCtxRef.current.getSnapshot()), [registryResult]);
83
- // Memoize the context value on its actual inputs a fresh object every
84
- // render would re-render every usePlayView() consumer even when nothing
85
- // changed (wasted renders).
91
+ // Keep the value of the context on its real inputs. A new object on each render
92
+ // renders every usePlayView() consumer again, also when nothing changed, and those
93
+ // renders are lost work.
86
94
  const viewValue = useMemo(() => ({
87
95
  spec,
88
96
  handlers,
@@ -92,24 +100,25 @@ function ActorProviderInner({ registryResult, spec, store, children, }) {
92
100
  return _jsx(ViewContext.Provider, { value: viewValue, children: children });
93
101
  }
94
102
  /**
95
- * ActorProvider — escape hatch primitive for composing actor lifecycle with custom providers.
103
+ * ActorProvider — the low-level provider that composes the actor lifecycle with your own providers.
96
104
  *
97
- * Subscribes to actor.currentView signal, manages the per-view StateStore lifecycle,
98
- * wraps children in StateProvider and PlayErrorBoundary, and injects onRenderError
99
- * into the component registry.
105
+ * It subscribes to the actor.currentView signal. It manages the StateStore
106
+ * lifecycle of each view. It wraps the children in StateProvider and in
107
+ * PlayErrorBoundary. It also puts onRenderError into the component registry.
100
108
  *
101
- * Standard usage: prefer <PlayUIProvider> unless you need to compose providers manually.
109
+ * Standard use: prefer <PlayUIProvider>, and use this component only when you
110
+ * compose the providers yourself.
102
111
  *
103
112
  * @example
104
113
  * ```tsx
105
- * // Custom composition (escape hatch):
114
+ * // A custom composition:
106
115
  * <ActorProvider actor={actor} registryResult={registryResult}>
107
116
  * <JSONUIProvider registry={registryResult.registry}>
108
117
  * <PlayRenderer />
109
118
  * </JSONUIProvider>
110
119
  * </ActorProvider>
111
120
  *
112
- * // Standard usage: prefer PlayUIProvider
121
+ * // Standard use: prefer PlayUIProvider
113
122
  * <PlayUIProvider actor={actor} registryResult={registryResult}>
114
123
  * <PlayRenderer />
115
124
  * </PlayUIProvider>
@@ -118,45 +127,47 @@ function ActorProviderInner({ registryResult, spec, store, children, }) {
118
127
  * @public
119
128
  */
120
129
  export const ActorProvider = ({ actor, registryResult, store: externalStore, fallback = null, onError, onRenderError, children, }) => {
121
- // React state for triggering re-renders (NOT business logic state)
122
- // Signal is source of truth, useState is just React's render trigger
130
+ // React state, for the trigger of a new render. It is NOT the state of the business
131
+ // logic. The signal is the source of truth, and useState is the render trigger of
132
+ // React only.
123
133
  const [view, setView] = useState(() => actor.currentView.get());
124
- // Store lifecycle (reseed on viewKey change, refresh /context in place
125
- // otherwise, actor-swap reset, guard identity cache) the shared
126
- // coordinator from @xmachines/play-actor; only the reactivity wiring
127
- // (render path + effects below) is React's.
134
+ // The store lifecycle: it seeds the store again on a change of the viewKey, it
135
+ // refreshes /context in place in every other case, it resets the store on a change of
136
+ // the actor, and it guards the identity cache. The shared coordinator comes from
137
+ // @xmachines/play-actor. Only the wiring of the reactivity, which is the render path
138
+ // and the effects below, belongs to React.
128
139
  const storeLifecycleRef = useRef(null);
129
140
  storeLifecycleRef.current ??= createViewStoreLifecycle(createViewStore);
130
141
  const storeLifecycle = storeLifecycleRef.current;
131
- // Latest external store for the signal effect below the effect's deps are
132
- // [actor], so it must not close over a possibly-stale prop.
142
+ // The newest external store, for the signal effect below. The deps of that effect are
143
+ // [actor]. Therefore the effect must hold no prop that can be old.
133
144
  const externalStoreRef = useRef(externalStore);
134
145
  externalStoreRef.current = externalStore;
135
- // Subscribe to signal changes. The [actor] dep re-creates the watcher when
136
- // the actor prop swaps without it the watcher keeps tracking the OLD
137
- // actor's currentView signal and the rendered view freezes on the old actor
138
- // while events flow to the new one.
146
+ // Subscribe to the signal changes. The [actor] dependency makes the watcher again
147
+ // when the actor prop changes. Without it, the watcher tracks the currentView signal
148
+ // of the OLD actor, and the view on the screen freezes on the old actor while the
149
+ // events go to the new one.
139
150
  //
140
- // Store sync happens HERE, before setView triggers the re-render, so the
141
- // store and the spec the children see are always a consistent pair and so
142
- // store subscribers are never notified during a render pass.
151
+ // The store update happens HERE, before setView starts the new render. Therefore the
152
+ // store and the spec of the children are always a consistent pair, and the store
153
+ // notifies its subscribers never during a render pass.
143
154
  useSignalEffect(() => {
144
155
  const currentView = actor.currentView.get();
145
156
  if (currentView) {
146
- // Controlled mode included: /context is machinery-owned in both
147
- // modes, and refreshing the external store is allowed here (the
148
- // effect runs post-commit, never during a render pass).
157
+ // The controlled mode is here too: the machinery owns /context in both modes, and a
158
+ // refresh of the external store is permitted here, because the effect runs after the
159
+ // commit, and never during a render pass.
149
160
  storeLifecycle.resolve(actor, currentView, externalStoreRef.current);
150
161
  }
151
162
  setView(currentView);
152
163
  }, [actor]);
153
- // Controlled mode: refresh the external store's /context BEFORE paint. The
154
- // render path hands children the external store untouched (the machinery
155
- // must not notify store subscribers mid-render), and the passive signal
156
- // effect above runs after paint this layout effect closes the first-paint
157
- // gap. Keyed on the store identity too, so swapping the controlled store
158
- // prop mid-session brings the NEW store in line immediately instead of
159
- // waiting for the next view emission.
164
+ // The controlled mode: refresh the /context of the external store BEFORE the paint.
165
+ // The render path gives the children the external store without a change, because the
166
+ // machinery must notify no store subscriber during a render, and the passive signal
167
+ // effect above runs after the paint. This layout effect closes the gap of the first
168
+ // paint. Its key also holds the identity of the store. Therefore a new controlled
169
+ // store prop during a session brings the NEW store in line at once, and it waits not
170
+ // for the next emission of a view.
160
171
  useLayoutEffect(() => {
161
172
  if (!externalStore)
162
173
  return;
@@ -164,11 +175,13 @@ export const ActorProvider = ({ actor, registryResult, store: externalStore, fal
164
175
  if (currentView)
165
176
  refreshContextSubtree(externalStore, currentView);
166
177
  }, [externalStore, actor]);
167
- // Inject onRenderError prop into registry (non-enumerable, overrides defineRegistry-level handler)
168
- // Centralised here per D-19 one location for all framework renderers.
169
- // Memoized on its actual inputs: rebuilding the injected registry every render
170
- // would churn registry identity and invalidate ActorProviderInner's handlers
171
- // useMemo on every render (wasted work + wasted consumer re-renders).
178
+ // Put the onRenderError prop into the registry. The property is not enumerable, and
179
+ // it replaces the handler of the defineRegistry level.
180
+ // D-19 puts this work here: one place for every framework renderer.
181
+ // The code keeps the result on its real inputs. A new injected registry on each render
182
+ // churns the identity of the registry, and it therefore invalidates the handlers
183
+ // useMemo of ActorProviderInner on each render. That is lost work, and each consumer
184
+ // also renders again for nothing.
172
185
  const activeRegistryResult = useMemo(() => {
173
186
  if (!onRenderError)
174
187
  return registryResult;
@@ -177,25 +190,26 @@ export const ActorProvider = ({ actor, registryResult, store: externalStore, fal
177
190
  registry: attachRenderErrorHandler(registryResult.registry, onRenderError),
178
191
  };
179
192
  }, [registryResult, onRenderError]);
180
- // Resolve the store for StateProvider on the render path too it covers
181
- // the first render (the useState initializer seeded `view` before any
182
- // effect ran) and is a no-op afterwards: reseeding branches on viewKey, and
183
- // the /context refresh compares before writing, so no subscriber is
184
- // notified mid-render. The EXTERNAL store's refresh is deferred here for
185
- // the same mid-render reason the layout effect above handles it.
186
- // Children get the guarded store: /context is read-only to the spec
187
- // ($bindState, setState, chained set) machine context changes only
188
- // through events; the identity is cached per underlying store inside the
189
- // coordinator, so consumers stay referentially stable.
193
+ // Resolve the store of StateProvider on the render path too. This covers the first
194
+ // render, where the initializer of useState seeded `view` before an effect ran, and it
195
+ // does nothing after that: a new seed branches on the viewKey, and the /context
196
+ // refresh compares the values before a write. Therefore the store notifies no
197
+ // subscriber during a render. The refresh of the EXTERNAL store waits here, for the
198
+ // same reason of the render, and the layout effect above does it.
199
+ // The children receive the store with the guard: /context is read-only to the spec,
200
+ // which includes $bindState, setState, and a chained set, because the machine context
201
+ // changes through an event only. The coordinator keeps the identity of the guard for
202
+ // each store below it. Therefore each consumer stays stable by its reference.
190
203
  const guardedStore = view
191
204
  ? storeLifecycle.resolve(actor, view, externalStore, { refreshExternalStore: false })
192
205
  .guardedStore
193
206
  : null;
194
- // No view in current state render fallback INSIDE ActorContext so a
195
- // fallback component can call useActor() (e.g. to send a retry event).
196
- // Parity with the error-boundary fallback below and with the Solid/Svelte/Vue
197
- // renderers, which all provide context to their null-view fallbacks.
198
- // ViewContext is intentionally NOT provided: there is no view spec to expose.
207
+ // The current state has no view: render the fallback INSIDE ActorContext, so that a
208
+ // fallback component can call useActor(), for example to send an event of a retry.
209
+ // The fallback of the error boundary below does the same, and so do the renderers of
210
+ // Solid, of Svelte, and of Vue: each of them gives the context to its fallback of a
211
+ // null view.
212
+ // The code gives ViewContext deliberately NOT: there is no view spec to give.
199
213
  if (!view || !guardedStore) {
200
214
  return (_jsx(ActorContext.Provider, { value: actor, children: fallback }));
201
215
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ActorProvider.js","sourceRoot":"","sources":["../src/ActorProvider.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ActorProvider.js","sourceRoot":"","sources":["../src/ActorProvider.tsx"],"names":[],"mappings":"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"}