@exponential_app/eui 0.0.0-stage → 0.2.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.
- package/LICENSE +201 -0
- package/NOTICE +54 -0
- package/README.md +377 -2
- package/catalog/a11y.json +705 -0
- package/catalog/basic-map.json +104 -0
- package/catalog/code.json +58 -0
- package/catalog/core.catalog.json +5190 -0
- package/catalog/core.schema.json +24542 -0
- package/catalog/host.json +95 -0
- package/catalog/layout.json +20 -0
- package/catalog/limits.json +9 -0
- package/catalog/locale.json +48 -0
- package/catalog/macros.json +4152 -0
- package/catalog/recipes.json +64 -0
- package/catalog/strings.json +84 -0
- package/catalog/style.json +180 -0
- package/catalog/theme.schema.json +47754 -0
- package/catalog/tokens.json +47 -0
- package/conformance/README.md +218 -0
- package/conformance/baseline.ts +101 -0
- package/conformance/browser-page.ts +146 -0
- package/conformance/browser-suites.ts +699 -0
- package/conformance/compare.ts +201 -0
- package/conformance/dom.ts +97 -0
- package/conformance/dump.ts +163 -0
- package/conformance/fonts.json +157 -0
- package/conformance/manifest.json +233 -0
- package/conformance/parity-compare.ts +191 -0
- package/conformance/parity-report.schema.json +73 -0
- package/conformance/parity.ts +412 -0
- package/conformance/pixel.ts +177 -0
- package/conformance/primitives-page.ts +49 -0
- package/conformance/report.schema.json +66 -0
- package/conformance/run.ts +118 -0
- package/conformance/voice-wave-child.ts +102 -0
- package/dist/chunks/index-5fmaa0xq.js +8384 -0
- package/dist/chunks/index-5fmaa0xq.js.map +10 -0
- package/dist/chunks/index-62yzr94z.js +2784 -0
- package/dist/chunks/index-62yzr94z.js.map +10 -0
- package/dist/chunks/index-bg2jsgjq.js +8541 -0
- package/dist/chunks/index-bg2jsgjq.js.map +15 -0
- package/dist/chunks/index-fy7y2nz8.js +186 -0
- package/dist/chunks/index-fy7y2nz8.js.map +9 -0
- package/dist/chunks/index-gtk2gwsb.js +4555 -0
- package/dist/chunks/index-gtk2gwsb.js.map +31 -0
- package/dist/chunks/index-t6qz1770.js +95 -0
- package/dist/chunks/index-t6qz1770.js.map +11 -0
- package/dist/conformance.js +230462 -0
- package/dist/conformance.js.map +10 -0
- package/dist/entries/prompt.js +251 -0
- package/dist/entries/prompt.js.map +11 -0
- package/dist/entries/schema.js +1725 -0
- package/dist/entries/schema.js.map +11 -0
- package/dist/host/index.js +194 -0
- package/dist/host/index.js.map +9 -0
- package/dist/index.js +3840 -0
- package/dist/index.js.map +29 -0
- package/dist/types/src/a11y.d.ts +21 -0
- package/dist/types/src/animation.d.ts +76 -0
- package/dist/types/src/basic-map.d.ts +38 -0
- package/dist/types/src/builder.d.ts +50 -0
- package/dist/types/src/catalog.d.ts +54 -0
- package/dist/types/src/catalog.described.d.ts +33 -0
- package/dist/types/src/catalog.generated.d.ts +904 -0
- package/dist/types/src/chart.d.ts +46 -0
- package/dist/types/src/code.d.ts +44 -0
- package/dist/types/src/color.d.ts +20 -0
- package/dist/types/src/conformance.d.ts +39 -0
- package/dist/types/src/connector/app.d.ts +14 -0
- package/dist/types/src/connector/connector.d.ts +77 -0
- package/dist/types/src/connector/index.d.ts +4 -0
- package/dist/types/src/css.d.ts +27 -0
- package/dist/types/src/define.d.ts +66 -0
- package/dist/types/src/direction.d.ts +16 -0
- package/dist/types/src/dynamic.d.ts +161 -0
- package/dist/types/src/entries/prompt.d.ts +11 -0
- package/dist/types/src/entries/schema.d.ts +8 -0
- package/dist/types/src/expr.d.ts +71 -0
- package/dist/types/src/extension.d.ts +4 -0
- package/dist/types/src/format.d.ts +112 -0
- package/dist/types/src/geometry.d.ts +40 -0
- package/dist/types/src/host/contract.d.ts +225 -0
- package/dist/types/src/host/decoders.d.ts +61 -0
- package/dist/types/src/host/index.d.ts +15 -0
- package/dist/types/src/host/package.d.ts +102 -0
- package/dist/types/src/host/policy.d.ts +107 -0
- package/dist/types/src/host/record-store.d.ts +103 -0
- package/dist/types/src/host/records.d.ts +45 -0
- package/dist/types/src/host/router.d.ts +38 -0
- package/dist/types/src/host/runtime.d.ts +213 -0
- package/dist/types/src/host/signature.d.ts +52 -0
- package/dist/types/src/host/sources.d.ts +22 -0
- package/dist/types/src/host/tools.d.ts +42 -0
- package/dist/types/src/host/transports.d.ts +109 -0
- package/dist/types/src/index.d.ts +69 -0
- package/dist/types/src/layout.d.ts +20 -0
- package/dist/types/src/limits.d.ts +21 -0
- package/dist/types/src/list.d.ts +133 -0
- package/dist/types/src/locale.d.ts +22 -0
- package/dist/types/src/macros.d.ts +29 -0
- package/dist/types/src/overlay.d.ts +27 -0
- package/dist/types/src/prompt.d.ts +44 -0
- package/dist/types/src/qr-code.d.ts +30 -0
- package/dist/types/src/recipes.d.ts +17 -0
- package/dist/types/src/reducer.d.ts +41 -0
- package/dist/types/src/resizable.d.ts +38 -0
- package/dist/types/src/schema.d.ts +7 -0
- package/dist/types/src/strings.d.ts +13 -0
- package/dist/types/src/style.d.ts +201 -0
- package/dist/types/src/test-preload.d.ts +1 -0
- package/dist/types/src/text-shimmer.d.ts +24 -0
- package/dist/types/src/theme-types.d.ts +162 -0
- package/dist/types/src/theme.d.ts +75 -0
- package/dist/types/src/themes.d.ts +22 -0
- package/dist/types/src/tree-guides.d.ts +17 -0
- package/dist/types/src/types.d.ts +320 -0
- package/dist/types/src/validate.d.ts +31 -0
- package/dist/types/src/voice-wave.d.ts +181 -0
- package/dist/types/src/web/base-css.d.ts +1 -0
- package/dist/types/src/web/box-css.d.ts +63 -0
- package/dist/types/src/web/coerce.d.ts +32 -0
- package/dist/types/src/web/custom-icons.generated.d.ts +4 -0
- package/dist/types/src/web/data.d.ts +107 -0
- package/dist/types/src/web/dates.d.ts +12 -0
- package/dist/types/src/web/form.d.ts +44 -0
- package/dist/types/src/web/host-types.d.ts +126 -0
- package/dist/types/src/web/index.d.ts +35 -0
- package/dist/types/src/web/inputs.d.ts +55 -0
- package/dist/types/src/web/list.d.ts +16 -0
- package/dist/types/src/web/listbox.d.ts +14 -0
- package/dist/types/src/web/markdown.d.ts +96 -0
- package/dist/types/src/web/media.d.ts +63 -0
- package/dist/types/src/web/parts.d.ts +4 -0
- package/dist/types/src/web/primitives/alert-dialog.d.ts +10 -0
- package/dist/types/src/web/primitives/alert.d.ts +9 -0
- package/dist/types/src/web/primitives/avatar-color.d.ts +2 -0
- package/dist/types/src/web/primitives/avatar.d.ts +13 -0
- package/dist/types/src/web/primitives/badge.d.ts +10 -0
- package/dist/types/src/web/primitives/breadcrumb.d.ts +10 -0
- package/dist/types/src/web/primitives/button.d.ts +6 -0
- package/dist/types/src/web/primitives/calendar.d.ts +43 -0
- package/dist/types/src/web/primitives/card.d.ts +9 -0
- package/dist/types/src/web/primitives/checkbox.d.ts +5 -0
- package/dist/types/src/web/primitives/choice-tiles.d.ts +32 -0
- package/dist/types/src/web/primitives/cn.d.ts +3 -0
- package/dist/types/src/web/primitives/code-block.d.ts +24 -0
- package/dist/types/src/web/primitives/command.d.ts +134 -0
- package/dist/types/src/web/primitives/context-ring.d.ts +24 -0
- package/dist/types/src/web/primitives/dialog-arms.d.ts +6 -0
- package/dist/types/src/web/primitives/dialog.d.ts +24 -0
- package/dist/types/src/web/primitives/disclosure-header.d.ts +5 -0
- package/dist/types/src/web/primitives/dock.d.ts +42 -0
- package/dist/types/src/web/primitives/dropdown-menu.d.ts +14 -0
- package/dist/types/src/web/primitives/empty-state.d.ts +15 -0
- package/dist/types/src/web/primitives/glass-card.d.ts +4 -0
- package/dist/types/src/web/primitives/hover-card.d.ts +7 -0
- package/dist/types/src/web/primitives/icon-disc.d.ts +12 -0
- package/dist/types/src/web/primitives/index.d.ts +50 -0
- package/dist/types/src/web/primitives/input.d.ts +5 -0
- package/dist/types/src/web/primitives/kbd.d.ts +4 -0
- package/dist/types/src/web/primitives/label.d.ts +3 -0
- package/dist/types/src/web/primitives/measure.d.ts +16 -0
- package/dist/types/src/web/primitives/menu-surface.d.ts +17 -0
- package/dist/types/src/web/primitives/meter.d.ts +21 -0
- package/dist/types/src/web/primitives/popover.d.ts +3 -0
- package/dist/types/src/web/primitives/progress-ring.d.ts +5 -0
- package/dist/types/src/web/primitives/progress.d.ts +8 -0
- package/dist/types/src/web/primitives/scroll-area.d.ts +49 -0
- package/dist/types/src/web/primitives/segmented-control.d.ts +5 -0
- package/dist/types/src/web/primitives/select.d.ts +47 -0
- package/dist/types/src/web/primitives/separator.d.ts +3 -0
- package/dist/types/src/web/primitives/sheet-chrome.d.ts +4 -0
- package/dist/types/src/web/primitives/sheet.d.ts +20 -0
- package/dist/types/src/web/primitives/skeleton.d.ts +3 -0
- package/dist/types/src/web/primitives/spinner.d.ts +3 -0
- package/dist/types/src/web/primitives/switch.d.ts +4 -0
- package/dist/types/src/web/primitives/table.d.ts +11 -0
- package/dist/types/src/web/primitives/tabs.d.ts +13 -0
- package/dist/types/src/web/primitives/textarea.d.ts +3 -0
- package/dist/types/src/web/primitives/toast.d.ts +163 -0
- package/dist/types/src/web/primitives/tooltip.d.ts +3 -0
- package/dist/types/src/web/primitives/truncate.d.ts +7 -0
- package/dist/types/src/web/primitives/typeahead-portal.d.ts +12 -0
- package/dist/types/src/web/primitives/voice-wave.d.ts +50 -0
- package/dist/types/src/web/round5.d.ts +107 -0
- package/dist/types/src/web/share.d.ts +6 -0
- package/dist/types/src/web/table.d.ts +20 -0
- package/dist/types/src/web/theme-css.d.ts +69 -0
- package/dist/types/src/web/urls.d.ts +21 -0
- package/dist/web/index.js +2565 -0
- package/dist/web/index.js.map +28 -0
- package/dist/web/primitives/index.js +1476 -0
- package/dist/web/primitives/index.js.map +57 -0
- package/docs/components.generated.json +6783 -0
- package/docs/package-format.md +182 -0
- package/docs/round-1-contract.md +679 -0
- package/docs/round-2-contract.md +476 -0
- package/docs/round-3-contract.md +174 -0
- package/docs/round-5-contract.md +268 -0
- package/docs/themes.generated.json +3647 -0
- package/fixtures/animations.json +2890 -0
- package/fixtures/bench-list.json +58 -0
- package/fixtures/bind-time.json +54734 -0
- package/fixtures/catalog-basic-map.json +1692 -0
- package/fixtures/catalog-components.json +10293 -0
- package/fixtures/catalog-extension.json +620 -0
- package/fixtures/catalog-macros.json +51805 -0
- package/fixtures/code-tokens.json +1993 -0
- package/fixtures/conformance-baseline.json +59016 -0
- package/fixtures/conformance-cases.json +49 -0
- package/fixtures/conformance-known.json +2111 -0
- package/fixtures/control-geometry.json +5129 -0
- package/fixtures/dashboard.data.json +74 -0
- package/fixtures/dashboard.json +781 -0
- package/fixtures/demo-surface.json +47 -0
- package/fixtures/format.json +870 -0
- package/fixtures/host-package.json +1262 -0
- package/fixtures/host-policy.json +1209 -0
- package/fixtures/host-router.json +2034 -0
- package/fixtures/host-transport.json +590 -0
- package/fixtures/interactions-round1.json +1058 -0
- package/fixtures/kitchen-sink.expanded.json +11972 -0
- package/fixtures/kitchen-sink.json +3140 -0
- package/fixtures/layout-geometry-round1.json +7278 -0
- package/fixtures/layout-geometry.json +2072 -0
- package/fixtures/overlay-geometry.json +272 -0
- package/fixtures/pointer.json +89 -0
- package/fixtures/primitive-specimens.json +59 -0
- package/fixtures/prompt-budget.json +33 -0
- package/fixtures/qr-code.json +480 -0
- package/fixtures/resizable.json +714 -0
- package/fixtures/round4-contract.json +2985 -0
- package/fixtures/specimens.json +11168 -0
- package/fixtures/style-conditions.json +336 -0
- package/fixtures/template-items.json +2215 -0
- package/fixtures/text-direction.json +309 -0
- package/fixtures/text-shimmer.json +96 -0
- package/fixtures/theme-extends.json +573 -0
- package/fixtures/theme-invalid.json +1300 -0
- package/fixtures/theme-recipes.json +61762 -0
- package/fixtures/theme-resolved.json +25969 -0
- package/fixtures/toast-stack.json +215 -0
- package/fixtures/tree-guides.json +224 -0
- package/fixtures/virtual-list.json +733 -0
- package/fixtures/voice-wave.json +19236 -0
- package/generated/ExponentialUICatalog.generated.kt +67 -0
- package/generated/ExponentialUICatalog.generated.swift +67 -0
- package/generated/ExponentialUIThemes.generated.kt +23 -0
- package/generated/ExponentialUIThemes.generated.swift +23 -0
- package/generated/catalog.descriptions.generated.rs +6 -0
- package/generated/catalog.generated.rs +80 -0
- package/generated/catalog.themes.generated.rs +34 -0
- package/generated/core.descriptions.json +2726 -0
- package/generated/core.runtime.json +3944 -0
- package/package.json +87 -4
- package/themes/exponential.recipes.json +49 -0
- package/themes/exponential.theme.json +768 -0
- package/themes/neutral.theme.json +6178 -0
- package/themes/orange.theme.json +43 -0
- package/themes/playful.theme.json +219 -0
- package/vendor/a2ui/LICENSE.txt +203 -0
- package/vendor/a2ui/README.md +27 -0
- package/vendor/a2ui/v0_9/basic_catalog.json +1387 -0
- package/vendor/a2ui/v0_9/basic_catalog_rules.txt +5 -0
- package/vendor/a2ui/v0_9/client_capabilities.json +97 -0
- package/vendor/a2ui/v0_9/client_to_server.json +104 -0
- package/vendor/a2ui/v0_9/common_types.json +315 -0
- package/vendor/a2ui/v0_9/server_to_client.json +132 -0
- package/vendor/json-render/LICENSE.txt +201 -0
- package/vendor/json-render/README.md +13 -0
- package/vendor/nayuki-qr/LICENSE.txt +20 -0
- package/vendor/nayuki-qr/README.md +10 -0
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import type { AppPackage } from "./package.js";
|
|
2
|
+
import type { ParsedSource, SourceResolver } from "./sources.js";
|
|
3
|
+
/** The binding scheme: `records:<kind>[?query]`. */
|
|
4
|
+
export declare const RECORDS_SCHEME = "records";
|
|
5
|
+
/** The write functions (no consent card: the app's own rows). */
|
|
6
|
+
export declare const RECORDS_FUNCTIONS: readonly string[];
|
|
7
|
+
/** The neutral query's defaults (catalog/host.json `package.records.query`). */
|
|
8
|
+
export declare const RECORDS_QUERY: {
|
|
9
|
+
readonly sortDefault: "createdAt";
|
|
10
|
+
readonly orderDefault: "desc";
|
|
11
|
+
readonly limitDefault: 100;
|
|
12
|
+
readonly limitMax: 500;
|
|
13
|
+
};
|
|
14
|
+
/** Query keys a host may give a meaning (Exponential does); never a field filter. */
|
|
15
|
+
export declare const RECORDS_RESERVED_PARAMS: readonly string[];
|
|
16
|
+
export interface RecordRow {
|
|
17
|
+
id: string;
|
|
18
|
+
kind: string;
|
|
19
|
+
data: Record<string, unknown>;
|
|
20
|
+
createdBy: string | null;
|
|
21
|
+
createdAt: string;
|
|
22
|
+
updatedAt: string;
|
|
23
|
+
}
|
|
24
|
+
export type RecordsFilterOp = `eq` | `gt` | `gte` | `lt` | `lte`;
|
|
25
|
+
export interface RecordsQuery {
|
|
26
|
+
kind: string;
|
|
27
|
+
mine: boolean;
|
|
28
|
+
sort: string;
|
|
29
|
+
order: `asc` | `desc`;
|
|
30
|
+
limit: number;
|
|
31
|
+
/** By field, then operator. */
|
|
32
|
+
filters: {
|
|
33
|
+
field: string;
|
|
34
|
+
op: RecordsFilterOp;
|
|
35
|
+
value: string;
|
|
36
|
+
}[];
|
|
37
|
+
}
|
|
38
|
+
export interface RecordsValue {
|
|
39
|
+
rows: Record<string, unknown>[];
|
|
40
|
+
count: number;
|
|
41
|
+
}
|
|
42
|
+
/** `records:<kind>?…` (as `parseSource` gives it) → the query; null = not
|
|
43
|
+
* a records source. */
|
|
44
|
+
export declare function parseRecordsSource(source: Pick<ParsedSource, `scheme` | `name` | `params`>): RecordsQuery | null;
|
|
45
|
+
/** The value a `records:` binding emits over `rows` (any kind): the kind's
|
|
46
|
+
* matching rows sorted (ties by id) then cut at the limit, `count` before
|
|
47
|
+
* the limit. `names` = user id → the display name (`author`). */
|
|
48
|
+
export declare function recordsValue(rows: readonly RecordRow[], query: RecordsQuery, ctx: {
|
|
49
|
+
me: string | null;
|
|
50
|
+
names?: Record<string, string>;
|
|
51
|
+
}): RecordsValue;
|
|
52
|
+
/** What a host provides: one package's records, any transport. */
|
|
53
|
+
export interface RecordStore {
|
|
54
|
+
/** Every row of the package (any kind) now, then on every change; returns the cancel. */
|
|
55
|
+
subscribe(emit: (rows: readonly RecordRow[]) => void): () => void;
|
|
56
|
+
/** Create (no id) or shallow-patch `data` (id); resolves the row's id. The
|
|
57
|
+
* caller has validated the result against the kind's schema. */
|
|
58
|
+
upsert(input: {
|
|
59
|
+
kind: string;
|
|
60
|
+
data: Record<string, unknown>;
|
|
61
|
+
id?: string;
|
|
62
|
+
}): Promise<{
|
|
63
|
+
id: string;
|
|
64
|
+
}>;
|
|
65
|
+
delete(id: string): Promise<void>;
|
|
66
|
+
/** One row by id (the patch base). */
|
|
67
|
+
get(id: string): RecordRow | undefined;
|
|
68
|
+
}
|
|
69
|
+
/** The reference store: in memory, `now` + `newId` injectable. */
|
|
70
|
+
export declare class MemoryRecordStore implements RecordStore {
|
|
71
|
+
private readonly options;
|
|
72
|
+
private rows;
|
|
73
|
+
private listeners;
|
|
74
|
+
private seq;
|
|
75
|
+
constructor(options?: {
|
|
76
|
+
me?: string | null;
|
|
77
|
+
now?: () => string;
|
|
78
|
+
newId?: () => string;
|
|
79
|
+
rows?: readonly RecordRow[];
|
|
80
|
+
});
|
|
81
|
+
subscribe(emit: (rows: readonly RecordRow[]) => void): () => void;
|
|
82
|
+
get(id: string): RecordRow | undefined;
|
|
83
|
+
upsert(input: {
|
|
84
|
+
kind: string;
|
|
85
|
+
data: Record<string, unknown>;
|
|
86
|
+
id?: string;
|
|
87
|
+
}): Promise<{
|
|
88
|
+
id: string;
|
|
89
|
+
}>;
|
|
90
|
+
delete(id: string): Promise<void>;
|
|
91
|
+
private changed;
|
|
92
|
+
}
|
|
93
|
+
/** A package's records on a host: the `records` source resolver and the
|
|
94
|
+
* two write functions (pass them to `ExponentialHost` as `sources` /
|
|
95
|
+
* `functions`). A write is validated against the kind's schema (a patch:
|
|
96
|
+
* the merged data) before the store sees it; a refusal throws. */
|
|
97
|
+
export declare function recordsHost(pkg: Pick<AppPackage, `records`>, store: RecordStore, ctx?: {
|
|
98
|
+
me: string | null;
|
|
99
|
+
names?: Record<string, string>;
|
|
100
|
+
}): {
|
|
101
|
+
sources: Record<string, SourceResolver>;
|
|
102
|
+
functions: Record<string, (args: Record<string, unknown>) => Promise<unknown>>;
|
|
103
|
+
};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { PackageIssue } from "./package.js";
|
|
2
|
+
/** `^[a-z][a-z0-9_]{0,31}$`: a kind's name (catalog/host.json `package.records`). */
|
|
3
|
+
export declare const RECORD_KIND_PATTERN: RegExp;
|
|
4
|
+
/** The keys every record row carries; a schema may not declare them. */
|
|
5
|
+
export declare const RECORD_RESERVED_KEYS: readonly string[];
|
|
6
|
+
export declare const RECORD_FIELD_TYPES: readonly string[];
|
|
7
|
+
export declare const RECORD_ITEM_TYPES: readonly string[];
|
|
8
|
+
export declare const RECORD_FORMATS: readonly string[];
|
|
9
|
+
export interface RecordItems {
|
|
10
|
+
type: `string` | `number` | `integer` | `boolean`;
|
|
11
|
+
enum?: string[];
|
|
12
|
+
}
|
|
13
|
+
export interface RecordField {
|
|
14
|
+
type: `string` | `number` | `integer` | `boolean` | `array`;
|
|
15
|
+
/** Strings only: the allowed values. */
|
|
16
|
+
enum?: string[];
|
|
17
|
+
/** Arrays only: what an item is. */
|
|
18
|
+
items?: RecordItems;
|
|
19
|
+
/** Strings: characters; arrays: items. */
|
|
20
|
+
maxLength?: number;
|
|
21
|
+
minimum?: number;
|
|
22
|
+
maximum?: number;
|
|
23
|
+
/** Strings only: `date` (YYYY-MM-DD), `date-time` (ISO 8601), `time` (HH:MM[:SS]). */
|
|
24
|
+
format?: `date` | `date-time` | `time`;
|
|
25
|
+
description?: string;
|
|
26
|
+
}
|
|
27
|
+
export interface RecordSchema {
|
|
28
|
+
type: `object`;
|
|
29
|
+
properties: Record<string, RecordField>;
|
|
30
|
+
required?: string[];
|
|
31
|
+
/** Default false: a key outside `properties` is refused. */
|
|
32
|
+
additionalProperties?: boolean;
|
|
33
|
+
}
|
|
34
|
+
export interface RecordKind {
|
|
35
|
+
schema: RecordSchema;
|
|
36
|
+
title?: string;
|
|
37
|
+
description?: string;
|
|
38
|
+
}
|
|
39
|
+
/** Every problem with a kind's schema, each with a JSON pointer under `at`. */
|
|
40
|
+
export declare function validateRecordSchema(schema: unknown, at: string): PackageIssue[];
|
|
41
|
+
/** Every problem with `data` against `schema` (a valid one): `/field`
|
|
42
|
+
* pointers. A null or missing optional field passes; a required one does
|
|
43
|
+
* not; a key the schema does not declare is refused unless
|
|
44
|
+
* `additionalProperties` is true. */
|
|
45
|
+
export declare function validateRecord(schema: RecordSchema, data: unknown): PackageIssue[];
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { HostOp } from "./contract.js";
|
|
2
|
+
import type { AvailableExtension, PackageIssue, AppPackage } from "./package.js";
|
|
3
|
+
export interface HostRouterOptions {
|
|
4
|
+
/** Extension catalog ids the host registered (negotiation). */
|
|
5
|
+
extensionIds?: readonly string[];
|
|
6
|
+
/** VAPP-161: their versions and components (a package's `extensions`
|
|
7
|
+
* are checked against them; unset = only that the id is registered). */
|
|
8
|
+
extensions?: readonly AvailableExtension[];
|
|
9
|
+
}
|
|
10
|
+
export interface SurfaceInfo {
|
|
11
|
+
surfaceId: string;
|
|
12
|
+
catalogId: string;
|
|
13
|
+
/** The package whose template created it (its function policy). */
|
|
14
|
+
packageId?: string;
|
|
15
|
+
}
|
|
16
|
+
export declare class HostRouter {
|
|
17
|
+
private extensionIds;
|
|
18
|
+
private surfaces;
|
|
19
|
+
private packages;
|
|
20
|
+
private extensions;
|
|
21
|
+
constructor(options?: HostRouterOptions);
|
|
22
|
+
get supportedCatalogIds(): string[];
|
|
23
|
+
registerExtension(id: string, available?: AvailableExtension): void;
|
|
24
|
+
/** Install a declarative package: its templates become `applyTemplate`
|
|
25
|
+
* targets. Returns the validation issues (installed only when none). */
|
|
26
|
+
installPackage(pkg: AppPackage): PackageIssue[];
|
|
27
|
+
package(id: string): AppPackage | undefined;
|
|
28
|
+
surface(id: string): SurfaceInfo | undefined;
|
|
29
|
+
surfaceIds(): string[];
|
|
30
|
+
/** One server message → the ops to perform, in order. Never throws. */
|
|
31
|
+
route(message: unknown): HostOp[];
|
|
32
|
+
private findPackage;
|
|
33
|
+
private invalid;
|
|
34
|
+
private missing;
|
|
35
|
+
}
|
|
36
|
+
/** A2UI: an omitted path or `/` is the whole data model (`""` in JSON
|
|
37
|
+
* pointer terms, which every surface's setPointer takes). */
|
|
38
|
+
export declare function normalizePath(path: string | undefined): string;
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
import type { ResolvedTheme } from "../theme-types.js";
|
|
2
|
+
import type { ExtensionDef, FlatComponent, ReduceIssue, UiNode } from "../types.js";
|
|
3
|
+
import type { ClientMessage, HostOp } from "./contract.js";
|
|
4
|
+
import type { PackageIssue, AppPackage } from "./package.js";
|
|
5
|
+
import type { FunctionDecision, FunctionPolicy, MediaOptions, MediaRequest, UrlPolicy } from "./policy.js";
|
|
6
|
+
import { HostRouter } from "./router.js";
|
|
7
|
+
import type { SourceResolvers } from "./sources.js";
|
|
8
|
+
export type TransportStatus = `connecting` | `open` | `closed` | `error`;
|
|
9
|
+
/** Messages in, client messages out. Adapters: `transports.ts`. */
|
|
10
|
+
export interface Transport {
|
|
11
|
+
/** Start delivering messages; report the connection state. */
|
|
12
|
+
start(receive: (message: unknown) => void, status: (status: TransportStatus, detail?: string) => void): void;
|
|
13
|
+
send(message: ClientMessage): void | Promise<void>;
|
|
14
|
+
close(): void;
|
|
15
|
+
}
|
|
16
|
+
export interface FunctionCallInfo {
|
|
17
|
+
surfaceId: string;
|
|
18
|
+
componentId: string;
|
|
19
|
+
name: string;
|
|
20
|
+
args: Record<string, unknown>;
|
|
21
|
+
}
|
|
22
|
+
export type HostFunction = (args: Record<string, unknown>, call: FunctionCallInfo) => unknown | Promise<unknown>;
|
|
23
|
+
export interface HostPolicy {
|
|
24
|
+
/** The declarative gate; `ask` decisions go to onFunctionCall. */
|
|
25
|
+
functions?: FunctionPolicy;
|
|
26
|
+
/** The consent hook: true runs the call. Unset = `ask` is denied. */
|
|
27
|
+
onFunctionCall?: (call: FunctionCallInfo) => boolean | Promise<boolean>;
|
|
28
|
+
urls?: UrlPolicy;
|
|
29
|
+
/** Opens an allowed url (default: `window.open(url, "_blank")`). */
|
|
30
|
+
openUrl?: (url: string) => void;
|
|
31
|
+
media?: MediaOptions;
|
|
32
|
+
}
|
|
33
|
+
export interface HostOptions {
|
|
34
|
+
transport?: Transport;
|
|
35
|
+
functions?: Record<string, HostFunction>;
|
|
36
|
+
sources?: SourceResolvers;
|
|
37
|
+
extensions?: readonly ExtensionDef[];
|
|
38
|
+
packages?: readonly AppPackage[];
|
|
39
|
+
policy?: HostPolicy;
|
|
40
|
+
/** Every client message that leaves (after the transport got it). */
|
|
41
|
+
onSend?: (message: ClientMessage) => void;
|
|
42
|
+
/** Ops the host performs (tests, logging). */
|
|
43
|
+
onOp?: (op: HostOp) => void;
|
|
44
|
+
/** Every problem the host meets (a package that failed validation, an
|
|
45
|
+
* error it answered a message with, an invalid surface theme). A
|
|
46
|
+
* transport-less host has no server to tell: this is where they land. */
|
|
47
|
+
onIssue?: (issue: HostIssue) => void;
|
|
48
|
+
}
|
|
49
|
+
/** One problem the host met; `host.issues` keeps the latest ones. */
|
|
50
|
+
export interface HostIssue {
|
|
51
|
+
/** A host error code (`TEMPLATE_NOT_FOUND`…) or `PACKAGE_INVALID`. */
|
|
52
|
+
code: string;
|
|
53
|
+
message: string;
|
|
54
|
+
surfaceId?: string;
|
|
55
|
+
/** A JSON pointer (into the package or the message). */
|
|
56
|
+
path?: string;
|
|
57
|
+
packageId?: string;
|
|
58
|
+
}
|
|
59
|
+
/** A package passed in `HostOptions.packages` that failed validation. */
|
|
60
|
+
export declare class PackageError extends Error {
|
|
61
|
+
readonly packageId: string;
|
|
62
|
+
readonly issues: PackageIssue[];
|
|
63
|
+
constructor(packageId: string, issues: PackageIssue[]);
|
|
64
|
+
}
|
|
65
|
+
/** A `createSurface.theme` (a built-in id or a theme JSON) → the resolved
|
|
66
|
+
* theme, or why it is unusable. */
|
|
67
|
+
export declare function resolveSurfaceTheme(input: unknown): {
|
|
68
|
+
theme: ResolvedTheme | null;
|
|
69
|
+
issues: string[];
|
|
70
|
+
};
|
|
71
|
+
export interface FunctionOutcome {
|
|
72
|
+
decision: FunctionDecision;
|
|
73
|
+
result?: unknown;
|
|
74
|
+
error?: string;
|
|
75
|
+
}
|
|
76
|
+
type Listener = () => void;
|
|
77
|
+
/** One surface's state: the flat components, the data model, the reduced
|
|
78
|
+
* tree. Mutations notify subscribers; `root` is reduced lazily. */
|
|
79
|
+
export declare class SurfaceStore {
|
|
80
|
+
private extensions;
|
|
81
|
+
readonly surfaceId: string;
|
|
82
|
+
catalogId: string;
|
|
83
|
+
packageId?: string;
|
|
84
|
+
sendDataModel: boolean;
|
|
85
|
+
/** The flat components, mutated in place while nothing holds them. */
|
|
86
|
+
private list;
|
|
87
|
+
/** `list` was handed out (`components`): the next update copies first. */
|
|
88
|
+
private shared;
|
|
89
|
+
private positions;
|
|
90
|
+
data: Record<string, unknown>;
|
|
91
|
+
/** The server's `createSurface.theme`, resolved (undefined = the
|
|
92
|
+
* renderer's own theme). */
|
|
93
|
+
theme?: ResolvedTheme;
|
|
94
|
+
private reduced;
|
|
95
|
+
private listeners;
|
|
96
|
+
version: number;
|
|
97
|
+
constructor(surfaceId: string, catalogId: string, extensions: () => readonly ExtensionDef[]);
|
|
98
|
+
/** The flat components as a SNAPSHOT: an array handed out here is never
|
|
99
|
+
* mutated afterwards (the next update copies first), so a renderer that
|
|
100
|
+
* keeps it sees a stable value; a stream nobody reads stays linear. */
|
|
101
|
+
get components(): readonly FlatComponent[];
|
|
102
|
+
/** The flat component with this id (undefined = none). */
|
|
103
|
+
component(id: string): FlatComponent | undefined;
|
|
104
|
+
get root(): UiNode | null;
|
|
105
|
+
get issues(): ReduceIssue[];
|
|
106
|
+
/** Round 2 §4: the reducer's lifted data templates (absent without any). */
|
|
107
|
+
get templates(): Record<string, UiNode> | undefined;
|
|
108
|
+
private reduce;
|
|
109
|
+
/** A2UI: a later update replaces components BY ID and keeps the rest
|
|
110
|
+
* (an id → position map: a streamed surface costs linear, VAPP-103). */
|
|
111
|
+
setComponents(components: readonly FlatComponent[]): void;
|
|
112
|
+
/** Re-reduce on the next read (the extension set changed). */
|
|
113
|
+
invalidate(): void;
|
|
114
|
+
/** Write the data model at `pointer` (`undefined` removes); a refused
|
|
115
|
+
* write (writePointer) changes nothing and returns the reason. */
|
|
116
|
+
setData(pointer: string, value: unknown): string | undefined;
|
|
117
|
+
subscribe(listener: Listener): () => void;
|
|
118
|
+
notify(): void;
|
|
119
|
+
}
|
|
120
|
+
export declare class ExponentialHost {
|
|
121
|
+
private options;
|
|
122
|
+
readonly router: HostRouter;
|
|
123
|
+
private stores;
|
|
124
|
+
/** Per surface, one entry per bound path (VAPP-122: a re-bind of a path
|
|
125
|
+
* cancels the earlier subscription at that path). */
|
|
126
|
+
private subscriptions;
|
|
127
|
+
/** Per surface: the FLAT component owning a failed node → that
|
|
128
|
+
* component as it was when it failed + the node ids already reported. */
|
|
129
|
+
private paintErrors;
|
|
130
|
+
private listeners;
|
|
131
|
+
private functions;
|
|
132
|
+
private sources;
|
|
133
|
+
private extensions;
|
|
134
|
+
status: TransportStatus;
|
|
135
|
+
statusDetail?: string;
|
|
136
|
+
/** The last UNSUPPORTED_CATALOG id seen (the catalog-update banner). */
|
|
137
|
+
unsupportedCatalog?: string;
|
|
138
|
+
/** The latest problems (newest last, capped); a new array per change. */
|
|
139
|
+
issues: readonly HostIssue[];
|
|
140
|
+
constructor(options?: HostOptions);
|
|
141
|
+
/** False for a local-only host (packages, in-memory feeds): no
|
|
142
|
+
* `host_offline` state to show. */
|
|
143
|
+
get hasTransport(): boolean;
|
|
144
|
+
get supportedCatalogIds(): string[];
|
|
145
|
+
clientCapabilities(): {
|
|
146
|
+
"v0.9": {
|
|
147
|
+
supportedCatalogIds: string[];
|
|
148
|
+
};
|
|
149
|
+
};
|
|
150
|
+
get extensionDefs(): readonly ExtensionDef[];
|
|
151
|
+
registerExtension(ext: ExtensionDef): void;
|
|
152
|
+
registerFunction(name: string, fn: HostFunction): void;
|
|
153
|
+
registerSource(scheme: string, resolver: SourceResolvers[string]): void;
|
|
154
|
+
/** Install a package; its validation issues are returned AND reported
|
|
155
|
+
* (`issues`, `onIssue`). A package with issues is not installed. */
|
|
156
|
+
installPackage(pkg: AppPackage): PackageIssue[];
|
|
157
|
+
private report;
|
|
158
|
+
surface(id: string): SurfaceStore | undefined;
|
|
159
|
+
surfaceIds(): string[];
|
|
160
|
+
subscribe(listener: Listener): () => void;
|
|
161
|
+
private notify;
|
|
162
|
+
connect(): void;
|
|
163
|
+
close(): void;
|
|
164
|
+
/** One server message (a transport calls this; tests and in-memory hosts
|
|
165
|
+
* may call it directly). */
|
|
166
|
+
receive(message: unknown): HostOp[];
|
|
167
|
+
send(message: ClientMessage): void;
|
|
168
|
+
private perform;
|
|
169
|
+
private unbind;
|
|
170
|
+
/** A component's server event: the A2UI client action message. */
|
|
171
|
+
action(event: {
|
|
172
|
+
surfaceId: string;
|
|
173
|
+
componentId: string;
|
|
174
|
+
name: string;
|
|
175
|
+
context?: Record<string, unknown>;
|
|
176
|
+
payload?: Record<string, unknown>;
|
|
177
|
+
timestamp?: string;
|
|
178
|
+
}): ClientMessage;
|
|
179
|
+
/** The policy decision for a call, before any consent hook. */
|
|
180
|
+
decide(surfaceId: string, name: string): FunctionDecision;
|
|
181
|
+
/** An action `functionCall` to a host function: gate, consent, run. A
|
|
182
|
+
* built-in other than openUrl and bind has no effect as an action. */
|
|
183
|
+
callFunction(call: FunctionCallInfo): Promise<FunctionOutcome>;
|
|
184
|
+
/** VAPP-122: the `bind` action: re-follow `path` from `source` with
|
|
185
|
+
* `params` appended (`sourceWithParams`), through the router like a
|
|
186
|
+
* server's bindDataModel (the surface's package allowlist applies; a
|
|
187
|
+
* refusal is the usual SOURCE_DENIED / VALIDATION_FAILED error). True
|
|
188
|
+
* when the bind op ran. */
|
|
189
|
+
bind(surfaceId: string, args: Record<string, unknown>): boolean;
|
|
190
|
+
/** The URL policy every href passes (relative urls against the urls' or
|
|
191
|
+
* the media `baseUrl`). */
|
|
192
|
+
urlPolicy(): UrlPolicy;
|
|
193
|
+
/** openUrl / Link through the URL policy. True when it opened. */
|
|
194
|
+
openUrl(url: string): boolean;
|
|
195
|
+
/** A renderer's painter for `componentId` failed. Reported ONCE per
|
|
196
|
+
* surface + component id (whatever the message) as an A2UI
|
|
197
|
+
* `RENDER_FAILED` error (and so a host issue), and not again until that
|
|
198
|
+
* component's props change (an `updateComponents` naming it, or the
|
|
199
|
+
* surface re-created). A part or template-instance id counts under the
|
|
200
|
+
* flat component it belongs to (`card.body` → `card`), so the record is
|
|
201
|
+
* bounded by the surface's components. */
|
|
202
|
+
paintError(error: {
|
|
203
|
+
surfaceId: string;
|
|
204
|
+
componentId: string;
|
|
205
|
+
message: string;
|
|
206
|
+
}): void;
|
|
207
|
+
private forgetPaintErrors;
|
|
208
|
+
/** The media policy every src passes (`policy.media`). */
|
|
209
|
+
mediaOptions(): MediaOptions | undefined;
|
|
210
|
+
/** The image loader's request (absolute url + auth headers). */
|
|
211
|
+
mediaRequest(url: string): MediaRequest | null;
|
|
212
|
+
}
|
|
213
|
+
export {};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { PackageIssue } from "./package.js";
|
|
2
|
+
/** The context the signed bytes start with. */
|
|
3
|
+
export declare const PACKAGE_FILE_SIGNATURE_CONTEXT = "exponential-ui/package-file/v1\n";
|
|
4
|
+
export declare const PACKAGE_FILE_SIGNATURE_ALG = "ed25519";
|
|
5
|
+
export declare const AUTHOR_KEY_PREFIX = "ed25519:";
|
|
6
|
+
export declare const AUTHOR_NAME_MAX = 80;
|
|
7
|
+
export interface PackageFileAuthor {
|
|
8
|
+
name: string;
|
|
9
|
+
/** `ed25519:` + the 32-byte public key, unpadded base64url. */
|
|
10
|
+
key: string;
|
|
11
|
+
}
|
|
12
|
+
export interface PackageFileSignature {
|
|
13
|
+
alg: `ed25519`;
|
|
14
|
+
/** The 64-byte signature, unpadded base64url. */
|
|
15
|
+
value: string;
|
|
16
|
+
}
|
|
17
|
+
export type PackageFileVerification = {
|
|
18
|
+
status: `unsigned`;
|
|
19
|
+
} | {
|
|
20
|
+
status: `valid`;
|
|
21
|
+
author: PackageFileAuthor;
|
|
22
|
+
} | {
|
|
23
|
+
status: `invalid`;
|
|
24
|
+
issues: PackageIssue[];
|
|
25
|
+
};
|
|
26
|
+
/** RFC 8785 (JCS): no whitespace, keys sorted by UTF-16 code units, strings
|
|
27
|
+
* and numbers as ECMAScript's JSON.stringify writes them (`1`, `1e+21`, `-0`
|
|
28
|
+
* = `0`); an undefined member is skipped. Throws on a non-finite number or a
|
|
29
|
+
* value JSON has no form for. */
|
|
30
|
+
export declare function canonicalJson(value: unknown): string;
|
|
31
|
+
/** What the signature covers: the context line + the canonical JSON of the
|
|
32
|
+
* file without `signature`, as UTF-8. */
|
|
33
|
+
export declare function packageFileSignedBytes(file: Record<string, unknown>): Uint8Array<ArrayBuffer>;
|
|
34
|
+
export declare function base64UrlEncode(bytes: Uint8Array): string;
|
|
35
|
+
/** Strict: the url-safe alphabet, no padding; null otherwise. */
|
|
36
|
+
export declare function base64UrlDecode(text: string): Uint8Array<ArrayBuffer> | null;
|
|
37
|
+
/** The 32-byte public key of `author.key`; null when malformed. */
|
|
38
|
+
export declare function authorPublicKey(key: unknown): Uint8Array<ArrayBuffer> | null;
|
|
39
|
+
/** The file signed by the holder of the 32-byte Ed25519 `seed`, as
|
|
40
|
+
* `author` `name`: every key but `signature` kept, then `author` and
|
|
41
|
+
* `signature` (replaced when present). */
|
|
42
|
+
export declare function signPackageFile<T extends Record<string, unknown>>(file: T, signer: {
|
|
43
|
+
name: string;
|
|
44
|
+
seed: Uint8Array;
|
|
45
|
+
}): Promise<Omit<T, `author` | `signature`> & {
|
|
46
|
+
author: PackageFileAuthor;
|
|
47
|
+
signature: PackageFileSignature;
|
|
48
|
+
}>;
|
|
49
|
+
/** Is the file signed, and by whom: `unsigned` without `signature` (an
|
|
50
|
+
* `author` alone is an unverified claim), `valid` with the author, or
|
|
51
|
+
* `invalid` with every problem as a JSON pointer. */
|
|
52
|
+
export declare function verifyPackageFile(file: unknown): Promise<PackageFileVerification>;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export interface ParsedSource {
|
|
2
|
+
/** The source as written. */
|
|
3
|
+
uri: string;
|
|
4
|
+
scheme: string;
|
|
5
|
+
name: string;
|
|
6
|
+
params: Record<string, string>;
|
|
7
|
+
}
|
|
8
|
+
/** `exp:issues?board=b1&limit=20` → `{scheme: "exp", name: "issues",
|
|
9
|
+
* params: {board: "b1", limit: "20"}}`; null when it does not parse. */
|
|
10
|
+
export declare function parseSource(uri: string): ParsedSource | null;
|
|
11
|
+
/** What a resolver emits into: the value lands at the bound path. */
|
|
12
|
+
export type SourceEmit = (value: unknown) => void;
|
|
13
|
+
/** A scheme's resolver: start following `source`, return the cancel. */
|
|
14
|
+
export type SourceResolver = (source: ParsedSource, emit: SourceEmit) => (() => void) | void;
|
|
15
|
+
export type SourceResolvers = Record<string, SourceResolver>;
|
|
16
|
+
/** VAPP-122: `source` with `params` appended as its query, for the `bind`
|
|
17
|
+
* action (`{functionCall: {call: "bind", args: {path, source, params}}}`):
|
|
18
|
+
* keys sorted, key and value percent-encoded (everything but
|
|
19
|
+
* `A-Z a-z 0-9 - _ . ! ~ * ' ( )`), a null or undefined value skipped, an
|
|
20
|
+
* object or array as JSON, after `?` or `&`. A repeated key parses with
|
|
21
|
+
* the last value, so a param overrides the source's own. */
|
|
22
|
+
export declare function sourceWithParams(source: string, params?: Record<string, unknown> | null): string;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { PackageIssue } from "./package.js";
|
|
2
|
+
/** `^[a-z][a-z0-9_-]{0,31}$`: a tool's id. */
|
|
3
|
+
export declare const TOOL_ID_PATTERN: RegExp;
|
|
4
|
+
export declare const TOOL_KINDS: readonly string[];
|
|
5
|
+
export interface PackageTool {
|
|
6
|
+
kind: `mcp` | `script`;
|
|
7
|
+
title: string;
|
|
8
|
+
description?: string;
|
|
9
|
+
/** A remote MCP server (Streamable HTTP). */
|
|
10
|
+
url?: string;
|
|
11
|
+
/** A local MCP server (stdio) or the script's process. */
|
|
12
|
+
command?: string;
|
|
13
|
+
args?: string[];
|
|
14
|
+
/** Variable NAMES the host passes through, never values. */
|
|
15
|
+
env?: string[];
|
|
16
|
+
}
|
|
17
|
+
/** One row of the consent card. */
|
|
18
|
+
export interface ToolConsentRow {
|
|
19
|
+
id: string;
|
|
20
|
+
kind: `mcp` | `script`;
|
|
21
|
+
transport: `http` | `stdio` | `script`;
|
|
22
|
+
title: string;
|
|
23
|
+
description: string | null;
|
|
24
|
+
/** The url, or the command line exactly as it runs. */
|
|
25
|
+
target: string;
|
|
26
|
+
env: string[];
|
|
27
|
+
}
|
|
28
|
+
/** Every problem with a package's `tools`, ids in sorted order. */
|
|
29
|
+
export declare function validateTools(tools: unknown): PackageIssue[];
|
|
30
|
+
/** The consent card's rows for a (valid) package's tools, by id. */
|
|
31
|
+
export declare function toolConsent(pkg: {
|
|
32
|
+
tools?: Record<string, PackageTool>;
|
|
33
|
+
}): ToolConsentRow[];
|
|
34
|
+
/** The key a remembered grant is stored under: ANY change to the tool's
|
|
35
|
+
* definition is a new key (the card asks again). */
|
|
36
|
+
export declare function toolConsentKey(packageId: string, toolId: string, tool: PackageTool): string;
|
|
37
|
+
/** The tool a host function name calls: `tools.<id>` (a script) or
|
|
38
|
+
* `tools.<id>.<name>` (an MCP server's tool); null = not a tool call. */
|
|
39
|
+
export declare function toolCall(name: string): {
|
|
40
|
+
toolId: string;
|
|
41
|
+
tool: string | null;
|
|
42
|
+
} | null;
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import type { ClientMessage } from "./contract.js";
|
|
2
|
+
import { JsonlDecoder, SseDecoder } from "./decoders.js";
|
|
3
|
+
import type { Decoded } from "./decoders.js";
|
|
4
|
+
import type { Transport, TransportStatus } from "./runtime.js";
|
|
5
|
+
type Receive = (message: unknown) => void;
|
|
6
|
+
type Status = (status: TransportStatus, detail?: string) => void;
|
|
7
|
+
/** In-memory: `feed` messages in, read what the host sent from `sent`. */
|
|
8
|
+
export declare class MemoryTransport implements Transport {
|
|
9
|
+
readonly sent: ClientMessage[];
|
|
10
|
+
private receiveFn?;
|
|
11
|
+
private pending;
|
|
12
|
+
onSend?: (message: ClientMessage) => void;
|
|
13
|
+
start(receive: Receive, status: Status): void;
|
|
14
|
+
feed(...messages: unknown[]): void;
|
|
15
|
+
/** JSONL text, as a stream server would send it. */
|
|
16
|
+
feedJsonl(text: string): void;
|
|
17
|
+
send(message: ClientMessage): void;
|
|
18
|
+
close(): void;
|
|
19
|
+
}
|
|
20
|
+
export interface HttpTransportOptions {
|
|
21
|
+
/** The stream to read (GET). */
|
|
22
|
+
url: string;
|
|
23
|
+
/** Where client messages go (POST, JSON body); default `url`. */
|
|
24
|
+
postUrl?: string;
|
|
25
|
+
headers?: Record<string, string>;
|
|
26
|
+
/** Reconnect after a drop (an error or an aborted stream), ms (0 =
|
|
27
|
+
* never). Default 2000. */
|
|
28
|
+
reconnectMs?: number;
|
|
29
|
+
/** Reconnect after a CLEAN end of the stream too (the server resumes it).
|
|
30
|
+
* Default false: a stream that ends is done (status `closed`). An SSE
|
|
31
|
+
* stream that sent a `retry:` field signals this itself. */
|
|
32
|
+
resumable?: boolean;
|
|
33
|
+
fetch?: typeof fetch;
|
|
34
|
+
}
|
|
35
|
+
declare abstract class StreamTransport implements Transport {
|
|
36
|
+
protected options: HttpTransportOptions;
|
|
37
|
+
private controller?;
|
|
38
|
+
/** Bumped by every start/close: a loop whose generation is stale exits
|
|
39
|
+
* (an old loop asleep in its reconnect wait never runs beside a new
|
|
40
|
+
* one). */
|
|
41
|
+
private generation;
|
|
42
|
+
constructor(options: HttpTransportOptions);
|
|
43
|
+
protected abstract decoder(): {
|
|
44
|
+
push(chunk: string): Decoded;
|
|
45
|
+
end(): Decoded;
|
|
46
|
+
retryMs?: number;
|
|
47
|
+
};
|
|
48
|
+
protected abstract accept(): string;
|
|
49
|
+
start(receive: Receive, status: Status): void;
|
|
50
|
+
private run;
|
|
51
|
+
send(message: ClientMessage): Promise<void>;
|
|
52
|
+
close(): void;
|
|
53
|
+
}
|
|
54
|
+
/** A2UI JSONL over a streamed HTTP response (`application/jsonl`). */
|
|
55
|
+
export declare class JsonlStreamTransport extends StreamTransport {
|
|
56
|
+
protected decoder(): JsonlDecoder;
|
|
57
|
+
protected accept(): string;
|
|
58
|
+
}
|
|
59
|
+
/** Server-Sent Events read through fetch (headers allowed, unlike
|
|
60
|
+
* EventSource). */
|
|
61
|
+
export declare class SseTransport extends StreamTransport {
|
|
62
|
+
protected decoder(): SseDecoder;
|
|
63
|
+
protected accept(): string;
|
|
64
|
+
}
|
|
65
|
+
/** One A2UI message (or JSONL) per frame; client messages go back as
|
|
66
|
+
* frames. */
|
|
67
|
+
export declare class WebSocketTransport implements Transport {
|
|
68
|
+
private options;
|
|
69
|
+
private socket?;
|
|
70
|
+
/** Bumped by every start/close: a stale socket's reconnect timer is a
|
|
71
|
+
* no-op. */
|
|
72
|
+
private generation;
|
|
73
|
+
constructor(options: {
|
|
74
|
+
url: string;
|
|
75
|
+
protocols?: string | string[];
|
|
76
|
+
reconnectMs?: number;
|
|
77
|
+
WebSocket?: typeof WebSocket;
|
|
78
|
+
});
|
|
79
|
+
start(receive: Receive, status: Status): void;
|
|
80
|
+
send(message: ClientMessage): void;
|
|
81
|
+
close(): void;
|
|
82
|
+
}
|
|
83
|
+
export interface McpTransportOptions {
|
|
84
|
+
/** The MCP server's streamable-HTTP endpoint. */
|
|
85
|
+
url: string;
|
|
86
|
+
/** The tool whose result carries the surface (called once at start). */
|
|
87
|
+
tool: string;
|
|
88
|
+
arguments?: Record<string, unknown>;
|
|
89
|
+
/** The tool client messages go to; default `a2ui_event`. */
|
|
90
|
+
actionTool?: string;
|
|
91
|
+
headers?: Record<string, string>;
|
|
92
|
+
fetch?: typeof fetch;
|
|
93
|
+
}
|
|
94
|
+
/** A2UI over MCP: calls `tool`, delivers the A2UI resources in its result,
|
|
95
|
+
* and sends every client message as a tools/call to `actionTool` (its
|
|
96
|
+
* result may carry more messages). JSON-RPC over plain POST; an SSE
|
|
97
|
+
* response body is read through the SSE decoder. */
|
|
98
|
+
export declare class McpTransport implements Transport {
|
|
99
|
+
private options;
|
|
100
|
+
private id;
|
|
101
|
+
private receiveFn?;
|
|
102
|
+
private session?;
|
|
103
|
+
constructor(options: McpTransportOptions);
|
|
104
|
+
start(receive: Receive, status: Status): void;
|
|
105
|
+
send(message: ClientMessage): Promise<void>;
|
|
106
|
+
close(): void;
|
|
107
|
+
private rpc;
|
|
108
|
+
}
|
|
109
|
+
export {};
|