@revisium/formula 0.1.0-alpha.1 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -9,6 +9,8 @@
9
9
 
10
10
  Formula expression parser and evaluator for [Revisium](https://revisium.io).
11
11
 
12
+ [**Specification**](./SPEC.md) • [**API Reference**](#api)
13
+
12
14
  </div>
13
15
 
14
16
  ## Installation
@@ -20,26 +22,91 @@ npm install @revisium/formula
20
22
  ## Usage
21
23
 
22
24
  ```typescript
23
- import { detectVersion } from '@revisium/formula';
25
+ import { parseExpression, evaluate } from '@revisium/formula';
26
+
27
+ // Simple arithmetic
28
+ parseExpression('price * 1.1');
29
+ // { minVersion: "1.0", features: [], dependencies: ["price"] }
30
+ evaluate('price * 1.1', { price: 100 });
31
+ // 110
32
+
33
+ // Nested object paths
34
+ parseExpression('stats.damage * multiplier');
35
+ // { minVersion: "1.1", features: ["nested_path"], dependencies: ["stats.damage", "multiplier"] }
36
+ evaluate('stats.damage * multiplier', { stats: { damage: 50 }, multiplier: 2 });
37
+ // 100
38
+
39
+ // Array index access
40
+ parseExpression('items[0].price + items[1].price');
41
+ // { minVersion: "1.1", features: ["array_index", "nested_path"], dependencies: ["items[0].price", "items[1].price"] }
42
+ evaluate('items[0].price + items[1].price', { items: [{ price: 10 }, { price: 20 }] });
43
+ // 30
44
+
45
+ // Comparisons
46
+ evaluate('price > 100', { price: 150 });
47
+ // true
48
+
49
+ // Type inference
50
+ import { inferFormulaType } from '@revisium/formula';
51
+
52
+ inferFormulaType('price * quantity', { price: 'number', quantity: 'number' });
53
+ // 'number'
54
+
55
+ inferFormulaType('price > 100');
56
+ // 'boolean'
57
+
58
+ // Schema validation
59
+ import { validateFormulaAgainstSchema } from '@revisium/formula';
60
+
61
+ const schema = {
62
+ type: 'object',
63
+ properties: {
64
+ price: { type: 'number' },
65
+ quantity: { type: 'number' },
66
+ total: { type: 'number', 'x-formula': { version: 1, expression: 'price * quantity' } }
67
+ }
68
+ };
69
+
70
+ validateFormulaAgainstSchema('price * quantity', 'total', schema);
71
+ // null (valid)
72
+
73
+ validateFormulaAgainstSchema('price > 100', 'total', schema);
74
+ // { field: 'total', error: "Type mismatch: formula returns 'boolean' but field expects 'number'" }
75
+ ```
24
76
 
25
- // Simple v1.0 formula
26
- const result1 = detectVersion('baseDamage * attackSpeed');
27
- // { minVersion: "1.0", features: [], dependencies: ["baseDamage", "attackSpeed"] }
77
+ ## API
28
78
 
29
- // v1.1 formula with nested paths
30
- const result2 = detectVersion('stats.damage * /multiplier');
31
- // { minVersion: "1.1", features: ["nested_path", "root_path"], dependencies: [...] }
79
+ ### Parser API
32
80
 
33
- // Excel-style running total
34
- const result3 = detectVersion('if(#first, value, @prev.runningTotal + value)');
35
- // { minVersion: "1.1", features: ["context_token"], dependencies: [...] }
36
- ```
81
+ | Function | Description |
82
+ |----------|-------------|
83
+ | `parseFormula` | Low-level parser returning AST, dependencies, features |
84
+ | `validateSyntax` | Validate expression syntax |
85
+ | `evaluate` | Evaluate expression with context |
86
+ | `inferFormulaType` | Infer return type of expression |
37
87
 
38
- ## API
88
+ ### Expression API
39
89
 
40
90
  | Function | Description |
41
91
  |----------|-------------|
42
- | `detectVersion` | Analyze formula and detect minimum required version |
92
+ | `parseExpression` | Parse expression, extract dependencies and version |
93
+ | `validateFormulaSyntax` | Validate formula expression syntax |
94
+
95
+ ### Graph API
96
+
97
+ | Function | Description |
98
+ |----------|-------------|
99
+ | `buildDependencyGraph` | Build dependency graph from `Record<string, string[]>` |
100
+ | `detectCircularDependencies` | Detect circular dependencies in graph |
101
+ | `getTopologicalOrder` | Get evaluation order for nodes |
102
+
103
+ ### Schema Validation
104
+
105
+ | Function | Description |
106
+ |----------|-------------|
107
+ | `extractSchemaFormulas` | Extract formulas from JSON Schema |
108
+ | `validateFormulaAgainstSchema` | Validate single formula against schema |
109
+ | `validateSchemaFormulas` | Validate all formulas in schema |
43
110
 
44
111
  ## Path Syntax
45
112
 
@@ -49,21 +116,6 @@ const result3 = detectVersion('if(#first, value, @prev.runningTotal + value)');
49
116
  | `obj.field` | Nested object | `stats.damage` |
50
117
  | `arr[N]` | Array index | `items[0].price` |
51
118
  | `arr[-1]` | Last element | `items[-1]` |
52
- | `arr[*]` | Wildcard | `items[*].price` |
53
- | `../field` | Parent (relative) | `../quantity` |
54
- | `/field` | Root (absolute) | `/basePrice` |
55
-
56
- ## Array Context Tokens
57
-
58
- | Token | Type | Description |
59
- |-------|------|-------------|
60
- | `#index` | number | Current array index |
61
- | `#length` | number | Array length |
62
- | `#first` | boolean | Is first element |
63
- | `#last` | boolean | Is last element |
64
- | `@prev` | object | Previous element |
65
- | `@next` | object | Next element |
66
- | `@current` | object | Current element |
67
119
 
68
120
  ## Version Detection
69
121
 
@@ -71,14 +123,7 @@ const result3 = detectVersion('if(#first, value, @prev.runningTotal + value)');
71
123
  |---------|-------------|
72
124
  | Simple refs (`field`) | 1.0 |
73
125
  | Nested paths (`a.b`) | 1.1 |
74
- | Arrays (`[0]`, `[*]`) | 1.1 |
75
- | Relative (`../`) | 1.1 |
76
- | Context tokens | 1.1 |
77
- | FK refs (`@table.field`) | 2.0 |
78
-
79
- ## Specification
80
-
81
- See [Formula Specification v1.1](https://github.com/revisium/architecture/blob/master/specs/formula-v1.spec.md).
126
+ | Array index (`[0]`, `[-1]`) | 1.1 |
82
127
 
83
128
  ## License
84
129