msgpackr 1.8.0 → 1.8.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
@@ -118,7 +118,7 @@
118
118
  let size = source.length;
119
119
  let value = this ? this.unpack(source, size) : defaultUnpackr.unpack(source, size);
120
120
  if (forEach) {
121
- forEach(value);
121
+ if (forEach(value) === false) return;
122
122
  while(position$1 < size) {
123
123
  lastPosition = position$1;
124
124
  if (forEach(checkedRead()) === false) {
@@ -1168,7 +1168,7 @@
1168
1168
  if (maxSharedStructures > 8160)
1169
1169
  throw new Error('Maximum maxSharedStructure is 8160')
1170
1170
  if (options.structuredClone && options.moreTypes == undefined) {
1171
- options.moreTypes = true;
1171
+ this.moreTypes = true;
1172
1172
  }
1173
1173
  let maxOwnStructures = options.maxOwnStructures;
1174
1174
  if (maxOwnStructures == null)
@@ -1329,6 +1329,23 @@
1329
1329
  position = start;
1330
1330
  }
1331
1331
  };
1332
+ const packArray = (value) => {
1333
+ var length = value.length;
1334
+ if (length < 0x10) {
1335
+ target[position++] = 0x90 | length;
1336
+ } else if (length < 0x10000) {
1337
+ target[position++] = 0xdc;
1338
+ target[position++] = length >> 8;
1339
+ target[position++] = length & 0xff;
1340
+ } else {
1341
+ target[position++] = 0xdd;
1342
+ targetView.setUint32(position, length);
1343
+ position += 4;
1344
+ }
1345
+ for (let i = 0; i < length; i++) {
1346
+ pack(value[i]);
1347
+ }
1348
+ };
1332
1349
  const pack = (value) => {
1333
1350
  if (position > safeEnd)
1334
1351
  target = makeRoom(position);
@@ -1511,22 +1528,8 @@
1511
1528
  let constructor = value.constructor;
1512
1529
  if (constructor === Object) {
1513
1530
  writeObject(value, true);
1514
- } else if (constructor === Array || Array.isArray(value)) {
1515
- length = value.length;
1516
- if (length < 0x10) {
1517
- target[position++] = 0x90 | length;
1518
- } else if (length < 0x10000) {
1519
- target[position++] = 0xdc;
1520
- target[position++] = length >> 8;
1521
- target[position++] = length & 0xff;
1522
- } else {
1523
- target[position++] = 0xdd;
1524
- targetView.setUint32(position, length);
1525
- position += 4;
1526
- }
1527
- for (let i = 0; i < length; i++) {
1528
- pack(value[i]);
1529
- }
1531
+ } else if (constructor === Array) {
1532
+ packArray(value);
1530
1533
  } else if (constructor === Map) {
1531
1534
  length = value.size;
1532
1535
  if (length < 0x10) {
@@ -1555,7 +1558,16 @@
1555
1558
  target[position++] = extension.type;
1556
1559
  target[position++] = 0;
1557
1560
  }
1558
- pack(extension.write.call(this, value));
1561
+ let writeResult = extension.write.call(this, value);
1562
+ if (writeResult === value) { // avoid infinite recursion
1563
+ if (Array.isArray(value)) {
1564
+ packArray(value);
1565
+ } else {
1566
+ writeObject(value);
1567
+ }
1568
+ } else {
1569
+ pack(writeResult);
1570
+ }
1559
1571
  return
1560
1572
  }
1561
1573
  let currentTarget = target;
@@ -1592,8 +1604,13 @@
1592
1604
  return
1593
1605
  }
1594
1606
  }
1595
- // no extension found, write as object
1596
- writeObject(value, !value.hasOwnProperty); // if it doesn't have hasOwnProperty, don't do hasOwnProperty checks
1607
+ // check isArray after extensions, because extensions can extend Array
1608
+ if (Array.isArray(value)) {
1609
+ packArray(value);
1610
+ } else {
1611
+ // no extension found, write as object
1612
+ writeObject(value, !value.hasOwnProperty); // if it doesn't have hasOwnProperty, don't do hasOwnProperty checks
1613
+ }
1597
1614
  }
1598
1615
  }
