@autochitect/engine 1.0.0 → 1.1.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 CHANGED
@@ -1,23 +1,23 @@
1
- # forecaster
1
+ # @autochitect/engine
2
2
 
3
- A 245KB WebAssembly financial modeling engine. Write cost models in a purpose-built DSL, get instant evaluation with a full dependency graph. Runs entirely client-side — no server, no latency, no data leaving the browser.
3
+ A 245KB WebAssembly cost estimation engine. Define cost models in a purpose-built DSL, get instant estimates with full dependency tracing. Runs entirely client-side — no server, no latency, no data leaving the browser.
4
4
 
5
5
  ## Install
6
6
 
7
7
  ```bash
8
- npm install forecaster
8
+ pnpm install @autochitect/engine
9
9
  ```
10
10
 
11
11
  ## Quick start
12
12
 
13
13
  ```javascript
14
- import { createEngine } from 'forecaster';
14
+ import { createEngine } from '@autochitect/engine';
15
15
 
16
16
  const engine = await createEngine(
17
- new URL('forecaster/engine.wasm', import.meta.url)
17
+ new URL('@autochitect/engine/engine.wasm', import.meta.url)
18
18
  );
19
19
 
20
- const result = engine.evaluate(`
20
+ const result = engine.estimate(`
21
21
  revenue: Input
22
22
  cost_ratio: Input
23
23
  costs = revenue * cost_ratio
@@ -35,66 +35,133 @@ console.log(result.results);
35
35
 
36
36
  **`result.results`** — computed values for every variable.
37
37
 
38
- **`result.graph`** — the full dependency DAG showing how each value was derived. Nodes have `kind` (input, constant, formula, map, scan) and edges show data flow. Use this to build audit trails, trace calculations back to source inputs, or render interactive visualizations.
38
+ **`result.graph`** — the full dependency DAG showing how each value was derived. Nodes have `kind` (input, constant, formula, map, scan) and edges show data flow. Build audit trails, trace calculations back to source inputs, or render interactive cost breakdowns.
39
39
 
40
40
  **`result.errors`** / **`result.warnings`** — with line and column numbers.
41
41
 
42
42
  ## The DSL
43
43
 
44
- The language is deliberately small. It's not a spreadsheet formula language — it's designed for financial modeling specifically.
44
+ The language is deliberately small. It's designed for cost estimation and financial modeling specifically.
45
45
 
46
46
  ```
47
- # Declarations
47
+ # Inputs — bind to external data (your JSON)
48
48
  revenue: Input("annual_revenue")
49
+ headcount: Input
50
+
51
+ # Constants — fixed values
49
52
  tax_rate: Const(0.21)
53
+ avg_salary: Const(85000)
54
+
55
+ # Params — tunable scenario knobs
50
56
  growth: Param
51
57
 
52
- # Formulas
58
+ # Formulas — define cost relationships
59
+ labor_cost = headcount * avg_salary
53
60
  gross_profit = revenue * (1 - cost_ratio)
54
61
  net_income = gross_profit * (1 - tax_rate)
55
62
 
56
- # Array operations
63
+ # Array operations — project over time
57
64
  periods = SEQUENCE(12, 1, 1)
58
65
  monthly = MAP(periods, LAMBDA(p, revenue / 12 * POWER(1 + growth, p)))
59
66
 
60
- # Accumulation
67
+ # Accumulation — running totals
61
68
  cumulative = SCAN(monthly, 0, LAMBDA(acc, m, acc + m))
62
69
  ```
63
70
 
64
- **Inputs** bind to external data (your JSON). **Constants** are fixed values. **References** alias other variables.
71
+ **Inputs** bind to external data (your JSON). **Constants** are fixed values. **Params** are tunable scenario knobs.
65
72
 
66
73
  **MAP** transforms arrays element-wise. **SCAN** accumulates (like reduce, but returns intermediate results). **LAMBDA** defines inline functions with named parameters.
67
74
 
68
- The engine compiles this into a directed acyclic graph, topologically sorts it, and evaluates in one pass. The graph is immutable — switching scenarios just swaps the input context, so it's instant.
75
+ The engine compiles this into a directed acyclic graph, topologically sorts it, and estimates in one pass. The graph is immutable — switching scenarios just swaps the input context, so it's instant.
76
+
77
+ ## Node.js usage
78
+
79
+ ```javascript
80
+ import { createEngine } from '@autochitect/engine';
81
+ import { fileURLToPath } from 'url';
82
+ import { dirname, join } from 'path';
83
+ import { createRequire } from 'module';
84
+
85
+ const require = createRequire(import.meta.url);
86
+ const wasmPath = require.resolve('@autochitect/engine/engine.wasm');
87
+ const engine = await createEngine(wasmPath);
88
+
89
+ const result = engine.estimate(`
90
+ headcount: Input
91
+ avg_salary: Const(85000)
92
+ benefits_rate: Const(0.3)
93
+
94
+ labor_cost = headcount * avg_salary
95
+ benefits = labor_cost * benefits_rate
96
+ total_people_cost = labor_cost + benefits
97
+ `, {
98
+ headcount: 12,
99
+ });
100
+
101
+ console.log(result.results);
102
+ // {
103
+ // headcount: 12,
104
+ // avg_salary: 85000,
105
+ // benefits_rate: 0.3,
106
+ // labor_cost: 1020000,
107
+ // benefits: 306000,
108
+ // total_people_cost: 1326000
109
+ // }
110
+ ```
69
111
 
70
112
  ## Browser usage
71
113
 
72
114
  ```html
73
115
  <script type="module">
74
- import { createEngine } from './node_modules/forecaster/index.mjs';
75
- const engine = await createEngine('./node_modules/forecaster/engine.wasm');
76
- const result = engine.evaluate('x = 2 + 2', {});
77
- document.body.textContent = JSON.stringify(result.results);
116
+ import { createEngine } from './node_modules/@autochitect/engine/index.mjs';
117
+
118
+ const engine = await createEngine(
119
+ new URL('./node_modules/@autochitect/engine/engine.wasm', import.meta.url)
120
+ );
121
+
122
+ const result = engine.estimate(`
123
+ units: Input
124
+ price_per_unit: Input
125
+ discount_rate: Input
126
+
127
+ subtotal = units * price_per_unit
128
+ discount = subtotal * discount_rate
129
+ total = subtotal - discount
130
+ `, {
131
+ units: 1000,
132
+ price_per_unit: 49.99,
133
+ discount_rate: 0.15,
134
+ });
135
+
136
+ console.log(result.results);
137
+ // { units: 1000, price_per_unit: 49.99, discount_rate: 0.15,
138
+ // subtotal: 49990, discount: 7498.5, total: 42491.5 }
78
139
  </script>
79
140
  ```
80
141
 
81
- ## Node.js usage
142
+ When using a bundler (Vite, webpack, etc.), import the WASM file directly:
82
143
 
83
144
  ```javascript
84
- import { createEngine } from 'forecaster';
85
- import { fileURLToPath } from 'url';
86
- import { dirname, join } from 'path';
145
+ import { createEngine } from '@autochitect/engine';
87
146
 
88
- const __dirname = dirname(fileURLToPath(import.meta.url));
89
- const wasmPath = join(__dirname, 'node_modules/forecaster/engine.wasm');
90
- const engine = await createEngine(wasmPath);
147
+ const engine = await createEngine(
148
+ new URL('@autochitect/engine/engine.wasm', import.meta.url)
149
+ );
91
150
  ```
92
151
 
93
152
  ## Options
94
153
 
95
154
  ```javascript
96
- // Skip the dependency graph for faster evaluation
97
- engine.evaluate(source, inputs, { graph: false });
155
+ // Skip the dependency graph for faster estimation
156
+ engine.estimate(source, inputs, { graph: false });
157
+ ```
158
+
159
+ ## TypeScript
160
+
161
+ Full type definitions are included. Key types:
162
+
163
+ ```typescript
164
+ import type { Engine, EstimateResult, EstimateOptions } from '@autochitect/engine';
98
165
  ```
99
166
 
100
167
  ## License
package/engine.wasm CHANGED
Binary file
package/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export interface EvalResult {
1
+ export interface EstimateResult {
2
2
  success: boolean;
3
3
  results: Record<string, number | number[] | string | null>;
4
4
  errors: Array<{ message: string; line: number; col: number }>;
@@ -16,12 +16,12 @@ export interface EvalResult {
16
16
  };
17
17
  }
18
18
 
19
- export interface EvalOptions {
19
+ export interface EstimateOptions {
20
20
  graph?: boolean;
21
21
  }
22
22
 
23
23
  export interface Engine {
24
- evaluate(source: string, inputs?: Record<string, unknown>, options?: EvalOptions): EvalResult;
24
+ estimate(source: string, inputs?: Record<string, unknown>, options?: EstimateOptions): EstimateResult;
25
25
  }
26
26
 
27
27
  export function createEngine(wasmSource: string | Response | ArrayBuffer): Promise<Engine>;
package/index.mjs CHANGED
@@ -112,11 +112,11 @@ export async function createEngine(wasmSource) {
112
112
  }
113
113
 
114
114
  return {
115
- evaluate(source, inputs = {}, options = {}) {
115
+ estimate(source, inputs = {}, options = {}) {
116
116
  const includeGraph = options.graph !== false;
117
117
  const src = writeString(source);
118
118
  const json = writeString(JSON.stringify(inputs));
119
- const resultLen = instance.exports.wasm_eval(
119
+ const resultLen = instance.exports.wasm_estimate(
120
120
  src.ptr, src.len,
121
121
  json.ptr, json.len,
122
122
  includeGraph ? 1 : 0
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@autochitect/engine",
3
- "version": "1.0.0",
4
- "description": "A 245KB WebAssembly financial modeling engine. Define cost models in a purpose-built DSL, get instant evaluation with full dependency tracing. No server required.",
3
+ "version": "1.1.0",
4
+ "description": "A 245KB WebAssembly financial modeling engine. Define cost models in a purpose-built DSL, get instant estimates with full dependency tracing. No server required.",
5
5
  "license": "MIT",
6
6
  "type": "module",
7
7
  "main": "index.mjs",