@lemmabase/lemma-engine 0.8.12 → 0.8.13

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('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
  ```
@@ -112,13 +112,30 @@ 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). Each set has `name`, `repository`, and `specs` temporal versions as full `LemmaSpec` objects (`effective_from`, `start_line`, `source_type`, …). |
118
+ | `schema(repo, name, effective?)` | `SpecSchema`; `repo` null for workspace. |
119
+ | `run(repo, name, ruleNames, data, effective?)` | Evaluate. `rules: []` runs everything; pass an array to filter. Returns a `Response`. |
118
120
  | `format(code, attribute?)` | Canonical formatting; throws `EngineError` on parse error. |
119
121
 
120
122
  Full TypeScript types are bundled - see `lemma.d.ts`.
121
123
 
124
+ ### Registry dependencies
125
+
126
+ Specs that reference `uses … @org/pkg` need that package available. `fetch` only downloads; call `load_batch` to load the dependency, then load your workspace:
127
+
128
+ ```javascript
129
+ import { Lemma } from '@lemmabase/lemma-engine';
130
+
131
+ const engine = await Lemma();
132
+ const { source, id } = await engine.fetch('@lemma/std');
133
+ await engine.load_batch({ '': source }, id);
134
+ await engine.load(sourceThatUsesStd, 'app.lemma');
135
+ ```
136
+
137
+ In the browser, the registry must allow your origin (CORS). Use `https` or `http://localhost` when using `fetch`.
138
+
122
139
  ## Status
123
140
 
124
141
  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).
@@ -11,41 +11,54 @@ type ReadableStreamType = "bytes";
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;
18
23
  invert(_spec_name: string, _rule_name: string, _target_json: string, _provided_values_json: string): any;
19
24
  /**
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.
25
+ * Same data as [`Engine::list`]: grouped [`ResolvedRepository`] JSON without planning.
31
26
  */
32
27
  list(): any;
33
28
  /**
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`).
29
+ * Load Lemma source. Throws with an array of serialized errors
30
+ * (same shape as `EngineError` in `engine/packages/npm/lemma.d.ts`).
31
+ */
32
+ load(code: string, attribute: string): void;
33
+ /**
34
+ * Load multiple Lemma sources in one planning pass (same as [`Engine::load_batch`]).
36
35
  *
37
- * Breaking: previously rejected with an array of strings.
36
+ * `sources` is a plain object mapping path labels to source text. Labels become
37
+ * [`SourceType::Path`]; use `""` as a key for [`SourceType::Volatile`].
38
+ *
39
+ * `dependency`: when non-empty after trim, sources are tagged as that dependency id.
40
+ *
41
+ * Throws with an array of `JsError` on failure.
38
42
  */
39
- load(code: string, attribute: string): Promise<any>;
43
+ load_batch(sources: any, dependency?: string | null): void;
40
44
  constructor();
45
+ /**
46
+ * Loaded repositories (workspace and dependencies): `{ name, dependency }`.
47
+ */
48
+ repositories(): any;
41
49
  /**
42
50
  * Evaluate spec. Returns [`crate::evaluation::Response`] as a JS object. Throws on planning/runtime error.
51
+ *
52
+ * `repository`: repository qualifier (`@org/pkg`), or `null`/empty for workspace (same as
53
+ * [`Engine::run`] `repo: None`).
43
54
  */
44
- run(spec: string, rule_names: any, data_values: any, effective?: string | null): any;
55
+ run(repository: string | null | undefined, spec: string, rule_names: any, data_values: any, effective?: string | null): any;
45
56
  /**
46
57
  * Planning schema for the spec ([`crate::planning::execution_plan::SpecSchema`]). Throws on error.
58
+ *
59
+ * `repository`: qualifier string or `null`/empty for workspace ([`Engine::schema`]).
47
60
  */
48
- schema(spec: string, effective?: string | null): any;
61
+ schema(repository: string | null | undefined, spec: string, effective?: string | null): any;
49
62
  }
