@assistant-ui/react-generative-ui 0.0.24 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/dist/a2ui.d.ts +1 -4
- package/dist/a2ui.d.ts.map +1 -1
- package/dist/a2ui.js +1 -4
- package/dist/index.d.ts +1 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -10
- package/dist/index.server.d.ts +1 -2
- package/dist/index.server.d.ts.map +1 -1
- package/dist/index.server.js +1 -10
- package/dist/ir.d.ts +1 -111
- package/dist/ir.d.ts.map +1 -1
- package/dist/ir.js +1 -175
- package/dist/slack.d.ts +1 -4
- package/dist/slack.d.ts.map +1 -1
- package/dist/slack.js +1 -4
- package/dist/teams.d.ts +1 -4
- package/dist/teams.d.ts.map +1 -1
- package/dist/teams.js +1 -4
- package/package.json +4 -5
- package/src/a2ui.ts +1 -22
- package/src/index.server.ts +1 -2
- package/src/index.test.ts +75 -0
- package/src/index.ts +1 -2
- package/src/ir.ts +1 -279
- package/src/slack.ts +1 -39
- package/src/teams.ts +1 -35
- package/dist/JSONGenerativeUI.client.d.ts +0 -28
- package/dist/JSONGenerativeUI.client.d.ts.map +0 -1
- package/dist/JSONGenerativeUI.client.js +0 -101
- package/dist/JSONGenerativeUI.client.js.map +0 -1
- package/dist/JSONGenerativeUI.server.d.ts +0 -21
- package/dist/JSONGenerativeUI.server.d.ts.map +0 -1
- package/dist/JSONGenerativeUI.server.js +0 -32
- package/dist/JSONGenerativeUI.server.js.map +0 -1
- package/dist/JSONGenerativeUI.shared.d.ts +0 -63
- package/dist/JSONGenerativeUI.shared.d.ts.map +0 -1
- package/dist/JSONGenerativeUI.shared.js +0 -31
- package/dist/JSONGenerativeUI.shared.js.map +0 -1
- package/dist/RadioGroupScope.d.ts +0 -6
- package/dist/RadioGroupScope.d.ts.map +0 -1
- package/dist/RadioGroupScope.js +0 -25
- package/dist/RadioGroupScope.js.map +0 -1
- package/dist/a2ui/BindingContext.d.ts +0 -11
- package/dist/a2ui/BindingContext.d.ts.map +0 -1
- package/dist/a2ui/BindingContext.js +0 -12
- package/dist/a2ui/BindingContext.js.map +0 -1
- package/dist/a2ui/PresentRenderer.d.ts +0 -11
- package/dist/a2ui/PresentRenderer.d.ts.map +0 -1
- package/dist/a2ui/PresentRenderer.js +0 -39
- package/dist/a2ui/PresentRenderer.js.map +0 -1
- package/dist/a2ui/convert.d.ts +0 -15
- package/dist/a2ui/convert.d.ts.map +0 -1
- package/dist/a2ui/convert.js +0 -728
- package/dist/a2ui/convert.js.map +0 -1
- package/dist/a2ui/dataModel.d.ts +0 -9
- package/dist/a2ui/dataModel.d.ts.map +0 -1
- package/dist/a2ui/dataModel.js +0 -44
- package/dist/a2ui/dataModel.js.map +0 -1
- package/dist/a2ui/reducer.d.ts +0 -8
- package/dist/a2ui/reducer.d.ts.map +0 -1
- package/dist/a2ui/reducer.js +0 -242
- package/dist/a2ui/reducer.js.map +0 -1
- package/dist/a2ui/snapshot.d.ts +0 -3
- package/dist/a2ui/snapshot.d.ts.map +0 -1
- package/dist/a2ui/snapshot.js +0 -33
- package/dist/a2ui/snapshot.js.map +0 -1
- package/dist/a2ui/types.d.ts +0 -88
- package/dist/a2ui/types.d.ts.map +0 -1
- package/dist/a2ui/types.js +0 -6
- package/dist/a2ui/types.js.map +0 -1
- package/dist/a2ui/valueFunctions.d.ts +0 -16
- package/dist/a2ui/valueFunctions.d.ts.map +0 -1
- package/dist/a2ui/valueFunctions.js +0 -332
- package/dist/a2ui/valueFunctions.js.map +0 -1
- package/dist/actionRegistry.d.ts +0 -29
- package/dist/actionRegistry.d.ts.map +0 -1
- package/dist/actionRegistry.js +0 -41
- package/dist/actionRegistry.js.map +0 -1
- package/dist/answeredValues.d.ts +0 -16
- package/dist/answeredValues.d.ts.map +0 -1
- package/dist/answeredValues.js +0 -37
- package/dist/answeredValues.js.map +0 -1
- package/dist/buildPresentParameters.d.ts +0 -21
- package/dist/buildPresentParameters.d.ts.map +0 -1
- package/dist/buildPresentParameters.js +0 -95
- package/dist/buildPresentParameters.js.map +0 -1
- package/dist/constants.d.ts +0 -15
- package/dist/constants.d.ts.map +0 -1
- package/dist/constants.js +0 -19
- package/dist/constants.js.map +0 -1
- package/dist/convert/boundSpec.d.ts +0 -48
- package/dist/convert/boundSpec.d.ts.map +0 -1
- package/dist/convert/boundSpec.js +0 -108
- package/dist/convert/boundSpec.js.map +0 -1
- package/dist/convert/copyBounded.d.ts +0 -25
- package/dist/convert/copyBounded.d.ts.map +0 -1
- package/dist/convert/copyBounded.js +0 -38
- package/dist/convert/copyBounded.js.map +0 -1
- package/dist/convert/isElement.d.ts +0 -3
- package/dist/convert/isElement.d.ts.map +0 -1
- package/dist/convert/isElement.js +0 -6
- package/dist/convert/isElement.js.map +0 -1
- package/dist/convert/takeRun.d.ts +0 -6
- package/dist/convert/takeRun.d.ts.map +0 -1
- package/dist/convert/takeRun.js +0 -20
- package/dist/convert/takeRun.js.map +0 -1
- package/dist/defineGenerativeComponents.d.ts +0 -29
- package/dist/defineGenerativeComponents.d.ts.map +0 -1
- package/dist/defineGenerativeComponents.js +0 -34
- package/dist/defineGenerativeComponents.js.map +0 -1
- package/dist/fieldReferences.d.ts +0 -9
- package/dist/fieldReferences.d.ts.map +0 -1
- package/dist/fieldReferences.js +0 -53
- package/dist/fieldReferences.js.map +0 -1
- package/dist/generativeUIToJSX.d.ts +0 -18
- package/dist/generativeUIToJSX.d.ts.map +0 -1
- package/dist/generativeUIToJSX.js +0 -76
- package/dist/generativeUIToJSX.js.map +0 -1
- package/dist/index.shared.d.ts +0 -15
- package/dist/index.shared.d.ts.map +0 -1
- package/dist/index.shared.js +0 -9
- package/dist/ir.js.map +0 -1
- package/dist/renderGenerativeUI.d.ts +0 -14
- package/dist/renderGenerativeUI.d.ts.map +0 -1
- package/dist/renderGenerativeUI.js +0 -83
- package/dist/renderGenerativeUI.js.map +0 -1
- package/dist/scopeSchema.d.ts +0 -6
- package/dist/scopeSchema.d.ts.map +0 -1
- package/dist/scopeSchema.js +0 -56
- package/dist/scopeSchema.js.map +0 -1
- package/dist/slack/constants.d.ts +0 -93
- package/dist/slack/constants.d.ts.map +0 -1
- package/dist/slack/constants.js +0 -146
- package/dist/slack/constants.js.map +0 -1
- package/dist/slack/decodeBlockAction.d.ts +0 -10
- package/dist/slack/decodeBlockAction.d.ts.map +0 -1
- package/dist/slack/decodeBlockAction.js +0 -129
- package/dist/slack/decodeBlockAction.js.map +0 -1
- package/dist/slack/fromSlackBlocks.d.ts +0 -27
- package/dist/slack/fromSlackBlocks.d.ts.map +0 -1
- package/dist/slack/fromSlackBlocks.js +0 -483
- package/dist/slack/fromSlackBlocks.js.map +0 -1
- package/dist/slack/toSlackBlocks.d.ts +0 -4
- package/dist/slack/toSlackBlocks.d.ts.map +0 -1
- package/dist/slack/toSlackBlocks.js +0 -901
- package/dist/slack/toSlackBlocks.js.map +0 -1
- package/dist/slack/types.d.ts +0 -204
- package/dist/slack/types.d.ts.map +0 -1
- package/dist/slack/types.js +0 -0
- package/dist/teams/constants.d.ts +0 -34
- package/dist/teams/constants.d.ts.map +0 -1
- package/dist/teams/constants.js +0 -68
- package/dist/teams/constants.js.map +0 -1
- package/dist/teams/decodeSubmitData.d.ts +0 -26
- package/dist/teams/decodeSubmitData.d.ts.map +0 -1
- package/dist/teams/decodeSubmitData.js +0 -70
- package/dist/teams/decodeSubmitData.js.map +0 -1
- package/dist/teams/temporalId.d.ts +0 -5
- package/dist/teams/temporalId.d.ts.map +0 -1
- package/dist/teams/temporalId.js +0 -28
- package/dist/teams/temporalId.js.map +0 -1
- package/dist/teams/toAdaptiveCard.d.ts +0 -45
- package/dist/teams/toAdaptiveCard.d.ts.map +0 -1
- package/dist/teams/toAdaptiveCard.js +0 -642
- package/dist/teams/toAdaptiveCard.js.map +0 -1
- package/dist/teams/toTeamsAttachments.d.ts +0 -10
- package/dist/teams/toTeamsAttachments.d.ts.map +0 -1
- package/dist/teams/toTeamsAttachments.js +0 -99
- package/dist/teams/toTeamsAttachments.js.map +0 -1
- package/dist/teams/types.d.ts +0 -224
- package/dist/teams/types.d.ts.map +0 -1
- package/dist/teams/types.js +0 -0
- package/dist/temporal.d.ts +0 -33
- package/dist/temporal.d.ts.map +0 -1
- package/dist/temporal.js +0 -153
- package/dist/temporal.js.map +0 -1
- package/dist/types.d.ts +0 -99
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -0
- package/dist/vocabulary/alert.d.ts +0 -32
- package/dist/vocabulary/alert.d.ts.map +0 -1
- package/dist/vocabulary/alert.js +0 -160
- package/dist/vocabulary/alert.js.map +0 -1
- package/dist/vocabulary/collectFormValues.d.ts +0 -23
- package/dist/vocabulary/collectFormValues.d.ts.map +0 -1
- package/dist/vocabulary/collectFormValues.js +0 -44
- package/dist/vocabulary/collectFormValues.js.map +0 -1
- package/dist/vocabulary/data.d.ts +0 -66
- package/dist/vocabulary/data.d.ts.map +0 -1
- package/dist/vocabulary/data.js +0 -503
- package/dist/vocabulary/data.js.map +0 -1
- package/dist/vocabulary/dispatch.d.ts +0 -9
- package/dist/vocabulary/dispatch.d.ts.map +0 -1
- package/dist/vocabulary/dispatch.js +0 -50
- package/dist/vocabulary/dispatch.js.map +0 -1
- package/dist/vocabulary/fact.d.ts +0 -19
- package/dist/vocabulary/fact.d.ts.map +0 -1
- package/dist/vocabulary/fact.js +0 -51
- package/dist/vocabulary/fact.js.map +0 -1
- package/dist/vocabulary/form.d.ts +0 -11
- package/dist/vocabulary/form.d.ts.map +0 -1
- package/dist/vocabulary/form.js +0 -23
- package/dist/vocabulary/form.js.map +0 -1
- package/dist/vocabulary/formatValue.d.ts +0 -7
- package/dist/vocabulary/formatValue.d.ts.map +0 -1
- package/dist/vocabulary/formatValue.js +0 -76
- package/dist/vocabulary/formatValue.js.map +0 -1
- package/dist/vocabulary/icon.d.ts +0 -41
- package/dist/vocabulary/icon.d.ts.map +0 -1
- package/dist/vocabulary/icon.js +0 -272
- package/dist/vocabulary/icon.js.map +0 -1
- package/dist/vocabulary/index.d.ts +0 -12
- package/dist/vocabulary/index.d.ts.map +0 -1
- package/dist/vocabulary/index.js +0 -36
- package/dist/vocabulary/index.js.map +0 -1
- package/dist/vocabulary/interactive.d.ts +0 -230
- package/dist/vocabulary/interactive.d.ts.map +0 -1
- package/dist/vocabulary/interactive.js +0 -584
- package/dist/vocabulary/interactive.js.map +0 -1
- package/dist/vocabulary/layout.d.ts +0 -79
- package/dist/vocabulary/layout.d.ts.map +0 -1
- package/dist/vocabulary/layout.js +0 -139
- package/dist/vocabulary/layout.js.map +0 -1
- package/dist/vocabulary/list.d.ts +0 -14
- package/dist/vocabulary/list.d.ts.map +0 -1
- package/dist/vocabulary/list.js +0 -50
- package/dist/vocabulary/list.js.map +0 -1
- package/dist/vocabulary/media.d.ts +0 -25
- package/dist/vocabulary/media.d.ts.map +0 -1
- package/dist/vocabulary/media.js +0 -42
- package/dist/vocabulary/media.js.map +0 -1
- package/dist/vocabulary/text.d.ts +0 -57
- package/dist/vocabulary/text.d.ts.map +0 -1
- package/dist/vocabulary/text.js +0 -49
- package/dist/vocabulary/text.js.map +0 -1
- package/dist/vocabulary/toTextContent.d.ts +0 -2
- package/dist/vocabulary/toTextContent.d.ts.map +0 -1
- package/dist/vocabulary/toTextContent.js +0 -6
- package/dist/vocabulary/toTextContent.js.map +0 -1
- package/src/JSONGenerativeUI.client.tsx +0 -168
- package/src/JSONGenerativeUI.server.tsx +0 -39
- package/src/JSONGenerativeUI.shared.ts +0 -90
- package/src/JSONGenerativeUI.test.tsx +0 -1298
- package/src/RadioGroupScope.server.test.tsx +0 -24
- package/src/RadioGroupScope.tsx +0 -34
- package/src/a2ui/BindingContext.ts +0 -26
- package/src/a2ui/PresentRenderer.tsx +0 -83
- package/src/a2ui/convert.test.ts +0 -2923
- package/src/a2ui/convert.ts +0 -1207
- package/src/a2ui/dataModel.ts +0 -69
- package/src/a2ui/reducer.test.ts +0 -422
- package/src/a2ui/reducer.ts +0 -363
- package/src/a2ui/snapshot.test.ts +0 -52
- package/src/a2ui/snapshot.ts +0 -52
- package/src/a2ui/types.ts +0 -114
- package/src/a2ui/valueFunctions.test.ts +0 -271
- package/src/a2ui/valueFunctions.ts +0 -523
- package/src/actionRegistry.test.ts +0 -90
- package/src/actionRegistry.ts +0 -88
- package/src/answeredValues.test.ts +0 -33
- package/src/answeredValues.tsx +0 -70
- package/src/buildPresentParameters.test.ts +0 -246
- package/src/buildPresentParameters.ts +0 -130
- package/src/constants.ts +0 -17
- package/src/convert/boundSpec.test.ts +0 -192
- package/src/convert/boundSpec.ts +0 -134
- package/src/convert/copyBounded.test.ts +0 -131
- package/src/convert/copyBounded.ts +0 -38
- package/src/convert/isElement.ts +0 -6
- package/src/convert/takeRun.test.ts +0 -64
- package/src/convert/takeRun.ts +0 -19
- package/src/defineGenerativeComponents.ts +0 -38
- package/src/fieldReferences.test.ts +0 -66
- package/src/fieldReferences.ts +0 -83
- package/src/generativeUIToJSX.test.ts +0 -268
- package/src/generativeUIToJSX.ts +0 -152
- package/src/index.server.test.ts +0 -106
- package/src/index.shared.ts +0 -61
- package/src/ir.test.ts +0 -203
- package/src/renderGenerativeUI.test.tsx +0 -373
- package/src/renderGenerativeUI.tsx +0 -165
- package/src/scopeSchema.test.ts +0 -72
- package/src/scopeSchema.ts +0 -71
- package/src/slack/a2uiSlack.test.ts +0 -198
- package/src/slack/constants.ts +0 -194
- package/src/slack/datePicker.test.ts +0 -612
- package/src/slack/decodeBlockAction.test.ts +0 -233
- package/src/slack/decodeBlockAction.ts +0 -232
- package/src/slack/fromSlackBlocks.test.ts +0 -1465
- package/src/slack/fromSlackBlocks.ts +0 -789
- package/src/slack/toSlackBlocks.test.ts +0 -3065
- package/src/slack/toSlackBlocks.ts +0 -1818
- package/src/slack/types.ts +0 -264
- package/src/teams/constants.ts +0 -93
- package/src/teams/decodeSubmitData.test.ts +0 -397
- package/src/teams/decodeSubmitData.ts +0 -110
- package/src/teams/temporal.test.ts +0 -766
- package/src/teams/temporalId.ts +0 -56
- package/src/teams/toAdaptiveCard.test.ts +0 -1897
- package/src/teams/toAdaptiveCard.ts +0 -1057
- package/src/teams/toTeamsAttachments.test.ts +0 -74
- package/src/teams/toTeamsAttachments.ts +0 -133
- package/src/teams/types.ts +0 -266
- package/src/temporal.test.ts +0 -337
- package/src/temporal.ts +0 -263
- package/src/types.ts +0 -119
- package/src/vocabulary/alert.test.tsx +0 -427
- package/src/vocabulary/alert.tsx +0 -217
- package/src/vocabulary/collectFormValues.test.ts +0 -389
- package/src/vocabulary/collectFormValues.ts +0 -116
- package/src/vocabulary/data.test.tsx +0 -858
- package/src/vocabulary/data.tsx +0 -819
- package/src/vocabulary/datepicker.dom.test.tsx +0 -1457
- package/src/vocabulary/dispatch.ts +0 -83
- package/src/vocabulary/fact.test.tsx +0 -94
- package/src/vocabulary/fact.tsx +0 -54
- package/src/vocabulary/form.test.tsx +0 -113
- package/src/vocabulary/form.tsx +0 -39
- package/src/vocabulary/formatValue.test.ts +0 -72
- package/src/vocabulary/formatValue.ts +0 -127
- package/src/vocabulary/icon.test.tsx +0 -64
- package/src/vocabulary/icon.tsx +0 -174
- package/src/vocabulary/index.test.ts +0 -65
- package/src/vocabulary/index.ts +0 -33
- package/src/vocabulary/interactive.dispatch.test.tsx +0 -454
- package/src/vocabulary/interactive.dom.test.tsx +0 -1747
- package/src/vocabulary/interactive.test.tsx +0 -377
- package/src/vocabulary/interactive.tsx +0 -1109
- package/src/vocabulary/layout.test.tsx +0 -323
- package/src/vocabulary/layout.tsx +0 -247
- package/src/vocabulary/list.test.tsx +0 -222
- package/src/vocabulary/list.tsx +0 -50
- package/src/vocabulary/media.test.tsx +0 -85
- package/src/vocabulary/media.tsx +0 -56
- package/src/vocabulary/text.test.tsx +0 -102
- package/src/vocabulary/text.tsx +0 -60
- package/src/vocabulary/toTextContent.ts +0 -2
package/dist/answeredValues.js
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
import { jsx } from "react/jsx-runtime";
|
|
3
|
-
//#region src/answeredValues.tsx
|
|
4
|
-
let answeredValuesContext;
|
|
5
|
-
const supportsContext = typeof React.createContext === "function";
|
|
6
|
-
const useValuesContext = supportsContext ? React.useContext : () => void 0;
|
|
7
|
-
const getAnsweredValuesContext = () => supportsContext ? answeredValuesContext ??= React.createContext(void 0) : void 0;
|
|
8
|
-
const isPlainObject = (value) => {
|
|
9
|
-
if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
|
|
10
|
-
const prototype = Object.getPrototypeOf(value);
|
|
11
|
-
return prototype === Object.prototype || prototype === null;
|
|
12
|
-
};
|
|
13
|
-
const findAnsweredValues = (interactions) => {
|
|
14
|
-
const entries = interactions?.entries;
|
|
15
|
-
if (!entries) return void 0;
|
|
16
|
-
for (let index = entries.length - 1; index >= 0; index--) {
|
|
17
|
-
const interaction = entries[index];
|
|
18
|
-
if (interaction.type !== "action" || !isPlainObject(interaction.payload)) continue;
|
|
19
|
-
const input = interaction.payload["$input"];
|
|
20
|
-
if (isPlainObject(input)) return input;
|
|
21
|
-
}
|
|
22
|
-
};
|
|
23
|
-
const AnsweredValuesProvider = ({ values, children }) => {
|
|
24
|
-
const Context = getAnsweredValuesContext();
|
|
25
|
-
return Context ? /* @__PURE__ */ jsx(Context.Provider, {
|
|
26
|
-
value: values,
|
|
27
|
-
children
|
|
28
|
-
}) : children;
|
|
29
|
-
};
|
|
30
|
-
const useAnsweredValue = (name) => {
|
|
31
|
-
const values = useValuesContext(getAnsweredValuesContext());
|
|
32
|
-
return name !== void 0 && values && Object.hasOwn(values, name) ? values[name] : void 0;
|
|
33
|
-
};
|
|
34
|
-
//#endregion
|
|
35
|
-
export { AnsweredValuesProvider, findAnsweredValues, useAnsweredValue };
|
|
36
|
-
|
|
37
|
-
//# sourceMappingURL=answeredValues.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"answeredValues.js","names":[],"sources":["../src/answeredValues.tsx"],"sourcesContent":["import * as React from \"react\";\n\ntype AnsweredValues = Readonly<Record<string, unknown>>;\n\ntype ToolInteractionLog = {\n readonly entries: readonly {\n readonly type: string;\n readonly payload: unknown;\n }[];\n};\n\nlet answeredValuesContext:\n | React.Context<AnsweredValues | undefined>\n | undefined;\nconst supportsContext = typeof React.createContext === \"function\";\nconst useValuesContext = supportsContext ? React.useContext : () => undefined;\n\nconst getAnsweredValuesContext = () =>\n supportsContext\n ? (answeredValuesContext ??= React.createContext<\n AnsweredValues | undefined\n >(undefined))\n : undefined;\n\nconst isPlainObject = (value: unknown): value is AnsweredValues => {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n return false;\n }\n const prototype = Object.getPrototypeOf(value);\n return prototype === Object.prototype || prototype === null;\n};\n\nexport const findAnsweredValues = (\n interactions: ToolInteractionLog | undefined,\n): AnsweredValues | undefined => {\n const entries = interactions?.entries;\n if (!entries) return undefined;\n\n for (let index = entries.length - 1; index >= 0; index--) {\n const interaction = entries[index]!;\n if (interaction.type !== \"action\" || !isPlainObject(interaction.payload)) {\n continue;\n }\n const input = interaction.payload[\"$input\"];\n if (isPlainObject(input)) return input;\n }\n return undefined;\n};\n\nexport const AnsweredValuesProvider = ({\n values,\n children,\n}: {\n values: AnsweredValues | undefined;\n children: React.ReactNode;\n}) => {\n const Context = getAnsweredValuesContext();\n return Context ? (\n <Context.Provider value={values}>{children}</Context.Provider>\n ) : (\n children\n );\n};\n\nexport const useAnsweredValue = (name: string | undefined): unknown => {\n const values = useValuesContext(getAnsweredValuesContext()!);\n return name !== undefined && values && Object.hasOwn(values, name)\n ? values[name]\n : undefined;\n};\n"],"mappings":";;;AAWA,IAAI;AAGJ,MAAM,kBAAkB,OAAO,MAAM,kBAAkB;AACvD,MAAM,mBAAmB,kBAAkB,MAAM,mBAAmB,KAAA;AAEpE,MAAM,iCACJ,kBACK,0BAA0B,MAAM,cAE/B,KAAA,CAAS,IACX,KAAA;AAEN,MAAM,iBAAiB,UAA4C;CACjE,IAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,MAAM,QAAQ,KAAK,GACpE,OAAO;CAET,MAAM,YAAY,OAAO,eAAe,KAAK;CAC7C,OAAO,cAAc,OAAO,aAAa,cAAc;AACzD;AAEA,MAAa,sBACX,iBAC+B;CAC/B,MAAM,UAAU,cAAc;CAC9B,IAAI,CAAC,SAAS,OAAO,KAAA;CAErB,KAAK,IAAI,QAAQ,QAAQ,SAAS,GAAG,SAAS,GAAG,SAAS;EACxD,MAAM,cAAc,QAAQ;EAC5B,IAAI,YAAY,SAAS,YAAY,CAAC,cAAc,YAAY,OAAO,GACrE;EAEF,MAAM,QAAQ,YAAY,QAAQ;EAClC,IAAI,cAAc,KAAK,GAAG,OAAO;CACnC;AAEF;AAEA,MAAa,0BAA0B,EACrC,QACA,eAII;CACJ,MAAM,UAAU,yBAAyB;CACzC,OAAO,UACL,oBAAC,QAAQ,UAAT;EAAkB,OAAO;EAAS;CAA2B,CAAA,IAE7D;AAEJ;AAEA,MAAa,oBAAoB,SAAsC;CACrE,MAAM,SAAS,iBAAiB,yBAAyB,CAAE;CAC3D,OAAO,SAAS,KAAA,KAAa,UAAU,OAAO,OAAO,QAAQ,IAAI,IAC7D,OAAO,QACP,KAAA;AACN"}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import type { JSONSchema7 } from "json-schema";
|
|
2
|
-
import type { GenerativeUILibrary } from "./types.js";
|
|
3
|
-
/**
|
|
4
|
-
* Builds the JSON schema for the `present` tool from a {@link GenerativeUILibrary}.
|
|
5
|
-
*
|
|
6
|
-
* The model produces a node `{ $type, $key?, ...props }` where `$type` selects
|
|
7
|
-
* a component, the optional `$key` pins a stable identity for list items that
|
|
8
|
-
* may reorder, and the rest are its props. The schema is a flat object: `$type`
|
|
9
|
-
* is an enum of the component names, every component's props are merged into
|
|
10
|
-
* one optional bag, and `children` recurses via `$defs` so the tree can nest.
|
|
11
|
-
*
|
|
12
|
-
* It is intentionally flat rather than a per-`$type` discriminated union. Tool /
|
|
13
|
-
* function-call schemas (OpenAI and others) require the top-level parameters to
|
|
14
|
-
* be a plain object and reject a top-level `oneOf`/`anyOf`/`enum`. So props can't
|
|
15
|
-
* be refined per `$type` at the root; the model is guided instead by `$type`'s
|
|
16
|
-
* description (which lists each component) and each prop's own description. The
|
|
17
|
-
* renderer validates nothing here — an unknown `$type` or stray prop is handled
|
|
18
|
-
* at render time — so a looser schema only costs the model a hint, not safety.
|
|
19
|
-
*/
|
|
20
|
-
export declare function buildPresentParameters(library: GenerativeUILibrary): JSONSchema7;
|
|
21
|
-
//# sourceMappingURL=buildPresentParameters.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"buildPresentParameters.d.ts","sourceRoot":"","sources":["../src/buildPresentParameters.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAyB,MAAM,aAAa,CAAC;AAEtE,OAAO,KAAK,EAAE,mBAAmB,EAAE,mBAAgB;AAGnD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,mBAAmB,GAC3B,WAAW,CA+Fb"}
|
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
import { TYPE_KEY } from "./constants.js";
|
|
2
|
-
import { scopeSchema } from "./scopeSchema.js";
|
|
3
|
-
import { toJSONSchema } from "assistant-stream";
|
|
4
|
-
//#region src/buildPresentParameters.ts
|
|
5
|
-
/**
|
|
6
|
-
* Builds the JSON schema for the `present` tool from a {@link GenerativeUILibrary}.
|
|
7
|
-
*
|
|
8
|
-
* The model produces a node `{ $type, $key?, ...props }` where `$type` selects
|
|
9
|
-
* a component, the optional `$key` pins a stable identity for list items that
|
|
10
|
-
* may reorder, and the rest are its props. The schema is a flat object: `$type`
|
|
11
|
-
* is an enum of the component names, every component's props are merged into
|
|
12
|
-
* one optional bag, and `children` recurses via `$defs` so the tree can nest.
|
|
13
|
-
*
|
|
14
|
-
* It is intentionally flat rather than a per-`$type` discriminated union. Tool /
|
|
15
|
-
* function-call schemas (OpenAI and others) require the top-level parameters to
|
|
16
|
-
* be a plain object and reject a top-level `oneOf`/`anyOf`/`enum`. So props can't
|
|
17
|
-
* be refined per `$type` at the root; the model is guided instead by `$type`'s
|
|
18
|
-
* description (which lists each component) and each prop's own description. The
|
|
19
|
-
* renderer validates nothing here — an unknown `$type` or stray prop is handled
|
|
20
|
-
* at render time — so a looser schema only costs the model a hint, not safety.
|
|
21
|
-
*/
|
|
22
|
-
function buildPresentParameters(library) {
|
|
23
|
-
const names = Object.keys(library);
|
|
24
|
-
const props = /* @__PURE__ */ new Map();
|
|
25
|
-
const propOwners = /* @__PURE__ */ new Map();
|
|
26
|
-
const componentSchemas = {};
|
|
27
|
-
for (const [index, name] of names.entries()) {
|
|
28
|
-
const definition = `component${index}`;
|
|
29
|
-
const { schema: propsSchema, referenced } = scopeSchema(toJSONSchema(library[name].properties), `#/$defs/${definition}`);
|
|
30
|
-
if (propsSchema.type !== "object") throw new Error(`[@assistant-ui/react-generative-ui] Component "${name}": \`properties\` must be an object schema (e.g. \`z.object({ ... })\`).`);
|
|
31
|
-
let merged = false;
|
|
32
|
-
for (const [key, schema] of Object.entries(propsSchema.properties ?? {})) {
|
|
33
|
-
if (key.startsWith("$") || key === "children") continue;
|
|
34
|
-
if (key === "__proto__") continue;
|
|
35
|
-
if (!props.has(key)) {
|
|
36
|
-
props.set(key, schema);
|
|
37
|
-
merged = true;
|
|
38
|
-
}
|
|
39
|
-
propOwners.set(key, [...propOwners.get(key) ?? [], name]);
|
|
40
|
-
}
|
|
41
|
-
if (referenced && merged) {
|
|
42
|
-
const { $schema: _, $id: _id, ...embedded } = propsSchema;
|
|
43
|
-
componentSchemas[definition] = embedded;
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
if (process.env["NODE_ENV"] !== "production") for (const [key, owners] of propOwners) {
|
|
47
|
-
if (owners.length < 2) continue;
|
|
48
|
-
console.warn(`[@assistant-ui/react-generative-ui] Prop "${key}" is declared by ${formatComponentList(owners)}; keeping "${owners[0]}"'s schema. Rename or align the prop type to avoid an ambiguous schema.`);
|
|
49
|
-
}
|
|
50
|
-
const typeDescription = names.length > 0 ? `The component to render. ${names.map((name) => `"${name}": ${library[name].description}`).join("; ")}` : "The component to render.";
|
|
51
|
-
const node = {
|
|
52
|
-
type: "object",
|
|
53
|
-
properties: {
|
|
54
|
-
[TYPE_KEY]: {
|
|
55
|
-
type: "string",
|
|
56
|
-
enum: names,
|
|
57
|
-
description: typeDescription
|
|
58
|
-
},
|
|
59
|
-
$key: {
|
|
60
|
-
description: "Stable identity for this UI node. Use it for list items that may reorder.",
|
|
61
|
-
anyOf: [{ type: "string" }, { type: "number" }]
|
|
62
|
-
},
|
|
63
|
-
...Object.fromEntries(props),
|
|
64
|
-
children: { $ref: "#/$defs/children" }
|
|
65
|
-
},
|
|
66
|
-
required: [TYPE_KEY]
|
|
67
|
-
};
|
|
68
|
-
const children = {
|
|
69
|
-
description: "Nested generative UI rendered inside this component.",
|
|
70
|
-
anyOf: [
|
|
71
|
-
{ type: "string" },
|
|
72
|
-
{ $ref: "#/$defs/node" },
|
|
73
|
-
{
|
|
74
|
-
type: "array",
|
|
75
|
-
items: { anyOf: [{ type: "string" }, { $ref: "#/$defs/node" }] }
|
|
76
|
-
}
|
|
77
|
-
]
|
|
78
|
-
};
|
|
79
|
-
return {
|
|
80
|
-
...node,
|
|
81
|
-
$defs: {
|
|
82
|
-
node,
|
|
83
|
-
children,
|
|
84
|
-
...componentSchemas
|
|
85
|
-
}
|
|
86
|
-
};
|
|
87
|
-
}
|
|
88
|
-
function formatComponentList(names) {
|
|
89
|
-
if (names.length <= 2) return names.map((name) => `"${name}"`).join(" and ");
|
|
90
|
-
return `${names.slice(0, -1).map((name) => `"${name}"`).join(", ")}, and "${names[names.length - 1]}"`;
|
|
91
|
-
}
|
|
92
|
-
//#endregion
|
|
93
|
-
export { buildPresentParameters };
|
|
94
|
-
|
|
95
|
-
//# sourceMappingURL=buildPresentParameters.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"buildPresentParameters.js","names":[],"sources":["../src/buildPresentParameters.ts"],"sourcesContent":["import { toJSONSchema } from \"assistant-stream\";\nimport type { JSONSchema7, JSONSchema7Definition } from \"json-schema\";\nimport { TYPE_KEY } from \"./constants\";\nimport type { GenerativeUILibrary } from \"./types\";\nimport { scopeSchema } from \"./scopeSchema\";\n\n/**\n * Builds the JSON schema for the `present` tool from a {@link GenerativeUILibrary}.\n *\n * The model produces a node `{ $type, $key?, ...props }` where `$type` selects\n * a component, the optional `$key` pins a stable identity for list items that\n * may reorder, and the rest are its props. The schema is a flat object: `$type`\n * is an enum of the component names, every component's props are merged into\n * one optional bag, and `children` recurses via `$defs` so the tree can nest.\n *\n * It is intentionally flat rather than a per-`$type` discriminated union. Tool /\n * function-call schemas (OpenAI and others) require the top-level parameters to\n * be a plain object and reject a top-level `oneOf`/`anyOf`/`enum`. So props can't\n * be refined per `$type` at the root; the model is guided instead by `$type`'s\n * description (which lists each component) and each prop's own description. The\n * renderer validates nothing here — an unknown `$type` or stray prop is handled\n * at render time — so a looser schema only costs the model a hint, not safety.\n */\nexport function buildPresentParameters(\n library: GenerativeUILibrary,\n): JSONSchema7 {\n const names = Object.keys(library);\n\n // Merge every component's props into one optional bag. `$`-prefixed keys and\n // `children` are framework-reserved (see ir.ts), so drop any author-declared\n // copies. On a name clash the first component's schema wins — props are an\n // advisory hint here, not a strict per-component contract.\n const props = new Map<string, JSONSchema7Definition>();\n const propOwners = new Map<string, string[]>();\n const componentSchemas: Record<string, JSONSchema7> = {};\n for (const [index, name] of names.entries()) {\n const definition = `component${index}`;\n const { schema: propsSchema, referenced } = scopeSchema(\n toJSONSchema(library[name]!.properties),\n `#/$defs/${definition}`,\n );\n if (propsSchema.type !== \"object\") {\n throw new Error(\n `[@assistant-ui/react-generative-ui] Component \"${name}\": ` +\n \"`properties` must be an object schema (e.g. `z.object({ ... })`).\",\n );\n }\n let merged = false;\n for (const [key, schema] of Object.entries(propsSchema.properties ?? {})) {\n if (key.startsWith(\"$\") || key === \"children\") continue;\n // secure-json-parse rejects the whole tool-argument payload on this key,\n // so advertising it would cost the model the node rather than one prop.\n if (key === \"__proto__\") continue;\n if (!props.has(key)) {\n props.set(key, schema);\n merged = true;\n }\n propOwners.set(key, [...(propOwners.get(key) ?? []), name]);\n }\n if (referenced && merged) {\n // `$schema` is only valid at a schema-resource root, and an embedded\n // `$id` would both collide across components and re-base the pointers\n // scopeSchema just rewrote to be document-root relative.\n const { $schema: _, $id: _id, ...embedded } = propsSchema;\n componentSchemas[definition] = embedded;\n }\n }\n\n if (process.env[\"NODE_ENV\"] !== \"production\") {\n for (const [key, owners] of propOwners) {\n if (owners.length < 2) continue;\n // eslint-disable-next-line no-console\n console.warn(\n `[@assistant-ui/react-generative-ui] Prop \"${key}\" is declared by ` +\n `${formatComponentList(owners)}; keeping \"${owners[0]}\"'s schema. ` +\n \"Rename or align the prop type to avoid an ambiguous schema.\",\n );\n }\n }\n\n // Carry each component's description on the `$type` enum, since there are no\n // per-branch schemas to hang them on anymore.\n const typeDescription =\n names.length > 0\n ? `The component to render. ${names\n .map((name) => `\"${name}\": ${library[name]!.description}`)\n .join(\"; \")}`\n : \"The component to render.\";\n\n const node: JSONSchema7 = {\n type: \"object\",\n properties: {\n [TYPE_KEY]: { type: \"string\", enum: names, description: typeDescription },\n $key: {\n description:\n \"Stable identity for this UI node. Use it for list items that may reorder.\",\n anyOf: [{ type: \"string\" }, { type: \"number\" }],\n },\n ...Object.fromEntries(props),\n children: { $ref: \"#/$defs/children\" },\n },\n required: [TYPE_KEY],\n };\n\n const children: JSONSchema7 = {\n description: \"Nested generative UI rendered inside this component.\",\n anyOf: [\n { type: \"string\" },\n { $ref: \"#/$defs/node\" },\n {\n type: \"array\",\n items: { anyOf: [{ type: \"string\" }, { $ref: \"#/$defs/node\" }] },\n },\n ],\n };\n\n return {\n ...node,\n $defs: { node, children, ...componentSchemas },\n };\n}\n\nfunction formatComponentList(names: string[]) {\n if (names.length <= 2) return names.map((name) => `\"${name}\"`).join(\" and \");\n\n return `${names\n .slice(0, -1)\n .map((name) => `\"${name}\"`)\n .join(\", \")}, and \"${names[names.length - 1]}\"`;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAuBA,SAAgB,uBACd,SACa;CACb,MAAM,QAAQ,OAAO,KAAK,OAAO;CAMjC,MAAM,wBAAQ,IAAI,IAAmC;CACrD,MAAM,6BAAa,IAAI,IAAsB;CAC7C,MAAM,mBAAgD,CAAC;CACvD,KAAK,MAAM,CAAC,OAAO,SAAS,MAAM,QAAQ,GAAG;EAC3C,MAAM,aAAa,YAAY;EAC/B,MAAM,EAAE,QAAQ,aAAa,eAAe,YAC1C,aAAa,QAAQ,KAAK,CAAE,UAAU,GACtC,WAAW,YACb;EACA,IAAI,YAAY,SAAS,UACvB,MAAM,IAAI,MACR,kDAAkD,KAAK,yEAEzD;EAEF,IAAI,SAAS;EACb,KAAK,MAAM,CAAC,KAAK,WAAW,OAAO,QAAQ,YAAY,cAAc,CAAC,CAAC,GAAG;GACxE,IAAI,IAAI,WAAW,GAAG,KAAK,QAAQ,YAAY;GAG/C,IAAI,QAAQ,aAAa;GACzB,IAAI,CAAC,MAAM,IAAI,GAAG,GAAG;IACnB,MAAM,IAAI,KAAK,MAAM;IACrB,SAAS;GACX;GACA,WAAW,IAAI,KAAK,CAAC,GAAI,WAAW,IAAI,GAAG,KAAK,CAAC,GAAI,IAAI,CAAC;EAC5D;EACA,IAAI,cAAc,QAAQ;GAIxB,MAAM,EAAE,SAAS,GAAG,KAAK,KAAK,GAAG,aAAa;GAC9C,iBAAiB,cAAc;EACjC;CACF;CAEA,IAAI,QAAQ,IAAI,gBAAgB,cAC9B,KAAK,MAAM,CAAC,KAAK,WAAW,YAAY;EACtC,IAAI,OAAO,SAAS,GAAG;EAEvB,QAAQ,KACN,6CAA6C,IAAI,mBAC5C,oBAAoB,MAAM,EAAE,aAAa,OAAO,GAAG,wEAE1D;CACF;CAKF,MAAM,kBACJ,MAAM,SAAS,IACX,4BAA4B,MACzB,KAAK,SAAS,IAAI,KAAK,KAAK,QAAQ,KAAK,CAAE,aAAa,CAAC,CACzD,KAAK,IAAI,MACZ;CAEN,MAAM,OAAoB;EACxB,MAAM;EACN,YAAY;IACT,WAAW;IAAE,MAAM;IAAU,MAAM;IAAO,aAAa;GAAgB;GACxE,MAAM;IACJ,aACE;IACF,OAAO,CAAC,EAAE,MAAM,SAAS,GAAG,EAAE,MAAM,SAAS,CAAC;GAChD;GACA,GAAG,OAAO,YAAY,KAAK;GAC3B,UAAU,EAAE,MAAM,mBAAmB;EACvC;EACA,UAAU,CAAC,QAAQ;CACrB;CAEA,MAAM,WAAwB;EAC5B,aAAa;EACb,OAAO;GACL,EAAE,MAAM,SAAS;GACjB,EAAE,MAAM,eAAe;GACvB;IACE,MAAM;IACN,OAAO,EAAE,OAAO,CAAC,EAAE,MAAM,SAAS,GAAG,EAAE,MAAM,eAAe,CAAC,EAAE;GACjE;EACF;CACF;CAEA,OAAO;EACL,GAAG;EACH,OAAO;GAAE;GAAM;GAAU,GAAG;EAAiB;CAC/C;AACF;AAEA,SAAS,oBAAoB,OAAiB;CAC5C,IAAI,MAAM,UAAU,GAAG,OAAO,MAAM,KAAK,SAAS,IAAI,KAAK,EAAE,CAAC,CAAC,KAAK,OAAO;CAE3E,OAAO,GAAG,MACP,MAAM,GAAG,EAAE,CAAC,CACZ,KAAK,SAAS,IAAI,KAAK,EAAE,CAAC,CAC1B,KAAK,IAAI,EAAE,SAAS,MAAM,MAAM,SAAS,GAAG;AACjD"}
|
package/dist/constants.d.ts
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The wire key naming the component to render.
|
|
3
|
-
*
|
|
4
|
-
* The model emits nodes as flat objects `{ [TYPE_KEY]: name, ...props }`. We
|
|
5
|
-
* use `$type` rather than `type` so a component's own `type` prop (e.g. a
|
|
6
|
-
* button's `type="submit"`) flows through as an ordinary prop without
|
|
7
|
-
* colliding with the discriminator. It mirrors the `$type` discriminator
|
|
8
|
-
* convention used by JSON polymorphism elsewhere.
|
|
9
|
-
*/
|
|
10
|
-
export declare const TYPE_KEY = "$type";
|
|
11
|
-
export declare const GENERATED_NAME_ATTR = "data-aui-generated-name";
|
|
12
|
-
export declare const FIELD_NAME_ATTR = "data-aui-field-name";
|
|
13
|
-
export declare const FIELD_VALUE_ATTR = "data-aui-field-value";
|
|
14
|
-
export declare const CHECKBOX_GROUP_ATTR = "data-aui-checkbox-group";
|
|
15
|
-
//# sourceMappingURL=constants.d.ts.map
|
package/dist/constants.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,eAAO,MAAM,QAAQ,UAAU,CAAC;AAEhC,eAAO,MAAM,mBAAmB,4BAA4B,CAAC;AAE7D,eAAO,MAAM,eAAe,wBAAwB,CAAC;AACrD,eAAO,MAAM,gBAAgB,yBAAyB,CAAC;AAEvD,eAAO,MAAM,mBAAmB,4BAA4B,CAAC"}
|
package/dist/constants.js
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
//#region src/constants.ts
|
|
2
|
-
/**
|
|
3
|
-
* The wire key naming the component to render.
|
|
4
|
-
*
|
|
5
|
-
* The model emits nodes as flat objects `{ [TYPE_KEY]: name, ...props }`. We
|
|
6
|
-
* use `$type` rather than `type` so a component's own `type` prop (e.g. a
|
|
7
|
-
* button's `type="submit"`) flows through as an ordinary prop without
|
|
8
|
-
* colliding with the discriminator. It mirrors the `$type` discriminator
|
|
9
|
-
* convention used by JSON polymorphism elsewhere.
|
|
10
|
-
*/
|
|
11
|
-
const TYPE_KEY = "$type";
|
|
12
|
-
const GENERATED_NAME_ATTR = "data-aui-generated-name";
|
|
13
|
-
const FIELD_NAME_ATTR = "data-aui-field-name";
|
|
14
|
-
const FIELD_VALUE_ATTR = "data-aui-field-value";
|
|
15
|
-
const CHECKBOX_GROUP_ATTR = "data-aui-checkbox-group";
|
|
16
|
-
//#endregion
|
|
17
|
-
export { CHECKBOX_GROUP_ATTR, FIELD_NAME_ATTR, FIELD_VALUE_ATTR, GENERATED_NAME_ATTR, TYPE_KEY };
|
|
18
|
-
|
|
19
|
-
//# sourceMappingURL=constants.js.map
|
package/dist/constants.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","names":[],"sources":["../src/constants.ts"],"sourcesContent":["/**\n * The wire key naming the component to render.\n *\n * The model emits nodes as flat objects `{ [TYPE_KEY]: name, ...props }`. We\n * use `$type` rather than `type` so a component's own `type` prop (e.g. a\n * button's `type=\"submit\"`) flows through as an ordinary prop without\n * colliding with the discriminator. It mirrors the `$type` discriminator\n * convention used by JSON polymorphism elsewhere.\n */\nexport const TYPE_KEY = \"$type\";\n\nexport const GENERATED_NAME_ATTR = \"data-aui-generated-name\";\n\nexport const FIELD_NAME_ATTR = \"data-aui-field-name\";\nexport const FIELD_VALUE_ATTR = \"data-aui-field-value\";\n\nexport const CHECKBOX_GROUP_ATTR = \"data-aui-checkbox-group\";\n"],"mappings":";;;;;;;;;;AASA,MAAa,WAAW;AAExB,MAAa,sBAAsB;AAEnC,MAAa,kBAAkB;AAC/B,MAAa,mBAAmB;AAEhC,MAAa,sBAAsB"}
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
/** The maximum traversal depth, counted in visited values, not tree levels. */
|
|
2
|
-
export declare const MAX_TRAVERSAL_DEPTH = 64;
|
|
3
|
-
/**
|
|
4
|
-
* The element-nesting ceiling a caller observes. `boundNode` visits an element
|
|
5
|
-
* and its `children` array separately, so one level of nesting spends two of
|
|
6
|
-
* {@link MAX_TRAVERSAL_DEPTH}; it runs before the conversion walk and is never
|
|
7
|
-
* the looser of the two. A root array costs one more level than a root object.
|
|
8
|
-
*/
|
|
9
|
-
export declare const MAX_ELEMENT_DEPTH: number;
|
|
10
|
-
/**
|
|
11
|
-
* The maximum number of entries kept at any single level (root, or a
|
|
12
|
-
* `children` array at any depth) of the raw spec, before it ever reaches
|
|
13
|
-
* `normalizeSpec`. Bounds a hostile array's reported `length` so the pre-pass
|
|
14
|
-
* can never be made to walk further than this regardless of what the array
|
|
15
|
-
* claims about itself.
|
|
16
|
-
*/
|
|
17
|
-
export declare const CHILDREN_CAP = 200;
|
|
18
|
-
/**
|
|
19
|
-
* The total number of nodes {@link boundSpec} will visit across one walk,
|
|
20
|
-
* regardless of how many times a shared reference recurs. Bounds the
|
|
21
|
-
* combinatorial work a DAG of shared or self-referential nodes would
|
|
22
|
-
* otherwise force even though each individual array stays within
|
|
23
|
-
* {@link CHILDREN_CAP}.
|
|
24
|
-
*/
|
|
25
|
-
export declare const NODE_BUDGET = 5000;
|
|
26
|
-
export type ClampReason = "children" | "budget" | "cycle" | "depth";
|
|
27
|
-
/** Renders the warning detail a protocol reports for one {@link ClampReason}. */
|
|
28
|
-
export declare function clampReasonDetail(reason: ClampReason): string;
|
|
29
|
-
/**
|
|
30
|
-
* Produces a bounded plain copy of a raw generative-ui spec before it
|
|
31
|
-
* reaches `normalizeSpec`, whose own traversal of the root array or any
|
|
32
|
-
* `children` array walks the full reported length of a hostile proxied
|
|
33
|
-
* array before any per-field cap downstream ever applies. Every array
|
|
34
|
-
* (root, or `children` at any depth) is capped to {@link CHILDREN_CAP}
|
|
35
|
-
* entries by index, which bounds a proxy however it fabricates `length` or
|
|
36
|
-
* replaces its array methods; recursion itself is capped at
|
|
37
|
-
* {@link MAX_TRAVERSAL_DEPTH}. Every object is returned as a plain copy whose
|
|
38
|
-
* `children` came from a single read, because a record that answers
|
|
39
|
-
* `[[HasProperty]]` and `[[Get]]`, or two `[[Get]]`s, differently would
|
|
40
|
-
* otherwise hand the bound one value and `normalizeSpec` another, skipping
|
|
41
|
-
* every bound here for that subtree. `onClamp` fires once per level that was
|
|
42
|
-
* truncated, receiving the reason for that truncation: `"children"`,
|
|
43
|
-
* `"depth"`, `"budget"`, or `"cycle"`. The walk also spends a total budget of
|
|
44
|
-
* {@link NODE_BUDGET} nodes, so shared references cannot multiply work
|
|
45
|
-
* exponentially, and a node that is its own ancestor is cut to `null`.
|
|
46
|
-
*/
|
|
47
|
-
export declare function boundSpec(spec: unknown, onClamp: (reason: ClampReason) => void): unknown;
|
|
48
|
-
//# sourceMappingURL=boundSpec.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"boundSpec.d.ts","sourceRoot":"","sources":["../../src/convert/boundSpec.ts"],"names":[],"mappings":"AAEA,+EAA+E;AAC/E,eAAO,MAAM,mBAAmB,KAAK,CAAC;AAEtC;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,QAA0B,CAAC;AAEzD;;;;;;GAMG;AACH,eAAO,MAAM,YAAY,MAAM,CAAC;AAEhC;;;;;;GAMG;AACH,eAAO,MAAM,WAAW,OAAO,CAAC;AAEhC,MAAM,MAAM,WAAW,GAAG,UAAU,GAAG,QAAQ,GAAG,OAAO,GAAG,OAAO,CAAC;AAEpE,iFAAiF;AACjF,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAS7D;AA6DD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,SAAS,CACvB,IAAI,EAAE,OAAO,EACb,OAAO,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,IAAI,GACrC,OAAO,CAQT"}
|
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
import { copyBounded } from "./copyBounded.js";
|
|
2
|
-
//#region src/convert/boundSpec.ts
|
|
3
|
-
/** The maximum traversal depth, counted in visited values, not tree levels. */
|
|
4
|
-
const MAX_TRAVERSAL_DEPTH = 64;
|
|
5
|
-
/**
|
|
6
|
-
* The element-nesting ceiling a caller observes. `boundNode` visits an element
|
|
7
|
-
* and its `children` array separately, so one level of nesting spends two of
|
|
8
|
-
* {@link MAX_TRAVERSAL_DEPTH}; it runs before the conversion walk and is never
|
|
9
|
-
* the looser of the two. A root array costs one more level than a root object.
|
|
10
|
-
*/
|
|
11
|
-
const MAX_ELEMENT_DEPTH = 32;
|
|
12
|
-
/**
|
|
13
|
-
* The maximum number of entries kept at any single level (root, or a
|
|
14
|
-
* `children` array at any depth) of the raw spec, before it ever reaches
|
|
15
|
-
* `normalizeSpec`. Bounds a hostile array's reported `length` so the pre-pass
|
|
16
|
-
* can never be made to walk further than this regardless of what the array
|
|
17
|
-
* claims about itself.
|
|
18
|
-
*/
|
|
19
|
-
const CHILDREN_CAP = 200;
|
|
20
|
-
/**
|
|
21
|
-
* The total number of nodes {@link boundSpec} will visit across one walk,
|
|
22
|
-
* regardless of how many times a shared reference recurs. Bounds the
|
|
23
|
-
* combinatorial work a DAG of shared or self-referential nodes would
|
|
24
|
-
* otherwise force even though each individual array stays within
|
|
25
|
-
* {@link CHILDREN_CAP}.
|
|
26
|
-
*/
|
|
27
|
-
const NODE_BUDGET = 5e3;
|
|
28
|
-
/** Renders the warning detail a protocol reports for one {@link ClampReason}. */
|
|
29
|
-
function clampReasonDetail(reason) {
|
|
30
|
-
if (reason === "budget") return `the tree was truncated after ${NODE_BUDGET} nodes.`;
|
|
31
|
-
if (reason === "cycle") return "a self-referencing node was dropped.";
|
|
32
|
-
if (reason === "depth") return `nodes deeper than 32 levels were dropped.`;
|
|
33
|
-
return `children were clamped to 200 entries.`;
|
|
34
|
-
}
|
|
35
|
-
function boundNode(value, depth, onClamp, state, ancestors) {
|
|
36
|
-
if (state.remaining <= 0) {
|
|
37
|
-
if (!state.exhausted) {
|
|
38
|
-
state.exhausted = true;
|
|
39
|
-
onClamp("budget");
|
|
40
|
-
}
|
|
41
|
-
return null;
|
|
42
|
-
}
|
|
43
|
-
state.remaining -= 1;
|
|
44
|
-
if (depth > 64) {
|
|
45
|
-
onClamp("depth");
|
|
46
|
-
return null;
|
|
47
|
-
}
|
|
48
|
-
if (Array.isArray(value)) {
|
|
49
|
-
if (ancestors.has(value)) {
|
|
50
|
-
onClamp("cycle");
|
|
51
|
-
return null;
|
|
52
|
-
}
|
|
53
|
-
ancestors.add(value);
|
|
54
|
-
const { items: bounded, truncated } = copyBounded(value, 200);
|
|
55
|
-
if (truncated) onClamp("children");
|
|
56
|
-
const result = bounded.map((item) => boundNode(item, depth + 1, onClamp, state, ancestors));
|
|
57
|
-
ancestors.delete(value);
|
|
58
|
-
return result;
|
|
59
|
-
}
|
|
60
|
-
if (value !== null && typeof value === "object") {
|
|
61
|
-
const record = value;
|
|
62
|
-
const children = record["children"];
|
|
63
|
-
if (children === void 0) return {
|
|
64
|
-
...record,
|
|
65
|
-
children: void 0
|
|
66
|
-
};
|
|
67
|
-
if (ancestors.has(value)) {
|
|
68
|
-
onClamp("cycle");
|
|
69
|
-
return null;
|
|
70
|
-
}
|
|
71
|
-
ancestors.add(value);
|
|
72
|
-
const result = {
|
|
73
|
-
...record,
|
|
74
|
-
children: boundNode(children, depth + 1, onClamp, state, ancestors)
|
|
75
|
-
};
|
|
76
|
-
ancestors.delete(value);
|
|
77
|
-
return result;
|
|
78
|
-
}
|
|
79
|
-
return value;
|
|
80
|
-
}
|
|
81
|
-
/**
|
|
82
|
-
* Produces a bounded plain copy of a raw generative-ui spec before it
|
|
83
|
-
* reaches `normalizeSpec`, whose own traversal of the root array or any
|
|
84
|
-
* `children` array walks the full reported length of a hostile proxied
|
|
85
|
-
* array before any per-field cap downstream ever applies. Every array
|
|
86
|
-
* (root, or `children` at any depth) is capped to {@link CHILDREN_CAP}
|
|
87
|
-
* entries by index, which bounds a proxy however it fabricates `length` or
|
|
88
|
-
* replaces its array methods; recursion itself is capped at
|
|
89
|
-
* {@link MAX_TRAVERSAL_DEPTH}. Every object is returned as a plain copy whose
|
|
90
|
-
* `children` came from a single read, because a record that answers
|
|
91
|
-
* `[[HasProperty]]` and `[[Get]]`, or two `[[Get]]`s, differently would
|
|
92
|
-
* otherwise hand the bound one value and `normalizeSpec` another, skipping
|
|
93
|
-
* every bound here for that subtree. `onClamp` fires once per level that was
|
|
94
|
-
* truncated, receiving the reason for that truncation: `"children"`,
|
|
95
|
-
* `"depth"`, `"budget"`, or `"cycle"`. The walk also spends a total budget of
|
|
96
|
-
* {@link NODE_BUDGET} nodes, so shared references cannot multiply work
|
|
97
|
-
* exponentially, and a node that is its own ancestor is cut to `null`.
|
|
98
|
-
*/
|
|
99
|
-
function boundSpec(spec, onClamp) {
|
|
100
|
-
return boundNode(spec, 0, onClamp, {
|
|
101
|
-
remaining: NODE_BUDGET,
|
|
102
|
-
exhausted: false
|
|
103
|
-
}, /* @__PURE__ */ new WeakSet());
|
|
104
|
-
}
|
|
105
|
-
//#endregion
|
|
106
|
-
export { CHILDREN_CAP, MAX_ELEMENT_DEPTH, MAX_TRAVERSAL_DEPTH, NODE_BUDGET, boundSpec, clampReasonDetail };
|
|
107
|
-
|
|
108
|
-
//# sourceMappingURL=boundSpec.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"boundSpec.js","names":[],"sources":["../../src/convert/boundSpec.ts"],"sourcesContent":["import { copyBounded } from \"./copyBounded\";\n\n/** The maximum traversal depth, counted in visited values, not tree levels. */\nexport const MAX_TRAVERSAL_DEPTH = 64;\n\n/**\n * The element-nesting ceiling a caller observes. `boundNode` visits an element\n * and its `children` array separately, so one level of nesting spends two of\n * {@link MAX_TRAVERSAL_DEPTH}; it runs before the conversion walk and is never\n * the looser of the two. A root array costs one more level than a root object.\n */\nexport const MAX_ELEMENT_DEPTH = MAX_TRAVERSAL_DEPTH / 2;\n\n/**\n * The maximum number of entries kept at any single level (root, or a\n * `children` array at any depth) of the raw spec, before it ever reaches\n * `normalizeSpec`. Bounds a hostile array's reported `length` so the pre-pass\n * can never be made to walk further than this regardless of what the array\n * claims about itself.\n */\nexport const CHILDREN_CAP = 200;\n\n/**\n * The total number of nodes {@link boundSpec} will visit across one walk,\n * regardless of how many times a shared reference recurs. Bounds the\n * combinatorial work a DAG of shared or self-referential nodes would\n * otherwise force even though each individual array stays within\n * {@link CHILDREN_CAP}.\n */\nexport const NODE_BUDGET = 5000;\n\nexport type ClampReason = \"children\" | \"budget\" | \"cycle\" | \"depth\";\n\n/** Renders the warning detail a protocol reports for one {@link ClampReason}. */\nexport function clampReasonDetail(reason: ClampReason): string {\n if (reason === \"budget\") {\n return `the tree was truncated after ${NODE_BUDGET} nodes.`;\n }\n if (reason === \"cycle\") return \"a self-referencing node was dropped.\";\n if (reason === \"depth\") {\n return `nodes deeper than ${MAX_ELEMENT_DEPTH} levels were dropped.`;\n }\n return `children were clamped to ${CHILDREN_CAP} entries.`;\n}\n\ninterface BoundState {\n remaining: number;\n exhausted: boolean;\n}\n\nfunction boundNode(\n value: unknown,\n depth: number,\n onClamp: (reason: ClampReason) => void,\n state: BoundState,\n ancestors: WeakSet<object>,\n): unknown {\n if (state.remaining <= 0) {\n if (!state.exhausted) {\n state.exhausted = true;\n onClamp(\"budget\");\n }\n return null;\n }\n state.remaining -= 1;\n if (depth > MAX_TRAVERSAL_DEPTH) {\n onClamp(\"depth\");\n return null;\n }\n if (Array.isArray(value)) {\n if (ancestors.has(value)) {\n onClamp(\"cycle\");\n return null;\n }\n ancestors.add(value);\n const { items: bounded, truncated } = copyBounded(value, CHILDREN_CAP);\n if (truncated) onClamp(\"children\");\n const result = bounded.map((item) =>\n boundNode(item, depth + 1, onClamp, state, ancestors),\n );\n ancestors.delete(value);\n return result;\n }\n if (value !== null && typeof value === \"object\") {\n const record = value as Record<string, unknown>;\n const children = record[\"children\"];\n // The spread performs a `children` read of its own, so the copy states the\n // bounded value even when there is none.\n if (children === undefined) return { ...record, children: undefined };\n if (ancestors.has(value)) {\n onClamp(\"cycle\");\n return null;\n }\n ancestors.add(value);\n const result = {\n ...record,\n children: boundNode(children, depth + 1, onClamp, state, ancestors),\n };\n ancestors.delete(value);\n return result;\n }\n return value;\n}\n\n/**\n * Produces a bounded plain copy of a raw generative-ui spec before it\n * reaches `normalizeSpec`, whose own traversal of the root array or any\n * `children` array walks the full reported length of a hostile proxied\n * array before any per-field cap downstream ever applies. Every array\n * (root, or `children` at any depth) is capped to {@link CHILDREN_CAP}\n * entries by index, which bounds a proxy however it fabricates `length` or\n * replaces its array methods; recursion itself is capped at\n * {@link MAX_TRAVERSAL_DEPTH}. Every object is returned as a plain copy whose\n * `children` came from a single read, because a record that answers\n * `[[HasProperty]]` and `[[Get]]`, or two `[[Get]]`s, differently would\n * otherwise hand the bound one value and `normalizeSpec` another, skipping\n * every bound here for that subtree. `onClamp` fires once per level that was\n * truncated, receiving the reason for that truncation: `\"children\"`,\n * `\"depth\"`, `\"budget\"`, or `\"cycle\"`. The walk also spends a total budget of\n * {@link NODE_BUDGET} nodes, so shared references cannot multiply work\n * exponentially, and a node that is its own ancestor is cut to `null`.\n */\nexport function boundSpec(\n spec: unknown,\n onClamp: (reason: ClampReason) => void,\n): unknown {\n return boundNode(\n spec,\n 0,\n onClamp,\n { remaining: NODE_BUDGET, exhausted: false },\n new WeakSet(),\n );\n}\n"],"mappings":";;;AAGA,MAAa,sBAAsB;;;;;;;AAQnC,MAAa,oBAAA;;;;;;;;AASb,MAAa,eAAe;;;;;;;;AAS5B,MAAa,cAAc;;AAK3B,SAAgB,kBAAkB,QAA6B;CAC7D,IAAI,WAAW,UACb,OAAO,gCAAgC,YAAY;CAErD,IAAI,WAAW,SAAS,OAAO;CAC/B,IAAI,WAAW,SACb,OAAO;CAET,OAAO;AACT;AAOA,SAAS,UACP,OACA,OACA,SACA,OACA,WACS;CACT,IAAI,MAAM,aAAa,GAAG;EACxB,IAAI,CAAC,MAAM,WAAW;GACpB,MAAM,YAAY;GAClB,QAAQ,QAAQ;EAClB;EACA,OAAO;CACT;CACA,MAAM,aAAa;CACnB,IAAI,QAAA,IAA6B;EAC/B,QAAQ,OAAO;EACf,OAAO;CACT;CACA,IAAI,MAAM,QAAQ,KAAK,GAAG;EACxB,IAAI,UAAU,IAAI,KAAK,GAAG;GACxB,QAAQ,OAAO;GACf,OAAO;EACT;EACA,UAAU,IAAI,KAAK;EACnB,MAAM,EAAE,OAAO,SAAS,cAAc,YAAY,OAAA,GAAmB;EACrE,IAAI,WAAW,QAAQ,UAAU;EACjC,MAAM,SAAS,QAAQ,KAAK,SAC1B,UAAU,MAAM,QAAQ,GAAG,SAAS,OAAO,SAAS,CACtD;EACA,UAAU,OAAO,KAAK;EACtB,OAAO;CACT;CACA,IAAI,UAAU,QAAQ,OAAO,UAAU,UAAU;EAC/C,MAAM,SAAS;EACf,MAAM,WAAW,OAAO;EAGxB,IAAI,aAAa,KAAA,GAAW,OAAO;GAAE,GAAG;GAAQ,UAAU,KAAA;EAAU;EACpE,IAAI,UAAU,IAAI,KAAK,GAAG;GACxB,QAAQ,OAAO;GACf,OAAO;EACT;EACA,UAAU,IAAI,KAAK;EACnB,MAAM,SAAS;GACb,GAAG;GACH,UAAU,UAAU,UAAU,QAAQ,GAAG,SAAS,OAAO,SAAS;EACpE;EACA,UAAU,OAAO,KAAK;EACtB,OAAO;CACT;CACA,OAAO;AACT;;;;;;;;;;;;;;;;;;;AAoBA,SAAgB,UACd,MACA,SACS;CACT,OAAO,UACL,MACA,GACA,SACA;EAAE,WAAW;EAAa,WAAW;CAAM,mBAC3C,IAAI,QAAQ,CACd;AACF"}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Copies at most `cap` entries out of `value` by index.
|
|
3
|
-
*
|
|
4
|
-
* Every array method dispatches on the input: a replaced `slice` is called
|
|
5
|
-
* directly, and the intrinsic `Array.prototype.slice.call` still reaches a
|
|
6
|
-
* `constructor` with a `@@species` whose `[[Construct]]` returns an arbitrary
|
|
7
|
-
* object, which then supplies the `map` or `some` the caller runs next. Reading
|
|
8
|
-
* indices consults neither, so it is the only form that bounds a hostile array.
|
|
9
|
-
*
|
|
10
|
-
* Absent indices stay absent, matching what `slice` produces for a sparse
|
|
11
|
-
* input, so callers that skip holes still skip them. `truncated` comes from the
|
|
12
|
-
* same `length` read as the bound, so an input cannot report one figure to the
|
|
13
|
-
* cap and another to the caller's warning.
|
|
14
|
-
*
|
|
15
|
-
* A reported `length` is normalized the way `ToLength` does before it reaches
|
|
16
|
-
* `count`, because a fractional one would otherwise reach `items.length` and
|
|
17
|
-
* throw `RangeError` where `slice` returns a bounded result. `truncated` reads
|
|
18
|
-
* that same normalized figure, so a `length` whose `valueOf` answers differently
|
|
19
|
-
* on a second conversion cannot separate the warning from the bound.
|
|
20
|
-
*/
|
|
21
|
-
export declare const copyBounded: <T>(value: readonly T[], cap: number) => {
|
|
22
|
-
readonly items: T[];
|
|
23
|
-
readonly truncated: boolean;
|
|
24
|
-
};
|
|
25
|
-
//# sourceMappingURL=copyBounded.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"copyBounded.d.ts","sourceRoot":"","sources":["../../src/convert/copyBounded.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,WAAW,GAAI,CAAC,EAC3B,OAAO,SAAS,CAAC,EAAE,EACnB,KAAK,MAAM,KACV;IAAE,QAAQ,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAA;CAcpD,CAAC"}
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
//#region src/convert/copyBounded.ts
|
|
2
|
-
/**
|
|
3
|
-
* Copies at most `cap` entries out of `value` by index.
|
|
4
|
-
*
|
|
5
|
-
* Every array method dispatches on the input: a replaced `slice` is called
|
|
6
|
-
* directly, and the intrinsic `Array.prototype.slice.call` still reaches a
|
|
7
|
-
* `constructor` with a `@@species` whose `[[Construct]]` returns an arbitrary
|
|
8
|
-
* object, which then supplies the `map` or `some` the caller runs next. Reading
|
|
9
|
-
* indices consults neither, so it is the only form that bounds a hostile array.
|
|
10
|
-
*
|
|
11
|
-
* Absent indices stay absent, matching what `slice` produces for a sparse
|
|
12
|
-
* input, so callers that skip holes still skip them. `truncated` comes from the
|
|
13
|
-
* same `length` read as the bound, so an input cannot report one figure to the
|
|
14
|
-
* cap and another to the caller's warning.
|
|
15
|
-
*
|
|
16
|
-
* A reported `length` is normalized the way `ToLength` does before it reaches
|
|
17
|
-
* `count`, because a fractional one would otherwise reach `items.length` and
|
|
18
|
-
* throw `RangeError` where `slice` returns a bounded result. `truncated` reads
|
|
19
|
-
* that same normalized figure, so a `length` whose `valueOf` answers differently
|
|
20
|
-
* on a second conversion cannot separate the warning from the bound.
|
|
21
|
-
*/
|
|
22
|
-
const copyBounded = (value, cap) => {
|
|
23
|
-
const reported = value.length;
|
|
24
|
-
const integral = Math.trunc(Number(reported));
|
|
25
|
-
const usable = Number.isNaN(integral) || integral <= 0 ? 0 : Math.min(integral, Number.MAX_SAFE_INTEGER);
|
|
26
|
-
const count = Math.min(cap, usable);
|
|
27
|
-
const items = [];
|
|
28
|
-
for (let index = 0; index < count; index += 1) if (index in value) items[index] = value[index];
|
|
29
|
-
items.length = count;
|
|
30
|
-
return {
|
|
31
|
-
items,
|
|
32
|
-
truncated: usable > cap
|
|
33
|
-
};
|
|
34
|
-
};
|
|
35
|
-
//#endregion
|
|
36
|
-
export { copyBounded };
|
|
37
|
-
|
|
38
|
-
//# sourceMappingURL=copyBounded.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"copyBounded.js","names":[],"sources":["../../src/convert/copyBounded.ts"],"sourcesContent":["/**\n * Copies at most `cap` entries out of `value` by index.\n *\n * Every array method dispatches on the input: a replaced `slice` is called\n * directly, and the intrinsic `Array.prototype.slice.call` still reaches a\n * `constructor` with a `@@species` whose `[[Construct]]` returns an arbitrary\n * object, which then supplies the `map` or `some` the caller runs next. Reading\n * indices consults neither, so it is the only form that bounds a hostile array.\n *\n * Absent indices stay absent, matching what `slice` produces for a sparse\n * input, so callers that skip holes still skip them. `truncated` comes from the\n * same `length` read as the bound, so an input cannot report one figure to the\n * cap and another to the caller's warning.\n *\n * A reported `length` is normalized the way `ToLength` does before it reaches\n * `count`, because a fractional one would otherwise reach `items.length` and\n * throw `RangeError` where `slice` returns a bounded result. `truncated` reads\n * that same normalized figure, so a `length` whose `valueOf` answers differently\n * on a second conversion cannot separate the warning from the bound.\n */\nexport const copyBounded = <T>(\n value: readonly T[],\n cap: number,\n): { readonly items: T[]; readonly truncated: boolean } => {\n const reported = value.length;\n const integral = Math.trunc(Number(reported));\n const usable =\n Number.isNaN(integral) || integral <= 0\n ? 0\n : Math.min(integral, Number.MAX_SAFE_INTEGER);\n const count = Math.min(cap, usable);\n const items: T[] = [];\n for (let index = 0; index < count; index += 1) {\n if (index in value) items[index] = value[index] as T;\n }\n items.length = count;\n return { items, truncated: usable > cap };\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAoBA,MAAa,eACX,OACA,QACyD;CACzD,MAAM,WAAW,MAAM;CACvB,MAAM,WAAW,KAAK,MAAM,OAAO,QAAQ,CAAC;CAC5C,MAAM,SACJ,OAAO,MAAM,QAAQ,KAAK,YAAY,IAClC,IACA,KAAK,IAAI,UAAU,OAAO,gBAAgB;CAChD,MAAM,QAAQ,KAAK,IAAI,KAAK,MAAM;CAClC,MAAM,QAAa,CAAC;CACpB,KAAK,IAAI,QAAQ,GAAG,QAAQ,OAAO,SAAS,GAC1C,IAAI,SAAS,OAAO,MAAM,SAAS,MAAM;CAE3C,MAAM,SAAS;CACf,OAAO;EAAE;EAAO,WAAW,SAAS;CAAI;AAC1C"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"isElement.d.ts","sourceRoot":"","sources":["../../src/convert/isElement.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,iBAAc;AAEnE,eAAO,MAAM,SAAS,GACpB,MAAM,gBAAgB,KACrB,IAAI,IAAI,mBACwD,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"isElement.js","names":[],"sources":["../../src/convert/isElement.ts"],"sourcesContent":["import type { NormalizedUIElement, NormalizedUINode } from \"../ir\";\n\nexport const isElement = (\n node: NormalizedUINode,\n): node is NormalizedUIElement =>\n typeof node === \"object\" && node !== null && !Array.isArray(node);\n"],"mappings":";AAEA,MAAa,aACX,SAEA,OAAO,SAAS,YAAY,SAAS,QAAQ,CAAC,MAAM,QAAQ,IAAI"}
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import type { NormalizedUIElement, NormalizedUINode } from "../ir.js";
|
|
2
|
-
export declare function takeRun(nodes: readonly (NormalizedUINode | undefined)[], index: number, matches: (element: NormalizedUIElement) => boolean): {
|
|
3
|
-
run: NormalizedUIElement[];
|
|
4
|
-
next: number;
|
|
5
|
-
};
|
|
6
|
-
//# sourceMappingURL=takeRun.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"takeRun.d.ts","sourceRoot":"","sources":["../../src/convert/takeRun.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,iBAAc;AAGnE,wBAAgB,OAAO,CACrB,KAAK,EAAE,SAAS,CAAC,gBAAgB,GAAG,SAAS,CAAC,EAAE,EAChD,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,CAAC,OAAO,EAAE,mBAAmB,KAAK,OAAO,GACjD;IAAE,GAAG,EAAE,mBAAmB,EAAE,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAW9C"}
|
package/dist/convert/takeRun.js
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { isElement } from "./isElement.js";
|
|
2
|
-
//#region src/convert/takeRun.ts
|
|
3
|
-
function takeRun(nodes, index, matches) {
|
|
4
|
-
const run = [];
|
|
5
|
-
let next = index;
|
|
6
|
-
while (next < nodes.length) {
|
|
7
|
-
const candidate = nodes[next];
|
|
8
|
-
if (candidate === void 0 || !isElement(candidate) || !matches(candidate)) break;
|
|
9
|
-
run.push(candidate);
|
|
10
|
-
next += 1;
|
|
11
|
-
}
|
|
12
|
-
return {
|
|
13
|
-
run,
|
|
14
|
-
next
|
|
15
|
-
};
|
|
16
|
-
}
|
|
17
|
-
//#endregion
|
|
18
|
-
export { takeRun };
|
|
19
|
-
|
|
20
|
-
//# sourceMappingURL=takeRun.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"takeRun.js","names":[],"sources":["../../src/convert/takeRun.ts"],"sourcesContent":["import type { NormalizedUIElement, NormalizedUINode } from \"../ir\";\nimport { isElement } from \"./isElement\";\n\nexport function takeRun(\n nodes: readonly (NormalizedUINode | undefined)[],\n index: number,\n matches: (element: NormalizedUIElement) => boolean,\n): { run: NormalizedUIElement[]; next: number } {\n const run: NormalizedUIElement[] = [];\n let next = index;\n while (next < nodes.length) {\n const candidate = nodes[next];\n if (candidate === undefined || !isElement(candidate) || !matches(candidate))\n break;\n run.push(candidate);\n next += 1;\n }\n return { run, next };\n}\n"],"mappings":";;AAGA,SAAgB,QACd,OACA,OACA,SAC8C;CAC9C,MAAM,MAA6B,CAAC;CACpC,IAAI,OAAO;CACX,OAAO,OAAO,MAAM,QAAQ;EAC1B,MAAM,YAAY,MAAM;EACxB,IAAI,cAAc,KAAA,KAAa,CAAC,UAAU,SAAS,KAAK,CAAC,QAAQ,SAAS,GACxE;EACF,IAAI,KAAK,SAAS;EAClB,QAAQ;CACV;CACA,OAAO;EAAE;EAAK;CAAK;AACrB"}
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import type { GenerativeUILibrary } from "./types.js";
|
|
2
|
-
/**
|
|
3
|
-
* Authoring helper for a `"use generative"` generative-UI library — the set of
|
|
4
|
-
* components the model may render. Each component colocates its `properties`
|
|
5
|
-
* schema (kept on every build, drives the tool parameters) with its `render`
|
|
6
|
-
* (kept only on the client). Pass the result to {@link JSONGenerativeUI}:
|
|
7
|
-
*
|
|
8
|
-
* ```tsx
|
|
9
|
-
* "use generative";
|
|
10
|
-
* const generative = new JSONGenerativeUI({
|
|
11
|
-
* library: defineGenerativeComponents({
|
|
12
|
-
* Card: {
|
|
13
|
-
* description: "A card.",
|
|
14
|
-
* properties: z.object({ title: z.string() }),
|
|
15
|
-
* render: (props) => <Card {...props} />,
|
|
16
|
-
* },
|
|
17
|
-
* }),
|
|
18
|
-
* });
|
|
19
|
-
* ```
|
|
20
|
-
*
|
|
21
|
-
* Unlike {@link defineToolkit}, it has **no runtime implementation**. A
|
|
22
|
-
* `"use generative"` compiler unwraps the `defineGenerativeComponents(...)` call
|
|
23
|
-
* per build, dropping each `render` (and its client-only imports) from the server
|
|
24
|
-
* build. Reaching it at runtime means the module wasn't compiled (the directive
|
|
25
|
-
* is missing, or it was used outside a `"use generative"` file), so it throws
|
|
26
|
-
* rather than shipping client `render` code to the server.
|
|
27
|
-
*/
|
|
28
|
-
export declare function defineGenerativeComponents(_library: GenerativeUILibrary): GenerativeUILibrary;
|
|
29
|
-
//# sourceMappingURL=defineGenerativeComponents.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"defineGenerativeComponents.d.ts","sourceRoot":"","sources":["../src/defineGenerativeComponents.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,mBAAgB;AAEnD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,0BAA0B,CACxC,QAAQ,EAAE,mBAAmB,GAC5B,mBAAmB,CAOrB"}
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
//#region src/defineGenerativeComponents.ts
|
|
2
|
-
/**
|
|
3
|
-
* Authoring helper for a `"use generative"` generative-UI library — the set of
|
|
4
|
-
* components the model may render. Each component colocates its `properties`
|
|
5
|
-
* schema (kept on every build, drives the tool parameters) with its `render`
|
|
6
|
-
* (kept only on the client). Pass the result to {@link JSONGenerativeUI}:
|
|
7
|
-
*
|
|
8
|
-
* ```tsx
|
|
9
|
-
* "use generative";
|
|
10
|
-
* const generative = new JSONGenerativeUI({
|
|
11
|
-
* library: defineGenerativeComponents({
|
|
12
|
-
* Card: {
|
|
13
|
-
* description: "A card.",
|
|
14
|
-
* properties: z.object({ title: z.string() }),
|
|
15
|
-
* render: (props) => <Card {...props} />,
|
|
16
|
-
* },
|
|
17
|
-
* }),
|
|
18
|
-
* });
|
|
19
|
-
* ```
|
|
20
|
-
*
|
|
21
|
-
* Unlike {@link defineToolkit}, it has **no runtime implementation**. A
|
|
22
|
-
* `"use generative"` compiler unwraps the `defineGenerativeComponents(...)` call
|
|
23
|
-
* per build, dropping each `render` (and its client-only imports) from the server
|
|
24
|
-
* build. Reaching it at runtime means the module wasn't compiled (the directive
|
|
25
|
-
* is missing, or it was used outside a `"use generative"` file), so it throws
|
|
26
|
-
* rather than shipping client `render` code to the server.
|
|
27
|
-
*/
|
|
28
|
-
function defineGenerativeComponents(_library) {
|
|
29
|
-
throw new Error("[assistant-ui] defineGenerativeComponents() has no runtime implementation — it is stripped at build time by the use-generative compiler. Reaching it means this module was not compiled (e.g. used outside a \"use generative\" file). Add the directive, or do not use it here.");
|
|
30
|
-
}
|
|
31
|
-
//#endregion
|
|
32
|
-
export { defineGenerativeComponents };
|
|
33
|
-
|
|
34
|
-
//# sourceMappingURL=defineGenerativeComponents.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"defineGenerativeComponents.js","names":[],"sources":["../src/defineGenerativeComponents.ts"],"sourcesContent":["import type { GenerativeUILibrary } from \"./types\";\n\n/**\n * Authoring helper for a `\"use generative\"` generative-UI library — the set of\n * components the model may render. Each component colocates its `properties`\n * schema (kept on every build, drives the tool parameters) with its `render`\n * (kept only on the client). Pass the result to {@link JSONGenerativeUI}:\n *\n * ```tsx\n * \"use generative\";\n * const generative = new JSONGenerativeUI({\n * library: defineGenerativeComponents({\n * Card: {\n * description: \"A card.\",\n * properties: z.object({ title: z.string() }),\n * render: (props) => <Card {...props} />,\n * },\n * }),\n * });\n * ```\n *\n * Unlike {@link defineToolkit}, it has **no runtime implementation**. A\n * `\"use generative\"` compiler unwraps the `defineGenerativeComponents(...)` call\n * per build, dropping each `render` (and its client-only imports) from the server\n * build. Reaching it at runtime means the module wasn't compiled (the directive\n * is missing, or it was used outside a `\"use generative\"` file), so it throws\n * rather than shipping client `render` code to the server.\n */\nexport function defineGenerativeComponents(\n _library: GenerativeUILibrary,\n): GenerativeUILibrary {\n throw new Error(\n \"[assistant-ui] defineGenerativeComponents() has no runtime implementation \" +\n \"— it is stripped at build time by the use-generative compiler. Reaching \" +\n \"it means this module was not compiled (e.g. used outside a \" +\n '\"use generative\" file). Add the directive, or do not use it here.',\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AA4BA,SAAgB,2BACd,UACqB;CACrB,MAAM,IAAI,MACR,kRAIF;AACF"}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Whether `value` contains a `{ "$field": name }` or `{ "$field": name, "fallback": value }` reference within 64 levels.
|
|
3
|
-
*/
|
|
4
|
-
export declare const hasFieldReference: (value: unknown) => boolean;
|
|
5
|
-
/**
|
|
6
|
-
* Replaces each `{ "$field": name }` reference inside `value` with the own property `name` of `fields`, or with the reference's own `fallback` when that is `undefined`. A reference that still resolves to `undefined` is dropped from its object or array, and a cyclic reference or anything nested deeper than 64 levels is kept as is.
|
|
7
|
-
*/
|
|
8
|
-
export declare const resolveFieldReferences: (value: unknown, fields: Readonly<Record<string, unknown>>) => unknown;
|
|
9
|
-
//# sourceMappingURL=fieldReferences.d.ts.map
|