@lemmabase/lemma-engine 0.9.0 → 0.9.1
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 +4 -4
- package/lemma.bindings.d.ts +16 -14
- package/lemma.bindings.js +148 -149
- package/lemma.d.ts +192 -116
- package/lemma.iife.js +1 -1
- package/lemma_bg.wasm +0 -0
- package/lemma_bg.wasm.d.ts +13 -13
- package/package.json +1 -1
package/lemma.d.ts
CHANGED
|
@@ -14,7 +14,7 @@ declare module './lemma.bindings.js' {
|
|
|
14
14
|
/**
|
|
15
15
|
* Load Lemma source(s).
|
|
16
16
|
* - string → volatile workspace source
|
|
17
|
-
* - object
|
|
17
|
+
* - object → labeled sources (key insertion order); `[label, code][]` → labeled sources (array order)
|
|
18
18
|
* Throws `EngineError[]` on failure. `null`/`undefined` rejected.
|
|
19
19
|
*/
|
|
20
20
|
load(code: string): void;
|
|
@@ -31,7 +31,7 @@ declare module './lemma.bindings.js' {
|
|
|
31
31
|
* each item has `repository` (name or null for workspace) and `specs`
|
|
32
32
|
* (`ListedSpec` rows: name, effective_from, effective_to).
|
|
33
33
|
*/
|
|
34
|
-
list():
|
|
34
|
+
list(): ResolvedRepository[];
|
|
35
35
|
|
|
36
36
|
/**
|
|
37
37
|
* Spec interface and temporal window at `effective`. Lemma text is {@link Engine.source}.
|
|
@@ -61,7 +61,7 @@ declare module './lemma.bindings.js' {
|
|
|
61
61
|
): void;
|
|
62
62
|
|
|
63
63
|
/** Resource limits configured for this engine. */
|
|
64
|
-
limits():
|
|
64
|
+
limits(): ResourceLimits;
|
|
65
65
|
|
|
66
66
|
/**
|
|
67
67
|
* Canonical formatting of Lemma source. Throws `EngineError` on parse error.
|
|
@@ -70,19 +70,28 @@ declare module './lemma.bindings.js' {
|
|
|
70
70
|
format(code: string, attribute?: string | null): string;
|
|
71
71
|
|
|
72
72
|
/**
|
|
73
|
-
*
|
|
73
|
+
* Evaluate a spec. Pass integers as numbers, decimals as strings in `data`.
|
|
74
74
|
*/
|
|
75
|
-
run(
|
|
76
|
-
repository: string | null | undefined,
|
|
77
|
-
spec: string,
|
|
78
|
-
effective: string | null | undefined,
|
|
79
|
-
data_values?: Record<string, unknown>,
|
|
80
|
-
rule_names?: string[] | string | null,
|
|
81
|
-
explain?: boolean,
|
|
82
|
-
): EvaluationResponse;
|
|
75
|
+
run(options: RunOptions): Response;
|
|
83
76
|
}
|
|
84
77
|
}
|
|
85
78
|
|
|
79
|
+
/** Options for {@link Engine.run}. */
|
|
80
|
+
export interface RunOptions {
|
|
81
|
+
/** Spec name (required). */
|
|
82
|
+
spec: string;
|
|
83
|
+
/** Repository qualifier (e.g. `@org/repo`), or omit for workspace. */
|
|
84
|
+
repository?: string | null;
|
|
85
|
+
/** ISO datetime for temporal resolution, or omit for now. */
|
|
86
|
+
effective?: string | null;
|
|
87
|
+
/** Input data values. Pass integers as numbers, decimals as strings. */
|
|
88
|
+
data?: Record<string, unknown>;
|
|
89
|
+
/** Rule names to evaluate, or omit for all rules. */
|
|
90
|
+
rules?: string[] | string | null;
|
|
91
|
+
/** Include explanation tree in response. */
|
|
92
|
+
explain?: boolean;
|
|
93
|
+
}
|
|
94
|
+
|
|
86
95
|
/**
|
|
87
96
|
* Source location attached to an {@link EngineError}. Line and column are
|
|
88
97
|
* 1-based; `length` is the UTF-8 byte length of the offending span.
|
|
@@ -126,75 +135,129 @@ export interface EngineError {
|
|
|
126
135
|
suggestion: string | null;
|
|
127
136
|
/** Present for `missing_repository` and `registry` errors (`@…` id). */
|
|
128
137
|
repository: string | null;
|
|
138
|
+
/** Present only for `kind: "registry"`. */
|
|
139
|
+
registry_kind:
|
|
140
|
+
| "not_found"
|
|
141
|
+
| "unauthorized"
|
|
142
|
+
| "network_error"
|
|
143
|
+
| "server_error"
|
|
144
|
+
| "other"
|
|
145
|
+
| null;
|
|
146
|
+
/** Present only for `kind: "request"`. */
|
|
147
|
+
request_kind: "spec_not_found" | "rule_not_found" | "invalid_request" | null;
|
|
148
|
+
/** Present only for `kind: "resource_limit"`. */
|
|
149
|
+
limit_name: string | null;
|
|
150
|
+
limit_value: string | null;
|
|
151
|
+
actual_value: string | null;
|
|
129
152
|
}
|
|
130
153
|
|
|
131
154
|
// ---------------------------------------------------------------------------
|
|
132
155
|
// Show envelope (return shape of Engine.show)
|
|
133
156
|
// ---------------------------------------------------------------------------
|
|
134
157
|
|
|
135
|
-
/**
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
158
|
+
/**
|
|
159
|
+
* API value fields shared by `RuleResult` (flattened into its top-level fields),
|
|
160
|
+
* `ShowData.prefilled`, `ShowData.suggestion`, and range endpoints.
|
|
161
|
+
* A `None` field is absent (not `null`) per Rust `skip_serializing_if`.
|
|
162
|
+
* When present: always `display`, plus exactly one typed field.
|
|
163
|
+
*/
|
|
164
|
+
export interface RuleResultValueEndpoint {
|
|
165
|
+
/** Engine-rendered string (`LiteralValue::display_value`). */
|
|
166
|
+
display?: string;
|
|
167
|
+
/** All declared measure units, keyed by unit name. */
|
|
141
168
|
measure?: Record<string, string>;
|
|
142
|
-
/** All declared ratio units
|
|
169
|
+
/** All declared ratio units, keyed by unit name. */
|
|
143
170
|
ratio?: Record<string, string>;
|
|
171
|
+
number?: string;
|
|
172
|
+
boolean?: boolean;
|
|
173
|
+
text?: string;
|
|
174
|
+
date?: string;
|
|
175
|
+
time?: string;
|
|
176
|
+
calendar?: { value: string; unit: string };
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* API value shared by `RuleResult` (flattened into its top-level fields),
|
|
181
|
+
* `ShowData.prefilled`, and `ShowData.suggestion`. When present: always `display`,
|
|
182
|
+
* plus exactly one typed field for a non-range value; `range` is set instead for a
|
|
183
|
+
* range value. A range endpoint (`range.from`/`range.to`) never itself carries a
|
|
184
|
+
* `range` field.
|
|
185
|
+
*/
|
|
186
|
+
export interface RuleResultValue extends RuleResultValueEndpoint {
|
|
187
|
+
range?: { from: RuleResultValueEndpoint; to: RuleResultValueEndpoint };
|
|
144
188
|
}
|
|
145
189
|
|
|
190
|
+
/** Where a custom type's extension chain is rooted: local to this spec, or imported. */
|
|
191
|
+
export type TypeDefiningSpec = { kind: "local" } | { kind: "import" };
|
|
192
|
+
|
|
146
193
|
export type TypeExtends =
|
|
147
|
-
| "primitive"
|
|
194
|
+
| { kind: "primitive" }
|
|
148
195
|
| {
|
|
196
|
+
kind: "custom";
|
|
149
197
|
parent: string;
|
|
150
198
|
family: string;
|
|
151
|
-
defining_spec:
|
|
199
|
+
defining_spec: TypeDefiningSpec;
|
|
152
200
|
};
|
|
153
201
|
|
|
154
|
-
|
|
202
|
+
/** A unit-scoped bound (Measure/DateRange/TimeRange/MeasureRange minimum/maximum/lower/upper). */
|
|
203
|
+
export interface NamedBound {
|
|
204
|
+
value: string;
|
|
205
|
+
unit: string;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
export interface MeasureUnit {
|
|
155
209
|
name: string;
|
|
156
210
|
factor: { numer: string; denom: string };
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
211
|
+
/** (measure_ref, exponent) pairs from a compound unit declaration (e.g. meter/second). */
|
|
212
|
+
derived_measure_factors: [string, number][];
|
|
213
|
+
decomposition: Record<string, number>;
|
|
214
|
+
minimum?: string;
|
|
215
|
+
maximum?: string;
|
|
216
|
+
suggestion?: string;
|
|
160
217
|
}
|
|
161
218
|
|
|
162
|
-
export interface
|
|
219
|
+
export interface RatioUnit {
|
|
163
220
|
name: string;
|
|
164
221
|
value: { numer: string; denom: string };
|
|
165
|
-
minimum?: string
|
|
166
|
-
maximum?: string
|
|
167
|
-
suggestion?: string
|
|
222
|
+
minimum?: string;
|
|
223
|
+
maximum?: string;
|
|
224
|
+
suggestion?: string;
|
|
168
225
|
}
|
|
169
226
|
|
|
170
|
-
/**
|
|
171
|
-
*
|
|
172
|
-
*
|
|
227
|
+
/**
|
|
228
|
+
* Discriminated union over the 12 Lemma type kinds reachable at the API boundary.
|
|
229
|
+
* Field `kind` is the serde tag; kind-specific fields sit at the top level next to
|
|
230
|
+
* `kind`, `name`, and `extends`. The `veto`/`undetermined` `TypeSpecification`
|
|
231
|
+
* variants are internal sentinels that never reach a successfully planned API
|
|
232
|
+
* response and are intentionally excluded.
|
|
233
|
+
*/
|
|
173
234
|
export type LemmaType =
|
|
174
235
|
& { name: string | null; extends: TypeExtends }
|
|
175
236
|
& (
|
|
176
237
|
| { kind: "boolean"; help: string }
|
|
177
238
|
| {
|
|
178
239
|
kind: "measure";
|
|
179
|
-
minimum:
|
|
180
|
-
maximum:
|
|
240
|
+
minimum: NamedBound | null;
|
|
241
|
+
maximum: NamedBound | null;
|
|
181
242
|
decimals: number | null;
|
|
182
|
-
units:
|
|
243
|
+
units: MeasureUnit[];
|
|
244
|
+
traits: ("duration" | "calendar")[];
|
|
245
|
+
decomposition: Record<string, number> | null;
|
|
183
246
|
help: string;
|
|
184
247
|
}
|
|
185
248
|
| {
|
|
186
|
-
kind: "
|
|
249
|
+
kind: "number";
|
|
187
250
|
minimum: string | null;
|
|
188
251
|
maximum: string | null;
|
|
189
252
|
decimals: number | null;
|
|
190
|
-
units: UnitDef[];
|
|
191
253
|
help: string;
|
|
192
254
|
}
|
|
193
255
|
| {
|
|
194
|
-
kind: "
|
|
256
|
+
kind: "numberrange";
|
|
257
|
+
lower: string | null;
|
|
258
|
+
upper: string | null;
|
|
195
259
|
minimum: string | null;
|
|
196
260
|
maximum: string | null;
|
|
197
|
-
decimals: number | null;
|
|
198
261
|
help: string;
|
|
199
262
|
}
|
|
200
263
|
| {
|
|
@@ -202,76 +265,98 @@ export type LemmaType =
|
|
|
202
265
|
minimum: string | null;
|
|
203
266
|
maximum: string | null;
|
|
204
267
|
decimals: number | null;
|
|
205
|
-
units:
|
|
268
|
+
units: RatioUnit[];
|
|
206
269
|
help: string;
|
|
207
270
|
}
|
|
208
271
|
| {
|
|
209
|
-
kind: "
|
|
272
|
+
kind: "ratiorange";
|
|
273
|
+
lower: string | null;
|
|
274
|
+
upper: string | null;
|
|
210
275
|
minimum: string | null;
|
|
211
276
|
maximum: string | null;
|
|
212
|
-
|
|
213
|
-
units: RatioUnitDef[];
|
|
277
|
+
units: RatioUnit[];
|
|
214
278
|
help: string;
|
|
215
279
|
}
|
|
216
280
|
| {
|
|
217
281
|
kind: "text";
|
|
218
|
-
minimum: number | null;
|
|
219
|
-
maximum: number | null;
|
|
220
282
|
length: number | null;
|
|
221
283
|
options: string[];
|
|
222
284
|
help: string;
|
|
223
285
|
}
|
|
224
286
|
| { kind: "date"; minimum: string | null; maximum: string | null; help: string }
|
|
287
|
+
| {
|
|
288
|
+
kind: "daterange";
|
|
289
|
+
lower: string | null;
|
|
290
|
+
upper: string | null;
|
|
291
|
+
minimum: NamedBound | null;
|
|
292
|
+
maximum: NamedBound | null;
|
|
293
|
+
help: string;
|
|
294
|
+
}
|
|
225
295
|
| { kind: "time"; minimum: string | null; maximum: string | null; help: string }
|
|
226
|
-
| {
|
|
296
|
+
| {
|
|
297
|
+
kind: "timerange";
|
|
298
|
+
lower: string | null;
|
|
299
|
+
upper: string | null;
|
|
300
|
+
minimum: NamedBound | null;
|
|
301
|
+
maximum: NamedBound | null;
|
|
302
|
+
help: string;
|
|
303
|
+
}
|
|
304
|
+
| {
|
|
305
|
+
kind: "measurerange";
|
|
306
|
+
lower: NamedBound | null;
|
|
307
|
+
upper: NamedBound | null;
|
|
308
|
+
minimum: NamedBound | null;
|
|
309
|
+
maximum: NamedBound | null;
|
|
310
|
+
units: MeasureUnit[];
|
|
311
|
+
decomposition: Record<string, number> | null;
|
|
312
|
+
help: string;
|
|
313
|
+
}
|
|
227
314
|
);
|
|
228
315
|
|
|
229
316
|
/** One input declared in a spec. Omitted fields are absent (not `null`). */
|
|
230
|
-
export interface
|
|
317
|
+
export interface ShowData {
|
|
231
318
|
type: LemmaType;
|
|
232
319
|
/** Spec literal or literal `with` binding; UIs may skip review. */
|
|
233
|
-
prefilled?:
|
|
320
|
+
prefilled?: RuleResultValue;
|
|
234
321
|
/** `-> suggest ...` suggestion; prompt with prefill in interactive UIs. */
|
|
235
|
-
suggestion?:
|
|
322
|
+
suggestion?: RuleResultValue;
|
|
236
323
|
/** Local rule names that transitively need this data (planning time). */
|
|
237
324
|
needed_by_rules: string[];
|
|
238
325
|
}
|
|
239
326
|
|
|
240
327
|
/** Return shape of {@link Engine.run}. */
|
|
241
|
-
export interface
|
|
328
|
+
export interface Response {
|
|
242
329
|
spec: string;
|
|
243
330
|
effective: string;
|
|
331
|
+
/** Declared temporal window of the resolved spec version actually evaluated. */
|
|
332
|
+
spec_effective_from?: string;
|
|
333
|
+
spec_effective_to?: string;
|
|
244
334
|
results: Record<string, RuleResult>;
|
|
245
335
|
}
|
|
246
336
|
|
|
247
|
-
|
|
337
|
+
/**
|
|
338
|
+
* A rule's result. Fields of `RuleResultValue` are flattened directly onto this
|
|
339
|
+
* object (the Rust side uses `#[serde(flatten)]`), so a measure result's map appears
|
|
340
|
+
* at `result.measure`, not nested under a `value` key.
|
|
341
|
+
*/
|
|
342
|
+
export type RuleResult = RuleResultValue & {
|
|
248
343
|
vetoed: boolean;
|
|
249
|
-
|
|
250
|
-
veto_reason?: string | null;
|
|
344
|
+
veto_reason?: string;
|
|
251
345
|
rule_type: string;
|
|
252
|
-
/** Input keys still unbound for this rule (
|
|
346
|
+
/** Input keys still unbound for this rule (run-data-aware; same keys as Show.data). */
|
|
253
347
|
missing_data?: string[];
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
boolean?: boolean | null;
|
|
258
|
-
text?: string | null;
|
|
259
|
-
date?: unknown | null;
|
|
260
|
-
time?: unknown | null;
|
|
261
|
-
calendar?: { value: string; unit: string } | null;
|
|
262
|
-
range?: { from: RuleResultPayload; to: RuleResultPayload } | null;
|
|
263
|
-
/** Present when `run(..., explain: true)`. Shape: documentation/schemas/explanation.v1.json */
|
|
264
|
-
explanation?: Explanation | null;
|
|
265
|
-
}
|
|
348
|
+
/** Present when `run(..., explain: true)`. Shape: documentation/schemas/api.v1.json (`RuleResult.explanation`). */
|
|
349
|
+
explanation?: Explanation;
|
|
350
|
+
};
|
|
266
351
|
|
|
267
352
|
/** One evaluated unless condition, stated as a fact. */
|
|
268
|
-
export interface
|
|
353
|
+
export interface Cause {
|
|
269
354
|
condition: string;
|
|
270
355
|
value: string;
|
|
271
356
|
children?: ExplanationNode[];
|
|
272
357
|
}
|
|
273
358
|
|
|
274
|
-
export interface
|
|
359
|
+
export interface ConversionStep {
|
|
275
360
|
role: "outcome" | "rule" | "source";
|
|
276
361
|
text: string;
|
|
277
362
|
}
|
|
@@ -283,7 +368,7 @@ export type ExplanationNode =
|
|
|
283
368
|
name: string;
|
|
284
369
|
result: string;
|
|
285
370
|
body: string;
|
|
286
|
-
causes?:
|
|
371
|
+
causes?: Cause[];
|
|
287
372
|
children?: ExplanationNode[];
|
|
288
373
|
}
|
|
289
374
|
| {
|
|
@@ -303,16 +388,12 @@ export type ExplanationNode =
|
|
|
303
388
|
| {
|
|
304
389
|
type: "conversion";
|
|
305
390
|
expression: string;
|
|
306
|
-
steps:
|
|
391
|
+
steps: ConversionStep[];
|
|
307
392
|
operands: ExplanationNode[];
|
|
308
393
|
}
|
|
309
394
|
| {
|
|
310
395
|
type: "veto";
|
|
311
396
|
message?: string;
|
|
312
|
-
}
|
|
313
|
-
| {
|
|
314
|
-
type: "unit_equivalence";
|
|
315
|
-
text: string;
|
|
316
397
|
};
|
|
317
398
|
|
|
318
399
|
/** Root and nested rule explanation (same shape). */
|
|
@@ -321,69 +402,64 @@ export interface Explanation {
|
|
|
321
402
|
name: string;
|
|
322
403
|
result: string;
|
|
323
404
|
body: string;
|
|
324
|
-
causes?:
|
|
405
|
+
causes?: Cause[];
|
|
325
406
|
children?: ExplanationNode[];
|
|
326
407
|
}
|
|
327
408
|
|
|
328
|
-
export interface RuleResultPayload {
|
|
329
|
-
measure?: Record<string, string> | null;
|
|
330
|
-
ratio?: Record<string, string> | null;
|
|
331
|
-
number?: string | null;
|
|
332
|
-
boolean?: boolean | null;
|
|
333
|
-
text?: string | null;
|
|
334
|
-
date?: unknown | null;
|
|
335
|
-
time?: unknown | null;
|
|
336
|
-
calendar?: { value: string; unit: string } | null;
|
|
337
|
-
}
|
|
338
|
-
|
|
339
409
|
/** Half-open `[effective_from, effective_to)` for one loaded temporal row. */
|
|
340
410
|
export interface ShowVersion {
|
|
341
|
-
effective_from?: string
|
|
342
|
-
effective_to?: string
|
|
411
|
+
effective_from?: string;
|
|
412
|
+
effective_to?: string;
|
|
343
413
|
}
|
|
344
414
|
|
|
415
|
+
/** Provenance of a loaded source. Externally tagged; the unit `Volatile` variant
|
|
416
|
+
* is the bare string `"volatile"`. */
|
|
417
|
+
export type SourceType = "volatile" | { path: string } | { dependency: string };
|
|
418
|
+
|
|
419
|
+
/** Parsed literal value (meta field value). Externally tagged. */
|
|
420
|
+
export type LiteralValue =
|
|
421
|
+
| { number: string }
|
|
422
|
+
| { number_with_unit: [string, string] }
|
|
423
|
+
| { text: string }
|
|
424
|
+
| { date: string }
|
|
425
|
+
| { time: string }
|
|
426
|
+
| { boolean: "true" | "false" | "yes" | "no" }
|
|
427
|
+
| { range: [LiteralValue, LiteralValue] };
|
|
428
|
+
|
|
429
|
+
/** Spec `meta` field value. Externally tagged. */
|
|
430
|
+
export type MetaValue = { literal: LiteralValue } | { unquoted: string };
|
|
431
|
+
|
|
345
432
|
/** Return shape of {@link Engine.show}. */
|
|
346
433
|
export interface Show {
|
|
347
434
|
spec: string;
|
|
348
|
-
commentary?: string
|
|
349
|
-
effective_from?: string
|
|
350
|
-
effective_to?: string
|
|
435
|
+
commentary?: string;
|
|
436
|
+
effective_from?: string;
|
|
437
|
+
effective_to?: string;
|
|
351
438
|
start_line: number;
|
|
352
|
-
source_type?:
|
|
439
|
+
source_type?: SourceType;
|
|
353
440
|
versions?: ShowVersion[];
|
|
354
|
-
data: Record<string,
|
|
441
|
+
data: Record<string, ShowData>;
|
|
355
442
|
/** Rule result types; measure and ratio entries expose `units[]` like their data counterparts. */
|
|
356
443
|
rules: Record<string, LemmaType>;
|
|
357
|
-
meta: Record<string,
|
|
444
|
+
meta: Record<string, MetaValue>;
|
|
358
445
|
}
|
|
359
446
|
|
|
360
|
-
/**
|
|
361
|
-
export interface
|
|
447
|
+
/** Slim listed spec row (engine `list`). */
|
|
448
|
+
export interface ListedSpec {
|
|
362
449
|
name: string;
|
|
363
|
-
effective_from?:
|
|
364
|
-
effective_to?:
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
/** JSON mirror of Rust `ResolvedRepository` (engine `list`). */
|
|
368
|
-
export interface ResolvedRepositoryJson {
|
|
369
|
-
repository: string | null;
|
|
370
|
-
specs: ListedSpecJson[];
|
|
450
|
+
effective_from?: string;
|
|
451
|
+
effective_to?: string;
|
|
371
452
|
}
|
|
372
453
|
|
|
373
|
-
/**
|
|
374
|
-
export interface
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
hour: number;
|
|
379
|
-
minute: number;
|
|
380
|
-
second: number;
|
|
381
|
-
microsecond: number;
|
|
382
|
-
timezone: unknown;
|
|
454
|
+
/** Rust `ResolvedRepository` (engine `list`). */
|
|
455
|
+
export interface ResolvedRepository {
|
|
456
|
+
/** Absent for the local workspace group (only real repositories carry a name). */
|
|
457
|
+
repository?: string;
|
|
458
|
+
specs: ListedSpec[];
|
|
383
459
|
}
|
|
384
460
|
|
|
385
|
-
/**
|
|
386
|
-
export interface
|
|
461
|
+
/** Rust `ResourceLimits`. */
|
|
462
|
+
export interface ResourceLimits {
|
|
387
463
|
max_source_size_bytes: number;
|
|
388
464
|
max_expression_depth: number;
|
|
389
465
|
max_expression_count: number;
|