@streetui/dsl 1.0.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/LICENSE +21 -0
- package/README.md +26 -0
- package/dist/index.cjs +421 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +278 -0
- package/dist/index.d.ts +278 -0
- package/dist/index.js +385 -0
- package/dist/index.js.map +1 -0
- package/package.json +47 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 StreetUI contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# @streetui/dsl
|
|
2
|
+
|
|
3
|
+
StreetUI semantic TypeScript DSL
|
|
4
|
+
|
|
5
|
+
Part of [StreetUI](https://github.com/streetui/streetui) — a semantic,
|
|
6
|
+
signal-based UI framework with its own reactivity and keyed DOM reconciler
|
|
7
|
+
(no virtual DOM).
|
|
8
|
+
|
|
9
|
+
## Install
|
|
10
|
+
|
|
11
|
+
```sh
|
|
12
|
+
npm install @streetui/dsl
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Usage
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
import * as pkg from '@streetui/dsl';
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Both ESM (`import`) and CommonJS (`require`) entry points are shipped, with
|
|
22
|
+
matching TypeScript declarations.
|
|
23
|
+
|
|
24
|
+
## License
|
|
25
|
+
|
|
26
|
+
MIT
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,421 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
AppBuilder: () => AppBuilder,
|
|
24
|
+
ContainerBuilderImpl: () => ContainerBuilderImpl,
|
|
25
|
+
FormBuilderImpl: () => FormBuilderImpl,
|
|
26
|
+
ListBuilderImpl: () => ListBuilderImpl,
|
|
27
|
+
PageBuilderImpl: () => PageBuilderImpl,
|
|
28
|
+
SectionBuilderImpl: () => SectionBuilderImpl,
|
|
29
|
+
StreetApp: () => StreetApp,
|
|
30
|
+
reactiveListItemKey: () => reactiveListItemKey,
|
|
31
|
+
reactiveListItemSignature: () => reactiveListItemSignature,
|
|
32
|
+
streetui: () => streetui
|
|
33
|
+
});
|
|
34
|
+
module.exports = __toCommonJS(index_exports);
|
|
35
|
+
|
|
36
|
+
// src/builders.ts
|
|
37
|
+
var import_state = require("@streetui/state");
|
|
38
|
+
function isSignal(v) {
|
|
39
|
+
return v !== null && typeof v === "object" && typeof v["get"] === "function" && typeof v["subscribe"] === "function";
|
|
40
|
+
}
|
|
41
|
+
function bindValue(graph, node, propKey, value) {
|
|
42
|
+
if (isSignal(value)) {
|
|
43
|
+
const signalId = `${node.id}:${propKey}`;
|
|
44
|
+
node.stateRefs.push({ signalId, propKey });
|
|
45
|
+
graph.registerHandler(`__signal__${signalId}`, value);
|
|
46
|
+
return value.peek();
|
|
47
|
+
}
|
|
48
|
+
return value;
|
|
49
|
+
}
|
|
50
|
+
function applyA11yProps(props, options) {
|
|
51
|
+
if (options.role !== void 0) props["role"] = options.role;
|
|
52
|
+
if (options.tabIndex !== void 0) props["tabindex"] = String(options.tabIndex);
|
|
53
|
+
if (options.ariaLabel !== void 0) props["aria-label"] = options.ariaLabel;
|
|
54
|
+
if (options.ariaLabelledBy !== void 0) props["aria-labelledby"] = options.ariaLabelledBy;
|
|
55
|
+
if (options.ariaDescribedBy !== void 0) props["aria-describedby"] = options.ariaDescribedBy;
|
|
56
|
+
if (options.ariaExpanded !== void 0) props["aria-expanded"] = String(options.ariaExpanded);
|
|
57
|
+
if (options.ariaControls !== void 0) props["aria-controls"] = options.ariaControls;
|
|
58
|
+
if (options.ariaHidden !== void 0) props["aria-hidden"] = String(options.ariaHidden);
|
|
59
|
+
if (options.ariaLive !== void 0) props["aria-live"] = options.ariaLive;
|
|
60
|
+
if (options.ariaCurrent !== void 0) props["aria-current"] = String(options.ariaCurrent);
|
|
61
|
+
if (options.ariaInvalid !== void 0) props["aria-invalid"] = String(options.ariaInvalid);
|
|
62
|
+
if (options.ariaRequired !== void 0) props["aria-required"] = String(options.ariaRequired);
|
|
63
|
+
}
|
|
64
|
+
function containerProps(options) {
|
|
65
|
+
const props = {};
|
|
66
|
+
if (options.class !== void 0) props["class"] = options.class;
|
|
67
|
+
if (options.id !== void 0) props["id"] = options.id;
|
|
68
|
+
if (options.key !== void 0) props["key"] = options.key;
|
|
69
|
+
applyA11yProps(props, options);
|
|
70
|
+
return props;
|
|
71
|
+
}
|
|
72
|
+
function itemIdentity(item, index) {
|
|
73
|
+
if (item !== null && typeof item === "object") {
|
|
74
|
+
const obj = item;
|
|
75
|
+
if ("id" in obj) return `id:${String(obj["id"])}`;
|
|
76
|
+
if ("key" in obj) return `key:${String(obj["key"])}`;
|
|
77
|
+
return `idx:${index}`;
|
|
78
|
+
}
|
|
79
|
+
return `val:${String(item)}`;
|
|
80
|
+
}
|
|
81
|
+
function itemValueSignature(item) {
|
|
82
|
+
try {
|
|
83
|
+
return JSON.stringify(item) ?? String(item);
|
|
84
|
+
} catch {
|
|
85
|
+
return String(item);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
function reactiveListItemSignature(item) {
|
|
89
|
+
return itemValueSignature(item);
|
|
90
|
+
}
|
|
91
|
+
function reactiveListItemKey(item, index) {
|
|
92
|
+
return itemIdentity(item, index);
|
|
93
|
+
}
|
|
94
|
+
var ContentBuilderBase = class {
|
|
95
|
+
constructor(_node, _graph) {
|
|
96
|
+
this._node = _node;
|
|
97
|
+
this._graph = _graph;
|
|
98
|
+
}
|
|
99
|
+
heading(text, options = {}) {
|
|
100
|
+
const props = { level: options.level ?? 1 };
|
|
101
|
+
if (options.class !== void 0) props["class"] = options.class;
|
|
102
|
+
if (options.id !== void 0) props["id"] = options.id;
|
|
103
|
+
applyA11yProps(props, options);
|
|
104
|
+
const node = this._graph.createNode("heading", { parent: this._node, props });
|
|
105
|
+
const resolved = bindValue(this._graph, node, "text", text);
|
|
106
|
+
node.setProp("text", resolved);
|
|
107
|
+
}
|
|
108
|
+
text(content, options = {}) {
|
|
109
|
+
const props = {};
|
|
110
|
+
if (options.class !== void 0) props["class"] = options.class;
|
|
111
|
+
if (options.id !== void 0) props["id"] = options.id;
|
|
112
|
+
applyA11yProps(props, options);
|
|
113
|
+
const node = this._graph.createNode("text", { parent: this._node, props });
|
|
114
|
+
const resolved = bindValue(this._graph, node, "text", content);
|
|
115
|
+
node.setProp("text", resolved);
|
|
116
|
+
}
|
|
117
|
+
button(label, options = {}) {
|
|
118
|
+
const props = {};
|
|
119
|
+
if (options.class !== void 0) props["class"] = options.class;
|
|
120
|
+
if (options.id !== void 0) props["id"] = options.id;
|
|
121
|
+
applyA11yProps(props, options);
|
|
122
|
+
const node = this._graph.createNode("button", { parent: this._node, props });
|
|
123
|
+
const resolved = bindValue(this._graph, node, "label", label);
|
|
124
|
+
node.setProp("label", resolved);
|
|
125
|
+
if (options.disabled !== void 0) {
|
|
126
|
+
const resolvedDisabled = bindValue(this._graph, node, "disabled", options.disabled);
|
|
127
|
+
node.setProp("disabled", resolvedDisabled);
|
|
128
|
+
}
|
|
129
|
+
if (options.onClick !== void 0) {
|
|
130
|
+
const handlerKey = `click:${node.id}`;
|
|
131
|
+
this._graph.registerHandler(handlerKey, options.onClick);
|
|
132
|
+
node.addEvent({ type: "click", handlerKey });
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
input(options = {}) {
|
|
136
|
+
const props = {};
|
|
137
|
+
props["inputType"] = options.type ?? "text";
|
|
138
|
+
if (options.placeholder !== void 0) props["placeholder"] = options.placeholder;
|
|
139
|
+
if (options.class !== void 0) props["class"] = options.class;
|
|
140
|
+
if (options.id !== void 0) props["id"] = options.id;
|
|
141
|
+
applyA11yProps(props, options);
|
|
142
|
+
const nodeOpts = {
|
|
143
|
+
props,
|
|
144
|
+
parent: this._node
|
|
145
|
+
};
|
|
146
|
+
if (options.id !== void 0) nodeOpts.key = options.id;
|
|
147
|
+
const node = this._graph.createNode("input", nodeOpts);
|
|
148
|
+
const bindSignal = options.bind;
|
|
149
|
+
const valueBindable = bindSignal !== void 0 ? bindSignal : options.value;
|
|
150
|
+
const inputHandler = bindSignal !== void 0 ? (v) => bindSignal.set(v) : options.onInput;
|
|
151
|
+
if (valueBindable !== void 0) {
|
|
152
|
+
const resolved = bindValue(this._graph, node, "value", valueBindable);
|
|
153
|
+
node.setProp("value", resolved);
|
|
154
|
+
}
|
|
155
|
+
if (options.disabled !== void 0) {
|
|
156
|
+
const resolved = bindValue(this._graph, node, "disabled", options.disabled);
|
|
157
|
+
node.setProp("disabled", resolved);
|
|
158
|
+
}
|
|
159
|
+
if (inputHandler !== void 0) {
|
|
160
|
+
const handlerKey = `input:${node.id}`;
|
|
161
|
+
this._graph.registerHandler(handlerKey, inputHandler);
|
|
162
|
+
node.addEvent({ type: "input", handlerKey });
|
|
163
|
+
}
|
|
164
|
+
if (options.onChange !== void 0) {
|
|
165
|
+
const handlerKey = `change:${node.id}`;
|
|
166
|
+
this._graph.registerHandler(handlerKey, options.onChange);
|
|
167
|
+
node.addEvent({ type: "change", handlerKey });
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
image(options) {
|
|
171
|
+
const props = {
|
|
172
|
+
src: options.src,
|
|
173
|
+
alt: options.alt
|
|
174
|
+
};
|
|
175
|
+
if (options.width !== void 0) props["width"] = options.width;
|
|
176
|
+
if (options.height !== void 0) props["height"] = options.height;
|
|
177
|
+
if (options.class !== void 0) props["class"] = options.class;
|
|
178
|
+
if (options.id !== void 0) props["id"] = options.id;
|
|
179
|
+
applyA11yProps(props, options);
|
|
180
|
+
const nodeOpts = {
|
|
181
|
+
props,
|
|
182
|
+
parent: this._node
|
|
183
|
+
};
|
|
184
|
+
if (options.id !== void 0) nodeOpts.key = options.id;
|
|
185
|
+
this._graph.createNode("image", nodeOpts);
|
|
186
|
+
}
|
|
187
|
+
link(label, options) {
|
|
188
|
+
const props = {
|
|
189
|
+
href: options.href,
|
|
190
|
+
external: options.external ?? false
|
|
191
|
+
};
|
|
192
|
+
if (options.class !== void 0) props["class"] = options.class;
|
|
193
|
+
if (options.id !== void 0) props["id"] = options.id;
|
|
194
|
+
applyA11yProps(props, options);
|
|
195
|
+
const node = this._graph.createNode("link", { parent: this._node, props });
|
|
196
|
+
const resolved = bindValue(this._graph, node, "label", label);
|
|
197
|
+
node.setProp("label", resolved);
|
|
198
|
+
if (options.onClick !== void 0) {
|
|
199
|
+
const handlerKey = `click:${node.id}`;
|
|
200
|
+
this._graph.registerHandler(handlerKey, options.onClick);
|
|
201
|
+
node.addEvent({ type: "click", handlerKey });
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
};
|
|
205
|
+
var ContainerBuilderBase = class extends ContentBuilderBase {
|
|
206
|
+
section(key, builder, options = {}) {
|
|
207
|
+
const node = this._graph.createNode("section", {
|
|
208
|
+
key,
|
|
209
|
+
parent: this._node,
|
|
210
|
+
props: containerProps(options)
|
|
211
|
+
});
|
|
212
|
+
builder(new SectionBuilderImpl(node, this._graph));
|
|
213
|
+
}
|
|
214
|
+
container(key, builder, options = {}) {
|
|
215
|
+
const node = this._graph.createNode("container", {
|
|
216
|
+
key,
|
|
217
|
+
parent: this._node,
|
|
218
|
+
props: containerProps(options)
|
|
219
|
+
});
|
|
220
|
+
builder(new ContainerBuilderImpl(node, this._graph));
|
|
221
|
+
}
|
|
222
|
+
list(key, builder, options = {}) {
|
|
223
|
+
const node = this._graph.createNode("list", {
|
|
224
|
+
key,
|
|
225
|
+
parent: this._node,
|
|
226
|
+
props: containerProps(options)
|
|
227
|
+
});
|
|
228
|
+
builder(new ListBuilderImpl(node, this._graph));
|
|
229
|
+
}
|
|
230
|
+
listOf(key, items, renderItem, options = {}) {
|
|
231
|
+
const graph = this._graph;
|
|
232
|
+
const node = graph.createNode("reactive-list", {
|
|
233
|
+
key,
|
|
234
|
+
parent: this._node,
|
|
235
|
+
props: containerProps(options)
|
|
236
|
+
});
|
|
237
|
+
const signalId = `${node.id}:items`;
|
|
238
|
+
node.stateRefs.push({ signalId, propKey: "items" });
|
|
239
|
+
graph.registerHandler(`__signal__${signalId}`, items);
|
|
240
|
+
const buildItem = (item, index) => {
|
|
241
|
+
const itemKey = reactiveListItemKey(item, index);
|
|
242
|
+
const itemNode = graph.createNode("list-item", {
|
|
243
|
+
key: itemKey,
|
|
244
|
+
props: { key: itemKey, _sig: reactiveListItemSignature(item) }
|
|
245
|
+
});
|
|
246
|
+
renderItem(item, index, new ContainerBuilderImpl(itemNode, graph));
|
|
247
|
+
return itemNode;
|
|
248
|
+
};
|
|
249
|
+
const buildAll = (raw) => {
|
|
250
|
+
const arr = Array.isArray(raw) ? raw : [];
|
|
251
|
+
return arr.map((item, i) => buildItem(item, i));
|
|
252
|
+
};
|
|
253
|
+
graph.registerHandler(`__listbuild__${node.id}`, buildAll);
|
|
254
|
+
const current = isSignal(items) ? items.peek() : items;
|
|
255
|
+
const initial = Array.isArray(current) ? current : [];
|
|
256
|
+
initial.forEach((item, i) => {
|
|
257
|
+
node.appendChild(buildItem(item, i));
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
form(key, builder, options = {}) {
|
|
261
|
+
const props = containerProps(options);
|
|
262
|
+
const node = this._graph.createNode("form", {
|
|
263
|
+
key,
|
|
264
|
+
parent: this._node,
|
|
265
|
+
props
|
|
266
|
+
});
|
|
267
|
+
if (options.onSubmit !== void 0) {
|
|
268
|
+
const handlerKey = `submit:${node.id}`;
|
|
269
|
+
this._graph.registerHandler(handlerKey, options.onSubmit);
|
|
270
|
+
node.addEvent({ type: "submit", handlerKey });
|
|
271
|
+
}
|
|
272
|
+
builder(new FormBuilderImpl(node, this._graph));
|
|
273
|
+
}
|
|
274
|
+
when(condition, builder, elseBuilder) {
|
|
275
|
+
const graph = this._graph;
|
|
276
|
+
const node = graph.createNode("conditional", {
|
|
277
|
+
parent: this._node,
|
|
278
|
+
props: containerProps({})
|
|
279
|
+
});
|
|
280
|
+
const buildBranch = (build, tag) => {
|
|
281
|
+
const branchKey = `when-${tag}:${node.id}`;
|
|
282
|
+
const branch = graph.createNode("container", {
|
|
283
|
+
key: branchKey,
|
|
284
|
+
props: { key: branchKey }
|
|
285
|
+
});
|
|
286
|
+
build(new ContainerBuilderImpl(branch, graph));
|
|
287
|
+
return branch;
|
|
288
|
+
};
|
|
289
|
+
const buildAll = (raw) => {
|
|
290
|
+
if (raw) return [buildBranch(builder, "then")];
|
|
291
|
+
return elseBuilder !== void 0 ? [buildBranch(elseBuilder, "else")] : [];
|
|
292
|
+
};
|
|
293
|
+
if (isSignal(condition)) {
|
|
294
|
+
const signalId = `${node.id}:items`;
|
|
295
|
+
node.stateRefs.push({ signalId, propKey: "items" });
|
|
296
|
+
graph.registerHandler(`__signal__${signalId}`, condition);
|
|
297
|
+
graph.registerHandler(`__listbuild__${node.id}`, buildAll);
|
|
298
|
+
const current = condition.peek();
|
|
299
|
+
for (const child of buildAll(current)) node.appendChild(child);
|
|
300
|
+
} else {
|
|
301
|
+
for (const child of buildAll(condition)) node.appendChild(child);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
errorBoundary(id, builder, options) {
|
|
305
|
+
const sources = options.source === void 0 ? [] : Array.isArray(options.source) ? [...options.source] : [options.source];
|
|
306
|
+
const localError = (0, import_state.signal)(void 0);
|
|
307
|
+
const retryNonce = (0, import_state.signal)(0);
|
|
308
|
+
const readError = () => {
|
|
309
|
+
const local = localError.peek();
|
|
310
|
+
if (local !== void 0 && local !== null) return local;
|
|
311
|
+
for (const s of sources) {
|
|
312
|
+
const e = s.peek();
|
|
313
|
+
if (e !== void 0 && e !== null) return e;
|
|
314
|
+
}
|
|
315
|
+
return void 0;
|
|
316
|
+
};
|
|
317
|
+
const hasError = (0, import_state.derived)(() => {
|
|
318
|
+
retryNonce.get();
|
|
319
|
+
localError.get();
|
|
320
|
+
for (const s of sources) s.get();
|
|
321
|
+
return readError() !== void 0;
|
|
322
|
+
});
|
|
323
|
+
const retry = () => {
|
|
324
|
+
localError.set(void 0);
|
|
325
|
+
options.onRetry?.();
|
|
326
|
+
retryNonce.update((n) => n + 1);
|
|
327
|
+
};
|
|
328
|
+
this.container(id, (c) => {
|
|
329
|
+
c.when(
|
|
330
|
+
hasError,
|
|
331
|
+
// Error state → fallback.
|
|
332
|
+
(fb) => options.fallback(fb, readError(), retry),
|
|
333
|
+
// Healthy state → body, guarded against synchronous build throws.
|
|
334
|
+
(body) => {
|
|
335
|
+
try {
|
|
336
|
+
builder(body);
|
|
337
|
+
} catch (err) {
|
|
338
|
+
queueMicrotask(() => localError.set(err));
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
);
|
|
342
|
+
}, { id });
|
|
343
|
+
}
|
|
344
|
+
};
|
|
345
|
+
var SectionBuilderImpl = class extends ContainerBuilderBase {
|
|
346
|
+
};
|
|
347
|
+
var ContainerBuilderImpl = class extends ContainerBuilderBase {
|
|
348
|
+
};
|
|
349
|
+
var FormBuilderImpl = class extends ContainerBuilderBase {
|
|
350
|
+
};
|
|
351
|
+
var ListBuilderImpl = class extends ContentBuilderBase {
|
|
352
|
+
item(key, builder, options = {}) {
|
|
353
|
+
const node = this._graph.createNode("list-item", {
|
|
354
|
+
key,
|
|
355
|
+
parent: this._node,
|
|
356
|
+
props: containerProps(options)
|
|
357
|
+
});
|
|
358
|
+
builder(new ContainerBuilderImpl(node, this._graph));
|
|
359
|
+
}
|
|
360
|
+
};
|
|
361
|
+
var PageBuilderImpl = class extends ContainerBuilderBase {
|
|
362
|
+
};
|
|
363
|
+
var AppBuilder = class {
|
|
364
|
+
constructor(_graph) {
|
|
365
|
+
this._graph = _graph;
|
|
366
|
+
}
|
|
367
|
+
page(key, builder) {
|
|
368
|
+
const node = this._graph.createNode("page", {
|
|
369
|
+
key,
|
|
370
|
+
parent: this._graph.root,
|
|
371
|
+
props: { key }
|
|
372
|
+
});
|
|
373
|
+
builder(new PageBuilderImpl(node, this._graph));
|
|
374
|
+
}
|
|
375
|
+
};
|
|
376
|
+
|
|
377
|
+
// src/dsl.ts
|
|
378
|
+
var import_graph = require("@streetui/graph");
|
|
379
|
+
var StreetApp = class {
|
|
380
|
+
_graph;
|
|
381
|
+
_builder;
|
|
382
|
+
constructor(options) {
|
|
383
|
+
const graphOpts = { name: options.name };
|
|
384
|
+
if (options.version !== void 0) graphOpts.version = options.version;
|
|
385
|
+
this._graph = new import_graph.ApplicationGraph(graphOpts);
|
|
386
|
+
this._builder = new AppBuilder(this._graph);
|
|
387
|
+
}
|
|
388
|
+
page(key, builder) {
|
|
389
|
+
this._builder.page(key, builder);
|
|
390
|
+
return this;
|
|
391
|
+
}
|
|
392
|
+
/** Compile to ApplicationGraph — validates and returns the graph. */
|
|
393
|
+
build() {
|
|
394
|
+
const dc = this._graph.validate();
|
|
395
|
+
dc.throwIfErrors();
|
|
396
|
+
return this._graph;
|
|
397
|
+
}
|
|
398
|
+
/** Access graph before building (useful for inspection). */
|
|
399
|
+
get graph() {
|
|
400
|
+
return this._graph;
|
|
401
|
+
}
|
|
402
|
+
};
|
|
403
|
+
var streetui = {
|
|
404
|
+
app(options) {
|
|
405
|
+
return new StreetApp(options);
|
|
406
|
+
}
|
|
407
|
+
};
|
|
408
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
409
|
+
0 && (module.exports = {
|
|
410
|
+
AppBuilder,
|
|
411
|
+
ContainerBuilderImpl,
|
|
412
|
+
FormBuilderImpl,
|
|
413
|
+
ListBuilderImpl,
|
|
414
|
+
PageBuilderImpl,
|
|
415
|
+
SectionBuilderImpl,
|
|
416
|
+
StreetApp,
|
|
417
|
+
reactiveListItemKey,
|
|
418
|
+
reactiveListItemSignature,
|
|
419
|
+
streetui
|
|
420
|
+
});
|
|
421
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/builders.ts","../src/dsl.ts"],"sourcesContent":["export * from './dsl-types.js';\nexport * from './builders.js';\nexport * from './dsl.js';\n","/**\n * DSL builder implementations.\n *\n * Each builder wraps a GraphNode and provides the fluent API\n * for constructing the Semantic Application Graph via the DSL.\n *\n * Builders do NOT render anything — they only build the graph.\n */\n\nimport { ApplicationGraph, GraphNode, type Props } from '@streetui/graph';\nimport type {\n ContentDSL,\n ContainerDSL,\n SectionDSL,\n PageDSL,\n FormDSL,\n ListDSL,\n AppDSL,\n HeadingOptions,\n TextOptions,\n ButtonOptions,\n InputOptions,\n LinkOptions,\n ImageOptions,\n ContainerOptions,\n SectionOptions,\n FormOptions,\n ListOptions,\n A11yOptions,\n Bindable,\n BindableText,\n TextValue,\n ErrorBoundaryOptions,\n ErrorSource,\n PageBuilder,\n SectionBuilder,\n ContainerBuilder as ContainerBuilderFn,\n FormBuilder,\n ListBuilder,\n} from './dsl-types.js';\nimport { signal, derived, type Signal, type ReadonlySignal } from '@streetui/state';\n\n// ── Signal helpers ────────────────────────────────────────────────────────────\n\nfunction isSignal(v: unknown): v is Signal<unknown> | ReadonlySignal<unknown> {\n return (\n v !== null &&\n typeof v === 'object' &&\n typeof (v as Record<string, unknown>)['get'] === 'function' &&\n typeof (v as Record<string, unknown>)['subscribe'] === 'function'\n );\n}\n\n/** Register a signal binding on the node and return the current static value. */\nfunction bindValue<T>(\n graph: ApplicationGraph,\n node: GraphNode,\n propKey: string,\n value: Bindable<T>,\n): T {\n if (isSignal(value)) {\n const signalId = `${node.id}:${propKey}`;\n node.stateRefs.push({ signalId, propKey });\n graph.registerHandler(`__signal__${signalId}`, value as unknown as () => unknown);\n return (value as ReadonlySignal<T>).peek();\n }\n return value as T;\n}\n\n// ── Helper to build Props from ContainerOptions ───────────────────────────────\n\n/**\n * Copy accessibility options onto a props bag as their corresponding HTML/ARIA\n * attribute names. Values are written as strings (booleans become \"true\"/\"false\"\n * rather than being dropped) so ARIA state attributes render literally. These\n * flow to the DOM via the renderer's generic attribute pass — no ARIA-specific\n * renderer code is involved.\n */\nfunction applyA11yProps(props: Props, options: A11yOptions): void {\n if (options.role !== undefined) props['role'] = options.role;\n if (options.tabIndex !== undefined) props['tabindex'] = String(options.tabIndex);\n if (options.ariaLabel !== undefined) props['aria-label'] = options.ariaLabel;\n if (options.ariaLabelledBy !== undefined) props['aria-labelledby'] = options.ariaLabelledBy;\n if (options.ariaDescribedBy !== undefined) props['aria-describedby'] = options.ariaDescribedBy;\n if (options.ariaExpanded !== undefined) props['aria-expanded'] = String(options.ariaExpanded);\n if (options.ariaControls !== undefined) props['aria-controls'] = options.ariaControls;\n if (options.ariaHidden !== undefined) props['aria-hidden'] = String(options.ariaHidden);\n if (options.ariaLive !== undefined) props['aria-live'] = options.ariaLive;\n if (options.ariaCurrent !== undefined) props['aria-current'] = String(options.ariaCurrent);\n if (options.ariaInvalid !== undefined) props['aria-invalid'] = String(options.ariaInvalid);\n if (options.ariaRequired !== undefined) props['aria-required'] = String(options.ariaRequired);\n}\n\nfunction containerProps(options: ContainerOptions): Props {\n const props: Props = {};\n if (options.class !== undefined) props['class'] = options.class;\n if (options.id !== undefined) props['id'] = options.id;\n if (options.key !== undefined) props['key'] = options.key;\n applyA11yProps(props, options);\n return props;\n}\n\n// ── Reactive-list item keying ──────────────────────────────────────────────────\n//\n// The `listOf` DSL signature does not take an explicit key extractor, so we\n// derive a stable reconciliation key from each item. The key combines an\n// *identity* part (so reordering the same items reuses their DOM nodes) with a\n// *value signature* (so an item whose data changed is treated as a fresh node\n// and re-rendered rather than silently kept stale by the shallow reconciler).\n\nfunction itemIdentity(item: unknown, index: number): string {\n if (item !== null && typeof item === 'object') {\n const obj = item as Record<string, unknown>;\n if ('id' in obj) return `id:${String(obj['id'])}`;\n if ('key' in obj) return `key:${String(obj['key'])}`;\n return `idx:${index}`;\n }\n return `val:${String(item)}`;\n}\n\nfunction itemValueSignature(item: unknown): string {\n try {\n return JSON.stringify(item) ?? String(item);\n } catch {\n return String(item);\n }\n}\n\n/** Content signature used to detect in-place data changes of a stable item. */\nexport function reactiveListItemSignature(item: unknown): string {\n return itemValueSignature(item);\n}\n\n/** Stable, identity-only reconciliation key for a reactive-list item. */\nexport function reactiveListItemKey(item: unknown, index: number): string {\n return itemIdentity(item, index);\n}\n\n// ── Base content builder ──────────────────────────────────────────────────────\n\nclass ContentBuilderBase implements ContentDSL {\n constructor(\n protected readonly _node: GraphNode,\n protected readonly _graph: ApplicationGraph,\n ) {}\n\n heading(text: BindableText, options: HeadingOptions = {}): void {\n const props: Props = { level: options.level ?? 1 };\n if (options.class !== undefined) props['class'] = options.class;\n if (options.id !== undefined) props['id'] = options.id;\n applyA11yProps(props, options);\n const node = this._graph.createNode('heading', { parent: this._node, props });\n const resolved = bindValue<TextValue>(this._graph, node, 'text', text);\n node.setProp('text', resolved);\n }\n\n text(content: BindableText, options: TextOptions = {}): void {\n const props: Props = {};\n if (options.class !== undefined) props['class'] = options.class;\n if (options.id !== undefined) props['id'] = options.id;\n applyA11yProps(props, options);\n const node = this._graph.createNode('text', { parent: this._node, props });\n const resolved = bindValue<TextValue>(this._graph, node, 'text', content);\n node.setProp('text', resolved);\n }\n\n button(label: BindableText, options: ButtonOptions = {}): void {\n const props: Props = {};\n if (options.class !== undefined) props['class'] = options.class;\n if (options.id !== undefined) props['id'] = options.id;\n applyA11yProps(props, options);\n const node = this._graph.createNode('button', { parent: this._node, props });\n const resolved = bindValue<TextValue>(this._graph, node, 'label', label);\n node.setProp('label', resolved);\n if (options.disabled !== undefined) {\n const resolvedDisabled = bindValue(this._graph, node, 'disabled', options.disabled);\n node.setProp('disabled', resolvedDisabled);\n }\n if (options.onClick !== undefined) {\n const handlerKey = `click:${node.id}`;\n this._graph.registerHandler(handlerKey, options.onClick as () => unknown);\n node.addEvent({ type: 'click', handlerKey });\n }\n }\n\n input(options: InputOptions = {}): void {\n const props: Props = {};\n props['inputType'] = options.type ?? 'text';\n if (options.placeholder !== undefined) props['placeholder'] = options.placeholder;\n if (options.class !== undefined) props['class'] = options.class;\n if (options.id !== undefined) props['id'] = options.id;\n applyA11yProps(props, options);\n const nodeOpts: { key?: string; props: Props; parent: GraphNode } = {\n props,\n parent: this._node,\n };\n if (options.id !== undefined) nodeOpts.key = options.id;\n const node = this._graph.createNode('input', nodeOpts);\n\n // Two-way `bind` expands to a value binding + an input write-back. The type\n // system (BoundInputOptions vs ControlledInputOptions) guarantees `bind` is\n // never combined with explicit `value`/`onInput`, so there is no ambiguity.\n const bindSignal = options.bind;\n const valueBindable: Bindable<string> | undefined =\n bindSignal !== undefined ? bindSignal : options.value;\n const inputHandler: ((value: string) => void) | undefined =\n bindSignal !== undefined ? (v: string) => bindSignal.set(v) : options.onInput;\n\n if (valueBindable !== undefined) {\n const resolved = bindValue(this._graph, node, 'value', valueBindable);\n node.setProp('value', resolved);\n }\n if (options.disabled !== undefined) {\n const resolved = bindValue(this._graph, node, 'disabled', options.disabled);\n node.setProp('disabled', resolved);\n }\n if (inputHandler !== undefined) {\n const handlerKey = `input:${node.id}`;\n this._graph.registerHandler(handlerKey, inputHandler as () => unknown);\n node.addEvent({ type: 'input', handlerKey });\n }\n if (options.onChange !== undefined) {\n const handlerKey = `change:${node.id}`;\n this._graph.registerHandler(handlerKey, options.onChange as () => unknown);\n node.addEvent({ type: 'change', handlerKey });\n }\n }\n\n image(options: ImageOptions): void {\n const props: Props = {\n src: options.src,\n alt: options.alt,\n };\n if (options.width !== undefined) props['width'] = options.width;\n if (options.height !== undefined) props['height'] = options.height;\n if (options.class !== undefined) props['class'] = options.class;\n if (options.id !== undefined) props['id'] = options.id;\n applyA11yProps(props, options);\n const nodeOpts: { key?: string; props: Props; parent: GraphNode } = {\n props,\n parent: this._node,\n };\n if (options.id !== undefined) nodeOpts.key = options.id;\n this._graph.createNode('image', nodeOpts);\n }\n\n link(label: BindableText, options: LinkOptions): void {\n const props: Props = {\n href: options.href,\n external: options.external ?? false,\n };\n if (options.class !== undefined) props['class'] = options.class;\n if (options.id !== undefined) props['id'] = options.id;\n applyA11yProps(props, options);\n const node = this._graph.createNode('link', { parent: this._node, props });\n const resolved = bindValue<TextValue>(this._graph, node, 'label', label);\n node.setProp('label', resolved);\n if (options.onClick !== undefined) {\n const handlerKey = `click:${node.id}`;\n this._graph.registerHandler(handlerKey, options.onClick as () => unknown);\n node.addEvent({ type: 'click', handlerKey });\n }\n }\n}\n\n// ── Container builder ─────────────────────────────────────────────────────────\n\nclass ContainerBuilderBase extends ContentBuilderBase implements ContainerDSL {\n section(key: string, builder: SectionBuilder, options: SectionOptions = {}): void {\n const node = this._graph.createNode('section', {\n key,\n parent: this._node,\n props: containerProps(options),\n });\n builder(new SectionBuilderImpl(node, this._graph));\n }\n\n container(key: string, builder: ContainerBuilderFn, options: ContainerOptions = {}): void {\n const node = this._graph.createNode('container', {\n key,\n parent: this._node,\n props: containerProps(options),\n });\n builder(new ContainerBuilderImpl(node, this._graph));\n }\n\n list(key: string, builder: ListBuilder, options: ListOptions = {}): void {\n const node = this._graph.createNode('list', {\n key,\n parent: this._node,\n props: containerProps(options),\n });\n builder(new ListBuilderImpl(node, this._graph));\n }\n\n listOf<T>(\n key: string,\n items: Signal<T[]> | ReadonlySignal<T[]>,\n renderItem: (item: T, index: number, content: ContentDSL) => void,\n options: ListOptions = {},\n ): void {\n const graph = this._graph;\n const node = graph.createNode('reactive-list', {\n key,\n parent: this._node,\n props: containerProps(options),\n });\n\n // Register the driving signal so the runtime/renderer can subscribe to it.\n const signalId = `${node.id}:items`;\n node.stateRefs.push({ signalId, propKey: 'items' });\n graph.registerHandler(`__signal__${signalId}`, items as unknown as () => unknown);\n\n // Build a single detached list-item subtree for one item. The item's\n // reconciliation `key` is identity-only, and its value signature is stored\n // in the internal `_sig` prop so the renderer can detect (and apply a\n // targeted update for) a data change on an item whose identity is stable.\n const buildItem = (item: T, index: number): GraphNode => {\n const itemKey = reactiveListItemKey(item, index);\n const itemNode = graph.createNode('list-item', {\n key: itemKey,\n props: { key: itemKey, _sig: reactiveListItemSignature(item) },\n });\n renderItem(item, index, new ContainerBuilderImpl(itemNode, graph));\n return itemNode;\n };\n\n // Factory the renderer invokes on every change to produce the desired,\n // freshly-rendered child nodes for the new items array.\n const buildAll = (raw: unknown): GraphNode[] => {\n const arr = Array.isArray(raw) ? (raw as T[]) : [];\n return arr.map((item, i) => buildItem(item, i));\n };\n graph.registerHandler(`__listbuild__${node.id}`, buildAll as unknown as () => unknown);\n\n // Build the initial children into the graph so the first mount renders them.\n const current = isSignal(items)\n ? (items as ReadonlySignal<T[]>).peek()\n : (items as unknown as T[]);\n const initial = Array.isArray(current) ? current : [];\n initial.forEach((item, i) => {\n node.appendChild(buildItem(item, i));\n });\n }\n\n form(key: string, builder: FormBuilder, options: FormOptions = {}): void {\n const props: Props = containerProps(options);\n const node = this._graph.createNode('form', {\n key,\n parent: this._node,\n props,\n });\n if (options.onSubmit !== undefined) {\n const handlerKey = `submit:${node.id}`;\n this._graph.registerHandler(handlerKey, options.onSubmit as () => unknown);\n node.addEvent({ type: 'submit', handlerKey });\n }\n builder(new FormBuilderImpl(node, this._graph));\n }\n\n when(\n condition: Bindable<boolean>,\n builder: ContainerBuilderFn,\n elseBuilder?: ContainerBuilderFn,\n ): void {\n const graph = this._graph;\n // A dedicated 'conditional' node reuses the reactive-list reconciliation\n // machinery (same signal subscription + keyed reconcile) but renders as a\n // neutral <div> rather than a <ul>. It holds zero or one child branch.\n const node = graph.createNode('conditional', {\n parent: this._node,\n props: containerProps({}),\n });\n\n // Build the active branch as a single keyed container. Distinct keys for the\n // then/else branches make a flip a clean swap under the keyed reconciler.\n const buildBranch = (build: ContainerBuilderFn, tag: 'then' | 'else'): GraphNode => {\n const branchKey = `when-${tag}:${node.id}`;\n const branch = graph.createNode('container', {\n key: branchKey,\n props: { key: branchKey },\n });\n build(new ContainerBuilderImpl(branch, graph));\n return branch;\n };\n\n const buildAll = (raw: unknown): GraphNode[] => {\n if (raw) return [buildBranch(builder, 'then')];\n return elseBuilder !== undefined ? [buildBranch(elseBuilder, 'else')] : [];\n };\n\n if (isSignal(condition)) {\n const signalId = `${node.id}:items`;\n node.stateRefs.push({ signalId, propKey: 'items' });\n graph.registerHandler(`__signal__${signalId}`, condition as unknown as () => unknown);\n graph.registerHandler(`__listbuild__${node.id}`, buildAll as unknown as () => unknown);\n const current = (condition as ReadonlySignal<boolean>).peek();\n for (const child of buildAll(current)) node.appendChild(child);\n } else {\n // Static condition — resolve once at build time, no reactive wiring.\n for (const child of buildAll(condition)) node.appendChild(child);\n }\n }\n\n errorBoundary(\n id: string,\n builder: ContainerBuilderFn,\n options: ErrorBoundaryOptions,\n ): void {\n // Normalise the observed error source(s) into an array.\n const sources: ErrorSource[] =\n options.source === undefined\n ? []\n : Array.isArray(options.source)\n ? [...options.source]\n : [options.source];\n\n // The boundary's own captured error (from a synchronous build throw) and a\n // retry nonce that forces a re-evaluation even when the boolean is unchanged.\n const localError = signal<unknown>(undefined);\n const retryNonce = signal<number>(0);\n\n const readError = (): unknown => {\n const local = localError.peek();\n if (local !== undefined && local !== null) return local;\n for (const s of sources) {\n const e = s.peek();\n if (e !== undefined && e !== null) return e;\n }\n return undefined;\n };\n\n // Reactive condition: true while an error is present. Reads every input so a\n // change in any source (or a retry) re-runs the conditional.\n const hasError = derived<boolean>(() => {\n retryNonce.get();\n localError.get();\n for (const s of sources) s.get();\n return readError() !== undefined;\n });\n\n const retry = (): void => {\n localError.set(undefined);\n options.onRetry?.();\n // Force the body branch to re-attempt even if no observed value changed.\n retryNonce.update((n) => n + 1);\n };\n\n // Wrap in a container so the whole boundary is addressable and disposes as a\n // unit. `when` provides the reactive body↔fallback swap (and its cleanup).\n this.container(id, (c) => {\n c.when(\n hasError,\n // Error state → fallback.\n (fb) => options.fallback(fb, readError(), retry),\n // Healthy state → body, guarded against synchronous build throws.\n (body) => {\n try {\n builder(body);\n } catch (err) {\n // Surface the throw as the boundary's error on the next microtask\n // (deferred to avoid re-entrant reconciliation during this build).\n queueMicrotask(() => localError.set(err));\n }\n },\n );\n }, { id });\n }\n}\n\n// ── Concrete builder implementations ─────────────────────────────────────────\n\nexport class SectionBuilderImpl extends ContainerBuilderBase implements SectionDSL {}\nexport class ContainerBuilderImpl extends ContainerBuilderBase implements ContainerDSL {}\nexport class FormBuilderImpl extends ContainerBuilderBase implements FormDSL {}\n\nexport class ListBuilderImpl extends ContentBuilderBase implements ListDSL {\n item(key: string, builder: ContainerBuilderFn, options: ContainerOptions = {}): void {\n const node = this._graph.createNode('list-item', {\n key,\n parent: this._node,\n props: containerProps(options),\n });\n builder(new ContainerBuilderImpl(node, this._graph));\n }\n}\n\nexport class PageBuilderImpl extends ContainerBuilderBase implements PageDSL {}\n\n// ── App builder ───────────────────────────────────────────────────────────────\n\nexport class AppBuilder implements AppDSL {\n constructor(private readonly _graph: ApplicationGraph) {}\n\n page(key: string, builder: PageBuilder): void {\n const node = this._graph.createNode('page', {\n key,\n parent: this._graph.root,\n props: { key },\n });\n builder(new PageBuilderImpl(node, this._graph));\n }\n}\n","/**\n * StreetUI DSL entry point.\n *\n * Usage:\n * import { streetui } from '@streetui/dsl';\n *\n * const app = streetui.app({ name: 'My App' });\n * app.page('home', page => {\n * page.section('hero', section => {\n * section.heading('Welcome');\n * section.button('Click me', { onClick: () => {} });\n * });\n * });\n *\n * const graph = app.build();\n */\n\nimport { ApplicationGraph } from '@streetui/graph';\nimport { AppBuilder } from './builders.js';\n\nexport interface AppOptions {\n readonly name: string;\n readonly version?: string;\n}\n\nexport class StreetApp {\n private readonly _graph: ApplicationGraph;\n private readonly _builder: AppBuilder;\n\n constructor(options: AppOptions) {\n const graphOpts: { name: string; version?: string } = { name: options.name };\n if (options.version !== undefined) graphOpts.version = options.version;\n this._graph = new ApplicationGraph(graphOpts);\n this._builder = new AppBuilder(this._graph);\n }\n\n page(key: string, builder: Parameters<AppBuilder['page']>[1]): this {\n this._builder.page(key, builder);\n return this;\n }\n\n /** Compile to ApplicationGraph — validates and returns the graph. */\n build(): ApplicationGraph {\n const dc = this._graph.validate();\n dc.throwIfErrors();\n return this._graph;\n }\n\n /** Access graph before building (useful for inspection). */\n get graph(): ApplicationGraph {\n return this._graph;\n }\n}\n\nexport interface StreetUI {\n app(options: AppOptions): StreetApp;\n}\n\nexport const streetui: StreetUI = {\n app(options: AppOptions): StreetApp {\n return new StreetApp(options);\n },\n};\n"],"mappings":"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","names":[]}
|