@lemmabase/lemma-engine 0.8.12 → 0.8.14

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
@@ -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: scale
10
+ data money: quantity
11
11
  -> unit eur 1.00
12
12
  -> decimals 2
13
13
 
@@ -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('pricing', [], { quantity: 50, is_vip: false }, null);
33
+ const response = engine.run(null, 'pricing', [], { quantity: 50, is_vip: false }, null);
34
34
  // response.results.unit_price → 16 eur
35
35
  // response.results.total → 800 eur
36
36
  ```
@@ -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, scale-family mismatches - all caught at `load()` time. Bad specs never reach `run()`.
45
+ - **Statically checked.** Type errors, missing data, cycles, quantity-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
 
@@ -112,13 +112,31 @@ A pre-wired Monaco adapter ships at `@lemmabase/lemma-engine/monaco`.
112
112
  | Method | Description |
113
113
  |--------|-------------|
114
114
  | `load(code, attribute?)` | Parse and validate a `.lemma` spec set. Resolves on success; rejects with `EngineError[]`. |
115
- | `list()` | All loaded specs with metadata and an inlined `SpecSchema`. |
116
- | `schema(spec, effective?)` | `SpecSchema` for the spec at the given effective date. |
117
- | `run(spec, rules, data, effective?)` | Evaluate. `rules: []` runs everything; pass an array to filter. Returns a `Response`. |
115
+ | `load_batch(sources, dependency?)` | Load many sources in one planning pass (see `lemma.d.ts`). |
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. |
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`. |
118
121
  | `format(code, attribute?)` | Canonical formatting; throws `EngineError` on parse error. |
119
122
 
120
123
  Full TypeScript types are bundled - see `lemma.d.ts`.
121
124
 
125
+ ### Registry dependencies
126
+
127
+ Specs that reference `uses … @org/pkg` need that package available. `fetch` only downloads; call `load_batch` to load the dependency, then load your workspace:
128
+
129
+ ```javascript
130
+ import { Lemma } from '@lemmabase/lemma-engine';
131
+
132
+ const engine = await Lemma();
133
+ const { source, id } = await engine.fetch('@lemma/std');
134
+ await engine.load_batch({ '': source }, id);
135
+ await engine.load(sourceThatUsesStd, 'app.lemma');
136
+ ```
137
+
138
+ In the browser, the registry must allow your origin (CORS). Use `https` or `http://localhost` when using `fetch`.
139
+
122
140
  ## Status
123
141
 
124
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).
@@ -6,46 +6,63 @@
6
6
  * *This API requires the following crate features to be activated: `ReadableStreamType`*
7
7
  */
8
8
 
9
- type ReadableStreamType = "bytes";
9
+ export type ReadableStreamType = "bytes";
10
10
 
