@manifesto-ai/core 2.5.0 → 2.6.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.
Files changed (182) hide show
  1. package/README.md +8 -7
  2. package/dist/index.d.ts +1749 -19
  3. package/dist/index.js +18456 -36
  4. package/dist/index.js.map +1 -1
  5. package/package.json +2 -2
  6. package/dist/__tests__/apply.test.d.ts +0 -2
  7. package/dist/__tests__/apply.test.d.ts.map +0 -1
  8. package/dist/__tests__/apply.test.js +0 -279
  9. package/dist/__tests__/apply.test.js.map +0 -1
  10. package/dist/__tests__/defaults.test.d.ts +0 -2
  11. package/dist/__tests__/defaults.test.d.ts.map +0 -1
  12. package/dist/__tests__/defaults.test.js +0 -74
  13. package/dist/__tests__/defaults.test.js.map +0 -1
  14. package/dist/__tests__/jcs.test.d.ts +0 -2
  15. package/dist/__tests__/jcs.test.d.ts.map +0 -1
  16. package/dist/__tests__/jcs.test.js +0 -45
  17. package/dist/__tests__/jcs.test.js.map +0 -1
  18. package/dist/core/apply.d.ts +0 -17
  19. package/dist/core/apply.d.ts.map +0 -1
  20. package/dist/core/apply.js +0 -198
  21. package/dist/core/apply.js.map +0 -1
  22. package/dist/core/compute.d.ts +0 -17
  23. package/dist/core/compute.d.ts.map +0 -1
  24. package/dist/core/compute.js +0 -305
  25. package/dist/core/compute.js.map +0 -1
  26. package/dist/core/compute.test.d.ts +0 -2
  27. package/dist/core/compute.test.d.ts.map +0 -1
  28. package/dist/core/compute.test.js +0 -950
  29. package/dist/core/compute.test.js.map +0 -1
  30. package/dist/core/explain.d.ts +0 -14
  31. package/dist/core/explain.d.ts.map +0 -1
  32. package/dist/core/explain.js +0 -78
  33. package/dist/core/explain.js.map +0 -1
  34. package/dist/core/index.d.ts +0 -5
  35. package/dist/core/index.d.ts.map +0 -1
  36. package/dist/core/index.js +0 -5
  37. package/dist/core/index.js.map +0 -1
  38. package/dist/core/validate.d.ts +0 -16
  39. package/dist/core/validate.d.ts.map +0 -1
  40. package/dist/core/validate.js +0 -361
  41. package/dist/core/validate.js.map +0 -1
  42. package/dist/core/validate.test.d.ts +0 -2
  43. package/dist/core/validate.test.d.ts.map +0 -1
  44. package/dist/core/validate.test.js +0 -638
  45. package/dist/core/validate.test.js.map +0 -1
  46. package/dist/core/validation-utils.d.ts +0 -20
  47. package/dist/core/validation-utils.d.ts.map +0 -1
  48. package/dist/core/validation-utils.js +0 -292
  49. package/dist/core/validation-utils.js.map +0 -1
  50. package/dist/errors.d.ts +0 -30
  51. package/dist/errors.d.ts.map +0 -1
  52. package/dist/errors.js +0 -51
  53. package/dist/errors.js.map +0 -1
  54. package/dist/evaluator/computed.d.ts +0 -14
  55. package/dist/evaluator/computed.d.ts.map +0 -1
  56. package/dist/evaluator/computed.js +0 -60
  57. package/dist/evaluator/computed.js.map +0 -1
  58. package/dist/evaluator/context.d.ts +0 -62
  59. package/dist/evaluator/context.d.ts.map +0 -1
  60. package/dist/evaluator/context.js +0 -44
  61. package/dist/evaluator/context.js.map +0 -1
  62. package/dist/evaluator/dag.d.ts +0 -30
  63. package/dist/evaluator/dag.d.ts.map +0 -1
  64. package/dist/evaluator/dag.js +0 -121
  65. package/dist/evaluator/dag.js.map +0 -1
  66. package/dist/evaluator/expr.d.ts +0 -11
  67. package/dist/evaluator/expr.d.ts.map +0 -1
  68. package/dist/evaluator/expr.js +0 -667
  69. package/dist/evaluator/expr.js.map +0 -1
  70. package/dist/evaluator/expr.test.d.ts +0 -2
  71. package/dist/evaluator/expr.test.d.ts.map +0 -1
  72. package/dist/evaluator/expr.test.js +0 -508
  73. package/dist/evaluator/expr.test.js.map +0 -1
  74. package/dist/evaluator/flow.d.ts +0 -36
  75. package/dist/evaluator/flow.d.ts.map +0 -1
  76. package/dist/evaluator/flow.js +0 -390
  77. package/dist/evaluator/flow.js.map +0 -1
  78. package/dist/evaluator/flow.test.d.ts +0 -2
  79. package/dist/evaluator/flow.test.d.ts.map +0 -1
  80. package/dist/evaluator/flow.test.js +0 -499
  81. package/dist/evaluator/flow.test.js.map +0 -1
  82. package/dist/evaluator/index.d.ts +0 -6
  83. package/dist/evaluator/index.d.ts.map +0 -1
  84. package/dist/evaluator/index.js +0 -6
  85. package/dist/evaluator/index.js.map +0 -1
  86. package/dist/factories.d.ts +0 -22
  87. package/dist/factories.d.ts.map +0 -1
  88. package/dist/factories.js +0 -44
  89. package/dist/factories.js.map +0 -1
  90. package/dist/index.d.ts.map +0 -1
  91. package/dist/index.test.d.ts +0 -2
  92. package/dist/index.test.d.ts.map +0 -1
  93. package/dist/index.test.js +0 -14
  94. package/dist/index.test.js.map +0 -1
  95. package/dist/schema/action.d.ts +0 -14
  96. package/dist/schema/action.d.ts.map +0 -1
  97. package/dist/schema/action.js +0 -30
  98. package/dist/schema/action.js.map +0 -1
  99. package/dist/schema/common.d.ts +0 -37
  100. package/dist/schema/common.d.ts.map +0 -1
  101. package/dist/schema/common.js +0 -20
  102. package/dist/schema/common.js.map +0 -1
  103. package/dist/schema/computed.d.ts +0 -23
  104. package/dist/schema/computed.d.ts.map +0 -1
  105. package/dist/schema/computed.js +0 -34
  106. package/dist/schema/computed.js.map +0 -1
  107. package/dist/schema/defaults.d.ts +0 -12
  108. package/dist/schema/defaults.d.ts.map +0 -1
  109. package/dist/schema/defaults.js +0 -19
  110. package/dist/schema/defaults.js.map +0 -1
  111. package/dist/schema/domain.d.ts +0 -50
  112. package/dist/schema/domain.d.ts.map +0 -1
  113. package/dist/schema/domain.js +0 -60
  114. package/dist/schema/domain.js.map +0 -1
  115. package/dist/schema/expr.d.ts +0 -310
  116. package/dist/schema/expr.d.ts.map +0 -1
  117. package/dist/schema/expr.js +0 -289
  118. package/dist/schema/expr.js.map +0 -1
  119. package/dist/schema/field.d.ts +0 -48
  120. package/dist/schema/field.d.ts.map +0 -1
  121. package/dist/schema/field.js +0 -31
  122. package/dist/schema/field.js.map +0 -1
  123. package/dist/schema/flow.d.ts +0 -103
  124. package/dist/schema/flow.d.ts.map +0 -1
  125. package/dist/schema/flow.js +0 -82
  126. package/dist/schema/flow.js.map +0 -1
  127. package/dist/schema/host-context.d.ts +0 -12
  128. package/dist/schema/host-context.d.ts.map +0 -1
  129. package/dist/schema/host-context.js +0 -23
  130. package/dist/schema/host-context.js.map +0 -1
  131. package/dist/schema/index.d.ts +0 -15
  132. package/dist/schema/index.d.ts.map +0 -1
  133. package/dist/schema/index.js +0 -28
  134. package/dist/schema/index.js.map +0 -1
  135. package/dist/schema/patch.d.ts +0 -59
  136. package/dist/schema/patch.d.ts.map +0 -1
  137. package/dist/schema/patch.js +0 -60
  138. package/dist/schema/patch.js.map +0 -1
  139. package/dist/schema/result.d.ts +0 -142
  140. package/dist/schema/result.d.ts.map +0 -1
  141. package/dist/schema/result.js +0 -94
  142. package/dist/schema/result.js.map +0 -1
  143. package/dist/schema/snapshot.d.ts +0 -153
  144. package/dist/schema/snapshot.d.ts.map +0 -1
  145. package/dist/schema/snapshot.js +0 -160
  146. package/dist/schema/snapshot.js.map +0 -1
  147. package/dist/schema/trace.d.ts +0 -98
  148. package/dist/schema/trace.d.ts.map +0 -1
  149. package/dist/schema/trace.js +0 -90
  150. package/dist/schema/trace.js.map +0 -1
  151. package/dist/schema/type-spec.d.ts +0 -34
  152. package/dist/schema/type-spec.d.ts.map +0 -1
  153. package/dist/schema/type-spec.js +0 -40
  154. package/dist/schema/type-spec.js.map +0 -1
  155. package/dist/utils/canonical.d.ts +0 -37
  156. package/dist/utils/canonical.d.ts.map +0 -1
  157. package/dist/utils/canonical.js +0 -122
  158. package/dist/utils/canonical.js.map +0 -1
  159. package/dist/utils/canonical.test.d.ts +0 -2
  160. package/dist/utils/canonical.test.d.ts.map +0 -1
  161. package/dist/utils/canonical.test.js +0 -183
  162. package/dist/utils/canonical.test.js.map +0 -1
  163. package/dist/utils/hash.d.ts +0 -55
  164. package/dist/utils/hash.d.ts.map +0 -1
  165. package/dist/utils/hash.js +0 -183
  166. package/dist/utils/hash.js.map +0 -1
  167. package/dist/utils/hash.test.d.ts +0 -2
  168. package/dist/utils/hash.test.d.ts.map +0 -1
  169. package/dist/utils/hash.test.js +0 -253
  170. package/dist/utils/hash.test.js.map +0 -1
  171. package/dist/utils/index.d.ts +0 -4
  172. package/dist/utils/index.d.ts.map +0 -1
  173. package/dist/utils/index.js +0 -4
  174. package/dist/utils/index.js.map +0 -1
  175. package/dist/utils/path.d.ts +0 -40
  176. package/dist/utils/path.d.ts.map +0 -1
  177. package/dist/utils/path.js +0 -132
  178. package/dist/utils/path.js.map +0 -1
  179. package/dist/utils/path.test.d.ts +0 -2
  180. package/dist/utils/path.test.d.ts.map +0 -1
  181. package/dist/utils/path.test.js +0 -191
  182. package/dist/utils/path.test.js.map +0 -1
