@tellegen/engine 0.2.0 → 0.3.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.
Files changed (44) hide show
  1. package/README.md +19 -14
  2. package/dist/generated/contracts.d.ts +25 -17
  3. package/dist/generated/contracts.d.ts.map +1 -1
  4. package/dist/generated/contracts.js +3 -3
  5. package/dist/generated/study-contracts.d.ts +426 -0
  6. package/dist/generated/study-contracts.d.ts.map +1 -0
  7. package/dist/generated/study-contracts.js +4 -0
  8. package/dist/generated/study-contracts.js.map +1 -0
  9. package/dist/generated/study-schema.d.ts +2 -0
  10. package/dist/generated/study-schema.d.ts.map +1 -0
  11. package/dist/generated/study-schema.js +3 -0
  12. package/dist/generated/study-schema.js.map +1 -0
  13. package/dist/host.d.ts +12 -0
  14. package/dist/host.d.ts.map +1 -1
  15. package/dist/host.js +58 -10
  16. package/dist/host.js.map +1 -1
  17. package/dist/index.d.ts +309 -119
  18. package/dist/index.d.ts.map +1 -1
  19. package/dist/index.js +359 -110
  20. package/dist/index.js.map +1 -1
  21. package/dist/input-limit.d.ts +1 -1
  22. package/dist/input-limit.js +1 -1
  23. package/dist/module.d.ts +1 -0
  24. package/dist/module.d.ts.map +1 -1
  25. package/dist/module.js.map +1 -1
  26. package/dist/protocol.d.ts +87 -26
  27. package/dist/protocol.d.ts.map +1 -1
  28. package/dist/protocol.js +60 -23
  29. package/dist/protocol.js.map +1 -1
  30. package/dist/study-document.d.ts +46 -0
  31. package/dist/study-document.d.ts.map +1 -0
  32. package/dist/study-document.js +183 -0
  33. package/dist/study-document.js.map +1 -0
  34. package/dist/study-document.test.d.ts +2 -0
  35. package/dist/study-document.test.d.ts.map +1 -0
  36. package/dist/study-document.test.js +119 -0
  37. package/dist/study-document.test.js.map +1 -0
  38. package/dist/wasm-pkg/tellegen.d.ts +167 -85
  39. package/dist/wasm-pkg/tellegen.js +667 -187
  40. package/dist/wasm-pkg/tellegen_bg.wasm +0 -0
  41. package/dist/wasm-pkg/tellegen_bg.wasm.d.ts +27 -9
  42. package/dist/worker.js +15 -3
  43. package/dist/worker.js.map +1 -1
  44. package/package.json +20 -3
