ngx-json-render 0.9.0 → 0.9.2
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 +67 -7
- package/fesm2022/ngx-json-render-devtools.mjs +3 -3
- package/fesm2022/ngx-json-render-router.mjs +71 -0
- package/fesm2022/ngx-json-render-router.mjs.map +1 -0
- package/fesm2022/ngx-json-render-testing.mjs +6 -6
- package/fesm2022/ngx-json-render.mjs +172 -47
- package/fesm2022/ngx-json-render.mjs.map +1 -1
- package/package.json +14 -4
- package/schematics/ng-add/index.cjs +1 -1
- package/types/ngx-json-render-router.d.ts +39 -0
- package/types/ngx-json-render.d.ts +75 -7
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/ngx-json-render) [](https://github.com/shteynu/ngx-json-render/actions/workflows/ci.yml) [](https://github.com/shteynu/ngx-json-render/blob/main/LICENSE)
|
|
4
4
|
|
|
5
|
-
Angular renderer for [json-render](https://github.com/vercel-labs/json-render)
|
|
5
|
+
Generative UI for Angular: a renderer for [json-render](https://github.com/vercel-labs/json-render). Give an LLM a catalog of your components, stream back a JSON spec, and render it as real Angular components. No `innerHTML`, no `eval`, no framework lock-in on the wire format.
|
|
6
6
|
|
|
7
7
|
Built on `@json-render/core` (the same spec format, expressions, state store, actions, and streaming compiler used by the React, Vue, Solid, and Svelte renderers) and idiomatic modern Angular: standalone components, signals, `OnPush` everywhere, and zoneless — no `NgZone`, no Zone.js.
|
|
8
8
|
|
|
@@ -57,12 +57,14 @@ npx skills add shteynu/ngx-json-render --skill ngx-json-render
|
|
|
57
57
|
|
|
58
58
|
The source is [`skills/ngx-json-render/SKILL.md`](https://github.com/shteynu/ngx-json-render/blob/main/skills/ngx-json-render/SKILL.md);
|
|
59
59
|
the Material catalog has one too (`--skill ngx-json-render-material`).
|
|
60
|
+
An agent that reads [llms.txt](https://llmstxt.org) instead can start from
|
|
61
|
+
<https://shteynu.github.io/ngx-json-render/llms.txt>.
|
|
60
62
|
|
|
61
63
|
## The shortest path: a ready-made catalog
|
|
62
64
|
|
|
63
65
|
Writing a catalog is the honest first step, but you do not have to take it to
|
|
64
66
|
see a spec render. [`ngx-json-render-material`](https://www.npmjs.com/package/ngx-json-render-material)
|
|
65
|
-
ships
|
|
67
|
+
ships 33 Angular Material components already registered, so a generated spec
|
|
66
68
|
renders with nothing else wired up:
|
|
67
69
|
|
|
68
70
|
```bash
|
|
@@ -119,7 +121,7 @@ against `@hashbrownai/angular` 0.6.1, as published on 2026-09-30:
|
|
|
119
121
|
| What the model emits | A json-render spec, streamed as RFC 6902 patches — the format the React, Vue, Svelte and Solid renderers read, so a catalog and a spec move between frameworks unchanged | Hashbrown's own JSON, generated against a schema built from the components you expose; read by Hashbrown's Angular and React clients |
|
|
120
122
|
| Server | Anything that streams text: the [AI SDK](https://ai-sdk.dev) in a few lines, or your own endpoint; `catalog.prompt()` writes the system prompt | An [AG-UI](https://docs.ag-ui.com) endpoint, built with Hashbrown's adapters (OpenAI, Anthropic, Google, Azure, Bedrock, Ollama) or your own mapping |
|
|
121
123
|
| Angular | 20, 21 and 22, each tested in CI | 22 only since 0.6 (0.5 supported 20 and 21) |
|
|
122
|
-
| Components | Your own, or
|
|
124
|
+
| Components | Your own, or 33 ready-made Angular Material ones ([`ngx-json-render-material`](https://www.npmjs.com/package/ngx-json-render-material)) | Your own (`exposeComponent`, UI kits) |
|
|
123
125
|
| Beyond rendering | Rendering-focused: state and two-way bindings in the spec, actions, visibility, repeat, watch, confirmation dialogs | An agent toolkit: client-side tools, a QuickJS sandbox for model-written code, shared agent state, interrupts, streaming Markdown |
|
|
124
126
|
| License | Apache-2.0 | MIT |
|
|
125
127
|
|
|
@@ -250,6 +252,38 @@ export class Page {
|
|
|
250
252
|
}
|
|
251
253
|
```
|
|
252
254
|
|
|
255
|
+
### Defaults for the whole app
|
|
256
|
+
|
|
257
|
+
A chat renders a spec in every message, and binding the same registry and handlers on each one gets old. `provideJsonRender` sets them once:
|
|
258
|
+
|
|
259
|
+
```ts
|
|
260
|
+
bootstrapApplication(App, {
|
|
261
|
+
providers: [
|
|
262
|
+
provideJsonRender(() => {
|
|
263
|
+
const orders = inject(OrderService); // the function form runs in an injection context
|
|
264
|
+
return {
|
|
265
|
+
registry,
|
|
266
|
+
catalog,
|
|
267
|
+
handlers: { cancelOrder: (params) => orders.cancel(params['id']) },
|
|
268
|
+
};
|
|
269
|
+
}),
|
|
270
|
+
],
|
|
271
|
+
});
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
```html
|
|
275
|
+
<json-render [spec]="m.spec" />
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
Every option input can be provided: `registry`, `fallback`, `validate`, `renderLimits`, `catalog`, `handlers`, `onAction`, `navigate`, `validationFunctions`, `functions` and `directives`. Per-instance inputs (`spec`, `loading`, `state`, `store`) cannot. The rules:
|
|
279
|
+
|
|
280
|
+
- An input bound on the element wins over the provided value. One left `null` or `undefined` falls through to it.
|
|
281
|
+
- `handlers`, `functions`, `validationFunctions` and `directives` merge by name instead, the element's entry winning a name both define. A chat can provide app-wide handlers and still add one for a single message.
|
|
282
|
+
- Everything else replaces. A `registry` belongs to its catalog, so two are never mixed behind your back; to combine them, spread them yourself (`{ ...registry, ...extraRegistry }`).
|
|
283
|
+
- It works in application, route and component `providers`. A provider below another extends it by the same rules.
|
|
284
|
+
|
|
285
|
+
With no registry bound and none provided, the renderer throws, naming both ways to supply one.
|
|
286
|
+
|
|
253
287
|
## Streaming a UI from an LLM
|
|
254
288
|
|
|
255
289
|
Specs stream as JSONL patch lines (RFC 6902). Render partial specs as they arrive — the renderer tolerates missing elements while `loading` is true:
|
|
@@ -391,15 +425,16 @@ import { JsonRenderer, injectChatUI } from 'ngx-json-render';
|
|
|
391
425
|
@for (m of chat.messages(); track m.id) {
|
|
392
426
|
<p>{{ m.text }}</p>
|
|
393
427
|
@if (m.spec) {
|
|
394
|
-
<json-render [spec]="m.spec"
|
|
428
|
+
<json-render [spec]="m.spec" />
|
|
395
429
|
}
|
|
396
430
|
}
|
|
397
431
|
<button (click)="chat.send('show me revenue for the quarter')">Ask</button>
|
|
398
432
|
`,
|
|
399
433
|
})
|
|
400
434
|
export class ChatPage {
|
|
435
|
+
// The registry comes from provideJsonRender({ registry }) in the app's
|
|
436
|
+
// providers: see "Defaults for the whole app".
|
|
401
437
|
readonly chat = injectChatUI({ api: '/api/chat' });
|
|
402
|
-
readonly registry = registry;
|
|
403
438
|
}
|
|
404
439
|
```
|
|
405
440
|
|
|
@@ -965,7 +1000,26 @@ rather than the one holding session, entitlement or billing state.
|
|
|
965
1000
|
**A spec chooses the navigation target.** `onSuccess: { navigate }` passes its
|
|
966
1001
|
string to the `navigate` callback you provide, verbatim. Treat it as untrusted:
|
|
967
1002
|
match it against known routes, and never hand it to `window.location` or
|
|
968
|
-
`router.navigateByUrl` unchecked.
|
|
1003
|
+
`router.navigateByUrl` unchecked. `ngx-json-render/router` does the checking
|
|
1004
|
+
for an app on the Angular `Router`:
|
|
1005
|
+
|
|
1006
|
+
```ts
|
|
1007
|
+
import { injectRouterNavigate } from 'ngx-json-render/router';
|
|
1008
|
+
|
|
1009
|
+
provideJsonRender(() => ({
|
|
1010
|
+
registry,
|
|
1011
|
+
navigate: injectRouterNavigate({ allow: ['/thanks', /^\/orders\/\d+$/] }),
|
|
1012
|
+
}));
|
|
1013
|
+
```
|
|
1014
|
+
|
|
1015
|
+
It passes a path to `router.navigateByUrl` only when `allow` lets it through
|
|
1016
|
+
(strings match the path exactly, before any `?` or `#`; a `RegExp` is tested
|
|
1017
|
+
against it; a function decides). `allow` is required, because only the app
|
|
1018
|
+
knows which of its routes a generated UI may open. Whatever `allow` says, a
|
|
1019
|
+
path that does not start with a single `/` is refused: no other origin, no
|
|
1020
|
+
`javascript:` or other scheme, no relative path, no backslash or control
|
|
1021
|
+
character. A refused path, or a navigation the router rejects, is reported
|
|
1022
|
+
with `console.warn` and goes nowhere.
|
|
969
1023
|
|
|
970
1024
|
**A spec cannot render forever.** Two elements naming each other as children,
|
|
971
1025
|
or one naming itself, would recurse until the tab died. The renderer refuses to
|
|
@@ -1013,6 +1067,8 @@ Components: `JsonRenderer` (`<json-render>`), `JrChildren`, `JrConfirmDialog`, `
|
|
|
1013
1067
|
|
|
1014
1068
|
Injectables/helpers: `injectRenderContext`, `injectElementKey`, `injectRepeatScope`, `injectStateStore`, `injectStateValue`, `injectStateBinding`, `injectBoundProp`, `injectActions`, `injectAction`, `injectValidation`, `injectFieldValidation`, `injectUIStream`, `injectChatUI`, `injectDevtoolsActive`, `injectConfirmContext`, `jsonRenderMessage`, `isActionCancelled`, `checkSpec`.
|
|
1015
1069
|
|
|
1070
|
+
App-wide defaults: `provideJsonRender`, the `JSON_RENDER_CONFIG` token it fills, and the type `JsonRenderConfig`.
|
|
1071
|
+
|
|
1016
1072
|
Tokens: `JR_CONFIRM_DIALOG` (replace the confirmation dialog), `JR_CONFIRM_LABELS` (its two words), `CONFIRM_CONTEXT`, `RENDER_CONTEXT`, `REPEAT_SCOPE`.
|
|
1017
1073
|
|
|
1018
1074
|
Spec checking: `checkSpec`, `formatSpecCheckIssues`, and the types
|
|
@@ -1031,6 +1087,8 @@ Schema alone (`ngx-json-render/schema`): `schema`, `AngularSchema`, `AngularSpec
|
|
|
1031
1087
|
|
|
1032
1088
|
MCP Apps (`ngx-json-render/mcp`): `injectJsonRenderApp`, `parseSpecFromToolResult`, `messageText`, and the types `JsonRenderApp`, `JsonRenderAppOptions`. Needs the optional peers `@modelcontextprotocol/ext-apps` and `@modelcontextprotocol/sdk`.
|
|
1033
1089
|
|
|
1090
|
+
Router (`ngx-json-render/router`): `injectRouterNavigate`, and the type `RouterNavigateOptions`. Needs the optional peer `@angular/router`, which an Angular app on the router already has.
|
|
1091
|
+
|
|
1034
1092
|
Devtools (`ngx-json-render/devtools`): `JsonRenderDevtools` (`<json-render-devtools>`), and the types `DevtoolsEvent`, `PanelPosition`. Needs the optional peer `@json-render/devtools`.
|
|
1035
1093
|
|
|
1036
1094
|
Testing (`ngx-json-render/testing`): `renderSpec`, `renderComponent`, `recordedTransport`, `specStream`, `usageLine`.
|
|
@@ -1042,7 +1100,7 @@ Everything from `@json-render/core` (types, `createStateStore`, `nestedToFlat`,
|
|
|
1042
1100
|
| Input | Type | Purpose |
|
|
1043
1101
|
| --------------------- | ------------------------------------ | ------------------------------------------------------- |
|
|
1044
1102
|
| `spec` | `Spec \| null` | The UI spec (may be partial while streaming) |
|
|
1045
|
-
| `registry` | `ComponentRegistry` | Catalog type →
|
|
1103
|
+
| `registry` | `ComponentRegistry` | Catalog type → component; required unless provided |
|
|
1046
1104
|
| `loading` | `boolean` | Suppress missing-element warnings while streaming |
|
|
1047
1105
|
| `fallback` | `Type<unknown>` | Component for unknown types |
|
|
1048
1106
|
| `validate` | `'off' \| 'warn' \| 'strict'` | Check the settled spec's structure (default `'off'`) |
|
|
@@ -1059,6 +1117,8 @@ Everything from `@json-render/core` (types, `createStateStore`, `nestedToFlat`,
|
|
|
1059
1117
|
|
|
1060
1118
|
Output: `(stateChange)` — batched `{ path, value }[]` in uncontrolled mode.
|
|
1061
1119
|
|
|
1120
|
+
Every input but `spec`, `loading`, `state` and `store` can come from `provideJsonRender` instead; see [Defaults for the whole app](#defaults-for-the-whole-app).
|
|
1121
|
+
|
|
1062
1122
|
## License
|
|
1063
1123
|
|
|
1064
1124
|
Apache-2.0
|
|
@@ -238,10 +238,10 @@ class JsonRenderDevtools {
|
|
|
238
238
|
this.events = null;
|
|
239
239
|
});
|
|
240
240
|
}
|
|
241
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
242
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.
|
|
241
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: JsonRenderDevtools, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
242
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.25", type: JsonRenderDevtools, isStandalone: true, selector: "json-render-devtools", inputs: { renderer: { classPropertyName: "renderer", publicName: "renderer", isSignal: true, isRequired: false, transformFunction: null }, spec: { classPropertyName: "spec", publicName: "spec", isSignal: true, isRequired: false, transformFunction: null }, catalog: { classPropertyName: "catalog", publicName: "catalog", isSignal: true, isRequired: false, transformFunction: null }, chat: { classPropertyName: "chat", publicName: "chat", isSignal: true, isRequired: false, transformFunction: null }, initialOpen: { classPropertyName: "initialOpen", publicName: "initialOpen", isSignal: true, isRequired: false, transformFunction: null }, position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null }, hotkey: { classPropertyName: "hotkey", publicName: "hotkey", isSignal: true, isRequired: false, transformFunction: null }, bufferSize: { classPropertyName: "bufferSize", publicName: "bufferSize", isSignal: true, isRequired: false, transformFunction: null }, reserveSpace: { classPropertyName: "reserveSpace", publicName: "reserveSpace", isSignal: true, isRequired: false, transformFunction: null }, allowDockToggle: { classPropertyName: "allowDockToggle", publicName: "allowDockToggle", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { event: "event" }, ngImport: i0, template: '', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
243
243
|
}
|
|
244
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
244
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: JsonRenderDevtools, decorators: [{
|
|
245
245
|
type: Component,
|
|
246
246
|
args: [{
|
|
247
247
|
selector: 'json-render-devtools',
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { inject } from '@angular/core';
|
|
2
|
+
import { Router } from '@angular/router';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* A `navigate` for `<json-render>` that hands a spec's
|
|
6
|
+
* `onSuccess: { navigate }` path to the Angular `Router`, but only a path
|
|
7
|
+
* inside the app that `allow` lets through. Anything else is refused with a
|
|
8
|
+
* warning and goes nowhere.
|
|
9
|
+
*
|
|
10
|
+
* Call it in an injection context — in the function form of
|
|
11
|
+
* `provideJsonRender`, or in a field initializer:
|
|
12
|
+
*
|
|
13
|
+
* ```ts
|
|
14
|
+
* provideJsonRender(() => ({
|
|
15
|
+
* registry,
|
|
16
|
+
* navigate: injectRouterNavigate({ allow: ['/thanks', /^\/orders\/\d+$/] }),
|
|
17
|
+
* }));
|
|
18
|
+
* ```
|
|
19
|
+
*
|
|
20
|
+
* Whatever `allow` says, a path is refused unless it starts with a single
|
|
21
|
+
* `/`: no other origin (`https://…`, `//host`), no scheme (`javascript:…`),
|
|
22
|
+
* no path relative to wherever the user happens to be. A backslash or a
|
|
23
|
+
* control character refuses it too, since browsers read `/\host` as
|
|
24
|
+
* `//host`.
|
|
25
|
+
*/
|
|
26
|
+
function injectRouterNavigate(options) {
|
|
27
|
+
const router = inject(Router);
|
|
28
|
+
const allowed = toPredicate(options.allow);
|
|
29
|
+
return (path) => {
|
|
30
|
+
if (!isAppPath(path)) {
|
|
31
|
+
console.warn(`[ngx-json-render] Refused to navigate to ${JSON.stringify(path)}: a spec may only navigate to a path inside the app, starting with a single "/".`);
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
const pathname = path.split(/[?#]/, 1)[0];
|
|
35
|
+
if (!allowed(pathname)) {
|
|
36
|
+
console.warn(`[ngx-json-render] Refused to navigate to "${path}": "${pathname}" is not in the allow list given to injectRouterNavigate.`);
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
router.navigateByUrl(path).catch((error) => {
|
|
40
|
+
console.warn(`[ngx-json-render] Navigation to "${path}" failed.`, error);
|
|
41
|
+
});
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
function isAppPath(path) {
|
|
45
|
+
return (typeof path === 'string' &&
|
|
46
|
+
/^\/(?![/\\])/.test(path) &&
|
|
47
|
+
!/[\\\u0000-\u001f\u007f]/.test(path));
|
|
48
|
+
}
|
|
49
|
+
function toPredicate(allow) {
|
|
50
|
+
if (typeof allow === 'function')
|
|
51
|
+
return allow;
|
|
52
|
+
return (path) => allow.some((rule) => {
|
|
53
|
+
if (typeof rule === 'string')
|
|
54
|
+
return rule === path;
|
|
55
|
+
// A global or sticky RegExp keeps `lastIndex` between calls; reset it so
|
|
56
|
+
// one rule answers the same way for the same path every time.
|
|
57
|
+
rule.lastIndex = 0;
|
|
58
|
+
return rule.test(path);
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/*
|
|
63
|
+
* Public API Surface of ngx-json-render/router
|
|
64
|
+
*/
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Generated bundle index. Do not edit.
|
|
68
|
+
*/
|
|
69
|
+
|
|
70
|
+
export { injectRouterNavigate };
|
|
71
|
+
//# sourceMappingURL=ngx-json-render-router.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ngx-json-render-router.mjs","sources":["../../../projects/ngx-json-render/router/src/router-navigate.ts","../../../projects/ngx-json-render/router/src/public-api.ts","../../../projects/ngx-json-render/router/src/ngx-json-render-router.ts"],"sourcesContent":["import { inject } from '@angular/core';\nimport { Router } from '@angular/router';\n\n/** Which paths a spec may send the app to. */\nexport interface RouterNavigateOptions {\n /**\n * The paths a spec may navigate to. A string must equal the path exactly; a\n * `RegExp` is tested against it; a function decides on its own. The path is\n * what comes before any `?` or `#`, so a query string or fragment neither\n * helps nor hurts a match, and is passed on to the router as written.\n *\n * Required: a spec is model output, and the app is what knows which of its\n * routes a generated UI has any business opening.\n */\n readonly allow: readonly (string | RegExp)[] | ((path: string) => boolean);\n}\n\n/**\n * A `navigate` for `<json-render>` that hands a spec's\n * `onSuccess: { navigate }` path to the Angular `Router`, but only a path\n * inside the app that `allow` lets through. Anything else is refused with a\n * warning and goes nowhere.\n *\n * Call it in an injection context — in the function form of\n * `provideJsonRender`, or in a field initializer:\n *\n * ```ts\n * provideJsonRender(() => ({\n * registry,\n * navigate: injectRouterNavigate({ allow: ['/thanks', /^\\/orders\\/\\d+$/] }),\n * }));\n * ```\n *\n * Whatever `allow` says, a path is refused unless it starts with a single\n * `/`: no other origin (`https://…`, `//host`), no scheme (`javascript:…`),\n * no path relative to wherever the user happens to be. A backslash or a\n * control character refuses it too, since browsers read `/\\host` as\n * `//host`.\n */\nexport function injectRouterNavigate(\n options: RouterNavigateOptions,\n): (path: string) => void {\n const router = inject(Router);\n const allowed = toPredicate(options.allow);\n return (path) => {\n if (!isAppPath(path)) {\n console.warn(\n `[ngx-json-render] Refused to navigate to ${JSON.stringify(path)}: a spec may only navigate to a path inside the app, starting with a single \"/\".`,\n );\n return;\n }\n const pathname = path.split(/[?#]/, 1)[0];\n if (!allowed(pathname)) {\n console.warn(\n `[ngx-json-render] Refused to navigate to \"${path}\": \"${pathname}\" is not in the allow list given to injectRouterNavigate.`,\n );\n return;\n }\n router.navigateByUrl(path).catch((error: unknown) => {\n console.warn(`[ngx-json-render] Navigation to \"${path}\" failed.`, error);\n });\n };\n}\n\nfunction isAppPath(path: unknown): path is string {\n return (\n typeof path === 'string' &&\n /^\\/(?![/\\\\])/.test(path) &&\n !/[\\\\\\u0000-\\u001f\\u007f]/.test(path)\n );\n}\n\nfunction toPredicate(\n allow: RouterNavigateOptions['allow'],\n): (path: string) => boolean {\n if (typeof allow === 'function') return allow;\n return (path) =>\n allow.some((rule) => {\n if (typeof rule === 'string') return rule === path;\n // A global or sticky RegExp keeps `lastIndex` between calls; reset it so\n // one rule answers the same way for the same path every time.\n rule.lastIndex = 0;\n return rule.test(path);\n });\n}\n","/*\n * Public API Surface of ngx-json-render/router\n */\n\nexport {\n injectRouterNavigate,\n type RouterNavigateOptions,\n} from './router-navigate';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;;AAiBA;;;;;;;;;;;;;;;;;;;;;AAqBG;AACG,SAAU,oBAAoB,CAClC,OAA8B,EAAA;AAE9B,IAAA,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;IAC7B,MAAM,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC;IAC1C,OAAO,CAAC,IAAI,KAAI;AACd,QAAA,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE;AACpB,YAAA,OAAO,CAAC,IAAI,CACV,CAAA,yCAAA,EAA4C,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA,gFAAA,CAAkF,CACnJ;YACD;QACF;AACA,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;AACzC,QAAA,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE;YACtB,OAAO,CAAC,IAAI,CACV,CAAA,0CAAA,EAA6C,IAAI,CAAA,IAAA,EAAO,QAAQ,CAAA,yDAAA,CAA2D,CAC5H;YACD;QACF;QACA,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,KAAc,KAAI;YAClD,OAAO,CAAC,IAAI,CAAC,CAAA,iCAAA,EAAoC,IAAI,CAAA,SAAA,CAAW,EAAE,KAAK,CAAC;AAC1E,QAAA,CAAC,CAAC;AACJ,IAAA,CAAC;AACH;AAEA,SAAS,SAAS,CAAC,IAAa,EAAA;AAC9B,IAAA,QACE,OAAO,IAAI,KAAK,QAAQ;AACxB,QAAA,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC;AACzB,QAAA,CAAC,yBAAyB,CAAC,IAAI,CAAC,IAAI,CAAC;AAEzC;AAEA,SAAS,WAAW,CAClB,KAAqC,EAAA;IAErC,IAAI,OAAO,KAAK,KAAK,UAAU;AAAE,QAAA,OAAO,KAAK;AAC7C,IAAA,OAAO,CAAC,IAAI,KACV,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,KAAI;QAClB,IAAI,OAAO,IAAI,KAAK,QAAQ;YAAE,OAAO,IAAI,KAAK,IAAI;;;AAGlD,QAAA,IAAI,CAAC,SAAS,GAAG,CAAC;AAClB,QAAA,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;AACxB,IAAA,CAAC,CAAC;AACN;;ACpFA;;AAEG;;ACFH;;AAEG;;"}
|
|
@@ -256,14 +256,14 @@ class JrComponentTestHost {
|
|
|
256
256
|
parent = inject(Injector);
|
|
257
257
|
component = signal(null, ...(ngDevMode ? [{ debugName: "component" }] : /* istanbul ignore next */ []));
|
|
258
258
|
injector = signal(this.parent, ...(ngDevMode ? [{ debugName: "injector" }] : /* istanbul ignore next */ []));
|
|
259
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
260
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.
|
|
259
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: JrComponentTestHost, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
260
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.25", type: JrComponentTestHost, isStandalone: true, selector: "jr-component-test-host", ngImport: i0, template: `
|
|
261
261
|
@if (component(); as type) {
|
|
262
262
|
<ng-container *ngComponentOutlet="type; injector: injector()" />
|
|
263
263
|
}
|
|
264
264
|
`, isInline: true, dependencies: [{ kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule"], exportAs: ["ngComponentOutlet"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
265
265
|
}
|
|
266
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
266
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: JrComponentTestHost, decorators: [{
|
|
267
267
|
type: Component,
|
|
268
268
|
args: [{
|
|
269
269
|
selector: 'jr-component-test-host',
|
|
@@ -420,8 +420,8 @@ class JrTestHost {
|
|
|
420
420
|
validationFunctions = signal(undefined, ...(ngDevMode ? [{ debugName: "validationFunctions" }] : /* istanbul ignore next */ []));
|
|
421
421
|
directives = signal(undefined, ...(ngDevMode ? [{ debugName: "directives" }] : /* istanbul ignore next */ []));
|
|
422
422
|
record = () => { };
|
|
423
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
424
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.
|
|
423
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: JrTestHost, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
424
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.25", type: JrTestHost, isStandalone: true, selector: "jr-test-host", ngImport: i0, template: `
|
|
425
425
|
<json-render
|
|
426
426
|
[spec]="spec()"
|
|
427
427
|
[registry]="registry()"
|
|
@@ -439,7 +439,7 @@ class JrTestHost {
|
|
|
439
439
|
/>
|
|
440
440
|
`, isInline: true, dependencies: [{ kind: "component", type: JsonRenderer, selector: "json-render", inputs: ["spec", "registry", "loading", "fallback", "validate", "renderLimits", "catalog", "state", "store", "handlers", "onAction", "navigate", "validationFunctions", "functions", "directives"], outputs: ["stateChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
441
441
|
}
|
|
442
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
442
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: JrTestHost, decorators: [{
|
|
443
443
|
type: Component,
|
|
444
444
|
args: [{
|
|
445
445
|
selector: 'jr-test-host',
|