@swmmrs/swmmrs 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +264 -0
- package/dist/README.md +264 -0
- package/dist/serial/README.md +264 -0
- package/dist/serial/swmmrs.d.ts +395 -0
- package/dist/serial/swmmrs.js +3169 -0
- package/dist/serial/swmmrs_bg.wasm +0 -0
- package/dist/snippets/swmmrs-parallel-5d1c71108133e81d/worker-pool/browser.js +98 -0
- package/dist/swmmrs.d.ts +422 -0
- package/dist/swmmrs.js +3330 -0
- package/dist/swmmrs_bg.wasm +0 -0
- package/index.d.ts +2 -0
- package/index.js +2 -0
- package/lib/swmmrs/client.d.ts +11 -0
- package/lib/swmmrs/client.d.ts.map +1 -0
- package/lib/swmmrs/client.js +82 -0
- package/lib/swmmrs/client.js.map +1 -0
- package/lib/swmmrs/enums.d.ts +41 -0
- package/lib/swmmrs/enums.d.ts.map +1 -0
- package/lib/swmmrs/enums.js +2 -0
- package/lib/swmmrs/enums.js.map +1 -0
- package/lib/swmmrs/exceptions.d.ts +98 -0
- package/lib/swmmrs/exceptions.d.ts.map +1 -0
- package/lib/swmmrs/exceptions.js +86 -0
- package/lib/swmmrs/exceptions.js.map +1 -0
- package/lib/swmmrs/index.d.ts +27 -0
- package/lib/swmmrs/index.d.ts.map +1 -0
- package/lib/swmmrs/index.js +13 -0
- package/lib/swmmrs/index.js.map +1 -0
- package/lib/swmmrs/objects/amm.d.ts +114 -0
- package/lib/swmmrs/objects/amm.d.ts.map +1 -0
- package/lib/swmmrs/objects/amm.js +19 -0
- package/lib/swmmrs/objects/amm.js.map +1 -0
- package/lib/swmmrs/objects/collections.d.ts +109 -0
- package/lib/swmmrs/objects/collections.d.ts.map +1 -0
- package/lib/swmmrs/objects/collections.js +158 -0
- package/lib/swmmrs/objects/collections.js.map +1 -0
- package/lib/swmmrs/objects/definitions.d.ts +215 -0
- package/lib/swmmrs/objects/definitions.d.ts.map +1 -0
- package/lib/swmmrs/objects/definitions.js +69 -0
- package/lib/swmmrs/objects/definitions.js.map +1 -0
- package/lib/swmmrs/objects/lids.d.ts +446 -0
- package/lib/swmmrs/objects/lids.d.ts.map +1 -0
- package/lib/swmmrs/objects/lids.js +90 -0
- package/lib/swmmrs/objects/lids.js.map +1 -0
- package/lib/swmmrs/objects/links.d.ts +615 -0
- package/lib/swmmrs/objects/links.d.ts.map +1 -0
- package/lib/swmmrs/objects/links.js +90 -0
- package/lib/swmmrs/objects/links.js.map +1 -0
- package/lib/swmmrs/objects/nodes.d.ts +494 -0
- package/lib/swmmrs/objects/nodes.d.ts.map +1 -0
- package/lib/swmmrs/objects/nodes.js +147 -0
- package/lib/swmmrs/objects/nodes.js.map +1 -0
- package/lib/swmmrs/objects/options.d.ts +112 -0
- package/lib/swmmrs/objects/options.d.ts.map +1 -0
- package/lib/swmmrs/objects/options.js +27 -0
- package/lib/swmmrs/objects/options.js.map +1 -0
- package/lib/swmmrs/objects/rtk.d.ts +82 -0
- package/lib/swmmrs/objects/rtk.d.ts.map +1 -0
- package/lib/swmmrs/objects/rtk.js +19 -0
- package/lib/swmmrs/objects/rtk.js.map +1 -0
- package/lib/swmmrs/objects/subcatchments.d.ts +575 -0
- package/lib/swmmrs/objects/subcatchments.d.ts.map +1 -0
- package/lib/swmmrs/objects/subcatchments.js +243 -0
- package/lib/swmmrs/objects/subcatchments.js.map +1 -0
- package/lib/swmmrs/output.d.ts +412 -0
- package/lib/swmmrs/output.d.ts.map +1 -0
- package/lib/swmmrs/output.js +507 -0
- package/lib/swmmrs/output.js.map +1 -0
- package/lib/swmmrs/protocol.d.ts +80 -0
- package/lib/swmmrs/protocol.d.ts.map +1 -0
- package/lib/swmmrs/protocol.js +2 -0
- package/lib/swmmrs/protocol.js.map +1 -0
- package/lib/swmmrs/runtime.d.ts +22 -0
- package/lib/swmmrs/runtime.d.ts.map +1 -0
- package/lib/swmmrs/runtime.js +146 -0
- package/lib/swmmrs/runtime.js.map +1 -0
- package/lib/swmmrs/scenarios.d.ts +41 -0
- package/lib/swmmrs/scenarios.d.ts.map +1 -0
- package/lib/swmmrs/scenarios.js +2 -0
- package/lib/swmmrs/scenarios.js.map +1 -0
- package/lib/swmmrs/simulation.d.ts +249 -0
- package/lib/swmmrs/simulation.d.ts.map +1 -0
- package/lib/swmmrs/simulation.js +415 -0
- package/lib/swmmrs/simulation.js.map +1 -0
- package/lib/swmmrs/snapshots.d.ts +192 -0
- package/lib/swmmrs/snapshots.d.ts.map +1 -0
- package/lib/swmmrs/snapshots.js +2 -0
- package/lib/swmmrs/snapshots.js.map +1 -0
- package/lib/swmmrs/types.d.ts +123 -0
- package/lib/swmmrs/types.d.ts.map +1 -0
- package/lib/swmmrs/types.js +2 -0
- package/lib/swmmrs/types.js.map +1 -0
- package/lib/swmmrs/worker.d.ts +2 -0
- package/lib/swmmrs/worker.d.ts.map +1 -0
- package/lib/swmmrs/worker.js +488 -0
- package/lib/swmmrs/worker.js.map +1 -0
- package/package.json +33 -0
- package/src/swmmrs/client.ts +76 -0
- package/src/swmmrs/enums.ts +73 -0
- package/src/swmmrs/exceptions.ts +120 -0
- package/src/swmmrs/index.ts +79 -0
- package/src/swmmrs/objects/amm.ts +113 -0
- package/src/swmmrs/objects/collections.ts +153 -0
- package/src/swmmrs/objects/definitions.ts +246 -0
- package/src/swmmrs/objects/lids.ts +487 -0
- package/src/swmmrs/objects/links.ts +626 -0
- package/src/swmmrs/objects/nodes.ts +504 -0
- package/src/swmmrs/objects/options.ts +114 -0
- package/src/swmmrs/objects/rtk.ts +79 -0
- package/src/swmmrs/objects/subcatchments.ts +650 -0
- package/src/swmmrs/output.ts +798 -0
- package/src/swmmrs/protocol.ts +62 -0
- package/src/swmmrs/runtime.ts +188 -0
- package/src/swmmrs/scenarios.ts +40 -0
- package/src/swmmrs/simulation.ts +406 -0
- package/src/swmmrs/snapshots.ts +199 -0
- package/src/swmmrs/types.ts +123 -0
- package/src/swmmrs/worker.ts +233 -0
- package/worker-node.js +142 -0
- package/worker.js +1 -0
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type { SimulationState, ModelTime } from "./enums.js";
|
|
2
|
+
import type { ErrorDetails } from "./exceptions.js";
|
|
3
|
+
import type { NodeConfiguration, NodePatch, NodeOperations } from "./objects/nodes.js";
|
|
4
|
+
import type { LinkConfiguration, LinkPatch, LinkOperations } from "./objects/links.js";
|
|
5
|
+
import type { SubcatchmentConfiguration, SubcatchmentPatch, SubcatchmentOperations } from "./objects/subcatchments.js";
|
|
6
|
+
import type { ModelOptions, ModelOptionsPatch, OptionsOperations } from "./objects/options.js";
|
|
7
|
+
import type { DefinitionOperations } from "./objects/definitions.js";
|
|
8
|
+
import type { AmmOperations } from "./objects/amm.js";
|
|
9
|
+
import type { RtkOperations } from "./objects/rtk.js";
|
|
10
|
+
import type { LidOperations } from "./objects/lids.js";
|
|
11
|
+
import type { OutputOperations } from "./output.js";
|
|
12
|
+
import type { ScenarioOperations } from "./scenarios.js";
|
|
13
|
+
import type { NodeResults, LinkResults, NodeSnapshot, LinkSnapshot, SubcatchmentResults, SubcatchmentSnapshot, RainGageResults, SimulationStatistics } from "./snapshots.js";
|
|
14
|
+
import type { SimulationInfo, SimulationStatus, RunResults } from "./types.js";
|
|
15
|
+
|
|
16
|
+
type Operation<A extends unknown[], R> = { args: A; result: R };
|
|
17
|
+
export interface Operations extends NodeOperations, LinkOperations, SubcatchmentOperations, OptionsOperations, DefinitionOperations, AmmOperations, RtkOperations, LidOperations, OutputOperations, ScenarioOperations {
|
|
18
|
+
open: Operation<[Uint8Array, Record<string, Uint8Array>, number], SimulationInfo>;
|
|
19
|
+
state: Operation<[], SimulationState>;
|
|
20
|
+
info: Operation<[], SimulationInfo>;
|
|
21
|
+
status: Operation<[], SimulationStatus>;
|
|
22
|
+
start: Operation<[boolean], void>;
|
|
23
|
+
step: Operation<[], ModelTime | null>;
|
|
24
|
+
stride: Operation<[number, boolean], ModelTime | null>;
|
|
25
|
+
node: Operation<[string], NodeResults>;
|
|
26
|
+
link: Operation<[string], LinkResults>;
|
|
27
|
+
nodes: Operation<[readonly string[] | undefined], NodeSnapshot>;
|
|
28
|
+
links: Operation<[readonly string[] | undefined], LinkSnapshot>;
|
|
29
|
+
subcatchment: Operation<[string], SubcatchmentResults>;
|
|
30
|
+
subcatchments: Operation<[readonly string[] | undefined], SubcatchmentSnapshot>;
|
|
31
|
+
rainGage: Operation<[string], RainGageResults>;
|
|
32
|
+
nodeConfiguration: Operation<[string], NodeConfiguration>;
|
|
33
|
+
linkConfiguration: Operation<[string], LinkConfiguration>;
|
|
34
|
+
subcatchmentConfiguration: Operation<[string], SubcatchmentConfiguration>;
|
|
35
|
+
configureNode: Operation<[string, NodePatch], void>;
|
|
36
|
+
configureLink: Operation<[string, LinkPatch], void>;
|
|
37
|
+
configureSubcatchment: Operation<[string, SubcatchmentPatch], void>;
|
|
38
|
+
setNodeExternalInflow: Operation<[string, number], void>;
|
|
39
|
+
setLinkTargetSetting: Operation<[string, number], void>;
|
|
40
|
+
setOutfallStage: Operation<[string, number], void>;
|
|
41
|
+
setRainGagePrecipitation: Operation<[string, number], void>;
|
|
42
|
+
setRainGageRainfallOverride: Operation<[string, number | null], void>;
|
|
43
|
+
options: Operation<[], ModelOptions>;
|
|
44
|
+
configureOptions: Operation<[ModelOptionsPatch], void>;
|
|
45
|
+
statistics: Operation<[], SimulationStatistics>;
|
|
46
|
+
finish: Operation<[], RunResults>;
|
|
47
|
+
run: Operation<[boolean], RunResults>;
|
|
48
|
+
end: Operation<[], void>;
|
|
49
|
+
finalizeReport: Operation<[], void>;
|
|
50
|
+
report: Operation<[], void>;
|
|
51
|
+
resetSolver: Operation<[], void>;
|
|
52
|
+
sleepWorkers: Operation<[], void>;
|
|
53
|
+
readFile: Operation<[string], Uint8Array>;
|
|
54
|
+
close: Operation<[], void>;
|
|
55
|
+
}
|
|
56
|
+
export type Method = keyof Operations;
|
|
57
|
+
export type Args<K extends Method> = Operations[K]["args"];
|
|
58
|
+
export type Result<K extends Method> = Operations[K]["result"];
|
|
59
|
+
export type Call = <K extends Method>(method: K, ...args: Args<K>) => Promise<Result<K>>;
|
|
60
|
+
export type Request = { [K in Method]: { id: number; method: K; args: Args<K> } }[Method];
|
|
61
|
+
export type Response = { id: number; ok: true; result: unknown } |
|
|
62
|
+
{ id: number; ok: false; error: ErrorDetails; fatal: boolean };
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import type { FileContents } from "./types.js";
|
|
2
|
+
|
|
3
|
+
const encoder = new TextEncoder();
|
|
4
|
+
|
|
5
|
+
type NodeProcess = {
|
|
6
|
+
versions?: { node?: unknown };
|
|
7
|
+
getBuiltinModule?: (specifier: string) => unknown;
|
|
8
|
+
};
|
|
9
|
+
type NodeOsModule = { availableParallelism?: () => number };
|
|
10
|
+
type RuntimeGlobal = typeof globalThis & {
|
|
11
|
+
process?: NodeProcess;
|
|
12
|
+
navigator?: { hardwareConcurrency?: number };
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
const runtimeGlobal = globalThis as RuntimeGlobal;
|
|
16
|
+
|
|
17
|
+
/** True when this module is running in Node rather than a browser page/worker. */
|
|
18
|
+
export const isNodeRuntime = typeof runtimeGlobal.process?.versions?.node === "string";
|
|
19
|
+
|
|
20
|
+
function hardwareConcurrency(): number {
|
|
21
|
+
const browserValue = runtimeGlobal.navigator?.hardwareConcurrency;
|
|
22
|
+
if (typeof browserValue === "number" && Number.isFinite(browserValue) && browserValue > 0) return Math.floor(browserValue);
|
|
23
|
+
const os = runtimeGlobal.process?.getBuiltinModule?.("node:os") as NodeOsModule | undefined;
|
|
24
|
+
const nodeValue = os?.availableParallelism?.();
|
|
25
|
+
return typeof nodeValue === "number" && Number.isFinite(nodeValue) && nodeValue > 0 ? Math.floor(nodeValue) : 1;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const hostThreadCapacity = hardwareConcurrency();
|
|
29
|
+
|
|
30
|
+
export interface RuntimeInfo {
|
|
31
|
+
readonly maxThreads: number;
|
|
32
|
+
readonly defaultThreads: number;
|
|
33
|
+
readonly parallel: boolean;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
async function runtimeCapacity(): Promise<number> {
|
|
37
|
+
if (!isNodeRuntime || runtimeGlobal.navigator?.hardwareConcurrency !== undefined || hostThreadCapacity > 1) {
|
|
38
|
+
return hostThreadCapacity;
|
|
39
|
+
}
|
|
40
|
+
const os = await dynamicImport("node:os") as NodeOsModule;
|
|
41
|
+
const value = os.availableParallelism?.();
|
|
42
|
+
return typeof value === "number" && Number.isFinite(value) && value > 0 ? Math.floor(value) : hostThreadCapacity;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/** Return host solver capacity without requiring browser globals in Node. */
|
|
46
|
+
export async function runtimeInfo(): Promise<RuntimeInfo> {
|
|
47
|
+
const parallel = isNodeRuntime || Boolean(runtimeGlobal.crossOriginIsolated);
|
|
48
|
+
const maxThreads = await runtimeCapacity();
|
|
49
|
+
return {
|
|
50
|
+
maxThreads,
|
|
51
|
+
defaultThreads: isNodeRuntime ? 1 : parallel ? maxThreads : 1,
|
|
52
|
+
parallel,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export interface WorkerCreationOptions {
|
|
57
|
+
workerUrl?: string | URL;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
type NodeWorkerPort = {
|
|
61
|
+
on(event: "message", listener: (value: unknown) => void): NodeWorkerPort;
|
|
62
|
+
on(event: "messageerror" | "error", listener: (error: unknown) => void): NodeWorkerPort;
|
|
63
|
+
on(event: "exit", listener: (code: number) => void): NodeWorkerPort;
|
|
64
|
+
postMessage(value: unknown, transferList?: readonly ArrayBuffer[]): void;
|
|
65
|
+
terminate(): Promise<number>;
|
|
66
|
+
};
|
|
67
|
+
type NodeWorkerConstructor = new (
|
|
68
|
+
filename: string | URL,
|
|
69
|
+
options?: { type?: "module"; workerData?: unknown },
|
|
70
|
+
) => NodeWorkerPort;
|
|
71
|
+
type NodeWorkerModule = { Worker?: NodeWorkerConstructor };
|
|
72
|
+
type NodeFsModule = { readFile(path: string | URL): Promise<Uint8Array> };
|
|
73
|
+
|
|
74
|
+
async function dynamicImport(specifier: string): Promise<unknown> {
|
|
75
|
+
return import(specifier);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function messageError(reason: unknown): Error {
|
|
79
|
+
return reason instanceof Error ? reason : new Error(String(reason));
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/** DOM-shaped adapter around node:worker_threads.Worker. */
|
|
83
|
+
class NodeWorkerAdapter {
|
|
84
|
+
#worker: NodeWorkerPort;
|
|
85
|
+
#terminated = false;
|
|
86
|
+
#failed = false;
|
|
87
|
+
#pendingError: Error | undefined;
|
|
88
|
+
#onerror: ((event: ErrorEvent) => void) | null = null;
|
|
89
|
+
|
|
90
|
+
onmessage: ((event: MessageEvent<unknown>) => void) | null = null;
|
|
91
|
+
onmessageerror: ((event: MessageEvent<unknown>) => void) | null = null;
|
|
92
|
+
|
|
93
|
+
get onerror(): ((event: ErrorEvent) => void) | null {
|
|
94
|
+
return this.#onerror;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
set onerror(handler: ((event: ErrorEvent) => void) | null) {
|
|
98
|
+
this.#onerror = handler;
|
|
99
|
+
const pending = this.#pendingError;
|
|
100
|
+
if (handler && pending) {
|
|
101
|
+
this.#pendingError = undefined;
|
|
102
|
+
queueMicrotask(() => handler(this.#errorEvent(pending)));
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
constructor(worker: NodeWorkerPort) {
|
|
107
|
+
this.#worker = worker;
|
|
108
|
+
worker.on("message", (data) => this.onmessage?.({ data } as MessageEvent<unknown>));
|
|
109
|
+
worker.on("messageerror", (error) => this.onmessageerror?.({ data: error } as MessageEvent<unknown>));
|
|
110
|
+
worker.on("error", (error) => this.#reportError(error));
|
|
111
|
+
worker.on("exit", (code) => {
|
|
112
|
+
if (!this.#terminated && code !== 0) this.#reportError(new Error(`SWMM worker exited with code ${code}`));
|
|
113
|
+
else if (!this.#terminated && code === 0) this.#reportError(new Error("SWMM worker exited unexpectedly"));
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
postMessage(message: unknown, transfer?: Transferable[]): void {
|
|
118
|
+
this.#worker.postMessage(message, transfer as readonly ArrayBuffer[] | undefined);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
terminate(): void {
|
|
122
|
+
this.#terminated = true;
|
|
123
|
+
void this.#worker.terminate();
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
#errorEvent(error: Error): ErrorEvent {
|
|
127
|
+
return { message: error.message, error, preventDefault() {} } as ErrorEvent;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
#reportError(reason: unknown): void {
|
|
131
|
+
if (this.#terminated || this.#failed) return;
|
|
132
|
+
this.#failed = true;
|
|
133
|
+
const error = messageError(reason);
|
|
134
|
+
if (this.#onerror) this.#onerror(this.#errorEvent(error));
|
|
135
|
+
else this.#pendingError = error;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/** Convert supported model input values to bytes without requiring browser globals. */
|
|
140
|
+
export async function bytes(value: FileContents): Promise<Uint8Array> {
|
|
141
|
+
if (typeof value === "string") return encoder.encode(value);
|
|
142
|
+
if (typeof Blob !== "undefined" && value instanceof Blob) return new Uint8Array(await value.arrayBuffer());
|
|
143
|
+
if (value instanceof ArrayBuffer) return new Uint8Array(value);
|
|
144
|
+
if (ArrayBuffer.isView(value)) return new Uint8Array(value.buffer, value.byteOffset, value.byteLength);
|
|
145
|
+
throw new TypeError("SWMM files must be strings, Blobs, ArrayBuffers, or typed arrays");
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
function wasmInitializer(bindings: unknown): (input?: unknown) => Promise<unknown> {
|
|
149
|
+
if (!bindings || typeof bindings !== "object" || !("default" in bindings)) {
|
|
150
|
+
throw new TypeError("WASM bindings must export a default initializer");
|
|
151
|
+
}
|
|
152
|
+
const initializer = bindings.default;
|
|
153
|
+
if (typeof initializer !== "function") throw new TypeError("WASM bindings must export a default initializer");
|
|
154
|
+
return initializer as (input?: unknown) => Promise<unknown>;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/** Read a generated wasm file from disk in Node. Browser callers should use loadWasm. */
|
|
158
|
+
export async function wasmInput(url: string | URL): Promise<Uint8Array> {
|
|
159
|
+
if (!isNodeRuntime) throw new Error("wasmInput is only available in Node");
|
|
160
|
+
const fs = await dynamicImport("node:fs/promises") as NodeFsModule;
|
|
161
|
+
const value = await fs.readFile(url);
|
|
162
|
+
return new Uint8Array(value.buffer, value.byteOffset, value.byteLength);
|
|
163
|
+
}
|
|
164
|
+
/** Initialize generated wasm with file bytes in Node and its normal URL loader in browsers. */
|
|
165
|
+
export async function loadWasm(bindings: unknown, moduleUrl: string | URL): Promise<unknown> {
|
|
166
|
+
const initializer = wasmInitializer(bindings);
|
|
167
|
+
if (!isNodeRuntime) return initializer();
|
|
168
|
+
return initializer({ module_or_path: await wasmInput(new URL("./swmmrs_bg.wasm", moduleUrl)) });
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/** Create one isolated worker using browser Worker or node:worker_threads. */
|
|
172
|
+
export async function createWorker(options: WorkerCreationOptions = {}): Promise<Worker> {
|
|
173
|
+
if (!isNodeRuntime) {
|
|
174
|
+
const WorkerConstructor = runtimeGlobal.Worker;
|
|
175
|
+
if (typeof WorkerConstructor !== "function") throw new Error("SWMM needs browser workers");
|
|
176
|
+
const url = options.workerUrl ?? new URL("./worker.js", import.meta.url);
|
|
177
|
+
return new WorkerConstructor(url, { type: "module" });
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
const { Worker: NodeWorker } = await dynamicImport("node:worker_threads") as NodeWorkerModule;
|
|
181
|
+
if (!NodeWorker) throw new Error("Node worker_threads are unavailable");
|
|
182
|
+
const target = options.workerUrl ?? new URL("./worker.js", import.meta.url);
|
|
183
|
+
const bootstrap = new URL("../../worker-node.js", import.meta.url);
|
|
184
|
+
return new NodeWorkerAdapter(new NodeWorker(bootstrap, {
|
|
185
|
+
type: "module",
|
|
186
|
+
workerData: { target: target instanceof URL ? target.href : target, name: "" },
|
|
187
|
+
})) as unknown as Worker;
|
|
188
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { SimulationInfo } from "./types.js";
|
|
2
|
+
|
|
3
|
+
/** Transferable bytes and files captured at one quiescent simulation boundary. */
|
|
4
|
+
export interface CheckpointBundle {
|
|
5
|
+
/** Bundle format identifier. */
|
|
6
|
+
readonly format: "swmmrs.checkpoint.bundle";
|
|
7
|
+
/** Supported bundle format version. */
|
|
8
|
+
readonly version: 1;
|
|
9
|
+
/** Isolated solver root used for manifest paths; never use it as a host path. */
|
|
10
|
+
readonly root: string;
|
|
11
|
+
/** Manifest path relative to `root`. */
|
|
12
|
+
readonly manifestPath: string;
|
|
13
|
+
/** Canonical core checkpoint JSON, untouched by the binding. */
|
|
14
|
+
readonly manifest: Uint8Array;
|
|
15
|
+
/** Manifest sidecars and validated external dependencies, keyed relative to `root`. */
|
|
16
|
+
readonly files: Readonly<Record<string, Uint8Array>>;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
type Operation<Args extends unknown[], Result> = { args: Args; result: Result };
|
|
20
|
+
|
|
21
|
+
/** Worker protocol additions for hotstarts, checkpoints, resume, and state load. */
|
|
22
|
+
export interface ScenarioOperations {
|
|
23
|
+
useHotstart: Operation<[Uint8Array | null], void>;
|
|
24
|
+
saveHotstart: Operation<[], Uint8Array>;
|
|
25
|
+
exportCheckpoint: Operation<[], CheckpointBundle>;
|
|
26
|
+
loadCheckpointState: Operation<[CheckpointBundle], void>;
|
|
27
|
+
/** The thread count is the final argument, matching the ordinary open operation. */
|
|
28
|
+
resumeCheckpoint: Operation<[CheckpointBundle, number], SimulationInfo>;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/** Low-level scenario operation names; prefer the methods on `Simulation` for execution. */
|
|
32
|
+
export type ScenarioMethod = keyof ScenarioOperations;
|
|
33
|
+
/** Argument tuple for a low-level scenario operation.
|
|
34
|
+
* @typeParam K - Scenario operation name.
|
|
35
|
+
*/
|
|
36
|
+
export type ScenarioArgs<K extends ScenarioMethod> = ScenarioOperations[K]["args"];
|
|
37
|
+
/** Resolved result type for a low-level scenario operation.
|
|
38
|
+
* @typeParam K - Scenario operation name.
|
|
39
|
+
*/
|
|
40
|
+
export type ScenarioResult<K extends ScenarioMethod> = ScenarioOperations[K]["result"];
|