import { parseExpression, evaluate } from '@revisium/formula';
// Simple arithmetic
parseExpression('price * 1.1');
// { minVersion: "1.0", features: [], dependencies: ["price"] }
evaluate('price * 1.1', { price: 100 });
// 110
// Nested object paths
parseExpression('stats.damage * multiplier');
// { minVersion: "1.1", features: ["nested_path"], dependencies: ["stats.damage", "multiplier"] }
evaluate('stats.damage * multiplier', { stats: { damage: 50 }, multiplier: 2 });
// 100
// Array index access
parseExpression('items[0].price + items[1].price');
// { minVersion: "1.1", features: ["array_index", "nested_path"], dependencies: ["items[0].price", "items[1].price"] }
evaluate('items[0].price + items[1].price', { items: [{ price: 10 }, { price: 20 }] });
// 30
// Comparisons
evaluate('price > 100', { price: 150 });
// true
// Fields named like functions
evaluate('max(max, 0)', { max: 10 });
// 10 (max() function is called with field "max" as argument)
evaluate('max(max - field.min, 0)', { max: 100, field: { min: 20 } });
// 80
// AST serialization (inverse of parseFormula)
import { parseFormula, serializeAst, replaceDependencies } from '@revisium/formula';
serializeAst(parseFormula('(a + b) * 2').ast);
// "(a + b) * 2"
serializeAst(parseFormula('a + b * 2').ast);
// "a + b * 2" (no unnecessary parentheses)
serializeAst(parseFormula('items[*].price').ast);
// "items[*].price"
// Dependency replacement
const ast = parseFormula('price * quantity + 10').ast;
const newAst = replaceDependencies(ast, { price: 'cost', quantity: 'qty' });
serializeAst(newAst);
// "cost * qty + 10"
// Replace with different path types
const ast2 = parseFormula('items[*].price * 2').ast;
const newAst2 = replaceDependencies(ast2, { 'items[*].price': 'products[*].cost' });
serializeAst(newAst2);
// "products[*].cost * 2"
// Type inference
import { inferFormulaType } from '@revisium/formula';
inferFormulaType('price * quantity', { price: 'number', quantity: 'number' });
// 'number'
inferFormulaType('price > 100');
// 'boolean'
// Array item formulas with path resolution
import { evaluateWithContext } from '@revisium/formula';
// Absolute path: /field always resolves from root data
evaluateWithContext('price * (1 + /taxRate)', {
rootData: { taxRate: 0.1, items: [{ price: 100 }] },
itemData: { price: 100 },
currentPath: 'items[0]'
});
// 110
// Relative path: ../field resolves from parent (root)
evaluateWithContext('price * (1 - ../discount)', {
rootData: { discount: 0.2, items: [] },
itemData: { price: 100 },
currentPath: 'items[0]'
});
// 80