@sdeverywhere/runtime 0.2.7 → 0.2.9

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 CHANGED
@@ -150,7 +150,7 @@ The `emcc` command line options should be similar to the following:
150
150
 
151
151
  ```
152
152
  $ emcc \
153
- build/<mymodel>.c build/macros.c build/model.c build/vensim.c \
153
+ build/<mymodel>.c build/macros.c build/model.c build/vensim.c build/allocation.c \
154
154
  -Ibuild -o ./output/<mymodel>.js -Wall -Os \
155
155
  -s STRICT=1 -s MALLOC=emmalloc -s FILESYSTEM=0 -s MODULARIZE=1 \
156
156
  -s EXPORTED_FUNCTIONS="['_malloc','_free','_getInitialTime','_getFinalTime','_getSaveper','_setLookup','_runModelWithBuffers']" \
package/dist/index.cjs CHANGED
@@ -51,8 +51,8 @@ var __async = (__this, __arguments, generator) => {
51
51
  };
52
52
 
53
53
  // src/index.ts
54
- var src_exports = {};
55
- __export(src_exports, {
54
+ var index_exports = {};
55
+ __export(index_exports, {
56
56
  BufferedRunModelParams: () => BufferedRunModelParams,
57
57
  MockJsModel: () => MockJsModel,
58
58
  MockWasmModule: () => MockWasmModule,
@@ -62,14 +62,18 @@ __export(src_exports, {
62
62
  Outputs: () => Outputs,
63
63
  ReferencedRunModelParams: () => ReferencedRunModelParams,
64
64
  Series: () => Series,
65
+ createConstantDef: () => createConstantDef,
65
66
  createInputValue: () => createInputValue,
66
67
  createLookupDef: () => createLookupDef,
67
68
  createRunnableModel: () => createRunnableModel,
68
69
  createSynchronousModelRunner: () => createSynchronousModelRunner,
70
+ decodeConstants: () => decodeConstants,
69
71
  decodeLookups: () => decodeLookups,
72
+ encodeConstants: () => encodeConstants,
70
73
  encodeLookups: () => encodeLookups,
71
74
  encodeVarIndices: () => encodeVarIndices,
72
75
  execJsModel: () => execJsModel,
76
+ getEncodedConstantBufferLengths: () => getEncodedConstantBufferLengths,
73
77
  getEncodedLookupBufferLengths: () => getEncodedLookupBufferLengths,
74
78
  getEncodedVarIndicesLength: () => getEncodedVarIndicesLength,
75
79
  getJsModelFunctions: () => getJsModelFunctions,
@@ -78,7 +82,7 @@ __export(src_exports, {
78
82
  perfElapsed: () => perfElapsed,
79
83
  perfNow: () => perfNow
80
84
  });
81
- module.exports = __toCommonJS(src_exports);
85
+ module.exports = __toCommonJS(index_exports);
82
86
 
83
87
  // src/_shared/inputs.ts
84
88
  function createInputValue(varId, defaultValue, initialValue) {
@@ -251,6 +255,66 @@ function encodeVarIndices(varSpecs, indicesArray) {
251
255
  }
252
256
  }
253
257
  }
258
+ function getEncodedConstantBufferLengths(constantDefs) {
259
+ var _a;
260
+ let constantIndicesLength = 1;
261
+ let constantsLength = 0;
262
+ for (const constantDef of constantDefs) {
263
+ const varSpec = constantDef.varRef.varSpec;
264
+ if (varSpec === void 0) {
265
+ throw new Error("Cannot compute constant buffer lengths until all constant var specs are defined");
266
+ }
267
+ constantIndicesLength += 2;
268
+ const subCount = ((_a = varSpec.subscriptIndices) == null ? void 0 : _a.length) || 0;
269
+ constantIndicesLength += subCount;
270
+ constantsLength += 1;
271
+ }
272
+ return {
273
+ constantIndicesLength,
274
+ constantsLength
275
+ };
276
+ }
277
+ function encodeConstants(constantDefs, constantIndicesArray, constantsArray) {
278
+ let ci = 0;
279
+ constantIndicesArray[ci++] = constantDefs.length;
280
+ let constantDataOffset = 0;
281
+ for (const constantDef of constantDefs) {
282
+ const varSpec = constantDef.varRef.varSpec;
283
+ constantIndicesArray[ci++] = varSpec.varIndex;
284
+ const subs = varSpec.subscriptIndices;
285
+ const subCount = (subs == null ? void 0 : subs.length) || 0;
286
+ constantIndicesArray[ci++] = subCount;
287
+ for (let i = 0; i < subCount; i++) {
288
+ constantIndicesArray[ci++] = subs[i];
289
+ }
290
+ constantsArray[constantDataOffset++] = constantDef.value;
291
+ }
292
+ }
293
+ function decodeConstants(constantIndicesArray, constantsArray) {
294
+ const constantDefs = [];
295
+ let ci = 0;
296
+ const constantCount = constantIndicesArray[ci++];
297
+ for (let i = 0; i < constantCount; i++) {
298
+ const varIndex = constantIndicesArray[ci++];
299
+ const subCount = constantIndicesArray[ci++];
300
+ const subscriptIndices = subCount > 0 ? Array(subCount) : void 0;
301
+ for (let subIndex = 0; subIndex < subCount; subIndex++) {
302
+ subscriptIndices[subIndex] = constantIndicesArray[ci++];
303
+ }
304
+ const varSpec = {
305
+ varIndex,
306
+ subscriptIndices
307
+ };
308
+ const value = constantsArray[i];
309
+ constantDefs.push({
310
+ varRef: {
311
+ varSpec
312
+ },
313
+ value
314
+ });
315
+ }
316
+ return constantDefs;
317
+ }
254
318
  function getEncodedLookupBufferLengths(lookupDefs) {
255
319
  var _a, _b;
256
320
  let lookupIndicesLength = 1;
@@ -332,6 +396,14 @@ function decodeLookups(lookupIndicesArray, lookupsArray) {
332
396
  return lookupDefs;
333
397
  }
334
398
 
399
+ // src/_shared/constant-def.ts
400
+ function createConstantDef(varRef, value) {
401
+ return {
402
+ varRef,
403
+ value
404
+ };
405
+ }
406
+
335
407
  // src/_shared/lookup-def.ts
336
408
  function createLookupDef(varRef, points) {
337
409
  let flatPoints;
@@ -502,7 +574,7 @@ function resolveVarRef(listing, varRef, varKind) {
502
574
  }
503
575
 
504
576
  // src/runnable-model/buffered-run-model-params.ts
505
- var headerLengthInElements = 16;
577
+ var headerLengthInElements = 20;
506
578
  var extrasLengthInElements = 1;
507
579
  var Int32Section = class {
508
580
  constructor() {
@@ -547,6 +619,10 @@ var BufferedRunModelParams = class {
547
619
  this.outputs = new Float64Section();
548
620
  /** The output indices section of the `encoded` buffer. */
549
621
  this.outputIndices = new Int32Section();
622
+ /** The constant values section of the `encoded` buffer. */
623
+ this.constants = new Float64Section();
624
+ /** The constant indices section of the `encoded` buffer. */
625
+ this.constantIndices = new Int32Section();
550
626
  /** The lookup data section of the `encoded` buffer. */
551
627
  this.lookups = new Float64Section();
552
628
  /** The lookup indices section of the `encoded` buffer. */
@@ -614,6 +690,13 @@ var BufferedRunModelParams = class {
614
690
  }
615
691
  }
616
692
  // from RunModelParams interface
693
+ getConstants() {
694
+ if (this.constantIndices.lengthInElements === 0) {
695
+ return void 0;
696
+ }
697
+ return decodeConstants(this.constantIndices.view, this.constants.view);
698
+ }
699
+ // from RunModelParams interface
617
700
  getLookups() {
618
701
  if (this.lookupIndices.lengthInElements === 0) {
619
702
  return void 0;
@@ -658,6 +741,19 @@ var BufferedRunModelParams = class {
658
741
  } else {
659
742
  outputIndicesLengthInElements = 0;
660
743
  }
744
+ let constantsLengthInElements;
745
+ let constantIndicesLengthInElements;
746
+ if ((options == null ? void 0 : options.constants) !== void 0 && options.constants.length > 0) {
747
+ for (const constantDef of options.constants) {
748
+ resolveVarRef(this.listing, constantDef.varRef, "constant");
749
+ }
750
+ const encodedLengths = getEncodedConstantBufferLengths(options.constants);
751
+ constantsLengthInElements = encodedLengths.constantsLength;
752
+ constantIndicesLengthInElements = encodedLengths.constantIndicesLength;
753
+ } else {
754
+ constantsLengthInElements = 0;
755
+ constantIndicesLengthInElements = 0;
756
+ }
661
757
  let lookupsLengthInElements;
662
758
  let lookupIndicesLengthInElements;
663
759
  if ((options == null ? void 0 : options.lookups) !== void 0 && options.lookups.length > 0) {
@@ -685,6 +781,8 @@ var BufferedRunModelParams = class {
685
781
  const inputsOffsetInBytes = section("float64", inputsLengthInElements);
686
782
  const outputsOffsetInBytes = section("float64", outputsLengthInElements);
687
783
  const outputIndicesOffsetInBytes = section("int32", outputIndicesLengthInElements);
784
+ const constantsOffsetInBytes = section("float64", constantsLengthInElements);
785
+ const constantIndicesOffsetInBytes = section("int32", constantIndicesLengthInElements);
688
786
  const lookupsOffsetInBytes = section("float64", lookupsLengthInElements);
689
787
  const lookupIndicesOffsetInBytes = section("int32", lookupIndicesLengthInElements);
690
788
  const requiredLengthInBytes = byteOffset;
@@ -703,6 +801,10 @@ var BufferedRunModelParams = class {
703
801
  headerView[headerIndex++] = outputsLengthInElements;
704
802
  headerView[headerIndex++] = outputIndicesOffsetInBytes;
705
803
  headerView[headerIndex++] = outputIndicesLengthInElements;
804
+ headerView[headerIndex++] = constantsOffsetInBytes;
805
+ headerView[headerIndex++] = constantsLengthInElements;
806
+ headerView[headerIndex++] = constantIndicesOffsetInBytes;
807
+ headerView[headerIndex++] = constantIndicesLengthInElements;
706
808
  headerView[headerIndex++] = lookupsOffsetInBytes;
707
809
  headerView[headerIndex++] = lookupsLengthInElements;
708
810
  headerView[headerIndex++] = lookupIndicesOffsetInBytes;
@@ -711,6 +813,8 @@ var BufferedRunModelParams = class {
711
813
  this.extras.update(this.encoded, extrasOffsetInBytes, extrasLengthInElements);
712
814
  this.outputs.update(this.encoded, outputsOffsetInBytes, outputsLengthInElements);
713
815
  this.outputIndices.update(this.encoded, outputIndicesOffsetInBytes, outputIndicesLengthInElements);
816
+ this.constants.update(this.encoded, constantsOffsetInBytes, constantsLengthInElements);
817
+ this.constantIndices.update(this.encoded, constantIndicesOffsetInBytes, constantIndicesLengthInElements);
714
818
  this.lookups.update(this.encoded, lookupsOffsetInBytes, lookupsLengthInElements);
715
819
  this.lookupIndices.update(this.encoded, lookupIndicesOffsetInBytes, lookupIndicesLengthInElements);
716
820
  const inputsView = this.inputs.view;
@@ -725,6 +829,9 @@ var BufferedRunModelParams = class {
725
829
  if (this.outputIndices.view) {
726
830
  encodeVarIndices(outputVarSpecs, this.outputIndices.view);
727
831
  }
832
+ if (constantIndicesLengthInElements > 0) {
833
+ encodeConstants(options.constants, this.constantIndices.view, this.constants.view);
834
+ }
728
835
  if (lookupIndicesLengthInElements > 0) {
729
836
  encodeLookups(options.lookups, this.lookupIndices.view, this.lookups.view);
730
837
  }
@@ -753,6 +860,10 @@ var BufferedRunModelParams = class {
753
860
  const outputsLengthInElements = headerView[headerIndex++];
754
861
  const outputIndicesOffsetInBytes = headerView[headerIndex++];
755
862
  const outputIndicesLengthInElements = headerView[headerIndex++];
863
+ const constantsOffsetInBytes = headerView[headerIndex++];
864
+ const constantsLengthInElements = headerView[headerIndex++];
865
+ const constantIndicesOffsetInBytes = headerView[headerIndex++];
866
+ const constantIndicesLengthInElements = headerView[headerIndex++];
756
867
  const lookupsOffsetInBytes = headerView[headerIndex++];
757
868
  const lookupsLengthInElements = headerView[headerIndex++];
758
869
  const lookupIndicesOffsetInBytes = headerView[headerIndex++];
@@ -761,9 +872,11 @@ var BufferedRunModelParams = class {
761
872
  const inputsLengthInBytes = inputsLengthInElements * Float64Array.BYTES_PER_ELEMENT;
762
873
  const outputsLengthInBytes = outputsLengthInElements * Float64Array.BYTES_PER_ELEMENT;
763
874
  const outputIndicesLengthInBytes = outputIndicesLengthInElements * Int32Array.BYTES_PER_ELEMENT;
875
+ const constantsLengthInBytes = constantsLengthInElements * Float64Array.BYTES_PER_ELEMENT;
876
+ const constantIndicesLengthInBytes = constantIndicesLengthInElements * Int32Array.BYTES_PER_ELEMENT;
764
877
  const lookupsLengthInBytes = lookupsLengthInElements * Float64Array.BYTES_PER_ELEMENT;
765
878
  const lookupIndicesLengthInBytes = lookupIndicesLengthInElements * Int32Array.BYTES_PER_ELEMENT;
766
- const requiredLengthInBytes = headerLengthInBytes + extrasLengthInBytes + inputsLengthInBytes + outputsLengthInBytes + outputIndicesLengthInBytes + lookupsLengthInBytes + lookupIndicesLengthInBytes;
879
+ const requiredLengthInBytes = headerLengthInBytes + extrasLengthInBytes + inputsLengthInBytes + outputsLengthInBytes + outputIndicesLengthInBytes + constantsLengthInBytes + constantIndicesLengthInBytes + lookupsLengthInBytes + lookupIndicesLengthInBytes;
767
880
  if (buffer.byteLength < requiredLengthInBytes) {
768
881
  throw new Error("Buffer must be long enough to contain sections declared in header");
769
882
  }
@@ -771,6 +884,8 @@ var BufferedRunModelParams = class {
771
884
  this.inputs.update(this.encoded, inputsOffsetInBytes, inputsLengthInElements);
772
885
  this.outputs.update(this.encoded, outputsOffsetInBytes, outputsLengthInElements);
773
886
  this.outputIndices.update(this.encoded, outputIndicesOffsetInBytes, outputIndicesLengthInElements);
887
+ this.constants.update(this.encoded, constantsOffsetInBytes, constantsLengthInElements);
888
+ this.constantIndices.update(this.encoded, constantIndicesOffsetInBytes, constantIndicesLengthInElements);
774
889
  this.lookups.update(this.encoded, lookupsOffsetInBytes, lookupsLengthInElements);
775
890
  this.lookupIndices.update(this.encoded, lookupIndicesOffsetInBytes, lookupIndicesLengthInElements);
776
891
  }
@@ -847,6 +962,14 @@ var ReferencedRunModelParams = class {
847
962
  }
848
963
  }
849
964
  // from RunModelParams interface
965
+ getConstants() {
966
+ if (this.constants !== void 0 && this.constants.length > 0) {
967
+ return this.constants;
968
+ } else {
969
+ return void 0;
970
+ }
971
+ }
972
+ // from RunModelParams interface
850
973
  getLookups() {
851
974
  if (this.lookups !== void 0 && this.lookups.length > 0) {
852
975
  return this.lookups;
@@ -876,7 +999,13 @@ var ReferencedRunModelParams = class {
876
999
  this.inputs = inputs;
877
1000
  this.outputs = outputs;
878
1001
  this.outputsLengthInElements = outputs.varIds.length * outputs.seriesLength;
1002
+ this.constants = options == null ? void 0 : options.constants;
879
1003
  this.lookups = options == null ? void 0 : options.lookups;
1004
+ if (this.constants) {
1005
+ for (const constantDef of this.constants) {
1006
+ resolveVarRef(this.listing, constantDef.varRef, "constant");
1007
+ }
1008
+ }
880
1009
  if (this.lookups) {
881
1010
  for (const lookupDef of this.lookups) {
882
1011
  resolveVarRef(this.listing, lookupDef.varRef, "lookup");
@@ -1116,6 +1245,8 @@ function getJsModelFunctions() {
1116
1245
  let ctx;
1117
1246
  const cachedVectors = /* @__PURE__ */ new Map();
1118
1247
  const cachedSortVectors = /* @__PURE__ */ new Map();
1248
+ const cachedInvertWorkMatrices = /* @__PURE__ */ new Map();
1249
+ const cachedInvertResultMatrices = /* @__PURE__ */ new Map();
1119
1250
  return {
1120
1251
  setContext(context) {
1121
1252
  ctx = context;
@@ -1150,6 +1281,74 @@ function getJsModelFunctions() {
1150
1281
  INTEGER(x) {
1151
1282
  return Math.trunc(x);
1152
1283
  },
1284
+ INVERT_MATRIX(matrix, n) {
1285
+ let work = cachedInvertWorkMatrices.get(n);
1286
+ if (work === void 0) {
1287
+ work = Array(n);
1288
+ for (let i = 0; i < n; i++) {
1289
+ work[i] = Array(2 * n);
1290
+ }
1291
+ cachedInvertWorkMatrices.set(n, work);
1292
+ }
1293
+ let result = cachedInvertResultMatrices.get(n);
1294
+ if (result === void 0) {
1295
+ result = Array(n);
1296
+ for (let i = 0; i < n; i++) {
1297
+ result[i] = Array(n);
1298
+ }
1299
+ cachedInvertResultMatrices.set(n, result);
1300
+ }
1301
+ for (let i = 0; i < n; i++) {
1302
+ for (let j = 0; j < n; j++) {
1303
+ work[i][j] = matrix[i][j];
1304
+ work[i][n + j] = i === j ? 1 : 0;
1305
+ }
1306
+ }
1307
+ for (let k = 0; k < n; k++) {
1308
+ let pivot = k;
1309
+ let max = Math.abs(work[k][k]);
1310
+ for (let i = k + 1; i < n; i++) {
1311
+ const v = Math.abs(work[i][k]);
1312
+ if (v > max) {
1313
+ max = v;
1314
+ pivot = i;
1315
+ }
1316
+ }
1317
+ if (max === 0) {
1318
+ for (let i = 0; i < n; i++) {
1319
+ for (let j = 0; j < n; j++) {
1320
+ result[i][j] = _NA_;
1321
+ }
1322
+ }
1323
+ return result;
1324
+ }
1325
+ if (pivot !== k) {
1326
+ const tmpRow = work[k];
1327
+ work[k] = work[pivot];
1328
+ work[pivot] = tmpRow;
1329
+ }
1330
+ const p = work[k][k];
1331
+ for (let j = 0; j < 2 * n; j++) {
1332
+ work[k][j] /= p;
1333
+ }
1334
+ for (let i = 0; i < n; i++) {
1335
+ if (i !== k) {
1336
+ const f = work[i][k];
1337
+ if (f !== 0) {
1338
+ for (let j = 0; j < 2 * n; j++) {
1339
+ work[i][j] -= f * work[k][j];
1340
+ }
1341
+ }
1342
+ }
1343
+ }
1344
+ }
1345
+ for (let i = 0; i < n; i++) {
1346
+ for (let j = 0; j < n; j++) {
1347
+ result[i][j] = work[i][n + j];
1348
+ }
1349
+ }
1350
+ return result;
1351
+ },
1153
1352
  LN(x) {
1154
1353
  return Math.log(x);
1155
1354
  },
@@ -1356,6 +1555,7 @@ var BaseRunnableModel = class {
1356
1555
  const t0 = perfNow();
1357
1556
  (_a = this.onRunModel) == null ? void 0 : _a.call(this, inputsArray, outputsArray, {
1358
1557
  outputIndices: outputIndicesArray,
1558
+ constants: params.getConstants(),
1359
1559
  lookups: params.getLookups()
1360
1560
  });
1361
1561
  const elapsed = perfElapsed(t0);
@@ -1397,13 +1597,14 @@ function initJsModel(model) {
1397
1597
  inputs,
1398
1598
  outputs,
1399
1599
  options == null ? void 0 : options.outputIndices,
1600
+ options == null ? void 0 : options.constants,
1400
1601
  options == null ? void 0 : options.lookups,
1401
1602
  void 0
1402
1603
  );
1403
1604
  }
1404
1605
  });
1405
1606
  }
1406
- function runJsModel(model, initialTime, finalTime, timeStep, saveFreq, numSavePoints, inputs, outputs, outputIndices, lookups, stopAfterTime) {
1607
+ function runJsModel(model, initialTime, finalTime, timeStep, saveFreq, numSavePoints, inputs, outputs, outputIndices, constants, lookups, stopAfterTime) {
1407
1608
  let time = initialTime;
1408
1609
  model.setTime(time);
1409
1610
  const fnContext = {
@@ -1412,6 +1613,11 @@ function runJsModel(model, initialTime, finalTime, timeStep, saveFreq, numSavePo
1412
1613
  };
1413
1614
  model.getModelFunctions().setContext(fnContext);
1414
1615
  model.initConstants();
1616
+ if (constants !== void 0) {
1617
+ for (const constantDef of constants) {
1618
+ model.setConstant(constantDef.varRef.varSpec, constantDef.value);
1619
+ }
1620
+ }
1415
1621
  if (lookups !== void 0) {
1416
1622
  for (const lookupDef of lookups) {
1417
1623
  model.setLookup(lookupDef.varRef.varSpec, lookupDef.points);
@@ -1498,6 +1704,7 @@ var MockJsModel = class {
1498
1704
  // from JsModel interface
1499
1705
  this.kind = "js";
1500
1706
  this.vars = /* @__PURE__ */ new Map();
1707
+ this.constants = /* @__PURE__ */ new Map();
1501
1708
  this.lookups = /* @__PURE__ */ new Map();
1502
1709
  this.outputVarIds = options.outputVarIds;
1503
1710
  this.outputVarNames = options.outputVarIds;
@@ -1550,6 +1757,14 @@ var MockJsModel = class {
1550
1757
  setInputs() {
1551
1758
  }
1552
1759
  // from JsModel interface
1760
+ setConstant(varSpec, value) {
1761
+ const varId = this.varIdForSpec(varSpec);
1762
+ if (varId === void 0) {
1763
+ throw new Error(`No constant variable found for spec ${varSpec}`);
1764
+ }
1765
+ this.constants.set(varId, value);
1766
+ }
1767
+ // from JsModel interface
1553
1768
  setLookup(varSpec, points) {
1554
1769
  const varId = this.varIdForSpec(varSpec);
1555
1770
  if (varId === void 0) {
@@ -1574,6 +1789,7 @@ var MockJsModel = class {
1574
1789
  }
1575
1790
  // from JsModel interface
1576
1791
  initConstants() {
1792
+ this.constants.clear();
1577
1793
  }
1578
1794
  // from JsModel interface
1579
1795
  initLevels() {
@@ -1581,7 +1797,7 @@ var MockJsModel = class {
1581
1797
  // from JsModel interface
1582
1798
  evalAux() {
1583
1799
  var _a;
1584
- (_a = this.onEvalAux) == null ? void 0 : _a.call(this, this.vars, this.lookups);
1800
+ (_a = this.onEvalAux) == null ? void 0 : _a.call(this, this.vars, this.constants.size > 0 ? this.constants : void 0, this.lookups);
1585
1801
  }
1586
1802
  // from JsModel interface
1587
1803
  evalLevels() {
@@ -1664,11 +1880,18 @@ var WasmModel = class {
1664
1880
  this.outputVarIds = wasmModule.outputVarIds;
1665
1881
  this.modelListing = wasmModule.modelListing;
1666
1882
  this.wasmSetLookup = wasmModule.cwrap("setLookup", null, ["number", "number", "number", "number"]);
1667
- this.wasmRunModel = wasmModule.cwrap("runModelWithBuffers", null, ["number", "number", "number"]);
1883
+ this.wasmRunModel = wasmModule.cwrap("runModelWithBuffers", null, [
1884
+ "number",
1885
+ "number",
1886
+ "number",
1887
+ "number",
1888
+ "number",
1889
+ "number"
1890
+ ]);
1668
1891
  }
1669
1892
  // from RunnableModel interface
1670
1893
  runModel(params) {
1671
- var _a, _b, _c, _d, _e, _f, _g;
1894
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
1672
1895
  const lookups = params.getLookups();
1673
1896
  if (lookups !== void 0) {
1674
1897
  for (const lookupDef of lookups) {
@@ -1704,7 +1927,48 @@ var WasmModel = class {
1704
1927
  this.wasmSetLookup(varIndex, subIndicesAddress, pointsAddress, numPoints);
1705
1928
  }
1706
1929
  }
1707
- params.copyInputs((_d = this.inputsBuffer) == null ? void 0 : _d.getArrayView(), (numElements) => {
1930
+ let constantIndicesBuffer;
1931
+ let constantValuesBuffer;
1932
+ const constants = params.getConstants();
1933
+ if (constants !== void 0 && constants.length > 0) {
1934
+ let totalIndicesSize = 1;
1935
+ for (const constantDef of constants) {
1936
+ const numSubElements = ((_d = constantDef.varRef.varSpec.subscriptIndices) == null ? void 0 : _d.length) || 0;
1937
+ totalIndicesSize += 2 + numSubElements;
1938
+ }
1939
+ if (this.constantIndicesBuffer === void 0 || this.constantIndicesBuffer.numElements < totalIndicesSize) {
1940
+ (_e = this.constantIndicesBuffer) == null ? void 0 : _e.dispose();
1941
+ this.constantIndicesBuffer = createInt32WasmBuffer(this.wasmModule, totalIndicesSize);
1942
+ }
1943
+ const numConstants = constants.length;
1944
+ if (this.constantValuesBuffer === void 0 || this.constantValuesBuffer.numElements < numConstants) {
1945
+ (_f = this.constantValuesBuffer) == null ? void 0 : _f.dispose();
1946
+ this.constantValuesBuffer = createFloat64WasmBuffer(this.wasmModule, numConstants);
1947
+ }
1948
+ const indicesView = this.constantIndicesBuffer.getArrayView();
1949
+ const valuesView = this.constantValuesBuffer.getArrayView();
1950
+ let indicesOffset = 0;
1951
+ let valuesOffset = 0;
1952
+ indicesView[indicesOffset++] = numConstants;
1953
+ for (const constantDef of constants) {
1954
+ const varSpec = constantDef.varRef.varSpec;
1955
+ const numSubElements = ((_g = varSpec.subscriptIndices) == null ? void 0 : _g.length) || 0;
1956
+ indicesView[indicesOffset++] = varSpec.varIndex;
1957
+ indicesView[indicesOffset++] = numSubElements;
1958
+ if (numSubElements > 0) {
1959
+ for (let i = 0; i < numSubElements; i++) {
1960
+ indicesView[indicesOffset++] = varSpec.subscriptIndices[i];
1961
+ }
1962
+ }
1963
+ valuesView[valuesOffset++] = constantDef.value;
1964
+ }
1965
+ constantIndicesBuffer = this.constantIndicesBuffer;
1966
+ constantValuesBuffer = this.constantValuesBuffer;
1967
+ } else {
1968
+ constantIndicesBuffer = void 0;
1969
+ constantValuesBuffer = void 0;
1970
+ }
1971
+ params.copyInputs((_h = this.inputsBuffer) == null ? void 0 : _h.getArrayView(), (numElements) => {
1708
1972
  var _a2;
1709
1973
  (_a2 = this.inputsBuffer) == null ? void 0 : _a2.dispose();
1710
1974
  this.inputsBuffer = createFloat64WasmBuffer(this.wasmModule, numElements);
@@ -1712,7 +1976,7 @@ var WasmModel = class {
1712
1976
  });
1713
1977
  let outputIndicesBuffer;
1714
1978
  if (params.getOutputIndicesLength() > 0) {
1715
- params.copyOutputIndices((_e = this.outputIndicesBuffer) == null ? void 0 : _e.getArrayView(), (numElements) => {
1979
+ params.copyOutputIndices((_i = this.outputIndicesBuffer) == null ? void 0 : _i.getArrayView(), (numElements) => {
1716
1980
  var _a2;
1717
1981
  (_a2 = this.outputIndicesBuffer) == null ? void 0 : _a2.dispose();
1718
1982
  this.outputIndicesBuffer = createInt32WasmBuffer(this.wasmModule, numElements);
@@ -1724,14 +1988,19 @@ var WasmModel = class {
1724
1988
  }
1725
1989
  const outputsLengthInElements = params.getOutputsLength();
1726
1990
  if (this.outputsBuffer === void 0 || this.outputsBuffer.numElements < outputsLengthInElements) {
1727
- (_f = this.outputsBuffer) == null ? void 0 : _f.dispose();
1991
+ (_j = this.outputsBuffer) == null ? void 0 : _j.dispose();
1728
1992
  this.outputsBuffer = createFloat64WasmBuffer(this.wasmModule, outputsLengthInElements);
1729
1993
  }
1730
1994
  const t0 = perfNow();
1731
1995
  this.wasmRunModel(
1732
- ((_g = this.inputsBuffer) == null ? void 0 : _g.getAddress()) || 0,
1996
+ ((_k = this.inputsBuffer) == null ? void 0 : _k.getAddress()) || 0,
1997
+ // Always pass 0 (NULL) for input indices, since we assume that all input values are
1998
+ // provided and are in the same order as the input variables defined in the model spec
1999
+ 0,
1733
2000
  this.outputsBuffer.getAddress(),
1734
- (outputIndicesBuffer == null ? void 0 : outputIndicesBuffer.getAddress()) || 0
2001
+ (outputIndicesBuffer == null ? void 0 : outputIndicesBuffer.getAddress()) || 0,
2002
+ (constantValuesBuffer == null ? void 0 : constantValuesBuffer.getAddress()) || 0,
2003
+ (constantIndicesBuffer == null ? void 0 : constantIndicesBuffer.getAddress()) || 0
1735
2004
  );
1736
2005
  const elapsed = perfElapsed(t0);
1737
2006
  params.storeOutputs(this.outputsBuffer.getArrayView());
@@ -1739,13 +2008,17 @@ var WasmModel = class {
1739
2008
  }
1740
2009
  // from RunnableModel interface
1741
2010
  terminate() {
1742
- var _a, _b, _c;
2011
+ var _a, _b, _c, _d, _e;
1743
2012
  (_a = this.inputsBuffer) == null ? void 0 : _a.dispose();
1744
2013
  this.inputsBuffer = void 0;
1745
2014
  (_b = this.outputsBuffer) == null ? void 0 : _b.dispose();
1746
2015
  this.outputsBuffer = void 0;
1747
2016
  (_c = this.outputIndicesBuffer) == null ? void 0 : _c.dispose();
1748
2017
  this.outputIndicesBuffer = void 0;
2018
+ (_d = this.constantValuesBuffer) == null ? void 0 : _d.dispose();
2019
+ this.constantValuesBuffer = void 0;
2020
+ (_e = this.constantIndicesBuffer) == null ? void 0 : _e.dispose();
2021
+ this.constantIndicesBuffer = void 0;
1749
2022
  }
1750
2023
  };
1751
2024
  function initWasmModel(wasmModule) {
@@ -1761,6 +2034,7 @@ var MockWasmModule = class {
1761
2034
  this.mallocOffset = 8;
1762
2035
  this.allocs = /* @__PURE__ */ new Map();
1763
2036
  this.lookups = /* @__PURE__ */ new Map();
2037
+ this.constants = /* @__PURE__ */ new Map();
1764
2038
  this.initialTime = options.initialTime;
1765
2039
  this.finalTime = options.finalTime;
1766
2040
  this.outputVarIds = options.outputVarIds;
@@ -1800,11 +2074,35 @@ var MockWasmModule = class {
1800
2074
  this.lookups.set(varId, new JsModelLookup(numPoints, points));
1801
2075
  };
1802
2076
  case "runModelWithBuffers":
1803
- return (inputsAddress, outputsAddress, outputIndicesAddress) => {
2077
+ return (inputsAddress, _inputIndicesAddress, outputsAddress, outputIndicesAddress, constantValuesAddress, constantIndicesAddress) => {
1804
2078
  const inputs = this.getHeapView("float64", inputsAddress);
1805
2079
  const outputs = this.getHeapView("float64", outputsAddress);
1806
2080
  const outputIndices = this.getHeapView("int32", outputIndicesAddress);
1807
- this.onRunModel(inputs, outputs, this.lookups, outputIndices);
2081
+ this.constants.clear();
2082
+ if (constantValuesAddress !== 0 && constantIndicesAddress !== 0) {
2083
+ const constantValues = this.getHeapView("float64", constantValuesAddress);
2084
+ const constantIndices = this.getHeapView("int32", constantIndicesAddress);
2085
+ const numConstants = constantIndices[0];
2086
+ let indicesOffset = 1;
2087
+ let valuesOffset = 0;
2088
+ for (let i = 0; i < numConstants; i++) {
2089
+ const varIndex = constantIndices[indicesOffset++];
2090
+ const subCount = constantIndices[indicesOffset++];
2091
+ indicesOffset += subCount;
2092
+ const varId = this.varIdForSpec({ varIndex });
2093
+ if (varId) {
2094
+ this.constants.set(varId, constantValues[valuesOffset++]);
2095
+ }
2096
+ }
2097
+ }
2098
+ this.onRunModel(
2099
+ inputs,
2100
+ outputs,
2101
+ this.constants.size > 0 ? this.constants : void 0,
2102
+ this.lookups,
2103
+ outputIndices
2104
+ );
2105
+ this.constants.clear();
1808
2106
  };
1809
2107
  default:
1810
2108
  throw new Error(`Unhandled call to cwrap with function name '${fname}'`);
@@ -1882,7 +2180,7 @@ function createRunnerFromRunnableModel(model) {
1882
2180
  }
1883
2181
  return runModelSync(inputs, outputs, options);
1884
2182
  },
1885
- terminate: () => __async(this, null, function* () {
2183
+ terminate: () => __async(null, null, function* () {
1886
2184
  if (!terminated) {
1887
2185
  model.terminate();
1888
2186
  terminated = true;
@@ -2169,14 +2467,18 @@ var ModelContextImpl = class {
2169
2467
  Outputs,
2170
2468
  ReferencedRunModelParams,
2171
2469
  Series,
2470
+ createConstantDef,
2172
2471
  createInputValue,
2173
2472
  createLookupDef,
2174
2473
  createRunnableModel,
2175
2474
  createSynchronousModelRunner,
2475
+ decodeConstants,
2176
2476
  decodeLookups,
2477
+ encodeConstants,
2177
2478
  encodeLookups,
2178
2479
  encodeVarIndices,
2179
2480
  execJsModel,
2481
+ getEncodedConstantBufferLengths,
2180
2482
  getEncodedLookupBufferLengths,
2181
2483
  getEncodedVarIndicesLength,
2182
2484
  getJsModelFunctions,