@bike4mind/cli 0.2.64-worktree-refactor-extract-search-query-builders.21815 → 0.2.64

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 (85) hide show
  1. package/bin/bike4mind-cli.mjs +6 -6
  2. package/dist/BubblewrapRuntime-BHbtqvLx.mjs +72 -0
  3. package/dist/ConfigStore-CllM6jOf.mjs +8614 -0
  4. package/dist/ImageStore-DaKT_Ew8.mjs +202 -0
  5. package/dist/ProxyManager-Dl2nFk-A.mjs +259 -0
  6. package/dist/ProxyManager-kiOD1X8-.mjs +3 -0
  7. package/dist/SandboxOrchestrator-BEW3rqYi.mjs +159 -0
  8. package/dist/SandboxOrchestrator-CHZgSR3P.mjs +3 -0
  9. package/dist/SandboxRuntimeAdapter-C1B4t20N.mjs +57 -0
  10. package/dist/SandboxRuntimeAdapter-D7UAG13n.mjs +3 -0
  11. package/dist/SeatbeltRuntime-D4m0VOcD.mjs +116 -0
  12. package/dist/StderrViolationParser-D0afQ3-1.mjs +70 -0
  13. package/dist/ViolationLogStore-CZl35HcA.mjs +96 -0
  14. package/dist/bashExecute-BTkdqlSs-5foM20Lb.mjs +466 -0
  15. package/dist/commands/doctorCommand.mjs +101 -0
  16. package/dist/commands/headlessCommand.mjs +319 -0
  17. package/dist/commands/mcpCommand.mjs +218 -0
  18. package/dist/commands/updateCommand.mjs +40 -0
  19. package/dist/createFile-yQfh8uvk-I-yM5DxC.mjs +63 -0
  20. package/dist/deleteFile-DKHfnyny-G3b1Kj2T.mjs +66 -0
  21. package/dist/globFiles-D1en6joM-8jekiXdX.mjs +100 -0
  22. package/dist/grepSearch-aMamoBn_-DCJcY8JS.mjs +173 -0
  23. package/dist/index.mjs +6722 -0
  24. package/dist/pathValidation-Cgjh5WQO-DiCZTcq6.mjs +63 -0
  25. package/dist/store-Dw1nZX2Y.mjs +128 -0
  26. package/dist/store-nZExNOWX.mjs +3 -0
  27. package/dist/terminalSetup-rmr1P8KF.mjs +254 -0
  28. package/dist/tools-C6M5aW8W.mjs +20907 -0
  29. package/dist/treeSitterEngine-DCSXcm_3.mjs +309 -0
  30. package/dist/types-DBEjF9YS.mjs +59 -0
  31. package/dist/types-DK3P88Px.mjs +3 -0
  32. package/dist/updateChecker-Cu9dkHxV.mjs +120 -0
  33. package/package.json +10 -10
  34. package/dist/BubblewrapRuntime-PMIOLWKR.js +0 -71
  35. package/dist/HydrationEngine-YL2HWJ3V.js +0 -9
  36. package/dist/ImageStore-MMUOUPI2.js +0 -224
  37. package/dist/ProxyManager-HEB4TLVX.js +0 -7
  38. package/dist/SandboxOrchestrator-UIJ5GYBB.js +0 -8
  39. package/dist/SandboxRuntimeAdapter-FQ56MAB2.js +0 -13
  40. package/dist/SeatbeltRuntime-EE3TTLEP.js +0 -98
  41. package/dist/StderrViolationParser-7OYPM2DJ.js +0 -59
  42. package/dist/ViolationLogStore-RIIUVURH.js +0 -104
  43. package/dist/artifactExtractor-R7DIP2XO.js +0 -180
  44. package/dist/bashExecute-GLGLD3JD.js +0 -379
  45. package/dist/chunk-4BIBE3J7.js +0 -48
  46. package/dist/chunk-5LZS5CVJ.js +0 -161
  47. package/dist/chunk-BDQBOLYG.js +0 -120
  48. package/dist/chunk-BPFEGDC7.js +0 -192
  49. package/dist/chunk-EPIYC3LA.js +0 -13770
  50. package/dist/chunk-G4ZGEQFT.js +0 -250
  51. package/dist/chunk-GQGOWACU.js +0 -770
  52. package/dist/chunk-J6ZBI6TI.js +0 -1079
  53. package/dist/chunk-JW3JRHH7.js +0 -12433
  54. package/dist/chunk-KQAMBXAW.js +0 -163
  55. package/dist/chunk-KUVV2NAB.js +0 -19125
  56. package/dist/chunk-LTLJRF6I.js +0 -44
  57. package/dist/chunk-PFBYGCOW.js +0 -449
  58. package/dist/chunk-QWB6ZYY4.js +0 -48
  59. package/dist/chunk-SGPRXN4C.js +0 -245
  60. package/dist/chunk-UZUHPHZC.js +0 -95
  61. package/dist/chunk-WBE7SQUB.js +0 -241
  62. package/dist/chunk-Y4WOJJM3.js +0 -147
  63. package/dist/commands/doctorCommand.js +0 -87
  64. package/dist/commands/headlessCommand.js +0 -380
  65. package/dist/commands/mcpCommand.js +0 -203
  66. package/dist/commands/updateCommand.js +0 -42
  67. package/dist/create-C4VEEEYR.js +0 -12
  68. package/dist/createFile-6PSPLW6R.js +0 -71
  69. package/dist/deleteFile-AUSRLWIK.js +0 -73
  70. package/dist/formatConverter-5QEJDW24.js +0 -7
  71. package/dist/globFiles-TSRN64N2.js +0 -120
  72. package/dist/grepSearch-634XWZOJ.js +0 -216
  73. package/dist/index.js +0 -6779
  74. package/dist/llmMarkdownGenerator-Z6NB26TT.js +0 -371
  75. package/dist/markdownGenerator-SK2ZQQL4.js +0 -269
  76. package/dist/mementoService-N4IM6QAC.js +0 -12
  77. package/dist/notificationDeduplicator-HUC53NEW.js +0 -9
  78. package/dist/src-F4KZCAA2.js +0 -319
  79. package/dist/src-ISX322I7.js +0 -1101
  80. package/dist/store-CAB6BV3P.js +0 -11
  81. package/dist/subtractCredits-D4KEM6VU.js +0 -12
  82. package/dist/terminalSetup-C5FHMLC3.js +0 -214
  83. package/dist/treeSitterEngine-4SGFQDY3.js +0 -330
  84. package/dist/types-KB5NP6T4.js +0 -7
  85. package/dist/utils-JCHWDM4Z.js +0 -31
