msgpackr 1.9.2 → 1.9.4

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
@@ -984,10 +984,10 @@
984
984
  currentExtensions[0] = () => {}; // notepack defines extension 0 to mean undefined, so use that as the default here
985
985
  currentExtensions[0].noBuffer = true;
986
986
 
987
- let glbl = typeof globalThis === 'object' ? globalThis : window;
987
+ let errors = { Error, TypeError, ReferenceError };
988
988
  currentExtensions[0x65] = () => {
989
989
  let data = read();
990
- return (glbl[data[0]] || Error)(data[1])
990
+ return (errors[data[0]] || Error)(data[1])
991
991
  };
992
992
 
993
993
  currentExtensions[0x69] = (data) => {
@@ -1025,6 +1025,7 @@
1025
1025
 
1026
1026
  const typedArrays = ['Int8','Uint8','Uint8Clamped','Int16','Uint16','Int32','Uint32','Float32','Float64','BigInt64','BigUint64'].map(type => type + 'Array');
1027
1027
 
1028
+ let glbl = typeof globalThis === 'object' ? globalThis : window;
1028
1029
  currentExtensions[0x74] = (data) => {
1029
1030
  let typeCode = data[0];
1030
1031
  let typedArrayName = typedArrays[typeCode];
@@ -1529,7 +1530,7 @@
1529
1530
  targetView.setFloat64(position, value);
1530
1531
  position += 8;
1531
1532
  }
1532
- } else if (type === 'object') {
1533
+ } else if (type === 'object' || type === 'function') {
1533
1534
  if (!value)
1534
1535
  target[position++] = 0xc0;
1535
1536
  else {
@@ -1636,6 +1637,11 @@
1636
1637
  } else {
1637
1638
  if (value.toJSON) // use this as an alternate mechanism for expressing how to serialize
1638
1639
  return pack(value.toJSON());
1640
+
1641
+ // if there is a writeFunction, use it, otherwise just encode as undefined
1642
+ if (type === 'function')
1643
+ return pack(this.writeFunction && this.writeFunction(value));
1644
+
1639
1645
  // no extension found, write as object
1640
1646
  writeObject(value, !value.hasOwnProperty); // if it doesn't have hasOwnProperty, don't do hasOwnProperty checks
1641
1647
  }
@@ -1670,14 +1676,12 @@
1670
1676
  target[position++] = 0;
1671
1677
  target[position++] = 0;
1672
1678
  }
1673
- } else if (type === 'function') {
1674
- pack(this.writeFunction && this.writeFunction()); // if there is a writeFunction, use it, otherwise just encode as undefined
1675
1679
  } else {
1676
1680
  throw new Error('Unknown type: ' + type)
1677
1681
  }
1678
1682
  };
1679
1683
 
1680
- const writeObject = this.useRecords === false ? this.variableMapSize ? (object) => {
1684
+ const writePlainObject = (this.variableMapSize || this.coercibleKeyAsNumber) ? (object) => {
1681
1685
  // this method is slightly slower, but generates "preferred serialization" (optimally small for smaller objects)
1682
1686
  let keys = Object.keys(object);
1683
1687
  let length = keys.length;
@@ -1693,9 +1697,19 @@
1693
1697
  position += 4;
1694
1698
  }
1695
1699
  let key;
1696
- for (let i = 0; i < length; i++) {
1697
- pack(key = keys[i]);
1698
- pack(object[key]);
1700
+ if (this.coercibleKeyAsNumber) {
1701
+ for (let i = 0; i < length; i++) {
1702
+ key = keys[i];
1703
+ let num = Number(key);
1704
+ pack(isNaN(num) ? key : num);
1705
+ pack(object[key]);
1706
+ }
1707
+
1708
+ } else {
1709
+ for (let i = 0; i < length; i++) {
1710
+ pack(key = keys[i]);
1711
+ pack(object[key]);
1712
+ }
1699
1713
  }
1700
1714
  } :
1701
1715
  (object, safePrototype) => {
@@ -1712,7 +1726,9 @@
1712
1726
  }
1713
1727
  target[objectOffset++ + start] = size >> 8;
1714
1728
  target[objectOffset + start] = size & 0xff;
1715
- } :
1729
+ };
1730
+
1731
+ const writeRecord = this.useRecords === false ? writePlainObject :
1716
1732
  (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)
1717
1733
  (object, safePrototype) => {
1718
1734
  let nextTransition, transition = structures.transitions || (structures.transitions = Object.create(null));
@@ -1784,6 +1800,14 @@
1784
1800
  if (safePrototype || object.hasOwnProperty(key))
1785
1801
  pack(object[key]);
1786
1802
  };
1803
+
1804
+ // craete reference to useRecords if useRecords is a function
1805
+ const checkUseRecords = typeof this.useRecords == 'function' && this.useRecords;
1806
+
1807
+ const writeObject = checkUseRecords ? (object, safePrototype) => {
1808
+ checkUseRecords(object) ? writeRecord(object,safePrototype) : writePlainObject(object,safePrototype);
1809
+ } : writeRecord;
1810
+
1787
1811
  const makeRoom = (end) => {
1788
1812
  let newSize;
1789
1813
  if (end > 0x1000000) {
@@ -3159,8 +3183,30 @@
3159
3183
  var deserialized = packr.unpack(serialized);
3160
3184
  assert.deepEqual(deserialized, data);
3161
3185
  });
