msgpackr 1.7.0 → 1.7.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.
package/dist/test.js CHANGED
@@ -190,7 +190,7 @@
190
190
 
191
191
  if (position == srcEnd) {
192
192
  // finished reading this source, cleanup references
193
- if (currentStructures?.restoreStructures)
193
+ if (currentStructures && currentStructures.restoreStructures)
194
194
  restoreStructures();
195
195
  currentStructures = null;
196
196
  src = null;
@@ -205,7 +205,7 @@
205
205
  // else more to read, but we are reading sequentially, so don't clear source yet
206
206
  return result
207
207
  } catch(error) {
208
- if (currentStructures?.restoreStructures)
208
+ if (currentStructures && currentStructures.restoreStructures)
209
209
  restoreStructures();
210
210
  clearSource();
211
211
  if (error instanceof RangeError || error.message.startsWith('Unexpected end of buffer') || position > srcEnd) {
@@ -826,7 +826,7 @@
826
826
  })
827
827
  }
828
828
  else
829
- throw new Error('Unknown extension type ' + type)
829
+ throw new Error('Unknown extension type ' + type)``
830
830
  }
831
831
 
832
832
  var keyCache = new Array(4096);
@@ -841,7 +841,7 @@
841
841
  return readFixedString(length)
842
842
  } else { // not cacheable, go back and do a standard read
843
843
  position--;
844
- return read()
844
+ return read().toString()
845
845
  }
846
846
  let key = ((length << 5) ^ (length > 1 ? dataView.getUint16(position) : length > 0 ? src[position] : 0)) & 0xfff;
847
847
  let entry = keyCache[key];
@@ -895,16 +895,7 @@
895
895
 
896
896
  // the registration of the record definition extension (as "r")
