@adia-ai/web-components 0.5.5 → 0.5.6

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.
@@ -45,12 +45,17 @@
45
45
 
46
46
  import { UIElement } from '../../core/element.js';
47
47
 
48
- function makeButton({ icon, text = '' }) {
48
+ function makeButton({ icon, text = '', title = '' }) {
49
49
  const btn = document.createElement('button-ui');
50
50
  btn.setAttribute('icon', icon);
51
51
  btn.setAttribute('variant', 'ghost');
52
52
  btn.setAttribute('size', 'sm');
53
53
  if (text) btn.setAttribute('text', text);
54
+ // §190a (v0.5.6): supply title= for icon-only buttons. button-ui's §184
55
+ // FEEDBACK-08 §8 a11y safety-net mirrors title → aria-label automatically
56
+ // when the button is icon-only. Closes the per-render console.warn class
57
+ // captured 2026-05-14 ("Icon-only button is missing an accessible name").
58
+ if (!text && title) btn.setAttribute('title', title);
54
59
  return btn;
55
60
  }
56
61
 
@@ -142,11 +147,12 @@ export class UIAgentFeedbackBar extends UIElement {
142
147
  #build() {
143
148
  this.innerHTML = '';
144
149
 
145
- this.#upEl = makeButton({ icon: 'thumbs-up' });
146
- this.#downEl = makeButton({ icon: 'thumbs-down' });
150
+ this.#upEl = makeButton({ icon: 'thumbs-up', title: 'Rate this response positively' });
151
+ this.#downEl = makeButton({ icon: 'thumbs-down', title: 'Rate this response negatively' });
147
152
  this.#saveEl = makeButton({
148
153
  icon: this.saveIcon || 'bookmark-simple',
149
154
  text: this.saveLabel || '',
155
+ title: this.saveLabel ? '' : 'Save this response',
150
156
  });
151
157
  if (!this.saveLabel) this.#saveEl.hidden = true;
152
158
 
@@ -6,10 +6,10 @@
6
6
 
7
7
  import { UIFormElement } from '../../core/form.js';
8
8
 
