@assistant-ui/react-generative-ui 0.0.17 → 0.0.19
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/dist/JSONGenerativeUI.client.d.ts +1 -2
- package/dist/JSONGenerativeUI.client.d.ts.map +1 -1
- package/dist/JSONGenerativeUI.server.d.ts +1 -2
- package/dist/JSONGenerativeUI.server.d.ts.map +1 -1
- package/dist/JSONGenerativeUI.shared.d.ts +8 -9
- package/dist/JSONGenerativeUI.shared.d.ts.map +1 -1
- package/dist/a2ui/convert.d.ts +1 -2
- package/dist/a2ui/convert.d.ts.map +1 -1
- package/dist/a2ui/convert.js +11 -2
- package/dist/a2ui/convert.js.map +1 -1
- package/dist/a2ui/reducer.d.ts +1 -2
- package/dist/a2ui/reducer.d.ts.map +1 -1
- package/dist/a2ui/reducer.js +63 -10
- package/dist/a2ui/reducer.js.map +1 -1
- package/dist/a2ui/types.d.ts +17 -18
- package/dist/a2ui/types.d.ts.map +1 -1
- package/dist/actionRegistry.d.ts +5 -6
- package/dist/actionRegistry.d.ts.map +1 -1
- package/dist/buildPresentParameters.d.ts +2 -3
- package/dist/buildPresentParameters.d.ts.map +1 -1
- package/dist/buildPresentParameters.js +4 -3
- package/dist/buildPresentParameters.js.map +1 -1
- package/dist/constants.d.ts +2 -2
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +2 -1
- package/dist/constants.js.map +1 -1
- package/dist/convert/boundSpec.d.ts +7 -8
- package/dist/convert/boundSpec.d.ts.map +1 -1
- package/dist/convert/copyBounded.d.ts +1 -2
- package/dist/convert/copyBounded.d.ts.map +1 -1
- package/dist/convert/isElement.d.ts +1 -2
- package/dist/convert/isElement.d.ts.map +1 -1
- package/dist/convert/takeRun.d.ts +1 -2
- package/dist/convert/takeRun.d.ts.map +1 -1
- package/dist/defineGenerativeComponents.d.ts +1 -2
- package/dist/defineGenerativeComponents.d.ts.map +1 -1
- package/dist/generativeUIToJSX.d.ts +2 -3
- package/dist/generativeUIToJSX.d.ts.map +1 -1
- package/dist/ir.d.ts +28 -29
- package/dist/ir.d.ts.map +1 -1
- package/dist/renderGenerativeUI.d.ts +1 -2
- package/dist/renderGenerativeUI.d.ts.map +1 -1
- package/dist/renderGenerativeUI.js +1 -1
- package/dist/renderGenerativeUI.js.map +1 -1
- package/dist/slack/constants.d.ts +35 -36
- package/dist/slack/constants.d.ts.map +1 -1
- package/dist/slack/decodeBlockAction.d.ts +1 -2
- package/dist/slack/decodeBlockAction.d.ts.map +1 -1
- package/dist/slack/fromSlackBlocks.d.ts +1 -2
- package/dist/slack/fromSlackBlocks.d.ts.map +1 -1
- package/dist/slack/toSlackBlocks.d.ts +1 -2
- package/dist/slack/toSlackBlocks.d.ts.map +1 -1
- package/dist/slack/types.d.ts +32 -33
- package/dist/slack/types.d.ts.map +1 -1
- package/dist/teams/constants.d.ts +14 -15
- package/dist/teams/constants.d.ts.map +1 -1
- package/dist/teams/decodeSubmitData.d.ts +1 -2
- package/dist/teams/decodeSubmitData.d.ts.map +1 -1
- package/dist/teams/toAdaptiveCard.d.ts +6 -7
- package/dist/teams/toAdaptiveCard.d.ts.map +1 -1
- package/dist/teams/toTeamsAttachments.d.ts +1 -2
- package/dist/teams/toTeamsAttachments.d.ts.map +1 -1
- package/dist/teams/types.d.ts +29 -30
- package/dist/teams/types.d.ts.map +1 -1
- package/dist/types.d.ts +9 -10
- package/dist/types.d.ts.map +1 -1
- package/dist/vocabulary/alert.d.ts +2 -3
- package/dist/vocabulary/alert.d.ts.map +1 -1
- package/dist/vocabulary/alert.js +21 -16
- package/dist/vocabulary/alert.js.map +1 -1
- package/dist/vocabulary/collectFormValues.d.ts +6 -5
- package/dist/vocabulary/collectFormValues.d.ts.map +1 -1
- package/dist/vocabulary/collectFormValues.js +3 -2
- package/dist/vocabulary/collectFormValues.js.map +1 -1
- package/dist/vocabulary/data.d.ts +1 -2
- package/dist/vocabulary/data.d.ts.map +1 -1
- package/dist/vocabulary/data.js +20 -12
- package/dist/vocabulary/data.js.map +1 -1
- package/dist/vocabulary/dispatch.d.ts +2 -3
- package/dist/vocabulary/dispatch.d.ts.map +1 -1
- package/dist/vocabulary/fact.d.ts +1 -2
- package/dist/vocabulary/fact.d.ts.map +1 -1
- package/dist/vocabulary/fact.js +3 -2
- package/dist/vocabulary/fact.js.map +1 -1
- package/dist/vocabulary/form.d.ts +1 -2
- package/dist/vocabulary/form.d.ts.map +1 -1
- package/dist/vocabulary/icon.d.ts +1 -2
- package/dist/vocabulary/icon.d.ts.map +1 -1
- package/dist/vocabulary/index.d.ts +1 -2
- package/dist/vocabulary/index.d.ts.map +1 -1
- package/dist/vocabulary/interactive.d.ts +10 -9
- package/dist/vocabulary/interactive.d.ts.map +1 -1
- package/dist/vocabulary/interactive.js +30 -23
- package/dist/vocabulary/interactive.js.map +1 -1
- package/dist/vocabulary/layout.d.ts +1 -2
- package/dist/vocabulary/layout.d.ts.map +1 -1
- package/dist/vocabulary/layout.js +7 -5
- package/dist/vocabulary/layout.js.map +1 -1
- package/dist/vocabulary/list.d.ts +1 -2
- package/dist/vocabulary/list.d.ts.map +1 -1
- package/dist/vocabulary/media.d.ts +1 -2
- package/dist/vocabulary/media.d.ts.map +1 -1
- package/dist/vocabulary/text.d.ts +2 -3
- package/dist/vocabulary/text.d.ts.map +1 -1
- package/dist/vocabulary/text.js +4 -3
- package/dist/vocabulary/text.js.map +1 -1
- package/dist/vocabulary/toTextContent.d.ts +4 -0
- package/dist/vocabulary/toTextContent.d.ts.map +1 -0
- package/dist/vocabulary/toTextContent.js +6 -0
- package/dist/vocabulary/toTextContent.js.map +1 -0
- package/package.json +12 -10
- package/src/a2ui/convert.test.ts +36 -0
- package/src/a2ui/convert.ts +21 -2
- package/src/a2ui/reducer.test.ts +223 -0
- package/src/a2ui/reducer.ts +76 -12
- package/src/buildPresentParameters.ts +7 -4
- package/src/constants.ts +2 -0
- package/src/renderGenerativeUI.test.tsx +57 -0
- package/src/renderGenerativeUI.tsx +3 -1
- package/src/slack/fromSlackBlocks.test.ts +4 -1
- package/src/slack/toSlackBlocks.test.ts +8 -4
- package/src/teams/toAdaptiveCard.test.ts +5 -3
- package/src/vocabulary/alert.test.tsx +10 -0
- package/src/vocabulary/alert.tsx +16 -7
- package/src/vocabulary/collectFormValues.test.ts +38 -0
- package/src/vocabulary/collectFormValues.ts +11 -2
- package/src/vocabulary/data.test.tsx +40 -0
- package/src/vocabulary/data.tsx +47 -26
- package/src/vocabulary/fact.test.tsx +12 -0
- package/src/vocabulary/fact.tsx +3 -2
- package/src/vocabulary/form.test.tsx +1 -0
- package/src/vocabulary/interactive.test.tsx +55 -1
- package/src/vocabulary/interactive.tsx +50 -29
- package/src/vocabulary/layout.test.tsx +17 -0
- package/src/vocabulary/layout.tsx +8 -4
- package/src/vocabulary/list.test.tsx +5 -4
- package/src/vocabulary/text.test.tsx +29 -0
- package/src/vocabulary/text.tsx +4 -3
- package/src/vocabulary/toTextContent.ts +2 -0
- package/dist/node_modules/.pnpm/@types_json-schema@7.0.15/node_modules/@types/json-schema/index.d.ts +0 -141
- package/dist/node_modules/.pnpm/@types_json-schema@7.0.15/node_modules/@types/json-schema/index.d.ts.map +0 -1
|
@@ -11,7 +11,7 @@ import { JSONGenerativeUIOptions, PresentTool, PresentToolOptions, PromptUserToo
|
|
|
11
11
|
* `actions` registry (if provided) is threaded into the render context so
|
|
12
12
|
* interactive components can fire `$action` through `$dispatch`.
|
|
13
13
|
*/
|
|
14
|
-
declare class JSONGenerativeUI {
|
|
14
|
+
export declare class JSONGenerativeUI {
|
|
15
15
|
private readonly library;
|
|
16
16
|
private readonly parameters;
|
|
17
17
|
private readonly actions;
|
|
@@ -26,5 +26,4 @@ declare class JSONGenerativeUI {
|
|
|
26
26
|
promptUser(): PromptUserTool;
|
|
27
27
|
}
|
|
28
28
|
//#endregion
|
|
29
|
-
export { JSONGenerativeUI };
|
|
30
29
|
//# sourceMappingURL=JSONGenerativeUI.client.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"JSONGenerativeUI.client.d.ts","names":[],"sources":["../src/JSONGenerativeUI.client.tsx"],"mappings":";;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"JSONGenerativeUI.client.d.ts","names":[],"sources":["../src/JSONGenerativeUI.client.tsx"],"mappings":";;;;;;;;;;;;;qBAkCa;mBACM;mBACA;mBACA;EAEL,YAAA,SAAS;;;;;;mBAWJ;EAejB,QAAQ,UAAU,qBAAqB;EASvC,cAAc"}
|
|
@@ -13,12 +13,11 @@ import { JSONGenerativeUIOptions, PresentTool, PresentToolOptions, PromptUserToo
|
|
|
13
13
|
* `as` casts here because the tool types require a `render` for frontend/human
|
|
14
14
|
* tools; on the server it is structurally absent and never read.
|
|
15
15
|
*/
|
|
16
|
-
declare class JSONGenerativeUI {
|
|
16
|
+
export declare class JSONGenerativeUI {
|
|
17
17
|
private readonly parameters;
|
|
18
18
|
constructor(options: JSONGenerativeUIOptions);
|
|
19
19
|
present(options?: PresentToolOptions): PresentTool;
|
|
20
20
|
promptUser(): PromptUserTool;
|
|
21
21
|
}
|
|
22
22
|
//#endregion
|
|
23
|
-
export { JSONGenerativeUI };
|
|
24
23
|
//# sourceMappingURL=JSONGenerativeUI.server.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"JSONGenerativeUI.server.d.ts","names":[],"sources":["../src/JSONGenerativeUI.server.tsx"],"mappings":";;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"JSONGenerativeUI.server.d.ts","names":[],"sources":["../src/JSONGenerativeUI.server.tsx"],"mappings":";;;;;;;;;;;;;;;qBAwBa;mBACM;EAEL,YAAA,SAAS;EAIrB,QAAQ,UAAU,qBAAqB;EAIvC,cAAc"}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { JSONSchema7 } from "./node_modules/.pnpm/@types_json-schema@7.0.15/node_modules/@types/json-schema/index.js";
|
|
2
1
|
import { ActionRegistry } from "./actionRegistry.js";
|
|
3
2
|
import { GenerativeUILibrary } from "./types.js";
|
|
4
3
|
import { ToolDefinition } from "@assistant-ui/react";
|
|
4
|
+
import { JSONSchema7 } from "json-schema";
|
|
5
5
|
//#region src/JSONGenerativeUI.shared.d.ts
|
|
6
6
|
/** Options for {@link JSONGenerativeUI}. */
|
|
7
|
-
type JSONGenerativeUIOptions = {
|
|
7
|
+
export type JSONGenerativeUIOptions = {
|
|
8
8
|
/**
|
|
9
9
|
* The components the model is allowed to render, keyed by the `$type` it
|
|
10
10
|
* selects them with. Author it with `defineGenerativeComponents({ ... })` so a
|
|
@@ -20,7 +20,7 @@ type JSONGenerativeUIOptions = {
|
|
|
20
20
|
actions?: ActionRegistry;
|
|
21
21
|
};
|
|
22
22
|
/** Options for {@link JSONGenerativeUI.present}. */
|
|
23
|
-
type PresentToolOptions = {
|
|
23
|
+
export type PresentToolOptions = {
|
|
24
24
|
/**
|
|
25
25
|
* Set `"standalone"` to render the component on its own surface (outside the
|
|
26
26
|
* chain-of-thought trace), e.g. a full-bleed artifact like a card. Omit it for
|
|
@@ -35,17 +35,17 @@ type BackendDefaultMetadata = {
|
|
|
35
35
|
};
|
|
36
36
|
};
|
|
37
37
|
/** The `present` tool, as the model sees it (no client `render`/`execute`). */
|
|
38
|
-
type PresentTool = ToolDefinition<Record<string, unknown>, Record<string, never>> & BackendDefaultMetadata;
|
|
38
|
+
export type PresentTool = ToolDefinition<Record<string, unknown>, Record<string, never>> & BackendDefaultMetadata;
|
|
39
39
|
/** The `prompt_user` tool, as the model sees it (no client `render`). */
|
|
40
|
-
type PromptUserTool = ToolDefinition<Record<string, unknown>, unknown> & BackendDefaultMetadata;
|
|
40
|
+
export type PromptUserTool = ToolDefinition<Record<string, unknown>, unknown> & BackendDefaultMetadata;
|
|
41
41
|
/** The tool `parameters` schema, built once per instance (see `buildPresentParameters`). */
|
|
42
|
-
type PresentParameters = JSONSchema7;
|
|
42
|
+
export type PresentParameters = JSONSchema7;
|
|
43
43
|
/**
|
|
44
44
|
* The schema-only half of the `present` tool, shared by both builds. The server
|
|
45
45
|
* build returns exactly this; the client build adds `execute` and `render`.
|
|
46
46
|
* Takes the already-built `parameters` so it isn't recomputed per tool.
|
|
47
47
|
*/
|
|
48
|
-
declare function presentToolBase(parameters: PresentParameters, options?: PresentToolOptions): {
|
|
48
|
+
export declare function presentToolBase(parameters: PresentParameters, options?: PresentToolOptions): {
|
|
49
49
|
display?: "standalone";
|
|
50
50
|
type: "frontend";
|
|
51
51
|
description: string;
|
|
@@ -55,11 +55,10 @@ declare function presentToolBase(parameters: PresentParameters, options?: Presen
|
|
|
55
55
|
* The schema-only half of the `prompt_user` tool, shared by both builds. The
|
|
56
56
|
* server build returns exactly this; the client build adds `render`.
|
|
57
57
|
*/
|
|
58
|
-
declare function promptUserToolBase(parameters: PresentParameters): {
|
|
58
|
+
export declare function promptUserToolBase(parameters: PresentParameters): {
|
|
59
59
|
type: "human";
|
|
60
60
|
description: string;
|
|
61
61
|
parameters: JSONSchema7;
|
|
62
62
|
};
|
|
63
63
|
//#endregion
|
|
64
|
-
export { JSONGenerativeUIOptions, PresentParameters, PresentTool, PresentToolOptions, PromptUserTool, presentToolBase, promptUserToolBase };
|
|
65
64
|
//# sourceMappingURL=JSONGenerativeUI.shared.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"JSONGenerativeUI.shared.d.ts","names":[],"sources":["../src/JSONGenerativeUI.shared.ts"],"mappings":";;;;;;
|
|
1
|
+
{"version":3,"file":"JSONGenerativeUI.shared.d.ts","names":[],"sources":["../src/JSONGenerativeUI.shared.ts"],"mappings":";;;;;;YAMY;;;;;;EAMV,SAAS;;;;;;;EAOT,UAAU;;;YAIA;;;;;;;EAOV;;KAGG;EACH;IACE;;;;YAKQ,cAAc,eACxB,yBACA,yBAEA;;YAGU,iBAAiB,eAAe,oCAC1C;;YAYU,oBAAoB;;;;;;wBAOhB,gBACd,YAAY,mBACZ,UAAU;;;;;;;;;;wBAcI,mBAAmB,YAAY;;;cAAA"}
|
package/dist/a2ui/convert.d.ts
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import { UIElement } from "../ir.js";
|
|
2
2
|
import { A2uiSurfaceState } from "./types.js";
|
|
3
3
|
//#region src/a2ui/convert.d.ts
|
|
4
|
-
declare function convertSurfaceToUISpec(surface: A2uiSurfaceState): {
|
|
4
|
+
export declare function convertSurfaceToUISpec(surface: A2uiSurfaceState): {
|
|
5
5
|
spec: UIElement | null;
|
|
6
6
|
warnings: string[];
|
|
7
7
|
};
|
|
8
8
|
//#endregion
|
|
9
|
-
export { convertSurfaceToUISpec };
|
|
10
9
|
//# sourceMappingURL=convert.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"convert.d.ts","names":[],"sources":["../../src/a2ui/convert.ts"],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"convert.d.ts","names":[],"sources":["../../src/a2ui/convert.ts"],"mappings":";;;wBAscgB,uBAAuB,SAAS;EAC9C,MAAM;EACN"}
|
package/dist/a2ui/convert.js
CHANGED
|
@@ -20,6 +20,15 @@ const isPlainObject = (value) => {
|
|
|
20
20
|
const prototype = Object.getPrototypeOf(value);
|
|
21
21
|
return prototype === Object.prototype || prototype === null;
|
|
22
22
|
};
|
|
23
|
+
const setOwnProperty = (target, key, value) => {
|
|
24
|
+
if (key === "__proto__") Object.defineProperty(target, key, {
|
|
25
|
+
value,
|
|
26
|
+
enumerable: true,
|
|
27
|
+
configurable: true,
|
|
28
|
+
writable: true
|
|
29
|
+
});
|
|
30
|
+
else target[key] = value;
|
|
31
|
+
};
|
|
23
32
|
const isBinding = (value) => isPlainObject(value) && Object.keys(value).length === 1 && typeof value["path"] === "string";
|
|
24
33
|
const isTemplateChildren = (value) => isPlainObject(value) && Object.keys(value).length === 1 && isPlainObject(value["template"]) && Object.keys(value["template"]).length === 2 && typeof value["template"]["componentId"] === "string" && typeof value["template"]["path"] === "string";
|
|
25
34
|
const decodePointer = (path) => {
|
|
@@ -54,7 +63,7 @@ const materialize = (value, source) => {
|
|
|
54
63
|
const result = {};
|
|
55
64
|
for (const [key, entry] of Object.entries(value)) {
|
|
56
65
|
const resolved = materialize(entry, source);
|
|
57
|
-
if (resolved !== void 0) result
|
|
66
|
+
if (resolved !== void 0) setOwnProperty(result, key, resolved);
|
|
58
67
|
}
|
|
59
68
|
return result;
|
|
60
69
|
};
|
|
@@ -274,7 +283,7 @@ function convertComponent(componentId, dataSource, context, depth, visited) {
|
|
|
274
283
|
for (const [key, value] of Object.entries(node)) {
|
|
275
284
|
if (key === "id" || key === "component" || key === "children") continue;
|
|
276
285
|
const resolved = materialize(value, dataSource);
|
|
277
|
-
if (resolved !== void 0) props
|
|
286
|
+
if (resolved !== void 0) setOwnProperty(props, key, resolved);
|
|
278
287
|
}
|
|
279
288
|
const mapped = mappedProps(node, props, dataSource, context);
|
|
280
289
|
if (!mapped) return null;
|
package/dist/a2ui/convert.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"convert.js","names":[],"sources":["../../src/a2ui/convert.ts"],"sourcesContent":["import type { UIElement } from \"../ir\";\nimport {\n A2UI_SURFACE_ID,\n type A2uiSurfaceState,\n type A2uiTemplateChildren,\n} from \"./types\";\n\nconst DEPTH_CAP = 32;\nconst TEMPLATE_ITEM_CAP = 100;\nconst NODE_BUDGET = 5000;\n\nconst SUPPORTED_COMPONENTS = new Set([\n \"Text\",\n \"Image\",\n \"Row\",\n \"Column\",\n \"Card\",\n \"Divider\",\n \"Button\",\n \"TextField\",\n \"CheckBox\",\n]);\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\nconst isPlainObject = (value: unknown): value is Record<string, unknown> => {\n if (!isRecord(value)) return false;\n const prototype = Object.getPrototypeOf(value);\n return prototype === Object.prototype || prototype === null;\n};\n\nconst isBinding = (value: unknown): value is { readonly path: string } =>\n isPlainObject(value) &&\n Object.keys(value).length === 1 &&\n typeof value[\"path\"] === \"string\";\n\nconst isTemplateChildren = (value: unknown): value is A2uiTemplateChildren =>\n isPlainObject(value) &&\n Object.keys(value).length === 1 &&\n isPlainObject(value[\"template\"]) &&\n Object.keys(value[\"template\"]).length === 2 &&\n typeof value[\"template\"][\"componentId\"] === \"string\" &&\n typeof value[\"template\"][\"path\"] === \"string\";\n\nconst decodePointer = (path: string): string[] | undefined => {\n if (path === \"\" || path === \"/\") return [];\n if (!path.startsWith(\"/\")) return undefined;\n return path\n .slice(1)\n .split(\"/\")\n .map((segment) => segment.replaceAll(\"~1\", \"/\").replaceAll(\"~0\", \"~\"));\n};\n\nconst resolvePointer = (source: unknown, path: string): unknown => {\n const segments = decodePointer(path);\n if (!segments) return undefined;\n let current = source;\n for (const segment of segments) {\n if (Array.isArray(current)) {\n if (!/^(0|[1-9]\\d*)$/.test(segment)) return undefined;\n current = current[Number(segment)];\n continue;\n }\n if (!isRecord(current) || !Object.hasOwn(current, segment)) {\n return undefined;\n }\n current = current[segment];\n }\n return current;\n};\n\nconst bindingPath = (value: unknown): string | undefined =>\n isBinding(value) ? value.path : undefined;\n\nconst lastPointerSegment = (path: string | undefined): string | undefined => {\n if (!path) return undefined;\n const segments = decodePointer(path);\n return segments?.at(-1);\n};\n\nconst materialize = (value: unknown, source: unknown): unknown => {\n if (isBinding(value)) return resolvePointer(source, value.path);\n if (Array.isArray(value)) {\n return value\n .map((entry) => materialize(entry, source))\n .filter((entry) => entry !== undefined);\n }\n if (!isPlainObject(value)) return value;\n const result: Record<string, unknown> = {};\n for (const [key, entry] of Object.entries(value)) {\n const resolved = materialize(entry, source);\n if (resolved !== undefined) result[key] = resolved;\n }\n return result;\n};\n\nconst firstDefined = (\n props: Record<string, unknown>,\n keys: readonly string[],\n): unknown => {\n for (const key of keys) {\n if (props[key] !== undefined) return props[key];\n }\n return undefined;\n};\n\nconst stringProp = (\n props: Record<string, unknown>,\n keys: readonly string[],\n): string | undefined => {\n const value = firstDefined(props, keys);\n return typeof value === \"string\" ? value : undefined;\n};\n\nconst sourceSurfaceId = (surface: A2uiSurfaceState): string =>\n (surface as A2uiSurfaceState & { [A2UI_SURFACE_ID]?: string })[\n A2UI_SURFACE_ID\n ] ?? \"\";\n\ntype ConversionContext = {\n readonly surface: A2uiSurfaceState;\n readonly surfaceId: string;\n readonly warnings: string[];\n emittedNodes: number;\n depthWarned: boolean;\n budgetWarned: boolean;\n templateCapWarned: boolean;\n};\n\nconst reserveNode = (context: ConversionContext): boolean => {\n if (context.emittedNodes >= NODE_BUDGET) {\n if (!context.budgetWarned) {\n context.warnings.push(`A2UI node budget of ${NODE_BUDGET} was reached.`);\n context.budgetWarned = true;\n }\n return false;\n }\n context.emittedNodes++;\n return true;\n};\n\nconst childrenOf = (\n node: Record<string, unknown>,\n dataSource: unknown,\n context: ConversionContext,\n depth: number,\n visited: Set<string>,\n): UIElement[] => {\n const children = node[\"children\"];\n if (!Array.isArray(children)) return [];\n const result: UIElement[] = [];\n for (const childId of children) {\n if (typeof childId !== \"string\") {\n context.warnings.push(\n `Component \"${String(node[\"id\"] ?? \"\")}\" has a malformed child reference.`,\n );\n continue;\n }\n const child = convertComponent(\n childId,\n dataSource,\n context,\n depth + 1,\n visited,\n );\n if (child) result.push(child);\n }\n return result;\n};\n\nconst mappedAction = (\n node: Record<string, unknown>,\n props: Record<string, unknown>,\n dataSource: unknown,\n context: ConversionContext,\n): UIElement[\"$action\"] | undefined => {\n const action = props[\"action\"];\n const actionName =\n typeof action === \"string\"\n ? action\n : isRecord(action) && typeof action[\"name\"] === \"string\"\n ? action[\"name\"]\n : undefined;\n if (!actionName) return undefined;\n const rawContext = isRecord(action) ? action[\"context\"] : undefined;\n const resolvedContext =\n rawContext === undefined ? undefined : materialize(rawContext, dataSource);\n return {\n type: \"a2ui:action\",\n name: actionName,\n surfaceId: context.surfaceId,\n sourceComponentId: typeof node[\"id\"] === \"string\" ? node[\"id\"] : \"\",\n ...(resolvedContext !== undefined ? { context: resolvedContext } : {}),\n };\n};\n\nconst mappedProps = (\n node: Record<string, unknown>,\n props: Record<string, unknown>,\n dataSource: unknown,\n context: ConversionContext,\n): UIElement | undefined => {\n const component = node[\"component\"];\n\n if (component === \"Text\") {\n const text = stringProp(props, [\"text\", \"value\"]);\n const variant = props[\"variant\"];\n if (typeof variant === \"string\" && /^h[1-6]$/.test(variant)) {\n return {\n $type: \"Header\",\n ...(text !== undefined ? { text } : {}),\n };\n }\n if (variant === \"caption\") {\n return {\n $type: \"Caption\",\n ...(text !== undefined ? { value: text } : {}),\n };\n }\n return {\n $type: \"Markdown\",\n ...(text !== undefined ? { value: text } : {}),\n };\n }\n\n if (component === \"Image\") {\n const src = stringProp(props, [\"src\", \"url\"]);\n const alt = stringProp(props, [\"alt\", \"altText\"]);\n const size = props[\"size\"];\n const round = props[\"round\"];\n return {\n $type: \"Image\",\n ...(src !== undefined ? { src } : {}),\n ...(alt !== undefined ? { alt } : {}),\n ...(typeof size === \"string\" || typeof size === \"number\" ? { size } : {}),\n ...(typeof round === \"boolean\" ? { round } : {}),\n };\n }\n\n if (component === \"Row\") {\n const gap = props[\"gap\"];\n const align = firstDefined(props, [\"align\", \"alignment\"]);\n const justify = firstDefined(props, [\"justify\", \"distribution\"]);\n return {\n $type: \"Row\",\n ...(typeof gap === \"number\" ? { gap } : {}),\n ...(typeof align === \"string\" ? { align } : {}),\n ...(typeof justify === \"string\" ? { justify } : {}),\n };\n }\n\n if (component === \"Column\") {\n const gap = props[\"gap\"];\n const align = firstDefined(props, [\"align\", \"alignment\"]);\n return {\n $type: \"Col\",\n ...(typeof gap === \"number\" ? { gap } : {}),\n ...(typeof align === \"string\" ? { align } : {}),\n };\n }\n\n if (component === \"Card\") {\n const title = props[\"title\"];\n const padding = props[\"padding\"];\n const background = props[\"background\"];\n return {\n $type: \"Card\",\n ...(typeof title === \"string\" ? { title } : {}),\n ...(typeof padding === \"number\" ? { padding } : {}),\n ...(typeof background === \"string\" ? { background } : {}),\n };\n }\n\n if (component === \"Divider\") {\n return {\n $type: \"Divider\",\n ...(typeof props[\"flush\"] === \"boolean\" ? { flush: props[\"flush\"] } : {}),\n };\n }\n\n if (component === \"Button\") {\n const label = stringProp(props, [\"label\", \"text\"]);\n const buttonStyle = props[\"buttonStyle\"];\n const block = props[\"block\"];\n const submit = props[\"submit\"];\n const action = mappedAction(node, props, dataSource, context);\n return {\n $type: \"Button\",\n ...(label !== undefined ? { label } : {}),\n ...(typeof buttonStyle === \"string\" ? { buttonStyle } : {}),\n ...(typeof block === \"boolean\" ? { block } : {}),\n ...(typeof submit === \"boolean\" ? { submit } : {}),\n ...(action ? { $action: action } : {}),\n };\n }\n\n const binding = firstDefined(node, [\"text\", \"value\", \"binding\"]);\n const name = lastPointerSegment(bindingPath(binding));\n const label = stringProp(props, [\"label\"]);\n\n if (component === \"TextField\") {\n const placeholder = stringProp(props, [\"placeholder\"]);\n const multiline =\n typeof props[\"multiline\"] === \"boolean\"\n ? props[\"multiline\"]\n : props[\"textFieldType\"] === \"longText\"\n ? true\n : undefined;\n return {\n $type: \"Input\",\n ...(placeholder !== undefined ? { placeholder } : {}),\n ...(multiline !== undefined ? { multiline } : {}),\n ...(label !== undefined ? { label } : {}),\n ...(name !== undefined ? { name } : {}),\n };\n }\n\n if (component === \"CheckBox\") {\n const defaultChecked = firstDefined(props, [\"defaultChecked\", \"value\"]);\n return {\n $type: \"Checkbox\",\n ...(label !== undefined ? { label } : {}),\n ...(name !== undefined ? { name } : {}),\n ...(typeof defaultChecked === \"boolean\" ? { defaultChecked } : {}),\n };\n }\n\n return undefined;\n};\n\nconst convertTemplate = (\n node: Record<string, unknown>,\n templateChildren: A2uiTemplateChildren,\n dataSource: unknown,\n context: ConversionContext,\n depth: number,\n visited: Set<string>,\n): UIElement | null => {\n if (!reserveNode(context)) return null;\n const list = resolvePointer(dataSource, templateChildren.template.path);\n if (!Array.isArray(list)) {\n context.warnings.push(\n `Template on component \"${String(node[\"id\"] ?? \"\")}\" did not resolve to a list.`,\n );\n return { $type: \"ListView\", children: [] };\n }\n const itemCount = Math.min(list.length, TEMPLATE_ITEM_CAP);\n if (list.length > TEMPLATE_ITEM_CAP && !context.templateCapWarned) {\n context.warnings.push(\n `A2UI template expansion was capped at ${TEMPLATE_ITEM_CAP} items.`,\n );\n context.templateCapWarned = true;\n }\n const children: UIElement[] = [];\n for (let index = 0; index < itemCount; index++) {\n if (!reserveNode(context)) break;\n const child = convertComponent(\n templateChildren.template.componentId,\n list[index],\n context,\n depth + 1,\n visited,\n );\n children.push({\n $type: \"ListViewItem\",\n ...(child ? { children: child } : {}),\n });\n }\n return { $type: \"ListView\", children };\n};\n\nfunction convertComponent(\n componentId: string,\n dataSource: unknown,\n context: ConversionContext,\n depth: number,\n visited: Set<string>,\n): UIElement | null {\n if (depth >= DEPTH_CAP) {\n if (!context.depthWarned) {\n context.warnings.push(`A2UI depth cap of ${DEPTH_CAP} was reached.`);\n context.depthWarned = true;\n }\n return null;\n }\n if (visited.has(componentId)) {\n context.warnings.push(`A2UI component cycle detected at \"${componentId}\".`);\n return null;\n }\n const node = context.surface.components.get(componentId);\n if (!node) {\n context.warnings.push(`A2UI component \"${componentId}\" was not found.`);\n return null;\n }\n const component = node[\"component\"];\n\n visited.add(componentId);\n try {\n const templateChildren = node[\"children\"];\n if (isTemplateChildren(templateChildren)) {\n return convertTemplate(\n node,\n templateChildren,\n dataSource,\n context,\n depth,\n visited,\n );\n }\n if (typeof component !== \"string\" || !SUPPORTED_COMPONENTS.has(component)) {\n context.warnings.push(\n `Unknown A2UI component \"${String(component ?? \"\")}\" was skipped.`,\n );\n return null;\n }\n if (!reserveNode(context)) return null;\n const props: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(node)) {\n if (key === \"id\" || key === \"component\" || key === \"children\") continue;\n const resolved = materialize(value, dataSource);\n if (resolved !== undefined) props[key] = resolved;\n }\n const mapped = mappedProps(node, props, dataSource, context);\n if (!mapped) return null;\n const children = childrenOf(node, dataSource, context, depth, visited);\n return {\n ...mapped,\n ...(children.length > 0 ? { children } : {}),\n };\n } finally {\n visited.delete(componentId);\n }\n}\n\nexport function convertSurfaceToUISpec(surface: A2uiSurfaceState): {\n spec: UIElement | null;\n warnings: string[];\n} {\n const warnings: string[] = [];\n if (!surface.components.has(\"root\")) {\n return {\n spec: null,\n warnings: ['A2UI root component \"root\" was not found.'],\n };\n }\n const context: ConversionContext = {\n surface,\n surfaceId: sourceSurfaceId(surface),\n warnings,\n emittedNodes: 0,\n depthWarned: false,\n budgetWarned: false,\n templateCapWarned: false,\n };\n try {\n const spec = convertComponent(\n \"root\",\n surface.dataModel,\n context,\n 0,\n new Set(),\n );\n return { spec, warnings };\n } catch {\n warnings.push(\"A2UI surface conversion encountered malformed input.\");\n return { spec: null, warnings };\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"convert.js","names":[],"sources":["../../src/a2ui/convert.ts"],"sourcesContent":["import type { UIElement } from \"../ir\";\nimport {\n A2UI_SURFACE_ID,\n type A2uiSurfaceState,\n type A2uiTemplateChildren,\n} from \"./types\";\n\nconst DEPTH_CAP = 32;\nconst TEMPLATE_ITEM_CAP = 100;\nconst NODE_BUDGET = 5000;\n\nconst SUPPORTED_COMPONENTS = new Set([\n \"Text\",\n \"Image\",\n \"Row\",\n \"Column\",\n \"Card\",\n \"Divider\",\n \"Button\",\n \"TextField\",\n \"CheckBox\",\n]);\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\nconst isPlainObject = (value: unknown): value is Record<string, unknown> => {\n if (!isRecord(value)) return false;\n const prototype = Object.getPrototypeOf(value);\n return prototype === Object.prototype || prototype === null;\n};\n\nconst setOwnProperty = (\n target: Record<string, unknown>,\n key: string,\n value: unknown,\n) => {\n if (key === \"__proto__\") {\n Object.defineProperty(target, key, {\n value,\n enumerable: true,\n configurable: true,\n writable: true,\n });\n } else {\n target[key] = value;\n }\n};\n\nconst isBinding = (value: unknown): value is { readonly path: string } =>\n isPlainObject(value) &&\n Object.keys(value).length === 1 &&\n typeof value[\"path\"] === \"string\";\n\nconst isTemplateChildren = (value: unknown): value is A2uiTemplateChildren =>\n isPlainObject(value) &&\n Object.keys(value).length === 1 &&\n isPlainObject(value[\"template\"]) &&\n Object.keys(value[\"template\"]).length === 2 &&\n typeof value[\"template\"][\"componentId\"] === \"string\" &&\n typeof value[\"template\"][\"path\"] === \"string\";\n\nconst decodePointer = (path: string): string[] | undefined => {\n if (path === \"\" || path === \"/\") return [];\n if (!path.startsWith(\"/\")) return undefined;\n return path\n .slice(1)\n .split(\"/\")\n .map((segment) => segment.replaceAll(\"~1\", \"/\").replaceAll(\"~0\", \"~\"));\n};\n\nconst resolvePointer = (source: unknown, path: string): unknown => {\n const segments = decodePointer(path);\n if (!segments) return undefined;\n let current = source;\n for (const segment of segments) {\n if (Array.isArray(current)) {\n if (!/^(0|[1-9]\\d*)$/.test(segment)) return undefined;\n current = current[Number(segment)];\n continue;\n }\n if (!isRecord(current) || !Object.hasOwn(current, segment)) {\n return undefined;\n }\n current = current[segment];\n }\n return current;\n};\n\nconst bindingPath = (value: unknown): string | undefined =>\n isBinding(value) ? value.path : undefined;\n\nconst lastPointerSegment = (path: string | undefined): string | undefined => {\n if (!path) return undefined;\n const segments = decodePointer(path);\n return segments?.at(-1);\n};\n\nconst materialize = (value: unknown, source: unknown): unknown => {\n if (isBinding(value)) return resolvePointer(source, value.path);\n if (Array.isArray(value)) {\n return value\n .map((entry) => materialize(entry, source))\n .filter((entry) => entry !== undefined);\n }\n if (!isPlainObject(value)) return value;\n const result: Record<string, unknown> = {};\n for (const [key, entry] of Object.entries(value)) {\n const resolved = materialize(entry, source);\n if (resolved !== undefined) {\n setOwnProperty(result, key, resolved);\n }\n }\n return result;\n};\n\nconst firstDefined = (\n props: Record<string, unknown>,\n keys: readonly string[],\n): unknown => {\n for (const key of keys) {\n if (props[key] !== undefined) return props[key];\n }\n return undefined;\n};\n\nconst stringProp = (\n props: Record<string, unknown>,\n keys: readonly string[],\n): string | undefined => {\n const value = firstDefined(props, keys);\n return typeof value === \"string\" ? value : undefined;\n};\n\nconst sourceSurfaceId = (surface: A2uiSurfaceState): string =>\n (surface as A2uiSurfaceState & { [A2UI_SURFACE_ID]?: string })[\n A2UI_SURFACE_ID\n ] ?? \"\";\n\ntype ConversionContext = {\n readonly surface: A2uiSurfaceState;\n readonly surfaceId: string;\n readonly warnings: string[];\n emittedNodes: number;\n depthWarned: boolean;\n budgetWarned: boolean;\n templateCapWarned: boolean;\n};\n\nconst reserveNode = (context: ConversionContext): boolean => {\n if (context.emittedNodes >= NODE_BUDGET) {\n if (!context.budgetWarned) {\n context.warnings.push(`A2UI node budget of ${NODE_BUDGET} was reached.`);\n context.budgetWarned = true;\n }\n return false;\n }\n context.emittedNodes++;\n return true;\n};\n\nconst childrenOf = (\n node: Record<string, unknown>,\n dataSource: unknown,\n context: ConversionContext,\n depth: number,\n visited: Set<string>,\n): UIElement[] => {\n const children = node[\"children\"];\n if (!Array.isArray(children)) return [];\n const result: UIElement[] = [];\n for (const childId of children) {\n if (typeof childId !== \"string\") {\n context.warnings.push(\n `Component \"${String(node[\"id\"] ?? \"\")}\" has a malformed child reference.`,\n );\n continue;\n }\n const child = convertComponent(\n childId,\n dataSource,\n context,\n depth + 1,\n visited,\n );\n if (child) result.push(child);\n }\n return result;\n};\n\nconst mappedAction = (\n node: Record<string, unknown>,\n props: Record<string, unknown>,\n dataSource: unknown,\n context: ConversionContext,\n): UIElement[\"$action\"] | undefined => {\n const action = props[\"action\"];\n const actionName =\n typeof action === \"string\"\n ? action\n : isRecord(action) && typeof action[\"name\"] === \"string\"\n ? action[\"name\"]\n : undefined;\n if (!actionName) return undefined;\n const rawContext = isRecord(action) ? action[\"context\"] : undefined;\n const resolvedContext =\n rawContext === undefined ? undefined : materialize(rawContext, dataSource);\n return {\n type: \"a2ui:action\",\n name: actionName,\n surfaceId: context.surfaceId,\n sourceComponentId: typeof node[\"id\"] === \"string\" ? node[\"id\"] : \"\",\n ...(resolvedContext !== undefined ? { context: resolvedContext } : {}),\n };\n};\n\nconst mappedProps = (\n node: Record<string, unknown>,\n props: Record<string, unknown>,\n dataSource: unknown,\n context: ConversionContext,\n): UIElement | undefined => {\n const component = node[\"component\"];\n\n if (component === \"Text\") {\n const text = stringProp(props, [\"text\", \"value\"]);\n const variant = props[\"variant\"];\n if (typeof variant === \"string\" && /^h[1-6]$/.test(variant)) {\n return {\n $type: \"Header\",\n ...(text !== undefined ? { text } : {}),\n };\n }\n if (variant === \"caption\") {\n return {\n $type: \"Caption\",\n ...(text !== undefined ? { value: text } : {}),\n };\n }\n return {\n $type: \"Markdown\",\n ...(text !== undefined ? { value: text } : {}),\n };\n }\n\n if (component === \"Image\") {\n const src = stringProp(props, [\"src\", \"url\"]);\n const alt = stringProp(props, [\"alt\", \"altText\"]);\n const size = props[\"size\"];\n const round = props[\"round\"];\n return {\n $type: \"Image\",\n ...(src !== undefined ? { src } : {}),\n ...(alt !== undefined ? { alt } : {}),\n ...(typeof size === \"string\" || typeof size === \"number\" ? { size } : {}),\n ...(typeof round === \"boolean\" ? { round } : {}),\n };\n }\n\n if (component === \"Row\") {\n const gap = props[\"gap\"];\n const align = firstDefined(props, [\"align\", \"alignment\"]);\n const justify = firstDefined(props, [\"justify\", \"distribution\"]);\n return {\n $type: \"Row\",\n ...(typeof gap === \"number\" ? { gap } : {}),\n ...(typeof align === \"string\" ? { align } : {}),\n ...(typeof justify === \"string\" ? { justify } : {}),\n };\n }\n\n if (component === \"Column\") {\n const gap = props[\"gap\"];\n const align = firstDefined(props, [\"align\", \"alignment\"]);\n return {\n $type: \"Col\",\n ...(typeof gap === \"number\" ? { gap } : {}),\n ...(typeof align === \"string\" ? { align } : {}),\n };\n }\n\n if (component === \"Card\") {\n const title = props[\"title\"];\n const padding = props[\"padding\"];\n const background = props[\"background\"];\n return {\n $type: \"Card\",\n ...(typeof title === \"string\" ? { title } : {}),\n ...(typeof padding === \"number\" ? { padding } : {}),\n ...(typeof background === \"string\" ? { background } : {}),\n };\n }\n\n if (component === \"Divider\") {\n return {\n $type: \"Divider\",\n ...(typeof props[\"flush\"] === \"boolean\" ? { flush: props[\"flush\"] } : {}),\n };\n }\n\n if (component === \"Button\") {\n const label = stringProp(props, [\"label\", \"text\"]);\n const buttonStyle = props[\"buttonStyle\"];\n const block = props[\"block\"];\n const submit = props[\"submit\"];\n const action = mappedAction(node, props, dataSource, context);\n return {\n $type: \"Button\",\n ...(label !== undefined ? { label } : {}),\n ...(typeof buttonStyle === \"string\" ? { buttonStyle } : {}),\n ...(typeof block === \"boolean\" ? { block } : {}),\n ...(typeof submit === \"boolean\" ? { submit } : {}),\n ...(action ? { $action: action } : {}),\n };\n }\n\n const binding = firstDefined(node, [\"text\", \"value\", \"binding\"]);\n const name = lastPointerSegment(bindingPath(binding));\n const label = stringProp(props, [\"label\"]);\n\n if (component === \"TextField\") {\n const placeholder = stringProp(props, [\"placeholder\"]);\n const multiline =\n typeof props[\"multiline\"] === \"boolean\"\n ? props[\"multiline\"]\n : props[\"textFieldType\"] === \"longText\"\n ? true\n : undefined;\n return {\n $type: \"Input\",\n ...(placeholder !== undefined ? { placeholder } : {}),\n ...(multiline !== undefined ? { multiline } : {}),\n ...(label !== undefined ? { label } : {}),\n ...(name !== undefined ? { name } : {}),\n };\n }\n\n if (component === \"CheckBox\") {\n const defaultChecked = firstDefined(props, [\"defaultChecked\", \"value\"]);\n return {\n $type: \"Checkbox\",\n ...(label !== undefined ? { label } : {}),\n ...(name !== undefined ? { name } : {}),\n ...(typeof defaultChecked === \"boolean\" ? { defaultChecked } : {}),\n };\n }\n\n return undefined;\n};\n\nconst convertTemplate = (\n node: Record<string, unknown>,\n templateChildren: A2uiTemplateChildren,\n dataSource: unknown,\n context: ConversionContext,\n depth: number,\n visited: Set<string>,\n): UIElement | null => {\n if (!reserveNode(context)) return null;\n const list = resolvePointer(dataSource, templateChildren.template.path);\n if (!Array.isArray(list)) {\n context.warnings.push(\n `Template on component \"${String(node[\"id\"] ?? \"\")}\" did not resolve to a list.`,\n );\n return { $type: \"ListView\", children: [] };\n }\n const itemCount = Math.min(list.length, TEMPLATE_ITEM_CAP);\n if (list.length > TEMPLATE_ITEM_CAP && !context.templateCapWarned) {\n context.warnings.push(\n `A2UI template expansion was capped at ${TEMPLATE_ITEM_CAP} items.`,\n );\n context.templateCapWarned = true;\n }\n const children: UIElement[] = [];\n for (let index = 0; index < itemCount; index++) {\n if (!reserveNode(context)) break;\n const child = convertComponent(\n templateChildren.template.componentId,\n list[index],\n context,\n depth + 1,\n visited,\n );\n children.push({\n $type: \"ListViewItem\",\n ...(child ? { children: child } : {}),\n });\n }\n return { $type: \"ListView\", children };\n};\n\nfunction convertComponent(\n componentId: string,\n dataSource: unknown,\n context: ConversionContext,\n depth: number,\n visited: Set<string>,\n): UIElement | null {\n if (depth >= DEPTH_CAP) {\n if (!context.depthWarned) {\n context.warnings.push(`A2UI depth cap of ${DEPTH_CAP} was reached.`);\n context.depthWarned = true;\n }\n return null;\n }\n if (visited.has(componentId)) {\n context.warnings.push(`A2UI component cycle detected at \"${componentId}\".`);\n return null;\n }\n const node = context.surface.components.get(componentId);\n if (!node) {\n context.warnings.push(`A2UI component \"${componentId}\" was not found.`);\n return null;\n }\n const component = node[\"component\"];\n\n visited.add(componentId);\n try {\n const templateChildren = node[\"children\"];\n if (isTemplateChildren(templateChildren)) {\n return convertTemplate(\n node,\n templateChildren,\n dataSource,\n context,\n depth,\n visited,\n );\n }\n if (typeof component !== \"string\" || !SUPPORTED_COMPONENTS.has(component)) {\n context.warnings.push(\n `Unknown A2UI component \"${String(component ?? \"\")}\" was skipped.`,\n );\n return null;\n }\n if (!reserveNode(context)) return null;\n const props: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(node)) {\n if (key === \"id\" || key === \"component\" || key === \"children\") continue;\n const resolved = materialize(value, dataSource);\n if (resolved !== undefined) setOwnProperty(props, key, resolved);\n }\n const mapped = mappedProps(node, props, dataSource, context);\n if (!mapped) return null;\n const children = childrenOf(node, dataSource, context, depth, visited);\n return {\n ...mapped,\n ...(children.length > 0 ? { children } : {}),\n };\n } finally {\n visited.delete(componentId);\n }\n}\n\nexport function convertSurfaceToUISpec(surface: A2uiSurfaceState): {\n spec: UIElement | null;\n warnings: string[];\n} {\n const warnings: string[] = [];\n if (!surface.components.has(\"root\")) {\n return {\n spec: null,\n warnings: ['A2UI root component \"root\" was not found.'],\n };\n }\n const context: ConversionContext = {\n surface,\n surfaceId: sourceSurfaceId(surface),\n warnings,\n emittedNodes: 0,\n depthWarned: false,\n budgetWarned: false,\n templateCapWarned: false,\n };\n try {\n const spec = convertComponent(\n \"root\",\n surface.dataModel,\n context,\n 0,\n new Set(),\n );\n return { spec, warnings };\n } catch {\n warnings.push(\"A2UI surface conversion encountered malformed input.\");\n return { spec: null, warnings };\n }\n}\n"],"mappings":";;AAOA,MAAM,YAAY;AAClB,MAAM,oBAAoB;AAC1B,MAAM,cAAc;AAEpB,MAAM,uCAAuB,IAAI,IAAI;CACnC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF,CAAC;AAED,MAAM,YAAY,UAChB,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAErE,MAAM,iBAAiB,UAAqD;CAC1E,IAAI,CAAC,SAAS,KAAK,GAAG,OAAO;CAC7B,MAAM,YAAY,OAAO,eAAe,KAAK;CAC7C,OAAO,cAAc,OAAO,aAAa,cAAc;AACzD;AAEA,MAAM,kBACJ,QACA,KACA,UACG;CACH,IAAI,QAAQ,aACV,OAAO,eAAe,QAAQ,KAAK;EACjC;EACA,YAAY;EACZ,cAAc;EACd,UAAU;CACZ,CAAC;MAED,OAAO,OAAO;AAElB;AAEA,MAAM,aAAa,UACjB,cAAc,KAAK,KACnB,OAAO,KAAK,KAAK,CAAC,CAAC,WAAW,KAC9B,OAAO,MAAM,YAAY;AAE3B,MAAM,sBAAsB,UAC1B,cAAc,KAAK,KACnB,OAAO,KAAK,KAAK,CAAC,CAAC,WAAW,KAC9B,cAAc,MAAM,WAAW,KAC/B,OAAO,KAAK,MAAM,WAAW,CAAC,CAAC,WAAW,KAC1C,OAAO,MAAM,WAAW,CAAC,mBAAmB,YAC5C,OAAO,MAAM,WAAW,CAAC,YAAY;AAEvC,MAAM,iBAAiB,SAAuC;CAC5D,IAAI,SAAS,MAAM,SAAS,KAAK,OAAO,CAAC;CACzC,IAAI,CAAC,KAAK,WAAW,GAAG,GAAG,OAAO,KAAA;CAClC,OAAO,KACJ,MAAM,CAAC,CAAC,CACR,MAAM,GAAG,CAAC,CACV,KAAK,YAAY,QAAQ,WAAW,MAAM,GAAG,CAAC,CAAC,WAAW,MAAM,GAAG,CAAC;AACzE;AAEA,MAAM,kBAAkB,QAAiB,SAA0B;CACjE,MAAM,WAAW,cAAc,IAAI;CACnC,IAAI,CAAC,UAAU,OAAO,KAAA;CACtB,IAAI,UAAU;CACd,KAAK,MAAM,WAAW,UAAU;EAC9B,IAAI,MAAM,QAAQ,OAAO,GAAG;GAC1B,IAAI,CAAC,iBAAiB,KAAK,OAAO,GAAG,OAAO,KAAA;GAC5C,UAAU,QAAQ,OAAO,OAAO;GAChC;EACF;EACA,IAAI,CAAC,SAAS,OAAO,KAAK,CAAC,OAAO,OAAO,SAAS,OAAO,GACvD;EAEF,UAAU,QAAQ;CACpB;CACA,OAAO;AACT;AAEA,MAAM,eAAe,UACnB,UAAU,KAAK,IAAI,MAAM,OAAO,KAAA;AAElC,MAAM,sBAAsB,SAAiD;CAC3E,IAAI,CAAC,MAAM,OAAO,KAAA;CAElB,OADiB,cAAc,IACjB,CAAC,EAAE,GAAG,EAAE;AACxB;AAEA,MAAM,eAAe,OAAgB,WAA6B;CAChE,IAAI,UAAU,KAAK,GAAG,OAAO,eAAe,QAAQ,MAAM,IAAI;CAC9D,IAAI,MAAM,QAAQ,KAAK,GACrB,OAAO,MACJ,KAAK,UAAU,YAAY,OAAO,MAAM,CAAC,CAAC,CAC1C,QAAQ,UAAU,UAAU,KAAA,CAAS;CAE1C,IAAI,CAAC,cAAc,KAAK,GAAG,OAAO;CAClC,MAAM,SAAkC,CAAC;CACzC,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,KAAK,GAAG;EAChD,MAAM,WAAW,YAAY,OAAO,MAAM;EAC1C,IAAI,aAAa,KAAA,GACf,eAAe,QAAQ,KAAK,QAAQ;CAExC;CACA,OAAO;AACT;AAEA,MAAM,gBACJ,OACA,SACY;CACZ,KAAK,MAAM,OAAO,MAChB,IAAI,MAAM,SAAS,KAAA,GAAW,OAAO,MAAM;AAG/C;AAEA,MAAM,cACJ,OACA,SACuB;CACvB,MAAM,QAAQ,aAAa,OAAO,IAAI;CACtC,OAAO,OAAO,UAAU,WAAW,QAAQ,KAAA;AAC7C;AAEA,MAAM,mBAAmB,YACtB,QACC,oBACG;AAYP,MAAM,eAAe,YAAwC;CAC3D,IAAI,QAAQ,gBAAgB,aAAa;EACvC,IAAI,CAAC,QAAQ,cAAc;GACzB,QAAQ,SAAS,KAAK,uBAAuB,YAAY,cAAc;GACvE,QAAQ,eAAe;EACzB;EACA,OAAO;CACT;CACA,QAAQ;CACR,OAAO;AACT;AAEA,MAAM,cACJ,MACA,YACA,SACA,OACA,YACgB;CAChB,MAAM,WAAW,KAAK;CACtB,IAAI,CAAC,MAAM,QAAQ,QAAQ,GAAG,OAAO,CAAC;CACtC,MAAM,SAAsB,CAAC;CAC7B,KAAK,MAAM,WAAW,UAAU;EAC9B,IAAI,OAAO,YAAY,UAAU;GAC/B,QAAQ,SAAS,KACf,cAAc,OAAO,KAAK,SAAS,EAAE,EAAE,mCACzC;GACA;EACF;EACA,MAAM,QAAQ,iBACZ,SACA,YACA,SACA,QAAQ,GACR,OACF;EACA,IAAI,OAAO,OAAO,KAAK,KAAK;CAC9B;CACA,OAAO;AACT;AAEA,MAAM,gBACJ,MACA,OACA,YACA,YACqC;CACrC,MAAM,SAAS,MAAM;CACrB,MAAM,aACJ,OAAO,WAAW,WACd,SACA,SAAS,MAAM,KAAK,OAAO,OAAO,YAAY,WAC5C,OAAO,UACP,KAAA;CACR,IAAI,CAAC,YAAY,OAAO,KAAA;CACxB,MAAM,aAAa,SAAS,MAAM,IAAI,OAAO,aAAa,KAAA;CAC1D,MAAM,kBACJ,eAAe,KAAA,IAAY,KAAA,IAAY,YAAY,YAAY,UAAU;CAC3E,OAAO;EACL,MAAM;EACN,MAAM;EACN,WAAW,QAAQ;EACnB,mBAAmB,OAAO,KAAK,UAAU,WAAW,KAAK,QAAQ;EACjE,GAAI,oBAAoB,KAAA,IAAY,EAAE,SAAS,gBAAgB,IAAI,CAAC;CACtE;AACF;AAEA,MAAM,eACJ,MACA,OACA,YACA,YAC0B;CAC1B,MAAM,YAAY,KAAK;CAEvB,IAAI,cAAc,QAAQ;EACxB,MAAM,OAAO,WAAW,OAAO,CAAC,QAAQ,OAAO,CAAC;EAChD,MAAM,UAAU,MAAM;EACtB,IAAI,OAAO,YAAY,YAAY,WAAW,KAAK,OAAO,GACxD,OAAO;GACL,OAAO;GACP,GAAI,SAAS,KAAA,IAAY,EAAE,KAAK,IAAI,CAAC;EACvC;EAEF,IAAI,YAAY,WACd,OAAO;GACL,OAAO;GACP,GAAI,SAAS,KAAA,IAAY,EAAE,OAAO,KAAK,IAAI,CAAC;EAC9C;EAEF,OAAO;GACL,OAAO;GACP,GAAI,SAAS,KAAA,IAAY,EAAE,OAAO,KAAK,IAAI,CAAC;EAC9C;CACF;CAEA,IAAI,cAAc,SAAS;EACzB,MAAM,MAAM,WAAW,OAAO,CAAC,OAAO,KAAK,CAAC;EAC5C,MAAM,MAAM,WAAW,OAAO,CAAC,OAAO,SAAS,CAAC;EAChD,MAAM,OAAO,MAAM;EACnB,MAAM,QAAQ,MAAM;EACpB,OAAO;GACL,OAAO;GACP,GAAI,QAAQ,KAAA,IAAY,EAAE,IAAI,IAAI,CAAC;GACnC,GAAI,QAAQ,KAAA,IAAY,EAAE,IAAI,IAAI,CAAC;GACnC,GAAI,OAAO,SAAS,YAAY,OAAO,SAAS,WAAW,EAAE,KAAK,IAAI,CAAC;GACvE,GAAI,OAAO,UAAU,YAAY,EAAE,MAAM,IAAI,CAAC;EAChD;CACF;CAEA,IAAI,cAAc,OAAO;EACvB,MAAM,MAAM,MAAM;EAClB,MAAM,QAAQ,aAAa,OAAO,CAAC,SAAS,WAAW,CAAC;EACxD,MAAM,UAAU,aAAa,OAAO,CAAC,WAAW,cAAc,CAAC;EAC/D,OAAO;GACL,OAAO;GACP,GAAI,OAAO,QAAQ,WAAW,EAAE,IAAI,IAAI,CAAC;GACzC,GAAI,OAAO,UAAU,WAAW,EAAE,MAAM,IAAI,CAAC;GAC7C,GAAI,OAAO,YAAY,WAAW,EAAE,QAAQ,IAAI,CAAC;EACnD;CACF;CAEA,IAAI,cAAc,UAAU;EAC1B,MAAM,MAAM,MAAM;EAClB,MAAM,QAAQ,aAAa,OAAO,CAAC,SAAS,WAAW,CAAC;EACxD,OAAO;GACL,OAAO;GACP,GAAI,OAAO,QAAQ,WAAW,EAAE,IAAI,IAAI,CAAC;GACzC,GAAI,OAAO,UAAU,WAAW,EAAE,MAAM,IAAI,CAAC;EAC/C;CACF;CAEA,IAAI,cAAc,QAAQ;EACxB,MAAM,QAAQ,MAAM;EACpB,MAAM,UAAU,MAAM;EACtB,MAAM,aAAa,MAAM;EACzB,OAAO;GACL,OAAO;GACP,GAAI,OAAO,UAAU,WAAW,EAAE,MAAM,IAAI,CAAC;GAC7C,GAAI,OAAO,YAAY,WAAW,EAAE,QAAQ,IAAI,CAAC;GACjD,GAAI,OAAO,eAAe,WAAW,EAAE,WAAW,IAAI,CAAC;EACzD;CACF;CAEA,IAAI,cAAc,WAChB,OAAO;EACL,OAAO;EACP,GAAI,OAAO,MAAM,aAAa,YAAY,EAAE,OAAO,MAAM,SAAS,IAAI,CAAC;CACzE;CAGF,IAAI,cAAc,UAAU;EAC1B,MAAM,QAAQ,WAAW,OAAO,CAAC,SAAS,MAAM,CAAC;EACjD,MAAM,cAAc,MAAM;EAC1B,MAAM,QAAQ,MAAM;EACpB,MAAM,SAAS,MAAM;EACrB,MAAM,SAAS,aAAa,MAAM,OAAO,YAAY,OAAO;EAC5D,OAAO;GACL,OAAO;GACP,GAAI,UAAU,KAAA,IAAY,EAAE,MAAM,IAAI,CAAC;GACvC,GAAI,OAAO,gBAAgB,WAAW,EAAE,YAAY,IAAI,CAAC;GACzD,GAAI,OAAO,UAAU,YAAY,EAAE,MAAM,IAAI,CAAC;GAC9C,GAAI,OAAO,WAAW,YAAY,EAAE,OAAO,IAAI,CAAC;GAChD,GAAI,SAAS,EAAE,SAAS,OAAO,IAAI,CAAC;EACtC;CACF;CAEA,MAAM,UAAU,aAAa,MAAM;EAAC;EAAQ;EAAS;CAAS,CAAC;CAC/D,MAAM,OAAO,mBAAmB,YAAY,OAAO,CAAC;CACpD,MAAM,QAAQ,WAAW,OAAO,CAAC,OAAO,CAAC;CAEzC,IAAI,cAAc,aAAa;EAC7B,MAAM,cAAc,WAAW,OAAO,CAAC,aAAa,CAAC;EACrD,MAAM,YACJ,OAAO,MAAM,iBAAiB,YAC1B,MAAM,eACN,MAAM,qBAAqB,aACzB,OACA,KAAA;EACR,OAAO;GACL,OAAO;GACP,GAAI,gBAAgB,KAAA,IAAY,EAAE,YAAY,IAAI,CAAC;GACnD,GAAI,cAAc,KAAA,IAAY,EAAE,UAAU,IAAI,CAAC;GAC/C,GAAI,UAAU,KAAA,IAAY,EAAE,MAAM,IAAI,CAAC;GACvC,GAAI,SAAS,KAAA,IAAY,EAAE,KAAK,IAAI,CAAC;EACvC;CACF;CAEA,IAAI,cAAc,YAAY;EAC5B,MAAM,iBAAiB,aAAa,OAAO,CAAC,kBAAkB,OAAO,CAAC;EACtE,OAAO;GACL,OAAO;GACP,GAAI,UAAU,KAAA,IAAY,EAAE,MAAM,IAAI,CAAC;GACvC,GAAI,SAAS,KAAA,IAAY,EAAE,KAAK,IAAI,CAAC;GACrC,GAAI,OAAO,mBAAmB,YAAY,EAAE,eAAe,IAAI,CAAC;EAClE;CACF;AAGF;AAEA,MAAM,mBACJ,MACA,kBACA,YACA,SACA,OACA,YACqB;CACrB,IAAI,CAAC,YAAY,OAAO,GAAG,OAAO;CAClC,MAAM,OAAO,eAAe,YAAY,iBAAiB,SAAS,IAAI;CACtE,IAAI,CAAC,MAAM,QAAQ,IAAI,GAAG;EACxB,QAAQ,SAAS,KACf,0BAA0B,OAAO,KAAK,SAAS,EAAE,EAAE,6BACrD;EACA,OAAO;GAAE,OAAO;GAAY,UAAU,CAAC;EAAE;CAC3C;CACA,MAAM,YAAY,KAAK,IAAI,KAAK,QAAQ,iBAAiB;CACzD,IAAI,KAAK,SAAS,qBAAqB,CAAC,QAAQ,mBAAmB;EACjE,QAAQ,SAAS,KACf,yCAAyC,kBAAkB,QAC7D;EACA,QAAQ,oBAAoB;CAC9B;CACA,MAAM,WAAwB,CAAC;CAC/B,KAAK,IAAI,QAAQ,GAAG,QAAQ,WAAW,SAAS;EAC9C,IAAI,CAAC,YAAY,OAAO,GAAG;EAC3B,MAAM,QAAQ,iBACZ,iBAAiB,SAAS,aAC1B,KAAK,QACL,SACA,QAAQ,GACR,OACF;EACA,SAAS,KAAK;GACZ,OAAO;GACP,GAAI,QAAQ,EAAE,UAAU,MAAM,IAAI,CAAC;EACrC,CAAC;CACH;CACA,OAAO;EAAE,OAAO;EAAY;CAAS;AACvC;AAEA,SAAS,iBACP,aACA,YACA,SACA,OACA,SACkB;CAClB,IAAI,SAAS,WAAW;EACtB,IAAI,CAAC,QAAQ,aAAa;GACxB,QAAQ,SAAS,KAAK,qBAAqB,UAAU,cAAc;GACnE,QAAQ,cAAc;EACxB;EACA,OAAO;CACT;CACA,IAAI,QAAQ,IAAI,WAAW,GAAG;EAC5B,QAAQ,SAAS,KAAK,qCAAqC,YAAY,GAAG;EAC1E,OAAO;CACT;CACA,MAAM,OAAO,QAAQ,QAAQ,WAAW,IAAI,WAAW;CACvD,IAAI,CAAC,MAAM;EACT,QAAQ,SAAS,KAAK,mBAAmB,YAAY,iBAAiB;EACtE,OAAO;CACT;CACA,MAAM,YAAY,KAAK;CAEvB,QAAQ,IAAI,WAAW;CACvB,IAAI;EACF,MAAM,mBAAmB,KAAK;EAC9B,IAAI,mBAAmB,gBAAgB,GACrC,OAAO,gBACL,MACA,kBACA,YACA,SACA,OACA,OACF;EAEF,IAAI,OAAO,cAAc,YAAY,CAAC,qBAAqB,IAAI,SAAS,GAAG;GACzE,QAAQ,SAAS,KACf,2BAA2B,OAAO,aAAa,EAAE,EAAE,eACrD;GACA,OAAO;EACT;EACA,IAAI,CAAC,YAAY,OAAO,GAAG,OAAO;EAClC,MAAM,QAAiC,CAAC;EACxC,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,IAAI,GAAG;GAC/C,IAAI,QAAQ,QAAQ,QAAQ,eAAe,QAAQ,YAAY;GAC/D,MAAM,WAAW,YAAY,OAAO,UAAU;GAC9C,IAAI,aAAa,KAAA,GAAW,eAAe,OAAO,KAAK,QAAQ;EACjE;EACA,MAAM,SAAS,YAAY,MAAM,OAAO,YAAY,OAAO;EAC3D,IAAI,CAAC,QAAQ,OAAO;EACpB,MAAM,WAAW,WAAW,MAAM,YAAY,SAAS,OAAO,OAAO;EACrE,OAAO;GACL,GAAG;GACH,GAAI,SAAS,SAAS,IAAI,EAAE,SAAS,IAAI,CAAC;EAC5C;CACF,UAAU;EACR,QAAQ,OAAO,WAAW;CAC5B;AACF;AAEA,SAAgB,uBAAuB,SAGrC;CACA,MAAM,WAAqB,CAAC;CAC5B,IAAI,CAAC,QAAQ,WAAW,IAAI,MAAM,GAChC,OAAO;EACL,MAAM;EACN,UAAU,CAAC,6CAA2C;CACxD;CAEF,MAAM,UAA6B;EACjC;EACA,WAAW,gBAAgB,OAAO;EAClC;EACA,cAAc;EACd,aAAa;EACb,cAAc;EACd,mBAAmB;CACrB;CACA,IAAI;EAQF,OAAO;GAAE,MAPI,iBACX,QACA,QAAQ,WACR,SACA,mBACA,IAAI,IAAI,CAEE;GAAG;EAAS;CAC1B,QAAQ;EACN,SAAS,KAAK,sDAAsD;EACpE,OAAO;GAAE,MAAM;GAAM;EAAS;CAChC;AACF"}
|
package/dist/a2ui/reducer.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { A2uiOperationResult, A2uiState } from "./types.js";
|
|
2
2
|
//#region src/a2ui/reducer.d.ts
|
|
3
|
-
declare function applyA2uiOperations(state: A2uiState, operations: unknown): A2uiOperationResult;
|
|
3
|
+
export declare function applyA2uiOperations(state: A2uiState, operations: unknown): A2uiOperationResult;
|
|
4
4
|
//#endregion
|
|
5
|
-
export { applyA2uiOperations };
|
|
6
5
|
//# sourceMappingURL=reducer.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reducer.d.ts","names":[],"sources":["../../src/a2ui/reducer.ts"],"mappings":";;
|
|
1
|
+
{"version":3,"file":"reducer.d.ts","names":[],"sources":["../../src/a2ui/reducer.ts"],"mappings":";;wBAuNgB,oBACd,OAAO,WACP,sBACC"}
|
package/dist/a2ui/reducer.js
CHANGED
|
@@ -6,6 +6,8 @@ const OPERATION_KEYS = /* @__PURE__ */ new Set([
|
|
|
6
6
|
"updateDataModel",
|
|
7
7
|
"deleteSurface"
|
|
8
8
|
]);
|
|
9
|
+
const MAX_AUTO_VIVIFY_ARRAY_INDEX = 1e4;
|
|
10
|
+
const INVALID_POINTER = Symbol("invalidPointer");
|
|
9
11
|
const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
10
12
|
const isVersion = (value) => value === "v0.9" || value === "v1.0";
|
|
11
13
|
const surfaceIdOf = (payload) => {
|
|
@@ -44,7 +46,7 @@ const decodePointer = (path) => {
|
|
|
44
46
|
return path.slice(1).split("/").map((segment) => segment.replaceAll("~1", "/").replaceAll("~0", "~"));
|
|
45
47
|
};
|
|
46
48
|
const isArrayIndex = (segment) => segment === "0" || /^[1-9]\d*$/.test(segment);
|
|
47
|
-
const setAtPointer = (model, path, value) => {
|
|
49
|
+
const setAtPointer = (model, path, value, nullDeletes) => {
|
|
48
50
|
const segments = decodePointer(path);
|
|
49
51
|
if (!segments) return {
|
|
50
52
|
ok: false,
|
|
@@ -54,24 +56,75 @@ const setAtPointer = (model, path, value) => {
|
|
|
54
56
|
ok: true,
|
|
55
57
|
value
|
|
56
58
|
};
|
|
59
|
+
const remove = (current, index) => {
|
|
60
|
+
const segment = segments[index];
|
|
61
|
+
const isLast = index === segments.length - 1;
|
|
62
|
+
if (Array.isArray(current)) {
|
|
63
|
+
if (segment !== "-" && !isArrayIndex(segment)) return current;
|
|
64
|
+
const targetIndex = segment === "-" ? current.length : Number(segment);
|
|
65
|
+
if (isLast) {
|
|
66
|
+
if (segment === "-" || !Object.prototype.hasOwnProperty.call(current, targetIndex)) return current;
|
|
67
|
+
const clone = current.slice();
|
|
68
|
+
delete clone[targetIndex];
|
|
69
|
+
return clone;
|
|
70
|
+
}
|
|
71
|
+
const child = current[targetIndex];
|
|
72
|
+
if (!Array.isArray(child) && !isRecord(child)) return current;
|
|
73
|
+
const next = remove(child, index + 1);
|
|
74
|
+
if (next === child) return current;
|
|
75
|
+
const clone = current.slice();
|
|
76
|
+
clone[targetIndex] = next;
|
|
77
|
+
return clone;
|
|
78
|
+
}
|
|
79
|
+
if (!isRecord(current)) return current;
|
|
80
|
+
if (!Object.prototype.hasOwnProperty.call(current, segment)) return current;
|
|
81
|
+
if (isLast) {
|
|
82
|
+
const clone = { ...current };
|
|
83
|
+
delete clone[segment];
|
|
84
|
+
return clone;
|
|
85
|
+
}
|
|
86
|
+
const child = current[segment];
|
|
87
|
+
if (!Array.isArray(child) && !isRecord(child)) return current;
|
|
88
|
+
const next = remove(child, index + 1);
|
|
89
|
+
if (next === child) return current;
|
|
90
|
+
return {
|
|
91
|
+
...current,
|
|
92
|
+
[segment]: next
|
|
93
|
+
};
|
|
94
|
+
};
|
|
95
|
+
if (nullDeletes && value === null) return {
|
|
96
|
+
ok: true,
|
|
97
|
+
value: remove(model, 0)
|
|
98
|
+
};
|
|
57
99
|
const update = (current, index) => {
|
|
58
100
|
const segment = segments[index];
|
|
59
101
|
const isLast = index === segments.length - 1;
|
|
60
102
|
if (Array.isArray(current)) {
|
|
61
103
|
if (segment !== "-" && !isArrayIndex(segment)) return current;
|
|
104
|
+
const targetIndex = segment === "-" ? current.length : Number(segment);
|
|
105
|
+
if (segment !== "-" && targetIndex >= current.length && targetIndex > MAX_AUTO_VIVIFY_ARRAY_INDEX) return INVALID_POINTER;
|
|
106
|
+
const next = isLast ? value : update(current[targetIndex], index + 1);
|
|
107
|
+
if (next === INVALID_POINTER) return INVALID_POINTER;
|
|
62
108
|
const clone = current.slice();
|
|
63
|
-
|
|
64
|
-
clone[targetIndex] = isLast ? value : update(clone[targetIndex], index + 1);
|
|
109
|
+
clone[targetIndex] = next;
|
|
65
110
|
return clone;
|
|
66
111
|
}
|
|
67
|
-
const
|
|
68
|
-
const child =
|
|
69
|
-
|
|
70
|
-
return
|
|
112
|
+
const record = isRecord(current) ? current : {};
|
|
113
|
+
const child = Object.hasOwn(record, segment) ? record[segment] : void 0;
|
|
114
|
+
const next = isLast ? value : update(child ?? (isArrayIndex(segments[index + 1] ?? "") || segments[index + 1] === "-" ? [] : {}), index + 1);
|
|
115
|
+
if (next === INVALID_POINTER) return INVALID_POINTER;
|
|
116
|
+
return {
|
|
117
|
+
...record,
|
|
118
|
+
[segment]: next
|
|
119
|
+
};
|
|
71
120
|
};
|
|
72
|
-
|
|
121
|
+
const result = update(model, 0);
|
|
122
|
+
return result === INVALID_POINTER ? {
|
|
123
|
+
ok: false,
|
|
124
|
+
value: model
|
|
125
|
+
} : {
|
|
73
126
|
ok: true,
|
|
74
|
-
value:
|
|
127
|
+
value: result
|
|
75
128
|
};
|
|
76
129
|
};
|
|
77
130
|
const dataModelValue = (payload) => {
|
|
@@ -160,7 +213,7 @@ function applyA2uiOperations(state, operations) {
|
|
|
160
213
|
warnings.push(`Operation at index ${index} has a malformed data model path.`);
|
|
161
214
|
continue;
|
|
162
215
|
}
|
|
163
|
-
const result = setAtPointer(surface.dataModel, path, update.value);
|
|
216
|
+
const result = setAtPointer(surface.dataModel, path, update.value, version === "v1.0");
|
|
164
217
|
if (!result.ok) {
|
|
165
218
|
warnings.push(`Operation at index ${index} has an invalid JSON Pointer path.`);
|
|
166
219
|
continue;
|
package/dist/a2ui/reducer.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reducer.js","names":[],"sources":["../../src/a2ui/reducer.ts"],"sourcesContent":["import {\n A2UI_SURFACE_ID,\n type A2uiOperationResult,\n type A2uiState,\n type A2uiSurfaceState,\n} from \"./types\";\n\nconst OPERATION_KEYS = new Set([\n \"createSurface\",\n \"updateComponents\",\n \"updateDataModel\",\n \"deleteSurface\",\n]);\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\nconst isVersion = (value: unknown): value is \"v0.9\" | \"v1.0\" =>\n value === \"v0.9\" || value === \"v1.0\";\n\nconst surfaceIdOf = (payload: Record<string, unknown>): string | undefined => {\n const surfaceId = payload[\"surfaceId\"];\n return typeof surfaceId === \"string\" && surfaceId.length > 0\n ? surfaceId\n : undefined;\n};\n\nconst withSurfaceId = (\n surface: A2uiSurfaceState,\n surfaceId: string,\n): A2uiSurfaceState => {\n Object.defineProperty(surface, A2UI_SURFACE_ID, {\n value: surfaceId,\n enumerable: false,\n });\n return surface;\n};\n\nconst getSurfaceId = (surface: A2uiSurfaceState): string | undefined =>\n (surface as A2uiSurfaceState & { [A2UI_SURFACE_ID]?: string })[\n A2UI_SURFACE_ID\n ];\n\nconst cloneSurface = (\n surface: A2uiSurfaceState,\n surfaceId: string,\n): A2uiSurfaceState =>\n withSurfaceId(\n {\n components: new Map(surface.components),\n dataModel: surface.dataModel,\n },\n getSurfaceId(surface) ?? surfaceId,\n );\n\nconst upsertComponents = (\n surface: A2uiSurfaceState,\n components: unknown,\n warnings: string[],\n operationIndex: number,\n): void => {\n if (!Array.isArray(components)) {\n warnings.push(\n `Operation at index ${operationIndex} has malformed components.`,\n );\n return;\n }\n\n for (\n let componentIndex = 0;\n componentIndex < components.length;\n componentIndex++\n ) {\n const component = components[componentIndex];\n if (\n !isRecord(component) ||\n typeof component[\"id\"] !== \"string\" ||\n component[\"id\"].length === 0 ||\n typeof component[\"component\"] !== \"string\" ||\n component[\"component\"].length === 0\n ) {\n warnings.push(\n `Component at index ${componentIndex} in operation ${operationIndex} is malformed.`,\n );\n continue;\n }\n surface.components.set(component[\"id\"], { ...component });\n }\n};\n\nconst decodePointer = (path: string): string[] | undefined => {\n if (path === \"\" || path === \"/\") return [];\n if (!path.startsWith(\"/\")) return undefined;\n return path\n .slice(1)\n .split(\"/\")\n .map((segment) => segment.replaceAll(\"~1\", \"/\").replaceAll(\"~0\", \"~\"));\n};\n\nconst isArrayIndex = (segment: string): boolean =>\n segment === \"0\" || /^[1-9]\\d*$/.test(segment);\n\nconst setAtPointer = (\n model: unknown,\n path: string,\n value: unknown,\n): { readonly ok: boolean; readonly value: unknown } => {\n const segments = decodePointer(path);\n if (!segments) return { ok: false, value: model };\n if (segments.length === 0) return { ok: true, value };\n\n const update = (current: unknown, index: number): unknown => {\n const segment = segments[index]!;\n const isLast = index === segments.length - 1;\n\n if (Array.isArray(current)) {\n if (segment !== \"-\" && !isArrayIndex(segment)) return current;\n const clone = current.slice();\n const targetIndex = segment === \"-\" ? clone.length : Number(segment);\n clone[targetIndex] = isLast\n ? value\n : update(clone[targetIndex], index + 1);\n return clone;\n }\n\n const clone: Record<string, unknown> = isRecord(current)\n ? { ...current }\n : {};\n const child = clone[segment];\n clone[segment] = isLast\n ? value\n : update(\n child ??\n (isArrayIndex(segments[index + 1] ?? \"\") ||\n segments[index + 1] === \"-\"\n ? []\n : {}),\n index + 1,\n );\n return clone;\n };\n\n return { ok: true, value: update(model, 0) };\n};\n\nconst dataModelValue = (\n payload: Record<string, unknown>,\n): { readonly found: boolean; readonly value: unknown } => {\n for (const key of [\"contents\", \"value\", \"data\"] as const) {\n if (payload[key] !== undefined) {\n return { found: true, value: payload[key] };\n }\n }\n return { found: false, value: undefined };\n};\n\nexport function applyA2uiOperations(\n state: A2uiState,\n operations: unknown,\n): A2uiOperationResult {\n const nextState = new Map(state);\n const warnings: string[] = [];\n\n if (!Array.isArray(operations)) {\n return {\n state: nextState,\n warnings: [\"A2UI operations must be an array.\"],\n };\n }\n\n for (let index = 0; index < operations.length; index++) {\n try {\n const entry = operations[index];\n if (!isRecord(entry)) {\n warnings.push(`Operation at index ${index} is malformed.`);\n continue;\n }\n\n const version = entry[\"version\"];\n if (!isVersion(version)) {\n warnings.push(\n `Operation at index ${index} has an unsupported version.`,\n );\n continue;\n }\n\n const operationKeys = Object.keys(entry).filter(\n (key) => key !== \"version\",\n );\n if (operationKeys.length !== 1) {\n warnings.push(\n `Operation at index ${index} must contain exactly one operation key.`,\n );\n continue;\n }\n\n const operationKey = operationKeys[0]!;\n if (!OPERATION_KEYS.has(operationKey)) {\n warnings.push(\n `Unknown A2UI operation \"${operationKey}\" at index ${index}.`,\n );\n continue;\n }\n\n const payload = entry[operationKey];\n if (!isRecord(payload)) {\n warnings.push(`Operation at index ${index} has a malformed payload.`);\n continue;\n }\n\n const surfaceId = surfaceIdOf(payload);\n if (!surfaceId) {\n warnings.push(`Operation at index ${index} has no valid surfaceId.`);\n continue;\n }\n\n if (operationKey === \"createSurface\") {\n const surface = withSurfaceId(\n {\n components: new Map(),\n dataModel:\n version === \"v1.0\" && payload[\"dataModel\"] !== undefined\n ? payload[\"dataModel\"]\n : undefined,\n },\n surfaceId,\n );\n if (version === \"v1.0\" && payload[\"components\"] !== undefined) {\n upsertComponents(surface, payload[\"components\"], warnings, index);\n }\n nextState.set(surfaceId, surface);\n continue;\n }\n\n if (operationKey === \"deleteSurface\") {\n nextState.delete(surfaceId);\n continue;\n }\n\n const currentSurface = nextState.get(surfaceId);\n if (!currentSurface) {\n warnings.push(\n `Operation at index ${index} references missing surface \"${surfaceId}\".`,\n );\n continue;\n }\n const surface = cloneSurface(currentSurface, surfaceId);\n\n if (operationKey === \"updateComponents\") {\n upsertComponents(surface, payload[\"components\"], warnings, index);\n nextState.set(surfaceId, surface);\n continue;\n }\n\n const update = dataModelValue(payload);\n if (!update.found) {\n warnings.push(`Operation at index ${index} has no data model value.`);\n continue;\n }\n const path = payload[\"path\"] ?? \"/\";\n if (typeof path !== \"string\") {\n warnings.push(\n `Operation at index ${index} has a malformed data model path.`,\n );\n continue;\n }\n const result = setAtPointer(surface.dataModel, path, update.value);\n if (!result.ok) {\n warnings.push(\n `Operation at index ${index} has an invalid JSON Pointer path.`,\n );\n continue;\n }\n surface.dataModel = result.value;\n nextState.set(surfaceId, surface);\n } catch {\n warnings.push(`Operation at index ${index} is malformed.`);\n }\n }\n\n return { state: nextState, warnings };\n}\n"],"mappings":";;AAOA,MAAM,iCAAiB,IAAI,IAAI;CAC7B;CACA;CACA;CACA;AACF,CAAC;AAED,MAAM,YAAY,UAChB,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAErE,MAAM,aAAa,UACjB,UAAU,UAAU,UAAU;AAEhC,MAAM,eAAe,YAAyD;CAC5E,MAAM,YAAY,QAAQ;CAC1B,OAAO,OAAO,cAAc,YAAY,UAAU,SAAS,IACvD,YACA,KAAA;AACN;AAEA,MAAM,iBACJ,SACA,cACqB;CACrB,OAAO,eAAe,SAAS,iBAAiB;EAC9C,OAAO;EACP,YAAY;CACd,CAAC;CACD,OAAO;AACT;AAEA,MAAM,gBAAgB,YACnB,QACC;AAGJ,MAAM,gBACJ,SACA,cAEA,cACE;CACE,YAAY,IAAI,IAAI,QAAQ,UAAU;CACtC,WAAW,QAAQ;AACrB,GACA,aAAa,OAAO,KAAK,SAC3B;AAEF,MAAM,oBACJ,SACA,YACA,UACA,mBACS;CACT,IAAI,CAAC,MAAM,QAAQ,UAAU,GAAG;EAC9B,SAAS,KACP,sBAAsB,eAAe,2BACvC;EACA;CACF;CAEA,KACE,IAAI,iBAAiB,GACrB,iBAAiB,WAAW,QAC5B,kBACA;EACA,MAAM,YAAY,WAAW;EAC7B,IACE,CAAC,SAAS,SAAS,KACnB,OAAO,UAAU,UAAU,YAC3B,UAAU,KAAK,CAAC,WAAW,KAC3B,OAAO,UAAU,iBAAiB,YAClC,UAAU,YAAY,CAAC,WAAW,GAClC;GACA,SAAS,KACP,sBAAsB,eAAe,gBAAgB,eAAe,eACtE;GACA;EACF;EACA,QAAQ,WAAW,IAAI,UAAU,OAAO,EAAE,GAAG,UAAU,CAAC;CAC1D;AACF;AAEA,MAAM,iBAAiB,SAAuC;CAC5D,IAAI,SAAS,MAAM,SAAS,KAAK,OAAO,CAAC;CACzC,IAAI,CAAC,KAAK,WAAW,GAAG,GAAG,OAAO,KAAA;CAClC,OAAO,KACJ,MAAM,CAAC,CAAC,CACR,MAAM,GAAG,CAAC,CACV,KAAK,YAAY,QAAQ,WAAW,MAAM,GAAG,CAAC,CAAC,WAAW,MAAM,GAAG,CAAC;AACzE;AAEA,MAAM,gBAAgB,YACpB,YAAY,OAAO,aAAa,KAAK,OAAO;AAE9C,MAAM,gBACJ,OACA,MACA,UACsD;CACtD,MAAM,WAAW,cAAc,IAAI;CACnC,IAAI,CAAC,UAAU,OAAO;EAAE,IAAI;EAAO,OAAO;CAAM;CAChD,IAAI,SAAS,WAAW,GAAG,OAAO;EAAE,IAAI;EAAM;CAAM;CAEpD,MAAM,UAAU,SAAkB,UAA2B;EAC3D,MAAM,UAAU,SAAS;EACzB,MAAM,SAAS,UAAU,SAAS,SAAS;EAE3C,IAAI,MAAM,QAAQ,OAAO,GAAG;GAC1B,IAAI,YAAY,OAAO,CAAC,aAAa,OAAO,GAAG,OAAO;GACtD,MAAM,QAAQ,QAAQ,MAAM;GAC5B,MAAM,cAAc,YAAY,MAAM,MAAM,SAAS,OAAO,OAAO;GACnE,MAAM,eAAe,SACjB,QACA,OAAO,MAAM,cAAc,QAAQ,CAAC;GACxC,OAAO;EACT;EAEA,MAAM,QAAiC,SAAS,OAAO,IACnD,EAAE,GAAG,QAAQ,IACb,CAAC;EACL,MAAM,QAAQ,MAAM;EACpB,MAAM,WAAW,SACb,QACA,OACE,UACG,aAAa,SAAS,QAAQ,MAAM,EAAE,KACvC,SAAS,QAAQ,OAAO,MACpB,CAAC,IACD,CAAC,IACP,QAAQ,CACV;EACJ,OAAO;CACT;CAEA,OAAO;EAAE,IAAI;EAAM,OAAO,OAAO,OAAO,CAAC;CAAE;AAC7C;AAEA,MAAM,kBACJ,YACyD;CACzD,KAAK,MAAM,OAAO;EAAC;EAAY;EAAS;CAAM,GAC5C,IAAI,QAAQ,SAAS,KAAA,GACnB,OAAO;EAAE,OAAO;EAAM,OAAO,QAAQ;CAAK;CAG9C,OAAO;EAAE,OAAO;EAAO,OAAO,KAAA;CAAU;AAC1C;AAEA,SAAgB,oBACd,OACA,YACqB;CACrB,MAAM,YAAY,IAAI,IAAI,KAAK;CAC/B,MAAM,WAAqB,CAAC;CAE5B,IAAI,CAAC,MAAM,QAAQ,UAAU,GAC3B,OAAO;EACL,OAAO;EACP,UAAU,CAAC,mCAAmC;CAChD;CAGF,KAAK,IAAI,QAAQ,GAAG,QAAQ,WAAW,QAAQ,SAC7C,IAAI;EACF,MAAM,QAAQ,WAAW;EACzB,IAAI,CAAC,SAAS,KAAK,GAAG;GACpB,SAAS,KAAK,sBAAsB,MAAM,eAAe;GACzD;EACF;EAEA,MAAM,UAAU,MAAM;EACtB,IAAI,CAAC,UAAU,OAAO,GAAG;GACvB,SAAS,KACP,sBAAsB,MAAM,6BAC9B;GACA;EACF;EAEA,MAAM,gBAAgB,OAAO,KAAK,KAAK,CAAC,CAAC,QACtC,QAAQ,QAAQ,SACnB;EACA,IAAI,cAAc,WAAW,GAAG;GAC9B,SAAS,KACP,sBAAsB,MAAM,yCAC9B;GACA;EACF;EAEA,MAAM,eAAe,cAAc;EACnC,IAAI,CAAC,eAAe,IAAI,YAAY,GAAG;GACrC,SAAS,KACP,2BAA2B,aAAa,aAAa,MAAM,EAC7D;GACA;EACF;EAEA,MAAM,UAAU,MAAM;EACtB,IAAI,CAAC,SAAS,OAAO,GAAG;GACtB,SAAS,KAAK,sBAAsB,MAAM,0BAA0B;GACpE;EACF;EAEA,MAAM,YAAY,YAAY,OAAO;EACrC,IAAI,CAAC,WAAW;GACd,SAAS,KAAK,sBAAsB,MAAM,yBAAyB;GACnE;EACF;EAEA,IAAI,iBAAiB,iBAAiB;GACpC,MAAM,UAAU,cACd;IACE,4BAAY,IAAI,IAAI;IACpB,WACE,YAAY,UAAU,QAAQ,iBAAiB,KAAA,IAC3C,QAAQ,eACR,KAAA;GACR,GACA,SACF;GACA,IAAI,YAAY,UAAU,QAAQ,kBAAkB,KAAA,GAClD,iBAAiB,SAAS,QAAQ,eAAe,UAAU,KAAK;GAElE,UAAU,IAAI,WAAW,OAAO;GAChC;EACF;EAEA,IAAI,iBAAiB,iBAAiB;GACpC,UAAU,OAAO,SAAS;GAC1B;EACF;EAEA,MAAM,iBAAiB,UAAU,IAAI,SAAS;EAC9C,IAAI,CAAC,gBAAgB;GACnB,SAAS,KACP,sBAAsB,MAAM,+BAA+B,UAAU,GACvE;GACA;EACF;EACA,MAAM,UAAU,aAAa,gBAAgB,SAAS;EAEtD,IAAI,iBAAiB,oBAAoB;GACvC,iBAAiB,SAAS,QAAQ,eAAe,UAAU,KAAK;GAChE,UAAU,IAAI,WAAW,OAAO;GAChC;EACF;EAEA,MAAM,SAAS,eAAe,OAAO;EACrC,IAAI,CAAC,OAAO,OAAO;GACjB,SAAS,KAAK,sBAAsB,MAAM,0BAA0B;GACpE;EACF;EACA,MAAM,OAAO,QAAQ,WAAW;EAChC,IAAI,OAAO,SAAS,UAAU;GAC5B,SAAS,KACP,sBAAsB,MAAM,kCAC9B;GACA;EACF;EACA,MAAM,SAAS,aAAa,QAAQ,WAAW,MAAM,OAAO,KAAK;EACjE,IAAI,CAAC,OAAO,IAAI;GACd,SAAS,KACP,sBAAsB,MAAM,mCAC9B;GACA;EACF;EACA,QAAQ,YAAY,OAAO;EAC3B,UAAU,IAAI,WAAW,OAAO;CAClC,QAAQ;EACN,SAAS,KAAK,sBAAsB,MAAM,eAAe;CAC3D;CAGF,OAAO;EAAE,OAAO;EAAW;CAAS;AACtC"}
|
|
1
|
+
{"version":3,"file":"reducer.js","names":[],"sources":["../../src/a2ui/reducer.ts"],"sourcesContent":["import {\n A2UI_SURFACE_ID,\n type A2uiOperationResult,\n type A2uiState,\n type A2uiSurfaceState,\n} from \"./types\";\n\nconst OPERATION_KEYS = new Set([\n \"createSurface\",\n \"updateComponents\",\n \"updateDataModel\",\n \"deleteSurface\",\n]);\n// This defensive ceiling is well above the renderer's displayed-item limit.\nconst MAX_AUTO_VIVIFY_ARRAY_INDEX = 10_000;\nconst INVALID_POINTER = Symbol(\"invalidPointer\");\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\nconst isVersion = (value: unknown): value is \"v0.9\" | \"v1.0\" =>\n value === \"v0.9\" || value === \"v1.0\";\n\nconst surfaceIdOf = (payload: Record<string, unknown>): string | undefined => {\n const surfaceId = payload[\"surfaceId\"];\n return typeof surfaceId === \"string\" && surfaceId.length > 0\n ? surfaceId\n : undefined;\n};\n\nconst withSurfaceId = (\n surface: A2uiSurfaceState,\n surfaceId: string,\n): A2uiSurfaceState => {\n Object.defineProperty(surface, A2UI_SURFACE_ID, {\n value: surfaceId,\n enumerable: false,\n });\n return surface;\n};\n\nconst getSurfaceId = (surface: A2uiSurfaceState): string | undefined =>\n (surface as A2uiSurfaceState & { [A2UI_SURFACE_ID]?: string })[\n A2UI_SURFACE_ID\n ];\n\nconst cloneSurface = (\n surface: A2uiSurfaceState,\n surfaceId: string,\n): A2uiSurfaceState =>\n withSurfaceId(\n {\n components: new Map(surface.components),\n dataModel: surface.dataModel,\n },\n getSurfaceId(surface) ?? surfaceId,\n );\n\nconst upsertComponents = (\n surface: A2uiSurfaceState,\n components: unknown,\n warnings: string[],\n operationIndex: number,\n): void => {\n if (!Array.isArray(components)) {\n warnings.push(\n `Operation at index ${operationIndex} has malformed components.`,\n );\n return;\n }\n\n for (\n let componentIndex = 0;\n componentIndex < components.length;\n componentIndex++\n ) {\n const component = components[componentIndex];\n if (\n !isRecord(component) ||\n typeof component[\"id\"] !== \"string\" ||\n component[\"id\"].length === 0 ||\n typeof component[\"component\"] !== \"string\" ||\n component[\"component\"].length === 0\n ) {\n warnings.push(\n `Component at index ${componentIndex} in operation ${operationIndex} is malformed.`,\n );\n continue;\n }\n surface.components.set(component[\"id\"], { ...component });\n }\n};\n\nconst decodePointer = (path: string): string[] | undefined => {\n if (path === \"\" || path === \"/\") return [];\n if (!path.startsWith(\"/\")) return undefined;\n return path\n .slice(1)\n .split(\"/\")\n .map((segment) => segment.replaceAll(\"~1\", \"/\").replaceAll(\"~0\", \"~\"));\n};\n\nconst isArrayIndex = (segment: string): boolean =>\n segment === \"0\" || /^[1-9]\\d*$/.test(segment);\n\nconst setAtPointer = (\n model: unknown,\n path: string,\n value: unknown,\n nullDeletes: boolean,\n): { readonly ok: boolean; readonly value: unknown } => {\n const segments = decodePointer(path);\n if (!segments) return { ok: false, value: model };\n if (segments.length === 0) return { ok: true, value };\n\n const remove = (current: unknown, index: number): unknown => {\n const segment = segments[index]!;\n const isLast = index === segments.length - 1;\n\n if (Array.isArray(current)) {\n if (segment !== \"-\" && !isArrayIndex(segment)) return current;\n const targetIndex = segment === \"-\" ? current.length : Number(segment);\n if (isLast) {\n if (\n segment === \"-\" ||\n !Object.prototype.hasOwnProperty.call(current, targetIndex)\n ) {\n return current;\n }\n const clone = current.slice();\n // Preserve indices referenced by other JSON Pointers.\n delete clone[targetIndex];\n return clone;\n }\n const child = current[targetIndex];\n if (!Array.isArray(child) && !isRecord(child)) return current;\n const next = remove(child, index + 1);\n if (next === child) return current;\n const clone = current.slice();\n clone[targetIndex] = next;\n return clone;\n }\n\n if (!isRecord(current)) return current;\n if (!Object.prototype.hasOwnProperty.call(current, segment)) return current;\n if (isLast) {\n const clone = { ...current };\n delete clone[segment];\n return clone;\n }\n const child = current[segment];\n if (!Array.isArray(child) && !isRecord(child)) return current;\n const next = remove(child, index + 1);\n if (next === child) return current;\n return { ...current, [segment]: next };\n };\n\n if (nullDeletes && value === null) {\n return { ok: true, value: remove(model, 0) };\n }\n\n const update = (current: unknown, index: number): unknown => {\n const segment = segments[index]!;\n const isLast = index === segments.length - 1;\n\n if (Array.isArray(current)) {\n if (segment !== \"-\" && !isArrayIndex(segment)) return current;\n const targetIndex = segment === \"-\" ? current.length : Number(segment);\n if (\n segment !== \"-\" &&\n targetIndex >= current.length &&\n targetIndex > MAX_AUTO_VIVIFY_ARRAY_INDEX\n ) {\n return INVALID_POINTER;\n }\n const next = isLast ? value : update(current[targetIndex], index + 1);\n if (next === INVALID_POINTER) return INVALID_POINTER;\n const clone = current.slice();\n clone[targetIndex] = next;\n return clone;\n }\n\n const record: Record<string, unknown> = isRecord(current) ? current : {};\n const child = Object.hasOwn(record, segment) ? record[segment] : undefined;\n const next = isLast\n ? value\n : update(\n child ??\n (isArrayIndex(segments[index + 1] ?? \"\") ||\n segments[index + 1] === \"-\"\n ? []\n : {}),\n index + 1,\n );\n if (next === INVALID_POINTER) return INVALID_POINTER;\n return { ...record, [segment]: next };\n };\n\n const result = update(model, 0);\n return result === INVALID_POINTER\n ? { ok: false, value: model }\n : { ok: true, value: result };\n};\n\nconst dataModelValue = (\n payload: Record<string, unknown>,\n): { readonly found: boolean; readonly value: unknown } => {\n for (const key of [\"contents\", \"value\", \"data\"] as const) {\n if (payload[key] !== undefined) {\n return { found: true, value: payload[key] };\n }\n }\n return { found: false, value: undefined };\n};\n\nexport function applyA2uiOperations(\n state: A2uiState,\n operations: unknown,\n): A2uiOperationResult {\n const nextState = new Map(state);\n const warnings: string[] = [];\n\n if (!Array.isArray(operations)) {\n return {\n state: nextState,\n warnings: [\"A2UI operations must be an array.\"],\n };\n }\n\n for (let index = 0; index < operations.length; index++) {\n try {\n const entry = operations[index];\n if (!isRecord(entry)) {\n warnings.push(`Operation at index ${index} is malformed.`);\n continue;\n }\n\n const version = entry[\"version\"];\n if (!isVersion(version)) {\n warnings.push(\n `Operation at index ${index} has an unsupported version.`,\n );\n continue;\n }\n\n const operationKeys = Object.keys(entry).filter(\n (key) => key !== \"version\",\n );\n if (operationKeys.length !== 1) {\n warnings.push(\n `Operation at index ${index} must contain exactly one operation key.`,\n );\n continue;\n }\n\n const operationKey = operationKeys[0]!;\n if (!OPERATION_KEYS.has(operationKey)) {\n warnings.push(\n `Unknown A2UI operation \"${operationKey}\" at index ${index}.`,\n );\n continue;\n }\n\n const payload = entry[operationKey];\n if (!isRecord(payload)) {\n warnings.push(`Operation at index ${index} has a malformed payload.`);\n continue;\n }\n\n const surfaceId = surfaceIdOf(payload);\n if (!surfaceId) {\n warnings.push(`Operation at index ${index} has no valid surfaceId.`);\n continue;\n }\n\n if (operationKey === \"createSurface\") {\n const surface = withSurfaceId(\n {\n components: new Map(),\n dataModel:\n version === \"v1.0\" && payload[\"dataModel\"] !== undefined\n ? payload[\"dataModel\"]\n : undefined,\n },\n surfaceId,\n );\n if (version === \"v1.0\" && payload[\"components\"] !== undefined) {\n upsertComponents(surface, payload[\"components\"], warnings, index);\n }\n nextState.set(surfaceId, surface);\n continue;\n }\n\n if (operationKey === \"deleteSurface\") {\n nextState.delete(surfaceId);\n continue;\n }\n\n const currentSurface = nextState.get(surfaceId);\n if (!currentSurface) {\n warnings.push(\n `Operation at index ${index} references missing surface \"${surfaceId}\".`,\n );\n continue;\n }\n const surface = cloneSurface(currentSurface, surfaceId);\n\n if (operationKey === \"updateComponents\") {\n upsertComponents(surface, payload[\"components\"], warnings, index);\n nextState.set(surfaceId, surface);\n continue;\n }\n\n const update = dataModelValue(payload);\n if (!update.found) {\n warnings.push(`Operation at index ${index} has no data model value.`);\n continue;\n }\n const path = payload[\"path\"] ?? \"/\";\n if (typeof path !== \"string\") {\n warnings.push(\n `Operation at index ${index} has a malformed data model path.`,\n );\n continue;\n }\n const result = setAtPointer(\n surface.dataModel,\n path,\n update.value,\n version === \"v1.0\",\n );\n if (!result.ok) {\n warnings.push(\n `Operation at index ${index} has an invalid JSON Pointer path.`,\n );\n continue;\n }\n surface.dataModel = result.value;\n nextState.set(surfaceId, surface);\n } catch {\n warnings.push(`Operation at index ${index} is malformed.`);\n }\n }\n\n return { state: nextState, warnings };\n}\n"],"mappings":"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"}
|
package/dist/a2ui/types.d.ts
CHANGED
|
@@ -1,73 +1,72 @@
|
|
|
1
1
|
//#region src/a2ui/types.d.ts
|
|
2
|
-
declare const A2UI_SURFACE_ID: unique symbol;
|
|
3
|
-
type A2uiVersion = "v0.9" | "v1.0";
|
|
4
|
-
interface A2uiTemplateChildren {
|
|
2
|
+
export declare const A2UI_SURFACE_ID: unique symbol;
|
|
3
|
+
export type A2uiVersion = "v0.9" | "v1.0";
|
|
4
|
+
export interface A2uiTemplateChildren {
|
|
5
5
|
readonly template: {
|
|
6
6
|
readonly componentId: string;
|
|
7
7
|
readonly path: string;
|
|
8
8
|
};
|
|
9
9
|
}
|
|
10
|
-
interface ComponentNode extends Record<string, unknown> {
|
|
10
|
+
export interface ComponentNode extends Record<string, unknown> {
|
|
11
11
|
readonly id: string;
|
|
12
12
|
readonly component: string;
|
|
13
13
|
readonly children?: readonly string[] | A2uiTemplateChildren;
|
|
14
14
|
}
|
|
15
|
-
interface A2uiCreateSurfaceV09Payload {
|
|
15
|
+
export interface A2uiCreateSurfaceV09Payload {
|
|
16
16
|
readonly surfaceId: string;
|
|
17
17
|
readonly catalogId?: string;
|
|
18
18
|
readonly theme?: unknown;
|
|
19
19
|
readonly attachDataModel?: unknown;
|
|
20
20
|
}
|
|
21
|
-
interface A2uiCreateSurfaceV10Payload {
|
|
21
|
+
export interface A2uiCreateSurfaceV10Payload {
|
|
22
22
|
readonly surfaceId: string;
|
|
23
23
|
readonly surfaceProperties?: unknown;
|
|
24
24
|
readonly sendDataModel?: unknown;
|
|
25
25
|
readonly components?: readonly ComponentNode[];
|
|
26
26
|
readonly dataModel?: unknown;
|
|
27
27
|
}
|
|
28
|
-
interface A2uiUpdateComponentsPayload {
|
|
28
|
+
export interface A2uiUpdateComponentsPayload {
|
|
29
29
|
readonly surfaceId: string;
|
|
30
30
|
readonly components: readonly ComponentNode[];
|
|
31
31
|
}
|
|
32
|
-
interface A2uiUpdateDataModelPayload {
|
|
32
|
+
export interface A2uiUpdateDataModelPayload {
|
|
33
33
|
readonly surfaceId: string;
|
|
34
34
|
readonly path?: string;
|
|
35
35
|
readonly contents?: unknown;
|
|
36
36
|
readonly value?: unknown;
|
|
37
37
|
readonly data?: unknown;
|
|
38
38
|
}
|
|
39
|
-
interface A2uiDeleteSurfacePayload {
|
|
39
|
+
export interface A2uiDeleteSurfacePayload {
|
|
40
40
|
readonly surfaceId: string;
|
|
41
41
|
}
|
|
42
|
-
type A2uiCreateSurfaceOperation = {
|
|
42
|
+
export type A2uiCreateSurfaceOperation = {
|
|
43
43
|
readonly version: "v0.9";
|
|
44
44
|
readonly createSurface: A2uiCreateSurfaceV09Payload;
|
|
45
45
|
} | {
|
|
46
46
|
readonly version: "v1.0";
|
|
47
47
|
readonly createSurface: A2uiCreateSurfaceV10Payload;
|
|
48
48
|
};
|
|
49
|
-
interface A2uiUpdateComponentsOperation {
|
|
49
|
+
export interface A2uiUpdateComponentsOperation {
|
|
50
50
|
readonly version: A2uiVersion;
|
|
51
51
|
readonly updateComponents: A2uiUpdateComponentsPayload;
|
|
52
52
|
}
|
|
53
|
-
interface A2uiUpdateDataModelOperation {
|
|
53
|
+
export interface A2uiUpdateDataModelOperation {
|
|
54
54
|
readonly version: A2uiVersion;
|
|
55
55
|
readonly updateDataModel: A2uiUpdateDataModelPayload;
|
|
56
56
|
}
|
|
57
|
-
interface A2uiDeleteSurfaceOperation {
|
|
57
|
+
export interface A2uiDeleteSurfaceOperation {
|
|
58
58
|
readonly version: A2uiVersion;
|
|
59
59
|
readonly deleteSurface: A2uiDeleteSurfacePayload;
|
|
60
60
|
}
|
|
61
|
-
type A2uiOperation = A2uiCreateSurfaceOperation | A2uiUpdateComponentsOperation | A2uiUpdateDataModelOperation | A2uiDeleteSurfaceOperation;
|
|
62
|
-
type A2uiSurfaceState = {
|
|
61
|
+
export type A2uiOperation = A2uiCreateSurfaceOperation | A2uiUpdateComponentsOperation | A2uiUpdateDataModelOperation | A2uiDeleteSurfaceOperation;
|
|
62
|
+
export type A2uiSurfaceState = {
|
|
63
63
|
components: Map<string, Record<string, unknown>>;
|
|
64
64
|
dataModel: unknown;
|
|
65
65
|
};
|
|
66
|
-
type A2uiState = ReadonlyMap<string, A2uiSurfaceState>;
|
|
67
|
-
interface A2uiOperationResult {
|
|
66
|
+
export type A2uiState = ReadonlyMap<string, A2uiSurfaceState>;
|
|
67
|
+
export interface A2uiOperationResult {
|
|
68
68
|
readonly state: A2uiState;
|
|
69
69
|
readonly warnings: string[];
|
|
70
70
|
}
|
|
71
71
|
//#endregion
|
|
72
|
-
export { A2UI_SURFACE_ID, A2uiCreateSurfaceOperation, A2uiCreateSurfaceV09Payload, A2uiCreateSurfaceV10Payload, A2uiDeleteSurfaceOperation, A2uiDeleteSurfacePayload, A2uiOperation, A2uiOperationResult, A2uiState, A2uiSurfaceState, A2uiTemplateChildren, A2uiUpdateComponentsOperation, A2uiUpdateComponentsPayload, A2uiUpdateDataModelOperation, A2uiUpdateDataModelPayload, A2uiVersion, ComponentNode };
|
|
73
72
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/a2ui/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","names":[],"sources":["../../src/a2ui/types.ts"],"mappings":";
|
|
1
|
+
{"version":3,"file":"types.d.ts","names":[],"sources":["../../src/a2ui/types.ts"],"mappings":";qBAAa;YAED;iBAEK;WACN;aACE;aACA;;;iBAII,sBAAsB;WAC5B;WACA;WACA,+BAA+B;;iBAGzB;WACN;WACA;WACA;WACA;;iBAGM;WACN;WACA;WACA;WACA,sBAAsB;WACtB;;iBAGM;WACN;WACA,qBAAqB;;iBAGf;WACN;WACA;WACA;WACA;WACA;;iBAGM;WACN;;YAGC;WAEG;WACA,eAAe;;WAGf;WACA,eAAe;;iBAGb;WACN,SAAS;WACT,kBAAkB;;iBAGZ;WACN,SAAS;WACT,iBAAiB;;iBAGX;WACN,SAAS;WACT,eAAe;;YAGd,gBACR,6BACA,gCACA,+BACA;YAEQ;EACV,YAAY,YAAY;EACxB;;YAGU,YAAY,oBAAoB;iBAE3B;WACN,OAAO;WACP"}
|
package/dist/actionRegistry.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Action } from "./ir.js";
|
|
2
2
|
//#region src/actionRegistry.d.ts
|
|
3
3
|
/** Context handed to an {@link ActionHandler} when an `$action` fires. */
|
|
4
|
-
type ActionDispatchContext = {
|
|
4
|
+
export type ActionDispatchContext = {
|
|
5
5
|
/**
|
|
6
6
|
* The action payload. For fire-and-forget actions this is the `$action` as the model emitted it. For an interactive component the user's runtime input is merged in under the reserved `$input` key: a single value for a standalone control's dispatch, or an object keyed by each field's `name` for a `Form` or a `Card` with `asForm` set. A model-supplied `value` field is never clobbered.
|
|
7
7
|
*/
|
|
@@ -14,19 +14,18 @@ type ActionDispatchContext = {
|
|
|
14
14
|
* value is left as `unknown` and documented per-action). The return value is
|
|
15
15
|
* handed back to `dispatch`'s caller as `unknown`.
|
|
16
16
|
*/
|
|
17
|
-
type ActionHandler = (ctx: ActionDispatchContext) => unknown | Promise<unknown>;
|
|
17
|
+
export type ActionHandler = (ctx: ActionDispatchContext) => unknown | Promise<unknown>;
|
|
18
18
|
/**
|
|
19
19
|
* The host-provided map from `$action.type` to {@link ActionHandler}. This is the single dispatch target for rendered generative UI: every interactive component fires its `$action` here through the injected `$dispatch` (a submit Button defers to its ancestor form's dispatch instead). The payload's `$input` takes one of two shapes: a single value for a standalone control's dispatch (`Select`, `Input`, `DatePicker`, `Checkbox`, `RadioGroup`), or an object keyed by field `name` for a `Form` or a `Card` with `asForm` set. Construct it with {@link createActionRegistry} and pass it to `JSONGenerativeUI`.
|
|
20
20
|
*/
|
|
21
|
-
type ActionRegistry = {
|
|
21
|
+
export type ActionRegistry = {
|
|
22
22
|
dispatch(action: Action): unknown;
|
|
23
23
|
has(type: string): boolean;
|
|
24
24
|
};
|
|
25
|
-
declare function createActionRegistry(handlers: Readonly<Record<string, ActionHandler>>): ActionRegistry;
|
|
25
|
+
export declare function createActionRegistry(handlers: Readonly<Record<string, ActionHandler>>): ActionRegistry;
|
|
26
26
|
/** A no-op registry used when no handlers are provided. Dispatch resolves to
|
|
27
27
|
* `undefined` and logs a warning in dev for unknown types, so a model-emitted
|
|
28
28
|
* action with no handler degrades to "does nothing" rather than throwing. */
|
|
29
|
-
declare const emptyActionRegistry: ActionRegistry;
|
|
29
|
+
export declare const emptyActionRegistry: ActionRegistry;
|
|
30
30
|
//#endregion
|
|
31
|
-
export { ActionDispatchContext, ActionHandler, ActionRegistry, createActionRegistry, emptyActionRegistry };
|
|
32
31
|
//# sourceMappingURL=actionRegistry.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"actionRegistry.d.ts","names":[],"sources":["../src/actionRegistry.ts"],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"actionRegistry.d.ts","names":[],"sources":["../src/actionRegistry.ts"],"mappings":";;;YAGY;;;;WAID,SAAS;;;;;;;;;YAUR,iBACV,KAAK,oCACQ;;;;YAKH;EACV,SAAS,QAAQ;EACjB,IAAI;;wBAGU,qBACd,UAAU,SAAS,eAAe,kBACjC;;;;qBA0CU,qBAAqB"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { JSONSchema7 } from "./node_modules/.pnpm/@types_json-schema@7.0.15/node_modules/@types/json-schema/index.js";
|
|
2
1
|
import { GenerativeUILibrary } from "./types.js";
|
|
2
|
+
import { JSONSchema7 } from "json-schema";
|
|
3
3
|
//#region src/buildPresentParameters.d.ts
|
|
4
4
|
/**
|
|
5
5
|
* Builds the JSON schema for the `present` tool from a {@link GenerativeUILibrary}.
|
|
@@ -18,7 +18,6 @@ import { GenerativeUILibrary } from "./types.js";
|
|
|
18
18
|
* renderer validates nothing here — an unknown `$type` or stray prop is handled
|
|
19
19
|
* at render time — so a looser schema only costs the model a hint, not safety.
|
|
20
20
|
*/
|
|
21
|
-
declare function buildPresentParameters(library: GenerativeUILibrary): JSONSchema7;
|
|
21
|
+
export declare function buildPresentParameters(library: GenerativeUILibrary): JSONSchema7;
|
|
22
22
|
//#endregion
|
|
23
|
-
export { buildPresentParameters };
|
|
24
23
|
//# sourceMappingURL=buildPresentParameters.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"buildPresentParameters.d.ts","names":[],"sources":["../src/buildPresentParameters.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"buildPresentParameters.d.ts","names":[],"sources":["../src/buildPresentParameters.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;wBAsBgB,uBACd,SAAS,sBACR"}
|