897
897
  const recordDefinition = (id, highByte) => {
898
- let structure;
899
- if (currentUnpackr.freezeData) {
900
- currentUnpackr.freezeData = false;
901
- try {
902
- structure = read();
903
- } finally {
904
- currentUnpackr.freezeData = true;
905
- }
906
- } else
907
- structure = read();
898
+ let structure = read().map(property => property.toString()); // ensure that all keys are strings and that the array is mutable
908
899
  let firstByte = id;
909
900
  if (highByte !== undefined) {
910
901
  id = id < 32 ? -((highByte << 5) + id) : ((highByte << 5) + id);
@@ -1180,19 +1171,45 @@
1180
1171
  writeStruct(value);
1181
1172
  else
1182
1173
  pack(value);
1183
- if (bundledStrings$1) {
1184
- writeBundles(start, pack);
1185
- }
1186
- packr.offset = position$1; // update the offset so next serialization doesn't write over our buffer, but can continue writing to same buffer sequentially
1174
+ let lastBundle = bundledStrings$1;
1175
+ if (bundledStrings$1)
1176
+ writeBundles(start, pack, 0);
1187
1177
  if (referenceMap && referenceMap.idsToInsert) {
1188
- position$1 += referenceMap.idsToInsert.length * 6;
1178
+ let idsToInsert = referenceMap.idsToInsert.sort((a, b) => a.offset > b.offset ? 1 : -1);
1179
+ let i = idsToInsert.length;
1180
+ let incrementPosition = -1;
1181
+ while (lastBundle && i > 0) {
1182
+ let insertionPoint = idsToInsert[--i].offset + start;
1183
+ if (insertionPoint < (lastBundle.stringsPosition + start) && incrementPosition === -1)
1184
+ incrementPosition = 0;
1185
+ if (insertionPoint > (lastBundle.position + start)) {
1186
+ if (incrementPosition >= 0)
1187
+ incrementPosition += 6;
1188
+ } else {
1189
+ if (incrementPosition >= 0) {
1190
+ // update the bundle reference now
1191
+ targetView.setUint32(lastBundle.position + start,
1192
+ targetView.getUint32(lastBundle.position + start) + incrementPosition);
1193
+ incrementPosition = -1; // reset
1194
+ }
1195
+ lastBundle = lastBundle.previous;
1196
+ i++;
1197
+ }
1198
+ }
1199
+ if (incrementPosition >= 0 && lastBundle) {
1200
+ // update the bundle reference now
1201
+ targetView.setUint32(lastBundle.position + start,
1202
+ targetView.getUint32(lastBundle.position + start) + incrementPosition);
1203
+ }
1204
+ position$1 += idsToInsert.length * 6;
1189
1205
  if (position$1 > safeEnd)
1190
1206
  makeRoom(position$1);
1191
1207
  packr.offset = position$1;
1192
- let serialized = insertIds(target.subarray(start, position$1), referenceMap.idsToInsert);
1208
+ let serialized = insertIds(target.subarray(start, position$1), idsToInsert);
1193
1209
  referenceMap = null;
1194
1210
  return serialized
1195
1211
  }
1212
+ packr.offset = position$1; // update the offset so next serialization doesn't write over our buffer, but can continue writing to same buffer sequentially
1196
1213
  if (encodeOptions & REUSE_BUFFER_MODE) {
1197
1214
  target.start = start;
1198
1215
  target.end = position$1;
@@ -1249,13 +1266,15 @@
1249
1266
  let maxBytes = (bundledStrings$1[0] ? bundledStrings$1[0].length * 3 + bundledStrings$1[1].length : 0) + 10;
1250
1267
  if (position$1 + maxBytes > safeEnd)
1251
1268
  target = makeRoom(position$1 + maxBytes);
1252
- if (bundledStrings$1.position) { // here we use the 0x62 extension to write the last bundle and reserve sapce for the reference pointer to the next/current bundle
1269
+ let lastBundle;
1270
+ if (bundledStrings$1.position) { // here we use the 0x62 extension to write the last bundle and reserve space for the reference pointer to the next/current bundle
1271
+ lastBundle = bundledStrings$1;
1253
1272
  target[position$1] = 0xc8; // ext 16
1254
1273
  position$1 += 3; // reserve for the writing bundle size
1255
1274
  target[position$1++] = 0x62; // 'b'
1256
1275
  extStart = position$1 - start;
1257
1276
  position$1 += 4; // reserve for writing bundle reference
1258
- writeBundles(start, pack); // write the last bundles
1277
+ writeBundles(start, pack, 0); // write the last bundles
1259
1278
  targetView.setUint16(extStart + start - 3, position$1 - start - extStart);
1260
1279
  } else { // here we use the 0x62 extension just to reserve the space for the reference pointer to the bundle (will be updated once the bundle is written)
1261
1280
  target[position$1++] = 0xd6; // fixext 4
@@ -1264,6 +1283,7 @@
1264
1283
  position$1 += 4; // reserve for writing bundle reference
1265
1284
  }
1266
1285
  bundledStrings$1 = ['', '']; // create new ones
1286
+ bundledStrings$1.previous = lastBundle;
1267
1287
  bundledStrings$1.size = 0;
1268
1288
  bundledStrings$1.position = extStart;
1269
1289
  }
@@ -1953,7 +1973,6 @@
1953
1973
  let nextId;
1954
1974
  let distanceToMove = idsToInsert.length * 6;
1955
1975
  let lastEnd = serialized.length - distanceToMove;
1956
- idsToInsert.sort((a, b) => a.offset > b.offset ? 1 : -1);
1957
1976
  while (nextId = idsToInsert.pop()) {
1958
1977
  let offset = nextId.offset;
1959
1978
  let id = nextId.id;
@@ -1971,9 +1990,10 @@
1971
1990
  return serialized
1972
1991
  }
1973
1992
 
1974
- function writeBundles(start, pack) {
1993
+ function writeBundles(start, pack, incrementPosition) {
1975
1994
  if (bundledStrings$1.length > 0) {
1976
- targetView.setUint32(bundledStrings$1.position + start, position$1 - bundledStrings$1.position - start);
1995
+ targetView.setUint32(bundledStrings$1.position + start, position$1 + incrementPosition - bundledStrings$1.position - start);
1996
+ bundledStrings$1.stringsPosition = position$1 - start;
1977
1997
  let writeStrings = bundledStrings$1;
1978
1998
  bundledStrings$1 = null;
1979
1999
  pack(writeStrings[0]);
@@ -2450,7 +2470,7 @@
2450
2470
  case 27: recordId = src[position++] + (src[position++] << 8) + (src[position++] << 16) + (src[position++] << 24); break;
2451
2471
  }
2452
2472
  }
2453
- let structure = unpackr.typedStructs?.[recordId];
2473
+ let structure = unpackr.typedStructs && unpackr.typedStructs[recordId];
2454
2474
  if (!structure) {
2455
2475
  // copy src buffer because getStructures will override it
2456
2476
  src = Uint8Array.prototype.slice.call(src, position, srcEnd);
@@ -2742,7 +2762,7 @@
2742
2762
  packr._mergeStructures(existing);
2743
2763
  return compatible;
2744
2764
  };
2745
- packr.lastTypedStructuresLength = packr.typedStructs?.length;
2765
+ packr.lastTypedStructuresLength = packr.typedStructs && packr.typedStructs.length;
2746
2766
  return structures;
2747
2767
  }
2748
2768
 
@@ -3159,6 +3179,47 @@
3159
3179
  assert.equal(deserialized.uint16Array[0], 3);
3160
3180
  assert.equal(deserialized.uint16Array[1], 4);
3161
3181
  });
3182
+ test('big bundledStrings', function() {
3183
+ const MSGPACK_OPTIONS = {bundleStrings: true};
3184
+ const packer = new Packr$1(MSGPACK_OPTIONS);
3185
+ const unpacker = new Unpackr$1(MSGPACK_OPTIONS);
3186
+
3187
+ const payload = {
3188
+ output: [
3189
+ {
3190
+ url: 'https://www.example.com/',
3191
+ },
3192
+ ],
3193
+ };
3194
+
3195
+ for (let i = 0; i < 10000; i++) {
3196
+ payload.output.push(payload.output[0]);
3197
+ }
3198
+ let deserialized = unpacker.unpack(packer.pack(payload));
3199
+ assert.equal(deserialized.output[0].url, payload.output[0].url);
3200
+ });
3201
+ test('structured clone with bundled strings', function() {
3202
+ const packer = new Packr$1({
3203
+ structuredClone: true, // both options must be enabled
3204
+ bundleStrings: true,
3205
+ });
3206
+
3207
+ const v = {};
3208
+
3209
+ let shared = {
3210
+ name1: v,
3211
+ name2: v,
3212
+ };
3213
+
3214
+ let deserialized = packer.unpack(packer.pack(shared));
3215
+ assert.equal(deserialized.name1, deserialized.name2);
3216
+
3217
+ shared = {};
3218
+ shared.aaaa = shared; // key length >= 4
3219
+
3220
+ deserialized = packer.unpack(packer.pack(shared));
3221
+ assert.equal(deserialized.aaaa, deserialized);
3222
+ });
3162
3223
 
3163
3224
  test('object without prototype', function(){
3164
3225
  var data = Object.create(null);