@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
|
@@ -1,268 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from "vitest";
|
|
2
|
-
import { generativeUIToJSX } from "./generativeUIToJSX";
|
|
3
|
-
|
|
4
|
-
describe("generativeUIToJSX pretty depth bound", () => {
|
|
5
|
-
it("tolerates children nested in arrays beyond the depth bound", () => {
|
|
6
|
-
let node: unknown = { $type: "Text", value: "leaf" };
|
|
7
|
-
for (let i = 0; i < 100; i++) node = [node];
|
|
8
|
-
expect(() =>
|
|
9
|
-
generativeUIToJSX({ $type: "Card", children: node }, { pretty: true }),
|
|
10
|
-
).not.toThrow();
|
|
11
|
-
});
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
describe("generativeUIToJSX", () => {
|
|
15
|
-
it("renders a leaf element as a self-closing tag", () => {
|
|
16
|
-
expect(generativeUIToJSX({ $type: "Weather", id: "5d99d2e9" })).toBe(
|
|
17
|
-
'<Weather id="5d99d2e9" />',
|
|
18
|
-
);
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
it("renders an element with no props", () => {
|
|
22
|
-
expect(generativeUIToJSX({ $type: "Divider" })).toBe("<Divider />");
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
it("formats prop types as JSX attributes", () => {
|
|
26
|
-
expect(
|
|
27
|
-
generativeUIToJSX({
|
|
28
|
-
$type: "Box",
|
|
29
|
-
label: "hi",
|
|
30
|
-
count: 3,
|
|
31
|
-
open: true,
|
|
32
|
-
hidden: false,
|
|
33
|
-
data: { a: 1 },
|
|
34
|
-
}),
|
|
35
|
-
).toBe('<Box label="hi" count={3} open hidden={false} data={{"a":1}} />');
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
it("uses the expression form for strings with quotes", () => {
|
|
39
|
-
expect(generativeUIToJSX({ $type: "Note", text: 'say "hi"' })).toBe(
|
|
40
|
-
'<Note text={"say \\"hi\\""} />',
|
|
41
|
-
);
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
it("emits a model-provided $key as the JSX key attribute", () => {
|
|
45
|
-
expect(
|
|
46
|
-
generativeUIToJSX({ $type: "Text", $key: "1:Text", children: "hello" }),
|
|
47
|
-
).toBe('<Text key="1:Text">hello</Text>');
|
|
48
|
-
expect(generativeUIToJSX({ $type: "Item", $key: 2 })).toBe(
|
|
49
|
-
"<Item key={2} />",
|
|
50
|
-
);
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
it("renders string children between tags", () => {
|
|
54
|
-
expect(
|
|
55
|
-
generativeUIToJSX({ $type: "Text", tone: "muted", children: "hello" }),
|
|
56
|
-
).toBe('<Text tone="muted">hello</Text>');
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
it("renders nested and arrayed children recursively", () => {
|
|
60
|
-
expect(
|
|
61
|
-
generativeUIToJSX({
|
|
62
|
-
$type: "Card",
|
|
63
|
-
title: "Hi",
|
|
64
|
-
children: [
|
|
65
|
-
{ $type: "Text", children: "a" },
|
|
66
|
-
{ $type: "Text", tone: "muted", children: "b" },
|
|
67
|
-
],
|
|
68
|
-
}),
|
|
69
|
-
).toBe('<Card title="Hi"><Text>a</Text><Text tone="muted">b</Text></Card>');
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
it("bounds deeply nested trees instead of overflowing the stack", () => {
|
|
73
|
-
let node: any = { $type: "Text", children: "deep" };
|
|
74
|
-
for (let i = 0; i < 5000; i++) node = { $type: "Card", children: node };
|
|
75
|
-
expect(() => generativeUIToJSX(node)).not.toThrow();
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
it("returns empty string for non-renderable nodes", () => {
|
|
79
|
-
expect(generativeUIToJSX(null)).toBe("");
|
|
80
|
-
expect(generativeUIToJSX(true)).toBe("");
|
|
81
|
-
expect(generativeUIToJSX({})).toBe(""); // no $type yet (still streaming)
|
|
82
|
-
});
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
describe("generativeUIToJSX with escape: true", () => {
|
|
86
|
-
it.each([false, true])(
|
|
87
|
-
"preserves literal entities in string props and keys with pretty=%s",
|
|
88
|
-
(pretty) => {
|
|
89
|
-
expect(
|
|
90
|
-
generativeUIToJSX(
|
|
91
|
-
{ $type: "Text", $key: "A", value: "& A A" },
|
|
92
|
-
{ escape: true, pretty },
|
|
93
|
-
),
|
|
94
|
-
).toBe('<Text key={"A"} value={"& A A"} />');
|
|
95
|
-
},
|
|
96
|
-
);
|
|
97
|
-
|
|
98
|
-
it("keeps entity spelling in the default display form", () => {
|
|
99
|
-
expect(generativeUIToJSX({ $type: "Text", value: "& A" })).toBe(
|
|
100
|
-
'<Text value="& A" />',
|
|
101
|
-
);
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
it("escapes a string child containing HTML-like tags", () => {
|
|
105
|
-
expect(
|
|
106
|
-
generativeUIToJSX(
|
|
107
|
-
{ $type: "Text", children: "<script>alert(1)</script>" },
|
|
108
|
-
{ escape: true },
|
|
109
|
-
),
|
|
110
|
-
).toBe('<Text>{"<script>alert(1)</script>"}</Text>');
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
it("escapes a string child containing braces", () => {
|
|
114
|
-
expect(
|
|
115
|
-
generativeUIToJSX(
|
|
116
|
-
{ $type: "Text", children: "a {b} c" },
|
|
117
|
-
{ escape: true },
|
|
118
|
-
),
|
|
119
|
-
).toBe('<Text>{"a {b} c"}</Text>');
|
|
120
|
-
});
|
|
121
|
-
|
|
122
|
-
it("escapes a string child containing an ampersand", () => {
|
|
123
|
-
expect(
|
|
124
|
-
generativeUIToJSX({ $type: "Text", children: "Q&A" }, { escape: true }),
|
|
125
|
-
).toBe('<Text>{"Q&A"}</Text>');
|
|
126
|
-
});
|
|
127
|
-
|
|
128
|
-
it("leaves a plain text child verbatim", () => {
|
|
129
|
-
expect(
|
|
130
|
-
generativeUIToJSX(
|
|
131
|
-
{ $type: "Text", children: "hello world" },
|
|
132
|
-
{ escape: true },
|
|
133
|
-
),
|
|
134
|
-
).toBe("<Text>hello world</Text>");
|
|
135
|
-
});
|
|
136
|
-
|
|
137
|
-
it("leaves numbers, arrays, and nested objects unaffected", () => {
|
|
138
|
-
expect(
|
|
139
|
-
generativeUIToJSX(
|
|
140
|
-
{
|
|
141
|
-
$type: "Card",
|
|
142
|
-
children: [
|
|
143
|
-
{ $type: "Text", children: 42 },
|
|
144
|
-
{ $type: "Text", data: { a: 1 }, children: "plain" },
|
|
145
|
-
],
|
|
146
|
-
},
|
|
147
|
-
{ escape: true },
|
|
148
|
-
),
|
|
149
|
-
).toBe('<Card><Text>42</Text><Text data={{"a":1}}>plain</Text></Card>');
|
|
150
|
-
});
|
|
151
|
-
});
|
|
152
|
-
|
|
153
|
-
describe("generativeUIToJSX with pretty: true", () => {
|
|
154
|
-
const nestedCard = {
|
|
155
|
-
$type: "Card",
|
|
156
|
-
title: "Hi",
|
|
157
|
-
children: [
|
|
158
|
-
{ $type: "Text", children: "a" },
|
|
159
|
-
{
|
|
160
|
-
$type: "Box",
|
|
161
|
-
children: { $type: "Text", tone: "muted", children: "b" },
|
|
162
|
-
},
|
|
163
|
-
],
|
|
164
|
-
};
|
|
165
|
-
|
|
166
|
-
it("keeps default output single-line and byte-identical without pretty", () => {
|
|
167
|
-
expect(generativeUIToJSX(nestedCard)).toBe(
|
|
168
|
-
'<Card title="Hi"><Text>a</Text><Box><Text tone="muted">b</Text></Box></Card>',
|
|
169
|
-
);
|
|
170
|
-
});
|
|
171
|
-
|
|
172
|
-
it("block-nests elements with two-space grandchild indentation", () => {
|
|
173
|
-
expect(generativeUIToJSX(nestedCard, { pretty: true })).toBe(
|
|
174
|
-
[
|
|
175
|
-
'<Card title="Hi">',
|
|
176
|
-
" <Text>a</Text>",
|
|
177
|
-
" <Box>",
|
|
178
|
-
' <Text tone="muted">b</Text>',
|
|
179
|
-
" </Box>",
|
|
180
|
-
"</Card>",
|
|
181
|
-
].join("\n"),
|
|
182
|
-
);
|
|
183
|
-
});
|
|
184
|
-
|
|
185
|
-
it("keeps elements with only string or number children on one line", () => {
|
|
186
|
-
expect(
|
|
187
|
-
generativeUIToJSX(
|
|
188
|
-
{ $type: "Text", tone: "muted", children: "hello" },
|
|
189
|
-
{ pretty: true },
|
|
190
|
-
),
|
|
191
|
-
).toBe('<Text tone="muted">hello</Text>');
|
|
192
|
-
expect(
|
|
193
|
-
generativeUIToJSX({ $type: "Text", children: 42 }, { pretty: true }),
|
|
194
|
-
).toBe("<Text>42</Text>");
|
|
195
|
-
expect(generativeUIToJSX({ $type: "Divider" }, { pretty: true })).toBe(
|
|
196
|
-
"<Divider />",
|
|
197
|
-
);
|
|
198
|
-
});
|
|
199
|
-
|
|
200
|
-
it("renders a root-level array with each item on its own line", () => {
|
|
201
|
-
expect(
|
|
202
|
-
generativeUIToJSX(
|
|
203
|
-
[
|
|
204
|
-
{ $type: "Text", children: "a" },
|
|
205
|
-
{ $type: "Text", children: "b" },
|
|
206
|
-
],
|
|
207
|
-
{ pretty: true },
|
|
208
|
-
),
|
|
209
|
-
).toBe("<Text>a</Text>\n<Text>b</Text>");
|
|
210
|
-
});
|
|
211
|
-
|
|
212
|
-
it("puts mixed text and element children each on their own line", () => {
|
|
213
|
-
expect(
|
|
214
|
-
generativeUIToJSX(
|
|
215
|
-
{
|
|
216
|
-
$type: "Card",
|
|
217
|
-
children: ["hello", { $type: "Text", children: "world" }, 7],
|
|
218
|
-
},
|
|
219
|
-
{ pretty: true },
|
|
220
|
-
),
|
|
221
|
-
).toBe(
|
|
222
|
-
["<Card>", " hello", " <Text>world</Text>", " 7", "</Card>"].join(
|
|
223
|
-
"\n",
|
|
224
|
-
),
|
|
225
|
-
);
|
|
226
|
-
});
|
|
227
|
-
|
|
228
|
-
it("skips non-renderable children without blank lines", () => {
|
|
229
|
-
expect(
|
|
230
|
-
generativeUIToJSX(
|
|
231
|
-
{
|
|
232
|
-
$type: "Card",
|
|
233
|
-
children: [
|
|
234
|
-
null,
|
|
235
|
-
{ $type: "Text", children: "a" },
|
|
236
|
-
false,
|
|
237
|
-
{ $type: "Text", children: "b" },
|
|
238
|
-
true,
|
|
239
|
-
],
|
|
240
|
-
},
|
|
241
|
-
{ pretty: true },
|
|
242
|
-
),
|
|
243
|
-
).toBe(
|
|
244
|
-
["<Card>", " <Text>a</Text>", " <Text>b</Text>", "</Card>"].join("\n"),
|
|
245
|
-
);
|
|
246
|
-
});
|
|
247
|
-
|
|
248
|
-
it("composes escape with pretty", () => {
|
|
249
|
-
expect(
|
|
250
|
-
generativeUIToJSX(
|
|
251
|
-
{
|
|
252
|
-
$type: "Card",
|
|
253
|
-
children: {
|
|
254
|
-
$type: "Text",
|
|
255
|
-
children: "<script>alert(1)</script>",
|
|
256
|
-
},
|
|
257
|
-
},
|
|
258
|
-
{ escape: true, pretty: true },
|
|
259
|
-
),
|
|
260
|
-
).toBe(
|
|
261
|
-
[
|
|
262
|
-
"<Card>",
|
|
263
|
-
' <Text>{"<script>alert(1)</script>"}</Text>',
|
|
264
|
-
"</Card>",
|
|
265
|
-
].join("\n"),
|
|
266
|
-
);
|
|
267
|
-
});
|
|
268
|
-
});
|
package/src/generativeUIToJSX.ts
DELETED
|
@@ -1,152 +0,0 @@
|
|
|
1
|
-
import { TYPE_KEY } from "./constants";
|
|
2
|
-
|
|
3
|
-
/** Options for {@link generativeUIToJSX}. */
|
|
4
|
-
export interface GenerativeUIToJSXOptions {
|
|
5
|
-
/** Escape string children so the output is safe to paste back into a JSX file. Defaults to `false`. */
|
|
6
|
-
escape?: boolean;
|
|
7
|
-
/** Pretty-print nested element trees with two-space indentation. Defaults to `false`. */
|
|
8
|
-
pretty?: boolean;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Serializes a generative-UI node to a JSX-like string for display: the "view source" of a model-produced tree. The wire form `{ $type: "Weather", id: "x" }` becomes `<Weather id="x" />`, and nested `children` render between tags: `<Card title="Hi"><Text>hello</Text></Card>`. A model-provided `$key` becomes the JSX `key` attribute.
|
|
13
|
-
*
|
|
14
|
-
* By default this is a faithful textual rendering, not a parser: text children are emitted verbatim (not HTML/JSX-escaped), so the result is meant to be shown, not re-parsed. Returns `""` for nodes that aren't renderable (no `$type` yet, `null`, booleans).
|
|
15
|
-
*
|
|
16
|
-
* Pass `{ escape: true }` to make the output safe to paste back into JSX: any string child containing `<`, `>`, `&`, `{`, or `}` is emitted as a JSON-stringified expression (`{JSON.stringify(child)}`) instead of verbatim, while a string child with none of those characters still renders verbatim.
|
|
17
|
-
*
|
|
18
|
-
* Pass `{ pretty: true }` to pretty-print nested element trees with two-space indentation, while pure text children stay on one line.
|
|
19
|
-
*/
|
|
20
|
-
export function generativeUIToJSX(
|
|
21
|
-
node: unknown,
|
|
22
|
-
options?: GenerativeUIToJSXOptions,
|
|
23
|
-
): string {
|
|
24
|
-
return toJSX(node, 0, options?.escape ?? false, options?.pretty ?? false, 0);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* The deepest tree we serialize. Input is model-produced, so a runaway/
|
|
29
|
-
* adversarial response could nest arbitrarily deep and overflow the stack — past
|
|
30
|
-
* this depth (far beyond any real UI) we stop. Mirrors the renderer's bound.
|
|
31
|
-
*/
|
|
32
|
-
const MAX_DEPTH = 64;
|
|
33
|
-
|
|
34
|
-
/** Characters that would break JSX if emitted verbatim inside a text child. */
|
|
35
|
-
const UNSAFE_CHILD_CHARS = /[<>&{}]/;
|
|
36
|
-
|
|
37
|
-
function toJSX(
|
|
38
|
-
node: unknown,
|
|
39
|
-
depth: number,
|
|
40
|
-
escape: boolean,
|
|
41
|
-
pretty: boolean,
|
|
42
|
-
indent: number,
|
|
43
|
-
): string {
|
|
44
|
-
if (depth > MAX_DEPTH) return "";
|
|
45
|
-
if (node == null || typeof node === "boolean") return "";
|
|
46
|
-
if (typeof node === "string") return formatChildText(node, escape);
|
|
47
|
-
if (typeof node === "number") return String(node);
|
|
48
|
-
if (Array.isArray(node)) {
|
|
49
|
-
if (pretty) {
|
|
50
|
-
return collectBlockLines(node, depth, escape, indent).join("\n");
|
|
51
|
-
}
|
|
52
|
-
return node
|
|
53
|
-
.map((child) => toJSX(child, depth + 1, escape, false, 0))
|
|
54
|
-
.join("");
|
|
55
|
-
}
|
|
56
|
-
if (typeof node !== "object") return "";
|
|
57
|
-
|
|
58
|
-
const {
|
|
59
|
-
[TYPE_KEY]: type,
|
|
60
|
-
$key,
|
|
61
|
-
children,
|
|
62
|
-
...props
|
|
63
|
-
} = node as Record<string, unknown>;
|
|
64
|
-
if (typeof type !== "string") return "";
|
|
65
|
-
|
|
66
|
-
const attrs =
|
|
67
|
-
formatAttr("key", $key, escape) +
|
|
68
|
-
Object.entries(props)
|
|
69
|
-
.map(([key, value]) => formatAttr(key, value, escape))
|
|
70
|
-
.join("");
|
|
71
|
-
|
|
72
|
-
if (!pretty) {
|
|
73
|
-
const inner =
|
|
74
|
-
children === undefined
|
|
75
|
-
? ""
|
|
76
|
-
: toJSX(children, depth + 1, escape, false, 0);
|
|
77
|
-
|
|
78
|
-
return inner === ""
|
|
79
|
-
? `<${type}${attrs} />`
|
|
80
|
-
: `<${type}${attrs}>${inner}</${type}>`;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
const pad = " ".repeat(indent);
|
|
84
|
-
|
|
85
|
-
if (children === undefined || !hasElementChild(children)) {
|
|
86
|
-
const inner =
|
|
87
|
-
children === undefined
|
|
88
|
-
? ""
|
|
89
|
-
: toJSX(children, depth + 1, escape, false, 0);
|
|
90
|
-
return inner === ""
|
|
91
|
-
? `${pad}<${type}${attrs} />`
|
|
92
|
-
: `${pad}<${type}${attrs}>${inner}</${type}>`;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
const lines = collectBlockLines(children, depth + 1, escape, indent + 1);
|
|
96
|
-
if (lines.length === 0) {
|
|
97
|
-
return `${pad}<${type}${attrs} />`;
|
|
98
|
-
}
|
|
99
|
-
return `${pad}<${type}${attrs}>\n${lines.join("\n")}\n${pad}</${type}>`;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
function hasElementChild(node: unknown, depth = 0): boolean {
|
|
103
|
-
if (depth > MAX_DEPTH) return false;
|
|
104
|
-
if (Array.isArray(node))
|
|
105
|
-
return node.some((child) => hasElementChild(child, depth + 1));
|
|
106
|
-
return (
|
|
107
|
-
node != null &&
|
|
108
|
-
typeof node === "object" &&
|
|
109
|
-
typeof (node as Record<string, unknown>)[TYPE_KEY] === "string"
|
|
110
|
-
);
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
function collectBlockLines(
|
|
114
|
-
node: unknown,
|
|
115
|
-
depth: number,
|
|
116
|
-
escape: boolean,
|
|
117
|
-
indent: number,
|
|
118
|
-
): string[] {
|
|
119
|
-
if (depth > MAX_DEPTH) return [];
|
|
120
|
-
if (node == null || typeof node === "boolean") return [];
|
|
121
|
-
if (Array.isArray(node)) {
|
|
122
|
-
return node.flatMap((child) =>
|
|
123
|
-
collectBlockLines(child, depth + 1, escape, indent),
|
|
124
|
-
);
|
|
125
|
-
}
|
|
126
|
-
if (typeof node === "string") {
|
|
127
|
-
return [`${" ".repeat(indent)}${formatChildText(node, escape)}`];
|
|
128
|
-
}
|
|
129
|
-
if (typeof node === "number") {
|
|
130
|
-
return [`${" ".repeat(indent)}${String(node)}`];
|
|
131
|
-
}
|
|
132
|
-
const rendered = toJSX(node, depth, escape, true, indent);
|
|
133
|
-
return rendered === "" ? [] : [rendered];
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
function formatChildText(value: string, escape: boolean): string {
|
|
137
|
-
return escape && UNSAFE_CHILD_CHARS.test(value)
|
|
138
|
-
? `{${JSON.stringify(value)}}`
|
|
139
|
-
: value;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
/** Formats one prop as a JSX attribute (`id="x"`, `count={3}`, `open`, …). */
|
|
143
|
-
function formatAttr(key: string, value: unknown, escape: boolean): string {
|
|
144
|
-
if (value === undefined) return "";
|
|
145
|
-
if (value === true) return ` ${key}`;
|
|
146
|
-
if (typeof value === "string") {
|
|
147
|
-
return /["\n]/.test(value) || (escape && value.includes("&"))
|
|
148
|
-
? ` ${key}={${JSON.stringify(value)}}`
|
|
149
|
-
: ` ${key}="${value}"`;
|
|
150
|
-
}
|
|
151
|
-
return ` ${key}={${JSON.stringify(value)}}`;
|
|
152
|
-
}
|
package/src/index.server.test.ts
DELETED
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
/// <reference types="node" />
|
|
2
|
-
import { describe, expect, it } from "vitest";
|
|
3
|
-
import { existsSync, readFileSync, statSync } from "node:fs";
|
|
4
|
-
import { dirname, join, relative, resolve } from "node:path";
|
|
5
|
-
|
|
6
|
-
const SRC_DIR = resolve(__dirname);
|
|
7
|
-
|
|
8
|
-
// Next.js fails the build when a module reachable from a Server Component
|
|
9
|
-
// names one of these React APIs in an import; the namespace import is allowed.
|
|
10
|
-
const CLIENT_ONLY_REACT_APIS = new Set([
|
|
11
|
-
"Component",
|
|
12
|
-
"PureComponent",
|
|
13
|
-
"createContext",
|
|
14
|
-
"createFactory",
|
|
15
|
-
"useActionState",
|
|
16
|
-
"useEffect",
|
|
17
|
-
"useEffectEvent",
|
|
18
|
-
"useImperativeHandle",
|
|
19
|
-
"useInsertionEffect",
|
|
20
|
-
"useLayoutEffect",
|
|
21
|
-
"useOptimistic",
|
|
22
|
-
"useReducer",
|
|
23
|
-
"useRef",
|
|
24
|
-
"useState",
|
|
25
|
-
"useSyncExternalStore",
|
|
26
|
-
"useTransition",
|
|
27
|
-
]);
|
|
28
|
-
|
|
29
|
-
const RELATIVE_SPECIFIER_RE = /\b(?:from|import)\s*\(?\s*["'](\.[^"']*)["']/g;
|
|
30
|
-
|
|
31
|
-
const NAMED_FROM_REACT_RE =
|
|
32
|
-
/(?:import|export)\s+(type\s+)?(?:\w+\s*,\s*)?\{([^}]*)\}\s+from\s+["']react["']/g;
|
|
33
|
-
|
|
34
|
-
function resolveRelative(fromFile: string, spec: string): string | undefined {
|
|
35
|
-
const base = resolve(dirname(fromFile), spec);
|
|
36
|
-
return [
|
|
37
|
-
base,
|
|
38
|
-
`${base}.ts`,
|
|
39
|
-
`${base}.tsx`,
|
|
40
|
-
join(base, "index.ts"),
|
|
41
|
-
join(base, "index.tsx"),
|
|
42
|
-
].find((candidate) => existsSync(candidate) && statSync(candidate).isFile());
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
function collectGraph(entry: string): Set<string> {
|
|
46
|
-
const visited = new Set<string>();
|
|
47
|
-
const pending = [entry];
|
|
48
|
-
while (pending.length > 0) {
|
|
49
|
-
const file = pending.pop()!;
|
|
50
|
-
if (visited.has(file)) continue;
|
|
51
|
-
visited.add(file);
|
|
52
|
-
for (const [, spec] of readFileSync(file, "utf8").matchAll(
|
|
53
|
-
RELATIVE_SPECIFIER_RE,
|
|
54
|
-
)) {
|
|
55
|
-
const resolved = resolveRelative(file, spec!);
|
|
56
|
-
if (resolved) pending.push(resolved);
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
return visited;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
function clientOnlyReactImports(file: string): string[] {
|
|
63
|
-
const names: string[] = [];
|
|
64
|
-
for (const [, typeOnly, specifiers] of readFileSync(file, "utf8").matchAll(
|
|
65
|
-
NAMED_FROM_REACT_RE,
|
|
66
|
-
)) {
|
|
67
|
-
if (typeOnly) continue;
|
|
68
|
-
for (const specifier of specifiers!.split(",")) {
|
|
69
|
-
const name = specifier.trim().split(/\s+as\s+/)[0]!;
|
|
70
|
-
if (CLIENT_ONLY_REACT_APIS.has(name)) names.push(name);
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
return names;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
// Server code reaches every entry: the subpaths carry no react-server
|
|
77
|
-
// condition, and the docs app resolves the root to its source through
|
|
78
|
-
// tsconfig paths, which skip that condition.
|
|
79
|
-
const ENTRIES = [
|
|
80
|
-
"index.server.ts",
|
|
81
|
-
"index.ts",
|
|
82
|
-
"ir.ts",
|
|
83
|
-
"a2ui.ts",
|
|
84
|
-
"slack.ts",
|
|
85
|
-
"teams.ts",
|
|
86
|
-
];
|
|
87
|
-
|
|
88
|
-
describe("published entries", () => {
|
|
89
|
-
const graph = new Set(
|
|
90
|
-
ENTRIES.flatMap((entry) => [...collectGraph(join(SRC_DIR, entry))]),
|
|
91
|
-
);
|
|
92
|
-
|
|
93
|
-
it("reach the vocabulary and the client renderer", () => {
|
|
94
|
-
expect(graph).toContain(join(SRC_DIR, "vocabulary", "interactive.tsx"));
|
|
95
|
-
expect(graph).toContain(join(SRC_DIR, "JSONGenerativeUI.client.tsx"));
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
it("never name a client-only React API in an import", () => {
|
|
99
|
-
const violations = [...graph].flatMap((file) =>
|
|
100
|
-
clientOnlyReactImports(file).map(
|
|
101
|
-
(name) => `${relative(SRC_DIR, file)}: ${name}`,
|
|
102
|
-
),
|
|
103
|
-
);
|
|
104
|
-
expect(violations).toEqual([]);
|
|
105
|
-
});
|
|
106
|
-
});
|
package/src/index.shared.ts
DELETED
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
export { renderGenerativeUI } from "./renderGenerativeUI";
|
|
2
|
-
export { generativeUIToJSX } from "./generativeUIToJSX";
|
|
3
|
-
export type { GenerativeUIToJSXOptions } from "./generativeUIToJSX";
|
|
4
|
-
export { buildPresentParameters } from "./buildPresentParameters";
|
|
5
|
-
export { defineGenerativeComponents } from "./defineGenerativeComponents";
|
|
6
|
-
export { TYPE_KEY } from "./constants";
|
|
7
|
-
export { normalizeUINode, normalizeSpec } from "./ir";
|
|
8
|
-
export {
|
|
9
|
-
TEXT_SIZES,
|
|
10
|
-
IMAGE_SIZE_TOKENS,
|
|
11
|
-
WEIGHTS,
|
|
12
|
-
COLORS,
|
|
13
|
-
ALIGNS,
|
|
14
|
-
JUSTIFIES,
|
|
15
|
-
BUTTON_STYLES,
|
|
16
|
-
ALERT_TONES,
|
|
17
|
-
ICON_NAMES,
|
|
18
|
-
} from "./ir";
|
|
19
|
-
export { defaultGenerativeUILibrary } from "./vocabulary";
|
|
20
|
-
export { createActionRegistry, emptyActionRegistry } from "./actionRegistry";
|
|
21
|
-
export type {
|
|
22
|
-
ActionHandler,
|
|
23
|
-
ActionRegistry,
|
|
24
|
-
ActionDispatchContext,
|
|
25
|
-
} from "./actionRegistry";
|
|
26
|
-
export type {
|
|
27
|
-
JSONGenerativeUIOptions,
|
|
28
|
-
PresentTool,
|
|
29
|
-
PresentToolOptions,
|
|
30
|
-
PromptUserTool,
|
|
31
|
-
} from "./JSONGenerativeUI.shared";
|
|
32
|
-
export type {
|
|
33
|
-
GenerativeUILibrary,
|
|
34
|
-
GenerativeUIComponent,
|
|
35
|
-
GenerativeUIElement,
|
|
36
|
-
GenerativeUIProps,
|
|
37
|
-
GenerativeUINode,
|
|
38
|
-
GenerativeUIStatus,
|
|
39
|
-
GenerativeUIRenderContext,
|
|
40
|
-
GenerativeUIAction,
|
|
41
|
-
GenerativeUIDispatch,
|
|
42
|
-
} from "./types";
|
|
43
|
-
export type {
|
|
44
|
-
UINode,
|
|
45
|
-
UIElement,
|
|
46
|
-
UIChildren,
|
|
47
|
-
LegacyComponentNode,
|
|
48
|
-
Action,
|
|
49
|
-
UISpec,
|
|
50
|
-
NormalizedUINode,
|
|
51
|
-
NormalizedUIElement,
|
|
52
|
-
TextSize,
|
|
53
|
-
ImageSize,
|
|
54
|
-
Weight,
|
|
55
|
-
Color,
|
|
56
|
-
Align,
|
|
57
|
-
Justify,
|
|
58
|
-
ButtonStyle,
|
|
59
|
-
AlertTone,
|
|
60
|
-
IconName,
|
|
61
|
-
} from "./ir";
|