@threadplane/render 0.0.49 → 0.0.51
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.
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { InjectionToken, ChangeDetectionStrategy, Component, signal, Injectable, makeEnvironmentProviders, reflectComponentType, input,
|
|
2
|
+
import { InjectionToken, inject, ChangeDetectionStrategy, Component, signal, Injectable, makeEnvironmentProviders, reflectComponentType, input, Injector, DestroyRef, effect, computed, runInInjectionContext, output } from '@angular/core';
|
|
3
3
|
import { NgComponentOutlet } from '@angular/common';
|
|
4
4
|
import { resolveElementProps, evaluateVisibility, resolveBindings } from '@json-render/core';
|
|
5
5
|
|
|
@@ -9,6 +9,13 @@ const RENDER_CONTEXT = new InjectionToken('RENDER_CONTEXT');
|
|
|
9
9
|
// SPDX-License-Identifier: MIT
|
|
10
10
|
const REPEAT_SCOPE = new InjectionToken('REPEAT_SCOPE');
|
|
11
11
|
|
|
12
|
+
// SPDX-License-Identifier: MIT
|
|
13
|
+
const RENDER_HOST = new InjectionToken('RENDER_HOST');
|
|
14
|
+
/** Obtain the element-scoped RenderHost from inside a mounted view component. */
|
|
15
|
+
function injectRenderHost() {
|
|
16
|
+
return inject(RENDER_HOST);
|
|
17
|
+
}
|
|
18
|
+
|
|
12
19
|
// SPDX-License-Identifier: MIT
|
|
13
20
|
class DefaultFallbackComponent {
|
|
14
21
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: DefaultFallbackComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
@@ -44,24 +51,71 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImpor
|
|
|
44
51
|
}] });
|
|
45
52
|
|
|
46
53
|
function normalize(entry) {
|
|
47
|
-
// Bare Type — register with the default fallback.
|
|
48
54
|
if (typeof entry === 'function') {
|
|
49
55
|
return { component: entry, fallback: DefaultFallbackComponent };
|
|
50
56
|
}
|
|
51
|
-
// Object form — preserve component; use configured fallback or default.
|
|
52
57
|
return {
|
|
53
58
|
component: entry.component,
|
|
54
59
|
fallback: entry.fallback ?? DefaultFallbackComponent,
|
|
60
|
+
schema: entry.schema,
|
|
61
|
+
description: entry.description,
|
|
55
62
|
};
|
|
56
63
|
}
|
|
64
|
+
/**
|
|
65
|
+
* Build an {@link AngularRegistry} from a plain object mapping tool-call names
|
|
66
|
+
* to Angular components (or fully specified {@link RenderViewEntry} objects).
|
|
67
|
+
*
|
|
68
|
+
* The returned registry is consumed by both `provideRender` (to drive
|
|
69
|
+
* dynamic component rendering) and `provideChat` (via `renderRegistry`) so
|
|
70
|
+
* that a single `defineAngularRegistry` call wires both layers.
|
|
71
|
+
*
|
|
72
|
+
* **Entry forms**
|
|
73
|
+
* - Bare `Type<unknown>` — the component is paired with the built-in
|
|
74
|
+
* `DefaultFallbackComponent` while its props are still streaming.
|
|
75
|
+
* - `RenderViewEntry` object — lets you supply a custom `fallback` component,
|
|
76
|
+
* an optional Standard Schema (`schema`) used as a mount-readiness gate, and
|
|
77
|
+
* an optional `description` for model-facing tool registration.
|
|
78
|
+
*
|
|
79
|
+
* **Registry accessor**
|
|
80
|
+
* The returned object exposes a single `getEntry(name: string)` accessor that
|
|
81
|
+
* returns the fully-normalized {@link NormalizedEntry} (component + fallback +
|
|
82
|
+
* optional schema + optional description) or `undefined` when the name is not
|
|
83
|
+
* registered. Use `names()` to enumerate all registered names.
|
|
84
|
+
*
|
|
85
|
+
* @param componentMap Object whose keys are tool-call names and whose values
|
|
86
|
+
* are either bare Angular component classes or {@link RenderViewEntry} objects.
|
|
87
|
+
* @returns An {@link AngularRegistry} with `getEntry` and `names` accessors.
|
|
88
|
+
* @example
|
|
89
|
+
* ```ts
|
|
90
|
+
* import { defineAngularRegistry } from '@threadplane/render';
|
|
91
|
+
* import { DayCardComponent } from './day-card.component';
|
|
92
|
+
* import { LoadingSpinnerComponent } from './loading-spinner.component';
|
|
93
|
+
* import { z } from 'zod';
|
|
94
|
+
*
|
|
95
|
+
* export const registry = defineAngularRegistry({
|
|
96
|
+
* // Bare component — uses DefaultFallbackComponent while streaming.
|
|
97
|
+
* summary_card: SummaryCardComponent,
|
|
98
|
+
*
|
|
99
|
+
* // Full entry — custom fallback + schema-gated mounting.
|
|
100
|
+
* day_card: {
|
|
101
|
+
* component: DayCardComponent,
|
|
102
|
+
* fallback: LoadingSpinnerComponent,
|
|
103
|
+
* schema: z.object({ label: z.string(), day: z.number() }),
|
|
104
|
+
* description: 'Renders a single itinerary day card.',
|
|
105
|
+
* },
|
|
106
|
+
* });
|
|
107
|
+
*
|
|
108
|
+
* // Look up a registered entry at runtime:
|
|
109
|
+
* const entry = registry.getEntry('day_card'); // NormalizedEntry | undefined
|
|
110
|
+
* ```
|
|
111
|
+
*/
|
|
57
112
|
function defineAngularRegistry(componentMap) {
|
|
58
113
|
const map = new Map();
|
|
59
114
|
for (const [name, entry] of Object.entries(componentMap)) {
|
|
60
115
|
map.set(name, normalize(entry));
|
|
61
116
|
}
|
|
62
117
|
return {
|
|
63
|
-
|
|
64
|
-
getFallback: (name) => map.get(name)?.fallback,
|
|
118
|
+
getEntry: (name) => map.get(name),
|
|
65
119
|
names: () => [...map.keys()],
|
|
66
120
|
};
|
|
67
121
|
}
|
|
@@ -187,6 +241,41 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImpor
|
|
|
187
241
|
|
|
188
242
|
// SPDX-License-Identifier: MIT
|
|
189
243
|
const RENDER_CONFIG = new InjectionToken('RENDER_CONFIG');
|
|
244
|
+
/**
|
|
245
|
+
* Bootstrap `@threadplane/render` in an Angular application or standalone
|
|
246
|
+
* component tree.
|
|
247
|
+
*
|
|
248
|
+
* Registers the shared {@link RenderConfig} token and the internal
|
|
249
|
+
* `RenderLifecycleService` that coordinates mount/unmount events across
|
|
250
|
+
* dynamically rendered components. Call this once alongside `provideChat` in
|
|
251
|
+
* `bootstrapApplication` (or the root `ApplicationConfig`).
|
|
252
|
+
*
|
|
253
|
+
* @param config Options bag that controls the render feature set:
|
|
254
|
+
* - `registry` — component registry returned by {@link defineAngularRegistry};
|
|
255
|
+
* maps tool-call names to Angular components.
|
|
256
|
+
* - `store` — optional `StateStore` for `\@json-render/core` state binding.
|
|
257
|
+
* - `functions` — optional map of computed functions available inside specs.
|
|
258
|
+
* - `handlers` — optional map of event handlers triggered by spec actions.
|
|
259
|
+
* @returns An `EnvironmentProviders` value suitable for the `providers` array
|
|
260
|
+
* of `bootstrapApplication` or `ApplicationConfig`.
|
|
261
|
+
* @example
|
|
262
|
+
* ```ts
|
|
263
|
+
* // main.ts
|
|
264
|
+
* import { bootstrapApplication } from '@angular/platform-browser';
|
|
265
|
+
* import { defineAngularRegistry, provideRender } from '@threadplane/render';
|
|
266
|
+
* import { provideChat } from '@threadplane/chat';
|
|
267
|
+
* import { DayCardComponent } from './day-card.component';
|
|
268
|
+
*
|
|
269
|
+
* const registry = defineAngularRegistry({ day_card: DayCardComponent });
|
|
270
|
+
*
|
|
271
|
+
* bootstrapApplication(AppComponent, {
|
|
272
|
+
* providers: [
|
|
273
|
+
* provideRender({ registry }),
|
|
274
|
+
* provideChat({ renderRegistry: registry }),
|
|
275
|
+
* ],
|
|
276
|
+
* });
|
|
277
|
+
* ```
|
|
278
|
+
*/
|
|
190
279
|
function provideRender(config) {
|
|
191
280
|
return makeEnvironmentProviders([
|
|
192
281
|
{ provide: RENDER_CONFIG, useValue: config },
|
|
@@ -210,13 +299,35 @@ function buildPropResolutionContext(store, repeatScope, functions) {
|
|
|
210
299
|
return ctx;
|
|
211
300
|
}
|
|
212
301
|
|
|
302
|
+
function isPromise(v) {
|
|
303
|
+
return typeof v?.then === 'function';
|
|
304
|
+
}
|
|
305
|
+
/**
|
|
306
|
+
* Decide whether the REAL component may mount, or the fallback skeleton should
|
|
307
|
+
* show. Pure (no Angular, no signals) so it is trivially unit-testable.
|
|
308
|
+
*
|
|
309
|
+
* - Any undefined-valued prop → pending (a json-render state binding is still
|
|
310
|
+
* loading).
|
|
311
|
+
* - A schema-declared contract → pending until the (possibly streaming) props
|
|
312
|
+
* validate against it. SYNC validation only: render is synchronous, so an
|
|
313
|
+
* async (Promise) validate result cannot gate a sync mount and is treated as
|
|
314
|
+
* ready. View schemas should therefore be synchronous (Zod is).
|
|
315
|
+
*/
|
|
316
|
+
function isElementReady(entry, resolvedProps) {
|
|
317
|
+
for (const v of Object.values(resolvedProps)) {
|
|
318
|
+
if (v === undefined)
|
|
319
|
+
return false;
|
|
320
|
+
}
|
|
321
|
+
const schema = entry?.schema;
|
|
322
|
+
if (schema) {
|
|
323
|
+
const out = schema['~standard'].validate(resolvedProps);
|
|
324
|
+
if (!isPromise(out) && out.issues !== undefined)
|
|
325
|
+
return false;
|
|
326
|
+
}
|
|
327
|
+
return true;
|
|
328
|
+
}
|
|
329
|
+
|
|
213
330
|
// SPDX-License-Identifier: MIT
|
|
214
|
-
/** Magic prefix on `emit()` strings that catalog components use to
|
|
215
|
-
* write back to the data model (binding `path` and the new value). The
|
|
216
|
-
* render-element's emitFn intercepts this and writes via the state
|
|
217
|
-
* store, sidestepping the normal `el.on[event]` handler binding which
|
|
218
|
-
* the catalog components have no way to declare for arbitrary paths. */
|
|
219
|
-
const A2UI_DATAMODEL_PREFIX = 'a2ui:datamodel:';
|
|
220
331
|
/** Cache of declared input names per component class. NgComponentOutlet
|
|
221
332
|
* passes every key in its `inputs` prop to the target; Angular dev mode
|
|
222
333
|
* raises NG0303 for any input the component doesn't declare. We strip
|
|
@@ -249,32 +360,6 @@ function filterInputsForClass(cls, inputs) {
|
|
|
249
360
|
}
|
|
250
361
|
return out;
|
|
251
362
|
}
|
|
252
|
-
/** Best-effort string→typed coercion for datamodel writes. Catalog
|
|
253
|
-
* components emit raw string values; the underlying state may have
|
|
254
|
-
* been declared as number/boolean/array, and consumers reading the
|
|
255
|
-
* resolved props expect the correct type. */
|
|
256
|
-
function coerceValue(raw) {
|
|
257
|
-
if (raw === '')
|
|
258
|
-
return '';
|
|
259
|
-
if (raw === 'true')
|
|
260
|
-
return true;
|
|
261
|
-
if (raw === 'false')
|
|
262
|
-
return false;
|
|
263
|
-
// JSON-array passthrough (MultipleChoice emits stringified arrays)
|
|
264
|
-
if (raw.startsWith('[') && raw.endsWith(']')) {
|
|
265
|
-
try {
|
|
266
|
-
return JSON.parse(raw);
|
|
267
|
-
}
|
|
268
|
-
catch { /* fall through */ }
|
|
269
|
-
}
|
|
270
|
-
// Numeric — only if the entire string parses cleanly as a number
|
|
271
|
-
if (/^-?\d+(?:\.\d+)?$/.test(raw)) {
|
|
272
|
-
const n = Number(raw);
|
|
273
|
-
if (!Number.isNaN(n))
|
|
274
|
-
return n;
|
|
275
|
-
}
|
|
276
|
-
return raw;
|
|
277
|
-
}
|
|
278
363
|
/**
|
|
279
364
|
* Recursive element renderer.
|
|
280
365
|
*
|
|
@@ -295,6 +380,7 @@ class RenderElementComponent {
|
|
|
295
380
|
repeatScope = inject(REPEAT_SCOPE, { optional: true });
|
|
296
381
|
parentInjector = inject(Injector);
|
|
297
382
|
destroyRef = inject(DestroyRef);
|
|
383
|
+
destroyed = false;
|
|
298
384
|
constructor() {
|
|
299
385
|
this.destroyRef.onDestroy(() => {
|
|
300
386
|
const el = this.element();
|
|
@@ -307,6 +393,7 @@ class RenderElementComponent {
|
|
|
307
393
|
elementType: el.type,
|
|
308
394
|
});
|
|
309
395
|
}
|
|
396
|
+
this.destroyed = true;
|
|
310
397
|
});
|
|
311
398
|
// Latch mountedReal=true once the real component is selected. Lives in
|
|
312
399
|
// an effect (not the computed) because Angular forbids signal writes
|
|
@@ -319,7 +406,7 @@ class RenderElementComponent {
|
|
|
319
406
|
if (!el)
|
|
320
407
|
return;
|
|
321
408
|
// Only latch when notReady is false AND a real component is registered.
|
|
322
|
-
if (!this.notReady() && this.
|
|
409
|
+
if (!this.notReady() && this.entry()?.component) {
|
|
323
410
|
this.mountedReal.set(true);
|
|
324
411
|
}
|
|
325
412
|
});
|
|
@@ -338,21 +425,28 @@ class RenderElementComponent {
|
|
|
338
425
|
}
|
|
339
426
|
/** The UIElement definition from the spec. Only propagates when reference changes. */
|
|
340
427
|
element = computed(() => this.spec()?.elements?.[this.elementKey()], { ...(ngDevMode ? { debugName: "element" } : {}), equal: Object.is });
|
|
428
|
+
/** The full normalized registry entry for this element type. */
|
|
429
|
+
entry = computed(() => {
|
|
430
|
+
const el = this.element();
|
|
431
|
+
return el ? this.ctx.registry.getEntry(el.type) : undefined;
|
|
432
|
+
}, ...(ngDevMode ? [{ debugName: "entry" }] : []));
|
|
341
433
|
/** The Angular component class for this element type. */
|
|
342
434
|
componentClass = computed(() => {
|
|
343
435
|
const el = this.element();
|
|
344
436
|
if (!el)
|
|
345
437
|
return null;
|
|
346
|
-
return this.
|
|
438
|
+
return this.entry()?.component ?? null;
|
|
347
439
|
}, ...(ngDevMode ? [{ debugName: "componentClass" }] : []));
|
|
348
440
|
/** Prop resolution context built from store + repeat scope. */
|
|
349
441
|
propCtx = computed(() => buildPropResolutionContext(this.ctx.store, this.repeatScope ?? undefined, this.ctx.functions), ...(ngDevMode ? [{ debugName: "propCtx" }] : []));
|
|
350
442
|
/** Once real mounts, never revert to fallback even if a state-bound
|
|
351
443
|
* prop later becomes undefined. Per-instance monotonic gate. */
|
|
352
444
|
mountedReal = signal(false, ...(ngDevMode ? [{ debugName: "mountedReal" }] : []));
|
|
353
|
-
/** True when
|
|
354
|
-
*
|
|
355
|
-
*
|
|
445
|
+
/** True when the element is not yet ready to mount the real component.
|
|
446
|
+
* Delegates to `isElementReady` which checks:
|
|
447
|
+
* 1. Any undefined-valued resolved prop (state binding still loading).
|
|
448
|
+
* 2. A sync Standard-Schema gate if the registry entry declares a schema.
|
|
449
|
+
* Framework-injected keys (bindings, emit, loading, childKeys, spec) are
|
|
356
450
|
* excluded — only consumer-resolved props matter for readiness. */
|
|
357
451
|
notReady = computed(() => {
|
|
358
452
|
if (this.mountedReal())
|
|
@@ -361,11 +455,7 @@ class RenderElementComponent {
|
|
|
361
455
|
if (!el || !el.props)
|
|
362
456
|
return false;
|
|
363
457
|
const resolved = resolveElementProps(el.props, this.propCtx());
|
|
364
|
-
|
|
365
|
-
if (v === undefined)
|
|
366
|
-
return true;
|
|
367
|
-
}
|
|
368
|
-
return false;
|
|
458
|
+
return !isElementReady(this.entry(), resolved);
|
|
369
459
|
}, ...(ngDevMode ? [{ debugName: "notReady" }] : []));
|
|
370
460
|
/** Picks fallback or real based on notReady. The mountedReal latch is
|
|
371
461
|
* driven by a constructor effect (not this computed) — Angular forbids
|
|
@@ -374,9 +464,9 @@ class RenderElementComponent {
|
|
|
374
464
|
const el = this.element();
|
|
375
465
|
if (!el)
|
|
376
466
|
return null;
|
|
377
|
-
const real = this.
|
|
467
|
+
const real = this.entry()?.component ?? null;
|
|
378
468
|
if (this.notReady()) {
|
|
379
|
-
return this.
|
|
469
|
+
return this.entry()?.fallback ?? null;
|
|
380
470
|
}
|
|
381
471
|
return real;
|
|
382
472
|
}, ...(ngDevMode ? [{ debugName: "mountClass" }] : []));
|
|
@@ -389,28 +479,8 @@ class RenderElementComponent {
|
|
|
389
479
|
return false;
|
|
390
480
|
return evaluateVisibility(el.visible, this.propCtx());
|
|
391
481
|
}, ...(ngDevMode ? [{ debugName: "visible" }] : []));
|
|
392
|
-
/**
|
|
393
|
-
|
|
394
|
-
* input components (TextField, MultipleChoice, CheckBox, Slider,
|
|
395
|
-
* DateTimeInput) emit when the user changes their value. The render
|
|
396
|
-
* lib's state store is the single source of truth for in-surface UI
|
|
397
|
-
* state; writing through it triggers re-render with the new value
|
|
398
|
-
* and re-evaluates any path-bound props (validation, computed
|
|
399
|
-
* visibility, etc.).
|
|
400
|
-
*
|
|
401
|
-
* The string format is `a2ui:datamodel:<path>:<value>` where:
|
|
402
|
-
* - `<path>` is a JSON-Pointer-style path (e.g. `/name`, `/form/email`)
|
|
403
|
-
* - `<value>` is the raw value rendered as a string. We attempt to
|
|
404
|
-
* coerce numeric and boolean literals back to their typed form
|
|
405
|
-
* so downstream consumers see correct types; arrays come through
|
|
406
|
-
* as JSON-stringified payloads (catalog components emit them via
|
|
407
|
-
* `JSON.stringify`).
|
|
408
|
-
*/
|
|
409
|
-
emitFn = (event) => {
|
|
410
|
-
if (event.startsWith(A2UI_DATAMODEL_PREFIX)) {
|
|
411
|
-
this.applyDatamodelWrite(event);
|
|
412
|
-
return;
|
|
413
|
-
}
|
|
482
|
+
/** Invokes the element's `on[event]` handler bindings. */
|
|
483
|
+
invokeHandlers(event, payload) {
|
|
414
484
|
const el = this.element();
|
|
415
485
|
if (!el?.on)
|
|
416
486
|
return;
|
|
@@ -421,31 +491,27 @@ class RenderElementComponent {
|
|
|
421
491
|
for (const b of bindings) {
|
|
422
492
|
const handler = this.ctx.handlers?.[b.action];
|
|
423
493
|
if (handler) {
|
|
424
|
-
|
|
494
|
+
const params = { ...(b.params ?? {}), ...(payload ?? {}) };
|
|
495
|
+
runInInjectionContext(this.parentInjector, () => handler(params));
|
|
425
496
|
}
|
|
426
497
|
}
|
|
427
|
-
};
|
|
428
|
-
applyDatamodelWrite(event) {
|
|
429
|
-
// Strip the prefix, then split path and value at the last `:` —
|
|
430
|
-
// path may itself contain `:` characters (rare but legal in
|
|
431
|
-
// JSON-Pointer per RFC 6901), and values can certainly contain
|
|
432
|
-
// them (URLs, time strings). Catalog components emit
|
|
433
|
-
// `a2ui:datamodel:<path>:<value>` where path is the binding's
|
|
434
|
-
// path-ref (usually starts with `/`); split the LAST `:` because
|
|
435
|
-
// the value is the only field guaranteed to come last.
|
|
436
|
-
const rest = event.slice(A2UI_DATAMODEL_PREFIX.length);
|
|
437
|
-
const lastColon = rest.lastIndexOf(':');
|
|
438
|
-
if (lastColon === -1)
|
|
439
|
-
return;
|
|
440
|
-
const path = rest.slice(0, lastColon);
|
|
441
|
-
const rawValue = rest.slice(lastColon + 1);
|
|
442
|
-
if (!path)
|
|
443
|
-
return;
|
|
444
|
-
const store = this.ctx.store;
|
|
445
|
-
if (!store)
|
|
446
|
-
return;
|
|
447
|
-
store.set(path, coerceValue(rawValue));
|
|
448
498
|
}
|
|
499
|
+
/** Element-scoped host injected by mounted view components via
|
|
500
|
+
* injectRenderHost(). `set` writes the store; `emit` routes element
|
|
501
|
+
* handlers; `result` surfaces a RenderResultEvent for this element. */
|
|
502
|
+
host = {
|
|
503
|
+
set: (path, value) => { if (this.destroyed)
|
|
504
|
+
return; this.ctx.store?.set(path, value); },
|
|
505
|
+
emit: (event, payload) => { if (this.destroyed)
|
|
506
|
+
return; this.invokeHandlers(event, payload); },
|
|
507
|
+
result: (value) => { if (this.destroyed)
|
|
508
|
+
return; this.ctx.emitEvent?.({ type: 'result', value, elementKey: this.elementKey() }); },
|
|
509
|
+
};
|
|
510
|
+
/** Emit function passed to mounted view components as the `emit` framework
|
|
511
|
+
* input. Delegates to the element's `on[event]` handler bindings. */
|
|
512
|
+
emitFn = (event) => {
|
|
513
|
+
this.invokeHandlers(event);
|
|
514
|
+
};
|
|
449
515
|
/** Resolved inputs for non-repeat elements. */
|
|
450
516
|
resolvedInputs = computed(() => {
|
|
451
517
|
const el = this.element();
|
|
@@ -520,7 +586,9 @@ class RenderElementComponent {
|
|
|
520
586
|
return this.repeatInputs().map(inputs => filterInputsForClass(cls, inputs));
|
|
521
587
|
}, ...(ngDevMode ? [{ debugName: "filteredRepeatInputs" }] : []));
|
|
522
588
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: RenderElementComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
523
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.6", type: RenderElementComponent, isStandalone: true, selector: "render-element", inputs: { elementKey: { classPropertyName: "elementKey", publicName: "elementKey", isSignal: true, isRequired: true, transformFunction: null }, spec: { classPropertyName: "spec", publicName: "spec", isSignal: true, isRequired: true, transformFunction: null } },
|
|
589
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.6", type: RenderElementComponent, isStandalone: true, selector: "render-element", inputs: { elementKey: { classPropertyName: "elementKey", publicName: "elementKey", isSignal: true, isRequired: true, transformFunction: null }, spec: { classPropertyName: "spec", publicName: "spec", isSignal: true, isRequired: true, transformFunction: null } }, providers: [
|
|
590
|
+
{ provide: RENDER_HOST, useFactory: (el) => el.host, deps: [RenderElementComponent] },
|
|
591
|
+
], ngImport: i0, template: `
|
|
524
592
|
@if (!element()?.repeat) {
|
|
525
593
|
@if (visible()) {
|
|
526
594
|
<ng-container
|
|
@@ -543,6 +611,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImpor
|
|
|
543
611
|
standalone: true,
|
|
544
612
|
imports: [NgComponentOutlet],
|
|
545
613
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
614
|
+
providers: [
|
|
615
|
+
{ provide: RENDER_HOST, useFactory: (el) => el.host, deps: [RenderElementComponent] },
|
|
616
|
+
],
|
|
546
617
|
template: `
|
|
547
618
|
@if (!element()?.repeat) {
|
|
548
619
|
@if (visible()) {
|
|
@@ -606,6 +677,21 @@ function toRenderRegistry(registry) {
|
|
|
606
677
|
return defineAngularRegistry(registry);
|
|
607
678
|
}
|
|
608
679
|
|
|
680
|
+
// SPDX-License-Identifier: MIT
|
|
681
|
+
/**
|
|
682
|
+
* Wraps an emit function so it becomes a no-op once `isDestroyed()` returns
|
|
683
|
+
* true. Prevents Angular NG0953 ("emit on a destroyed OutputRef") when a late
|
|
684
|
+
* event (e.g. an ask client-tool resolving during teardown) tries to fire
|
|
685
|
+
* after the owning component has been destroyed.
|
|
686
|
+
*/
|
|
687
|
+
function makeGuardedEmit(emit, isDestroyed) {
|
|
688
|
+
return (event) => {
|
|
689
|
+
if (isDestroyed())
|
|
690
|
+
return;
|
|
691
|
+
emit(event);
|
|
692
|
+
};
|
|
693
|
+
}
|
|
694
|
+
|
|
609
695
|
// SPDX-License-Identifier: MIT
|
|
610
696
|
/**
|
|
611
697
|
* Top-level entry point for rendering a json-render spec.
|
|
@@ -634,6 +720,9 @@ class RenderSpecComponent {
|
|
|
634
720
|
viewRegistry = inject(VIEW_REGISTRY, { optional: true });
|
|
635
721
|
destroyRef = inject(DestroyRef);
|
|
636
722
|
lifecycle = inject(RenderLifecycleService, { optional: true });
|
|
723
|
+
destroyed = false;
|
|
724
|
+
/** Guarded OutputRef emit — no-ops after destroy (NG0953). */
|
|
725
|
+
guardedEmit = makeGuardedEmit((e) => this.events.emit(e), () => this.destroyed);
|
|
637
726
|
/** Internal store, lazily created once and reused across spec changes. */
|
|
638
727
|
_internalStore;
|
|
639
728
|
getOrCreateInternalStore() {
|
|
@@ -663,7 +752,7 @@ class RenderSpecComponent {
|
|
|
663
752
|
if (this.viewRegistry)
|
|
664
753
|
return toRenderRegistry(this.viewRegistry);
|
|
665
754
|
// Fallback: empty registry
|
|
666
|
-
return {
|
|
755
|
+
return { getEntry: () => undefined, names: () => [] };
|
|
667
756
|
}, ...(ngDevMode ? [{ debugName: "resolvedRegistry" }] : []));
|
|
668
757
|
/** Wraps input handlers to emit RenderHandlerEvent after execution. */
|
|
669
758
|
wrappedHandlers = computed(() => {
|
|
@@ -692,8 +781,8 @@ class RenderSpecComponent {
|
|
|
692
781
|
/** Emits a RenderEvent through the events output and notifies the
|
|
693
782
|
* lifecycle service (single tap point — all events flow through here). */
|
|
694
783
|
emitTapped = (event) => {
|
|
695
|
-
this.
|
|
696
|
-
if (!this.lifecycle)
|
|
784
|
+
this.guardedEmit(event);
|
|
785
|
+
if (this.destroyed || !this.lifecycle)
|
|
697
786
|
return;
|
|
698
787
|
switch (event.type) {
|
|
699
788
|
case 'lifecycle':
|
|
@@ -741,6 +830,7 @@ class RenderSpecComponent {
|
|
|
741
830
|
});
|
|
742
831
|
this.destroyRef.onDestroy(() => {
|
|
743
832
|
this.emitTapped({ type: 'lifecycle', event: 'destroyed', scope: 'spec' });
|
|
833
|
+
this.destroyed = true;
|
|
744
834
|
});
|
|
745
835
|
}
|
|
746
836
|
ngOnInit() {
|
|
@@ -786,5 +876,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImpor
|
|
|
786
876
|
* Generated bundle index. Do not edit.
|
|
787
877
|
*/
|
|
788
878
|
|
|
789
|
-
export { DefaultFallbackComponent, RENDER_CONFIG, RENDER_CONTEXT, RENDER_LIFECYCLE, REPEAT_SCOPE, RenderElementComponent, RenderSpecComponent, VIEW_REGISTRY, defineAngularRegistry, overrideViews, provideRender, provideViews, signalStateStore, toRenderRegistry, views, withViews, withoutViews };
|
|
879
|
+
export { DefaultFallbackComponent, RENDER_CONFIG, RENDER_CONTEXT, RENDER_HOST, RENDER_LIFECYCLE, REPEAT_SCOPE, RenderElementComponent, RenderSpecComponent, VIEW_REGISTRY, defineAngularRegistry, injectRenderHost, overrideViews, provideRender, provideViews, signalStateStore, toRenderRegistry, views, withViews, withoutViews };
|
|
790
880
|
//# sourceMappingURL=threadplane-render.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"threadplane-render.mjs","sources":["../../../../libs/render/src/lib/contexts/render-context.ts","../../../../libs/render/src/lib/contexts/repeat-scope.ts","../../../../libs/render/src/lib/default-fallback.component.ts","../../../../libs/render/src/lib/define-angular-registry.ts","../../../../libs/render/src/lib/signal-state-store.ts","../../../../libs/render/src/lib/lifecycle.ts","../../../../libs/render/src/lib/render-lifecycle.service.ts","../../../../libs/render/src/lib/provide-render.ts","../../../../libs/render/src/lib/internals/prop-signal.ts","../../../../libs/render/src/lib/render-element.component.ts","../../../../libs/render/src/lib/provide-views.ts","../../../../libs/render/src/lib/views.ts","../../../../libs/render/src/lib/render-spec.component.ts","../../../../libs/render/src/public-api.ts","../../../../libs/render/src/threadplane-render.ts"],"sourcesContent":["// SPDX-License-Identifier: MIT\nimport { InjectionToken } from '@angular/core';\nimport type { StateStore, ComputedFunction } from '@json-render/core';\nimport type { AngularRegistry } from '../render.types';\nimport type { RenderEvent } from '../render-event';\n\nexport interface RenderContext {\n registry: AngularRegistry;\n store: StateStore;\n functions?: Record<string, ComputedFunction>;\n handlers?: Record<string, (params: Record<string, unknown>) => unknown | Promise<unknown>>;\n emitEvent?: (event: RenderEvent) => void;\n loading?: boolean;\n}\n\nexport const RENDER_CONTEXT = new InjectionToken<RenderContext>('RENDER_CONTEXT');\n","// SPDX-License-Identifier: MIT\nimport { InjectionToken } from '@angular/core';\n\nexport interface RepeatScope {\n item: unknown;\n index: number;\n basePath: string;\n}\n\nexport const REPEAT_SCOPE = new InjectionToken<RepeatScope>('REPEAT_SCOPE');\n","// SPDX-License-Identifier: MIT\nimport { Component, ChangeDetectionStrategy } from '@angular/core';\n\n@Component({\n selector: 'render-default-fallback',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n styles: [`\n :host { display: block; width: 100%; }\n .render-default-fallback {\n border: 1px solid var(--ngaf-chat-separator, #303540);\n border-radius: 10px;\n padding: 14px;\n background: var(--ngaf-chat-surface-alt, #1a1d23);\n }\n .render-default-fallback__label {\n font-size: 12px;\n color: var(--ngaf-chat-text-muted, #9aa0aa);\n margin-bottom: 10px;\n display: flex;\n align-items: center;\n gap: 6px;\n }\n .render-default-fallback__rows {\n display: flex; flex-direction: column; gap: 8px;\n }\n .render-default-fallback__row {\n height: 10px; border-radius: 5px;\n background: linear-gradient(\n 90deg,\n var(--ngaf-chat-separator, #303540) 0%,\n color-mix(in srgb, var(--ngaf-chat-separator, #303540) 70%, transparent) 50%,\n var(--ngaf-chat-separator, #303540) 100%\n );\n background-size: 200% 100%;\n animation: render-default-fallback-shimmer 1.4s ease-in-out infinite;\n }\n .render-default-fallback__row:nth-child(1) { width: 70%; }\n .render-default-fallback__row:nth-child(2) { width: 90%; }\n .render-default-fallback__row:nth-child(3) { width: 50%; }\n @keyframes render-default-fallback-shimmer {\n 0% { background-position: 200% 0; }\n 100% { background-position: -200% 0; }\n }\n `],\n template: `\n <div class=\"render-default-fallback\" role=\"status\" aria-live=\"polite\">\n <div class=\"render-default-fallback__label\">\n <span aria-hidden=\"true\">✨</span>\n <span>Building UI…</span>\n </div>\n <div class=\"render-default-fallback__rows\">\n <div class=\"render-default-fallback__row\"></div>\n <div class=\"render-default-fallback__row\"></div>\n <div class=\"render-default-fallback__row\"></div>\n </div>\n </div>\n `,\n})\nexport class DefaultFallbackComponent {}\n","// SPDX-License-Identifier: MIT\nimport { Type } from '@angular/core';\nimport type { AngularRegistry, RenderViewEntry } from './render.types';\nimport { DefaultFallbackComponent } from './default-fallback.component';\n\ntype RegistryInput = Record<string, Type<unknown> | RenderViewEntry>;\n\ninterface NormalizedEntry {\n component: Type<unknown>;\n fallback: Type<unknown>;\n}\n\nfunction normalize(entry: Type<unknown> | RenderViewEntry): NormalizedEntry {\n // Bare Type — register with the default fallback.\n if (typeof entry === 'function') {\n return { component: entry, fallback: DefaultFallbackComponent };\n }\n // Object form — preserve component; use configured fallback or default.\n return {\n component: entry.component,\n fallback: entry.fallback ?? DefaultFallbackComponent,\n };\n}\n\nexport function defineAngularRegistry(componentMap: RegistryInput): AngularRegistry {\n const map = new Map<string, NormalizedEntry>();\n for (const [name, entry] of Object.entries(componentMap)) {\n map.set(name, normalize(entry));\n }\n return {\n get: (name: string) => map.get(name)?.component,\n getFallback: (name: string) => map.get(name)?.fallback,\n names: () => [...map.keys()],\n };\n}\n","// SPDX-License-Identifier: MIT\nimport { signal } from '@angular/core';\nimport type { StateStore, StateModel } from '@json-render/core';\n\nfunction parsePointer(path: string): string[] {\n if (!path || path === '/') return [];\n return path.split('/').filter((_, i) => i > 0).map(s => s.replace(/~1/g, '/').replace(/~0/g, '~'));\n}\n\nfunction getByPath(obj: unknown, segments: string[]): unknown {\n let current: unknown = obj;\n for (const seg of segments) {\n if (current == null || typeof current !== 'object') return undefined;\n current = (current as Record<string, unknown>)[seg];\n }\n return current;\n}\n\nfunction setByPath(obj: unknown, segments: string[], value: unknown): unknown {\n if (segments.length === 0) return value;\n const [head, ...rest] = segments;\n\n if (Array.isArray(obj)) {\n const index = Number(head);\n const clone = [...obj];\n clone[index] = setByPath(clone[index], rest, value);\n return clone;\n }\n\n const record = (obj != null && typeof obj === 'object')\n ? { ...obj as Record<string, unknown> }\n : {} as Record<string, unknown>;\n record[head] = setByPath(record[head], rest, value);\n return record;\n}\n\nexport function signalStateStore(initialState: StateModel = {}): StateStore {\n const state = signal<StateModel>(initialState);\n const listeners = new Set<() => void>();\n\n function notify(): void {\n for (const listener of listeners) listener();\n }\n\n return {\n get(path: string): unknown {\n return getByPath(state(), parsePointer(path));\n },\n set(path: string, value: unknown): void {\n const segments = parsePointer(path);\n const current = getByPath(state(), segments);\n if (current === value) return;\n state.set(setByPath(state(), segments, value) as StateModel);\n notify();\n },\n update(updates: Record<string, unknown>): void {\n let current = state();\n let changed = false;\n for (const [path, value] of Object.entries(updates)) {\n const segments = parsePointer(path);\n const existing = getByPath(current, segments);\n if (existing !== value) {\n current = setByPath(current, segments, value) as StateModel;\n changed = true;\n }\n }\n if (changed) {\n state.set(current);\n notify();\n }\n },\n getSnapshot(): StateModel {\n return state();\n },\n subscribe(listener: () => void): () => void {\n listeners.add(listener);\n return () => listeners.delete(listener);\n },\n };\n}\n","// SPDX-License-Identifier: MIT\nimport { InjectionToken, Signal } from '@angular/core';\n\nexport interface RenderLifecycle {\n /** First mount event in this render context. Sticky — does not reset. */\n readonly firstMountAt: Signal<{ kind: 'spec' | 'element'; elementType?: string; at: number } | null>;\n /** Total mount count since render context started. */\n readonly mountCount: Signal<number>;\n /** Epoch ms of the most recent mount event. */\n readonly lastMountAt: Signal<number | null>;\n /** Epoch ms of the most recent state-change event. */\n readonly lastStateChangeAt: Signal<number | null>;\n /** Most recent handler invocation. */\n readonly lastHandlerInvokedAt: Signal<{ action: string; at: number } | null>;\n}\n\nexport const RENDER_LIFECYCLE = new InjectionToken<RenderLifecycle>('RENDER_LIFECYCLE');\n","// SPDX-License-Identifier: MIT\nimport { Injectable, signal } from '@angular/core';\nimport type { RenderLifecycle } from './lifecycle';\n\n/**\n * Provided by `provideRender()` — opt-in. Scope follows the consumer's\n * `provideRender` call (root-scoped by default, sub-tree if `provideRender`\n * is in a sub-injector).\n */\n@Injectable()\nexport class RenderLifecycleService implements RenderLifecycle {\n private _firstMountAt = signal<{ kind: 'spec' | 'element'; elementType?: string; at: number } | null>(null);\n private _mountCount = signal(0);\n private _lastMountAt = signal<number | null>(null);\n private _lastStateChangeAt = signal<number | null>(null);\n private _lastHandlerInvokedAt = signal<{ action: string; at: number } | null>(null);\n\n readonly firstMountAt = this._firstMountAt.asReadonly();\n readonly mountCount = this._mountCount.asReadonly();\n readonly lastMountAt = this._lastMountAt.asReadonly();\n readonly lastStateChangeAt = this._lastStateChangeAt.asReadonly();\n readonly lastHandlerInvokedAt = this._lastHandlerInvokedAt.asReadonly();\n\n notifyLifecycle(event: { kind: 'spec' | 'element'; type: 'mounted' | 'destroyed'; elementType?: string }): void {\n if (event.type === 'mounted') {\n const now = Date.now();\n if (this._firstMountAt() === null) {\n this._firstMountAt.set({ kind: event.kind, elementType: event.elementType, at: now });\n }\n this._mountCount.update((c) => c + 1);\n this._lastMountAt.set(now);\n }\n }\n\n notifyStateChange(): void {\n this._lastStateChangeAt.set(Date.now());\n }\n\n notifyHandlerInvoked(action: string): void {\n this._lastHandlerInvokedAt.set({ action, at: Date.now() });\n }\n}\n","// SPDX-License-Identifier: MIT\nimport { InjectionToken, makeEnvironmentProviders } from '@angular/core';\nimport type { RenderConfig } from './render.types';\nimport { RENDER_LIFECYCLE } from './lifecycle';\nimport { RenderLifecycleService } from './render-lifecycle.service';\n\nexport const RENDER_CONFIG = new InjectionToken<RenderConfig>('RENDER_CONFIG');\n\nexport function provideRender(config: RenderConfig) {\n return makeEnvironmentProviders([\n { provide: RENDER_CONFIG, useValue: config },\n RenderLifecycleService,\n { provide: RENDER_LIFECYCLE, useExisting: RenderLifecycleService },\n ]);\n}\n","// SPDX-License-Identifier: MIT\nimport type { StateStore, ComputedFunction, PropResolutionContext } from '@json-render/core';\nimport type { RepeatScope } from '../contexts/repeat-scope';\n\nexport function buildPropResolutionContext(\n store: StateStore,\n repeatScope?: RepeatScope,\n functions?: Record<string, ComputedFunction>,\n): PropResolutionContext {\n const ctx: PropResolutionContext = {\n stateModel: store.getSnapshot(),\n };\n if (repeatScope) {\n ctx.repeatItem = repeatScope.item;\n ctx.repeatIndex = repeatScope.index;\n ctx.repeatBasePath = repeatScope.basePath;\n }\n if (functions) {\n ctx.functions = functions;\n }\n return ctx;\n}\n","// SPDX-License-Identifier: MIT\nimport {\n ChangeDetectionStrategy,\n Component,\n computed,\n DestroyRef,\n effect,\n inject,\n Injector,\n input,\n OnInit,\n reflectComponentType,\n runInInjectionContext,\n signal,\n type Signal,\n type Type,\n} from '@angular/core';\nimport { NgComponentOutlet } from '@angular/common';\nimport {\n evaluateVisibility,\n resolveBindings,\n resolveElementProps,\n} from '@json-render/core';\nimport type { Spec, UIElement } from '@json-render/core';\n\nimport { RENDER_CONTEXT } from './contexts/render-context';\nimport { REPEAT_SCOPE } from './contexts/repeat-scope';\nimport type { RepeatScope } from './contexts/repeat-scope';\nimport { buildPropResolutionContext } from './internals/prop-signal';\nimport type { AngularComponentRenderer } from './render.types';\n\n/** Magic prefix on `emit()` strings that catalog components use to\n * write back to the data model (binding `path` and the new value). The\n * render-element's emitFn intercepts this and writes via the state\n * store, sidestepping the normal `el.on[event]` handler binding which\n * the catalog components have no way to declare for arbitrary paths. */\nconst A2UI_DATAMODEL_PREFIX = 'a2ui:datamodel:';\n\n/** Cache of declared input names per component class. NgComponentOutlet\n * passes every key in its `inputs` prop to the target; Angular dev mode\n * raises NG0303 for any input the component doesn't declare. We strip\n * undeclared keys before mounting so simple view components (`StatCard`,\n * `Container`, etc.) don't get spammed with framework-only inputs\n * (`bindings`, `emit`, `loading`, `childKeys`, `spec`) they ignore. */\n/** `null` means reflection failed (likely uncompiled / non-component) — in\n * that case we pass inputs through unmodified rather than swallow them.\n * An empty Set means the component genuinely declares zero inputs (e.g. a\n * pure presentational fallback) and ALL keys should be dropped. */\nconst declaredInputsCache = new WeakMap<Type<unknown>, Set<string> | null>();\nfunction getDeclaredInputs(cls: Type<unknown>): Set<string> | null {\n if (declaredInputsCache.has(cls)) return declaredInputsCache.get(cls)!;\n const meta = reflectComponentType(cls);\n const result = meta ? new Set<string>(meta.inputs.map(i => i.templateName)) : null;\n declaredInputsCache.set(cls, result);\n return result;\n}\nfunction filterInputsForClass(\n cls: Type<unknown> | null,\n inputs: Record<string, unknown>,\n): Record<string, unknown> {\n if (!cls) return inputs;\n const declared = getDeclaredInputs(cls);\n if (declared === null) return inputs;\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(inputs)) {\n if (declared.has(k)) out[k] = v;\n }\n return out;\n}\n\n/** Best-effort string→typed coercion for datamodel writes. Catalog\n * components emit raw string values; the underlying state may have\n * been declared as number/boolean/array, and consumers reading the\n * resolved props expect the correct type. */\nfunction coerceValue(raw: string): unknown {\n if (raw === '') return '';\n if (raw === 'true') return true;\n if (raw === 'false') return false;\n // JSON-array passthrough (MultipleChoice emits stringified arrays)\n if (raw.startsWith('[') && raw.endsWith(']')) {\n try { return JSON.parse(raw); } catch { /* fall through */ }\n }\n // Numeric — only if the entire string parses cleanly as a number\n if (/^-?\\d+(?:\\.\\d+)?$/.test(raw)) {\n const n = Number(raw);\n if (!Number.isNaN(n)) return n;\n }\n return raw;\n}\n\n/**\n * Recursive element renderer.\n *\n * For each element key it:\n * 1. Looks up the UIElement from spec.elements\n * 2. Resolves the component class from the registry\n * 3. Evaluates visibility\n * 4. Resolves prop expressions and bindings\n * 5. Renders via NgComponentOutlet with resolved inputs\n *\n * For elements with `repeat`, it iterates over the state array,\n * creating a child Injector with RepeatScope for each item.\n */\n@Component({\n selector: 'render-element',\n standalone: true,\n imports: [NgComponentOutlet],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n @if (!element()?.repeat) {\n @if (visible()) {\n <ng-container\n *ngComponentOutlet=\"mountClass(); inputs: filteredResolvedInputs(); injector: parentInjector\"\n />\n }\n } @else {\n @for (repeatInjector of repeatInjectors(); track $index) {\n <ng-container\n *ngComponentOutlet=\"mountClass(); inputs: filteredRepeatInputs()[$index]; injector: repeatInjector\"\n />\n }\n }\n `,\n})\nexport class RenderElementComponent implements OnInit {\n readonly elementKey = input.required<string>();\n readonly spec = input.required<Spec>();\n\n private readonly ctx = inject(RENDER_CONTEXT);\n private readonly repeatScope = inject(REPEAT_SCOPE, { optional: true });\n readonly parentInjector = inject(Injector);\n private readonly destroyRef = inject(DestroyRef);\n\n constructor() {\n this.destroyRef.onDestroy(() => {\n const el = this.element();\n if (el && (el as any)['lifecycle'] && this.ctx.emitEvent) {\n this.ctx.emitEvent({\n type: 'lifecycle',\n event: 'destroyed',\n scope: 'element',\n elementKey: this.elementKey(),\n elementType: el.type,\n });\n }\n });\n\n // Latch mountedReal=true once the real component is selected. Lives in\n // an effect (not the computed) because Angular forbids signal writes\n // inside computed — they're for derivation only. Effects are the\n // idiomatic place for \"signal change → signal write\" side effects.\n effect(() => {\n if (this.mountedReal()) return;\n const el = this.element();\n if (!el) return;\n // Only latch when notReady is false AND a real component is registered.\n if (!this.notReady() && this.ctx.registry.get(el.type)) {\n this.mountedReal.set(true);\n }\n });\n }\n\n ngOnInit(): void {\n const el = this.element();\n if (el && (el as any)['lifecycle'] && this.ctx.emitEvent) {\n this.ctx.emitEvent({\n type: 'lifecycle',\n event: 'mounted',\n scope: 'element',\n elementKey: this.elementKey(),\n elementType: el.type,\n });\n }\n }\n\n /** The UIElement definition from the spec. Only propagates when reference changes. */\n readonly element: Signal<UIElement | undefined> = computed(\n () => this.spec()?.elements?.[this.elementKey()],\n { equal: Object.is },\n );\n\n /** The Angular component class for this element type. */\n readonly componentClass = computed<AngularComponentRenderer | null>(() => {\n const el = this.element();\n if (!el) return null;\n return this.ctx.registry.get(el.type) ?? null;\n });\n\n /** Prop resolution context built from store + repeat scope. */\n private readonly propCtx = computed(() =>\n buildPropResolutionContext(\n this.ctx.store,\n this.repeatScope ?? undefined,\n this.ctx.functions,\n ),\n );\n\n /** Once real mounts, never revert to fallback even if a state-bound\n * prop later becomes undefined. Per-instance monotonic gate. */\n private readonly mountedReal = signal<boolean>(false);\n\n /** True when ANY resolved prop value is undefined (i.e. a state\n * binding points at a path the store hasn't populated). Framework-\n * injected keys (bindings, emit, loading, childKeys, spec) are\n * excluded — only consumer-resolved props matter for readiness. */\n readonly notReady = computed<boolean>(() => {\n if (this.mountedReal()) return false;\n const el = this.element();\n if (!el || !el.props) return false;\n const resolved = resolveElementProps(el.props, this.propCtx());\n for (const v of Object.values(resolved)) {\n if (v === undefined) return true;\n }\n return false;\n });\n\n /** Picks fallback or real based on notReady. The mountedReal latch is\n * driven by a constructor effect (not this computed) — Angular forbids\n * signal writes inside computed. */\n readonly mountClass = computed<AngularComponentRenderer | null>(() => {\n const el = this.element();\n if (!el) return null;\n const real = this.ctx.registry.get(el.type) ?? null;\n if (this.notReady()) {\n return this.ctx.registry.getFallback(el.type) ?? null;\n }\n return real;\n });\n\n /** Whether the element is visible (non-repeat path). */\n readonly visible = computed(() => {\n const el = this.element();\n if (!el) return false;\n if (this.mountClass() === null) return false;\n return evaluateVisibility(el.visible, this.propCtx());\n });\n\n /** Emit function that delegates to context handlers AND handles the\n * canonical `a2ui:datamodel:<path>:<value>` write-back protocol that\n * input components (TextField, MultipleChoice, CheckBox, Slider,\n * DateTimeInput) emit when the user changes their value. The render\n * lib's state store is the single source of truth for in-surface UI\n * state; writing through it triggers re-render with the new value\n * and re-evaluates any path-bound props (validation, computed\n * visibility, etc.).\n *\n * The string format is `a2ui:datamodel:<path>:<value>` where:\n * - `<path>` is a JSON-Pointer-style path (e.g. `/name`, `/form/email`)\n * - `<value>` is the raw value rendered as a string. We attempt to\n * coerce numeric and boolean literals back to their typed form\n * so downstream consumers see correct types; arrays come through\n * as JSON-stringified payloads (catalog components emit them via\n * `JSON.stringify`).\n */\n private readonly emitFn = (event: string) => {\n if (event.startsWith(A2UI_DATAMODEL_PREFIX)) {\n this.applyDatamodelWrite(event);\n return;\n }\n const el = this.element();\n if (!el?.on) return;\n const binding = el.on[event];\n if (!binding) return;\n const bindings = Array.isArray(binding) ? binding : [binding];\n for (const b of bindings) {\n const handler = this.ctx.handlers?.[b.action];\n if (handler) {\n runInInjectionContext(this.parentInjector, () =>\n handler(b.params as Record<string, unknown> ?? {}),\n );\n }\n }\n };\n\n private applyDatamodelWrite(event: string): void {\n // Strip the prefix, then split path and value at the last `:` —\n // path may itself contain `:` characters (rare but legal in\n // JSON-Pointer per RFC 6901), and values can certainly contain\n // them (URLs, time strings). Catalog components emit\n // `a2ui:datamodel:<path>:<value>` where path is the binding's\n // path-ref (usually starts with `/`); split the LAST `:` because\n // the value is the only field guaranteed to come last.\n const rest = event.slice(A2UI_DATAMODEL_PREFIX.length);\n const lastColon = rest.lastIndexOf(':');\n if (lastColon === -1) return;\n const path = rest.slice(0, lastColon);\n const rawValue = rest.slice(lastColon + 1);\n if (!path) return;\n const store = this.ctx.store;\n if (!store) return;\n store.set(path, coerceValue(rawValue));\n }\n\n /** Resolved inputs for non-repeat elements. */\n readonly resolvedInputs = computed(() => {\n const el = this.element();\n if (!el) return {};\n const ctx = this.propCtx();\n const resolved = resolveElementProps(el.props ?? {}, ctx);\n const bindings = resolveBindings(el.props ?? {}, ctx);\n return {\n ...resolved,\n bindings,\n emit: this.emitFn,\n loading: this.ctx.loading ?? false,\n childKeys: el.children ?? [],\n spec: this.spec(),\n };\n });\n\n /** `resolvedInputs` filtered down to keys the target component actually\n * declares — silences NG0303 dev-mode warnings from framework-only\n * inputs (bindings/emit/loading/childKeys/spec) passed to simple view\n * components that don't declare them. */\n readonly filteredResolvedInputs = computed(() =>\n filterInputsForClass(this.mountClass() as Type<unknown> | null, this.resolvedInputs()),\n );\n\n // --- Repeat support ---\n\n /** Items from the state array for repeat elements. */\n private readonly repeatItems = computed<unknown[]>(() => {\n const el = this.element();\n if (!el?.repeat) return [];\n const items = this.ctx.store.get(el.repeat.statePath);\n return Array.isArray(items) ? items : [];\n });\n\n /** One RepeatScope per repeat item, shared between injectors and inputs. */\n private readonly repeatScopes = computed(() => {\n const el = this.element();\n if (!el?.repeat) return [];\n return this.repeatItems().map((item, index) => ({\n item,\n index,\n basePath: `${el.repeat!.statePath}/${index}`,\n } satisfies RepeatScope));\n });\n\n /** One child Injector per repeat item, providing RepeatScope. */\n readonly repeatInjectors = computed(() => {\n return this.repeatScopes().map(scope =>\n Injector.create({\n providers: [{ provide: REPEAT_SCOPE, useValue: scope }],\n parent: this.parentInjector,\n }),\n );\n });\n\n /** Resolved inputs for each repeat item. */\n readonly repeatInputs = computed(() => {\n const el = this.element();\n if (!el?.repeat) return [];\n return this.repeatScopes().map(scope => {\n const ctx = buildPropResolutionContext(\n this.ctx.store,\n scope,\n this.ctx.functions,\n );\n const resolved = resolveElementProps(el.props ?? {}, ctx);\n const bindings = resolveBindings(el.props ?? {}, ctx);\n return {\n ...resolved,\n bindings,\n emit: this.emitFn,\n loading: this.ctx.loading ?? false,\n childKeys: el.children ?? [],\n spec: this.spec(),\n };\n });\n });\n\n /** `repeatInputs` filtered per-item to declared component inputs. */\n readonly filteredRepeatInputs = computed(() => {\n const cls = this.mountClass() as Type<unknown> | null;\n return this.repeatInputs().map(inputs => filterInputsForClass(cls, inputs));\n });\n}\n","// SPDX-License-Identifier: MIT\nimport { InjectionToken, makeEnvironmentProviders } from '@angular/core';\nimport type { ViewRegistry } from './views';\n\nexport const VIEW_REGISTRY = new InjectionToken<ViewRegistry>('VIEW_REGISTRY');\n\nexport function provideViews(registry: ViewRegistry) {\n return makeEnvironmentProviders([\n { provide: VIEW_REGISTRY, useValue: registry },\n ]);\n}\n","// SPDX-License-Identifier: MIT\nimport { Type } from '@angular/core';\nimport type { AngularRegistry, RenderViewEntry } from './render.types';\nimport { defineAngularRegistry } from './define-angular-registry';\n\n/**\n * A registry of view components available for generative UI rendering.\n * Each entry is either a bare component Type (legacy shape) or a\n * `RenderViewEntry` { component, fallback? }.\n */\nexport type ViewRegistry = Readonly<Record<string, Type<unknown> | RenderViewEntry>>;\n\n/**\n * Creates a view registry from a name → component map.\n */\nexport function views(map: Record<string, Type<unknown> | RenderViewEntry>): ViewRegistry {\n return Object.freeze({ ...map });\n}\n\n/**\n * Adds views to a registry without overwriting existing entries.\n * New keys are added; keys that already exist in `base` are preserved.\n */\nexport function withViews(\n base: ViewRegistry,\n additions: Record<string, Type<unknown> | RenderViewEntry>,\n): ViewRegistry {\n return Object.freeze({ ...additions, ...base });\n}\n\n/**\n * Replaces views in a registry. Keys in `overrides` win over `base`.\n * Use this to swap an existing renderer; use `withViews` to add NEW\n * node types without touching existing entries.\n */\nexport function overrideViews(\n base: ViewRegistry,\n overrides: Record<string, Type<unknown> | RenderViewEntry>,\n): ViewRegistry {\n return Object.freeze({ ...base, ...overrides });\n}\n\n/**\n * Removes views from a registry by name.\n */\nexport function withoutViews(\n base: ViewRegistry,\n ...names: string[]\n): ViewRegistry {\n const result = { ...base };\n for (const name of names) delete result[name];\n return Object.freeze(result);\n}\n\n/**\n * Converts a ViewRegistry to an AngularRegistry for use with RenderSpecComponent.\n */\nexport function toRenderRegistry(registry: ViewRegistry): AngularRegistry {\n return defineAngularRegistry(registry);\n}\n","// SPDX-License-Identifier: MIT\nimport {\n ChangeDetectionStrategy,\n Component,\n computed,\n DestroyRef,\n effect,\n inject,\n input,\n OnInit,\n output,\n} from '@angular/core';\nimport type { ComputedFunction, Spec, StateStore } from '@json-render/core';\n\nimport { RenderElementComponent } from './render-element.component';\nimport { RENDER_CONFIG } from './provide-render';\nimport { VIEW_REGISTRY } from './provide-views';\nimport { toRenderRegistry } from './views';\nimport { RENDER_CONTEXT } from './contexts/render-context';\nimport type { RenderContext } from './contexts/render-context';\nimport type { AngularRegistry } from './render.types';\nimport { signalStateStore } from './signal-state-store';\nimport type { RenderEvent } from './render-event';\nimport { RenderLifecycleService } from './render-lifecycle.service';\n\n/**\n * Top-level entry point for rendering a json-render spec.\n *\n * Accepts the spec, registry, store, functions, handlers, and loading\n * as inputs. Provides `RENDER_CONTEXT` to child `RenderElementComponent`\n * instances via `viewProviders`.\n *\n * Falls back to `RENDER_CONFIG` (from `provideRender()`) for registry\n * and store defaults when inputs are not provided.\n *\n * @example\n * ```html\n * <render-spec [spec]=\"spec()\" [registry]=\"registry\" [store]=\"store\" />\n * ```\n */\n@Component({\n selector: 'render-spec',\n standalone: true,\n imports: [RenderElementComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n viewProviders: [\n {\n provide: RENDER_CONTEXT,\n useFactory: () => inject(RenderSpecComponent)._context(),\n },\n ],\n template: `\n @if (spec()?.root; as rootKey) {\n <render-element [elementKey]=\"rootKey\" [spec]=\"spec()!\" />\n }\n `,\n})\nexport class RenderSpecComponent implements OnInit {\n readonly spec = input<Spec | null>(null);\n readonly registry = input<AngularRegistry | undefined>(undefined);\n readonly store = input<StateStore | undefined>(undefined);\n readonly functions = input<Record<string, ComputedFunction> | undefined>(undefined);\n readonly handlers = input<Record<string, (params: Record<string, unknown>) => unknown | Promise<unknown>> | undefined>(undefined);\n readonly loading = input<boolean>(false);\n readonly events = output<RenderEvent>();\n\n private readonly config = inject(RENDER_CONFIG, { optional: true });\n private readonly viewRegistry = inject(VIEW_REGISTRY, { optional: true });\n private readonly destroyRef = inject(DestroyRef);\n private readonly lifecycle = inject(RenderLifecycleService, { optional: true });\n\n /** Internal store, lazily created once and reused across spec changes. */\n private _internalStore: StateStore | undefined;\n\n private getOrCreateInternalStore(): StateStore {\n if (!this._internalStore) {\n this._internalStore = signalStateStore(this.spec()?.state ?? {});\n }\n return this._internalStore;\n }\n\n /** Resolved store: input > config > internal (from spec.state). */\n private readonly resolvedStore = computed<StateStore>(() => {\n const inputStore = this.store();\n if (inputStore) return inputStore;\n const configStore = this.config?.store;\n if (configStore) return configStore;\n return this.getOrCreateInternalStore();\n });\n\n /** Resolved registry: input > config > VIEW_REGISTRY token > empty fallback. */\n private readonly resolvedRegistry = computed<AngularRegistry>(() => {\n const inputRegistry = this.registry();\n if (inputRegistry) return inputRegistry;\n const configRegistry = this.config?.registry;\n if (configRegistry) return configRegistry;\n if (this.viewRegistry) return toRenderRegistry(this.viewRegistry);\n // Fallback: empty registry\n return { get: () => undefined, getFallback: () => undefined, names: () => [] };\n });\n\n /** Wraps input handlers to emit RenderHandlerEvent after execution. */\n private readonly wrappedHandlers = computed(() => {\n const inputHandlers = this.handlers() ?? this.config?.handlers;\n if (!inputHandlers) return undefined;\n const wrapped: Record<string, (params: Record<string, unknown>) => unknown | Promise<unknown>> = {};\n for (const [name, handler] of Object.entries(inputHandlers)) {\n wrapped[name] = (params: Record<string, unknown>) => {\n const result = handler(params);\n if (result instanceof Promise) {\n result.then(\n (r) => {\n this.emitTapped({ type: 'handler', action: name, params, result: r });\n },\n () => {\n this.emitTapped({ type: 'handler', action: name, params, result: undefined });\n },\n );\n } else {\n this.emitTapped({ type: 'handler', action: name, params, result });\n }\n return result;\n };\n }\n return wrapped;\n });\n\n /** Emits a RenderEvent through the events output and notifies the\n * lifecycle service (single tap point — all events flow through here). */\n private readonly emitTapped = (event: RenderEvent): void => {\n this.events.emit(event);\n if (!this.lifecycle) return;\n switch (event.type) {\n case 'lifecycle':\n this.lifecycle.notifyLifecycle({\n kind: event.scope,\n type: event.event,\n elementType: event.elementType,\n });\n break;\n case 'stateChange':\n this.lifecycle.notifyStateChange();\n break;\n case 'handler':\n this.lifecycle.notifyHandlerInvoked(event.action);\n break;\n }\n };\n\n /** Emits a RenderEvent through the events output. */\n private readonly emitEvent = (event: RenderEvent) => {\n this.emitTapped(event);\n };\n\n /** The RenderContext provided to children via viewProviders. */\n readonly _context = computed<RenderContext>(() => ({\n registry: this.resolvedRegistry(),\n store: this.resolvedStore(),\n functions: this.functions() ?? this.config?.functions,\n handlers: this.wrappedHandlers(),\n emitEvent: this.emitEvent,\n loading: this.loading(),\n }));\n\n constructor() {\n // Subscribe to store changes and emit state change events\n effect(() => {\n const store = this.resolvedStore();\n const unsub = store.subscribe(() => {\n const snapshot = store.getSnapshot() as Record<string, unknown>;\n this.emitTapped({\n type: 'stateChange',\n path: '/',\n value: snapshot,\n snapshot,\n });\n });\n this.destroyRef.onDestroy(unsub);\n });\n\n this.destroyRef.onDestroy(() => {\n this.emitTapped({ type: 'lifecycle', event: 'destroyed', scope: 'spec' });\n });\n }\n\n ngOnInit(): void {\n this.emitTapped({ type: 'lifecycle', event: 'mounted', scope: 'spec' });\n }\n}\n","// SPDX-License-Identifier: MIT\n\n// Types\nexport type {\n AngularComponentInputs,\n AngularComponentRenderer,\n AngularRegistry,\n RenderConfig,\n} from './lib/render.types';\n\n// Contexts\nexport { RENDER_CONTEXT } from './lib/contexts/render-context';\nexport type { RenderContext } from './lib/contexts/render-context';\nexport { REPEAT_SCOPE } from './lib/contexts/repeat-scope';\nexport type { RepeatScope } from './lib/contexts/repeat-scope';\n\n// Registry\nexport { defineAngularRegistry } from './lib/define-angular-registry';\n\n// State\nexport { signalStateStore } from './lib/signal-state-store';\n\n// Provider\nexport { provideRender, RENDER_CONFIG } from './lib/provide-render';\n\n// Components\nexport { RenderElementComponent } from './lib/render-element.component';\nexport { RenderSpecComponent } from './lib/render-spec.component';\n\n// Views\nexport { views, withViews, overrideViews, withoutViews, toRenderRegistry } from './lib/views';\nexport type { ViewRegistry } from './lib/views';\nexport { provideViews, VIEW_REGISTRY } from './lib/provide-views';\n\n// Events\nexport type {\n RenderEvent,\n RenderHandlerEvent,\n RenderStateChangeEvent,\n RenderLifecycleEvent,\n} from './lib/render-event';\n\n// Lifecycle\nexport { RENDER_LIFECYCLE } from './lib/lifecycle';\nexport type { RenderLifecycle } from './lib/lifecycle';\n\n// Fallback\nexport { DefaultFallbackComponent } from './lib/default-fallback.component';\nexport type { RenderViewEntry } from './lib/render.types';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"threadplane-render.mjs","sources":["../../../../libs/render/src/lib/contexts/render-context.ts","../../../../libs/render/src/lib/contexts/repeat-scope.ts","../../../../libs/render/src/lib/contexts/render-host.ts","../../../../libs/render/src/lib/default-fallback.component.ts","../../../../libs/render/src/lib/define-angular-registry.ts","../../../../libs/render/src/lib/signal-state-store.ts","../../../../libs/render/src/lib/lifecycle.ts","../../../../libs/render/src/lib/render-lifecycle.service.ts","../../../../libs/render/src/lib/provide-render.ts","../../../../libs/render/src/lib/internals/prop-signal.ts","../../../../libs/render/src/lib/internals/element-readiness.ts","../../../../libs/render/src/lib/render-element.component.ts","../../../../libs/render/src/lib/provide-views.ts","../../../../libs/render/src/lib/views.ts","../../../../libs/render/src/lib/internals/guarded-emit.ts","../../../../libs/render/src/lib/render-spec.component.ts","../../../../libs/render/src/public-api.ts","../../../../libs/render/src/threadplane-render.ts"],"sourcesContent":["// SPDX-License-Identifier: MIT\nimport { InjectionToken } from '@angular/core';\nimport type { StateStore, ComputedFunction } from '@json-render/core';\nimport type { AngularRegistry } from '../render.types';\nimport type { RenderEvent } from '../render-event';\n\nexport interface RenderContext {\n registry: AngularRegistry;\n store: StateStore;\n functions?: Record<string, ComputedFunction>;\n handlers?: Record<string, (params: Record<string, unknown>) => unknown | Promise<unknown>>;\n emitEvent?: (event: RenderEvent) => void;\n loading?: boolean;\n}\n\nexport const RENDER_CONTEXT = new InjectionToken<RenderContext>('RENDER_CONTEXT');\n","// SPDX-License-Identifier: MIT\nimport { InjectionToken } from '@angular/core';\n\nexport interface RepeatScope {\n item: unknown;\n index: number;\n basePath: string;\n}\n\nexport const REPEAT_SCOPE = new InjectionToken<RepeatScope>('REPEAT_SCOPE');\n","// SPDX-License-Identifier: MIT\nimport { InjectionToken, inject } from '@angular/core';\n\n/**\n * The element-scoped host a mounted view component talks back through.\n * Agent-agnostic: `result(value)` just means \"this component produced a\n * value\"; the render lib surfaces it as a RenderResultEvent and never\n * interprets it. Provided per-element by RenderElementComponent.\n */\nexport interface RenderHost {\n /** Write a value to the render state store at a JSON-Pointer path. */\n set(path: string, value: unknown): void;\n /** Fire a named event; routed to the element's `on[event]` handlers. */\n emit(event: string, payload?: Record<string, unknown>): void;\n /** Announce this component's result value (e.g. a HITL submission). */\n result(value: unknown): void;\n}\n\nexport const RENDER_HOST = new InjectionToken<RenderHost>('RENDER_HOST');\n\n/** Obtain the element-scoped RenderHost from inside a mounted view component. */\nexport function injectRenderHost(): RenderHost {\n return inject(RENDER_HOST);\n}\n","// SPDX-License-Identifier: MIT\nimport { Component, ChangeDetectionStrategy } from '@angular/core';\n\n@Component({\n selector: 'render-default-fallback',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n styles: [`\n :host { display: block; width: 100%; }\n .render-default-fallback {\n border: 1px solid var(--ngaf-chat-separator, #303540);\n border-radius: 10px;\n padding: 14px;\n background: var(--ngaf-chat-surface-alt, #1a1d23);\n }\n .render-default-fallback__label {\n font-size: 12px;\n color: var(--ngaf-chat-text-muted, #9aa0aa);\n margin-bottom: 10px;\n display: flex;\n align-items: center;\n gap: 6px;\n }\n .render-default-fallback__rows {\n display: flex; flex-direction: column; gap: 8px;\n }\n .render-default-fallback__row {\n height: 10px; border-radius: 5px;\n background: linear-gradient(\n 90deg,\n var(--ngaf-chat-separator, #303540) 0%,\n color-mix(in srgb, var(--ngaf-chat-separator, #303540) 70%, transparent) 50%,\n var(--ngaf-chat-separator, #303540) 100%\n );\n background-size: 200% 100%;\n animation: render-default-fallback-shimmer 1.4s ease-in-out infinite;\n }\n .render-default-fallback__row:nth-child(1) { width: 70%; }\n .render-default-fallback__row:nth-child(2) { width: 90%; }\n .render-default-fallback__row:nth-child(3) { width: 50%; }\n @keyframes render-default-fallback-shimmer {\n 0% { background-position: 200% 0; }\n 100% { background-position: -200% 0; }\n }\n `],\n template: `\n <div class=\"render-default-fallback\" role=\"status\" aria-live=\"polite\">\n <div class=\"render-default-fallback__label\">\n <span aria-hidden=\"true\">✨</span>\n <span>Building UI…</span>\n </div>\n <div class=\"render-default-fallback__rows\">\n <div class=\"render-default-fallback__row\"></div>\n <div class=\"render-default-fallback__row\"></div>\n <div class=\"render-default-fallback__row\"></div>\n </div>\n </div>\n `,\n})\nexport class DefaultFallbackComponent {}\n","// SPDX-License-Identifier: MIT\nimport { Type } from '@angular/core';\nimport type { AngularRegistry, NormalizedEntry, RenderViewEntry } from './render.types';\nimport { DefaultFallbackComponent } from './default-fallback.component';\n\ntype RegistryInput = Record<string, Type<unknown> | RenderViewEntry>;\n\nfunction normalize(entry: Type<unknown> | RenderViewEntry): NormalizedEntry {\n if (typeof entry === 'function') {\n return { component: entry, fallback: DefaultFallbackComponent };\n }\n return {\n component: entry.component,\n fallback: entry.fallback ?? DefaultFallbackComponent,\n schema: entry.schema,\n description: entry.description,\n };\n}\n\n/**\n * Build an {@link AngularRegistry} from a plain object mapping tool-call names\n * to Angular components (or fully specified {@link RenderViewEntry} objects).\n *\n * The returned registry is consumed by both `provideRender` (to drive\n * dynamic component rendering) and `provideChat` (via `renderRegistry`) so\n * that a single `defineAngularRegistry` call wires both layers.\n *\n * **Entry forms**\n * - Bare `Type<unknown>` — the component is paired with the built-in\n * `DefaultFallbackComponent` while its props are still streaming.\n * - `RenderViewEntry` object — lets you supply a custom `fallback` component,\n * an optional Standard Schema (`schema`) used as a mount-readiness gate, and\n * an optional `description` for model-facing tool registration.\n *\n * **Registry accessor**\n * The returned object exposes a single `getEntry(name: string)` accessor that\n * returns the fully-normalized {@link NormalizedEntry} (component + fallback +\n * optional schema + optional description) or `undefined` when the name is not\n * registered. Use `names()` to enumerate all registered names.\n *\n * @param componentMap Object whose keys are tool-call names and whose values\n * are either bare Angular component classes or {@link RenderViewEntry} objects.\n * @returns An {@link AngularRegistry} with `getEntry` and `names` accessors.\n * @example\n * ```ts\n * import { defineAngularRegistry } from '@threadplane/render';\n * import { DayCardComponent } from './day-card.component';\n * import { LoadingSpinnerComponent } from './loading-spinner.component';\n * import { z } from 'zod';\n *\n * export const registry = defineAngularRegistry({\n * // Bare component — uses DefaultFallbackComponent while streaming.\n * summary_card: SummaryCardComponent,\n *\n * // Full entry — custom fallback + schema-gated mounting.\n * day_card: {\n * component: DayCardComponent,\n * fallback: LoadingSpinnerComponent,\n * schema: z.object({ label: z.string(), day: z.number() }),\n * description: 'Renders a single itinerary day card.',\n * },\n * });\n *\n * // Look up a registered entry at runtime:\n * const entry = registry.getEntry('day_card'); // NormalizedEntry | undefined\n * ```\n */\nexport function defineAngularRegistry(componentMap: RegistryInput): AngularRegistry {\n const map = new Map<string, NormalizedEntry>();\n for (const [name, entry] of Object.entries(componentMap)) {\n map.set(name, normalize(entry));\n }\n return {\n getEntry: (name: string) => map.get(name),\n names: () => [...map.keys()],\n };\n}\n","// SPDX-License-Identifier: MIT\nimport { signal } from '@angular/core';\nimport type { StateStore, StateModel } from '@json-render/core';\n\nfunction parsePointer(path: string): string[] {\n if (!path || path === '/') return [];\n return path.split('/').filter((_, i) => i > 0).map(s => s.replace(/~1/g, '/').replace(/~0/g, '~'));\n}\n\nfunction getByPath(obj: unknown, segments: string[]): unknown {\n let current: unknown = obj;\n for (const seg of segments) {\n if (current == null || typeof current !== 'object') return undefined;\n current = (current as Record<string, unknown>)[seg];\n }\n return current;\n}\n\nfunction setByPath(obj: unknown, segments: string[], value: unknown): unknown {\n if (segments.length === 0) return value;\n const [head, ...rest] = segments;\n\n if (Array.isArray(obj)) {\n const index = Number(head);\n const clone = [...obj];\n clone[index] = setByPath(clone[index], rest, value);\n return clone;\n }\n\n const record = (obj != null && typeof obj === 'object')\n ? { ...obj as Record<string, unknown> }\n : {} as Record<string, unknown>;\n record[head] = setByPath(record[head], rest, value);\n return record;\n}\n\nexport function signalStateStore(initialState: StateModel = {}): StateStore {\n const state = signal<StateModel>(initialState);\n const listeners = new Set<() => void>();\n\n function notify(): void {\n for (const listener of listeners) listener();\n }\n\n return {\n get(path: string): unknown {\n return getByPath(state(), parsePointer(path));\n },\n set(path: string, value: unknown): void {\n const segments = parsePointer(path);\n const current = getByPath(state(), segments);\n if (current === value) return;\n state.set(setByPath(state(), segments, value) as StateModel);\n notify();\n },\n update(updates: Record<string, unknown>): void {\n let current = state();\n let changed = false;\n for (const [path, value] of Object.entries(updates)) {\n const segments = parsePointer(path);\n const existing = getByPath(current, segments);\n if (existing !== value) {\n current = setByPath(current, segments, value) as StateModel;\n changed = true;\n }\n }\n if (changed) {\n state.set(current);\n notify();\n }\n },\n getSnapshot(): StateModel {\n return state();\n },\n subscribe(listener: () => void): () => void {\n listeners.add(listener);\n return () => listeners.delete(listener);\n },\n };\n}\n","// SPDX-License-Identifier: MIT\nimport { InjectionToken, Signal } from '@angular/core';\n\nexport interface RenderLifecycle {\n /** First mount event in this render context. Sticky — does not reset. */\n readonly firstMountAt: Signal<{ kind: 'spec' | 'element'; elementType?: string; at: number } | null>;\n /** Total mount count since render context started. */\n readonly mountCount: Signal<number>;\n /** Epoch ms of the most recent mount event. */\n readonly lastMountAt: Signal<number | null>;\n /** Epoch ms of the most recent state-change event. */\n readonly lastStateChangeAt: Signal<number | null>;\n /** Most recent handler invocation. */\n readonly lastHandlerInvokedAt: Signal<{ action: string; at: number } | null>;\n}\n\nexport const RENDER_LIFECYCLE = new InjectionToken<RenderLifecycle>('RENDER_LIFECYCLE');\n","// SPDX-License-Identifier: MIT\nimport { Injectable, signal } from '@angular/core';\nimport type { RenderLifecycle } from './lifecycle';\n\n/**\n * Provided by `provideRender()` — opt-in. Scope follows the consumer's\n * `provideRender` call (root-scoped by default, sub-tree if `provideRender`\n * is in a sub-injector).\n */\n@Injectable()\nexport class RenderLifecycleService implements RenderLifecycle {\n private _firstMountAt = signal<{ kind: 'spec' | 'element'; elementType?: string; at: number } | null>(null);\n private _mountCount = signal(0);\n private _lastMountAt = signal<number | null>(null);\n private _lastStateChangeAt = signal<number | null>(null);\n private _lastHandlerInvokedAt = signal<{ action: string; at: number } | null>(null);\n\n readonly firstMountAt = this._firstMountAt.asReadonly();\n readonly mountCount = this._mountCount.asReadonly();\n readonly lastMountAt = this._lastMountAt.asReadonly();\n readonly lastStateChangeAt = this._lastStateChangeAt.asReadonly();\n readonly lastHandlerInvokedAt = this._lastHandlerInvokedAt.asReadonly();\n\n notifyLifecycle(event: { kind: 'spec' | 'element'; type: 'mounted' | 'destroyed'; elementType?: string }): void {\n if (event.type === 'mounted') {\n const now = Date.now();\n if (this._firstMountAt() === null) {\n this._firstMountAt.set({ kind: event.kind, elementType: event.elementType, at: now });\n }\n this._mountCount.update((c) => c + 1);\n this._lastMountAt.set(now);\n }\n }\n\n notifyStateChange(): void {\n this._lastStateChangeAt.set(Date.now());\n }\n\n notifyHandlerInvoked(action: string): void {\n this._lastHandlerInvokedAt.set({ action, at: Date.now() });\n }\n}\n","// SPDX-License-Identifier: MIT\nimport { InjectionToken, makeEnvironmentProviders } from '@angular/core';\nimport type { RenderConfig } from './render.types';\nimport { RENDER_LIFECYCLE } from './lifecycle';\nimport { RenderLifecycleService } from './render-lifecycle.service';\n\nexport const RENDER_CONFIG = new InjectionToken<RenderConfig>('RENDER_CONFIG');\n\n/**\n * Bootstrap `@threadplane/render` in an Angular application or standalone\n * component tree.\n *\n * Registers the shared {@link RenderConfig} token and the internal\n * `RenderLifecycleService` that coordinates mount/unmount events across\n * dynamically rendered components. Call this once alongside `provideChat` in\n * `bootstrapApplication` (or the root `ApplicationConfig`).\n *\n * @param config Options bag that controls the render feature set:\n * - `registry` — component registry returned by {@link defineAngularRegistry};\n * maps tool-call names to Angular components.\n * - `store` — optional `StateStore` for `\\@json-render/core` state binding.\n * - `functions` — optional map of computed functions available inside specs.\n * - `handlers` — optional map of event handlers triggered by spec actions.\n * @returns An `EnvironmentProviders` value suitable for the `providers` array\n * of `bootstrapApplication` or `ApplicationConfig`.\n * @example\n * ```ts\n * // main.ts\n * import { bootstrapApplication } from '@angular/platform-browser';\n * import { defineAngularRegistry, provideRender } from '@threadplane/render';\n * import { provideChat } from '@threadplane/chat';\n * import { DayCardComponent } from './day-card.component';\n *\n * const registry = defineAngularRegistry({ day_card: DayCardComponent });\n *\n * bootstrapApplication(AppComponent, {\n * providers: [\n * provideRender({ registry }),\n * provideChat({ renderRegistry: registry }),\n * ],\n * });\n * ```\n */\nexport function provideRender(config: RenderConfig) {\n return makeEnvironmentProviders([\n { provide: RENDER_CONFIG, useValue: config },\n RenderLifecycleService,\n { provide: RENDER_LIFECYCLE, useExisting: RenderLifecycleService },\n ]);\n}\n","// SPDX-License-Identifier: MIT\nimport type { StateStore, ComputedFunction, PropResolutionContext } from '@json-render/core';\nimport type { RepeatScope } from '../contexts/repeat-scope';\n\nexport function buildPropResolutionContext(\n store: StateStore,\n repeatScope?: RepeatScope,\n functions?: Record<string, ComputedFunction>,\n): PropResolutionContext {\n const ctx: PropResolutionContext = {\n stateModel: store.getSnapshot(),\n };\n if (repeatScope) {\n ctx.repeatItem = repeatScope.item;\n ctx.repeatIndex = repeatScope.index;\n ctx.repeatBasePath = repeatScope.basePath;\n }\n if (functions) {\n ctx.functions = functions;\n }\n return ctx;\n}\n","// SPDX-License-Identifier: MIT\nimport type { NormalizedEntry } from '../render.types';\n\nfunction isPromise(v: unknown): v is Promise<unknown> {\n return typeof (v as { then?: unknown } | null)?.then === 'function';\n}\n\n/**\n * Decide whether the REAL component may mount, or the fallback skeleton should\n * show. Pure (no Angular, no signals) so it is trivially unit-testable.\n *\n * - Any undefined-valued prop → pending (a json-render state binding is still\n * loading).\n * - A schema-declared contract → pending until the (possibly streaming) props\n * validate against it. SYNC validation only: render is synchronous, so an\n * async (Promise) validate result cannot gate a sync mount and is treated as\n * ready. View schemas should therefore be synchronous (Zod is).\n */\nexport function isElementReady(\n entry: NormalizedEntry | undefined,\n resolvedProps: Record<string, unknown>,\n): boolean {\n for (const v of Object.values(resolvedProps)) {\n if (v === undefined) return false;\n }\n const schema = entry?.schema;\n if (schema) {\n const out = schema['~standard'].validate(resolvedProps);\n if (!isPromise(out) && out.issues !== undefined) return false;\n }\n return true;\n}\n","// SPDX-License-Identifier: MIT\nimport {\n ChangeDetectionStrategy,\n Component,\n computed,\n DestroyRef,\n effect,\n inject,\n Injector,\n input,\n OnInit,\n reflectComponentType,\n runInInjectionContext,\n signal,\n type Signal,\n type Type,\n} from '@angular/core';\nimport { NgComponentOutlet } from '@angular/common';\nimport {\n evaluateVisibility,\n resolveBindings,\n resolveElementProps,\n} from '@json-render/core';\nimport type { Spec, UIElement } from '@json-render/core';\n\nimport { RENDER_CONTEXT } from './contexts/render-context';\nimport { RENDER_HOST, type RenderHost } from './contexts/render-host';\nimport { REPEAT_SCOPE } from './contexts/repeat-scope';\nimport type { RepeatScope } from './contexts/repeat-scope';\nimport { buildPropResolutionContext } from './internals/prop-signal';\nimport { isElementReady } from './internals/element-readiness';\nimport type { AngularComponentRenderer, NormalizedEntry } from './render.types';\n\n/** Cache of declared input names per component class. NgComponentOutlet\n * passes every key in its `inputs` prop to the target; Angular dev mode\n * raises NG0303 for any input the component doesn't declare. We strip\n * undeclared keys before mounting so simple view components (`StatCard`,\n * `Container`, etc.) don't get spammed with framework-only inputs\n * (`bindings`, `emit`, `loading`, `childKeys`, `spec`) they ignore. */\n/** `null` means reflection failed (likely uncompiled / non-component) — in\n * that case we pass inputs through unmodified rather than swallow them.\n * An empty Set means the component genuinely declares zero inputs (e.g. a\n * pure presentational fallback) and ALL keys should be dropped. */\nconst declaredInputsCache = new WeakMap<Type<unknown>, Set<string> | null>();\nfunction getDeclaredInputs(cls: Type<unknown>): Set<string> | null {\n if (declaredInputsCache.has(cls)) return declaredInputsCache.get(cls)!;\n const meta = reflectComponentType(cls);\n const result = meta ? new Set<string>(meta.inputs.map(i => i.templateName)) : null;\n declaredInputsCache.set(cls, result);\n return result;\n}\nfunction filterInputsForClass(\n cls: Type<unknown> | null,\n inputs: Record<string, unknown>,\n): Record<string, unknown> {\n if (!cls) return inputs;\n const declared = getDeclaredInputs(cls);\n if (declared === null) return inputs;\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(inputs)) {\n if (declared.has(k)) out[k] = v;\n }\n return out;\n}\n\n/**\n * Recursive element renderer.\n *\n * For each element key it:\n * 1. Looks up the UIElement from spec.elements\n * 2. Resolves the component class from the registry\n * 3. Evaluates visibility\n * 4. Resolves prop expressions and bindings\n * 5. Renders via NgComponentOutlet with resolved inputs\n *\n * For elements with `repeat`, it iterates over the state array,\n * creating a child Injector with RepeatScope for each item.\n */\n@Component({\n selector: 'render-element',\n standalone: true,\n imports: [NgComponentOutlet],\n changeDetection: ChangeDetectionStrategy.OnPush,\n providers: [\n { provide: RENDER_HOST, useFactory: (el: RenderElementComponent) => el.host, deps: [RenderElementComponent] },\n ],\n template: `\n @if (!element()?.repeat) {\n @if (visible()) {\n <ng-container\n *ngComponentOutlet=\"mountClass(); inputs: filteredResolvedInputs(); injector: parentInjector\"\n />\n }\n } @else {\n @for (repeatInjector of repeatInjectors(); track $index) {\n <ng-container\n *ngComponentOutlet=\"mountClass(); inputs: filteredRepeatInputs()[$index]; injector: repeatInjector\"\n />\n }\n }\n `,\n})\nexport class RenderElementComponent implements OnInit {\n readonly elementKey = input.required<string>();\n readonly spec = input.required<Spec>();\n\n private readonly ctx = inject(RENDER_CONTEXT);\n private readonly repeatScope = inject(REPEAT_SCOPE, { optional: true });\n readonly parentInjector = inject(Injector);\n private readonly destroyRef = inject(DestroyRef);\n\n private destroyed = false;\n\n constructor() {\n this.destroyRef.onDestroy(() => {\n const el = this.element();\n if (el && (el as any)['lifecycle'] && this.ctx.emitEvent) {\n this.ctx.emitEvent({\n type: 'lifecycle',\n event: 'destroyed',\n scope: 'element',\n elementKey: this.elementKey(),\n elementType: el.type,\n });\n }\n this.destroyed = true;\n });\n\n // Latch mountedReal=true once the real component is selected. Lives in\n // an effect (not the computed) because Angular forbids signal writes\n // inside computed — they're for derivation only. Effects are the\n // idiomatic place for \"signal change → signal write\" side effects.\n effect(() => {\n if (this.mountedReal()) return;\n const el = this.element();\n if (!el) return;\n // Only latch when notReady is false AND a real component is registered.\n if (!this.notReady() && this.entry()?.component) {\n this.mountedReal.set(true);\n }\n });\n }\n\n ngOnInit(): void {\n const el = this.element();\n if (el && (el as any)['lifecycle'] && this.ctx.emitEvent) {\n this.ctx.emitEvent({\n type: 'lifecycle',\n event: 'mounted',\n scope: 'element',\n elementKey: this.elementKey(),\n elementType: el.type,\n });\n }\n }\n\n /** The UIElement definition from the spec. Only propagates when reference changes. */\n readonly element: Signal<UIElement | undefined> = computed(\n () => this.spec()?.elements?.[this.elementKey()],\n { equal: Object.is },\n );\n\n /** The full normalized registry entry for this element type. */\n readonly entry = computed<NormalizedEntry | undefined>(() => {\n const el = this.element();\n return el ? this.ctx.registry.getEntry(el.type) : undefined;\n });\n\n /** The Angular component class for this element type. */\n readonly componentClass = computed<AngularComponentRenderer | null>(() => {\n const el = this.element();\n if (!el) return null;\n return this.entry()?.component ?? null;\n });\n\n /** Prop resolution context built from store + repeat scope. */\n private readonly propCtx = computed(() =>\n buildPropResolutionContext(\n this.ctx.store,\n this.repeatScope ?? undefined,\n this.ctx.functions,\n ),\n );\n\n /** Once real mounts, never revert to fallback even if a state-bound\n * prop later becomes undefined. Per-instance monotonic gate. */\n private readonly mountedReal = signal<boolean>(false);\n\n /** True when the element is not yet ready to mount the real component.\n * Delegates to `isElementReady` which checks:\n * 1. Any undefined-valued resolved prop (state binding still loading).\n * 2. A sync Standard-Schema gate if the registry entry declares a schema.\n * Framework-injected keys (bindings, emit, loading, childKeys, spec) are\n * excluded — only consumer-resolved props matter for readiness. */\n readonly notReady = computed<boolean>(() => {\n if (this.mountedReal()) return false;\n const el = this.element();\n if (!el || !el.props) return false;\n const resolved = resolveElementProps(el.props, this.propCtx());\n return !isElementReady(this.entry(), resolved);\n });\n\n /** Picks fallback or real based on notReady. The mountedReal latch is\n * driven by a constructor effect (not this computed) — Angular forbids\n * signal writes inside computed. */\n readonly mountClass = computed<AngularComponentRenderer | null>(() => {\n const el = this.element();\n if (!el) return null;\n const real = this.entry()?.component ?? null;\n if (this.notReady()) {\n return this.entry()?.fallback ?? null;\n }\n return real;\n });\n\n /** Whether the element is visible (non-repeat path). */\n readonly visible = computed(() => {\n const el = this.element();\n if (!el) return false;\n if (this.mountClass() === null) return false;\n return evaluateVisibility(el.visible, this.propCtx());\n });\n\n /** Invokes the element's `on[event]` handler bindings. */\n private invokeHandlers(event: string, payload?: Record<string, unknown>): void {\n const el = this.element();\n if (!el?.on) return;\n const binding = el.on[event];\n if (!binding) return;\n const bindings = Array.isArray(binding) ? binding : [binding];\n for (const b of bindings) {\n const handler = this.ctx.handlers?.[b.action];\n if (handler) {\n const params = { ...(b.params as Record<string, unknown> ?? {}), ...(payload ?? {}) };\n runInInjectionContext(this.parentInjector, () => handler(params));\n }\n }\n }\n\n /** Element-scoped host injected by mounted view components via\n * injectRenderHost(). `set` writes the store; `emit` routes element\n * handlers; `result` surfaces a RenderResultEvent for this element. */\n readonly host: RenderHost = {\n set: (path: string, value: unknown) => { if (this.destroyed) return; this.ctx.store?.set(path, value); },\n emit: (event: string, payload?: Record<string, unknown>) => { if (this.destroyed) return; this.invokeHandlers(event, payload); },\n result: (value: unknown) => { if (this.destroyed) return; this.ctx.emitEvent?.({ type: 'result', value, elementKey: this.elementKey() }); },\n };\n\n /** Emit function passed to mounted view components as the `emit` framework\n * input. Delegates to the element's `on[event]` handler bindings. */\n private readonly emitFn = (event: string) => {\n this.invokeHandlers(event);\n };\n\n /** Resolved inputs for non-repeat elements. */\n readonly resolvedInputs = computed(() => {\n const el = this.element();\n if (!el) return {};\n const ctx = this.propCtx();\n const resolved = resolveElementProps(el.props ?? {}, ctx);\n const bindings = resolveBindings(el.props ?? {}, ctx);\n return {\n ...resolved,\n bindings,\n emit: this.emitFn,\n loading: this.ctx.loading ?? false,\n childKeys: el.children ?? [],\n spec: this.spec(),\n };\n });\n\n /** `resolvedInputs` filtered down to keys the target component actually\n * declares — silences NG0303 dev-mode warnings from framework-only\n * inputs (bindings/emit/loading/childKeys/spec) passed to simple view\n * components that don't declare them. */\n readonly filteredResolvedInputs = computed(() =>\n filterInputsForClass(this.mountClass() as Type<unknown> | null, this.resolvedInputs()),\n );\n\n // --- Repeat support ---\n\n /** Items from the state array for repeat elements. */\n private readonly repeatItems = computed<unknown[]>(() => {\n const el = this.element();\n if (!el?.repeat) return [];\n const items = this.ctx.store.get(el.repeat.statePath);\n return Array.isArray(items) ? items : [];\n });\n\n /** One RepeatScope per repeat item, shared between injectors and inputs. */\n private readonly repeatScopes = computed(() => {\n const el = this.element();\n if (!el?.repeat) return [];\n return this.repeatItems().map((item, index) => ({\n item,\n index,\n basePath: `${el.repeat!.statePath}/${index}`,\n } satisfies RepeatScope));\n });\n\n /** One child Injector per repeat item, providing RepeatScope. */\n readonly repeatInjectors = computed(() => {\n return this.repeatScopes().map(scope =>\n Injector.create({\n providers: [{ provide: REPEAT_SCOPE, useValue: scope }],\n parent: this.parentInjector,\n }),\n );\n });\n\n /** Resolved inputs for each repeat item. */\n readonly repeatInputs = computed(() => {\n const el = this.element();\n if (!el?.repeat) return [];\n return this.repeatScopes().map(scope => {\n const ctx = buildPropResolutionContext(\n this.ctx.store,\n scope,\n this.ctx.functions,\n );\n const resolved = resolveElementProps(el.props ?? {}, ctx);\n const bindings = resolveBindings(el.props ?? {}, ctx);\n return {\n ...resolved,\n bindings,\n emit: this.emitFn,\n loading: this.ctx.loading ?? false,\n childKeys: el.children ?? [],\n spec: this.spec(),\n };\n });\n });\n\n /** `repeatInputs` filtered per-item to declared component inputs. */\n readonly filteredRepeatInputs = computed(() => {\n const cls = this.mountClass() as Type<unknown> | null;\n return this.repeatInputs().map(inputs => filterInputsForClass(cls, inputs));\n });\n}\n","// SPDX-License-Identifier: MIT\nimport { InjectionToken, makeEnvironmentProviders } from '@angular/core';\nimport type { ViewRegistry } from './views';\n\nexport const VIEW_REGISTRY = new InjectionToken<ViewRegistry>('VIEW_REGISTRY');\n\nexport function provideViews(registry: ViewRegistry) {\n return makeEnvironmentProviders([\n { provide: VIEW_REGISTRY, useValue: registry },\n ]);\n}\n","// SPDX-License-Identifier: MIT\nimport { Type } from '@angular/core';\nimport type { AngularRegistry, RenderViewEntry } from './render.types';\nimport { defineAngularRegistry } from './define-angular-registry';\n\n/**\n * A registry of view components available for generative UI rendering.\n * Each entry is either a bare component Type (legacy shape) or a\n * `RenderViewEntry` { component, fallback? }.\n */\nexport type ViewRegistry = Readonly<Record<string, Type<unknown> | RenderViewEntry>>;\n\n/**\n * Creates a view registry from a name → component map.\n */\nexport function views(map: Record<string, Type<unknown> | RenderViewEntry>): ViewRegistry {\n return Object.freeze({ ...map });\n}\n\n/**\n * Adds views to a registry without overwriting existing entries.\n * New keys are added; keys that already exist in `base` are preserved.\n */\nexport function withViews(\n base: ViewRegistry,\n additions: Record<string, Type<unknown> | RenderViewEntry>,\n): ViewRegistry {\n return Object.freeze({ ...additions, ...base });\n}\n\n/**\n * Replaces views in a registry. Keys in `overrides` win over `base`.\n * Use this to swap an existing renderer; use `withViews` to add NEW\n * node types without touching existing entries.\n */\nexport function overrideViews(\n base: ViewRegistry,\n overrides: Record<string, Type<unknown> | RenderViewEntry>,\n): ViewRegistry {\n return Object.freeze({ ...base, ...overrides });\n}\n\n/**\n * Removes views from a registry by name.\n */\nexport function withoutViews(\n base: ViewRegistry,\n ...names: string[]\n): ViewRegistry {\n const result = { ...base };\n for (const name of names) delete result[name];\n return Object.freeze(result);\n}\n\n/**\n * Converts a ViewRegistry to an AngularRegistry for use with RenderSpecComponent.\n */\nexport function toRenderRegistry(registry: ViewRegistry): AngularRegistry {\n return defineAngularRegistry(registry);\n}\n","// SPDX-License-Identifier: MIT\n/**\n * Wraps an emit function so it becomes a no-op once `isDestroyed()` returns\n * true. Prevents Angular NG0953 (\"emit on a destroyed OutputRef\") when a late\n * event (e.g. an ask client-tool resolving during teardown) tries to fire\n * after the owning component has been destroyed.\n */\nexport function makeGuardedEmit<E>(\n emit: (event: E) => void,\n isDestroyed: () => boolean,\n): (event: E) => void {\n return (event: E) => {\n if (isDestroyed()) return;\n emit(event);\n };\n}\n","// SPDX-License-Identifier: MIT\nimport {\n ChangeDetectionStrategy,\n Component,\n computed,\n DestroyRef,\n effect,\n inject,\n input,\n OnInit,\n output,\n} from '@angular/core';\nimport type { ComputedFunction, Spec, StateStore } from '@json-render/core';\n\nimport { RenderElementComponent } from './render-element.component';\nimport { RENDER_CONFIG } from './provide-render';\nimport { VIEW_REGISTRY } from './provide-views';\nimport { toRenderRegistry } from './views';\nimport { RENDER_CONTEXT } from './contexts/render-context';\nimport type { RenderContext } from './contexts/render-context';\nimport type { AngularRegistry } from './render.types';\nimport { signalStateStore } from './signal-state-store';\nimport type { RenderEvent } from './render-event';\nimport { RenderLifecycleService } from './render-lifecycle.service';\nimport { makeGuardedEmit } from './internals/guarded-emit';\n\n/**\n * Top-level entry point for rendering a json-render spec.\n *\n * Accepts the spec, registry, store, functions, handlers, and loading\n * as inputs. Provides `RENDER_CONTEXT` to child `RenderElementComponent`\n * instances via `viewProviders`.\n *\n * Falls back to `RENDER_CONFIG` (from `provideRender()`) for registry\n * and store defaults when inputs are not provided.\n *\n * @example\n * ```html\n * <render-spec [spec]=\"spec()\" [registry]=\"registry\" [store]=\"store\" />\n * ```\n */\n@Component({\n selector: 'render-spec',\n standalone: true,\n imports: [RenderElementComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n viewProviders: [\n {\n provide: RENDER_CONTEXT,\n useFactory: () => inject(RenderSpecComponent)._context(),\n },\n ],\n template: `\n @if (spec()?.root; as rootKey) {\n <render-element [elementKey]=\"rootKey\" [spec]=\"spec()!\" />\n }\n `,\n})\nexport class RenderSpecComponent implements OnInit {\n readonly spec = input<Spec | null>(null);\n readonly registry = input<AngularRegistry | undefined>(undefined);\n readonly store = input<StateStore | undefined>(undefined);\n readonly functions = input<Record<string, ComputedFunction> | undefined>(undefined);\n readonly handlers = input<Record<string, (params: Record<string, unknown>) => unknown | Promise<unknown>> | undefined>(undefined);\n readonly loading = input<boolean>(false);\n readonly events = output<RenderEvent>();\n\n private readonly config = inject(RENDER_CONFIG, { optional: true });\n private readonly viewRegistry = inject(VIEW_REGISTRY, { optional: true });\n private readonly destroyRef = inject(DestroyRef);\n private readonly lifecycle = inject(RenderLifecycleService, { optional: true });\n\n private destroyed = false;\n\n /** Guarded OutputRef emit — no-ops after destroy (NG0953). */\n private readonly guardedEmit = makeGuardedEmit<RenderEvent>(\n (e) => this.events.emit(e),\n () => this.destroyed,\n );\n\n /** Internal store, lazily created once and reused across spec changes. */\n private _internalStore: StateStore | undefined;\n\n private getOrCreateInternalStore(): StateStore {\n if (!this._internalStore) {\n this._internalStore = signalStateStore(this.spec()?.state ?? {});\n }\n return this._internalStore;\n }\n\n /** Resolved store: input > config > internal (from spec.state). */\n private readonly resolvedStore = computed<StateStore>(() => {\n const inputStore = this.store();\n if (inputStore) return inputStore;\n const configStore = this.config?.store;\n if (configStore) return configStore;\n return this.getOrCreateInternalStore();\n });\n\n /** Resolved registry: input > config > VIEW_REGISTRY token > empty fallback. */\n private readonly resolvedRegistry = computed<AngularRegistry>(() => {\n const inputRegistry = this.registry();\n if (inputRegistry) return inputRegistry;\n const configRegistry = this.config?.registry;\n if (configRegistry) return configRegistry;\n if (this.viewRegistry) return toRenderRegistry(this.viewRegistry);\n // Fallback: empty registry\n return { getEntry: () => undefined, names: () => [] };\n });\n\n /** Wraps input handlers to emit RenderHandlerEvent after execution. */\n private readonly wrappedHandlers = computed(() => {\n const inputHandlers = this.handlers() ?? this.config?.handlers;\n if (!inputHandlers) return undefined;\n const wrapped: Record<string, (params: Record<string, unknown>) => unknown | Promise<unknown>> = {};\n for (const [name, handler] of Object.entries(inputHandlers)) {\n wrapped[name] = (params: Record<string, unknown>) => {\n const result = handler(params);\n if (result instanceof Promise) {\n result.then(\n (r) => {\n this.emitTapped({ type: 'handler', action: name, params, result: r });\n },\n () => {\n this.emitTapped({ type: 'handler', action: name, params, result: undefined });\n },\n );\n } else {\n this.emitTapped({ type: 'handler', action: name, params, result });\n }\n return result;\n };\n }\n return wrapped;\n });\n\n /** Emits a RenderEvent through the events output and notifies the\n * lifecycle service (single tap point — all events flow through here). */\n private readonly emitTapped = (event: RenderEvent): void => {\n this.guardedEmit(event);\n if (this.destroyed || !this.lifecycle) return;\n switch (event.type) {\n case 'lifecycle':\n this.lifecycle.notifyLifecycle({\n kind: event.scope,\n type: event.event,\n elementType: event.elementType,\n });\n break;\n case 'stateChange':\n this.lifecycle.notifyStateChange();\n break;\n case 'handler':\n this.lifecycle.notifyHandlerInvoked(event.action);\n break;\n }\n };\n\n /** Emits a RenderEvent through the events output. */\n private readonly emitEvent = (event: RenderEvent) => {\n this.emitTapped(event);\n };\n\n /** The RenderContext provided to children via viewProviders. */\n readonly _context = computed<RenderContext>(() => ({\n registry: this.resolvedRegistry(),\n store: this.resolvedStore(),\n functions: this.functions() ?? this.config?.functions,\n handlers: this.wrappedHandlers(),\n emitEvent: this.emitEvent,\n loading: this.loading(),\n }));\n\n constructor() {\n // Subscribe to store changes and emit state change events\n effect(() => {\n const store = this.resolvedStore();\n const unsub = store.subscribe(() => {\n const snapshot = store.getSnapshot() as Record<string, unknown>;\n this.emitTapped({\n type: 'stateChange',\n path: '/',\n value: snapshot,\n snapshot,\n });\n });\n this.destroyRef.onDestroy(unsub);\n });\n\n this.destroyRef.onDestroy(() => {\n this.emitTapped({ type: 'lifecycle', event: 'destroyed', scope: 'spec' });\n this.destroyed = true;\n });\n }\n\n ngOnInit(): void {\n this.emitTapped({ type: 'lifecycle', event: 'mounted', scope: 'spec' });\n }\n}\n","// SPDX-License-Identifier: MIT\n\n// Types\nexport type {\n AngularComponentInputs,\n AngularComponentRenderer,\n AngularRegistry,\n RenderConfig,\n} from './lib/render.types';\nexport type {\n StandardSchemaV1,\n StandardSchemaInferInput,\n StandardSchemaInferOutput,\n} from './lib/standard-schema';\n\n// Contexts\nexport { RENDER_CONTEXT } from './lib/contexts/render-context';\nexport type { RenderContext } from './lib/contexts/render-context';\nexport { REPEAT_SCOPE } from './lib/contexts/repeat-scope';\nexport type { RepeatScope } from './lib/contexts/repeat-scope';\nexport { RENDER_HOST, injectRenderHost } from './lib/contexts/render-host';\nexport type { RenderHost } from './lib/contexts/render-host';\n\n// Registry\nexport { defineAngularRegistry } from './lib/define-angular-registry';\n\n// State\nexport { signalStateStore } from './lib/signal-state-store';\n\n// Provider\nexport { provideRender, RENDER_CONFIG } from './lib/provide-render';\n\n// Components\nexport { RenderElementComponent } from './lib/render-element.component';\nexport { RenderSpecComponent } from './lib/render-spec.component';\n\n// Views\nexport { views, withViews, overrideViews, withoutViews, toRenderRegistry } from './lib/views';\nexport type { ViewRegistry } from './lib/views';\nexport { provideViews, VIEW_REGISTRY } from './lib/provide-views';\n\n// Events\nexport type {\n RenderEvent,\n RenderHandlerEvent,\n RenderStateChangeEvent,\n RenderLifecycleEvent,\n RenderResultEvent,\n} from './lib/render-event';\n\n// Lifecycle\nexport { RENDER_LIFECYCLE } from './lib/lifecycle';\nexport type { RenderLifecycle } from './lib/lifecycle';\n\n// Fallback\nexport { DefaultFallbackComponent } from './lib/default-fallback.component';\nexport type { RenderViewEntry } from './lib/render.types';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -3,6 +3,37 @@ import { Type, InjectionToken, OnInit, Injector, Signal } from '@angular/core';
|
|
|
3
3
|
import { Spec, StateStore, ComputedFunction, StateModel, UIElement } from '@json-render/core';
|
|
4
4
|
import * as _threadplane_render from '@threadplane/render';
|
|
5
5
|
|
|
6
|
+
interface StandardSchemaV1<Input = unknown, Output = Input> {
|
|
7
|
+
readonly '~standard': StandardSchemaProps<Input, Output>;
|
|
8
|
+
}
|
|
9
|
+
interface StandardSchemaProps<Input = unknown, Output = Input> {
|
|
10
|
+
readonly version: 1;
|
|
11
|
+
readonly vendor: string;
|
|
12
|
+
readonly validate: (value: unknown) => StandardSchemaResult<Output> | Promise<StandardSchemaResult<Output>>;
|
|
13
|
+
readonly types?: StandardSchemaTypes<Input, Output> | undefined;
|
|
14
|
+
}
|
|
15
|
+
type StandardSchemaResult<Output> = StandardSchemaSuccessResult<Output> | StandardSchemaFailureResult;
|
|
16
|
+
interface StandardSchemaSuccessResult<Output> {
|
|
17
|
+
readonly value: Output;
|
|
18
|
+
readonly issues?: undefined;
|
|
19
|
+
}
|
|
20
|
+
interface StandardSchemaFailureResult {
|
|
21
|
+
readonly issues: ReadonlyArray<StandardSchemaIssue>;
|
|
22
|
+
}
|
|
23
|
+
interface StandardSchemaIssue {
|
|
24
|
+
readonly message: string;
|
|
25
|
+
readonly path?: ReadonlyArray<PropertyKey | StandardSchemaPathSegment> | undefined;
|
|
26
|
+
}
|
|
27
|
+
interface StandardSchemaPathSegment {
|
|
28
|
+
readonly key: PropertyKey;
|
|
29
|
+
}
|
|
30
|
+
interface StandardSchemaTypes<Input = unknown, Output = Input> {
|
|
31
|
+
readonly input: Input;
|
|
32
|
+
readonly output: Output;
|
|
33
|
+
}
|
|
34
|
+
type StandardSchemaInferInput<Schema extends StandardSchemaV1> = NonNullable<Schema['~standard']['types']>['input'];
|
|
35
|
+
type StandardSchemaInferOutput<Schema extends StandardSchemaV1> = NonNullable<Schema['~standard']['types']>['output'];
|
|
36
|
+
|
|
6
37
|
interface AngularComponentInputs {
|
|
7
38
|
/** Two-way binding paths: prop name → absolute state path */
|
|
8
39
|
bindings?: Record<string, string>;
|
|
@@ -29,15 +60,28 @@ type AngularComponentRenderer = Type<unknown>;
|
|
|
29
60
|
interface RenderViewEntry {
|
|
30
61
|
component: Type<unknown>;
|
|
31
62
|
fallback?: Type<unknown>;
|
|
63
|
+
/** Optional props contract for this component (Zod/Valibot/ArkType via
|
|
64
|
+
* Standard Schema). Enforced as a MOUNT-READINESS GATE: while a streaming
|
|
65
|
+
* tool call's props do not yet validate against this schema, the element's
|
|
66
|
+
* fallback is shown instead of the real component (sync validation only).
|
|
67
|
+
* Consumers (e.g. client-tools) also read it to advertise the component
|
|
68
|
+
* to a model and to validate incoming props. */
|
|
69
|
+
schema?: StandardSchemaV1;
|
|
70
|
+
/** Optional human/model-facing description of what this component renders. */
|
|
71
|
+
description?: string;
|
|
72
|
+
}
|
|
73
|
+
/** A fully-normalized registry entry: real component + a guaranteed fallback,
|
|
74
|
+
* plus the optional props schema (mount-readiness gate) and description. */
|
|
75
|
+
interface NormalizedEntry {
|
|
76
|
+
component: Type<unknown>;
|
|
77
|
+
fallback: Type<unknown>;
|
|
78
|
+
schema?: StandardSchemaV1;
|
|
79
|
+
description?: string;
|
|
32
80
|
}
|
|
33
81
|
interface AngularRegistry {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
* lib's default fallback if the entry omits one, OR undefined if
|
|
38
|
-
* the name is not registered.
|
|
39
|
-
*/
|
|
40
|
-
getFallback(name: string): AngularComponentRenderer | undefined;
|
|
82
|
+
/** The full normalized entry for a registered name, or undefined. The single
|
|
83
|
+
* accessor — component, fallback, schema, and description all hang off it. */
|
|
84
|
+
getEntry(name: string): NormalizedEntry | undefined;
|
|
41
85
|
names(): string[];
|
|
42
86
|
}
|
|
43
87
|
interface RenderConfig {
|
|
@@ -66,7 +110,12 @@ interface RenderLifecycleEvent {
|
|
|
66
110
|
readonly elementKey?: string;
|
|
67
111
|
readonly elementType?: string;
|
|
68
112
|
}
|
|
69
|
-
|
|
113
|
+
interface RenderResultEvent {
|
|
114
|
+
readonly type: 'result';
|
|
115
|
+
readonly value: unknown;
|
|
116
|
+
readonly elementKey?: string;
|
|
117
|
+
}
|
|
118
|
+
type RenderEvent = RenderHandlerEvent | RenderStateChangeEvent | RenderLifecycleEvent | RenderResultEvent;
|
|
70
119
|
|
|
71
120
|
interface RenderContext {
|
|
72
121
|
registry: AngularRegistry;
|
|
@@ -85,12 +134,113 @@ interface RepeatScope {
|
|
|
85
134
|
}
|
|
86
135
|
declare const REPEAT_SCOPE: InjectionToken<RepeatScope>;
|
|
87
136
|
|
|
137
|
+
/**
|
|
138
|
+
* The element-scoped host a mounted view component talks back through.
|
|
139
|
+
* Agent-agnostic: `result(value)` just means "this component produced a
|
|
140
|
+
* value"; the render lib surfaces it as a RenderResultEvent and never
|
|
141
|
+
* interprets it. Provided per-element by RenderElementComponent.
|
|
142
|
+
*/
|
|
143
|
+
interface RenderHost {
|
|
144
|
+
/** Write a value to the render state store at a JSON-Pointer path. */
|
|
145
|
+
set(path: string, value: unknown): void;
|
|
146
|
+
/** Fire a named event; routed to the element's `on[event]` handlers. */
|
|
147
|
+
emit(event: string, payload?: Record<string, unknown>): void;
|
|
148
|
+
/** Announce this component's result value (e.g. a HITL submission). */
|
|
149
|
+
result(value: unknown): void;
|
|
150
|
+
}
|
|
151
|
+
declare const RENDER_HOST: InjectionToken<RenderHost>;
|
|
152
|
+
/** Obtain the element-scoped RenderHost from inside a mounted view component. */
|
|
153
|
+
declare function injectRenderHost(): RenderHost;
|
|
154
|
+
|
|
88
155
|
type RegistryInput = Record<string, Type<unknown> | RenderViewEntry>;
|
|
156
|
+
/**
|
|
157
|
+
* Build an {@link AngularRegistry} from a plain object mapping tool-call names
|
|
158
|
+
* to Angular components (or fully specified {@link RenderViewEntry} objects).
|
|
159
|
+
*
|
|
160
|
+
* The returned registry is consumed by both `provideRender` (to drive
|
|
161
|
+
* dynamic component rendering) and `provideChat` (via `renderRegistry`) so
|
|
162
|
+
* that a single `defineAngularRegistry` call wires both layers.
|
|
163
|
+
*
|
|
164
|
+
* **Entry forms**
|
|
165
|
+
* - Bare `Type<unknown>` — the component is paired with the built-in
|
|
166
|
+
* `DefaultFallbackComponent` while its props are still streaming.
|
|
167
|
+
* - `RenderViewEntry` object — lets you supply a custom `fallback` component,
|
|
168
|
+
* an optional Standard Schema (`schema`) used as a mount-readiness gate, and
|
|
169
|
+
* an optional `description` for model-facing tool registration.
|
|
170
|
+
*
|
|
171
|
+
* **Registry accessor**
|
|
172
|
+
* The returned object exposes a single `getEntry(name: string)` accessor that
|
|
173
|
+
* returns the fully-normalized {@link NormalizedEntry} (component + fallback +
|
|
174
|
+
* optional schema + optional description) or `undefined` when the name is not
|
|
175
|
+
* registered. Use `names()` to enumerate all registered names.
|
|
176
|
+
*
|
|
177
|
+
* @param componentMap Object whose keys are tool-call names and whose values
|
|
178
|
+
* are either bare Angular component classes or {@link RenderViewEntry} objects.
|
|
179
|
+
* @returns An {@link AngularRegistry} with `getEntry` and `names` accessors.
|
|
180
|
+
* @example
|
|
181
|
+
* ```ts
|
|
182
|
+
* import { defineAngularRegistry } from '@threadplane/render';
|
|
183
|
+
* import { DayCardComponent } from './day-card.component';
|
|
184
|
+
* import { LoadingSpinnerComponent } from './loading-spinner.component';
|
|
185
|
+
* import { z } from 'zod';
|
|
186
|
+
*
|
|
187
|
+
* export const registry = defineAngularRegistry({
|
|
188
|
+
* // Bare component — uses DefaultFallbackComponent while streaming.
|
|
189
|
+
* summary_card: SummaryCardComponent,
|
|
190
|
+
*
|
|
191
|
+
* // Full entry — custom fallback + schema-gated mounting.
|
|
192
|
+
* day_card: {
|
|
193
|
+
* component: DayCardComponent,
|
|
194
|
+
* fallback: LoadingSpinnerComponent,
|
|
195
|
+
* schema: z.object({ label: z.string(), day: z.number() }),
|
|
196
|
+
* description: 'Renders a single itinerary day card.',
|
|
197
|
+
* },
|
|
198
|
+
* });
|
|
199
|
+
*
|
|
200
|
+
* // Look up a registered entry at runtime:
|
|
201
|
+
* const entry = registry.getEntry('day_card'); // NormalizedEntry | undefined
|
|
202
|
+
* ```
|
|
203
|
+
*/
|
|
89
204
|
declare function defineAngularRegistry(componentMap: RegistryInput): AngularRegistry;
|
|
90
205
|
|
|
91
206
|
declare function signalStateStore(initialState?: StateModel): StateStore;
|
|
92
207
|
|
|
93
208
|
declare const RENDER_CONFIG: InjectionToken<RenderConfig>;
|
|
209
|
+
/**
|
|
210
|
+
* Bootstrap `@threadplane/render` in an Angular application or standalone
|
|
211
|
+
* component tree.
|
|
212
|
+
*
|
|
213
|
+
* Registers the shared {@link RenderConfig} token and the internal
|
|
214
|
+
* `RenderLifecycleService` that coordinates mount/unmount events across
|
|
215
|
+
* dynamically rendered components. Call this once alongside `provideChat` in
|
|
216
|
+
* `bootstrapApplication` (or the root `ApplicationConfig`).
|
|
217
|
+
*
|
|
218
|
+
* @param config Options bag that controls the render feature set:
|
|
219
|
+
* - `registry` — component registry returned by {@link defineAngularRegistry};
|
|
220
|
+
* maps tool-call names to Angular components.
|
|
221
|
+
* - `store` — optional `StateStore` for `\@json-render/core` state binding.
|
|
222
|
+
* - `functions` — optional map of computed functions available inside specs.
|
|
223
|
+
* - `handlers` — optional map of event handlers triggered by spec actions.
|
|
224
|
+
* @returns An `EnvironmentProviders` value suitable for the `providers` array
|
|
225
|
+
* of `bootstrapApplication` or `ApplicationConfig`.
|
|
226
|
+
* @example
|
|
227
|
+
* ```ts
|
|
228
|
+
* // main.ts
|
|
229
|
+
* import { bootstrapApplication } from '@angular/platform-browser';
|
|
230
|
+
* import { defineAngularRegistry, provideRender } from '@threadplane/render';
|
|
231
|
+
* import { provideChat } from '@threadplane/chat';
|
|
232
|
+
* import { DayCardComponent } from './day-card.component';
|
|
233
|
+
*
|
|
234
|
+
* const registry = defineAngularRegistry({ day_card: DayCardComponent });
|
|
235
|
+
*
|
|
236
|
+
* bootstrapApplication(AppComponent, {
|
|
237
|
+
* providers: [
|
|
238
|
+
* provideRender({ registry }),
|
|
239
|
+
* provideChat({ renderRegistry: registry }),
|
|
240
|
+
* ],
|
|
241
|
+
* });
|
|
242
|
+
* ```
|
|
243
|
+
*/
|
|
94
244
|
declare function provideRender(config: RenderConfig): _angular_core.EnvironmentProviders;
|
|
95
245
|
|
|
96
246
|
/**
|
|
@@ -113,10 +263,13 @@ declare class RenderElementComponent implements OnInit {
|
|
|
113
263
|
private readonly repeatScope;
|
|
114
264
|
readonly parentInjector: Injector;
|
|
115
265
|
private readonly destroyRef;
|
|
266
|
+
private destroyed;
|
|
116
267
|
constructor();
|
|
117
268
|
ngOnInit(): void;
|
|
118
269
|
/** The UIElement definition from the spec. Only propagates when reference changes. */
|
|
119
270
|
readonly element: Signal<UIElement | undefined>;
|
|
271
|
+
/** The full normalized registry entry for this element type. */
|
|
272
|
+
readonly entry: Signal<NormalizedEntry | undefined>;
|
|
120
273
|
/** The Angular component class for this element type. */
|
|
121
274
|
readonly componentClass: Signal<AngularComponentRenderer | null>;
|
|
122
275
|
/** Prop resolution context built from store + repeat scope. */
|
|
@@ -124,9 +277,11 @@ declare class RenderElementComponent implements OnInit {
|
|
|
124
277
|
/** Once real mounts, never revert to fallback even if a state-bound
|
|
125
278
|
* prop later becomes undefined. Per-instance monotonic gate. */
|
|
126
279
|
private readonly mountedReal;
|
|
127
|
-
/** True when
|
|
128
|
-
*
|
|
129
|
-
*
|
|
280
|
+
/** True when the element is not yet ready to mount the real component.
|
|
281
|
+
* Delegates to `isElementReady` which checks:
|
|
282
|
+
* 1. Any undefined-valued resolved prop (state binding still loading).
|
|
283
|
+
* 2. A sync Standard-Schema gate if the registry entry declares a schema.
|
|
284
|
+
* Framework-injected keys (bindings, emit, loading, childKeys, spec) are
|
|
130
285
|
* excluded — only consumer-resolved props matter for readiness. */
|
|
131
286
|
readonly notReady: Signal<boolean>;
|
|
132
287
|
/** Picks fallback or real based on notReady. The mountedReal latch is
|
|
@@ -135,25 +290,15 @@ declare class RenderElementComponent implements OnInit {
|
|
|
135
290
|
readonly mountClass: Signal<AngularComponentRenderer | null>;
|
|
136
291
|
/** Whether the element is visible (non-repeat path). */
|
|
137
292
|
readonly visible: Signal<boolean>;
|
|
138
|
-
/**
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
*
|
|
142
|
-
*
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
*
|
|
146
|
-
*
|
|
147
|
-
* The string format is `a2ui:datamodel:<path>:<value>` where:
|
|
148
|
-
* - `<path>` is a JSON-Pointer-style path (e.g. `/name`, `/form/email`)
|
|
149
|
-
* - `<value>` is the raw value rendered as a string. We attempt to
|
|
150
|
-
* coerce numeric and boolean literals back to their typed form
|
|
151
|
-
* so downstream consumers see correct types; arrays come through
|
|
152
|
-
* as JSON-stringified payloads (catalog components emit them via
|
|
153
|
-
* `JSON.stringify`).
|
|
154
|
-
*/
|
|
293
|
+
/** Invokes the element's `on[event]` handler bindings. */
|
|
294
|
+
private invokeHandlers;
|
|
295
|
+
/** Element-scoped host injected by mounted view components via
|
|
296
|
+
* injectRenderHost(). `set` writes the store; `emit` routes element
|
|
297
|
+
* handlers; `result` surfaces a RenderResultEvent for this element. */
|
|
298
|
+
readonly host: RenderHost;
|
|
299
|
+
/** Emit function passed to mounted view components as the `emit` framework
|
|
300
|
+
* input. Delegates to the element's `on[event]` handler bindings. */
|
|
155
301
|
private readonly emitFn;
|
|
156
|
-
private applyDatamodelWrite;
|
|
157
302
|
/** Resolved inputs for non-repeat elements. */
|
|
158
303
|
readonly resolvedInputs: Signal<{}>;
|
|
159
304
|
/** `resolvedInputs` filtered down to keys the target component actually
|
|
@@ -208,6 +353,9 @@ declare class RenderSpecComponent implements OnInit {
|
|
|
208
353
|
private readonly viewRegistry;
|
|
209
354
|
private readonly destroyRef;
|
|
210
355
|
private readonly lifecycle;
|
|
356
|
+
private destroyed;
|
|
357
|
+
/** Guarded OutputRef emit — no-ops after destroy (NG0953). */
|
|
358
|
+
private readonly guardedEmit;
|
|
211
359
|
/** Internal store, lazily created once and reused across spec changes. */
|
|
212
360
|
private _internalStore;
|
|
213
361
|
private getOrCreateInternalStore;
|
|
@@ -289,5 +437,5 @@ declare class DefaultFallbackComponent {
|
|
|
289
437
|
static ɵcmp: _angular_core.ɵɵComponentDeclaration<DefaultFallbackComponent, "render-default-fallback", never, {}, {}, never, never, true, never>;
|
|
290
438
|
}
|
|
291
439
|
|
|
292
|
-
export { DefaultFallbackComponent, RENDER_CONFIG, RENDER_CONTEXT, RENDER_LIFECYCLE, REPEAT_SCOPE, RenderElementComponent, RenderSpecComponent, VIEW_REGISTRY, defineAngularRegistry, overrideViews, provideRender, provideViews, signalStateStore, toRenderRegistry, views, withViews, withoutViews };
|
|
293
|
-
export type { AngularComponentInputs, AngularComponentRenderer, AngularRegistry, RenderConfig, RenderContext, RenderEvent, RenderHandlerEvent, RenderLifecycle, RenderLifecycleEvent, RenderStateChangeEvent, RenderViewEntry, RepeatScope, ViewRegistry };
|
|
440
|
+
export { DefaultFallbackComponent, RENDER_CONFIG, RENDER_CONTEXT, RENDER_HOST, RENDER_LIFECYCLE, REPEAT_SCOPE, RenderElementComponent, RenderSpecComponent, VIEW_REGISTRY, defineAngularRegistry, injectRenderHost, overrideViews, provideRender, provideViews, signalStateStore, toRenderRegistry, views, withViews, withoutViews };
|
|
441
|
+
export type { AngularComponentInputs, AngularComponentRenderer, AngularRegistry, RenderConfig, RenderContext, RenderEvent, RenderHandlerEvent, RenderHost, RenderLifecycle, RenderLifecycleEvent, RenderResultEvent, RenderStateChangeEvent, RenderViewEntry, RepeatScope, StandardSchemaInferInput, StandardSchemaInferOutput, StandardSchemaV1, ViewRegistry };
|