@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.
Files changed (120) hide show
  1. package/README.md +264 -0
  2. package/dist/README.md +264 -0
  3. package/dist/serial/README.md +264 -0
  4. package/dist/serial/swmmrs.d.ts +395 -0
  5. package/dist/serial/swmmrs.js +3169 -0
  6. package/dist/serial/swmmrs_bg.wasm +0 -0
  7. package/dist/snippets/swmmrs-parallel-5d1c71108133e81d/worker-pool/browser.js +98 -0
  8. package/dist/swmmrs.d.ts +422 -0
  9. package/dist/swmmrs.js +3330 -0
  10. package/dist/swmmrs_bg.wasm +0 -0
  11. package/index.d.ts +2 -0
  12. package/index.js +2 -0
  13. package/lib/swmmrs/client.d.ts +11 -0
  14. package/lib/swmmrs/client.d.ts.map +1 -0
  15. package/lib/swmmrs/client.js +82 -0
  16. package/lib/swmmrs/client.js.map +1 -0
  17. package/lib/swmmrs/enums.d.ts +41 -0
  18. package/lib/swmmrs/enums.d.ts.map +1 -0
  19. package/lib/swmmrs/enums.js +2 -0
  20. package/lib/swmmrs/enums.js.map +1 -0
  21. package/lib/swmmrs/exceptions.d.ts +98 -0
  22. package/lib/swmmrs/exceptions.d.ts.map +1 -0
  23. package/lib/swmmrs/exceptions.js +86 -0
  24. package/lib/swmmrs/exceptions.js.map +1 -0
  25. package/lib/swmmrs/index.d.ts +27 -0
  26. package/lib/swmmrs/index.d.ts.map +1 -0
  27. package/lib/swmmrs/index.js +13 -0
  28. package/lib/swmmrs/index.js.map +1 -0
  29. package/lib/swmmrs/objects/amm.d.ts +114 -0
  30. package/lib/swmmrs/objects/amm.d.ts.map +1 -0
  31. package/lib/swmmrs/objects/amm.js +19 -0
  32. package/lib/swmmrs/objects/amm.js.map +1 -0
  33. package/lib/swmmrs/objects/collections.d.ts +109 -0
  34. package/lib/swmmrs/objects/collections.d.ts.map +1 -0
  35. package/lib/swmmrs/objects/collections.js +158 -0
  36. package/lib/swmmrs/objects/collections.js.map +1 -0
  37. package/lib/swmmrs/objects/definitions.d.ts +215 -0
  38. package/lib/swmmrs/objects/definitions.d.ts.map +1 -0
  39. package/lib/swmmrs/objects/definitions.js +69 -0
  40. package/lib/swmmrs/objects/definitions.js.map +1 -0
  41. package/lib/swmmrs/objects/lids.d.ts +446 -0
  42. package/lib/swmmrs/objects/lids.d.ts.map +1 -0
  43. package/lib/swmmrs/objects/lids.js +90 -0
  44. package/lib/swmmrs/objects/lids.js.map +1 -0
  45. package/lib/swmmrs/objects/links.d.ts +615 -0
  46. package/lib/swmmrs/objects/links.d.ts.map +1 -0
  47. package/lib/swmmrs/objects/links.js +90 -0
  48. package/lib/swmmrs/objects/links.js.map +1 -0
  49. package/lib/swmmrs/objects/nodes.d.ts +494 -0
  50. package/lib/swmmrs/objects/nodes.d.ts.map +1 -0
  51. package/lib/swmmrs/objects/nodes.js +147 -0
  52. package/lib/swmmrs/objects/nodes.js.map +1 -0
  53. package/lib/swmmrs/objects/options.d.ts +112 -0
  54. package/lib/swmmrs/objects/options.d.ts.map +1 -0
  55. package/lib/swmmrs/objects/options.js +27 -0
  56. package/lib/swmmrs/objects/options.js.map +1 -0
  57. package/lib/swmmrs/objects/rtk.d.ts +82 -0
  58. package/lib/swmmrs/objects/rtk.d.ts.map +1 -0
  59. package/lib/swmmrs/objects/rtk.js +19 -0
  60. package/lib/swmmrs/objects/rtk.js.map +1 -0
  61. package/lib/swmmrs/objects/subcatchments.d.ts +575 -0
  62. package/lib/swmmrs/objects/subcatchments.d.ts.map +1 -0
  63. package/lib/swmmrs/objects/subcatchments.js +243 -0
  64. package/lib/swmmrs/objects/subcatchments.js.map +1 -0
  65. package/lib/swmmrs/output.d.ts +412 -0
  66. package/lib/swmmrs/output.d.ts.map +1 -0
  67. package/lib/swmmrs/output.js +507 -0
  68. package/lib/swmmrs/output.js.map +1 -0
  69. package/lib/swmmrs/protocol.d.ts +80 -0
  70. package/lib/swmmrs/protocol.d.ts.map +1 -0
  71. package/lib/swmmrs/protocol.js +2 -0
  72. package/lib/swmmrs/protocol.js.map +1 -0
  73. package/lib/swmmrs/runtime.d.ts +22 -0
  74. package/lib/swmmrs/runtime.d.ts.map +1 -0
  75. package/lib/swmmrs/runtime.js +146 -0
  76. package/lib/swmmrs/runtime.js.map +1 -0
  77. package/lib/swmmrs/scenarios.d.ts +41 -0
  78. package/lib/swmmrs/scenarios.d.ts.map +1 -0
  79. package/lib/swmmrs/scenarios.js +2 -0
  80. package/lib/swmmrs/scenarios.js.map +1 -0
  81. package/lib/swmmrs/simulation.d.ts +249 -0
  82. package/lib/swmmrs/simulation.d.ts.map +1 -0
  83. package/lib/swmmrs/simulation.js +415 -0
  84. package/lib/swmmrs/simulation.js.map +1 -0
  85. package/lib/swmmrs/snapshots.d.ts +192 -0
  86. package/lib/swmmrs/snapshots.d.ts.map +1 -0
  87. package/lib/swmmrs/snapshots.js +2 -0
  88. package/lib/swmmrs/snapshots.js.map +1 -0
  89. package/lib/swmmrs/types.d.ts +123 -0
  90. package/lib/swmmrs/types.d.ts.map +1 -0
  91. package/lib/swmmrs/types.js +2 -0
  92. package/lib/swmmrs/types.js.map +1 -0
  93. package/lib/swmmrs/worker.d.ts +2 -0
  94. package/lib/swmmrs/worker.d.ts.map +1 -0
  95. package/lib/swmmrs/worker.js +488 -0
  96. package/lib/swmmrs/worker.js.map +1 -0
  97. package/package.json +33 -0
  98. package/src/swmmrs/client.ts +76 -0
  99. package/src/swmmrs/enums.ts +73 -0
  100. package/src/swmmrs/exceptions.ts +120 -0
  101. package/src/swmmrs/index.ts +79 -0
  102. package/src/swmmrs/objects/amm.ts +113 -0
  103. package/src/swmmrs/objects/collections.ts +153 -0
  104. package/src/swmmrs/objects/definitions.ts +246 -0
  105. package/src/swmmrs/objects/lids.ts +487 -0
  106. package/src/swmmrs/objects/links.ts +626 -0
  107. package/src/swmmrs/objects/nodes.ts +504 -0
  108. package/src/swmmrs/objects/options.ts +114 -0
  109. package/src/swmmrs/objects/rtk.ts +79 -0
  110. package/src/swmmrs/objects/subcatchments.ts +650 -0
  111. package/src/swmmrs/output.ts +798 -0
  112. package/src/swmmrs/protocol.ts +62 -0
  113. package/src/swmmrs/runtime.ts +188 -0
  114. package/src/swmmrs/scenarios.ts +40 -0
  115. package/src/swmmrs/simulation.ts +406 -0
  116. package/src/swmmrs/snapshots.ts +199 -0
  117. package/src/swmmrs/types.ts +123 -0
  118. package/src/swmmrs/worker.ts +233 -0
  119. package/worker-node.js +142 -0
  120. package/worker.js +1 -0
