@xmachines/play-dom 2.1.1 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -6,9 +6,9 @@
6
6
  * it returns a `disconnect` cleanup function.
7
7
  *
8
8
  * The factory holds the factory options (`functions`, `validationFunctions`,
9
- * `navigate`, `onRenderError`, and `fallback`) from the moment of its creation, and
10
- * it applies them on every `mount()` call. Give the mount options (`store` and
11
- * `loading`) to the `mount()` call itself, through `MountOptions`.
9
+ * `navigate`, `onRenderError`, `onError`, and `fallback`) from the moment of its
10
+ * creation, and it applies them on every `mount()` call. Give the mount options
11
+ * (`store` and `loading`) to the `mount()` call itself, through `MountOptions`.
12
12
  *
13
13
  * This factory is parallel to `<PlayUIProvider registryResult={...}>` in the
14
14
  * framework renderers.
@@ -31,6 +31,7 @@
31
31
  *
32
32
  * @packageDocumentation
33
33
  */
34
+ import { asCleanup } from "@xmachines/play";
34
35
  import { PlayRenderer } from "./PlayRenderer.js";
35
36
  /**
36
37
  * Creates the mount function of the complete DOM renderer.
@@ -47,11 +48,15 @@ import { PlayRenderer } from "./PlayRenderer.js";
47
48
  * - `validationFunctions` — your own check functions. They are available at `ctx.ctx.validationFunctions`.
48
49
  * - `navigate` — the navigation callback. The renderer calls it for `onSuccess: { navigate: "..." }`.
49
50
  * - `onRenderError` — the `(error, name)` handler of a component render error and of an action handler rejection.
50
- * - `fallback` — the element to show when the first view of the actor is `null`.
51
- * @returns The `MountFn`: `(actor, container, mountOptions?) disconnect`
51
+ * - `onError` — the `(error, reset)` handler of a failure of a complete rebuild. The renderer
52
+ * contains such a failure always, and this option says where the report goes.
53
+ * - `fallback` — the content to show when the view of the actor is `null`, and after a contained
54
+ * failure of a rebuild. Give a FUNCTION when the factory mounts more than one
55
+ * time, so that each renderer owns its own element.
56
+ * @returns The {@link DisposablePlayUI}: `(actor, container, mountOptions?) → disconnect`
52
57
  */
53
58
  export function createPlayUI(registryResult, options = {}) {
54
- const { onRenderError, fallback, functions, directives, validationFunctions, navigate, onConfirm, } = options;
59
+ const { onRenderError, onError, fallback, functions, directives, validationFunctions, navigate, onConfirm, } = options;
55
60
  return function mount(actor, container, mountOptions) {
56
61
  // Each option of UIProviderOptions (onRenderError, functions, validationFunctions,
57
62
  // and navigate) goes directly through PlayDomOptions, then PlayRenderer, then
@@ -66,18 +71,29 @@ export function createPlayUI(registryResult, options = {}) {
66
71
  ...(navigate !== undefined && { navigate }),
67
72
  ...(onConfirm !== undefined && { onConfirm }),
68
73
  ...(onRenderError !== undefined && { onRenderError }),
74
+ // PlayRenderer owns both of them now. It contains a rebuild that throws always,
75
+ // and it shows the fallback for every null view and after each contained
76
+ // failure. The factory therefore forwards the two options, and it appends
77
+ // nothing itself.
78
+ ...(onError !== undefined && { onError }),
79
+ // The producer travels UNCHANGED. PlayRenderer calls it at the first moment it
80
+ // needs the element, and it holds the memo — one mount builds one renderer, so
81
+ // a second memo here would hold the same element for the same lifetime. A
82
+ // producer gives every renderer its own element; a single element that every
83
+ // mount shares would pass from one container to the next on each null view,
84
+ // because appendChild moves a node.
85
+ ...(fallback != null && { fallback }),
69
86
  };
70
87
  const renderer = new PlayRenderer(container, actor, registryResult.registry, rendererOptions);
88
+ // connect() renders the first view synchronously, and PlayRenderer appends the
89
+ // fallback itself when that view is null.
90
+ // It needs no `try`: PlayRenderer contains a failed rebuild AND a handler of the
91
+ // host that throws, so `connect()` returns for every view. `mount()` therefore
92
+ // always reaches the `return` below, and the caller always receives the release.
71
93
  renderer.connect();
72
- // Handle the fallback of a null view on the first mount.
73
- // connect() calls _render() synchronously. Therefore the container holds the view
74
- // already at this point, when actor.currentView is not null.
75
- if (fallback != null && container.childNodes.length === 0) {
76
- container.appendChild(fallback);
77
- }
78
- return function disconnect() {
94
+ return asCleanup(function disconnect() {
79
95
  renderer.disconnect();
80
- };
96
+ });
81
97
  };
82
98
  }
