@lemmabase/lemma-engine 0.8.15 → 0.8.17

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
@@ -30,7 +30,7 @@ import { Lemma } from '@lemmabase/lemma-engine';
30
30
  const engine = await Lemma();
31
31
  await engine.load(pricing, 'pricing.lemma');
32
32
 
33
- const response = engine.run(null, 'pricing', [], { quantity: 50, is_vip: false }, null);
33
+ const response = engine.run(null, 'pricing', null, { quantity: 50, is_vip: false }, null);
34
34
  // response.results.unit_price → 16 eur
35
35
  // response.results.total → 800 eur
36
36
  ```
@@ -114,10 +114,10 @@ A pre-wired Monaco adapter ships at `@lemmabase/lemma-engine/monaco`.
114
114
  | `load(code, attribute?)` | Parse and validate a `.lemma` spec set. Resolves on success; rejects with `EngineError[]`. |
115
115
  | `load_batch(sources, dependency?)` | Load many sources in one planning pass (see `lemma.d.ts`). |
116
116
  | `fetch(name)` | Download registry source only; resolves with `{ source, id }`. Does not load. Rejects with `EngineError[]`. |
117
- | `list()` | JSON array of `ResolvedRepository`: each has `repository` and `specs` (spec sets). Always includes embedded `lemma` / `spec si`. |
118
- | `format_repository(repo)` | Canonical Lemma source for a loaded repository, formatted from the in-engine AST. Use `"lemma"` for the embedded SI stdlib. |
117
+ | `list()` | JSON array of `ResolvedRepository`: each has `repository` and `specs` (spec sets). Always includes embedded `lemma` / `spec units`. |
118
+ | `format_repository(repo)` | Canonical Lemma source for a loaded repository, formatted from the in-engine AST. Use `"lemma"` for the embedded units stdlib. |
119
119
  | `schema(repo, name, effective?)` | `SpecSchema`; `repo` null for workspace. |
120
- | `run(repo, name, ruleNames, data, effective?)` | Evaluate. `rules: []` runs everything; pass an array to filter. Returns a `Response`. |
120
+ | `run(repo, name, ruleNames, data, effective?, explain?)` | Evaluate. Omit/`null` `ruleNames` for all rules; pass a non-empty array to scope. `[]` errors. Returns a `Response`. |
121
121
  | `format(code, attribute?)` | Canonical formatting; throws `EngineError` on parse error. |
122
122
 
123
123
  Full TypeScript types are bundled - see `lemma.d.ts`.
@@ -139,12 +139,12 @@ In the browser, the registry must allow your origin (CORS). Use `https` or `http
139
139
 
140
140
  ## Status
141
141
 
