yaml-flow 2.4.0 → 2.6.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 +212 -0
- package/browser/card-compute.js +446 -0
- package/browser/live-cards.js +1381 -0
- package/browser/live-cards.schema.json +246 -0
- package/dist/card-compute/index.cjs +324 -0
- package/dist/card-compute/index.cjs.map +1 -0
- package/dist/card-compute/index.d.cts +68 -0
- package/dist/card-compute/index.d.ts +68 -0
- package/dist/card-compute/index.js +319 -0
- package/dist/card-compute/index.js.map +1 -0
- package/dist/{constants-DcCDDQON.d.ts → constants-BEbO2_OK.d.ts} +1 -1
- package/dist/{constants-Dbk6ArN5.d.cts → constants-BNjeIlZ8.d.cts} +1 -1
- package/dist/continuous-event-graph/index.d.cts +5 -135
- package/dist/continuous-event-graph/index.d.ts +5 -135
- package/dist/event-graph/index.d.cts +3 -3
- package/dist/event-graph/index.d.ts +3 -3
- package/dist/index.cjs +579 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -3
- package/dist/index.d.ts +6 -3
- package/dist/index.js +573 -5
- package/dist/index.js.map +1 -1
- package/dist/inference/index.cjs +450 -0
- package/dist/inference/index.cjs.map +1 -0
- package/dist/inference/index.d.cts +229 -0
- package/dist/inference/index.d.ts +229 -0
- package/dist/inference/index.js +443 -0
- package/dist/inference/index.js.map +1 -0
- package/dist/types-C2lOwquM.d.cts +135 -0
- package/dist/{types-CTu8RqY0.d.cts → types-DAI_a2as.d.cts} +11 -0
- package/dist/{types-CTu8RqY0.d.ts → types-DAI_a2as.d.ts} +11 -0
- package/dist/types-mS_pPftm.d.ts +135 -0
- package/package.json +13 -2
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"$id": "https://nsreehari.github.io/boards/live-cards.schema.json",
|
|
4
|
+
"title": "LiveCards Node Schema",
|
|
5
|
+
"description": "Schema for Card and ExternalSource nodes in the LiveCards Board/Canvas engine",
|
|
6
|
+
|
|
7
|
+
"definitions": {
|
|
8
|
+
|
|
9
|
+
"bind_ref": {
|
|
10
|
+
"description": "A state path reference, e.g. 'state.raw_quotes' or 'state.compute_vars.total'",
|
|
11
|
+
"type": "string",
|
|
12
|
+
"pattern": "^state\\."
|
|
13
|
+
},
|
|
14
|
+
|
|
15
|
+
"bind_or_literal": {
|
|
16
|
+
"description": "A literal value or a bind reference object",
|
|
17
|
+
"oneOf": [
|
|
18
|
+
{ "type": "string" },
|
|
19
|
+
{ "type": "number" },
|
|
20
|
+
{ "type": "boolean" },
|
|
21
|
+
{ "type": "array" },
|
|
22
|
+
{ "type": "object",
|
|
23
|
+
"properties": { "bind": { "$ref": "#/definitions/bind_ref" } },
|
|
24
|
+
"required": ["bind"]
|
|
25
|
+
}
|
|
26
|
+
]
|
|
27
|
+
},
|
|
28
|
+
|
|
29
|
+
"compute_expr": {
|
|
30
|
+
"description": "A declarative JSON compute expression",
|
|
31
|
+
"type": "object",
|
|
32
|
+
"required": ["fn"],
|
|
33
|
+
"properties": {
|
|
34
|
+
"fn": {
|
|
35
|
+
"type": "string",
|
|
36
|
+
"description": "Function name from the built-in vocabulary",
|
|
37
|
+
"enum": [
|
|
38
|
+
"sum", "avg", "min", "max", "count", "first", "last",
|
|
39
|
+
"add", "sub", "mul", "div", "round", "abs", "mod",
|
|
40
|
+
"gt", "gte", "lt", "lte", "eq", "neq",
|
|
41
|
+
"if", "and", "or", "not",
|
|
42
|
+
"concat", "upper", "lower", "template",
|
|
43
|
+
"filter", "pluck", "map", "sort", "slice", "flat", "unique", "group",
|
|
44
|
+
"get", "default",
|
|
45
|
+
"now", "diff_days", "format_date"
|
|
46
|
+
]
|
|
47
|
+
},
|
|
48
|
+
"input": {
|
|
49
|
+
"description": "state.path, literal, array of inputs, or nested compute_expr",
|
|
50
|
+
"oneOf": [
|
|
51
|
+
{ "type": "string" },
|
|
52
|
+
{ "type": "number" },
|
|
53
|
+
{ "type": "boolean" },
|
|
54
|
+
{ "type": "array" },
|
|
55
|
+
{ "$ref": "#/definitions/compute_expr" }
|
|
56
|
+
]
|
|
57
|
+
},
|
|
58
|
+
"field": { "type": "string", "description": "For pluck/sum/group — the object key to extract" },
|
|
59
|
+
"where": { "$ref": "#/definitions/compute_expr", "description": "For filter — predicate expression ($ = current item)" },
|
|
60
|
+
"cond": { "$ref": "#/definitions/compute_expr", "description": "For if — condition expression" },
|
|
61
|
+
"then": { "description": "For if — value when cond is truthy" },
|
|
62
|
+
"else": { "description": "For if — value when cond is falsy" },
|
|
63
|
+
"format": { "type": "string", "description": "For format_date — date format string" }
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
|
|
67
|
+
"meta": {
|
|
68
|
+
"type": "object",
|
|
69
|
+
"properties": {
|
|
70
|
+
"title": { "type": "string" },
|
|
71
|
+
"tags": { "type": "array", "items": { "type": "string" } }
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
|
|
75
|
+
"data": {
|
|
76
|
+
"type": "object",
|
|
77
|
+
"properties": {
|
|
78
|
+
"requires": {
|
|
79
|
+
"type": "array",
|
|
80
|
+
"items": { "type": "string" },
|
|
81
|
+
"description": "IDs of upstream nodes this node depends on"
|
|
82
|
+
},
|
|
83
|
+
"provides": {
|
|
84
|
+
"type": "object",
|
|
85
|
+
"description": "Subset of state exposed downstream. Keys are published names, values are bind refs.",
|
|
86
|
+
"additionalProperties": { "$ref": "#/definitions/bind_or_literal" }
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
|
|
91
|
+
"source_def": {
|
|
92
|
+
"type": "object",
|
|
93
|
+
"required": ["kind", "bindTo"],
|
|
94
|
+
"properties": {
|
|
95
|
+
"kind": { "enum": ["api", "websocket", "static", "llm"] },
|
|
96
|
+
"bindTo": { "$ref": "#/definitions/bind_ref", "description": "state path to write fetched data into" },
|
|
97
|
+
"method": { "enum": ["GET", "POST", "PUT", "DELETE"], "default": "GET" },
|
|
98
|
+
"url_template": { "type": "string", "description": "URL with {{var}} placeholders" },
|
|
99
|
+
"headers": { "type": "object", "additionalProperties": { "$ref": "#/definitions/bind_or_literal" } },
|
|
100
|
+
"body_template": { "type": "object", "description": "Request body with {{var}} placeholders or bind refs" },
|
|
101
|
+
"template_vars": {
|
|
102
|
+
"type": "object",
|
|
103
|
+
"additionalProperties": { "$ref": "#/definitions/bind_or_literal" },
|
|
104
|
+
"description": "Variables for url/body templates — static values or bind refs"
|
|
105
|
+
},
|
|
106
|
+
"poll_interval": { "type": "integer", "minimum": 0, "description": "Auto-refresh in seconds (0 = manual)" },
|
|
107
|
+
"transform": { "type": "string", "description": "Dot-path to extract from response, e.g. 'data.items'" }
|
|
108
|
+
}
|
|
109
|
+
},
|
|
110
|
+
|
|
111
|
+
"render_element": {
|
|
112
|
+
"type": "object",
|
|
113
|
+
"required": ["kind"],
|
|
114
|
+
"properties": {
|
|
115
|
+
"id": { "type": "string", "description": "Optional element ID for targeted updates" },
|
|
116
|
+
"kind": {
|
|
117
|
+
"enum": ["metric", "table", "chart", "form", "filter", "list",
|
|
118
|
+
"notes", "todo", "alert", "narrative", "badge", "text",
|
|
119
|
+
"markdown", "custom"]
|
|
120
|
+
},
|
|
121
|
+
"label": { "type": "string", "description": "Heading above this element" },
|
|
122
|
+
"className": { "type": "string", "description": "Bootstrap grid class, e.g. 'col-12 col-md-6'" },
|
|
123
|
+
"visible": { "type": "string", "description": "state path — element shown only if truthy" },
|
|
124
|
+
"data": {
|
|
125
|
+
"type": "object",
|
|
126
|
+
"properties": {
|
|
127
|
+
"bind": { "$ref": "#/definitions/bind_ref", "description": "state path to read data from" },
|
|
128
|
+
"writeTo": { "$ref": "#/definitions/bind_ref", "description": "state path for user input (form, filter, todo, notes)" },
|
|
129
|
+
"columns": { "type": "array", "items": { "type": "string" }, "description": "table: visible columns" },
|
|
130
|
+
"maxRows": { "type": "integer", "description": "table/list: max rows to display" },
|
|
131
|
+
"sortable": { "type": "boolean", "default": true, "description": "table: enable click-to-sort" },
|
|
132
|
+
"placeholder": { "type": "string", "description": "Empty-state message" },
|
|
133
|
+
"chartType": { "enum": ["bar", "line", "pie", "doughnut"] },
|
|
134
|
+
"chartOptions": { "type": "object", "description": "Chart.js options passthrough" },
|
|
135
|
+
"fields": { "type": "object", "description": "JSON Schema for form/filter fields" },
|
|
136
|
+
"thresholds": {
|
|
137
|
+
"type": "object",
|
|
138
|
+
"properties": {
|
|
139
|
+
"green": { "type": "string" },
|
|
140
|
+
"amber": { "type": "string" }
|
|
141
|
+
}
|
|
142
|
+
},
|
|
143
|
+
"colorMap": { "type": "object", "description": "badge: value → Bootstrap color" },
|
|
144
|
+
"style": { "enum": ["heading", "muted", "default"], "description": "text: display style" }
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
},
|
|
149
|
+
|
|
150
|
+
"view": {
|
|
151
|
+
"type": "object",
|
|
152
|
+
"required": ["elements"],
|
|
153
|
+
"properties": {
|
|
154
|
+
"elements": {
|
|
155
|
+
"type": "array",
|
|
156
|
+
"minItems": 1,
|
|
157
|
+
"items": { "$ref": "#/definitions/render_element" }
|
|
158
|
+
},
|
|
159
|
+
"layout": {
|
|
160
|
+
"type": "object",
|
|
161
|
+
"properties": {
|
|
162
|
+
"board": {
|
|
163
|
+
"type": "object",
|
|
164
|
+
"properties": {
|
|
165
|
+
"col": { "type": "integer", "minimum": 1, "maximum": 12 },
|
|
166
|
+
"order": { "type": "integer" }
|
|
167
|
+
}
|
|
168
|
+
},
|
|
169
|
+
"canvas": {
|
|
170
|
+
"type": "object",
|
|
171
|
+
"properties": {
|
|
172
|
+
"x": { "type": "number" },
|
|
173
|
+
"y": { "type": "number" },
|
|
174
|
+
"w": { "type": "number" },
|
|
175
|
+
"h": { "type": "number" }
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
},
|
|
180
|
+
"features": {
|
|
181
|
+
"type": "object",
|
|
182
|
+
"properties": {
|
|
183
|
+
"chat": { "type": "boolean", "default": false },
|
|
184
|
+
"notes": { "type": "boolean", "default": false },
|
|
185
|
+
"refresh": { "type": "boolean", "default": true }
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
},
|
|
191
|
+
|
|
192
|
+
"oneOf": [
|
|
193
|
+
{
|
|
194
|
+
"title": "Card",
|
|
195
|
+
"description": "A renderable card node with view elements",
|
|
196
|
+
"type": "object",
|
|
197
|
+
"required": ["id", "type", "view", "state"],
|
|
198
|
+
"additionalProperties": false,
|
|
199
|
+
"properties": {
|
|
200
|
+
"id": { "type": "string" },
|
|
201
|
+
"type": { "const": "card" },
|
|
202
|
+
"meta": { "$ref": "#/definitions/meta" },
|
|
203
|
+
"data": { "$ref": "#/definitions/data" },
|
|
204
|
+
"view": { "$ref": "#/definitions/view" },
|
|
205
|
+
"state": { "type": "object", "additionalProperties": true,
|
|
206
|
+
"properties": {
|
|
207
|
+
"status": { "enum": ["fresh", "stale", "loading", "error"] },
|
|
208
|
+
"lastRun": { "type": "string", "format": "date-time" },
|
|
209
|
+
"error": { "type": "string" }
|
|
210
|
+
}
|
|
211
|
+
},
|
|
212
|
+
"compute": {
|
|
213
|
+
"type": "object",
|
|
214
|
+
"description": "Derived state: key = state path to write, value = compute_expr",
|
|
215
|
+
"additionalProperties": { "$ref": "#/definitions/compute_expr" }
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
},
|
|
219
|
+
{
|
|
220
|
+
"title": "ExternalSource",
|
|
221
|
+
"description": "A data-only node that fetches from external systems (no view)",
|
|
222
|
+
"type": "object",
|
|
223
|
+
"required": ["id", "type", "source", "state"],
|
|
224
|
+
"additionalProperties": false,
|
|
225
|
+
"properties": {
|
|
226
|
+
"id": { "type": "string" },
|
|
227
|
+
"type": { "const": "source" },
|
|
228
|
+
"meta": { "$ref": "#/definitions/meta" },
|
|
229
|
+
"data": { "$ref": "#/definitions/data" },
|
|
230
|
+
"source": { "$ref": "#/definitions/source_def" },
|
|
231
|
+
"state": { "type": "object", "additionalProperties": true,
|
|
232
|
+
"properties": {
|
|
233
|
+
"status": { "enum": ["fresh", "stale", "loading", "error"] },
|
|
234
|
+
"lastRun": { "type": "string", "format": "date-time" },
|
|
235
|
+
"error": { "type": "string" }
|
|
236
|
+
}
|
|
237
|
+
},
|
|
238
|
+
"compute": {
|
|
239
|
+
"type": "object",
|
|
240
|
+
"description": "Derived state: key = state path to write, value = compute_expr",
|
|
241
|
+
"additionalProperties": { "$ref": "#/definitions/compute_expr" }
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
]
|
|
246
|
+
}
|
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
// src/card-compute/index.ts
|
|
6
|
+
function deepGet(obj, path) {
|
|
7
|
+
if (!path || !obj) return void 0;
|
|
8
|
+
const parts = path.split(".");
|
|
9
|
+
let cur = obj;
|
|
10
|
+
for (let i = 0; i < parts.length; i++) {
|
|
11
|
+
if (cur == null) return void 0;
|
|
12
|
+
cur = cur[parts[i]];
|
|
13
|
+
}
|
|
14
|
+
return cur;
|
|
15
|
+
}
|
|
16
|
+
function deepSet(obj, path, value) {
|
|
17
|
+
const parts = path.split(".");
|
|
18
|
+
let cur = obj;
|
|
19
|
+
for (let i = 0; i < parts.length - 1; i++) {
|
|
20
|
+
if (cur[parts[i]] == null || typeof cur[parts[i]] !== "object") cur[parts[i]] = {};
|
|
21
|
+
cur = cur[parts[i]];
|
|
22
|
+
}
|
|
23
|
+
cur[parts[parts.length - 1]] = value;
|
|
24
|
+
}
|
|
25
|
+
var _fns = {};
|
|
26
|
+
_fns.sum = (input, _e, opts) => {
|
|
27
|
+
const a = Array.isArray(input) ? input : [];
|
|
28
|
+
return opts.field ? a.reduce((s, r) => s + (Number(r[opts.field]) || 0), 0) : a.reduce((s, v) => s + (Number(v) || 0), 0);
|
|
29
|
+
};
|
|
30
|
+
_fns.avg = (input, _e, opts) => {
|
|
31
|
+
const s = _fns.sum(input, _e, opts);
|
|
32
|
+
const n = Array.isArray(input) ? input.length : 1;
|
|
33
|
+
return n ? s / n : 0;
|
|
34
|
+
};
|
|
35
|
+
_fns.min = (input, _e, opts) => {
|
|
36
|
+
const a = Array.isArray(input) ? input : [];
|
|
37
|
+
const vals = opts.field ? a.map((r) => Number(r[opts.field])) : a.map(Number);
|
|
38
|
+
return vals.length ? Math.min(...vals) : 0;
|
|
39
|
+
};
|
|
40
|
+
_fns.max = (input, _e, opts) => {
|
|
41
|
+
const a = Array.isArray(input) ? input : [];
|
|
42
|
+
const vals = opts.field ? a.map((r) => Number(r[opts.field])) : a.map(Number);
|
|
43
|
+
return vals.length ? Math.max(...vals) : 0;
|
|
44
|
+
};
|
|
45
|
+
_fns.count = (input) => Array.isArray(input) ? input.length : input != null ? 1 : 0;
|
|
46
|
+
_fns.first = (input) => Array.isArray(input) ? input[0] : input;
|
|
47
|
+
_fns.last = (input) => Array.isArray(input) ? input[input.length - 1] : input;
|
|
48
|
+
_fns.add = (input) => {
|
|
49
|
+
const a = Array.isArray(input) ? input : [];
|
|
50
|
+
return a.reduce((s, v) => s + Number(v), 0);
|
|
51
|
+
};
|
|
52
|
+
_fns.sub = (input) => {
|
|
53
|
+
const a = Array.isArray(input) ? input : [];
|
|
54
|
+
return a.length >= 2 ? Number(a[0]) - Number(a[1]) : 0;
|
|
55
|
+
};
|
|
56
|
+
_fns.mul = (input) => {
|
|
57
|
+
const a = Array.isArray(input) ? input : [];
|
|
58
|
+
return a.reduce((s, v) => s * Number(v), 1);
|
|
59
|
+
};
|
|
60
|
+
_fns.div = (input) => {
|
|
61
|
+
const a = Array.isArray(input) ? input : [];
|
|
62
|
+
return a.length >= 2 && Number(a[1]) !== 0 ? Number(a[0]) / Number(a[1]) : 0;
|
|
63
|
+
};
|
|
64
|
+
_fns.round = (input, _e, opts) => {
|
|
65
|
+
const decimals = opts.decimals != null ? opts.decimals : 0;
|
|
66
|
+
const factor = Math.pow(10, decimals);
|
|
67
|
+
return Math.round(Number(input) * factor) / factor;
|
|
68
|
+
};
|
|
69
|
+
_fns.abs = (input) => Math.abs(Number(input));
|
|
70
|
+
_fns.mod = (input) => {
|
|
71
|
+
const a = Array.isArray(input) ? input : [];
|
|
72
|
+
return a.length >= 2 ? Number(a[0]) % Number(a[1]) : 0;
|
|
73
|
+
};
|
|
74
|
+
_fns.gt = (input) => {
|
|
75
|
+
const a = Array.isArray(input) ? input : [];
|
|
76
|
+
return a.length >= 2 && Number(a[0]) > Number(a[1]);
|
|
77
|
+
};
|
|
78
|
+
_fns.gte = (input) => {
|
|
79
|
+
const a = Array.isArray(input) ? input : [];
|
|
80
|
+
return a.length >= 2 && Number(a[0]) >= Number(a[1]);
|
|
81
|
+
};
|
|
82
|
+
_fns.lt = (input) => {
|
|
83
|
+
const a = Array.isArray(input) ? input : [];
|
|
84
|
+
return a.length >= 2 && Number(a[0]) < Number(a[1]);
|
|
85
|
+
};
|
|
86
|
+
_fns.lte = (input) => {
|
|
87
|
+
const a = Array.isArray(input) ? input : [];
|
|
88
|
+
return a.length >= 2 && Number(a[0]) <= Number(a[1]);
|
|
89
|
+
};
|
|
90
|
+
_fns.eq = (input) => {
|
|
91
|
+
const a = Array.isArray(input) ? input : [];
|
|
92
|
+
return a.length >= 2 && a[0] === a[1];
|
|
93
|
+
};
|
|
94
|
+
_fns.neq = (input) => {
|
|
95
|
+
const a = Array.isArray(input) ? input : [];
|
|
96
|
+
return a.length >= 2 && a[0] !== a[1];
|
|
97
|
+
};
|
|
98
|
+
_fns.and = (input) => {
|
|
99
|
+
const a = Array.isArray(input) ? input : [];
|
|
100
|
+
return a.every(Boolean);
|
|
101
|
+
};
|
|
102
|
+
_fns.or = (input) => {
|
|
103
|
+
const a = Array.isArray(input) ? input : [];
|
|
104
|
+
return a.some(Boolean);
|
|
105
|
+
};
|
|
106
|
+
_fns.not = (input) => !input;
|
|
107
|
+
_fns.concat = (input) => {
|
|
108
|
+
const a = Array.isArray(input) ? input : [];
|
|
109
|
+
return a.map((v) => v != null ? String(v) : "").join("");
|
|
110
|
+
};
|
|
111
|
+
_fns.upper = (input) => String(input || "").toUpperCase();
|
|
112
|
+
_fns.lower = (input) => String(input || "").toLowerCase();
|
|
113
|
+
_fns.template = (input, _e, opts) => {
|
|
114
|
+
let t = String(opts.format || "");
|
|
115
|
+
if (input && typeof input === "object" && !Array.isArray(input)) {
|
|
116
|
+
for (const k of Object.keys(input)) {
|
|
117
|
+
const v = input[k];
|
|
118
|
+
t = t.split("{{" + k + "}}").join(v != null ? String(v) : "");
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return t;
|
|
122
|
+
};
|
|
123
|
+
_fns.join = (input, _e, opts) => {
|
|
124
|
+
const a = Array.isArray(input) ? input : [];
|
|
125
|
+
const sep = opts.separator != null ? String(opts.separator) : ", ";
|
|
126
|
+
return a.map((v) => v != null ? String(v) : "").join(sep);
|
|
127
|
+
};
|
|
128
|
+
_fns.split = (input, _e, opts) => {
|
|
129
|
+
const sep = opts.separator != null ? String(opts.separator) : ",";
|
|
130
|
+
return String(input || "").split(sep).map((s) => s.trim());
|
|
131
|
+
};
|
|
132
|
+
_fns.trim = (input) => String(input || "").trim();
|
|
133
|
+
_fns.pluck = (input, _e, opts) => Array.isArray(input) ? input.map((r) => r[opts.field]) : [];
|
|
134
|
+
_fns.filter = (input, _e, opts) => {
|
|
135
|
+
if (!Array.isArray(input)) return [];
|
|
136
|
+
if (opts.field) return input.filter((r) => !!r[opts.field]);
|
|
137
|
+
return input.filter(Boolean);
|
|
138
|
+
};
|
|
139
|
+
_fns.map = (input) => Array.isArray(input) ? input.slice() : [];
|
|
140
|
+
_fns.sort = (input, _e, opts) => {
|
|
141
|
+
const a = Array.isArray(input) ? input.slice() : [];
|
|
142
|
+
const f = opts.field;
|
|
143
|
+
const dir = opts.direction === "desc" ? -1 : 1;
|
|
144
|
+
if (f) return a.sort((x, y) => x[f] > y[f] ? dir : x[f] < y[f] ? -dir : 0);
|
|
145
|
+
return a.sort((x, y) => x > y ? dir : x < y ? -dir : 0);
|
|
146
|
+
};
|
|
147
|
+
_fns.slice = (input, _e, opts) => Array.isArray(input) ? input.slice(opts.start || 0, opts.end) : input;
|
|
148
|
+
_fns.flat = (input, _e, opts) => {
|
|
149
|
+
const depth = opts.depth != null ? opts.depth : 1;
|
|
150
|
+
return Array.isArray(input) ? input.flat(depth) : [input];
|
|
151
|
+
};
|
|
152
|
+
_fns.unique = (input) => {
|
|
153
|
+
if (!Array.isArray(input)) return [input];
|
|
154
|
+
const seen = /* @__PURE__ */ new Set();
|
|
155
|
+
return input.filter((v) => {
|
|
156
|
+
const key = typeof v === "object" ? JSON.stringify(v) : v;
|
|
157
|
+
if (seen.has(key)) return false;
|
|
158
|
+
seen.add(key);
|
|
159
|
+
return true;
|
|
160
|
+
});
|
|
161
|
+
};
|
|
162
|
+
_fns.group = (input, _e, opts) => {
|
|
163
|
+
const a = Array.isArray(input) ? input : [];
|
|
164
|
+
const g = {};
|
|
165
|
+
a.forEach((r) => {
|
|
166
|
+
const k = String(r[opts.field] || "");
|
|
167
|
+
if (!g[k]) g[k] = [];
|
|
168
|
+
g[k].push(r);
|
|
169
|
+
});
|
|
170
|
+
return g;
|
|
171
|
+
};
|
|
172
|
+
_fns.flatten_keys = (input) => {
|
|
173
|
+
if (!input || typeof input !== "object" || Array.isArray(input)) return [];
|
|
174
|
+
const result = [];
|
|
175
|
+
for (const k of Object.keys(input)) {
|
|
176
|
+
const vals = Array.isArray(input[k]) ? input[k] : [input[k]];
|
|
177
|
+
vals.forEach((v) => result.push({ key: k, value: v }));
|
|
178
|
+
}
|
|
179
|
+
return result;
|
|
180
|
+
};
|
|
181
|
+
_fns.entries = (input) => {
|
|
182
|
+
if (!input || typeof input !== "object" || Array.isArray(input)) return [];
|
|
183
|
+
return Object.keys(input).map((k) => ({ key: k, value: input[k] }));
|
|
184
|
+
};
|
|
185
|
+
_fns.from_entries = (input) => {
|
|
186
|
+
if (!Array.isArray(input)) return {};
|
|
187
|
+
const obj = {};
|
|
188
|
+
input.forEach((item) => {
|
|
189
|
+
if (item.key != null) obj[item.key] = item.value;
|
|
190
|
+
});
|
|
191
|
+
return obj;
|
|
192
|
+
};
|
|
193
|
+
_fns.length = (input) => {
|
|
194
|
+
if (Array.isArray(input)) return input.length;
|
|
195
|
+
if (typeof input === "string") return input.length;
|
|
196
|
+
if (input && typeof input === "object") return Object.keys(input).length;
|
|
197
|
+
return 0;
|
|
198
|
+
};
|
|
199
|
+
_fns.get = (input, _e, opts) => deepGet(input, opts.field || opts.path || "");
|
|
200
|
+
_fns.default = (input, _e, opts) => input != null ? input : opts.value;
|
|
201
|
+
_fns.coalesce = (input) => {
|
|
202
|
+
const a = Array.isArray(input) ? input : [];
|
|
203
|
+
for (let i = 0; i < a.length; i++) {
|
|
204
|
+
if (a[i] != null) return a[i];
|
|
205
|
+
}
|
|
206
|
+
return null;
|
|
207
|
+
};
|
|
208
|
+
_fns.now = () => (/* @__PURE__ */ new Date()).toISOString();
|
|
209
|
+
_fns.diff_days = (input) => {
|
|
210
|
+
const a = Array.isArray(input) ? input : [];
|
|
211
|
+
return a.length >= 2 ? Math.floor((new Date(a[0]).getTime() - new Date(a[1]).getTime()) / 864e5) : 0;
|
|
212
|
+
};
|
|
213
|
+
_fns.format_date = (input, _e, opts) => {
|
|
214
|
+
try {
|
|
215
|
+
const d = new Date(input);
|
|
216
|
+
if (opts.format === "iso") return d.toISOString();
|
|
217
|
+
if (opts.format === "date") return d.toLocaleDateString();
|
|
218
|
+
if (opts.format === "time") return d.toLocaleTimeString();
|
|
219
|
+
return d.toLocaleDateString();
|
|
220
|
+
} catch {
|
|
221
|
+
return String(input);
|
|
222
|
+
}
|
|
223
|
+
};
|
|
224
|
+
_fns.parse_date = (input) => {
|
|
225
|
+
try {
|
|
226
|
+
return new Date(input).toISOString();
|
|
227
|
+
} catch {
|
|
228
|
+
return null;
|
|
229
|
+
}
|
|
230
|
+
};
|
|
231
|
+
_fns.to_number = (input) => Number(input) || 0;
|
|
232
|
+
_fns.to_string = (input) => input != null ? String(input) : "";
|
|
233
|
+
_fns.to_bool = (input) => !!input;
|
|
234
|
+
_fns.type_of = (input) => Array.isArray(input) ? "array" : typeof input;
|
|
235
|
+
_fns.is_null = (input) => input == null;
|
|
236
|
+
_fns.is_empty = (input) => {
|
|
237
|
+
if (input == null) return true;
|
|
238
|
+
if (Array.isArray(input)) return input.length === 0;
|
|
239
|
+
if (typeof input === "string") return input.length === 0;
|
|
240
|
+
if (typeof input === "object") return Object.keys(input).length === 0;
|
|
241
|
+
return false;
|
|
242
|
+
};
|
|
243
|
+
var _customFns = {};
|
|
244
|
+
function evalExpr(expr, node) {
|
|
245
|
+
if (expr == null) return expr;
|
|
246
|
+
if (typeof expr !== "object" || Array.isArray(expr)) return expr;
|
|
247
|
+
const e = expr;
|
|
248
|
+
if (!e.fn) return expr;
|
|
249
|
+
let input = e.input;
|
|
250
|
+
if (typeof input === "string" && input.startsWith("state.")) {
|
|
251
|
+
input = deepGet(node, input);
|
|
252
|
+
} else if (Array.isArray(input)) {
|
|
253
|
+
input = input.map((v) => {
|
|
254
|
+
if (typeof v === "string" && v.startsWith("state.")) return deepGet(node, v);
|
|
255
|
+
if (v && typeof v === "object" && v.fn) return evalExpr(v, node);
|
|
256
|
+
return v;
|
|
257
|
+
});
|
|
258
|
+
} else if (input && typeof input === "object" && input.fn) {
|
|
259
|
+
input = evalExpr(input, node);
|
|
260
|
+
}
|
|
261
|
+
if (e.fn === "if") {
|
|
262
|
+
const cond = evalExpr(e.cond, node);
|
|
263
|
+
if (cond) {
|
|
264
|
+
return e.then && typeof e.then === "object" && e.then.fn ? evalExpr(e.then, node) : e.then;
|
|
265
|
+
} else {
|
|
266
|
+
return e.else && typeof e.else === "object" && e.else.fn ? evalExpr(e.else, node) : e.else;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
if (e.fn === "filter" && Array.isArray(input) && e.where) {
|
|
270
|
+
return input.filter((item) => {
|
|
271
|
+
const tmp = { state: { ...node.state, $: item } };
|
|
272
|
+
return evalExpr(e.where, tmp);
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
if (e.fn === "map" && Array.isArray(input) && e.apply) {
|
|
276
|
+
return input.map((item) => {
|
|
277
|
+
const tmp = { state: { ...node.state, $: item } };
|
|
278
|
+
return evalExpr(e.apply, tmp);
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
const fn = _customFns[e.fn] || _fns[e.fn];
|
|
282
|
+
if (!fn) {
|
|
283
|
+
console.warn('CardCompute: unknown function "' + e.fn + '"');
|
|
284
|
+
return void 0;
|
|
285
|
+
}
|
|
286
|
+
return fn(input, evalExpr, e);
|
|
287
|
+
}
|
|
288
|
+
function run(node) {
|
|
289
|
+
if (!node || !node.compute) return node;
|
|
290
|
+
if (!node.state) node.state = {};
|
|
291
|
+
for (const key of Object.keys(node.compute)) {
|
|
292
|
+
try {
|
|
293
|
+
const val = evalExpr(node.compute[key], node);
|
|
294
|
+
deepSet(node.state, key, val);
|
|
295
|
+
} catch (err) {
|
|
296
|
+
console.error(`CardCompute.run error on "${node.id || "?"}.${key}":`, err);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
return node;
|
|
300
|
+
}
|
|
301
|
+
function resolve(node, path) {
|
|
302
|
+
return deepGet(node, path);
|
|
303
|
+
}
|
|
304
|
+
function registerFunction(name, fn) {
|
|
305
|
+
_customFns[name] = fn;
|
|
306
|
+
}
|
|
307
|
+
var CardCompute = {
|
|
308
|
+
run,
|
|
309
|
+
eval: evalExpr,
|
|
310
|
+
resolve,
|
|
311
|
+
registerFunction,
|
|
312
|
+
get functions() {
|
|
313
|
+
const all = {};
|
|
314
|
+
for (const k of Object.keys(_fns)) all[k] = _fns[k];
|
|
315
|
+
for (const k of Object.keys(_customFns)) all[k] = _customFns[k];
|
|
316
|
+
return all;
|
|
317
|
+
}
|
|
318
|
+
};
|
|
319
|
+
var card_compute_default = CardCompute;
|
|
320
|
+
|
|
321
|
+
exports.CardCompute = CardCompute;
|
|
322
|
+
exports.default = card_compute_default;
|
|
323
|
+
//# sourceMappingURL=index.cjs.map
|
|
324
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/card-compute/index.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * card-compute — Pure JSON expression evaluator for node-based cards.\n *\n * Isomorphic: works in browser, Node.js, and bundlers.\n * No DOM dependency. No eval(). Pure declarative JSON expressions.\n *\n * @example\n * ```typescript\n * import { CardCompute } from 'yaml-flow/card-compute';\n *\n * const node = {\n * id: 'sales',\n * state: { data: [{ revenue: 100 }, { revenue: 200 }] },\n * compute: {\n * total: { fn: 'sum', input: 'state.data', field: 'revenue' },\n * avg: { fn: 'avg', input: 'state.data', field: 'revenue' },\n * },\n * };\n * CardCompute.run(node);\n * // node.state.total === 300\n * // node.state.avg === 150\n * ```\n */\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/** A compute expression — pure JSON, arbitrarily nestable. */\nexport interface ComputeExpr {\n fn: string;\n input?: string | number | boolean | ComputeExpr | (string | number | boolean | ComputeExpr)[];\n field?: string;\n where?: ComputeExpr;\n apply?: ComputeExpr;\n cond?: ComputeExpr;\n then?: unknown;\n else?: unknown;\n format?: string;\n decimals?: number;\n separator?: string;\n direction?: 'asc' | 'desc';\n start?: number;\n end?: number;\n depth?: number;\n path?: string;\n value?: unknown;\n [key: string]: unknown;\n}\n\n/** Minimal node shape expected by CardCompute. */\nexport interface ComputeNode {\n id?: string;\n state?: Record<string, unknown>;\n compute?: Record<string, ComputeExpr>;\n [key: string]: unknown;\n}\n\n/** Internal evaluator signature passed to compute functions. */\nexport type EvalFn = (expr: unknown, node: ComputeNode) => unknown;\n\n/** A compute function implementation. */\nexport type ComputeFn = (input: unknown, evalFn: EvalFn, opts: ComputeExpr) => unknown;\n\n// ---------------------------------------------------------------------------\n// Deep path utilities\n// ---------------------------------------------------------------------------\n\nfunction deepGet(obj: unknown, path: string): unknown {\n if (!path || !obj) return undefined;\n const parts = path.split('.');\n let cur: unknown = obj;\n for (let i = 0; i < parts.length; i++) {\n if (cur == null) return undefined;\n cur = (cur as Record<string, unknown>)[parts[i]];\n }\n return cur;\n}\n\nfunction deepSet(obj: Record<string, unknown>, path: string, value: unknown): void {\n const parts = path.split('.');\n let cur: Record<string, unknown> = obj;\n for (let i = 0; i < parts.length - 1; i++) {\n if (cur[parts[i]] == null || typeof cur[parts[i]] !== 'object') cur[parts[i]] = {};\n cur = cur[parts[i]] as Record<string, unknown>;\n }\n cur[parts[parts.length - 1]] = value;\n}\n\n// ---------------------------------------------------------------------------\n// Built-in functions (53)\n// ---------------------------------------------------------------------------\n\nconst _fns: Record<string, ComputeFn> = {};\n\n// ---- Aggregates ----\n\n_fns.sum = (input, _e, opts) => {\n const a = Array.isArray(input) ? input : [];\n return opts.field\n ? a.reduce((s, r) => s + (Number(r[opts.field!]) || 0), 0)\n : a.reduce((s, v) => s + (Number(v) || 0), 0);\n};\n\n_fns.avg = (input, _e, opts) => {\n const s = _fns.sum(input, _e, opts) as number;\n const n = Array.isArray(input) ? input.length : 1;\n return n ? s / n : 0;\n};\n\n_fns.min = (input, _e, opts) => {\n const a = Array.isArray(input) ? input : [];\n const vals = opts.field ? a.map(r => Number(r[opts.field!])) : a.map(Number);\n return vals.length ? Math.min(...vals) : 0;\n};\n\n_fns.max = (input, _e, opts) => {\n const a = Array.isArray(input) ? input : [];\n const vals = opts.field ? a.map(r => Number(r[opts.field!])) : a.map(Number);\n return vals.length ? Math.max(...vals) : 0;\n};\n\n_fns.count = (input) => Array.isArray(input) ? input.length : (input != null ? 1 : 0);\n_fns.first = (input) => Array.isArray(input) ? input[0] : input;\n_fns.last = (input) => Array.isArray(input) ? input[input.length - 1] : input;\n\n// ---- Math ----\n\n_fns.add = (input) => { const a = Array.isArray(input) ? input : []; return a.reduce((s, v) => s + Number(v), 0); };\n_fns.sub = (input) => { const a = Array.isArray(input) ? input : []; return a.length >= 2 ? Number(a[0]) - Number(a[1]) : 0; };\n_fns.mul = (input) => { const a = Array.isArray(input) ? input : []; return a.reduce((s, v) => s * Number(v), 1); };\n_fns.div = (input) => { const a = Array.isArray(input) ? input : []; return a.length >= 2 && Number(a[1]) !== 0 ? Number(a[0]) / Number(a[1]) : 0; };\n\n_fns.round = (input, _e, opts) => {\n const decimals = opts.decimals != null ? (opts.decimals as number) : 0;\n const factor = Math.pow(10, decimals);\n return Math.round(Number(input) * factor) / factor;\n};\n\n_fns.abs = (input) => Math.abs(Number(input));\n_fns.mod = (input) => { const a = Array.isArray(input) ? input : []; return a.length >= 2 ? Number(a[0]) % Number(a[1]) : 0; };\n\n// ---- Compare ----\n\n_fns.gt = (input) => { const a = Array.isArray(input) ? input : []; return a.length >= 2 && Number(a[0]) > Number(a[1]); };\n_fns.gte = (input) => { const a = Array.isArray(input) ? input : []; return a.length >= 2 && Number(a[0]) >= Number(a[1]); };\n_fns.lt = (input) => { const a = Array.isArray(input) ? input : []; return a.length >= 2 && Number(a[0]) < Number(a[1]); };\n_fns.lte = (input) => { const a = Array.isArray(input) ? input : []; return a.length >= 2 && Number(a[0]) <= Number(a[1]); };\n_fns.eq = (input) => { const a = Array.isArray(input) ? input : []; return a.length >= 2 && a[0] === a[1]; };\n_fns.neq = (input) => { const a = Array.isArray(input) ? input : []; return a.length >= 2 && a[0] !== a[1]; };\n\n// ---- Logic ----\n\n_fns.and = (input) => { const a = Array.isArray(input) ? input : []; return a.every(Boolean); };\n_fns.or = (input) => { const a = Array.isArray(input) ? input : []; return a.some(Boolean); };\n_fns.not = (input) => !input;\n// \"if\" is handled in evalExpr\n\n// ---- String ----\n\n_fns.concat = (input) => {\n const a = Array.isArray(input) ? input : [];\n return a.map(v => v != null ? String(v) : '').join('');\n};\n\n_fns.upper = (input) => String(input || '').toUpperCase();\n_fns.lower = (input) => String(input || '').toLowerCase();\n\n_fns.template = (input, _e, opts) => {\n let t = String(opts.format || '');\n if (input && typeof input === 'object' && !Array.isArray(input)) {\n for (const k of Object.keys(input as Record<string, unknown>)) {\n const v = (input as Record<string, unknown>)[k];\n t = t.split('{{' + k + '}}').join(v != null ? String(v) : '');\n }\n }\n return t;\n};\n\n_fns.join = (input, _e, opts) => {\n const a = Array.isArray(input) ? input : [];\n const sep = opts.separator != null ? String(opts.separator) : ', ';\n return a.map(v => v != null ? String(v) : '').join(sep);\n};\n\n_fns.split = (input, _e, opts) => {\n const sep = opts.separator != null ? String(opts.separator) : ',';\n return String(input || '').split(sep).map(s => s.trim());\n};\n\n_fns.trim = (input) => String(input || '').trim();\n\n// ---- Collection ----\n\n_fns.pluck = (input, _e, opts) => Array.isArray(input) ? input.map(r => r[opts.field!]) : [];\n\n_fns.filter = (input, _e, opts) => {\n if (!Array.isArray(input)) return [];\n if (opts.field) return input.filter(r => !!r[opts.field!]);\n return input.filter(Boolean);\n};\n\n_fns.map = (input) => Array.isArray(input) ? input.slice() : [];\n\n_fns.sort = (input, _e, opts) => {\n const a = Array.isArray(input) ? input.slice() : [];\n const f = opts.field;\n const dir = opts.direction === 'desc' ? -1 : 1;\n if (f) return a.sort((x, y) => x[f] > y[f] ? dir : x[f] < y[f] ? -dir : 0);\n return a.sort((x, y) => x > y ? dir : x < y ? -dir : 0);\n};\n\n_fns.slice = (input, _e, opts) => Array.isArray(input) ? input.slice(opts.start || 0, opts.end as number | undefined) : input;\n_fns.flat = (input, _e, opts) => {\n const depth = opts.depth != null ? (opts.depth as number) : 1;\n return Array.isArray(input) ? input.flat(depth) : [input];\n};\n\n_fns.unique = (input) => {\n if (!Array.isArray(input)) return [input];\n const seen = new Set<unknown>();\n return input.filter(v => {\n const key = typeof v === 'object' ? JSON.stringify(v) : v;\n if (seen.has(key)) return false;\n seen.add(key);\n return true;\n });\n};\n\n_fns.group = (input, _e, opts) => {\n const a = Array.isArray(input) ? input : [];\n const g: Record<string, unknown[]> = {};\n a.forEach(r => { const k = String(r[opts.field!] || ''); if (!g[k]) g[k] = []; g[k].push(r); });\n return g;\n};\n\n_fns.flatten_keys = (input) => {\n if (!input || typeof input !== 'object' || Array.isArray(input)) return [];\n const result: { key: string; value: unknown }[] = [];\n for (const k of Object.keys(input as Record<string, unknown>)) {\n const vals = Array.isArray((input as Record<string, unknown>)[k])\n ? (input as Record<string, unknown>)[k] as unknown[]\n : [(input as Record<string, unknown>)[k]];\n vals.forEach(v => result.push({ key: k, value: v }));\n }\n return result;\n};\n\n_fns.entries = (input) => {\n if (!input || typeof input !== 'object' || Array.isArray(input)) return [];\n return Object.keys(input as Record<string, unknown>).map(k => ({ key: k, value: (input as Record<string, unknown>)[k] }));\n};\n\n_fns.from_entries = (input) => {\n if (!Array.isArray(input)) return {};\n const obj: Record<string, unknown> = {};\n input.forEach(item => { if (item.key != null) obj[item.key] = item.value; });\n return obj;\n};\n\n_fns.length = (input) => {\n if (Array.isArray(input)) return input.length;\n if (typeof input === 'string') return input.length;\n if (input && typeof input === 'object') return Object.keys(input).length;\n return 0;\n};\n\n// ---- Lookup ----\n\n_fns.get = (input, _e, opts) => deepGet(input, opts.field || opts.path || '');\n_fns.default = (input, _e, opts) => input != null ? input : opts.value;\n_fns.coalesce = (input) => {\n const a = Array.isArray(input) ? input : [];\n for (let i = 0; i < a.length; i++) { if (a[i] != null) return a[i]; }\n return null;\n};\n\n// ---- Date ----\n\n_fns.now = () => new Date().toISOString();\n_fns.diff_days = (input) => {\n const a = Array.isArray(input) ? input : [];\n return a.length >= 2 ? Math.floor((new Date(a[0]).getTime() - new Date(a[1]).getTime()) / 86400000) : 0;\n};\n\n_fns.format_date = (input, _e, opts) => {\n try {\n const d = new Date(input as string);\n if (opts.format === 'iso') return d.toISOString();\n if (opts.format === 'date') return d.toLocaleDateString();\n if (opts.format === 'time') return d.toLocaleTimeString();\n return d.toLocaleDateString();\n } catch { return String(input); }\n};\n\n_fns.parse_date = (input) => {\n try { return new Date(input as string).toISOString(); } catch { return null; }\n};\n\n// ---- Type ----\n\n_fns.to_number = (input) => Number(input) || 0;\n_fns.to_string = (input) => input != null ? String(input) : '';\n_fns.to_bool = (input) => !!input;\n_fns.type_of = (input) => Array.isArray(input) ? 'array' : typeof input;\n_fns.is_null = (input) => input == null;\n_fns.is_empty = (input) => {\n if (input == null) return true;\n if (Array.isArray(input)) return input.length === 0;\n if (typeof input === 'string') return input.length === 0;\n if (typeof input === 'object') return Object.keys(input).length === 0;\n return false;\n};\n\n// ---------------------------------------------------------------------------\n// Custom function registry\n// ---------------------------------------------------------------------------\n\nconst _customFns: Record<string, ComputeFn> = {};\n\n// ---------------------------------------------------------------------------\n// Expression evaluator\n// ---------------------------------------------------------------------------\n\nfunction evalExpr(expr: unknown, node: ComputeNode): unknown {\n if (expr == null) return expr;\n if (typeof expr !== 'object' || Array.isArray(expr)) return expr;\n\n const e = expr as ComputeExpr;\n if (!e.fn) return expr;\n\n // Resolve input\n let input: unknown = e.input;\n if (typeof input === 'string' && input.startsWith('state.')) {\n input = deepGet(node, input);\n } else if (Array.isArray(input)) {\n input = input.map(v => {\n if (typeof v === 'string' && (v as string).startsWith('state.')) return deepGet(node, v as string);\n if (v && typeof v === 'object' && (v as ComputeExpr).fn) return evalExpr(v, node);\n return v;\n });\n } else if (input && typeof input === 'object' && (input as ComputeExpr).fn) {\n input = evalExpr(input, node);\n }\n\n // Special: if\n if (e.fn === 'if') {\n const cond = evalExpr(e.cond, node);\n if (cond) {\n return (e.then && typeof e.then === 'object' && (e.then as ComputeExpr).fn) ? evalExpr(e.then, node) : e.then;\n } else {\n return (e.else && typeof e.else === 'object' && (e.else as ComputeExpr).fn) ? evalExpr(e.else, node) : e.else;\n }\n }\n\n // Special: filter with where\n if (e.fn === 'filter' && Array.isArray(input) && e.where) {\n return (input as unknown[]).filter(item => {\n const tmp: ComputeNode = { state: { ...node.state, $: item } };\n return evalExpr(e.where, tmp);\n });\n }\n\n // Special: map with apply\n if (e.fn === 'map' && Array.isArray(input) && e.apply) {\n return (input as unknown[]).map(item => {\n const tmp: ComputeNode = { state: { ...node.state, $: item } };\n return evalExpr(e.apply as ComputeExpr, tmp);\n });\n }\n\n const fn = _customFns[e.fn] || _fns[e.fn];\n if (!fn) {\n console.warn('CardCompute: unknown function \"' + e.fn + '\"');\n return undefined;\n }\n\n return fn(input, evalExpr, e);\n}\n\n// ---------------------------------------------------------------------------\n// run — evaluate all node.compute declarations\n// ---------------------------------------------------------------------------\n\nfunction run(node: ComputeNode): ComputeNode {\n if (!node || !node.compute) return node;\n if (!node.state) node.state = {};\n\n for (const key of Object.keys(node.compute)) {\n try {\n const val = evalExpr(node.compute[key], node);\n deepSet(node.state, key, val);\n } catch (err) {\n console.error(`CardCompute.run error on \"${node.id || '?'}.${key}\":`, err);\n }\n }\n\n return node;\n}\n\n// ---------------------------------------------------------------------------\n// resolve — deep get from node\n// ---------------------------------------------------------------------------\n\nfunction resolve(node: ComputeNode, path: string): unknown {\n return deepGet(node, path);\n}\n\n// ---------------------------------------------------------------------------\n// registerFunction — extend the vocabulary\n// ---------------------------------------------------------------------------\n\nfunction registerFunction(name: string, fn: ComputeFn): void {\n _customFns[name] = fn;\n}\n\n// ---------------------------------------------------------------------------\n// Export\n// ---------------------------------------------------------------------------\n\nexport const CardCompute = {\n run,\n eval: evalExpr,\n resolve,\n registerFunction,\n get functions(): Record<string, ComputeFn> {\n const all: Record<string, ComputeFn> = {};\n for (const k of Object.keys(_fns)) all[k] = _fns[k];\n for (const k of Object.keys(_customFns)) all[k] = _customFns[k];\n return all;\n },\n};\n\nexport default CardCompute;\n"]}
|