50
63
 
51
64
  export class IntoUnderlyingByteSource {
@@ -109,16 +122,19 @@ export interface InitOutput {
109
122
  readonly intounderlyingsource_cancel: (a: number) => void;
110
123
  readonly intounderlyingsource_pull: (a: number, b: number) => number;
111
124
  readonly __wbg_engine_free: (a: number, b: number) => void;
125
+ readonly wasmengine_fetch: (a: number, b: number, c: number) => number;
112
126
  readonly wasmengine_format: (a: number, b: number, c: number, d: number, e: number, f: number) => void;
113
127
  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
128
  readonly wasmengine_list: (a: number, b: number) => void;
115
- readonly wasmengine_load: (a: number, b: number, c: number, d: number, e: number) => number;
129
+ readonly wasmengine_load: (a: number, b: number, c: number, d: number, e: number, f: number) => void;
130
+ readonly wasmengine_load_batch: (a: number, b: number, c: number, d: number, e: number) => void;
116
131
  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;
132
+ readonly wasmengine_repositories: (a: number, b: number) => void;
133
+ readonly wasmengine_run: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number) => void;
134
+ readonly wasmengine_schema: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number) => void;
135
+ readonly __wasm_bindgen_func_elem_10830: (a: number, b: number, c: number, d: number) => void;
136
+ readonly __wasm_bindgen_func_elem_2759: (a: number, b: number, c: number, d: number) => void;
137
+ readonly __wasm_bindgen_func_elem_10848: (a: number, b: number, c: number, d: number) => void;
122
138
  readonly __wbindgen_export: (a: number, b: number) => number;
123
139
  readonly __wbindgen_export2: (a: number, b: number, c: number, d: number) => number;
124
140
  readonly __wbindgen_export3: (a: number) => void;
package/lemma.bindings.js CHANGED
@@ -11,6 +11,18 @@ export class Engine {
11
11
  const ptr = this.__destroy_into_raw();
12
12
  wasm.__wbg_engine_free(ptr, 0);
13
13
  }
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
+ * @param {string} name
18
+ * @returns {Promise<any>}
19
+ */
20
+ fetch(name) {
21
+ const ptr0 = passStringToWasm0(name, wasm.__wbindgen_export, wasm.__wbindgen_export2);
22
+ const len0 = WASM_VECTOR_LEN;
23
+ const ret = wasm.wasmengine_fetch(this.__wbg_ptr, ptr0, len0);
24
+ return takeObject(ret);
25
+ }
14
26
  /**
15
27
  * Returns formatted source string on success; throws with error message on failure.
16
28
  * @param {string} code
@@ -67,17 +79,7 @@ export class Engine {
67
79
  }
68
80
  }
69
81
  /**
70
- * Loaded specs, each paired with its planning schema.
71
- *
72
- * Each entry has `{ name, effective_from, effective_to, schema }`. The
73
- * pair describes a half-open `[effective_from, effective_to)` validity
74
- * range; `effective_from` is `null` when the first version has no
75
- * declared start, and `effective_to` is `null` for the latest version of
76
- * a name (no successor). Order matches [`Engine::list_specs_with_ranges`].
77
- *
78
- * `schema` is the same envelope returned by [`WasmEngine::schema`] for
79
- * `(name, effective_from)`; shipping it inline saves the N+1 round-trip
80
- * every consumer (playground, dashboards, docs) was doing.
82
+ * Same data as [`Engine::list`]: grouped [`ResolvedRepository`] JSON without planning.
81
83
  * @returns {any}
82
84
  */
83
85
  list() {
@@ -96,21 +98,54 @@ export class Engine {
96
98
  }
97
99
  }
98
100
  /**
99
- * Load Lemma source. Resolves with `undefined` on success; rejects with an array of
100
- * serialized errors (same shape as `EngineError` in `engine/packages/npm/lemma.d.ts`).
101
- *
102
- * Breaking: previously rejected with an array of strings.
101
+ * Load Lemma source. Throws with an array of serialized errors
102
+ * (same shape as `EngineError` in `engine/packages/npm/lemma.d.ts`).
103
103
  * @param {string} code
104
104
  * @param {string} attribute
105
- * @returns {Promise<any>}
106
105
  */