83
99
  //# sourceMappingURL=create-play-ui.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"create-play-ui.js","sourceRoot":"","sources":["../src/create-play-ui.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAKH,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAuCjD;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,YAAY,CAC3B,cAAoC,EACpC,UAA+B,EAAE;IAEjC,MAAM,EACL,aAAa,EACb,QAAQ,EACR,SAAS,EACT,UAAU,EACV,mBAAmB,EACnB,QAAQ,EACR,SAAS,GACT,GAAG,OAAO,CAAC;IAEZ,OAAO,SAAS,KAAK,CAAC,KAAK,EAAE,SAAS,EAAE,YAAY;QACnD,mFAAmF;QACnF,8EAA8E;QAC9E,qCAAqC;QACrC,MAAM,eAAe,GAAG;YACvB,cAAc;YACd,GAAG,CAAC,YAAY,EAAE,KAAK,KAAK,SAAS,IAAI,EAAE,KAAK,EAAE,YAAY,CAAC,KAAK,EAAE,CAAC;YACvE,GAAG,CAAC,YAAY,EAAE,OAAO,KAAK,SAAS,IAAI,EAAE,OAAO,EAAE,YAAY,CAAC,OAAO,EAAE,CAAC;YAC7E,GAAG,CAAC,SAAS,KAAK,SAAS,IAAI,EAAE,SAAS,EAAE,CAAC;YAC7C,GAAG,CAAC,UAAU,KAAK,SAAS,IAAI,EAAE,UAAU,EAAE,CAAC;YAC/C,GAAG,CAAC,mBAAmB,KAAK,SAAS,IAAI,EAAE,mBAAmB,EAAE,CAAC;YACjE,GAAG,CAAC,QAAQ,KAAK,SAAS,IAAI,EAAE,QAAQ,EAAE,CAAC;YAC3C,GAAG,CAAC,SAAS,KAAK,SAAS,IAAI,EAAE,SAAS,EAAE,CAAC;YAC7C,GAAG,CAAC,aAAa,KAAK,SAAS,IAAI,EAAE,aAAa,EAAE,CAAC;SACrD,CAAC;QAEF,MAAM,QAAQ,GAAG,IAAI,YAAY,CAChC,SAAS,EACT,KAAK,EACL,cAAc,CAAC,QAAQ,EACvB,eAAe,CACf,CAAC;QACF,QAAQ,CAAC,OAAO,EAAE,CAAC;QAEnB,yDAAyD;QACzD,kFAAkF;QAClF,6DAA6D;QAC7D,IAAI,QAAQ,IAAI,IAAI,IAAI,SAAS,CAAC,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC3D,SAAS,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;QACjC,CAAC;QAED,OAAO,SAAS,UAAU;YACzB,QAAQ,CAAC,UAAU,EAAE,CAAC;QACvB,CAAC,CAAC;IACH,CAAC,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"create-play-ui.js","sourceRoot":"","sources":["../src/create-play-ui.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,OAAO,EAAE,SAAS,EAAgB,MAAM,iBAAiB,CAAC;AAI1D,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAiEjD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,UAAU,YAAY,CAC3B,cAAoC,EACpC,UAA+B,EAAE;IAEjC,MAAM,EACL,aAAa,EACb,OAAO,EACP,QAAQ,EACR,SAAS,EACT,UAAU,EACV,mBAAmB,EACnB,QAAQ,EACR,SAAS,GACT,GAAG,OAAO,CAAC;IAEZ,OAAO,SAAS,KAAK,CAAC,KAAK,EAAE,SAAS,EAAE,YAAY;QACnD,mFAAmF;QACnF,8EAA8E;QAC9E,qCAAqC;QACrC,MAAM,eAAe,GAAG;YACvB,cAAc;YACd,GAAG,CAAC,YAAY,EAAE,KAAK,KAAK,SAAS,IAAI,EAAE,KAAK,EAAE,YAAY,CAAC,KAAK,EAAE,CAAC;YACvE,GAAG,CAAC,YAAY,EAAE,OAAO,KAAK,SAAS,IAAI,EAAE,OAAO,EAAE,YAAY,CAAC,OAAO,EAAE,CAAC;YAC7E,GAAG,CAAC,SAAS,KAAK,SAAS,IAAI,EAAE,SAAS,EAAE,CAAC;YAC7C,GAAG,CAAC,UAAU,KAAK,SAAS,IAAI,EAAE,UAAU,EAAE,CAAC;YAC/C,GAAG,CAAC,mBAAmB,KAAK,SAAS,IAAI,EAAE,mBAAmB,EAAE,CAAC;YACjE,GAAG,CAAC,QAAQ,KAAK,SAAS,IAAI,EAAE,QAAQ,EAAE,CAAC;YAC3C,GAAG,CAAC,SAAS,KAAK,SAAS,IAAI,EAAE,SAAS,EAAE,CAAC;YAC7C,GAAG,CAAC,aAAa,KAAK,SAAS,IAAI,EAAE,aAAa,EAAE,CAAC;YACrD,gFAAgF;YAChF,yEAAyE;YACzE,0EAA0E;YAC1E,kBAAkB;YAClB,GAAG,CAAC,OAAO,KAAK,SAAS,IAAI,EAAE,OAAO,EAAE,CAAC;YACzC,+EAA+E;YAC/E,+EAA+E;YAC/E,0EAA0E;YAC1E,6EAA6E;YAC7E,4EAA4E;YAC5E,oCAAoC;YACpC,GAAG,CAAC,QAAQ,IAAI,IAAI,IAAI,EAAE,QAAQ,EAAE,CAAC;SACrC,CAAC;QAEF,MAAM,QAAQ,GAAG,IAAI,YAAY,CAChC,SAAS,EACT,KAAK,EACL,cAAc,CAAC,QAAQ,EACvB,eAAe,CACf,CAAC;QACF,+EAA+E;QAC/E,0CAA0C;QAC1C,iFAAiF;QACjF,+EAA+E;QAC/E,iFAAiF;QACjF,QAAQ,CAAC,OAAO,EAAE,CAAC;QAEnB,OAAO,SAAS,CAAC,SAAS,UAAU;YACnC,QAAQ,CAAC,UAAU,EAAE,CAAC;QACvB,CAAC,CAAC,CAAC;IACJ,CAAC,CAAC;AACH,CAAC"}
