msgpackr 2.0.0 → 2.0.1

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/node.cjs CHANGED
@@ -96,7 +96,7 @@ class Unpackr {
96
96
  currentUnpackr = this;
97
97
  if (this.structures) {
98
98
  currentStructures = this.structures;
99
- return checkedRead();
99
+ return checkedRead(options);
100
100
  } else if (!currentStructures || currentStructures.length > 0) {
101
101
  currentStructures = [];
102
102
  }
@@ -105,7 +105,7 @@ class Unpackr {
105
105
  if (!currentStructures || currentStructures.length > 0)
106
106
  currentStructures = [];
107
107
  }
108
- return checkedRead();
108
+ return checkedRead(options);
109
109
  }
110
110
  unpackMultiple(source, forEach) {
111
111
  let values, lastPosition = 0;
@@ -140,6 +140,8 @@ class Unpackr {
140
140
  }
141
141
  }
142
142
  _mergeStructures(loadedStructures, existingStructures) {
143
+ if (this._onLoadedStructures)
144
+ loadedStructures = this._onLoadedStructures(loadedStructures);
143
145
  loadedStructures = loadedStructures || [];
144
146
  if (Object.isFrozen(loadedStructures))
145
147
  loadedStructures = loadedStructures.map(structure => structure.slice(0));
@@ -176,7 +178,15 @@ function checkedRead(options) {
176
178
  if (sharedLength < currentStructures.length)
177
179
  currentStructures.length = sharedLength;
178
180
  }
179
- let result = read();
181
+ let result;
182
+ if (currentUnpackr._readStruct && src[position$1] < 0x40 && src[position$1] >= 0x20) {
183
+ result = currentUnpackr._readStruct(src, position$1, srcEnd);
184
+ src = null; // dispose of this so that recursive unpack calls don't save state
185
+ if (!(options && options.lazy) && result)
186
+ result = result.toJSON();
187
+ position$1 = srcEnd;
188
+ } else
189
+ result = read();
180
190
  if (bundledStrings$1) { // bundled strings to skip past
181
191
  position$1 = bundledStrings$1.postBundlePosition;
182
192
  bundledStrings$1 = null;
@@ -1141,6 +1151,8 @@ currentExtensions[0xff] = (data) => {
1141
1151
  // currentExtensions[0x52] = () =>
1142
1152
 
1143
1153
  function saveState(callback) {
1154
+ if (currentUnpackr && currentUnpackr._onSaveState)
1155
+ currentUnpackr._onSaveState();
1144
1156
  let savedSrcEnd = srcEnd;
1145
1157
  let savedPosition = position$1;
1146
1158
  let savedStringPosition = stringPosition;
@@ -1210,6 +1222,10 @@ function roundFloat32(float32Number) {
1210
1222
  let multiplier = mult10[((u8Array[3] & 0x7f) << 1) | (u8Array[2] >> 7)];
1211
1223
  return ((multiplier * float32Number + (float32Number > 0 ? 0.5 : -0.5)) >> 0) / multiplier;
1212
1224
  }
1225
+ // Marker for downstream libraries (e.g. structon) to detect per-instance
1226
+ // struct-decoding hooks (this._readStruct, this._onLoadedStructures,
1227
+ // this._onSaveState). See `checkedRead` for the dispatch.
1228
+ Unpackr.SUPPORTS_STRUCT_HOOKS = true;
1213
1229
 
1214
1230
  let textEncoder;
1215
1231
  try {
@@ -1333,7 +1349,14 @@ class Packr extends Unpackr {
1333
1349
  hasSharedUpdate = false;
1334
1350
  let encodingError;
1335
1351
  try {
1336
- pack(value);
1352
+ if (packr._writeStruct && value && typeof value === 'object') {
1353
+ if (value.constructor === Object) writeStruct(value); // simple object
1354
+ else if (value.constructor !== Map && !Array.isArray(value) && !extensionClasses.some(extClass => value instanceof extClass)) {
1355
+ // allow user classes, if they don't need special handling (but do use toJSON if available)
1356
+ writeStruct(value.toJSON ? value.toJSON() : value);
1357
+ } else pack(value);
1358
+ } else
1359
+ pack(value);
1337
1360
  let lastBundle = bundledStrings;
1338
1361
  if (bundledStrings)
1339
1362
  writeBundles(start, pack, 0);
@@ -1389,7 +1412,7 @@ class Packr extends Unpackr {
1389
1412
  let sharedLength = structures.sharedLength || 0;
1390
1413
  // we can't rely on start/end with REUSE_BUFFER_MODE since they will (probably) change when we save
1391
1414
  let returnBuffer = target.subarray(start, position);
1392
- let newSharedData = prepareStructures(structures, packr);
1415
+ let newSharedData = (packr._prepareStructures || prepareStructures)(structures, packr);
1393
1416
  if (!encodingError) { // TODO: If there is an encoding error, should make the structures as uninitialized so they get rebuilt next time
1394
1417
  if (packr.saveStructures(newSharedData, newSharedData.isCompatible) === false) {
1395
1418
  // get updated structures and try again if the update failed
@@ -1558,7 +1581,7 @@ class Packr extends Unpackr {
1558
1581
  } else if (type === 'number') {
1559
1582
  if (value >>> 0 === value) {// positive integer, 32-bit or less
1560
1583
  // positive uint
1561
- if (value < 0x40 || (value < 0x80 && this.useRecords === false)) {
1584
+ if (value < 0x20 || (value < 0x80 && this.useRecords === false) || (value < 0x40 && !this._writeStruct)) {
1562
1585
  target[position++] = value;
1563
1586
  } else if (value < 0x100) {
1564
1587
  target[position++] = 0xcc;
@@ -1949,6 +1972,24 @@ class Packr extends Unpackr {
1949
1972
  checkUseRecords(object) ? writeRecord(object) : writePlainObject(object);
1950
1973
  } : writeRecord;
1951
1974
 
1975
+ const writeStruct = (object) => {
1976
+ let newPosition = packr._writeStruct(object, target, start, position, structures, makeRoom, (value, newPosition, notifySharedUpdate) => {
1977
+ if (notifySharedUpdate)
1978
+ return hasSharedUpdate = true;
1979
+ position = newPosition;
1980
+ let startTarget = target;
1981
+ pack(value);
1982
+ resetStructures();
1983
+ if (startTarget !== target) {
1984
+ return { position, targetView, target }; // indicate the buffer was re-allocated
1985
+ }
1986
+ return position;
1987
+ });
1988
+ if (newPosition === 0) // bail and go to a msgpack object
1989
+ return writeObject(object);
1990
+ position = newPosition;
1991
+ };
1992
+
1952
1993
  const makeRoom = (end) => {
1953
1994
  let newSize;
1954
1995
  if (end > 0x1000000) {
@@ -2068,6 +2109,8 @@ class Packr extends Unpackr {
2068
2109
  clearSharedData() {
2069
2110
  if (this.structures)
2070
2111
  this.structures = [];
2112
+ if (this.typedStructs)
2113
+ this.typedStructs = [];
2071
2114
  }
2072
2115
  }
2073
2116
 
@@ -2309,6 +2352,11 @@ function prepareStructures(structures, packr) {
2309
2352
  return structures;
2310
2353
  }
2311
2354
 
2355
+ // Marker for downstream libraries (e.g. structon) to detect that this Packr
2356
+ // supports per-instance struct-encoding hooks (this._writeStruct,
2357
+ // this._prepareStructures). See `pack` for the dispatch.
2358
+ Packr.SUPPORTS_STRUCT_HOOKS = true;
2359
+
2312
2360
  let defaultPackr = new Packr({ useRecords: false });
2313
2361
  const pack = defaultPackr.pack;
2314
2362
  const encode = defaultPackr.pack;