107
106
  load(code, attribute) {
108
- const ptr0 = passStringToWasm0(code, wasm.__wbindgen_export, wasm.__wbindgen_export2);
109
- const len0 = WASM_VECTOR_LEN;
110
- const ptr1 = passStringToWasm0(attribute, wasm.__wbindgen_export, wasm.__wbindgen_export2);
111
- const len1 = WASM_VECTOR_LEN;
112
- const ret = wasm.wasmengine_load(this.__wbg_ptr, ptr0, len0, ptr1, len1);
113
- return takeObject(ret);
107
+ try {
108
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
109
+ const ptr0 = passStringToWasm0(code, wasm.__wbindgen_export, wasm.__wbindgen_export2);
110
+ const len0 = WASM_VECTOR_LEN;
111
+ const ptr1 = passStringToWasm0(attribute, wasm.__wbindgen_export, wasm.__wbindgen_export2);
112
+ const len1 = WASM_VECTOR_LEN;
113
+ wasm.wasmengine_load(retptr, this.__wbg_ptr, ptr0, len0, ptr1, len1);
114
+ var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
115
+ var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
116
+ if (r1) {
117
+ throw takeObject(r0);
118
+ }
119
+ } finally {
120
+ wasm.__wbindgen_add_to_stack_pointer(16);
121
+ }
122
+ }
123
+ /**
124
+ * Load multiple Lemma sources in one planning pass (same as [`Engine::load_batch`]).
125
+ *
126
+ * `sources` is a plain object mapping path labels to source text. Labels become
127
+ * [`SourceType::Path`]; use `""` as a key for [`SourceType::Volatile`].
128
+ *
129
+ * `dependency`: when non-empty after trim, sources are tagged as that dependency id.
130
+ *
131
+ * Throws with an array of `JsError` on failure.
132
+ * @param {any} sources
133
+ * @param {string | null} [dependency]
134
+ */
135
+ load_batch(sources, dependency) {
136
+ try {
137
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
138
+ var ptr0 = isLikeNone(dependency) ? 0 : passStringToWasm0(dependency, wasm.__wbindgen_export, wasm.__wbindgen_export2);
139
+ var len0 = WASM_VECTOR_LEN;
140
+ wasm.wasmengine_load_batch(retptr, this.__wbg_ptr, addHeapObject(sources), ptr0, len0);
141
+ var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
142
+ var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
143
+ if (r1) {
144
+ throw takeObject(r0);
145
+ }
146
+ } finally {
147
+ wasm.__wbindgen_add_to_stack_pointer(16);
148
+ }
114
149
  }