package/dist/index.d.ts CHANGED
@@ -7,6 +7,24 @@ import type { BranchRatingDeltas, BrowserFormulation, DemandDeltas, NetworkBranc
7
7
  export { CONTRACT_SOURCE_SHA256, CONTRACT_VERSION, FORMULATION_IDS, SOLVE_STATUSES, } from "./generated/contracts.js";
8
8
  export { MAX_ENGINE_INPUT_BYTES } from "./input-limit.js";
9
9
  export type { BranchRatingDeltas, BrowserFormulation, CaseSummary, DemandDeltas, Network, NetworkBranch, NetworkBus, ProblemCaps, SensRequest, SensitivityColumn, SensitivityMatrix, Solution, SolveIteration, SolveRequest, SolveResponse, } from "./generated/contracts.js";
10
+ /** One structured PowerIO finding. */
11
+ export interface PowerIoDiagnostic {
12
+ code: string;
13
+ severity: "note" | "remark" | "warning" | "error";
14
+ message: string;
15
+ id?: string;
16
+ target?: string;
17
+ spans?: {
18
+ source: string;
19
+ byte_start: number;
20
+ byte_end: number;
21
+ }[];
22
+ related?: string[];
23
+ details?: Record<string, unknown>;
24
+ suggested_action?: string;
25
+ }
26
+ /** Compact display spelling for a structured PowerIO finding. */
27
+ export declare function formatPowerIoDiagnostic(diagnostic: PowerIoDiagnostic): string;
10
28
  export interface CaseFileSummary {
11
29
  name: string;
12
30
  base_mva: number;
@@ -27,12 +45,15 @@ export interface CaseFileSummary {
27
45
  * package echoes the kind it was saved with), `synthetic_pending` when the
28
46
  * case awaits placement. */
29
47
  coords_kind: "file" | "synthetic_pending" | "synthetic" | "manual";
48
+ /** Findings produced while PowerIO parsed the retained module. */
49
+ diagnostics: PowerIoDiagnostic[];
50
+ /** Tellegen display notes, such as omitted unlocated analysis rows. */
30
51
  warnings: string[];
31
52
  }
32
53
  export interface TopologyBus {
33
54
  id: number;
34
- /** powerio row uid, stamped at ingest (e.g. "buses:0"). */
35
- uid: string;
55
+ /** PowerIO row uid when the source carries one. */
56
+ uid: string | null;
36
57
  /** False for a display-only row synthesized by analysis lowering. */
37
58
  editable?: boolean;
38
59
  demand_mw: number;
@@ -40,8 +61,8 @@ export interface TopologyBus {
40
61
  }
41
62
  export interface TopologyBranch {
42
63
  id: number;
43
- /** powerio row uid, stamped at ingest (e.g. "branches:0"). */
44
- uid: string;
64
+ /** PowerIO row uid when the source carries one. */
65
+ uid: string | null;
45
66
  /** False for a display-only row synthesized by analysis lowering. */
46
67
  editable?: boolean;
47
68
  from: number;
@@ -56,9 +77,13 @@ export interface Topology {
56
77
  /** One parse per dropped file: summary stats, plus map geometry when the
57
78
  * file carries coordinates and topology for synthetic placement otherwise. */
58
79
  export interface IngestedCase extends CaseFileSummary {
59
- network_json: string;
80
+ /** Calculation declared by a typed problem instance. */
81
+ formulation?: Formulation;
82
+ /** Generation 2 PowerIO IR used for display edits and every solver Study. */
83
+ module_json: string;
60
84
  topology: Topology;
61
85
  view: {
86
+ coordinate_space?: "geographic" | "diagram";
62
87
  buses: NetworkBus[];
63
88
  branches: NetworkBranch[];
64
89
  } | null;
@@ -80,6 +105,8 @@ export interface DistGraphBus {
80
105
  id: string;
81
106
  terminals: string[];
82
107
  grounded: string[];
108
+ /** Declared or conservative conventional neutral terminal, when present. */
109
+ neutral_terminal?: string | null;
83
110
  xy?: [number, number];
84
111
  load_kw: number;
85
112
  gen_kw: number;
@@ -103,13 +130,12 @@ export interface DistGraph {
103
130
  buses: DistGraphBus[];
104
131
  edges: DistGraphEdge[];
105
132
  }
106
- /** One multiconductor parse for the viewing path: element counts, connected
107
- * load and generation (kW), parse warnings, coordinate provenance, and the
108
- * bus/terminal graph. No solve, no network JSON — distribution cases are viewed,
109
- * not solved. `coords_kind` tells the frontend how to place buses: `geographic`
110
- * drops `xy` straight onto the map, `planar` fits provided positions into a box
111
- * at a placement center, `synthetic` runs the force layout. */
133
+ /** Multiconductor case data, terminal graph, and retained PowerIO IR. */
112
134
  export interface IngestedDistCase {
135
+ module_json?: string;
136
+ geo_layer?: string;
137
+ mc_pf_enabled?: boolean;
138
+ mc_pf_unavailable_reason?: string | null;
113
139
  name: string | null;
114
140
  model: "multiconductor";
115
141
  n_bus: number;
@@ -124,7 +150,7 @@ export interface IngestedDistCase {
124
150
  n_shunt: number;
125
151
  /** Capacitor banks read as their own type, which only the BMOPF reader does.
126
152
  * A `.dss` or PMD capacitor counts in `n_shunt` instead. Optional because an
127
- * engine build before this field satisfies the same `^0.1.0` range. */
153
+ * older compatible engine payload can omit it. */
128
154
  n_capacitor?: number;
129
155
  load_kw: number;
130
156
  gen_kw: number;
@@ -133,32 +159,79 @@ export interface IngestedDistCase {
133
159
  placed_buses: number;
134
160
  coords_space: "geographic" | "projected" | "diagram" | "unknown" | "none";
135
161
  coords_kind: "geographic" | "planar" | "synthetic";
136
- warnings: string[];
162
+ diagnostics: PowerIoDiagnostic[];
137
163
  graph: DistGraph;
164
+ /** Explicit capability from the reader; absent means inspection only. */
165
+ mc_pf_supported?: boolean;
166
+ /** Reader explanation for an inspection-only distribution payload. */
167
+ mc_pf_reason?: string;
138
168
  }
139
- /** A study restored from a saved `.pio.json` package: the ingest payload plus the
140
- * restored formulation, solve options, and folded edit state. `deltas` are keyed by
141
- * bus id and `rates` by branch id — the numeric keys the sliders use. */
142
- export interface LoadedPackage extends IngestedCase {
143
- formulation: Formulation;
144
- options: {
145
- shed: boolean;
146
- warm_start: boolean;
147
- };
148
- deltas: DemandDeltas;
149
- rates: BranchRatingDeltas;
150
- }
151
- /** A study state written to a target format: the serialized case text, the writer's
152
- * fidelity warnings (empty when the conversion is faithful), and the format token and
153
- * file extension so a caller can name the download. */
169
+ /** A materialized case written to a target format: the serialized case text,
170
+ * this output operation's diagnostics, and the format token and file extension. */
154
171
  export interface ExportedCase {
155
172
  text: string;
156
- warnings: string[];
173
+ diagnostics: PowerIoDiagnostic[];
157
174
  format: string;
158
175
  extension: string;
159
176
  }
177
+ /** One weighted LMP objective term, addressed by its PowerIO bus id. */
178
+ export interface CapacityPlanBusWeightJson {
179
+ bus: number;
180
+ weight: number;
181
+ }
182
+ export type ImplicitObjectiveJson = {
183
+ kind: "weighted_lmp";
184
+ weights: CapacityPlanBusWeightJson[];
185
+ };
186
+ /** Capacity increases considered by the bounded planning search. */
187
+ export interface CapacityPlanSpecJson {
188
+ objective: ImplicitObjectiveJson;
189
+ candidates: string[];
190
+ max_increase_per_branch_mw: number;
191
+ budget_mw: number;
192
+ increment_mw: number;
193
+ max_changed_lines: number;
194
+ exact_solve_budget: number;
195
+ }
196
+ export interface CapacityPlanRatingChangeJson {
197
+ branch: string;
198
+ delta_mw: number;
199
+ }
200
+ /** One recorded search step: the gradient direction, the trial, the first
201
+ * order prediction, the exact outcome, and whether the step was kept. */
202
+ export interface CapacityPlanIterationJson {
203
+ gradient: Array<{
204
+ branch: string;
205
+ value: number;
206
+ }>;
207
+ delta_mw: CapacityPlanRatingChangeJson[];
208
+ predicted_phi_delta: number;
209
+ exact_phi_delta: number | null;
210
+ first_order_error: number | null;
211
+ first_order_error_rel: number | null;
212
+ accepted: boolean;
213
+ reason: string;
214
+ }
215
+ export interface CapacityPlanResultSummaryJson {
216
+ phi: number;
217
+ declared_objective: number;
218
+ /** One-based position in this planning operation's exact solve budget. */
219
+ exact_solve: number;
220
+ }
221
+ /** The outcome of one bounded planning search and its unapplied
222
+ * proposal. */
223
+ export interface CapacityPlanOutcomeJson {
224
+ baseline: CapacityPlanResultSummaryJson;
225
+ exact_verified_result: CapacityPlanResultSummaryJson;
226
+ baseline_phi: number;
227
+ final_phi: number;
228
+ proposal: CapacityPlanRatingChangeJson[];
229
+ spent_budget_mw: number;
230
+ exact_solves: number;
231
+ iterations: CapacityPlanIterationJson[];
232
+ }
160
233
  export declare function preloadEngine(): Promise<void>;
161
- export type JsonDropKind = "balanced-package" | "multiconductor-package" | "model-json" | "transmission" | "distribution" | "ambiguous" | "unknown";
234
+ export type JsonDropKind = "module" | "transmission" | "distribution" | "ambiguous" | "unknown";
162
235
  export interface JsonDropClassification {
163
236
  kind: JsonDropKind;
164
237
  format: string | null;
@@ -167,17 +240,11 @@ export interface JsonDropClassification {
167
240
  * ambiguous documents carry no payload; every recognized family carries the
168
241
  * same typed payload returned by its dedicated ingest API. */
169
242
  export type IngestedJsonDrop = {
170
- kind: "balanced-package";
171
- format: null;
172
- payload: LoadedPackage;
173
- } | {
174
- kind: "multiconductor-package";
175
- format: null;
176
- payload: IngestedDistCase;
177
- } | {
178
- kind: "model-json";
243
+ /** A generation 2 `pio-ir` document; the payload family follows the
244
+ * network family carried by the module value. */
245
+ kind: "module";
179
246
  format: null;
180
- payload: IngestedCase;
247
+ payload: IngestedCase | IngestedDistCase;
181
248
  } | {
182
249
  kind: "transmission";
183
250
  format: string;
@@ -191,8 +258,8 @@ export type IngestedJsonDrop = {
191
258
  format: null;
192
259
  payload: null;
193
260
  };
194
- /** Classify JSON bytes through powerio's Rust routing table. Package markers
195
- * also pass the strict package reader so the payload family is authoritative. */
261
+ /** Classify JSON bytes through powerio's Rust routing table. A stored module
262
+ * passes the strict module reader so the payload family is authoritative. */
196
263
  export declare function classifyJson(bytes: Uint8Array): Promise<JsonDropClassification>;
197
264
  /** Classify and ingest one dropped JSON document in the same engine request.
198
265
  * This avoids parsing a recognized package once to classify it and again to
@@ -204,12 +271,6 @@ export declare function formatOf(name: string): string | null;
204
271
  * decoded text: powerio refuses a text format whose bytes are not UTF-8, where
205
272
  * `File.text()` would have replaced each offending byte with U+FFFD. */
206
273
  export declare function ingestCase(bytes: Uint8Array, format: string): Promise<IngestedCase>;
207
- /** Parse powerio's own model JSON (the `model-json` export, or the payload a
208
- * package carries) for viewing. It is not a case format, so it does not go
209
- * through `ingestCase`. */
210
- export declare function ingestModelJson(networkJson: string): Promise<IngestedCase>;
211
- /** Byte entry point for a dropped model JSON document. */
212
- export declare function ingestModelJsonBytes(bytes: Uint8Array): Promise<IngestedCase>;
213
274
  /** Parse a multiconductor distribution case for viewing. `format` is a
214
275
  * distribution reader token (`dss`, `bmopf`, `pmd`) or `pio` for a `.pio.json`
215
276
  * package carrying a multiconductor payload. Rejects on malformed input or a
@@ -217,33 +278,18 @@ export declare function ingestModelJsonBytes(bytes: Uint8Array): Promise<Ingeste
217
278
  export declare function ingestDistCase(text: string, format: string): Promise<IngestedDistCase>;
218
279
  /** Byte entry point for a dropped distribution case or package. */
219
280
  export declare function ingestDistCaseBytes(bytes: Uint8Array, format: string): Promise<IngestedDistCase>;
220
- /** Substations from a PowerWorld .pwd display file. `x`/`y` are diagram
221
- * coordinates as stored; `lon`/`lat` are the engine's approximate projection
222
- * (powerio's inverse of the auto layout Mercator — hand edited diagrams
223
- * drift from it). */
224
- export interface DisplayPreview {
225
- substations: {
226
- number: number;
227
- name: string;
228
- x: number;
229
- y: number;
230
- lon: number;
231
- lat: number;
232
- }[];
233
- canvas_width: number;
234
- canvas_height: number;
235
- }
281
+ /** A PowerWorld drawing decoded in its declared diagram coordinate system. */
282
+ export type DisplayPreview = ParsedGeoLayer;
236
283
  /** True for binary display files (PowerWorld .pwd), read via parseDisplay.
237
284
  * Kept separate from formatOf: a .pwd is display data, not a case format. */
238
285
  export declare function isDisplayFile(name: string): boolean;
239
286
  export declare function parseDisplay(bytes: Uint8Array): Promise<DisplayPreview>;
240
287
  /** A parsed geographic sidecar: the layer as its canonical `.geo.json`
241
288
  * document (hand it to {@link applyGeo} or `BrowserStudy.applyGeoLayer`),
242
- * the tolerant reader's notes on records it could not use, and the feature
243
- * counts. */
289
+ * the reader's structured diagnostics, and the feature counts. */
244
290
  export interface ParsedGeoLayer {
245
291
  layer: string;
246
- warnings: string[];
292
+ diagnostics: PowerIoDiagnostic[];
247
293
  n_points: number;
248
294
  n_routes: number;
249
295
  }
@@ -254,9 +300,12 @@ export interface GeoApplyReport {
254
300
  unmatched_features: number;
255
301
  notes: string[];
256
302
  }
257
- /** The refreshed ingest payload after a geo apply: `network_json`, the view,
303
+ /** The refreshed ingest payload after a geo apply: `module_json`, the view,
258
304
  * and the summary all reflect the applied coordinates, and `report` carries
259
305
  * the matched/unmatched counts for the warnings panel. */
306
+ export interface AppliedMcGeoCase extends IngestedDistCase {
307
+ report: GeoApplyReport;
308
+ }
260
309
  export interface AppliedGeoCase extends IngestedCase {
261
310
  report: GeoApplyReport;
262
311
  }
@@ -274,36 +323,159 @@ export declare function parseGeo(bytes: Uint8Array, hint: string): Promise<Parse
274
323
  /** Apply a parsed layer onto a case network (matching by uid, external id,
275
324
  * name, and the unordered branch endpoint pair). Rejects when nothing
276
325
  * matched. */
277
- export declare function applyGeo(networkJson: string, layer: string): Promise<AppliedGeoCase>;
326
+ export declare function applyGeo(moduleJson: string, layer: string): Promise<AppliedGeoCase>;
327
+ /** Apply geographic or drawing coordinates to a multiconductor case. */
328
+ export declare function applyMcGeo(moduleJson: string, layer: string): Promise<AppliedMcGeoCase>;
278
329
  /** Stamp a computed layout (bus id => [lon, lat]) onto a case network with
279
330
  * its provenance, so saves and exports carry it. */
280
- export declare function applyLayout(networkJson: string, coords: Record<number, [number, number]>, kind: "synthetic" | "manual"): Promise<StampedLayoutCase>;
331
+ export declare function applyLayout(moduleJson: string, coords: Record<number, [number, number]>, kind: "synthetic" | "manual"): Promise<StampedLayoutCase>;
281
332
  /** A case's coordinates as a canonical `.geo.json` document. Rejects when the
282
333
  * case carries none. */
283
- export declare function extractGeo(networkJson: string): Promise<string>;
334
+ export declare function extractGeo(moduleJson: string): Promise<string>;
284
335
  /** Fill case coordinates from a PowerWorld `.pwd` sibling: substation symbols
285
336
  * project to approximate longitude/latitude and join onto buses through the
286
337
  * `SubNum` extras key. Rejects when no bus joined. */
287
- export declare function applyDisplayGeo(networkJson: string, bytes: Uint8Array): Promise<AppliedGeoCase>;
338
+ export declare function applyDisplayGeo(moduleJson: string, bytes: Uint8Array): Promise<AppliedGeoCase>;
288
339
  export declare function capabilities(): Promise<ProblemCaps[]>;
289
- export declare function solveJson(networkJson: string, request?: SolveRequest): Promise<SolveResponse>;
340
+ export declare function solveModule(moduleJson: string, request?: SolveRequest): Promise<SolveResponse>;
341
+ /** Portable terminal-aware result returned by the multiconductor fixed-point
342
+ * BMOPF entry point. Complex quantities use `{re, im}` so the JSON remains
343
+ * lossless across the wasm boundary. */
344
+ export interface McPfOptions {
345
+ tolerance?: number;
346
+ max_iterations?: number;
347
+ damping?: number;
348
+ zero_voltage_tolerance?: number;
349
+ /** Absolute physical KCL floor in amperes; default 1e-6. */
350
+ absolute_kcl_tolerance?: number;
351
+ /** Relative KCL tolerance against prepared incident current. */
352
+ relative_kcl_tolerance?: number;
353
+ /** Apply the OpenDSS-style bounded-voltage load envelope; default true. */
354
+ voltage_envelope?: boolean;
355
+ /** Nominal-impedance breakpoint in per unit; default 0.5. */
356
+ v_low_pu?: number;
357
+ /** Lower edge of the normal load-model range; default 0.85. */
358
+ v_min_pu?: number;
359
+ /** Upper edge of the normal load-model range; default 1.15. */
360
+ v_max_pu?: number;
361
+ }
362
+ export interface McComplex {
363
+ re: number;
364
+ im: number;
365
+ }
366
+ export interface McElementPort {
367
+ element: string;
368
+ kind: string;
369
+ branch: number;
370
+ bus: string;
371
+ terminal: string;
372
+ current_into_element: McComplex;
373
+ power_into_element: McComplex;
374
+ }
375
+ export interface McSourceReaction {
376
+ source: string;
377
+ terminal: string;
378
+ current_into_network: McComplex;
379
+ power_into_network: McComplex;
380
+ }
381
+ export interface McPfResult {
382
+ converged: boolean;
383
+ voltage_valid: boolean;
384
+ min_voltage_pu: number | null;
385
+ max_voltage_pu: number | null;
386
+ voltage_violations: Array<{
387
+ load: string;
388
+ branch: number;
389
+ bus: string;
390
+ voltage: number;
391
+ nominal_voltage: number;
392
+ voltage_pu: number;
393
+ bound: "minimum" | "maximum";
394
+ }>;
395
+ iterations: number;
396
+ factorization_count: number;
397
+ matrix_dimension: number;
398
+ matrix_nonzeros: number;
399
+ voltage_change: number;
400
+ physical_kcl_residual: number;
401
+ scaled_kcl_residual: number;
402
+ terminals: Array<{
403
+ bus: string;
404
+ terminal: string;
405
+ voltage: McComplex;
406
+ current_into_network: McComplex;
407
+ power_into_network: McComplex;
408
+ }>;
409
+ element_ports: McElementPort[];
410
+ source_reactions: McSourceReaction[];
411
+ }
412
+ /** Self-contained saved Study result for a supported distribution AC PF.
413
+ * The input and solution modules make this replayable; `result` is the rich
414
+ * terminal/element view rendered by the Study panel. */
415
+ export interface McStudySnapshot {
416
+ schema: "tellegen-mc-pf-study";
417
+ version: 1;
418
+ id: string;
419
+ title: string;
420
+ formulation: "mc_ac_pf";
421
+ input_module: string;
422
+ solution_module: string;
423
+ options: McPfOptions;
424
+ result: McPfResult;
425
+ }
426
+ export interface McLoadPowerEdit {
427
+ load: string;
428
+ branch: number;
429
+ p_w: number;
430
+ q_var: number;
431
+ }
432
+ export interface McLoadBranchState extends McLoadPowerEdit {
433
+ bus: string;
434
+ base_p_w: number;
435
+ base_q_var: number;
436
+ }
437
+ /** A live fixed-point current-injection solver retained in the shared engine
438
+ * worker. Load edits reuse its sparse LU and previous converged phasors. */
439
+ export declare class BrowserMcPfSession {
440
+ private readonly host;
441
+ private readonly handle;
442
+ constructor(host: EngineHost, handle: number);
443
+ result(): Promise<McPfResult>;
444
+ loadBranches(): Promise<McLoadBranchState[]>;
445
+ replaceLoadPowers(edits: McLoadPowerEdit[]): Promise<McPfResult>;
446
+ inputModule(): Promise<string>;
447
+ snapshot(studyId: string, studyTitle: string): Promise<McStudySnapshot>;
448
+ free(): void;
449
+ }
450
+ /** Parse, prepare, factor, and solve a persistent multiconductor PF session. */
451
+ export declare function createMcPfSession(moduleJson: string, options?: McPfOptions, signal?: AbortSignal): Promise<BrowserMcPfSession>;
452
+ /** Parse and solve a raw BMOPF multiconductor case in the wasm module. */
453
+ export declare function solveMcBmopf(text: string, options?: McPfOptions): Promise<McPfResult>;
454
+ /** Solve a stored PowerIO multiconductor module through the same PF engine. */
455
+ export declare function solveMcModule(moduleJson: string, options?: McPfOptions, signal?: AbortSignal): Promise<McPfResult>;
456
+ /** Solve a supported multiconductor Study input and return a replayable
457
+ * snapshot containing the typed input, PowerIO solution, and rich result. */
458
+ export declare function solveMcStudy(moduleJson: string, studyId: string, studyTitle: string, options?: McPfOptions, signal?: AbortSignal): Promise<McStudySnapshot>;
459
+ /** Validate and canonicalize a saved multiconductor Study snapshot without
460
+ * running the solver again. */
461
+ export declare function replayMcStudy(snapshotJson: string): Promise<McStudySnapshot>;
462
+ /** Update both saved modules with matching positions while retaining the solved values. */
463
+ export declare function applyMcStudyGeo(snapshot: McStudySnapshot, layer: string): Promise<McStudySnapshot>;
290
464
  export { errorText } from "./errors.js";
291
465
  /** True when the engine wasm module has failed to load in a way it can never
292
466
  * recover from in this browser. Nothing solves client side when this is true;
293
467
  * the caller decides whether a server fallback exists. */
294
468
  export declare function isPermanentEngineFailure(message: string): boolean;
295
- /** The sensitivity selection target: a bus (the ∂LMP/∂d column at that bus) or a
296
- * branch (the ∂LMP/∂rating column at that branch). Ids are the external element
469
+ /** The sensitivity selection target: a bus (the nodal-value/demand column at that bus) or a
470
+ * branch (the nodal-value/rating column at that branch). Ids are the external element
297
471
  * ids; `BrowserStudy` translates them to the engine's dense indices. */
298
472
  export type SensTarget = {
299
473
  bus: number;
300
474
  } | {
301
475
  branch: number;
302
476
  };
303
- /** The formulations the full wasm build solves entirely in the browser. Each returns LMP,
304
- * so the price map, legend, and the ∂LMP/∂d overlay apply unchanged to all of them. Tags
305
- * are the engine's serde-lowercase `Problem` variants accepted by `new Study(json, tag)`.
306
- * `dcopf` is the default (zero regression from the prior fixed behavior). */
477
+ /** Calculation names accepted by the browser engine. Power flow returns voltages
478
+ * and flows; OPF calculations also return an objective and LMPs. */
307
479
  export type Formulation = BrowserFormulation;
308
480
  /** UI-facing formulation menu: tag, a short label, and a one-line description. The order
309
481
  * is the menu order; `dcopf` is first and is the default. */
@@ -313,95 +485,113 @@ export declare const FORMULATIONS: ReadonlyArray<{
313
485
  hint: string;
314
486
  disabled?: boolean;
315
487
  }>;
316
- /** The default formulation: DC OPF, preserving the prior fixed behavior byte-for-byte. */
488
+ /** DC OPF is the default calculation. */
317
489
  export declare const DEFAULT_FORMULATION: Formulation;
318
- /** Build-once browser transport for the reactive demand drag. The network is
319
- * parsed and the model built when the Study is created; `commit` solves exactly
490
+ /** Browser transport for the reactive demand drag. The retained PowerIO module
491
+ * is parsed and the model built when the Study is created; `commit` solves exactly
320
492
  * at the UI's absolute demand delta state and `preview` returns a first-order
321
493
  * linearization toward an absolute demand delta state, neither re-parsing the
322
494
  * network. The wasm Study lives behind the engine host (a dedicated worker
323
495
  * when the browser allows one), so every method is async. */
324
496
  export declare class BrowserStudy {
325
497
  #private;
326
- constructor(host: EngineHost, handle: number);
498
+ constructor(host: EngineHost, handle: number, formulation?: Formulation, planningHost?: () => EngineHost);
327
499
  /** Exact solve at demand = base + `deltas` and ratings = base + `rates`, replacing
328
- * the committed point. When `target` names a bus or branch, its ∂LMP/∂parameter
500
+ * the committed point. When `target` names a bus or branch, its nodal-value/parameter
329
501
  * column is computed in the *same* solve and returned (no second round-trip);
330
502
  * otherwise `sensitivity` is null. `caseId` labels the returned column. Returns the
331
503
  * UI Solution, the solver iterates, and the column. */
332
- commit(caseId: string, deltas: DemandDeltas, rates: BranchRatingDeltas, target: SensTarget | null): Promise<{
504
+ commit(caseId: string, deltas: DemandDeltas, rates: BranchRatingDeltas, target: SensTarget | null, signal?: AbortSignal): Promise<{
333
505
  solution: Solution;
334
506
  iterations: SolveIteration[];
335
507
  sensitivity: SensitivityColumn | null;
336
508
  }>;
337
- /** The ∂LMP/∂parameter column at `target` for this study's formulation, computed by
509
+ /** The nodal-value/parameter column at `target` for this study's formulation, computed by
338
510
  * an exact re-solve at the edited point (the same one-call path `commit` uses, but
339
511
  * returning only the column). Used when a bus or branch is selected so the overlay
340
512
  * matches the active formulation rather than always the DC sensitivity. `caseId`
341
513
  * labels the column; returns null when no recognized column comes back. */
342
514
  sensitivity(caseId: string, deltas: DemandDeltas, rates: BranchRatingDeltas, target: SensTarget): Promise<SensitivityColumn | null>;
343
- /** First-order LMP preview for replacing the committed point with
515
+ /** First order nodal value preview for replacing the committed point with
344
516
  * demand = base + `deltas` and ratings = base + `rates`, with no re-solve:
345
- * predicted per-bus ΔLMP and the predicted Δobjective. */
517
+ * predicted per-bus nodal value changes and the predicted objective change. */
346
518
  preview(deltas: DemandDeltas, rates?: BranchRatingDeltas): Promise<{
347
- lmp: {
519
+ prices: {
348
520
  bus: number;
349
- usd_per_mwh: number;
521
+ value: number;
350
522
  }[];
351
523
  objectiveDelta: number | null;
524
+ units: string | null;
352
525
  }>;
353
526
  /** The Study's current exact solution. Called immediately after Study creation
354
527
  * to cache the base point for formulation comparisons. */
528
+ currentView(): Promise<import("./generated/study-contracts.js").SolveResponse>;
355
529
  currentSolution(): Promise<Solution>;
356
- /** Serialize this study as a `.pio.json` package: the base network payload, the
357
- * edit log as the study block, and the formulation and solve options under
358
- * `study.app["tellegen"]`. The returned text is ready to download or hand to
359
- * `exportStudy`. */
360
- savePackage(): Promise<string>;
530
+ /** Materialize the current case as generation 2 PowerIO IR. */
531
+ saveModule(): Promise<string>;
532
+ /** Preserve the materialized instance's inner objective and constraints in PowerIO IR. */
533
+ saveInstanceModule(): Promise<string>;
534
+ /** Serialize the current exact DC OPF result as a PowerIO solution module.
535
+ * Its embedded problem instance contains the materialized case that was
536
+ * solved. */
537
+ saveSolutionModule(): Promise<string>;
538
+ /** Write the current materialized case to one PowerIO target format. */
539
+ export(format: string): Promise<ExportedCase>;
540
+ /** Run a bounded differentiable planning search over the committed
541
+ * operating point. Read only: the committed case, edits, and revision are
542
+ * untouched; the returned outcome carries the unapplied proposal and the
543
+ * search trace (gradient, per step prediction, exact result, first
544
+ * order error, accept or reject reason). Rejects on a non-DC formulation
545
+ * or an unknown element key. Worker hosts stop the solve on cancellation;
546
+ * the synchronous fallback finishes the wasm call but rejects its result. */
547
+ plan(spec: CapacityPlanSpecJson, signal?: AbortSignal): Promise<CapacityPlanOutcomeJson>;
361
548
  /** Apply a parsed geographic layer (the canonical `.geo.json` from
362
549
  * `parseGeo` or `applyLayout`) onto this study's base network, so the next
363
- * `savePackage` or export carries the coordinates on screen. Locations are
550
+ * `saveModule` or export carries the coordinates on screen. Locations are
364
551
  * metadata the model never reads; nothing re-solves. */
365
552
  applyGeoLayer(layer: string): Promise<GeoApplyReport>;
366
553
  /** Release the wasm Study; call when discarding it (e.g. the case's
367
- * networkJson changed, or the case was removed). Fire and forget: the
554
+ * module input changed, or the case was removed). Fire and forget: the
368
555
  * handle is invalid from this call on. */
369
556
  free(): void;
370
557
  }
371
- export declare function createStudy(networkJson: string, formulation?: Formulation): Promise<BrowserStudy>;
372
- /** Restore a study saved by `BrowserStudy.savePackage`: the case, edit sliders,
373
- * formulation, and solve options in one step. Rejects on a malformed package or one
374
- * that is not a tellegen study (the engine fails the load closed). */
375
- export declare function loadPackage(text: string): Promise<LoadedPackage>;
376
- /** Restore a dropped package without decoding it in JavaScript. */
377
- export declare function loadPackageBytes(bytes: Uint8Array): Promise<LoadedPackage>;
378
- /** Export a saved study package at commit `commit` to a powerio `format` (`matpower`,
379
- * `psse`, `model-json`, ...). Returns the serialized case text, the writer's fidelity
380
- * warnings, and the format token and file extension. */
381
- export declare function exportStudy(packageJson: string, commit: number, format: string): Promise<ExportedCase>;
558
+ export declare function createStudy(moduleJson: string, formulation?: Formulation, options?: {
559
+ isolated?: boolean;
560
+ signal?: AbortSignal;
561
+ }): Promise<BrowserStudy>;
382
562
  export interface EngineTransport {
383
563
  preloadEngine(): Promise<void>;
384
564
  classifyJson(bytes: Uint8Array): Promise<JsonDropClassification>;
385
565
  ingestJsonDrop(bytes: Uint8Array): Promise<IngestedJsonDrop>;
386
566
  ingestCase(bytes: Uint8Array, format: string): Promise<IngestedCase>;
387
- ingestModelJson(networkJson: string): Promise<IngestedCase>;
388
- ingestModelJsonBytes(bytes: Uint8Array): Promise<IngestedCase>;
389
567
  ingestDistCase(text: string, format: string): Promise<IngestedDistCase>;
390
568
  ingestDistCaseBytes(bytes: Uint8Array, format: string): Promise<IngestedDistCase>;
391
569
  parseDisplay(bytes: Uint8Array): Promise<DisplayPreview>;
392
570
  parseGeo(bytes: Uint8Array, hint: string): Promise<ParsedGeoLayer>;
393
- applyGeo(networkJson: string, layer: string): Promise<AppliedGeoCase>;
394
- applyLayout(networkJson: string, coords: Record<number, [number, number]>, kind: "synthetic" | "manual"): Promise<StampedLayoutCase>;
395
- extractGeo(networkJson: string): Promise<string>;
396
- applyDisplayGeo(networkJson: string, bytes: Uint8Array): Promise<AppliedGeoCase>;
571
+ applyGeo(moduleJson: string, layer: string): Promise<AppliedGeoCase>;
572
+ applyMcGeo?(moduleJson: string, layer: string): Promise<AppliedMcGeoCase>;
573
+ applyLayout(moduleJson: string, coords: Record<number, [number, number]>, kind: "synthetic" | "manual"): Promise<StampedLayoutCase>;
574
+ extractGeo(moduleJson: string): Promise<string>;
575
+ applyDisplayGeo(moduleJson: string, bytes: Uint8Array): Promise<AppliedGeoCase>;
397
576
  capabilities(): Promise<ProblemCaps[]>;
398
- solveJson(networkJson: string, request?: SolveRequest): Promise<SolveResponse>;
399
- createStudy(networkJson: string, formulation?: Formulation): Promise<BrowserStudy>;
400
- loadPackage(text: string): Promise<LoadedPackage>;
401
- loadPackageBytes(bytes: Uint8Array): Promise<LoadedPackage>;
402
- exportStudy(packageJson: string, commit: number, format: string): Promise<ExportedCase>;
577
+ solveModule(moduleJson: string, request?: SolveRequest): Promise<SolveResponse>;
578
+ solveMcBmopf(text: string, options?: McPfOptions): Promise<McPfResult>;
579
+ solveMcModule(moduleJson: string, options?: McPfOptions, signal?: AbortSignal): Promise<McPfResult>;
580
+ solveMcStudy(moduleJson: string, studyId: string, studyTitle: string, options?: McPfOptions, signal?: AbortSignal): Promise<McStudySnapshot>;
581
+ createMcPfSession(moduleJson: string, options?: McPfOptions, signal?: AbortSignal): Promise<BrowserMcPfSession>;
582
+ replayMcStudy(snapshotJson: string): Promise<McStudySnapshot>;
583
+ applyMcStudyGeo?(snapshot: McStudySnapshot, layer: string): Promise<McStudySnapshot>;
584
+ createStudy(moduleJson: string, formulation?: Formulation, options?: {
585
+ isolated?: boolean;
586
+ signal?: AbortSignal;
587
+ }): Promise<BrowserStudy>;
403
588
  }
404
589
  export declare const browserWasmTransport: EngineTransport;
405
590
  export declare function createBrowserWasmTransport(): EngineTransport;
406
591
  export { BrowserStudy as Study };
592
+ export { IndexedDbStudyStore, StudyDocumentController, studyBackend, } from "./study-document.js";
593
+ export type { StudyBackend, StudyStore } from "./study-document.js";
594
+ export type { CreateStudy, StudyBundle, StudyDocument, StudyRequest, StudyOperation, StudyOperationResult, GoalRevision, DecisionSpace, StudyObjective, StateNode, Comparison, } from "./generated/study-contracts.js";
595
+ export type { ModelDetails, SolveResponse as StudyView, SearchOptions, StudySummary, } from "./generated/study-contracts.js";
596
+ export { studySchema } from "./generated/study-schema.js";
407
597
  //# sourceMappingURL=index.d.ts.map