@zhama/a2ui-core 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 +161 -0
- package/dist/builders/index.cjs +496 -0
- package/dist/builders/index.cjs.map +1 -0
- package/dist/builders/index.d.cts +538 -0
- package/dist/builders/index.d.ts +538 -0
- package/dist/builders/index.js +445 -0
- package/dist/builders/index.js.map +1 -0
- package/dist/index.cjs +869 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +43 -0
- package/dist/index.d.ts +43 -0
- package/dist/index.js +802 -0
- package/dist/index.js.map +1 -0
- package/dist/types/index.cjs +22 -0
- package/dist/types/index.cjs.map +1 -0
- package/dist/types/index.d.cts +711 -0
- package/dist/types/index.d.ts +711 -0
- package/dist/types/index.js +15 -0
- package/dist/types/index.js.map +1 -0
- package/dist/validators/index.cjs +313 -0
- package/dist/validators/index.cjs.map +1 -0
- package/dist/validators/index.d.cts +68 -0
- package/dist/validators/index.d.ts +68 -0
- package/dist/validators/index.js +308 -0
- package/dist/validators/index.js.map +1 -0
- package/package.json +89 -0
package/README.md
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
# @zhama/a2ui-core
|
|
2
|
+
|
|
3
|
+
A2UI Protocol Core Library - Framework-agnostic TypeScript types and builders for A2UI protocol.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
A2UI (Agent to UI) is a JSON-based streaming UI protocol for dynamically rendering user interfaces. This library provides:
|
|
8
|
+
|
|
9
|
+
- **Types**: Complete TypeScript type definitions for A2UI v0.8 and v0.9
|
|
10
|
+
- **Builders**: Convenient functions to build messages and components
|
|
11
|
+
- **Validators**: Message validation utilities
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install @zhama/a2ui-core
|
|
17
|
+
# or
|
|
18
|
+
pnpm add @zhama/a2ui-core
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Quick Start
|
|
22
|
+
|
|
23
|
+
```typescript
|
|
24
|
+
import {
|
|
25
|
+
// Builders
|
|
26
|
+
text, column, button, card,
|
|
27
|
+
createSurface, updateComponents, updateDataModel,
|
|
28
|
+
createV09Messages,
|
|
29
|
+
|
|
30
|
+
// Validators
|
|
31
|
+
validateMessage,
|
|
32
|
+
|
|
33
|
+
// Utils
|
|
34
|
+
path, generateId,
|
|
35
|
+
|
|
36
|
+
// Types
|
|
37
|
+
type ComponentInstance,
|
|
38
|
+
type ServerToClientMessage,
|
|
39
|
+
} from '@zhama/a2ui-core';
|
|
40
|
+
|
|
41
|
+
// Create components
|
|
42
|
+
const title = text('Hello World', { id: 'title', usageHint: 'h1' });
|
|
43
|
+
const greeting = text({ path: '/user/name' }, { id: 'greeting' });
|
|
44
|
+
const root = column(['title', 'greeting'], { id: 'root' });
|
|
45
|
+
|
|
46
|
+
// Create messages
|
|
47
|
+
const messages = createV09Messages({
|
|
48
|
+
surfaceId: 'my-surface',
|
|
49
|
+
components: [title, greeting, root],
|
|
50
|
+
dataModel: { user: { name: 'John' } },
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
// Validate messages
|
|
54
|
+
const result = validateMessage(messages[0]);
|
|
55
|
+
console.log(result.valid); // true
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## API Reference
|
|
59
|
+
|
|
60
|
+
### Types
|
|
61
|
+
|
|
62
|
+
#### Primitives
|
|
63
|
+
- `StringOrPath` - String literal or data path binding
|
|
64
|
+
- `NumberOrPath` - Number literal or data path binding
|
|
65
|
+
- `BooleanOrPath` - Boolean literal or data path binding
|
|
66
|
+
|
|
67
|
+
#### Components
|
|
68
|
+
- `TextComponent`, `ImageComponent`, `IconComponent`, `VideoComponent`, `AudioPlayerComponent`
|
|
69
|
+
- `RowComponent`, `ColumnComponent`, `ListComponent`, `CardComponent`
|
|
70
|
+
- `TabsComponent`, `DividerComponent`, `ModalComponent`
|
|
71
|
+
- `ButtonComponent`, `CheckBoxComponent`, `TextFieldComponent`
|
|
72
|
+
- `DateTimeInputComponent`, `ChoicePickerComponent`, `SliderComponent`
|
|
73
|
+
|
|
74
|
+
#### Messages
|
|
75
|
+
- `CreateSurfaceMessage`, `UpdateComponentsMessage`, `UpdateDataModelMessage`, `DeleteSurfaceMessage` (v0.9)
|
|
76
|
+
- `BeginRenderingMessage`, `SurfaceUpdateMessage`, `DataModelUpdateMessage` (v0.8)
|
|
77
|
+
|
|
78
|
+
### Builders
|
|
79
|
+
|
|
80
|
+
#### Component Builders
|
|
81
|
+
```typescript
|
|
82
|
+
// Content components
|
|
83
|
+
text(content: StringOrPath, options?: TextOptions): ComponentInstance
|
|
84
|
+
image(url: StringOrPath, options?: ImageOptions): ComponentInstance
|
|
85
|
+
icon(name: StringOrPath, options?: IconOptions): ComponentInstance
|
|
86
|
+
|
|
87
|
+
// Layout components
|
|
88
|
+
row(children: ChildrenProperty, options?: LayoutOptions): ComponentInstance
|
|
89
|
+
column(children: ChildrenProperty, options?: LayoutOptions): ComponentInstance
|
|
90
|
+
card(childId: string, options?: CardOptions): ComponentInstance
|
|
91
|
+
|
|
92
|
+
// Interactive components
|
|
93
|
+
button(childId: string, action: Action, options?: ButtonOptions): ComponentInstance
|
|
94
|
+
textField(label: StringOrPath, text?: StringOrPath, options?: TextFieldOptions): ComponentInstance
|
|
95
|
+
|
|
96
|
+
// Convenience
|
|
97
|
+
textButton(buttonText: string, action: Action, options?: ButtonOptions): [ComponentInstance, ComponentInstance]
|
|
98
|
+
h1(content: StringOrPath, options?: TextOptions): ComponentInstance
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
#### Message Builders
|
|
102
|
+
```typescript
|
|
103
|
+
// v0.9
|
|
104
|
+
createSurface(surfaceId: string, catalogId?: string): CreateSurfaceMessage
|
|
105
|
+
updateComponents(surfaceId: string, components: ComponentInstance[]): UpdateComponentsMessage
|
|
106
|
+
updateDataModel(surfaceId: string, value: unknown, path?: string): UpdateDataModelMessage
|
|
107
|
+
deleteSurface(surfaceId: string): DeleteSurfaceMessage
|
|
108
|
+
createV09Messages(options: CreateV09Options): ServerToClientMessageV09[]
|
|
109
|
+
|
|
110
|
+
// v0.8
|
|
111
|
+
beginRendering(rootId: string, surfaceId?: string, styles?: Record<string, string>): BeginRenderingMessage
|
|
112
|
+
surfaceUpdate(components: ComponentInstanceV08[], surfaceId?: string): SurfaceUpdateMessage
|
|
113
|
+
dataModelUpdate(contents: ValueMap[], surfaceId?: string): DataModelUpdateMessage
|
|
114
|
+
createV08Messages(options: CreateV08Options): ServerToClientMessageV08[]
|
|
115
|
+
|
|
116
|
+
// Utilities
|
|
117
|
+
messagesToJsonl(messages: ServerToClientMessage[]): string
|
|
118
|
+
jsonlToMessages(jsonl: string): ServerToClientMessage[]
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
#### Data Model Builders
|
|
122
|
+
```typescript
|
|
123
|
+
objectToValueMap(obj: DataObject): ValueMap[]
|
|
124
|
+
valueToValueMap(key: string, value: DataValue): ValueMap
|
|
125
|
+
valueMapToObject(valueMaps: ValueMap[]): DataObject
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### Validators
|
|
129
|
+
|
|
130
|
+
```typescript
|
|
131
|
+
validateMessage(message: ServerToClientMessage, options?: ValidationOptions): ValidationResult
|
|
132
|
+
validateMessages(messages: ServerToClientMessage[], options?: ValidationOptions): ValidationResult
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### Utils
|
|
136
|
+
|
|
137
|
+
```typescript
|
|
138
|
+
path(dataPath: string): { path: string } // Create data binding
|
|
139
|
+
isPathBinding(value): boolean // Check if value is a path binding
|
|
140
|
+
generateId(prefix?: string): string // Generate unique ID
|
|
141
|
+
uuid(): string // Generate UUID v4
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## Protocol Versions
|
|
145
|
+
|
|
146
|
+
### v0.9 (Prompt-first)
|
|
147
|
+
- `createSurface` - Create a new surface
|
|
148
|
+
- `updateComponents` - Update components with flat component list
|
|
149
|
+
- `updateDataModel` - Update data model
|
|
150
|
+
- `deleteSurface` - Delete surface
|
|
151
|
+
|
|
152
|
+
### v0.8 (Structured output)
|
|
153
|
+
- `beginRendering` - Signal to begin rendering
|
|
154
|
+
- `surfaceUpdate` - Update components
|
|
155
|
+
- `dataModelUpdate` - Update data model using ValueMap format
|
|
156
|
+
- `deleteSurface` - Delete surface
|
|
157
|
+
|
|
158
|
+
## License
|
|
159
|
+
|
|
160
|
+
MIT
|
|
161
|
+
|
|
@@ -0,0 +1,496 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// src/builders/id-generator.ts
|
|
4
|
+
var componentIdCounter = 0;
|
|
5
|
+
function generateId(prefix = "comp") {
|
|
6
|
+
return `${prefix}_${Date.now()}_${componentIdCounter++}`;
|
|
7
|
+
}
|
|
8
|
+
function resetIdCounter() {
|
|
9
|
+
componentIdCounter = 0;
|
|
10
|
+
}
|
|
11
|
+
function getIdCounter() {
|
|
12
|
+
return componentIdCounter;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// src/builders/component-builder.ts
|
|
16
|
+
function text(content, options = {}) {
|
|
17
|
+
const { id = generateId("text"), weight, usageHint } = options;
|
|
18
|
+
return {
|
|
19
|
+
id,
|
|
20
|
+
component: "Text",
|
|
21
|
+
text: content,
|
|
22
|
+
...weight !== void 0 && { weight },
|
|
23
|
+
...usageHint && { usageHint }
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
function image(url, options = {}) {
|
|
27
|
+
const { id = generateId("image"), weight, fit, usageHint } = options;
|
|
28
|
+
return {
|
|
29
|
+
id,
|
|
30
|
+
component: "Image",
|
|
31
|
+
url,
|
|
32
|
+
...weight !== void 0 && { weight },
|
|
33
|
+
...fit && { fit },
|
|
34
|
+
...usageHint && { usageHint }
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
function icon(name, options = {}) {
|
|
38
|
+
const { id = generateId("icon"), weight } = options;
|
|
39
|
+
return {
|
|
40
|
+
id,
|
|
41
|
+
component: "Icon",
|
|
42
|
+
name,
|
|
43
|
+
...weight !== void 0 && { weight }
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
function video(url, options = {}) {
|
|
47
|
+
const { id = generateId("video"), weight } = options;
|
|
48
|
+
return {
|
|
49
|
+
id,
|
|
50
|
+
component: "Video",
|
|
51
|
+
url,
|
|
52
|
+
...weight !== void 0 && { weight }
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
function audioPlayer(url, options = {}) {
|
|
56
|
+
const { id = generateId("audio"), weight, description } = options;
|
|
57
|
+
return {
|
|
58
|
+
id,
|
|
59
|
+
component: "AudioPlayer",
|
|
60
|
+
url,
|
|
61
|
+
...weight !== void 0 && { weight },
|
|
62
|
+
...description && { description }
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
function row(children, options = {}) {
|
|
66
|
+
const { id = generateId("row"), weight, alignment, distribution } = options;
|
|
67
|
+
return {
|
|
68
|
+
id,
|
|
69
|
+
component: "Row",
|
|
70
|
+
children,
|
|
71
|
+
...weight !== void 0 && { weight },
|
|
72
|
+
...alignment && { alignment },
|
|
73
|
+
...distribution && { distribution }
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
function column(children, options = {}) {
|
|
77
|
+
const { id = generateId("column"), weight, alignment, distribution } = options;
|
|
78
|
+
return {
|
|
79
|
+
id,
|
|
80
|
+
component: "Column",
|
|
81
|
+
children,
|
|
82
|
+
...weight !== void 0 && { weight },
|
|
83
|
+
...alignment && { alignment },
|
|
84
|
+
...distribution && { distribution }
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
function list(children, options = {}) {
|
|
88
|
+
const { id = generateId("list"), weight, direction, alignment } = options;
|
|
89
|
+
return {
|
|
90
|
+
id,
|
|
91
|
+
component: "List",
|
|
92
|
+
children,
|
|
93
|
+
...weight !== void 0 && { weight },
|
|
94
|
+
...direction && { direction },
|
|
95
|
+
...alignment && { alignment }
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
function card(childId, options = {}) {
|
|
99
|
+
const { id = generateId("card"), weight } = options;
|
|
100
|
+
return {
|
|
101
|
+
id,
|
|
102
|
+
component: "Card",
|
|
103
|
+
child: childId,
|
|
104
|
+
...weight !== void 0 && { weight }
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
function tabs(items, options = {}) {
|
|
108
|
+
const { id = generateId("tabs"), weight } = options;
|
|
109
|
+
return {
|
|
110
|
+
id,
|
|
111
|
+
component: "Tabs",
|
|
112
|
+
tabItems: items.map((item) => ({
|
|
113
|
+
title: item.title,
|
|
114
|
+
child: item.childId
|
|
115
|
+
})),
|
|
116
|
+
...weight !== void 0 && { weight }
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
function divider(options = {}) {
|
|
120
|
+
const { id = generateId("divider"), weight, axis } = options;
|
|
121
|
+
return {
|
|
122
|
+
id,
|
|
123
|
+
component: "Divider",
|
|
124
|
+
...weight !== void 0 && { weight },
|
|
125
|
+
...axis && { axis }
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
function modal(entryPointChildId, contentChildId, options = {}) {
|
|
129
|
+
const { id = generateId("modal"), weight } = options;
|
|
130
|
+
return {
|
|
131
|
+
id,
|
|
132
|
+
component: "Modal",
|
|
133
|
+
entryPointChild: entryPointChildId,
|
|
134
|
+
contentChild: contentChildId,
|
|
135
|
+
...weight !== void 0 && { weight }
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
function button(childId, action, options = {}) {
|
|
139
|
+
const { id = generateId("button"), weight, primary } = options;
|
|
140
|
+
return {
|
|
141
|
+
id,
|
|
142
|
+
component: "Button",
|
|
143
|
+
child: childId,
|
|
144
|
+
action,
|
|
145
|
+
...weight !== void 0 && { weight },
|
|
146
|
+
...primary !== void 0 && { primary }
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
function checkbox(label, value, options = {}) {
|
|
150
|
+
const { id = generateId("checkbox"), weight } = options;
|
|
151
|
+
return {
|
|
152
|
+
id,
|
|
153
|
+
component: "CheckBox",
|
|
154
|
+
label,
|
|
155
|
+
value,
|
|
156
|
+
...weight !== void 0 && { weight }
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
function textField(label, textValue, options = {}) {
|
|
160
|
+
const { id = generateId("textfield"), weight, usageHint, validationRegexp } = options;
|
|
161
|
+
return {
|
|
162
|
+
id,
|
|
163
|
+
component: "TextField",
|
|
164
|
+
label,
|
|
165
|
+
...textValue !== void 0 && { text: textValue },
|
|
166
|
+
...weight !== void 0 && { weight },
|
|
167
|
+
...usageHint && { usageHint },
|
|
168
|
+
...validationRegexp && { validationRegexp }
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
function dateTimeInput(value, options = {}) {
|
|
172
|
+
const { id = generateId("datetime"), weight, enableDate, enableTime, outputFormat, label } = options;
|
|
173
|
+
return {
|
|
174
|
+
id,
|
|
175
|
+
component: "DateTimeInput",
|
|
176
|
+
value,
|
|
177
|
+
...weight !== void 0 && { weight },
|
|
178
|
+
...enableDate !== void 0 && { enableDate },
|
|
179
|
+
...enableTime !== void 0 && { enableTime },
|
|
180
|
+
...outputFormat && { outputFormat },
|
|
181
|
+
...label && { label }
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
function choicePicker(optionsList, value, usageHint, options = {}) {
|
|
185
|
+
const { id = generateId("choice"), weight, label } = options;
|
|
186
|
+
return {
|
|
187
|
+
id,
|
|
188
|
+
component: "ChoicePicker",
|
|
189
|
+
options: optionsList,
|
|
190
|
+
value,
|
|
191
|
+
usageHint,
|
|
192
|
+
...weight !== void 0 && { weight },
|
|
193
|
+
...label && { label }
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
function slider(value, options = {}) {
|
|
197
|
+
const { id = generateId("slider"), weight, label, min, max } = options;
|
|
198
|
+
return {
|
|
199
|
+
id,
|
|
200
|
+
component: "Slider",
|
|
201
|
+
value,
|
|
202
|
+
...weight !== void 0 && { weight },
|
|
203
|
+
...label && { label },
|
|
204
|
+
...min !== void 0 && { min },
|
|
205
|
+
...max !== void 0 && { max }
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
function textButton(buttonText, action, options = {}) {
|
|
209
|
+
const textId = options.textId ?? generateId("btn_text");
|
|
210
|
+
const textComp = text(buttonText, { id: textId });
|
|
211
|
+
const buttonComp = button(textId, action, options);
|
|
212
|
+
return [textComp, buttonComp];
|
|
213
|
+
}
|
|
214
|
+
function h1(content, options = {}) {
|
|
215
|
+
return text(content, { ...options, usageHint: "h1" });
|
|
216
|
+
}
|
|
217
|
+
function h2(content, options = {}) {
|
|
218
|
+
return text(content, { ...options, usageHint: "h2" });
|
|
219
|
+
}
|
|
220
|
+
function h3(content, options = {}) {
|
|
221
|
+
return text(content, { ...options, usageHint: "h3" });
|
|
222
|
+
}
|
|
223
|
+
function h4(content, options = {}) {
|
|
224
|
+
return text(content, { ...options, usageHint: "h4" });
|
|
225
|
+
}
|
|
226
|
+
function h5(content, options = {}) {
|
|
227
|
+
return text(content, { ...options, usageHint: "h5" });
|
|
228
|
+
}
|
|
229
|
+
function caption(content, options = {}) {
|
|
230
|
+
return text(content, { ...options, usageHint: "caption" });
|
|
231
|
+
}
|
|
232
|
+
function body(content, options = {}) {
|
|
233
|
+
return text(content, { ...options, usageHint: "body" });
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// src/types/messages.ts
|
|
237
|
+
var STANDARD_CATALOG_ID = "https://a2ui.dev/specification/0.9/standard_catalog_definition.json";
|
|
238
|
+
|
|
239
|
+
// src/builders/data-model-builder.ts
|
|
240
|
+
var DEFAULT_PATH_MAPPINGS = {};
|
|
241
|
+
function objectToValueMap(obj, prefix = "") {
|
|
242
|
+
const entries = [];
|
|
243
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
244
|
+
const fullKey = prefix ? `${prefix}/${key}` : `/${key}`;
|
|
245
|
+
entries.push(valueToValueMap(fullKey, value));
|
|
246
|
+
}
|
|
247
|
+
return entries;
|
|
248
|
+
}
|
|
249
|
+
function valueToValueMap(key, value) {
|
|
250
|
+
if (value === null || value === void 0) {
|
|
251
|
+
return { key, valueString: "" };
|
|
252
|
+
}
|
|
253
|
+
if (typeof value === "string") {
|
|
254
|
+
return { key, valueString: value };
|
|
255
|
+
}
|
|
256
|
+
if (typeof value === "number") {
|
|
257
|
+
return { key, valueNumber: value };
|
|
258
|
+
}
|
|
259
|
+
if (typeof value === "boolean") {
|
|
260
|
+
return { key, valueBoolean: value };
|
|
261
|
+
}
|
|
262
|
+
if (Array.isArray(value)) {
|
|
263
|
+
return {
|
|
264
|
+
key,
|
|
265
|
+
valueMap: value.map((item, index) => valueToValueMap(String(index), item))
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
if (typeof value === "object") {
|
|
269
|
+
const nestedMaps = [];
|
|
270
|
+
for (const [k, v] of Object.entries(value)) {
|
|
271
|
+
nestedMaps.push(valueToValueMap(k, v));
|
|
272
|
+
}
|
|
273
|
+
return { key, valueMap: nestedMaps };
|
|
274
|
+
}
|
|
275
|
+
return { key, valueString: String(value) };
|
|
276
|
+
}
|
|
277
|
+
function normalizePath(path, pathMappings = {}) {
|
|
278
|
+
let normalizedPath = path.replace(/\./g, "/");
|
|
279
|
+
if (!normalizedPath.startsWith("/")) {
|
|
280
|
+
normalizedPath = `/${normalizedPath}`;
|
|
281
|
+
}
|
|
282
|
+
for (const [from, to] of Object.entries(pathMappings)) {
|
|
283
|
+
const fromPattern = new RegExp(`^/${from}(/|$)`);
|
|
284
|
+
if (fromPattern.test(normalizedPath)) {
|
|
285
|
+
normalizedPath = normalizedPath.replace(fromPattern, `/${to}$1`);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
return normalizedPath;
|
|
289
|
+
}
|
|
290
|
+
function updatesToValueMap(updates, basePath = "", pathMappings = DEFAULT_PATH_MAPPINGS) {
|
|
291
|
+
const entries = [];
|
|
292
|
+
for (const update of updates) {
|
|
293
|
+
const rawPath = update.path.startsWith("/") ? update.path : `${basePath}/${update.path}`;
|
|
294
|
+
const normalizedPath = normalizePath(rawPath, pathMappings);
|
|
295
|
+
if (update.value !== null && typeof update.value === "object" && !Array.isArray(update.value)) {
|
|
296
|
+
const flattenedEntries = flattenObjectToValueMap(
|
|
297
|
+
update.value,
|
|
298
|
+
normalizedPath
|
|
299
|
+
);
|
|
300
|
+
entries.push(...flattenedEntries);
|
|
301
|
+
} else {
|
|
302
|
+
entries.push(valueToValueMap(normalizedPath, update.value));
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
return entries;
|
|
306
|
+
}
|
|
307
|
+
function flattenObjectToValueMap(obj, basePath) {
|
|
308
|
+
const entries = [];
|
|
309
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
310
|
+
const fullPath = `${basePath}/${key}`;
|
|
311
|
+
if (value !== null && typeof value === "object" && !Array.isArray(value)) {
|
|
312
|
+
const nestedEntries = flattenObjectToValueMap(value, fullPath);
|
|
313
|
+
entries.push(...nestedEntries);
|
|
314
|
+
} else {
|
|
315
|
+
entries.push(valueToValueMap(fullPath, value));
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
return entries;
|
|
319
|
+
}
|
|
320
|
+
function valueMapToObject(valueMaps) {
|
|
321
|
+
const result = {};
|
|
322
|
+
for (const valueMap of valueMaps) {
|
|
323
|
+
const key = valueMap.key.startsWith("/") ? valueMap.key.slice(1) : valueMap.key;
|
|
324
|
+
if (valueMap.valueString !== void 0) {
|
|
325
|
+
result[key] = valueMap.valueString;
|
|
326
|
+
} else if (valueMap.valueNumber !== void 0) {
|
|
327
|
+
result[key] = valueMap.valueNumber;
|
|
328
|
+
} else if (valueMap.valueBoolean !== void 0) {
|
|
329
|
+
result[key] = valueMap.valueBoolean;
|
|
330
|
+
} else if (valueMap.valueMap !== void 0) {
|
|
331
|
+
result[key] = valueMapToObject(valueMap.valueMap);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
return result;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
// src/builders/message-builder.ts
|
|
338
|
+
function createSurface(surfaceId, catalogId = STANDARD_CATALOG_ID) {
|
|
339
|
+
return {
|
|
340
|
+
createSurface: {
|
|
341
|
+
surfaceId,
|
|
342
|
+
catalogId
|
|
343
|
+
}
|
|
344
|
+
};
|
|
345
|
+
}
|
|
346
|
+
function updateComponents(surfaceId, components) {
|
|
347
|
+
return {
|
|
348
|
+
updateComponents: {
|
|
349
|
+
surfaceId,
|
|
350
|
+
components
|
|
351
|
+
}
|
|
352
|
+
};
|
|
353
|
+
}
|
|
354
|
+
function updateDataModel(surfaceId, value, path, op = "replace") {
|
|
355
|
+
return {
|
|
356
|
+
updateDataModel: {
|
|
357
|
+
surfaceId,
|
|
358
|
+
...path && { path },
|
|
359
|
+
op,
|
|
360
|
+
...op !== "remove" && { value }
|
|
361
|
+
}
|
|
362
|
+
};
|
|
363
|
+
}
|
|
364
|
+
function deleteSurface(surfaceId) {
|
|
365
|
+
return {
|
|
366
|
+
deleteSurface: {
|
|
367
|
+
surfaceId
|
|
368
|
+
}
|
|
369
|
+
};
|
|
370
|
+
}
|
|
371
|
+
function createV09Messages(options) {
|
|
372
|
+
const { surfaceId, catalogId = STANDARD_CATALOG_ID, components, dataModel } = options;
|
|
373
|
+
const messages = [
|
|
374
|
+
createSurface(surfaceId, catalogId),
|
|
375
|
+
updateComponents(surfaceId, components)
|
|
376
|
+
];
|
|
377
|
+
if (dataModel) {
|
|
378
|
+
messages.push(updateDataModel(surfaceId, dataModel));
|
|
379
|
+
}
|
|
380
|
+
return messages;
|
|
381
|
+
}
|
|
382
|
+
function beginRendering(rootId, surfaceId = "@default", styles) {
|
|
383
|
+
return {
|
|
384
|
+
beginRendering: {
|
|
385
|
+
surfaceId,
|
|
386
|
+
root: rootId,
|
|
387
|
+
...styles && { styles }
|
|
388
|
+
}
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
function surfaceUpdate(components, surfaceId = "@default") {
|
|
392
|
+
return {
|
|
393
|
+
surfaceUpdate: {
|
|
394
|
+
surfaceId,
|
|
395
|
+
components
|
|
396
|
+
}
|
|
397
|
+
};
|
|
398
|
+
}
|
|
399
|
+
function dataModelUpdate(contents, surfaceId = "@default", path) {
|
|
400
|
+
return {
|
|
401
|
+
dataModelUpdate: {
|
|
402
|
+
surfaceId,
|
|
403
|
+
contents,
|
|
404
|
+
...path && { path }
|
|
405
|
+
}
|
|
406
|
+
};
|
|
407
|
+
}
|
|
408
|
+
function dataModelInit(data, surfaceId = "@default") {
|
|
409
|
+
return dataModelUpdate(objectToValueMap(data), surfaceId);
|
|
410
|
+
}
|
|
411
|
+
function pathUpdate(path, value, surfaceId = "@default") {
|
|
412
|
+
return {
|
|
413
|
+
dataModelUpdate: {
|
|
414
|
+
surfaceId,
|
|
415
|
+
path,
|
|
416
|
+
contents: [valueToValueMap("", value)]
|
|
417
|
+
}
|
|
418
|
+
};
|
|
419
|
+
}
|
|
420
|
+
function deleteSurfaceV08(surfaceId) {
|
|
421
|
+
return {
|
|
422
|
+
deleteSurface: {
|
|
423
|
+
surfaceId
|
|
424
|
+
}
|
|
425
|
+
};
|
|
426
|
+
}
|
|
427
|
+
function createV08Messages(options) {
|
|
428
|
+
const { rootId, components, dataModel, surfaceId = "@default", styles } = options;
|
|
429
|
+
const messages = [
|
|
430
|
+
surfaceUpdate(components, surfaceId)
|
|
431
|
+
];
|
|
432
|
+
if (dataModel) {
|
|
433
|
+
messages.push(dataModelInit(dataModel, surfaceId));
|
|
434
|
+
}
|
|
435
|
+
messages.push(beginRendering(rootId, surfaceId, styles));
|
|
436
|
+
return messages;
|
|
437
|
+
}
|
|
438
|
+
function messagesToJsonl(messages) {
|
|
439
|
+
return messages.map((msg) => JSON.stringify(msg)).join("\n");
|
|
440
|
+
}
|
|
441
|
+
function jsonlToMessages(jsonl) {
|
|
442
|
+
return jsonl.split("\n").filter((line) => line.trim()).map((line) => JSON.parse(line));
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
exports.DEFAULT_PATH_MAPPINGS = DEFAULT_PATH_MAPPINGS;
|
|
446
|
+
exports.audioPlayer = audioPlayer;
|
|
447
|
+
exports.beginRendering = beginRendering;
|
|
448
|
+
exports.body = body;
|
|
449
|
+
exports.button = button;
|
|
450
|
+
exports.caption = caption;
|
|
451
|
+
exports.card = card;
|
|
452
|
+
exports.checkbox = checkbox;
|
|
453
|
+
exports.choicePicker = choicePicker;
|
|
454
|
+
exports.column = column;
|
|
455
|
+
exports.createSurface = createSurface;
|
|
456
|
+
exports.createV08Messages = createV08Messages;
|
|
457
|
+
exports.createV09Messages = createV09Messages;
|
|
458
|
+
exports.dataModelInit = dataModelInit;
|
|
459
|
+
exports.dataModelUpdate = dataModelUpdate;
|
|
460
|
+
exports.dateTimeInput = dateTimeInput;
|
|
461
|
+
exports.deleteSurface = deleteSurface;
|
|
462
|
+
exports.deleteSurfaceV08 = deleteSurfaceV08;
|
|
463
|
+
exports.divider = divider;
|
|
464
|
+
exports.flattenObjectToValueMap = flattenObjectToValueMap;
|
|
465
|
+
exports.generateId = generateId;
|
|
466
|
+
exports.getIdCounter = getIdCounter;
|
|
467
|
+
exports.h1 = h1;
|
|
468
|
+
exports.h2 = h2;
|
|
469
|
+
exports.h3 = h3;
|
|
470
|
+
exports.h4 = h4;
|
|
471
|
+
exports.h5 = h5;
|
|
472
|
+
exports.icon = icon;
|
|
473
|
+
exports.image = image;
|
|
474
|
+
exports.jsonlToMessages = jsonlToMessages;
|
|
475
|
+
exports.list = list;
|
|
476
|
+
exports.messagesToJsonl = messagesToJsonl;
|
|
477
|
+
exports.modal = modal;
|
|
478
|
+
exports.normalizePath = normalizePath;
|
|
479
|
+
exports.objectToValueMap = objectToValueMap;
|
|
480
|
+
exports.pathUpdate = pathUpdate;
|
|
481
|
+
exports.resetIdCounter = resetIdCounter;
|
|
482
|
+
exports.row = row;
|
|
483
|
+
exports.slider = slider;
|
|
484
|
+
exports.surfaceUpdate = surfaceUpdate;
|
|
485
|
+
exports.tabs = tabs;
|
|
486
|
+
exports.text = text;
|
|
487
|
+
exports.textButton = textButton;
|
|
488
|
+
exports.textField = textField;
|
|
489
|
+
exports.updateComponents = updateComponents;
|
|
490
|
+
exports.updateDataModel = updateDataModel;
|
|
491
|
+
exports.updatesToValueMap = updatesToValueMap;
|
|
492
|
+
exports.valueMapToObject = valueMapToObject;
|
|
493
|
+
exports.valueToValueMap = valueToValueMap;
|
|
494
|
+
exports.video = video;
|
|
495
|
+
//# sourceMappingURL=index.cjs.map
|
|
496
|
+
//# sourceMappingURL=index.cjs.map
|