115
150
  constructor() {
116
151
  const ret = wasm.wasmengine_new();
@@ -118,22 +153,47 @@ export class Engine {
118
153
  EngineFinalization.register(this, this.__wbg_ptr, this);
119
154
  return this;
120
155
  }
156
+ /**
157
+ * Loaded repositories (workspace and dependencies): `{ name, dependency }`.
158
+ * @returns {any}
159
+ */
160
+ repositories() {
161
+ try {
162
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
163
+ wasm.wasmengine_repositories(retptr, this.__wbg_ptr);
164
+ var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
165
+ var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
166
+ var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
167
+ if (r2) {
168
+ throw takeObject(r1);
169
+ }
170
+ return takeObject(r0);
171
+ } finally {
172
+ wasm.__wbindgen_add_to_stack_pointer(16);
173
+ }
174
+ }
121
175
  /**
122
176
  * Evaluate spec. Returns [`crate::evaluation::Response`] as a JS object. Throws on planning/runtime error.
177
+ *
178
+ * `repository`: repository qualifier (`@org/pkg`), or `null`/empty for workspace (same as
179
+ * [`Engine::run`] `repo: None`).
180
+ * @param {string | null | undefined} repository
123
181
  * @param {string} spec
124
182
  * @param {any} rule_names
125
183
  * @param {any} data_values
126
184
  * @param {string | null} [effective]
127
185
  * @returns {any}
128
186
  */
129
- run(spec, rule_names, data_values, effective) {
187
+ run(repository, spec, rule_names, data_values, effective) {
130
188
  try {
131
189
  const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
132
- const ptr0 = passStringToWasm0(spec, wasm.__wbindgen_export, wasm.__wbindgen_export2);
133
- const len0 = WASM_VECTOR_LEN;
134
- var ptr1 = isLikeNone(effective) ? 0 : passStringToWasm0(effective, wasm.__wbindgen_export, wasm.__wbindgen_export2);
135
- var len1 = WASM_VECTOR_LEN;
136
- wasm.wasmengine_run(retptr, this.__wbg_ptr, ptr0, len0, addHeapObject(rule_names), addHeapObject(data_values), ptr1, len1);
190
+ var ptr0 = isLikeNone(repository) ? 0 : passStringToWasm0(repository, wasm.__wbindgen_export, wasm.__wbindgen_export2);
191
+ var len0 = WASM_VECTOR_LEN;
192
+ const ptr1 = passStringToWasm0(spec, wasm.__wbindgen_export, wasm.__wbindgen_export2);
193
+ const len1 = WASM_VECTOR_LEN;
194
+ var ptr2 = isLikeNone(effective) ? 0 : passStringToWasm0(effective, wasm.__wbindgen_export, wasm.__wbindgen_export2);
195
+ var len2 = WASM_VECTOR_LEN;
196
+ wasm.wasmengine_run(retptr, this.__wbg_ptr, ptr0, len0, ptr1, len1, addHeapObject(rule_names), addHeapObject(data_values), ptr2, len2);
137
197
  var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
138
198
  var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
139
199
  var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
@@ -147,18 +207,23 @@ export class Engine {
147
207
  }
148
208
  /**
149
209
  * Planning schema for the spec ([`crate::planning::execution_plan::SpecSchema`]). Throws on error.
210
+ *
211
+ * `repository`: qualifier string or `null`/empty for workspace ([`Engine::schema`]).
212
+ * @param {string | null | undefined} repository
150
213
  * @param {string} spec
151
214
  * @param {string | null} [effective]
152
215
  * @returns {any}
153
216
  */
154
- schema(spec, effective) {
217
+ schema(repository, spec, effective) {
155
218
  try {
156
219
  const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
157
- const ptr0 = passStringToWasm0(spec, wasm.__wbindgen_export, wasm.__wbindgen_export2);
158
- const len0 = WASM_VECTOR_LEN;
159
- var ptr1 = isLikeNone(effective) ? 0 : passStringToWasm0(effective, wasm.__wbindgen_export, wasm.__wbindgen_export2);
160
- var len1 = WASM_VECTOR_LEN;
161
- wasm.wasmengine_schema(retptr, this.__wbg_ptr, ptr0, len0, ptr1, len1);
220
+ var ptr0 = isLikeNone(repository) ? 0 : passStringToWasm0(repository, wasm.__wbindgen_export, wasm.__wbindgen_export2);
221
+ var len0 = WASM_VECTOR_LEN;
222
+ const ptr1 = passStringToWasm0(spec, wasm.__wbindgen_export, wasm.__wbindgen_export2);
223
+ const len1 = WASM_VECTOR_LEN;
224
+ var ptr2 = isLikeNone(effective) ? 0 : passStringToWasm0(effective, wasm.__wbindgen_export, wasm.__wbindgen_export2);
225
+ var len2 = WASM_VECTOR_LEN;
226
+ wasm.wasmengine_schema(retptr, this.__wbg_ptr, ptr0, len0, ptr1, len1, ptr2, len2);
162
227
  var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
163
228
  var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
164
229
  var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
@@ -618,7 +683,7 @@ function __wbg_get_imports() {
618
683
  const a = state0.a;
619
684
  state0.a = 0;
620
685
  try {
621
- return __wasm_bindgen_func_elem_10704(a, state0.b, arg0, arg1);
686
+ return __wasm_bindgen_func_elem_10848(a, state0.b, arg0, arg1);
622
687
  } finally {
623
688
  state0.a = a;
624
689
  }
@@ -777,13 +842,13 @@ function __wbg_get_imports() {
777
842
  return addHeapObject(ret);
778
843
  },
779
844
  __wbindgen_cast_0000000000000001: function(arg0, arg1) {
780
- // Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [Externref], shim_idx: 1306, ret: Result(Unit), inner_ret: Some(Result(Unit)) }, mutable: true }) -> Externref`.
781
- const ret = makeMutClosure(arg0, arg1, __wasm_bindgen_func_elem_10686);
845
+ // Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [Externref], shim_idx: 1343, ret: Result(Unit), inner_ret: Some(Result(Unit)) }, mutable: true }) -> Externref`.
846
+ const ret = makeMutClosure(arg0, arg1, __wasm_bindgen_func_elem_10830);
782
847
  return addHeapObject(ret);
783
848
  },
784
849
  __wbindgen_cast_0000000000000002: function(arg0, arg1) {
785
850
  // 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`.
786
- const ret = makeMutClosure(arg0, arg1, __wasm_bindgen_func_elem_2761);
851
+ const ret = makeMutClosure(arg0, arg1, __wasm_bindgen_func_elem_2759);
787
852
  return addHeapObject(ret);
788
853
  },
789
854
  __wbindgen_cast_0000000000000003: function(arg0) {
@@ -820,10 +885,10 @@ function __wbg_get_imports() {
820
885
  };
821
886
  }
822
887
 
823
- function __wasm_bindgen_func_elem_10686(arg0, arg1, arg2) {
888
+ function __wasm_bindgen_func_elem_10830(arg0, arg1, arg2) {
824
889
  try {
825
890
  const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
826
- wasm.__wasm_bindgen_func_elem_10686(retptr, arg0, arg1, addHeapObject(arg2));
891
+ wasm.__wasm_bindgen_func_elem_10830(retptr, arg0, arg1, addHeapObject(arg2));
827
892
  var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
828
893
  var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
829
894
  if (r1) {
@@ -834,10 +899,10 @@ function __wasm_bindgen_func_elem_10686(arg0, arg1, arg2) {
834
899
  }
835
900
  }
836
901
 
837
- function __wasm_bindgen_func_elem_2761(arg0, arg1, arg2) {
902
+ function __wasm_bindgen_func_elem_2759(arg0, arg1, arg2) {
838
903
  try {
839
904
  const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
840
- wasm.__wasm_bindgen_func_elem_2761(retptr, arg0, arg1, addHeapObject(arg2));
905
+ wasm.__wasm_bindgen_func_elem_2759(retptr, arg0, arg1, addHeapObject(arg2));
841
906
  var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
842
907
  var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
843
908
  if (r1) {
@@ -848,8 +913,8 @@ function __wasm_bindgen_func_elem_2761(arg0, arg1, arg2) {
848
913
  }
849
914
  }
850
915
 
851
- function __wasm_bindgen_func_elem_10704(arg0, arg1, arg2, arg3) {
852
- wasm.__wasm_bindgen_func_elem_10704(arg0, arg1, addHeapObject(arg2), addHeapObject(arg3));
916
+ function __wasm_bindgen_func_elem_10848(arg0, arg1, arg2, arg3) {
917
+ wasm.__wasm_bindgen_func_elem_10848(arg0, arg1, addHeapObject(arg2), addHeapObject(arg3));
853
918
  }
854
919
 
855
920
 
package/lemma.d.ts CHANGED
@@ -3,6 +3,59 @@ export { Engine, initSync } from './lemma.bindings.js';
3
3
  export declare function init(): Promise<void>;
4
4
  export declare function Lemma(): Promise<Engine>;
5
5
 
6
+ /** Resolved shape of {@link Engine.fetch}. */
7
+ export interface RegistryFetchResult {
8
+ source: string;
9
+ id: string;
10
+ }
11
+
12
+ declare module './lemma.bindings.js' {
13
+ interface Engine {
14
+ /**
15
+ * Load multiple Lemma sources in one planning pass. Object keys become error-reporting
16
+ * paths (`SourceType::Path`); use `""` for volatile/inline. Non-empty `dependency` tags
17
+ * the batch as that dependency id. Throws `EngineError[]` on failure.
18
+ */
19
+ load_batch(
20
+ sources: Record<string, string>,
21
+ dependency?: string | null,
22
+ ): void;
23
+
24
+ /**
25
+ * Download Lemma source from the registry for `name` (e.g. `@org/pkg`). Resolves with
26
+ * `{ source, id }`; does not load the engine. Rejects with `EngineError[]` like `load`.
27
+ */
28
+ fetch(name: string): Promise<RegistryFetchResult>;
29
+
30
+ /**
31
+ * JSON serialization of `Vec<ResolvedRepository>` from [`Engine::list`]:
32
+ * each item has `repository` ([`LemmaRepository`]) and `specs` (`LemmaSpecSet[]`),
33
+ * each set has `repository`, `name`, and `specs` (`LemmaSpec[]`).
34
+ */
35
+ list(): ResolvedRepositoryJson[];
36
+
37
+ /**
38
+ * `repository`: qualifier or `null`/omit for workspace — same as `Engine::schema` `repo`.
39
+ */
40
+ schema(
41
+ repository: string | null | undefined,
42
+ spec: string,
43
+ effective?: string | null,
44
+ ): SpecSchema;
45
+
46
+ /**
47
+ * `repository`: qualifier or `null`/omit for workspace — same as `Engine::run` `repo`.
48
+ */
49
+ run(
50
+ repository: string | null | undefined,
51
+ spec: string,
52
+ rule_names: string[] | string,
53
+ data_values: Record<string, unknown>,
54
+ effective?: string | null,
55
+ ): any;
56
+ }
57
+ }
58
+
6
59
  /**
7
60
  * Source location attached to an {@link EngineError}. Line and column are
8
61
  * 1-based; `length` is the UTF-8 byte length of the offending span.
@@ -16,11 +69,12 @@ export interface EngineErrorSource {
16
69
 
17
70
  /**
18
71
  * Structured error thrown by {@link Engine.run}, {@link Engine.schema},
19
- * {@link Engine.format}, and rejected from {@link Engine.load} (as an array).
72
+ * {@link Engine.format}, {@link Engine.load}, and {@link Engine.load_batch}
73
+ * (as an array), and rejected from {@link Engine.fetch} (as an array).
20
74
  *
21
75
  * - `kind` classifies the failure ("parsing" for syntax, "validation" for
22
- * semantic/planning including bad data values, "request" for bad API input,
23
- * etc.).
76
+ * semantic/planning including bad data values, "missing_repository" when a
77
+ * referenced repo is not loaded, "request" for bad API input, etc.).
24
78
  * - `message` is the inner reason only. Callers that previously parsed
25
79
  * `"Failed to parse data 'X' as Y: ..."` strings should now use `related_data`
26
80
  * for attribution and `message` for the reason.
@@ -29,17 +83,26 @@ export interface EngineErrorSource {
29
83
  * - `source` points at the offending range in the original Lemma source.
30
84
  */
31
85
  export interface EngineError {
32
- kind: "parsing" | "validation" | "inversion" | "registry" | "request" | "resource_limit";
86
+ kind:
87
+ | "parsing"
88
+ | "validation"
89
+ | "inversion"
90
+ | "registry"
91
+ | "missing_repository"
92
+ | "request"
93
+ | "resource_limit";
33
94
  message: string;
34
95
  related_data: string | null;
35
96
  spec: string | null;
36
97
  related_spec: string | null;
37
98
  source: EngineErrorSource | null;
38
99
  suggestion: string | null;
100
+ /** Present for `missing_repository` and `registry` errors (`@…` id). */
101
+ repository: string | null;
39
102
  }
40
103
 
41
104
  // ---------------------------------------------------------------------------
42
- // Schema envelope (return shape of Engine.schema and Engine.list entries)
105
+ // Schema envelope (return shape of Engine.schema)
43
106
  // ---------------------------------------------------------------------------
44
107
 
45
108
  /** Literal value produced by `JSON.stringify` on a Lemma `LiteralValue`. */
@@ -103,9 +166,12 @@ export type LemmaType =
103
166
  | { kind: "veto"; message: string | null }
104
167
  );
105
168
 
106
- /** One input on a spec. `default` is omitted (not `null`) when absent. */
169
+ /** One input declared in a spec. Omitted fields are absent (not `null`). */
107
170
  export interface DataEntry {
108
171
  type: LemmaType;
172
+ /** Literal bound in the source (`data x: literal`). */
173
+ bound_value?: LiteralValue;
174
+ /** `-> default ...` suggestion; omitted from `bound_value` until evaluation applies it. */
109
175
  default?: LiteralValue;
110
176
  }
111
177
 
@@ -117,11 +183,60 @@ export interface SpecSchema {
117
183
  meta: Record<string, unknown>;
118
184
  }
119
185
 
120
- /** One row of {@link Engine.list}. The schema is always inlined so callers
121
- * never need a second `engine.schema(name, effective_from)` round-trip. */
122
- export interface SpecListEntry {
186
+ /** JSON mirror of Rust `ResolvedRepository` (engine `list`). */
187
+ export interface ResolvedRepositoryJson {
188
+ repository: LemmaRepositoryJson;
189
+ /** [`LemmaSpecSet`] list for this resolved repository. */
190
+ specs: LemmaSpecSetJson[];
191
+ }
192
+
193
+ /** JSON mirror of Rust `LemmaSpecSet` as serialized by the engine. */
194
+ export interface LemmaSpecSetJson {
195
+ repository: LemmaRepositoryJson;
123
196
  name: string;
124
- effective_from: string | null;
125
- effective_to: string | null;
126
- schema: SpecSchema;
197
+ /** Temporal versions, ascending `effective_from` (same order as `iter_specs`). */
198
+ specs: LemmaSpecJson[];
199
+ }
200
+
201
+ /** JSON mirror of Rust `LemmaRepository`. */
202
+ export interface LemmaRepositoryJson {
203
+ name: string | null;
204
+ dependency: string | null;
205
+ start_line: number;
206
+ source_type: unknown;
207
+ }
208
+
209
+ /** JSON mirror of Rust `EffectiveDate` (externally tagged). */
210
+ export type EffectiveDateJson =
211
+ | { Origin: null }
212
+ | { DateTimeValue: DateTimeValueJson };
213
+
214
+ /** JSON mirror of Rust `DateTimeValue`. */
215
+ export interface DateTimeValueJson {
216
+ year: number;
217
+ month: number;
218
+ day: number;
219
+ hour: number;
220
+ minute: number;
221
+ second: number;
222
+ microsecond: number;
223
+ timezone: unknown;
224
+ }
225
+
226
+ /** JSON mirror of Rust `LemmaSpec` (full AST; deep nodes are engine-shaped). */
227
+ export interface LemmaSpecJson {
228
+ name: string;
229
+ effective_from: EffectiveDateJson;
230
+ source_type: unknown;
231
+ start_line: number;
232
+ commentary: string | null;
233
+ data: unknown[];
234
+ rules: unknown[];
235
+ meta_fields: unknown[];
236
+ }
237
+
238
+ /** One entry of {@link Engine.repositories}. */
239
+ export interface RepositoryEntry {
240
+ name: string | null;
241
+ dependency: string | null;
127
242
  }