msgpackr 1.7.0-alpha5 → 1.7.0-beta1

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
@@ -33,7 +33,7 @@ const C1 = new C1Type();
33
33
  C1.name = 'MessagePack 0xC1';
34
34
  var sequentialMode = false;
35
35
  var inlineObjectReadThreshold = 2;
36
- var readStruct, onLoadedStructures;
36
+ var readStruct, onLoadedStructures, onSaveState;
37
37
  try {
38
38
  new Function('');
39
39
  } catch(error) {
@@ -210,7 +210,7 @@ function checkedRead(options) {
210
210
  // else more to read, but we are reading sequentially, so don't clear source yet
211
211
  return result
212
212
  } catch(error) {
213
- if (currentStructures.restoreStructures)
213
+ if (currentStructures?.restoreStructures)
214
214
  restoreStructures();
215
215
  clearSource();
216
216
  if (error instanceof RangeError || error.message.startsWith('Unexpected end of buffer') || position > srcEnd) {
@@ -932,7 +932,16 @@ function readKey() {
932
932
 
933
933
  // the registration of the record definition extension (as "r")
934
934
  const recordDefinition = (id, highByte) => {
935
- var structure = read();
935
+ let structure;
936
+ if (currentUnpackr.freezeData) {
937
+ currentUnpackr.freezeData = false;
938
+ try {
939
+ structure = read();
940
+ } finally {
941
+ currentUnpackr.freezeData = true;
942
+ }
943
+ } else
944
+ structure = read();
936
945
  let firstByte = id;
937
946
  if (highByte !== undefined) {
938
947
  id = id < 32 ? -((highByte << 5) + id) : ((highByte << 5) + id);
@@ -1034,6 +1043,8 @@ currentExtensions[0xff] = (data) => {
1034
1043
  // currentExtensions[0x52] = () =>
1035
1044
 
1036
1045
  function saveState(callback) {
1046
+ if (onSaveState)
1047
+ onSaveState();
1037
1048
  let savedSrcEnd = srcEnd;
1038
1049
  let savedPosition = position;
1039
1050
  let savedStringPosition = stringPosition;
@@ -1103,9 +1114,10 @@ function roundFloat32(float32Number) {
1103
1114
  let multiplier = mult10[((u8Array[3] & 0x7f) << 1) | (u8Array[2] >> 7)];
1104
1115
  return ((multiplier * float32Number + (float32Number > 0 ? 0.5 : -0.5)) >> 0) / multiplier
1105
1116
  }
1106
- function setReadStruct(updatedReadStruct, loadedStructs) {
1117
+ function setReadStruct(updatedReadStruct, loadedStructs, saveState) {
1107
1118
  readStruct = updatedReadStruct;
1108
1119
  onLoadedStructures = loadedStructs;
1120
+ onSaveState = saveState;
1109
1121
  }
1110
1122
 
1111
1123
  let textEncoder;
@@ -2071,11 +2083,13 @@ const ASCII = 3; // the MIBenum from https://www.iana.org/assignments/character-
2071
2083
  const NUMBER = 0;
2072
2084
  const UTF8 = 2;
2073
2085
  const OBJECT_DATA = 1;
2086
+ const DATE = 16;
2074
2087
  const TYPE_NAMES = ['num', 'object', 'string', 'ascii'];
2088
+ TYPE_NAMES[DATE] = 'date';
2075
2089
  const float32Headers = [false, true, true, false, false, true, true, false];
2076
2090
  let updatedPosition;
2077
2091
  const hasNodeBuffer$1 = typeof Buffer !== 'undefined';
2078
- let textEncoder$1;
2092
+ let textEncoder$1, currentSource;
2079
2093
  try {
2080
2094
  textEncoder$1 = new TextEncoder();
2081
2095
  } catch (error) {}
@@ -2116,6 +2130,7 @@ function writeStruct(object, target, position, structures, makeRoom, pack, packr
2116
2130
  return 0;
2117
2131
  position += headerSize;
2118
2132
  let queuedReferences = [];
2133
+ let usedAscii0;
2119
2134
  let keyIndex = 0;
2120
2135
  for (let key in object) {
2121
2136
  let value = object[key];
@@ -2131,7 +2146,8 @@ function writeStruct(object, target, position, structures, makeRoom, pack, packr
2131
2146
  string16: null,
2132
2147
  object16: null,
2133
2148
  num32: null,
2134
- float64: null
2149
+ float64: null,
2150
+ date64: null
2135
2151
  };
2136
2152
  }
2137
2153
  if (position > safeEnd) {
@@ -2224,25 +2240,47 @@ function writeStruct(object, target, position, structures, makeRoom, pack, packr
2224
2240
  refPosition += encodeUtf8(target, value, refPosition);
2225
2241
  isNotAscii = refPosition - strStart > strLength;
2226
2242
  }
2227
- if (refOffset < 0x100) {
2228
- if (isNotAscii)
2229
- transition = nextTransition.string8 || createTypeTransition(nextTransition, UTF8, 1);
2230
- else
2231
- transition = nextTransition.ascii8 || createTypeTransition(nextTransition, ASCII, 1);
2243
+ if (refOffset < 0xa0 || (refOffset < 0xf6 && (nextTransition.ascii8 || nextTransition.string8))) {
2244
+ // short strings
2245
+ if (isNotAscii) {
2246
+ if (!(transition = nextTransition.string8)) {
2247
+ if (typedStructs.length > 10 && (transition = nextTransition.ascii8)) {
2248
+ // we can safely change ascii to utf8 in place since they are compatible
2249
+ transition.__type = UTF8;
2250
+ nextTransition.ascii8 = null;
2251
+ nextTransition.string8 = transition;
2252
+ pack(null, 0, true); // special call to notify that structures have been updated
2253
+ } else {
2254
+ transition = createTypeTransition(nextTransition, UTF8, 1);
2255
+ }
2256
+ }
2257
+ } else if (refOffset === 0 && !usedAscii0) {
2258
+ usedAscii0 = true;
2259
+ transition = nextTransition.ascii0 || createTypeTransition(nextTransition, ASCII, 0);
2260
+ break; // don't increment position
2261
+ }// else ascii:
2262
+ else if (!(transition = nextTransition.ascii8) && !(typedStructs.length > 10 && (transition = nextTransition.string8)))
2263
+ transition = createTypeTransition(nextTransition, ASCII, 1);
2232
2264
  target[position++] = refOffset;
2233
2265
  } else {
2234
- if (isNotAscii)
2266
+ // TODO: Enable ascii16 at some point, but get the logic right
2267
+ //if (isNotAscii)
2235
2268
  transition = nextTransition.string16 || createTypeTransition(nextTransition, UTF8, 2);
2236
- else
2237
- transition = nextTransition.ascii16 || createTypeTransition(nextTransition, ASCII, 2);
2269
+ //else
2270
+ //transition = nextTransition.ascii16 || createTypeTransition(nextTransition, ASCII, 2);
2238
2271
  targetView.setUint16(position, refOffset, true);
2239
2272
  position += 2;
2240
2273
  }
2241
2274
  break;
2242
2275
  case 'object':
2243
2276
  if (value) {
2244
- //transition = nextTransition.object16 || createTypeTransition(nextTransition, OBJECT_DATA, 2);
2245
- queuedReferences.push(key, value, keyIndex);
2277
+ if (value.constructor === Date) {
2278
+ transition = nextTransition.date64 || createTypeTransition(nextTransition, DATE, 8);
2279
+ targetView.setFloat64(position, value.getTime(), true);
2280
+ position += 8;
2281
+ } else {
2282
+ queuedReferences.push(key, value, keyIndex);
2283
+ }
2246
2284
  break;
2247
2285
  } else { // null
2248
2286
  nextTransition = anyType(nextTransition, position, targetView, -10); // match CBOR with this
@@ -2332,7 +2370,7 @@ function writeStruct(object, target, position, structures, makeRoom, pack, packr
2332
2370
  targetView.setUint32(position, refOffset, true);
2333
2371
  position += 4;
2334
2372
  }
2335
- } else {
2373
+ } else { // null or undefined
2336
2374
  transition = nextTransition.object16 || createTypeTransition(nextTransition, OBJECT_DATA, 2);
2337
2375
  targetView.setInt16(position, value === null ? -10 : -9, true);
2338
2376
  position += 2;
@@ -2460,7 +2498,8 @@ function onLoadedStructures$1(sharedData) {
2460
2498
  string16: null,
2461
2499
  object16: null,
2462
2500
  num32: null,
2463
- float64: null
2501
+ float64: null,
2502
+ date64: null,
2464
2503
  };
2465
2504
  }
2466
2505
  transition = createTypeTransition(nextTransition, type, size);
@@ -2472,9 +2511,8 @@ function onLoadedStructures$1(sharedData) {
2472
2511
  this.lastTypedStructuresLength = typed.length;
2473
2512
  return named;
2474
2513
  }
2475
- var sourceSymbol = Symbol('source');
2514
+ var sourceSymbol = Symbol.for('source');
2476
2515
  function readStruct$1(src, position, srcEnd, unpackr) {
2477
- // var stringLength = (src[position++] << 8) | src[position++];
2478
2516
  let recordId = src[position++] - 0x20;
2479
2517
  if (recordId >= 24) {
2480
2518
  switch(recordId) {
@@ -2535,13 +2573,13 @@ function readStruct$1(src, position, srcEnd, unpackr) {
2535
2573
  case 0: getRef = () => 0; break;
2536
2574
  case 1:
2537
2575
  getRef = (source, position) => {
2538
- let ref = source.src[position + property.offset];
2576
+ let ref = source.bytes[position + property.offset];
2539
2577
  return ref >= 0xf6 ? toConstant(ref) : ref;
2540
2578
  };
2541
2579
  break;
2542
2580
  case 2:
2543
2581
  getRef = (source, position) => {
2544
- let src = source.src;
2582
+ let src = source.bytes;
2545
2583
  let dataView = src.dataView || (src.dataView = new DataView(src.buffer, src.byteOffset, src.byteLength));
2546
2584
  let ref = dataView.getUint16(position + property.offset, true);
2547
2585
  return ref >= 0xff00 ? toConstant(ref & 0xff) : ref;
@@ -2549,7 +2587,7 @@ function readStruct$1(src, position, srcEnd, unpackr) {
2549
2587
  break;
2550
2588
  case 4:
2551
2589
  getRef = (source, position) => {
2552
- let src = source.src;
2590
+ let src = source.bytes;
2553
2591
  let dataView = src.dataView || (src.dataView = new DataView(src.buffer, src.byteOffset, src.byteLength));
2554
2592
  let ref = dataView.getUint32(position + property.offset, true);
2555
2593
  return ref >= 0xffffff00 ? toConstant(ref & 0xff) : ref;
@@ -2567,7 +2605,7 @@ function readStruct$1(src, position, srcEnd, unpackr) {
2567
2605
  property.multiGetCount = 0;
2568
2606
  get = function() {
2569
2607
  let source = this[sourceSymbol];
2570
- let src = source.src;
2608
+ let src = source.bytes;
2571
2609
  let position = source.position;
2572
2610
  let refStart = currentOffset + position;
2573
2611
  let ref = getRef(source, position);
@@ -2583,7 +2621,7 @@ function readStruct$1(src, position, srcEnd, unpackr) {
2583
2621
  next = next.next;
2584
2622
  }
2585
2623
  if (end == null)
2586
- end = source.srcEnd - refStart;
2624
+ end = source.bytesEnd - refStart;
2587
2625
  if (source.srcString) {
2588
2626
  return source.srcString.slice(ref, end);
2589
2627
  }
@@ -2599,7 +2637,7 @@ function readStruct$1(src, position, srcEnd, unpackr) {
2599
2637
  asciiEnd = null;
2600
2638
  } while((next = next.next));
2601
2639
  if (asciiEnd == null)
2602
- asciiEnd = source.srcEnd - refStart
2640
+ asciiEnd = source.bytesEnd - refStart
2603
2641
  source.srcString = src.toString('latin1', refStart, refStart + asciiEnd);
2604
2642
  return source.srcString.slice(ref, end);
2605
2643
  }
@@ -2623,7 +2661,7 @@ function readStruct$1(src, position, srcEnd, unpackr) {
2623
2661
  let refStart = currentOffset + position;
2624
2662
  let ref = getRef(source, position);
2625
2663
  if (typeof ref !== 'number') return ref;
2626
- let src = source.src;
2664
+ let src = source.bytes;
2627
2665
  let end, next = property.next;
2628
2666
  while(next) {
2629
2667
  end = next.getRef(source, position);
@@ -2634,11 +2672,16 @@ function readStruct$1(src, position, srcEnd, unpackr) {
2634
2672
  next = next.next;
2635
2673
  }
2636
2674
  if (end == null)
2637
- end = source.srcEnd - refStart;
2675
+ end = source.bytesEnd - refStart;
2638
2676
  if (type === UTF8) {
2639
2677
  return src.toString('utf8', ref + refStart, end + refStart);
2640
2678
  } else {
2641
- return unpackr.unpack(src, { start: ref + refStart, end: end + refStart }); // could reuse this object
2679
+ currentSource = source;
2680
+ try {
2681
+ return unpackr.unpack(src, { start: ref + refStart, end: end + refStart });
2682
+ } finally {
2683
+ currentSource = null;
2684
+ }
2642
2685
  }
2643
2686
  };
2644
2687
  break;
@@ -2647,7 +2690,7 @@ function readStruct$1(src, position, srcEnd, unpackr) {
2647
2690
  case 4:
2648
2691
  get = function () {
2649
2692
  let source = this[sourceSymbol];
2650
- let src = source.src;
2693
+ let src = source.bytes;
2651
2694
  let dataView = src.dataView || (src.dataView = new DataView(src.buffer, src.byteOffset, src.byteLength));
2652
2695
  let position = source.position + property.offset;
2653
2696
  let value = dataView.getInt32(position, true);
@@ -2666,7 +2709,7 @@ function readStruct$1(src, position, srcEnd, unpackr) {
2666
2709
  case 8:
2667
2710
  get = function () {
2668
2711
  let source = this[sourceSymbol];
2669
- let src = source.src;
2712
+ let src = source.bytes;
2670
2713
  let dataView = src.dataView || (src.dataView = new DataView(src.buffer, src.byteOffset, src.byteLength));
2671
2714
  let value = dataView.getFloat64(source.position + property.offset, true);
2672
2715
  if (isNaN(value)) {
@@ -2680,12 +2723,22 @@ function readStruct$1(src, position, srcEnd, unpackr) {
2680
2723
  case 1:
2681
2724
  get = function () {
2682
2725
  let source = this[sourceSymbol];
2683
- let src = source.src;
2726
+ let src = source.bytes;
2684
2727
  let value = src[source.position + property.offset];
2685
2728
  return value < 0xf6 ? value : toConstant(value);
2686
2729
  };
2687
2730
  break;
2688
2731
  }
2732
+ break;
2733
+ case DATE:
2734
+ get = function () {
2735
+ let source = this[sourceSymbol];
2736
+ let src = source.bytes;
2737
+ let dataView = src.dataView || (src.dataView = new DataView(src.buffer, src.byteOffset, src.byteLength));
2738
+ return new Date(dataView.getFloat64(source.position + property.offset, true));
2739
+ };
2740
+ break;
2741
+
2689
2742
  }
2690
2743
  property.get = get;
2691
2744
  }
@@ -2694,10 +2747,10 @@ function readStruct$1(src, position, srcEnd, unpackr) {
2694
2747
  }
2695
2748
  var instance = new construct();
2696
2749
  instance[sourceSymbol] = {
2697
- src,
2750
+ bytes: src,
2698
2751
  position,
2699
2752
  srcString: '',
2700
- srcEnd
2753
+ bytesEnd: srcEnd
2701
2754
  };
2702
2755
  return instance;
2703
2756
  }
@@ -2710,6 +2763,14 @@ function toConstant(code) {
2710
2763
  }
2711
2764
  throw new Error('Unknown constant');
2712
2765
  }
2766
+
2767
+ function saveState$1() {
2768
+ if (currentSource) {
2769
+ currentSource.bytes = Uint8Array.prototype.slice.call(currentSource.bytes, currentSource.position, currentSource.bytesEnd);
2770
+ currentSource.position = 0;
2771
+ currentSource.bytesEnd = currentSource.bytes.length;
2772
+ }
2773
+ }
2713
2774
  function prepareStructures$1(structures, packr) {
2714
2775
  if (packr.typedStructs) {
2715
2776
  let structMap = new Map();
@@ -2739,7 +2800,7 @@ function prepareStructures$1(structures, packr) {
2739
2800
  return structures;
2740
2801
  }
2741
2802
 
2742
- setReadStruct(readStruct$1, onLoadedStructures$1);
2803
+ setReadStruct(readStruct$1, onLoadedStructures$1, saveState$1);
2743
2804
 
2744
2805
  class PackrStream extends stream.Transform {
2745
2806
  constructor(options) {