142
- Lemma is in early development. Expect breaking changes between minor versions; **don't put it in front of paying customers yet**. Production-readiness tracking lives in the [main repo](https://github.com/lemma/lemma).
142
+ Lemma is pre-1.0. The WASM API is stable for most use cases, but breaking changes may occur between minor versions. Pin your dependency version and review the [changelog](https://github.com/lemma/lemma/blob/main/CHANGELOG.md) before upgrading.
143
143
 
144
144
  ## Related
145
145
 
146
146
  - [`lemmabase.com`](https://lemmabase.com): public database for Lemma Specs
147
- - [`lemma-cli`](https://crates.io/crates/lemma-cli): REPL, HTTP server, MCP server, formatter
147
+ - [`lemma`](https://crates.io/crates/lemma): REPL, HTTP server, MCP server, formatter
148
148
  - [`lemma-engine`](https://crates.io/crates/lemma-engine): same engine as a Rust crate
149
149
  - [`lemma_engine` on Hex](https://hex.pm/packages/lemma_engine): Elixir bindings via Rustler
150
150
  - VS Code / Cursor extension: search "Lemma Language" in the marketplace
@@ -24,7 +24,7 @@ export class Engine {
24
24
  * Canonical Lemma source for `repository`, formatted from the in-engine AST (e.g. `"lemma"`).
25
25
  */
26
26
  format_repository(repository: string): string;
27
- invert(_spec_name: string, _rule_name: string, _target_json: string, _provided_values_json: string): any;
27
+ invert(spec_name: string, rule_name: string, target_json: string, provided_values_json: string): any;
28
28
  /**
29
29
  * Same data as [`Engine::list`]: grouped [`ResolvedRepository`] JSON without planning.
30
30
  */
@@ -56,7 +56,7 @@ export class Engine {
56
56
  * `repository`: repository qualifier (`@org/pkg`), or `null`/empty for workspace (same as
57
57
  * [`Engine::run`] `repo: None`).
58
58
  */
59
- run(repository: string | null | undefined, spec: string, rule_names: any, data_values: any, rule_result_units: any, effective?: string | null): any;
59
+ run(repository: string | null | undefined, spec: string, rule_names: any, data_values: any, effective?: string | null, explain?: boolean | null): any;
60
60
  /**
61
61
  * Planning schema for the spec ([`crate::planning::execution_plan::SpecSchema`]). Throws on error.
62
62
  *
@@ -137,9 +137,9 @@ export interface InitOutput {
137
137
  readonly wasmengine_repositories: (a: number, b: number) => void;
138
138
  readonly wasmengine_run: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number, k: number) => void;
139
139
  readonly wasmengine_schema: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number) => void;
140
- readonly __wasm_bindgen_func_elem_11795: (a: number, b: number, c: number, d: number) => void;
141
- readonly __wasm_bindgen_func_elem_2721: (a: number, b: number, c: number, d: number) => void;
142
- readonly __wasm_bindgen_func_elem_11803: (a: number, b: number, c: number, d: number) => void;
140
+ readonly __wasm_bindgen_func_elem_12158: (a: number, b: number, c: number, d: number) => void;
141
+ readonly __wasm_bindgen_func_elem_2731: (a: number, b: number, c: number, d: number) => void;
142
+ readonly __wasm_bindgen_func_elem_12161: (a: number, b: number, c: number, d: number) => void;
143
143
  readonly __wbindgen_export: (a: number, b: number) => number;
144
144
  readonly __wbindgen_export2: (a: number, b: number, c: number, d: number) => number;
145
145
  readonly __wbindgen_export3: (a: number) => void;
package/lemma.bindings.js CHANGED
@@ -80,22 +80,22 @@ export class Engine {
80
80
  }
81
81
  }
82
82
  /**
83
- * @param {string} _spec_name
84
- * @param {string} _rule_name
85
- * @param {string} _target_json
86
- * @param {string} _provided_values_json
83
+ * @param {string} spec_name
84
+ * @param {string} rule_name
85
+ * @param {string} target_json
86
+ * @param {string} provided_values_json
87
87
  * @returns {any}
88
88
  */
89
- invert(_spec_name, _rule_name, _target_json, _provided_values_json) {
89
+ invert(spec_name, rule_name, target_json, provided_values_json) {
90
90
  try {
91
91
  const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
92
- const ptr0 = passStringToWasm0(_spec_name, wasm.__wbindgen_export, wasm.__wbindgen_export2);
92
+ const ptr0 = passStringToWasm0(spec_name, wasm.__wbindgen_export, wasm.__wbindgen_export2);
93
93
  const len0 = WASM_VECTOR_LEN;
94
- const ptr1 = passStringToWasm0(_rule_name, wasm.__wbindgen_export, wasm.__wbindgen_export2);
94
+ const ptr1 = passStringToWasm0(rule_name, wasm.__wbindgen_export, wasm.__wbindgen_export2);
95
95
  const len1 = WASM_VECTOR_LEN;
96
- const ptr2 = passStringToWasm0(_target_json, wasm.__wbindgen_export, wasm.__wbindgen_export2);
96
+ const ptr2 = passStringToWasm0(target_json, wasm.__wbindgen_export, wasm.__wbindgen_export2);
97
97
  const len2 = WASM_VECTOR_LEN;
98
- const ptr3 = passStringToWasm0(_provided_values_json, wasm.__wbindgen_export, wasm.__wbindgen_export2);
98
+ const ptr3 = passStringToWasm0(provided_values_json, wasm.__wbindgen_export, wasm.__wbindgen_export2);
99
99
  const len3 = WASM_VECTOR_LEN;
100
100
  wasm.wasmengine_invert(retptr, this.__wbg_ptr, ptr0, len0, ptr1, len1, ptr2, len2, ptr3, len3);
101
101
  var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
@@ -212,11 +212,11 @@ export class Engine {
212
212
  * @param {string} spec
213
213
  * @param {any} rule_names
214
214
  * @param {any} data_values
215
- * @param {any} rule_result_units
216
215
  * @param {string | null} [effective]
216
+ * @param {boolean | null} [explain]
217
217
  * @returns {any}
218
218
  */
219
- run(repository, spec, rule_names, data_values, rule_result_units, effective) {
219
+ run(repository, spec, rule_names, data_values, effective, explain) {
220
220
  try {
221
221
  const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
222
222
  var ptr0 = isLikeNone(repository) ? 0 : passStringToWasm0(repository, wasm.__wbindgen_export, wasm.__wbindgen_export2);
@@ -225,7 +225,7 @@ export class Engine {
225
225
  const len1 = WASM_VECTOR_LEN;
226
226
  var ptr2 = isLikeNone(effective) ? 0 : passStringToWasm0(effective, wasm.__wbindgen_export, wasm.__wbindgen_export2);
227
227
  var len2 = WASM_VECTOR_LEN;
228
- wasm.wasmengine_run(retptr, this.__wbg_ptr, ptr0, len0, ptr1, len1, addHeapObject(rule_names), addHeapObject(data_values), addHeapObject(rule_result_units), ptr2, len2);
228
+ wasm.wasmengine_run(retptr, this.__wbg_ptr, ptr0, len0, ptr1, len1, addHeapObject(rule_names), addHeapObject(data_values), ptr2, len2, isLikeNone(explain) ? 0xFFFFFF : explain ? 1 : 0);
229
229
  var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
230
230
  var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
231
231
  var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
@@ -715,7 +715,7 @@ function __wbg_get_imports() {
715
715
  const a = state0.a;
716
716
  state0.a = 0;
717
717
  try {
718
- return __wasm_bindgen_func_elem_11803(a, state0.b, arg0, arg1);
718
+ return __wasm_bindgen_func_elem_12161(a, state0.b, arg0, arg1);
719
719
  } finally {
720
720
  state0.a = a;
721
721
  }
@@ -874,13 +874,13 @@ function __wbg_get_imports() {
874
874
  return addHeapObject(ret);
875
875
  },
876
876
  __wbindgen_cast_0000000000000001: function(arg0, arg1) {
877
- // Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [Externref], shim_idx: 1416, ret: Result(Unit), inner_ret: Some(Result(Unit)) }, mutable: true }) -> Externref`.
878
- const ret = makeMutClosure(arg0, arg1, __wasm_bindgen_func_elem_11795);
877
+ // Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [Externref], shim_idx: 1412, ret: Result(Unit), inner_ret: Some(Result(Unit)) }, mutable: true }) -> Externref`.
878
+ const ret = makeMutClosure(arg0, arg1, __wasm_bindgen_func_elem_12158);
879
879
  return addHeapObject(ret);
880
880
  },
881
881
  __wbindgen_cast_0000000000000002: function(arg0, arg1) {
882
882
  // Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [NamedExternref("IteratorResult<any>")], shim_idx: 7, ret: Result(Unit), inner_ret: Some(Result(Unit)) }, mutable: true }) -> Externref`.
883
- const ret = makeMutClosure(arg0, arg1, __wasm_bindgen_func_elem_2721);
883
+ const ret = makeMutClosure(arg0, arg1, __wasm_bindgen_func_elem_2731);
884
884
  return addHeapObject(ret);
885
885
  },
886
886
  __wbindgen_cast_0000000000000003: function(arg0) {
@@ -917,10 +917,10 @@ function __wbg_get_imports() {
917
917
  };
918
918
  }
919
919
 
920
- function __wasm_bindgen_func_elem_11795(arg0, arg1, arg2) {
920
+ function __wasm_bindgen_func_elem_12158(arg0, arg1, arg2) {
921
921
  try {
922
922
  const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
923
- wasm.__wasm_bindgen_func_elem_11795(retptr, arg0, arg1, addHeapObject(arg2));
923
+ wasm.__wasm_bindgen_func_elem_12158(retptr, arg0, arg1, addHeapObject(arg2));
924
924
  var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
925
925
  var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
926
926
  if (r1) {
@@ -931,10 +931,10 @@ function __wasm_bindgen_func_elem_11795(arg0, arg1, arg2) {
931
931
  }
932
932
  }
933
933
 
934
- function __wasm_bindgen_func_elem_2721(arg0, arg1, arg2) {
934
+ function __wasm_bindgen_func_elem_2731(arg0, arg1, arg2) {
935
935
  try {
936
936
  const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
937
- wasm.__wasm_bindgen_func_elem_2721(retptr, arg0, arg1, addHeapObject(arg2));
937
+ wasm.__wasm_bindgen_func_elem_2731(retptr, arg0, arg1, addHeapObject(arg2));
938
938
  var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
939
939
  var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
940
940
  if (r1) {
@@ -945,8 +945,8 @@ function __wasm_bindgen_func_elem_2721(arg0, arg1, arg2) {
945
945
  }
946
946
  }
947
947
 
948
- function __wasm_bindgen_func_elem_11803(arg0, arg1, arg2, arg3) {
949
- wasm.__wasm_bindgen_func_elem_11803(arg0, arg1, addHeapObject(arg2), addHeapObject(arg3));
948
+ function __wasm_bindgen_func_elem_12161(arg0, arg1, arg2, arg3) {
949
+ wasm.__wasm_bindgen_func_elem_12161(arg0, arg1, addHeapObject(arg2), addHeapObject(arg3));
950
950
  }
951
951
 
952
952
 
package/lemma.d.ts CHANGED
@@ -35,7 +35,7 @@ declare module './lemma.bindings.js' {
35
35
  list(): ResolvedRepositoryJson[];
36
36
 
37
37
  /**
38
- * Formatted Lemma source for a loaded repository (from in-engine AST). Use `"lemma"` for embedded SI stdlib.
38
+ * Formatted Lemma source for a loaded repository (from in-engine AST). Use `"lemma"` for embedded units stdlib.
39
39
  */
40
40
  format_repository(repository: string): string;
41
41
 
@@ -56,9 +56,9 @@ declare module './lemma.bindings.js' {
56
56
  spec: string,
57
57
  rule_names: string[] | string,
58
58
  data_values: Record<string, unknown>,
59
- rule_result_units?: Record<string, string> | null,
60
59
  effective?: string | null,
61
- ): any;
60
+ explain?: boolean,
61
+ ): EvaluationResponse;
62
62
  }
63
63
  }
64
64
 
@@ -207,6 +207,47 @@ export interface DataEntry {
207
207
  default?: LiteralValue;
208
208
  }
209
209
 
210
+ /** Return shape of {@link Engine.run}. */
211
+ export interface EvaluationResponse {
212
+ spec: string;
213
+ effective: string;
214
+ results: Record<string, RuleResult>;
215
+ data: EvaluationDataEntry[];
216
+ }
217
+
218
+ export interface RuleResult {
219
+ vetoed: boolean;
220
+ display?: string | null;
221
+ veto_reason?: string | null;
222
+ rule_type: string;
223
+ quantity?: Record<string, string> | null;
224
+ ratio?: Record<string, string> | null;
225
+ number?: string | null;
226
+ boolean?: boolean | null;
227
+ text?: string | null;
228
+ date?: unknown | null;
229
+ time?: unknown | null;
230
+ calendar?: { value: string; unit: string } | null;
231
+ range?: { from: RuleResultPayload; to: RuleResultPayload } | null;
232
+ explanation?: unknown | null;
233
+ }
234
+
235
+ export interface RuleResultPayload {
236
+ quantity?: Record<string, string> | null;
237
+ ratio?: Record<string, string> | null;
238
+ number?: string | null;
239
+ boolean?: boolean | null;
240
+ text?: string | null;
241
+ date?: unknown | null;
242
+ time?: unknown | null;
243
+ calendar?: { value: string; unit: string } | null;
244
+ }
245
+
246
+ export interface EvaluationDataEntry {
247
+ path: string;
248
+ value: unknown;
249
+ }
250
+
210
251
  /** Return shape of {@link Engine.schema}. */
211
252
  export interface SpecSchema {
212
253
  spec: string;