@lemmabase/lemma-engine 0.8.20 → 0.8.22
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 +6 -2
- package/lemma.bindings.d.ts +2 -4
- package/lemma.bindings.js +7 -37
- package/lemma.d.ts +14 -8
- package/lemma.iife.js +1 -1
- package/lemma_bg.wasm +0 -0
- package/lemma_bg.wasm.d.ts +2 -3
- package/monaco.js +39 -36
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@ Pricing tiers, tax brackets, leave entitlement, eligibility checks, discount sta
|
|
|
7
7
|
```lemma
|
|
8
8
|
spec pricing 2026-01-01
|
|
9
9
|
|
|
10
|
-
data money:
|
|
10
|
+
data money: measure
|
|
11
11
|
-> unit eur 1.00
|
|
12
12
|
-> decimals 2
|
|
13
13
|
|
|
@@ -42,7 +42,7 @@ The `Response` carries every rule's value (or `veto` if no result could be compu
|
|
|
42
42
|
- **Deterministic.** `(spec, data, effective_date) → result`. No DB, no clock, no ambient state. Same inputs → same outputs, every time.
|
|
43
43
|
- **Explainable.** The `Response` tells you which rules contributed and why; pair it with the [CLI](https://github.com/lemma/lemma) for a full reasoning trace.
|
|
44
44
|
- **Time-aware.** Multiple versions of the same spec coexist. Pass an `effective` date and the engine resolves the version in force on that day.
|
|
45
|
-
- **Statically checked.** Type errors, missing data, cycles,
|
|
45
|
+
- **Statically checked.** Type errors, missing data, cycles, measure-family mismatches - all caught at `load()` time. Bad specs never reach `run()`.
|
|
46
46
|
- **Runs anywhere V8 does.** ~2 MB WASM, no native binary, no postinstall script.
|
|
47
47
|
- **Editor in a tab.** Includes an in-process language server and a Monaco adapter, so you can build a real Lemma editor experience client-side - diagnostics, completion, formatting... even without setting up a server.
|
|
48
48
|
|
|
@@ -141,6 +141,10 @@ In the browser, the registry must allow your origin (CORS). Use `https` or `http
|
|
|
141
141
|
|
|
142
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
|
+
### WASM panic behavior
|
|
145
|
+
|
|
146
|
+
Rust panics cannot unwind on the `wasm32` target, so an internal invariant violation (a bug) traps the WASM instance. The call throws a `RuntimeError` which you can catch with `try/catch` to fail gracefully, but the module's linear memory is poisoned — constructing a new `Engine()` from the same initialized module is not safe. To recover, re-initialize the WASM module (`init()` again) or, for robust containment, run the engine in a Web Worker and respawn the worker on trap. The panic message (prefixed `BUG: ...`) is logged to the console before the trap. All domain-level failures (invalid specs, bad data, impossible rules) are reported as `EngineError[]` or vetoes and never cause traps.
|
|
147
|
+
|
|
144
148
|
## Related
|
|
145
149
|
|
|
146
150
|
- [`lemmabase.com`](https://lemmabase.com): public database for Lemma Specs
|
package/lemma.bindings.d.ts
CHANGED
|
@@ -24,7 +24,6 @@ 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;
|
|
28
27
|
/**
|
|
29
28
|
* Same data as [`Engine::list`]: grouped [`ResolvedRepository`] JSON without planning.
|
|
30
29
|
*/
|
|
@@ -125,16 +124,15 @@ export interface InitOutput {
|
|
|
125
124
|
readonly wasmengine_fetch: (a: number, b: number, c: number) => number;
|
|
126
125
|
readonly wasmengine_format: (a: number, b: number, c: number, d: number, e: number, f: number) => void;
|
|
127
126
|
readonly wasmengine_format_repository: (a: number, b: number, c: number, d: number) => void;
|
|
128
|
-
readonly wasmengine_invert: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number) => void;
|
|
129
127
|
readonly wasmengine_list: (a: number, b: number) => void;
|
|
130
128
|
readonly wasmengine_load: (a: number, b: number, c: number, d: number, e: number, f: number) => void;
|
|
131
129
|
readonly wasmengine_load_batch: (a: number, b: number, c: number, d: number, e: number) => void;
|
|
132
130
|
readonly wasmengine_new: () => number;
|
|
133
131
|
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;
|
|
134
132
|
readonly wasmengine_schema: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number) => void;
|
|
135
|
-
readonly
|
|
133
|
+
readonly __wasm_bindgen_func_elem_12297: (a: number, b: number, c: number, d: number) => void;
|
|
136
134
|
readonly __wasm_bindgen_func_elem_2740: (a: number, b: number, c: number, d: number) => void;
|
|
137
|
-
readonly
|
|
135
|
+
readonly __wasm_bindgen_func_elem_12302: (a: number, b: number, c: number, d: number) => void;
|
|
138
136
|
readonly __wbindgen_export: (a: number, b: number) => number;
|
|
139
137
|
readonly __wbindgen_export2: (a: number, b: number, c: number, d: number) => number;
|
|
140
138
|
readonly __wbindgen_export3: (a: number) => void;
|
package/lemma.bindings.js
CHANGED
|
@@ -79,36 +79,6 @@ export class Engine {
|
|
|
79
79
|
wasm.__wbindgen_export4(deferred3_0, deferred3_1, 1);
|
|
80
80
|
}
|
|
81
81
|
}
|
|
82
|
-
/**
|
|
83
|
-
* @param {string} spec_name
|
|
84
|
-
* @param {string} rule_name
|
|
85
|
-
* @param {string} target_json
|
|
86
|
-
* @param {string} provided_values_json
|
|
87
|
-
* @returns {any}
|
|
88
|
-
*/
|
|
89
|
-
invert(spec_name, rule_name, target_json, provided_values_json) {
|
|
90
|
-
try {
|
|
91
|
-
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
|
92
|
-
const ptr0 = passStringToWasm0(spec_name, wasm.__wbindgen_export, wasm.__wbindgen_export2);
|
|
93
|
-
const len0 = WASM_VECTOR_LEN;
|
|
94
|
-
const ptr1 = passStringToWasm0(rule_name, wasm.__wbindgen_export, wasm.__wbindgen_export2);
|
|
95
|
-
const len1 = WASM_VECTOR_LEN;
|
|
96
|
-
const ptr2 = passStringToWasm0(target_json, wasm.__wbindgen_export, wasm.__wbindgen_export2);
|
|
97
|
-
const len2 = WASM_VECTOR_LEN;
|
|
98
|
-
const ptr3 = passStringToWasm0(provided_values_json, wasm.__wbindgen_export, wasm.__wbindgen_export2);
|
|
99
|
-
const len3 = WASM_VECTOR_LEN;
|
|
100
|
-
wasm.wasmengine_invert(retptr, this.__wbg_ptr, ptr0, len0, ptr1, len1, ptr2, len2, ptr3, len3);
|
|
101
|
-
var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
|
|
102
|
-
var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
|
|
103
|
-
var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
|
|
104
|
-
if (r2) {
|
|
105
|
-
throw takeObject(r1);
|
|
106
|
-
}
|
|
107
|
-
return takeObject(r0);
|
|
108
|
-
} finally {
|
|
109
|
-
wasm.__wbindgen_add_to_stack_pointer(16);
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
82
|
/**
|
|
113
83
|
* Same data as [`Engine::list`]: grouped [`ResolvedRepository`] JSON without planning.
|
|
114
84
|
* @returns {any}
|
|
@@ -696,7 +666,7 @@ function __wbg_get_imports() {
|
|
|
696
666
|
const a = state0.a;
|
|
697
667
|
state0.a = 0;
|
|
698
668
|
try {
|
|
699
|
-
return
|
|
669
|
+
return __wasm_bindgen_func_elem_12302(a, state0.b, arg0, arg1);
|
|
700
670
|
} finally {
|
|
701
671
|
state0.a = a;
|
|
702
672
|
}
|
|
@@ -855,8 +825,8 @@ function __wbg_get_imports() {
|
|
|
855
825
|
return addHeapObject(ret);
|
|
856
826
|
},
|
|
857
827
|
__wbindgen_cast_0000000000000001: function(arg0, arg1) {
|
|
858
|
-
// Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [Externref], shim_idx:
|
|
859
|
-
const ret = makeMutClosure(arg0, arg1,
|
|
828
|
+
// Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [Externref], shim_idx: 1414, ret: Result(Unit), inner_ret: Some(Result(Unit)) }, mutable: true }) -> Externref`.
|
|
829
|
+
const ret = makeMutClosure(arg0, arg1, __wasm_bindgen_func_elem_12297);
|
|
860
830
|
return addHeapObject(ret);
|
|
861
831
|
},
|
|
862
832
|
__wbindgen_cast_0000000000000002: function(arg0, arg1) {
|
|
@@ -898,10 +868,10 @@ function __wbg_get_imports() {
|
|
|
898
868
|
};
|
|
899
869
|
}
|
|
900
870
|
|
|
901
|
-
function
|
|
871
|
+
function __wasm_bindgen_func_elem_12297(arg0, arg1, arg2) {
|
|
902
872
|
try {
|
|
903
873
|
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
|
904
|
-
wasm.
|
|
874
|
+
wasm.__wasm_bindgen_func_elem_12297(retptr, arg0, arg1, addHeapObject(arg2));
|
|
905
875
|
var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
|
|
906
876
|
var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
|
|
907
877
|
if (r1) {
|
|
@@ -926,8 +896,8 @@ function __wasm_bindgen_func_elem_2740(arg0, arg1, arg2) {
|
|
|
926
896
|
}
|
|
927
897
|
}
|
|
928
898
|
|
|
929
|
-
function
|
|
930
|
-
wasm.
|
|
899
|
+
function __wasm_bindgen_func_elem_12302(arg0, arg1, arg2, arg3) {
|
|
900
|
+
wasm.__wasm_bindgen_func_elem_12302(arg0, arg1, addHeapObject(arg2), addHeapObject(arg3));
|
|
931
901
|
}
|
|
932
902
|
|
|
933
903
|
|
package/lemma.d.ts
CHANGED
|
@@ -50,6 +50,10 @@ declare module './lemma.bindings.js' {
|
|
|
50
50
|
|
|
51
51
|
/**
|
|
52
52
|
* `repository`: qualifier or `null`/omit for workspace — same as `Engine::run` `repo`.
|
|
53
|
+
*
|
|
54
|
+
* `data_values`: pass integers as numbers, decimals as strings (e.g.
|
|
55
|
+
* `{ quantity: 42, rate: "0.075" }`). Non-integer numbers are rejected
|
|
56
|
+
* to prevent silent precision loss from IEEE 754 doubles.
|
|
53
57
|
*/
|
|
54
58
|
run(
|
|
55
59
|
repository: string | null | undefined,
|
|
@@ -147,7 +151,7 @@ export type LemmaType =
|
|
|
147
151
|
& (
|
|
148
152
|
| { kind: "boolean"; help: string }
|
|
149
153
|
| {
|
|
150
|
-
kind: "
|
|
154
|
+
kind: "measure";
|
|
151
155
|
minimum: string | null;
|
|
152
156
|
maximum: string | null;
|
|
153
157
|
decimals: number | null;
|
|
@@ -155,7 +159,7 @@ export type LemmaType =
|
|
|
155
159
|
help: string;
|
|
156
160
|
}
|
|
157
161
|
| {
|
|
158
|
-
kind: "
|
|
162
|
+
kind: "measure range";
|
|
159
163
|
minimum: string | null;
|
|
160
164
|
maximum: string | null;
|
|
161
165
|
decimals: number | null;
|
|
@@ -201,9 +205,11 @@ export type LemmaType =
|
|
|
201
205
|
/** One input declared in a spec. Omitted fields are absent (not `null`). */
|
|
202
206
|
export interface DataEntry {
|
|
203
207
|
type: LemmaType;
|
|
204
|
-
/**
|
|
205
|
-
|
|
206
|
-
/**
|
|
208
|
+
/** Spec literal or literal `with` binding; UIs may skip review. */
|
|
209
|
+
prefilled?: LiteralValue;
|
|
210
|
+
/** Caller overlay when schema was built with supplied values. */
|
|
211
|
+
supplied?: LiteralValue;
|
|
212
|
+
/** `-> default ...` suggestion; prompt with prefill in interactive UIs. */
|
|
207
213
|
default?: LiteralValue;
|
|
208
214
|
}
|
|
209
215
|
|
|
@@ -220,7 +226,7 @@ export interface RuleResult {
|
|
|
220
226
|
display?: string | null;
|
|
221
227
|
veto_reason?: string | null;
|
|
222
228
|
rule_type: string;
|
|
223
|
-
|
|
229
|
+
measure?: Record<string, string> | null;
|
|
224
230
|
ratio?: Record<string, string> | null;
|
|
225
231
|
number?: string | null;
|
|
226
232
|
boolean?: boolean | null;
|
|
@@ -233,7 +239,7 @@ export interface RuleResult {
|
|
|
233
239
|
}
|
|
234
240
|
|
|
235
241
|
export interface RuleResultPayload {
|
|
236
|
-
|
|
242
|
+
measure?: Record<string, string> | null;
|
|
237
243
|
ratio?: Record<string, string> | null;
|
|
238
244
|
number?: string | null;
|
|
239
245
|
boolean?: boolean | null;
|
|
@@ -252,7 +258,7 @@ export interface EvaluationDataEntry {
|
|
|
252
258
|
export interface SpecSchema {
|
|
253
259
|
spec: string;
|
|
254
260
|
data: Record<string, DataEntry>;
|
|
255
|
-
/** Rule result types;
|
|
261
|
+
/** Rule result types; measure and ratio entries expose `units[]` like their data counterparts. */
|
|
256
262
|
rules: Record<string, LemmaType>;
|
|
257
263
|
meta: Record<string, unknown>;
|
|
258
264
|
}
|