msgpackr 1.7.0-beta1 → 1.7.0

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/node.cjs CHANGED
@@ -185,6 +185,7 @@ function checkedRead(options) {
185
185
  let result;
186
186
  if (currentUnpackr.randomAccessStructure && src[position] < 0x40 && src[position] >= 0x20 && readStruct) {
187
187
  result = readStruct(src, position, srcEnd, currentUnpackr);
188
+ src = null; // dispose of this so that recursive unpack calls don't save state
188
189
  if (!(options && options.lazy) && result)
189
190
  result = result.toJSON();
190
191
  position = srcEnd;
@@ -195,7 +196,7 @@ function checkedRead(options) {
195
196
 
196
197
  if (position == srcEnd) {
197
198
  // finished reading this source, cleanup references
198
- if (currentStructures.restoreStructures)
199
+ if (currentStructures?.restoreStructures)
199
200
  restoreStructures();
200
201
  currentStructures = null;
201
202
  src = null;
@@ -250,7 +251,10 @@ function read() {
250
251
  if (currentUnpackr.mapsAsObjects) {
251
252
  let object = {};
252
253
  for (let i = 0; i < token; i++) {
253
- object[readKey()] = read();
254
+ let key = readKey();
255
+ if (key === '__proto__')
256
+ key = '__proto_';
257
+ object[key] = read();
254
258
  }
255
259
  return object
256
260
  } else {
@@ -479,7 +483,7 @@ function createStructureReader(structure, firstId) {
479
483
  // This initial function is quick to instantiate, but runs slower. After several iterations pay the cost to build the faster function
480
484
  if (readObject.count++ > inlineObjectReadThreshold) {
481
485
  let readObject = structure.read = (new Function('r', 'return function(){return ' + (currentUnpackr.freezeData ? 'Object.freeze' : '') +
482
- '({' + structure.map(key => validName.test(key) ? key + ':r()' : ('[' + JSON.stringify(key) + ']:r()')).join(',') + '})}'))(read);
486
+ '({' + structure.map(key => key === '__proto__' ? '__proto_:r()' : validName.test(key) ? key + ':r()' : ('[' + JSON.stringify(key) + ']:r()')).join(',') + '})}'))(read);
483
487
  if (structure.highByte === 0)
484
488
  structure.read = createSecondByteReader(firstId, structure.read);
485
489
  return readObject() // second byte is already read, if there is one so immediately read object
@@ -487,6 +491,8 @@ function createStructureReader(structure, firstId) {
487
491
  let object = {};
488
492
  for (let i = 0, l = structure.length; i < l; i++) {
489
493
  let key = structure[i];
494
+ if (key === '__proto__')
495
+ key = '__proto_';
490
496
  object[key] = read();
491
497
  }
492
498
  if (currentUnpackr.freezeData)
@@ -647,7 +653,10 @@ function readMap(length) {
647
653
  if (currentUnpackr.mapsAsObjects) {
648
654
  let object = {};
649
655
  for (let i = 0; i < length; i++) {
650
- object[readKey()] = read();
656
+ let key = readKey();
657
+ if (key === '__proto__')
658
+ key = '__proto_';
659
+ object[key] = read();
651
660
  }
652
661
  return object
653
662
  } else {
@@ -2087,6 +2096,14 @@ const DATE = 16;
2087
2096
  const TYPE_NAMES = ['num', 'object', 'string', 'ascii'];
2088
2097
  TYPE_NAMES[DATE] = 'date';
2089
2098
  const float32Headers = [false, true, true, false, false, true, true, false];
2099
+ let evalSupported;
2100
+ try {
2101
+ new Function('');
2102
+ evalSupported = true;
2103
+ } catch(error) {
2104
+ // if eval variants are not supported, do not create inline object readers ever
2105
+ }
2106
+
2090
2107
  let updatedPosition;
2091
2108
  const hasNodeBuffer$1 = typeof Buffer !== 'undefined';
2092
2109
  let textEncoder$1, currentSource;
@@ -2543,23 +2560,13 @@ function readStruct$1(src, position, srcEnd, unpackr) {
2543
2560
  };
2544
2561
  var prototype = construct.prototype;
2545
2562
  let properties = [];
2546
- Object.defineProperty(prototype, 'toJSON', {
2547
- value() {
2548
- // return an enumerable object with own properties to JSON stringify
2549
- let resolved = {};
2550
- for (let i = 0, l = properties.length; i < l; i++) {
2551
- let key = properties[i].key;
2552
- resolved[key] = this[key];
2553
- }
2554
- return resolved;
2555
- },
2556
- // not enumerable or anything
2557
- });
2558
2563
  let currentOffset = 0;
2559
2564
  let lastRefProperty;
2560
2565
  for (let i = 0, l = structure.length; i < l; i++) {
2561
2566
  let definition = structure[i];
2562
2567
  let [ type, size, key, enumerationOffset ] = definition;
2568
+ if (key === '__proto__')
2569
+ key = '__proto_';
2563
2570
  let property = {
2564
2571
  key,
2565
2572
  offset: currentOffset,
@@ -2603,8 +2610,7 @@ function readStruct$1(src, position, srcEnd, unpackr) {
2603
2610
  lastRefProperty.next = property;
2604
2611
  lastRefProperty = property;
2605
2612
  property.multiGetCount = 0;
2606
- get = function() {
2607
- let source = this[sourceSymbol];
2613
+ get = function(source) {
2608
2614
  let src = source.bytes;
2609
2615
  let position = source.position;
2610
2616
  let refStart = currentOffset + position;
@@ -2655,8 +2661,7 @@ function readStruct$1(src, position, srcEnd, unpackr) {
2655
2661
  if (lastRefProperty && !lastRefProperty.next)
2656
2662
  lastRefProperty.next = property;
2657
2663
  lastRefProperty = property;
2658
- get = function() {
2659
- let source = this[sourceSymbol];
2664
+ get = function(source) {
2660
2665
  let position = source.position;
2661
2666
  let refStart = currentOffset + position;
2662
2667
  let ref = getRef(source, position);
@@ -2688,8 +2693,7 @@ function readStruct$1(src, position, srcEnd, unpackr) {
2688
2693
  case NUMBER:
2689
2694
  switch(size) {
2690
2695
  case 4:
2691
- get = function () {
2692
- let source = this[sourceSymbol];
2696
+ get = function (source) {
2693
2697
  let src = source.bytes;
2694
2698
  let dataView = src.dataView || (src.dataView = new DataView(src.buffer, src.byteOffset, src.byteLength));
2695
2699
  let position = source.position + property.offset;
@@ -2707,8 +2711,7 @@ function readStruct$1(src, position, srcEnd, unpackr) {
2707
2711
  };
2708
2712
  break;
2709
2713
  case 8:
2710
- get = function () {
2711
- let source = this[sourceSymbol];
2714
+ get = function (source) {
2712
2715
  let src = source.bytes;
2713
2716
  let dataView = src.dataView || (src.dataView = new DataView(src.buffer, src.byteOffset, src.byteLength));
2714
2717
  let value = dataView.getFloat64(source.position + property.offset, true);
@@ -2721,8 +2724,7 @@ function readStruct$1(src, position, srcEnd, unpackr) {
2721
2724
  };
2722
2725
  break;
2723
2726
  case 1:
2724
- get = function () {
2725
- let source = this[sourceSymbol];
2727
+ get = function (source) {
2726
2728
  let src = source.bytes;
2727
2729
  let value = src[source.position + property.offset];
2728
2730
  return value < 0xf6 ? value : toConstant(value);
@@ -2731,8 +2733,7 @@ function readStruct$1(src, position, srcEnd, unpackr) {
2731
2733
  }
2732
2734
  break;
2733
2735
  case DATE:
2734
- get = function () {
2735
- let source = this[sourceSymbol];
2736
+ get = function (source) {
2736
2737
  let src = source.bytes;
2737
2738
  let dataView = src.dataView || (src.dataView = new DataView(src.buffer, src.byteOffset, src.byteLength));
2738
2739
  return new Date(dataView.getFloat64(source.position + property.offset, true));
@@ -2742,8 +2743,38 @@ function readStruct$1(src, position, srcEnd, unpackr) {
2742
2743
  }
2743
2744
  property.get = get;
2744
2745
  }
2745
- for (let property of properties) // assign in enumeration order
2746
- Object.defineProperty(prototype, property.key, { get: property.get, enumerable: true });
2746
+ // TODO: load the srcString for faster string decoding on toJSON
2747
+ if (evalSupported) {
2748
+ let objectLiteralProperties = [];
2749
+ let args = [];
2750
+ let i = 0;
2751
+ for (let property of properties) { // assign in enumeration order
2752
+ Object.defineProperty(prototype, property.key, { get: withSource(property.get), enumerable: true });
2753
+ let valueFunction = 'v' + i++;
2754
+ args.push(valueFunction);
2755
+ objectLiteralProperties.push('[' + JSON.stringify(property.key) + ']:' + valueFunction + '(s)');
2756
+ }
2757
+ let toObject = (new Function(...args, 'return function(s){return{' + objectLiteralProperties.join(',') + '}}')).apply(null, properties.map(prop => prop.get));
2758
+ Object.defineProperty(prototype, 'toJSON', {
2759
+ value() {
2760
+ return toObject(this[sourceSymbol]);
2761
+ }
2762
+ });
2763
+ } else {
2764
+ Object.defineProperty(prototype, 'toJSON', {
2765
+ value() {
2766
+ // return an enumerable object with own properties to JSON stringify
2767
+ let resolved = {};
2768
+ for (let i = 0, l = properties.length; i < l; i++) {
2769
+ let key = properties[i].key;
2770
+
2771
+ resolved[key] = this[key];
2772
+ }
2773
+ return resolved;
2774
+ },
2775
+ // not enumerable or anything
2776
+ });
2777
+ }
2747
2778
  }
2748
2779
  var instance = new construct();
2749
2780
  instance[sourceSymbol] = {
@@ -2763,6 +2794,11 @@ function toConstant(code) {
2763
2794
  }
2764
2795
  throw new Error('Unknown constant');
2765
2796
  }
2797
+ function withSource(get) {
2798
+ return function() {
2799
+ return get(this[sourceSymbol]);
2800
+ }
2801
+ }
2766
2802
 
2767
2803
  function saveState$1() {
2768
2804
  if (currentSource) {