streetui 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 +127 -0
- package/dist/bin.cjs +894 -0
- package/dist/bin.cjs.map +1 -0
- package/dist/bin.d.cts +1 -0
- package/dist/bin.d.ts +1 -0
- package/dist/bin.js +892 -0
- package/dist/bin.js.map +1 -0
- package/dist/compile-B0q07Hzq.d.cts +656 -0
- package/dist/compile-B0q07Hzq.d.ts +656 -0
- package/dist/create-bin.cjs +896 -0
- package/dist/create-bin.cjs.map +1 -0
- package/dist/create-bin.d.cts +1 -0
- package/dist/create-bin.d.ts +1 -0
- package/dist/create-bin.js +894 -0
- package/dist/create-bin.js.map +1 -0
- package/dist/hydration-diagnostics-BE6xVWD1.d.cts +89 -0
- package/dist/hydration-diagnostics-Bck5dMbz.d.ts +89 -0
- package/dist/index.cjs +4284 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +1759 -0
- package/dist/index.d.ts +1759 -0
- package/dist/index.js +4114 -0
- package/dist/index.js.map +1 -0
- package/dist/server-84Rz4g8W.d.cts +165 -0
- package/dist/server-D9GPmB49.d.ts +165 -0
- package/dist/server.cjs +972 -0
- package/dist/server.cjs.map +1 -0
- package/dist/server.d.cts +2 -0
- package/dist/server.d.ts +2 -0
- package/dist/server.js +940 -0
- package/dist/server.js.map +1 -0
- package/dist/testing.cjs +1754 -0
- package/dist/testing.cjs.map +1 -0
- package/dist/testing.d.cts +113 -0
- package/dist/testing.d.ts +113 -0
- package/dist/testing.js +1719 -0
- package/dist/testing.js.map +1 -0
- package/package.json +113 -0
- package/templates/basic/README.md +39 -0
- package/templates/basic/_gitignore +15 -0
- package/templates/basic/_package.json +21 -0
- package/templates/basic/public/styles.css +40 -0
- package/templates/basic/src/app.ts +62 -0
- package/templates/basic/src/main.ts +39 -0
- package/templates/basic/src/server.ts +40 -0
- package/templates/basic/streetui.config.ts +6 -0
- package/templates/basic/tsconfig.json +16 -0
- package/templates/ssr/README.md +46 -0
- package/templates/ssr/_gitignore +15 -0
- package/templates/ssr/_package.json +21 -0
- package/templates/ssr/public/favicon.svg +4 -0
- package/templates/ssr/public/styles.css +61 -0
- package/templates/ssr/src/app.ts +135 -0
- package/templates/ssr/src/main.ts +53 -0
- package/templates/ssr/src/server.ts +47 -0
- package/templates/ssr/streetui.config.ts +14 -0
- package/templates/ssr/tsconfig.json +16 -0
|
@@ -0,0 +1,656 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The single authoritative StreetUI framework version.
|
|
3
|
+
*
|
|
4
|
+
* This constant is the one source of truth for the version of the shipped
|
|
5
|
+
* `streetui` package. It is kept in lock-step with this package's
|
|
6
|
+
* `package.json` `version` field and with the bundled CLI's reported version
|
|
7
|
+
* (`streetui --version`) — the consolidated test-suite pins all three to the
|
|
8
|
+
* same coordinated release so they can never silently drift apart.
|
|
9
|
+
*/
|
|
10
|
+
declare const VERSION = "1.0.0";
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* StreetUI reactive signals — framework-owned reactivity, no external libraries.
|
|
14
|
+
*
|
|
15
|
+
* Architecture:
|
|
16
|
+
* Signal<T> — writable, holds a value, notifies on change
|
|
17
|
+
* DerivedSignal<T> — read-only, lazily computed from other signals
|
|
18
|
+
* effect() — side-effect that re-runs when dependencies change
|
|
19
|
+
* batch() — run multiple updates before notifying
|
|
20
|
+
*/
|
|
21
|
+
type Subscriber<T> = (value: T) => void;
|
|
22
|
+
type Unsubscribe = () => void;
|
|
23
|
+
/**
|
|
24
|
+
* Any reactive source that can have downstream consumers attached.
|
|
25
|
+
* Both Signal and DerivedSignal implement this.
|
|
26
|
+
*/
|
|
27
|
+
interface ReactiveSource<T> {
|
|
28
|
+
get(): T;
|
|
29
|
+
peek(): T;
|
|
30
|
+
subscribe(fn: Subscriber<T>): Unsubscribe;
|
|
31
|
+
/** Internal: remove a downstream consumer. */
|
|
32
|
+
_removeConsumer(consumer: ReactiveConsumer): void;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* A downstream consumer (DerivedSignal or Effect) that can be invalidated
|
|
36
|
+
* and can register itself as depending on a source.
|
|
37
|
+
*/
|
|
38
|
+
interface ReactiveConsumer {
|
|
39
|
+
_invalidate(): void;
|
|
40
|
+
/** Internal: called by a source to register a dependency. */
|
|
41
|
+
_addSource(src: ReactiveSource<unknown>): void;
|
|
42
|
+
}
|
|
43
|
+
interface ReadonlySignal<T> {
|
|
44
|
+
get(): T;
|
|
45
|
+
peek(): T;
|
|
46
|
+
subscribe(fn: Subscriber<T>): Unsubscribe;
|
|
47
|
+
}
|
|
48
|
+
declare class Signal<T> implements ReactiveSource<T>, ReadonlySignal<T> {
|
|
49
|
+
protected _value: T;
|
|
50
|
+
private readonly _subscribers;
|
|
51
|
+
private readonly _consumers;
|
|
52
|
+
constructor(initial: T);
|
|
53
|
+
get(): T;
|
|
54
|
+
peek(): T;
|
|
55
|
+
set(value: T): void;
|
|
56
|
+
update(fn: (current: T) => T): void;
|
|
57
|
+
subscribe(fn: Subscriber<T>): Unsubscribe;
|
|
58
|
+
_removeConsumer(consumer: ReactiveConsumer): void;
|
|
59
|
+
/**
|
|
60
|
+
* Called by the batch machinery after the batch has completed.
|
|
61
|
+
* Notifies subscribers with the final coalesced value.
|
|
62
|
+
*/
|
|
63
|
+
_flushBatch(value: unknown): void;
|
|
64
|
+
private _flush;
|
|
65
|
+
/**
|
|
66
|
+
* @internal DevTools inspection only. The number of live observers
|
|
67
|
+
* (direct subscribers plus derived/effect consumers). Read-only; never
|
|
68
|
+
* mutates reactive state.
|
|
69
|
+
*/
|
|
70
|
+
_observerCount(): number;
|
|
71
|
+
}
|
|
72
|
+
declare class DerivedSignal<T> implements ReactiveSource<T>, ReactiveConsumer, ReadonlySignal<T> {
|
|
73
|
+
private _value;
|
|
74
|
+
private _dirty;
|
|
75
|
+
private _disposed;
|
|
76
|
+
private readonly _fn;
|
|
77
|
+
private readonly _subscribers;
|
|
78
|
+
/** All upstream sources this derived currently reads from. */
|
|
79
|
+
private readonly _sources;
|
|
80
|
+
/** Downstream consumers that depend on this derived. */
|
|
81
|
+
private readonly _consumers;
|
|
82
|
+
constructor(fn: () => T);
|
|
83
|
+
get(): T;
|
|
84
|
+
peek(): T;
|
|
85
|
+
subscribe(fn: Subscriber<T>): Unsubscribe;
|
|
86
|
+
_addSource(src: ReactiveSource<unknown>): void;
|
|
87
|
+
_removeConsumer(consumer: ReactiveConsumer): void;
|
|
88
|
+
_invalidate(): void;
|
|
89
|
+
private _recompute;
|
|
90
|
+
dispose(): void;
|
|
91
|
+
/**
|
|
92
|
+
* @internal DevTools inspection only. Live observers (subscribers plus
|
|
93
|
+
* downstream consumers). Read-only.
|
|
94
|
+
*/
|
|
95
|
+
_observerCount(): number;
|
|
96
|
+
}
|
|
97
|
+
declare function signal<T>(initial: T): Signal<T>;
|
|
98
|
+
declare function derived<T>(fn: () => T): DerivedSignal<T>;
|
|
99
|
+
declare function effect(fn: () => void | (() => void)): Unsubscribe;
|
|
100
|
+
/**
|
|
101
|
+
* Run multiple signal updates as an atomic batch.
|
|
102
|
+
*
|
|
103
|
+
* Within the callback, calls to signal.set() are deferred — each signal
|
|
104
|
+
* accumulates its latest value. When the outermost batch() returns,
|
|
105
|
+
* each modified signal fires its subscribers exactly once with the final
|
|
106
|
+
* value. Nested batch() calls are supported; the flush only runs when the
|
|
107
|
+
* outermost batch exits.
|
|
108
|
+
*
|
|
109
|
+
* Example:
|
|
110
|
+
* batch(() => {
|
|
111
|
+
* count.set(1);
|
|
112
|
+
* count.set(2);
|
|
113
|
+
* count.set(3);
|
|
114
|
+
* });
|
|
115
|
+
* // subscribers see count = 3 exactly once
|
|
116
|
+
*/
|
|
117
|
+
declare function batch(fn: () => void): void;
|
|
118
|
+
/** True when inside a batch() call. Useful for advanced scheduling integration. */
|
|
119
|
+
declare function isBatching(): boolean;
|
|
120
|
+
/** Whether a signal is writable (`signal()`) or computed (`derived()`). */
|
|
121
|
+
type SignalKind = 'writable' | 'derived';
|
|
122
|
+
/** Classify a reactive value as writable or derived. */
|
|
123
|
+
declare function signalKind(source: ReadonlySignal<unknown>): SignalKind;
|
|
124
|
+
/**
|
|
125
|
+
* The number of live observers on a signal — direct subscribers plus derived
|
|
126
|
+
* or effect consumers — or `undefined` if the source does not expose the count.
|
|
127
|
+
* Read-only; safe for DevTools. Never mutates reactive state.
|
|
128
|
+
*/
|
|
129
|
+
declare function observerCount(source: ReadonlySignal<unknown>): number | undefined;
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Node and application identity utilities.
|
|
133
|
+
* Every node in the semantic graph has a stable, unique identity.
|
|
134
|
+
*/
|
|
135
|
+
/** Generate a framework-internal monotonic integer ID. */
|
|
136
|
+
declare function nextId(): number;
|
|
137
|
+
/** Reset the counter (test use only). */
|
|
138
|
+
declare function resetIdCounter(): void;
|
|
139
|
+
/** Opaque branded type for node IDs. */
|
|
140
|
+
type NodeId = string & {
|
|
141
|
+
readonly __brand: 'NodeId';
|
|
142
|
+
};
|
|
143
|
+
/** Create a NodeId from a string (must be unique at call site). */
|
|
144
|
+
declare function createNodeId(value: string): NodeId;
|
|
145
|
+
/** Generate a fresh, unique NodeId. */
|
|
146
|
+
declare function generateNodeId(prefix?: string): NodeId;
|
|
147
|
+
/** Parse the prefix from a NodeId. */
|
|
148
|
+
declare function nodeIdPrefix(id: NodeId): string;
|
|
149
|
+
/** Branded type for application IDs. */
|
|
150
|
+
type ApplicationId = string & {
|
|
151
|
+
readonly __brand: 'ApplicationId';
|
|
152
|
+
};
|
|
153
|
+
/** Generate a fresh application ID. */
|
|
154
|
+
declare function generateApplicationId(name: string): ApplicationId;
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Framework diagnostics — structured errors, warnings, and hints
|
|
158
|
+
* that flow through the compiler, validator, and runtime.
|
|
159
|
+
*/
|
|
160
|
+
type DiagnosticSeverity = 'error' | 'warning' | 'info';
|
|
161
|
+
interface DiagnosticLocation {
|
|
162
|
+
readonly file?: string;
|
|
163
|
+
readonly line?: number;
|
|
164
|
+
readonly column?: number;
|
|
165
|
+
readonly nodeId?: string;
|
|
166
|
+
}
|
|
167
|
+
interface Diagnostic {
|
|
168
|
+
readonly severity: DiagnosticSeverity;
|
|
169
|
+
readonly code: string;
|
|
170
|
+
readonly message: string;
|
|
171
|
+
readonly location: DiagnosticLocation | undefined;
|
|
172
|
+
readonly cause: unknown;
|
|
173
|
+
}
|
|
174
|
+
declare class DiagnosticError extends Error {
|
|
175
|
+
readonly diagnostics: readonly Diagnostic[];
|
|
176
|
+
constructor(diagnostics: readonly Diagnostic[]);
|
|
177
|
+
}
|
|
178
|
+
declare class DiagnosticCollector {
|
|
179
|
+
private readonly _diagnostics;
|
|
180
|
+
get diagnostics(): readonly Diagnostic[];
|
|
181
|
+
get hasErrors(): boolean;
|
|
182
|
+
get hasWarnings(): boolean;
|
|
183
|
+
error(code: string, message: string, location?: DiagnosticLocation, cause?: unknown): void;
|
|
184
|
+
warn(code: string, message: string, location?: DiagnosticLocation): void;
|
|
185
|
+
info(code: string, message: string, location?: DiagnosticLocation): void;
|
|
186
|
+
merge(other: DiagnosticCollector): void;
|
|
187
|
+
throwIfErrors(): void;
|
|
188
|
+
clear(): void;
|
|
189
|
+
}
|
|
190
|
+
/** Format a single diagnostic as a human-readable string. */
|
|
191
|
+
declare function formatDiagnostic(d: Diagnostic): string;
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Framework node primitives — the base abstraction for every node
|
|
195
|
+
* in the Semantic Application Graph.
|
|
196
|
+
*/
|
|
197
|
+
|
|
198
|
+
type SemanticNodeType = 'application' | 'page' | 'section' | 'container' | 'heading' | 'text' | 'button' | 'input' | 'form' | 'list' | 'list-item' | 'image' | 'link' | 'component' | 'slot' | 'fragment' | 'reactive-list' | 'conditional';
|
|
199
|
+
interface NodeMetadata {
|
|
200
|
+
readonly createdAt: number;
|
|
201
|
+
readonly [key: string]: unknown;
|
|
202
|
+
}
|
|
203
|
+
declare abstract class BaseNode {
|
|
204
|
+
readonly id: NodeId;
|
|
205
|
+
readonly type: SemanticNodeType;
|
|
206
|
+
readonly metadata: NodeMetadata;
|
|
207
|
+
constructor(type: SemanticNodeType, id?: NodeId);
|
|
208
|
+
abstract clone(): BaseNode;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Semantic Application Graph nodes.
|
|
213
|
+
*
|
|
214
|
+
* Every element in a StreetUI application is represented as a GraphNode.
|
|
215
|
+
* Nodes form a tree: each has an optional parent and an ordered list of children.
|
|
216
|
+
*/
|
|
217
|
+
|
|
218
|
+
type PropValue = string | number | boolean | null | undefined | string[] | number[] | Record<string, unknown>;
|
|
219
|
+
type Props = Record<string, PropValue>;
|
|
220
|
+
interface EventDescriptor {
|
|
221
|
+
readonly type: string;
|
|
222
|
+
/** Reference key into the application's handler registry. */
|
|
223
|
+
readonly handlerKey: string;
|
|
224
|
+
}
|
|
225
|
+
interface StateRef {
|
|
226
|
+
/** ID of the signal/store this node's property is bound to. */
|
|
227
|
+
readonly signalId: string;
|
|
228
|
+
/** The prop key on this node that is bound. */
|
|
229
|
+
readonly propKey: string;
|
|
230
|
+
}
|
|
231
|
+
interface GraphNodeData {
|
|
232
|
+
readonly id: NodeId;
|
|
233
|
+
readonly type: SemanticNodeType;
|
|
234
|
+
readonly key: string | undefined;
|
|
235
|
+
props: Props;
|
|
236
|
+
events: EventDescriptor[];
|
|
237
|
+
stateRefs: StateRef[];
|
|
238
|
+
children: GraphNode[];
|
|
239
|
+
parent: GraphNode | null;
|
|
240
|
+
}
|
|
241
|
+
declare class GraphNode implements GraphNodeData {
|
|
242
|
+
readonly id: NodeId;
|
|
243
|
+
readonly type: SemanticNodeType;
|
|
244
|
+
readonly key: string | undefined;
|
|
245
|
+
props: Props;
|
|
246
|
+
events: EventDescriptor[];
|
|
247
|
+
stateRefs: StateRef[];
|
|
248
|
+
children: GraphNode[];
|
|
249
|
+
parent: GraphNode | null;
|
|
250
|
+
constructor(type: SemanticNodeType, options?: {
|
|
251
|
+
id?: NodeId;
|
|
252
|
+
key?: string;
|
|
253
|
+
props?: Props;
|
|
254
|
+
events?: EventDescriptor[];
|
|
255
|
+
stateRefs?: StateRef[];
|
|
256
|
+
});
|
|
257
|
+
appendChild(child: GraphNode): void;
|
|
258
|
+
insertBefore(child: GraphNode, reference: GraphNode): void;
|
|
259
|
+
removeChild(child: GraphNode): void;
|
|
260
|
+
replaceChild(newChild: GraphNode, oldChild: GraphNode): void;
|
|
261
|
+
setProp(key: string, value: PropValue): void;
|
|
262
|
+
getProp<T extends PropValue = PropValue>(key: string): T | undefined;
|
|
263
|
+
addEvent(descriptor: EventDescriptor): void;
|
|
264
|
+
removeEvent(type: string): void;
|
|
265
|
+
get isLeaf(): boolean;
|
|
266
|
+
get depth(): number;
|
|
267
|
+
get root(): GraphNode;
|
|
268
|
+
/** Shallow clone — does not clone children. */
|
|
269
|
+
shallowClone(): GraphNode;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* The Semantic Application Graph.
|
|
274
|
+
*
|
|
275
|
+
* Holds the application root node and all its descendants.
|
|
276
|
+
* Supports traversal, lookup by ID, validation, and serialization.
|
|
277
|
+
*/
|
|
278
|
+
|
|
279
|
+
interface ApplicationGraphOptions {
|
|
280
|
+
readonly name: string;
|
|
281
|
+
readonly version?: string;
|
|
282
|
+
}
|
|
283
|
+
interface HandlerFn {
|
|
284
|
+
(...args: unknown[]): unknown;
|
|
285
|
+
}
|
|
286
|
+
declare class ApplicationGraph {
|
|
287
|
+
readonly root: GraphNode;
|
|
288
|
+
readonly name: string;
|
|
289
|
+
readonly version: string;
|
|
290
|
+
private readonly _nodeIndex;
|
|
291
|
+
/** Handler registry — maps handlerKey → actual function */
|
|
292
|
+
readonly handlers: Map<string, HandlerFn>;
|
|
293
|
+
constructor(options: ApplicationGraphOptions);
|
|
294
|
+
createNode(type: GraphNode['type'], options?: {
|
|
295
|
+
key?: string;
|
|
296
|
+
props?: Props;
|
|
297
|
+
parent?: GraphNode;
|
|
298
|
+
}): GraphNode;
|
|
299
|
+
attachNode(node: GraphNode, parent: GraphNode): void;
|
|
300
|
+
detachNode(node: GraphNode): void;
|
|
301
|
+
private _removeFromIndex;
|
|
302
|
+
/**
|
|
303
|
+
* Remove every handler-registry entry owned by a single node. A node owns:
|
|
304
|
+
* - one entry per event descriptor (its `handlerKey`),
|
|
305
|
+
* - one `__signal__<signalId>` entry per state ref (signalIds are namespaced
|
|
306
|
+
* by node id, so they are never shared between nodes), and
|
|
307
|
+
* - a `__listbuild__<id>` entry if it is a reactive-list.
|
|
308
|
+
* Called for every node in a detached subtree so removing list items (or
|
|
309
|
+
* discarding freshly-built-but-unadopted item subtrees) leaves no stale
|
|
310
|
+
* registrations behind.
|
|
311
|
+
*/
|
|
312
|
+
private _unregisterNodeHandlers;
|
|
313
|
+
registerHandler(key: string, fn: HandlerFn): void;
|
|
314
|
+
getHandler(key: string): HandlerFn | undefined;
|
|
315
|
+
/** True if a handler is currently registered under `key`. Inspection helper. */
|
|
316
|
+
hasHandler(key: string): boolean;
|
|
317
|
+
/** Number of currently-registered handlers. Inspection helper. */
|
|
318
|
+
get handlerCount(): number;
|
|
319
|
+
findById(id: NodeId): GraphNode | undefined;
|
|
320
|
+
findAll(predicate: (node: GraphNode) => boolean): GraphNode[];
|
|
321
|
+
findByType(type: GraphNode['type']): GraphNode[];
|
|
322
|
+
walk(visitor: (node: GraphNode, depth: number) => void): void;
|
|
323
|
+
private _walk;
|
|
324
|
+
get nodeCount(): number;
|
|
325
|
+
validate(): DiagnosticCollector;
|
|
326
|
+
serialize(): SerializedGraph;
|
|
327
|
+
private _serializeNode;
|
|
328
|
+
}
|
|
329
|
+
interface SerializedNode {
|
|
330
|
+
readonly id: string;
|
|
331
|
+
readonly type: string;
|
|
332
|
+
readonly key: string | undefined;
|
|
333
|
+
readonly props: Props;
|
|
334
|
+
readonly events: EventDescriptor[];
|
|
335
|
+
readonly stateRefs: unknown[];
|
|
336
|
+
readonly children: SerializedNode[];
|
|
337
|
+
}
|
|
338
|
+
interface SerializedGraph {
|
|
339
|
+
readonly name: string;
|
|
340
|
+
readonly version: string;
|
|
341
|
+
readonly root: SerializedNode;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
/**
|
|
345
|
+
* StreetUI DSL type system.
|
|
346
|
+
* All builder callbacks and option shapes live here.
|
|
347
|
+
*/
|
|
348
|
+
|
|
349
|
+
type Bindable<T> = T | ReadonlySignal<T> | Signal<T>;
|
|
350
|
+
type TextValue = string | number | boolean;
|
|
351
|
+
type BindableText = TextValue | ReadonlySignal<TextValue>;
|
|
352
|
+
/**
|
|
353
|
+
* Accessibility options shared by every element builder.
|
|
354
|
+
*
|
|
355
|
+
* These map to standard HTML/ARIA attributes and flow straight through to the
|
|
356
|
+
* DOM via the renderer's generic attribute pass — there is no separate ARIA
|
|
357
|
+
* abstraction to keep in sync. Prefer semantic HTML (button/a/input/etc.) and
|
|
358
|
+
* only reach for these when semantics alone are insufficient. `id` (already
|
|
359
|
+
* present on each option type) combined with the deterministic `a11yIds()`
|
|
360
|
+
* helper in `streetui` is how label/description/title associations are
|
|
361
|
+
* wired in an SSR/hydration-safe way.
|
|
362
|
+
*/
|
|
363
|
+
interface A11yOptions {
|
|
364
|
+
/** ARIA role (e.g. 'dialog', 'alert', 'status', 'navigation'). */
|
|
365
|
+
readonly role?: string;
|
|
366
|
+
/** tabindex value. Use 0 to make an element focusable, -1 to remove from tab order. */
|
|
367
|
+
readonly tabIndex?: number;
|
|
368
|
+
/** aria-label — an accessible name when no visible label element exists. */
|
|
369
|
+
readonly ariaLabel?: string;
|
|
370
|
+
/** aria-labelledby — id(s) of the element(s) that label this one. */
|
|
371
|
+
readonly ariaLabelledBy?: string;
|
|
372
|
+
/** aria-describedby — id(s) of the element(s) that describe this one. */
|
|
373
|
+
readonly ariaDescribedBy?: string;
|
|
374
|
+
/** aria-expanded — for disclosure widgets (rendered as the string "true"/"false"). */
|
|
375
|
+
readonly ariaExpanded?: boolean;
|
|
376
|
+
/** aria-controls — id of the element this one controls. */
|
|
377
|
+
readonly ariaControls?: string;
|
|
378
|
+
/** aria-hidden — hide decorative content from assistive tech. */
|
|
379
|
+
readonly ariaHidden?: boolean;
|
|
380
|
+
/** aria-live — announce dynamic changes ('polite' | 'assertive' | 'off'). */
|
|
381
|
+
readonly ariaLive?: 'off' | 'polite' | 'assertive';
|
|
382
|
+
/** aria-current — mark the current item in a set (e.g. 'page' for active nav). */
|
|
383
|
+
readonly ariaCurrent?: boolean | 'page' | 'step' | 'location' | 'date' | 'time';
|
|
384
|
+
/** aria-invalid — mark a form field as failing validation. */
|
|
385
|
+
readonly ariaInvalid?: boolean;
|
|
386
|
+
/** aria-required — mark a form field as required. */
|
|
387
|
+
readonly ariaRequired?: boolean;
|
|
388
|
+
}
|
|
389
|
+
interface TextOptions extends A11yOptions {
|
|
390
|
+
readonly class?: string;
|
|
391
|
+
readonly id?: string;
|
|
392
|
+
}
|
|
393
|
+
interface HeadingOptions extends TextOptions {
|
|
394
|
+
readonly level?: 1 | 2 | 3 | 4 | 5 | 6;
|
|
395
|
+
}
|
|
396
|
+
interface ButtonOptions extends A11yOptions {
|
|
397
|
+
readonly class?: string;
|
|
398
|
+
readonly id?: string;
|
|
399
|
+
readonly disabled?: Bindable<boolean>;
|
|
400
|
+
readonly onClick?: () => void;
|
|
401
|
+
}
|
|
402
|
+
interface InputOptionsBase extends A11yOptions {
|
|
403
|
+
readonly class?: string;
|
|
404
|
+
readonly id?: string;
|
|
405
|
+
readonly type?: 'text' | 'email' | 'password' | 'number' | 'tel' | 'url' | 'search';
|
|
406
|
+
readonly placeholder?: string;
|
|
407
|
+
readonly disabled?: Bindable<boolean>;
|
|
408
|
+
readonly onChange?: (value: string) => void;
|
|
409
|
+
}
|
|
410
|
+
/**
|
|
411
|
+
* Explicitly-controlled input: supply `value` and/or `onInput` yourself.
|
|
412
|
+
* `bind` is disallowed here (typed as `never`) so a two-way `bind` can never be
|
|
413
|
+
* combined with manual `value`/`onInput` wiring — the ambiguity is rejected by
|
|
414
|
+
* the type checker rather than resolved silently at runtime.
|
|
415
|
+
*/
|
|
416
|
+
interface ControlledInputOptions extends InputOptionsBase {
|
|
417
|
+
readonly value?: Bindable<string>;
|
|
418
|
+
readonly onInput?: (value: string) => void;
|
|
419
|
+
readonly bind?: never;
|
|
420
|
+
}
|
|
421
|
+
/**
|
|
422
|
+
* Two-way bound input: `bind` expands to `value` (read) + an input handler that
|
|
423
|
+
* writes the field value back into the signal. Manual `value`/`onInput` are
|
|
424
|
+
* disallowed here to keep the binding unambiguous.
|
|
425
|
+
*/
|
|
426
|
+
interface BoundInputOptions extends InputOptionsBase {
|
|
427
|
+
readonly bind: Signal<string>;
|
|
428
|
+
readonly value?: never;
|
|
429
|
+
readonly onInput?: never;
|
|
430
|
+
}
|
|
431
|
+
type InputOptions = ControlledInputOptions | BoundInputOptions;
|
|
432
|
+
interface LinkOptions extends A11yOptions {
|
|
433
|
+
readonly class?: string;
|
|
434
|
+
readonly id?: string;
|
|
435
|
+
readonly href: string;
|
|
436
|
+
readonly external?: boolean;
|
|
437
|
+
readonly onClick?: () => void;
|
|
438
|
+
}
|
|
439
|
+
interface ImageOptions extends A11yOptions {
|
|
440
|
+
readonly class?: string;
|
|
441
|
+
readonly id?: string;
|
|
442
|
+
readonly src: string;
|
|
443
|
+
readonly alt: string;
|
|
444
|
+
readonly width?: number;
|
|
445
|
+
readonly height?: number;
|
|
446
|
+
}
|
|
447
|
+
interface ContainerOptions extends A11yOptions {
|
|
448
|
+
readonly class?: string;
|
|
449
|
+
readonly id?: string;
|
|
450
|
+
readonly key?: string;
|
|
451
|
+
}
|
|
452
|
+
interface SectionOptions extends ContainerOptions {
|
|
453
|
+
}
|
|
454
|
+
interface FormOptions extends ContainerOptions {
|
|
455
|
+
readonly onSubmit?: (e: Event) => void;
|
|
456
|
+
}
|
|
457
|
+
interface ListOptions extends ContainerOptions {
|
|
458
|
+
}
|
|
459
|
+
type SectionBuilder = (section: SectionDSL) => void;
|
|
460
|
+
type ContainerBuilder = (container: ContainerDSL) => void;
|
|
461
|
+
type PageBuilder = (page: PageDSL) => void;
|
|
462
|
+
type FormBuilder = (form: FormDSL) => void;
|
|
463
|
+
type ListBuilder = (list: ListDSL) => void;
|
|
464
|
+
/** A reactive source of error state (e.g. `resource.error`). `null`/`undefined` means "no error". */
|
|
465
|
+
type ErrorSource = ReadonlySignal<unknown>;
|
|
466
|
+
/** Fallback UI builder — receives the current error and a `retry` callback. */
|
|
467
|
+
type ErrorFallbackBuilder = (fallback: ContainerDSL, error: unknown, retry: () => void) => void;
|
|
468
|
+
interface ErrorBoundaryOptions {
|
|
469
|
+
/** Renders when the boundary is in an error state. */
|
|
470
|
+
readonly fallback: ErrorFallbackBuilder;
|
|
471
|
+
/**
|
|
472
|
+
* Reactive error source(s) to observe — typically a resource's `error` signal.
|
|
473
|
+
* When any becomes non-null, the fallback replaces the body.
|
|
474
|
+
*/
|
|
475
|
+
readonly source?: ErrorSource | ReadonlyArray<ErrorSource>;
|
|
476
|
+
/** Invoked by the fallback's `retry()`, before the body is re-attempted (e.g. `resource.refetch`). */
|
|
477
|
+
readonly onRetry?: () => void;
|
|
478
|
+
}
|
|
479
|
+
interface ContentDSL {
|
|
480
|
+
heading(text: BindableText, options?: HeadingOptions): void;
|
|
481
|
+
text(content: BindableText, options?: TextOptions): void;
|
|
482
|
+
button(label: BindableText, options?: ButtonOptions): void;
|
|
483
|
+
input(options?: InputOptions): void;
|
|
484
|
+
image(options: ImageOptions): void;
|
|
485
|
+
link(label: BindableText, options: LinkOptions): void;
|
|
486
|
+
}
|
|
487
|
+
interface ContainerDSL extends ContentDSL {
|
|
488
|
+
section(key: string, builder: SectionBuilder, options?: SectionOptions): void;
|
|
489
|
+
container(key: string, builder: ContainerBuilder, options?: ContainerOptions): void;
|
|
490
|
+
list(key: string, builder: ListBuilder, options?: ListOptions): void;
|
|
491
|
+
/**
|
|
492
|
+
* Reactive list driven by a Signal<T[]>.
|
|
493
|
+
* When the signal value changes, the list is reconciled against the new items.
|
|
494
|
+
* The renderItem callback receives each item and a ContentDSL to build children.
|
|
495
|
+
*/
|
|
496
|
+
listOf<T>(key: string, items: Signal<T[]> | ReadonlySignal<T[]>, renderItem: (item: T, index: number, content: ContentDSL) => void, options?: ListOptions): void;
|
|
497
|
+
form(key: string, builder: FormBuilder, options?: FormOptions): void;
|
|
498
|
+
/**
|
|
499
|
+
* Conditionally render a subtree based on a boolean condition.
|
|
500
|
+
* When `condition` is a signal, the subtree is mounted/unmounted reactively as
|
|
501
|
+
* the value flips. When true the `builder` subtree is shown; when false it is
|
|
502
|
+
* removed (and its handlers/subscriptions torn down). An optional `elseBuilder`
|
|
503
|
+
* renders while the condition is false. Compiles into the same reactive
|
|
504
|
+
* reconciliation machinery as `listOf` — there is no separate render path.
|
|
505
|
+
*/
|
|
506
|
+
when(condition: Bindable<boolean>, builder: ContainerBuilder, elseBuilder?: ContainerBuilder): void;
|
|
507
|
+
/**
|
|
508
|
+
* Render `builder`, but swap to `options.fallback` when the boundary enters an
|
|
509
|
+
* error state. A boundary enters that state when (a) any observed `source`
|
|
510
|
+
* signal (e.g. a `resource.error`) becomes non-null, or (b) the body builder
|
|
511
|
+
* throws synchronously while building. The fallback receives the current error
|
|
512
|
+
* and a `retry()` callback (which clears the local error, runs `onRetry`, and
|
|
513
|
+
* re-attempts the body). Reuses the same reactive `when()` machinery, so its
|
|
514
|
+
* subtree — and all handlers/subscriptions within it — are torn down on
|
|
515
|
+
* removal. It does NOT trap arbitrary global errors; errors remain observable.
|
|
516
|
+
*/
|
|
517
|
+
errorBoundary(id: string, builder: ContainerBuilder, options: ErrorBoundaryOptions): void;
|
|
518
|
+
}
|
|
519
|
+
interface SectionDSL extends ContainerDSL {
|
|
520
|
+
}
|
|
521
|
+
interface FormDSL extends ContainerDSL {
|
|
522
|
+
}
|
|
523
|
+
interface ListDSL extends ContentDSL {
|
|
524
|
+
item(key: string, builder: ContainerBuilder, options?: ContainerOptions): void;
|
|
525
|
+
}
|
|
526
|
+
interface PageDSL extends ContainerDSL {
|
|
527
|
+
}
|
|
528
|
+
interface AppDSL {
|
|
529
|
+
page(key: string, builder: PageBuilder): void;
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
/**
|
|
533
|
+
* DSL builder implementations.
|
|
534
|
+
*
|
|
535
|
+
* Each builder wraps a GraphNode and provides the fluent API
|
|
536
|
+
* for constructing the Semantic Application Graph via the DSL.
|
|
537
|
+
*
|
|
538
|
+
* Builders do NOT render anything — they only build the graph.
|
|
539
|
+
*/
|
|
540
|
+
|
|
541
|
+
/** Content signature used to detect in-place data changes of a stable item. */
|
|
542
|
+
declare function reactiveListItemSignature(item: unknown): string;
|
|
543
|
+
/** Stable, identity-only reconciliation key for a reactive-list item. */
|
|
544
|
+
declare function reactiveListItemKey(item: unknown, index: number): string;
|
|
545
|
+
declare class ContentBuilderBase implements ContentDSL {
|
|
546
|
+
protected readonly _node: GraphNode;
|
|
547
|
+
protected readonly _graph: ApplicationGraph;
|
|
548
|
+
constructor(_node: GraphNode, _graph: ApplicationGraph);
|
|
549
|
+
heading(text: BindableText, options?: HeadingOptions): void;
|
|
550
|
+
text(content: BindableText, options?: TextOptions): void;
|
|
551
|
+
button(label: BindableText, options?: ButtonOptions): void;
|
|
552
|
+
input(options?: InputOptions): void;
|
|
553
|
+
image(options: ImageOptions): void;
|
|
554
|
+
link(label: BindableText, options: LinkOptions): void;
|
|
555
|
+
}
|
|
556
|
+
declare class ContainerBuilderBase extends ContentBuilderBase implements ContainerDSL {
|
|
557
|
+
section(key: string, builder: SectionBuilder, options?: SectionOptions): void;
|
|
558
|
+
container(key: string, builder: ContainerBuilder, options?: ContainerOptions): void;
|
|
559
|
+
list(key: string, builder: ListBuilder, options?: ListOptions): void;
|
|
560
|
+
listOf<T>(key: string, items: Signal<T[]> | ReadonlySignal<T[]>, renderItem: (item: T, index: number, content: ContentDSL) => void, options?: ListOptions): void;
|
|
561
|
+
form(key: string, builder: FormBuilder, options?: FormOptions): void;
|
|
562
|
+
when(condition: Bindable<boolean>, builder: ContainerBuilder, elseBuilder?: ContainerBuilder): void;
|
|
563
|
+
errorBoundary(id: string, builder: ContainerBuilder, options: ErrorBoundaryOptions): void;
|
|
564
|
+
}
|
|
565
|
+
declare class SectionBuilderImpl extends ContainerBuilderBase implements SectionDSL {
|
|
566
|
+
}
|
|
567
|
+
declare class ContainerBuilderImpl extends ContainerBuilderBase implements ContainerDSL {
|
|
568
|
+
}
|
|
569
|
+
declare class FormBuilderImpl extends ContainerBuilderBase implements FormDSL {
|
|
570
|
+
}
|
|
571
|
+
declare class ListBuilderImpl extends ContentBuilderBase implements ListDSL {
|
|
572
|
+
item(key: string, builder: ContainerBuilder, options?: ContainerOptions): void;
|
|
573
|
+
}
|
|
574
|
+
declare class PageBuilderImpl extends ContainerBuilderBase implements PageDSL {
|
|
575
|
+
}
|
|
576
|
+
declare class AppBuilder implements AppDSL {
|
|
577
|
+
private readonly _graph;
|
|
578
|
+
constructor(_graph: ApplicationGraph);
|
|
579
|
+
page(key: string, builder: PageBuilder): void;
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
/**
|
|
583
|
+
* StreetUI DSL entry point.
|
|
584
|
+
*
|
|
585
|
+
* Usage:
|
|
586
|
+
* import { streetui } from 'streetui';
|
|
587
|
+
*
|
|
588
|
+
* const app = streetui.app({ name: 'My App' });
|
|
589
|
+
* app.page('home', page => {
|
|
590
|
+
* page.section('hero', section => {
|
|
591
|
+
* section.heading('Welcome');
|
|
592
|
+
* section.button('Click me', { onClick: () => {} });
|
|
593
|
+
* });
|
|
594
|
+
* });
|
|
595
|
+
*
|
|
596
|
+
* const graph = app.build();
|
|
597
|
+
*/
|
|
598
|
+
|
|
599
|
+
interface AppOptions {
|
|
600
|
+
readonly name: string;
|
|
601
|
+
readonly version?: string;
|
|
602
|
+
}
|
|
603
|
+
declare class StreetApp {
|
|
604
|
+
private readonly _graph;
|
|
605
|
+
private readonly _builder;
|
|
606
|
+
constructor(options: AppOptions);
|
|
607
|
+
page(key: string, builder: Parameters<AppBuilder['page']>[1]): this;
|
|
608
|
+
/** Compile to ApplicationGraph — validates and returns the graph. */
|
|
609
|
+
build(): ApplicationGraph;
|
|
610
|
+
/** Access graph before building (useful for inspection). */
|
|
611
|
+
get graph(): ApplicationGraph;
|
|
612
|
+
}
|
|
613
|
+
interface StreetUI {
|
|
614
|
+
app(options: AppOptions): StreetApp;
|
|
615
|
+
}
|
|
616
|
+
declare const streetui: StreetUI;
|
|
617
|
+
|
|
618
|
+
/**
|
|
619
|
+
* StreetUI compiler entry point.
|
|
620
|
+
*
|
|
621
|
+
* Pipeline:
|
|
622
|
+
* StreetApp (DSL)
|
|
623
|
+
* → ApplicationGraph (build)
|
|
624
|
+
* → validate
|
|
625
|
+
* → transform
|
|
626
|
+
* → CompiledApplication
|
|
627
|
+
*/
|
|
628
|
+
|
|
629
|
+
interface CompiledApplication {
|
|
630
|
+
/** The fully built, validated, and transformed graph. */
|
|
631
|
+
readonly graph: ApplicationGraph;
|
|
632
|
+
/** Diagnostics accumulated during compilation. */
|
|
633
|
+
readonly diagnostics: DiagnosticCollector;
|
|
634
|
+
/** Metadata */
|
|
635
|
+
readonly name: string;
|
|
636
|
+
readonly version: string;
|
|
637
|
+
readonly compiledAt: number;
|
|
638
|
+
}
|
|
639
|
+
interface CompileOptions {
|
|
640
|
+
/** If true, compilation throws on errors. Defaults to true. */
|
|
641
|
+
readonly strict?: boolean;
|
|
642
|
+
/** If true, also throw on warnings. Defaults to false. */
|
|
643
|
+
readonly strictWarnings?: boolean;
|
|
644
|
+
}
|
|
645
|
+
/**
|
|
646
|
+
* Compile a StreetApp DSL definition into a CompiledApplication
|
|
647
|
+
* ready for the runtime to execute.
|
|
648
|
+
*/
|
|
649
|
+
declare function compile(app: StreetApp, options?: CompileOptions): CompiledApplication;
|
|
650
|
+
/**
|
|
651
|
+
* Compile from a pre-built ApplicationGraph (used when the graph
|
|
652
|
+
* was constructed programmatically rather than through the DSL).
|
|
653
|
+
*/
|
|
654
|
+
declare function compileGraph(graph: ApplicationGraph, options?: CompileOptions): CompiledApplication;
|
|
655
|
+
|
|
656
|
+
export { type ListDSL as $, type ApplicationId as A, BaseNode as B, type CompiledApplication as C, DiagnosticCollector as D, type ErrorBoundaryOptions as E, type ErrorFallbackBuilder as F, GraphNode as G, type ErrorSource as H, type EventDescriptor as I, type FormBuilder as J, FormBuilderImpl as K, type FormDSL as L, type FormOptions as M, type GraphNodeData as N, type HandlerFn as O, type PageDSL as P, type HeadingOptions as Q, type ReadonlySignal as R, StreetApp as S, type ImageOptions as T, type Unsubscribe as U, VERSION as V, type InputOptions as W, type InputOptionsBase as X, type LinkOptions as Y, type ListBuilder as Z, ListBuilderImpl as _, Signal as a, type ListOptions as a0, type NodeId as a1, type NodeMetadata as a2, type PageBuilder as a3, PageBuilderImpl as a4, type PropValue as a5, type Props as a6, type ReactiveConsumer as a7, type ReactiveSource as a8, type SectionBuilder as a9, signalKind as aA, streetui as aB, SectionBuilderImpl as aa, type SectionDSL as ab, type SectionOptions as ac, type SerializedGraph as ad, type SerializedNode as ae, type StateRef as af, type StreetUI as ag, type TextOptions as ah, type TextValue as ai, batch as aj, compile as ak, compileGraph as al, createNodeId as am, derived as an, effect as ao, formatDiagnostic as ap, generateApplicationId as aq, generateNodeId as ar, isBatching as as, nextId as at, nodeIdPrefix as au, observerCount as av, reactiveListItemKey as aw, reactiveListItemSignature as ax, resetIdCounter as ay, signal as az, type Subscriber as b, ApplicationGraph as c, type SemanticNodeType as d, type ContainerDSL as e, type SignalKind as f, type A11yOptions as g, AppBuilder as h, type AppDSL as i, type AppOptions as j, type ApplicationGraphOptions as k, type Bindable as l, type BindableText as m, type BoundInputOptions as n, type ButtonOptions as o, type CompileOptions as p, type ContainerBuilder as q, ContainerBuilderImpl as r, type ContainerOptions as s, type ContentDSL as t, type ControlledInputOptions as u, DerivedSignal as v, type Diagnostic as w, DiagnosticError as x, type DiagnosticLocation as y, type DiagnosticSeverity as z };
|