json-renderers-build 1.3.6 → 1.5.1

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 ADDED
@@ -0,0 +1,374 @@
1
+ # json-renderers-build
2
+
3
+ > **Headless Component Specification Compiler for JSON-Driven UIs**
4
+ > Compiles structured data, columns, and declarative component blueprints into JSON-to-DOM specification ASTs (`specAsJsonToDom`) using `json-to-spec`.
5
+
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
7
+ [![Version](https://img.shields.io/badge/version-1.3.6-emerald.svg)](package.json)
8
+ [![Architecture: Headless](https://img.shields.io/badge/Architecture-Headless%20Spec%20Builder-indigo.svg)](#the-story-of-json-renderers-build)
9
+
10
+ ---
11
+
12
+ ## The Story of `json-renderers-build`
13
+
14
+ In the **KeshavSoft Declarative UI Ecosystem**, rendering is split cleanly into two distinct, decoupled responsibilities:
15
+
16
+ 1. **Specification Compilation (THIS REPO — `json-renderers-build`)**
17
+ Transforms raw data, field arrays, and UI blueprints (`skeleton.json`) into an abstract, deterministic DOM Specification tree (`specAsJsonToDom`).
18
+ 2. **DOM Instantiation & Mounting (Downstream — `json-renderers` / `@keshavsoft/json-to-tag`)**
19
+ Consumes that compiled specification tree and constructs real browser DOM nodes (`HTMLElement`), mounting them into target HTML containers.
20
+
21
+ ```
22
+ ┌────────────────────────────────────────────────────────────────────────┐
23
+ │ 1. Raw Business Data & Columns │
24
+ │ data: [{ id: 1, name: "Alpha" }], columns: ["Name"] │
25
+ └───────────────────────────────────┬────────────────────────────────────┘
26
+ │
27
+ ▼
28
+ ┌────────────────────────────────────────────────────────────────────────┐
29
+ │ 2. json-renderers-build (THIS REPO) │
30
+ │ • Pre-packaged component skeletons (table, select, selectOptions) │
31
+ │ • Compiles templates via json-to-spec compiler │
32
+ │ • 100% HEADLESS: Zero DOM queries, zero document mutations │
33
+ └───────────────────────────────────┬────────────────────────────────────┘
34
+ │ returns: specAsJsonToDom (JSON AST)
35
+ ▼
36
+ ┌────────────────────────────────────────────────────────────────────────┐
37
+ │ 3. Downstream DOM Runtime (json-renderers / @keshavsoft/json-to-tag) │
38
+ │ • Takes JSON AST │
39
+ │ • Produces real DOM nodes (HTMLTableElement, HTMLSelectElement) │
40
+ │ • Mounts into document.getElementById(targetHtmlId) │
41
+ └────────────────────────────────────────────────────────────────────────┘
42
+ ```
43
+
44
+ ### Why a Dedicated Spec Builder?
45
+
46
+ - **100% Headless & Isomorphic:** Runs anywhere JavaScript runs — in Node.js (for SSR or static site generation), in Web Workers, in browser contexts, or in command-line build tools.
47
+ - **Pure Functional Pipeline:** Given the same data and columns, it returns the exact same specification AST every time. No DOM dependencies or mock DOMs (`jsdom`) required for unit testing.
48
+ - **Blueprint Separation:** Component skeletons (`skeleton.json`) and transformation rules can evolve independently from DOM lifecycle and styling concerns.
49
+ - **Core Engine for `json-renderers`:** Downstream library `json-renderers` relies on `json-renderers-build` to generate its AST before mounting.
50
+
51
+ ---
52
+
53
+ ## Features
54
+
55
+ - **Config-Driven Spec Generation:** Converts simple arrays of data and columns into fully structured DOM specifications.
56
+ - **Pre-Packaged Blueprints (v3):**
57
+ - **`table`:** Full `<table>`, `<thead>`, `<tbody>` structure styled with standard Bootstrap classes (`table table-hover table-striped mb-0`).
58
+ - **`select`:** Full `<select id="LedgerName">` containing dynamic `<option>` child nodes.
59
+ - **`selectOptionsOnly`:** Option fragment spec (`{ children: [ ...options ] }`) designed to inject options into pre-existing select containers.
60
+ - **Global & ESM Distribution:** Usable via npm or directly in the browser via CDN script (`window.ks.jsonRenderersBuild`).
61
+ - **Standardized Parameter Architecture:** Adheres to KeshavSoft's `in`-prefixed parameter convention and `local`-variable scoping pattern.
62
+
63
+ ---
64
+
65
+ ## Installation
66
+
67
+ ### NPM
68
+
69
+ ```bash
70
+ npm install json-renderers-build
71
+ ```
72
+
73
+ ### Browser (CDN / ES Module)
74
+
75
+ ```html
76
+ <!-- Load ES module bundle directly from CDN -->
77
+ <script type="module" src="https://cdn.jsdelivr.net/gh/keshavsoft/json-renderers-build@main/docs/dist/v3/min.js"></script>
78
+ ```
79
+
80
+ When loaded via `<script type="module">`, it automatically registers globally on:
81
+ ```javascript
82
+ window.ks.jsonRenderersBuild = {
83
+ meta: {
84
+ version: "v3.0.0",
85
+ description: "build table from store data and render to DOM uses json-to-spec, json-to-dom under the hood"
86
+ },
87
+ renderToDom: [Function: render]
88
+ };
89
+ ```
90
+
91
+ ---
92
+
93
+ ## Quick Start & Usage
94
+
95
+ ### 1. Generating a Table Specification (`table`)
96
+
97
+ The `table` renderer generates a complete table specification AST including headers (`<th>`) and data cells (`<td>`).
98
+
99
+ ```javascript
100
+ import render from "json-renderers-build";
101
+
102
+ const records = [
103
+ { id: 101, name: "Alpha Enterprise", city: "Hyderabad" },
104
+ { id: 102, name: "Beta Logistics", city: "Bengaluru" }
105
+ ];
106
+
107
+ const columns = [
108
+ { title: "ID" },
109
+ { title: "Name" },
110
+ { title: "City" }
111
+ ];
112
+
113
+ const spec = render({
114
+ type: "table",
115
+ data: records,
116
+ columns: columns
117
+ });
118
+
119
+ console.log(spec);
120
+ ```
121
+
122
+ #### Compiled Output AST (`specAsJsonToDom`):
123
+ ```json
124
+ {
125
+ "tagName": "table",
126
+ "attributes": {
127
+ "class": "table table-hover table-striped mb-0"
128
+ },
129
+ "children": [
130
+ {
131
+ "tagName": "thead",
132
+ "children": [
133
+ {
134
+ "tagName": "tr",
135
+ "children": [
136
+ { "tagName": "th", "textContent": "ID" },
137
+ { "tagName": "th", "textContent": "Name" },
138
+ { "tagName": "th", "textContent": "City" }
139
+ ]
140
+ }
141
+ ]
142
+ },
143
+ {
144
+ "tagName": "tbody",
145
+ "children": [
146
+ {
147
+ "tagName": "tr",
148
+ "children": [
149
+ { "tagName": "td", "textContent": 101 },
150
+ { "tagName": "td", "textContent": "Alpha Enterprise" },
151
+ { "tagName": "td", "textContent": "Hyderabad" }
152
+ ]
153
+ },
154
+ {
155
+ "tagName": "tr",
156
+ "children": [
157
+ { "tagName": "td", "textContent": 102 },
158
+ { "tagName": "td", "textContent": "Beta Logistics" },
159
+ { "tagName": "td", "textContent": "Bengaluru" }
160
+ ]
161
+ }
162
+ ]
163
+ }
164
+ ]
165
+ }
166
+ ```
167
+
168
+ ---
169
+
170
+ ### 2. Generating a Select Dropdown Specification (`select`)
171
+
172
+ The `select` renderer creates a complete `<select>` specification populated with `<option>` elements.
173
+
174
+ ```javascript
175
+ import render from "json-renderers-build";
176
+
177
+ const spec = render({
178
+ type: "select",
179
+ data: ["Account Receivable", "Account Payable", "Sales Revenue"]
180
+ });
181
+
182
+ console.log(spec);
183
+ ```
184
+
185
+ #### Compiled Output AST:
186
+ ```json
187
+ {
188
+ "tagName": "select",
189
+ "attributes": {
190
+ "id": "LedgerName"
191
+ },
192
+ "children": [
193
+ {
194
+ "tagName": "option",
195
+ "attributes": { "value": "Account Receivable" },
196
+ "textContent": "Account Receivable"
197
+ },
198
+ {
199
+ "tagName": "option",
200
+ "attributes": { "value": "Account Payable" },
201
+ "textContent": "Account Payable"
202
+ },
203
+ {
204
+ "tagName": "option",
205
+ "attributes": { "value": "Sales Revenue" },
206
+ "textContent": "Sales Revenue"
207
+ }
208
+ ]
209
+ }
210
+ ```
211
+
212
+ ---
213
+
214
+ ### 3. Generating Options-Only Fragment Specification (`selectOptionsOnly`)
215
+
216
+ When you already have a `<select>` element in your markup and only want to dynamically generate its `<option>` items:
217
+
218
+ ```javascript
219
+ import render from "json-renderers-build";
220
+
221
+ const spec = render({
222
+ type: "selectOptionsOnly",
223
+ data: ["North", "South", "East", "West"]
224
+ });
225
+
226
+ console.log(spec);
227
+ ```
228
+
229
+ #### Compiled Output AST:
230
+ ```json
231
+ {
232
+ "children": [
233
+ {
234
+ "tagName": "option",
235
+ "attributes": { "value": "North" },
236
+ "textContent": "North"
237
+ },
238
+ {
239
+ "tagName": "option",
240
+ "attributes": { "value": "South" },
241
+ "textContent": "South"
242
+ },
243
+ {
244
+ "tagName": "option",
245
+ "attributes": { "value": "East" },
246
+ "textContent": "East"
247
+ },
248
+ {
249
+ "tagName": "option",
250
+ "attributes": { "value": "West" },
251
+ "textContent": "West"
252
+ }
253
+ ]
254
+ }
255
+ ```
256
+
257
+ ---
258
+
259
+ ## Consumer Integration: From Spec to DOM
260
+
261
+ To convert the specification returned by `json-renderers-build` into real DOM nodes, downstream consumers (such as `json-renderers`) pipe the AST into `@keshavsoft/json-to-tag`:
262
+
263
+ ```javascript
264
+ import renderSpec from "json-renderers-build";
265
+ import jsonToTag from "@keshavsoft/json-to-tag";
266
+
267
+ // Step 1: Compile specification AST (Headless)
268
+ const spec = renderSpec({
269
+ type: "table",
270
+ data: myRecords,
271
+ columns: ["Name", "Amount"]
272
+ });
273
+
274
+ // Step 2: Unwrap children if fragment
275
+ let jsonToSend = spec;
276
+ if (!("tagName" in spec) && "children" in spec) {
277
+ jsonToSend = spec.children;
278
+ }
279
+
280
+ // Step 3: Instantiate DOM elements
281
+ const domElement = jsonToTag(jsonToSend);
282
+
283
+ // Step 4: Mount into target container
284
+ const container = document.getElementById("my-container");
285
+ container.replaceChildren(domElement);
286
+ ```
287
+
288
+ ---
289
+
290
+ ## API Reference
291
+
292
+ ### `render(options)` / `default export`
293
+
294
+ The entry point exported by `json-renderers-build` accepts a single configuration object:
295
+
296
+ ```javascript
297
+ render({
298
+ type = "table",
299
+ data = [],
300
+ columns
301
+ })
302
+ ```
303
+
304
+ | Parameter | Type | Default | Description |
305
+ |---|---|---|---|
306
+ | `type` | `string` | `"table"` | Type of component spec to build: `"table"`, `"select"`, or `"selectOptionsOnly"`. |
307
+ | `data` | `Array` | `[]` | Data array. For `table`: array of row objects. For `select` / `selectOptionsOnly`: array of strings. |
308
+ | `columns` | `Array` | `undefined` | Header columns for `table`. Accepts an array of strings (e.g. `["Name"]`) or an array of objects (e.g. `[{ title: "Name" }]`). |
309
+
310
+ **Returns:** `Object` — Compiled JSON-to-DOM specification AST (`specAsJsonToDom`).
311
+
312
+ ---
313
+
314
+ ## Project Structure
315
+
316
+ ```text
317
+ json-renderers-build/
318
+ ├── docs/ # Documentation & distribution portal
319
+ │ ├── dist/ # Production bundles (Vite build)
320
+ │ │ ├── min.js # Latest ES bundle
321
+ │ │ ├── v2/min.js # v2 bundle
322
+ │ │ └── v3/min.js # v3 bundle
323
+ │ └── index.html # Interactive Documentation & Live Playground
324
+ ├── samples/ # Runnable browser verification samples
325
+ │ ├── table/ # Table spec compilation demo
326
+ │ ├── select/ # Select dropdown spec demo
327
+ │ └── selectOptionsOnly/ # Options fragment demo
328
+ ├── src/ # Source code
329
+ │ ├── index.js # Entry router (exports ./v3/index.js)
330
+ │ ├── v1/ # Legacy v1 (early coupled prototype)
331
+ │ ├── v2/ # Legacy v2 (intermediate spec refactor)
332
+ │ └── v3/ # CURRENT: Pure headless spec compiler
333
+ │ ├── common/ # Shared utilities (deriveColumnsFromData.js)
334
+ │ ├── select/ # Select builder (index.js, skeleton.json)
335
+ │ ├── selectOptionsOnly/# Options fragment builder (index.js, skeleton.json)
336
+ │ ├── table/ # Table builder (index.js, skeleton.json)
337
+ │ ├── meta.js # Version & metadata descriptor
338
+ │ ├── registerGlobal.js # Global window.ks namespace attachment
339
+ │ └── index.js # Component dispatcher map
340
+ ├── package.json # Package definition & scripts
341
+ ├── vite.config.js # Vite build configuration
342
+ └── README.md # Complete repository guide
343
+ ```
344
+
345
+ ---
346
+
347
+ ## Evolution Story
348
+
349
+ | Version | Status | Architectural Role |
350
+ |---|---|---|
351
+ | **v1** | Legacy | Early coupled implementation. Required `targetHtmlId` and directly executed DOM mounting using `jsonToTag`. |
352
+ | **v2** | Deprecated | Decoupled output to return `specAsJsonToDom`, but still retained legacy parameter baggage (`targetHtmlId`, `showLog`). |
353
+ | **v3** | **Current** | **Pure Headless Spec Compiler**. Clean functional API: `(type, data, columns) => spec`. Supports `table`, `select`, and `selectOptionsOnly`. Decoupled from DOM. |
354
+
355
+ ---
356
+
357
+ ## Development & Build
358
+
359
+ ```bash
360
+ # Install dependencies
361
+ npm install
362
+
363
+ # Start Vite development server
364
+ npm run dev
365
+
366
+ # Build production bundle (into docs/dist/v3/min.js and docs/dist/min.js)
367
+ npm run build
368
+ ```
369
+
370
+ ---
371
+
372
+ ## License
373
+
374
+ MIT © [KeshavSoft](https://github.com/keshavsoft)
@@ -0,0 +1,320 @@
1
+ const g = {
2
+ version: "v4.0.0",
3
+ description: "build table from store data and render to DOM uses json-to-spec, json-to-dom under the hood"
4
+ }, j = (t) => {
5
+ var r;
6
+ typeof globalThis > "u" || !t || (globalThis.ks ?? (globalThis.ks = {}), (r = globalThis.ks).jsonRenderersBuild ?? (r.jsonRenderersBuild = {
7
+ meta: g,
8
+ renderToDom: t
9
+ }));
10
+ }, E = {
11
+ version: "v32",
12
+ description: "JSON-to-DOM engine with centralized traversal and responsibility-focused construction"
13
+ }, N = ({ inFuncDefinition: t } = {}) => {
14
+ if (typeof globalThis > "u" || !t) return;
15
+ globalThis.ks ?? (globalThis.ks = {});
16
+ const r = {
17
+ meta: E,
18
+ buildSpecElement: t
19
+ };
20
+ globalThis.ks.jsonToSpec = r;
21
+ }, O = (t, r) => f(t, r), b = (t, r) => Array.isArray(t) ? t.map((e) => O(e, r)).flat(1 / 0).filter(Boolean) : [], x = (t, r) => {
22
+ if ("source" in t && (t == null ? void 0 : t.source) in r) {
23
+ const e = r[t == null ? void 0 : t.source];
24
+ if (Array.isArray(e))
25
+ return e.map((o) => {
26
+ const c = t == null ? void 0 : t.template;
27
+ if (c)
28
+ return f(c, o);
29
+ });
30
+ }
31
+ }, F = (t, r) => {
32
+ let e = [];
33
+ for (const [n, o] of Object.entries(r)) {
34
+ const c = t == null ? void 0 : t.template;
35
+ if (c) {
36
+ const a = f(c, {
37
+ key: n,
38
+ value: o
39
+ });
40
+ e.push(a);
41
+ }
42
+ }
43
+ return e;
44
+ }, R = (t, r) => {
45
+ if ("source" in t && (t == null ? void 0 : t.source) in r) {
46
+ const e = r[t == null ? void 0 : t.source];
47
+ if (Array.isArray(e))
48
+ return e.map((o) => {
49
+ const c = t == null ? void 0 : t.template;
50
+ if (c)
51
+ return f(c, o);
52
+ });
53
+ }
54
+ }, D = (t, r) => {
55
+ if ("operation" in t) {
56
+ if (t.operation === "loopArray")
57
+ return x(t, r);
58
+ if (t.operation === "loopObject")
59
+ return F(t, r);
60
+ if (t.operation === "loopCollection")
61
+ return R(t, r);
62
+ }
63
+ }, A = (t, r) => {
64
+ if (typeof r == "string") return r;
65
+ if (typeof t != "string") return t;
66
+ if (t === "${value}")
67
+ return r.value;
68
+ const e = t.match(/^\$\{(.+?)\}$/);
69
+ if (e) {
70
+ const n = e[1];
71
+ return (r == null ? void 0 : r[n]) ?? "";
72
+ }
73
+ return t;
74
+ }, k = (t, r) => {
75
+ let e = {};
76
+ for (const [n, o] of Object.entries(t)) {
77
+ const c = A(o, r);
78
+ e[n] = c;
79
+ }
80
+ return e;
81
+ }, C = (t, r) => {
82
+ if ("tagName" in t) {
83
+ if ("textContent" in t) {
84
+ const e = A(t.textContent, r);
85
+ t.textContent = e;
86
+ }
87
+ if ("attributes" in t) {
88
+ const e = k(t.attributes, r);
89
+ t.attributes = e;
90
+ }
91
+ }
92
+ }, w = (t, r) => {
93
+ if (!t || typeof t != "object" || Array.isArray(t)) return null;
94
+ const e = structuredClone(t);
95
+ if (!e) return null;
96
+ if ("tagName" in e && C(e, r), "jsonToSpec" in e) {
97
+ const n = e == null ? void 0 : e.jsonToSpec, o = D(n, r);
98
+ Array.isArray(o) ? e.children = o : e.children = [o], delete e.jsonToSpec;
99
+ }
100
+ if (Array.isArray(e == null ? void 0 : e.children)) {
101
+ const n = b(e == null ? void 0 : e.children, r);
102
+ e.children = n;
103
+ }
104
+ return e;
105
+ }, f = (t, r) => t == null ? null : typeof Node < "u" && t instanceof Node ? t : Array.isArray(t) ? b(t, r) : typeof t == "object" ? w(t, r) : typeof t == "string" || typeof t == "number" ? document.createTextNode(String(t)) : t, y = (t, r) => f(t, r);
106
+ N({
107
+ inFuncDefinition: y
108
+ });
109
+ const V = {
110
+ default: {
111
+ tagName: "table",
112
+ attributes: {
113
+ class: "table table-hover table-striped mb-0"
114
+ },
115
+ children: [
116
+ {
117
+ tagName: "thead",
118
+ children: [
119
+ {
120
+ tagName: "tr",
121
+ jsonToSpec: {
122
+ operation: "loopCollection",
123
+ source: "columns",
124
+ template: {
125
+ tagName: "th",
126
+ textContent: "${title}"
127
+ }
128
+ },
129
+ children: []
130
+ }
131
+ ]
132
+ },
133
+ {
134
+ tagName: "tbody",
135
+ jsonToSpec: {
136
+ operation: "loopCollection",
137
+ source: "data",
138
+ template: {
139
+ tagName: "tr",
140
+ jsonToSpec: {
141
+ operation: "loopObject",
142
+ source: "data",
143
+ template: {
144
+ tagName: "td",
145
+ textContent: "${value}"
146
+ }
147
+ },
148
+ children: []
149
+ }
150
+ },
151
+ children: []
152
+ }
153
+ ]
154
+ }
155
+ }, I = ({
156
+ inColumns: t,
157
+ inData: r
158
+ } = {}) => {
159
+ const e = r ?? [], n = t;
160
+ return y(V.default, {
161
+ columns: n,
162
+ data: e
163
+ });
164
+ }, K = "select", B = {
165
+ id: "LedgerName"
166
+ }, M = {
167
+ operation: "loopArray",
168
+ source: "arrayOfStrings",
169
+ template: {
170
+ tagName: "option",
171
+ attributes: {
172
+ value: "${}"
173
+ },
174
+ textContent: "${}"
175
+ }
176
+ }, T = [], G = {
177
+ tagName: K,
178
+ attributes: B,
179
+ jsonToSpec: M,
180
+ children: T
181
+ }, z = ({
182
+ inData: t
183
+ } = {}) => y(G, {
184
+ arrayOfStrings: t ?? []
185
+ }), $ = ({ inItems: t, inRecipe: r, inExecute: e }) => {
186
+ const n = t, o = r, c = e;
187
+ return n.map((a) => d({
188
+ inSource: a,
189
+ inRecipe: o,
190
+ inExecute: c
191
+ })).flat(1 / 0).filter(Boolean);
192
+ }, L = ({ inSource: t, inRecipe: r, inExecute: e }) => {
193
+ const n = t, o = r, c = e;
194
+ let a = n;
195
+ typeof c == "function" && (a = c({
196
+ inSource: n,
197
+ inRecipe: o
198
+ }));
199
+ for (const [l, u] of Object.entries(a))
200
+ Array.isArray(u) && o && l in o && (a[l] = $({
201
+ inItems: u,
202
+ inRecipe: o[l],
203
+ inExecute: c
204
+ }));
205
+ return a;
206
+ }, d = ({ inSource: t, inRecipe: r, inExecute: e }) => {
207
+ const n = t, o = r, c = e;
208
+ return Array.isArray(n) ? $({
209
+ inItems: n,
210
+ inRecipe: o,
211
+ inExecute: c
212
+ }) : typeof n == "object" && n !== null ? L({
213
+ inSource: n,
214
+ inRecipe: o,
215
+ inExecute: c
216
+ }) : n;
217
+ }, P = ({ inKey: t, inDirective: r }) => {
218
+ const e = t, n = r;
219
+ return (n == null ? void 0 : n.alterKey) || e;
220
+ }, U = ({ inValue: t, inDirective: r, inExecute: e }) => {
221
+ const n = t, o = r, c = e;
222
+ return o && "transform" in o ? d({
223
+ inSource: n,
224
+ inRecipe: o,
225
+ inExecute: c
226
+ }) : n;
227
+ }, _ = ({ inValue: t, inDirective: r }) => {
228
+ const e = t, n = r;
229
+ return (n == null ? void 0 : n.valueType) === "array" && !Array.isArray(e) ? [e] : e;
230
+ }, q = ({ inValue: t, inDirective: r }) => {
231
+ const e = t, n = r;
232
+ return n != null && n.valueKey && e && typeof e == "object" ? e[n.valueKey] : e;
233
+ }, H = ({ inSource: t, inTransform: r, inExecute: e }) => {
234
+ const n = t, o = r, c = e, a = {};
235
+ for (const [l, u] of Object.entries(n)) {
236
+ if (!(l in o))
237
+ continue;
238
+ const i = o[l], h = P({ inKey: l, inDirective: i });
239
+ let s = u;
240
+ s = U({
241
+ inValue: s,
242
+ inDirective: i,
243
+ inExecute: c
244
+ }), s = _({ inValue: s, inDirective: i }), s = q({ inValue: s, inDirective: i }), a[h] = s;
245
+ }
246
+ return a;
247
+ };
248
+ function v(t, r) {
249
+ for (const e in t)
250
+ typeof t[e] == "object" && t[e] !== null ? v(t[e], r) : typeof t[e] == "string" && t[e] === "${}" && (t[e] = r);
251
+ return t;
252
+ }
253
+ const Q = ({ inSource: t, inOperation: r, inExecute: e }) => {
254
+ const n = t, o = r;
255
+ for (const [c, a] of Object.entries(o))
256
+ if ("operationType" in a && a.operationType === "loopArray" && c in n) {
257
+ const l = n[c].map((u) => {
258
+ const i = { ...a == null ? void 0 : a.template };
259
+ return v(i, u), i;
260
+ });
261
+ n[c] = l;
262
+ }
263
+ return n;
264
+ }, m = ({ inSource: t, inRecipe: r }) => {
265
+ let e = t;
266
+ const n = r;
267
+ return n && typeof n == "object" && "transform" in n && (e = H({
268
+ inSource: e,
269
+ inTransform: n.transform,
270
+ inExecute: m
271
+ })), n && typeof n == "object" && "operation" in n && (e = Q({
272
+ inSource: e,
273
+ inOperation: n.operation,
274
+ inExecute: m
275
+ })), e;
276
+ }, W = (t, r) => d({
277
+ inSource: t,
278
+ inRecipe: r,
279
+ inExecute: m
280
+ }), X = {
281
+ children: ""
282
+ }, Y = {
283
+ children: {
284
+ operationType: "loopArray",
285
+ template: {
286
+ tagName: "option",
287
+ attributes: {
288
+ value: "${}"
289
+ },
290
+ textContent: "${}"
291
+ }
292
+ }
293
+ }, Z = {
294
+ transform: X,
295
+ operation: Y
296
+ }, S = ({
297
+ inData: t
298
+ } = {}) => W({
299
+ Children: t ?? []
300
+ }, Z), p = {
301
+ table: I,
302
+ select: z,
303
+ selectOptionsOnly: S
304
+ }, J = ({
305
+ type: t = "table",
306
+ data: r,
307
+ columns: e
308
+ } = {}) => {
309
+ const n = t, o = p[n];
310
+ return o ? o({
311
+ inColumns: e,
312
+ inData: r
313
+ }) : (console.error(
314
+ `[Renderer] Unknown renderer type "${n}". Available types: ${Object.keys(p).join(", ")}`
315
+ ), null);
316
+ };
317
+ j(J);
318
+ export {
319
+ J as default
320
+ };