3162
-
3163
3186
  }
3187
+
3188
+ test('pack/unpack sample data with useRecords function', function () {
3189
+ var data = [
3190
+ {id: 1, type: 1, labels: {a: 1, b: 2}},
3191
+ {id: 2, type: 1, labels: {b: 1, c: 2}},
3192
+ {id: 3, type: 1, labels: {d: 1, e: 2}}
3193
+ ];
3194
+
3195
+ var alternatives = [
3196
+ {useRecords: false}, // 88 bytes
3197
+ {useRecords: true}, // 58 bytes
3198
+ {mapsAsObjects: true, useRecords: (v)=>!!v.id}, // 55 bytes
3199
+ {mapsAsObjects: true, variableMapSize: true, useRecords: (v)=>!!v.id} // 49 bytes
3200
+ ];
3201
+
3202
+ for(let o of alternatives) {
3203
+ let packr = new Packr(o);
3204
+ var serialized = packr.pack(data);
3205
+ var deserialized = packr.unpack(serialized);
3206
+ assert.deepEqual(deserialized, data);
3207
+ }
3208
+ });
3209
+
3164
3210
  test('mapAsEmptyObject combination', function () {
3165
3211
  const msgpackr = new Packr({ useRecords: false, encodeUndefinedAsNil: true, variableMapSize: true, mapAsEmptyObject: true, setAsEmptyObject: true });
3166
3212
 
@@ -3177,6 +3223,13 @@
3177
3223
  assert.deepEqual(unpacked.map, {});
3178
3224
  assert.deepEqual(unpacked.set, {});
3179
3225
  });
3226
+ test('pack/unpack numeric coercible keys', function () {
3227
+ var data = { a: 1, 2: 'test', '-3.45': 'test2'};
3228
+ let packr = new Packr({variableMapSize: true, coercibleKeyAsNumber: true, useRecords: false});
3229
+ var serialized = packr.pack(data);
3230
+ var deserialized = packr.unpack(serialized);
3231
+ assert.deepEqual(deserialized, data);
3232
+ });
3180
3233
  test('pack/unpack empty data with bundled strings', function () {
3181
3234
  var data = {};
3182
3235
  let packr = new Packr({bundleStrings: true});
@@ -3337,7 +3390,6 @@
3337
3390
  assert.deepEqual(data, deserialized);
3338
3391
  });
3339
3392
 
3340
-
3341
3393
  test('unregistered extended Array class read/write', function(){
3342
3394
  var instance = new ExtendArray2();
3343
3395
  instance.push(0);
@@ -3490,6 +3542,58 @@
3490
3542
  assert.equal(deserialized.extendedInstance[0], 0);
3491
3543
  });
3492
3544
 
3545
+ test('extended class pack/unpack proxied', function(){
3546
+ function Extended() {
3547
+
3548
+ }
3549
+ Extended.prototype.__call__ = function(){
3550
+ return this.value * 4
3551
+ };
3552
+ Extended.prototype.getDouble = function() {
3553
+ return this.value * 2
3554
+ };
3555
+
3556
+ var instance = function() { instance.__call__();/* callable stuff */ };
3557
+ Object.setPrototypeOf(instance,Extended.prototype);
3558
+
3559
+ instance.value = 4;
3560
+ var data = instance;
3561
+
3562
+ let packr = new Packr();
3563
+ addExtension({
3564
+ Class: Extended,
3565
+ type: 15,
3566
+ unpack: function(buffer) {
3567
+ var e = function() { e.__call__(); };
3568
+ Object.setPrototypeOf(e,Extended.prototype);
3569
+ e.value = packr.unpack(buffer);
3570
+ return e
3571
+ },
3572
+ pack: function(instance) {
3573
+ return packr.pack(instance.value)
3574
+ }
3575
+ });
3576
+ var serialized = pack(data);
3577
+ var deserialized = unpack(serialized);
3578
+ assert.equal(deserialized.getDouble(), 8);
3579
+ });
3580
+
3581
+ test.skip('convert Date to string', function(){
3582
+ var data = {
3583
+ aDate: new Date(),
3584
+ };
3585
+ new Packr();
3586
+ addExtension({
3587
+ Class: Date,
3588
+ write(date) {
3589
+ return date.toString()
3590
+ }
3591
+ });
3592
+ var serialized = pack(data);
3593
+ var deserialized = unpack(serialized);
3594
+ assert.equal(deserialized.aDate, data.aDate.toString());
3595
+ });
3596
+
3493
3597
  test('proto handling', function() {
3494
3598
  var objectWithProto = JSON.parse('{"__proto__":{"foo":3}}');
3495
3599
  var decoded = unpack(pack(objectWithProto));