@lemmabase/lemma-engine 0.8.22 → 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
@@ -206,11 +230,11 @@ export type LemmaType =
206
230
  export interface DataEntry {
207
231
  type: LemmaType;
208
232
  /** 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. */
213
- default?: LiteralValue;
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[];
214
238
  }
215
239
 
216
240
  /** Return shape of {@link Engine.run}. */
@@ -218,7 +242,6 @@ export interface EvaluationResponse {
218
242
  spec: string;
219
243
  effective: string;
220
244
  results: Record<string, RuleResult>;
221
- data: EvaluationDataEntry[];
222
245
  }
223
246
 
224
247
  export interface RuleResult {
@@ -226,6 +249,8 @@ export interface RuleResult {
226
249
  display?: string | null;
227
250
  veto_reason?: string | null;
228
251
  rule_type: string;
252
+ /** Input keys still unbound for this rule (overlay-aware; same keys as Show.data). */
253
+ missing_data?: string[];
229
254
  measure?: Record<string, string> | null;
230
255
  ratio?: Record<string, string> | null;
231
256
  number?: string | null;
@@ -235,7 +260,69 @@ export interface RuleResult {
235
260
  time?: unknown | null;
236
261
  calendar?: { value: string; unit: string } | null;
237
262
  range?: { from: RuleResultPayload; to: RuleResultPayload } | null;
238
- 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[];
239
326
  }
240
327
 
241
328
  export interface RuleResultPayload {
@@ -249,48 +336,40 @@ export interface RuleResultPayload {
249
336
  calendar?: { value: string; unit: string } | null;
250
337
  }
251
338
 
252
- export interface EvaluationDataEntry {
253
- path: string;
254
- 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;
255
343
  }
256
344
 
257
- /** Return shape of {@link Engine.schema}. */
258
- export interface SpecSchema {
345
+ /** Return shape of {@link Engine.show}. */
346
+ export interface Show {
259
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[];
260
354
  data: Record<string, DataEntry>;
261
355
  /** Rule result types; measure and ratio entries expose `units[]` like their data counterparts. */
262
356
  rules: Record<string, LemmaType>;
263
357
  meta: Record<string, unknown>;
264
358
  }
265
359
 
266
- /** JSON mirror of Rust `ResolvedRepository` (engine `list`). */
267
- export interface ResolvedRepositoryJson {
268
- repository: LemmaRepositoryJson;
269
- /** [`LemmaSpecSet`] list for this resolved repository. */
270
- specs: LemmaSpecSetJson[];
271
- }
272
-
273
- /** JSON mirror of Rust `LemmaSpecSet` as serialized by the engine. */
274
- export interface LemmaSpecSetJson {
275
- repository: LemmaRepositoryJson;
360
+ /** JSON mirror of slim listed spec row (engine `list`). */
361
+ export interface ListedSpecJson {
276
362
  name: string;
277
- /** Temporal versions, ascending `effective_from` (same order as `iter_specs`). */
278
- specs: LemmaSpecJson[];
363
+ effective_from?: DateTimeValueJson | null;
364
+ effective_to?: DateTimeValueJson | null;
279
365
  }
280
366
 
281
- /** JSON mirror of Rust `LemmaRepository`. */
282
- export interface LemmaRepositoryJson {
283
- name: string | null;
284
- dependency: string | null;
285
- start_line: number;
286
- source_type: unknown;
367
+ /** JSON mirror of Rust `ResolvedRepository` (engine `list`). */
368
+ export interface ResolvedRepositoryJson {
369
+ repository: string | null;
370
+ specs: ListedSpecJson[];
287
371
  }
288
372
 
289
- /** JSON mirror of Rust `EffectiveDate` (externally tagged). */
290
- export type EffectiveDateJson =
291
- | { Origin: null }
292
- | { DateTimeValue: DateTimeValueJson };
293
-
294
373
  /** JSON mirror of Rust `DateTimeValue`. */
295
374
  export interface DateTimeValueJson {
296
375
  year: number;
@@ -303,14 +382,16 @@ export interface DateTimeValueJson {
303
382
  timezone: unknown;
304
383
  }
305
384
 
306
- /** JSON mirror of Rust `LemmaSpec` (full AST; deep nodes are engine-shaped). */
307
- export interface LemmaSpecJson {
308
- name: string;
309
- effective_from: EffectiveDateJson;
310
- source_type: unknown;
311
- start_line: number;
312
- commentary: string | null;
313
- data: unknown[];
314
- rules: unknown[];
315
- 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;
316
397
  }