@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/lemma.d.ts CHANGED
@@ -3,6 +3,65 @@ 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
+ * Formatted Lemma source for a loaded repository (from in-engine AST). Use `"lemma"` for embedded SI stdlib.
39
+ */
40
+ format_repository(repository: string): string;
41
+
42
+ /**
43
+ * `repository`: qualifier or `null`/omit for workspace — same as `Engine::schema` `repo`.
44
+ */
45
+ schema(
46
+ repository: string | null | undefined,
47
+ spec: string,
48
+ effective?: string | null,
49
+ ): SpecSchema;
50
+
51
+ /**
52
+ * `repository`: qualifier or `null`/omit for workspace — same as `Engine::run` `repo`.
53
+ */
54
+ run(
55
+ repository: string | null | undefined,
56
+ spec: string,
57
+ rule_names: string[] | string,
58
+ data_values: Record<string, unknown>,
59
+ rule_result_units?: Record<string, string> | null,
60
+ effective?: string | null,
61
+ ): any;
62
+ }
63
+ }
64
+
6
65
  /**
7
66
  * Source location attached to an {@link EngineError}. Line and column are
8
67
  * 1-based; `length` is the UTF-8 byte length of the offending span.
@@ -16,11 +75,12 @@ export interface EngineErrorSource {
16
75
 
17
76
  /**
18
77
  * Structured error thrown by {@link Engine.run}, {@link Engine.schema},
19
- * {@link Engine.format}, and rejected from {@link Engine.load} (as an array).
78
+ * {@link Engine.format}, {@link Engine.load}, and {@link Engine.load_batch}
79
+ * (as an array), and rejected from {@link Engine.fetch} (as an array).
20
80
  *
21
81
  * - `kind` classifies the failure ("parsing" for syntax, "validation" for
22
- * semantic/planning including bad data values, "request" for bad API input,
23
- * etc.).
82
+ * semantic/planning including bad data values, "missing_repository" when a
83
+ * referenced repo is not loaded, "request" for bad API input, etc.).
24
84
  * - `message` is the inner reason only. Callers that previously parsed
25
85
  * `"Failed to parse data 'X' as Y: ..."` strings should now use `related_data`
26
86
  * for attribution and `message` for the reason.
@@ -29,17 +89,26 @@ export interface EngineErrorSource {
29
89
  * - `source` points at the offending range in the original Lemma source.
30
90
  */
31
91
  export interface EngineError {
32
- kind: "parsing" | "validation" | "inversion" | "registry" | "request" | "resource_limit";
92
+ kind:
93
+ | "parsing"
94
+ | "validation"
95
+ | "inversion"
96
+ | "registry"
97
+ | "missing_repository"
98
+ | "request"
99
+ | "resource_limit";
33
100
  message: string;
34
101
  related_data: string | null;
35
102
  spec: string | null;
36
103
  related_spec: string | null;
37
104
  source: EngineErrorSource | null;
38
105
  suggestion: string | null;
106
+ /** Present for `missing_repository` and `registry` errors (`@…` id). */
107
+ repository: string | null;
39
108
  }
40
109
 
41
110
  // ---------------------------------------------------------------------------
42
- // Schema envelope (return shape of Engine.schema and Engine.list entries)
111
+ // Schema envelope (return shape of Engine.schema)
43
112
  // ---------------------------------------------------------------------------
44
113
 
45
114
  /** Literal value produced by `JSON.stringify` on a Lemma `LiteralValue`. */
@@ -54,8 +123,21 @@ export type TypeExtends =
54
123
  defining_spec: unknown;
55
124
  };
56
125
 
57
- export interface UnitDef { name: string; value: string }
58
- export interface RatioUnitDef { name: string; value: string }
126
+ export interface UnitDef {
127
+ name: string;
128
+ factor: { numer: string; denom: string };
129
+ minimum?: string | null;
130
+ maximum?: string | null;
131
+ default?: string | null;
132
+ }
133
+
134
+ export interface RatioUnitDef {
135
+ name: string;
136
+ value: { numer: string; denom: string };
137
+ minimum?: string | null;
138
+ maximum?: string | null;
139
+ default?: string | null;
140
+ }
59
141
 
