@xmachines/play-dom 1.0.0-beta.16

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.
@@ -0,0 +1,58 @@
1
+ /**
2
+ * PlayRenderer.ts — XMachines wrapper around the pure dom-renderer layer.
3
+ *
4
+ * Bridges actor.currentView (TC39 Signal) to the inner DOM renderer using watchSignal.
5
+ * Exposes connect() / disconnect() methods following the same pattern as
6
+ * play-react, play-vue, and play-solid PlayRenderer classes.
7
+ *
8
+ * State store: uses external `store` option if provided (controlled mode); otherwise
9
+ * creates a fresh @xstate/store atom per view transition seeded from spec.state.
10
+ */
11
+ import type { AbstractActor, Viewable } from "@xmachines/play-actor";
12
+ import type { AnyActorLogic } from "xstate";
13
+ import type { DomRegistry, PlayDomOptions } from "./types.js";
14
+ /**
15
+ * PlayRenderer connects an actor's currentView signal to the DOM renderer.
16
+ *
17
+ * Usage:
18
+ * ```typescript
19
+ * const renderer = new PlayRenderer(container, actor, registry, { actions: { ... } });
20
+ * renderer.connect();
21
+ *
22
+ * // Controlled mode — bring your own store:
23
+ * import { createAtom } from "@xstate/store";
24
+ * import { xstateStoreStateStore } from "@json-render/xstate";
25
+ * const store = xstateStoreStateStore({ atom: createAtom({ username: "" }) });
26
+ * const renderer = new PlayRenderer(container, actor, registry, { store, actions: { ... } });
27
+ *
28
+ * // Later:
29
+ * renderer.disconnect();
30
+ * ```
31
+ */
32
+ export declare class PlayRenderer {
33
+ private readonly container;
34
+ private readonly actor;
35
+ private readonly registry;
36
+ private readonly options;
37
+ private _unwatch;
38
+ /**
39
+ * @param container - The `HTMLElement` to render into. Cleared and repopulated on every view transition.
40
+ * @param actor - Actor instance providing the `currentView` signal (must implement `Viewable`).
41
+ * @param registry - Map of component type names to `DomComponentRenderer` functions.
42
+ * @param options - Optional configuration: `actions` map (action name → XState event type) and
43
+ * optional external `store` (controlled mode — when omitted, a fresh `@xstate/store` atom is
44
+ * created per view transition seeded from `spec.state`).
45
+ */
46
+ constructor(container: HTMLElement, actor: AbstractActor<AnyActorLogic> & Viewable, registry: DomRegistry, options?: PlayDomOptions);
47
+ /**
48
+ * Start watching actor.currentView and render to container.
49
+ * Renders the initial view synchronously, then subscribes to signal changes.
50
+ */
51
+ connect(): void;
52
+ /**
53
+ * Stop watching and clear the container.
54
+ */
55
+ disconnect(): void;
56
+ private _render;
57
+ }
58
+ //# sourceMappingURL=PlayRenderer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PlayRenderer.d.ts","sourceRoot":"","sources":["../src/PlayRenderer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAMH,OAAO,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAgB,MAAM,uBAAuB,CAAC;AACnF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAE5C,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE9D;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,YAAY;IAYvB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAdzB,OAAO,CAAC,QAAQ,CAA6B;IAE7C;;;;;;;OAOG;gBAEe,SAAS,EAAE,WAAW,EACtB,KAAK,EAAE,aAAa,CAAC,aAAa,CAAC,GAAG,QAAQ,EAC9C,QAAQ,EAAE,WAAW,EACrB,OAAO,GAAE,cAAmB;IAG9C;;;OAGG;IACH,OAAO,IAAI,IAAI;IAKf;;OAEG;IACH,UAAU,IAAI,IAAI;IAMlB,OAAO,CAAC,OAAO;CA8Bf"}
@@ -0,0 +1,91 @@
1
+ /**
2
+ * PlayRenderer.ts — XMachines wrapper around the pure dom-renderer layer.
3
+ *
4
+ * Bridges actor.currentView (TC39 Signal) to the inner DOM renderer using watchSignal.
5
+ * Exposes connect() / disconnect() methods following the same pattern as
6
+ * play-react, play-vue, and play-solid PlayRenderer classes.
7
+ *
8
+ * State store: uses external `store` option if provided (controlled mode); otherwise
9
+ * creates a fresh @xstate/store atom per view transition seeded from spec.state.
10
+ */
11
+ import { watchSignal } from "@xmachines/play-signals";
12
+ import { createAtom } from "@xstate/store";
13
+ import { xstateStoreStateStore } from "@json-render/xstate";
14
+ import { renderSpec } from "./dom-renderer.js";
15
+ /**
16
+ * PlayRenderer connects an actor's currentView signal to the DOM renderer.
17
+ *
18
+ * Usage:
19
+ * ```typescript
20
+ * const renderer = new PlayRenderer(container, actor, registry, { actions: { ... } });
21
+ * renderer.connect();
22
+ *
23
+ * // Controlled mode — bring your own store:
24
+ * import { createAtom } from "@xstate/store";
25
+ * import { xstateStoreStateStore } from "@json-render/xstate";
26
+ * const store = xstateStoreStateStore({ atom: createAtom({ username: "" }) });
27
+ * const renderer = new PlayRenderer(container, actor, registry, { store, actions: { ... } });
28
+ *
29
+ * // Later:
30
+ * renderer.disconnect();
31
+ * ```
32
+ */
33
+ export class PlayRenderer {
34
+ container;
35
+ actor;
36
+ registry;
37
+ options;
38
+ _unwatch = null;
39
+ /**
40
+ * @param container - The `HTMLElement` to render into. Cleared and repopulated on every view transition.
41
+ * @param actor - Actor instance providing the `currentView` signal (must implement `Viewable`).
42
+ * @param registry - Map of component type names to `DomComponentRenderer` functions.
43
+ * @param options - Optional configuration: `actions` map (action name → XState event type) and
44
+ * optional external `store` (controlled mode — when omitted, a fresh `@xstate/store` atom is
45
+ * created per view transition seeded from `spec.state`).
46
+ */
47
+ constructor(container, actor, registry, options = {}) {
48
+ this.container = container;
49
+ this.actor = actor;
50
+ this.registry = registry;
51
+ this.options = options;
52
+ }
53
+ /**
54
+ * Start watching actor.currentView and render to container.
55
+ * Renders the initial view synchronously, then subscribes to signal changes.
56
+ */
57
+ connect() {
58
+ this._render(this.actor.currentView.get());
59
+ this._unwatch = watchSignal(this.actor.currentView, (view) => this._render(view));
60
+ }
61
+ /**
62
+ * Stop watching and clear the container.
63
+ */
64
+ disconnect() {
65
+ this._unwatch?.();
66
+ this._unwatch = null;
67
+ this.container.replaceChildren();
68
+ }
69
+ _render(view) {
70
+ this.container.replaceChildren();
71
+ if (!view)
72
+ return;
73
+ // Resolve the store: external (controlled) or fresh per-view atom
74
+ const store = this.options.store
75
+ ? this.options.store
76
+ : xstateStoreStateStore({
77
+ atom: createAtom(view.spec.state ?? {}),
78
+ });
79
+ const send = this.actor.send.bind(this.actor);
80
+ const actorActions = this.options.actions ?? {};
81
+ const rerender = () => {
82
+ this.container.replaceChildren();
83
+ const node = renderSpec(view.spec, store, this.registry, send, this.actor, actorActions);
84
+ if (node)
85
+ this.container.appendChild(node);
86
+ };
87
+ store.subscribe(rerender);
88
+ rerender();
89
+ }
90
+ }
91
+ //# sourceMappingURL=PlayRenderer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PlayRenderer.js","sourceRoot":"","sources":["../src/PlayRenderer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAEtD,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAG5D,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAG/C;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,OAAO,YAAY;IAYN;IACA;IACA;IACA;IAdV,QAAQ,GAAwB,IAAI,CAAC;IAE7C;;;;;;;OAOG;IACH,YACkB,SAAsB,EACtB,KAA8C,EAC9C,QAAqB,EACrB,UAA0B,EAAE;QAH5B,cAAS,GAAT,SAAS,CAAa;QACtB,UAAK,GAAL,KAAK,CAAyC;QAC9C,aAAQ,GAAR,QAAQ,CAAa;QACrB,YAAO,GAAP,OAAO,CAAqB;IAC3C,CAAC;IAEJ;;;OAGG;IACH,OAAO;QACN,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE,CAAC,CAAC;QAC3C,IAAI,CAAC,QAAQ,GAAG,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IACnF,CAAC;IAED;;OAEG;IACH,UAAU;QACT,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAC;QAClB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACrB,IAAI,CAAC,SAAS,CAAC,eAAe,EAAE,CAAC;IAClC,CAAC;IAEO,OAAO,CAAC,IAAyB;QACxC,IAAI,CAAC,SAAS,CAAC,eAAe,EAAE,CAAC;QACjC,IAAI,CAAC,IAAI;YAAE,OAAO;QAElB,kEAAkE;QAClE,MAAM,KAAK,GAAe,IAAI,CAAC,OAAO,CAAC,KAAK;YAC3C,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK;YACpB,CAAC,CAAC,qBAAqB,CAAC;gBACtB,IAAI,EAAE,UAAU,CAAE,IAAI,CAAC,IAAI,CAAC,KAAiC,IAAI,EAAE,CAAC;aACpE,CAAC,CAAC;QAEL,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC9C,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,IAAI,EAAE,CAAC;QAEhD,MAAM,QAAQ,GAAG,GAAS,EAAE;YAC3B,IAAI,CAAC,SAAS,CAAC,eAAe,EAAE,CAAC;YACjC,MAAM,IAAI,GAAG,UAAU,CACtB,IAAI,CAAC,IAAI,EACT,KAAK,EACL,IAAI,CAAC,QAAQ,EACb,IAAI,EACJ,IAAI,CAAC,KAAK,EACV,YAAY,CACZ,CAAC;YACF,IAAI,IAAI;gBAAE,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QAC5C,CAAC,CAAC;QAEF,KAAK,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;QAC1B,QAAQ,EAAE,CAAC;IACZ,CAAC;CACD"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * connect-renderer.ts — Backward compatibility wrapper around PlayRenderer.
3
+ *
4
+ * Provides the original `connectRenderer()` function API for consumers that
5
+ * have not yet migrated to the PlayRenderer class-based API.
6
+ *
7
+ * The implementation delegates entirely to PlayRenderer.
8
+ */
9
+ import type { ConnectRendererOptions } from "./types.js";
10
+ /**
11
+ * Connect a signal-driven DOM renderer to an actor's currentView signal.
12
+ *
13
+ * Subscribes to `actor.currentView` via TC39 Signals and renders `DomComponentRenderer`
14
+ * functions into the provided `container` element on every state change.
15
+ *
16
+ * - Renders the initial view immediately (synchronous)
17
+ * - Re-renders when `actor.currentView` signal changes (via microtask)
18
+ * - Clears container when view is `null` (optionally appends fallback)
19
+ *
20
+ * @param options - ConnectRendererOptions
21
+ * @returns A cleanup function that stops all DOM mutations
22
+ *
23
+ * @example
24
+ * ```typescript
25
+ * import { connectRenderer, type DomComponentRenderer } from "@xmachines/play-dom";
26
+ *
27
+ * const unwatch = connectRenderer({
28
+ * actor,
29
+ * registry: {
30
+ * Home: (element, ctx) => {
31
+ * const el = document.createElement("div");
32
+ * el.textContent = element.props.title as string;
33
+ * return el;
34
+ * },
35
+ * },
36
+ * container: document.getElementById("app")!,
37
+ * });
38
+ *
39
+ * // Later: stop watching
40
+ * unwatch();
41
+ * ```
42
+ */
43
+ export declare function connectRenderer(options: ConnectRendererOptions): () => void;
44
+ //# sourceMappingURL=connect-renderer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connect-renderer.d.ts","sourceRoot":"","sources":["../src/connect-renderer.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAEzD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,sBAAsB,GAAG,MAAM,IAAI,CAiB3E"}
@@ -0,0 +1,54 @@
1
+ /**
2
+ * connect-renderer.ts — Backward compatibility wrapper around PlayRenderer.
3
+ *
4
+ * Provides the original `connectRenderer()` function API for consumers that
5
+ * have not yet migrated to the PlayRenderer class-based API.
6
+ *
7
+ * The implementation delegates entirely to PlayRenderer.
8
+ */
9
+ import { PlayRenderer } from "./PlayRenderer.js";
10
+ /**
11
+ * Connect a signal-driven DOM renderer to an actor's currentView signal.
12
+ *
13
+ * Subscribes to `actor.currentView` via TC39 Signals and renders `DomComponentRenderer`
14
+ * functions into the provided `container` element on every state change.
15
+ *
16
+ * - Renders the initial view immediately (synchronous)
17
+ * - Re-renders when `actor.currentView` signal changes (via microtask)
18
+ * - Clears container when view is `null` (optionally appends fallback)
19
+ *
20
+ * @param options - ConnectRendererOptions
21
+ * @returns A cleanup function that stops all DOM mutations
22
+ *
23
+ * @example
24
+ * ```typescript
25
+ * import { connectRenderer, type DomComponentRenderer } from "@xmachines/play-dom";
26
+ *
27
+ * const unwatch = connectRenderer({
28
+ * actor,
29
+ * registry: {
30
+ * Home: (element, ctx) => {
31
+ * const el = document.createElement("div");
32
+ * el.textContent = element.props.title as string;
33
+ * return el;
34
+ * },
35
+ * },
36
+ * container: document.getElementById("app")!,
37
+ * });
38
+ *
39
+ * // Later: stop watching
40
+ * unwatch();
41
+ * ```
42
+ */
43
+ export function connectRenderer(options) {
44
+ const playDomOptions = options.actions ? { actions: options.actions } : {};
45
+ const renderer = new PlayRenderer(options.container, options.actor, options.registry, playDomOptions);
46
+ renderer.connect();
47
+ // Handle fallback for null view (backward compat)
48
+ // If container is empty after initial render, append fallback
49
+ if (options.fallback && options.container.children.length === 0) {
50
+ options.container.appendChild(options.fallback);
51
+ }
52
+ return () => renderer.disconnect();
53
+ }
54
+ //# sourceMappingURL=connect-renderer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connect-renderer.js","sourceRoot":"","sources":["../src/connect-renderer.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAGjD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,MAAM,UAAU,eAAe,CAAC,OAA+B;IAC9D,MAAM,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAC3E,MAAM,QAAQ,GAAG,IAAI,YAAY,CAChC,OAAO,CAAC,SAAS,EACjB,OAAO,CAAC,KAAK,EACb,OAAO,CAAC,QAAQ,EAChB,cAAc,CACd,CAAC;IACF,QAAQ,CAAC,OAAO,EAAE,CAAC;IAEnB,kDAAkD;IAClD,8DAA8D;IAC9D,IAAI,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACjE,OAAO,CAAC,SAAS,CAAC,WAAW,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACjD,CAAC;IAED,OAAO,GAAG,EAAE,CAAC,QAAQ,CAAC,UAAU,EAAE,CAAC;AACpC,CAAC"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * dom-renderer.ts — Pure json-render-core compatible DOM renderer.
3
+ *
4
+ * Zero XMachines dependencies. Takes a Spec + StateStore + DomRegistry
5
+ * and produces DOM nodes.
6
+ *
7
+ * This layer is upstreamable to @json-render/dom as a PR to vercel-labs/json-render.
8
+ */
9
+ import type { Spec, StateStore } from "@json-render/core";
10
+ import type { DomRegistry, DomRenderContext } from "./types.js";
11
+ /**
12
+ * Render a Spec tree into DOM nodes using the provided DomRegistry.
13
+ *
14
+ * @param spec - The json-render Spec describing the UI tree
15
+ * @param store - StateStore holding the current state values
16
+ * @param registry - Map of element type names to DomComponentRenderer functions
17
+ * @param send - Function to dispatch XState events from UI interactions
18
+ * @param actor - Raw actor — available to DOM components for state reading, complex events
19
+ * @param actorActions - Map of json-render action names → XState event types
20
+ * @returns The root DOM node, or null if root element is invisible or unknown
21
+ */
22
+ export declare function renderSpec(spec: Spec, store: StateStore, registry: DomRegistry, send: DomRenderContext["send"], actor: DomRenderContext["actor"], actorActions: Record<string, string>): Node | null;
23
+ //# sourceMappingURL=dom-renderer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dom-renderer.d.ts","sourceRoot":"","sources":["../src/dom-renderer.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,IAAI,EAAE,UAAU,EAAa,MAAM,mBAAmB,CAAC;AAErE,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEhE;;;;;;;;;;GAUG;AACH,wBAAgB,UAAU,CACzB,IAAI,EAAE,IAAI,EACV,KAAK,EAAE,UAAU,EACjB,QAAQ,EAAE,WAAW,EACrB,IAAI,EAAE,gBAAgB,CAAC,MAAM,CAAC,EAC9B,KAAK,EAAE,gBAAgB,CAAC,OAAO,CAAC,EAChC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAClC,IAAI,GAAG,IAAI,CAsDb"}
@@ -0,0 +1,103 @@
1
+ /**
2
+ * dom-renderer.ts — Pure json-render-core compatible DOM renderer.
3
+ *
4
+ * Zero XMachines dependencies. Takes a Spec + StateStore + DomRegistry
5
+ * and produces DOM nodes.
6
+ *
7
+ * This layer is upstreamable to @json-render/dom as a PR to vercel-labs/json-render.
8
+ */
9
+ import { evaluateVisibility, resolveDynamicValue } from "@json-render/core";
10
+ import { resolveProps } from "./resolve-state.js";
11
+ /**
12
+ * Render a Spec tree into DOM nodes using the provided DomRegistry.
13
+ *
14
+ * @param spec - The json-render Spec describing the UI tree
15
+ * @param store - StateStore holding the current state values
16
+ * @param registry - Map of element type names to DomComponentRenderer functions
17
+ * @param send - Function to dispatch XState events from UI interactions
18
+ * @param actor - Raw actor — available to DOM components for state reading, complex events
19
+ * @param actorActions - Map of json-render action names → XState event types
20
+ * @returns The root DOM node, or null if root element is invisible or unknown
21
+ */
22
+ export function renderSpec(spec, store, registry, send, actor, actorActions) {
23
+ function renderElement(key) {
24
+ const element = spec.elements[key];
25
+ if (!element)
26
+ return null;
27
+ // Evaluate visibility condition
28
+ if (element.visible !== undefined) {
29
+ const stateModel = store.getSnapshot();
30
+ const visible = evaluateVisibility(element.visible, { stateModel });
31
+ if (!visible)
32
+ return null;
33
+ }
34
+ // Resolve $state expressions in props
35
+ const resolvedProps = resolveProps(element.props ?? {}, store);
36
+ // Build context for this element
37
+ const ctx = {
38
+ spec,
39
+ store,
40
+ send,
41
+ actor,
42
+ actorActions,
43
+ renderChildren: (keys) => keys.flatMap((k) => {
44
+ const n = renderElement(k);
45
+ return n ? [n] : [];
46
+ }),
47
+ };
48
+ // Look up renderer in registry
49
+ const renderer = registry[element.type];
50
+ if (!renderer)
51
+ return null; // unknown type → null (matches json-render behavior)
52
+ // Create resolved element to pass to renderer
53
+ const resolvedElement = { ...element, props: resolvedProps };
54
+ const node = renderer(resolvedElement, ctx);
55
+ if (!node)
56
+ return null;
57
+ // Wire event handlers from element.on
58
+ if (element.on && node instanceof HTMLElement) {
59
+ wireEventHandlers(node, element.on, ctx);
60
+ }
61
+ // Append children into the node if it has children and is an HTMLElement
62
+ const childKeys = element.children ?? [];
63
+ if (childKeys.length > 0 && node instanceof HTMLElement) {
64
+ const childNodes = ctx.renderChildren(childKeys);
65
+ childNodes.forEach((child) => node.appendChild(child));
66
+ }
67
+ return node;
68
+ }
69
+ return renderElement(spec.root);
70
+ }
71
+ /**
72
+ * Wire event handlers from element.on bindings to DOM event listeners.
73
+ *
74
+ * Maps json-render event names to DOM events (e.g. "click" → "click").
75
+ * For each binding, checks actorActions map to find the XState event type.
76
+ * If found, calls send() with that event type on the DOM event.
77
+ */
78
+ function wireEventHandlers(node, on, ctx) {
79
+ if (!on)
80
+ return;
81
+ for (const [domEvent, binding] of Object.entries(on)) {
82
+ // binding can be ActionBinding | ActionBinding[]
83
+ const bindings = Array.isArray(binding) ? binding : [binding];
84
+ node.addEventListener(domEvent, () => {
85
+ for (const b of bindings) {
86
+ const eventType = ctx.actorActions[b.action];
87
+ if (eventType) {
88
+ // Resolve DynamicValue params ($state:/ references) against current store
89
+ const stateModel = ctx.store.getSnapshot();
90
+ const resolvedParams = {};
91
+ if (b.params) {
92
+ for (const [key, val] of Object.entries(b.params)) {
93
+ resolvedParams[key] = resolveDynamicValue(val, stateModel);
94
+ }
95
+ }
96
+ ctx.send({ type: eventType, ...resolvedParams });
97
+ }
98
+ // Unknown action → no-op (matches json-render silent behavior)
99
+ }
100
+ });
101
+ }
102
+ }
103
+ //# sourceMappingURL=dom-renderer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dom-renderer.js","sourceRoot":"","sources":["../src/dom-renderer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ import { PlayError } from "@xmachines/play";
2
+ /**
3
+ * Thrown by `connectRenderer` when the `components` option is `null` or `undefined`.
4
+ *
5
+ * A missing catalog is a programmer error — the components map must be provided
6
+ * to the renderer. The `componentName` that was being looked up is encoded in
7
+ * the error message.
8
+ *
9
+ * **Error code:** `PLAY_RENDERER_MISSING_CATALOG`
10
+ *
11
+ * @example
12
+ * ```typescript
13
+ * import { MissingCatalogError } from "@xmachines/play-dom";
14
+ *
15
+ * // In a catch block:
16
+ * if (err instanceof MissingCatalogError) {
17
+ * console.error("components option was not provided to connectRenderer()");
18
+ * }
19
+ * ```
20
+ */
21
+ export declare class MissingCatalogError extends PlayError {
22
+ constructor(componentName: string, catalogValue: null | undefined);
23
+ }
24
+ /**
25
+ * Thrown by `connectRenderer` when the component name from `actor.currentView` does
26
+ * not exist as a key in the `components` catalog.
27
+ *
28
+ * This is a programmer error — either the machine's `meta.view.component` name is
29
+ * misspelled, or the component was not registered in the catalog passed to the renderer.
30
+ *
31
+ * **Error code:** `PLAY_RENDERER_MISSING_COMPONENT`
32
+ *
33
+ * @example
34
+ * ```typescript
35
+ * import { MissingComponentError } from "@xmachines/play-dom";
36
+ *
37
+ * if (err instanceof MissingComponentError) {
38
+ * // err.message lists both the missing name and available components
39
+ * console.error(err.message);
40
+ * }
41
+ * ```
42
+ */
43
+ export declare class MissingComponentError extends PlayError {
44
+ constructor(componentName: string, availableComponents: string[]);
45
+ }
46
+ //# 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;;;;;;;;;;;;;;;;;;GAkBG;AACH,qBAAa,mBAAoB,SAAQ,SAAS;gBACrC,aAAa,EAAE,MAAM,EAAE,YAAY,EAAE,IAAI,GAAG,SAAS;CAQjE;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,qBAAa,qBAAsB,SAAQ,SAAS;gBACvC,aAAa,EAAE,MAAM,EAAE,mBAAmB,EAAE,MAAM,EAAE;CAQhE"}
package/dist/errors.js ADDED
@@ -0,0 +1,52 @@
1
+ import { PlayError } from "@xmachines/play";
2
+ /**
3
+ * Thrown by `connectRenderer` when the `components` option is `null` or `undefined`.
4
+ *
5
+ * A missing catalog is a programmer error — the components map must be provided
6
+ * to the renderer. The `componentName` that was being looked up is encoded in
7
+ * the error message.
8
+ *
9
+ * **Error code:** `PLAY_RENDERER_MISSING_CATALOG`
10
+ *
11
+ * @example
12
+ * ```typescript
13
+ * import { MissingCatalogError } from "@xmachines/play-dom";
14
+ *
15
+ * // In a catch block:
16
+ * if (err instanceof MissingCatalogError) {
17
+ * console.error("components option was not provided to connectRenderer()");
18
+ * }
19
+ * ```
20
+ */
21
+ export class MissingCatalogError extends PlayError {
22
+ constructor(componentName, catalogValue) {
23
+ super("PlayRenderer", "PLAY_RENDERER_MISSING_CATALOG", `Components catalog is ${catalogValue === null ? "null" : "undefined"}. Cannot render component "${componentName}".`);
24
+ this.name = "MissingCatalogError";
25
+ }
26
+ }
27
+ /**
28
+ * Thrown by `connectRenderer` when the component name from `actor.currentView` does
29
+ * not exist as a key in the `components` catalog.
30
+ *
31
+ * This is a programmer error — either the machine's `meta.view.component` name is
32
+ * misspelled, or the component was not registered in the catalog passed to the renderer.
33
+ *
34
+ * **Error code:** `PLAY_RENDERER_MISSING_COMPONENT`
35
+ *
36
+ * @example
37
+ * ```typescript
38
+ * import { MissingComponentError } from "@xmachines/play-dom";
39
+ *
40
+ * if (err instanceof MissingComponentError) {
41
+ * // err.message lists both the missing name and available components
42
+ * console.error(err.message);
43
+ * }
44
+ * ```
45
+ */
46
+ export class MissingComponentError extends PlayError {
47
+ constructor(componentName, availableComponents) {
48
+ super("PlayRenderer", "PLAY_RENDERER_MISSING_COMPONENT", `Component "${componentName}" not found in catalog. Available components: ${availableComponents.join(", ")}`);
49
+ this.name = "MissingComponentError";
50
+ }
51
+ }
52
+ //# 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;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,OAAO,mBAAoB,SAAQ,SAAS;IACjD,YAAY,aAAqB,EAAE,YAA8B;QAChE,KAAK,CACJ,cAAc,EACd,+BAA+B,EAC/B,yBAAyB,YAAY,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,8BAA8B,aAAa,IAAI,CACpH,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAC;IACnC,CAAC;CACD;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,OAAO,qBAAsB,SAAQ,SAAS;IACnD,YAAY,aAAqB,EAAE,mBAA6B;QAC/D,KAAK,CACJ,cAAc,EACd,iCAAiC,EACjC,cAAc,aAAa,iDAAiD,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC5G,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,uBAAuB,CAAC;IACrC,CAAC;CACD"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * @xmachines/play-dom - Vanilla DOM renderer for XMachines Play architecture
3
+ *
4
+ * Provides a two-layer architecture:
5
+ * - Inner layer (dom-renderer): Pure json-render-core compatible DOM renderer.
6
+ * Zero XMachines dependencies. Upstreamable to @json-render/dom.
7
+ * - Outer layer (PlayRenderer): XMachines wrapper. Bridges actor.currentView
8
+ * (TC39 Signal) to the inner DOM renderer using watchSignal.
9
+ *
10
+ * Also provides connectRenderer() as a backward-compat convenience function.
11
+ *
12
+ * No framework required. Pure DOM APIs only.
13
+ *
14
+ * @packageDocumentation
15
+ */
16
+ export { connectRenderer } from "./connect-renderer.js";
17
+ export { PlayRenderer } from "./PlayRenderer.js";
18
+ export { renderSpec } from "./dom-renderer.js";
19
+ export type { DomComponentRenderer, DomRegistry, DomRenderContext, ConnectRendererOptions, PlayDomOptions, } from "./types.js";
20
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,YAAY,EACX,oBAAoB,EACpB,WAAW,EACX,gBAAgB,EAChB,sBAAsB,EACtB,cAAc,GACd,MAAM,YAAY,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,19 @@
1
+ /**
2
+ * @xmachines/play-dom - Vanilla DOM renderer for XMachines Play architecture
3
+ *
4
+ * Provides a two-layer architecture:
5
+ * - Inner layer (dom-renderer): Pure json-render-core compatible DOM renderer.
6
+ * Zero XMachines dependencies. Upstreamable to @json-render/dom.
7
+ * - Outer layer (PlayRenderer): XMachines wrapper. Bridges actor.currentView
8
+ * (TC39 Signal) to the inner DOM renderer using watchSignal.
9
+ *
10
+ * Also provides connectRenderer() as a backward-compat convenience function.
11
+ *
12
+ * No framework required. Pure DOM APIs only.
13
+ *
14
+ * @packageDocumentation
15
+ */
16
+ export { connectRenderer } from "./connect-renderer.js";
17
+ export { PlayRenderer } from "./PlayRenderer.js";
18
+ export { renderSpec } from "./dom-renderer.js";
19
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * resolve-state.ts — Resolves json-render dynamic value expressions against a StateStore.
3
+ *
4
+ * Pure function — no XMachines dependencies. Upstreamable to @json-render/dom.
5
+ */
6
+ import type { StateStore } from "@json-render/core";
7
+ /**
8
+ * Resolve all props in an element's props object.
9
+ * Returns a new props object with all $state expressions resolved against the store.
10
+ */
11
+ export declare function resolveProps(props: Record<string, unknown>, store: StateStore): Record<string, unknown>;
12
+ //# sourceMappingURL=resolve-state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve-state.d.ts","sourceRoot":"","sources":["../src/resolve-state.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAEpD;;;GAGG;AACH,wBAAgB,YAAY,CAC3B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,KAAK,EAAE,UAAU,GACf,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAMzB"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * resolve-state.ts — Resolves json-render dynamic value expressions against a StateStore.
3
+ *
4
+ * Pure function — no XMachines dependencies. Upstreamable to @json-render/dom.
5
+ */
6
+ /**
7
+ * Resolve all props in an element's props object.
8
+ * Returns a new props object with all $state expressions resolved against the store.
9
+ */
10
+ export function resolveProps(props, store) {
11
+ const result = {};
12
+ for (const [key, value] of Object.entries(props)) {
13
+ result[key] = resolveValue(value, store);
14
+ }
15
+ return result;
16
+ }
17
+ /**
18
+ * Resolve a single value that may contain json-render dynamic expressions.
19
+ * - `{ "$state": "/path" }` → store.get("/path")
20
+ * - Arrays → each element resolved recursively
21
+ * - Nested objects → each value resolved recursively
22
+ * - Plain values → returned as-is
23
+ */
24
+ function resolveValue(value, store) {
25
+ if (value === null || typeof value !== "object")
26
+ return value;
27
+ if (Array.isArray(value))
28
+ return value.map((v) => resolveValue(v, store));
29
+ const obj = value;
30
+ // $state binding: { "$state": "/path" }
31
+ if ("$state" in obj && typeof obj["$state"] === "string") {
32
+ return store.get(obj["$state"]);
33
+ }
34
+ // Nested plain object — recurse
35
+ const resolved = {};
36
+ for (const [k, v] of Object.entries(obj)) {
37
+ resolved[k] = resolveValue(v, store);
38
+ }
39
+ return resolved;
40
+ }
41
+ //# sourceMappingURL=resolve-state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve-state.js","sourceRoot":"","sources":["../src/resolve-state.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH;;;GAGG;AACH,MAAM,UAAU,YAAY,CAC3B,KAA8B,EAC9B,KAAiB;IAEjB,MAAM,MAAM,GAA4B,EAAE,CAAC;IAC3C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAClD,MAAM,CAAC,GAAG,CAAC,GAAG,YAAY,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IAC1C,CAAC;IACD,OAAO,MAAM,CAAC;AACf,CAAC;AAED;;;;;;GAMG;AACH,SAAS,YAAY,CAAC,KAAc,EAAE,KAAiB;IACtD,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC9D,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC;IAE1E,MAAM,GAAG,GAAG,KAAgC,CAAC;IAE7C,wCAAwC;IACxC,IAAI,QAAQ,IAAI,GAAG,IAAI,OAAO,GAAG,CAAC,QAAQ,CAAC,KAAK,QAAQ,EAAE,CAAC;QAC1D,OAAO,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC;IACjC,CAAC;IAED,gCAAgC;IAChC,MAAM,QAAQ,GAA4B,EAAE,CAAC;IAC7C,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QAC1C,QAAQ,CAAC,CAAC,CAAC,GAAG,YAAY,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IACtC,CAAC;IACD,OAAO,QAAQ,CAAC;AACjB,CAAC"}
@@ -0,0 +1,73 @@
1
+ /**
2
+ * TypeScript type definitions for play-dom
3
+ *
4
+ * @packageDocumentation
5
+ */
6
+ import type { Spec, UIElement, StateStore } from "@json-render/core";
7
+ import type { AbstractActor, Viewable } from "@xmachines/play-actor";
8
+ import type { AnyActorLogic } from "xstate";
9
+ /**
10
+ * Context passed to each DomComponentRenderer when rendering an element.
11
+ */
12
+ export interface DomRenderContext {
13
+ /** Full spec tree */
14
+ spec: Spec;
15
+ /** State store bound to spec.state */
16
+ store: StateStore;
17
+ /** Send an event to the actor */
18
+ send: (event: {
19
+ type: string;
20
+ } & Record<string, unknown>) => void;
21
+ /** Raw actor — access from any DOM component for state reading, complex events, lifecycle */
22
+ actor: AbstractActor<AnyActorLogic> & Viewable;
23
+ /** Map of json-render action names → XState event types */
24
+ actorActions: Record<string, string>;
25
+ /** Recursively render child elements by key */
26
+ renderChildren: (keys: string[]) => Node[];
27
+ }
28
+ /**
29
+ * Pure DOM component renderer — receives a UIElement + context and returns a DOM node.
30
+ * No framework required. Return null for unknown/unsupported elements.
31
+ */
32
+ export type DomComponentRenderer = (element: UIElement, ctx: DomRenderContext) => HTMLElement | Text | null;
33
+ /**
34
+ * Registry of component renderers keyed by element type.
35
+ */
36
+ export type DomRegistry = Record<string, DomComponentRenderer>;
37
+ /**
38
+ * Options for PlayRenderer.
39
+ */
40
+ export interface PlayDomOptions {
41
+ /** Map of json-render actionName → XState event type */
42
+ actions?: Record<string, string>;
43
+ /**
44
+ * Optional external StateStore (e.g. from `xstateStoreStateStore` in @json-render/xstate).
45
+ * When provided, PlayRenderer operates in controlled mode — spec.state is ignored and
46
+ * this store is the single source of truth for UI state (form values, etc.).
47
+ * When omitted, a fresh @xstate/store atom is created internally per view transition,
48
+ * seeded from spec.state.
49
+ */
50
+ store?: StateStore;
51
+ }
52
+ /**
53
+ * Options for connectRenderer() — backward compat API.
54
+ */
55
+ export interface ConnectRendererOptions {
56
+ /** Actor instance with currentView signal (requires Viewable capability) */
57
+ actor: AbstractActor<AnyActorLogic> & Viewable;
58
+ /** Registry of component renderers — replaces old `components` map */
59
+ registry: DomRegistry;
60
+ /** Container element to render into */
61
+ container: HTMLElement;
62
+ /** Optional element shown when currentView is null (defaults to nothing — clears container) */
63
+ fallback?: HTMLElement | null;
64
+ /** Map of json-render actionName → XState event type */
65
+ actions?: Record<string, string>;
66
+ /**
67
+ * Optional external StateStore (e.g. from `xstateStoreStateStore` in @json-render/xstate).
68
+ * When provided, PlayRenderer operates in controlled mode — spec.state is ignored.
69
+ * When omitted, a fresh @xstate/store atom is created internally per view transition.
70
+ */
71
+ store?: StateStore;
72
+ }
73
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACrE,OAAO,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACrE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAE5C;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAChC,qBAAqB;IACrB,IAAI,EAAE,IAAI,CAAC;IACX,sCAAsC;IACtC,KAAK,EAAE,UAAU,CAAC;IAClB,iCAAiC;IACjC,IAAI,EAAE,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;IAClE,6FAA6F;IAC7F,KAAK,EAAE,aAAa,CAAC,aAAa,CAAC,GAAG,QAAQ,CAAC;IAC/C,2DAA2D;IAC3D,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,+CAA+C;IAC/C,cAAc,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,IAAI,EAAE,CAAC;CAC3C;AAED;;;GAGG;AACH,MAAM,MAAM,oBAAoB,GAAG,CAClC,OAAO,EAAE,SAAS,EAClB,GAAG,EAAE,gBAAgB,KACjB,WAAW,GAAG,IAAI,GAAG,IAAI,CAAC;AAE/B;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC;AAE/D;;GAEG;AACH,MAAM,WAAW,cAAc;IAC9B,wDAAwD;IACxD,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEjC;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,UAAU,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACtC,4EAA4E;IAC5E,KAAK,EAAE,aAAa,CAAC,aAAa,CAAC,GAAG,QAAQ,CAAC;IAE/C,sEAAsE;IACtE,QAAQ,EAAE,WAAW,CAAC;IAEtB,uCAAuC;IACvC,SAAS,EAAE,WAAW,CAAC;IAEvB,+FAA+F;IAC/F,QAAQ,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;IAE9B,wDAAwD;IACxD,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEjC;;;;OAIG;IACH,KAAK,CAAC,EAAE,UAAU,CAAC;CACnB"}
package/dist/types.js ADDED
@@ -0,0 +1,7 @@
1
+ /**
2
+ * TypeScript type definitions for play-dom
3
+ *
4
+ * @packageDocumentation
5
+ */
6
+ export {};
7
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
package/package.json ADDED
@@ -0,0 +1,62 @@
1
+ {
2
+ "name": "@xmachines/play-dom",
3
+ "version": "1.0.0-beta.16",
4
+ "description": "Vanilla DOM renderer for XMachines Play architecture with signal-driven rendering",
5
+ "keywords": [
6
+ "actor",
7
+ "dom",
8
+ "renderer",
9
+ "signals",
10
+ "state-machine",
11
+ "ui",
12
+ "xmachines"
13
+ ],
14
+ "license": "MIT",
15
+ "author": "XMachines Contributors",
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "git@gitlab.com:xmachin-es/xmachines-js.git",
19
+ "directory": "packages/play-dom"
20
+ },
21
+ "files": [
22
+ "dist",
23
+ "README.md",
24
+ "LICENSE"
25
+ ],
26
+ "type": "module",
27
+ "exports": {
28
+ ".": {
29
+ "types": "./dist/index.d.ts",
30
+ "import": "./dist/index.js"
31
+ }
32
+ },
33
+ "publishConfig": {
34
+ "access": "public"
35
+ },
36
+ "scripts": {
37
+ "build": "tsc --build",
38
+ "clean": "rm -rf dist *.tsbuildinfo",
39
+ "typecheck": "tsc --noEmit",
40
+ "test": "vitest",
41
+ "prepublishOnly": "npm run build"
42
+ },
43
+ "dependencies": {
44
+ "@xmachines/play": "1.0.0-beta.16",
45
+ "@xmachines/play-actor": "1.0.0-beta.16",
46
+ "@xmachines/play-signals": "1.0.0-beta.16"
47
+ },
48
+ "devDependencies": {
49
+ "@json-render/core": "^0.16.0",
50
+ "@json-render/xstate": "^0.16.0",
51
+ "@types/node": "^25.5.0",
52
+ "@xmachines/shared": "1.0.0-beta.16",
53
+ "@xstate/store": ">=3.17.0",
54
+ "typescript": "^5.9.3 || ^6.0.2",
55
+ "vitest": "^4.1.2"
56
+ },
57
+ "peerDependencies": {
58
+ "@json-render/core": "^0.16.0",
59
+ "@json-render/xstate": "^0.16.0",
60
+ "@xstate/store": ">=3.17.0"
61
+ }
62
+ }