msgpackr 2.0.0 → 2.0.2

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.
@@ -93,7 +93,7 @@
93
93
  currentUnpackr = this;
94
94
  if (this.structures) {
95
95
  currentStructures = this.structures;
96
- return checkedRead();
96
+ return checkedRead(options);
97
97
  } else if (!currentStructures || currentStructures.length > 0) {
98
98
  currentStructures = [];
99
99
  }
@@ -102,7 +102,7 @@
102
102
  if (!currentStructures || currentStructures.length > 0)
103
103
  currentStructures = [];
104
104
  }
105
- return checkedRead();
105
+ return checkedRead(options);
106
106
  }
107
107
  unpackMultiple(source, forEach) {
108
108
  let values, lastPosition = 0;
@@ -137,6 +137,8 @@
137
137
  }
138
138
  }
139
139
  _mergeStructures(loadedStructures, existingStructures) {
140
+ if (this._onLoadedStructures)
141
+ loadedStructures = this._onLoadedStructures(loadedStructures);
140
142
  loadedStructures = loadedStructures || [];
141
143
  if (Object.isFrozen(loadedStructures))
142
144
  loadedStructures = loadedStructures.map(structure => structure.slice(0));
@@ -173,7 +175,15 @@
173
175
  if (sharedLength < currentStructures.length)
174
176
  currentStructures.length = sharedLength;
175
177
  }
176
- let result = read();
178
+ let result;
179
+ if (currentUnpackr._readStruct && src[position$1] < 0x40 && src[position$1] >= 0x20) {
180
+ result = currentUnpackr._readStruct(src, position$1, srcEnd);
181
+ src = null; // dispose of this so that recursive unpack calls don't save state
182
+ if (!(options && options.lazy) && result)
183
+ result = result.toJSON();
184
+ position$1 = srcEnd;
185
+ } else
186
+ result = read();
177
187
  if (bundledStrings$1) { // bundled strings to skip past
178
188
  position$1 = bundledStrings$1.postBundlePosition;
179
189
  bundledStrings$1 = null;
@@ -1098,6 +1108,8 @@
1098
1108
  // currentExtensions[0x52] = () =>
1099
1109
 
1100
1110
  function saveState(callback) {
1111
+ if (currentUnpackr && currentUnpackr._onSaveState)
1112
+ currentUnpackr._onSaveState();
1101
1113
  let savedSrcEnd = srcEnd;
1102
1114
  let savedPosition = position$1;
1103
1115
  let savedSrcStringStart = srcStringStart;
@@ -1163,6 +1175,10 @@
1163
1175
  let multiplier = mult10[((u8Array[3] & 0x7f) << 1) | (u8Array[2] >> 7)];
1164
1176
  return ((multiplier * float32Number + (float32Number > 0 ? 0.5 : -0.5)) >> 0) / multiplier;
1165
1177
  }
1178
+ // Marker for downstream libraries (e.g. structon) to detect per-instance
1179
+ // struct-decoding hooks (this._readStruct, this._onLoadedStructures,
1180
+ // this._onSaveState). See `checkedRead` for the dispatch.
1181
+ Unpackr.SUPPORTS_STRUCT_HOOKS = true;
1166
1182
 
1167
1183
  let textEncoder;
1168
1184
  try {
@@ -1286,7 +1302,14 @@
1286
1302
  hasSharedUpdate = false;
1287
1303
  let encodingError;
1288
1304
  try {
1289
- pack(value);
1305
+ if (packr._writeStruct && value && typeof value === 'object') {
1306
+ if (value.constructor === Object) writeStruct(value); // simple object
1307
+ else if (value.constructor !== Map && !Array.isArray(value) && !extensionClasses.some(extClass => value instanceof extClass)) {
1308
+ // allow user classes, if they don't need special handling (but do use toJSON if available)
1309
+ writeStruct(value.toJSON ? value.toJSON() : value);
1310
+ } else pack(value);
1311
+ } else
1312
+ pack(value);
1290
1313
  let lastBundle = bundledStrings;
1291
1314
  if (bundledStrings)
1292
1315
  writeBundles(start, pack, 0);
@@ -1342,7 +1365,7 @@
1342
1365
  let sharedLength = structures.sharedLength || 0;
1343
1366
  // we can't rely on start/end with REUSE_BUFFER_MODE since they will (probably) change when we save
1344
1367
  let returnBuffer = target.subarray(start, position);
1345
- let newSharedData = prepareStructures(structures, packr);
1368
+ let newSharedData = (packr._prepareStructures || prepareStructures)(structures, packr);
1346
1369
  if (!encodingError) { // TODO: If there is an encoding error, should make the structures as uninitialized so they get rebuilt next time
1347
1370
  if (packr.saveStructures(newSharedData, newSharedData.isCompatible) === false) {
1348
1371
  // get updated structures and try again if the update failed
@@ -1511,7 +1534,7 @@
1511
1534
  } else if (type === 'number') {
1512
1535
  if (value >>> 0 === value) {// positive integer, 32-bit or less
1513
1536
  // positive uint
1514
- if (value < 0x40 || (value < 0x80 && this.useRecords === false)) {
1537
+ if (value < 0x20 || (value < 0x80 && this.useRecords === false) || (value < 0x40 && !this._writeStruct)) {
1515
1538
  target[position++] = value;
1516
1539
  } else if (value < 0x100) {
1517
1540
  target[position++] = 0xcc;
@@ -1902,6 +1925,24 @@
1902
1925
  checkUseRecords(object) ? writeRecord(object) : writePlainObject(object);
1903
1926
  } : writeRecord;
1904
1927
 
1928
+ const writeStruct = (object) => {
1929
+ let newPosition = packr._writeStruct(object, target, start, position, structures, makeRoom, (value, newPosition, notifySharedUpdate) => {
1930
+ if (notifySharedUpdate)
1931
+ return hasSharedUpdate = true;
1932
+ position = newPosition;
1933
+ let startTarget = target;
1934
+ pack(value);
1935
+ resetStructures();
1936
+ if (startTarget !== target) {
1937
+ return { position, targetView, target }; // indicate the buffer was re-allocated
1938
+ }
1939
+ return position;
1940
+ });
1941
+ if (newPosition === 0) // bail and go to a msgpack object
1942
+ return writeObject(object);
1943
+ position = newPosition;
1944
+ };
1945
+
1905
1946
  const makeRoom = (end) => {
1906
1947
  let newSize;
1907
1948
  if (end > 0x1000000) {
@@ -2021,6 +2062,8 @@
2021
2062
  clearSharedData() {
2022
2063
  if (this.structures)
2023
2064
  this.structures = [];
2065
+ if (this.typedStructs)
2066
+ this.typedStructs = [];
2024
2067
  }
2025
2068
  }
2026
2069
 
@@ -2262,6 +2305,11 @@
2262
2305
  return structures;
2263
2306
  }
2264
2307
 
2308
+ // Marker for downstream libraries (e.g. structon) to detect that this Packr
2309
+ // supports per-instance struct-encoding hooks (this._writeStruct,
2310
+ // this._prepareStructures). See `pack` for the dispatch.
2311
+ Packr.SUPPORTS_STRUCT_HOOKS = true;
2312
+
2265
2313
  let defaultPackr = new Packr({ useRecords: false });
2266
2314
  const pack = defaultPackr.pack;
2267
2315
  const encode = defaultPackr.pack;