1599
1616
  } else if (type === 'boolean') {
@@ -1846,12 +1863,11 @@
1846
1863
  if (notifySharedUpdate)
1847
1864
  return hasSharedUpdate = true;
1848
1865
  position = newPosition;
1849
- if (start > 0) {
1850
- pack(value);
1851
- if (start == 0)
1852
- return { position, targetView, target }; // indicate the buffer was re-allocated
1853
- } else
1854
- pack(value);
1866
+ let startTarget = target;
1867
+ pack(value);
1868
+ if (startTarget !== target) {
1869
+ return { position, targetView, target }; // indicate the buffer was re-allocated
1870
+ }
1855
1871
  return position;
1856
1872
  }, this);
1857
1873
  if (newPosition === 0) // bail and go to a msgpack object
@@ -2769,24 +2785,35 @@
2769
2785
  let objectLiteralProperties = [];
2770
2786
  let args = [];
2771
2787
  let i = 0;
2788
+ let hasInheritedProperties;
2772
2789
  for (let property of properties) { // assign in enumeration order
2790
+ if (unpackr.alwaysLazyProperty && unpackr.alwaysLazyProperty(property.key)) {
2791
+ // these properties are not eagerly evaluated and this can be used for creating properties
2792
+ // that are not serialized as JSON
2793
+ hasInheritedProperties = true;
2794
+ continue;
2795
+ }
2773
2796
  Object.defineProperty(prototype, property.key, { get: withSource(property.get), enumerable: true });
2774
2797
  let valueFunction = 'v' + i++;
2775
2798
  args.push(valueFunction);
2776
2799
  objectLiteralProperties.push('[' + JSON.stringify(property.key) + ']:' + valueFunction + '(s)');
2777
2800
  }
2801
+ if (hasInheritedProperties) {
2802
+ objectLiteralProperties.push('__proto__:this');
2803
+ }
2778
2804
  let toObject = (new Function(...args, 'return function(s){return{' + objectLiteralProperties.join(',') + '}}')).apply(null, properties.map(prop => prop.get));
