@lemmabase/lemma-engine 0.8.21 → 0.9.0

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
@@ -12,14 +12,13 @@ export interface RegistryFetchResult {
12
12
  declare module './lemma.bindings.js' {
13
13
  interface Engine {
14
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.
15
+ * Load Lemma source(s).
16
+ * - string volatile workspace source
17
+ * - object or `[label, code][]` labeled sources in one planning pass
18
+ * Throws `EngineError[]` on failure. `null`/`undefined` rejected.
18
19
  */
19
- load_batch(
20
- sources: Record<string, string>,
21
- dependency?: string | null,
22
- ): void;
20
+ load(code: string): void;
21
+ load(sources: Record<string, string> | Array<[string, string]>): void;
23
22
 
24
23
  /**
25
24
  * Download Lemma source from the registry for `name` (e.g. `@org/pkg`). Resolves with
@@ -29,38 +28,56 @@ declare module './lemma.bindings.js' {
29
28
 
30
29
  /**
31
30
  * 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[]`).
31
+ * each item has `repository` (name or null for workspace) and `specs`
32
+ * (`ListedSpec` rows: name, effective_from, effective_to).
34
33
  */
35
34
  list(): ResolvedRepositoryJson[];
36
35
 
37
36
  /**
38
- * Formatted Lemma source for a loaded repository (from in-engine AST). Use `"lemma"` for embedded units stdlib.
37
+ * Spec interface and temporal window at `effective`. Lemma text is {@link Engine.source}.
38
+ */
39
+ show(
40
+ repository: string | null | undefined,
41
+ spec: string,
42
+ effective?: string | null,
43
+ ): Show;
44
+
45
+ /**
46
+ * Formatted canonical Lemma source. Omit `spec` for whole-repository text.
39
47
  */
40
- format_repository(repository: string): string;
48
+ source(
49
+ repository: string | null | undefined,
50
+ spec?: string | null,
51
+ effective?: string | null,
52
+ ): string;
41
53
 
42
54
  /**
43
- * `repository`: qualifier or `null`/omit for workspace — same as `Engine::schema` `repo`.
55
+ * Remove a temporal spec slice. `effective`: ISO datetime or omit for now.
44
56
  */
45
- schema(
57
+ remove(
46
58
  repository: string | null | undefined,
47
59
  spec: string,
48
60
  effective?: string | null,
49
- ): SpecSchema;
61
+ ): void;
62
+
63
+ /** Resource limits configured for this engine. */
64
+ limits(): ResourceLimitsJson;
50
65
 
51
66
  /**
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.
67
+ * Canonical formatting of Lemma source. Throws `EngineError` on parse error.
68
+ * `attribute` is an optional path label used in error messages.
69
+ */
70
+ format(code: string, attribute?: string | null): string;
71
+
72
+ /**
73
+ * `data_values`: pass integers as numbers, decimals as strings.
57
74
  */
58
75
  run(
59
76
  repository: string | null | undefined,
60
77
  spec: string,
61
- rule_names: string[] | string,
62
- data_values: Record<string, unknown>,
63
- effective?: string | null,
78
+ effective: string | null | undefined,
79
+ data_values?: Record<string, unknown>,
80
+ rule_names?: string[] | string | null,
64
81
  explain?: boolean,
65
82
  ): EvaluationResponse;
66
83
  }
@@ -78,8 +95,8 @@ export interface EngineErrorSource {
78
95
  }
79
96
 
80
97
  /**
81
- * Structured error thrown by {@link Engine.run}, {@link Engine.schema},
82
- * {@link Engine.format}, {@link Engine.load}, and {@link Engine.load_batch}
98
+ * Structured error thrown by {@link Engine.run}, {@link Engine.show},
99
+ * {@link Engine.load}, and {@link Engine.fetch}
83
100
  * (as an array), and rejected from {@link Engine.fetch} (as an array).
84
101
  *
85
102
  * - `kind` classifies the failure ("parsing" for syntax, "validation" for
@@ -112,13 +129,20 @@ export interface EngineError {
112
129
  }
113
130
 
114
131
  // ---------------------------------------------------------------------------
115
- // Schema envelope (return shape of Engine.schema)
132
+ // Show envelope (return shape of Engine.show)
116
133
  // ---------------------------------------------------------------------------
117
134
 
118
- /** Literal value produced by `JSON.stringify` on a Lemma `LiteralValue`. */
119
- export type LiteralValue = unknown;
135
+ /** Literal value on API wire (`suggestion`, `prefilled`, committed `value`). Canonical plan storage omits `measure` / `ratio` maps. */
136
+ export interface WireLiteralValue {
137
+ value: unknown;
138
+ lemma_type: LemmaType;
139
+ display_value: string;
140
+ /** All declared measure units when the type has unit definitions. */
141
+ measure?: Record<string, string>;
142
+ /** All declared ratio units when the type has unit definitions. */
143
+ ratio?: Record<string, string>;
144
+ }
120
145
 
121
- /** Extension classification serialized on every {@link LemmaType}. */
122
146
  export type TypeExtends =
123
147
  | "primitive"
124
148
  | {
@@ -132,7 +156,7 @@ export interface UnitDef {
132
156
  factor: { numer: string; denom: string };
133
157
  minimum?: string | null;
134
158
  maximum?: string | null;
135
- default?: string | null;
159
+ suggestion?: string | null;
136
160
  }
137
161
 
138
162
  export interface RatioUnitDef {
@@ -140,7 +164,7 @@ export interface RatioUnitDef {
140
164
  value: { numer: string; denom: string };
141
165
  minimum?: string | null;
142
166
  maximum?: string | null;
143
- default?: string | null;
167
+ suggestion?: string | null;
144
168
  }
145
169
 
146
170
  /** Discriminated union over the 10 Lemma type kinds. Field `kind` is the
@@ -205,10 +229,12 @@ export type LemmaType =
205
229
  /** One input declared in a spec. Omitted fields are absent (not `null`). */
206
230
  export interface DataEntry {
207
231
  type: LemmaType;
208
- /** Literal bound in the source (`data x: literal`). */
209
- bound_value?: LiteralValue;
210
- /** `-> default ...` suggestion; omitted from `bound_value` until evaluation applies it. */
211
- default?: LiteralValue;
232
+ /** Spec literal or literal `with` binding; UIs may skip review. */
233
+ prefilled?: WireLiteralValue;
234
+ /** `-> suggest ...` suggestion; prompt with prefill in interactive UIs. */
235
+ suggestion?: WireLiteralValue;
236
+ /** Local rule names that transitively need this data (planning time). */
237
+ needed_by_rules: string[];
212
238
  }
213
239
 
214
240
  /** Return shape of {@link Engine.run}. */
@@ -216,7 +242,6 @@ export interface EvaluationResponse {
216
242
  spec: string;
217
243
  effective: string;
218
244
  results: Record<string, RuleResult>;
219
- data: EvaluationDataEntry[];
220
245
  }
221
246
 
222
247
  export interface RuleResult {
@@ -224,6 +249,8 @@ export interface RuleResult {
224
249
  display?: string | null;
225
250
  veto_reason?: string | null;
226
251
  rule_type: string;
252
+ /** Input keys still unbound for this rule (overlay-aware; same keys as Show.data). */
253
+ missing_data?: string[];
227
254
  measure?: Record<string, string> | null;
228
255
  ratio?: Record<string, string> | null;
229
256
  number?: string | null;
@@ -233,7 +260,69 @@ export interface RuleResult {
233
260
  time?: unknown | null;
234
261
  calendar?: { value: string; unit: string } | null;
235
262
  range?: { from: RuleResultPayload; to: RuleResultPayload } | null;
236
- explanation?: unknown | null;
263
+ /** Present when `run(..., explain: true)`. Shape: documentation/schemas/explanation.v1.json */
264
+ explanation?: Explanation | null;
265
+ }
266
+
267
+ /** One evaluated unless condition, stated as a fact. */
268
+ export interface ExplanationCause {
269
+ condition: string;
270
+ value: string;
271
+ children?: ExplanationNode[];
272
+ }
273
+
274
+ export interface ExplanationConversionStep {
275
+ role: "outcome" | "rule" | "source";
276
+ text: string;
277
+ }
278
+
279
+ /** Nested explanation tree node (tagged by `type`). */
280
+ export type ExplanationNode =
281
+ | {
282
+ type: "rule";
283
+ name: string;
284
+ result: string;
285
+ body: string;
286
+ causes?: ExplanationCause[];
287
+ children?: ExplanationNode[];
288
+ }
289
+ | {
290
+ type: "compose";
291
+ expression: string;
292
+ operands: ExplanationNode[];
293
+ }
294
+ | {
295
+ type: "data";
296
+ name: string;
297
+ display: string;
298
+ }
299
+ | {
300
+ type: "data_unused";
301
+ name: string;
302
+ }
303
+ | {
304
+ type: "conversion";
305
+ expression: string;
306
+ steps: ExplanationConversionStep[];
307
+ operands: ExplanationNode[];
308
+ }
309
+ | {
310
+ type: "veto";
311
+ message?: string;
312
+ }
313
+ | {
314
+ type: "unit_equivalence";
315
+ text: string;
316
+ };
317
+
318
+ /** Root and nested rule explanation (same shape). */
319
+ export interface Explanation {
320
+ type: "rule";
321
+ name: string;
322
+ result: string;
323
+ body: string;
324
+ causes?: ExplanationCause[];
325
+ children?: ExplanationNode[];
237
326
  }
238
327
 
239
328
  export interface RuleResultPayload {
@@ -247,48 +336,40 @@ export interface RuleResultPayload {
247
336
  calendar?: { value: string; unit: string } | null;
248
337
  }
249
338
 
250
- export interface EvaluationDataEntry {
251
- path: string;
252
- value: unknown;
339
+ /** Half-open `[effective_from, effective_to)` for one loaded temporal row. */
340
+ export interface ShowVersion {
341
+ effective_from?: string | null;
342
+ effective_to?: string | null;
253
343
  }
254
344
 
255
- /** Return shape of {@link Engine.schema}. */
256
- export interface SpecSchema {
345
+ /** Return shape of {@link Engine.show}. */
346
+ export interface Show {
257
347
  spec: string;
348
+ commentary?: string | null;
349
+ effective_from?: string | null;
350
+ effective_to?: string | null;
351
+ start_line: number;
352
+ source_type?: string | null;
353
+ versions?: ShowVersion[];
258
354
  data: Record<string, DataEntry>;
259
355
  /** Rule result types; measure and ratio entries expose `units[]` like their data counterparts. */
260
356
  rules: Record<string, LemmaType>;
261
357
  meta: Record<string, unknown>;
262
358
  }
263
359
 
264
- /** JSON mirror of Rust `ResolvedRepository` (engine `list`). */
265
- export interface ResolvedRepositoryJson {
266
- repository: LemmaRepositoryJson;
267
- /** [`LemmaSpecSet`] list for this resolved repository. */
268
- specs: LemmaSpecSetJson[];
269
- }
270
-
271
- /** JSON mirror of Rust `LemmaSpecSet` as serialized by the engine. */
272
- export interface LemmaSpecSetJson {
273
- repository: LemmaRepositoryJson;
360
+ /** JSON mirror of slim listed spec row (engine `list`). */
361
+ export interface ListedSpecJson {
274
362
  name: string;
275
- /** Temporal versions, ascending `effective_from` (same order as `iter_specs`). */
276
- specs: LemmaSpecJson[];
363
+ effective_from?: DateTimeValueJson | null;
364
+ effective_to?: DateTimeValueJson | null;
277
365
  }
278
366
 
279
- /** JSON mirror of Rust `LemmaRepository`. */
280
- export interface LemmaRepositoryJson {
281
- name: string | null;
282
- dependency: string | null;
283
- start_line: number;
284
- source_type: unknown;
367
+ /** JSON mirror of Rust `ResolvedRepository` (engine `list`). */
368
+ export interface ResolvedRepositoryJson {
369
+ repository: string | null;
370
+ specs: ListedSpecJson[];
285
371
  }
286
372
 
287
- /** JSON mirror of Rust `EffectiveDate` (externally tagged). */
288
- export type EffectiveDateJson =
289
- | { Origin: null }
290
- | { DateTimeValue: DateTimeValueJson };
291
-
292
373
  /** JSON mirror of Rust `DateTimeValue`. */
293
374
  export interface DateTimeValueJson {
294
375
  year: number;
@@ -301,14 +382,16 @@ export interface DateTimeValueJson {
301
382
  timezone: unknown;
302
383
  }
303
384
 
304
- /** JSON mirror of Rust `LemmaSpec` (full AST; deep nodes are engine-shaped). */
305
- export interface LemmaSpecJson {
306
- name: string;
307
- effective_from: EffectiveDateJson;
308
- source_type: unknown;
309
- start_line: number;
310
- commentary: string | null;
311
- data: unknown[];
312
- rules: unknown[];
313
- meta_fields: unknown[];
385
+ /** JSON mirror of Rust `ResourceLimits`. */
386
+ export interface ResourceLimitsJson {
387
+ max_source_size_bytes: number;
388
+ max_expression_depth: number;
389
+ max_expression_count: number;
390
+ max_data_value_bytes: number;
391
+ max_loaded_bytes: number;
392
+ max_sources: number;
393
+ max_normalized_expression_nodes: number;
394
+ max_spec_dependency_depth: number;
395
+ max_dag_specs: number;
396
+ max_normal_form_depth: number;
314
397
  }