@swmmrs/swmmrs 0.1.0 → 0.2.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.
@@ -1,233 +1,233 @@
1
- import type { Simulation as NativeSimulation, OutputReader as NativeOutputReader } from "../../dist/swmmrs.js";
2
- import type { ConfigurationDiagnostic, ErrorDetails } from "./exceptions.js";
3
- import type { Request, Response, Result, Method } from "./protocol.js";
4
- import type { RunResults } from "./types.js";
5
- import type { CheckpointBundle } from "./scenarios.js";
6
- import { loadWasm } from "./runtime.js";
7
-
8
- // This module runs in a dedicated worker; the public build also uses DOM types.
9
- const host = globalThis as unknown as {
10
- onmessage: ((event: MessageEvent<Request>) => void) | null;
11
- postMessage(message: Response, transfer?: Transferable[]): void;
12
- };
13
- const decoder = new TextDecoder();
14
- let simulation: NativeSimulation | undefined;
15
- let outputReader: NativeOutputReader | undefined;
16
- let terminateThreadPool: (() => void) | undefined;
17
- let queue = Promise.resolve();
18
-
19
- function shutdown(): void {
20
- const errors: unknown[] = [];
21
- try { simulation?.close(); } catch (error) { errors.push(error); }
22
- try { simulation?.free(); } catch (error) { errors.push(error); }
23
- simulation = undefined;
24
- try { outputReader?.free(); } catch (error) { errors.push(error); }
25
- outputReader = undefined;
26
- try { terminateThreadPool?.(); } catch (error) { errors.push(error); }
27
- if (errors.length) {
28
- const [primary, ...secondary] = errors;
29
- const error = primary instanceof Error ? primary : new Error(String(primary));
30
- if (secondary.length) Object.assign(error, { cleanupError: secondary.map(String).join("; ") });
31
- throw error;
32
- }
33
- }
34
-
35
- function results(owner: NativeSimulation): RunResults {
36
- return {
37
- report: decoder.decode(owner.readFile("model.rpt")),
38
- output: owner.status().saveResults ? owner.readFile("model.out") : new Uint8Array(),
39
- };
40
- }
41
-
42
- async function dispatch(request: Request): Promise<void> {
43
- const { id, method } = request;
44
- try {
45
- let result: Result<Method> = undefined;
46
- if (request.method === "open" || request.method === "resumeCheckpoint" || request.method === "openOutput") {
47
- if (simulation || outputReader) throw new Error("An owner is already open");
48
- const threads = request.method === "open" ? request.args[2]
49
- : request.method === "resumeCheckpoint" ? request.args[1] : 1;
50
- const bindings = threads === 1
51
- ? await import("../../dist/serial/swmmrs.js")
52
- : await import("../../dist/swmmrs.js");
53
- const moduleUrl = threads === 1
54
- ? new URL("../../dist/serial/swmmrs.js", import.meta.url).href
55
- : new URL("../../dist/swmmrs.js", import.meta.url).href;
56
- terminateThreadPool = bindings.terminateThreadPool;
57
- await loadWasm(bindings, moduleUrl);
58
- await bindings.initThreadPool(threads, moduleUrl);
59
- if (request.method === "openOutput") {
60
- outputReader = new bindings.OutputReader(request.args[0]);
61
- result = outputReader.outputMetadata();
62
- } else {
63
- simulation = request.method === "open"
64
- ? new bindings.Simulation(request.args[0], request.args[1])
65
- : bindings.Simulation.resumeCheckpoint(request.args[0]);
66
- result = simulation.info();
67
- }
68
- } else if (request.method === "close" || request.method === "closeOutput") {
69
- shutdown();
70
- } else if (request.method === "outputMetadata" || request.method === "outputReadBulkSeries" ||
71
- request.method === "outputReadBulkSeriesByPeriod" || request.method === "outputReadStoredDates" ||
72
- request.method === "outputSubcatchmentSeries" || request.method === "outputNodeSeries" ||
73
- request.method === "outputLinkSeries" || request.method === "outputSystemSeries") {
74
- if (!outputReader) throw new Error("Output reader is closed");
75
- switch (request.method) {
76
- case "outputMetadata": result = outputReader.outputMetadata(); break;
77
- case "outputReadBulkSeries": result = outputReader.outputReadBulkSeries(...request.args); break;
78
- case "outputReadBulkSeriesByPeriod": result = outputReader.outputReadBulkSeriesByPeriod(...request.args); break;
79
- case "outputReadStoredDates": result = outputReader.outputReadStoredDates(...request.args); break;
80
- case "outputSubcatchmentSeries": result = outputReader.outputSubcatchmentSeries(...request.args); break;
81
- case "outputNodeSeries": result = outputReader.outputNodeSeries(...request.args); break;
82
- case "outputLinkSeries": result = outputReader.outputLinkSeries(...request.args); break;
83
- case "outputSystemSeries": result = outputReader.outputSystemSeries(...request.args); break;
84
- }
85
- } else {
86
- if (!simulation) throw new Error("Simulation is closed");
87
- switch (request.method) {
88
- case "state": result = simulation.state as Result<"state">; break;
89
- case "info": result = simulation.info(); break;
90
- case "status": result = simulation.status(); break;
91
- case "start": simulation.start(...request.args); break;
92
- case "step": result = simulation.step() ?? null; break;
93
- case "stride": result = simulation.stride(...request.args) ?? null; break;
94
- case "node": result = simulation.node(...request.args); break;
95
- case "link": result = simulation.link(...request.args); break;
96
- case "nodes": result = simulation.nodes(request.args[0] === undefined ? undefined : [...request.args[0]]); break;
97
- case "links": result = simulation.links(request.args[0] === undefined ? undefined : [...request.args[0]]); break;
98
- case "subcatchment": result = simulation.subcatchment(...request.args); break;
99
- case "nodeExternalInflow": result = simulation.nodeExternalInflow(...request.args); break;
100
- case "outfallFixedStage": result = simulation.outfallFixedStage(...request.args) ?? null; break;
101
- case "nodeQuality": result = simulation.nodeQuality(...request.args); break;
102
- case "nodeQualitySnapshot": result = simulation.nodeQualitySnapshot(request.args[0] === undefined ? undefined : [...request.args[0]]); break;
103
- case "overrideNodePollutantConcentrations": simulation.overrideNodePollutantConcentrations(...request.args); break;
104
- case "nodeExternalPollutantMassFlux": result = simulation.nodeExternalPollutantMassFlux(...request.args); break;
105
- case "nodeExternalPollutantMassFluxValue": result = simulation.nodeExternalPollutantMassFluxValue(...request.args); break;
106
- case "updateNodeExternalPollutantMassFlux": simulation.updateNodeExternalPollutantMassFlux(...request.args); break;
107
- case "nodeStatistics": result = simulation.nodeStatistics(...request.args); break;
108
- case "storageStatistics": result = simulation.storageStatistics(...request.args); break;
109
- case "outfallStatistics": result = simulation.outfallStatistics(...request.args); break;
110
- case "nodeStatisticsSnapshot": result = simulation.nodeStatisticsSnapshot(request.args[0] === undefined ? undefined : [...request.args[0]]); break;
111
- case "nodeTotalInflowVolume": result = simulation.nodeTotalInflowVolume(...request.args); break;
112
- case "linkQuality": result = simulation.linkQuality(...request.args); break;
113
- case "linkQualitySnapshot": result = simulation.linkQualitySnapshot(request.args[0] === undefined ? undefined : [...request.args[0]]); break;
114
- case "overrideLinkPollutantConcentrations": simulation.overrideLinkPollutantConcentrations(...request.args); break;
115
- case "linkExternalPollutantMassFlux": result = simulation.linkExternalPollutantMassFlux(...request.args); break;
116
- case "linkExternalPollutantMassFluxValue": result = simulation.linkExternalPollutantMassFluxValue(...request.args); break;
117
- case "updateLinkExternalPollutantMassFlux": simulation.updateLinkExternalPollutantMassFlux(...request.args); break;
118
- case "setLinkFlowLimit": simulation.setLinkFlowLimit(...request.args); break;
119
- case "linkStatistics": result = simulation.linkStatistics(...request.args); break;
120
- case "pumpStatistics": result = simulation.pumpStatistics(...request.args); break;
121
- case "linkStatisticsSnapshot": result = simulation.linkStatisticsSnapshot(request.args[0] === undefined ? undefined : [...request.args[0]]); break;
122
- case "linkInlet": result = simulation.linkInlet(...request.args); break;
123
- case "inletResults": result = simulation.inletResults(...request.args); break;
124
- case "updateInlet": simulation.updateInlet(...request.args); break;
125
- case "subcatchments": result = simulation.subcatchments(request.args[0] === undefined ? undefined : [...request.args[0]]); break;
126
- case "rainGage": result = simulation.rainGage(...request.args); break;
127
- case "nodeConfiguration": result = simulation.nodeConfiguration(...request.args); break;
128
- case "linkConfiguration": result = simulation.linkConfiguration(...request.args); break;
129
- case "useRainGageExternalPrecipitation": simulation.useRainGageExternalPrecipitation(...request.args); break;
130
- case "rainGageExternalPrecipitationRate": result = simulation.rainGageExternalPrecipitationRate(...request.args) ?? null; break;
131
- case "rainGageRainfallOverride": result = simulation.rainGageRainfallOverride(...request.args) ?? null; break;
132
- case "subcatchmentPrecipitationScaleFactors": result = simulation.subcatchmentPrecipitationScaleFactors(...request.args); break;
133
- case "setSubcatchmentPrecipitationScaleFactors": simulation.setSubcatchmentPrecipitationScaleFactors(...request.args); break;
134
- case "subcatchmentExternalForcing": result = simulation.subcatchmentExternalForcing(...request.args); break;
135
- case "setSubcatchmentExternalRainfall": simulation.setSubcatchmentExternalRainfall(...request.args); break;
136
- case "setSubcatchmentExternalSnowfall": simulation.setSubcatchmentExternalSnowfall(...request.args); break;
137
- case "subcatchmentQuality": result = simulation.subcatchmentQuality(...request.args); break;
138
- case "subcatchmentQualitySnapshot": result = simulation.subcatchmentQualitySnapshot(request.args[0] === undefined ? undefined : [...request.args[0]]); break;
139
- case "subcatchmentNamedSettings": result = simulation.subcatchmentNamedSettings(...request.args); break;
140
- case "subcatchmentNamedSetting": result = simulation.subcatchmentNamedSetting(...request.args); break;
141
- case "updateSubcatchmentNamedSettings": simulation.updateSubcatchmentNamedSettings(...request.args); break;
142
- case "subcatchmentExternalPollutantBuildupIncrement": result = simulation.subcatchmentExternalPollutantBuildupIncrement(...request.args); break;
143
- case "subcatchmentExternalPollutantBuildupIncrementValue": result = simulation.subcatchmentExternalPollutantBuildupIncrementValue(...request.args); break;
144
- case "updateSubcatchmentExternalPollutantBuildupIncrement": simulation.updateSubcatchmentExternalPollutantBuildupIncrement(...request.args); break;
145
- case "subcatchmentStatistics": result = simulation.subcatchmentStatistics(...request.args); break;
146
- case "subcatchmentStatisticsSnapshot": result = simulation.subcatchmentStatisticsSnapshot(request.args[0] === undefined ? undefined : [...request.args[0]]); break;
147
- case "subcatchmentConfiguration": result = simulation.subcatchmentConfiguration(...request.args); break;
148
- case "configureNode": simulation.configureNode(...request.args); break;
149
- case "configureLink": simulation.configureLink(...request.args); break;
150
- case "configureSubcatchment": simulation.configureSubcatchment(...request.args); break;
151
- case "setNodeExternalInflow": simulation.setNodeExternalInflow(...request.args); break;
152
- case "setLinkTargetSetting": simulation.setLinkTargetSetting(...request.args); break;
153
- case "setOutfallStage": simulation.setOutfallStage(...request.args); break;
154
- case "setRainGagePrecipitation": simulation.setRainGagePrecipitation(...request.args); break;
155
- case "setRainGageRainfallOverride": simulation.setRainGageRainfallOverride(...request.args); break;
156
- case "options": result = simulation.options(); break;
157
- case "configureOptions": simulation.configureOptions(...request.args); break;
158
- case "updateSchedule": simulation.updateSchedule(...request.args); break;
159
- case "maximumRoutingStepSeconds": result = simulation.maximumRoutingStepSeconds(); break;
160
- case "ammModelConfiguration": result = simulation.ammModelConfiguration(...request.args); break;
161
- case "configureAmmModel": simulation.configureAmmModel(...request.args); break;
162
- case "ammAssignments": result = simulation.ammAssignments(); break;
163
- case "replaceAmmAssignments": simulation.replaceAmmAssignments(...request.args); break;
164
- case "unitHydrographConfiguration": result = simulation.unitHydrographConfiguration(...request.args); break;
165
- case "configureUnitHydrograph": simulation.configureUnitHydrograph(...request.args); break;
166
- case "rdiiAssignments": result = simulation.rdiiAssignments(); break;
167
- case "replaceRdiiAssignments": simulation.replaceRdiiAssignments(...request.args); break;
168
- case "aquiferConfiguration": result = simulation.aquiferConfiguration(...request.args); break;
169
- case "configureAquifer": simulation.configureAquifer(...request.args); break;
170
- case "snowmeltConfiguration": result = simulation.snowmeltConfiguration(...request.args); break;
171
- case "configureSnowmelt": simulation.configureSnowmelt(...request.args); break;
172
- case "snowmeltSurfaceConfiguration": result = simulation.snowmeltSurfaceConfiguration(...request.args); break;
173
- case "configureSnowmeltSurface": simulation.configureSnowmeltSurface(...request.args); break;
174
- case "lidControlConfiguration": result = simulation.lidControlConfiguration(...request.args); break;
175
- case "configureLidControl": simulation.configureLidControl(...request.args); break;
176
- case "lidUnitCount": result = simulation.lidUnitCount(...request.args); break;
177
- case "lidUnitConfiguration": result = simulation.lidUnitConfiguration(...request.args); break;
178
- case "configureLidUnit": simulation.configureLidUnit(...request.args); break;
179
- case "lidUnitSnapshot": result = simulation.lidUnitSnapshot(...request.args); break;
180
- case "subcatchmentLidSnapshot": result = simulation.subcatchmentLidSnapshot(...request.args); break;
181
- case "useHotstart": simulation.useHotstart(...request.args); break;
182
- case "saveHotstart": result = simulation.saveHotstart(); break;
183
- case "exportCheckpoint": result = simulation.exportCheckpoint(); break;
184
- case "loadCheckpointState": simulation.loadCheckpointState(...request.args); break;
185
- case "statistics": result = simulation.statistics(); break;
186
- case "finish": simulation.finish(); result = results(simulation); break;
187
- case "run": simulation.run(...request.args); result = results(simulation); break;
188
- case "end": simulation.end(); break;
189
- case "finalizeReport": simulation.finalizeReport(); break;
190
- case "report": simulation.report(); break;
191
- case "resetSolver": simulation.resetSolver(); break;
192
- case "sleepWorkers": simulation.sleepWorkers(); break;
193
- case "readFile": result = simulation.readFile(...request.args); break;
194
- default: {
195
- const unhandled: never = request;
196
- throw new Error(`Unknown simulation operation: ${String(unhandled)}`);
197
- }
198
- }
199
- }
200
- const transfers: ArrayBuffer[] = [];
201
- if (result instanceof Uint8Array) transfers.push(result.buffer as ArrayBuffer);
202
- else if (result && typeof result === "object") {
203
- if ("output" in result && result.output instanceof Uint8Array) transfers.push(result.output.buffer as ArrayBuffer);
204
- if (request.method === "exportCheckpoint") {
205
- const checkpoint = result as CheckpointBundle;
206
- transfers.push(checkpoint.manifest.buffer as ArrayBuffer);
207
- for (const bytes of Object.values(checkpoint.files)) transfers.push(bytes.buffer as ArrayBuffer);
208
- }
209
- }
210
- host.postMessage({ id, ok: true, result }, transfers);
211
- } catch (error) {
212
- const fatal = error instanceof WebAssembly.RuntimeError || method === "open" || method === "resumeCheckpoint" || method === "openOutput" || method === "close" || method === "closeOutput";
213
- const source = error && typeof error === "object" ? error as Record<string, unknown> : {};
214
- const detail: ErrorDetails = {
215
- message: error instanceof Error ? error.message : String(error),
216
- code: typeof source.code === "number" ? source.code : error instanceof WebAssembly.RuntimeError ? 9999 : undefined,
217
- operation: typeof source.operation === "string" ? source.operation : method,
218
- detail: typeof source.detail === "string" ? source.detail : undefined,
219
- semanticCode: typeof source.semanticCode === "string" ? source.semanticCode : undefined,
220
- category: typeof source.category === "string" ? source.category : undefined,
221
- diagnostics: Array.isArray(source.diagnostics) ? source.diagnostics as ConfigurationDiagnostic[] : undefined,
222
- report: typeof source.report === "string" ? source.report : undefined,
223
- cleanupError: typeof source.cleanupError === "string" ? source.cleanupError : undefined,
224
- };
225
- if (fatal && method !== "close") {
226
- try { shutdown(); } catch (cleanupError) { detail.cleanupError = String(cleanupError); }
227
- }
228
- host.postMessage({ id, ok: false, error: detail, fatal });
229
- }
230
- }
231
-
232
- // Native calls are synchronous. Initialization must finish before later requests.
233
- host.onmessage = ({ data }) => { queue = queue.then(() => dispatch(data)); };
1
+ import type { Simulation as NativeSimulation, OutputReader as NativeOutputReader } from "../../dist/swmmrs.js";
2
+ import type { ConfigurationDiagnostic, ErrorDetails } from "./exceptions.js";
3
+ import type { Request, Response, Result, Method } from "./protocol.js";
4
+ import type { RunResults } from "./types.js";
5
+ import type { CheckpointBundle } from "./scenarios.js";
6
+ import { loadWasm } from "./runtime.js";
7
+
8
+ // This module runs in a dedicated worker; the public build also uses DOM types.
9
+ const host = globalThis as unknown as {
10
+ onmessage: ((event: MessageEvent<Request>) => void) | null;
11
+ postMessage(message: Response, transfer?: Transferable[]): void;
12
+ };
13
+ const decoder = new TextDecoder();
14
+ let simulation: NativeSimulation | undefined;
15
+ let outputReader: NativeOutputReader | undefined;
16
+ let terminateThreadPool: (() => void) | undefined;
17
+ let queue = Promise.resolve();
18
+
19
+ function shutdown(): void {
20
+ const errors: unknown[] = [];
21
+ try { simulation?.close(); } catch (error) { errors.push(error); }
22
+ try { simulation?.free(); } catch (error) { errors.push(error); }
23
+ simulation = undefined;
24
+ try { outputReader?.free(); } catch (error) { errors.push(error); }
25
+ outputReader = undefined;
26
+ try { terminateThreadPool?.(); } catch (error) { errors.push(error); }
27
+ if (errors.length) {
28
+ const [primary, ...secondary] = errors;
29
+ const error = primary instanceof Error ? primary : new Error(String(primary));
30
+ if (secondary.length) Object.assign(error, { cleanupError: secondary.map(String).join("; ") });
31
+ throw error;
32
+ }
33
+ }
34
+
35
+ function results(owner: NativeSimulation): RunResults {
36
+ return {
37
+ report: decoder.decode(owner.readFile("model.rpt")),
38
+ output: owner.status().saveResults ? owner.readFile("model.out") : new Uint8Array(),
39
+ };
40
+ }
41
+
42
+ async function dispatch(request: Request): Promise<void> {
43
+ const { id, method } = request;
44
+ try {
45
+ let result: Result<Method> = undefined;
46
+ if (request.method === "open" || request.method === "resumeCheckpoint" || request.method === "openOutput") {
47
+ if (simulation || outputReader) throw new Error("An owner is already open");
48
+ const threads = request.method === "open" ? request.args[2]
49
+ : request.method === "resumeCheckpoint" ? request.args[1] : 1;
50
+ const bindings = threads === 1
51
+ ? await import("../../dist/serial/swmmrs.js")
52
+ : await import("../../dist/swmmrs.js");
53
+ const moduleUrl = threads === 1
54
+ ? new URL("../../dist/serial/swmmrs.js", import.meta.url).href
55
+ : new URL("../../dist/swmmrs.js", import.meta.url).href;
56
+ terminateThreadPool = bindings.terminateThreadPool;
57
+ await loadWasm(bindings, moduleUrl);
58
+ await bindings.initThreadPool(threads, moduleUrl);
59
+ if (request.method === "openOutput") {
60
+ outputReader = new bindings.OutputReader(request.args[0]);
61
+ result = outputReader.outputMetadata();
62
+ } else {
63
+ simulation = request.method === "open"
64
+ ? new bindings.Simulation(request.args[0], request.args[1])
65
+ : bindings.Simulation.resumeCheckpoint(request.args[0]);
66
+ result = simulation.info();
67
+ }
68
+ } else if (request.method === "close" || request.method === "closeOutput") {
69
+ shutdown();
70
+ } else if (request.method === "outputMetadata" || request.method === "outputReadBulkSeries" ||
71
+ request.method === "outputReadBulkSeriesByPeriod" || request.method === "outputReadStoredDates" ||
72
+ request.method === "outputSubcatchmentSeries" || request.method === "outputNodeSeries" ||
73
+ request.method === "outputLinkSeries" || request.method === "outputSystemSeries") {
74
+ if (!outputReader) throw new Error("Output reader is closed");
75
+ switch (request.method) {
76
+ case "outputMetadata": result = outputReader.outputMetadata(); break;
77
+ case "outputReadBulkSeries": result = outputReader.outputReadBulkSeries(...request.args); break;
78
+ case "outputReadBulkSeriesByPeriod": result = outputReader.outputReadBulkSeriesByPeriod(...request.args); break;
79
+ case "outputReadStoredDates": result = outputReader.outputReadStoredDates(...request.args); break;
80
+ case "outputSubcatchmentSeries": result = outputReader.outputSubcatchmentSeries(...request.args); break;
81
+ case "outputNodeSeries": result = outputReader.outputNodeSeries(...request.args); break;
82
+ case "outputLinkSeries": result = outputReader.outputLinkSeries(...request.args); break;
83
+ case "outputSystemSeries": result = outputReader.outputSystemSeries(...request.args); break;
84
+ }
85
+ } else {
86
+ if (!simulation) throw new Error("Simulation is closed");
87
+ switch (request.method) {
88
+ case "state": result = simulation.state as Result<"state">; break;
89
+ case "info": result = simulation.info(); break;
90
+ case "status": result = simulation.status(); break;
91
+ case "start": simulation.start(...request.args); break;
92
+ case "step": result = simulation.step() ?? null; break;
93
+ case "stride": result = simulation.stride(...request.args) ?? null; break;
94
+ case "node": result = simulation.node(...request.args); break;
95
+ case "link": result = simulation.link(...request.args); break;
96
+ case "nodes": result = simulation.nodes(request.args[0] === undefined ? undefined : [...request.args[0]]); break;
97
+ case "links": result = simulation.links(request.args[0] === undefined ? undefined : [...request.args[0]]); break;
98
+ case "subcatchment": result = simulation.subcatchment(...request.args); break;
99
+ case "nodeExternalInflow": result = simulation.nodeExternalInflow(...request.args); break;
100
+ case "outfallFixedStage": result = simulation.outfallFixedStage(...request.args) ?? null; break;
101
+ case "nodeQuality": result = simulation.nodeQuality(...request.args); break;
102
+ case "nodeQualitySnapshot": result = simulation.nodeQualitySnapshot(request.args[0] === undefined ? undefined : [...request.args[0]]); break;
103
+ case "overrideNodePollutantConcentrations": simulation.overrideNodePollutantConcentrations(...request.args); break;
104
+ case "nodeExternalPollutantMassFlux": result = simulation.nodeExternalPollutantMassFlux(...request.args); break;
105
+ case "nodeExternalPollutantMassFluxValue": result = simulation.nodeExternalPollutantMassFluxValue(...request.args); break;
106
+ case "updateNodeExternalPollutantMassFlux": simulation.updateNodeExternalPollutantMassFlux(...request.args); break;
107
+ case "nodeStatistics": result = simulation.nodeStatistics(...request.args); break;
108
+ case "storageStatistics": result = simulation.storageStatistics(...request.args); break;
109
+ case "outfallStatistics": result = simulation.outfallStatistics(...request.args); break;
110
+ case "nodeStatisticsSnapshot": result = simulation.nodeStatisticsSnapshot(request.args[0] === undefined ? undefined : [...request.args[0]]); break;
111
+ case "nodeTotalInflowVolume": result = simulation.nodeTotalInflowVolume(...request.args); break;
112
+ case "linkQuality": result = simulation.linkQuality(...request.args); break;
113
+ case "linkQualitySnapshot": result = simulation.linkQualitySnapshot(request.args[0] === undefined ? undefined : [...request.args[0]]); break;
114
+ case "overrideLinkPollutantConcentrations": simulation.overrideLinkPollutantConcentrations(...request.args); break;
115
+ case "linkExternalPollutantMassFlux": result = simulation.linkExternalPollutantMassFlux(...request.args); break;
116
+ case "linkExternalPollutantMassFluxValue": result = simulation.linkExternalPollutantMassFluxValue(...request.args); break;
117
+ case "updateLinkExternalPollutantMassFlux": simulation.updateLinkExternalPollutantMassFlux(...request.args); break;
118
+ case "setLinkFlowLimit": simulation.setLinkFlowLimit(...request.args); break;
119
+ case "linkStatistics": result = simulation.linkStatistics(...request.args); break;
120
+ case "pumpStatistics": result = simulation.pumpStatistics(...request.args); break;
121
+ case "linkStatisticsSnapshot": result = simulation.linkStatisticsSnapshot(request.args[0] === undefined ? undefined : [...request.args[0]]); break;
122
+ case "linkInlet": result = simulation.linkInlet(...request.args); break;
123
+ case "inletResults": result = simulation.inletResults(...request.args); break;
124
+ case "updateInlet": simulation.updateInlet(...request.args); break;
125
+ case "subcatchments": result = simulation.subcatchments(request.args[0] === undefined ? undefined : [...request.args[0]]); break;
126
+ case "rainGage": result = simulation.rainGage(...request.args); break;
127
+ case "nodeConfiguration": result = simulation.nodeConfiguration(...request.args); break;
128
+ case "linkConfiguration": result = simulation.linkConfiguration(...request.args); break;
129
+ case "useRainGageExternalPrecipitation": simulation.useRainGageExternalPrecipitation(...request.args); break;
130
+ case "rainGageExternalPrecipitationRate": result = simulation.rainGageExternalPrecipitationRate(...request.args) ?? null; break;
131
+ case "rainGageRainfallOverride": result = simulation.rainGageRainfallOverride(...request.args) ?? null; break;
132
+ case "subcatchmentPrecipitationScaleFactors": result = simulation.subcatchmentPrecipitationScaleFactors(...request.args); break;
133
+ case "setSubcatchmentPrecipitationScaleFactors": simulation.setSubcatchmentPrecipitationScaleFactors(...request.args); break;
134
+ case "subcatchmentExternalForcing": result = simulation.subcatchmentExternalForcing(...request.args); break;
135
+ case "setSubcatchmentExternalRainfall": simulation.setSubcatchmentExternalRainfall(...request.args); break;
136
+ case "setSubcatchmentExternalSnowfall": simulation.setSubcatchmentExternalSnowfall(...request.args); break;
137
+ case "subcatchmentQuality": result = simulation.subcatchmentQuality(...request.args); break;
138
+ case "subcatchmentQualitySnapshot": result = simulation.subcatchmentQualitySnapshot(request.args[0] === undefined ? undefined : [...request.args[0]]); break;
139
+ case "subcatchmentNamedSettings": result = simulation.subcatchmentNamedSettings(...request.args); break;
140
+ case "subcatchmentNamedSetting": result = simulation.subcatchmentNamedSetting(...request.args); break;
141
+ case "updateSubcatchmentNamedSettings": simulation.updateSubcatchmentNamedSettings(...request.args); break;
142
+ case "subcatchmentExternalPollutantBuildupIncrement": result = simulation.subcatchmentExternalPollutantBuildupIncrement(...request.args); break;
143
+ case "subcatchmentExternalPollutantBuildupIncrementValue": result = simulation.subcatchmentExternalPollutantBuildupIncrementValue(...request.args); break;
144
+ case "updateSubcatchmentExternalPollutantBuildupIncrement": simulation.updateSubcatchmentExternalPollutantBuildupIncrement(...request.args); break;
145
+ case "subcatchmentStatistics": result = simulation.subcatchmentStatistics(...request.args); break;
146
+ case "subcatchmentStatisticsSnapshot": result = simulation.subcatchmentStatisticsSnapshot(request.args[0] === undefined ? undefined : [...request.args[0]]); break;
147
+ case "subcatchmentConfiguration": result = simulation.subcatchmentConfiguration(...request.args); break;
148
+ case "configureNode": simulation.configureNode(...request.args); break;
149
+ case "configureLink": simulation.configureLink(...request.args); break;
150
+ case "configureSubcatchment": simulation.configureSubcatchment(...request.args); break;
151
+ case "setNodeExternalInflow": simulation.setNodeExternalInflow(...request.args); break;
152
+ case "setLinkTargetSetting": simulation.setLinkTargetSetting(...request.args); break;
153
+ case "setOutfallStage": simulation.setOutfallStage(...request.args); break;
154
+ case "setRainGagePrecipitation": simulation.setRainGagePrecipitation(...request.args); break;
155
+ case "setRainGageRainfallOverride": simulation.setRainGageRainfallOverride(...request.args); break;
156
+ case "options": result = simulation.options(); break;
157
+ case "configureOptions": simulation.configureOptions(...request.args); break;
158
+ case "updateSchedule": simulation.updateSchedule(...request.args); break;
159
+ case "maximumRoutingStepSeconds": result = simulation.maximumRoutingStepSeconds(); break;
160
+ case "ammModelConfiguration": result = simulation.ammModelConfiguration(...request.args); break;
161
+ case "configureAmmModel": simulation.configureAmmModel(...request.args); break;
162
+ case "ammAssignments": result = simulation.ammAssignments(); break;
163
+ case "replaceAmmAssignments": simulation.replaceAmmAssignments(...request.args); break;
164
+ case "unitHydrographConfiguration": result = simulation.unitHydrographConfiguration(...request.args); break;
165
+ case "configureUnitHydrograph": simulation.configureUnitHydrograph(...request.args); break;
166
+ case "rdiiAssignments": result = simulation.rdiiAssignments(); break;
167
+ case "replaceRdiiAssignments": simulation.replaceRdiiAssignments(...request.args); break;
168
+ case "aquiferConfiguration": result = simulation.aquiferConfiguration(...request.args); break;
169
+ case "configureAquifer": simulation.configureAquifer(...request.args); break;
170
+ case "snowmeltConfiguration": result = simulation.snowmeltConfiguration(...request.args); break;
171
+ case "configureSnowmelt": simulation.configureSnowmelt(...request.args); break;
172
+ case "snowmeltSurfaceConfiguration": result = simulation.snowmeltSurfaceConfiguration(...request.args); break;
173
+ case "configureSnowmeltSurface": simulation.configureSnowmeltSurface(...request.args); break;
174
+ case "lidControlConfiguration": result = simulation.lidControlConfiguration(...request.args); break;
175
+ case "configureLidControl": simulation.configureLidControl(...request.args); break;
176
+ case "lidUnitCount": result = simulation.lidUnitCount(...request.args); break;
177
+ case "lidUnitConfiguration": result = simulation.lidUnitConfiguration(...request.args); break;
178
+ case "configureLidUnit": simulation.configureLidUnit(...request.args); break;
179
+ case "lidUnitSnapshot": result = simulation.lidUnitSnapshot(...request.args); break;
180
+ case "subcatchmentLidSnapshot": result = simulation.subcatchmentLidSnapshot(...request.args); break;
181
+ case "useHotstart": simulation.useHotstart(...request.args); break;
182
+ case "saveHotstart": result = simulation.saveHotstart(); break;
183
+ case "exportCheckpoint": result = simulation.exportCheckpoint(); break;
184
+ case "loadCheckpointState": simulation.loadCheckpointState(...request.args); break;
185
+ case "statistics": result = simulation.statistics(); break;
186
+ case "finish": simulation.finish(); result = results(simulation); break;
187
+ case "run": simulation.run(...request.args); result = results(simulation); break;
188
+ case "end": simulation.end(); break;
189
+ case "finalizeReport": simulation.finalizeReport(); break;
190
+ case "report": simulation.report(); break;
191
+ case "resetSolver": simulation.resetSolver(); break;
192
+ case "sleepWorkers": simulation.sleepWorkers(); break;
193
+ case "readFile": result = simulation.readFile(...request.args); break;
194
+ default: {
195
+ const unhandled: never = request;
196
+ throw new Error(`Unknown simulation operation: ${String(unhandled)}`);
197
+ }
198
+ }
199
+ }
200
+ const transfers: ArrayBuffer[] = [];
201
+ if (result instanceof Uint8Array) transfers.push(result.buffer as ArrayBuffer);
202
+ else if (result && typeof result === "object") {
203
+ if ("output" in result && result.output instanceof Uint8Array) transfers.push(result.output.buffer as ArrayBuffer);
204
+ if (request.method === "exportCheckpoint") {
205
+ const checkpoint = result as CheckpointBundle;
206
+ transfers.push(checkpoint.manifest.buffer as ArrayBuffer);
207
+ for (const bytes of Object.values(checkpoint.files)) transfers.push(bytes.buffer as ArrayBuffer);
208
+ }
209
+ }
210
+ host.postMessage({ id, ok: true, result }, transfers);
211
+ } catch (error) {
212
+ const fatal = error instanceof WebAssembly.RuntimeError || method === "open" || method === "resumeCheckpoint" || method === "openOutput" || method === "close" || method === "closeOutput";
213
+ const source = error && typeof error === "object" ? error as Record<string, unknown> : {};
214
+ const detail: ErrorDetails = {
215
+ message: error instanceof Error ? error.message : String(error),
216
+ code: typeof source.code === "number" ? source.code : error instanceof WebAssembly.RuntimeError ? 9999 : undefined,
217
+ operation: typeof source.operation === "string" ? source.operation : method,
218
+ detail: typeof source.detail === "string" ? source.detail : undefined,
219
+ semanticCode: typeof source.semanticCode === "string" ? source.semanticCode : undefined,
220
+ category: typeof source.category === "string" ? source.category : undefined,
221
+ diagnostics: Array.isArray(source.diagnostics) ? source.diagnostics as ConfigurationDiagnostic[] : undefined,
222
+ report: typeof source.report === "string" ? source.report : undefined,
223
+ cleanupError: typeof source.cleanupError === "string" ? source.cleanupError : undefined,
224
+ };
225
+ if (fatal && method !== "close") {
226
+ try { shutdown(); } catch (cleanupError) { detail.cleanupError = String(cleanupError); }
227
+ }
228
+ host.postMessage({ id, ok: false, error: detail, fatal });
229
+ }
230
+ }
231
+
232
+ // Native calls are synchronous. Initialization must finish before later requests.
233
+ host.onmessage = ({ data }) => { queue = queue.then(() => dispatch(data)); };