@@ -52,6 +52,7 @@
52
52
  *
53
53
  * @packageDocumentation
54
54
  */
55
+ import { type Cleanup } from "@xmachines/play";
55
56
  import type { AbstractActor, Viewable } from "@xmachines/play-actor";
56
57
  import type { AnyActorLogic } from "xstate";
57
58
  import type { Catalog } from "@xmachines/json-render-core";
@@ -81,5 +82,5 @@ import type { PlayDomOptions } from "./types.js";
81
82
  * `CreatePlayUIOptions`. You can also use `defineRegistry` with `PlayRenderer`
82
83
  * directly.
83
84
  */
84
- export declare function createRenderer<C extends Catalog>(catalog: C, componentMap: ComponentRegistry<C>): (actor: AbstractActor<AnyActorLogic> & Viewable, container: HTMLElement, options?: Omit<PlayDomOptions, "registryResult">) => () => void;
85
+ export declare function createRenderer<C extends Catalog>(catalog: C, componentMap: ComponentRegistry<C>): (actor: AbstractActor<AnyActorLogic> & Viewable, container: HTMLElement, options?: Omit<PlayDomOptions, "registryResult">) => Cleanup;
85
86
  //# sourceMappingURL=create-renderer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"create-renderer.d.ts","sourceRoot":"","sources":["../src/create-renderer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACrE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAC5C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AACpE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAIjD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,cAAc,CAAC,CAAC,SAAS,OAAO,EAC/C,OAAO,EAAE,CAAC,EACV,YAAY,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAChC,CACF,KAAK,EAAE,aAAa,CAAC,aAAa,CAAC,GAAG,QAAQ,EAC9C,SAAS,EAAE,WAAW,EACtB,OAAO,CAAC,EAAE,IAAI,CAAC,cAAc,EAAE,gBAAgB,CAAC,KAC5C,MAAM,IAAI,CAWd"}
