ngx-json-render 0.7.7 → 0.8.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 +42 -5
- package/fesm2022/ngx-json-render-mcp.mjs +132 -0
- package/fesm2022/ngx-json-render-mcp.mjs.map +1 -0
- package/fesm2022/ngx-json-render-schema.mjs +107 -0
- package/fesm2022/ngx-json-render-schema.mjs.map +1 -0
- package/fesm2022/ngx-json-render.mjs +128 -124
- package/fesm2022/ngx-json-render.mjs.map +1 -1
- package/package.json +20 -2
- package/types/ngx-json-render-mcp.d.ts +93 -0
- package/types/ngx-json-render-schema.d.ts +74 -0
- package/types/ngx-json-render.d.ts +34 -85
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { NgComponentOutlet } from '@angular/common';
|
|
2
2
|
import * as i0 from '@angular/core';
|
|
3
3
|
import { signal, Injectable, isDevMode, inject, computed, untracked, effect, DestroyRef, InjectionToken, input, output, viewChild, afterNextRender, ChangeDetectionStrategy, Component, Injector, forwardRef } from '@angular/core';
|
|
4
|
-
import { createStateStore, getByPath, runValidation, resolveAction, nextActionDispatchId, notifyActionDispatch, notifyActionSettle, executeAction, isDevtoolsActive, subscribeDevtoolsActive, resolveRepeatStatePath, evaluateVisibility, resolveElementProps, resolveBindings, resolveActionParam, autoFixSpec, validateSpec, createDirectiveRegistry, resolveRepeatItemStatePath, removeByPath, addByPath, setByPath, SPEC_DATA_PART_TYPE, nestedToFlat, createMixedStreamParser
|
|
4
|
+
import { createStateStore, getByPath, runValidation, resolveAction, nextActionDispatchId, notifyActionDispatch, notifyActionSettle, executeAction, isDevtoolsActive, subscribeDevtoolsActive, resolveRepeatStatePath, evaluateVisibility, resolveElementProps, resolveBindings, resolveActionParam, autoFixSpec, validateSpec, createDirectiveRegistry, resolveRepeatItemStatePath, removeByPath, addByPath, setByPath, SPEC_DATA_PART_TYPE, nestedToFlat, createMixedStreamParser } from '@json-render/core';
|
|
5
5
|
export { autoFixSpec, createStateStore, formatSpecIssues, nestedToFlat, validateSpec } from '@json-render/core';
|
|
6
|
+
export { schema } from 'ngx-json-render/schema';
|
|
6
7
|
|
|
7
8
|
const EMPTY = signal(undefined, ...(ngDevMode ? [{ debugName: "EMPTY" }] : /* istanbul ignore next */ []));
|
|
8
9
|
/**
|
|
@@ -92,6 +93,37 @@ function isPlainObject(value) {
|
|
|
92
93
|
Object.getPrototypeOf(value) === Object.prototype);
|
|
93
94
|
}
|
|
94
95
|
|
|
96
|
+
/**
|
|
97
|
+
* Whether two values hold the same JSON content.
|
|
98
|
+
*
|
|
99
|
+
* For telling a value that arrived as a new object from one that changed — a
|
|
100
|
+
* spec element, or a leaf of `spec.state`, when the host hands over a spec
|
|
101
|
+
* built from fresh objects. Plain objects and arrays are compared by what
|
|
102
|
+
* they hold; anything else only by identity, which data parsed from JSON
|
|
103
|
+
* never needs. A container reached twice on the way down counts as
|
|
104
|
+
* different: JSON cannot refer to itself, and treating such a value as
|
|
105
|
+
* changed is what the renderer did before it compared anything.
|
|
106
|
+
*/
|
|
107
|
+
function sameJson(a, b, seen = new Set()) {
|
|
108
|
+
if (Object.is(a, b))
|
|
109
|
+
return true;
|
|
110
|
+
if (!isPlainContainer(a) || !isPlainContainer(b))
|
|
111
|
+
return false;
|
|
112
|
+
if (Array.isArray(a) !== Array.isArray(b) || seen.has(a))
|
|
113
|
+
return false;
|
|
114
|
+
seen.add(a);
|
|
115
|
+
const keys = Object.keys(a);
|
|
116
|
+
if (keys.length !== Object.keys(b).length)
|
|
117
|
+
return false;
|
|
118
|
+
return keys.every((key) => Object.hasOwn(b, key) && sameJson(a[key], b[key], seen));
|
|
119
|
+
}
|
|
120
|
+
function isPlainContainer(value) {
|
|
121
|
+
if (typeof value !== 'object' || value === null)
|
|
122
|
+
return false;
|
|
123
|
+
const prototype = Object.getPrototypeOf(value);
|
|
124
|
+
return (Array.isArray(value) || prototype === Object.prototype || prototype === null);
|
|
125
|
+
}
|
|
126
|
+
|
|
95
127
|
/**
|
|
96
128
|
* The state store of a `<json-render>` subtree.
|
|
97
129
|
*
|
|
@@ -151,7 +183,10 @@ class JsonRenderStateService {
|
|
|
151
183
|
});
|
|
152
184
|
// Uncontrolled mode: when the (resolved) initial state changes — e.g.
|
|
153
185
|
// `spec.state` grows while streaming — diff it against the previous
|
|
154
|
-
// initial state and apply only the changed leaves to the store.
|
|
186
|
+
// initial state and apply only the changed leaves to the store. Leaves
|
|
187
|
+
// compare by content: arrays are leaves, and a spec handed over again as
|
|
188
|
+
// new objects would otherwise write every array back, over whatever the
|
|
189
|
+
// user has since changed inside it.
|
|
155
190
|
let prevFlat = {};
|
|
156
191
|
effect(() => {
|
|
157
192
|
if (this.root.store())
|
|
@@ -166,7 +201,7 @@ class JsonRenderStateService {
|
|
|
166
201
|
]);
|
|
167
202
|
const updates = {};
|
|
168
203
|
for (const key of allKeys) {
|
|
169
|
-
if (prevFlat[key]
|
|
204
|
+
if (!sameJson(prevFlat[key], nextFlat[key])) {
|
|
170
205
|
updates[key] = key in nextFlat ? nextFlat[key] : undefined;
|
|
171
206
|
}
|
|
172
207
|
}
|
|
@@ -1085,8 +1120,6 @@ function injectDevtoolsActive() {
|
|
|
1085
1120
|
*
|
|
1086
1121
|
* - a registered directive, whose `resolve` receives the whole context and may
|
|
1087
1122
|
* read any path at all;
|
|
1088
|
-
* - a `$bindState` or `$bindItem` prop — the renderer keeps two-way bound
|
|
1089
|
-
* elements resolving on every write, see `JrElement.resolvedElement`;
|
|
1090
1123
|
* - a `$`-prefixed key it doesn't recognise, which is what an expression added
|
|
1091
1124
|
* to core after this was written would look like;
|
|
1092
1125
|
* - a read of the whole state (`''` or `'/'`), and a condition it can't parse.
|
|
@@ -1123,10 +1156,13 @@ class StateReader {
|
|
|
1123
1156
|
return this.item(value['$item']);
|
|
1124
1157
|
if ('$index' in value && value['$index'] === true)
|
|
1125
1158
|
return true;
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1159
|
+
// A two-way binding reads the path it writes back to.
|
|
1160
|
+
if (typeof value['$bindState'] === 'string') {
|
|
1161
|
+
return this.state(value['$bindState']);
|
|
1162
|
+
}
|
|
1163
|
+
if (typeof value['$bindItem'] === 'string') {
|
|
1164
|
+
return this.boundItem(value['$bindItem']);
|
|
1165
|
+
}
|
|
1130
1166
|
if ('$cond' in value && '$then' in value && '$else' in value) {
|
|
1131
1167
|
return (this.condition(value['$cond']) &&
|
|
1132
1168
|
this.value(value['$then']) &&
|
|
@@ -1220,6 +1256,17 @@ class StateReader {
|
|
|
1220
1256
|
this.paths.add(path);
|
|
1221
1257
|
return true;
|
|
1222
1258
|
}
|
|
1259
|
+
/**
|
|
1260
|
+
* A `$bindItem`, joined the way core joins it — which is not quite how it
|
|
1261
|
+
* joins an `$item` read. Outside a repeat it resolves to nothing.
|
|
1262
|
+
*/
|
|
1263
|
+
boundItem(itemPath) {
|
|
1264
|
+
if (this.repeatBasePath === undefined)
|
|
1265
|
+
return true;
|
|
1266
|
+
return this.state(itemPath === ''
|
|
1267
|
+
? this.repeatBasePath
|
|
1268
|
+
: `${this.repeatBasePath}/${itemPath}`);
|
|
1269
|
+
}
|
|
1223
1270
|
/**
|
|
1224
1271
|
* A read of the repeat item, as the state path it sits at. The item value
|
|
1225
1272
|
* reaches the element on its own, but only as the same object when an
|
|
@@ -1422,6 +1469,15 @@ function sameContent(a, b, seen = new Set()) {
|
|
|
1422
1469
|
return keys.every((key) => Object.hasOwn(b, key) &&
|
|
1423
1470
|
sameContent(a[key], b[key], seen));
|
|
1424
1471
|
}
|
|
1472
|
+
/**
|
|
1473
|
+
* Whether a state write at `written` can change the value at `bound`: the
|
|
1474
|
+
* same path, a container above it, or a path inside it.
|
|
1475
|
+
*/
|
|
1476
|
+
function touches(written, bound) {
|
|
1477
|
+
return (written === bound ||
|
|
1478
|
+
bound.startsWith(`${written}/`) ||
|
|
1479
|
+
written.startsWith(`${bound}/`));
|
|
1480
|
+
}
|
|
1425
1481
|
/** Element keys already warned about by the check on skipped writes. */
|
|
1426
1482
|
const warnedSkippedWrites = new Set();
|
|
1427
1483
|
const EMPTY_READS = new Set();
|
|
@@ -1458,8 +1514,17 @@ class JrElement {
|
|
|
1458
1514
|
repeatScope = inject(REPEAT_SCOPE, { optional: true });
|
|
1459
1515
|
parentPath = inject(RENDER_PATH, { optional: true });
|
|
1460
1516
|
devtoolsActive = injectDevtoolsActive();
|
|
1461
|
-
/**
|
|
1462
|
-
|
|
1517
|
+
/**
|
|
1518
|
+
* The raw (unresolved) element from the spec.
|
|
1519
|
+
*
|
|
1520
|
+
* Compared by content, not identity. A streamed patch shares every element
|
|
1521
|
+
* it did not touch, and the identity check settles those at once; but a
|
|
1522
|
+
* spec can also arrive as all-new objects — a whole-spec part, a host that
|
|
1523
|
+
* fetches it again, `buildSpecFromParts` replaying a message — and then an
|
|
1524
|
+
* element whose content is unchanged would resolve, and every container
|
|
1525
|
+
* with a fresh `children` array re-render, for nothing.
|
|
1526
|
+
*/
|
|
1527
|
+
rawElement = computed(() => this.root.spec()?.elements?.[this.elementKey()], { ...(ngDevMode ? { debugName: "rawElement" } : /* istanbul ignore next */ {}), equal: (a, b) => sameJson(a, b) });
|
|
1463
1528
|
/**
|
|
1464
1529
|
* The state paths this element's expressions can read, or null when the
|
|
1465
1530
|
* spec doesn't say — see {@link collectStateReads} for when that is.
|
|
@@ -1543,40 +1608,55 @@ class JrElement {
|
|
|
1543
1608
|
return evaluateVisibility(el.visible, this.resolutionCtx());
|
|
1544
1609
|
}, ...(ngDevMode ? [{ debugName: "visible" }] : /* istanbul ignore next */ []));
|
|
1545
1610
|
/**
|
|
1546
|
-
*
|
|
1611
|
+
* How many state writes have touched a path this element is two-way bound
|
|
1612
|
+
* to. See {@link resolution} for why those writes count on their own.
|
|
1613
|
+
*/
|
|
1614
|
+
boundWrites = signal(0, ...(ngDevMode ? [{ debugName: "boundWrites" }] : /* istanbul ignore next */ []));
|
|
1615
|
+
/**
|
|
1616
|
+
* The element with all prop expressions resolved, and the bound writes it
|
|
1617
|
+
* was resolved after.
|
|
1547
1618
|
*
|
|
1548
|
-
* Resolving builds a new props object
|
|
1549
|
-
*
|
|
1550
|
-
*
|
|
1551
|
-
*
|
|
1619
|
+
* Resolving builds a new props object every time, so a result that holds
|
|
1620
|
+
* the same values as the last one counts as unchanged and keeps the old
|
|
1621
|
+
* object; otherwise one keystroke would re-run every catalog template that
|
|
1622
|
+
* happened to resolve.
|
|
1552
1623
|
*
|
|
1553
|
-
*
|
|
1554
|
-
*
|
|
1555
|
-
*
|
|
1556
|
-
*
|
|
1557
|
-
*
|
|
1558
|
-
*
|
|
1559
|
-
*
|
|
1624
|
+
* A write to a path the element is bound to always counts, though. Its
|
|
1625
|
+
* component writes the user's input into the DOM before it reaches state,
|
|
1626
|
+
* so the DOM can differ from a prop whose value never did: typing and a
|
|
1627
|
+
* `clearStatePath` in the same turn take the prop from '' through 'milk'
|
|
1628
|
+
* back to '' with nobody reading 'milk'. The README tells catalog authors
|
|
1629
|
+
* to sync such inputs with an effect on props, and that effect only gets to
|
|
1630
|
+
* put the DOM right if it runs. Writes anywhere else compare by value, like
|
|
1631
|
+
* any element's.
|
|
1560
1632
|
*/
|
|
1561
|
-
|
|
1633
|
+
resolution = computed(() => {
|
|
1634
|
+
const boundWrites = this.boundWrites();
|
|
1562
1635
|
const el = this.rawElement();
|
|
1563
1636
|
if (!el)
|
|
1564
|
-
return undefined;
|
|
1637
|
+
return { element: undefined, boundWrites };
|
|
1565
1638
|
return {
|
|
1566
|
-
|
|
1567
|
-
|
|
1639
|
+
element: {
|
|
1640
|
+
...el,
|
|
1641
|
+
props: resolveElementProps(el.props ?? {}, this.resolutionCtx()),
|
|
1642
|
+
},
|
|
1643
|
+
boundWrites,
|
|
1568
1644
|
};
|
|
1569
|
-
}, { ...(ngDevMode ? { debugName: "
|
|
1570
|
-
if (a
|
|
1645
|
+
}, { ...(ngDevMode ? { debugName: "resolution" } : /* istanbul ignore next */ {}), equal: (a, b) => {
|
|
1646
|
+
if (a.boundWrites !== b.boundWrites)
|
|
1647
|
+
return false;
|
|
1648
|
+
if (a.element === b.element)
|
|
1571
1649
|
return true;
|
|
1572
|
-
if (!a || !b
|
|
1650
|
+
if (!a.element || !b.element)
|
|
1573
1651
|
return false;
|
|
1574
|
-
const { props: aProps, ...aRest } = a;
|
|
1575
|
-
const { props: bProps, ...bRest } = b;
|
|
1652
|
+
const { props: aProps, ...aRest } = a.element;
|
|
1653
|
+
const { props: bProps, ...bRest } = b.element;
|
|
1576
1654
|
// Everything but props is the spec element itself, never state.
|
|
1577
1655
|
return (sameValues(aRest, bRest, true) &&
|
|
1578
1656
|
sameValues(aProps, bProps, !untracked(this.root.store)));
|
|
1579
1657
|
} });
|
|
1658
|
+
/** The element with all prop expressions resolved. */
|
|
1659
|
+
resolvedElement = computed(() => this.resolution().element, ...(ngDevMode ? [{ debugName: "resolvedElement" }] : /* istanbul ignore next */ []));
|
|
1580
1660
|
/** Two-way binding paths ($bindState / $bindItem) by prop name. */
|
|
1581
1661
|
bindings = computed(() => {
|
|
1582
1662
|
const el = this.rawElement();
|
|
@@ -1687,6 +1767,21 @@ class JrElement {
|
|
|
1687
1767
|
});
|
|
1688
1768
|
});
|
|
1689
1769
|
}
|
|
1770
|
+
// Count the writes that touch a path this element is bound to. Only an
|
|
1771
|
+
// element with bindings listens, and it reads them when a write arrives,
|
|
1772
|
+
// so a binding that moves (a repeat item that shifts) is followed without
|
|
1773
|
+
// subscribing again.
|
|
1774
|
+
effect((onCleanup) => {
|
|
1775
|
+
if (!this.bindings())
|
|
1776
|
+
return;
|
|
1777
|
+
const unsubscribe = this.state.subscribeChanges((changes) => {
|
|
1778
|
+
const paths = Object.values(untracked(this.bindings) ?? {});
|
|
1779
|
+
if (changes.some((change) => paths.some((path) => touches(change.path, path)))) {
|
|
1780
|
+
this.boundWrites.update((count) => count + 1);
|
|
1781
|
+
}
|
|
1782
|
+
});
|
|
1783
|
+
onCleanup(unsubscribe);
|
|
1784
|
+
});
|
|
1690
1785
|
// Warn (once per type) about unknown component types.
|
|
1691
1786
|
const warnedTypes = new Set();
|
|
1692
1787
|
effect(() => {
|
|
@@ -3622,97 +3717,6 @@ function injectChatUI(options) {
|
|
|
3622
3717
|
* - `ui-stream` / `chat-ui` — the two hooks, composed from the above.
|
|
3623
3718
|
*/
|
|
3624
3719
|
|
|
3625
|
-
/**
|
|
3626
|
-
* The schema for ngx-json-render.
|
|
3627
|
-
*
|
|
3628
|
-
* Defines:
|
|
3629
|
-
* - Spec: A flat tree of elements with keys, types, props, and children references
|
|
3630
|
-
* - Catalog: Components with props schemas, and optional actions
|
|
3631
|
-
*
|
|
3632
|
-
* This is the same spec grammar the other json-render renderers use, so
|
|
3633
|
-
* catalogs and specs are portable across frameworks.
|
|
3634
|
-
*/
|
|
3635
|
-
const schema = defineSchema((s) => ({
|
|
3636
|
-
// What the AI-generated SPEC looks like
|
|
3637
|
-
spec: s.object({
|
|
3638
|
-
/** Root element key */
|
|
3639
|
-
root: s.string(),
|
|
3640
|
-
/** Flat map of elements by key */
|
|
3641
|
-
elements: s.record(s.object({
|
|
3642
|
-
/** Component type from catalog */
|
|
3643
|
-
type: s.ref('catalog.components'),
|
|
3644
|
-
/** Component props */
|
|
3645
|
-
props: s.propsOf('catalog.components'),
|
|
3646
|
-
/** Child element keys (flat reference) */
|
|
3647
|
-
children: s.array(s.string()),
|
|
3648
|
-
/** Visibility condition */
|
|
3649
|
-
visible: { ...s.any(), ...s.optional() },
|
|
3650
|
-
/** Repeat children from a state array */
|
|
3651
|
-
repeat: { ...s.any(), ...s.optional() },
|
|
3652
|
-
})),
|
|
3653
|
-
}),
|
|
3654
|
-
// What the CATALOG must provide
|
|
3655
|
-
catalog: s.object({
|
|
3656
|
-
/** Component definitions */
|
|
3657
|
-
components: s.map({
|
|
3658
|
-
/** Zod schema for component props */
|
|
3659
|
-
props: s.zod(),
|
|
3660
|
-
/** Slots for this component. Use ['default'] for children, or named slots like ['header', 'footer'] */
|
|
3661
|
-
slots: s.array(s.string()),
|
|
3662
|
-
/** Description for AI generation hints */
|
|
3663
|
-
description: s.string(),
|
|
3664
|
-
/** Example prop values used in prompt examples (auto-generated from Zod schema if omitted) */
|
|
3665
|
-
example: s.any(),
|
|
3666
|
-
}),
|
|
3667
|
-
/** Action definitions (optional) */
|
|
3668
|
-
actions: s.map({
|
|
3669
|
-
/** Zod schema for action params */
|
|
3670
|
-
params: s.zod(),
|
|
3671
|
-
/** Description for AI generation hints */
|
|
3672
|
-
description: s.string(),
|
|
3673
|
-
}),
|
|
3674
|
-
}),
|
|
3675
|
-
}), {
|
|
3676
|
-
builtInActions: [
|
|
3677
|
-
{
|
|
3678
|
-
name: 'setState',
|
|
3679
|
-
description: 'Update a value in the state model at the given statePath. Params: { statePath: string, value: any }',
|
|
3680
|
-
},
|
|
3681
|
-
{
|
|
3682
|
-
name: 'pushState',
|
|
3683
|
-
description: 'Append an item to an array in state. Params: { statePath: string, value: any, clearStatePath?: string }. Value can contain {"$state":"/path"} refs and "$id" for auto IDs.',
|
|
3684
|
-
},
|
|
3685
|
-
{
|
|
3686
|
-
name: 'removeState',
|
|
3687
|
-
description: 'Remove an item from an array in state by index. Params: { statePath: string, index: number }',
|
|
3688
|
-
},
|
|
3689
|
-
{
|
|
3690
|
-
name: 'validateForm',
|
|
3691
|
-
description: 'Validate all registered form fields and write the result to state. Params: { statePath?: string }. Defaults to /formValidation. Result: { valid: boolean, errors: Record<string, string[]> }.',
|
|
3692
|
-
},
|
|
3693
|
-
{
|
|
3694
|
-
name: 'submitForm',
|
|
3695
|
-
description: "Validate all registered form fields and, only if every one passes, dispatch another action. Params: { action: string, params?: object, statePath?: string }. Writes the same { valid, errors } result as validateForm. Use this on a form's submit button: it is validateForm and the submit in one binding, and the submit is skipped when the form is invalid.",
|
|
3696
|
-
},
|
|
3697
|
-
],
|
|
3698
|
-
defaultRules: [
|
|
3699
|
-
// Element integrity
|
|
3700
|
-
"CRITICAL INTEGRITY CHECK: Before outputting ANY element that references children, you MUST have already output (or will output) each child as its own element. If an element has children: ['a', 'b'], then elements 'a' and 'b' MUST exist. A missing child element causes that entire branch of the UI to be invisible.",
|
|
3701
|
-
'SELF-CHECK: After generating all elements, mentally walk the tree from root. Every key in every children array must resolve to a defined element. If you find a gap, output the missing element immediately.',
|
|
3702
|
-
'REQUIRED FIELDS: Every element MUST include a "children" array. Leaf elements (text, badges, inputs, images) use an empty array: "children": []. Omitting "children" fails validation.',
|
|
3703
|
-
// Field placement
|
|
3704
|
-
'CRITICAL: The "visible" field goes on the ELEMENT object, NOT inside "props". Correct: {"type":"<ComponentName>","props":{},"visible":{"$state":"/tab","eq":"home"},"children":[...]}.',
|
|
3705
|
-
'CRITICAL: The "on" field goes on the ELEMENT object, NOT inside "props". Use on.press, on.change, on.submit etc. NEVER put action/actionParams inside props.',
|
|
3706
|
-
// State and data
|
|
3707
|
-
'When the user asks for a UI that displays data (e.g. blog posts, products, users), ALWAYS include a state field with realistic sample data. The state field is a top-level field on the spec (sibling of root/elements).',
|
|
3708
|
-
'When building repeating content backed by a state array (e.g. posts, products, items), use the "repeat" field on a container element. Example: { "type": "<ContainerComponent>", "props": {}, "repeat": { "statePath": "/posts", "key": "id" }, "children": ["post-card"] }. For a nested list stored on the enclosing item, use "repeat": { "statePath": { "$item": "comments" }, "key": "id" }. The $item statePath form is valid only inside another repeat. Inside repeated children, use { "$item": "field" } to read a field from the current item, and { "$index": true } for the current array index. For two-way binding to an item field use { "$bindItem": "completed" }. Do NOT hardcode individual elements for each array item.',
|
|
3709
|
-
// Design quality
|
|
3710
|
-
'Design with visual hierarchy: use container components to group content, heading components for section titles, proper spacing, and status indicators. ONLY use components from the AVAILABLE COMPONENTS list.',
|
|
3711
|
-
'For data-rich UIs, use multi-column layout components if available. For forms and single-column content, use vertical layout components. ONLY use components from the AVAILABLE COMPONENTS list.',
|
|
3712
|
-
'Always include realistic, professional-looking sample data. For blogs include 3-4 posts with varied titles, authors, dates, categories. For products include names, prices, images. Never leave data empty.',
|
|
3713
|
-
],
|
|
3714
|
-
});
|
|
3715
|
-
|
|
3716
3720
|
/*
|
|
3717
3721
|
* Public API Surface of ngx-json-render
|
|
3718
3722
|
*/
|
|
@@ -3722,5 +3726,5 @@ const schema = defineSchema((s) => ({
|
|
|
3722
3726
|
* Generated bundle index. Do not edit.
|
|
3723
3727
|
*/
|
|
3724
3728
|
|
|
3725
|
-
export { CONFIRM_CONTEXT, ELEMENT_KEY, JR_CONFIRM_DIALOG, JR_CONFIRM_LABELS, JrChildren, JrConfirmDialog, JrElement, JrRepeatScope, JsonRenderActionsService, JsonRenderRootContext, JsonRenderStateService, JsonRenderValidationService, JsonRenderer, RENDER_CONTEXT, REPEAT_SCOPE, applyPatch, buildSpecFromParts, checkSpec, createStoreSetState, defineRegistry, flatToTree, formatSpecCheckIssues, getTextFromParts, injectAction, injectActions, injectBoundProp, injectChatUI, injectConfirmContext, injectDevtoolsActive, injectElementKey, injectFieldValidation, injectRenderContext, injectRepeatScope, injectStateBinding, injectStateStore, injectStateValue, injectUIStream, injectValidation, isActionCancelled, jsonRenderMessage
|
|
3729
|
+
export { CONFIRM_CONTEXT, ELEMENT_KEY, JR_CONFIRM_DIALOG, JR_CONFIRM_LABELS, JrChildren, JrConfirmDialog, JrElement, JrRepeatScope, JsonRenderActionsService, JsonRenderRootContext, JsonRenderStateService, JsonRenderValidationService, JsonRenderer, RENDER_CONTEXT, REPEAT_SCOPE, applyPatch, buildSpecFromParts, checkSpec, createStoreSetState, defineRegistry, flatToTree, formatSpecCheckIssues, getTextFromParts, injectAction, injectActions, injectBoundProp, injectChatUI, injectConfirmContext, injectDevtoolsActive, injectElementKey, injectFieldValidation, injectRenderContext, injectRepeatScope, injectStateBinding, injectStateStore, injectStateValue, injectUIStream, injectValidation, isActionCancelled, jsonRenderMessage };
|
|
3726
3730
|
//# sourceMappingURL=ngx-json-render.mjs.map
|