60
142
  /** Discriminated union over the 10 Lemma type kinds. Field `kind` is the
61
143
  * serde tag; kind-specific fields sit at the top level next to `kind`,
@@ -65,11 +147,18 @@ export type LemmaType =
65
147
  & (
66
148
  | { kind: "boolean"; help: string }
67
149
  | {
68
- kind: "scale";
150
+ kind: "quantity";
151
+ minimum: string | null;
152
+ maximum: string | null;
153
+ decimals: number | null;
154
+ units: UnitDef[];
155
+ help: string;
156
+ }
157
+ | {
158
+ kind: "quantity range";
69
159
  minimum: string | null;
70
160
  maximum: string | null;
71
161
  decimals: number | null;
72
- precision: string | null;
73
162
  units: UnitDef[];
74
163
  help: string;
75
164
  }
@@ -78,7 +167,6 @@ export type LemmaType =
78
167
  minimum: string | null;
79
168
  maximum: string | null;
80
169
  decimals: number | null;
81
- precision: string | null;
82
170
  help: string;
83
171
  }
84
172
  | {
@@ -89,6 +177,14 @@ export type LemmaType =
89
177
  units: RatioUnitDef[];
90
178
  help: string;
91
179
  }
180
+ | {
181
+ kind: "ratio range";
182
+ minimum: string | null;
183
+ maximum: string | null;
184
+ decimals: number | null;
185
+ units: RatioUnitDef[];
186
+ help: string;
187
+ }
92
188
  | {
93
189
  kind: "text";
94
190
  minimum: number | null;
@@ -99,13 +195,15 @@ export type LemmaType =
99
195
  }
100
196
  | { kind: "date"; minimum: string | null; maximum: string | null; help: string }
101
197
  | { kind: "time"; minimum: string | null; maximum: string | null; help: string }
102
- | { kind: "duration"; help: string }
103
198
  | { kind: "veto"; message: string | null }
104
199
  );
105
200
 
106
- /** One input on a spec. `default` is omitted (not `null`) when absent. */
201
+ /** One input declared in a spec. Omitted fields are absent (not `null`). */
107
202
  export interface DataEntry {
108
203
  type: LemmaType;
204
+ /** Literal bound in the source (`data x: literal`). */
205
+ bound_value?: LiteralValue;
206
+ /** `-> default ...` suggestion; omitted from `bound_value` until evaluation applies it. */
109
207
  default?: LiteralValue;
110
208
  }
111
209
 
@@ -113,15 +211,65 @@ export interface DataEntry {
113
211
  export interface SpecSchema {
114
212
  spec: string;
115
213
  data: Record<string, DataEntry>;
214
+ /** Rule result types; quantity and ratio entries expose `units[]` like their data counterparts. */
116
215
  rules: Record<string, LemmaType>;
117
216
  meta: Record<string, unknown>;
118
217
  }
119
218
 
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 {
219
+ /** JSON mirror of Rust `ResolvedRepository` (engine `list`). */
220
+ export interface ResolvedRepositoryJson {
221
+ repository: LemmaRepositoryJson;
222
+ /** [`LemmaSpecSet`] list for this resolved repository. */
223
+ specs: LemmaSpecSetJson[];
224
+ }
225
+
226
+ /** JSON mirror of Rust `LemmaSpecSet` as serialized by the engine. */
227
+ export interface LemmaSpecSetJson {
228
+ repository: LemmaRepositoryJson;
123
229
  name: string;
124
- effective_from: string | null;
125
- effective_to: string | null;
126
- schema: SpecSchema;
230
+ /** Temporal versions, ascending `effective_from` (same order as `iter_specs`). */
231
+ specs: LemmaSpecJson[];
232
+ }
233
+
234
+ /** JSON mirror of Rust `LemmaRepository`. */
235
+ export interface LemmaRepositoryJson {
236
+ name: string | null;
237
+ dependency: string | null;
238
+ start_line: number;
239
+ source_type: unknown;
240
+ }
241
+
242
+ /** JSON mirror of Rust `EffectiveDate` (externally tagged). */
243
+ export type EffectiveDateJson =
244
+ | { Origin: null }
245
+ | { DateTimeValue: DateTimeValueJson };
246
+
247
+ /** JSON mirror of Rust `DateTimeValue`. */
248
+ export interface DateTimeValueJson {
249
+ year: number;
250
+ month: number;
251
+ day: number;
252
+ hour: number;
253
+ minute: number;
254
+ second: number;
255
+ microsecond: number;
256
+ timezone: unknown;
257
+ }
258
+
259
+ /** JSON mirror of Rust `LemmaSpec` (full AST; deep nodes are engine-shaped). */
260
+ export interface LemmaSpecJson {
261
+ name: string;
262
+ effective_from: EffectiveDateJson;
263
+ source_type: unknown;
264
+ start_line: number;
265
+ commentary: string | null;
266
+ data: unknown[];
267
+ rules: unknown[];
268
+ meta_fields: unknown[];
269
+ }
270
+
271
+ /** One entry of {@link Engine.repositories}. */
272
+ export interface RepositoryEntry {
273
+ name: string | null;
274
+ dependency: string | null;
127
275
  }