msgpackr 1.7.1 → 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
@@ -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,20 +1171,44 @@
1180
1171
  writeStruct(value);
1181
1172
  else
1182
1173
  pack(value);
1174
+ let lastBundle = bundledStrings$1;
1175
+ if (bundledStrings$1)
1176
+ writeBundles(start, pack, 0);
1183
1177
  if (referenceMap && referenceMap.idsToInsert) {
1184
- let incrementPosition = referenceMap.idsToInsert.length * 6;
1185
- if (bundledStrings$1)
1186
- writeBundles(start, pack, incrementPosition);
1187
- position$1 += incrementPosition;
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;
1188
1205
  if (position$1 > safeEnd)
1189
1206
  makeRoom(position$1);
1190
1207
  packr.offset = position$1;
1191
- let serialized = insertIds(target.subarray(start, position$1), referenceMap.idsToInsert);
1208
+ let serialized = insertIds(target.subarray(start, position$1), idsToInsert);
1192
1209
  referenceMap = null;
1193
1210
  return serialized
1194
1211
  }
1195
- if (bundledStrings$1)
1196
- writeBundles(start, pack, 0);
1197
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
1198
1213
  if (encodeOptions & REUSE_BUFFER_MODE) {
1199
1214
  target.start = start;
@@ -1251,13 +1266,15 @@
1251
1266
  let maxBytes = (bundledStrings$1[0] ? bundledStrings$1[0].length * 3 + bundledStrings$1[1].length : 0) + 10;
1252
1267
  if (position$1 + maxBytes > safeEnd)
1253
1268
  target = makeRoom(position$1 + maxBytes);
1254
- 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;
1255
1272
  target[position$1] = 0xc8; // ext 16
1256
1273
  position$1 += 3; // reserve for the writing bundle size
1257
1274
  target[position$1++] = 0x62; // 'b'
1258
1275
  extStart = position$1 - start;
1259
1276
  position$1 += 4; // reserve for writing bundle reference
1260
- writeBundles(start, pack); // write the last bundles
1277
+ writeBundles(start, pack, 0); // write the last bundles
1261
1278
  targetView.setUint16(extStart + start - 3, position$1 - start - extStart);
1262
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)
1263
1280
  target[position$1++] = 0xd6; // fixext 4
@@ -1266,6 +1283,7 @@
1266
1283
  position$1 += 4; // reserve for writing bundle reference
1267
1284
  }
1268
1285
  bundledStrings$1 = ['', '']; // create new ones
1286
+ bundledStrings$1.previous = lastBundle;
1269
1287
  bundledStrings$1.size = 0;
1270
1288
  bundledStrings$1.position = extStart;
1271
1289
  }
@@ -1955,7 +1973,6 @@
1955
1973
  let nextId;
1956
1974
  let distanceToMove = idsToInsert.length * 6;
1957
1975
  let lastEnd = serialized.length - distanceToMove;
1958
- idsToInsert.sort((a, b) => a.offset > b.offset ? 1 : -1);
1959
1976
  while (nextId = idsToInsert.pop()) {
1960
1977
  let offset = nextId.offset;
1961
1978
  let id = nextId.id;
@@ -1976,6 +1993,7 @@
1976
1993
  function writeBundles(start, pack, incrementPosition) {
1977
1994
  if (bundledStrings$1.length > 0) {
1978
1995
  targetView.setUint32(bundledStrings$1.position + start, position$1 + incrementPosition - bundledStrings$1.position - start);
1996
+ bundledStrings$1.stringsPosition = position$1 - start;
1979
1997
  let writeStrings = bundledStrings$1;
1980
1998
  bundledStrings$1 = null;
1981
1999
  pack(writeStrings[0]);
@@ -3161,7 +3179,25 @@
3161
3179
  assert.equal(deserialized.uint16Array[0], 3);
3162
3180
  assert.equal(deserialized.uint16Array[1], 4);
3163
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
+ };
3164
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
+ });
3165
3201
  test('structured clone with bundled strings', function() {
3166
3202
  const packer = new Packr$1({
3167
3203
  structuredClone: true, // both options must be enabled
@@ -3170,13 +3206,19 @@
3170
3206
 
3171
3207
  const v = {};
3172
3208
 
3173
- const shared = {
3209
+ let shared = {
3174
3210
  name1: v,
3175
- name2: v, // one key has to be named `data`
3211
+ name2: v,
3176
3212
  };
3177
3213
 
3178
3214
  let deserialized = packer.unpack(packer.pack(shared));
3179
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);
3180
3222
  });
3181
3223
 
3182
3224
  test('object without prototype', function(){