9
- export interface SegmentedChangeEventDetail {
10
- value: string;
9
+ export interface SegmentedChangeEventDetail<V extends string = string> {
10
+ value: V;
11
11
  }
12
- export type SegmentedChangeEvent = CustomEvent<SegmentedChangeEventDetail>;
12
+ export type SegmentedChangeEvent<V extends string = string> = CustomEvent<SegmentedChangeEventDetail<V>>;
13
13
 
14
14
  export class UISegmented extends UIFormElement {
15
15
  /** Selected segment's value. */
@@ -16,10 +16,10 @@ export interface SelectOption {
16
16
  divider?: boolean;
17
17
  }
18
18
 
19
- export interface SelectChangeEventDetail {
20
- value: string;
19
+ export interface SelectChangeEventDetail<V extends string = string> {
20
+ value: V;
21
21
  }
22
- export type SelectChangeEvent = CustomEvent<SelectChangeEventDetail>;
22
+ export type SelectChangeEvent<V extends string = string> = CustomEvent<SelectChangeEventDetail<V>>;
23
23
 
24
24
  export interface SelectActionEventDetail {
25
25
  action: string;
@@ -6,13 +6,13 @@
6
6
 
7
7
  import { UIFormElement } from '../../core/form.js';
8
8
 
9
- export interface SwitchChangeEventDetail {
9
+ export interface SwitchChangeEventDetail<V extends string = string> {
10
10
  /** Submitted value (defaults to `"on"` when checked). */
11
- value: string;
11
+ value: V;
12
12
  /** Current checked state. */
13
13
  checked: boolean;
14
14
  }
15
- export type SwitchChangeEvent = CustomEvent<SwitchChangeEventDetail>;
15
+ export type SwitchChangeEvent<V extends string = string> = CustomEvent<SwitchChangeEventDetail<V>>;
16
16
 
17
17
  export class UISwitch extends UIFormElement {
18
18
  /** Checked state — reflected, toggles on click. */
@@ -12,6 +12,28 @@
12
12
 
13
13
  import { UIElement } from '../../core/element.js';
14
14
 
15
+ /** Options accepted by `UIToast.show(opts)` — the imperative one-shot path. */
16
+ export interface UIToastShowOptions {
17
+ /** Toast message text. */
18
+ text?: string;
19
+ /** Semantic variant. Legacy alias `"error"` is auto-mapped to `"danger"`. */
20
+ variant?: 'default' | 'info' | 'success' | 'warning' | 'danger' | 'primary' | 'muted' | 'neutral' | 'error';
21
+ /** Auto-dismiss time in milliseconds. 0 disables auto-dismiss. Default `4000`. */
22
+ duration?: number;
23
+ /** Screen position. Default `'bottom-right'`. */
24
+ position?: 'top-left' | 'top-center' | 'top-right' | 'bottom-left' | 'bottom-center' | 'bottom-right';
25
+ }
26
+
27
+ /** Returned by `UIToast.show()` — imperative handle for dismiss / update. */
28
+ export interface UIToastFeedHandle {
29
+ /** Stable id assigned by `<feed-ui>`. `null` if the toast couldn't be posted. */
30
+ id: string | null;
31
+ /** Dismiss the toast programmatically. */
32
+ dismiss(): void;
33
+ /** Mutate the toast's content in-place (e.g. promote from "loading" to "done"). */
34
+ update(patch: Partial<UIToastShowOptions>): void;
35
+ }
36
+
15
37
  export class UIToast extends UIElement {
16
38
  /** Auto-dismiss time in milliseconds. 0 disables auto-dismiss. */
17
39
  duration: number;
@@ -21,4 +43,17 @@ export class UIToast extends UIElement {
21
43
  text: string;
22
44
  /** Semantic variant — `default | info | success | warning | danger`. `primary` and `muted` are style hints; canonical "neutral but interesting" tone is `info`. */
23
45
  variant: 'default' | 'info' | 'success' | 'warning' | 'danger' | 'primary' | 'muted' | 'neutral';
46
+
47
+ /**
48
+ * Post a one-shot toast through the shared `<feed-ui>` host. Imperative
49
+ * alternative to declarative `<toast-ui>`. Returns a `UIToastFeedHandle`
50
+ * for programmatic dismiss / update.
51
+ *
52
+ * Legacy alias `variant: 'error'` is auto-mapped to `variant: 'danger'`.
53
+ *
54
+ * @example
55
+ * const t = UIToast.show({ text: 'Saved!', variant: 'success' });
56
+ * setTimeout(() => t.dismiss(), 1000);
57
+ */
58
+ static show(opts?: UIToastShowOptions): UIToastFeedHandle;
24
59
  }
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Anchor positioning — positions a popover/panel relative to an anchor
3
+ * element. Uses native CSS Anchor Positioning when supported (Chrome
4
+ * 125+), falls back to a JS implementation (`getBoundingClientRect()` +
5
+ * `position: fixed`) otherwise.
6
+ *
7
+ * Works with the Popover API: the popover renders in the top layer via
8
+ * `showPopover()` on a `popover="manual"` or `popover="auto"` element,
9
+ * and the position is wired with either `anchor()` + `position-area` or
10
+ * manual coords.
11
+ *
12
+ * Runtime exports mirror `core/anchor.js`. `.d.ts` authored in v0.5.6
13
+ * §191 to close the §178 audit-script baseline missing-sibling gap.
14
+ *
15
+ * @see ./anchor.js (runtime SoT)
16
+ * @see ../USAGE.md (consumer guide)
17
+ */
18
+
19
+ /**
20
+ * Placement vocabulary for {@link anchorPopover}. Mirrors a subset of
21
+ * the floating-ui / Popper conventions. `-start` aligns the popover's
22
+ * leading edge to the anchor's leading edge along the perpendicular
23
+ * axis; `-end` aligns the trailing edges; bare (no suffix) centers.
24
+ */
25
+ export type Placement =
26
+ | 'bottom'
27
+ | 'bottom-start'
28
+ | 'bottom-end'
29
+ | 'top'
30
+ | 'top-start'
31
+ | 'top-end'
32
+ | 'left'
33
+ | 'left-start'
34
+ | 'left-end'
35
+ | 'right'
36
+ | 'right-start'
37
+ | 'right-end';
38
+
39
+ /**
40
+ * Options for {@link anchorPopover}.
41
+ */
42
+ export interface AnchorOptions {
43
+ /** Where to place the popover relative to its anchor. Default: `bottom-start`. */
44
+ placement?: Placement;
45
+ /** Pixel gap on the main (anchor-adjacent) axis. Default: 4. */
46
+ gap?: number;
47
+ /**
48
+ * When true, the popover's `width` is constrained to match the
49
+ * anchor's width — useful for combobox-style listboxes.
50
+ */
51
+ matchWidth?: boolean;
52
+ }
53
+
54
+ /**
55
+ * `true` when the current browser supports the CSS Anchor Positioning
56
+ * primitives the native path uses (`anchor-name`, `position-area`).
57
+ * `false` otherwise (browser falls back to the JS positioning path).
58
+ */
59
+ export const supportsAnchorCSS: boolean;
60
+
61
+ /**
62
+ * Position `popover` relative to `anchor`. Picks the native CSS Anchor
63
+ * Positioning path when available, otherwise the JS fallback. Returns a
64
+ * cleanup function — call it to detach listeners / restore inline
65
+ * styles.
66
+ */
67
+ export function anchorPopover(
68
+ anchor: Element,
69
+ popover: HTMLElement,
70
+ options?: AnchorOptions,
71
+ ): () => void;
@@ -0,0 +1,171 @@
1
+ /**
2
+ * Controller pattern — host-attached state objects that reflect into
3
+ * the DOM + notify subscribers on change. `BaseController` is the
4
+ * minimal contract; `RouteController` is the canonical routing-state
5
+ * implementation used by `<router-ui>` (see `core/provider.js`).
6
+ *
7
+ * Runtime exports mirror `core/controller.js`. `.d.ts` authored in
8
+ * v0.5.6 §191 to close the §178 audit-script baseline missing-sibling
9
+ * gap.
10
+ *
11
+ * @see ./controller.js (runtime SoT)
12
+ * @see ./provider.js (`<router-ui>` consumer of `RouteController`)
13
+ */
14
+
15
+ /**
16
+ * Static schema each {@link BaseController} subclass should declare so
17
+ * the dev-warn at `connect()` time can identify the controller in
18
+ * diagnostics. Optional but conventional.
19
+ */
20
+ export interface ControllerSchema {
21
+ /** Stable lowercase controller identifier (e.g. `"route"`). */
22
+ name: string;
23
+ /** Map of public state field names → human-readable type label. */
24
+ state?: Record<string, string>;
25
+ /** List of canonical command names available on the controller. */
26
+ commands?: ReadonlyArray<string>;
27
+ /** Host attributes the controller writes via `reflect()`. */
28
+ attributes?: ReadonlyArray<string>;
29
+ }
30
+
31
+ /**
32
+ * Base class for host-attached controllers.
33
+ *
34
+ * Subclasses MUST implement `getState()` and SHOULD declare a static
35
+ * `schema`; the constructor warns when these are missing the first
36
+ * time the controller is connected.
37
+ */
38
+ export class BaseController {
39
+ /** Optional schema (subclasses declare via `static schema = …`). */
40
+ static schema?: ControllerSchema;
41
+
42
+ /** The host element this controller is attached to, or `null`. */
43
+ readonly host: Element | null;
44
+
45
+ /**
46
+ * Wire the controller to a host element. Calls
47
+ * {@link onConnect} + {@link reflect} once.
48
+ */
49
+ connect(host: Element): void;
50
+
51
+ /**
52
+ * Detach from `host` (or the currently-connected host if omitted).
53
+ * Calls {@link onDisconnect}.
54
+ */
55
+ disconnect(host?: Element): void;
56
+
57
+ /**
58
+ * Subscribe to state-change notifications. Returns an unsubscribe
59
+ * function.
60
+ */
61
+ subscribe(fn: () => void): () => void;
62
+
63
+ /**
64
+ * Run subscriber callbacks + `reflect()` after a state mutation.
65
+ * Subclasses call this from their command implementations.
66
+ */
67
+ notify(): void;
68
+
69
+ /** Lifecycle hook — override to wire listeners at connect time. */
70
+ onConnect(host: Element): void;
71
+
72
+ /** Lifecycle hook — override to release listeners at disconnect time. */
73
+ onDisconnect(host: Element): void;
74
+
75
+ /**
76
+ * Override to write controller state into the host (attributes,
77
+ * data-* properties, etc.). Called on every {@link notify} + at
78
+ * `connect()`.
79
+ */
80
+ reflect(): void;
81
+
82
+ /**
83
+ * Return the controller's current public state. Subclasses MUST
84
+ * override. The default implementation throws.
85
+ */
86
+ getState(): unknown;
87
+ }
88
+
89
+ /**
90
+ * A single route declaration consumed by {@link RouteController}.
91
+ */
92
+ export interface Route {
93
+ /**
94
+ * Path pattern. Static segments match literally; segments prefixed
95
+ * with `:` are captured into `params`. e.g. `/users/:id`.
96
+ */
97
+ path: string;
98
+ /** Optional content URL for `<router-ui>` to fetch + inject. */
99
+ content?: string;
100
+ /** Optional document title to set when the route matches. */
101
+ title?: string;
102
+ /** Optional section identifier (consumer-defined). */
103
+ section?: string;
104
+ /** Open-ended — route definitions can carry arbitrary metadata. */
105
+ [key: string]: unknown;
106
+ }
107
+
108
+ /**
109
+ * Public state shape returned by {@link RouteController.getState}.
110
+ */
111
+ export interface RouteState {
112
+ /** Current pathname being matched. */
113
+ path: string;
114
+ /** Captured `:param` values from the matched route. */
115
+ params: Record<string, string>;
116
+ /** The matched route declaration, or `null` if no match. */
117
+ route: Route | null;
118
+ /** Previous pathname (before the most recent navigation). */
119
+ previous: string;
120
+ }
121
+
122
+ /**
123
+ * Imperative commands exposed by {@link RouteController}. Wire-up
124
+ * stable across both code-driven navigation + DOM-driven link clicks
125
+ * (the latter via `<router-ui>`'s click delegation).
126
+ */
127
+ export interface RouteCommands {
128
+ /** Push a new pathname onto the history stack + re-match routes. */
129
+ navigate(path: string): void;
130
+ /** Replace the current history entry's pathname + re-match. */
131
+ replace(path: string): void;
132
+ /** Equivalent to `history.back()` when `historySync` is on. */
133
+ back(): void;
134
+ /** Equivalent to `history.forward()` when `historySync` is on. */
135
+ forward(): void;
136
+ /** Swap the routes table at runtime (re-matches the current path). */
137
+ setRoutes(routes: ReadonlyArray<Route>): void;
138
+ }
139
+
140
+ /**
141
+ * Constructor options for {@link RouteController}.
142
+ */
143
+ export interface RouteControllerOptions {
144
+ /** Initial routes table. May be empty + updated later via `setRoutes`. */
145
+ routes?: ReadonlyArray<Route>;
146
+ /** Initial pathname (defaults to `location.pathname`). */
147
+ initial?: string;
148
+ /**
149
+ * When `true` (default), navigate/replace push to History API +
150
+ * `popstate` syncs state on browser back/forward.
151
+ */
152
+ historySync?: boolean;
153
+ }
154
+
155
+ /**
156
+ * Routing-state controller. Used by `<router-ui>` (see
157
+ * `core/provider.js`) as the canonical history-syncing route matcher.
158
+ * Can also be used standalone — `notify()` fires whenever the path
159
+ * changes; `getState()` returns the current match.
160
+ */
161
+ export class RouteController extends BaseController {
162
+ static schema: ControllerSchema;
163
+
164
+ constructor(options?: RouteControllerOptions);
165
+
166
+ /** Public state — path, params, matched route, previous path. */
167
+ getState(): RouteState;
168
+
169
+ /** Imperative API; wire from command palette / link handlers. */
170
+ commands: RouteCommands;
171
+ }
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Minimal markdown → HTML renderer for LLM output. Handles fenced code
3
+ * blocks, inline code, bold, italic, links, lists, headings, and
4
+ * paragraphs. No external dependencies.
5
+ *
6
+ * Fenced code blocks with a language identifier emit `<code-ui
7
+ * language="…">…</code-ui>` so the syntax-highlight upgrade picks them
8
+ * up automatically (see SPEC-CODE-EDITOR-001). Unlabeled fences keep
9
+ * the bare `<pre><code>…</code></pre>` form.
10
+ *
11
+ * Runtime exports mirror `core/markdown.js`. `.d.ts` authored in v0.5.6
12
+ * §191 to close the §178 audit-script baseline missing-sibling gap.
13
+ *
14
+ * @see ./markdown.js (runtime SoT)
15
+ */
16
+
17
+ /**
18
+ * Render a markdown source string to HTML.
19
+ *
20
+ * The output is a sanitized HTML string suitable for direct
21
+ * `element.innerHTML` assignment — text content is HTML-escaped before
22
+ * inline formatting is applied. Consumer is responsible for any
23
+ * additional context-specific sanitization (e.g. URL-scheme allowlisting
24
+ * for the link targets).
25
+ */
26
+ export function renderMarkdown(src: string): string;
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Optional polyfills — for consumers extending BELOW the library's
3
+ * stated baseline (Chromium 125+, Safari 17.4+, Firefox 129+).
4
+ *
5
+ * **Side-effect-only module.** Importing this file runs feature checks
6
+ * at module-evaluation time and dynamically loads polyfills only when
7
+ * the runtime lacks support:
8
+ *
9
+ * - Popover API (consumers extending to Firefox < 125 / Safari < 17)
10
+ * - CSS Anchor Positioning (consumers extending to Safari < 26 /
11
+ * Firefox < 147)
12
+ *
13
+ * Browsers with native support skip the download. The polyfill
14
+ * packages (`@oddbird/popover-polyfill`, `@oddbird/css-anchor-positioning`)
15
+ * are optional — if not installed, the import silently fails.
16
+ *
17
+ * Consumers on the stated baseline should NOT import this module — the
18
+ * runtime checks resolve to no-op, but skipping the file avoids the
19
+ * conditional `import()` setup entirely.
20
+ *
21
+ * Runtime mirror: `core/polyfills.js`. `.d.ts` authored in v0.5.6 §191
22
+ * to close the §178 audit-script baseline missing-sibling gap.
23
+ *
24
+ * @see ./polyfills.js (runtime SoT)
25
+ */
26
+
27
+ // Side-effect-only module — no exports. The empty `export {}` marks
28
+ // the file as an ES module so TypeScript treats `import '...polyfills.js'`
29
+ // as a valid module side-effect import without complaining about a
30
+ // missing module shape.
31
+ export {};
@@ -0,0 +1,82 @@
1
+ /**
2
+ * `<router-ui>` provider — declarative + imperative client-side
3
+ * routing built on {@link RouteController} (re-declared here for
4
+ * historical reasons; the canonical export lives in `core/controller.js`).
5
+ *
6
+ * Two consumer paths:
7
+ *
8
+ * 1. **Declarative** — assign `router.routes = [...]` and the provider
9
+ * instantiates its own controller, wires `popstate`, intercepts
10
+ * same-origin link clicks, fetches each matched route's `content`
11
+ * URL, and injects into the host element.
12
+ *
13
+ * 2. **Controller-driven** — construct a {@link RouteController}
14
+ * yourself + assign to `router.controller`. Useful when multiple
15
+ * UI surfaces need to share routing state.
16
+ *
17
+ * Side-effect: importing this module calls
18
+ * `customElements.define('router-ui', UIRouter)`.
19
+ *
20
+ * Runtime exports mirror `core/provider.js`. `.d.ts` authored in v0.5.6
21
+ * §191 to close the §178 audit-script baseline missing-sibling gap.
22
+ *
23
+ * @see ./provider.js (runtime SoT — also defines `customElements`)
24
+ * @see ./controller.d.ts (canonical `RouteController` typing)
25
+ */
26
+
27
+ import { UIElement } from './element.js';
28
+ import type { Route, RouteCommands, RouteState, ControllerSchema, RouteControllerOptions } from './controller.js';
29
+ import { BaseController } from './controller.js';
30
+
31
+ /**
32
+ * Routing-state controller. Re-declared from `core/controller.js` for
33
+ * historical compatibility — both files define the same class shape;
34
+ * consumers can import either. New code should prefer
35
+ * `import { RouteController } from '@adia-ai/web-components/core/controller'`
36
+ * for the canonical path.
37
+ */
38
+ export class RouteController extends BaseController {
39
+ static schema: ControllerSchema;
40
+ constructor(options?: RouteControllerOptions);
41
+ getState(): RouteState;
42
+ commands: RouteCommands;
43
+ }
44
+
45
+ /**
46
+ * Optional async transform applied to fetched route content before
47
+ * injection. Useful for wrapping content in a layout shell.
48
+ */
49
+ export type TemplateResolver = (html: string, route: Route) => string | Promise<string>;
50
+
51
+ /**
52
+ * `<router-ui>` custom element. Side-effect-registered on module load.
53
+ */
54
+ export class UIRouter extends UIElement {
55
+ /** Currently-bound controller (declarative-mode controller is auto-created). */
56
+ controller?: RouteController;
57
+
58
+ /** Optional template wrapper hook — see {@link TemplateResolver}. */
59
+ templateResolver?: TemplateResolver;
60
+
61
+ /**
62
+ * Declarative-mode setter — assigning routes auto-creates an
63
+ * internal {@link RouteController} on first assignment, or
64
+ * `setRoutes`-replaces the table on subsequent ones.
65
+ */
66
+ set routes(list: ReadonlyArray<Route>);
67
+
68
+ /** Shortcut for `controller.commands.navigate(path)`. */
69
+ navigate(path: string): void;
70
+
71
+ /** Shortcut for `controller.commands.replace(path)`. */
72
+ replace(path: string): void;
73
+ }
74
+
75
+ /**
76
+ * `router-ui` is registered as a side-effect of module load.
77
+ */
78
+ declare global {
79
+ interface HTMLElementTagNameMap {
80
+ 'router-ui': UIRouter;
81
+ }
82
+ }
@@ -0,0 +1,78 @@
1
+ /**
2
+ * streams-bridge — proxy data-stream signals into A2UI surface data
3
+ * models (per OD-CHART-16 option b).
4
+ *
5
+ * The bridge duck-types the renderer (it needs `.process()`, nothing
6
+ * else), so it works with any A2UI-protocol consumer — the actual
7
+ * `A2UIRenderer` from `@adia-ai/a2ui-runtime`, a custom renderer, or
8
+ * a test stub.
9
+ *
10
+ * Contract:
11
+ * - One-way only: stream → data model. A2UI writes back to its model
12
+ * (e.g. via `update-data-model` wiring actions) do NOT propagate
13
+ * into the stream signal.
14
+ * - Tear down with the returned dispose function. Dispose detaches
15
+ * the effect; it does NOT release the stream's refcount.
16
+ * - `select` uses dot-separated path syntax (matches
17
+ * `data-stream-path` on the trait). `path` uses slash-separated
18
+ * syntax (matches A2UI bindings).
19
+ *
20
+ * Runtime exports mirror `core/streams-bridge.js`. `.d.ts` authored in
21
+ * v0.5.6 §191 to close the §178 audit-script baseline missing-sibling
22
+ * gap.
23
+ *
24
+ * @see ./streams-bridge.js (runtime SoT)
25
+ * @see ./data-stream.js (the stream registry the bridge reads from)
26
+ */
27
+
28
+ /**
29
+ * Minimal renderer contract the bridge requires. The actual
30
+ * `A2UIRenderer` from `@adia-ai/a2ui-runtime` satisfies this surface,
31
+ * as does any custom renderer that handles
32
+ * `{ type: 'updateDataModel', ... }` actions.
33
+ */
34
+ export interface BridgeRenderer {
35
+ process(action: {
36
+ type: 'updateDataModel';
37
+ surfaceId: string;
38
+ path: string;
39
+ value: unknown;
40
+ }): void;
41
+ }
42
+
43
+ /**
44
+ * Bridge options shared by {@link bridgeStream} and
45
+ * {@link bridgeStreamAsync}.
46
+ */
47
+ export interface BridgeOptions {
48
+ /** Target surface ID inside the renderer's data model. */
49
+ surfaceId: string;
50
+ /** Stream registry ID (the same string passed to `acquireStream`). */
51
+ streamId: string;
52
+ /** Slash-separated A2UI data-model path inside the surface. */
53
+ path: string;
54
+ /** Optional dot-separated path to a sub-value within the stream's signal value. */
55
+ select?: string;
56
+ }
57
+
58
+ /**
59
+ * Bridge a registered stream into a renderer's surface data model.
60
+ *
61
+ * If the stream is not yet registered, logs a warning and returns a
62
+ * no-op dispose. Use {@link bridgeStreamAsync} when the stream might
63
+ * register after this call (e.g. DOM source connecting on the same
64
+ * tick as the bridge wiring).
65
+ *
66
+ * Returns a dispose function — call it to detach the effect.
67
+ */
68
+ export function bridgeStream(renderer: BridgeRenderer, opts: BridgeOptions): () => void;
69
+
70
+ /**
71
+ * Async variant — awaits the stream's registration before attaching
72
+ * the effect. Resolves once the bridge is wired (the resolved value
73
+ * is the dispose function).
74
+ */
75
+ export function bridgeStreamAsync(
76
+ renderer: BridgeRenderer,
77
+ opts: BridgeOptions,
78
+ ): Promise<() => void>;
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Transport — `fetch` wrapper with timeout, exponential-backoff
3
+ * retries, and a normalized {@link TransportError} for predictable
4
+ * downstream handling.
5
+ *
6
+ * Zero dependencies. Vanilla-JS-friendly — drop into CodePen,
7
+ * StackBlitz, or any vanilla project.
8
+ *
9
+ * Runtime exports mirror `core/transport.js`. `.d.ts` authored in
10
+ * v0.5.6 §191 to close the §178 audit-script baseline missing-sibling
11
+ * gap.
12
+ *
13
+ * @see ./transport.js (runtime SoT)
14
+ */
15
+
16
+ /**
17
+ * Discriminator for {@link TransportError} kinds. Lets consumers
18
+ * branch on user-cancellation (`abort`) vs network errors (`network`)
19
+ * vs HTTP-level non-2xx (`http`) vs timeout exhaustion (`timeout`).
20
+ */
21
+ export type TransportErrorKind = 'abort' | 'timeout' | 'network' | 'http';
22
+
23
+ /**
24
+ * Options for {@link request} and {@link json}.
25
+ */
26
+ export interface TransportOptions {
27
+ /** Standard `fetch` init forwarded as-is (method, headers, body, …). */
28
+ init?: RequestInit;
29
+ /** Per-request timeout in ms. Default: 30 000. Aborts the underlying fetch. */
30
+ timeout?: number;
31
+ /** Retry attempts on 5xx + network failures. Default: 0. */
32
+ retries?: number;
33
+ /** Base retry delay in ms; exponential backoff applies. Default: 1000. */
34
+ retryDelay?: number;
35
+ /** External `AbortSignal` — aborts the request + skips retries. */
36
+ signal?: AbortSignal;
37
+ }
38
+
39
+ /**
40
+ * Resilient `fetch` with timeout + retries. Returns the raw `Response`
41
+ * — consumers handle status codes (the `request()` path does NOT throw
42
+ * on non-2xx responses; use {@link json} when 2xx-only is desired).
43
+ *
44
+ * Throws {@link TransportError} on:
45
+ * - Caller-driven abort (`kind: 'abort'`)
46
+ * - Timeout exhaustion (`kind: 'timeout'`)
47
+ * - Network failure after retries exhausted (`kind: 'network'`)
48
+ */
49
+ export function request(url: string, options?: TransportOptions): Promise<Response>;
50
+
51
+ /**
52
+ * JSON-typed variant of {@link request}. On 2xx responses, returns the
53
+ * parsed JSON body. On non-2xx responses, throws {@link TransportError}
54
+ * with `kind: 'http'` + the status code + the body (parsed as JSON if
55
+ * possible, else raw text).
56
+ */
57
+ export function json<T = unknown>(url: string, options?: TransportOptions): Promise<T>;
58
+
59
+ /**
60
+ * Normalized error thrown by {@link request} and {@link json}. The
61
+ * `kind` discriminator lets consumers branch on user-cancellation vs
62
+ * timeout vs network vs HTTP-level failures.
63
+ *
64
+ * Inherits `message` + `cause` from `Error`.
65
+ */
66
+ export class TransportError extends Error {
67
+ /** Error category — see {@link TransportErrorKind}. */
68
+ kind: TransportErrorKind;
69
+ /** HTTP status code on `kind: 'http'`; `undefined` otherwise. */
70
+ status?: number;
71
+ /** Response body on `kind: 'http'` (parsed JSON or raw text). */
72
+ body?: unknown;
73
+
74
+ constructor(
75
+ message: string,
76
+ options?: { kind?: TransportErrorKind; status?: number; body?: unknown; cause?: unknown },
77
+ );
78
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adia-ai/web-components",
3
- "version": "0.5.5",
3
+ "version": "0.5.6",
4
4
  "description": "AdiaUI web components \u2014 vanilla custom elements. A2UI runtime (renderer, registry, streams, wiring) lives in @adia-ai/a2ui-runtime.",
5
5
  "type": "module",
6
6
  "types": "./index.d.ts",