@sdeverywhere/runtime 0.2.2 → 0.2.3

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/dist/index.d.ts CHANGED
@@ -1,159 +1,59 @@
1
1
  import { Result } from 'neverthrow';
2
2
 
3
- /** An input variable identifier string, as used in SDEverywhere. */
3
+ /** A variable name, as used in the modeling tool. */
4
+ type VarName = string;
5
+ /** A variable identifier, as used in model code generated by SDEverywhere. */
6
+ type VarId = string;
7
+ /** An input variable identifier, as used in model code generated by SDEverywhere. */
4
8
  type InputVarId = string;
5
- /** An output variable identifier string, as used in SDEverywhere. */
9
+ /** An output variable identifier, as used in model code generated by SDEverywhere. */
6
10
  type OutputVarId = string;
7
11
  /**
8
- * The variable index values for use with the optional output indices buffer.
9
- * @hidden This is not yet part of the public API; it is exposed here for use in testing tools.
10
- */
11
- interface OutputVarSpec {
12
- /** The variable index as used in the generated C code. */
13
- varIndex: number;
14
- /** The subscript index values as used in the generated C code. */
15
- subscriptIndices?: number[];
16
- }
17
-
18
- /**
19
- * Type declaration for a WebAssembly module wrapper produced
20
- * by the Emscripten compiler. This only declares the minimal
21
- * set of fields needed by `WasmModel` and `WasmBuffer`.
22
- */
23
- interface WasmModule {
24
- /** @hidden */
25
- cwrap: (fname: string, rettype: string, argtypes: string[]) => any;
26
- /** @hidden */
27
- _malloc: (numBytes: number) => number;
28
- /** @hidden */
29
- _free: (byteOffset: number) => void;
30
- /** @hidden */
31
- HEAP32: Int32Array;
32
- /** @hidden */
33
- HEAPF64: Float64Array;
34
- }
35
-
36
- /**
37
- * Wraps a `WebAssembly.Memory` buffer allocated on the wasm heap.
12
+ * The variable index metadata that is used to identify a specific instance of a
13
+ * variable in a generated model.
38
14
  *
39
- * When this is used synchronously (in the browser's normal JavaScript thread),
40
- * the client can use `getArrayView` to write directly into the underlying memory.
41
- *
42
- * Note, however, that `WebAssembly.Memory` buffers cannot be transferred to/from
43
- * a Web Worker. When using this class in a worker thread, create a separate
44
- * `Float64Array` that can be transferred between the worker and the client running
45
- * in the browser's normal JS thread, and then use `getArrayView` to copy into and
46
- * out of the wasm buffer.
15
+ * @hidden This is not yet part of the public API.
47
16
  */
