@adia-ai/web-components 0.6.43 → 0.6.44

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # Changelog — @adia-ai/web-components
2
2
 
3
+ ## [0.6.44] — 2026-05-28
4
+
5
+ ### Fixed — `<canvas-ui>` no longer hard-requires `@adia-ai/web-modules` at build time (FEEDBACK-81)
6
+
7
+ - **`components/canvas/canvas.js`** — the A2UI renderer `<a2ui-root>` (which lives in `@adia-ai/web-modules`) was a top-level *static* import. Because `@adia-ai/web-components` declares no dependency on `@adia-ai/web-modules`, the default barrel `import '@adia-ai/web-components'` (which registers `<canvas-ui>`) failed to build for primitives-only consumers who omitted `web-modules` — a hard Vite/rolldown `UNRESOLVED_IMPORT … web-modules/runtime/a2ui-root`. The import is now lazy + guarded: `#ensureRenderer()` runs a `/* @vite-ignore */` dynamic import on `connected()`, and a missing `web-modules` degrades to a one-time console warning instead of breaking the build. Consumers that have `web-modules` keep the prior synchronous render path (fast-path when `<a2ui-root>` is already defined); `process` / `processAll` / `reset` / version-restore buffer until the renderer is ready, preserving call order. The primitives barrel is now self-contained.
8
+
9
+ ### Maintenance
10
+
11
+ - **`dist/web-components.min.js` + `dist/icons-manifest.js`** — bundle rebuild reflecting the `components/canvas/canvas.js` decouple above.
12
+
3
13
  ## [0.6.43] — 2026-05-27
4
14
 
5
15
  ### Added — `<list-ui>` `[contained]` prop declared in yaml
@@ -1,5 +1,9 @@
1
1
  import { UIElement } from '../../core/element.js';
2
- import '../../../web-modules/runtime/a2ui-root/a2ui-root.js';
2
+ // NOTE: the A2UI renderer (<a2ui-root>) lives in @adia-ai/web-modules and is
3
+ // loaded lazily + guarded inside #ensureRenderer() (kicked off from connected()).
4
+ // It is deliberately NOT a static import: @adia-ai/web-components declares no
5
+ // dependency on @adia-ai/web-modules, so a static cross-package import hard-fails
6
+ // the build for primitives-only consumers who never use <canvas-ui> (FEEDBACK-81).
3
7
 
4
8
  /**
5
9
  * <canvas-ui> — A2UI rendering surface.
@@ -25,6 +29,10 @@ export class UICanvas extends UIElement {
25
29
  #historyIndex = -1;
26
30
  static MAX_HISTORY = 10;
27
31
 
32
+ // FB-81: lazy/guarded <a2ui-root> loader state.
33
+ #rendererReady = null; // Promise<boolean> | null
34
+ static #warnedMissingRenderer = false;
35
+
28
36
  #onKeydown = (e) => {
29
37
  if (e.target.closest('input, textarea, [contenteditable]')) return;
30
38
  if (!this.contains(document.activeElement) && document.activeElement !== document.body) return;
@@ -66,6 +74,8 @@ export class UICanvas extends UIElement {
66
74
  this.addEventListener('input', this.#onInput);
67
75
  // Forward a2ui-retry from wired error cards so consumers can retry generation
68
76
  this.addEventListener('a2ui-retry', this.#onRetry);
77
+ // Kick off the lazy renderer load now that a canvas is in the DOM.
78
+ this.#ensureRenderer();
69
79
  }
70
80
 
71
81
  disconnected() {
@@ -79,6 +89,53 @@ export class UICanvas extends UIElement {
79
89
  this.#bound = false;
80
90
  }
81
91
 
92
+ /**
93
+ * Lazily load the A2UI renderer (<a2ui-root>) from @adia-ai/web-modules.
94
+ * Resolves true once the element is defined, false if web-modules is not
95
+ * installed (primitives-only consumers). Idempotent — the import runs once.
96
+ * Guarded so a missing sibling package degrades to a one-time warning
97
+ * instead of a hard build/runtime failure (FEEDBACK-81).
98
+ */
99
+ #ensureRenderer() {
100
+ if (this.#rendererReady) return this.#rendererReady;
101
+ if (customElements.get('a2ui-root')) {
102
+ this.#rendererReady = Promise.resolve(true);
103
+ return this.#rendererReady;
104
+ }
105
+ this.#rendererReady = import(/* @vite-ignore */ '../../../web-modules/runtime/a2ui-root/a2ui-root.js')
106
+ .then(() => customElements.whenDefined('a2ui-root'))
107
+ .then(() => true)
108
+ .catch((err) => {
109
+ if (!UICanvas.#warnedMissingRenderer) {
110
+ UICanvas.#warnedMissingRenderer = true;
111
+ console.warn(
112
+ '[canvas-ui] A2UI renderer <a2ui-root> could not be loaded — install ' +
113
+ '@adia-ai/web-modules to render generated UI in <canvas-ui>. Apps that ' +
114
+ 'use only primitives (and never <canvas-ui>) can ignore this.',
115
+ err,
116
+ );
117
+ }
118
+ return false;
119
+ });
120
+ return this.#rendererReady;
121
+ }
122
+
123
+ /**
124
+ * Run `fn(rootEl)` against the <a2ui-root> once it is available. Synchronous
125
+ * fast-path when the renderer is already upgraded (preserves prior timing for
126
+ * consumers that have @adia-ai/web-modules); otherwise defers until the lazy
127
+ * import resolves, preserving call order. No-op when web-modules is absent.
128
+ */
129
+ #whenRoot(fn) {
130
+ if (this.#rootEl && typeof this.#rootEl.process === 'function') {
131
+ fn(this.#rootEl);
132
+ return;
133
+ }
134
+ this.#ensureRenderer().then((ok) => {
135
+ if (ok && this.#rootEl && typeof this.#rootEl.process === 'function') fn(this.#rootEl);
136
+ });
137
+ }
138
+
82
139
  render() {
83
140
  if (this.#bound) return;
84
141
  this.#bound = true;
@@ -104,18 +161,19 @@ export class UICanvas extends UIElement {
104
161
 
105
162
  /** Process a single A2UI message. */
106
163
  process(message) {
107
- this.#rootEl?.process(message);
164
+ this.#whenRoot((root) => root.process(message));
108
165
  }
109
166
 
110
167
  /** Process an array of A2UI messages. */
111
168
  processAll(messages) {
112
- if (!this.#rootEl) return;
113
- for (const msg of messages) this.#rootEl.process(msg);
169
+ this.#whenRoot((root) => {
170
+ for (const msg of messages) root.process(msg);
171
+ });
114
172
  }
115
173
 
116
174
  /** Reset the canvas. */
117
175
  reset() {
118
- this.#rootEl?.reset();
176
+ this.#whenRoot((root) => root.reset());
119
177
  }
120
178
 
121
179
  /** Return formatted innerHTML of the a2ui-root. */
@@ -155,10 +213,12 @@ export class UICanvas extends UIElement {
155
213
 
156
214
  #restoreVersion() {
157
215
  const messages = this.#history[this.#historyIndex];
158
- this.#rootEl?.reset();
159
- if (messages) {
160
- for (const msg of messages) this.#rootEl?.process(msg);
161
- }
216
+ this.#whenRoot((root) => {
217
+ root.reset();
218
+ if (messages) {
219
+ for (const msg of messages) root.process(msg);
220
+ }
221
+ });
162
222
  }
163
223
 
164
224
  // ── Private ──