@@ -1,770 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- // ../../b4m-core/packages/services/dist/src/latticeService/DependencyTracker.js
4
- var DependencyTracker = class {
5
- constructor() {
6
- this.nodes = /* @__PURE__ */ new Map();
7
- this.topologicalOrder = null;
8
- this.hasChanges = true;
9
- }
10
- /**
11
- * Build the dependency graph from a rules store
12
- */
13
- build(rulesStore) {
14
- this.nodes.clear();
15
- this.topologicalOrder = null;
16
- this.hasChanges = true;
17
- for (const rule of rulesStore.rules) {
18
- if (!rule.enabled)
19
- continue;
20
- this.nodes.set(rule.id, {
21
- ruleId: rule.id,
22
- dependencies: new Set(rule.dependencies),
23
- dependents: /* @__PURE__ */ new Set()
24
- });
25
- }
26
- for (const node of this.nodes.values()) {
27
- for (const depId of node.dependencies) {
28
- const depNode = this.nodes.get(depId);
29
- if (depNode) {
30
- depNode.dependents.add(node.ruleId);
31
- }
32
- }
33
- }
34
- }
35
- /**
36
- * Add a single rule to the graph
37
- */
38
- addRule(rule) {
39
- if (!rule.enabled)
40
- return;
41
- this.nodes.set(rule.id, {
42
- ruleId: rule.id,
43
- dependencies: new Set(rule.dependencies),
44
- dependents: /* @__PURE__ */ new Set()
45
- });
46
- for (const depId of rule.dependencies) {
47
- const depNode = this.nodes.get(depId);
48
- if (depNode) {
49
- depNode.dependents.add(rule.id);
50
- }
51
- }
52
- this.hasChanges = true;
53
- this.topologicalOrder = null;
54
- }
55
- /**
56
- * Remove a rule from the graph
57
- */
58
- removeRule(ruleId) {
59
- const node = this.nodes.get(ruleId);
60
- if (!node)
61
- return;
62
- for (const depId of node.dependencies) {
63
- const depNode = this.nodes.get(depId);
64
- if (depNode) {
65
- depNode.dependents.delete(ruleId);
66
- }
67
- }
68
- for (const dependentId of node.dependents) {
69
- const dependentNode = this.nodes.get(dependentId);
70
- if (dependentNode) {
71
- dependentNode.dependencies.delete(ruleId);
72
- }
73
- }
74
- this.nodes.delete(ruleId);
75
- this.hasChanges = true;
76
- this.topologicalOrder = null;
77
- }
78
- /**
79
- * Update dependencies for a rule
80
- */
81
- updateDependencies(ruleId, newDependencies) {
82
- const node = this.nodes.get(ruleId);
83
- if (!node)
84
- return;
85
- for (const oldDepId of node.dependencies) {
86
- const oldDepNode = this.nodes.get(oldDepId);
87
- if (oldDepNode) {
88
- oldDepNode.dependents.delete(ruleId);
89
- }
90
- }
91
- node.dependencies = new Set(newDependencies);
92
- for (const newDepId of newDependencies) {
93
- const newDepNode = this.nodes.get(newDepId);
94
- if (newDepNode) {
95
- newDepNode.dependents.add(ruleId);
96
- }
97
- }
98
- this.hasChanges = true;
99
- this.topologicalOrder = null;
100
- }
101
- /**
102
- * Validate the dependency graph for cycles
103
- */
104
- validate() {
105
- const errors = [];
106
- const cycles = [];
107
- const visited = /* @__PURE__ */ new Set();
108
- const recursionStack = /* @__PURE__ */ new Set();
109
- const path = [];
110
- const dfs = (ruleId) => {
111
- visited.add(ruleId);
112
- recursionStack.add(ruleId);
113
- path.push(ruleId);
114
- try {
115
- const node = this.nodes.get(ruleId);
116
- if (node) {
117
- for (const depId of node.dependencies) {
118
- if (!visited.has(depId)) {
119
- dfs(depId);
120
- } else if (recursionStack.has(depId)) {
121
- const cycleStart = path.indexOf(depId);
122
- const cycle = [...path.slice(cycleStart), depId];
123
- cycles.push(cycle);
124
- errors.push({
125
- type: "CIRCULAR_DEPENDENCY",
126
- message: `Circular dependency detected: ${cycle.join(" \u2192 ")}`,
127
- context: {
128
- relatedRules: cycle
129
- }
130
- });
131
- }
132
- }
133
- }
134
- } finally {
135
- path.pop();
136
- recursionStack.delete(ruleId);
137
- }
138
- };
139
- for (const ruleId of this.nodes.keys()) {
140
- if (!visited.has(ruleId)) {
141
- dfs(ruleId);
142
- }
143
- }
144
- return {
145
- isValid: cycles.length === 0,
146
- errors,
147
- cycles
148
- };
149
- }
150
- /**
151
- * Get topological order for computation (dependencies before dependents)
152
- */
153
- getComputationOrder() {
154
- if (this.topologicalOrder && !this.hasChanges) {
155
- return this.topologicalOrder;
156
- }
157
- const inDegree = /* @__PURE__ */ new Map();
158
- const queue = [];
159
- const result = [];
160
- for (const [ruleId, node] of this.nodes) {
161
- inDegree.set(ruleId, node.dependencies.size);
162
- if (node.dependencies.size === 0) {
163
- queue.push(ruleId);
164
- }
165
- }
166
- let qi = 0;
167
- while (qi < queue.length) {
168
- const ruleId = queue[qi++];
169
- result.push(ruleId);
170
- const node = this.nodes.get(ruleId);
171
- if (node) {
172
- for (const dependentId of node.dependents) {
173
- const degree = inDegree.get(dependentId) - 1;
174
- inDegree.set(dependentId, degree);
175
- if (degree === 0) {
176
- queue.push(dependentId);
177
- }
178
- }
179
- }
180
- }
181
- if (result.length !== this.nodes.size) {
182
- console.warn("Dependency graph contains cycles; returning partial order");
183
- }
184
- this.topologicalOrder = result;
185
- this.hasChanges = false;
186
- return result;
187
- }
188
- /**
189
- * Get all rules affected by changes to a specific rule
190
- */
191
- getAffectedBy(ruleId) {
192
- const node = this.nodes.get(ruleId);
193
- if (!node) {
194
- return { directlyAffected: [], transitivelyAffected: [] };
195
- }
196
- const directlyAffected = Array.from(node.dependents);
197
- const transitivelyAffected = /* @__PURE__ */ new Set();
198
- const queue = [...directlyAffected];
199
- while (queue.length > 0) {
200
- const currentId = queue.shift();
201
- if (transitivelyAffected.has(currentId))
202
- continue;
203
- transitivelyAffected.add(currentId);
204
- const currentNode = this.nodes.get(currentId);
205
- if (currentNode) {
206
- for (const dependentId of currentNode.dependents) {
207
- if (!transitivelyAffected.has(dependentId)) {
208
- queue.push(dependentId);
209
- }
210
- }
211
- }
212
- }
213
- return {
214
- directlyAffected,
215
- transitivelyAffected: Array.from(transitivelyAffected)
216
- };
217
- }
218
- /**
219
- * Get direct dependencies of a rule
220
- */
221
- getDependencies(ruleId) {
222
- const node = this.nodes.get(ruleId);
223
- return node ? Array.from(node.dependencies) : [];
224
- }
225
- /**
226
- * Get direct dependents of a rule
227
- */
228
- getDependents(ruleId) {
229
- const node = this.nodes.get(ruleId);
230
- return node ? Array.from(node.dependents) : [];
231
- }
232
- /**
233
- * Check if adding a dependency would create a cycle
234
- */
235
- wouldCreateCycle(fromRuleId, toRuleId) {
236
- const visited = /* @__PURE__ */ new Set();
237
- const queue = [toRuleId];
238
- while (queue.length > 0) {
239
- const currentId = queue.shift();
240
- if (currentId === fromRuleId)
241
- return true;
242
- if (visited.has(currentId))
243
- continue;
244
- visited.add(currentId);
245
- const node = this.nodes.get(currentId);
246
- if (node) {
247
- for (const depId of node.dependencies) {
248
- if (!visited.has(depId)) {
249
- queue.push(depId);
250
- }
251
- }
252
- }
253
- }
254
- return false;
255
- }
256
- /**
257
- * Get all rule IDs in the graph
258
- */
259
- getAllRuleIds() {
260
- return Array.from(this.nodes.keys());
261
- }
262
- /**
263
- * Get the number of rules in the graph
264
- */
265
- size() {
266
- return this.nodes.size;
267
- }
268
- /**
269
- * Clear the entire graph
270
- */
271
- clear() {
272
- this.nodes.clear();
273
- this.topologicalOrder = null;
274
- this.hasChanges = true;
275
- }
276
- /**
277
- * Export graph for debugging/visualization
278
- */
279
- toDebugString() {
280
- const lines = ["Dependency Graph:"];
281
- for (const [ruleId, node] of this.nodes) {
282
- const deps = Array.from(node.dependencies).join(", ") || "(none)";
283
- const dependents = Array.from(node.dependents).join(", ") || "(none)";
284
- lines.push(` ${ruleId}:`);
285
- lines.push(` depends on: ${deps}`);
286
- lines.push(` depended by: ${dependents}`);
287
- }
288
- return lines.join("\n");
289
- }
290
- };
291
- function createDependencyTracker(rulesStore) {
292
- const tracker = new DependencyTracker();
293
- if (rulesStore) {
294
- tracker.build(rulesStore);
295
- }
296
- return tracker;
297
- }
298
-
299
- // ../../b4m-core/packages/services/dist/src/latticeService/HydrationEngine.js
300
- var HydrationEngine = class {
301
- constructor() {
302
- this.dependencyTracker = createDependencyTracker();
303
- }
304
- /**
305
- * Hydrate (compute) all values from data and rules
306
- */
307
- hydrate(data, rules, options = {}) {
308
- const startTime = performance.now();
309
- const errors = [];
310
- this.dependencyTracker.build(rules);
311
- const validation = this.dependencyTracker.validate();
312
- if (!validation.isValid) {
313
- return {
314
- values: {},
315
- errors: validation.errors,
316
- duration: performance.now() - startTime,
317
- rulesEvaluated: 0
318
- };
319
- }
320
- const computedValues = this.initializeFromData(data, options.scenario);
321
- const context = {
322
- data,
323
- rules,
324
- computedValues,
325
- scenario: options.scenario,
326
- errors
327
- };
328
- let ruleOrder = this.dependencyTracker.getComputationOrder();
329
- if (options.partialRuleIds && options.partialRuleIds.length > 0) {
330
- const neededRules = this.getNeededRules(options.partialRuleIds);
331
- ruleOrder = ruleOrder.filter((id) => neededRules.has(id));
332
- }
333
- let rulesEvaluated = 0;
334
- for (const ruleId of ruleOrder) {
335
- const rule = rules.rules.find((r) => r.id === ruleId);
336
- if (!rule || !rule.enabled)
337
- continue;
338
- try {
339
- this.evaluateRule(rule, context);
340
- rulesEvaluated++;
341
- } catch (error) {
342
- errors.push({
343
- type: "INVALID_OPERATION",
344
- message: `Error evaluating rule "${rule.name}": ${error instanceof Error ? error.message : String(error)}`,
345
- context: { relatedRules: [ruleId] }
346
- });
347
- }
348
- }
349
- return {
350
- values: computedValues,
351
- errors,
352
- duration: performance.now() - startTime,
353
- rulesEvaluated
354
- };
355
- }
356
- /**
357
- * Initialize computed values from base data (including scenario overrides)
358
- */
359
- initializeFromData(data, scenario) {
360
- const values = {};
361
- for (const entity of data.entities) {
362
- values[entity.id] = {};
363
- for (const attr of entity.attributes) {
364
- if (!attr.isComputed) {
365
- values[entity.id][attr.key] = {
366
- value: attr.value,
367
- computedByRuleId: "base",
368
- computedAt: /* @__PURE__ */ new Date()
369
- };
370
- }
371
- }
372
- }
373
- if (scenario) {
374
- for (const override of scenario.overrides) {
375
- if (!values[override.entityId]) {
376
- values[override.entityId] = {};
377
- }
378
- values[override.entityId][override.attributeKey] = {
379
- value: override.value,
380
- computedByRuleId: `scenario:${scenario.id}`,
381
- computedAt: /* @__PURE__ */ new Date()
382
- };
383
- }
384
- }
385
- return values;
386
- }
387
- /**
388
- * Get all rules needed to compute the given rules (including dependencies)
389
- */
390
- getNeededRules(ruleIds) {
391
- const needed = /* @__PURE__ */ new Set();
392
- const addWithDependencies = (ruleId) => {
393
- if (needed.has(ruleId))
394
- return;
395
- needed.add(ruleId);
396
- const deps = this.dependencyTracker.getDependencies(ruleId);
397
- for (const depId of deps) {
398
- addWithDependencies(depId);
399
- }
400
- };
401
- for (const ruleId of ruleIds) {
402
- addWithDependencies(ruleId);
403
- }
404
- return needed;
405
- }
406
- /**
407
- * Evaluate a single rule and store results
408
- */
409
- evaluateRule(rule, context) {
410
- const { definition } = rule;
411
- const inputValues = this.resolveInputs(definition.inputs, context);
412
- if (definition.conditions && definition.conditions.length > 0) {
413
- const conditionsMet = this.evaluateConditions(definition.conditions, context);
414
- if (!conditionsMet)
415
- return;
416
- }
417
- const result = this.applyOperation(definition.operation, inputValues, context);
418
- const { targetEntityId, targetAttribute } = definition.output;
419
- if (!context.computedValues[targetEntityId]) {
420
- context.computedValues[targetEntityId] = {};
421
- }
422
- context.computedValues[targetEntityId][targetAttribute] = {
423
- value: result,
424
- computedByRuleId: rule.id,
425
- computedAt: /* @__PURE__ */ new Date()
426
- };
427
- }
428
- /**
429
- * Resolve input references to actual values
430
- */
431
- resolveInputs(inputs, context) {
432
- const values = [];
433
- for (const input of inputs) {
434
- switch (input.type) {
435
- case "literal":
436
- values.push(this.parseLiteral(input.ref));
437
- break;
438
- case "attribute":
439
- case "entity": {
440
- const [entityId, attrKey] = input.selector ? [input.ref, input.selector] : input.ref.split(".");
441
- const entityValues = context.computedValues[entityId];
442
- if (entityValues && attrKey in entityValues) {
443
- values.push(entityValues[attrKey].value);
444
- } else {
445
- values.push(null);
446
- }
447
- break;
448
- }
449
- case "rule": {
450
- const rule = context.rules.rules.find((r) => r.id === input.ref);
451
- if (rule) {
452
- const { targetEntityId, targetAttribute } = rule.definition.output;
453
- const entityValues = context.computedValues[targetEntityId];
454
- if (entityValues && targetAttribute in entityValues) {
455
- values.push(entityValues[targetAttribute].value);
456
- } else {
457
- values.push(null);
458
- }
459
- } else {
460
- values.push(null);
461
- }
462
- break;
463
- }
464
- case "range": {
465
- const rangeValues = this.resolveRange(input.ref, input.selector, context);
466
- values.push(...rangeValues);
467
- break;
468
- }
469
- default:
470
- values.push(null);
471
- }
472
- }
473
- return values;
474
- }
475
- /**
476
- * Resolve a range reference to multiple values
477
- */
478
- resolveRange(entityPattern, selector, context) {
479
- const values = [];
480
- if (entityPattern.includes("*")) {
481
- for (const [entityId, entityValues] of Object.entries(context.computedValues)) {
482
- if (this.matchesPattern(entityId, entityPattern)) {
483
- if (selector === "*") {
484
- values.push(...Object.values(entityValues).map((v) => v.value));
485
- } else if (selector) {
486
- if (selector in entityValues) {
487
- values.push(entityValues[selector].value);
488
- }
489
- }
490
- }
491
- }
492
- } else {
493
- const entityValues = context.computedValues[entityPattern];
494
- if (entityValues) {
495
- if (selector === "*") {
496
- values.push(...Object.values(entityValues).map((v) => v.value));
497
- }
498
- }
499
- }
500
- return values;
501
- }
502
- /**
503
- * Check if an entity ID matches a pattern
504
- */
505
- matchesPattern(entityId, pattern) {
506
- if (pattern === "*")
507
- return true;
508
- if (!pattern.includes("*"))
509
- return entityId === pattern;
510
- const regex = new RegExp("^" + pattern.replace(/\*/g, ".*") + "$");
511
- return regex.test(entityId);
512
- }
513
- /**
514
- * Parse a literal string to a value
515
- */
516
- parseLiteral(value) {
517
- const num = parseFloat(value);
518
- if (!isNaN(num))
519
- return num;
520
- if (value.toLowerCase() === "true")
521
- return true;
522
- if (value.toLowerCase() === "false")
523
- return false;
524
- return value;
525
- }
526
- /**
527
- * Evaluate rule conditions
528
- */
529
- evaluateConditions(conditions, context) {
530
- if (!conditions || conditions.length === 0)
531
- return true;
532
- let result = true;
533
- let currentJoin;
534
- for (const condition of conditions) {
535
- const leftValue = this.resolveInputs([condition.left], context)[0];
536
- const rightValue = this.resolveInputs([condition.right], context)[0];
537
- const conditionResult = this.evaluateComparison(leftValue, condition.operator, rightValue);
538
- if (currentJoin === "OR") {
539
- result = result || conditionResult;
540
- } else {
541
- result = result && conditionResult;
542
- }
543
- currentJoin = condition.logicalJoin;
544
- }
545
- return result;
546
- }
547
- /**
548
- * Evaluate a comparison
549
- */
550
- evaluateComparison(left, operator, right) {
551
- switch (operator) {
552
- case "==":
553
- return left === right;
554
- case "!=":
555
- return left !== right;
556
- case ">":
557
- return left > right;
558
- case "<":
559
- return left < right;
560
- case ">=":
561
- return left >= right;
562
- case "<=":
563
- return left <= right;
564
- case "contains":
565
- return String(left).includes(String(right));
566
- case "in":
567
- return Array.isArray(right) && right.includes(left);
568
- default:
569
- return false;
570
- }
571
- }
572
- /**
573
- * Apply an operation to input values
574
- */
575
- applyOperation(operation, inputs, context) {
576
- const numericInputs = inputs.filter((v) => v !== null && typeof v === "number").map((v) => v);
577
- switch (operation) {
578
- // Arithmetic
579
- case "ADD":
580
- return numericInputs.reduce((a, b) => a + b, 0);
581
- case "SUBTRACT":
582
- if (numericInputs.length === 0)
583
- return 0;
584
- return numericInputs.slice(1).reduce((a, b) => a - b, numericInputs[0]);
585
- case "MULTIPLY":
586
- return numericInputs.reduce((a, b) => a * b, 1);
587
- case "DIVIDE":
588
- if (numericInputs.length < 2 || numericInputs[1] === 0) {
589
- context.errors.push({
590
- type: "DIVISION_BY_ZERO",
591
- message: "Division by zero"
592
- });
593
- return null;
594
- }
595
- return numericInputs[0] / numericInputs[1];
596
- case "ABS":
597
- return numericInputs.length > 0 ? Math.abs(numericInputs[0]) : 0;
598
- case "ROUND": {
599
- if (numericInputs.length === 0)
600
- return 0;
601
- const decimals = numericInputs[1] ?? 0;
602
- const factor = Math.pow(10, decimals);
603
- return Math.round(numericInputs[0] * factor) / factor;
604
- }
605
- case "FLOOR":
606
- return numericInputs.length > 0 ? Math.floor(numericInputs[0]) : 0;
607
- case "CEIL":
608
- return numericInputs.length > 0 ? Math.ceil(numericInputs[0]) : 0;
609
- case "POWER":
610
- if (numericInputs.length < 2)
611
- return numericInputs[0] ?? 0;
612
- return Math.pow(numericInputs[0], numericInputs[1]);
613
- case "SQRT":
614
- return numericInputs.length > 0 ? Math.sqrt(numericInputs[0]) : 0;
615
- // Aggregation
616
- case "SUM":
617
- return numericInputs.reduce((a, b) => a + b, 0);
618
- case "AVERAGE":
619
- if (numericInputs.length === 0)
620
- return 0;
621
- return numericInputs.reduce((a, b) => a + b, 0) / numericInputs.length;
622
- case "MIN":
623
- return numericInputs.length > 0 ? Math.min(...numericInputs) : 0;
624
- case "MAX":
625
- return numericInputs.length > 0 ? Math.max(...numericInputs) : 0;
626
- case "COUNT":
627
- return inputs.filter((v) => v !== null).length;
628
- case "MEDIAN": {
629
- if (numericInputs.length === 0)
630
- return 0;
631
- const sorted = [...numericInputs].sort((a, b) => a - b);
632
- const mid = Math.floor(sorted.length / 2);
633
- return sorted.length % 2 === 0 ? (sorted[mid - 1] + sorted[mid]) / 2 : sorted[mid];
634
- }
635
- // Logical
636
- case "IF":
637
- return inputs[0] ? inputs[1] : inputs[2];
638
- case "AND":
639
- return inputs.every((v) => Boolean(v));
640
- case "OR":
641
- return inputs.some((v) => Boolean(v));
642
- case "NOT":
643
- return !inputs[0];
644
- case "EQUALS":
645
- return inputs.length >= 2 && inputs[0] === inputs[1];
646
- case "GREATER_THAN":
647
- return inputs.length >= 2 && inputs[0] > inputs[1];
648
- case "LESS_THAN":
649
- return inputs.length >= 2 && inputs[0] < inputs[1];
650
- case "GREATER_THAN_OR_EQUAL":
651
- return inputs.length >= 2 && inputs[0] >= inputs[1];
652
- case "LESS_THAN_OR_EQUAL":
653
- return inputs.length >= 2 && inputs[0] <= inputs[1];
654
- case "BETWEEN": {
655
- if (inputs.length < 3)
656
- return false;
657
- const val = inputs[0];
658
- const min = inputs[1];
659
- const max = inputs[2];
660
- return val >= min && val <= max;
661
- }
662
- // Financial
663
- case "PERCENT_OF":
664
- if (numericInputs.length < 2 || numericInputs[1] === 0)
665
- return 0;
666
- return numericInputs[0] / numericInputs[1] * 100;
667
- case "GROWTH_RATE":
668
- if (numericInputs.length < 2 || numericInputs[1] === 0)
669
- return 0;
670
- return (numericInputs[0] - numericInputs[1]) / numericInputs[1] * 100;
671
- case "NPV": {
672
- if (numericInputs.length < 2)
673
- return 0;
674
- const rate = numericInputs[0];
675
- const cashflows = numericInputs.slice(1);
676
- return cashflows.reduce((npv, cf, i) => npv + cf / Math.pow(1 + rate, i + 1), 0);
677
- }
678
- case "IRR":
679
- return this.calculateIRR(numericInputs);
680
- case "PMT": {
681
- if (numericInputs.length < 3)
682
- return 0;
683
- const [rate, nper, pv, fv = 0, type = 0] = numericInputs;
684
- if (rate === 0)
685
- return -(pv + fv) / nper;
686
- const pvif = Math.pow(1 + rate, nper);
687
- let pmt = rate * (pv * pvif + fv) / (pvif - 1);
688
- if (type === 1)
689
- pmt = pmt / (1 + rate);
690
- return -pmt;
691
- }
692
- case "FV": {
693
- if (numericInputs.length < 3)
694
- return 0;
695
- const [rate, nper, pmt, pv = 0, type = 0] = numericInputs;
696
- if (rate === 0)
697
- return -(pv + pmt * nper);
698
- const pvif = Math.pow(1 + rate, nper);
699
- let fv = -pv * pvif - pmt * (pvif - 1) / rate;
700
- if (type === 1)
701
- fv = fv - pmt * rate * nper;
702
- return fv;
703
- }
704
- case "PV": {
705
- if (numericInputs.length < 3)
706
- return 0;
707
- const [rate, nper, pmt, fv = 0, type = 0] = numericInputs;
708
- if (rate === 0)
709
- return -(fv + pmt * nper);
710
- const pvif = Math.pow(1 + rate, nper);
711
- let pv = (-fv - pmt * (pvif - 1) / rate) / pvif;
712
- if (type === 1)
713
- pv = pv / (1 + rate);
714
- return pv;
715
- }
716
- // Special
717
- case "REFERENCE":
718
- return inputs[0];
719
- // Pass through
720
- case "LOOKUP": {
721
- if (inputs.length < 2)
722
- return null;
723
- const index = inputs[0];
724
- return inputs[Math.min(index + 1, inputs.length - 1)];
725
- }
726
- default:
727
- context.errors.push({
728
- type: "INVALID_OPERATION",
729
- message: `Unknown operation: ${operation}`
730
- });
731
- return null;
732
- }
733
- }
734
- /**
735
- * Calculate IRR using Newton's method
736
- */
737
- calculateIRR(cashflows, guess = 0.1, maxIterations = 100, tolerance = 1e-4) {
738
- let rate = guess;
739
- for (let i = 0; i < maxIterations; i++) {
740
- let npv = 0;
741
- let dnpv = 0;
742
- for (let j = 0; j < cashflows.length; j++) {
743
- const factor = Math.pow(1 + rate, j);
744
- npv += cashflows[j] / factor;
745
- dnpv -= j * cashflows[j] / Math.pow(1 + rate, j + 1);
746
- }
747
- if (Math.abs(npv) < tolerance) {
748
- return rate;
749
- }
750
- if (dnpv === 0)
751
- break;
752
- rate = rate - npv / dnpv;
753
- }
754
- return rate;
755
- }
756
- /**
757
- * Get the dependency tracker (for advanced use cases)
758
- */
759
- getDependencyTracker() {
760
- return this.dependencyTracker;
761
- }
762
- };
763
- function createHydrationEngine() {
764
- return new HydrationEngine();
765
- }
766
-
767
- export {
768
- HydrationEngine,
769
- createHydrationEngine
770
- };