@@ -0,0 +1,504 @@
1
+ import type { Call } from "../protocol.js";
2
+ import type { ModelTime, NodeKind } from "../enums.js";
3
+ import type { NodeResults } from "../snapshots.js";
4
+
5
+ /** Storage area/depth relationship represented by {@link StorageShape}. */
6
+ export type StorageShapeKind =
7
+ | "functional"
8
+ | "tabular"
9
+ | "cylindrical"
10
+ | "conical"
11
+ | "paraboloid"
12
+ | "pyramidal";
13
+ /** Canonical storage-shape declaration returned by {@link Node.configuration}. */
14
+ export interface StorageShape {
15
+ /** Functional, tabular, or geometric shape selector. */
16
+ readonly kind: StorageShapeKind;
17
+ /** Three canonical shape coefficients; interpretation depends on {@link kind}. */
18
+ readonly coefficients: readonly [number, number, number];
19
+ /** Canonical storage-curve ID for a tabular shape; otherwise `null`. */
20
+ readonly curve: string | null;
21
+ }
22
+
23
+ /** Replacement storage shape supplied through {@link NodePatch.shape}. */
24
+ export interface StorageShapePatch {
25
+ /** Shape to install; required even when only coefficients change. */
26
+ readonly kind: StorageShapeKind;
27
+ /** Shape coefficients, defaulting to `[0, 0, 0]`. Must be zero for a tabular shape. */
28
+ readonly coefficients?: readonly [number, number, number];
29
+ /** Storage-curve ID, required for a tabular shape. */
30
+ readonly curve?: string | null;
31
+ }
32
+
33
+ /** Storage seepage or Green-Ampt exfiltration parameters. */
34
+ export interface StorageExfiltration {
35
+ /** Saturated hydraulic conductivity in project infiltration-rate units (in/h or mm/h). */
36
+ readonly conductivity: number;
37
+ /** Suction head in project rainfall-depth units (in or mm). */
38
+ readonly suctionHead: number;
39
+ /** Initial moisture deficit as a dimensionless fraction. */
40
+ readonly moistureDeficit: number;
41
+ }
42
+
43
+ /** Replacement exfiltration parameters; zero suction and deficit select seepage. */
44
+ export interface StorageExfiltrationPatch {
45
+ /** {@inheritDoc StorageExfiltration.conductivity} */
46
+ readonly conductivity: number;
47
+ /** Suction head in in or mm; defaults to zero. */
48
+ readonly suctionHead?: number;
49
+ /** Initial moisture-deficit fraction; defaults to zero. */
50
+ readonly moistureDeficit?: number;
51
+ }
52
+
53
+ /** Declared outfall boundary model; separate from a runtime stage override. */
54
+ export type OutfallBoundaryKind = "free" | "normal" | "fixed" | "tidal" | "timeseries";
55
+
56
+ /** Outfall boundary declaration, not the current runtime override. */
57
+ export interface OutfallBoundary {
58
+ /** Boundary model. */
59
+ readonly kind: OutfallBoundaryKind;
60
+ /** Fixed-stage elevation in project length units. */
61
+ readonly stage: number;
62
+ /** Canonical tidal-curve or time-series ID; `null` for other boundary kinds. */
63
+ readonly reference: string | null;
64
+ }
65
+
66
+ /** Replacement outfall boundary supplied through {@link NodePatch.boundary}. */
67
+ export interface OutfallBoundaryPatch {
68
+ /** Boundary model to install. */
69
+ readonly kind: OutfallBoundaryKind;
70
+ /** Fixed-stage elevation in project length units; defaults to zero for `fixed`. */
71
+ readonly stage?: number;
72
+ /** Required curve ID for `tidal`, or time-series ID for `timeseries`. */
73
+ readonly reference?: string | null;
74
+ }
75
+
76
+ /** Flow-diversion rule used by a divider node. */
77
+ export type DividerRuleKind = "overflow" | "cutoff" | "tabular" | "weir";
78
+
79
+ /** Canonical divider declaration returned by {@link Node.configuration}. */
80
+ export interface DividerRule {
81
+ /** Flow-diversion rule. */
82
+ readonly kind: DividerRuleKind;
83
+ /** Minimum flow, maximum head, and discharge coefficient; applicability depends on the rule. */
84
+ readonly values: readonly [number, number, number];
85
+ /** Canonical diversion-curve ID for `tabular`; otherwise `null`. */
86
+ readonly curve: string | null;
87
+ }
88
+
89
+ /** Replacement divider rule supplied through {@link NodePatch.rule}. */
90
+ export interface DividerRulePatch {
91
+ /** Flow-diversion rule to install. */
92
+ readonly kind: DividerRuleKind;
93
+ /** Rule values, defaulting to zeros. `cutoff` accepts only minimum flow; `tabular` requires zeros. */
94
+ readonly values?: readonly [number, number, number];
95
+ /** Diversion-curve ID, required for `tabular`. */
96
+ readonly curve?: string | null;
97
+ }
98
+
99
+ /**
100
+ * Sparse, atomic declaration update accepted by {@link Node.configure}.
101
+ *
102
+ * Omitted top-level fields retain their values. Nested shape, exfiltration,
103
+ * boundary, and rule records replace that declaration rather than merging it.
104
+ * Kind-specific fields require the corresponding node kind. Runtime forcings,
105
+ * results, and the node ID are not accepted here.
106
+ */
107
+ export interface NodePatch {
108
+ /** {@inheritDoc NodeConfiguration.tag} */
109
+ readonly tag?: string;
110
+ /** {@inheritDoc NodeConfiguration.invertElevation} */
111
+ readonly invertElevation?: number;
112
+ /** {@inheritDoc NodeConfiguration.fullDepth} */
113
+ readonly fullDepth?: number;
114
+ /** {@inheritDoc NodeConfiguration.surchargeDepth} */
115
+ readonly surchargeDepth?: number;
116
+ /** {@inheritDoc NodeConfiguration.pondedArea} */
117
+ readonly pondedArea?: number;
118
+ /** {@inheritDoc NodeConfiguration.initialDepth} */
119
+ readonly initialDepth?: number;
120
+ /** {@inheritDoc NodeConfiguration.includedInReport} */
121
+ readonly includedInReport?: boolean;
122
+ /** Replacement storage area/depth relationship; storage nodes only. */
123
+ readonly shape?: StorageShapePatch;
124
+ /** Storage evaporation fraction; storage nodes only. */
125
+ readonly evaporationFraction?: number;
126
+ /** Replacement storage exfiltration parameters; `null` disables exfiltration. */
127
+ readonly exfiltration?: StorageExfiltrationPatch | null;
128
+ /** Replacement declared boundary; outfalls only. */
129
+ readonly boundary?: OutfallBoundaryPatch;
130
+ /** Whether reverse flow is blocked; outfalls only. */
131
+ readonly hasFlapGate?: boolean;
132
+ /** Receiving subcatchment ID for an outfall; `null` clears the relation. */
133
+ readonly routeToSubcatchment?: string | null;
134
+ /** Replacement flow-diversion rule; dividers only. */
135
+ readonly rule?: DividerRulePatch;
136
+ /** Diverted link ID for a divider; `null` clears the relation. */
137
+ readonly divertedLink?: string | null;
138
+ }
139
+
140
+ /**
141
+ * Detached, read-only node declarations returned by {@link Node.configuration}.
142
+ * Subtype fields are `null` when they do not apply to this node kind.
143
+ */
144
+ export interface NodeConfiguration {
145
+ /** Configured node kind; handles do not have public subtype subclasses. */
146
+ readonly kind: NodeKind;
147
+ /** Object tag. */
148
+ readonly tag: string;
149
+ /** Invert elevation in project length units (ft or m). */
150
+ readonly invertElevation: number;
151
+ /** Full depth above the invert in project length units. */
152
+ readonly fullDepth: number;
153
+ /** Additional surcharge depth in project length units. */
154
+ readonly surchargeDepth: number;
155
+ /** Ponding area in project length squared (ft² or m²). */
156
+ readonly pondedArea: number;
157
+ /** Initial water depth in project length units. */
158
+ readonly initialDepth: number;
159
+ /** Whether this node is selected for detailed reporting. */
160
+ readonly includedInReport: boolean;
161
+ /** Persistent additive API inflow in project flow units; set with {@link Node.setExternalInflow}. */
162
+ readonly externalInflow: number;
163
+ /** Storage area/depth relationship; `null` for other node kinds. */
164
+ readonly shape: StorageShape | null;
165
+ /** Storage evaporation fraction; `null` for other node kinds. */
166
+ readonly evaporationFraction: number | null;
167
+ /** Storage exfiltration parameters; `null` when absent or not applicable. */
168
+ readonly exfiltration: StorageExfiltration | null;
169
+ /** Declared outfall boundary; `null` for other node kinds. */
170
+ readonly boundary: OutfallBoundary | null;
171
+ /** Outfall reverse-flow flap gate; `null` for other node kinds. */
172
+ readonly hasFlapGate: boolean | null;
173
+ /** Canonical receiving-subcatchment ID for an outfall; `null` when unset or not applicable. */
174
+ readonly routeToSubcatchment: string | null;
175
+ /** Divider flow-diversion rule; `null` for other node kinds. */
176
+ readonly rule: DividerRule | null;
177
+ /** Canonical diverted-link ID for a divider; `null` when unset or not applicable. */
178
+ readonly divertedLink: string | null;
179
+ }
180
+
181
+ /** Detached current concentrations, in each pollutant's configured concentration units. */
182
+ export interface NodeQuality {
183
+ /** Canonical pollutant IDs defining the order of every concentration array. */
184
+ readonly pollutantIds: readonly string[];
185
+ /** Current node concentrations, aligned with {@link pollutantIds}. */
186
+ readonly concentrations: readonly number[];
187
+ /** Current inflow concentrations, aligned with {@link pollutantIds}. */
188
+ readonly inflowConcentrations: readonly number[];
189
+ /** Current reactor concentrations, aligned with {@link pollutantIds}. */
190
+ readonly reactorConcentrations: readonly number[];
191
+ }
192
+
193
+ /**
194
+ * Detached quality snapshot returned by `simulation.nodes.qualitySnapshot(ids)`.
195
+ * Matrices are pollutant-major: `[pollutantIndex][objectIndex]`.
196
+ * Concentrations use each pollutant's configured concentration units.
197
+ */
198
+ export interface NodeQualitySnapshot {
199
+ /** Canonical node IDs in selection order, defining each matrix's inner dimension. */
200
+ readonly objectIds: readonly string[];
201
+ /** Canonical pollutant IDs defining each matrix's outer dimension. */
202
+ readonly pollutantIds: readonly string[];
203
+ /** Current node concentrations. */
204
+ readonly concentrations: readonly (readonly number[])[];
205
+ /** Current inflow concentrations. */
206
+ readonly inflowConcentrations: readonly (readonly number[])[];
207
+ /** Current reactor concentrations. */
208
+ readonly reactorConcentrations: readonly (readonly number[])[];
209
+ }
210
+
211
+ /** Detached cumulative statistics for the current run, read with {@link Node.statistics}. */
212
+ export interface NodeStatistics {
213
+ /** Average reported depth in project length units; zero before reporting samples exist. */
214
+ readonly averageDepth: number;
215
+ /** Maximum depth in project length units. */
216
+ readonly maximumDepth: number;
217
+ /** Model calendar time of maximum depth, without a timezone. */
218
+ readonly maximumDepthTime: ModelTime;
219
+ /** Maximum reported depth in project length units. */
220
+ readonly maximumReportedDepth: number;
221
+ /** Cumulative flooded volume in project volume units (ft³ or m³). */
222
+ readonly floodedVolume: number;
223
+ /** Cumulative time flooded, in seconds. */
224
+ readonly timeFloodedSeconds: number;
225
+ /** Cumulative time surcharged, in seconds. */
226
+ readonly timeSurchargedSeconds: number;
227
+ /** Cumulative time Courant-critical, in seconds. */
228
+ readonly timeCourantCriticalSeconds: number;
229
+ /** Cumulative lateral inflow volume in project volume units, not a flow rate. */
230
+ readonly totalLateralInflow: number;
231
+ /** Maximum lateral inflow in project flow units. */
232
+ readonly maximumLateralInflow: number;
233
+ /** Maximum total inflow in project flow units. */
234
+ readonly maximumInflow: number;
235
+ /** Maximum overflow in project flow units. */
236
+ readonly maximumOverflow: number;
237
+ /** Maximum ponded volume in project volume units. */
238
+ readonly maximumPondedVolume: number;
239
+ /** Number of nonconverged routing steps. */
240
+ readonly nonconvergedCount: number;
241
+ /** Model calendar time of maximum inflow, without a timezone. */
242
+ readonly maximumInflowTime: ModelTime;
243
+ /** Model calendar time of maximum overflow, without a timezone. */
244
+ readonly maximumOverflowTime: ModelTime;
245
+ }
246
+
247
+ /** Detached storage-only cumulative statistics, read with {@link Node.storageStatistics}. */
248
+ export interface StorageStatistics {
249
+ /** Initial stored volume in project volume units (ft³ or m³). */
250
+ readonly initialVolume: number;
251
+ /** Average reported volume in project volume units; zero before reporting samples exist. */
252
+ readonly averageVolume: number;
253
+ /** Maximum stored volume in project volume units. */
254
+ readonly maximumVolume: number;
255
+ /** Maximum inflow in project flow units. */
256
+ readonly maximumInflow: number;
257
+ /** Cumulative evaporated volume in project volume units. */
258
+ readonly evaporationLosses: number;
259
+ /** Cumulative exfiltrated volume in project volume units. */
260
+ readonly exfiltrationLosses: number;
261
+ /** Model calendar time of maximum volume, without a timezone. */
262
+ readonly maximumVolumeTime: ModelTime;
263
+ }
264
+
265
+ /** Detached outfall-only cumulative statistics, read with {@link Node.outfallStatistics}. */
266
+ export interface OutfallStatistics {
267
+ /** Average discharge in project flow units; zero before discharge periods exist. */
268
+ readonly averageFlow: number;
269
+ /** Maximum discharge in project flow units. */
270
+ readonly maximumFlow: number;
271
+ /** Cumulative discharged loads keyed by canonical pollutant ID, in configured load units. */
272
+ readonly pollutantLoads: Readonly<Record<string, number>>;
273
+ /** Number of discharge periods used for the average. */
274
+ readonly periodCount: number;
275
+ }
276
+ /**
277
+ * Detached cumulative statistics from `simulation.nodes.statisticsSnapshot(ids)`.
278
+ * Every column follows {@link objectIds}; values and units match {@link NodeStatistics}.
279
+ */
280
+ export interface NodeStatisticsSnapshot {
281
+ /** Canonical node IDs in selection order. */
282
+ readonly objectIds: readonly string[];
283
+ /** {@inheritDoc NodeStatistics.averageDepth} */
284
+ readonly averageDepth: readonly number[];
285
+ /** {@inheritDoc NodeStatistics.maximumDepth} */
286
+ readonly maximumDepth: readonly number[];
287
+ /** {@inheritDoc NodeStatistics.maximumDepthTime} */
288
+ readonly maximumDepthTime: readonly ModelTime[];
289
+ /** {@inheritDoc NodeStatistics.maximumReportedDepth} */
290
+ readonly maximumReportedDepth: readonly number[];
291
+ /** {@inheritDoc NodeStatistics.floodedVolume} */
292
+ readonly floodedVolume: readonly number[];
293
+ /** {@inheritDoc NodeStatistics.timeFloodedSeconds} */
294
+ readonly timeFloodedSeconds: readonly number[];
295
+ /** {@inheritDoc NodeStatistics.timeSurchargedSeconds} */
296
+ readonly timeSurchargedSeconds: readonly number[];
297
+ /** {@inheritDoc NodeStatistics.timeCourantCriticalSeconds} */
298
+ readonly timeCourantCriticalSeconds: readonly number[];
299
+ /** {@inheritDoc NodeStatistics.totalLateralInflow} */
300
+ readonly totalLateralInflow: readonly number[];
301
+ /** {@inheritDoc NodeStatistics.maximumLateralInflow} */
302
+ readonly maximumLateralInflow: readonly number[];
303
+ /** {@inheritDoc NodeStatistics.maximumInflow} */
304
+ readonly maximumInflow: readonly number[];
305
+ /** {@inheritDoc NodeStatistics.maximumOverflow} */
306
+ readonly maximumOverflow: readonly number[];
307
+ /** {@inheritDoc NodeStatistics.maximumPondedVolume} */
308
+ readonly maximumPondedVolume: readonly number[];
309
+ /** {@inheritDoc NodeStatistics.nonconvergedCount} */
310
+ readonly nonconvergedCount: readonly number[];
311
+ /** {@inheritDoc NodeStatistics.maximumInflowTime} */
312
+ readonly maximumInflowTime: readonly ModelTime[];
313
+ /** {@inheritDoc NodeStatistics.maximumOverflowTime} */
314
+ readonly maximumOverflowTime: readonly ModelTime[];
315
+ }
316
+
317
+ /**
318
+ * Pollutant-ID-to-value mapping. Concentration overrides use configured concentration
319
+ * units; external mass fluxes use configured pollutant mass per project time units.
320
+ * Inputs may be sparse. Returned mappings are detached and read-only.
321
+ */
322
+ export type PollutantValues = Readonly<Record<string, number>>;
323
+
324
+ export interface NodeOperations {
325
+ nodeConfiguration: { args: [string]; result: NodeConfiguration };
326
+ configureNode: { args: [string, NodePatch]; result: void };
327
+ nodeExternalInflow: { args: [string]; result: number };
328
+ outfallFixedStage: { args: [string]; result: number | null };
329
+ nodeQuality: { args: [string]; result: NodeQuality };
330
+ nodeQualitySnapshot: { args: [readonly string[] | undefined]; result: NodeQualitySnapshot };
331
+ overrideNodePollutantConcentrations: { args: [string, PollutantValues]; result: void };
332
+ nodeExternalPollutantMassFlux: { args: [string]; result: PollutantValues };
333
+ nodeExternalPollutantMassFluxValue: { args: [string, string]; result: number };
334
+ updateNodeExternalPollutantMassFlux: { args: [string, PollutantValues, boolean]; result: void };
335
+ nodeStatistics: { args: [string]; result: NodeStatistics };
336
+ storageStatistics: { args: [string]; result: StorageStatistics };
337
+ outfallStatistics: { args: [string]; result: OutfallStatistics };
338
+ nodeStatisticsSnapshot: { args: [readonly string[] | undefined]; result: NodeStatisticsSnapshot };
339
+ nodeTotalInflowVolume: { args: [string]; result: number };
340
+ }
341
+
342
+ /**
343
+ * Owner-bound node handle obtained with `simulation.nodes.get(id)`.
344
+ *
345
+ * The constructor is private. Use {@link NodeConfiguration.kind} to distinguish
346
+ * junctions, storage nodes, outfalls, and dividers; there are no public subtype
347
+ * classes. Reads return detached, frozen records. Mutations require explicit
348
+ * methods, not assignments to those records.
349
+ *
350
+ * Operations reject when the owner is closed or failed, or the requested operation
351
+ * is invalid for its lifecycle state or node kind. Wrong-kind calls do not mutate
352
+ * the model. Read {@link statistics} before ending the run; hydraulic and quality
353
+ * reads remain available in `ended`.
354
+ */
355
+ export class Node {
356
+ /** Canonical configured node ID. */
357
+ readonly id: string;
358
+ readonly #call: Call;
359
+ private constructor(id: string, call: Call) { this.id = id; this.#call = call; Object.freeze(this); }
360
+ /** @internal */
361
+ static create(id: string, call: Call): Node { return new Node(id, call); }
362
+
363
+ /**
364
+ * Read current hydraulics in `running`, `complete`, or `ended`.
365
+ * @returns A detached {@link NodeResults} record in project units, not a time series.
366
+ */
367
+ results(): Promise<NodeResults> { return this.#call("node", this.id); }
368
+
369
+ /**
370
+ * Read common and kind-specific declarations in any healthy owner state.
371
+ * @returns A detached {@link NodeConfiguration}; non-applicable subtype fields are `null`.
372
+ */
373
+ configuration(): Promise<NodeConfiguration> { return this.#call("nodeConfiguration", this.id); }
374
+
375
+ /**
376
+ * Atomically update declarations in `open` or `ended`.
377
+ * An accepted edit in `ended` returns the owner to `open`.
378
+ * @param patch - Sparse {@link NodePatch}. Omitted top-level fields retain their values.
379
+ * @returns Resolves after the complete patch is accepted.
380
+ * @throws Rejects for an invalid patch, wrong node kind, or invalid lifecycle state;
381
+ * no part of a rejected patch is applied.
382
+ * @example
383
+ * ```typescript
384
+ * import type { Node } from "@swmmrs/swmmrs";
385
+ * declare const node: Node;
386
+ * await node.configure({ fullDepth: 4.5, initialDepth: 0.25 });
387
+ * ```
388
+ */
389
+ configure(patch: NodePatch): Promise<void> { return this.#call("configureNode", this.id, patch); }
390
+
391
+ /**
392
+ * Read the persistent additive API inflow in any healthy owner state.
393
+ * @returns Inflow in project flow units, excluding other inflow sources.
394
+ */
395
+ externalInflow(): Promise<number> { return this.#call("nodeExternalInflow", this.id); }
396
+
397
+ /**
398
+ * Set persistent additive API inflow in `open`, `running`, or `ended`.
399
+ * @param flow - Inflow in project flow units. Zero removes the API contribution.
400
+ * @returns Resolves after the forcing is updated.
401
+ */
402
+ setExternalInflow(flow: number): Promise<void> { return this.#call("setNodeExternalInflow", this.id, flow); }
403
+
404
+ /**
405
+ * Set a persistent fixed-stage override in `open`, `running`, or `ended`.
406
+ * This runtime forcing is separate from {@link NodePatch.boundary}.
407
+ * @param stage - Outfall boundary elevation in project length units (ft or m).
408
+ * @returns Resolves after the forcing is updated.
409
+ * @throws Rejects for a non-outfall node or an invalid stage or lifecycle state.
410
+ */
411
+ setOutfallStage(stage: number): Promise<void> { return this.#call("setOutfallStage", this.id, stage); }
412
+
413
+ /**
414
+ * Read the effective fixed stage in any healthy owner state; outfalls only.
415
+ * @returns Runtime override if set, otherwise the declared fixed stage, in project
416
+ * length units; `null` when neither supplies a fixed stage.
417
+ * @throws Rejects for a non-outfall node.
418
+ */
419
+ fixedStage(): Promise<number | null> { return this.#call("outfallFixedStage", this.id); }
420
+
421
+ /**
422
+ * Read current pollutant concentrations in `running`, `complete`, or `ended`.
423
+ * @returns Detached {@link NodeQuality} arrays aligned with their pollutant IDs.
424
+ */
425
+ quality(): Promise<NodeQuality> { return this.#call("nodeQuality", this.id); }
426
+
427
+ /**
428
+ * Queue concentration overrides for the next quality-routing step; requires `running`.
429
+ * The override expires after that step rather than becoming a persistent forcing.
430
+ * @param values - Sparse pollutant-ID map of nonnegative concentrations in each
431
+ * pollutant's configured concentration units.
432
+ * @returns Resolves after the overrides are queued.
433
+ * @throws Rejects invalid IDs, concentrations, or lifecycle states.
434
+ */
435
+ overridePollutantConcentrations(values: PollutantValues): Promise<void> {
436
+ return this.#call("overrideNodePollutantConcentrations", this.id, values);
437
+ }
438
+
439
+ /**
440
+ * Read persistent external pollutant mass fluxes in `open`, `running`, or `ended`.
441
+ * @returns A detached {@link PollutantValues} map in configured pollutant mass-flux units.
442
+ */
443
+ externalPollutantMassFlux(): Promise<PollutantValues> {
444
+ return this.#call("nodeExternalPollutantMassFlux", this.id);
445
+ }
446
+
447
+ /**
448
+ * Read one persistent external mass flux in `open`, `running`, or `ended`.
449
+ * @param pollutantId - Configured pollutant ID.
450
+ * @returns The pollutant's external mass flux in its configured mass-flux units.
451
+ * @throws Rejects an unknown pollutant ID or invalid lifecycle state.
452
+ */
453
+ externalPollutantMassFluxValue(pollutantId: string): Promise<number> {
454
+ return this.#call("nodeExternalPollutantMassFluxValue", this.id, pollutantId);
455
+ }
456
+
457
+ /**
458
+ * Update persistent external pollutant mass fluxes in `open`, `running`, or `ended`.
459
+ * @param values - Sparse pollutant-ID map in configured pollutant mass-flux units.
460
+ * @param replace - Defaults to `false`: merge supplied IDs. With `true`, replace
461
+ * the complete mapping and reset omitted pollutants to zero.
462
+ * @returns Resolves after the atomic update.
463
+ * @throws Rejects invalid pollutant IDs, values, or lifecycle states.
464
+ */
465
+ updateExternalPollutantMassFlux(values: PollutantValues, replace = false): Promise<void> {
466
+ return this.#call("updateNodeExternalPollutantMassFlux", this.id, values, replace);
467
+ }
468
+
469
+ /**
470
+ * Reset all persistent external pollutant mass fluxes to zero.
471
+ * Requires `open`, `running`, or `ended`; equivalent to
472
+ * `updateExternalPollutantMassFlux({}, true)`.
473
+ * @returns Resolves after the complete mapping is cleared.
474
+ */
475
+ clearExternalPollutantMassFlux(): Promise<void> {
476
+ return this.updateExternalPollutantMassFlux({}, true);
477
+ }
478
+
479
+ /**
480
+ * Read cumulative node statistics in `running` or `complete`, before ending the run.
481
+ * @returns A detached {@link NodeStatistics} record for the current run.
482
+ */
483
+ statistics(): Promise<NodeStatistics> { return this.#call("nodeStatistics", this.id); }
484
+
485
+ /**
486
+ * Read storage-only statistics in `running` or `complete`.
487
+ * @returns A detached {@link StorageStatistics} record for the current run.
488
+ * @throws Rejects for a non-storage node or invalid lifecycle state.
489
+ */
490
+ storageStatistics(): Promise<StorageStatistics> { return this.#call("storageStatistics", this.id); }
491
+
492
+ /**
493
+ * Read outfall-only statistics in `running` or `complete`.
494
+ * @returns A detached {@link OutfallStatistics} record for the current run.
495
+ * @throws Rejects for a non-outfall node or invalid lifecycle state.
496
+ */
497
+ outfallStatistics(): Promise<OutfallStatistics> { return this.#call("outfallStatistics", this.id); }
498
+
499
+ /**
500
+ * Read cumulative total inflow volume in `running` or `complete`.
501
+ * @returns Volume in project volume units (ft³ or m³), not a flow rate.
502
+ */
503
+ totalInflowVolume(): Promise<number> { return this.#call("nodeTotalInflowVolume", this.id); }
504
+ }
@@ -0,0 +1,114 @@
1
+ import type { CustomEllipseModel, InertiaDamping, ModelTime, NormalFlowLimit, SurchargeMethod } from "../enums.js";
2
+ import type { Call } from "../protocol.js";
3
+
4
+ /** Calendar month and day for seasonal sweeping; validated by the native solver. */
5
+ export type SweepDay = readonly [month: number, day: number];
6
+
7
+ /** Sparse model-option update. Omitted fields retain their values; tolerances are not writable. */
8
+ export interface ModelOptionsPatch {
9
+ /** Nominal routing step in seconds. Resets Courant factor to zero unless both are supplied. */
10
+ routingStepSeconds?: number;
11
+ /** Binary report interval in whole seconds, independent of iterator observation cadence. */
12
+ reportStepSeconds?: number;
13
+ /** Enable detailed report tables; object selection still uses `includedInReport`. */
14
+ detailedReportingEnabled?: boolean;
15
+ /** Ellipse cross-section interpretation. */
16
+ customEllipseModel?: CustomEllipseModel;
17
+ /** Surcharge treatment. */
18
+ surchargeMethod?: SurchargeMethod;
19
+ /** Allow configured nodal surface ponding. */
20
+ allowPonding?: boolean;
21
+ /** Dynamic Wave inertia-damping rule. */
22
+ inertiaDamping?: InertiaDamping;
23
+ /** Normal-flow limiting rule. */
24
+ normalFlowLimit?: NormalFlowLimit;
25
+ /** Allow steady-state routing skips. */
26
+ skipSteadyState?: boolean;
27
+ /** Process rainfall; does not create missing definitions. */
28
+ rainfallEnabled?: boolean;
29
+ /** Process rainfall-dependent infiltration/inflow. */
30
+ rdiiEnabled?: boolean;
31
+ /** Process snowmelt. */
32
+ snowmeltEnabled?: boolean;
33
+ /** Process groundwater. */
34
+ groundwaterEnabled?: boolean;
35
+ /** Route hydraulic flow. */
36
+ routingEnabled?: boolean;
37
+ /** Process water quality. */
38
+ qualityEnabled?: boolean;
39
+ /** Control-rule interval in whole seconds. */
40
+ ruleStepSeconds?: number;
41
+ /** First month/day for seasonal sweeping. */
42
+ sweepStart?: SweepDay;
43
+ /** Last month/day for seasonal sweeping. */
44
+ sweepEnd?: SweepDay;
45
+ /** Maximum Dynamic Wave trial iterations. */
46
+ maximumTrials?: number;
47
+ /** Model-requested solver threads, distinct from the worker capacity in `SimulationOptions.threads`. */
48
+ requestedThreads?: number;
49
+ /** Lower bound for variable routing steps in seconds. */
50
+ minimumRoutingStepSeconds?: number;
51
+ /** Conduit-lengthening time step in seconds. */
52
+ lengtheningStepSeconds?: number;
53
+ /** Antecedent dry period in seconds. */
54
+ antecedentDrySeconds?: number;
55
+ /** Variable-step adjustment factor. Explicit writes must be positive; reads may contain the disabled value zero. */
56
+ courantFactor?: number;
57
+ /** Minimum nodal surface area in ft² or m². */
58
+ minimumSurfaceArea?: number;
59
+ /** Minimum conduit slope as a ratio, not a percentage. */
60
+ minimumConduitSlope?: number;
61
+ }
62
+
63
+ /** Complete read-only option record, including all writable fields and solver tolerances. */
64
+ export interface ModelOptions extends Readonly<Required<ModelOptionsPatch>> {
65
+ /** Read-only hydraulic head convergence tolerance. */
66
+ readonly headTolerance: number;
67
+ /** Read-only system-flow convergence tolerance. */
68
+ readonly systemFlowTolerance: number;
69
+ /** Read-only lateral-flow convergence tolerance. */
70
+ readonly lateralFlowTolerance: number;
71
+ }
72
+
73
+ /** Sparse calendar boundaries for `Simulation.updateSchedule()`; omitted times retain their values. */
74
+ export interface SchedulePatch {
75
+ /** Simulation start in timezone-free model calendar time. */
76
+ startTime?: ModelTime;
77
+ /** First reporting time in timezone-free model calendar time. */
78
+ reportStart?: ModelTime;
79
+ /** Simulation end in timezone-free model calendar time. */
80
+ endTime?: ModelTime;
81
+ }
82
+
83
+ /** Option-family operations added to the shared worker protocol. */
84
+ export interface OptionsOperations {
85
+ updateSchedule: { args: [SchedulePatch]; result: void };
86
+ maximumRoutingStepSeconds: { args: []; result: number };
87
+ }
88
+
89
+ /** Stable model options. Updates are atomic and require an open or ended run. */
90
+ export class SimulationOptionsView {
91
+ readonly #call: Call;
92
+ private constructor(call: Call) { this.#call = call; }
93
+ /** @internal */
94
+ static create(call: Call): SimulationOptionsView { return new SimulationOptionsView(call); }
95
+ /** Read the complete option record in a healthy owner state.
96
+ * @returns Detached {@link ModelOptions}, including read-only solver tolerances.
97
+ */
98
+ read(): Promise<ModelOptions> { return this.#call("options"); }
99
+ /** Atomically update model options in `open` or `ended`; accepted edits return `ended` to `open`.
100
+ * @param patch - Sparse option values. Unknown keys, invalid types/enums, and solver-invalid values reject the whole patch.
101
+ * @returns Resolves after all supplied fields are accepted.
102
+ * @example
103
+ * ```typescript
104
+ * import type { Simulation } from "@swmmrs/swmmrs";
105
+ * declare const simulation: Simulation;
106
+ * await simulation.options.update({ routingStepSeconds: 30, reportStepSeconds: 300, qualityEnabled: true });
107
+ * ```
108
+ */
109
+ update(patch: ModelOptionsPatch): Promise<void> { return this.#call("configureOptions", patch); }
110
+ /** Read the maximum routing interval allowed by current configuration.
111
+ * @returns Maximum routing interval in seconds.
112
+ */
113
+ maximumRoutingStepSeconds(): Promise<number> { return this.#call("maximumRoutingStepSeconds"); }
114
+ }