@xmachines/play-dom 1.0.0-beta.26 → 1.0.0-beta.28

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.
Files changed (40) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +51 -0
  3. package/dist/PlayRenderer.d.ts +3 -2
  4. package/dist/PlayRenderer.d.ts.map +1 -1
  5. package/dist/PlayRenderer.js +3 -3
  6. package/dist/PlayRenderer.js.map +1 -1
  7. package/dist/connect-renderer.d.ts +1 -1
  8. package/dist/connect-renderer.d.ts.map +1 -1
  9. package/dist/index.d.ts +19 -10
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/index.js +19 -9
  12. package/dist/index.js.map +1 -1
  13. package/dist/json-render/index.d.ts +17 -0
  14. package/dist/json-render/index.d.ts.map +1 -0
  15. package/dist/json-render/index.js +16 -0
  16. package/dist/json-render/index.js.map +1 -0
  17. package/dist/json-render/renderer.d.ts +52 -0
  18. package/dist/json-render/renderer.d.ts.map +1 -0
  19. package/dist/json-render/renderer.js +101 -0
  20. package/dist/json-render/renderer.js.map +1 -0
  21. package/dist/json-render/types.d.ts +311 -0
  22. package/dist/json-render/types.d.ts.map +1 -0
  23. package/dist/json-render/types.js +116 -0
  24. package/dist/json-render/types.js.map +1 -0
  25. package/dist/{types.d.ts → xm-types.d.ts} +7 -31
  26. package/dist/xm-types.d.ts.map +1 -0
  27. package/dist/xm-types.js +10 -0
  28. package/dist/xm-types.js.map +1 -0
  29. package/package.json +5 -5
  30. package/dist/dom-renderer.d.ts +0 -23
  31. package/dist/dom-renderer.d.ts.map +0 -1
  32. package/dist/dom-renderer.js +0 -103
  33. package/dist/dom-renderer.js.map +0 -1
  34. package/dist/resolve-state.d.ts +0 -12
  35. package/dist/resolve-state.d.ts.map +0 -1
  36. package/dist/resolve-state.js +0 -41
  37. package/dist/resolve-state.js.map +0 -1
  38. package/dist/types.d.ts.map +0 -1
  39. package/dist/types.js +0 -7
  40. package/dist/types.js.map +0 -1
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Mikael Karon
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,51 @@
1
+ # @xmachines/play-dom
2
+
3
+ **Vanilla DOM renderer for XMachines**
4
+
5
+ `connectRenderer` — a framework-free `PlayRenderer` equivalent that wires an XState v5 actor's `currentView` TC39 Signal to pure DOM rendering via a catalog-typed `DomRegistry`.
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ npm install @xmachines/play-dom
11
+ ```
12
+
13
+ ## Key Exports
14
+
15
+ - `connectRenderer({ actor, registry, container })` — connect actor view signal to DOM
16
+ - `defineRegistry(catalog, { components, actions })` — build a catalog-typed `DomRegistry`
17
+ - `PlayRenderer` — class-based renderer (connect/disconnect lifecycle)
18
+ - `ComponentFn<C, K>` — catalog-typed DOM component function type
19
+ - `ComponentContext<C, K>` — context passed to each `ComponentFn` (props, emit, on, children, bindings)
20
+ - `renderSpec(spec, store, registry, send, actorActions)` — pure Spec → DOM renderer
21
+
22
+ ## Usage
23
+
24
+ ```ts
25
+ import { definePlayer } from "@xmachines/play-xstate";
26
+ import { connectRenderer, defineRegistry } from "@xmachines/play-dom";
27
+ import { authMachine, authCatalog, type AuthCatalog } from "@xmachines/play-actor-shared";
28
+ import type { ComponentFn } from "@xmachines/play-dom";
29
+
30
+ const Home: ComponentFn<AuthCatalog, "Home"> = ({ props }) => {
31
+ const el = document.createElement("section");
32
+ el.textContent = props.title;
33
+ return el;
34
+ };
35
+
36
+ const { registry } = defineRegistry(authCatalog, {
37
+ components: { Home /* ... */ },
38
+ actions: { login: "auth.login", logout: "auth.logout" },
39
+ });
40
+
41
+ const createPlayer = definePlayer({ machine: authMachine });
42
+ const actor = createPlayer();
43
+ actor.start();
44
+
45
+ const container = document.getElementById("app")!;
46
+ const disconnect = connectRenderer({ actor, registry, container });
47
+ ```
48
+
49
+ ## Learn More
50
+
51
+ - [DOM Router adapter `@xmachines/play-dom-router`](../play-dom-router/README.md)
@@ -1,5 +1,5 @@
1
1
  /**
2
- * PlayRenderer.ts — XMachines wrapper around the pure dom-renderer layer.
2
+ * PlayRenderer.ts — XMachines wrapper around the pure json-render/dom renderer layer.
3
3
  *
4
4
  * Bridges actor.currentView (TC39 Signal) to the inner DOM renderer using watchSignal.
5
5
  * Exposes connect() / disconnect() methods following the same pattern as
@@ -10,7 +10,8 @@
10
10
  */
11
11
  import type { AbstractActor, Viewable } from "@xmachines/play-actor";
12
12
  import type { AnyActorLogic } from "xstate";
13
- import type { DomRegistry, PlayDomOptions } from "./types.js";
13
+ import type { DomRegistry } from "./json-render/types.js";
14
+ import type { PlayDomOptions } from "./xm-types.js";
14
15
  /**
15
16
  * PlayRenderer connects an actor's currentView signal to the DOM renderer.
16
17
  *
@@ -1 +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;IAavB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAfzB,OAAO,CAAC,QAAQ,CAA6B;IAC7C,OAAO,CAAC,iBAAiB,CAA6B;IAEtD;;;;;;;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;IAQlB,OAAO,CAAC,OAAO;CAkCf"}
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,MAAM,wBAAwB,CAAC;AAC1D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEpD;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,YAAY;IAavB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAfzB,OAAO,CAAC,QAAQ,CAA6B;IAC7C,OAAO,CAAC,iBAAiB,CAA6B;IAEtD;;;;;;;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;IAQlB,OAAO,CAAC,OAAO;CA2Bf"}
@@ -1,5 +1,5 @@
1
1
  /**
2
- * PlayRenderer.ts — XMachines wrapper around the pure dom-renderer layer.
2
+ * PlayRenderer.ts — XMachines wrapper around the pure json-render/dom renderer layer.
3
3
  *
4
4
  * Bridges actor.currentView (TC39 Signal) to the inner DOM renderer using watchSignal.
5
5
  * Exposes connect() / disconnect() methods following the same pattern as
@@ -11,7 +11,7 @@
11
11
  import { watchSignal } from "@xmachines/play-signals";
12
12
  import { createAtom } from "@xstate/store";
13
13
  import { xstateStoreStateStore } from "@json-render/xstate";
14
- import { renderSpec } from "./dom-renderer.js";
14
+ import { renderSpec } from "./json-render/renderer.js";
15
15
  /**
16
16
  * PlayRenderer connects an actor's currentView signal to the DOM renderer.
17
17
  *
@@ -86,7 +86,7 @@ export class PlayRenderer {
86
86
  const actorActions = this.options.actions ?? {};
87
87
  const rerender = () => {
88
88
  this.container.replaceChildren();
89
- const node = renderSpec(view.spec, store, this.registry, send, this.actor, actorActions);
89
+ const node = renderSpec(view.spec, store, this.registry, send, actorActions);
90
90
  if (node)
91
91
  this.container.appendChild(node);
92
92
  };
@@ -1 +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;IAaN;IACA;IACA;IACA;IAfV,QAAQ,GAAwB,IAAI,CAAC;IACrC,iBAAiB,GAAwB,IAAI,CAAC;IAEtD;;;;;;;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,iBAAiB,EAAE,EAAE,CAAC;QAC3B,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC;QAC9B,IAAI,CAAC,SAAS,CAAC,eAAe,EAAE,CAAC;IAClC,CAAC;IAEO,OAAO,CAAC,IAAyB;QACxC,2DAA2D;QAC3D,IAAI,CAAC,iBAAiB,EAAE,EAAE,CAAC;QAC3B,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC;QAE9B,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,IAAI,CAAC,iBAAiB,GAAG,KAAK,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;QACnD,QAAQ,EAAE,CAAC;IACZ,CAAC;CACD"}
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,2BAA2B,CAAC;AAIvD;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,OAAO,YAAY;IAaN;IACA;IACA;IACA;IAfV,QAAQ,GAAwB,IAAI,CAAC;IACrC,iBAAiB,GAAwB,IAAI,CAAC;IAEtD;;;;;;;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,iBAAiB,EAAE,EAAE,CAAC;QAC3B,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC;QAC9B,IAAI,CAAC,SAAS,CAAC,eAAe,EAAE,CAAC;IAClC,CAAC;IAEO,OAAO,CAAC,IAAyB;QACxC,2DAA2D;QAC3D,IAAI,CAAC,iBAAiB,EAAE,EAAE,CAAC;QAC3B,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC;QAE9B,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,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,QAAQ,EAAE,IAAI,EAAE,YAAY,CAAC,CAAC;YAC7E,IAAI,IAAI;gBAAE,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QAC5C,CAAC,CAAC;QAEF,IAAI,CAAC,iBAAiB,GAAG,KAAK,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;QACnD,QAAQ,EAAE,CAAC;IACZ,CAAC;CACD"}
@@ -6,7 +6,7 @@
6
6
  *
7
7
  * The implementation delegates entirely to PlayRenderer.
8
8
  */
9
- import type { ConnectRendererOptions } from "./types.js";
9
+ import type { ConnectRendererOptions } from "./xm-types.js";
10
10
  /**
11
11
  * Connect a signal-driven DOM renderer to an actor's currentView signal.
12
12
  *
@@ -1 +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"}
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,eAAe,CAAC;AAE5D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,sBAAsB,GAAG,MAAM,IAAI,CAiB3E"}
package/dist/index.d.ts CHANGED
@@ -1,20 +1,29 @@
1
1
  /**
2
- * @xmachines/play-dom - Vanilla DOM renderer for XMachines Play architecture
2
+ * @xmachines/play-dom Vanilla DOM renderer for XMachines Play architecture.
3
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.
4
+ * Public API split into two layers:
9
5
  *
10
- * Also provides connectRenderer() as a backward-compat convenience function.
6
+ * **XMachines layer** (this package):
7
+ * - `PlayRenderer` — connects actor.currentView signal → DOM renderer
8
+ * - `connectRenderer()` — backward-compat functional API
9
+ * - `ConnectRendererOptions`, `PlayDomOptions`
11
10
  *
12
- * No framework required. Pure DOM APIs only.
11
+ * **json-render layer** (upstreamable to @json-render/dom):
12
+ * - `defineRegistry` — build a catalog-typed DomRegistry
13
+ * - `renderSpec` — pure Spec → DOM renderer (uses resolveElementProps from core)
14
+ * - `ComponentFn` — catalog-typed component function type
15
+ * - `ComponentContext` — catalog-typed render context (props, emit, on, children, bindings)
16
+ * - `ComponentRegistry` — catalog-typed registry input type
17
+ * - `DomComponentRenderer` — raw element-level renderer type
18
+ * - `DomRegistry` — raw registry type
19
+ * - `DomRenderContext` — raw render context
20
+ * - `EventHandle` — event handle returned by on()
13
21
  *
14
22
  * @packageDocumentation
15
23
  */
16
24
  export { connectRenderer } from "./connect-renderer.js";
17
25
  export { PlayRenderer } from "./PlayRenderer.js";
18
- export { renderSpec } from "./dom-renderer.js";
19
- export type { DomComponentRenderer, DomRegistry, DomRenderContext, ConnectRendererOptions, PlayDomOptions, } from "./types.js";
26
+ export type { ConnectRendererOptions, PlayDomOptions } from "./xm-types.js";
27
+ export { defineRegistry, renderSpec } from "./json-render/index.js";
28
+ export type { EventHandle, DomRenderContext, DomComponentRenderer, ComponentContext, ComponentFn, ComponentRegistry, DefineRegistryOptions, DefineRegistryResult, DomRegistry, } from "./json-render/index.js";
20
29
  //# sourceMappingURL=index.d.ts.map
@@ -1 +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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAGH,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAGjD,YAAY,EAAE,sBAAsB,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAG5E,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpE,YAAY,EACX,WAAW,EACX,gBAAgB,EAChB,oBAAoB,EACpB,gBAAgB,EAChB,WAAW,EACX,iBAAiB,EACjB,qBAAqB,EACrB,oBAAoB,EACpB,WAAW,GACX,MAAM,wBAAwB,CAAC"}
package/dist/index.js CHANGED
@@ -1,19 +1,29 @@
1
1
  /**
2
- * @xmachines/play-dom - Vanilla DOM renderer for XMachines Play architecture
2
+ * @xmachines/play-dom Vanilla DOM renderer for XMachines Play architecture.
3
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.
4
+ * Public API split into two layers:
9
5
  *
10
- * Also provides connectRenderer() as a backward-compat convenience function.
6
+ * **XMachines layer** (this package):
7
+ * - `PlayRenderer` — connects actor.currentView signal → DOM renderer
8
+ * - `connectRenderer()` — backward-compat functional API
9
+ * - `ConnectRendererOptions`, `PlayDomOptions`
11
10
  *
12
- * No framework required. Pure DOM APIs only.
11
+ * **json-render layer** (upstreamable to @json-render/dom):
12
+ * - `defineRegistry` — build a catalog-typed DomRegistry
13
+ * - `renderSpec` — pure Spec → DOM renderer (uses resolveElementProps from core)
14
+ * - `ComponentFn` — catalog-typed component function type
15
+ * - `ComponentContext` — catalog-typed render context (props, emit, on, children, bindings)
16
+ * - `ComponentRegistry` — catalog-typed registry input type
17
+ * - `DomComponentRenderer` — raw element-level renderer type
18
+ * - `DomRegistry` — raw registry type
19
+ * - `DomRenderContext` — raw render context
20
+ * - `EventHandle` — event handle returned by on()
13
21
  *
14
22
  * @packageDocumentation
15
23
  */
24
+ // XMachines integration layer
16
25
  export { connectRenderer } from "./connect-renderer.js";
17
26
  export { PlayRenderer } from "./PlayRenderer.js";
18
- export { renderSpec } from "./dom-renderer.js";
27
+ // json-render/dom layer (re-exported for consumer convenience)
28
+ export { defineRegistry, renderSpec } from "./json-render/index.js";
19
29
  //# 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;;;;;;;;;;;;;;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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,8BAA8B;AAC9B,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAKjD,+DAA+D;AAC/D,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * @json-render/dom barrel — re-exports all upstreamable DOM renderer code.
3
+ *
4
+ * This directory contains everything that belongs in a future @json-render/dom package:
5
+ * - types.ts — DomRenderContext, DomComponentRenderer, ComponentFn, ComponentContext,
6
+ * ComponentRegistry, DomRegistry, EventHandle, DefineRegistryOptions,
7
+ * DefineRegistryResult, defineRegistry
8
+ * - renderer.ts — renderSpec (pure Spec → DOM, uses resolveElementProps from @json-render/core)
9
+ *
10
+ * Zero XMachines dependencies. All XMachines integration lives in the parent src/ layer.
11
+ *
12
+ * @packageDocumentation
13
+ */
14
+ export { renderSpec } from "./renderer.js";
15
+ export { defineRegistry } from "./types.js";
16
+ export type { EventHandle, DomRenderContext, DomComponentRenderer, ComponentContext, ComponentFn, ComponentRegistry, DefineRegistryOptions, DefineRegistryResult, DomRegistry, } from "./types.js";
17
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/json-render/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,YAAY,EACX,WAAW,EACX,gBAAgB,EAChB,oBAAoB,EACpB,gBAAgB,EAChB,WAAW,EACX,iBAAiB,EACjB,qBAAqB,EACrB,oBAAoB,EACpB,WAAW,GACX,MAAM,YAAY,CAAC"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * @json-render/dom barrel — re-exports all upstreamable DOM renderer code.
3
+ *
4
+ * This directory contains everything that belongs in a future @json-render/dom package:
5
+ * - types.ts — DomRenderContext, DomComponentRenderer, ComponentFn, ComponentContext,
6
+ * ComponentRegistry, DomRegistry, EventHandle, DefineRegistryOptions,
7
+ * DefineRegistryResult, defineRegistry
8
+ * - renderer.ts — renderSpec (pure Spec → DOM, uses resolveElementProps from @json-render/core)
9
+ *
10
+ * Zero XMachines dependencies. All XMachines integration lives in the parent src/ layer.
11
+ *
12
+ * @packageDocumentation
13
+ */
14
+ export { renderSpec } from "./renderer.js";
15
+ export { defineRegistry } from "./types.js";
16
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/json-render/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * renderer.ts — Pure json-render-core compatible DOM renderer.
3
+ *
4
+ * Zero XMachines dependencies. Upstreamable to @json-render/dom.
5
+ *
6
+ * Implements the same element-rendering contract as the framework renderers
7
+ * (@json-render/react, /solid, /svelte, /vue):
8
+ *
9
+ * - Props resolved via `resolveElementProps` from `@json-render/core` (handles
10
+ * `$state`, `$item`, `$index`, `$bindState`, `$bindItem`, `$cond`, `$computed`,
11
+ * `$template` — the full expression set, not just `$state`)
12
+ * - Visibility evaluated via `evaluateVisibility` from `@json-render/core`
13
+ * - Event handling is done **once**, inside the `defineRegistry` component
14
+ * wrapper via the `emit`/`on` closures — `renderSpec` does NOT attach additional
15
+ * DOM event listeners (eliminates the double-dispatch bug)
16
+ * - Children are rendered and passed to the component function as `ctx.children`
17
+ * — `renderSpec` does NOT append them again after the component returns
18
+ * (eliminates the double-append bug)
19
+ *
20
+ * @packageDocumentation
21
+ */
22
+ import type { Spec, StateStore } from "@json-render/core";
23
+ import type { DomRegistry, DomRenderContext } from "./types.js";
24
+ /**
25
+ * Render a Spec tree into DOM nodes using the provided `DomRegistry`.
26
+ *
27
+ * Traverses the spec from `spec.root`, evaluates visibility, resolves all prop
28
+ * expressions (including `$state`, `$bindState`, `$computed`, `$template`, etc.),
29
+ * and calls the matching `DomComponentRenderer` for each visible element.
30
+ *
31
+ * Event wiring and child rendering are handled inside the component wrapper
32
+ * built by `defineRegistry` — this function only orchestrates the traversal.
33
+ *
34
+ * @param spec - The json-render `Spec` describing the UI tree.
35
+ * @param store - Live `StateStore` bound to `spec.state`.
36
+ * @param registry - Map of element type names → `DomComponentRenderer`.
37
+ * @param send - Dispatcher for interaction events (e.g. actor.send).
38
+ * @param actorActions - Map of catalog action names → event type strings.
39
+ * @returns The root DOM `Node`, or `null` if the root is invisible
40
+ * or has no registered renderer.
41
+ *
42
+ * @example
43
+ * ```ts
44
+ * const node = renderSpec(spec, store, registry, actor.send.bind(actor), {
45
+ * login: "auth.login",
46
+ * logout: "auth.logout",
47
+ * });
48
+ * if (node) container.appendChild(node);
49
+ * ```
50
+ */
51
+ export declare function renderSpec(spec: Spec, store: StateStore, registry: DomRegistry, send: DomRenderContext["send"], actorActions: Record<string, string>): Node | null;
52
+ //# sourceMappingURL=renderer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"renderer.d.ts","sourceRoot":"","sources":["../../src/json-render/renderer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAGH,OAAO,KAAK,EAAE,IAAI,EAAE,UAAU,EAAa,MAAM,mBAAmB,CAAC;AACrE,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEhE;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,UAAU,CACzB,IAAI,EAAE,IAAI,EACV,KAAK,EAAE,UAAU,EACjB,QAAQ,EAAE,WAAW,EACrB,IAAI,EAAE,gBAAgB,CAAC,MAAM,CAAC,EAC9B,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAClC,IAAI,GAAG,IAAI,CAyDb"}
@@ -0,0 +1,101 @@
1
+ /**
2
+ * renderer.ts — Pure json-render-core compatible DOM renderer.
3
+ *
4
+ * Zero XMachines dependencies. Upstreamable to @json-render/dom.
5
+ *
6
+ * Implements the same element-rendering contract as the framework renderers
7
+ * (@json-render/react, /solid, /svelte, /vue):
8
+ *
9
+ * - Props resolved via `resolveElementProps` from `@json-render/core` (handles
10
+ * `$state`, `$item`, `$index`, `$bindState`, `$bindItem`, `$cond`, `$computed`,
11
+ * `$template` — the full expression set, not just `$state`)
12
+ * - Visibility evaluated via `evaluateVisibility` from `@json-render/core`
13
+ * - Event handling is done **once**, inside the `defineRegistry` component
14
+ * wrapper via the `emit`/`on` closures — `renderSpec` does NOT attach additional
15
+ * DOM event listeners (eliminates the double-dispatch bug)
16
+ * - Children are rendered and passed to the component function as `ctx.children`
17
+ * — `renderSpec` does NOT append them again after the component returns
18
+ * (eliminates the double-append bug)
19
+ *
20
+ * @packageDocumentation
21
+ */
22
+ import { evaluateVisibility, resolveBindings, resolveElementProps } from "@json-render/core";
23
+ /**
24
+ * Render a Spec tree into DOM nodes using the provided `DomRegistry`.
25
+ *
26
+ * Traverses the spec from `spec.root`, evaluates visibility, resolves all prop
27
+ * expressions (including `$state`, `$bindState`, `$computed`, `$template`, etc.),
28
+ * and calls the matching `DomComponentRenderer` for each visible element.
29
+ *
30
+ * Event wiring and child rendering are handled inside the component wrapper
31
+ * built by `defineRegistry` — this function only orchestrates the traversal.
32
+ *
33
+ * @param spec - The json-render `Spec` describing the UI tree.
34
+ * @param store - Live `StateStore` bound to `spec.state`.
35
+ * @param registry - Map of element type names → `DomComponentRenderer`.
36
+ * @param send - Dispatcher for interaction events (e.g. actor.send).
37
+ * @param actorActions - Map of catalog action names → event type strings.
38
+ * @returns The root DOM `Node`, or `null` if the root is invisible
39
+ * or has no registered renderer.
40
+ *
41
+ * @example
42
+ * ```ts
43
+ * const node = renderSpec(spec, store, registry, actor.send.bind(actor), {
44
+ * login: "auth.login",
45
+ * logout: "auth.logout",
46
+ * });
47
+ * if (node) container.appendChild(node);
48
+ * ```
49
+ */
50
+ export function renderSpec(spec, store, registry, send, actorActions) {
51
+ function renderElement(key) {
52
+ const element = spec.elements[key];
53
+ if (!element)
54
+ return null;
55
+ const stateModel = store.getSnapshot();
56
+ // ── Visibility ────────────────────────────────────────────────────────
57
+ // Matches framework behavior: invisible elements are not rendered.
58
+ if (element.visible !== undefined) {
59
+ const visible = evaluateVisibility(element.visible, { stateModel });
60
+ if (!visible)
61
+ return null;
62
+ }
63
+ const rawProps = element.props ?? {};
64
+ // ── Bindings (before prop resolution) ────────────────────────────────
65
+ // resolveBindings must run on raw props — after resolveElementProps the
66
+ // $bindState/$bindItem expressions are replaced with resolved values.
67
+ const elementBindings = resolveBindings(rawProps, { stateModel }) ?? undefined;
68
+ // ── Prop resolution ───────────────────────────────────────────────────
69
+ // Use resolveElementProps from @json-render/core — handles the full
70
+ // DynamicValue expression set ($state, $item, $index, $bindState,
71
+ // $bindItem, $cond/$then/$else, $computed, $template).
72
+ // This replaces the former local resolveProps which only handled $state.
73
+ const resolvedProps = resolveElementProps(rawProps, { stateModel });
74
+ // ── DomRenderContext ──────────────────────────────────────────────────
75
+ // Build the context passed to DomComponentRenderer functions.
76
+ // renderChildren recurses into this same renderElement function.
77
+ const ctx = {
78
+ spec,
79
+ store,
80
+ send,
81
+ actorActions,
82
+ elementBindings,
83
+ renderChildren: (keys) => keys.flatMap((k) => {
84
+ const n = renderElement(k);
85
+ return n ? [n] : [];
86
+ }),
87
+ };
88
+ // ── Renderer lookup ───────────────────────────────────────────────────
89
+ const renderer = registry[element.type];
90
+ if (!renderer)
91
+ return null; // unknown type → null (matches framework behavior)
92
+ // ── Render ────────────────────────────────────────────────────────────
93
+ // Pass the resolved element. The component wrapper built by defineRegistry
94
+ // handles emit/on/children/bindings internally — do NOT wire events or
95
+ // append children here (doing so would double-fire and double-append).
96
+ const resolvedElement = { ...element, props: resolvedProps };
97
+ return renderer(resolvedElement, ctx);
98
+ }
99
+ return renderElement(spec.root);
100
+ }
101
+ //# sourceMappingURL=renderer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"renderer.js","sourceRoot":"","sources":["../../src/json-render/renderer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAI7F;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,UAAU,UAAU,CACzB,IAAU,EACV,KAAiB,EACjB,QAAqB,EACrB,IAA8B,EAC9B,YAAoC;IAEpC,SAAS,aAAa,CAAC,GAAW;QACjC,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;QACnC,IAAI,CAAC,OAAO;YAAE,OAAO,IAAI,CAAC;QAE1B,MAAM,UAAU,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;QAEvC,yEAAyE;QACzE,mEAAmE;QACnE,IAAI,OAAO,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YACnC,MAAM,OAAO,GAAG,kBAAkB,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,UAAU,EAAE,CAAC,CAAC;YACpE,IAAI,CAAC,OAAO;gBAAE,OAAO,IAAI,CAAC;QAC3B,CAAC;QAED,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC;QAErC,wEAAwE;QACxE,wEAAwE;QACxE,sEAAsE;QACtE,MAAM,eAAe,GAAG,eAAe,CAAC,QAAQ,EAAE,EAAE,UAAU,EAAE,CAAC,IAAI,SAAS,CAAC;QAE/E,yEAAyE;QACzE,oEAAoE;QACpE,kEAAkE;QAClE,uDAAuD;QACvD,yEAAyE;QACzE,MAAM,aAAa,GAAG,mBAAmB,CAAC,QAAQ,EAAE,EAAE,UAAU,EAAE,CAAC,CAAC;QAEpE,yEAAyE;QACzE,8DAA8D;QAC9D,iEAAiE;QACjE,MAAM,GAAG,GAAqB;YAC7B,IAAI;YACJ,KAAK;YACL,IAAI;YACJ,YAAY;YACZ,eAAe;YACf,cAAc,EAAE,CAAC,IAAc,EAAE,EAAE,CAClC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE;gBAClB,MAAM,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC;gBAC3B,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACrB,CAAC,CAAC;SACH,CAAC;QAEF,yEAAyE;QACzE,MAAM,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACxC,IAAI,CAAC,QAAQ;YAAE,OAAO,IAAI,CAAC,CAAC,mDAAmD;QAE/E,yEAAyE;QACzE,2EAA2E;QAC3E,uEAAuE;QACvE,uEAAuE;QACvE,MAAM,eAAe,GAAc,EAAE,GAAG,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,CAAC;QACxE,OAAO,QAAQ,CAAC,eAAe,EAAE,GAAG,CAAC,CAAC;IACvC,CAAC;IAED,OAAO,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACjC,CAAC"}
@@ -0,0 +1,311 @@
1
+ /**
2
+ * types.ts — Type definitions for @json-render/dom
3
+ *
4
+ * Zero XMachines dependencies. Upstreamable to @json-render/dom.
5
+ *
6
+ * Mirrors the component model from @json-render/react, /solid, /svelte, /vue:
7
+ * - `ComponentFn<C, K>` — catalog-typed component function
8
+ * - `ComponentContext<C, K>` — context passed to each component (props, children, emit, on, bindings)
9
+ * - `defineRegistry(catalog, options)` — build a catalog-typed DomRegistry
10
+ *
11
+ * Key difference from framework renderers: `ComponentFn` returns
12
+ * `HTMLElement | Text | null` instead of a framework node, and
13
+ * `actions` is a `Record<string, string>` event-type map instead of
14
+ * async handler functions (because DOM dispatches directly via `send`).
15
+ *
16
+ * @packageDocumentation
17
+ */
18
+ import type { Catalog, InferCatalogActions, InferCatalogComponents, InferComponentProps, Spec, StateStore, UIElement } from "@json-render/core";
19
+ /**
20
+ * Handle returned by `ComponentContext.on(eventName)`.
21
+ *
22
+ * Matches the `EventHandle` interface from @json-render/react, /solid, /svelte, /vue.
23
+ *
24
+ * @example
25
+ * ```ts
26
+ * const handle = on("submit");
27
+ * if (handle.bound) {
28
+ * btn.addEventListener("click", (e) => {
29
+ * if (handle.shouldPreventDefault) e.preventDefault();
30
+ * handle.emit();
31
+ * });
32
+ * }
33
+ * ```
34
+ */
35
+ export interface EventHandle {
36
+ /** Fire the bound action, resolving params from the current state store. */
37
+ emit: () => void;
38
+ /**
39
+ * Whether any binding for this event has `preventDefault: true`.
40
+ * Use to call `e.preventDefault()` on the triggering DOM event.
41
+ */
42
+ shouldPreventDefault: boolean;
43
+ /** `true` if an `on` binding exists for this event name; `false` otherwise. */
44
+ bound: boolean;
45
+ }
46
+ /**
47
+ * Low-level render context passed to each `DomComponentRenderer`.
48
+ *
49
+ * This is the raw renderer-level interface. Most component authors should use
50
+ * the higher-level `ComponentContext<C, K>` provided by `defineRegistry`.
51
+ */
52
+ export interface DomRenderContext {
53
+ /** Full spec tree for this render pass. */
54
+ spec: Spec;
55
+ /** Live state store bound to `spec.state`. */
56
+ store: StateStore;
57
+ /** Dispatch an event (e.g. to an XState actor). */
58
+ send: (event: {
59
+ type: string;
60
+ } & Record<string, unknown>) => void;
61
+ /** Map of json-render catalog action names → dispatch event type strings. */
62
+ actorActions: Record<string, string>;
63
+ /** Render a list of child element keys into DOM nodes. */
64
+ renderChildren: (keys: string[]) => Node[];
65
+ /**
66
+ * Pre-computed two-way binding paths for this element's props.
67
+ * Resolved from raw props before `resolveElementProps` runs — the resolved
68
+ * props no longer contain `$bindState`/`$bindItem` expressions.
69
+ * `undefined` when no binding expressions were found.
70
+ */
71
+ elementBindings?: Record<string, string> | undefined;
72
+ }
73
+ /**
74
+ * Raw DOM component renderer function.
75
+ *
76
+ * Receives a resolved `UIElement` and a `DomRenderContext`, and returns a DOM
77
+ * node or `null`. Prefer using `ComponentFn<C, K>` via `defineRegistry` for
78
+ * catalog-typed, framework-consistent components.
79
+ *
80
+ * @example
81
+ * ```ts
82
+ * const myRenderer: DomComponentRenderer = (element, ctx) => {
83
+ * const el = document.createElement("div");
84
+ * el.textContent = String(element.props.title ?? "");
85
+ * return el;
86
+ * };
87
+ * ```
88
+ */
89
+ export type DomComponentRenderer = (element: UIElement, ctx: DomRenderContext) => HTMLElement | Text | null;
90
+ /**
91
+ * Catalog-typed context passed to each DOM component function.
92
+ *
93
+ * Mirrors the `ComponentContext<C, K>` shape from @json-render/react, /solid,
94
+ * /svelte, /vue with three DOM-specific adaptations:
95
+ *
96
+ * - `children` is `Node[]` instead of a framework node/snippet/slot
97
+ * - `bindings` is `Record<string, string> | undefined` (path strings for DOM
98
+ * consumers that implement their own two-way binding, e.g. input value ↔ store)
99
+ * - `ctx` (low-level `DomRenderContext`) is exposed for advanced use cases
100
+ * (framework renderers do not expose this)
101
+ *
102
+ * @example
103
+ * ```ts
104
+ * const Login: ComponentFn<AuthCatalog, "Login"> = ({ props, emit, on, bindings }) => {
105
+ * const section = document.createElement("section");
106
+ *
107
+ * const input = document.createElement("input");
108
+ * input.value = props.username ?? "";
109
+ *
110
+ * // Two-way binding: write back to state store when input changes
111
+ * if (bindings?.username) {
112
+ * input.addEventListener("input", () => {
113
+ * // bindings.username contains the store path e.g. "/username"
114
+ * });
115
+ * }
116
+ *
117
+ * const btn = document.createElement("button");
118
+ * const handle = on("submit");
119
+ * btn.addEventListener("click", (e) => {
120
+ * if (handle.shouldPreventDefault) e.preventDefault();
121
+ * handle.emit();
122
+ * });
123
+ *
124
+ * section.append(input, btn);
125
+ * return section;
126
+ * };
127
+ * ```
128
+ */
129
+ export interface ComponentContext<C extends Catalog, K extends keyof InferCatalogComponents<C>> {
130
+ /** Catalog-typed, store-resolved props for this component. */
131
+ props: InferComponentProps<C, K>;
132
+ /**
133
+ * Rendered child nodes from the spec's `children` list.
134
+ * Append these into the returned element where children should appear.
135
+ */
136
+ children: Node[];
137
+ /**
138
+ * Two-way binding paths resolved from `$bindState` / `$bindItem` prop expressions.
139
+ *
140
+ * Keys match prop names that had `$bindState`/`$bindItem` expressions in the spec;
141
+ * values are the absolute state-store paths to write back to on user input.
142
+ *
143
+ * `undefined` when no bindings were found for this element.
144
+ */
145
+ bindings: Record<string, string> | undefined;
146
+ /**
147
+ * Dispatch a named event defined in the spec's `on` map.
148
+ *
149
+ * Resolves the catalog action binding, applies param expressions against the
150
+ * current state store, and calls `send()` with the mapped XState event type.
151
+ *
152
+ * @example
153
+ * ```ts
154
+ * btn.addEventListener("click", () => emit("submit"));
155
+ * ```
156
+ */
157
+ emit: (event: string) => void;
158
+ /**
159
+ * Get an `EventHandle` for a named event from the spec's `on` map.
160
+ *
161
+ * Use when you need `shouldPreventDefault` or want to check whether an `on`
162
+ * binding exists before attaching a listener.
163
+ *
164
+ * @example
165
+ * ```ts
166
+ * const handle = on("submit");
167
+ * if (handle.bound) {
168
+ * form.addEventListener("submit", (e) => {
169
+ * if (handle.shouldPreventDefault) e.preventDefault();
170
+ * handle.emit();
171
+ * });
172
+ * }
173
+ * ```
174
+ */
175
+ on: (event: string) => EventHandle;
176
+ /**
177
+ * Low-level render context.
178
+ *
179
+ * Exposes `send`, `store`, `actorActions`, and `renderChildren` for advanced
180
+ * use cases. Framework renderers do not expose this field — prefer `emit`/`on`
181
+ * for event dispatch and `children` for child rendering.
182
+ */
183
+ ctx: DomRenderContext;
184
+ }
185
+ /**
186
+ * Catalog-typed DOM component function.
187
+ *
188
+ * The DOM equivalent of `ComponentFn<C, K>` from @json-render/react, /solid,
189
+ * /svelte, /vue. The only structural difference is the return type:
190
+ * `HTMLElement | Text | null` instead of a framework node.
191
+ *
192
+ * Pass implementations to `defineRegistry` — do not call directly.
193
+ *
194
+ * @example
195
+ * ```ts
196
+ * import type { ComponentFn } from "@xmachines/play-dom";
197
+ * import type { AuthCatalog } from "@xmachines/play-actor-shared";
198
+ *
199
+ * export const Home: ComponentFn<AuthCatalog, "Home"> = ({ props, children }) => {
200
+ * const section = document.createElement("section");
201
+ * section.setAttribute("data-page", "home");
202
+ *
203
+ * const h2 = document.createElement("h2");
204
+ * h2.textContent = props.title;
205
+ * section.appendChild(h2);
206
+ *
207
+ * children.forEach((child) => section.appendChild(child));
208
+ * return section;
209
+ * };
210
+ * ```
211
+ */
212
+ export type ComponentFn<C extends Catalog, K extends keyof InferCatalogComponents<C>> = (ctx: ComponentContext<C, K>) => HTMLElement | Text | null;
213
+ /**
214
+ * Catalog-keyed map of `ComponentFn` implementations.
215
+ *
216
+ * Used as the `components` field in `DefineRegistryOptions`.
217
+ * TypeScript enforces that every component key declared in the catalog has
218
+ * a matching implementation.
219
+ */
220
+ export type ComponentRegistry<C extends Catalog> = {
221
+ [K in keyof InferCatalogComponents<C>]: ComponentFn<C, K>;
222
+ };
223
+ /**
224
+ * Raw registry of `DomComponentRenderer` functions keyed by element type.
225
+ *
226
+ * Passed to `connectRenderer` or `PlayRenderer`. Build with `defineRegistry`
227
+ * to get catalog-typed component functions automatically wrapped.
228
+ */
229
+ export type DomRegistry = Record<string, DomComponentRenderer>;
230
+ /**
231
+ * Options for `defineRegistry`.
232
+ *
233
+ * Mirrors `DefineRegistryOptions<C>` from @json-render/react, /solid, /svelte, /vue
234
+ * with one intentional difference: `actions` is a `Record<string, string>` event-type
235
+ * map rather than async handler functions, because the DOM renderer dispatches events
236
+ * directly via `send()` to an XState actor instead of calling framework action handlers.
237
+ */
238
+ export interface DefineRegistryOptions<C extends Catalog> {
239
+ /**
240
+ * Catalog-typed component implementations.
241
+ * Each key must match a component declared in the catalog.
242
+ */
243
+ components?: ComponentRegistry<C>;
244
+ /**
245
+ * Map of catalog action name → XState event type string.
246
+ *
247
+ * When a spec element fires `emit("login")`, the DOM renderer looks up
248
+ * `actions.login` (e.g. `"auth.login"`) and calls `send({ type: "auth.login", ...params })`.
249
+ *
250
+ * In the framework renderers this field holds async handler functions. In the DOM
251
+ * renderer it is a simpler string map because routing to the actor is handled by
252
+ * the XMachines play-dom layer rather than inside the json-render action system.
253
+ */
254
+ actions?: InferCatalogActions<C> extends Record<string, never> ? Record<string, string> : Record<keyof InferCatalogActions<C>, string>;
255
+ }
256
+ /**
257
+ * Result returned by `defineRegistry`.
258
+ *
259
+ * Mirrors the `{ registry }` field from @json-render/react, /solid, /svelte, /vue.
260
+ * The DOM result also exposes `actorActions` — the resolved event-type map — so
261
+ * callers can pass it directly to `connectRenderer` or `PlayRenderer`.
262
+ */
263
+ export interface DefineRegistryResult {
264
+ /**
265
+ * The built `DomRegistry`, ready to pass to `connectRenderer` or `PlayRenderer`.
266
+ */
267
+ registry: DomRegistry;
268
+ /**
269
+ * Resolved map of catalog action name → XState event type string.
270
+ *
271
+ * Pass to `connectRenderer({ ..., actions: actorActions })` or
272
+ * `new PlayRenderer(container, actor, registry, { actions: actorActions })`.
273
+ */
274
+ actorActions: Record<string, string>;
275
+ }
276
+ /**
277
+ * Build a `DomRegistry` from a catalog and component/action options.
278
+ *
279
+ * Mirrors the `defineRegistry(catalog, options)` API from @json-render/react,
280
+ * /solid, /svelte, /vue. The catalog parameter is used for TypeScript inference
281
+ * only (the same as in the framework renderers — it is not used at runtime).
282
+ *
283
+ * Each component in `options.components` is wrapped in a `DomComponentRenderer`
284
+ * adapter that:
285
+ * - Resolves props and two-way binding paths via `@json-render/core`
286
+ * - Builds `emit(event)` and `on(event)` closures over the element's `on` map
287
+ * - Renders child elements via `ctx.renderChildren`
288
+ * - Passes the assembled `ComponentContext` to your `ComponentFn`
289
+ *
290
+ * The `actions` map is passed through as `actorActions` so the caller does not
291
+ * need to manage it separately.
292
+ *
293
+ * @example
294
+ * ```ts
295
+ * import { defineRegistry } from "@xmachines/play-dom";
296
+ * import { authCatalog } from "@xmachines/play-actor-shared";
297
+ * import { Home, Login, Dashboard } from "./components/index.js";
298
+ *
299
+ * const { registry, actorActions } = defineRegistry(authCatalog, {
300
+ * components: { Home, Login, Dashboard, ... },
301
+ * actions: {
302
+ * login: "auth.login",
303
+ * logout: "auth.logout",
304
+ * },
305
+ * });
306
+ *
307
+ * connectRenderer({ actor, registry, container, actions: actorActions });
308
+ * ```
309
+ */
310
+ export declare function defineRegistry<C extends Catalog>(_catalog: C, options: DefineRegistryOptions<C>): DefineRegistryResult;
311
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/json-render/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,116 @@
1
+ /**
2
+ * types.ts — Type definitions for @json-render/dom
3
+ *
4
+ * Zero XMachines dependencies. Upstreamable to @json-render/dom.
5
+ *
6
+ * Mirrors the component model from @json-render/react, /solid, /svelte, /vue:
7
+ * - `ComponentFn<C, K>` — catalog-typed component function
8
+ * - `ComponentContext<C, K>` — context passed to each component (props, children, emit, on, bindings)
9
+ * - `defineRegistry(catalog, options)` — build a catalog-typed DomRegistry
10
+ *
11
+ * Key difference from framework renderers: `ComponentFn` returns
12
+ * `HTMLElement | Text | null` instead of a framework node, and
13
+ * `actions` is a `Record<string, string>` event-type map instead of
14
+ * async handler functions (because DOM dispatches directly via `send`).
15
+ *
16
+ * @packageDocumentation
17
+ */
18
+ import { resolveActionParam } from "@json-render/core";
19
+ /**
20
+ * Build a `DomRegistry` from a catalog and component/action options.
21
+ *
22
+ * Mirrors the `defineRegistry(catalog, options)` API from @json-render/react,
23
+ * /solid, /svelte, /vue. The catalog parameter is used for TypeScript inference
24
+ * only (the same as in the framework renderers — it is not used at runtime).
25
+ *
26
+ * Each component in `options.components` is wrapped in a `DomComponentRenderer`
27
+ * adapter that:
28
+ * - Resolves props and two-way binding paths via `@json-render/core`
29
+ * - Builds `emit(event)` and `on(event)` closures over the element's `on` map
30
+ * - Renders child elements via `ctx.renderChildren`
31
+ * - Passes the assembled `ComponentContext` to your `ComponentFn`
32
+ *
33
+ * The `actions` map is passed through as `actorActions` so the caller does not
34
+ * need to manage it separately.
35
+ *
36
+ * @example
37
+ * ```ts
38
+ * import { defineRegistry } from "@xmachines/play-dom";
39
+ * import { authCatalog } from "@xmachines/play-actor-shared";
40
+ * import { Home, Login, Dashboard } from "./components/index.js";
41
+ *
42
+ * const { registry, actorActions } = defineRegistry(authCatalog, {
43
+ * components: { Home, Login, Dashboard, ... },
44
+ * actions: {
45
+ * login: "auth.login",
46
+ * logout: "auth.logout",
47
+ * },
48
+ * });
49
+ *
50
+ * connectRenderer({ actor, registry, container, actions: actorActions });
51
+ * ```
52
+ */
53
+ export function defineRegistry(_catalog, options) {
54
+ const components = (options.components ?? {});
55
+ const actorActions = (options.actions ?? {});
56
+ const registry = {};
57
+ for (const key of Object.keys(components)) {
58
+ const fn = components[key];
59
+ registry[key] = (element, ctx) => {
60
+ const onBindings = element.on ?? {};
61
+ const stateModel = ctx.store.getSnapshot();
62
+ // ── emit ──────────────────────────────────────────────────────────
63
+ const emit = (eventName) => {
64
+ const binding = onBindings[eventName];
65
+ if (!binding)
66
+ return;
67
+ const bindings = Array.isArray(binding) ? binding : [binding];
68
+ for (const b of bindings) {
69
+ const xstateType = ctx.actorActions[b.action] ?? b.action;
70
+ const params = {};
71
+ if (b.params) {
72
+ for (const [k, v] of Object.entries(b.params)) {
73
+ params[k] = resolveActionParam(v, { stateModel });
74
+ }
75
+ }
76
+ ctx.send({ type: xstateType, ...params });
77
+ }
78
+ };
79
+ // ── on ────────────────────────────────────────────────────────────
80
+ const on = (eventName) => {
81
+ const binding = onBindings[eventName];
82
+ if (!binding) {
83
+ return { emit: () => { }, shouldPreventDefault: false, bound: false };
84
+ }
85
+ const bindings = Array.isArray(binding) ? binding : [binding];
86
+ return {
87
+ emit: () => emit(eventName),
88
+ // truthy check — matches @json-render/react and /solid
89
+ shouldPreventDefault: bindings.some((b) => b.preventDefault),
90
+ bound: true,
91
+ };
92
+ };
93
+ // ── bindings ──────────────────────────────────────────────────────
94
+ // Pre-computed by renderSpec on the raw (unresolved) props before
95
+ // resolveElementProps ran — $bindState/$bindItem expressions are
96
+ // no longer present in element.props at this point.
97
+ const bindings = ctx.elementBindings;
98
+ // ── children ──────────────────────────────────────────────────────
99
+ // Render children here (inside the wrapper) and pass them to the
100
+ // component. The outer renderSpec does NOT append children again —
101
+ // child rendering is solely the component's responsibility.
102
+ const children = ctx.renderChildren(element.children ?? []);
103
+ const componentCtx = {
104
+ props: element.props,
105
+ children,
106
+ bindings,
107
+ emit,
108
+ on,
109
+ ctx,
110
+ };
111
+ return fn(componentCtx);
112
+ };
113
+ }
114
+ return { registry, actorActions };
115
+ }
116
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/json-render/types.ts"],"names":[],"mappings":"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"}
@@ -1,39 +1,15 @@
1
1
  /**
2
- * TypeScript type definitions for play-dom
2
+ * xm-types.ts — XMachines-specific type definitions for play-dom.
3
+ *
4
+ * These types depend on @xmachines/play-actor and stay in play-dom.
5
+ * Pure json-render types live in ./json-render/types.ts.
3
6
  *
4
7
  * @packageDocumentation
5
8
  */
6
- import type { Spec, UIElement, StateStore } from "@json-render/core";
7
9
  import type { AbstractActor, Viewable } from "@xmachines/play-actor";
8
10
  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>;
11
+ import type { StateStore } from "@json-render/core";
12
+ import type { DomRegistry } from "./json-render/types.js";
37
13
  /**
38
14
  * Options for PlayRenderer.
39
15
  */
@@ -70,4 +46,4 @@ export interface ConnectRendererOptions {
70
46
  */
71
47
  store?: StateStore;
72
48
  }
73
- //# sourceMappingURL=types.d.ts.map
49
+ //# sourceMappingURL=xm-types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"xm-types.d.ts","sourceRoot":"","sources":["../src/xm-types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACrE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAC5C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAE1D;;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"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * xm-types.ts — XMachines-specific type definitions for play-dom.
3
+ *
4
+ * These types depend on @xmachines/play-actor and stay in play-dom.
5
+ * Pure json-render types live in ./json-render/types.ts.
6
+ *
7
+ * @packageDocumentation
8
+ */
9
+ export {};
10
+ //# sourceMappingURL=xm-types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"xm-types.js","sourceRoot":"","sources":["../src/xm-types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xmachines/play-dom",
3
- "version": "1.0.0-beta.26",
3
+ "version": "1.0.0-beta.28",
4
4
  "description": "Vanilla DOM renderer for XMachines Play architecture with signal-driven rendering",
5
5
  "keywords": [
6
6
  "actor",
@@ -43,15 +43,15 @@
43
43
  "prepublishOnly": "npm run build"
44
44
  },
45
45
  "dependencies": {
46
- "@xmachines/play": "1.0.0-beta.26",
47
- "@xmachines/play-actor": "1.0.0-beta.26",
48
- "@xmachines/play-signals": "1.0.0-beta.26"
46
+ "@xmachines/play": "1.0.0-beta.28",
47
+ "@xmachines/play-actor": "1.0.0-beta.28",
48
+ "@xmachines/play-signals": "1.0.0-beta.28"
49
49
  },
50
50
  "devDependencies": {
51
51
  "@json-render/core": "^0.16.0",
52
52
  "@json-render/xstate": "^0.16.0",
53
53
  "@types/node": "^25.5.0",
54
- "@xmachines/shared": "1.0.0-beta.26",
54
+ "@xmachines/shared": "1.0.0-beta.28",
55
55
  "@xstate/store": ">=3.17.0",
56
56
  "oxfmt": "^0.43.0",
57
57
  "oxlint": "^1.57.0",
@@ -1,23 +0,0 @@
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
@@ -1 +0,0 @@
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"}
@@ -1,103 +0,0 @@
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
@@ -1 +0,0 @@
1
- {"version":3,"file":"dom-renderer.js","sourceRoot":"","sources":["../src/dom-renderer.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAE5E,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGlD;;;;;;;;;;GAUG;AACH,MAAM,UAAU,UAAU,CACzB,IAAU,EACV,KAAiB,EACjB,QAAqB,EACrB,IAA8B,EAC9B,KAAgC,EAChC,YAAoC;IAEpC,SAAS,aAAa,CAAC,GAAW;QACjC,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;QACnC,IAAI,CAAC,OAAO;YAAE,OAAO,IAAI,CAAC;QAE1B,gCAAgC;QAChC,IAAI,OAAO,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YACnC,MAAM,UAAU,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;YACvC,MAAM,OAAO,GAAG,kBAAkB,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,UAAU,EAAE,CAAC,CAAC;YACpE,IAAI,CAAC,OAAO;gBAAE,OAAO,IAAI,CAAC;QAC3B,CAAC;QAED,sCAAsC;QACtC,MAAM,aAAa,GAAG,YAAY,CAAC,OAAO,CAAC,KAAK,IAAI,EAAE,EAAE,KAAK,CAAC,CAAC;QAE/D,iCAAiC;QACjC,MAAM,GAAG,GAAqB;YAC7B,IAAI;YACJ,KAAK;YACL,IAAI;YACJ,KAAK;YACL,YAAY;YACZ,cAAc,EAAE,CAAC,IAAc,EAAE,EAAE,CAClC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE;gBAClB,MAAM,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC;gBAC3B,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACrB,CAAC,CAAC;SACH,CAAC;QAEF,+BAA+B;QAC/B,MAAM,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACxC,IAAI,CAAC,QAAQ;YAAE,OAAO,IAAI,CAAC,CAAC,qDAAqD;QAEjF,8CAA8C;QAC9C,MAAM,eAAe,GAAc,EAAE,GAAG,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,CAAC;QACxE,MAAM,IAAI,GAAG,QAAQ,CAAC,eAAe,EAAE,GAAG,CAAC,CAAC;QAC5C,IAAI,CAAC,IAAI;YAAE,OAAO,IAAI,CAAC;QAEvB,sCAAsC;QACtC,IAAI,OAAO,CAAC,EAAE,IAAI,IAAI,YAAY,WAAW,EAAE,CAAC;YAC/C,iBAAiB,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;QAC1C,CAAC;QAED,yEAAyE;QACzE,MAAM,SAAS,GAAG,OAAO,CAAC,QAAQ,IAAI,EAAE,CAAC;QACzC,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,IAAI,IAAI,YAAY,WAAW,EAAE,CAAC;YACzD,MAAM,UAAU,GAAG,GAAG,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC;YACjD,UAAU,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;QACxD,CAAC;QAED,OAAO,IAAI,CAAC;IACb,CAAC;IAED,OAAO,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACjC,CAAC;AAED;;;;;;GAMG;AACH,SAAS,iBAAiB,CAAC,IAAiB,EAAE,EAAmB,EAAE,GAAqB;IACvF,IAAI,CAAC,EAAE;QAAE,OAAO;IAEhB,KAAK,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC;QACtD,iDAAiD;QACjD,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;QAE9D,IAAI,CAAC,gBAAgB,CAAC,QAAQ,EAAE,GAAG,EAAE;YACpC,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;gBAC1B,MAAM,SAAS,GAAG,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;gBAC7C,IAAI,SAAS,EAAE,CAAC;oBACf,0EAA0E;oBAC1E,MAAM,UAAU,GAAG,GAAG,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;oBAC3C,MAAM,cAAc,GAA4B,EAAE,CAAC;oBACnD,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC;wBACd,KAAK,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC;4BACnD,cAAc,CAAC,GAAG,CAAC,GAAG,mBAAmB,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;wBAC5D,CAAC;oBACF,CAAC;oBACD,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,cAAc,EAAE,CAAC,CAAC;gBAClD,CAAC;gBACD,+DAA+D;YAChE,CAAC;QACF,CAAC,CAAC,CAAC;IACJ,CAAC;AACF,CAAC"}
@@ -1,12 +0,0 @@
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
@@ -1 +0,0 @@
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"}
@@ -1,41 +0,0 @@
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
@@ -1 +0,0 @@
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"}
@@ -1 +0,0 @@
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 DELETED
@@ -1,7 +0,0 @@
1
- /**
2
- * TypeScript type definitions for play-dom
3
- *
4
- * @packageDocumentation
5
- */
6
- export {};
7
- //# sourceMappingURL=types.js.map
package/dist/types.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}