2779
2805
  Object.defineProperty(prototype, 'toJSON', {
2780
- value() {
2781
- return toObject(this[sourceSymbol]);
2806
+ value(omitUnderscoredProperties) {
2807
+ return toObject.call(this, this[sourceSymbol]);
2782
2808
  }
2783
2809
  });
2784
2810
  } else {
2785
2811
  Object.defineProperty(prototype, 'toJSON', {
2786
- value() {
2812
+ value(omitUnderscoredProperties) {
2787
2813
  // return an enumerable object with own properties to JSON stringify
2788
2814
  let resolved = {};
2789
2815
  for (let i = 0, l = properties.length; i < l; i++) {
2816
+ // TODO: check alwaysLazyProperty
2790
2817
  let key = properties[i].key;
2791
2818
 
2792
2819
  resolved[key] = this[key];
@@ -2920,6 +2947,20 @@
2920
2947
 
2921
2948
  var ITERATIONS = 4000;
2922
2949
 
2950
+ class ExtendArray extends Array {
2951
+ }
2952
+
2953
+ class ExtendArray2 extends Array {
2954
+ }
2955
+
2956
+ class ExtendArray3 extends Array {
2957
+ }
2958
+
2959
+
2960
+ class ExtendObject {
2961
+ }
2962
+
2963
+
2923
2964
  suite('msgpackr basic tests', function() {
2924
2965
  test('pack/unpack data', function () {
2925
2966
  var data = {
@@ -3187,6 +3228,73 @@
3187
3228
  assert.deepEqual(data, deserialized);
3188
3229
  assert.equal(deserialized.extendedInstance.getDouble(), 8);
3189
3230
  });
3231
+
3232
+ test('extended Array class read/write', function(){
3233
+ var instance = new ExtendArray();
3234
+ instance.push(0);
3235
+ instance.push(1);
3236
+ instance.push(2);
3237
+ var data = {
3238
+ prop1: 'has multi-byte: ᾜ',
3239
+ extendedInstance: instance,
3240
+ prop2: 'more string',
3241
+ num: 3,
3242
+ };
3243
+ new Packr();
3244
+ addExtension({
3245
+ Class: ExtendArray,
3246
+ type: 12,
3247
+ read: function(data) {
3248
+ Object.setPrototypeOf(data, ExtendArray.prototype);
3249
+ return data
3250
+ },
3251
+ write: function(instance) {
3252
+ return [...instance]
3253
+ }
3254
+ });
3255
+ var serialized = pack(data);
3256
+ var deserialized = unpack(serialized);
3257
+ assert.strictEqual(Object.getPrototypeOf(deserialized.extendedInstance), ExtendArray.prototype);
3258
+ assert.deepEqual(data, deserialized);
3259
+ });
3260
+
3261
+
3262
+ test('unregistered extended Array class read/write', function(){
3263
+ var instance = new ExtendArray2();
3264
+ instance.push(0);
3265
+ instance.push(1);
3266
+ instance.push(2);
3267
+ var data = {
3268
+ prop1: 'has multi-byte: ᾜ',
3269
+ extendedInstance: instance,
3270
+ prop2: 'more string',
3271
+ num: 3,
3272
+ };
3273
+ new Packr();
3274
+ var serialized = pack(data);
3275
+ var deserialized = unpack(serialized);
3276
+ assert.strictEqual(Object.getPrototypeOf(deserialized.extendedInstance), Array.prototype);
3277
+ assert.deepEqual(data, deserialized);
3278
+ });
3279
+
3280
+
3281
+ test('unregistered extended Object class read/write', function(){
3282
+ var instance = new ExtendObject();
3283
+ instance.test1 = "string";
3284
+ instance.test2 = 3421321;
3285
+ var data = {
3286
+ prop1: 'has multi-byte: ᾜ',
3287
+ extendedInstance: instance,
3288
+ prop2: 'more string',
3289
+ num: 3,
3290
+ };
3291
+ new Packr();
3292
+ var serialized = pack(data);
3293
+ var deserialized = unpack(serialized);
3294
+ assert.strictEqual(Object.getPrototypeOf(deserialized.extendedInstance), Object.prototype);
3295
+ assert.deepEqual(data, deserialized);
3296
+ });
3297
+
3190
3298
  test('extended class pack/unpack custom size', function(){
3191
3299
  function TestClass() {
3192
3300
 
@@ -3240,6 +3348,69 @@
3240
3348
  assert.deepEqual(data, deserialized);
3241
3349
  assert.equal(deserialized.extendedInstance.getDouble(), 8);
3242
3350
  });
3351
+ test('extended class return self', function(){
3352
+ function Extended() {
3353
+
3354
+ }
3355
+ Extended.prototype.getDouble = function() {
3356
+ return this.value * 2
3357
+ };
3358
+ var instance = new Extended();
3359
+ instance.value = 4;
3360
+ instance.string = 'decode this: ᾜ';
3361
+ var data = {
3362
+ prop1: 'has multi-byte: ᾜ',
3363
+ extendedInstance: instance,
3364
+ prop2: 'more string',
3365
+ num: 3,
3366
+ };
3367
+ new Packr();
3368
+ addExtension({
3369
+ Class: Extended,
3370
+ type: 13,
3371
+ read: function(data) {
3372
+ Object.setPrototypeOf(data, Extended.prototype);
3373
+ return data
3374
+ },
3375
+ write: function(data) {
3376
+ return data
3377
+ }
3378
+ });
3379
+ var serialized = pack(data);
3380
+ var deserialized = unpack(serialized);
3381
+ assert.deepEqual(data, deserialized);
3382
+ assert.strictEqual(Object.getPrototypeOf(deserialized.extendedInstance), Extended.prototype);
3383
+ assert.equal(deserialized.extendedInstance.getDouble(), 8);
3384
+ });
3385
+ test('extended Array class return self', function(){
3386
+ var instance = new ExtendArray3();
3387
+ instance.push(0);
3388
+ instance.push('has multi-byte: ᾜ');
3389
+ var data = {
3390
+ prop1: 'has multi-byte: ᾜ',
3391
+ extendedInstance: instance,
3392
+ prop2: 'more string',
3393
+ num: 3,
3394
+ };
3395
+ new Packr();
3396
+ addExtension({
3397
+ Class: ExtendArray3,
3398
+ type: 14,
3399
+ read: function(data) {
3400
+ Object.setPrototypeOf(data, ExtendArray3.prototype);
3401
+ return data
3402
+ },
3403
+ write: function(data) {
3404
+ return data
3405
+ }
3406
+ });
3407
+ var serialized = pack(data);
3408
+ var deserialized = unpack(serialized);
3409
+ assert.deepEqual(data, deserialized);
3410
+ assert.strictEqual(Object.getPrototypeOf(deserialized.extendedInstance), ExtendArray3.prototype);
3411
+ assert.equal(deserialized.extendedInstance[0], 0);
3412
+ });
3413
+
3243
3414
  test('proto handling', function() {
3244
3415
  var objectWithProto = JSON.parse('{"__proto__":{"foo":3}}');
3245
3416
  var decoded = unpack(pack(objectWithProto));