@maxhealth.tech/prefab 0.3.9 → 0.3.11
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/CHANGELOG.md +723 -671
- package/README.md +76 -10
- package/dist/a2ui/browser.d.ts +46 -0
- package/dist/a2ui/browser.d.ts.map +1 -0
- package/dist/a2ui/browser.js +58 -0
- package/dist/a2ui/browser.js.map +1 -0
- package/dist/a2ui/catalog.d.ts +72 -0
- package/dist/a2ui/catalog.d.ts.map +1 -0
- package/dist/a2ui/catalog.js +521 -0
- package/dist/a2ui/catalog.js.map +1 -0
- package/dist/a2ui/control.d.ts +20 -0
- package/dist/a2ui/control.d.ts.map +1 -0
- package/dist/a2ui/control.js +107 -0
- package/dist/a2ui/control.js.map +1 -0
- package/dist/a2ui/emit.d.ts +59 -0
- package/dist/a2ui/emit.d.ts.map +1 -0
- package/dist/a2ui/emit.js +373 -0
- package/dist/a2ui/emit.js.map +1 -0
- package/dist/a2ui/expr.d.ts +91 -0
- package/dist/a2ui/expr.d.ts.map +1 -0
- package/dist/a2ui/expr.js +201 -0
- package/dist/a2ui/expr.js.map +1 -0
- package/dist/a2ui/icons.d.ts +30 -0
- package/dist/a2ui/icons.d.ts.map +1 -0
- package/dist/a2ui/icons.js +87 -0
- package/dist/a2ui/icons.js.map +1 -0
- package/dist/a2ui/index.d.ts +29 -0
- package/dist/a2ui/index.d.ts.map +1 -0
- package/dist/a2ui/index.js +24 -0
- package/dist/a2ui/index.js.map +1 -0
- package/dist/a2ui/pipes.d.ts +49 -0
- package/dist/a2ui/pipes.d.ts.map +1 -0
- package/dist/a2ui/pipes.js +106 -0
- package/dist/a2ui/pipes.js.map +1 -0
- package/dist/a2ui/table.d.ts +31 -0
- package/dist/a2ui/table.d.ts.map +1 -0
- package/dist/a2ui/table.js +155 -0
- package/dist/a2ui/table.js.map +1 -0
- package/dist/a2ui/types.d.ts +174 -0
- package/dist/a2ui/types.d.ts.map +1 -0
- package/dist/a2ui/types.js +35 -0
- package/dist/a2ui/types.js.map +1 -0
- package/dist/a2ui.min.js +1 -0
- package/dist/app.d.ts +17 -0
- package/dist/app.d.ts.map +1 -1
- package/dist/app.js +19 -0
- package/dist/app.js.map +1 -1
- package/dist/auto/form.d.ts +25 -0
- package/dist/auto/form.d.ts.map +1 -1
- package/dist/auto/form.js +21 -8
- package/dist/auto/form.js.map +1 -1
- package/dist/core/version.d.ts +1 -1
- package/dist/core/version.d.ts.map +1 -1
- package/dist/core/version.js +1 -1
- package/dist/core/version.js.map +1 -1
- package/dist/index.d.ts +9 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/mcp/a2ui.d.ts +91 -0
- package/dist/mcp/a2ui.d.ts.map +1 -0
- package/dist/mcp/a2ui.js +134 -0
- package/dist/mcp/a2ui.js.map +1 -0
- package/dist/mcp/display.d.ts +28 -6
- package/dist/mcp/display.d.ts.map +1 -1
- package/dist/mcp/display.js +10 -9
- package/dist/mcp/display.js.map +1 -1
- package/dist/mcp/index.d.ts +7 -2
- package/dist/mcp/index.d.ts.map +1 -1
- package/dist/mcp/index.js +3 -1
- package/dist/mcp/index.js.map +1 -1
- package/dist/mcp/input-required.d.ts +79 -0
- package/dist/mcp/input-required.d.ts.map +1 -0
- package/dist/mcp/input-required.js +231 -0
- package/dist/mcp/input-required.js.map +1 -0
- package/dist/mcp/resource.d.ts +10 -0
- package/dist/mcp/resource.d.ts.map +1 -1
- package/dist/mcp/resource.js +12 -4
- package/dist/mcp/resource.js.map +1 -1
- package/dist/mcp/result.d.ts +7 -5
- package/dist/mcp/result.d.ts.map +1 -1
- package/dist/mcp/result.js +5 -3
- package/dist/mcp/result.js.map +1 -1
- package/dist/mcp/types.d.ts +117 -0
- package/dist/mcp/types.d.ts.map +1 -1
- package/dist/renderer/components/index.d.ts.map +1 -1
- package/dist/renderer/components/index.js +6 -0
- package/dist/renderer/components/index.js.map +1 -1
- package/dist/renderer/engine.d.ts +4 -0
- package/dist/renderer/engine.d.ts.map +1 -1
- package/dist/renderer/engine.js +24 -0
- package/dist/renderer/engine.js.map +1 -1
- package/dist/renderer.auto.min.js +13 -13
- package/dist/renderer.min.js +13 -13
- package/package.json +14 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"expr.d.ts","sourceRoot":"","sources":["../../src/a2ui/expr.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,iBAAiB,EAAoB,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAgBxG;;;;;GAKG;AACH,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;AAK9C;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAExD;AAED,6DAA6D;AAC7D,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,CAExD;AA0CD,6EAA6E;AAC7E,MAAM,MAAM,aAAa;AACvB,wCAAwC;AACtC;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE;AACpC,8DAA8D;GAC5D;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,eAAe,CAAA;CAAE;AAC7C;;;;GAIG;GACD;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,KAAK,EAAE,gBAAgB,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE;AAC5D,+DAA+D;GAC7D;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,gBAAgB,CAAA;CAAE;AAC5C,iFAAiF;GAC/E;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAA;AA8D9C;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,GAAE,SAAc,GAAG,aAAa,CAgC7E;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,GAAE,SAAc,GAAG,iBAAiB,GAAG,SAAS,CAU7G"}
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `{{ }}` template → A2UI data binding.
|
|
3
|
+
*
|
|
4
|
+
* `$prefab` interpolates arbitrary expressions client-side. A2UI binds values
|
|
5
|
+
* through JSON Pointers and, for text that mixes literals with values, through
|
|
6
|
+
* the `formatString` catalog function. Between them those cover more than a
|
|
7
|
+
* plain-path conversion would suggest:
|
|
8
|
+
*
|
|
9
|
+
* - `{{ user.name }}` → `{ path: '/user/name' }`
|
|
10
|
+
* - `Hi {{ name }}!` → `{ call: 'formatString', args: { value: 'Hi ${/name}!' } }`
|
|
11
|
+
* - `{{ p | currency:'EUR' }}` → `{ call: 'formatCurrency', args: { … } }`
|
|
12
|
+
* - `{{ count + 1 }}` → nothing; A2UI has no expression language
|
|
13
|
+
*
|
|
14
|
+
* What does not survive is arithmetic, conditionals, and the pipes that
|
|
15
|
+
* transform data rather than format it (see `./pipes.ts`). Those are reported as
|
|
16
|
+
* `expression` diagnostics rather than emitted as a binding that would render an
|
|
17
|
+
* empty string in someone's renderer.
|
|
18
|
+
*
|
|
19
|
+
* ## Scopes
|
|
20
|
+
*
|
|
21
|
+
* A binding is resolved against a {@link BindScope}, which is how names local to
|
|
22
|
+
* a region become pointers. Inside a list template A2UI resolves relative paths
|
|
23
|
+
* against the current item, so prefab's `$item` maps to the empty prefix; inside
|
|
24
|
+
* an inlined definition, a `Use`'s overrides map to wherever the emitter seeded
|
|
25
|
+
* them. Without this, a name that means something local would silently bind to
|
|
26
|
+
* the root of the data model and read whatever happened to be there.
|
|
27
|
+
*/
|
|
28
|
+
import { parsePipe, pipeCall } from './pipes.js';
|
|
29
|
+
/** Matches a string that is exactly one `{{ … }}` template and nothing else. */
|
|
30
|
+
const SOLE_TEMPLATE = /^\s*\{\{\s*(.+?)\s*\}\}\s*$/s;
|
|
31
|
+
/** Matches every `{{ … }}` occurrence, for interpolating mixed text. */
|
|
32
|
+
const EVERY_TEMPLATE = /\{\{\s*(.+?)\s*\}\}/g;
|
|
33
|
+
/**
|
|
34
|
+
* A plain member path: `user.name`, `items.0.label`, `count`, `$item.title`.
|
|
35
|
+
*
|
|
36
|
+
* Deliberately narrow. Anything outside this shape (operators, pipes, calls,
|
|
37
|
+
* ternaries, string literals) has no A2UI equivalent.
|
|
38
|
+
*/
|
|
39
|
+
const PLAIN_PATH = /^\$?[A-Za-z_][\w$]*(?:\.(?:[A-Za-z_$][\w$]*|\d+))*$/;
|
|
40
|
+
/** prefab's loop index. A2UI exposes the same thing as a system function. */
|
|
41
|
+
const LOOP_INDEX = '$index';
|
|
42
|
+
/**
|
|
43
|
+
* Escape one JSON Pointer reference token (RFC 6901 §3).
|
|
44
|
+
*
|
|
45
|
+
* `~` must be escaped before `/`, otherwise the `~1` produced for a slash gets
|
|
46
|
+
* re-escaped into `~01` on the second pass.
|
|
47
|
+
*/
|
|
48
|
+
export function escapePointerToken(token) {
|
|
49
|
+
return token.replace(/~/g, '~0').replace(/\//g, '~1');
|
|
50
|
+
}
|
|
51
|
+
/** Build a JSON Pointer from already-split path segments. */
|
|
52
|
+
export function toJsonPointer(segments) {
|
|
53
|
+
return '/' + segments.map(escapePointerToken).join('/');
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* prefab state expressions address state keys directly (`count`), but actions
|
|
57
|
+
* and docs also spell the same key as `state.count`. Both mean the root of the
|
|
58
|
+
* data model, so the prefix is stripped before the pointer is built.
|
|
59
|
+
*/
|
|
60
|
+
function stripStatePrefix(path) {
|
|
61
|
+
return path.startsWith('state.') ? path.slice('state.'.length) : path;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Resolve a member path to a JSON Pointer under `scope`.
|
|
65
|
+
*
|
|
66
|
+
* A leading segment named in the scope is replaced by its prefix; everything
|
|
67
|
+
* else resolves from the data-model root.
|
|
68
|
+
*/
|
|
69
|
+
function pathToPointer(expr, scope) {
|
|
70
|
+
if (!PLAIN_PATH.test(expr))
|
|
71
|
+
return undefined;
|
|
72
|
+
const segments = stripStatePrefix(expr).split('.');
|
|
73
|
+
const head = segments[0];
|
|
74
|
+
// `hasOwn` rather than a truthiness check: '' is a meaningful prefix, meaning
|
|
75
|
+
// "relative to the current template item".
|
|
76
|
+
const prefix = Object.hasOwn(scope, head) ? scope[head] : undefined;
|
|
77
|
+
if (prefix === undefined) {
|
|
78
|
+
// A `$`-prefixed name is a runtime binding prefab supplies ($event, $error,
|
|
79
|
+
// $result). Outside a scope that defines it, there is nothing to point at.
|
|
80
|
+
if (head.startsWith('$'))
|
|
81
|
+
return undefined;
|
|
82
|
+
return toJsonPointer(segments);
|
|
83
|
+
}
|
|
84
|
+
const rest = segments.slice(1);
|
|
85
|
+
if (prefix === '') {
|
|
86
|
+
// Relative to the current template item. `{{ $item }}` alone has no field to
|
|
87
|
+
// address, so it cannot become a pointer.
|
|
88
|
+
return rest.length === 0 ? undefined : rest.map(escapePointerToken).join('/');
|
|
89
|
+
}
|
|
90
|
+
return rest.length === 0 ? prefix : `${prefix}/${rest.map(escapePointerToken).join('/')}`;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Escape a literal segment for a `formatString` template.
|
|
94
|
+
*
|
|
95
|
+
* `${` is the interpolation opener, so a literal one has to be escaped or the
|
|
96
|
+
* renderer reads the surrounding text as an expression.
|
|
97
|
+
*/
|
|
98
|
+
function escapeFormatLiteral(text) {
|
|
99
|
+
return text.replace(/\$\{/g, '\\${');
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Convert mixed literal and template text into a `formatString` call.
|
|
103
|
+
*
|
|
104
|
+
* @returns `undefined` when any embedded expression is richer than a path, in
|
|
105
|
+
* which case the whole string is unbindable rather than partly interpolated.
|
|
106
|
+
*/
|
|
107
|
+
function toFormatString(value, scope) {
|
|
108
|
+
let failed;
|
|
109
|
+
let interpolated = '';
|
|
110
|
+
let cursor = 0;
|
|
111
|
+
for (const match of value.matchAll(EVERY_TEMPLATE)) {
|
|
112
|
+
const expr = match[1].trim();
|
|
113
|
+
const pointer = pathToPointer(expr, scope);
|
|
114
|
+
if (pointer == null) {
|
|
115
|
+
failed = expr;
|
|
116
|
+
break;
|
|
117
|
+
}
|
|
118
|
+
interpolated += escapeFormatLiteral(value.slice(cursor, match.index));
|
|
119
|
+
interpolated += `\${${pointer}}`;
|
|
120
|
+
cursor = match.index + match[0].length;
|
|
121
|
+
}
|
|
122
|
+
if (failed != null)
|
|
123
|
+
return undefined;
|
|
124
|
+
interpolated += escapeFormatLiteral(value.slice(cursor));
|
|
125
|
+
return { call: 'formatString', args: { value: interpolated } };
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Resolve a piped expression to a catalog-function call.
|
|
129
|
+
*
|
|
130
|
+
* The base must itself be a plain path or a literal, since A2UI function
|
|
131
|
+
* arguments take a value rather than an expression to evaluate.
|
|
132
|
+
*/
|
|
133
|
+
function toPipeCall(expr, scope) {
|
|
134
|
+
const pipe = parsePipe(expr);
|
|
135
|
+
if (pipe == null)
|
|
136
|
+
return undefined;
|
|
137
|
+
const pointer = pathToPointer(pipe.base, scope);
|
|
138
|
+
const value = pointer != null
|
|
139
|
+
? { path: pointer }
|
|
140
|
+
: /^-?\d+(\.\d+)?$/.test(pipe.base) ? Number(pipe.base) : undefined;
|
|
141
|
+
if (value === undefined)
|
|
142
|
+
return undefined;
|
|
143
|
+
const mapped = pipeCall(pipe, value);
|
|
144
|
+
if (mapped == null)
|
|
145
|
+
return undefined;
|
|
146
|
+
return { kind: 'format', value: mapped.call, ...(mapped.note != null && { note: mapped.note }) };
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Convert a prefab string value into an A2UI dynamic value.
|
|
150
|
+
*
|
|
151
|
+
* A whole-string template over a plain path becomes a binding, one over a
|
|
152
|
+
* formatting pipe becomes a catalog-function call, mixed text becomes a
|
|
153
|
+
* `formatString` call, a string with no template passes through, and anything
|
|
154
|
+
* else is unbindable.
|
|
155
|
+
*/
|
|
156
|
+
export function toBinding(value, scope = {}) {
|
|
157
|
+
const sole = SOLE_TEMPLATE.exec(value);
|
|
158
|
+
// The capture is lazy but still spans `}} … {{`, so `{{ a }} of {{ b }}`
|
|
159
|
+
// matches as one template whose body is `a }} of {{ b`. Rejecting a capture
|
|
160
|
+
// that contains delimiters sends those strings down the interpolation path,
|
|
161
|
+
// which is where they belong.
|
|
162
|
+
const isSole = sole != null && !sole[1].includes('{{') && !sole[1].includes('}}');
|
|
163
|
+
if (isSole) {
|
|
164
|
+
const expr = sole[1].trim();
|
|
165
|
+
if (expr === LOOP_INDEX && LOOP_INDEX in scope) {
|
|
166
|
+
return { kind: 'index', value: { call: '@index' } };
|
|
167
|
+
}
|
|
168
|
+
const pointer = pathToPointer(expr, scope);
|
|
169
|
+
if (pointer != null)
|
|
170
|
+
return { kind: 'binding', value: { path: pointer } };
|
|
171
|
+
// A pipe is not part of A2UI's expression language, but the common
|
|
172
|
+
// formatting ones exist in its catalog as functions.
|
|
173
|
+
const piped = toPipeCall(expr, scope);
|
|
174
|
+
if (piped != null)
|
|
175
|
+
return piped;
|
|
176
|
+
return { kind: 'unbindable', expression: expr };
|
|
177
|
+
}
|
|
178
|
+
if (!value.includes('{{'))
|
|
179
|
+
return { kind: 'literal', value };
|
|
180
|
+
const format = toFormatString(value, scope);
|
|
181
|
+
if (format != null)
|
|
182
|
+
return { kind: 'format', value: format };
|
|
183
|
+
return { kind: 'unbindable', expression: value };
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Resolve a value to an `A2uiDynamicString`, or `undefined` when it cannot be
|
|
187
|
+
* expressed. Callers pair this with a diagnostic when it returns `undefined`.
|
|
188
|
+
*/
|
|
189
|
+
export function dynamicString(value, scope = {}) {
|
|
190
|
+
if (value == null)
|
|
191
|
+
return undefined;
|
|
192
|
+
const r = toBinding(value, scope);
|
|
193
|
+
switch (r.kind) {
|
|
194
|
+
case 'literal': return r.value;
|
|
195
|
+
case 'binding': return r.value;
|
|
196
|
+
case 'format': return r.value;
|
|
197
|
+
case 'index': return r.value;
|
|
198
|
+
default: return undefined;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
//# sourceMappingURL=expr.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"expr.js","sourceRoot":"","sources":["../../src/a2ui/expr.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* prefab icon name → A2UI Basic catalog icon.
|
|
3
|
+
*
|
|
4
|
+
* The one place where the two catalogs disagree on *values* rather than on
|
|
5
|
+
* component shape. prefab's `Icon(name)` takes any string, because its renderer
|
|
6
|
+
* resolves Lucide names at runtime and new icons cost nothing. A2UI's
|
|
7
|
+
* `Icon.name` is a closed enum of 59 names, so an unrecognised value does not
|
|
8
|
+
* render as a fallback glyph — it makes the whole component fail validation.
|
|
9
|
+
*
|
|
10
|
+
* Passing the name through unchecked therefore emits an invalid surface for
|
|
11
|
+
* every icon outside those 59, which is most of them. Instead the name is
|
|
12
|
+
* normalised, matched against the enum, and dropped with a diagnostic when
|
|
13
|
+
* nothing fits, so an unmappable icon costs a glyph rather than the payload.
|
|
14
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* The A2UI Basic catalog's `Icon.name` enum, v1.0.
|
|
17
|
+
*
|
|
18
|
+
* Duplicated as a literal because prefab ships zero runtime dependencies and
|
|
19
|
+
* cannot read the catalog JSON at emit time. `test/a2ui-icons.test.ts` asserts
|
|
20
|
+
* this matches the vendored catalog exactly, so it cannot drift silently.
|
|
21
|
+
*/
|
|
22
|
+
export declare const A2UI_ICONS: readonly string[];
|
|
23
|
+
/**
|
|
24
|
+
* Resolve a prefab icon name to an A2UI one.
|
|
25
|
+
*
|
|
26
|
+
* @returns the catalog name, or `undefined` when nothing in the enum means the
|
|
27
|
+
* same thing. Callers drop the icon and record a diagnostic.
|
|
28
|
+
*/
|
|
29
|
+
export declare function a2uiIconName(name: string): string | undefined;
|
|
30
|
+
//# sourceMappingURL=icons.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"icons.d.ts","sourceRoot":"","sources":["../../src/a2ui/icons.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH;;;;;;GAMG;AACH,eAAO,MAAM,UAAU,EAAE,SAAS,MAAM,EAUvC,CAAA;AAiDD;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAG7D"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* prefab icon name → A2UI Basic catalog icon.
|
|
3
|
+
*
|
|
4
|
+
* The one place where the two catalogs disagree on *values* rather than on
|
|
5
|
+
* component shape. prefab's `Icon(name)` takes any string, because its renderer
|
|
6
|
+
* resolves Lucide names at runtime and new icons cost nothing. A2UI's
|
|
7
|
+
* `Icon.name` is a closed enum of 59 names, so an unrecognised value does not
|
|
8
|
+
* render as a fallback glyph — it makes the whole component fail validation.
|
|
9
|
+
*
|
|
10
|
+
* Passing the name through unchecked therefore emits an invalid surface for
|
|
11
|
+
* every icon outside those 59, which is most of them. Instead the name is
|
|
12
|
+
* normalised, matched against the enum, and dropped with a diagnostic when
|
|
13
|
+
* nothing fits, so an unmappable icon costs a glyph rather than the payload.
|
|
14
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* The A2UI Basic catalog's `Icon.name` enum, v1.0.
|
|
17
|
+
*
|
|
18
|
+
* Duplicated as a literal because prefab ships zero runtime dependencies and
|
|
19
|
+
* cannot read the catalog JSON at emit time. `test/a2ui-icons.test.ts` asserts
|
|
20
|
+
* this matches the vendored catalog exactly, so it cannot drift silently.
|
|
21
|
+
*/
|
|
22
|
+
export const A2UI_ICONS = [
|
|
23
|
+
'accountCircle', 'add', 'arrowBack', 'arrowForward', 'attachFile', 'calendarToday',
|
|
24
|
+
'call', 'camera', 'check', 'close', 'delete', 'download', 'edit', 'event', 'error',
|
|
25
|
+
'fastForward', 'favorite', 'favoriteOff', 'folder', 'help', 'home', 'info',
|
|
26
|
+
'locationOn', 'lock', 'lockOpen', 'mail', 'menu', 'moreVert', 'moreHoriz',
|
|
27
|
+
'notificationsOff', 'notifications', 'pause', 'payment', 'person', 'phone', 'photo',
|
|
28
|
+
'play', 'print', 'refresh', 'rewind', 'search', 'send', 'settings', 'share',
|
|
29
|
+
'shoppingCart', 'skipNext', 'skipPrevious', 'star', 'starHalf', 'starOff', 'stop',
|
|
30
|
+
'upload', 'visibility', 'visibilityOff', 'volumeDown', 'volumeMute', 'volumeOff',
|
|
31
|
+
'volumeUp', 'warning',
|
|
32
|
+
];
|
|
33
|
+
/** Lookup by normalised form, so `Arrow-Back`, `arrow_back` and `ArrowBack` all hit. */
|
|
34
|
+
const BY_NORMALISED = new Map(A2UI_ICONS.map(name => [normalise(name), name]));
|
|
35
|
+
/**
|
|
36
|
+
* Names that differ between the two vocabularies rather than merely in case.
|
|
37
|
+
*
|
|
38
|
+
* prefab follows Lucide, A2UI follows Material. Where the concept exists in both
|
|
39
|
+
* under different words, the alias keeps the icon; where it does not, the entry
|
|
40
|
+
* is absent and the icon is dropped rather than mapped to something that means
|
|
41
|
+
* something else. Keys are normalised, so one entry covers every spelling.
|
|
42
|
+
*/
|
|
43
|
+
const ALIASES = {
|
|
44
|
+
// Status and feedback
|
|
45
|
+
alertcircle: 'error', alerttriangle: 'warning', alertoctagon: 'error',
|
|
46
|
+
xcircle: 'error', circlex: 'error', circlealert: 'error',
|
|
47
|
+
checkcircle: 'check', circlecheck: 'check', checkcircle2: 'check',
|
|
48
|
+
infocircle: 'info', circleinfo: 'info', helpcircle: 'help', circlehelp: 'help',
|
|
49
|
+
bell: 'notifications', belloff: 'notificationsOff',
|
|
50
|
+
// Navigation
|
|
51
|
+
arrowleft: 'arrowBack', arrowright: 'arrowForward',
|
|
52
|
+
chevronleft: 'arrowBack', chevronright: 'arrowForward',
|
|
53
|
+
x: 'close', plus: 'add', trash: 'delete', trash2: 'delete',
|
|
54
|
+
ellipsisvertical: 'moreVert', ellipsis: 'moreHoriz', morehorizontal: 'moreHoriz',
|
|
55
|
+
morevertical: 'moreVert',
|
|
56
|
+
// Objects and actions
|
|
57
|
+
pencil: 'edit', pen: 'edit', squarepen: 'edit',
|
|
58
|
+
user: 'person', usercircle: 'accountCircle', circleuser: 'accountCircle',
|
|
59
|
+
eye: 'visibility', eyeoff: 'visibilityOff',
|
|
60
|
+
mappin: 'locationOn', map: 'locationOn',
|
|
61
|
+
image: 'photo', images: 'photo', file: 'folder', files: 'folder',
|
|
62
|
+
calendar: 'calendarToday', calendardays: 'calendarToday', clock: 'event',
|
|
63
|
+
creditcard: 'payment', cart: 'shoppingCart', shoppingbag: 'shoppingCart',
|
|
64
|
+
phonecall: 'call', mailopen: 'mail', inbox: 'mail',
|
|
65
|
+
cog: 'settings', gear: 'settings', sliders: 'settings',
|
|
66
|
+
rotatecw: 'refresh', rotateccw: 'refresh', refreshcw: 'refresh',
|
|
67
|
+
heart: 'favorite', heartoff: 'favoriteOff',
|
|
68
|
+
volume: 'volumeUp', volume1: 'volumeDown', volume2: 'volumeUp', volumex: 'volumeOff',
|
|
69
|
+
skipforward: 'skipNext', skipback: 'skipPrevious',
|
|
70
|
+
paperclip: 'attachFile', link: 'share', share2: 'share',
|
|
71
|
+
magnifyingglass: 'search', searchicon: 'search',
|
|
72
|
+
};
|
|
73
|
+
/** Case-insensitive, separator-insensitive key for matching either vocabulary. */
|
|
74
|
+
function normalise(name) {
|
|
75
|
+
return name.replace(/[\s._-]/g, '').toLowerCase();
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Resolve a prefab icon name to an A2UI one.
|
|
79
|
+
*
|
|
80
|
+
* @returns the catalog name, or `undefined` when nothing in the enum means the
|
|
81
|
+
* same thing. Callers drop the icon and record a diagnostic.
|
|
82
|
+
*/
|
|
83
|
+
export function a2uiIconName(name) {
|
|
84
|
+
const key = normalise(name);
|
|
85
|
+
return BY_NORMALISED.get(key) ?? ALIASES[key];
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=icons.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"icons.js","sourceRoot":"","sources":["../../src/a2ui/icons.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A2UI emitter — the second output target alongside the `$prefab` wire format.
|
|
3
|
+
*
|
|
4
|
+
* `$prefab` payloads render through prefab's own renderer, in an MCP Apps
|
|
5
|
+
* iframe or any web app. A2UI payloads render natively in the A2UI renderers
|
|
6
|
+
* (React, Angular, Lit, Flutter, Swift, Compose) with no iframe involved. Both
|
|
7
|
+
* come from the same server-side component tree.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* import { Column, H1, autoTable } from '@maxhealth.tech/prefab'
|
|
12
|
+
* import { PrefabApp } from '@maxhealth.tech/prefab'
|
|
13
|
+
*
|
|
14
|
+
* const app = new PrefabApp({ view: Column({ children: [H1('Users'), autoTable(rows)] }) })
|
|
15
|
+
* const { messages, diagnostics } = app.toA2UI()
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
export { emitA2UI } from './emit.js';
|
|
19
|
+
export type { A2uiEmitOptions, A2uiEmitResult } from './emit.js';
|
|
20
|
+
export { mappedTypes } from './catalog.js';
|
|
21
|
+
export { a2uiIconName, A2UI_ICONS } from './icons.js';
|
|
22
|
+
export { mappedPipes, parsePipe } from './pipes.js';
|
|
23
|
+
export type { ParsedPipe, PipeMapping } from './pipes.js';
|
|
24
|
+
export type { A2uiProps, EmitContext, Mapper } from './catalog.js';
|
|
25
|
+
export { toBinding, toJsonPointer, escapePointerToken, dynamicString } from './expr.js';
|
|
26
|
+
export type { BindingResult } from './expr.js';
|
|
27
|
+
export { A2UI_VERSION, A2UI_BASIC_CATALOG, A2UI_MIME, A2UI_SCHEME, A2UI_ROOT_ID, } from './types.js';
|
|
28
|
+
export type { A2uiAccessibility, A2uiAction, A2uiChildList, A2uiChildTemplate, A2uiComponent, A2uiCreateSurface, A2uiDataBinding, A2uiDeleteSurface, A2uiDiagnostic, A2uiDiagnosticKind, A2uiDynamicBoolean, A2uiDynamicNumber, A2uiDynamicString, A2uiDynamicValue, A2uiEventAction, A2uiFunctionAction, A2uiFunctionCall, A2uiMessage, A2uiMessageList, A2uiUpdateComponents, A2uiUpdateDataModel, } from './types.js';
|
|
29
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/a2ui/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AACpC,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAEhE,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAC1C,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AACrD,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AACnD,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AACzD,YAAY,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AAElE,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,WAAW,CAAA;AACvF,YAAY,EAAE,aAAa,EAAE,MAAM,WAAW,CAAA;AAE9C,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,SAAS,EACT,WAAW,EACX,YAAY,GACb,MAAM,YAAY,CAAA;AACnB,YAAY,EACV,iBAAiB,EACjB,UAAU,EACV,aAAa,EACb,iBAAiB,EACjB,aAAa,EACb,iBAAiB,EACjB,eAAe,EACf,iBAAiB,EACjB,cAAc,EACd,kBAAkB,EAClB,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,EACjB,gBAAgB,EAChB,eAAe,EACf,kBAAkB,EAClB,gBAAgB,EAChB,WAAW,EACX,eAAe,EACf,oBAAoB,EACpB,mBAAmB,GACpB,MAAM,YAAY,CAAA"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A2UI emitter — the second output target alongside the `$prefab` wire format.
|
|
3
|
+
*
|
|
4
|
+
* `$prefab` payloads render through prefab's own renderer, in an MCP Apps
|
|
5
|
+
* iframe or any web app. A2UI payloads render natively in the A2UI renderers
|
|
6
|
+
* (React, Angular, Lit, Flutter, Swift, Compose) with no iframe involved. Both
|
|
7
|
+
* come from the same server-side component tree.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* import { Column, H1, autoTable } from '@maxhealth.tech/prefab'
|
|
12
|
+
* import { PrefabApp } from '@maxhealth.tech/prefab'
|
|
13
|
+
*
|
|
14
|
+
* const app = new PrefabApp({ view: Column({ children: [H1('Users'), autoTable(rows)] }) })
|
|
15
|
+
* const { messages, diagnostics } = app.toA2UI()
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
export { emitA2UI } from './emit.js';
|
|
19
|
+
export { mappedTypes } from './catalog.js';
|
|
20
|
+
export { a2uiIconName, A2UI_ICONS } from './icons.js';
|
|
21
|
+
export { mappedPipes, parsePipe } from './pipes.js';
|
|
22
|
+
export { toBinding, toJsonPointer, escapePointerToken, dynamicString } from './expr.js';
|
|
23
|
+
export { A2UI_VERSION, A2UI_BASIC_CATALOG, A2UI_MIME, A2UI_SCHEME, A2UI_ROOT_ID, } from './types.js';
|
|
24
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/a2ui/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AAGpC,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAC1C,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AACrD,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAInD,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,WAAW,CAAA;AAGvF,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,SAAS,EACT,WAAW,EACX,YAAY,GACb,MAAM,YAAY,CAAA"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* prefab pipe → A2UI catalog function.
|
|
3
|
+
*
|
|
4
|
+
* `{{ price | currency:'USD' }}` was previously reported as unbindable on the
|
|
5
|
+
* grounds that A2UI has no expression language. That is true of the language and
|
|
6
|
+
* false of the catalog: A2UI ships `formatCurrency`, `formatNumber`, `formatDate`
|
|
7
|
+
* and `pluralize` as functions, which is exactly what these pipes are.
|
|
8
|
+
*
|
|
9
|
+
* Seven of prefab's twenty-two built-ins map. The rest — `truncate`, `join`,
|
|
10
|
+
* `selectattr`, `percent`, `compact` and friends — transform data rather than
|
|
11
|
+
* format it and have no equivalent, so they stay unbindable.
|
|
12
|
+
*
|
|
13
|
+
* The date pipes are the one inexact mapping. prefab renders through
|
|
14
|
+
* `toLocaleDateString()`, so the output follows the reader's locale; A2UI's
|
|
15
|
+
* `formatDate` requires an explicit Unicode TR35 pattern. Choosing a pattern
|
|
16
|
+
* changes what the reader sees, so it is done with a diagnostic rather than
|
|
17
|
+
* silently — losing the value entirely would be the worse trade.
|
|
18
|
+
*/
|
|
19
|
+
import type { A2uiDynamicValue, A2uiFunctionCall } from './types.js';
|
|
20
|
+
/** A pipe applied to a base expression: `path | name:arg`. */
|
|
21
|
+
export interface ParsedPipe {
|
|
22
|
+
base: string;
|
|
23
|
+
name: string;
|
|
24
|
+
arg?: string | number;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Split a pipe expression into its parts.
|
|
28
|
+
*
|
|
29
|
+
* Only a single pipe with at most one argument, which is the shape prefab's own
|
|
30
|
+
* evaluator handles. A chained expression returns `undefined` and is reported
|
|
31
|
+
* rather than half-translated.
|
|
32
|
+
*/
|
|
33
|
+
export declare function parsePipe(expr: string): ParsedPipe | undefined;
|
|
34
|
+
/** What a mapped pipe produces, plus anything the mapping cost. */
|
|
35
|
+
export interface PipeMapping {
|
|
36
|
+
call: A2uiFunctionCall;
|
|
37
|
+
/** Set when the translation is inexact, for the caller to report. */
|
|
38
|
+
note?: string;
|
|
39
|
+
}
|
|
40
|
+
/** Every prefab pipe with an A2UI equivalent, for docs and tests. */
|
|
41
|
+
export declare function mappedPipes(): string[];
|
|
42
|
+
/**
|
|
43
|
+
* Map a parsed pipe onto a catalog function.
|
|
44
|
+
*
|
|
45
|
+
* @param value the already-resolved base, as a binding or a literal.
|
|
46
|
+
* @returns `undefined` when the pipe transforms rather than formats.
|
|
47
|
+
*/
|
|
48
|
+
export declare function pipeCall(pipe: ParsedPipe, value: A2uiDynamicValue): PipeMapping | undefined;
|
|
49
|
+
//# sourceMappingURL=pipes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pipes.d.ts","sourceRoot":"","sources":["../../src/a2ui/pipes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAEpE,8DAA8D;AAC9D,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;CACtB;AAKD;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CA2B9D;AAED,mEAAmE;AACnE,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,gBAAgB,CAAA;IACtB,qEAAqE;IACrE,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AA2CD,qEAAqE;AACrE,wBAAgB,WAAW,IAAI,MAAM,EAAE,CAEtC;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,gBAAgB,GAAG,WAAW,GAAG,SAAS,CAE3F"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* prefab pipe → A2UI catalog function.
|
|
3
|
+
*
|
|
4
|
+
* `{{ price | currency:'USD' }}` was previously reported as unbindable on the
|
|
5
|
+
* grounds that A2UI has no expression language. That is true of the language and
|
|
6
|
+
* false of the catalog: A2UI ships `formatCurrency`, `formatNumber`, `formatDate`
|
|
7
|
+
* and `pluralize` as functions, which is exactly what these pipes are.
|
|
8
|
+
*
|
|
9
|
+
* Seven of prefab's twenty-two built-ins map. The rest — `truncate`, `join`,
|
|
10
|
+
* `selectattr`, `percent`, `compact` and friends — transform data rather than
|
|
11
|
+
* format it and have no equivalent, so they stay unbindable.
|
|
12
|
+
*
|
|
13
|
+
* The date pipes are the one inexact mapping. prefab renders through
|
|
14
|
+
* `toLocaleDateString()`, so the output follows the reader's locale; A2UI's
|
|
15
|
+
* `formatDate` requires an explicit Unicode TR35 pattern. Choosing a pattern
|
|
16
|
+
* changes what the reader sees, so it is done with a diagnostic rather than
|
|
17
|
+
* silently — losing the value entirely would be the worse trade.
|
|
18
|
+
*/
|
|
19
|
+
/** Matches `<base> | <name>` with an optional single `:arg`. */
|
|
20
|
+
const PIPE = /^(.+?)\s*\|\s*([A-Za-z_][\w]*)\s*(?::\s*(.+))?$/;
|
|
21
|
+
/**
|
|
22
|
+
* Split a pipe expression into its parts.
|
|
23
|
+
*
|
|
24
|
+
* Only a single pipe with at most one argument, which is the shape prefab's own
|
|
25
|
+
* evaluator handles. A chained expression returns `undefined` and is reported
|
|
26
|
+
* rather than half-translated.
|
|
27
|
+
*/
|
|
28
|
+
export function parsePipe(expr) {
|
|
29
|
+
const m = PIPE.exec(expr);
|
|
30
|
+
if (m == null)
|
|
31
|
+
return undefined;
|
|
32
|
+
const base = m[1].trim();
|
|
33
|
+
// A second `|` means a chain, which has no single-function equivalent.
|
|
34
|
+
if (base.includes('|'))
|
|
35
|
+
return undefined;
|
|
36
|
+
// `at` rather than indexing: an optional capture group is typed `string` but
|
|
37
|
+
// is genuinely absent when the pipe took no argument.
|
|
38
|
+
const raw = m.at(3)?.trim();
|
|
39
|
+
if (raw === undefined)
|
|
40
|
+
return { base, name: m[2] };
|
|
41
|
+
const quoted = /^'([^']*)'$|^"([^"]*)"$/.exec(raw);
|
|
42
|
+
if (quoted != null) {
|
|
43
|
+
// One alternative matched, so exactly one group is present. An empty capture
|
|
44
|
+
// is a real empty-string argument, which `??` keeps and `||` would discard.
|
|
45
|
+
const literal = quoted.at(1) ?? quoted.at(2);
|
|
46
|
+
return { base, name: m[2], arg: literal ?? '' };
|
|
47
|
+
}
|
|
48
|
+
const num = Number(raw);
|
|
49
|
+
if (!Number.isNaN(num))
|
|
50
|
+
return { base, name: m[2], arg: num };
|
|
51
|
+
// An unquoted, non-numeric argument is a reference prefab would resolve at
|
|
52
|
+
// render time. A2UI function args take a value, not an expression to evaluate.
|
|
53
|
+
return undefined;
|
|
54
|
+
}
|
|
55
|
+
/** Build a `formatDate` call, noting that an explicit pattern replaces the locale. */
|
|
56
|
+
function dateFormat(pattern, pipe) {
|
|
57
|
+
return (value) => ({
|
|
58
|
+
call: { call: 'formatDate', args: { value, format: pattern } },
|
|
59
|
+
note: `the "${pipe}" pipe renders in the reader's locale; A2UI needs an explicit pattern, so "${pattern}" was used`,
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
const BUILDERS = {
|
|
63
|
+
currency: (value, arg) => ({
|
|
64
|
+
call: {
|
|
65
|
+
call: 'formatCurrency',
|
|
66
|
+
// prefab defaults to USD when the pipe is given no code.
|
|
67
|
+
args: { value, currency: typeof arg === 'string' ? arg : 'USD' },
|
|
68
|
+
},
|
|
69
|
+
}),
|
|
70
|
+
number: (value, arg) => ({
|
|
71
|
+
call: {
|
|
72
|
+
call: 'formatNumber',
|
|
73
|
+
args: { value, ...(typeof arg === 'number' && { decimals: arg }) },
|
|
74
|
+
},
|
|
75
|
+
}),
|
|
76
|
+
round: (value, arg) => ({
|
|
77
|
+
call: {
|
|
78
|
+
call: 'formatNumber',
|
|
79
|
+
// prefab's `round` with no argument means whole numbers.
|
|
80
|
+
args: { value, decimals: typeof arg === 'number' ? arg : 0 },
|
|
81
|
+
},
|
|
82
|
+
}),
|
|
83
|
+
pluralize: (value, arg) => {
|
|
84
|
+
if (typeof arg !== 'string')
|
|
85
|
+
return undefined;
|
|
86
|
+
// prefab pluralizes by appending an s, which is the rule it can express.
|
|
87
|
+
return { call: { call: 'pluralize', args: { value, one: arg, other: `${arg}s` } } };
|
|
88
|
+
},
|
|
89
|
+
date: dateFormat('y-MM-dd', 'date'),
|
|
90
|
+
time: dateFormat('HH:mm', 'time'),
|
|
91
|
+
datetime: dateFormat('y-MM-dd HH:mm', 'datetime'),
|
|
92
|
+
};
|
|
93
|
+
/** Every prefab pipe with an A2UI equivalent, for docs and tests. */
|
|
94
|
+
export function mappedPipes() {
|
|
95
|
+
return Object.keys(BUILDERS).sort();
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Map a parsed pipe onto a catalog function.
|
|
99
|
+
*
|
|
100
|
+
* @param value the already-resolved base, as a binding or a literal.
|
|
101
|
+
* @returns `undefined` when the pipe transforms rather than formats.
|
|
102
|
+
*/
|
|
103
|
+
export function pipeCall(pipe, value) {
|
|
104
|
+
return BUILDERS[pipe.name]?.(value, pipe.arg);
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=pipes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pipes.js","sourceRoot":"","sources":["../../src/a2ui/pipes.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Table mappers — the one place a prefab component gains structure on the way
|
|
3
|
+
* out rather than losing it.
|
|
4
|
+
*
|
|
5
|
+
* The A2UI Basic catalog has no table component, so a table becomes a `Column`
|
|
6
|
+
* of `Row`s. For `DataTable` that would be a poor trade, because prefab's table
|
|
7
|
+
* is data-driven and flattening it would inline every row as its own component
|
|
8
|
+
* and lose the binding. A2UI's own answer is the child template: a `Column`
|
|
9
|
+
* whose `children` is `{ path, componentId }` instantiates one copy of the
|
|
10
|
+
* template component per item in a data-model list, and paths inside the
|
|
11
|
+
* template resolve relative to the current item. That maps onto `DataTable`
|
|
12
|
+
* exactly — one `Row` template, one `Text` per column bound to the column key —
|
|
13
|
+
* so the emitted surface stays as small and as reactive as the prefab original.
|
|
14
|
+
*
|
|
15
|
+
* The pattern follows `catalogs/basic/examples/18_track-list.json` in the A2UI
|
|
16
|
+
* specification, which is the normative example for templated lists.
|
|
17
|
+
*/
|
|
18
|
+
import type { ComponentJSON } from '../core/component.js';
|
|
19
|
+
import type { A2uiProps, EmitContext } from './catalog.js';
|
|
20
|
+
/** prefab table parts that only exist inside a `Table` and never map on their own. */
|
|
21
|
+
export declare const TABLE_PART_TYPES: readonly ["TableHead", "TableBody", "TableFooter", "TableRow", "TableCell", "TableHeader", "ExpandableRow"];
|
|
22
|
+
/**
|
|
23
|
+
* `DataTable` → a header `Row` plus a templated `Column`.
|
|
24
|
+
*
|
|
25
|
+
* A column key containing a `.` addresses a nested field on the row. Relative
|
|
26
|
+
* paths inside a template are JSON Pointers too, so the dots become slashes.
|
|
27
|
+
*/
|
|
28
|
+
export declare function mapDataTable(node: ComponentJSON, ctx: EmitContext): A2uiProps | undefined;
|
|
29
|
+
/** `Table` → a `Column` of `Row`s, one per `TableRow`. */
|
|
30
|
+
export declare function mapTable(node: ComponentJSON, ctx: EmitContext): A2uiProps | undefined;
|
|
31
|
+
//# sourceMappingURL=table.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"table.d.ts","sourceRoot":"","sources":["../../src/a2ui/table.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AACzD,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAG1D,sFAAsF;AACtF,eAAO,MAAM,gBAAgB,6GAEnB,CAAA;AAyCV;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,aAAa,EAAE,GAAG,EAAE,WAAW,GAAG,SAAS,GAAG,SAAS,CAkCzF;AAyCD,0DAA0D;AAC1D,wBAAgB,QAAQ,CAAC,IAAI,EAAE,aAAa,EAAE,GAAG,EAAE,WAAW,GAAG,SAAS,GAAG,SAAS,CAkBrF"}
|