ngx-json-render 0.5.1 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ngx-json-render",
3
- "version": "0.5.1",
3
+ "version": "0.7.0",
4
4
  "description": "Angular renderer for json-render — stream AI-generated JSON specs into real Angular components with signals.",
5
5
  "keywords": [
6
6
  "angular",
@@ -127,7 +127,8 @@ interface RenderLimits {
127
127
  * terminate. A tree that recurses into its items is not this.
128
128
  * - `too_deep` / `too_many_elements` — a {@link RenderLimits} cap was passed.
129
129
  * - `unknown_component` — a `type` the catalog does not define.
130
- * - `invalid_props` — the catalog's own schema rejected part of the spec.
130
+ * - `invalid_props` — an element's props fail its component's schema, or the
131
+ * element fails the catalog's spec schema: a missing `children`, say.
131
132
  */
132
133
  type SpecCheckIssueCode = SpecIssue['code'] | 'cycle' | 'too_deep' | 'too_many_elements' | 'unknown_component' | 'invalid_props';
133
134
  /**
@@ -154,6 +155,19 @@ interface SpecCatalog {
154
155
  readonly success: boolean;
155
156
  readonly error?: unknown;
156
157
  };
158
+ /**
159
+ * The definitions the catalog was created from. Where
160
+ * `data.components[type].props` is a schema — anything with a `safeParse`,
161
+ * as a Zod schema has — each element's props are checked against its own
162
+ * component's. Without it, props are checked only as far as `validate`
163
+ * checks them, which for a catalog of more than one component is not at
164
+ * all.
165
+ *
166
+ * `unknown` rather than that shape, so that a `Catalog` whose generic
167
+ * arguments were left off — and whose `data` is therefore `unknown` — still
168
+ * fits.
169
+ */
170
+ readonly data?: unknown;
157
171
  }
158
172
 
159
173
  /**
@@ -176,9 +190,10 @@ interface SpecCheckOptions {
176
190
  readonly limits?: RenderLimits | null;
177
191
  /**
178
192
  * The catalog the spec was generated for. Given one, the check also reports
179
- * component types the catalog does not define and props its own schema
180
- * rejects — the half of "is this spec renderable" that structure alone
181
- * cannot answer.
193
+ * component types the catalog does not define, elements its spec schema
194
+ * rejects, and props their component's schema rejects — the half of "is
195
+ * this spec renderable" that structure alone cannot answer. A prop written
196
+ * as an expression is not judged: it has no value until render time.
182
197
  */
183
198
  readonly catalog?: SpecCatalog | null;
184
199
  }
@@ -477,7 +492,11 @@ declare class JsonRenderer {
477
492
  /**
478
493
  * The catalog the spec was generated for. Given one, `validate` also checks
479
494
  * what structure alone cannot: that every `type` is a component the catalog
480
- * defines, and that the props match its schema.
495
+ * defines, that every element has the shape the catalog's spec schema asks
496
+ * for — a `children` array, even on a leaf — and that its props match its
497
+ * component's schema. A prop written as an expression — `$state`,
498
+ * `$bindState`, `$template`, a directive — has no value until render time,
499
+ * so it is not checked.
481
500
  *
482
501
  * Only read when `validate` is on, and — like the rest of the check —
483
502
  * skipped while `loading`.
@@ -601,6 +620,34 @@ declare class JrElement {
601
620
  private readonly devtoolsActive;
602
621
  /** The raw (unresolved) element from the spec. */
603
622
  readonly rawElement: Signal<UIElement<string, Record<string, unknown>> | undefined>;
623
+ /**
624
+ * The state paths this element's expressions can read, or null when the
625
+ * spec doesn't say — see {@link collectStateReads} for when that is.
626
+ */
627
+ private readonly stateReads;
628
+ /**
629
+ * One signal per path this element reads, each holding the value at that
630
+ * path. They are rebuilt only when the paths change, and a cell that stays
631
+ * keeps its last value, so a path that didn't change is not a change.
632
+ *
633
+ * A cell compares like a resolved prop does: primitives by value, objects
634
+ * by reference with the internal store (which copies every path it writes)
635
+ * and never equal with an external `store`, which may write into its
636
+ * snapshot in place.
637
+ */
638
+ private readonly stateCells;
639
+ /**
640
+ * How many times {@link readableState} has taken a snapshot. The dev-mode
641
+ * check compares it between state writes to tell which ones were skipped.
642
+ */
643
+ private snapshotsTaken;
644
+ /**
645
+ * The state to resolve against: the whole snapshot, but only as fresh as
646
+ * the paths this element reads. A write elsewhere doesn't reach it, so the
647
+ * element doesn't resolve anything for it. An element whose reads are
648
+ * unknown follows every write, as all elements did before.
649
+ */
650
+ private readonly readableState;
604
651
  /** Prop/visibility resolution context (state + repeat scope + extensions). */
605
652
  private readonly resolutionCtx;
606
653
  protected readonly visible: Signal<boolean>;
@@ -646,6 +693,14 @@ declare class JrElement {
646
693
  private readonly renderCtx;
647
694
  protected readonly outletInjector: _angular_core.DestroyableInjector;
648
695
  constructor();
696
+ /**
697
+ * Resolve this element against the whole current state and warn, once per
698
+ * element key, when that differs from what it shows after skipping a write.
699
+ *
700
+ * It only reports, and leaves the element as it is: correcting it here would
701
+ * make dev mode render what production doesn't.
702
+ */
703
+ private checkSkippedWrite;
649
704
  /**
650
705
  * Resolution context with a live state snapshot, so `$state` references in
651
706
  * later actions of a chain see mutations from earlier ones.
@@ -1105,8 +1160,10 @@ interface UIStreamOptions {
1105
1160
  renderLimits?: RenderLimits | null;
1106
1161
  /**
1107
1162
  * The catalog the spec was generated for. Given one, `validate` also checks
1108
- * every element `type` against the catalog and the props against its
1109
- * schema — the half a structural check cannot see.
1163
+ * every element `type` against the catalog and each element's props against
1164
+ * its component's schema — the half a structural check cannot see. Props
1165
+ * written as expressions are left alone: they have no value until render
1166
+ * time.
1110
1167
  */
1111
1168
  catalog?: SpecCatalog | null;
1112
1169
  /**
@@ -1216,8 +1273,10 @@ interface ChatUIOptions {
1216
1273
  renderLimits?: RenderLimits | null;
1217
1274
  /**
1218
1275
  * The catalog the spec was generated for. Given one, `validate` also checks
1219
- * every element `type` against the catalog and the props against its
1220
- * schema — the half a structural check cannot see.
1276
+ * every element `type` against the catalog and each element's props against
1277
+ * its component's schema — the half a structural check cannot see. Props
1278
+ * written as expressions are left alone: they have no value until render
1279
+ * time.
1221
1280
  */
1222
1281
  catalog?: SpecCatalog | null;
1223
1282
  }