@xmachines/play-react 1.0.0-beta.3 → 1.0.0-beta.30
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 +21 -0
- package/README.md +234 -266
- package/dist/PlayErrorBoundary.d.ts +55 -0
- package/dist/PlayErrorBoundary.d.ts.map +1 -0
- package/dist/PlayErrorBoundary.js +45 -0
- package/dist/PlayErrorBoundary.js.map +1 -0
- package/dist/PlayRenderer.d.ts +19 -28
- package/dist/PlayRenderer.d.ts.map +1 -1
- package/dist/PlayRenderer.js +61 -45
- package/dist/PlayRenderer.js.map +1 -1
- package/dist/errors.d.ts +23 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +26 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +11 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -1
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +50 -7
- package/dist/types.d.ts.map +1 -1
- package/dist/useActor.d.ts +26 -0
- package/dist/useActor.d.ts.map +1 -0
- package/dist/useActor.js +29 -0
- package/dist/useActor.js.map +1 -0
- package/dist/useSignalEffect.d.ts +6 -0
- package/dist/useSignalEffect.d.ts.map +1 -1
- package/dist/useSignalEffect.js +36 -19
- package/dist/useSignalEffect.js.map +1 -1
- package/package.json +29 -12
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PlayErrorBoundary - React error boundary for catching catalog component render errors
|
|
3
|
+
*
|
|
4
|
+
* @packageDocumentation
|
|
5
|
+
*/
|
|
6
|
+
import React from "react";
|
|
7
|
+
/**
|
|
8
|
+
* Props for PlayErrorBoundary
|
|
9
|
+
*
|
|
10
|
+
* @public
|
|
11
|
+
*/
|
|
12
|
+
export interface PlayErrorBoundaryProps {
|
|
13
|
+
/** Fallback UI to render when a child component throws. Defaults to null. */
|
|
14
|
+
fallback?: React.ReactNode;
|
|
15
|
+
/** Child components to render */
|
|
16
|
+
children: React.ReactNode;
|
|
17
|
+
/** Optional error handler callback — forwards errors to observability tools (Sentry, etc.) */
|
|
18
|
+
onError?: (error: Error, info: React.ErrorInfo) => void;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Internal state shape for PlayErrorBoundary
|
|
22
|
+
*
|
|
23
|
+
* @public
|
|
24
|
+
*/
|
|
25
|
+
export interface PlayErrorBoundaryState {
|
|
26
|
+
hasError: boolean;
|
|
27
|
+
error: Error | null;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* React class component error boundary for catching catalog component render errors.
|
|
31
|
+
*
|
|
32
|
+
* Wraps catalog component renders so failures are caught and forwarded to standard
|
|
33
|
+
* React error boundary protocol. Consumers can attach the `onError` prop to forward
|
|
34
|
+
* errors to production observability tools (Sentry, Datadog, etc.).
|
|
35
|
+
*
|
|
36
|
+
* **React 19 safety (Phase 29):** `componentDidCatch` calls `onError` for observability
|
|
37
|
+
* but does NOT re-throw. `getDerivedStateFromError` already sets the fallback state —
|
|
38
|
+
* re-throwing from `componentDidCatch` can unmount the entire React 19 root.
|
|
39
|
+
*
|
|
40
|
+
* Per CONS-14: Class component pattern works with all React versions (18 and 19).
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* ```tsx
|
|
44
|
+
* <PlayErrorBoundary fallback={<div>Something went wrong</div>} onError={Sentry.captureException}>
|
|
45
|
+
* <CatalogComponent {...props} />
|
|
46
|
+
* </PlayErrorBoundary>
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
export declare class PlayErrorBoundary extends React.Component<PlayErrorBoundaryProps, PlayErrorBoundaryState> {
|
|
50
|
+
constructor(props: PlayErrorBoundaryProps);
|
|
51
|
+
static getDerivedStateFromError(error: Error): PlayErrorBoundaryState;
|
|
52
|
+
componentDidCatch(error: Error, info: React.ErrorInfo): void;
|
|
53
|
+
render(): React.ReactNode;
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=PlayErrorBoundary.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PlayErrorBoundary.d.ts","sourceRoot":"","sources":["../src/PlayErrorBoundary.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B;;;;GAIG;AACH,MAAM,WAAW,sBAAsB;IACtC,6EAA6E;IAC7E,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,iCAAiC;IACjC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,8FAA8F;IAC9F,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC,SAAS,KAAK,IAAI,CAAC;CACxD;AAED;;;;GAIG;AACH,MAAM,WAAW,sBAAsB;IACtC,QAAQ,EAAE,OAAO,CAAC;IAClB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;CACpB;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBAAa,iBAAkB,SAAQ,KAAK,CAAC,SAAS,CACrD,sBAAsB,EACtB,sBAAsB,CACtB;gBACY,KAAK,EAAE,sBAAsB;IAKzC,MAAM,CAAC,wBAAwB,CAAC,KAAK,EAAE,KAAK,GAAG,sBAAsB;IAI5D,iBAAiB,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC,SAAS,GAAG,IAAI;IAI5D,MAAM,IAAI,KAAK,CAAC,SAAS;CAMlC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PlayErrorBoundary - React error boundary for catching catalog component render errors
|
|
3
|
+
*
|
|
4
|
+
* @packageDocumentation
|
|
5
|
+
*/
|
|
6
|
+
import React from "react";
|
|
7
|
+
/**
|
|
8
|
+
* React class component error boundary for catching catalog component render errors.
|
|
9
|
+
*
|
|
10
|
+
* Wraps catalog component renders so failures are caught and forwarded to standard
|
|
11
|
+
* React error boundary protocol. Consumers can attach the `onError` prop to forward
|
|
12
|
+
* errors to production observability tools (Sentry, Datadog, etc.).
|
|
13
|
+
*
|
|
14
|
+
* **React 19 safety (Phase 29):** `componentDidCatch` calls `onError` for observability
|
|
15
|
+
* but does NOT re-throw. `getDerivedStateFromError` already sets the fallback state —
|
|
16
|
+
* re-throwing from `componentDidCatch` can unmount the entire React 19 root.
|
|
17
|
+
*
|
|
18
|
+
* Per CONS-14: Class component pattern works with all React versions (18 and 19).
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```tsx
|
|
22
|
+
* <PlayErrorBoundary fallback={<div>Something went wrong</div>} onError={Sentry.captureException}>
|
|
23
|
+
* <CatalogComponent {...props} />
|
|
24
|
+
* </PlayErrorBoundary>
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
export class PlayErrorBoundary extends React.Component {
|
|
28
|
+
constructor(props) {
|
|
29
|
+
super(props);
|
|
30
|
+
this.state = { hasError: false, error: null };
|
|
31
|
+
}
|
|
32
|
+
static getDerivedStateFromError(error) {
|
|
33
|
+
return { hasError: true, error };
|
|
34
|
+
}
|
|
35
|
+
componentDidCatch(error, info) {
|
|
36
|
+
this.props.onError?.(error, info);
|
|
37
|
+
}
|
|
38
|
+
render() {
|
|
39
|
+
if (this.state.hasError) {
|
|
40
|
+
return this.props.fallback ?? null;
|
|
41
|
+
}
|
|
42
|
+
return this.props.children;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=PlayErrorBoundary.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PlayErrorBoundary.js","sourceRoot":"","sources":["../src/PlayErrorBoundary.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AA0B1B;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,OAAO,iBAAkB,SAAQ,KAAK,CAAC,SAG5C;IACA,YAAY,KAA6B;QACxC,KAAK,CAAC,KAAK,CAAC,CAAC;QACb,IAAI,CAAC,KAAK,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IAC/C,CAAC;IAED,MAAM,CAAC,wBAAwB,CAAC,KAAY;QAC3C,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;IAClC,CAAC;IAEQ,iBAAiB,CAAC,KAAY,EAAE,IAAqB;QAC7D,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IACnC,CAAC;IAEQ,MAAM;QACd,IAAI,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;YACzB,OAAO,IAAI,CAAC,KAAK,CAAC,QAAQ,IAAI,IAAI,CAAC;QACpC,CAAC;QACD,OAAO,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC;IAC5B,CAAC;CACD"}
|
package/dist/PlayRenderer.d.ts
CHANGED
|
@@ -1,18 +1,24 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* PlayRenderer - Main React renderer component for XMachines Play architecture
|
|
3
3
|
*
|
|
4
|
+
* Backed by @json-render/react for spec-driven UI rendering.
|
|
5
|
+
*
|
|
4
6
|
* @packageDocumentation
|
|
5
7
|
*/
|
|
6
8
|
import React from "react";
|
|
7
9
|
import type { PlayRendererProps } from "./types.js";
|
|
8
10
|
/**
|
|
9
11
|
* Main renderer component that subscribes to actor signals and renders UI
|
|
12
|
+
* via @json-render/react Renderer.
|
|
10
13
|
*
|
|
11
|
-
* Architecture
|
|
14
|
+
* Architecture:
|
|
12
15
|
* - Subscribes to actor.currentView signal via useSignalEffect
|
|
13
|
-
* -
|
|
14
|
-
* -
|
|
15
|
-
* -
|
|
16
|
+
* - Renders view.spec via StateProvider → ActionProvider → VisibilityProvider → Renderer
|
|
17
|
+
* - Routes action names to actor.send() via the `actions` prop mapping
|
|
18
|
+
* - State store: uses external `store` prop if provided (controlled mode); otherwise
|
|
19
|
+
* creates a fresh @xstate/store atom per view transition seeded from spec.state.
|
|
20
|
+
* The atom resets automatically when the actor transitions to a new view, mirroring
|
|
21
|
+
* the actor's currentView lifecycle.
|
|
16
22
|
*
|
|
17
23
|
* Invariant: Actor Authority - Actor decides all state transitions via guards.
|
|
18
24
|
* Invariant: Passive Infrastructure - Component observes signals and sends events.
|
|
@@ -21,37 +27,22 @@ import type { PlayRendererProps } from "./types.js";
|
|
|
21
27
|
* @example
|
|
22
28
|
* ```typescript
|
|
23
29
|
* import { PlayRenderer } from "@xmachines/play-react";
|
|
24
|
-
* import {
|
|
30
|
+
* import { defineRegistry } from "@json-render/react";
|
|
25
31
|
*
|
|
26
|
-
* const
|
|
27
|
-
* actor.start();
|
|
32
|
+
* const { registry } = defineRegistry(catalog, { components: { ... } });
|
|
28
33
|
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
* LoginForm: ({ error, send }) => <form onSubmit={(e) => {
|
|
32
|
-
* e.preventDefault();
|
|
33
|
-
* send({ type: "intent", name: "login.submit", payload: {...} });
|
|
34
|
-
* }}>...</form>
|
|
35
|
-
* };
|
|
34
|
+
* // Uncontrolled — fresh atom created per view, seeded from spec.state:
|
|
35
|
+
* <PlayRenderer actor={actor} registry={registry} actions={{ login: "auth.login" }} />
|
|
36
36
|
*
|
|
37
|
-
*
|
|
37
|
+
* // Controlled — caller provides and owns the store:
|
|
38
|
+
* import { createAtom } from "@xstate/store";
|
|
39
|
+
* import { xstateStoreStateStore } from "@json-render/xstate";
|
|
40
|
+
* const store = xstateStoreStateStore({ atom: createAtom({ username: "" }) });
|
|
41
|
+
* <PlayRenderer actor={actor} registry={registry} store={store} actions={{ login: "auth.login" }} />
|
|
38
42
|
* ```
|
|
39
43
|
*
|
|
40
44
|
* @param props - Component props
|
|
41
45
|
* @returns React element rendering current view from actor
|
|
42
|
-
*
|
|
43
|
-
* @remarks
|
|
44
|
-
* **Component lookup:** Dynamically looks up component from `components` map
|
|
45
|
-
* using `view.component` string from actor.currentView signal.
|
|
46
|
-
*
|
|
47
|
-
* **Event forwarding:** Injects `send` function as prop to components. Components
|
|
48
|
-
* call `send(event)` to forward intents to actor. Actor guards decide validity.
|
|
49
|
-
*
|
|
50
|
-
* **Error handling:** If component not found in catalog, logs error and shows
|
|
51
|
-
* fallback. This indicates missing component registration, not runtime error.
|
|
52
|
-
*
|
|
53
|
-
* **CRITICAL:** Never call actor.send() during render - only in event handlers.
|
|
54
|
-
* Calling send during render causes infinite render loops.
|
|
55
46
|
*/
|
|
56
47
|
export declare const PlayRenderer: React.FC<PlayRendererProps>;
|
|
57
48
|
//# sourceMappingURL=PlayRenderer.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PlayRenderer.d.ts","sourceRoot":"","sources":["../src/PlayRenderer.tsx"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"PlayRenderer.d.ts","sourceRoot":"","sources":["../src/PlayRenderer.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAA2B,MAAM,OAAO,CAAC;AAOhD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAYpD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CAqEpD,CAAC"}
|
package/dist/PlayRenderer.js
CHANGED
|
@@ -2,18 +2,36 @@ import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
|
|
|
2
2
|
/**
|
|
3
3
|
* PlayRenderer - Main React renderer component for XMachines Play architecture
|
|
4
4
|
*
|
|
5
|
+
* Backed by @json-render/react for spec-driven UI rendering.
|
|
6
|
+
*
|
|
5
7
|
* @packageDocumentation
|
|
6
8
|
*/
|
|
7
|
-
import React, { useState } from "react";
|
|
9
|
+
import React, { useState, useRef } from "react";
|
|
10
|
+
import { Renderer, StateProvider, ActionProvider, VisibilityProvider } from "@json-render/react";
|
|
11
|
+
import { createAtom } from "@xstate/store";
|
|
12
|
+
import { xstateStoreStateStore } from "@json-render/xstate";
|
|
8
13
|
import { useSignalEffect } from "./useSignalEffect.js";
|
|
14
|
+
import { PlayErrorBoundary } from "./PlayErrorBoundary.js";
|
|
15
|
+
import { ActorContext } from "./useActor.js";
|
|
16
|
+
/**
|
|
17
|
+
* Create a StateStore backed by a fresh @xstate/store atom seeded from the given state.
|
|
18
|
+
* Called internally per view transition when no external store prop is provided.
|
|
19
|
+
*/
|
|
20
|
+
function createViewStore(initialState) {
|
|
21
|
+
return xstateStoreStateStore({ atom: createAtom(initialState) });
|
|
22
|
+
}
|
|
9
23
|
/**
|
|
10
24
|
* Main renderer component that subscribes to actor signals and renders UI
|
|
25
|
+
* via @json-render/react Renderer.
|
|
11
26
|
*
|
|
12
|
-
* Architecture
|
|
27
|
+
* Architecture:
|
|
13
28
|
* - Subscribes to actor.currentView signal via useSignalEffect
|
|
14
|
-
* -
|
|
15
|
-
* -
|
|
16
|
-
* -
|
|
29
|
+
* - Renders view.spec via StateProvider → ActionProvider → VisibilityProvider → Renderer
|
|
30
|
+
* - Routes action names to actor.send() via the `actions` prop mapping
|
|
31
|
+
* - State store: uses external `store` prop if provided (controlled mode); otherwise
|
|
32
|
+
* creates a fresh @xstate/store atom per view transition seeded from spec.state.
|
|
33
|
+
* The atom resets automatically when the actor transitions to a new view, mirroring
|
|
34
|
+
* the actor's currentView lifecycle.
|
|
17
35
|
*
|
|
18
36
|
* Invariant: Actor Authority - Actor decides all state transitions via guards.
|
|
19
37
|
* Invariant: Passive Infrastructure - Component observes signals and sends events.
|
|
@@ -22,66 +40,64 @@ import { useSignalEffect } from "./useSignalEffect.js";
|
|
|
22
40
|
* @example
|
|
23
41
|
* ```typescript
|
|
24
42
|
* import { PlayRenderer } from "@xmachines/play-react";
|
|
25
|
-
* import {
|
|
43
|
+
* import { defineRegistry } from "@json-render/react";
|
|
26
44
|
*
|
|
27
|
-
* const
|
|
28
|
-
* actor.start();
|
|
45
|
+
* const { registry } = defineRegistry(catalog, { components: { ... } });
|
|
29
46
|
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
* LoginForm: ({ error, send }) => <form onSubmit={(e) => {
|
|
33
|
-
* e.preventDefault();
|
|
34
|
-
* send({ type: "intent", name: "login.submit", payload: {...} });
|
|
35
|
-
* }}>...</form>
|
|
36
|
-
* };
|
|
47
|
+
* // Uncontrolled — fresh atom created per view, seeded from spec.state:
|
|
48
|
+
* <PlayRenderer actor={actor} registry={registry} actions={{ login: "auth.login" }} />
|
|
37
49
|
*
|
|
38
|
-
*
|
|
50
|
+
* // Controlled — caller provides and owns the store:
|
|
51
|
+
* import { createAtom } from "@xstate/store";
|
|
52
|
+
* import { xstateStoreStateStore } from "@json-render/xstate";
|
|
53
|
+
* const store = xstateStoreStateStore({ atom: createAtom({ username: "" }) });
|
|
54
|
+
* <PlayRenderer actor={actor} registry={registry} store={store} actions={{ login: "auth.login" }} />
|
|
39
55
|
* ```
|
|
40
56
|
*
|
|
41
57
|
* @param props - Component props
|
|
42
58
|
* @returns React element rendering current view from actor
|
|
43
|
-
*
|
|
44
|
-
* @remarks
|
|
45
|
-
* **Component lookup:** Dynamically looks up component from `components` map
|
|
46
|
-
* using `view.component` string from actor.currentView signal.
|
|
47
|
-
*
|
|
48
|
-
* **Event forwarding:** Injects `send` function as prop to components. Components
|
|
49
|
-
* call `send(event)` to forward intents to actor. Actor guards decide validity.
|
|
50
|
-
*
|
|
51
|
-
* **Error handling:** If component not found in catalog, logs error and shows
|
|
52
|
-
* fallback. This indicates missing component registration, not runtime error.
|
|
53
|
-
*
|
|
54
|
-
* **CRITICAL:** Never call actor.send() during render - only in event handlers.
|
|
55
|
-
* Calling send during render causes infinite render loops.
|
|
56
59
|
*/
|
|
57
|
-
export const PlayRenderer = ({ actor,
|
|
60
|
+
export const PlayRenderer = ({ actor, registry, store: externalStore, fallback = null, onError, actions = {}, }) => {
|
|
58
61
|
// React state for triggering re-renders (NOT business logic state)
|
|
59
62
|
// Signal is source of truth, useState is just React's render trigger
|
|
60
63
|
const [view, setView] = useState(() => actor.currentView.get());
|
|
64
|
+
// Internal store ref — tracks the current per-view atom store.
|
|
65
|
+
// Keyed to view identity: recreated whenever the view changes (new spec.state seed).
|
|
66
|
+
// Ignored when externalStore is provided.
|
|
67
|
+
const internalStoreRef = useRef(null);
|
|
68
|
+
const lastViewRef = useRef(null);
|
|
61
69
|
// Subscribe to signal changes
|
|
62
70
|
useSignalEffect(() => {
|
|
63
71
|
const currentView = actor.currentView.get();
|
|
64
72
|
setView(currentView);
|
|
65
73
|
});
|
|
66
|
-
// No view in current state
|
|
74
|
+
// No view in current state — render fallback
|
|
67
75
|
if (!view) {
|
|
68
76
|
return _jsx(_Fragment, { children: fallback });
|
|
69
77
|
}
|
|
70
|
-
//
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
78
|
+
// Resolve the store to use for StateProvider:
|
|
79
|
+
// - External (controlled): use as-is, caller manages lifecycle
|
|
80
|
+
// - Internal: create a fresh atom when the view changes (new route/state)
|
|
81
|
+
let store;
|
|
82
|
+
if (externalStore) {
|
|
83
|
+
store = externalStore;
|
|
75
84
|
}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
85
|
+
else {
|
|
86
|
+
// Recreate the internal store when the view identity changes
|
|
87
|
+
// (view is a new object on every transition per deriveCurrentView)
|
|
88
|
+
if (internalStoreRef.current === null || lastViewRef.current !== view) {
|
|
89
|
+
const initialState = view.spec?.state ?? {};
|
|
90
|
+
internalStoreRef.current = createViewStore(initialState);
|
|
91
|
+
lastViewRef.current = view;
|
|
92
|
+
}
|
|
93
|
+
store = internalStoreRef.current;
|
|
82
94
|
}
|
|
83
|
-
//
|
|
84
|
-
//
|
|
85
|
-
|
|
95
|
+
// Build ActionProvider handlers from actions mapping
|
|
96
|
+
// Each handler calls actor.send() with the configured event type + params
|
|
97
|
+
const handlers = Object.fromEntries(Object.entries(actions).map(([actionName, eventType]) => [
|
|
98
|
+
actionName,
|
|
99
|
+
async (params = {}) => actor.send({ type: eventType, ...params }),
|
|
100
|
+
]));
|
|
101
|
+
return (_jsx(ActorContext.Provider, { value: actor, children: _jsx(PlayErrorBoundary, { fallback: fallback, ...(onError && { onError }), children: _jsx(StateProvider, { store: store, children: _jsx(ActionProvider, { handlers: handlers, children: _jsx(VisibilityProvider, { children: _jsx(Renderer, { spec: view.spec ?? null, registry: registry }) }) }) }) }) }));
|
|
86
102
|
};
|
|
87
103
|
//# sourceMappingURL=PlayRenderer.js.map
|
package/dist/PlayRenderer.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PlayRenderer.js","sourceRoot":"","sources":["../src/PlayRenderer.tsx"],"names":[],"mappings":";AAAA
|
|
1
|
+
{"version":3,"file":"PlayRenderer.js","sourceRoot":"","sources":["../src/PlayRenderer.tsx"],"names":[],"mappings":"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"}
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { PlayError } from "@xmachines/play";
|
|
2
|
+
/**
|
|
3
|
+
* Error class for renderer-level errors in the Play architecture.
|
|
4
|
+
*
|
|
5
|
+
* **Note (Phase 29):** `PlayErrorBoundary.componentDidCatch()` no longer throws
|
|
6
|
+
* this error. Re-throwing from `componentDidCatch` can unmount the entire React 19
|
|
7
|
+
* root. `RendererError` is retained for programmatic use in custom error handlers
|
|
8
|
+
* and parent boundaries — it is no longer emitted by the built-in boundary itself.
|
|
9
|
+
*
|
|
10
|
+
* **Error code:** `PLAY_RENDERER_RENDER_ERROR`
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* import { RendererError } from "@xmachines/play-react/errors";
|
|
15
|
+
*
|
|
16
|
+
* // Create a RendererError programmatically in a custom boundary:
|
|
17
|
+
* throw new RendererError("Custom render failure", { cause: originalError });
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
export declare class RendererError extends PlayError {
|
|
21
|
+
constructor(message: string, options?: ErrorOptions);
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,aAAc,SAAQ,SAAS;gBAC/B,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY;CAInD"}
|
package/dist/errors.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { PlayError } from "@xmachines/play";
|
|
2
|
+
/**
|
|
3
|
+
* Error class for renderer-level errors in the Play architecture.
|
|
4
|
+
*
|
|
5
|
+
* **Note (Phase 29):** `PlayErrorBoundary.componentDidCatch()` no longer throws
|
|
6
|
+
* this error. Re-throwing from `componentDidCatch` can unmount the entire React 19
|
|
7
|
+
* root. `RendererError` is retained for programmatic use in custom error handlers
|
|
8
|
+
* and parent boundaries — it is no longer emitted by the built-in boundary itself.
|
|
9
|
+
*
|
|
10
|
+
* **Error code:** `PLAY_RENDERER_RENDER_ERROR`
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* import { RendererError } from "@xmachines/play-react/errors";
|
|
15
|
+
*
|
|
16
|
+
* // Create a RendererError programmatically in a custom boundary:
|
|
17
|
+
* throw new RendererError("Custom render failure", { cause: originalError });
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
export class RendererError extends PlayError {
|
|
21
|
+
constructor(message, options) {
|
|
22
|
+
super("PlayRenderer", "PLAY_RENDERER_RENDER_ERROR", message, options);
|
|
23
|
+
this.name = "RendererError";
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,OAAO,aAAc,SAAQ,SAAS;IAC3C,YAAY,OAAe,EAAE,OAAsB;QAClD,KAAK,CAAC,cAAc,EAAE,4BAA4B,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;QACtE,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;IAC7B,CAAC;CACD"}
|
package/dist/index.d.ts
CHANGED
|
@@ -2,17 +2,27 @@
|
|
|
2
2
|
* @xmachines/play-react - React renderer for XMachines Play architecture
|
|
3
3
|
*
|
|
4
4
|
* Provides a thin React rendering layer that passively observes actor signals
|
|
5
|
-
* and renders UI components
|
|
5
|
+
* and renders UI components via @json-render/react. This package enables
|
|
6
6
|
* framework-swappable architecture where React is just a rendering target
|
|
7
7
|
* that subscribes to signal changes.
|
|
8
8
|
*
|
|
9
9
|
* **Key principle:** React state is NEVER used for business logic—only for
|
|
10
10
|
* triggering React's render cycle. Signals are the source of truth.
|
|
11
11
|
*
|
|
12
|
+
* Re-exports `defineRegistry`, `useStateBinding`, `ComponentFn`, and
|
|
13
|
+
* `ComponentContext` from `@json-render/react` so consumers import everything
|
|
14
|
+
* from `@xmachines/play-react` rather than `@json-render/react` directly.
|
|
15
|
+
*
|
|
12
16
|
* @packageDocumentation
|
|
13
17
|
* @module @xmachines/play-react
|
|
14
18
|
*/
|
|
15
19
|
export { PlayRenderer } from "./PlayRenderer.js";
|
|
16
20
|
export { useSignalEffect } from "./useSignalEffect.js";
|
|
21
|
+
export { PlayErrorBoundary } from "./PlayErrorBoundary.js";
|
|
22
|
+
export { useActor } from "./useActor.js";
|
|
23
|
+
export { defineRegistry, useStateBinding, useBoundProp } from "@json-render/react";
|
|
24
|
+
export type { ComponentFn, ComponentContext } from "@json-render/react";
|
|
17
25
|
export type { PlayRendererProps } from "./types.js";
|
|
26
|
+
export type { PlayErrorBoundaryProps, PlayErrorBoundaryState } from "./PlayErrorBoundary.js";
|
|
27
|
+
export type { PlayActor } from "./useActor.js";
|
|
18
28
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAGH,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAGzC,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACnF,YAAY,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAGxE,YAAY,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AACpD,YAAY,EAAE,sBAAsB,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAC7F,YAAY,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -2,17 +2,26 @@
|
|
|
2
2
|
* @xmachines/play-react - React renderer for XMachines Play architecture
|
|
3
3
|
*
|
|
4
4
|
* Provides a thin React rendering layer that passively observes actor signals
|
|
5
|
-
* and renders UI components
|
|
5
|
+
* and renders UI components via @json-render/react. This package enables
|
|
6
6
|
* framework-swappable architecture where React is just a rendering target
|
|
7
7
|
* that subscribes to signal changes.
|
|
8
8
|
*
|
|
9
9
|
* **Key principle:** React state is NEVER used for business logic—only for
|
|
10
10
|
* triggering React's render cycle. Signals are the source of truth.
|
|
11
11
|
*
|
|
12
|
+
* Re-exports `defineRegistry`, `useStateBinding`, `ComponentFn`, and
|
|
13
|
+
* `ComponentContext` from `@json-render/react` so consumers import everything
|
|
14
|
+
* from `@xmachines/play-react` rather than `@json-render/react` directly.
|
|
15
|
+
*
|
|
12
16
|
* @packageDocumentation
|
|
13
17
|
* @module @xmachines/play-react
|
|
14
18
|
*/
|
|
15
19
|
// Main exports
|
|
16
20
|
export { PlayRenderer } from "./PlayRenderer.js";
|
|
17
21
|
export { useSignalEffect } from "./useSignalEffect.js";
|
|
22
|
+
export { PlayErrorBoundary } from "./PlayErrorBoundary.js";
|
|
23
|
+
export { useActor } from "./useActor.js";
|
|
24
|
+
// Re-export from @json-render/react so consumers import everything from @xmachines/play-react.
|
|
25
|
+
// React's useContext works anywhere in the call tree — no wrapper needed.
|
|
26
|
+
export { defineRegistry, useStateBinding, useBoundProp } from "@json-render/react";
|
|
18
27
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,eAAe;AACf,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,+FAA+F;AAC/F,0EAA0E;AAC1E,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC"}
|
package/dist/types.d.ts
CHANGED
|
@@ -3,22 +3,65 @@
|
|
|
3
3
|
*
|
|
4
4
|
* @packageDocumentation
|
|
5
5
|
*/
|
|
6
|
+
import type { ComponentRegistry } from "@json-render/react";
|
|
7
|
+
import type { StateStore } from "@json-render/core";
|
|
6
8
|
import type { AbstractActor, Viewable } from "@xmachines/play-actor";
|
|
7
9
|
import type React from "react";
|
|
8
|
-
import type { AnyActorLogic } from "xstate";
|
|
10
|
+
import type { AnyActorLogic, EventFromLogic } from "xstate";
|
|
9
11
|
/**
|
|
10
12
|
* Props for PlayRenderer component
|
|
11
13
|
*
|
|
14
|
+
* @typeParam TLogic - The XState actor logic type. Defaults to `AnyActorLogic` for
|
|
15
|
+
* non-generic usage. When a specific machine type is provided, the `actions` values
|
|
16
|
+
* are constrained to the event type strings that the machine actually accepts.
|
|
17
|
+
*
|
|
12
18
|
* @property actor - Actor instance with currentView signal (requires Viewable capability)
|
|
13
|
-
* @property
|
|
19
|
+
* @property registry - ComponentRegistry from defineRegistry() in @json-render/react
|
|
20
|
+
* @property store - Optional external StateStore (e.g. from @json-render/xstate). When
|
|
21
|
+
* provided, PlayRenderer operates in controlled mode — spec.state is ignored and the
|
|
22
|
+
* store is the single source of truth for UI state. When omitted, a fresh
|
|
23
|
+
* @xstate/store atom is created internally per view transition, seeded from spec.state.
|
|
14
24
|
* @property fallback - Optional component shown when currentView is null
|
|
25
|
+
* @property onError - Optional callback invoked when a catalog component throws during render.
|
|
26
|
+
* Receives the error and React ErrorInfo — use to forward to Sentry, Datadog, etc.
|
|
27
|
+
* @property actions - Maps json-render action names to XState event type strings.
|
|
28
|
+
* Values are constrained to `EventFromLogic<TLogic>["type"]` — passing a non-existent
|
|
29
|
+
* event type string is a compile error when TLogic is specified.
|
|
15
30
|
*/
|
|
16
|
-
export interface PlayRendererProps {
|
|
31
|
+
export interface PlayRendererProps<TLogic extends AnyActorLogic = AnyActorLogic> {
|
|
17
32
|
/** Actor instance with currentView signal (requires Viewable capability) */
|
|
18
|
-
actor: AbstractActor<
|
|
19
|
-
/**
|
|
20
|
-
|
|
21
|
-
/**
|
|
33
|
+
actor: AbstractActor<TLogic> & Viewable;
|
|
34
|
+
/** ComponentRegistry from defineRegistry() in @json-render/react */
|
|
35
|
+
registry: ComponentRegistry;
|
|
36
|
+
/**
|
|
37
|
+
* Optional external StateStore (e.g. from `xstateStoreStateStore` in @json-render/xstate).
|
|
38
|
+
* When provided, PlayRenderer operates in controlled mode — spec.state is ignored and
|
|
39
|
+
* this store is the single source of truth for UI state (form values, etc.).
|
|
40
|
+
* When omitted, a fresh @xstate/store atom is created internally per view transition,
|
|
41
|
+
* seeded from spec.state. The atom resets automatically when the actor transitions to a
|
|
42
|
+
* new view, mirroring the actor's currentView lifecycle.
|
|
43
|
+
*/
|
|
44
|
+
store?: StateStore;
|
|
45
|
+
/** Optional component shown when currentView is null or a catalog component throws */
|
|
22
46
|
fallback?: React.ReactNode;
|
|
47
|
+
/**
|
|
48
|
+
* Optional error handler callback invoked when a catalog component throws during render.
|
|
49
|
+
* Forwarded directly to the internal `PlayErrorBoundary` — use to integrate with
|
|
50
|
+
* production observability tools (Sentry, Datadog, etc.).
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* ```tsx
|
|
54
|
+
* <PlayRenderer actor={actor} registry={registry} onError={Sentry.captureException} />
|
|
55
|
+
* ```
|
|
56
|
+
*/
|
|
57
|
+
onError?: (error: Error, info: React.ErrorInfo) => void;
|
|
58
|
+
/**
|
|
59
|
+
* Maps json-render action names to XState event type strings.
|
|
60
|
+
* Values are constrained to valid event types for TLogic — wrong event type strings
|
|
61
|
+
* are caught at compile time when TLogic is specified.
|
|
62
|
+
*/
|
|
63
|
+
actions?: {
|
|
64
|
+
[actionName: string]: EventFromLogic<TLogic>["type"];
|
|
65
|
+
};
|
|
23
66
|
}
|
|
24
67
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
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,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACrE,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAC;AAE5D;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,WAAW,iBAAiB,CAAC,MAAM,SAAS,aAAa,GAAG,aAAa;IAC9E,4EAA4E;IAC5E,KAAK,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,QAAQ,CAAC;IAExC,oEAAoE;IACpE,QAAQ,EAAE,iBAAiB,CAAC;IAE5B;;;;;;;OAOG;IACH,KAAK,CAAC,EAAE,UAAU,CAAC;IAEnB,sFAAsF;IACtF,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAE3B;;;;;;;;;OASG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC,SAAS,KAAK,IAAI,CAAC;IAExD;;;;OAIG;IACH,OAAO,CAAC,EAAE;QAAE,CAAC,UAAU,EAAE,MAAM,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAA;KAAE,CAAC;CACnE"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* useActor — React hook for accessing the raw actor inside a PlayRenderer tree.
|
|
3
|
+
*
|
|
4
|
+
* Components rendered inside PlayRenderer can call useActor() to get direct
|
|
5
|
+
* access to the actor instance without prop drilling.
|
|
6
|
+
*
|
|
7
|
+
* @throws {Error} If called outside a PlayRenderer tree
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```typescript
|
|
11
|
+
* import { useActor } from "@xmachines/play-react";
|
|
12
|
+
*
|
|
13
|
+
* function MyComponent() {
|
|
14
|
+
* const actor = useActor();
|
|
15
|
+
* return <button onClick={() => actor.send({ type: "SUBMIT" })}>Submit</button>;
|
|
16
|
+
* }
|
|
17
|
+
* ```
|
|
18
|
+
*
|
|
19
|
+
* @packageDocumentation
|
|
20
|
+
*/
|
|
21
|
+
import type { AbstractActor } from "@xmachines/play-actor";
|
|
22
|
+
import type { AnyActorLogic } from "xstate";
|
|
23
|
+
export type PlayActor = AbstractActor<AnyActorLogic>;
|
|
24
|
+
export declare const ActorContext: import("react").Context<PlayActor | null>;
|
|
25
|
+
export declare function useActor(): PlayActor;
|
|
26
|
+
//# sourceMappingURL=useActor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useActor.d.ts","sourceRoot":"","sources":["../src/useActor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAE5C,MAAM,MAAM,SAAS,GAAG,aAAa,CAAC,aAAa,CAAC,CAAC;AAErD,eAAO,MAAM,YAAY,2CAAwC,CAAC;AAElE,wBAAgB,QAAQ,IAAI,SAAS,CAIpC"}
|
package/dist/useActor.js
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* useActor — React hook for accessing the raw actor inside a PlayRenderer tree.
|
|
3
|
+
*
|
|
4
|
+
* Components rendered inside PlayRenderer can call useActor() to get direct
|
|
5
|
+
* access to the actor instance without prop drilling.
|
|
6
|
+
*
|
|
7
|
+
* @throws {Error} If called outside a PlayRenderer tree
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```typescript
|
|
11
|
+
* import { useActor } from "@xmachines/play-react";
|
|
12
|
+
*
|
|
13
|
+
* function MyComponent() {
|
|
14
|
+
* const actor = useActor();
|
|
15
|
+
* return <button onClick={() => actor.send({ type: "SUBMIT" })}>Submit</button>;
|
|
16
|
+
* }
|
|
17
|
+
* ```
|
|
18
|
+
*
|
|
19
|
+
* @packageDocumentation
|
|
20
|
+
*/
|
|
21
|
+
import { createContext, useContext } from "react";
|
|
22
|
+
export const ActorContext = createContext(null);
|
|
23
|
+
export function useActor() {
|
|
24
|
+
const actor = useContext(ActorContext);
|
|
25
|
+
if (!actor)
|
|
26
|
+
throw new Error("useActor() must be called inside <PlayRenderer>");
|
|
27
|
+
return actor;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=useActor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useActor.js","sourceRoot":"","sources":["../src/useActor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAMlD,MAAM,CAAC,MAAM,YAAY,GAAG,aAAa,CAAmB,IAAI,CAAC,CAAC;AAElE,MAAM,UAAU,QAAQ;IACvB,MAAM,KAAK,GAAG,UAAU,CAAC,YAAY,CAAC,CAAC;IACvC,IAAI,CAAC,KAAK;QAAE,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;IAC/E,OAAO,KAAK,CAAC;AACd,CAAC"}
|