@assistant-ui/react-generative-ui 0.0.20 → 0.0.22
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 +1 -1
- package/dist/JSONGenerativeUI.client.d.ts.map +1 -1
- package/dist/JSONGenerativeUI.client.js +30 -13
- package/dist/JSONGenerativeUI.client.js.map +1 -1
- package/dist/RadioGroupScope.d.ts +6 -0
- package/dist/RadioGroupScope.d.ts.map +1 -0
- package/dist/RadioGroupScope.js +25 -0
- package/dist/RadioGroupScope.js.map +1 -0
- package/dist/a2ui/BindingContext.d.ts +11 -0
- package/dist/a2ui/BindingContext.d.ts.map +1 -0
- package/dist/a2ui/BindingContext.js +12 -0
- package/dist/a2ui/BindingContext.js.map +1 -0
- package/dist/a2ui/PresentRenderer.d.ts +11 -0
- package/dist/a2ui/PresentRenderer.d.ts.map +1 -0
- package/dist/a2ui/PresentRenderer.js +39 -0
- package/dist/a2ui/PresentRenderer.js.map +1 -0
- package/dist/a2ui/convert.d.ts +6 -0
- package/dist/a2ui/convert.d.ts.map +1 -1
- package/dist/a2ui/convert.js +369 -87
- package/dist/a2ui/convert.js.map +1 -1
- package/dist/a2ui/dataModel.d.ts +9 -0
- package/dist/a2ui/dataModel.d.ts.map +1 -0
- package/dist/a2ui/dataModel.js +44 -0
- package/dist/a2ui/dataModel.js.map +1 -0
- package/dist/a2ui/reducer.d.ts +5 -0
- package/dist/a2ui/reducer.d.ts.map +1 -1
- package/dist/a2ui/reducer.js +3 -3
- package/dist/a2ui/reducer.js.map +1 -1
- package/dist/a2ui/types.d.ts +8 -2
- package/dist/a2ui/types.d.ts.map +1 -1
- package/dist/a2ui/types.js.map +1 -1
- package/dist/a2ui/valueFunctions.d.ts +16 -0
- package/dist/a2ui/valueFunctions.d.ts.map +1 -0
- package/dist/a2ui/valueFunctions.js +332 -0
- package/dist/a2ui/valueFunctions.js.map +1 -0
- package/dist/actionRegistry.d.ts +1 -1
- package/dist/actionRegistry.js.map +1 -1
- package/dist/answeredValues.d.ts +16 -0
- package/dist/answeredValues.d.ts.map +1 -0
- package/dist/answeredValues.js +37 -0
- package/dist/answeredValues.js.map +1 -0
- package/dist/constants.d.ts +2 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +3 -1
- package/dist/constants.js.map +1 -1
- package/dist/fieldReferences.d.ts +9 -0
- package/dist/fieldReferences.d.ts.map +1 -0
- package/dist/fieldReferences.js +53 -0
- package/dist/fieldReferences.js.map +1 -0
- package/dist/generativeUIToJSX.js +3 -3
- package/dist/generativeUIToJSX.js.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.server.js +2 -2
- package/dist/index.shared.js +2 -2
- package/dist/ir.d.ts +1 -1
- package/dist/ir.js.map +1 -1
- package/dist/renderGenerativeUI.d.ts.map +1 -1
- package/dist/renderGenerativeUI.js +12 -1
- package/dist/renderGenerativeUI.js.map +1 -1
- package/dist/slack/constants.d.ts +2 -0
- package/dist/slack/constants.d.ts.map +1 -1
- package/dist/slack/constants.js +3 -1
- package/dist/slack/constants.js.map +1 -1
- package/dist/slack/decodeBlockAction.d.ts +3 -1
- package/dist/slack/decodeBlockAction.d.ts.map +1 -1
- package/dist/slack/decodeBlockAction.js +58 -7
- package/dist/slack/decodeBlockAction.js.map +1 -1
- package/dist/slack/fromSlackBlocks.d.ts.map +1 -1
- package/dist/slack/fromSlackBlocks.js +20 -3
- package/dist/slack/fromSlackBlocks.js.map +1 -1
- package/dist/slack/toSlackBlocks.d.ts.map +1 -1
- package/dist/slack/toSlackBlocks.js +187 -19
- package/dist/slack/toSlackBlocks.js.map +1 -1
- package/dist/slack/types.d.ts +4 -0
- package/dist/slack/types.d.ts.map +1 -1
- package/dist/teams/constants.d.ts +1 -1
- package/dist/teams/constants.d.ts.map +1 -1
- package/dist/teams/constants.js +1 -1
- package/dist/teams/constants.js.map +1 -1
- package/dist/teams/decodeSubmitData.d.ts +4 -0
- package/dist/teams/decodeSubmitData.d.ts.map +1 -1
- package/dist/teams/decodeSubmitData.js +6 -1
- package/dist/teams/decodeSubmitData.js.map +1 -1
- package/dist/teams/toAdaptiveCard.d.ts +5 -4
- package/dist/teams/toAdaptiveCard.d.ts.map +1 -1
- package/dist/teams/toAdaptiveCard.js +56 -17
- package/dist/teams/toAdaptiveCard.js.map +1 -1
- package/dist/teams/types.d.ts +4 -1
- package/dist/teams/types.d.ts.map +1 -1
- package/dist/vocabulary/alert.d.ts +9 -2
- package/dist/vocabulary/alert.d.ts.map +1 -1
- package/dist/vocabulary/alert.js +116 -19
- package/dist/vocabulary/alert.js.map +1 -1
- package/dist/vocabulary/collectFormValues.d.ts +2 -1
- package/dist/vocabulary/collectFormValues.d.ts.map +1 -1
- package/dist/vocabulary/collectFormValues.js +10 -3
- package/dist/vocabulary/collectFormValues.js.map +1 -1
- package/dist/vocabulary/data.d.ts +22 -5
- package/dist/vocabulary/data.d.ts.map +1 -1
- package/dist/vocabulary/data.js +278 -83
- package/dist/vocabulary/data.js.map +1 -1
- package/dist/vocabulary/dispatch.d.ts +3 -2
- package/dist/vocabulary/dispatch.d.ts.map +1 -1
- package/dist/vocabulary/dispatch.js +33 -4
- package/dist/vocabulary/dispatch.js.map +1 -1
- package/dist/vocabulary/fact.d.ts +8 -1
- package/dist/vocabulary/fact.d.ts.map +1 -1
- package/dist/vocabulary/fact.js +37 -11
- package/dist/vocabulary/fact.js.map +1 -1
- package/dist/vocabulary/form.d.ts.map +1 -1
- package/dist/vocabulary/form.js +3 -3
- package/dist/vocabulary/form.js.map +1 -1
- package/dist/vocabulary/formatValue.d.ts +7 -0
- package/dist/vocabulary/formatValue.d.ts.map +1 -0
- package/dist/vocabulary/formatValue.js +76 -0
- package/dist/vocabulary/formatValue.js.map +1 -0
- package/dist/vocabulary/icon.d.ts +1 -1
- package/dist/vocabulary/interactive.d.ts +137 -8
- package/dist/vocabulary/interactive.d.ts.map +1 -1
- package/dist/vocabulary/interactive.js +404 -103
- package/dist/vocabulary/interactive.js.map +1 -1
- package/dist/vocabulary/layout.d.ts.map +1 -1
- package/dist/vocabulary/layout.js +4 -4
- package/dist/vocabulary/layout.js.map +1 -1
- package/dist/vocabulary/list.js +2 -2
- package/dist/vocabulary/list.js.map +1 -1
- package/dist/vocabulary/text.d.ts +1 -1
- package/package.json +6 -3
- package/src/JSONGenerativeUI.client.tsx +84 -40
- package/src/JSONGenerativeUI.test.tsx +964 -68
- package/src/RadioGroupScope.server.test.tsx +24 -0
- package/src/RadioGroupScope.tsx +34 -0
- package/src/a2ui/BindingContext.ts +26 -0
- package/src/a2ui/PresentRenderer.tsx +83 -0
- package/src/a2ui/convert.test.ts +1982 -145
- package/src/a2ui/convert.ts +677 -137
- package/src/a2ui/dataModel.ts +69 -0
- package/src/a2ui/reducer.test.ts +35 -0
- package/src/a2ui/reducer.ts +5 -4
- package/src/a2ui/types.ts +9 -2
- package/src/a2ui/valueFunctions.test.ts +271 -0
- package/src/a2ui/valueFunctions.ts +523 -0
- package/src/actionRegistry.ts +1 -1
- package/src/answeredValues.test.ts +33 -0
- package/src/answeredValues.tsx +70 -0
- package/src/constants.ts +4 -0
- package/src/fieldReferences.test.ts +66 -0
- package/src/fieldReferences.ts +83 -0
- package/src/generativeUIToJSX.test.ts +18 -0
- package/src/generativeUIToJSX.ts +4 -6
- package/src/index.server.test.ts +106 -0
- package/src/ir.ts +1 -1
- package/src/renderGenerativeUI.test.tsx +14 -5
- package/src/renderGenerativeUI.tsx +30 -1
- package/src/slack/a2uiSlack.test.ts +198 -0
- package/src/slack/constants.ts +3 -0
- package/src/slack/decodeBlockAction.test.ts +98 -0
- package/src/slack/decodeBlockAction.ts +110 -17
- package/src/slack/fromSlackBlocks.test.ts +222 -3
- package/src/slack/fromSlackBlocks.ts +53 -2
- package/src/slack/toSlackBlocks.test.ts +682 -3
- package/src/slack/toSlackBlocks.ts +374 -23
- package/src/slack/types.ts +4 -0
- package/src/teams/constants.ts +1 -1
- package/src/teams/decodeSubmitData.test.ts +33 -0
- package/src/teams/decodeSubmitData.ts +9 -1
- package/src/teams/toAdaptiveCard.test.ts +219 -0
- package/src/teams/toAdaptiveCard.ts +93 -19
- package/src/teams/types.ts +4 -1
- package/src/vocabulary/alert.test.tsx +288 -7
- package/src/vocabulary/alert.tsx +168 -26
- package/src/vocabulary/collectFormValues.test.ts +28 -1
- package/src/vocabulary/collectFormValues.ts +25 -5
- package/src/vocabulary/data.test.tsx +248 -6
- package/src/vocabulary/data.tsx +398 -100
- package/src/vocabulary/dispatch.ts +63 -2
- package/src/vocabulary/fact.test.tsx +67 -0
- package/src/vocabulary/fact.tsx +40 -9
- package/src/vocabulary/form.tsx +7 -2
- package/src/vocabulary/formatValue.test.ts +72 -0
- package/src/vocabulary/formatValue.ts +127 -0
- package/src/vocabulary/index.test.ts +2 -0
- package/src/vocabulary/interactive.dispatch.test.tsx +167 -79
- package/src/vocabulary/interactive.dom.test.tsx +1699 -0
- package/src/vocabulary/interactive.test.tsx +60 -4
- package/src/vocabulary/interactive.tsx +770 -151
- package/src/vocabulary/layout.test.tsx +6 -4
- package/src/vocabulary/layout.tsx +13 -2
- package/src/vocabulary/list.tsx +2 -2
package/dist/a2ui/convert.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"convert.js","names":[],"sources":["../../src/a2ui/convert.ts"],"sourcesContent":["import { ICON_NAMES, 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 \"Icon\",\n \"Row\",\n \"Column\",\n \"List\",\n \"Card\",\n \"Divider\",\n \"Button\",\n \"TextField\",\n \"CheckBox\",\n \"ChoicePicker\",\n \"DateTimeInput\",\n]);\n\nconst ICON_NAME_SET: ReadonlySet<string> = new Set(ICON_NAMES);\nconst ICON_SIZE_SET: ReadonlySet<string> = new Set([\"sm\", \"md\", \"lg\"]);\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 readonly keepUnknownComponents: 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 choiceOptions = (value: unknown): { label: string; value: string }[] => {\n if (!Array.isArray(value)) return [];\n const options: { label: string; value: string }[] = [];\n for (const option of value) {\n if (\n isRecord(option) &&\n typeof option[\"label\"] === \"string\" &&\n typeof option[\"value\"] === \"string\"\n ) {\n options.push({ label: option[\"label\"], value: option[\"value\"] });\n }\n }\n return options;\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\", \"description\"]);\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 === \"Icon\") {\n const name = stringProp(props, [\"name\"]);\n if (!name || !ICON_NAME_SET.has(name)) return undefined;\n const size = props[\"size\"];\n return {\n $type: \"Icon\",\n name,\n ...(typeof size === \"string\" && ICON_SIZE_SET.has(size) ? { size } : {}),\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 === \"List\") {\n const direction = props[\"direction\"];\n const align = props[\"align\"];\n if (direction === \"horizontal\") {\n return {\n $type: \"Row\",\n ...(typeof align === \"string\" ? { align } : {}),\n };\n }\n return { $type: \"ListView\" };\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 if (component === \"ChoicePicker\") {\n const options = choiceOptions(props[\"options\"]);\n const value = props[\"value\"];\n const defaultValue =\n typeof value === \"string\"\n ? value\n : Array.isArray(value) && typeof value[0] === \"string\"\n ? value[0]\n : undefined;\n const radioStyle =\n props[\"variant\"] === \"radio\" ||\n props[\"variant\"] === \"single\" ||\n props[\"variant\"] === \"singleSelection\" ||\n props[\"displayStyle\"] === \"radio\" ||\n (props[\"variant\"] === \"mutuallyExclusive\" &&\n props[\"displayStyle\"] !== \"chips\");\n if (radioStyle) {\n return {\n $type: \"RadioGroup\",\n options,\n ...(label !== undefined ? { label } : {}),\n ...(name !== undefined ? { name } : {}),\n ...(defaultValue !== undefined ? { defaultValue } : {}),\n };\n }\n const placeholder = stringProp(props, [\"placeholder\"]);\n return {\n $type: \"Select\",\n options,\n ...(placeholder !== undefined ? { placeholder } : {}),\n ...(label !== undefined ? { label } : {}),\n ...(name !== undefined ? { name } : {}),\n };\n }\n\n if (component === \"DateTimeInput\") {\n const value = stringProp(props, [\"value\"]);\n const min = stringProp(props, [\"min\"]);\n const max = stringProp(props, [\"max\"]);\n return {\n $type: \"DatePicker\",\n ...(value !== undefined ? { value } : {}),\n ...(min !== undefined ? { min } : {}),\n ...(max !== undefined ? { max } : {}),\n ...(label !== undefined ? { label } : {}),\n ...(name !== undefined ? { name } : {}),\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 retained?: UIElement,\n mappedContainer?: UIElement,\n): UIElement | null => {\n if (!reserveNode(context)) return null;\n const horizontalList =\n node[\"component\"] === \"List\" &&\n materialize(node[\"direction\"], dataSource) === \"horizontal\";\n const container = mappedContainer ??\n retained ?? {\n $type: horizontalList ? \"Row\" : \"ListView\",\n };\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 { ...container, 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 (!retained && !horizontalList && !reserveNode(context)) break;\n const child = convertComponent(\n templateChildren.template.componentId,\n list[index],\n context,\n depth + 1,\n visited,\n );\n if (retained || horizontalList) {\n if (child) children.push(child);\n } else {\n children.push({\n $type: \"ListViewItem\",\n ...(child ? { children: child } : {}),\n });\n }\n }\n return { ...container, 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 if (typeof component !== \"string\") {\n context.warnings.push(\n `Unknown A2UI component \"${String(component ?? \"\")}\" was skipped.`,\n );\n return null;\n }\n const templateChildren = node[\"children\"];\n const hasTemplate = isTemplateChildren(templateChildren);\n if (\n !SUPPORTED_COMPONENTS.has(component) &&\n !context.keepUnknownComponents &&\n !hasTemplate\n ) {\n context.warnings.push(\n `Unknown A2UI component \"${component}\" was skipped.`,\n );\n return null;\n }\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 && SUPPORTED_COMPONENTS.has(component)) {\n context.warnings.push(\n `A2UI component \"${component}\" could not be mapped and was skipped.`,\n );\n return null;\n }\n const retained =\n !mapped && context.keepUnknownComponents\n ? {\n $type: component,\n ...Object.fromEntries(\n Object.entries(props).filter(([key]) => !key.startsWith(\"$\")),\n ),\n }\n : undefined;\n if (hasTemplate) {\n return convertTemplate(\n node,\n templateChildren,\n dataSource,\n context,\n depth,\n visited,\n retained,\n component === \"List\" ? mapped : undefined,\n );\n }\n if (!reserveNode(context)) return null;\n const converted = mapped ?? retained;\n if (!converted) return null;\n const children = childrenOf(node, dataSource, context, depth, visited);\n const listChildren =\n component === \"List\" && mapped?.$type === \"ListView\"\n ? children.map((child) => ({ $type: \"ListViewItem\", children: child }))\n : children;\n return {\n ...converted,\n ...(listChildren.length > 0 ? { children: listChildren } : {}),\n };\n } finally {\n visited.delete(componentId);\n }\n}\n\nexport function convertSurfaceToUISpec(\n surface: A2uiSurfaceState,\n options: { readonly keepUnknownComponents?: boolean } = {},\n): {\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 keepUnknownComponents: options.keepUnknownComponents === true,\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 { ICON_NAMES, type UIElement } from \"../ir\";\nimport { A2UI_SURFACE_ID, type A2uiSurfaceState } from \"./types\";\nimport {\n evaluateA2uiValueFunction,\n type ExpressionPart,\n} from \"./valueFunctions\";\nimport { MAX_AUTO_VIVIFY_ARRAY_INDEX } from \"./reducer\";\nimport type { A2uiBinding } from \"./BindingContext\";\nimport { decodePointer, resolvePointer } from \"./dataModel\";\n\nconst DEPTH_CAP = 32;\nconst TEMPLATE_ITEM_CAP = 100;\nconst NODE_BUDGET = 5000;\nconst EVALUATION_BUDGET = 20_000;\n\nconst SUPPORTED_COMPONENTS = new Set([\n \"Text\",\n \"Image\",\n \"Icon\",\n \"Row\",\n \"Column\",\n \"List\",\n \"Card\",\n \"Divider\",\n \"Button\",\n \"TextField\",\n \"CheckBox\",\n \"ChoicePicker\",\n \"DateTimeInput\",\n \"Slider\",\n]);\n\nconst CHILD_LIST_COMPONENTS: ReadonlySet<string> = new Set([\n \"Row\",\n \"Column\",\n \"List\",\n]);\n\nconst ICON_NAME_SET: ReadonlySet<string> = new Set(ICON_NAMES);\nconst ICON_SIZE_SET: ReadonlySet<string> = new Set([\"sm\", \"md\", \"lg\"]);\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 FUNCTION_CALL_KEYS: ReadonlySet<string> = new Set([\n \"call\",\n \"args\",\n \"returnType\",\n \"catalogId\",\n]);\n\nconst isFunctionCall = (\n value: unknown,\n): value is {\n readonly call: string;\n readonly args?: Record<string, unknown>;\n} =>\n isPlainObject(value) &&\n typeof value[\"call\"] === \"string\" &&\n (value[\"args\"] === undefined || isPlainObject(value[\"args\"])) &&\n Object.keys(value).every((key) => FUNCTION_CALL_KEYS.has(key));\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\ntype ChildTemplate = { readonly componentId: string; readonly path: string };\n\nconst childTemplateOf = (children: unknown): ChildTemplate | undefined => {\n const template =\n isPlainObject(children) &&\n Object.keys(children).length === 1 &&\n isPlainObject(children[\"template\"])\n ? children[\"template\"]\n : children;\n return isPlainObject(template) &&\n Object.keys(template).length === 2 &&\n typeof template[\"componentId\"] === \"string\" &&\n typeof template[\"path\"] === \"string\"\n ? { componentId: template[\"componentId\"], path: template[\"path\"] }\n : undefined;\n};\n\nconst bindingPath = (value: unknown): string | undefined =>\n isBinding(value) ? value.path : undefined;\n\ntype Scope = { readonly data: unknown; readonly path: string };\n\nconst pointerIn = (scope: Scope, path: string): string =>\n (path.startsWith(\"/\") ? \"\" : scope.path) +\n decodePointer(path)\n .map((segment) => `/${segment.replaceAll(\"~\", \"~0\").replaceAll(\"/\", \"~1\")}`)\n .join(\"\");\n\nconst setIn = (\n value: unknown,\n segments: readonly string[],\n leaf: unknown,\n): unknown => {\n const [head, ...rest] = segments;\n if (head === undefined) return leaf;\n if (\n /^(0|[1-9]\\d*)$/.test(head) &&\n (Array.isArray(value) || value === undefined || value === null)\n ) {\n const list = Array.isArray(value) ? value : [];\n const index = Number(head);\n if (index >= list.length && index > MAX_AUTO_VIVIFY_ARRAY_INDEX) {\n return value;\n }\n const copy = [...list];\n copy[index] = setIn(copy[index], rest, leaf);\n return copy;\n }\n const copy: Record<string, unknown> = isRecord(value) ? { ...value } : {};\n setOwnProperty(\n copy,\n head,\n setIn(Object.hasOwn(copy, head) ? copy[head] : undefined, rest, leaf),\n );\n return copy;\n};\n\nconst withFieldReferences = (\n value: unknown,\n pointer: string,\n fields: ReadonlyMap<string, unknown>,\n): unknown => {\n if (fields.has(pointer)) return fields.get(pointer);\n let result = value;\n for (const [name, field] of fields) {\n if (name.startsWith(`${pointer}/`)) {\n result = setIn(result, decodePointer(name.slice(pointer.length)), field);\n }\n }\n return result;\n};\n\nconst materializeEntries = (\n value: Record<string, unknown>,\n source: unknown,\n context: ConversionContext,\n evaluate: boolean,\n depth: number,\n positional = false,\n): Record<string, unknown> => {\n const result: Record<string, unknown> = {};\n for (const [key, entry] of Object.entries(value)) {\n // An action's functionCall runs when the button fires, so only its arguments resolve here.\n const resolved =\n key === \"functionCall\" && isFunctionCall(entry)\n ? {\n ...entry,\n ...(entry.args !== undefined\n ? {\n args: materializeEntries(\n entry.args,\n source,\n context,\n evaluate,\n depth,\n true,\n ),\n }\n : {}),\n }\n : materialize(entry, source, context, evaluate, depth, positional);\n if (resolved !== undefined) {\n setOwnProperty(result, key, resolved);\n }\n }\n return result;\n};\n\nfunction materialize(\n value: unknown,\n source: unknown,\n context: ConversionContext,\n evaluate = true,\n depth = 0,\n positional = false,\n): unknown {\n if (isBinding(value)) {\n const pointer = pointerIn(\n { data: source, path: context.scopePath },\n value.path,\n );\n const resolved = resolvePointer(context.surface.dataModel, pointer);\n context.dependencies?.set(pointer, resolved);\n return resolved;\n }\n if (Array.isArray(value)) {\n const entries = value.map((entry) =>\n materialize(entry, source, context, evaluate, depth, positional),\n );\n return positional\n ? entries\n : entries.filter((entry) => entry !== undefined);\n }\n if (!isPlainObject(value)) return value;\n if (!evaluate || !isFunctionCall(value)) {\n return materializeEntries(\n value,\n source,\n context,\n evaluate,\n depth,\n positional,\n );\n }\n if (!spendEvaluation(context)) return undefined;\n if (depth >= DEPTH_CAP) {\n if (!context.functionDepthWarned) {\n context.warnings.push(\n `A2UI function nesting cap of ${DEPTH_CAP} was reached.`,\n );\n context.functionDepthWarned = true;\n }\n return undefined;\n }\n return evaluateA2uiValueFunction(\n value.call,\n materializeEntries(\n value.args ?? {},\n source,\n context,\n true,\n depth + 1,\n true,\n ),\n {\n resolve: (part) =>\n spendEvaluation(context)\n ? materialize(part, source, context, true, depth + 1)\n : undefined,\n warn: (message) => context.warnings.push(message),\n templates: context.templates,\n },\n );\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 stepModel: unknown;\n readonly surfaceId: string;\n readonly warnings: string[];\n emittedNodes: number;\n depthWarned: boolean;\n budgetWarned: boolean;\n templateCapWarned: boolean;\n evaluations: number;\n evaluationBudgetWarned: boolean;\n functionDepthWarned: boolean;\n readonly templates: Map<string, ExpressionPart[] | null>;\n readonly inputFields: Map<string, unknown>;\n readonly textFields: Map<string, boolean>;\n readonly boundActionEntries: {\n readonly target: Record<string, unknown>;\n readonly key: string;\n readonly pointer: string;\n }[];\n readonly boundUserMessages: {\n readonly action: Record<string, unknown>;\n readonly pointer: string;\n }[];\n readonly keepUnknownComponents: boolean;\n readonly bindings: Map<string, A2uiBinding> | undefined;\n readonly cache: Map<string, CachedComponent> | undefined;\n dependencies: Map<string, unknown> | undefined;\n scopePath: string;\n};\n\ntype CachedComponent = {\n readonly props: Record<string, unknown>;\n readonly mapped: UIElement | undefined;\n readonly dependencies: ReadonlyMap<string, unknown>;\n readonly evaluations: number;\n children?: readonly UIElement[];\n result?: UIElement;\n};\n\nconst BOUND_KEYS = [\"text\", \"value\", \"binding\"] as const;\n\nconst INPUT_COMPONENTS: ReadonlySet<string> = new Set([\n \"TextField\",\n \"CheckBox\",\n \"ChoicePicker\",\n \"DateTimeInput\",\n \"Slider\",\n]);\n\nconst DATE_PATTERN = /^\\d{4}-\\d{2}-\\d{2}$/;\n\nconst finiteNumber = (value: unknown): number | undefined =>\n typeof value === \"number\" && Number.isFinite(value) ? value : undefined;\n\nconst decimalPlaces = (value: number): number => {\n const [mantissa = \"\", exponent = \"0\"] = String(value).split(\"e\");\n return Math.max(0, (mantissa.split(\".\")[1]?.length ?? 0) - Number(exponent));\n};\n\n// A spec slider without `steps` is continuous, so its step leaves at least a hundred divisions and keeps every bound value on the grid.\nconst sliderStep = (\n min: number,\n max: number,\n value: number | undefined,\n steps: unknown,\n): number | undefined => {\n if (max <= min) return undefined;\n if (typeof steps === \"number\" && Number.isInteger(steps) && steps >= 1) {\n return (max - min) / steps;\n }\n const precision = Math.max(\n decimalPlaces(min),\n value === undefined ? 0 : decimalPlaces(value),\n );\n return Math.min(\n 10 ** Math.floor(Math.log10((max - min) / 100)),\n 10 ** -precision,\n );\n};\n\nconst recordBindings = (\n node: Record<string, unknown>,\n props: Record<string, unknown>,\n mapped: UIElement,\n scope: Scope,\n context: ConversionContext,\n) => {\n const component = node[\"component\"];\n const name = mapped[\"name\"];\n const boundKey = BOUND_KEYS.find((key) => node[key] !== undefined);\n const value = boundKey === undefined ? undefined : props[boundKey];\n if (INPUT_COMPONENTS.has(String(component)) && typeof name === \"string\") {\n context.textFields.set(\n name,\n (!context.textFields.has(name) || context.bindings !== undefined) &&\n (component === \"TextField\" || component === \"DateTimeInput\"),\n );\n const field = (fallback: unknown) =>\n fallback === undefined ? { $field: name } : { $field: name, fallback };\n // A single-choice picker collects one string, while the spec binds it to a string list.\n const listValued =\n component === \"ChoicePicker\" &&\n mapped.$type !== \"CheckboxGroup\" &&\n typeof value !== \"string\";\n context.inputFields.set(\n name,\n listValued\n ? [field(Array.isArray(value) ? value[0] : undefined)]\n : field(value),\n );\n }\n const action = mapped.$action;\n const raw = node[\"action\"];\n if (!action || !isRecord(raw)) return;\n const functionCall = action.type === \"a2ui:functionCall\";\n const event = isRecord(raw[\"event\"]) ? raw[\"event\"] : raw;\n const userMessage = event[\"userMessage\"];\n if (!functionCall && isBinding(userMessage)) {\n context.boundUserMessages.push({\n action,\n pointer: pointerIn(scope, userMessage.path),\n });\n }\n const rawEntries = functionCall\n ? isRecord(raw[\"functionCall\"])\n ? raw[\"functionCall\"][\"args\"]\n : undefined\n : event[\"context\"];\n const target = functionCall ? action[\"args\"] : action[\"context\"];\n if (!isRecord(rawEntries) || !isRecord(target)) return;\n for (const [key, entry] of Object.entries(rawEntries)) {\n if (isBinding(entry)) {\n context.boundActionEntries.push({\n target,\n key,\n pointer: pointerIn(scope, entry.path),\n });\n }\n }\n};\n\nconst spendEvaluation = (context: ConversionContext): boolean => {\n if (context.evaluations < EVALUATION_BUDGET) {\n context.evaluations++;\n return true;\n }\n if (!context.evaluationBudgetWarned) {\n context.warnings.push(\n `A2UI function evaluation budget of ${EVALUATION_BUDGET} was reached.`,\n );\n context.evaluationBudgetWarned = true;\n }\n return false;\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 childReferences = (node: Record<string, unknown>): unknown[] => {\n const children = node[\"children\"];\n const references: unknown[] = Array.isArray(children) ? [...children] : [];\n if (node[\"child\"] !== undefined) references.push(node[\"child\"]);\n if (node[\"component\"] === \"Modal\") {\n references.push(node[\"trigger\"], node[\"content\"]);\n }\n if (node[\"component\"] === \"Tabs\" && Array.isArray(node[\"tabs\"])) {\n for (const tab of node[\"tabs\"]) {\n references.push(isRecord(tab) ? tab[\"child\"] : undefined);\n }\n }\n return references;\n};\n\nconst childrenOf = (\n node: Record<string, unknown>,\n scope: Scope,\n context: ConversionContext,\n depth: number,\n visited: Set<string>,\n): UIElement[] => {\n const result: UIElement[] = [];\n for (const childId of childReferences(node)) {\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(childId, scope, context, depth + 1, visited);\n if (child) result.push(child);\n }\n return result;\n};\n\nconst textLabel = (\n node: Record<string, unknown>,\n children: readonly UIElement[],\n context: ConversionContext,\n): string | undefined => {\n const references = childReferences(node);\n const [reference] = references;\n const [child] = children;\n if (\n references.length !== 1 ||\n children.length !== 1 ||\n typeof reference !== \"string\" ||\n !child ||\n context.surface.components.get(reference)?.[\"component\"] !== \"Text\"\n ) {\n return undefined;\n }\n const text = child.$type === \"Header\" ? child[\"text\"] : child[\"value\"];\n return typeof text === \"string\" ? text : undefined;\n};\n\nconst mappedAction = (\n node: Record<string, unknown>,\n props: Record<string, unknown>,\n context: ConversionContext,\n): UIElement[\"$action\"] | undefined => {\n const action = props[\"action\"];\n if (action === undefined) return undefined;\n const source = {\n surfaceId: context.surfaceId,\n sourceComponentId: typeof node[\"id\"] === \"string\" ? node[\"id\"] : \"\",\n };\n const event =\n isRecord(action) && isRecord(action[\"event\"]) ? action[\"event\"] : action;\n const actionName =\n typeof event === \"string\"\n ? event\n : isRecord(event) && typeof event[\"name\"] === \"string\"\n ? event[\"name\"]\n : undefined;\n if (actionName) {\n const actionContext = isRecord(event) ? event[\"context\"] : undefined;\n const userMessage = isRecord(event) ? event[\"userMessage\"] : undefined;\n return {\n type: \"a2ui:action\",\n name: actionName,\n ...source,\n ...(typeof userMessage === \"string\" ? { userMessage } : {}),\n ...(actionContext !== undefined ? { context: actionContext } : {}),\n };\n }\n const functionCall = isRecord(action) ? action[\"functionCall\"] : undefined;\n if (isRecord(functionCall) && typeof functionCall[\"call\"] === \"string\") {\n const args = functionCall[\"args\"];\n return {\n type: \"a2ui:functionCall\",\n call: functionCall[\"call\"],\n ...source,\n ...(isRecord(args) ? { args } : {}),\n };\n }\n context.warnings.push(\n `Component \"${String(node[\"id\"] ?? \"\")}\" has a malformed action.`,\n );\n return undefined;\n};\n\nconst choiceOptions = (value: unknown): { label: string; value: string }[] => {\n if (!Array.isArray(value)) return [];\n const options: { label: string; value: string }[] = [];\n for (const option of value) {\n if (\n isRecord(option) &&\n typeof option[\"label\"] === \"string\" &&\n typeof option[\"value\"] === \"string\"\n ) {\n options.push({ label: option[\"label\"], value: option[\"value\"] });\n }\n }\n return options;\n};\n\nconst mappedProps = (\n node: Record<string, unknown>,\n props: Record<string, unknown>,\n context: ConversionContext,\n scope: Scope,\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\", \"description\"]);\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 === \"Icon\") {\n const name = stringProp(props, [\"name\"]);\n if (!name || !ICON_NAME_SET.has(name)) return undefined;\n const size = props[\"size\"];\n return {\n $type: \"Icon\",\n name,\n ...(typeof size === \"string\" && ICON_SIZE_SET.has(size) ? { size } : {}),\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 === \"List\") {\n const direction = props[\"direction\"];\n const align = props[\"align\"];\n if (direction === \"horizontal\") {\n return {\n $type: \"Row\",\n ...(typeof align === \"string\" ? { align } : {}),\n };\n }\n return { $type: \"ListView\" };\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 variantStyle =\n props[\"variant\"] === \"primary\"\n ? \"primary\"\n : props[\"variant\"] === \"borderless\"\n ? \"ghost\"\n : undefined;\n const buttonStyle =\n typeof props[\"buttonStyle\"] === \"string\"\n ? props[\"buttonStyle\"]\n : variantStyle;\n const block = props[\"block\"];\n const submit = props[\"submit\"];\n const action = mappedAction(node, props, context);\n return {\n $type: \"Button\",\n ...(label !== undefined ? { label } : {}),\n ...(buttonStyle !== undefined ? { buttonStyle } : {}),\n ...(typeof block === \"boolean\" ? { block } : {}),\n ...(typeof submit === \"boolean\" ? { submit } : {}),\n ...(action ? { $action: action } : {}),\n };\n }\n\n const bound = bindingPath(firstDefined(node, BOUND_KEYS));\n const name = bound === undefined ? undefined : pointerIn(scope, bound);\n const label = stringProp(props, [\"label\"]);\n\n if (component === \"TextField\") {\n const placeholder = stringProp(props, [\"placeholder\"]);\n const inputType =\n props[\"variant\"] === \"obscured\"\n ? \"password\"\n : props[\"variant\"] === \"number\"\n ? \"number\"\n : undefined;\n const multiline =\n typeof props[\"multiline\"] === \"boolean\"\n ? props[\"multiline\"]\n : props[\"variant\"] === \"longText\" ||\n props[\"textFieldType\"] === \"longText\"\n ? true\n : undefined;\n const initial = firstDefined(props, [\"value\", \"text\"]);\n const defaultValue =\n typeof initial === \"string\"\n ? initial\n : typeof initial === \"number\" && Number.isFinite(initial)\n ? String(initial)\n : undefined;\n return {\n $type: \"Input\",\n ...(inputType !== undefined ? { inputType } : {}),\n ...(placeholder !== undefined ? { placeholder } : {}),\n ...(multiline !== undefined ? { multiline } : {}),\n ...(label !== undefined ? { label } : {}),\n ...(name !== undefined ? { name } : {}),\n ...(defaultValue !== undefined ? { defaultValue } : {}),\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 if (component === \"Slider\") {\n const min = finiteNumber(props[\"min\"]) ?? 0;\n const max = finiteNumber(props[\"max\"]);\n if (max === undefined || max < min) return undefined;\n const value = finiteNumber(props[\"value\"]);\n const step = sliderStep(\n min,\n max,\n name === undefined\n ? value\n : finiteNumber(resolvePointer(context.stepModel, name)),\n props[\"steps\"],\n );\n return {\n $type: \"Slider\",\n min,\n max,\n ...(step !== undefined ? { step } : {}),\n ...(value !== undefined ? { defaultValue: value } : {}),\n ...(label !== undefined ? { label } : {}),\n ...(name !== undefined ? { name } : {}),\n };\n }\n\n if (component === \"ChoicePicker\") {\n const options = choiceOptions(props[\"options\"]);\n const value = props[\"value\"];\n const selected =\n typeof value === \"string\"\n ? [value]\n : Array.isArray(value)\n ? value.filter((entry): entry is string => typeof entry === \"string\")\n : [];\n if (props[\"variant\"] === \"multipleSelection\") {\n return {\n $type: \"CheckboxGroup\",\n options,\n ...(label !== undefined ? { label } : {}),\n ...(name !== undefined ? { name } : {}),\n ...(selected.length > 0 ? { defaultValue: selected } : {}),\n };\n }\n const [defaultValue] = selected;\n return {\n $type: \"RadioGroup\",\n options,\n ...(label !== undefined ? { label } : {}),\n ...(name !== undefined ? { name } : {}),\n ...(defaultValue !== undefined ? { defaultValue } : {}),\n };\n }\n\n if (component === \"DateTimeInput\") {\n const value = stringProp(props, [\"value\"]);\n const shapeValue =\n name === undefined ? value : resolvePointer(context.stepModel, name);\n if (\n props[\"enableTime\"] === true ||\n (typeof shapeValue === \"string\" &&\n shapeValue !== \"\" &&\n !DATE_PATTERN.test(shapeValue))\n ) {\n return {\n $type: \"Input\",\n ...(value !== undefined ? { defaultValue: value } : {}),\n ...(label !== undefined ? { label } : {}),\n ...(name !== undefined ? { name } : {}),\n };\n }\n const min = stringProp(props, [\"min\"]);\n const max = stringProp(props, [\"max\"]);\n return {\n $type: \"DatePicker\",\n ...(value !== undefined ? { value } : {}),\n ...(min !== undefined ? { min } : {}),\n ...(max !== undefined ? { max } : {}),\n ...(label !== undefined ? { label } : {}),\n ...(name !== undefined ? { name } : {}),\n };\n }\n\n return undefined;\n};\n\nconst convertTemplate = (\n node: Record<string, unknown>,\n template: ChildTemplate,\n scope: Scope,\n context: ConversionContext,\n depth: number,\n visited: Set<string>,\n converted: UIElement | undefined,\n): UIElement | null => {\n if (!reserveNode(context)) return null;\n const container = converted ?? { $type: \"ListView\" };\n const itemized = container.$type === \"ListView\";\n const list = resolvePointer(\n context.surface.dataModel,\n pointerIn(scope, template.path),\n );\n const listPointer = pointerIn(scope, 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 { ...container, 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 (itemized && !reserveNode(context)) break;\n const child = convertComponent(\n template.componentId,\n { data: list[index], path: `${listPointer}/${index}` },\n context,\n depth + 1,\n visited,\n );\n if (itemized) {\n children.push({\n $type: \"ListViewItem\",\n ...(child ? { children: child } : {}),\n });\n } else if (child) {\n children.push(child);\n }\n }\n return { ...container, children };\n};\n\nfunction convertComponent(\n componentId: string,\n scope: Scope,\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 if (typeof component !== \"string\") {\n context.warnings.push(\n `Unknown A2UI component \"${String(component ?? \"\")}\" was skipped.`,\n );\n return null;\n }\n const template = childTemplateOf(node[\"children\"]);\n if (\n !SUPPORTED_COMPONENTS.has(component) &&\n !context.keepUnknownComponents &&\n !template\n ) {\n context.warnings.push(\n `Unknown A2UI component \"${component}\" was skipped.`,\n );\n return null;\n }\n const cacheKey = context.cache\n ? JSON.stringify([componentId, scope.path, depth])\n : \"\";\n let cached = context.cache?.get(cacheKey);\n if (\n cached &&\n (context.evaluations + cached.evaluations > EVALUATION_BUDGET ||\n [...cached.dependencies].some(\n ([path, value]) =>\n !Object.is(resolvePointer(context.surface.dataModel, path), value),\n ))\n )\n cached = undefined;\n let props: Record<string, unknown>;\n let mapped: UIElement | undefined;\n if (cached) {\n props = cached.props;\n mapped = cached.mapped;\n context.evaluations += cached.evaluations;\n } else {\n props = {};\n const dependencies = new Map<string, unknown>();\n const evaluations = context.evaluations;\n context.dependencies = dependencies;\n context.scopePath = scope.path;\n for (const [key, value] of Object.entries(node)) {\n if (\n key === \"id\" ||\n key === \"component\" ||\n key === \"children\" ||\n key === \"child\"\n )\n continue;\n const resolved = materialize(\n value,\n scope.data,\n context,\n key !== \"checks\",\n );\n if (resolved !== undefined) setOwnProperty(props, key, resolved);\n }\n context.dependencies = undefined;\n mapped = mappedProps(node, props, context, scope);\n if (context.cache && context.warnings.length === 0 && !mapped?.$action) {\n cached = {\n props,\n mapped,\n dependencies,\n evaluations: context.evaluations - evaluations,\n };\n context.cache.set(cacheKey, cached);\n }\n }\n if (\n mapped &&\n context.bindings &&\n typeof mapped[\"name\"] === \"string\" &&\n INPUT_COMPONENTS.has(component)\n ) {\n const field = mapped.$type === \"Checkbox\" ? \"checked\" : \"value\";\n const defaultField =\n mapped.$type === \"Checkbox\" ? \"defaultChecked\" : \"defaultValue\";\n const fallback =\n mapped.$type === \"Checkbox\"\n ? false\n : mapped.$type === \"CheckboxGroup\"\n ? []\n : mapped.$type === \"Slider\"\n ? mapped[\"min\"]\n : \"\";\n const { [defaultField]: initialValue, ...rest } = mapped;\n mapped = { ...rest, [field]: initialValue ?? mapped[field] ?? fallback };\n context.bindings.set(mapped[\"name\"] as string, {\n value: mapped[field],\n arrayValue:\n component === \"ChoicePicker\" &&\n mapped.$type !== \"CheckboxGroup\" &&\n typeof props[\"value\"] !== \"string\",\n });\n }\n\n if (!mapped && SUPPORTED_COMPONENTS.has(component)) {\n context.warnings.push(\n `A2UI component \"${component}\" could not be mapped and was skipped.`,\n );\n return null;\n }\n const retained =\n !mapped && context.keepUnknownComponents\n ? {\n $type: component,\n ...Object.fromEntries(\n Object.entries(props).filter(([key]) => !key.startsWith(\"$\")),\n ),\n }\n : undefined;\n if (template) {\n return convertTemplate(\n node,\n template,\n scope,\n context,\n depth,\n visited,\n CHILD_LIST_COMPONENTS.has(component) ? mapped : retained,\n );\n }\n if (!reserveNode(context)) return null;\n const converted = mapped ?? retained;\n if (!converted) return null;\n recordBindings(node, props, converted, scope, context);\n const children = childrenOf(node, scope, context, depth, visited);\n if (mapped?.$type === \"Button\" && mapped[\"label\"] === undefined) {\n const label = textLabel(node, children, context);\n if (label !== undefined) return { ...mapped, label };\n }\n const listChildren =\n component === \"List\" && mapped?.$type === \"ListView\"\n ? children.map((child) => ({ $type: \"ListViewItem\", children: child }))\n : children;\n if (\n cached?.result &&\n cached.children?.length === listChildren.length &&\n cached.children.every((child, index) => child === listChildren[index])\n )\n return cached.result;\n const result = {\n ...converted,\n ...(listChildren.length > 0 ? { children: listChildren } : {}),\n };\n if (cached) {\n cached.children = listChildren;\n cached.result = result;\n }\n return result;\n } finally {\n visited.delete(componentId);\n }\n}\n\nexport function convertSurfaceToUISpec(\n surface: A2uiSurfaceState,\n options: {\n readonly keepUnknownComponents?: boolean;\n } = {},\n): {\n spec: UIElement | null;\n warnings: string[];\n} {\n return convertSurface(surface, options.keepUnknownComponents === true);\n}\n\nexport const createLiveSurfaceConverter = (surface: A2uiSurfaceState) => {\n const cache = new Map<string, CachedComponent>();\n const templates = new Map<string, ExpressionPart[] | null>();\n return (dataModel: unknown) => {\n const bindings = new Map<string, A2uiBinding>();\n const converted = convertSurface(\n { ...surface, dataModel, [A2UI_SURFACE_ID]: sourceSurfaceId(surface) },\n false,\n bindings,\n cache,\n templates,\n surface.dataModel,\n );\n return { ...converted, bindings };\n };\n};\n\nfunction convertSurface(\n surface: A2uiSurfaceState & { [A2UI_SURFACE_ID]?: string },\n keepUnknownComponents: boolean,\n bindings?: Map<string, A2uiBinding>,\n cache?: Map<string, CachedComponent>,\n templates = new Map<string, ExpressionPart[] | null>(),\n stepModel: unknown = surface.dataModel,\n): { spec: UIElement | null; warnings: string[] } {\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 stepModel,\n surfaceId: sourceSurfaceId(surface),\n warnings,\n emittedNodes: 0,\n depthWarned: false,\n budgetWarned: false,\n templateCapWarned: false,\n evaluations: 0,\n evaluationBudgetWarned: false,\n functionDepthWarned: false,\n templates,\n inputFields: new Map(),\n textFields: new Map(),\n boundActionEntries: [],\n boundUserMessages: [],\n keepUnknownComponents,\n bindings,\n cache,\n dependencies: undefined,\n scopePath: \"\",\n };\n try {\n const spec = convertComponent(\n \"root\",\n { data: surface.dataModel, path: \"\" },\n context,\n 0,\n new Set(),\n );\n for (const { target, key, pointer } of context.boundActionEntries) {\n const value = withFieldReferences(\n target[key],\n pointer,\n context.inputFields,\n );\n if (value !== undefined) setOwnProperty(target, key, value);\n }\n for (const { action, pointer } of context.boundUserMessages) {\n if (!context.textFields.get(pointer)) continue;\n const fallback = action[\"userMessage\"];\n setOwnProperty(\n action,\n \"userMessage\",\n typeof fallback === \"string\"\n ? { $field: pointer, fallback }\n : { $field: pointer },\n );\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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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export declare const equalData: (left: unknown, right: unknown) => boolean;
|
|
2
|
+
export declare const decodePointer: (path: string) => string[];
|
|
3
|
+
export declare const resolvePointer: (source: unknown, path: string) => unknown;
|
|
4
|
+
export declare const reconcileDataModel: (previous: unknown, incoming: unknown, local: unknown, editedPaths: ReadonlySet<string>) => {
|
|
5
|
+
incoming: unknown;
|
|
6
|
+
value: unknown;
|
|
7
|
+
editedPaths: Set<string>;
|
|
8
|
+
};
|
|
9
|
+
//# sourceMappingURL=dataModel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dataModel.d.ts","sourceRoot":"","sources":["../../src/a2ui/dataModel.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,SAAS,GAAI,MAAM,OAAO,EAAE,OAAO,OAAO,KAAG,OAgBzD,CAAC;AAEF,eAAO,MAAM,aAAa,GAAI,MAAM,MAAM,KAAG,MAAM,EAKlD,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,QAAQ,OAAO,EAAE,MAAM,MAAM,KAAG,OAc9D,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAC7B,UAAU,OAAO,EACjB,UAAU,OAAO,EACjB,OAAO,OAAO,EACd,aAAa,WAAW,CAAC,MAAM,CAAC;;;;CAkBjC,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { setAtPointer } from "./reducer.js";
|
|
2
|
+
//#region src/a2ui/dataModel.ts
|
|
3
|
+
const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
4
|
+
const equalData = (left, right) => {
|
|
5
|
+
if (Object.is(left, right)) return true;
|
|
6
|
+
if (Array.isArray(left) && Array.isArray(right)) return left.length === right.length && left.every((value, index) => equalData(value, right[index]));
|
|
7
|
+
if (!isRecord(left) || !isRecord(right)) return false;
|
|
8
|
+
const keys = Object.keys(left);
|
|
9
|
+
return keys.length === Object.keys(right).length && keys.every((key) => Object.hasOwn(right, key) && equalData(left[key], right[key]));
|
|
10
|
+
};
|
|
11
|
+
const decodePointer = (path) => {
|
|
12
|
+
if (path === "" || path === "/") return [];
|
|
13
|
+
return (path.startsWith("/") ? path.slice(1) : path).split("/").map((segment) => segment.replaceAll("~1", "/").replaceAll("~0", "~"));
|
|
14
|
+
};
|
|
15
|
+
const resolvePointer = (source, path) => {
|
|
16
|
+
let current = source;
|
|
17
|
+
for (const segment of decodePointer(path)) {
|
|
18
|
+
if (Array.isArray(current)) {
|
|
19
|
+
if (!/^(0|[1-9]\d*)$/.test(segment)) return void 0;
|
|
20
|
+
current = current[Number(segment)];
|
|
21
|
+
continue;
|
|
22
|
+
}
|
|
23
|
+
if (!isRecord(current) || !Object.hasOwn(current, segment)) return;
|
|
24
|
+
current = current[segment];
|
|
25
|
+
}
|
|
26
|
+
return current;
|
|
27
|
+
};
|
|
28
|
+
const reconcileDataModel = (previous, incoming, local, editedPaths) => {
|
|
29
|
+
let value = incoming;
|
|
30
|
+
const retained = /* @__PURE__ */ new Set();
|
|
31
|
+
for (const path of editedPaths) if (equalData(resolvePointer(previous, path), resolvePointer(incoming, path))) {
|
|
32
|
+
value = setAtPointer(value, path, resolvePointer(local, path), false).value;
|
|
33
|
+
retained.add(path);
|
|
34
|
+
}
|
|
35
|
+
return {
|
|
36
|
+
incoming,
|
|
37
|
+
value,
|
|
38
|
+
editedPaths: retained
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
//#endregion
|
|
42
|
+
export { decodePointer, equalData, reconcileDataModel, resolvePointer };
|
|
43
|
+
|
|
44
|
+
//# sourceMappingURL=dataModel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dataModel.js","names":[],"sources":["../../src/a2ui/dataModel.ts"],"sourcesContent":["import { setAtPointer } from \"./reducer\";\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\nexport const equalData = (left: unknown, right: unknown): boolean => {\n if (Object.is(left, right)) return true;\n if (Array.isArray(left) && Array.isArray(right)) {\n return (\n left.length === right.length &&\n left.every((value, index) => equalData(value, right[index]))\n );\n }\n if (!isRecord(left) || !isRecord(right)) return false;\n const keys = Object.keys(left);\n return (\n keys.length === Object.keys(right).length &&\n keys.every(\n (key) => Object.hasOwn(right, key) && equalData(left[key], right[key]),\n )\n );\n};\n\nexport const decodePointer = (path: string): string[] => {\n if (path === \"\" || path === \"/\") return [];\n return (path.startsWith(\"/\") ? path.slice(1) : path)\n .split(\"/\")\n .map((segment) => segment.replaceAll(\"~1\", \"/\").replaceAll(\"~0\", \"~\"));\n};\n\nexport const resolvePointer = (source: unknown, path: string): unknown => {\n let current = source;\n for (const segment of decodePointer(path)) {\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\nexport const reconcileDataModel = (\n previous: unknown,\n incoming: unknown,\n local: unknown,\n editedPaths: ReadonlySet<string>,\n) => {\n let value = incoming;\n const retained = new Set<string>();\n for (const path of editedPaths) {\n if (\n equalData(resolvePointer(previous, path), resolvePointer(incoming, path))\n ) {\n value = setAtPointer(\n value,\n path,\n resolvePointer(local, path),\n false,\n ).value;\n retained.add(path);\n }\n }\n return { incoming, value, editedPaths: retained };\n};\n"],"mappings":";;AAEA,MAAM,YAAY,UAChB,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAErE,MAAa,aAAa,MAAe,UAA4B;CACnE,IAAI,OAAO,GAAG,MAAM,KAAK,GAAG,OAAO;CACnC,IAAI,MAAM,QAAQ,IAAI,KAAK,MAAM,QAAQ,KAAK,GAC5C,OACE,KAAK,WAAW,MAAM,UACtB,KAAK,OAAO,OAAO,UAAU,UAAU,OAAO,MAAM,MAAM,CAAC;CAG/D,IAAI,CAAC,SAAS,IAAI,KAAK,CAAC,SAAS,KAAK,GAAG,OAAO;CAChD,MAAM,OAAO,OAAO,KAAK,IAAI;CAC7B,OACE,KAAK,WAAW,OAAO,KAAK,KAAK,CAAC,CAAC,UACnC,KAAK,OACF,QAAQ,OAAO,OAAO,OAAO,GAAG,KAAK,UAAU,KAAK,MAAM,MAAM,IAAI,CACvE;AAEJ;AAEA,MAAa,iBAAiB,SAA2B;CACvD,IAAI,SAAS,MAAM,SAAS,KAAK,OAAO,CAAC;CACzC,QAAQ,KAAK,WAAW,GAAG,IAAI,KAAK,MAAM,CAAC,IAAI,KAAA,CAC5C,MAAM,GAAG,CAAC,CACV,KAAK,YAAY,QAAQ,WAAW,MAAM,GAAG,CAAC,CAAC,WAAW,MAAM,GAAG,CAAC;AACzE;AAEA,MAAa,kBAAkB,QAAiB,SAA0B;CACxE,IAAI,UAAU;CACd,KAAK,MAAM,WAAW,cAAc,IAAI,GAAG;EACzC,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,MAAa,sBACX,UACA,UACA,OACA,gBACG;CACH,IAAI,QAAQ;CACZ,MAAM,2BAAW,IAAI,IAAY;CACjC,KAAK,MAAM,QAAQ,aACjB,IACE,UAAU,eAAe,UAAU,IAAI,GAAG,eAAe,UAAU,IAAI,CAAC,GACxE;EACA,QAAQ,aACN,OACA,MACA,eAAe,OAAO,IAAI,GAC1B,KACF,CAAC,CAAC;EACF,SAAS,IAAI,IAAI;CACnB;CAEF,OAAO;EAAE;EAAU;EAAO,aAAa;CAAS;AAClD"}
|
package/dist/a2ui/reducer.d.ts
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
1
|
import { type A2uiOperationResult, type A2uiState } from "./types.js";
|
|
2
|
+
export declare const MAX_AUTO_VIVIFY_ARRAY_INDEX = 10000;
|
|
3
|
+
export declare const setAtPointer: (model: unknown, path: string, value: unknown, nullDeletes: boolean) => {
|
|
4
|
+
readonly ok: boolean;
|
|
5
|
+
readonly value: unknown;
|
|
6
|
+
};
|
|
2
7
|
export declare function applyA2uiOperations(state: A2uiState, operations: unknown): A2uiOperationResult;
|
|
3
8
|
//# sourceMappingURL=reducer.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reducer.d.ts","sourceRoot":"","sources":["../../src/a2ui/reducer.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,mBAAmB,EACxB,KAAK,SAAS,
|
|
1
|
+
{"version":3,"file":"reducer.d.ts","sourceRoot":"","sources":["../../src/a2ui/reducer.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,mBAAmB,EACxB,KAAK,SAAS,EAGf,mBAAgB;AASjB,eAAO,MAAM,2BAA2B,QAAS,CAAC;AAyGlD,eAAO,MAAM,YAAY,GACvB,OAAO,OAAO,EACd,MAAM,MAAM,EACZ,OAAO,OAAO,EACd,aAAa,OAAO,KACnB;IAAE,QAAQ,CAAC,EAAE,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;CA4FjD,CAAC;AAaF,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,SAAS,EAChB,UAAU,EAAE,OAAO,GAClB,mBAAmB,CAiIrB"}
|
package/dist/a2ui/reducer.js
CHANGED
|
@@ -9,7 +9,7 @@ const OPERATION_KEYS = /* @__PURE__ */ new Set([
|
|
|
9
9
|
const MAX_AUTO_VIVIFY_ARRAY_INDEX = 1e4;
|
|
10
10
|
const INVALID_POINTER = Symbol("invalidPointer");
|
|
11
11
|
const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
12
|
-
const isVersion = (value) => value === "v0.9" || value === "v1.0";
|
|
12
|
+
const isVersion = (value) => value === "v0.9" || value === "v0.9.1" || value === "v1.0";
|
|
13
13
|
const surfaceIdOf = (payload) => {
|
|
14
14
|
const surfaceId = payload["surfaceId"];
|
|
15
15
|
return typeof surfaceId === "string" && surfaceId.length > 0 ? surfaceId : void 0;
|
|
@@ -108,7 +108,7 @@ const setAtPointer = (model, path, value, nullDeletes) => {
|
|
|
108
108
|
if (Array.isArray(current)) {
|
|
109
109
|
if (segment !== "-" && !isArrayIndex(segment)) return current;
|
|
110
110
|
const targetIndex = segment === "-" ? current.length : Number(segment);
|
|
111
|
-
if (segment !== "-" && targetIndex >= current.length && targetIndex >
|
|
111
|
+
if (segment !== "-" && targetIndex >= current.length && targetIndex > 1e4) return INVALID_POINTER;
|
|
112
112
|
const next = isLast ? value : update(current[targetIndex], index + 1);
|
|
113
113
|
if (next === INVALID_POINTER) return INVALID_POINTER;
|
|
114
114
|
const clone = current.slice();
|
|
@@ -237,6 +237,6 @@ function applyA2uiOperations(state, operations) {
|
|
|
237
237
|
};
|
|
238
238
|
}
|
|
239
239
|
//#endregion
|
|
240
|
-
export { applyA2uiOperations };
|
|
240
|
+
export { MAX_AUTO_VIVIFY_ARRAY_INDEX, applyA2uiOperations, setAtPointer };
|
|
241
241
|
|
|
242
242
|
//# sourceMappingURL=reducer.js.map
|
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// 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 catalogIdOf = (payload: Record<string, unknown>): string | undefined => {\n if (typeof payload[\"catalogId\"] === \"string\") {\n return payload[\"catalogId\"];\n }\n const surfaceProperties = payload[\"surfaceProperties\"];\n return isRecord(surfaceProperties) &&\n typeof surfaceProperties[\"catalogId\"] === \"string\"\n ? surfaceProperties[\"catalogId\"]\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 ...(surface.catalogId !== undefined\n ? { catalogId: surface.catalogId }\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 catalogId = catalogIdOf(payload);\n const surface = withSurfaceId(\n {\n ...(catalogId !== undefined ? { catalogId } : {}),\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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"}
|
|
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 type A2uiVersion,\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.\nexport const 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 A2uiVersion =>\n value === \"v0.9\" || value === \"v0.9.1\" || 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 catalogIdOf = (payload: Record<string, unknown>): string | undefined => {\n if (typeof payload[\"catalogId\"] === \"string\") {\n return payload[\"catalogId\"];\n }\n const surfaceProperties = payload[\"surfaceProperties\"];\n return isRecord(surfaceProperties) &&\n typeof surfaceProperties[\"catalogId\"] === \"string\"\n ? surfaceProperties[\"catalogId\"]\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 ...(surface.catalogId !== undefined\n ? { catalogId: surface.catalogId }\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\nexport const 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 catalogId = catalogIdOf(payload);\n const surface = withSurfaceId(\n {\n ...(catalogId !== undefined ? { catalogId } : {}),\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,5 +1,5 @@
|
|
|
1
1
|
export declare const A2UI_SURFACE_ID: unique symbol;
|
|
2
|
-
export type A2uiVersion = "v0.9" | "v1.0";
|
|
2
|
+
export type A2uiVersion = "v0.9" | "v0.9.1" | "v1.0";
|
|
3
3
|
export interface A2uiTemplateChildren {
|
|
4
4
|
readonly template: {
|
|
5
5
|
readonly componentId: string;
|
|
@@ -9,7 +9,10 @@ export interface A2uiTemplateChildren {
|
|
|
9
9
|
export interface ComponentNode extends Record<string, unknown> {
|
|
10
10
|
readonly id: string;
|
|
11
11
|
readonly component: string;
|
|
12
|
-
readonly children?: readonly string[] |
|
|
12
|
+
readonly children?: readonly string[] | {
|
|
13
|
+
readonly componentId: string;
|
|
14
|
+
readonly path: string;
|
|
15
|
+
} | A2uiTemplateChildren;
|
|
13
16
|
}
|
|
14
17
|
export interface A2uiCreateSurfaceV09Payload {
|
|
15
18
|
readonly surfaceId: string;
|
|
@@ -42,6 +45,9 @@ export interface A2uiDeleteSurfacePayload {
|
|
|
42
45
|
export type A2uiCreateSurfaceOperation = {
|
|
43
46
|
readonly version: "v0.9";
|
|
44
47
|
readonly createSurface: A2uiCreateSurfaceV09Payload;
|
|
48
|
+
} | {
|
|
49
|
+
readonly version: "v0.9.1";
|
|
50
|
+
readonly createSurface: A2uiCreateSurfaceV09Payload;
|
|
45
51
|
} | {
|
|
46
52
|
readonly version: "v1.0";
|
|
47
53
|
readonly createSurface: A2uiCreateSurfaceV10Payload;
|
package/dist/a2ui/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/a2ui/types.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,eAAe,eAA0B,CAAC;AAEvD,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/a2ui/types.ts"],"names":[],"mappings":"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"}
|
package/dist/a2ui/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","names":[],"sources":["../../src/a2ui/types.ts"],"sourcesContent":["export const A2UI_SURFACE_ID = Symbol(\"a2uiSurfaceId\");\n\nexport type A2uiVersion = \"v0.9\" | \"v1.0\";\n\nexport interface A2uiTemplateChildren {\n readonly template: {\n readonly componentId: string;\n readonly path: string;\n };\n}\n\nexport interface ComponentNode extends Record<string, unknown> {\n readonly id: string;\n readonly component: string;\n readonly children
|
|
1
|
+
{"version":3,"file":"types.js","names":[],"sources":["../../src/a2ui/types.ts"],"sourcesContent":["export const A2UI_SURFACE_ID = Symbol(\"a2uiSurfaceId\");\n\nexport type A2uiVersion = \"v0.9\" | \"v0.9.1\" | \"v1.0\";\n\nexport interface A2uiTemplateChildren {\n readonly template: {\n readonly componentId: string;\n readonly path: string;\n };\n}\n\nexport interface ComponentNode extends Record<string, unknown> {\n readonly id: string;\n readonly component: string;\n readonly children?:\n | readonly string[]\n | { readonly componentId: string; readonly path: string }\n | A2uiTemplateChildren;\n}\n\nexport interface A2uiCreateSurfaceV09Payload {\n readonly surfaceId: string;\n readonly catalogId?: string;\n readonly theme?: unknown;\n readonly attachDataModel?: unknown;\n}\n\nexport interface A2uiCreateSurfaceV10Payload {\n readonly surfaceId: string;\n readonly catalogId?: string;\n readonly surfaceProperties?: unknown;\n readonly sendDataModel?: unknown;\n readonly components?: readonly ComponentNode[];\n readonly dataModel?: unknown;\n}\n\nexport interface A2uiUpdateComponentsPayload {\n readonly surfaceId: string;\n readonly components: readonly ComponentNode[];\n}\n\nexport interface A2uiUpdateDataModelPayload {\n readonly surfaceId: string;\n readonly path?: string;\n readonly contents?: unknown;\n readonly value?: unknown;\n readonly data?: unknown;\n}\n\nexport interface A2uiDeleteSurfacePayload {\n readonly surfaceId: string;\n}\n\nexport type A2uiCreateSurfaceOperation =\n | {\n readonly version: \"v0.9\";\n readonly createSurface: A2uiCreateSurfaceV09Payload;\n }\n | {\n readonly version: \"v0.9.1\";\n readonly createSurface: A2uiCreateSurfaceV09Payload;\n }\n | {\n readonly version: \"v1.0\";\n readonly createSurface: A2uiCreateSurfaceV10Payload;\n };\n\nexport interface A2uiUpdateComponentsOperation {\n readonly version: A2uiVersion;\n readonly updateComponents: A2uiUpdateComponentsPayload;\n}\n\nexport interface A2uiUpdateDataModelOperation {\n readonly version: A2uiVersion;\n readonly updateDataModel: A2uiUpdateDataModelPayload;\n}\n\nexport interface A2uiDeleteSurfaceOperation {\n readonly version: A2uiVersion;\n readonly deleteSurface: A2uiDeleteSurfacePayload;\n}\n\nexport type A2uiOperation =\n | A2uiCreateSurfaceOperation\n | A2uiUpdateComponentsOperation\n | A2uiUpdateDataModelOperation\n | A2uiDeleteSurfaceOperation;\n\nexport type A2uiSurfaceSnapshotOperation =\n | {\n readonly version: \"v0.9\";\n readonly createSurface: A2uiCreateSurfaceV09Payload;\n }\n | {\n readonly version: \"v0.9\";\n readonly updateComponents: A2uiUpdateComponentsPayload;\n }\n | {\n readonly version: \"v0.9\";\n readonly updateDataModel: A2uiUpdateDataModelPayload;\n };\n\nexport type A2uiSurfaceState = {\n catalogId?: string;\n components: Map<string, Record<string, unknown>>;\n dataModel: unknown;\n};\n\nexport type A2uiState = ReadonlyMap<string, A2uiSurfaceState>;\n\nexport interface A2uiOperationResult {\n readonly state: A2uiState;\n readonly warnings: string[];\n}\n"],"mappings":";AAAA,MAAa,kBAAkB,OAAO,eAAe"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export type ExpressionPart = string | number | boolean | null | {
|
|
2
|
+
readonly path: string;
|
|
3
|
+
} | {
|
|
4
|
+
readonly call: string;
|
|
5
|
+
readonly args: Record<string, ExpressionPart>;
|
|
6
|
+
};
|
|
7
|
+
export type ValueFunctionContext = {
|
|
8
|
+
readonly resolve: (value: ExpressionPart) => unknown;
|
|
9
|
+
readonly warn: (message: string) => void;
|
|
10
|
+
readonly templates: Map<string, ExpressionPart[] | null>;
|
|
11
|
+
};
|
|
12
|
+
export declare class ExpressionSyntaxError extends Error {
|
|
13
|
+
}
|
|
14
|
+
export declare const parseExpressionTemplate: (template: string) => ExpressionPart[];
|
|
15
|
+
export declare const evaluateA2uiValueFunction: (name: string, args: Record<string, unknown>, context: ValueFunctionContext) => unknown;
|
|
16
|
+
//# sourceMappingURL=valueFunctions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"valueFunctions.d.ts","sourceRoot":"","sources":["../../src/a2ui/valueFunctions.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,cAAc,GACtB,MAAM,GACN,MAAM,GACN,OAAO,GACP,IAAI,GACJ;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACzB;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAA;CAAE,CAAC;AAE7E,MAAM,MAAM,oBAAoB,GAAG;IACjC,QAAQ,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,OAAO,CAAC;IACrD,QAAQ,CAAC,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,QAAQ,CAAC,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,EAAE,GAAG,IAAI,CAAC,CAAC;CAC1D,CAAC;AAEF,qBAAa,qBAAsB,SAAQ,KAAK;CAAG;AA2KnD,eAAO,MAAM,uBAAuB,GAAI,UAAU,MAAM,KAAG,cAAc,EAkCxE,CAAC;AAiSF,eAAO,MAAM,yBAAyB,GACpC,MAAM,MAAM,EACZ,MAAM,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,SAAS,oBAAoB,KAC5B,OAMF,CAAC"}
|