@lemmabase/lemma-engine 0.9.8 → 0.9.10

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,8 +3,8 @@ 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 {
6
+ /** Resolved shape of {@link Engine.install}. */
7
+ export interface RepositoryInstallResult {
8
8
  source: string;
9
9
  id: string;
10
10
  }
@@ -13,12 +13,14 @@ declare module './lemma.bindings.js' {
13
13
  namespace Engine {
14
14
  /** Create engine with named limit overrides. Unknown keys throw. */
15
15
  function withLimits(limits: Record<string, number>): Engine;
16
+ /** Restore an engine from {@link Engine.snapshot} bytes. */
17
+ function fromSnapshot(bytes: Uint8Array): Engine;
16
18
  }
17
19
 
18
20
  interface Engine {
19
21
  /**
20
22
  * Load Lemma source(s).
21
- * - string → volatile workspace source
23
+ * - string → volatile source in the default repository
22
24
  * - object → labeled sources (key insertion order); `[label, code][]` → labeled sources (array order)
23
25
  * Throws `EngineError[]` on failure. `null`/`undefined` rejected.
24
26
  */
@@ -26,14 +28,15 @@ declare module './lemma.bindings.js' {
26
28
  load(sources: Record<string, string> | Array<[string, string]>): void;
27
29
 
28
30
  /**
29
- * Download Lemma source from the registry for `name` (e.g. `@org/pkg`). Resolves with
30
- * `{ source, id }`; does not load the engine. Rejects with `EngineError[]` like `load`.
31
+ * Download Lemma source from LemmaBase for `name` (e.g. `@org/pkg`). Resolves with
32
+ * `{ source, id }`; does not load the engine and does not write `lemma_deps/`.
33
+ * Rejects with `EngineError[]` like `load`.
31
34
  */
32
- fetch(name: string): Promise<RegistryFetchResult>;
35
+ install(name: string): Promise<RepositoryInstallResult>;
33
36
 
34
37
  /**
35
38
  * JSON serialization of `Vec<ResolvedRepository>` from [`Engine::list`]:
36
- * each item has `repository` (name or null for workspace) and `specs`
39
+ * each item has `repository` (name, or omitted for the default repository) and `specs`
37
40
  * (`ListedSpec` rows: name, effective_from, effective_to).
38
41
  */
39
42
  list(): ResolvedRepository[];
@@ -66,13 +69,11 @@ declare module './lemma.bindings.js' {
66
69
  ): void;
67
70
 
68
71
  /**
69
- * Replace a temporal spec slice with new source (atomic remove + load).
72
+ * Replace identities in `code` (atomic upsert; Path/Dependency prune siblings).
70
73
  * `attribute` is the source label (path or `@owner/repo`); omit for volatile.
71
74
  */
72
75
  update(
73
76
  repository: string | null | undefined,
74
- spec: string,
75
- effective: string | null | undefined,
76
77
  code: string,
77
78
  attribute?: string | null,
78
79
  ): void;
@@ -80,6 +81,12 @@ declare module './lemma.bindings.js' {
80
81
  /** Resource limits configured for this engine. */
81
82
  limits(): ResourceLimits;
82
83
 
84
+ /**
85
+ * Persist parsed specs + plans + limits as opaque bytes.
86
+ * Restore with {@link Engine.fromSnapshot}.
87
+ */
88
+ snapshot(): Uint8Array;
89
+
83
90
  /**
84
91
  * Canonical formatting of Lemma source. Throws `EngineError` on parse error.
85
92
  * `attribute` is an optional path label used in error messages.
@@ -102,7 +109,7 @@ declare module './lemma.bindings.js' {
102
109
  export interface RunOptions {
103
110
  /** Spec name (required). */
104
111
  spec: string;
105
- /** Repository qualifier (e.g. `@org/repo`), or omit for workspace. */
112
+ /** Repository qualifier (e.g. `@org/repo`), or omit for the default repository. */
106
113
  repository?: string | null;
107
114
  /** ISO datetime for temporal resolution, or omit for now. */
108
115
  effective?: string | null;
@@ -127,8 +134,8 @@ export interface EngineErrorSource {
127
134
 
128
135
  /**
129
136
  * Structured error thrown by {@link Engine.run}, {@link Engine.show},
130
- * {@link Engine.load}, and {@link Engine.fetch}
131
- * (as an array), and rejected from {@link Engine.fetch} (as an array).
137
+ * {@link Engine.load}, and {@link Engine.install}
138
+ * (as an array), and rejected from {@link Engine.install} (as an array).
132
139
  *
133
140
  * - `kind` classifies the failure ("parsing" for syntax, "validation" for
134
141
  * semantic/planning including bad data values, "missing_repository" when a
@@ -179,7 +186,7 @@ export interface EngineError {
179
186
 
180
187
  /**
181
188
  * API value fields shared by `RuleResult` (flattened into its top-level fields),
182
- * `ShowData.prefilled`, `ShowData.suggestion`, and range endpoints.
189
+ * `ShowData.fill`, `ShowData.suggestion`, and range endpoints.
183
190
  * A `None` field is absent (not `null`) per Rust `skip_serializing_if`.
184
191
  * When present: always `display`, plus exactly one typed field.
185
192
  */
@@ -200,7 +207,7 @@ export interface RuleResultValueEndpoint {
200
207
 
201
208
  /**
202
209
  * API value shared by `RuleResult` (flattened into its top-level fields),
203
- * `ShowData.prefilled`, and `ShowData.suggestion`. When present: always `display`,
210
+ * `ShowData.fill`, and `ShowData.suggestion`. When present: always `display`,
204
211
  * plus exactly one typed field for a non-range value; `range` is set instead for a
205
212
  * range value. A range endpoint (`range.from`/`range.to`) never itself carries a
206
213
  * `range` field.
@@ -339,10 +346,10 @@ export type LemmaType =
339
346
  export interface ShowData {
340
347
  type: LemmaType;
341
348
  /** Spec literal or literal `with` binding; UIs may skip review. */
342
- prefilled?: RuleResultValue;
349
+ fill?: RuleResultValue;
343
350
  /** `-> suggest ...` suggestion; prompt with prefill in interactive UIs. */
344
351
  suggestion?: RuleResultValue;
345
- /** Local rule names that transitively need this data (planning time). */
352
+ /** Local rule names that transitively need this data after normalize. Empty = reuse catalog only. */
346
353
  needed_by_rules: string[];
347
354
  }
348
355
 
@@ -365,7 +372,7 @@ export type RuleResult = RuleResultValue & {
365
372
  vetoed: boolean;
366
373
  veto_reason?: string;
367
374
  rule_type: string;
368
- /** Input keys still unbound for this rule (run-data-aware; same keys as Show.data). */
375
+ /** Input keys still unbound for this rule (run-data-aware; subset of Show.data with non-empty needed_by_rules). */
369
376
  missing_data?: string[];
370
377
  /** Present when `run(..., explain: true)`. Shape: engine/schemas/api.v1.json (`RuleResult.explanation`). */
371
378
  explanation?: Explanation;
@@ -438,7 +445,7 @@ export interface ShowVersion {
438
445
  * is the bare string `"volatile"`. */
439
446
  export type SourceType = "volatile" | { path: string } | { dependency: string };
440
447
 
441
- /** Parsed literal value (meta field value). Externally tagged. */
448
+ /** Parsed literal value. Externally tagged. */
442
449
  export type LiteralValue =
443
450
  | { number: string }
444
451
  | { number_with_unit: [string, string] }
@@ -448,8 +455,111 @@ export type LiteralValue =
448
455
  | { boolean: "true" | "false" | "yes" | "no" }
449
456
  | { range: [LiteralValue, LiteralValue] };
450
457
 
451
- /** Spec `meta` field value. Externally tagged. */
452
- export type MetaValue = { literal: LiteralValue } | { unquoted: string };
458
+ /** Conversion target on a Show `as` expression. */
459
+ export type ShowConversionTarget =
460
+ | {
461
+ type:
462
+ | "boolean"
463
+ | "measure"
464
+ | "measure_range"
465
+ | "number"
466
+ | "number_range"
467
+ | "ratio"
468
+ | "ratio_range"
469
+ | "text"
470
+ | "date"
471
+ | "date_range"
472
+ | "time"
473
+ | "time_range";
474
+ }
475
+ | { unit: { unit_name: string } };
476
+
477
+ /** Resolved expression on a Show rule branch (tagged by `type`). */
478
+ export type ShowExpression =
479
+ | ({ type: "literal" } & RuleResultValue)
480
+ | { type: "data"; name: string }
481
+ | { type: "rule"; name: string }
482
+ | { type: "and"; left: ShowExpression; right: ShowExpression }
483
+ | { type: "not"; operand: ShowExpression }
484
+ | {
485
+ type: "arithmetic";
486
+ op: "add" | "subtract" | "multiply" | "divide" | "modulo" | "power";
487
+ left: ShowExpression;
488
+ right: ShowExpression;
489
+ }
490
+ | {
491
+ type: "comparison";
492
+ op:
493
+ | "greater_than"
494
+ | "less_than"
495
+ | "greater_than_or_equal"
496
+ | "less_than_or_equal"
497
+ | "is"
498
+ | "is_not";
499
+ left: ShowExpression;
500
+ right: ShowExpression;
501
+ }
502
+ | {
503
+ type: "unit_conversion";
504
+ operand: ShowExpression;
505
+ target: ShowConversionTarget;
506
+ }
507
+ | {
508
+ type: "math";
509
+ op:
510
+ | "sqrt"
511
+ | "sin"
512
+ | "cos"
513
+ | "tan"
514
+ | "asin"
515
+ | "acos"
516
+ | "atan"
517
+ | "log"
518
+ | "exp"
519
+ | "abs"
520
+ | "floor"
521
+ | "ceil"
522
+ | "round";
523
+ operand: ShowExpression;
524
+ }
525
+ | { type: "veto"; message?: string }
526
+ | { type: "now" }
527
+ | {
528
+ type: "date_relative";
529
+ kind: "in_past" | "in_future";
530
+ operand: ShowExpression;
531
+ }
532
+ | {
533
+ type: "date_calendar";
534
+ kind: "current" | "past" | "future" | "not_in";
535
+ unit: "year" | "month" | "week";
536
+ operand: ShowExpression;
537
+ }
538
+ | { type: "range_literal"; from: ShowExpression; to: ShowExpression }
539
+ | {
540
+ type: "past_future_range";
541
+ kind: "in_past" | "in_future";
542
+ operand: ShowExpression;
543
+ }
544
+ | {
545
+ type: "range_containment";
546
+ value: ShowExpression;
547
+ range: ShowExpression;
548
+ }
549
+ | { type: "is_veto"; operand: ShowExpression };
550
+
551
+ /** One arm of a rule's flat last-match table. Default arm omits condition. */
552
+ export interface ShowBranch {
553
+ condition?: ShowExpression;
554
+ result: ShowExpression;
555
+ }
556
+
557
+ /** Local rule on Show: result type, branches, stored depends_on_rules. */
558
+ export interface ShowRule {
559
+ type: LemmaType;
560
+ branches: ShowBranch[];
561
+ depends_on_rules: string[];
562
+ }
453
563
 
454
564
  /** Return shape of {@link Engine.show}. */
455
565
  export interface Show {
@@ -461,9 +571,9 @@ export interface Show {
461
571
  source_type?: SourceType;
462
572
  versions?: ShowVersion[];
463
573
  data: Record<string, ShowData>;
464
- /** Rule result types; measure and ratio entries expose `units[]` like their data counterparts. */
465
- rules: Record<string, LemmaType>;
466
- meta: Record<string, MetaValue>;
574
+ /** Local rule graph; measure/ratio units live under `type.units`. */
575
+ rules: Record<string, ShowRule>;
576
+ meta: Record<string, LiteralValue>;
467
577
  }
468
578
 
469
579
  /** Slim listed spec row (engine `list`). */
@@ -475,7 +585,7 @@ export interface ListedSpec {
475
585
 
476
586
  /** Rust `ResolvedRepository` (engine `list`). */
477
587
  export interface ResolvedRepository {
478
- /** Absent for the local workspace group (only real repositories carry a name). */
588
+ /** Absent for the default unnamed repository (only named repositories carry a name). */
479
589
  repository?: string;
480
590
  specs: ListedSpec[];
481
591
  }