1
+ {"version":3,"file":"create-renderer.d.ts","sourceRoot":"","sources":["../src/create-renderer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDG;AAEH,OAAO,EAAa,KAAK,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC1D,OAAO,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACrE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAC5C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AACpE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAIjD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,cAAc,CAAC,CAAC,SAAS,OAAO,EAC/C,OAAO,EAAE,CAAC,EACV,YAAY,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAChC,CACF,KAAK,EAAE,aAAa,CAAC,aAAa,CAAC,GAAG,QAAQ,EAC9C,SAAS,EAAE,WAAW,EACtB,OAAO,CAAC,EAAE,IAAI,CAAC,cAAc,EAAE,gBAAgB,CAAC,KAC5C,OAAO,CAWX"}
@@ -52,6 +52,7 @@
52
52
  *
53
53
  * @packageDocumentation
54
54
  */
55
+ import { asCleanup } from "@xmachines/play";
55
56
  import { PlayRenderer } from "./PlayRenderer.js";
56
57
  import { defineRegistry } from "@xmachines/json-render-dom";
57
58
  /**
@@ -86,7 +87,7 @@ export function createRenderer(catalog, componentMap) {
86
87
  registryResult,
87
88
  });
88
89
  renderer.connect();
89
- return () => renderer.disconnect();
90
+ return asCleanup(() => renderer.disconnect());
90
91
  };
91
92
  }
92
93
  //# sourceMappingURL=create-renderer.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"create-renderer.js","sourceRoot":"","sources":["../src/create-renderer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDG;AAOH,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAE5D;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,UAAU,cAAc,CAC7B,OAAU,EACV,YAAkC;IAMlC,MAAM,cAAc,GAAG,cAAc,CAAC,OAAO,EAAE,EAAE,UAAU,EAAE,YAAY,EAAE,CAAC,CAAC;IAE7E,OAAO,SAAS,KAAK,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,GAAG,EAAE;QACnD,MAAM,QAAQ,GAAG,IAAI,YAAY,CAAC,SAAS,EAAE,KAAK,EAAE,cAAc,CAAC,QAAQ,EAAE;YAC5E,GAAG,OAAO;YACV,cAAc;SACd,CAAC,CAAC;QACH,QAAQ,CAAC,OAAO,EAAE,CAAC;QACnB,OAAO,GAAG,EAAE,CAAC,QAAQ,CAAC,UAAU,EAAE,CAAC;IACpC,CAAC,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"create-renderer.js","sourceRoot":"","sources":["../src/create-renderer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDG;AAEH,OAAO,EAAE,SAAS,EAAgB,MAAM,iBAAiB,CAAC;AAM1D,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAE5D;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,UAAU,cAAc,CAC7B,OAAU,EACV,YAAkC;IAMlC,MAAM,cAAc,GAAG,cAAc,CAAC,OAAO,EAAE,EAAE,UAAU,EAAE,YAAY,EAAE,CAAC,CAAC;IAE7E,OAAO,SAAS,KAAK,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,GAAG,EAAE;QACnD,MAAM,QAAQ,GAAG,IAAI,YAAY,CAAC,SAAS,EAAE,KAAK,EAAE,cAAc,CAAC,QAAQ,EAAE;YAC5E,GAAG,OAAO;YACV,cAAc;SACd,CAAC,CAAC;QACH,QAAQ,CAAC,OAAO,EAAE,CAAC;QACnB,OAAO,SAAS,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC;IAC/C,CAAC,CAAC;AACH,CAAC"}
package/dist/index.d.ts CHANGED
@@ -5,9 +5,9 @@
5
5
  *
6
6
  * **The XMachines layer**, in this package:
7
7
  * - `createRenderer()` — the one-call factory. It returns `mount(actor, container, options?) → disconnect`
8
- * - `createPlayUI()` — the complete factory, with every option. It returns a `MountFn`
8
+ * - `createPlayUI()` — the complete factory, with every option. It returns a `DisposablePlayUI`
9
9
  * - `PlayRenderer` — the renderer class, with a `connect()` and `disconnect()` lifecycle
10
- * - `PlayDomOptions`, `CreatePlayUIOptions`, `MountFn`, `MountOptions`
10
+ * - `PlayDomOptions`, `CreatePlayUIOptions`, `MountFn`, `DisposablePlayUI`, `MountOptions`
11
11
  *
12
12
  * **The json-render layer**, re-exported from @xmachines/json-render-dom:
13
13
  * - `defineRegistry` — it builds a catalog-typed DomRegistry
@@ -28,10 +28,11 @@
28
28
  export { PlayRenderer } from "./PlayRenderer.js";
29
29
  export { createRenderer } from "./create-renderer.js";
30
30
  export { createPlayUI } from "./create-play-ui.js";
31
- export type { MountFn, MountOptions } from "./create-play-ui.js";
31
+ export type { MountFn, DisposablePlayUI, MountOptions } from "./create-play-ui.js";
32
32
  export type { PlayDomOptions, CreatePlayUIOptions } from "./types.js";
33
33
  export { defineRegistry, renderSpec, schema, createValidationRegistry, } from "@xmachines/json-render-dom";
34
34
  export type { ValidationRegistry, FieldValidationState } from "@xmachines/json-render-dom";
35
35
  export type { RenderSpecOptions } from "@xmachines/json-render-dom";
36
36
  export type { ConfirmHandler, EventHandle, SetState, RenderErrorHandler, UIProviderOptions, CatalogHasActions, BaseComponentProps, DomRenderContext, DomComponentRenderer, ComponentContext, ComponentFn, ComponentRegistry, Actions, ActionFn, DefineRegistryOptions, DefineRegistryResult, DomRegistry, DomSchema, } from "@xmachines/json-render-dom";
37
+ export { type Cleanup } from "@xmachines/play";
37
38
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAGH,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,YAAY,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAGjE,YAAY,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAGtE,OAAO,EACN,cAAc,EACd,UAAU,EACV,MAAM,EACN,wBAAwB,GACxB,MAAM,4BAA4B,CAAC;AACpC,YAAY,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAC3F,YAAY,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AACpE,YAAY,EACX,cAAc,EACd,WAAW,EACX,QAAQ,EACR,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,EACjB,kBAAkB,EAClB,gBAAgB,EAChB,oBAAoB,EACpB,gBAAgB,EAChB,WAAW,EACX,iBAAiB,EACjB,OAAO,EACP,QAAQ,EACR,qBAAqB,EACrB,oBAAoB,EACpB,WAAW,EACX,SAAS,GACT,MAAM,4BAA4B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAGH,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,YAAY,EAAE,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAGnF,YAAY,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAGtE,OAAO,EACN,cAAc,EACd,UAAU,EACV,MAAM,EACN,wBAAwB,GACxB,MAAM,4BAA4B,CAAC;AACpC,YAAY,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAC3F,YAAY,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AACpE,YAAY,EACX,cAAc,EACd,WAAW,EACX,QAAQ,EACR,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,EACjB,kBAAkB,EAClB,gBAAgB,EAChB,oBAAoB,EACpB,gBAAgB,EAChB,WAAW,EACX,iBAAiB,EACjB,OAAO,EACP,QAAQ,EACR,qBAAqB,EACrB,oBAAoB,EACpB,WAAW,EACX,SAAS,GACT,MAAM,4BAA4B,CAAC;AAKpC,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,iBAAiB,CAAC"}
package/dist/index.js CHANGED
@@ -5,9 +5,9 @@
5
5
  *
6
6
  * **The XMachines layer**, in this package:
7
7
  * - `createRenderer()` — the one-call factory. It returns `mount(actor, container, options?) → disconnect`
8
- * - `createPlayUI()` — the complete factory, with every option. It returns a `MountFn`
8
+ * - `createPlayUI()` — the complete factory, with every option. It returns a `DisposablePlayUI`
9
9
  * - `PlayRenderer` — the renderer class, with a `connect()` and `disconnect()` lifecycle
10
- * - `PlayDomOptions`, `CreatePlayUIOptions`, `MountFn`, `MountOptions`
10
+ * - `PlayDomOptions`, `CreatePlayUIOptions`, `MountFn`, `DisposablePlayUI`, `MountOptions`
11
11
  *
12
12
  * **The json-render layer**, re-exported from @xmachines/json-render-dom:
13
13
  * - `defineRegistry` — it builds a catalog-typed DomRegistry
@@ -31,4 +31,9 @@ export { createRenderer } from "./create-renderer.js";
31
31
  export { createPlayUI } from "./create-play-ui.js";
32
32
  // @xmachines/json-render-dom. This package re-exports it, for the convenience of a consumer
33
33
  export { defineRegistry, renderSpec, schema, createValidationRegistry, } from "@xmachines/json-render-dom";
34
+ // The release protocol of @xmachines/play. This package's own published `.d.ts` names
35
+ // exactly these, so a consumer reads them from here and needs no second manifest
36
+ // entry. It names `asCleanup` nowhere: a consumer of this package RECEIVES a
37
+ // release, and builds one only with @xmachines/play itself.
38
+ export {} from "@xmachines/play";
34
39
  //# 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;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,qCAAqC;AACrC,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAMnD,4FAA4F;AAC5F,OAAO,EACN,cAAc,EACd,UAAU,EACV,MAAM,EACN,wBAAwB,GACxB,MAAM,4BAA4B,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,qCAAqC;AACrC,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAMnD,4FAA4F;AAC5F,OAAO,EACN,cAAc,EACd,UAAU,EACV,MAAM,EACN,wBAAwB,GACxB,MAAM,4BAA4B,CAAC;AAuBpC,sFAAsF;AACtF,iFAAiF;AACjF,6EAA6E;AAC7E,4DAA4D;AAC5D,OAAO,EAAgB,MAAM,iBAAiB,CAAC"}
package/dist/types.d.ts CHANGED
@@ -47,6 +47,82 @@ export interface PlayDomOptions extends UIProviderOptions {
47
47
  * This option matches the `loading` prop of the framework renderer providers.
48
48
  */
49
49
  loading?: boolean;
50
+ /**
51
+ * The optional handler of a failure of a complete rebuild of the view.
52
+ *
53
+ * This option is NOT the same as `onRenderError`, which {@link UIProviderOptions}
54
+ * gives: the inner renderer routes a render error of one component, and a rejection
55
+ * of one action handler, to `onRenderError`. It contains each of them per element,
56
+ * and the rebuild continues. `onError` receives the failure of the complete rebuild
57
+ * that no per-element boundary caught.
58
+ *
59
+ * The renderer CONTAINS a rebuild that throws, with this option and without it: it
60
+ * resets the state of the failed rebuild, so that the next emission makes a complete
61
+ * render again, and it clears the container. `connect()` renders the first view
62
+ * synchronously, so a bad initial view makes `connect()` throw no more.
63
+ *
64
+ * A WRITE of the store takes the same path. The renderer resolves the props of every
65
+ * element that the write touched, so a `$computed` function that throws on the new
66
+ * state aborts that render too. The renderer contains such a failure as well, and the
67
+ * action handler that wrote the state receives no exception.
68
+ *
69
+ * This option says WHERE the report goes. Without it, the renderer writes the
70
+ * contained failure to `console.error`.
71
+ *
72
+ * A handler that THROWS reaches no caller: the renderer contains that throw too, and
73
+ * it writes the throw to `console.error`. A host that must escalate a failure raises
74
+ * it from a task of its own — `queueMicrotask(() => { throw error; })` — which
75
+ * reaches the global handler of the page and leaves the containment whole. The five
76
+ * renderers hold this one rule.
77
+ *
78
+ * The second parameter is the RESET, for a retry that the host starts — a "Retry"
79
+ * button of its own. It renders the view that the actor holds at the MOMENT OF THE
80
+ * CALL, so a host that keeps the callback cannot rewind the screen to the view that
81
+ * failed. A reset that the host calls from inside this handler does nothing, because
82
+ * no input changed between the two attempts, and a reset after `disconnect()` does
83
+ * nothing.
84
+ *
85
+ * A reset belongs to ONE connection. `connect()` starts a connection, and the reset of
86
+ * a report of an older connection does nothing. A host that calls `connect()` again
87
+ * from inside this handler abandons the connection that reported. The "Retry" button
88
+ * of that report must not render into the connection that took its place. Call the
89
+ * reset of the newest report.
90
+ *
91
+ * This option matches the `onError` prop of the framework renderer providers, and the
92
+ * five renderers hold the same three rules for the reset.
93
+ */
94
+ onError?: (error: unknown, reset: () => void) => void;
95
+ /**
96
+ * The optional element that the renderer shows when `currentView` is `null`, and
97
+ * after a failure of a rebuild that it contains.
98
+ *
99
+ * The renderer shows it for EVERY null view, and not for the first mount only: a view
100
+ * that returns to `null` after a view that was not `null` also shows it. The four
101
+ * framework providers hold the same rule for their placeholder content.
102
+ *
103
+ * The renderer shows it after a failure of a rebuild too. This option turns nothing
104
+ * on: the renderer contains such a failure always, and this option says only what the
105
+ * empty container shows. The next view that renders clears the container, which
106
+ * removes the element.
107
+ *
108
+ * **One element belongs to one renderer.** `appendChild` MOVES a node. Two renderers
109
+ * that hold the same element therefore take it from each other on every null view,
110
+ * and the container of the first one goes empty without a notice. Build one element
111
+ * for each `PlayRenderer`.
112
+ *
113
+ * A FUNCTION also works here. The renderer calls it at the first moment that it needs
114
+ * the element, and it keeps the result, so a renderer whose view is never null builds
115
+ * nothing. {@link CreatePlayUIOptions.fallback} passes such a function for each
116
+ * mount.
117
+ *
118
+ * A producer that THROWS is contained on BOTH paths — a null view, and a rebuild that
119
+ * failed — and the renderer writes it to `console.error` and NOT to
120
+ * {@link PlayDomOptions.onError}. On the second path the renderer calls the producer
121
+ * from inside the containment of the view, and a second trip through `onError` would
122
+ * report the failure of the fallback as a failure of the view. The container stays
123
+ * empty.
124
+ */
125
+ fallback?: HTMLElement | (() => HTMLElement) | null;
50
126
  }
