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/README.md CHANGED
@@ -239,7 +239,7 @@ app.post('/api/generate', async (req, res) => {
239
239
  });
240
240
  ```
241
241
 
242
- The patches apply to the `spec` signal as each line arrives, so the UI assembles on screen while the model is still generating — exactly what the [demo's Streaming tab](https://shteynu.github.io/ngx-json-render/) replays. Prefer structured output? `catalog.jsonSchema()` exports a JSON Schema for `streamObject`/tool calls, and `catalog.validate(spec)` checks a finished spec against the catalog.
242
+ The patches apply to the `spec` signal as each line arrives, so the UI assembles on screen while the model is still generating — exactly what the [demo's Streaming tab](https://shteynu.github.io/ngx-json-render/) replays. Prefer structured output? `catalog.jsonSchema()` exports a JSON Schema for `streamObject`/tool calls, and `checkSpec(spec, 'strict', { catalog })` checks a finished spec against the catalog, props included — see [Checking what the model produced](#checking-what-the-model-produced) for why that and not `catalog.validate(spec)` alone.
243
243
 
244
244
  ### Chat + GenUI
245
245
 
@@ -372,12 +372,23 @@ is a patch that has not arrived yet, not a defect, so nothing is reported and
372
372
  `strict` keeps rendering; the hooks check once, when the generation completes.
373
373
 
374
374
  Pass the catalog too, and the same check covers what structure alone cannot
375
- see — every `type` is one the catalog defines, and the props match its schema:
375
+ see — every `type` is one the catalog defines, and each element's props match
376
+ its component's schema:
376
377
 
377
378
  ```html
378
379
  <json-render [spec]="spec()" [registry]="registry" [catalog]="catalog" validate="strict" />
379
380
  ```
380
381
 
382
+ A prop written as an expression — `{"$state": …}`, `{"$bindState": …}`,
383
+ `{"$template": …}`, a directive — is not checked: it has no value until render
384
+ time. The catalog's spec schema also holds every element to the grammar, which
385
+ wants a `children` array even on a leaf.
386
+
387
+ The props check is this package's own. Core's `catalog.validate(spec)` gives an
388
+ element's props its component's schema only when the catalog has exactly one
389
+ component; with more, it checks element shapes and `type` names but not a
390
+ single prop.
391
+
381
392
  ### Capping what a spec may cost
382
393
 
383
394
  `validate` describes a spec. `renderLimits` constrains it:
@@ -606,6 +617,12 @@ A write reaches only the components whose resolved props actually changed. Writi
606
617
 
607
618
  Elements with a `$bindState` or `$bindItem` prop still re-run on every write. Their DOM can hold the user's input before state does, and the note below depends on them getting the chance to put it right.
608
619
 
620
+ Before any of that, a write only makes the elements that can read its path resolve their props at all. The renderer works the paths out from each element's spec — `$state`, `$item`, `$template` placeholders, both branches of a `$cond`, `$computed` arguments and `visible` conditions — so a write to `/user/name` leaves the todo list alone, and its `$computed` functions don't run. A `$computed` function should therefore depend only on its arguments: one that also reads the clock or a variable outside the spec is no longer called again by unrelated writes.
621
+
622
+ Some elements keep resolving on every write, because their reads can't be known from the spec: those using a directive (its `resolve` gets the whole state), those with a two-way binding, and any prop with a `$`-key the renderer doesn't recognise.
623
+
624
+ In dev mode each element that skipped a write resolves anyway, against the whole state, and the console warns once if that gives anything other than what it shows. The warning means a `$computed` function reads more than its arguments, or the renderer missed a read, which is a bug worth reporting. The element itself is left as production would leave it. The check calls the element's `$computed` functions again, so in dev mode they still run on every write.
625
+
609
626
  ### A note on inputs
610
627
 
611
628
  If a catalog component renders `<input [value]="ctx.props().value">`, remember that one-way bindings do not re-assert the DOM when the bound value returns to its previously applied value while the user typed in between (e.g. `pushState` + `clearStatePath`). Sync imperatively instead — see `InputComponent` in the demo app for the pattern.
@@ -748,10 +765,13 @@ not generate should set all three. See
748
765
  [Capping what a spec may cost](#capping-what-a-spec-may-cost).
749
766
 
750
767
  **A spec can name components you never built.** `validate` with a `catalog`
751
- reports every `type` the catalog does not define and every prop its schema
752
- rejects; `strict` refuses such a spec outright. Without a catalog the renderer
753
- only warns and draws nothing in that element's place, which degrades well but
754
- tells you nothing until you read the console.
768
+ reports every `type` the catalog does not define and every prop its component's
769
+ schema rejects; `strict` refuses such a spec outright. A prop bound to an
770
+ expression (`$state`, `$bindState`, `$template`, …) is not among them — its value
771
+ only exists at render time — so a component should not count on such a prop
772
+ having the type its schema declares. Without a catalog the renderer only warns
773
+ and draws nothing in that element's place, which degrades well but tells you
774
+ nothing until you read the console.
755
775
 
756
776
  **`confirm` is a UX affordance, not a security control.** It routes an action
757
777
  through the confirmation dialog before the handler runs, but it is set on the