@@ -1,667 +0,0 @@
1
- import { ok, err } from "../schema/common.js";
2
- import { createError } from "../errors.js";
3
- import { getByPath } from "../utils/path.js";
4
- import { withCollectionContext } from "./context.js";
5
- /**
6
- * Evaluate an expression node
7
- * All expressions are pure and total (always return a value or error)
8
- */
9
- export function evaluateExpr(expr, ctx) {
10
- switch (expr.kind) {
11
- // Literals
12
- case "lit":
13
- return ok(expr.value);
14
- case "get":
15
- return evaluateGet(expr.path, ctx);
16
- // Comparison
17
- case "eq":
18
- return evaluateBinary(expr.left, expr.right, ctx, (a, b) => a === b);
19
- case "neq":
20
- return evaluateBinary(expr.left, expr.right, ctx, (a, b) => a !== b);
21
- case "gt":
22
- return evaluateBinary(expr.left, expr.right, ctx, (a, b) => toNumber(a) > toNumber(b));
23
- case "gte":
24
- return evaluateBinary(expr.left, expr.right, ctx, (a, b) => toNumber(a) >= toNumber(b));
25
- case "lt":
26
- return evaluateBinary(expr.left, expr.right, ctx, (a, b) => toNumber(a) < toNumber(b));
27
- case "lte":
28
- return evaluateBinary(expr.left, expr.right, ctx, (a, b) => toNumber(a) <= toNumber(b));
29
- // Logical
30
- case "and":
31
- return evaluateAnd(expr.args, ctx);
32
- case "or":
33
- return evaluateOr(expr.args, ctx);
34
- case "not":
35
- return evaluateNot(expr.arg, ctx);
36
- // Conditional
37
- case "if":
38
- return evaluateIf(expr, ctx);
39
- // Arithmetic
40
- case "add":
41
- return evaluateBinary(expr.left, expr.right, ctx, (a, b) => toNumber(a) + toNumber(b));
42
- case "sub":
43
- return evaluateBinary(expr.left, expr.right, ctx, (a, b) => toNumber(a) - toNumber(b));
44
- case "mul":
45
- return evaluateBinary(expr.left, expr.right, ctx, (a, b) => toNumber(a) * toNumber(b));
46
- case "div":
47
- return evaluateDiv(expr.left, expr.right, ctx);
48
- case "mod":
49
- return evaluateMod(expr.left, expr.right, ctx);
50
- case "min":
51
- return evaluateMin(expr.args, ctx);
52
- case "max":
53
- return evaluateMax(expr.args, ctx);
54
- case "abs":
55
- return evaluateAbs(expr.arg, ctx);
56
- case "neg":
57
- return evaluateNeg(expr.arg, ctx);
58
- // String
59
- case "concat":
60
- return evaluateConcat(expr.args, ctx);
61
- case "substring":
62
- return evaluateSubstring(expr, ctx);
63
- case "trim":
64
- return evaluateTrim(expr.str, ctx);
65
- // Collection
66
- case "len":
67
- return evaluateLen(expr.arg, ctx);
68
- case "at":
69
- return evaluateAt(expr.array, expr.index, ctx);
70
- case "first":
71
- return evaluateFirst(expr.array, ctx);
72
- case "last":
73
- return evaluateLast(expr.array, ctx);
74
- case "slice":
75
- return evaluateSlice(expr, ctx);
76
- case "includes":
77
- return evaluateIncludes(expr.array, expr.item, ctx);
78
- case "filter":
79
- return evaluateFilter(expr.array, expr.predicate, ctx);
80
- case "map":
81
- return evaluateMap(expr.array, expr.mapper, ctx);
82
- case "find":
83
- return evaluateFind(expr.array, expr.predicate, ctx);
84
- case "every":
85
- return evaluateEvery(expr.array, expr.predicate, ctx);
86
- case "some":
87
- return evaluateSome(expr.array, expr.predicate, ctx);
88
- case "append":
89
- return evaluateAppend(expr.array, expr.items, ctx);
90
- // Object
91
- case "object":
92
- return evaluateObject(expr.fields, ctx);
93
- case "field":
94
- return evaluateField(expr.object, expr.property, ctx);
95
- case "keys":
96
- return evaluateKeys(expr.obj, ctx);
97
- case "values":
98
- return evaluateValues(expr.obj, ctx);
99
- case "entries":
100
- return evaluateEntries(expr.obj, ctx);
101
- case "merge":
102
- return evaluateMerge(expr.objects, ctx);
103
- // Type
104
- case "typeof":
105
- return evaluateTypeof(expr.arg, ctx);
106
- case "isNull":
107
- return evaluateIsNull(expr.arg, ctx);
108
- case "coalesce":
109
- return evaluateCoalesce(expr.args, ctx);
110
- default:
111
- return err(createError("INTERNAL_ERROR", `Unknown expression kind: ${expr.kind}`, ctx.currentAction ?? "", ctx.nodePath, ctx.trace.timestamp));
112
- }
113
- }
114
- // ============ Helper Functions ============
115
- function toNumber(value) {
116
- if (typeof value === "number")
117
- return value;
118
- if (typeof value === "string")
119
- return parseFloat(value) || 0;
120
- if (typeof value === "boolean")
121
- return value ? 1 : 0;
122
- return 0;
123
- }
124
- function toBoolean(value) {
125
- if (value === null || value === undefined)
126
- return false;
127
- if (typeof value === "boolean")
128
- return value;
129
- if (typeof value === "number")
130
- return value !== 0;
131
- if (typeof value === "string")
132
- return value.length > 0;
133
- return true;
134
- }
135
- function toString(value) {
136
- if (value === null || value === undefined)
137
- return "";
138
- if (typeof value === "string")
139
- return value;
140
- return String(value);
141
- }
142
- // ============ Get ============
143
- /**
144
- * Generate a deterministic UUID from intentId and counter
145
- * Uses a simple hash to create reproducible UUIDs
146
- */
147
- function generateDeterministicUuid(intentId, counter) {
148
- // Create a simple hash-based UUID from intentId and counter
149
- // This ensures the same intentId + counter always produces the same UUID
150
- const seed = `${intentId}-${counter}`;
151
- let hash = 0;
152
- for (let i = 0; i < seed.length; i++) {
153
- const char = seed.charCodeAt(i);
154
- hash = ((hash << 5) - hash) + char;
155
- hash = hash & hash; // Convert to 32-bit integer
156
- }
157
- // Convert hash to hex string and format as UUID
158
- const hex = Math.abs(hash).toString(16).padStart(8, '0');
159
- const hex2 = Math.abs(hash * 31).toString(16).padStart(4, '0');
160
- const hex3 = Math.abs(hash * 37).toString(16).padStart(4, '0');
161
- const hex4 = Math.abs(hash * 41).toString(16).padStart(4, '0');
162
- const hex5 = Math.abs(hash * 43).toString(16).padStart(12, '0');
163
- return `${hex.slice(0, 8)}-${hex2.slice(0, 4)}-4${hex3.slice(1, 4)}-${hex4.slice(0, 4)}-${hex5.slice(0, 12)}`;
164
- }
165
- function evaluateGet(path, ctx) {
166
- // Handle collection context variables
167
- if (path.startsWith("$item")) {
168
- if (ctx.$item === undefined) {
169
- return ok(undefined);
170
- }
171
- if (path === "$item") {
172
- return ok(ctx.$item);
173
- }
174
- // e.g., $item.completed
175
- const subPath = path.slice(6); // Remove "$item."
176
- return ok(getByPath(ctx.$item, subPath));
177
- }
178
- if (path === "$index") {
179
- return ok(ctx.$index);
180
- }
181
- if (path === "$array") {
182
- return ok(ctx.$array);
183
- }
184
- // Handle $system paths (special runtime values)
185
- if (path.startsWith("$system.")) {
186
- const systemPath = path.slice(8); // Remove "$system."
187
- if (systemPath === "uuid") {
188
- // Generate deterministic UUID from intentId + counter
189
- const intentId = ctx.intentId ?? "no-intent";
190
- const counter = ctx.uuidCounter ?? 0;
191
- // Increment counter for next uuid call (mutable on purpose for determinism across calls)
192
- if (ctx.uuidCounter !== undefined) {
193
- ctx.uuidCounter = counter + 1;
194
- }
195
- return ok(generateDeterministicUuid(intentId, counter));
196
- }
197
- if (systemPath === "timestamp") {
198
- // Return the snapshot's timestamp (set by Host)
199
- return ok(new Date(ctx.snapshot.meta.timestamp).toISOString());
200
- }
201
- // Unknown $system path
202
- return ok(undefined);
203
- }
204
- // Handle meta path (snapshot metadata)
205
- if (path.startsWith("meta.")) {
206
- const metaPath = path.slice(5); // Remove "meta."
207
- if (metaPath === "intentId") {
208
- return ok(ctx.intentId);
209
- }
210
- if (metaPath === "actionName") {
211
- return ok(ctx.currentAction);
212
- }
213
- return ok(getByPath(ctx.snapshot.meta, metaPath));
214
- }
215
- // Handle input path
216
- if (path.startsWith("input.") || path === "input") {
217
- const subPath = path === "input" ? "" : path.slice(6);
218
- return ok(subPath ? getByPath(ctx.snapshot.input, subPath) : ctx.snapshot.input);
219
- }
220
- // Handle computed path
221
- if (path.startsWith("computed.")) {
222
- return ok(ctx.snapshot.computed[path]);
223
- }
224
- // Handle system path (snapshot.system, not $system)
225
- if (path.startsWith("system.")) {
226
- const subPath = path.slice(7);
227
- return ok(getByPath(ctx.snapshot.system, subPath));
228
- }
229
- // Default: get from data
230
- return ok(getByPath(ctx.snapshot.data, path));
231
- }
232
- // ============ Binary Operations ============
233
- function evaluateBinary(left, right, ctx, op) {
234
- const leftResult = evaluateExpr(left, ctx);
235
- if (!leftResult.ok)
236
- return leftResult;
237
- const rightResult = evaluateExpr(right, ctx);
238
- if (!rightResult.ok)
239
- return rightResult;
240
- return ok(op(leftResult.value, rightResult.value));
241
- }
242
- // ============ Logical ============
243
- function evaluateAnd(args, ctx) {
244
- for (const arg of args) {
245
- const result = evaluateExpr(arg, ctx);
246
- if (!result.ok)
247
- return result;
248
- if (!toBoolean(result.value))
249
- return ok(false);
250
- }
251
- return ok(true);
252
- }
253
- function evaluateOr(args, ctx) {
254
- for (const arg of args) {
255
- const result = evaluateExpr(arg, ctx);
256
- if (!result.ok)
257
- return result;
258
- if (toBoolean(result.value))
259
- return ok(true);
260
- }
261
- return ok(false);
262
- }
263
- function evaluateNot(arg, ctx) {
264
- const result = evaluateExpr(arg, ctx);
265
- if (!result.ok)
266
- return result;
267
- return ok(!toBoolean(result.value));
268
- }
269
- // ============ Conditional ============
270
- function evaluateIf(expr, ctx) {
271
- const condResult = evaluateExpr(expr.cond, ctx);
272
- if (!condResult.ok)
273
- return condResult;
274
- return evaluateExpr(toBoolean(condResult.value) ? expr.then : expr.else, ctx);
275
- }
276
- // ============ Arithmetic ============
277
- function evaluateDiv(left, right, ctx) {
278
- const leftResult = evaluateExpr(left, ctx);
279
- if (!leftResult.ok)
280
- return leftResult;
281
- const rightResult = evaluateExpr(right, ctx);
282
- if (!rightResult.ok)
283
- return rightResult;
284
- const divisor = toNumber(rightResult.value);
285
- if (divisor === 0)
286
- return ok(null); // Division by zero returns null, not error
287
- return ok(toNumber(leftResult.value) / divisor);
288
- }
289
- function evaluateMod(left, right, ctx) {
290
- const leftResult = evaluateExpr(left, ctx);
291
- if (!leftResult.ok)
292
- return leftResult;
293
- const rightResult = evaluateExpr(right, ctx);
294
- if (!rightResult.ok)
295
- return rightResult;
296
- const divisor = toNumber(rightResult.value);
297
- if (divisor === 0)
298
- return ok(null);
299
- return ok(toNumber(leftResult.value) % divisor);
300
- }
301
- function evaluateMin(args, ctx) {
302
- if (args.length === 0)
303
- return ok(null);
304
- const values = [];
305
- for (const arg of args) {
306
- const result = evaluateExpr(arg, ctx);
307
- if (!result.ok)
308
- return result;
309
- values.push(toNumber(result.value));
310
- }
311
- return ok(Math.min(...values));
312
- }
313
- function evaluateMax(args, ctx) {
314
- if (args.length === 0)
315
- return ok(null);
316
- const values = [];
317
- for (const arg of args) {
318
- const result = evaluateExpr(arg, ctx);
319
- if (!result.ok)
320
- return result;
321
- values.push(toNumber(result.value));
322
- }
323
- return ok(Math.max(...values));
324
- }
325
- function evaluateAbs(arg, ctx) {
326
- const result = evaluateExpr(arg, ctx);
327
- if (!result.ok)
328
- return result;
329
- return ok(Math.abs(toNumber(result.value)));
330
- }
331
- function evaluateNeg(arg, ctx) {
332
- const result = evaluateExpr(arg, ctx);
333
- if (!result.ok)
334
- return result;
335
- return ok(-toNumber(result.value));
336
- }
337
- // ============ String ============
338
- function evaluateConcat(args, ctx) {
339
- // First, evaluate all arguments to determine if this is array or string concat
340
- const values = [];
341
- for (const arg of args) {
342
- const result = evaluateExpr(arg, ctx);
343
- if (!result.ok)
344
- return result;
345
- values.push(result.value);
346
- }
347
- // If any argument is an array, treat as array concatenation
348
- const hasArray = values.some(v => Array.isArray(v));
349
- if (hasArray) {
350
- const result = [];
351
- for (const value of values) {
352
- if (Array.isArray(value)) {
353
- result.push(...value);
354
- }
355
- else if (value !== null && value !== undefined) {
356
- // Single value gets added as element
357
- result.push(value);
358
- }
359
- }
360
- return ok(result);
361
- }
362
- // Otherwise, string concatenation
363
- const parts = values.map(v => toString(v));
364
- return ok(parts.join(""));
365
- }
366
- function evaluateSubstring(expr, ctx) {
367
- const strResult = evaluateExpr(expr.str, ctx);
368
- if (!strResult.ok)
369
- return strResult;
370
- const startResult = evaluateExpr(expr.start, ctx);
371
- if (!startResult.ok)
372
- return startResult;
373
- const str = toString(strResult.value);
374
- const start = toNumber(startResult.value);
375
- if (expr.end) {
376
- const endResult = evaluateExpr(expr.end, ctx);
377
- if (!endResult.ok)
378
- return endResult;
379
- return ok(str.substring(start, toNumber(endResult.value)));
380
- }
381
- return ok(str.substring(start));
382
- }
383
- function evaluateTrim(str, ctx) {
384
- const result = evaluateExpr(str, ctx);
385
- if (!result.ok)
386
- return result;
387
- return ok(toString(result.value).trim());
388
- }
389
- // ============ Collection ============
390
- function evaluateLen(arg, ctx) {
391
- const result = evaluateExpr(arg, ctx);
392
- if (!result.ok)
393
- return result;
394
- const value = result.value;
395
- if (Array.isArray(value))
396
- return ok(value.length);
397
- if (typeof value === "string")
398
- return ok(value.length);
399
- if (typeof value === "object" && value !== null)
400
- return ok(Object.keys(value).length);
401
- return ok(0);
402
- }
403
- function evaluateAt(array, index, ctx) {
404
- const arrayResult = evaluateExpr(array, ctx);
405
- if (!arrayResult.ok)
406
- return arrayResult;
407
- const indexResult = evaluateExpr(index, ctx);
408
- if (!indexResult.ok)
409
- return indexResult;
410
- const base = arrayResult.value;
411
- const key = indexResult.value;
412
- // Array indexing: at(array, numericIndex)
413
- if (Array.isArray(base)) {
414
- const idx = toNumber(key);
415
- if (idx < 0 || idx >= base.length)
416
- return ok(null);
417
- return ok(base[idx]);
418
- }
419
- // Record lookup: at(record, stringKey)
420
- if (typeof base === "object" && base !== null && typeof key === "string") {
421
- return ok(base[key] ?? null);
422
- }
423
- return ok(null);
424
- }
425
- function evaluateFirst(array, ctx) {
426
- const result = evaluateExpr(array, ctx);
427
- if (!result.ok)
428
- return result;
429
- const arr = result.value;
430
- if (!Array.isArray(arr) || arr.length === 0)
431
- return ok(null);
432
- return ok(arr[0]);
433
- }
434
- function evaluateLast(array, ctx) {
435
- const result = evaluateExpr(array, ctx);
436
- if (!result.ok)
437
- return result;
438
- const arr = result.value;
439
- if (!Array.isArray(arr) || arr.length === 0)
440
- return ok(null);
441
- return ok(arr[arr.length - 1]);
442
- }
443
- function evaluateSlice(expr, ctx) {
444
- const arrayResult = evaluateExpr(expr.array, ctx);
445
- if (!arrayResult.ok)
446
- return arrayResult;
447
- const startResult = evaluateExpr(expr.start, ctx);
448
- if (!startResult.ok)
449
- return startResult;
450
- const arr = arrayResult.value;
451
- if (!Array.isArray(arr))
452
- return ok([]);
453
- const start = toNumber(startResult.value);
454
- if (expr.end) {
455
- const endResult = evaluateExpr(expr.end, ctx);
456
- if (!endResult.ok)
457
- return endResult;
458
- return ok(arr.slice(start, toNumber(endResult.value)));
459
- }
460
- return ok(arr.slice(start));
461
- }
462
- function evaluateIncludes(array, item, ctx) {
463
- const arrayResult = evaluateExpr(array, ctx);
464
- if (!arrayResult.ok)
465
- return arrayResult;
466
- const itemResult = evaluateExpr(item, ctx);
467
- if (!itemResult.ok)
468
- return itemResult;
469
- const arr = arrayResult.value;
470
- if (!Array.isArray(arr))
471
- return ok(false);
472
- return ok(arr.includes(itemResult.value));
473
- }
474
- function evaluateFilter(array, predicate, ctx) {
475
- const arrayResult = evaluateExpr(array, ctx);
476
- if (!arrayResult.ok)
477
- return arrayResult;
478
- const arr = arrayResult.value;
479
- if (!Array.isArray(arr))
480
- return ok([]);
481
- const filtered = [];
482
- for (let i = 0; i < arr.length; i++) {
483
- const itemCtx = withCollectionContext(ctx, arr[i], i, arr);
484
- const predicateResult = evaluateExpr(predicate, itemCtx);
485
- if (!predicateResult.ok)
486
- return predicateResult;
487
- if (toBoolean(predicateResult.value)) {
488
- filtered.push(arr[i]);
489
- }
490
- }
491
- return ok(filtered);
492
- }
493
- function evaluateMap(array, mapper, ctx) {
494
- const arrayResult = evaluateExpr(array, ctx);
495
- if (!arrayResult.ok)
496
- return arrayResult;
497
- const arr = arrayResult.value;
498
- if (!Array.isArray(arr))
499
- return ok([]);
500
- const mapped = [];
501
- for (let i = 0; i < arr.length; i++) {
502
- const itemCtx = withCollectionContext(ctx, arr[i], i, arr);
503
- const mapResult = evaluateExpr(mapper, itemCtx);
504
- if (!mapResult.ok)
505
- return mapResult;
506
- mapped.push(mapResult.value);
507
- }
508
- return ok(mapped);
509
- }
510
- function evaluateFind(array, predicate, ctx) {
511
- const arrayResult = evaluateExpr(array, ctx);
512
- if (!arrayResult.ok)
513
- return arrayResult;
514
- const arr = arrayResult.value;
515
- if (!Array.isArray(arr))
516
- return ok(null);
517
- for (let i = 0; i < arr.length; i++) {
518
- const itemCtx = withCollectionContext(ctx, arr[i], i, arr);
519
- const predicateResult = evaluateExpr(predicate, itemCtx);
520
- if (!predicateResult.ok)
521
- return predicateResult;
522
- if (toBoolean(predicateResult.value)) {
523
- return ok(arr[i]);
524
- }
525
- }
526
- return ok(null);
527
- }
528
- function evaluateEvery(array, predicate, ctx) {
529
- const arrayResult = evaluateExpr(array, ctx);
530
- if (!arrayResult.ok)
531
- return arrayResult;
532
- const arr = arrayResult.value;
533
- if (!Array.isArray(arr))
534
- return ok(true);
535
- for (let i = 0; i < arr.length; i++) {
536
- const itemCtx = withCollectionContext(ctx, arr[i], i, arr);
537
- const predicateResult = evaluateExpr(predicate, itemCtx);
538
- if (!predicateResult.ok)
539
- return predicateResult;
540
- if (!toBoolean(predicateResult.value)) {
541
- return ok(false);
542
- }
543
- }
544
- return ok(true);
545
- }
546
- function evaluateSome(array, predicate, ctx) {
547
- const arrayResult = evaluateExpr(array, ctx);
548
- if (!arrayResult.ok)
549
- return arrayResult;
550
- const arr = arrayResult.value;
551
- if (!Array.isArray(arr))
552
- return ok(false);
553
- for (let i = 0; i < arr.length; i++) {
554
- const itemCtx = withCollectionContext(ctx, arr[i], i, arr);
555
- const predicateResult = evaluateExpr(predicate, itemCtx);
556
- if (!predicateResult.ok)
557
- return predicateResult;
558
- if (toBoolean(predicateResult.value)) {
559
- return ok(true);
560
- }
561
- }
562
- return ok(false);
563
- }
564
- function evaluateAppend(array, items, ctx) {
565
- const arrayResult = evaluateExpr(array, ctx);
566
- if (!arrayResult.ok)
567
- return arrayResult;
568
- const arr = arrayResult.value;
569
- const baseArray = Array.isArray(arr) ? [...arr] : [];
570
- for (const itemExpr of items) {
571
- const itemResult = evaluateExpr(itemExpr, ctx);
572
- if (!itemResult.ok)
573
- return itemResult;
574
- baseArray.push(itemResult.value);
575
- }
576
- return ok(baseArray);
577
- }
578
- // ============ Object ============
579
- function evaluateObject(fields, ctx) {
580
- const result = {};
581
- for (const [key, valueExpr] of Object.entries(fields)) {
582
- const valueResult = evaluateExpr(valueExpr, ctx);
583
- if (!valueResult.ok)
584
- return valueResult;
585
- result[key] = valueResult.value;
586
- }
587
- return ok(result);
588
- }
589
- function evaluateField(objectExpr, property, ctx) {
590
- const result = evaluateExpr(objectExpr, ctx);
591
- if (!result.ok)
592
- return result;
593
- const obj = result.value;
594
- if (typeof obj !== "object" || obj === null || Array.isArray(obj))
595
- return ok(null);
596
- return ok(obj[property] ?? null);
597
- }
598
- function evaluateKeys(obj, ctx) {
599
- const result = evaluateExpr(obj, ctx);
600
- if (!result.ok)
601
- return result;
602
- const value = result.value;
603
- if (typeof value !== "object" || value === null)
604
- return ok([]);
605
- return ok(Object.keys(value));
606
- }
607
- function evaluateValues(obj, ctx) {
608
- const result = evaluateExpr(obj, ctx);
609
- if (!result.ok)
610
- return result;
611
- const value = result.value;
612
- if (typeof value !== "object" || value === null)
613
- return ok([]);
614
- return ok(Object.values(value));
615
- }
616
- function evaluateEntries(obj, ctx) {
617
- const result = evaluateExpr(obj, ctx);
618
- if (!result.ok)
619
- return result;
620
- const value = result.value;
621
- if (typeof value !== "object" || value === null)
622
- return ok([]);
623
- return ok(Object.entries(value));
624
- }
625
- function evaluateMerge(objects, ctx) {
626
- const merged = {};
627
- for (const objExpr of objects) {
628
- const result = evaluateExpr(objExpr, ctx);
629
- if (!result.ok)
630
- return result;
631
- const value = result.value;
632
- if (typeof value === "object" && value !== null && !Array.isArray(value)) {
633
- Object.assign(merged, value);
634
- }
635
- }
636
- return ok(merged);
637
- }
638
- // ============ Type ============
639
- function evaluateTypeof(arg, ctx) {
640
- const result = evaluateExpr(arg, ctx);
641
- if (!result.ok)
642
- return result;
643
- const value = result.value;
644
- if (value === null)
645
- return ok("null");
646
- if (Array.isArray(value))
647
- return ok("array");
648
- return ok(typeof value);
649
- }
650
- function evaluateIsNull(arg, ctx) {
651
- const result = evaluateExpr(arg, ctx);
652
- if (!result.ok)
653
- return result;
654
- return ok(result.value === null || result.value === undefined);
655
- }
656
- function evaluateCoalesce(args, ctx) {
657
- for (const arg of args) {
658
- const result = evaluateExpr(arg, ctx);
659
- if (!result.ok)
660
- return result;
661
- if (result.value !== null && result.value !== undefined) {
662
- return result;
663
- }
664
- }
665
- return ok(null);
666
- }
667
- //# sourceMappingURL=expr.js.map