@sdeverywhere/runtime 0.2.5 → 0.2.6

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.cts CHANGED
@@ -180,15 +180,16 @@ interface LookupDef {
180
180
  /** The reference that identifies the lookup or data variable to be modified. */
181
181
  varRef: VarRef;
182
182
  /** The lookup data as a flat array of (x,y) pairs. */
183
- points: Float64Array;
183
+ points?: Float64Array;
184
184
  }
185
185
  /**
186
186
  * Create a `LookupDef` instance from the given array of `Point` objects.
187
187
  *
188
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.
189
+ * @param points The lookup data as an array of `Point` objects. This can be
190
+ * undefined, in which case the lookup data will be reset to the original data.
190
191
  */
191
- declare function createLookupDef(varRef: VarRef, points: Point[]): LookupDef;
192
+ declare function createLookupDef(varRef: VarRef, points: Point[] | undefined): LookupDef;
192
193
 
193
194
  /**
194
195
  * Return the length of the array that is required to store the variable
@@ -567,19 +568,60 @@ type JsModelLookupMode = 'interpolate' | 'forward' | 'backward';
567
568
  * @hidden This is not yet part of the public API; for internal use only.
568
569
  */
569
570
  declare class JsModelLookup {
570
- private readonly n;
571
- private readonly data;
571
+ /** The original data passed to the constructor. */
572
+ private readonly originalData;
573
+ /** The size (i.e., number of pairs) of the original data. */
574
+ private readonly originalSize;
575
+ /**
576
+ * The dynamic data array. This will be undefined initially, and the array
577
+ * will be allocated (or grown) by `setData`.
578
+ */
579
+ private dynamicData;
580
+ /** The size (i.e., number of pairs) of the dynamic data. */
581
+ private dynamicSize;
582
+ /**
583
+ * The active data array. This will be the same as either `originalData`
584
+ * or `dynamicData`, depending on whether the lookup data is overridden
585
+ * at runtime using `setData`.
586
+ */
587
+ private activeData;
588
+ /** The size (i.e., number of pairs) of the active data. */
589
+ private activeSize;
590
+ /**
591
+ * The inverted version of the active data array. This is allocated on demand
592
+ * only in the case of `LOOKUP INVERT` function calls.
593
+ */
572
594
  private invertedData?;
595
+ /**
596
+ * The input value for the last hit. This is cached for performance so that we
597
+ * can reduce the amount of linear searching in the common case where `LOOKUP`
598
+ * input values are monotonically increasing.
599
+ */
573
600
  private lastInput;
601
+ /** The index for the last hit (see `lastInput`). */
574
602
  private lastHitIndex;
575
603
  /**
576
- * @param n The number of (x,y) pairs in the lookup.
604
+ * @param size The number of (x,y) pairs in the lookup.
577
605
  * @param data The lookup data, as (x,y) pairs. The length of the array must be
578
606
  * >= 2*n. Note that the data will be stored by reference, so if there is a chance
579
607
  * that the array will be reused or modified by other code, be sure to pass in a
580
608
  * copy of the array.
581
609
  */
582
- constructor(n: number, data: number[] | Float64Array);
610
+ constructor(size: number, data: number[] | Float64Array | undefined);
611
+ /**
612
+ * Set new data for this lookup instance, or restore the original data.
613
+ *
614
+ * If `data` is undefined, the original data that was supplied to the constructor will
615
+ * be restored as the "active" data. Otherwise, `data` will be copied to an internal
616
+ * data buffer, which will be the "active" data. If `size` is greater than the size
617
+ * passed to previous calls, the internal data buffer will be grown as needed.
618
+ *
619
+ * @param size The number of (x,y) pairs in the lookup.
620
+ * @param data The lookup data, as (x,y) pairs. The length of the array must be
621
+ * >= 2*n. Note that the data will be copied into an internal data buffer, so it
622
+ * is not necessary to defensively copy data before calling this method.
623
+ */
624
+ setData(size: number, data: Float64Array | undefined): void;
583
625
  getValueForX(x: number, mode: JsModelLookupMode): number;
584
626
  getValueForY(y: number): number;
585
627
  /**
@@ -716,7 +758,7 @@ interface JsModel {
716
758
  /** @hidden */
717
759
  setInputs(inputValue: (index: number) => number): void;
718
760
  /** @hidden */
719
- setLookup(varSpec: VarSpec, points: Float64Array): void;
761
+ setLookup(varSpec: VarSpec, points: Float64Array | undefined): void;
720
762
  /** @hidden */
721
763
  storeOutputs(storeValue: (value: number) => void): void;
722
764
  /** @hidden */
@@ -787,7 +829,7 @@ declare class MockJsModel implements JsModel {
787
829
  setModelFunctions(fns: JsModelFunctions): void;
788
830
  setTime(time: number): void;
789
831
  setInputs(): void;
790
- setLookup(varSpec: VarSpec, points: Float64Array): void;
832
+ setLookup(varSpec: VarSpec, points: Float64Array | undefined): void;
791
833
  storeOutputs(storeValue: (value: number) => void): void;
792
834
  storeOutput(varSpec: VarSpec, storeValue: (value: number) => void): void;
793
835
  initConstants(): void;
package/dist/index.d.ts CHANGED
@@ -180,15 +180,16 @@ interface LookupDef {
180
180
  /** The reference that identifies the lookup or data variable to be modified. */
181
181
  varRef: VarRef;
182
182
  /** The lookup data as a flat array of (x,y) pairs. */
183
- points: Float64Array;
183
+ points?: Float64Array;
184
184
  }
185
185
  /**
186
186
  * Create a `LookupDef` instance from the given array of `Point` objects.
187
187
  *
188
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.
189
+ * @param points The lookup data as an array of `Point` objects. This can be
190
+ * undefined, in which case the lookup data will be reset to the original data.
190
191
  */
191
- declare function createLookupDef(varRef: VarRef, points: Point[]): LookupDef;
192
+ declare function createLookupDef(varRef: VarRef, points: Point[] | undefined): LookupDef;
192
193
 
193
194
  /**
194
195
  * Return the length of the array that is required to store the variable
@@ -567,19 +568,60 @@ type JsModelLookupMode = 'interpolate' | 'forward' | 'backward';
567
568
  * @hidden This is not yet part of the public API; for internal use only.
568
569
  */
569
570
  declare class JsModelLookup {
570
- private readonly n;
571
- private readonly data;
571
+ /** The original data passed to the constructor. */
572
+ private readonly originalData;
573
+ /** The size (i.e., number of pairs) of the original data. */
574
+ private readonly originalSize;
575
+ /**
576
+ * The dynamic data array. This will be undefined initially, and the array
577
+ * will be allocated (or grown) by `setData`.
578
+ */
579
+ private dynamicData;
580
+ /** The size (i.e., number of pairs) of the dynamic data. */
581
+ private dynamicSize;
582
+ /**
583
+ * The active data array. This will be the same as either `originalData`
584
+ * or `dynamicData`, depending on whether the lookup data is overridden
585
+ * at runtime using `setData`.
586
+ */
587
+ private activeData;
588
+ /** The size (i.e., number of pairs) of the active data. */
589
+ private activeSize;
590
+ /**
591
+ * The inverted version of the active data array. This is allocated on demand
592
+ * only in the case of `LOOKUP INVERT` function calls.
593
+ */
572
594
  private invertedData?;
595
+ /**
596
+ * The input value for the last hit. This is cached for performance so that we
597
+ * can reduce the amount of linear searching in the common case where `LOOKUP`
598
+ * input values are monotonically increasing.
599
+ */
573
600
  private lastInput;
601
+ /** The index for the last hit (see `lastInput`). */
574
602
  private lastHitIndex;
575
603
  /**
576
- * @param n The number of (x,y) pairs in the lookup.
604
+ * @param size The number of (x,y) pairs in the lookup.
577
605
  * @param data The lookup data, as (x,y) pairs. The length of the array must be
578
606
  * >= 2*n. Note that the data will be stored by reference, so if there is a chance
579
607
  * that the array will be reused or modified by other code, be sure to pass in a
580
608
  * copy of the array.
581
609
  */
582
- constructor(n: number, data: number[] | Float64Array);
610
+ constructor(size: number, data: number[] | Float64Array | undefined);
611
+ /**
612
+ * Set new data for this lookup instance, or restore the original data.
613
+ *
614
+ * If `data` is undefined, the original data that was supplied to the constructor will
615
+ * be restored as the "active" data. Otherwise, `data` will be copied to an internal
616
+ * data buffer, which will be the "active" data. If `size` is greater than the size
617
+ * passed to previous calls, the internal data buffer will be grown as needed.
618
+ *
619
+ * @param size The number of (x,y) pairs in the lookup.
620
+ * @param data The lookup data, as (x,y) pairs. The length of the array must be
621
+ * >= 2*n. Note that the data will be copied into an internal data buffer, so it
622
+ * is not necessary to defensively copy data before calling this method.
623
+ */
624
+ setData(size: number, data: Float64Array | undefined): void;
583
625
  getValueForX(x: number, mode: JsModelLookupMode): number;
584
626
  getValueForY(y: number): number;
585
627
  /**
@@ -716,7 +758,7 @@ interface JsModel {
716
758
  /** @hidden */
717
759
  setInputs(inputValue: (index: number) => number): void;
718
760
  /** @hidden */
719
- setLookup(varSpec: VarSpec, points: Float64Array): void;
761
+ setLookup(varSpec: VarSpec, points: Float64Array | undefined): void;
720
762
  /** @hidden */
721
763
  storeOutputs(storeValue: (value: number) => void): void;
722
764
  /** @hidden */
@@ -787,7 +829,7 @@ declare class MockJsModel implements JsModel {
787
829
  setModelFunctions(fns: JsModelFunctions): void;
788
830
  setTime(time: number): void;
789
831
  setInputs(): void;
790
- setLookup(varSpec: VarSpec, points: Float64Array): void;
832
+ setLookup(varSpec: VarSpec, points: Float64Array | undefined): void;
791
833
  storeOutputs(storeValue: (value: number) => void): void;
792
834
  storeOutput(varSpec: VarSpec, storeValue: (value: number) => void): void;
793
835
  initConstants(): void;
package/dist/index.js CHANGED
@@ -207,7 +207,7 @@ function encodeVarIndices(varSpecs, indicesArray) {
207
207
  }
208
208
  }
209
209
  function getEncodedLookupBufferLengths(lookupDefs) {
210
- var _a;
210
+ var _a, _b;
211
211
  let lookupIndicesLength = 1;
212
212
  let lookupsLength = 0;
213
213
  for (const lookupDef of lookupDefs) {
@@ -219,7 +219,7 @@ function getEncodedLookupBufferLengths(lookupDefs) {
219
219
  const subCount = ((_a = varSpec.subscriptIndices) == null ? void 0 : _a.length) || 0;
220
220
  lookupIndicesLength += subCount;
221
221
  lookupIndicesLength += 2;
222
- lookupsLength += lookupDef.points.length;
222
+ lookupsLength += ((_b = lookupDef.points) == null ? void 0 : _b.length) || 0;
223
223
  }
224
224
  return {
225
225
  lookupIndicesLength,
@@ -239,10 +239,15 @@ function encodeLookups(lookupDefs, lookupIndicesArray, lookupsArray) {
239
239
  for (let i = 0; i < subCount; i++) {
240
240
  lookupIndicesArray[li++] = subs[i];
241
241
  }
242
- lookupIndicesArray[li++] = lookupDataOffset;
243
- lookupIndicesArray[li++] = lookupDef.points.length;
244
- lookupsArray == null ? void 0 : lookupsArray.set(lookupDef.points, lookupDataOffset);
245
- lookupDataOffset += lookupDef.points.length;
242
+ if (lookupDef.points !== void 0) {
243
+ lookupIndicesArray[li++] = lookupDataOffset;
244
+ lookupIndicesArray[li++] = lookupDef.points.length;
245
+ lookupsArray == null ? void 0 : lookupsArray.set(lookupDef.points, lookupDataOffset);
246
+ lookupDataOffset += lookupDef.points.length;
247
+ } else {
248
+ lookupIndicesArray[li++] = -1;
249
+ lookupIndicesArray[li++] = 0;
250
+ }
246
251
  }
247
252
  }
248
253
  function decodeLookups(lookupIndicesArray, lookupsArray) {
@@ -263,10 +268,14 @@ function decodeLookups(lookupIndicesArray, lookupsArray) {
263
268
  subscriptIndices
264
269
  };
265
270
  let points;
266
- if (lookupsArray) {
267
- points = lookupsArray.slice(lookupDataOffset, lookupDataOffset + lookupDataLength);
271
+ if (lookupDataOffset >= 0) {
272
+ if (lookupsArray) {
273
+ points = lookupsArray.slice(lookupDataOffset, lookupDataOffset + lookupDataLength);
274
+ } else {
275
+ points = new Float64Array(0);
276
+ }
268
277
  } else {
269
- points = new Float64Array(0);
278
+ points = void 0;
270
279
  }
271
280
  lookupDefs.push({
272
281
  varRef: {
@@ -280,11 +289,14 @@ function decodeLookups(lookupIndicesArray, lookupsArray) {
280
289
 
281
290
  // src/_shared/lookup-def.ts
282
291
  function createLookupDef(varRef, points) {
283
- const flatPoints = new Float64Array(points.length * 2);
284
- let i = 0;
285
- for (const p of points) {
286
- flatPoints[i++] = p.x;
287
- flatPoints[i++] = p.y;
292
+ let flatPoints;
293
+ if (points) {
294
+ flatPoints = new Float64Array(points.length * 2);
295
+ let i = 0;
296
+ for (const p of points) {
297
+ flatPoints[i++] = p.x;
298
+ flatPoints[i++] = p.y;
299
+ }
288
300
  }
289
301
  return {
290
302
  varRef,
@@ -840,18 +852,59 @@ var _NA_ = -Number.MAX_VALUE;
840
852
  // src/js-model/js-model-lookup.ts
841
853
  var JsModelLookup = class {
842
854
  /**
843
- * @param n The number of (x,y) pairs in the lookup.
855
+ * @param size The number of (x,y) pairs in the lookup.
844
856
  * @param data The lookup data, as (x,y) pairs. The length of the array must be
845
857
  * >= 2*n. Note that the data will be stored by reference, so if there is a chance
846
858
  * that the array will be reused or modified by other code, be sure to pass in a
847
859
  * copy of the array.
848
860
  */
849
- constructor(n, data) {
850
- this.n = n;
851
- this.data = data;
852
- if (data.length < n * 2) {
853
- throw new Error(`Lookup data array length must be >= 2*size (length=${data.length} size=${n}`);
861
+ constructor(size, data) {
862
+ if (data && data.length < size * 2) {
863
+ throw new Error(`Lookup data array length must be >= 2*size (length=${data.length} size=${size}`);
864
+ }
865
+ this.originalData = data;
866
+ this.originalSize = size;
867
+ this.dynamicData = void 0;
868
+ this.dynamicSize = 0;
869
+ this.activeData = this.originalData;
870
+ this.activeSize = this.originalSize;
871
+ this.lastInput = Number.MAX_VALUE;
872
+ this.lastHitIndex = 0;
873
+ }
874
+ /**
875
+ * Set new data for this lookup instance, or restore the original data.
876
+ *
877
+ * If `data` is undefined, the original data that was supplied to the constructor will
878
+ * be restored as the "active" data. Otherwise, `data` will be copied to an internal
879
+ * data buffer, which will be the "active" data. If `size` is greater than the size
880
+ * passed to previous calls, the internal data buffer will be grown as needed.
881
+ *
882
+ * @param size The number of (x,y) pairs in the lookup.
883
+ * @param data The lookup data, as (x,y) pairs. The length of the array must be
884
+ * >= 2*n. Note that the data will be copied into an internal data buffer, so it
885
+ * is not necessary to defensively copy data before calling this method.
886
+ */
887
+ setData(size, data) {
888
+ if (data) {
889
+ if (data.length < size * 2) {
890
+ throw new Error(`Lookup data array length must be >= 2*size (length=${data.length} size=${size}`);
891
+ }
892
+ const dataLengthInElems = size * 2;
893
+ if (this.dynamicData === void 0 || dataLengthInElems > this.dynamicData.length) {
894
+ this.dynamicData = new Float64Array(dataLengthInElems);
895
+ }
896
+ this.dynamicSize = size;
897
+ if (size > 0) {
898
+ const subarray = data.subarray(0, dataLengthInElems);
899
+ this.dynamicData.set(subarray);
900
+ }
901
+ this.activeData = this.dynamicData;
902
+ this.activeSize = this.dynamicSize;
903
+ } else {
904
+ this.activeData = this.originalData;
905
+ this.activeSize = this.originalSize;
854
906
  }
907
+ this.invertedData = void 0;
855
908
  this.lastInput = Number.MAX_VALUE;
856
909
  this.lastHitIndex = 0;
857
910
  }
@@ -860,8 +913,8 @@ var JsModelLookup = class {
860
913
  }
861
914
  getValueForY(y) {
862
915
  if (this.invertedData === void 0) {
863
- const numValues = this.n * 2;
864
- const normalData = this.data;
916
+ const numValues = this.activeSize * 2;
917
+ const normalData = this.activeData;
865
918
  const invertedData = Array(numValues);
866
919
  for (let i = 0; i < numValues; i += 2) {
867
920
  invertedData[i] = normalData[i + 1];
@@ -876,11 +929,11 @@ var JsModelLookup = class {
876
929
  * NOTE: The x values are assumed to be monotonically increasing.
877
930
  */
878
931
  getValue(input, useInvertedData, mode) {
879
- if (this.n === 0) {
932
+ if (this.activeSize === 0) {
880
933
  return _NA_;
881
934
  }
882
- const data = useInvertedData ? this.invertedData : this.data;
883
- const max = this.n * 2;
935
+ const data = useInvertedData ? this.invertedData : this.activeData;
936
+ const max = this.activeSize * 2;
884
937
  const useCachedValues = !useInvertedData;
885
938
  let startIndex;
886
939
  if (useCachedValues && input >= this.lastInput) {
@@ -939,10 +992,10 @@ var JsModelLookup = class {
939
992
  * no points) or if the provided time is earlier than the first data point.
940
993
  */
941
994
  getValueForGameTime(time, defaultValue) {
942
- if (this.n <= 0) {
995
+ if (this.activeSize <= 0) {
943
996
  return defaultValue;
944
997
  }
945
- const x0 = this.data[0];
998
+ const x0 = this.activeData[0];
946
999
  if (time < x0) {
947
1000
  return defaultValue;
948
1001
  }
@@ -957,33 +1010,34 @@ var JsModelLookup = class {
957
1010
  * lookup behavior, so we implement it as a separate method here.
958
1011
  */
959
1012
  getValueBetweenTimes(input, mode) {
960
- if (this.n === 0) {
1013
+ if (this.activeSize === 0) {
961
1014
  return _NA_;
962
1015
  }
963
- const max = this.n * 2;
1016
+ const data = this.activeData;
1017
+ const max = this.activeSize * 2;
964
1018
  switch (mode) {
965
1019
  case "forward": {
966
1020
  input = Math.floor(input);
967
1021
  for (let xi = 0; xi < max; xi += 2) {
968
- const x = this.data[xi];
1022
+ const x = data[xi];
969
1023
  if (x >= input) {
970
- return this.data[xi + 1];
1024
+ return data[xi + 1];
971
1025
  }
972
1026
  }
973
- return this.data[max - 1];
1027
+ return data[max - 1];
974
1028
  }
975
1029
  case "backward": {
976
1030
  input = Math.floor(input);
977
1031
  for (let xi = 2; xi < max; xi += 2) {
978
- const x = this.data[xi];
1032
+ const x = data[xi];
979
1033
  if (x >= input) {
980
- return this.data[xi - 1];
1034
+ return data[xi - 1];
981
1035
  }
982
1036
  }
983
1037
  if (max >= 4) {
984
- return this.data[max - 3];
1038
+ return data[max - 3];
985
1039
  } else {
986
- return this.data[1];
1040
+ return data[1];
987
1041
  }
988
1042
  }
989
1043
  case "interpolate":
@@ -995,17 +1049,17 @@ var JsModelLookup = class {
995
1049
  throw new Error(msg);
996
1050
  }
997
1051
  for (let xi = 2; xi < max; xi += 2) {
998
- const x = this.data[xi];
1052
+ const x = data[xi];
999
1053
  if (x >= input) {
1000
- const last_x = this.data[xi - 2];
1001
- const last_y = this.data[xi - 1];
1002
- const y = this.data[xi + 1];
1054
+ const last_x = data[xi - 2];
1055
+ const last_y = data[xi - 1];
1056
+ const y = data[xi + 1];
1003
1057
  const dx = x - last_x;
1004
1058
  const dy = y - last_y;
1005
1059
  return last_y + dy / dx * (input - last_x);
1006
1060
  }
1007
1061
  }
1008
- return this.data[max - 1];
1062
+ return data[max - 1];
1009
1063
  }
1010
1064
  }
1011
1065
  }
@@ -1456,7 +1510,8 @@ var MockJsModel = class {
1456
1510
  if (varId === void 0) {
1457
1511
  throw new Error(`No lookup variable found for spec ${varSpec}`);
1458
1512
  }
1459
- this.lookups.set(varId, new JsModelLookup(points.length / 2, points));
1513
+ const numPoints = points ? points.length / 2 : 0;
1514
+ this.lookups.set(varId, new JsModelLookup(numPoints, points));
1460
1515
  }
1461
1516
  // from JsModel interface
1462
1517
  storeOutputs(storeValue) {
@@ -1585,14 +1640,21 @@ var WasmModel = class {
1585
1640
  } else {
1586
1641
  subIndicesAddress = 0;
1587
1642
  }
1588
- const numLookupElements = lookupDef.points.length;
1589
- if (this.lookupDataBuffer === void 0 || this.lookupDataBuffer.numElements < numLookupElements) {
1590
- (_c = this.lookupDataBuffer) == null ? void 0 : _c.dispose();
1591
- this.lookupDataBuffer = createFloat64WasmBuffer(this.wasmModule, numLookupElements);
1643
+ let pointsAddress;
1644
+ let numPoints;
1645
+ if (lookupDef.points) {
1646
+ const numLookupElements = lookupDef.points.length;
1647
+ if (this.lookupDataBuffer === void 0 || this.lookupDataBuffer.numElements < numLookupElements) {
1648
+ (_c = this.lookupDataBuffer) == null ? void 0 : _c.dispose();
1649
+ this.lookupDataBuffer = createFloat64WasmBuffer(this.wasmModule, numLookupElements);
1650
+ }
1651
+ this.lookupDataBuffer.getArrayView().set(lookupDef.points);
1652
+ pointsAddress = this.lookupDataBuffer.getAddress();
1653
+ numPoints = numLookupElements / 2;
1654
+ } else {
1655
+ pointsAddress = 0;
1656
+ numPoints = 0;
1592
1657
  }
1593
- this.lookupDataBuffer.getArrayView().set(lookupDef.points);
1594
- const pointsAddress = this.lookupDataBuffer.getAddress();
1595
- const numPoints = numLookupElements / 2;
1596
1658
  const varIndex = varSpec.varIndex;
1597
1659
  this.wasmSetLookup(varIndex, subIndicesAddress, pointsAddress, numPoints);
1598
1660
  }