51
127
  /**
52
128
  * The options of `createPlayUI()`, the complete DOM factory.
@@ -56,23 +132,39 @@ export interface PlayDomOptions extends UIProviderOptions {
56
132
  * holds all of them from the moment of its creation, and it gives them to
57
133
  * `PlayRenderer` on every `mount()` call.
58
134
  *
135
+ * It also takes {@link PlayDomOptions.onError}, which the factory forwards without a
136
+ * change: `PlayRenderer` owns it, and it receives every failure of a rebuild that the
137
+ * renderer contains. Read that entry for the complete rule. `fallback` below says what
138
+ * the factory adds to {@link PlayDomOptions.fallback}.
139
+ *
59
140
  * This type is parallel to the props of `PlayUIProvider` in the framework renderers.
60
141
  *
61
142
  * @see createPlayUI
62
143
  */
63
- export interface CreatePlayUIOptions extends UIProviderOptions {
144
+ export interface CreatePlayUIOptions extends UIProviderOptions, Pick<PlayDomOptions, "onError"> {
64
145
  /**
65
- * The optional fallback element. The factory shows it when `currentView` is `null` on the **first mount** only.
146
+ * The optional fallback content see {@link PlayDomOptions.fallback} for what the
147
+ * renderer does with it. The factory shows it for every null view, and after a
148
+ * failure of a rebuild that the renderer contains.
149
+ *
150
+ * **Give a FUNCTION when the factory mounts more than one time.** ONE factory serves
151
+ * every `mount()` call, and `appendChild` MOVES a node. A single element therefore
152
+ * passes from one container to the next on every null view, and the container that
153
+ * loses it goes empty without a notice. A function runs one time for each mount, so
154
+ * every renderer owns its own element:
66
155
  *
67
- * The factory appends the fallback directly after `mount()`, when the container is
68
- * empty at that moment, which means that the first view of the actor is `null`.
156
+ * ```typescript
157
+ * const mount = createPlayUI(registryResult, {
158
+ * fallback: () => {
159
+ * const element = document.createElement("p");
160
+ * element.textContent = "Loading…";
161
+ * return element;
162
+ * },
163
+ * });
164
+ * ```
69
165
  *
70
- * **Limitation:** when the view of the actor becomes `null` after the mount, the
71
- * renderer clears the container, and it does NOT append this fallback again. For a
72
- * dynamic fallback, which follows a null view after a view that was not null, use
73
- * `PlayRenderer` directly and wrap the `actor.currentView` signal to add the
74
- * fallback content.
166
+ * An element stays correct for a factory that mounts one time.
75
167
  */
76
- fallback?: HTMLElement | null;
168
+ fallback?: HTMLElement | (() => HTMLElement) | null;
77
169
  }
78
170
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,KAAK,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAE1F,YAAY,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAEpE;;;;;;;GAOG;AACH,MAAM,WAAW,cAAe,SAAQ,iBAAiB;IACxD;;;;;;;OAOG;IACH,cAAc,CAAC,EAAE,oBAAoB,CAAC;IAEtC;;;;;;;OAOG;IACH,KAAK,CAAC,EAAE,UAAU,CAAC;IAEnB;;;;;;;;;OASG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,mBAAoB,SAAQ,iBAAiB;IAC7D;;;;;;;;;;;OAWG;IACH,QAAQ,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;CAC9B"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,KAAK,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAE1F,YAAY,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAEpE;;;;;;;GAOG;AACH,MAAM,WAAW,cAAe,SAAQ,iBAAiB;IACxD;;;;;;;OAOG;IACH,cAAc,CAAC,EAAE,oBAAoB,CAAC;IAEtC;;;;;;;OAOG;IACH,KAAK,CAAC,EAAE,UAAU,CAAC;IAEnB;;;;;;;;;OASG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA2CG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;IAEtD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA6BG;IACH,QAAQ,CAAC,EAAE,WAAW,GAAG,CAAC,MAAM,WAAW,CAAC,GAAG,IAAI,CAAC;CACpD;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,WAAW,mBAAoB,SAAQ,iBAAiB,EAAE,IAAI,CAAC,cAAc,EAAE,SAAS,CAAC;IAC9F;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,QAAQ,CAAC,EAAE,WAAW,GAAG,CAAC,MAAM,WAAW,CAAC,GAAG,IAAI,CAAC;CACpD"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xmachines/play-dom",
3
- "version": "2.1.1",
3
+ "version": "3.0.0",
4
4
  "description": "Vanilla DOM renderer for XMachines Play architecture with signal-driven rendering",
5
5
  "keywords": [
6
6
  "actor",
@@ -46,17 +46,17 @@
46
46
  "test:coverage": "vitest run --coverage"
47
47
  },
48
48
  "dependencies": {
49
- "@xmachines/play": "2.1.1",
50
- "@xmachines/play-actor": "2.1.1",
51
- "@xmachines/play-signals": "2.1.1"
49
+ "@xmachines/play": "3.0.0",
50
+ "@xmachines/play-actor": "3.0.0",
51
+ "@xmachines/play-signals": "3.0.0"
52
52
  },
53
53
  "devDependencies": {
54
54
  "@testing-library/jest-dom": "^6.9.1",
55
55
  "@types/node": "^26.2.0",
56
56
  "@vitest/browser-playwright": "^4.1.11",
57
- "@xmachines/json-render-core": "^0.20.0-xm.2",
58
- "@xmachines/json-render-dom": "^0.20.0-xm.2",
59
- "@xmachines/json-render-xstate": "^0.20.0-xm.2",
57
+ "@xmachines/json-render-core": "^0.20.0-xm.4",
58
+ "@xmachines/json-render-dom": "^0.20.0-xm.4",
59
+ "@xmachines/json-render-xstate": "^0.20.0-xm.4",
60
60
  "@xstate/store": "^3.17.0",
61
61
  "oxfmt": "^0.64.0",
62
62
  "oxlint": "^1.79.0",
@@ -67,9 +67,9 @@
67
67
  "zod": "^4.4.1"
68
68
  },
69
69
  "peerDependencies": {
70
- "@xmachines/json-render-core": "^0.20.0-xm.2",
71
- "@xmachines/json-render-dom": "^0.20.0-xm.2",
72
- "@xmachines/json-render-xstate": "^0.20.0-xm.2",
70
+ "@xmachines/json-render-core": "^0.20.0-xm.4",
71
+ "@xmachines/json-render-dom": "^0.20.0-xm.4",
72
+ "@xmachines/json-render-xstate": "^0.20.0-xm.4",
73
73
  "@xstate/store": "^3.17.0",
74
74
  "xstate": "^5.31.0"
75
75
  },