msgpackr 1.9.1 → 1.9.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.js CHANGED
@@ -118,10 +118,10 @@
118
118
  let size = source.length;
119
119
  let value = this ? this.unpack(source, size) : defaultUnpackr.unpack(source, size);
120
120
  if (forEach) {
121
- if (forEach(value) === false) return;
121
+ if (forEach(value, lastPosition, position$1) === false) return;
122
122
  while(position$1 < size) {
123
123
  lastPosition = position$1;
124
- if (forEach(checkedRead()) === false) {
124
+ if (forEach(checkedRead(), lastPosition, position$1) === false) {
125
125
  return
126
126
  }
127
127
  }
@@ -193,6 +193,10 @@
193
193
  position$1 = bundledStrings$1.postBundlePosition;
194
194
  bundledStrings$1 = null;
195
195
  }
196
+ if (sequentialMode)
197
+ // we only need to restore the structures if there was an error, but if we completed a read,
198
+ // we can clear this out and keep the structures we read
199
+ currentStructures.restoreStructures = null;
196
200
 
197
201
  if (position$1 == srcEnd) {
198
202
  // finished reading this source, cleanup references
@@ -915,7 +919,10 @@
915
919
  structure.highByte = highByte;
916
920
  }
917
921
  let existingStructure = currentStructures[id];
918
- if (existingStructure && existingStructure.isShared) {
922
+ // If it is a shared structure, we need to restore any changes after reading.
923
+ // Also in sequential mode, we may get incomplete reads and thus errors, and we need to restore
924
+ // to the state prior to an incomplete read in order to properly resume.
925
+ if (existingStructure && (existingStructure.isShared || sequentialMode)) {
919
926
  (currentStructures.restoreStructures || (currentStructures.restoreStructures = []))[id] = existingStructure;
920
927
  }
921
928
  currentStructures[id] = structure;
@@ -925,10 +932,10 @@
925
932
  currentExtensions[0] = () => {}; // notepack defines extension 0 to mean undefined, so use that as the default here
926
933
  currentExtensions[0].noBuffer = true;
927
934
 
928
- let glbl = typeof globalThis === 'object' ? globalThis : window;
935
+ let errors = { Error, TypeError, ReferenceError };
929
936
  currentExtensions[0x65] = () => {
930
937
  let data = read();
931
- return (glbl[data[0]] || Error)(data[1])
938
+ return (errors[data[0]] || Error)(data[1])
932
939
  };
933
940
 
934
941
  currentExtensions[0x69] = (data) => {
@@ -966,6 +973,7 @@
966
973
 
967
974
  const typedArrays = ['Int8','Uint8','Uint8Clamped','Int16','Uint16','Int32','Uint32','Float32','Float64','BigInt64','BigUint64'].map(type => type + 'Array');
968
975
 
976
+ let glbl = typeof globalThis === 'object' ? globalThis : window;
969
977
  currentExtensions[0x74] = (data) => {
970
978
  let typeCode = data[0];
971
979
  let typedArrayName = typedArrays[typeCode];
@@ -1252,7 +1260,7 @@
1252
1260
  if (serializationsSinceTransitionRebuild < 10)
1253
1261
  serializationsSinceTransitionRebuild++;
1254
1262
  let sharedLength = structures.sharedLength || 0;
1255
- if (structures.length > sharedLength)
1263
+ if (structures.length > sharedLength && !isSequential)
1256
1264
  structures.length = sharedLength;
1257
1265
  if (transitionsCount > 10000) {
1258
1266
  // force a rebuild occasionally after a lot of transitions so it can get cleaned up
@@ -1460,7 +1468,7 @@
1460
1468
  targetView.setFloat64(position, value);
1461
1469
  position += 8;
1462
1470
  }
1463
- } else if (type === 'object') {
1471
+ } else if (type === 'object' || type === 'function') {
1464
1472
  if (!value)
1465
1473
  target[position++] = 0xc0;
1466
1474
  else {
@@ -1567,6 +1575,11 @@
1567
1575
  } else {
1568
1576
  if (value.toJSON) // use this as an alternate mechanism for expressing how to serialize
1569
1577
  return pack(value.toJSON());
1578
+
1579
+ // if there is a writeFunction, use it, otherwise just encode as undefined
1580
+ if (type === 'function')
1581
+ return pack(this.writeFunction && this.writeFunction(value));
1582
+
1570
1583
  // no extension found, write as object
1571
1584
  writeObject(value, !value.hasOwnProperty); // if it doesn't have hasOwnProperty, don't do hasOwnProperty checks
1572
1585
  }
@@ -1601,14 +1614,12 @@
1601
1614
  target[position++] = 0;
1602
1615
  target[position++] = 0;
1603
1616
  }
1604
- } else if (type === 'function') {
1605
- pack(this.writeFunction && this.writeFunction()); // if there is a writeFunction, use it, otherwise just encode as undefined
1606
1617
  } else {
1607
1618
  throw new Error('Unknown type: ' + type)
1608
1619
  }
1609
1620
  };
1610
1621
 
1611
- const writeObject = this.useRecords === false ? this.variableMapSize ? (object) => {
1622
+ const writePlainObject = this.variableMapSize ? (object) => {
1612
1623
  // this method is slightly slower, but generates "preferred serialization" (optimally small for smaller objects)
1613
1624
  let keys = Object.keys(object);
1614
1625
  let length = keys.length;
@@ -1643,7 +1654,9 @@
1643
1654
  }
1644
1655
  target[objectOffset++ + start] = size >> 8;
1645
1656
  target[objectOffset + start] = size & 0xff;
1646
- } :
1657
+ };
1658
+
1659
+ const writeRecord = this.useRecords === false ? writePlainObject :
1647
1660
  (options.progressiveRecords && !useTwoByteRecords) ? // this is about 2% faster for highly stable structures, since it only requires one for-in loop (but much more expensive when new structure needs to be written)
1648
1661
  (object, safePrototype) => {
1649
1662
  let nextTransition, transition = structures.transitions || (structures.transitions = Object.create(null));
@@ -1715,6 +1728,14 @@
1715
1728
  if (safePrototype || object.hasOwnProperty(key))
1716
1729
  pack(object[key]);
1717
1730
  };
1731
+
1732
+ // craete reference to useRecords if useRecords is a function
1733
+ const checkUseRecords = typeof this.useRecords == 'function' && this.useRecords;
1734
+
1735
+ const writeObject = checkUseRecords ? (object, safePrototype) => {
1736
+ checkUseRecords(object) ? writeRecord(object,safePrototype) : writePlainObject(object,safePrototype);
1737
+ } : writeRecord;
1738
+
1718
1739
  const makeRoom = (end) => {
1719
1740
  let newSize;
1720
1741
  if (end > 0x1000000) {
@@ -1887,7 +1908,10 @@
1887
1908
  }
1888
1909
  }, {
1889
1910
  pack(set, allocateForWrite, pack) {
1890
- if (this.setAsEmptyObject) return pack({})
1911
+ if (this.setAsEmptyObject) {
1912
+ allocateForWrite(0);
1913
+ return pack({})
1914
+ }
1891
1915
  let array = Array.from(set);
1892
1916
  let { target, position} = allocateForWrite(this.moreTypes ? 3 : 0);
1893
1917
  if (this.moreTypes) {