48
- declare class WasmBuffer<ArrType> {
49
- private readonly wasmModule;
50
- private byteOffset;
51
- private heapArray;
52
- /**
53
- * @param wasmModule The `WasmModule` used to initialize the memory.
54
- * @param byteOffset The byte offset within the wasm heap.
55
- * @param heapArray The array view on the underlying heap buffer.
56
- */
57
- constructor(wasmModule: WasmModule, byteOffset: number, heapArray: ArrType);
58
- /**
59
- * @return An `ArrType` view on the underlying heap buffer.
60
- */
61
- getArrayView(): ArrType;
62
- /**
63
- * @return The raw address of the underlying heap buffer.
64
- * @hidden This is intended for use by `WasmModel` only.
65
- */
66
- getAddress(): number;
67
- /**
68
- * Dispose the buffer by freeing the allocated heap memory.
69
- */
70
- dispose(): void;
17
+ interface VarSpec {
18
+ /** The variable index as used in the generated C/JS code. */
19
+ varIndex: number;
20
+ /** The subscript index values as used in the generated C/JS code. */
21
+ subscriptIndices?: number[] | Int32Array;
71
22
  }
72
23
  /**
73
- * Return a `WasmBuffer` that holds int32 elements.
74
- *
75
- * @hidden For internal use only.
76
- *
77
- * @param wasmModule The `WasmModule` used to initialize the memory.
78
- * @param numElements The number of elements in the buffer.
79
- */
80
- declare function createInt32WasmBuffer(wasmModule: WasmModule, numElements: number): WasmBuffer<Int32Array>;
81
- /**
82
- * Return a `WasmBuffer` that holds float64 elements.
83
- *
84
- * @hidden For internal use only.
85
- *
86
- * @param wasmModule The `WasmModule` used to initialize the memory.
87
- * @param numElements The number of elements in the buffer.
24
+ * A reference to a variable in the generated model. A variable can be identified
25
+ * using either a `VarName` (the variable name, as used in the modeling tool) or a
26
+ * `VarId` (the variable identifier, as used in model code generated by SDEverywhere).
88
27
  */
89
- declare function createFloat64WasmBuffer(wasmModule: WasmModule, numElements: number): WasmBuffer<Float64Array>;
90
-
91
- /**
92
- * An interface to the generated WebAssembly model. Allows for running the model with
93
- * a given set of input values, producing a set of output values.
94
- */
95
- declare class WasmModel {
96
- /** The start time for the model (aka `INITIAL TIME`). */
97
- readonly startTime: number;
98
- /** The end time for the model (aka `FINAL TIME`). */
99
- readonly endTime: number;
100
- /** The frequency with which output values are saved (aka `SAVEPER`). */
101
- readonly saveFreq: number;
102
- /** The number of save points for each output. */
103
- readonly numSavePoints: number;
28
+ interface VarRef {
104
29
  /**
105
- * The maximum number of output indices that can be passed for each run.
106
- * @hidden This is not yet part of the public API; it is exposed here for use
107
- * in experimental testing tools.
30
+ * The name of the variable, as used in the modeling tool. If defined, the implementation
31
+ * will use this to identify the variable, and will ignore the `varId` property.
108
32
  */
109
- readonly maxOutputIndices: number;
110
- private readonly wasmRunModel;
33
+ varName?: VarName;
111
34
  /**
112
- * @param wasmModule The `WasmModule` that provides access to the native functions.
35
+ * The identifier of the variable, as used in model code generated by SDEverywhere. If
36
+ * defined, the implementation will use this to identify the variable, and will ignore
37
+ * the `varName` property.
113
38
  */
114
- constructor(wasmModule: WasmModule);
39
+ varId?: VarId;
115
40
  /**
116
- * Run the model, using inputs from the `inputs` buffer, and writing outputs into
117
- * the `outputs` buffer.
41
+ * The low-level spec for the variable to be modified. If defined, the implementation
42
+ * will use this identify the variable. If it is undefined, the implementation will
43
+ * use the `varId` or `varName` to identify the variable, and may use this property
44
+ * to cache the resulting `VarSpec` in this property for performance reasons.
118
45
  *
119
- * @param inputs The buffer containing inputs in the order expected by the model.
120
- * @param outputs The buffer into which the model will store output values.
121
- * @param outputIndices The buffer used to control which variables are written to `outputs`.
46
+ * @hidden This is not yet part of the public API.
122
47
  */
123
- runModel(inputs: WasmBuffer<Float64Array>, outputs: WasmBuffer<Float64Array>, outputIndices?: WasmBuffer<Int32Array>): void;
48
+ varSpec?: VarSpec;
124
49
  }
125
- /**
126
- * The result of model initialization.
127
- */
128
- interface WasmModelInitResult {
129
- /** The wasm model. */
130
- model: WasmModel;
131
- /** The buffer used to pass input values to the model. */
132
- inputsBuffer: WasmBuffer<Float64Array>;
133
- /** The buffer used to receive output values from the model. */
134
- outputsBuffer: WasmBuffer<Float64Array>;
135
- /**
136
- * The buffer used to control which variables are written to `outputsBuffer`.
137
- * @hidden This is not yet part of the public API; it is exposed here for use
138
- * in experimental testing tools.
139
- */
140
- outputIndicesBuffer?: WasmBuffer<Int32Array>;
141
- /** The output variable IDs. */
142
- outputVarIds: OutputVarId[];
50
+ /** A data point. */
51
+ interface Point {
52
+ /** The x value (typically a time value). */
53
+ x: number;
54
+ /** The y value. */
55
+ y: number;
143
56
  }
144
- /**
145
- * Initialize the wasm model and buffers.
146
- *
147
- * @param wasmModule The `WasmModule` that wraps the `wasm` binary.
148
- * @param numInputs The number of input variables, per the spec file passed to `sde`.
149
- * @param outputVarIds The output variable IDs, per the spec file passed to `sde`.
150
- */
151
- declare function initWasmModelAndBuffers(wasmModule: WasmModule, numInputs: number, outputVarIds: OutputVarId[]): WasmModelInitResult;
152
- /**
153
- * @hidden This is not part of the public API; it is exposed here for use by
154
- * the synchronous and asynchronous model runner implementations.
155
- */
156
- declare function updateOutputIndices(indicesArray: Int32Array, outputVarSpecs: OutputVarSpec[]): void;
157
57
 
158
58
  /** Callback functions that are called when the input value is changed. */
159
59
  interface InputCallbacks {
@@ -186,13 +86,6 @@ declare function createInputValue(varId: InputVarId, defaultValue: number, initi
186
86
 
187
87
  /** Indicates the type of error encountered when parsing an outputs buffer. */
188
88
  type ParseError = 'invalid-point-count';
189
- /** A data point. */
190
- interface Point {
191
- /** The x value (typically a time value). */
192
- x: number;
193
- /** The y value. */
194
- y: number;
195
- }
196
89
  /**
197
90
  * A time series of data points for an output variable.
198
91
  */
@@ -242,7 +135,7 @@ declare class Outputs {
242
135
  * @hidden This is not yet part of the public API; it is exposed here for use
243
136
  * in experimental testing tools.
244
137
  */
245
- varSpecs?: OutputVarSpec[];
138
+ varSpecs?: VarSpec[];
246
139
  /**
247
140
  * @param varIds The output variable identifiers.
248
141
  * @param startTime The start time for the model.
@@ -257,7 +150,7 @@ declare class Outputs {
257
150
  * @hidden This is not yet part of the public API; it is exposed here for use
258
151
  * in experimental testing tools.
259
152
  */
260
- setVarSpecs(varSpecs: OutputVarSpec[]): void;
153
+ setVarSpecs(varSpecs: VarSpec[]): void;
261
154
  /**
262
155
  * Parse the given raw float buffer (produced by the model) and store the values
263
156
  * into this `Outputs` instance.
@@ -280,6 +173,698 @@ declare class Outputs {
280
173
  getSeriesForVar(varId: OutputVarId): Series | undefined;
281
174
  }
282
175
 
176
+ /**
177
+ * Specifies the data that will be used to set or override a lookup definition.
178
+ */
179
+ interface LookupDef {
180
+ /** The reference that identifies the lookup or data variable to be modified. */
181
+ varRef: VarRef;
182
+ /** The lookup data as a flat array of (x,y) pairs. */
183
+ points: Float64Array;
184
+ }
185
+ /**
186
+ * Create a `LookupDef` instance from the given array of `Point` objects.
187
+ *
188
+ * @param varRef The reference to the lookup or data variable to be modified.
189
+ * @param points The lookup data as an array of `Point` objects.
190
+ */
191
+ declare function createLookupDef(varRef: VarRef, points: Point[]): LookupDef;
192
+
193
+ /**
194
+ * Return the length of the array that is required to store the variable
195
+ * indices for the given `VarSpec` instances.
196
+ *
197
+ * @hidden This is not part of the public API; it is exposed here for use by
198
+ * the synchronous and asynchronous model runner implementations.
199
+ *
200
+ * @param varSpecs The `VarSpec` instances to encode.
201
+ */
202
+ declare function getEncodedVarIndicesLength(varSpecs: VarSpec[]): number;
203
+ /**
204
+ * Encode variable indices to the given array.
205
+ *
206
+ * @hidden This is not part of the public API; it is exposed here for use by
207
+ * the synchronous and asynchronous model runner implementations.
208
+ *
209
+ * @param varSpecs The `VarSpec` instances to encode.
210
+ */
211
+ declare function encodeVarIndices(varSpecs: VarSpec[], indicesArray: Int32Array): void;
212
+ /**
213
+ * Return the lengths of the arrays that are required to store the lookup data
214
+ * and indices for the given `LookupDef` instances.
215
+ *
216
+ * @hidden This is not part of the public API; it is exposed here for use by
217
+ * the synchronous and asynchronous model runner implementations.
218
+ *
219
+ * @param lookupDefs The `LookupDef` instances to encode.
220
+ */
221
+ declare function getEncodedLookupBufferLengths(lookupDefs: LookupDef[]): {
222
+ lookupIndicesLength: number;
223
+ lookupsLength: number;
224
+ };
225
+ /**
226
+ * Encode lookup data and indices to the given arrays.
227
+ *
228
+ * @hidden This is not part of the public API; it is exposed here for use by
229
+ * the synchronous and asynchronous model runner implementations.
230
+ *
231
+ * @param lookupDefs The `LookupDef` instances to encode.
232
+ * @param lookupIndicesArray The view on the lookup indices buffer.
233
+ * @param lookupsArray The view on the lookup data buffer. This can be undefined in
234
+ * the case where the data for the lookup(s) is empty.
235
+ */
236
+ declare function encodeLookups(lookupDefs: LookupDef[], lookupIndicesArray: Int32Array, lookupsArray: Float64Array | undefined): void;
237
+ /**
238
+ * Decode lookup data and indices from the given buffer views and return the
239
+ * reconstructed `LookupDef` instances.
240
+ *
241
+ * @hidden This is not part of the public API; it is exposed here for use by
242
+ * the synchronous and asynchronous model runner implementations.
243
+ *
244
+ * @param lookupIndicesArray The view on the lookup indices buffer.
245
+ * @param lookupsArray The view on the lookup data buffer. This can be undefined in
246
+ * the case where the data for the lookup(s) is empty.
247
+ */
248
+ declare function decodeLookups(lookupIndicesArray: Int32Array, lookupsArray: Float64Array | undefined): LookupDef[];
249
+
250
+ type SubscriptId = string;
251
+ type DimensionId = string;
252
+ /**
253
+ * This matches the shape of the minimal model `listing_min.json` that is generated
254
+ * by the `sde generate --list` command.
255
+ *
256
+ * @hidden This is not yet part of the public API; it is exposed here for
257
+ * internal use only.
258
+ */
259
+ interface ModelListingSpecs {
260
+ dimensions: {
261
+ id: DimensionId;
262
+ subIds: SubscriptId[];
263
+ }[];
264
+ variables: {
265
+ id: VarId;
266
+ index: number;
267
+ dimIds?: DimensionId[];
268
+ }[];
269
+ }
270
+ /**
271
+ * @hidden This is not yet part of the public API; it is exposed here for use
272
+ * in experimental testing tools.
273
+ */
274
+ declare class ModelListing {
275
+ readonly varSpecs: Map<VarId, VarSpec>;
276
+ constructor(listingObj: ModelListingSpecs);
277
+ /**
278
+ * Return the `VarSpec` for the given variable ID, or undefined if there is no spec defined
279
+ * in the listing for that variable.
280
+ */
281
+ getSpecForVarId(varId: VarId): VarSpec | undefined;
282
+ /**
283
+ * Return the `VarSpec` for the given variable name, or undefined if there is no spec defined
284
+ * in the listing for that variable.
285
+ */
286
+ getSpecForVarName(varName: VarName): VarSpec | undefined;
287
+ /**
288
+ * Create a new `Outputs` instance that uses the same start/end years as the given "normal"
289
+ * `Outputs` instance but is prepared for reading the specified internal variables from the model.
290
+ *
291
+ * @param normalOutputs The `Outputs` that is used to access normal output variables from the model.
292
+ * @param varIds The variable IDs to include with the new `Outputs` instance.
293
+ */
294
+ deriveOutputs(normalOutputs: Outputs, varIds: OutputVarId[]): Outputs;
295
+ }
296
+
297
+ /**
298
+ * Additional options that can be passed to a `runModel` call to influence the model run.
299
+ */
300
+ interface RunModelOptions {
301
+ /**
302
+ * If defined, override the data for the specified lookups and/or data variables.
303
+ *
304
+ * If data was already defined in the generated model, the data provided in a
305
+ * `LookupDef` here will override the default data in the generated model.
306
+ *
307
+ * Note that unlike the `inputs` parameter for `runModel` (which must be provided
308
+ * with each call), the data overrides provided here persist after the `runModel`
309
+ * call. If you pass `lookups` in your Nth `runModel` call, that lookup data will
310
+ * still be in effect for the (N+1)th call. In other words, if your lookup data
311
+ * is not changing, you do not need to supply it with every `runModel` call.
312
+ */
313
+ lookups?: LookupDef[];
314
+ }
315
+
316
+ /**
317
+ * Encapsulates the parameters that are passed to a `runModel` call.
318
+ *
319
+ * @hidden This is not yet exposed in the public API; it is currently only used by
320
+ * the implementations of the `RunnableModel` interface.
321
+ */
322
+ interface RunModelParams {
323
+ /**
324
+ * Return the array containing the inputs, or undefined if the implementation does not
325
+ * have the inputs readily available in an array. If this returns undefined, use
326
+ * `copyInputs` to copy the inputs into a provided array.
327
+ */
328
+ getInputs(): Float64Array | undefined;
329
+ /**
330
+ * Copy the input values into an array.
331
+ *
332
+ * @param array An existing array, or undefined. If `array` is undefined, or it is
333
+ * not large enough to hold the input values, the `create` function will be called
334
+ * to allocate a new array.
335
+ * @param create A function that allocates a new `Float64Array` with the given length.
336
+ */
337
+ copyInputs(array: Float64Array | undefined, create: (numElements: number) => Float64Array): void;
338
+ /**
339
+ * Return the length (in elements) of the output indices array, or 0 if the indices are
340
+ * not active (i.e., if they were not included in the latest `runModel` call).
341
+ */
342
+ getOutputIndicesLength(): number;
343
+ /**
344
+ * Return the array containing the output indices, or undefined if the implementation does not
345
+ * have the output indices readily available in an array. If this returns undefined, use
346
+ * `copyOutputIndices` to copy the output indices into a provided array.
347
+ */
348
+ getOutputIndices(): Int32Array | undefined;
349
+ /**
350
+ * Copy the output indices into an array.
351
+ *
352
+ * @param array An existing array, or undefined. If `array` is undefined, or it is
353
+ * not large enough to hold the input values, the `create` function will be called
354
+ * to allocate a new array.
355
+ * @param create A function that allocates a new `Int32Array` with the given length.
356
+ */
357
+ copyOutputIndices(array: Int32Array | undefined, create: (numElements: number) => Int32Array): void;
358
+ /**
359
+ * Return the length (in elements) of the array that will receive the outputs.
360
+ */
361
+ getOutputsLength(): number;
362
+ /**
363
+ * Return the array containing the outputs, or undefined if the implementation does not
364
+ * have an array available for writing the outputs.
365
+ */
366
+ getOutputs(): Float64Array | undefined;
367
+ /**
368
+ * Return the `Outputs` object, or undefined if the implementation does not keep a reference
369
+ * to the `Outputs` object that was passed to `runModel`.
370
+ */
371
+ getOutputsObject(): Outputs | undefined;
372
+ /**
373
+ * Store the output values that were written by the model. This will be used to populate
374
+ * the `Outputs` object that was passed to the latest `runModel` call.
375
+ *
376
+ * @param array The array that contains the output values.
377
+ */
378
+ storeOutputs(array: Float64Array): void;
379
+ /**
380
+ * Return an array containing lookup overrides, or undefined if no lookups were passed to
381
+ * the latest `runModel` call.
382
+ */
383
+ getLookups(): LookupDef[] | undefined;
384
+ /**
385
+ * Return the elapsed time (in milliseconds) of the model run.
386
+ */
387
+ getElapsedTime(): number;
388
+ /**
389
+ * Store the elapsed time of the model run.
390
+ *
391
+ * @param elapsed The model run time, in milliseconds.
392
+ */
393
+ storeElapsedTime(elapsed: number): void;
394
+ }
395
+
396
+ /**
397
+ * An implementation of `RunModelParams` that copies the input and output arrays into a single,
398
+ * combined buffer. This implementation is designed to work with an asynchronous `ModelRunner`
399
+ * implementation because the buffer can be transferred to/from a Web Worker or Node.js worker
400
+ * thread without copying (if it is marked `Transferable`).
401
+ *
402
+ * @hidden This is not yet exposed in the public API; it is currently only used by
403
+ * the implementations of the `RunnableModel` interface.
404
+ */
405
+ declare class BufferedRunModelParams implements RunModelParams {
406
+ private readonly listing?;
407
+ /**
408
+ * The array that holds all input and output values. This is grown as needed. The memory
409
+ * layout of the buffer is as follows:
410
+ * header
411
+ * extras (holds elapsed time, etc)
412
+ * inputs
413
+ * outputs
414
+ * outputIndices
415
+ * lookups (data)
416
+ * lookupIndices
417
+ */
418
+ private encoded;
419
+ /**
420
+ * The header section of the `encoded` buffer. The header declares the byte offset and length
421
+ * (in elements) of each section of the buffer.
422
+ */
423
+ private readonly header;
424
+ /** The extras section of the `encoded` buffer (holds elapsed time, etc). */
425
+ private readonly extras;
426
+ /** The inputs section of the `encoded` buffer. */
427
+ private readonly inputs;
428
+ /** The outputs section of the `encoded` buffer. */
429
+ private readonly outputs;
430
+ /** The output indices section of the `encoded` buffer. */
431
+ private readonly outputIndices;
432
+ /** The lookup data section of the `encoded` buffer. */
433
+ private readonly lookups;
434
+ /** The lookup indices section of the `encoded` buffer. */
435
+ private readonly lookupIndices;
436
+ /**
437
+ * @param listing The model listing that is used to locate a variable that is referenced by
438
+ * name or identifier. If undefined, variables cannot be referenced by name or identifier,
439
+ * and can only be referenced using a valid `VarSpec`.
440
+ */
441
+ constructor(listing?: ModelListing);
442
+ /**
443
+ * Return the encoded buffer from this instance, which can be passed to `updateFromEncodedBuffer`.
444
+ */
445
+ getEncodedBuffer(): ArrayBuffer;
446
+ getInputs(): Float64Array | undefined;
447
+ copyInputs(array: Float64Array | undefined, create: (numElements: number) => Float64Array): void;
448
+ getOutputIndicesLength(): number;
449
+ getOutputIndices(): Int32Array | undefined;
450
+ copyOutputIndices(array: Int32Array | undefined, create: (numElements: number) => Int32Array): void;
451
+ getOutputsLength(): number;
452
+ getOutputs(): Float64Array | undefined;
453
+ getOutputsObject(): Outputs | undefined;
454
+ storeOutputs(array: Float64Array): void;
455
+ getLookups(): LookupDef[] | undefined;
456
+ getElapsedTime(): number;
457
+ storeElapsedTime(elapsed: number): void;
458
+ /**
459
+ * Copy the outputs buffer to the given `Outputs` instance. This should be called
460
+ * after the `runModel` call has completed so that the output values are copied from
461
+ * the internal buffer to the `Outputs` instance that was passed to `runModel`.
462
+ *
463
+ * @param outputs The `Outputs` instance into which the output values will be copied.
464
+ */
465
+ finalizeOutputs(outputs: Outputs): void;
466
+ /**
467
+ * Update this instance using the parameters that are passed to a `runModel` call.
468
+ *
469
+ * @param inputs The model input values (must be in the same order as in the spec file).
470
+ * @param outputs The structure into which the model outputs will be stored.
471
+ * @param options Additional options that influence the model run.
472
+ */
473
+ updateFromParams(inputs: number[] | InputValue[], outputs: Outputs, options?: RunModelOptions): void;
474
+ /**
475
+ * Update this instance using the values contained in the encoded buffer from another
476
+ * `BufferedRunModelParams` instance.
477
+ *
478
+ * @param buffer An encoded buffer returned by `getEncodedBuffer`.
479
+ */
480
+ updateFromEncodedBuffer(buffer: ArrayBuffer): void;
481
+ }
482
+
483
+ /**
484
+ * An implementation of `RunModelParams` that keeps references to the `inputs` and
485
+ * `outputs` parameters that are passed to the `runModel` function. This implementation
486
+ * is best used with a synchronous `ModelRunner`.
487
+ *
488
+ * @hidden This is not yet exposed in the public API; it is currently only used by
489
+ * the implementations of the `RunnableModel` interface.
490
+ */
491
+ declare class ReferencedRunModelParams implements RunModelParams {
492
+ private readonly listing?;
493
+ private inputs;
494
+ private outputs;
495
+ private outputsLengthInElements;
496
+ private outputIndicesLengthInElements;
497
+ private lookups;
498
+ /**
499
+ * @param listing The model listing that is used to locate a variable that is referenced by
500
+ * name or identifier. If undefined, variables cannot be referenced by name or identifier,
501
+ * and can only be referenced using a valid `VarSpec`.
502
+ */
503
+ constructor(listing?: ModelListing);
504
+ getInputs(): Float64Array | undefined;
505
+ copyInputs(array: Float64Array | undefined, create: (numElements: number) => Float64Array): void;
506
+ getOutputIndicesLength(): number;
507
+ getOutputIndices(): Int32Array | undefined;
508
+ copyOutputIndices(array: Int32Array | undefined, create: (numElements: number) => Int32Array): void;
509
+ getOutputsLength(): number;
510
+ getOutputs(): Float64Array | undefined;
511
+ getOutputsObject(): Outputs | undefined;
512
+ storeOutputs(array: Float64Array): void;
513
+ getLookups(): LookupDef[] | undefined;
514
+ getElapsedTime(): number;
515
+ storeElapsedTime(elapsed: number): void;
516
+ /**
517
+ * Update this instance using the parameters that are passed to a `runModel` call.
518
+ *
519
+ * @param inputs The model input values (must be in the same order as in the spec file).
520
+ * @param outputs The structure into which the model outputs will be stored.
521
+ * @param options Additional options that influence the model run.
522
+ */
523
+ updateFromParams(inputs: number[] | InputValue[], outputs: Outputs, options?: RunModelOptions): void;
524
+ }
525
+
526
+ /**
527
+ * This interface exposes the properties and functions that allow a `ModelRunner`
528
+ * implementation to run a model that was generated by the SDEverywhere transpiler.
529
+ * The `runModel` method will synchronously run the wrapped model with a provided
530
+ * set of input and output parameters.
531
+ *
532
+ * @hidden This is not yet exposed in the public API; it is currently only used by
533
+ * the internal implementations of this interface, and from the runtime-async package.
534
+ */
535
+ interface RunnableModel {
536
+ /** The start time for the model (aka `INITIAL TIME`). */
537
+ readonly startTime: number;
538
+ /** The end time for the model (aka `FINAL TIME`). */
539
+ readonly endTime: number;
540
+ /** The frequency with which output values are saved (aka `SAVEPER`). */
541
+ readonly saveFreq: number;
542
+ /** The number of save points for each output. */
543
+ readonly numSavePoints: number;
544
+ /** The output variable IDs for this model. */
545
+ readonly outputVarIds: OutputVarId[];
546
+ /**
547
+ * The model listing that is used to resolve variables. This can be undefined,
548
+ * in which case variables cannot be referenced by name or identifier, and can only
549
+ * be referenced using a valid `VarSpec`.
550
+ */
551
+ readonly modelListing?: any;
552
+ /**
553
+ * Run the model synchronously on the current thread.
554
+ *
555
+ * @param params The parameters that control the model run.
556
+ */
557
+ runModel(params: RunModelParams): void;
558
+ /**
559
+ * Terminate the runner by releasing underlying resources (e.g., the worker thread or
560
+ * Wasm module/buffers).
561
+ */
562
+ terminate(): void;
563
+ }
564
+
565
+ type JsModelLookupMode = 'interpolate' | 'forward' | 'backward';
566
+ /**
567
+ * @hidden This is not yet part of the public API; for internal use only.
568
+ */
569
+ declare class JsModelLookup {
570
+ private readonly n;
571
+ private readonly data;
572
+ private invertedData?;
573
+ private lastInput;
574
+ private lastHitIndex;
575
+ /**
576
+ * @param n The number of (x,y) pairs in the lookup.
577
+ * @param data The lookup data, as (x,y) pairs. The length of the array must be
578
+ * >= 2*n. Note that the data will be stored by reference, so if there is a chance
579
+ * that the array will be reused or modified by other code, be sure to pass in a
580
+ * copy of the array.
581
+ */
582
+ constructor(n: number, data: number[] | Float64Array);
583
+ getValueForX(x: number, mode: JsModelLookupMode): number;
584
+ getValueForY(y: number): number;
585
+ /**
586
+ * Interpolate the y value from the array of (x,y) pairs.
587
+ * NOTE: The x values are assumed to be monotonically increasing.
588
+ */
589
+ private getValue;
590
+ /**
591
+ * Return the most appropriate y value from the array of (x,y) pairs when
592
+ * this instance is used to provide inputs for the `GAME` function.
593
+ *
594
+ * NOTE: The x values are assumed to be monotonically increasing.
595
+ *
596
+ * This method is similar to `getValueForX` in concept, except that this one
597
+ * returns the provided `defaultValue` if the `time` parameter is earlier than
598
+ * the first data point in the lookup. Also, this method always uses the
599
+ * `backward` interpolation mode, meaning that it holds the "current" value
600
+ * constant instead of interpolating.
601
+ *
602
+ * @param time The time that is used to select the data point that has an
603
+ * `x` value less than or equal to the provided time.
604
+ * @param defaultValue The value that is returned if this lookup is empty (has
605
+ * no points) or if the provided time is earlier than the first data point.
606
+ */
607
+ getValueForGameTime(time: number, defaultValue: number): number;
608
+ /**
609
+ * Interpolate the y value from the array of (x,y) pairs.
610
+ * NOTE: The x values are assumed to be monotonically increasing.
611
+ *
612
+ * This method is similar to `getValue` in concept, but Vensim produces results for
613
+ * the `GET DATA BETWEEN TIMES` function that differ in unexpected ways from normal
614
+ * lookup behavior, so we implement it as a separate method here.
615
+ */
616
+ getValueBetweenTimes(input: number, mode: JsModelLookupMode): number;
617
+ }
618
+
619
+ /**
620
+ * Provides access to the minimal set of control parameters that are used in the
621
+ * implementation of certain model functions.
622
+ *
623
+ * @hidden This is not yet part of the public API; for internal use by generated
624
+ * `JsModel` implementations.
625
+ */
626
+ interface JsModelFunctionContext {
627
+ timeStep: number;
628
+ currentTime: number;
629
+ }
630
+ /**
631
+ * Exposes all the model function implementations that are called by a `JsModel` at runtime.
632
+ *
633
+ * @hidden This is not yet part of the public API; for internal use by generated
634
+ * `JsModel` implementations.
635
+ */
636
+ interface JsModelFunctions {
637
+ setContext(context: JsModelFunctionContext): void;
638
+ ABS(x: number): number;
639
+ ARCCOS(x: number): number;
640
+ ARCSIN(x: number): number;
641
+ ARCTAN(x: number): number;
642
+ COS(x: number): number;
643
+ EXP(x: number): number;
644
+ GAME(inputs: JsModelLookup, x: number): number;
645
+ INTEG(value: number, rate: number): number;
646
+ INTEGER(x: number): number;
647
+ LN(x: number): number;
648
+ MAX(x: number, y: number): number;
649
+ MIN(x: number, y: number): number;
650
+ MODULO(x: number, y: number): number;
651
+ POW(x: number, y: number): number;
652
+ POWER(x: number, y: number): number;
653
+ PULSE(start: number, width: number): number;
654
+ PULSE_TRAIN(start: number, width: number, interval: number, end: number): number;
655
+ QUANTUM(x: number, y: number): number;
656
+ RAMP(slope: number, startTime: number, endTime: number): number;
657
+ SIN(x: number): number;
658
+ SQRT(x: number): number;
659
+ STEP(height: number, stepTime: number): number;
660
+ TAN(x: number): number;
661
+ VECTOR_SORT_ORDER(vector: number[], size: number, direction: number): number[];
662
+ XIDZ(a: number, b: number, x: number): number;
663
+ ZIDZ(a: number, b: number): number;
664
+ createLookup(size: number, data: number[] | Float64Array): JsModelLookup;
665
+ LOOKUP(lookup: JsModelLookup, x: number): number;
666
+ LOOKUP_FORWARD(lookup: JsModelLookup, x: number): number;
667
+ LOOKUP_BACKWARD(lookup: JsModelLookup, x: number): number;
668
+ LOOKUP_INVERT(lookup: JsModelLookup, y: number): number;
669
+ WITH_LOOKUP(x: number, lookup: JsModelLookup): number;
670
+ GET_DATA_BETWEEN_TIMES(lookup: JsModelLookup, x: number, mode: number): number;
671
+ }
672
+ /**
673
+ * Returns a default implementation of the `JsModelFunctions` interface. If needed,
674
+ * you can provide a custom implementation of any exposed function by overriding
675
+ * (setting) a new function implementation on the returned instance.
676
+ *
677
+ * @hidden This is not yet part of the public API; for internal use by generated
678
+ * `JsModel` implementations.
679
+ */
680
+ declare function getJsModelFunctions(): JsModelFunctions;
681
+
682
+ /**
683
+ * An interface that exposes the functions of a JavaScript model generated by the
684
+ * SDEverywhere transpiler. This allows for running the model with a given set of
685
+ * input values, which will produce a set of output values.
686
+ *
687
+ * This is a low-level interface that most developers will not need to interact
688
+ * with directly. Developers should instead use the `ModelRunner` interface to
689
+ * interact with a generated model. Use `createSynchronousModelRunner` to create
690
+ * a synchronous `ModelRunner`, or `spawnAsyncModelRunner` to create an asynchronous
691
+ * `ModelRunner`.
692
+ *
693
+ * @beta NOTE: The properties and methods exposed in this interface are meant for
694
+ * internal use only, and are subject to change in coordination with the code
695
+ * generated by the `@sdeverywhere/compile` package.
696
+ */
697
+ interface JsModel {
698
+ readonly kind: 'js';
699
+ readonly outputVarIds: string[];
700
+ readonly outputVarNames: string[];
701
+ readonly modelListing?: any;
702
+ /** @hidden */
703
+ getInitialTime(): number;
704
+ /** @hidden */
705
+ getFinalTime(): number;
706
+ /** @hidden */
707
+ getTimeStep(): number;
708
+ /** @hidden */
709
+ getSaveFreq(): number;
710
+ /** @hidden */
711
+ getModelFunctions(): JsModelFunctions;
712
+ /** @hidden */
713
+ setModelFunctions(functions: JsModelFunctions): void;
714
+ /** @hidden */
715
+ setTime(time: number): void;
716
+ /** @hidden */
717
+ setInputs(inputValue: (index: number) => number): void;
718
+ /** @hidden */
719
+ setLookup(varSpec: VarSpec, points: Float64Array): void;
720
+ /** @hidden */
721
+ storeOutputs(storeValue: (value: number) => void): void;
722
+ /** @hidden */
723
+ storeOutput(varSpec: VarSpec, storeValue: (value: number) => void): void;
724
+ /** @hidden */
725
+ initConstants(): void;
726
+ /** @hidden */
727
+ initLevels(): void;
728
+ /** @hidden */
729
+ evalAux(): void;
730
+ /** @hidden */
731
+ evalLevels(): void;
732
+ }
733
+ /**
734
+ * Create a `RunnableModel` from a given `JsModel` that was generated by the
735
+ * SDEverywhere transpiler.
736
+ *
737
+ * @hidden This is not part of the public API; only the top-level `createRunnableModel`
738
+ * function is exposed in the public API.
739
+ */
740
+ declare function initJsModel(model: JsModel): RunnableModel;
741
+
742
+ /**
743
+ * Run the given model synchronously and log the output values to the console in
744
+ * TSV (tab-separated values) format.
745
+ *
746
+ * @hidden This is mainly intended for use in implementing the `sde exec` command,
747
+ * so isn't exposed in the public API at this time.
748
+ *
749
+ * @param jsModel A `JsModel` instance.
750
+ */
751
+ declare function execJsModel(jsModel: JsModel): void;
752
+
753
+ /**
754
+ * @hidden This type is not part of the public API; it is exposed only for use in
755
+ * tests in the runtime-async package.
756
+ */
757
+ type OnEvalAux = (vars: Map<VarId, number>, lookups: Map<VarId, JsModelLookup>) => void;
758
+ /**
759
+ * @hidden This type is not part of the public API; it is exposed only for use in
760
+ * tests in the runtime-async package.
761
+ */
762
+ declare class MockJsModel implements JsModel {
763
+ readonly kind = "js";
764
+ readonly outputVarIds: OutputVarId[];
765
+ readonly outputVarNames: OutputVarId[];
766
+ readonly modelListing?: any;
767
+ private readonly internalListing?;
768
+ private readonly initialTime;
769
+ private readonly finalTime;
770
+ private readonly vars;
771
+ private readonly lookups;
772
+ private fns;
773
+ readonly onEvalAux: OnEvalAux;
774
+ constructor(options: {
775
+ initialTime: number;
776
+ finalTime: number;
777
+ outputVarIds: OutputVarId[];
778
+ listingJson?: string;
779
+ onEvalAux: OnEvalAux;
780
+ });
781
+ varIdForSpec(varSpec: VarSpec): VarId;
782
+ getInitialTime(): number;
783
+ getFinalTime(): number;
784
+ getTimeStep(): number;
785
+ getSaveFreq(): number;
786
+ getModelFunctions(): JsModelFunctions;
787
+ setModelFunctions(fns: JsModelFunctions): void;
788
+ setTime(time: number): void;
789
+ setInputs(): void;
790
+ setLookup(varSpec: VarSpec, points: Float64Array): void;
791
+ storeOutputs(storeValue: (value: number) => void): void;
792
+ storeOutput(varSpec: VarSpec, storeValue: (value: number) => void): void;
793
+ initConstants(): void;
794
+ initLevels(): void;
795
+ evalAux(): void;
796
+ evalLevels(): void;
797
+ }
798
+
799
+ /**
800
+ * Type declaration for a WebAssembly module wrapper produced
801
+ * by the Emscripten compiler. This only declares the minimal
802
+ * set of fields needed by the SDEverywhere runtime.
803
+ */
804
+ interface WasmModule {
805
+ readonly kind: 'wasm';
806
+ readonly outputVarIds: OutputVarId[];
807
+ readonly modelListing?: any;
808
+ /** @hidden */
809
+ cwrap: (fname: string, rettype: string, argtypes: string[]) => any;
810
+ /** @hidden */
811
+ _malloc: (numBytes: number) => number;
812
+ /** @hidden */
813
+ _free: (byteOffset: number) => void;
814
+ /** @hidden */
815
+ HEAP32: Int32Array;
816
+ /** @hidden */
817
+ HEAPF64: Float64Array;
818
+ }
819
+
820
+ /**
821
+ * Initialize the wasm model.
822
+ *
823
+ * @hidden This is not part of the public API; only the top-level `createRunnableModel`
824
+ * function is exposed in the public API.
825
+ *
826
+ * @param wasmModule The `WasmModule` that wraps the `wasm` binary.
827
+ * @return The initialized `WasmModel` instance.
828
+ */
829
+ declare function initWasmModel(wasmModule: WasmModule): RunnableModel;
830
+
831
+ /**
832
+ * @hidden This type is not part of the public API; it is exposed only for use in
833
+ * tests in the runtime-async package.
834
+ */
835
+ type OnRunModel = (inputs: Float64Array, outputs: Float64Array, lookups: Map<VarId, JsModelLookup>, outputIndices?: Int32Array) => void;
836
+ /**
837
+ * @hidden This type is not part of the public API; it is exposed only for use in
838
+ * tests in the runtime-async package.
839
+ */
840
+ declare class MockWasmModule implements WasmModule {
841
+ readonly kind = "wasm";
842
+ readonly outputVarIds: OutputVarId[];
843
+ readonly modelListing?: any;
844
+ private readonly internalListing?;
845
+ private readonly initialTime;
846
+ private readonly finalTime;
847
+ private readonly heap;
848
+ readonly HEAP32: Int32Array;
849
+ readonly HEAPF64: Float64Array;
850
+ private mallocOffset;
851
+ private readonly allocs;
852
+ private readonly lookups;
853
+ readonly onRunModel: OnRunModel;
854
+ constructor(options: {
855
+ initialTime: number;
856
+ finalTime: number;
857
+ outputVarIds: string[];
858
+ listingJson?: string;
859
+ onRunModel: OnRunModel;
860
+ });
861
+ varIdForSpec(varSpec: VarSpec): VarId;
862
+ cwrap(fname: string): (varIndex: number, _subIndicesAddress: number, pointsAddress: number, numPoints: number) => void;
863
+ _malloc(lengthInBytes: number): number;
864
+ _free(): void;
865
+ private getHeapView;
866
+ }
867
+
283
868
  /**
284
869
  * Abstraction that allows for running the wasm model on the JS thread
285
870
  * or asynchronously (e.g. in a Web Worker), depending on the implementation.
@@ -297,63 +882,45 @@ interface ModelRunner {
297
882
  *
298
883
  * @param inputs The model input values (must be in the same order as in the spec file).
299
884
  * @param outputs The structure into which the model outputs will be stored.
885
+ * @param options Additional options that influence the model run.
300
886
  * @return A promise that resolves with the outputs when the model run is complete.
301
887
  */
302
- runModel(inputs: InputValue[], outputs: Outputs): Promise<Outputs>;
888
+ runModel(inputs: number[] | InputValue[], outputs: Outputs, options?: RunModelOptions): Promise<Outputs>;
303
889
  /**
304
890
  * Run the model synchronously.
305
891
  *
306
892
  * @param inputs The model input values (must be in the same order as in the spec file).
307
893
  * @param outputs The structure into which the model outputs will be stored.
894
+ * @param options Additional options that influence the model run.
308
895
  * @return The outputs of the run.
309
896
  *
310
897
  * @hidden This is only intended for internal use; some implementations may not support
311
898
  * running the model synchronously, in which case this will be undefined.
312
899
  */
313
- runModelSync?(inputs: InputValue[], outputs: Outputs): Outputs;
900
+ runModelSync?(inputs: number[] | InputValue[], outputs: Outputs, options?: RunModelOptions): Outputs;
314
901
  /**
315
902
  * Terminate the runner by releasing underlying resources (e.g., the worker thread or
316
903
  * Wasm module/buffers).
317
904
  */
318
905
  terminate(): Promise<void>;
319
906
  }
320
- /**
321
- * Create a `ModelRunner` that runs the given wasm model on the JS thread.
322
- *
323
- * @param wasmResult The result of initializing the wasm model.
324
- */
325
- declare function createWasmModelRunner(wasmResult: WasmModelInitResult): ModelRunner;
326
-
327
- /**
328
- * @hidden This is not yet part of the public API; it is exposed here for use
329
- * in experimental testing tools.
330
- */
331
- declare class ModelListing {
332
- readonly varSpecs: Map<OutputVarId, OutputVarSpec>;
333
- constructor(modelJsonString: string);
334
- /**
335
- * Create a new `Outputs` instance that uses the same start/end years as the given "normal"
336
- * `Outputs` instance but is prepared for reading the specified internal variables from the model.
337
- *
338
- * @param normalOutputs The `Outputs` that is used to access normal output variables from the model.
339
- * @param varIds The variable IDs to include with the new `Outputs` instance.
340
- */
341
- deriveOutputs(normalOutputs: Outputs, varIds: OutputVarId[]): Outputs;
342
- }
343
907
 
908
+ /** Union of model types that are generated by the SDEverywhere transpiler/builder. */
909
+ type GeneratedModel = JsModel | WasmModule;
344
910
  /**
345
- * Return a timestamp that can be passed to `perfElapsed` for calculating the elapsed
346
- * time of an operation.
911
+ * Create a `RunnableModel` from a given `JsModel` or `WasmModule` that was generated by the
912
+ * SDEverywhere transpiler/builder.
347
913
  *
348
- * @hidden This is not part of the public API; exposed only for use in performance testing.
914
+ * @hidden This is not yet part of the public API; it is only exposed for use by
915
+ * the runtime-async package.
349
916
  */
350
- declare function perfNow(): unknown;
917
+ declare function createRunnableModel(generatedModel: GeneratedModel): RunnableModel;
351
918
  /**
352
- * Return the elapsed time between the given timestamp (created by `perfNow`) and now.
919
+ * Create a `ModelRunner` that runs a generated model on the JS thread.
353
920
  *
354
- * @hidden This is not part of the public API; exposed only for use in performance testing.
921
+ * @param generatedModel A `JsModel` or `WasmModule` generated by the SDEverywhere transpiler.
355
922
  */
356
- declare function perfElapsed(t0: unknown): number;
923
+ declare function createSynchronousModelRunner(generatedModel: GeneratedModel): ModelRunner;
357
924
 
358
925
  /**
359
926
  * A high-level interface that schedules running of the underlying `WasmModel`.
@@ -395,4 +962,4 @@ declare class ModelScheduler {
395
962
  private runWasmModelNow;
396
963
  }
397
964
 
398
- export { InputCallbacks, InputValue, InputVarId, ModelListing, ModelRunner, ModelScheduler, OutputVarId, OutputVarSpec, Outputs, ParseError, Point, Series, WasmBuffer, WasmModel, WasmModelInitResult, WasmModule, createFloat64WasmBuffer, createInputValue, createInt32WasmBuffer, createWasmModelRunner, initWasmModelAndBuffers, perfElapsed, perfNow, updateOutputIndices };
965
+ export { BufferedRunModelParams, GeneratedModel, InputCallbacks, InputValue, InputVarId, JsModel, JsModelFunctionContext, JsModelFunctions, LookupDef, MockJsModel, MockWasmModule, ModelListing, ModelListingSpecs, ModelRunner, ModelScheduler, OnEvalAux, OnRunModel, OutputVarId, Outputs, ParseError, Point, ReferencedRunModelParams, RunModelOptions, RunModelParams, RunnableModel, Series, VarId, VarName, VarRef, VarSpec, WasmModule, createInputValue, createLookupDef, createRunnableModel, createSynchronousModelRunner, decodeLookups, encodeLookups, encodeVarIndices, execJsModel, getEncodedLookupBufferLengths, getEncodedVarIndicesLength, getJsModelFunctions, initJsModel, initWasmModel };