11
11
  export class Engine {
12
12
  free(): void;
13
13
  [Symbol.dispose](): void;
14
+ /**
15
+ * Download Lemma source for a registry identifier via [`crate::registry::LemmaBase`]. Returns `{ source, id }`.
16
+ * Does not load this [`WasmEngine`]; call [`Self::load_batch`], etc., yourself.
17
+ */
18
+ fetch(name: string): Promise<any>;
14
19
  /**
15
20
  * Returns formatted source string on success; throws with error message on failure.
16
21
  */
17
22
  format(code: string, attribute?: string | null): any;
23
+ /**
24
+ * Canonical Lemma source for `repository`, formatted from the in-engine AST (e.g. `"lemma"`).
25
+ */
26
+ format_repository(repository: string): string;
18
27
  invert(_spec_name: string, _rule_name: string, _target_json: string, _provided_values_json: string): any;
19
28
  /**
20
- * Loaded specs, each paired with its planning schema.
21
- *
22
- * Each entry has `{ name, effective_from, effective_to, schema }`. The
23
- * pair describes a half-open `[effective_from, effective_to)` validity
24
- * range; `effective_from` is `null` when the first version has no
25
- * declared start, and `effective_to` is `null` for the latest version of
26
- * a name (no successor). Order matches [`Engine::list_specs_with_ranges`].
27
- *
28
- * `schema` is the same envelope returned by [`WasmEngine::schema`] for
29
- * `(name, effective_from)`; shipping it inline saves the N+1 round-trip
30
- * every consumer (playground, dashboards, docs) was doing.
29
+ * Same data as [`Engine::list`]: grouped [`ResolvedRepository`] JSON without planning.
31
30
  */
32
31
  list(): any;
33
32
  /**
34
- * Load Lemma source. Resolves with `undefined` on success; rejects with an array of
35
- * serialized errors (same shape as `EngineError` in `engine/packages/npm/lemma.d.ts`).
33
+ * Load Lemma source. Throws with an array of serialized errors
34
+ * (same shape as `EngineError` in `engine/packages/npm/lemma.d.ts`).
35
+ */
36
+ load(code: string, attribute: string): void;
37
+ /**
38
+ * Load multiple Lemma sources in one planning pass (same as [`Engine::load_batch`]).
39
+ *
40
+ * `sources` is a plain object mapping path labels to source text. Labels become
41
+ * [`SourceType::Path`]; use `""` as a key for [`SourceType::Volatile`].
36
42
  *
37
- * Breaking: previously rejected with an array of strings.
43
+ * `dependency`: when non-empty after trim, sources are tagged as that dependency id.
44
+ *
45
+ * Throws with an array of `JsError` on failure.
38
46
  */
39
- load(code: string, attribute: string): Promise<any>;
47
+ load_batch(sources: any, dependency?: string | null): void;
40
48
  constructor();
49
+ /**
50
+ * Loaded repositories (workspace and dependencies): `{ name, dependency }`.
51
+ */
52
+ repositories(): any;
41
53
  /**
42
54
  * Evaluate spec. Returns [`crate::evaluation::Response`] as a JS object. Throws on planning/runtime error.
55
+ *
56
+ * `repository`: repository qualifier (`@org/pkg`), or `null`/empty for workspace (same as
57
+ * [`Engine::run`] `repo: None`).
43
58
  */
44
- run(spec: string, rule_names: any, data_values: any, effective?: string | null): any;
59
+ run(repository: string | null | undefined, spec: string, rule_names: any, data_values: any, rule_result_units: any, effective?: string | null): any;
45
60
  /**
46
61
  * Planning schema for the spec ([`crate::planning::execution_plan::SpecSchema`]). Throws on error.
62
+ *
63
+ * `repository`: qualifier string or `null`/empty for workspace ([`Engine::schema`]).
47
64
  */
48
- schema(spec: string, effective?: string | null): any;
65
+ schema(repository: string | null | undefined, spec: string, effective?: string | null): any;
49
66
  }
50
67
 
51
68
  export class IntoUnderlyingByteSource {
@@ -109,16 +126,20 @@ export interface InitOutput {
109
126
  readonly intounderlyingsource_cancel: (a: number) => void;
110
127
  readonly intounderlyingsource_pull: (a: number, b: number) => number;
111
128
  readonly __wbg_engine_free: (a: number, b: number) => void;
129
+ readonly wasmengine_fetch: (a: number, b: number, c: number) => number;
112
130
  readonly wasmengine_format: (a: number, b: number, c: number, d: number, e: number, f: number) => void;
131
+ readonly wasmengine_format_repository: (a: number, b: number, c: number, d: number) => void;
113
132
  readonly wasmengine_invert: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number) => void;
114
133
  readonly wasmengine_list: (a: number, b: number) => void;
115
- readonly wasmengine_load: (a: number, b: number, c: number, d: number, e: number) => number;
134
+ readonly wasmengine_load: (a: number, b: number, c: number, d: number, e: number, f: number) => void;
135
+ readonly wasmengine_load_batch: (a: number, b: number, c: number, d: number, e: number) => void;
116
136
  readonly wasmengine_new: () => number;
117
- readonly wasmengine_run: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number) => void;
118
- readonly wasmengine_schema: (a: number, b: number, c: number, d: number, e: number, f: number) => void;
119
- readonly __wasm_bindgen_func_elem_10686: (a: number, b: number, c: number, d: number) => void;
120
- readonly __wasm_bindgen_func_elem_2761: (a: number, b: number, c: number, d: number) => void;
121
- readonly __wasm_bindgen_func_elem_10704: (a: number, b: number, c: number, d: number) => void;
137
+ readonly wasmengine_repositories: (a: number, b: number) => void;
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
+ 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_11787: (a: number, b: number, c: number, d: number) => void;
141
+ readonly __wasm_bindgen_func_elem_2722: (a: number, b: number, c: number, d: number) => void;
142
+ readonly __wasm_bindgen_func_elem_11799: (a: number, b: number, c: number, d: number) => void;
122
143
  readonly __wbindgen_export: (a: number, b: number) => number;
123
144
  readonly __wbindgen_export2: (a: number, b: number, c: number, d: number) => number;
124
145
  readonly __wbindgen_export3: (a: number) => void;