msgpackr 1.7.0-alpha4 → 1.7.0-alpha7

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) {
@@ -100,7 +100,7 @@ class Unpackr {
100
100
  currentUnpackr = this;
101
101
  if (this.structures) {
102
102
  currentStructures = this.structures;
103
- return checkedRead()
103
+ return checkedRead(options)
104
104
  } else if (!currentStructures || currentStructures.length > 0) {
105
105
  currentStructures = [];
106
106
  }
@@ -109,7 +109,7 @@ class Unpackr {
109
109
  if (!currentStructures || currentStructures.length > 0)
110
110
  currentStructures = [];
111
111
  }
112
- return checkedRead()
112
+ return checkedRead(options)
113
113
  }
114
114
  unpackMultiple(source, forEach) {
115
115
  let values, lastPosition = 0;
@@ -175,7 +175,7 @@ class Unpackr {
175
175
  return this.unpack(source, end)
176
176
  }
177
177
  }
178
- function checkedRead() {
178
+ function checkedRead(options) {
179
179
  try {
180
180
  if (!currentUnpackr.trusted && !sequentialMode) {
181
181
  let sharedLength = currentStructures.sharedLength || 0;
@@ -185,6 +185,8 @@ function checkedRead() {
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
+ if (!(options && options.lazy) && result)
189
+ result = result.toJSON();
188
190
  position = srcEnd;
189
191
  } else
190
192
  result = read();
@@ -208,7 +210,7 @@ function checkedRead() {
208
210
  // else more to read, but we are reading sequentially, so don't clear source yet
209
211
  return result
210
212
  } catch(error) {
211
- if (currentStructures.restoreStructures)
213
+ if (currentStructures?.restoreStructures)
212
214
  restoreStructures();
213
215
  clearSource();
214
216
  if (error instanceof RangeError || error.message.startsWith('Unexpected end of buffer') || position > srcEnd) {
@@ -1032,6 +1034,8 @@ currentExtensions[0xff] = (data) => {
1032
1034
  // currentExtensions[0x52] = () =>
1033
1035
 
1034
1036
  function saveState(callback) {
1037
+ if (onSaveState)
1038
+ onSaveState();
1035
1039
  let savedSrcEnd = srcEnd;
1036
1040
  let savedPosition = position;
1037
1041
  let savedStringPosition = stringPosition;
@@ -1101,9 +1105,10 @@ function roundFloat32(float32Number) {
1101
1105
  let multiplier = mult10[((u8Array[3] & 0x7f) << 1) | (u8Array[2] >> 7)];
1102
1106
  return ((multiplier * float32Number + (float32Number > 0 ? 0.5 : -0.5)) >> 0) / multiplier
1103
1107
  }
1104
- function setReadStruct(updatedReadStruct, loadedStructs) {
1108
+ function setReadStruct(updatedReadStruct, loadedStructs, saveState) {
1105
1109
  readStruct = updatedReadStruct;
1106
1110
  onLoadedStructures = loadedStructs;
1111
+ onSaveState = saveState;
1107
1112
  }
1108
1113
 
1109
1114
  let textEncoder;
@@ -2069,11 +2074,13 @@ const ASCII = 3; // the MIBenum from https://www.iana.org/assignments/character-
2069
2074
  const NUMBER = 0;
2070
2075
  const UTF8 = 2;
2071
2076
  const OBJECT_DATA = 1;
2077
+ const DATE = 16;
2072
2078
  const TYPE_NAMES = ['num', 'object', 'string', 'ascii'];
2079
+ TYPE_NAMES[DATE] = 'date';
2073
2080
  const float32Headers = [false, true, true, false, false, true, true, false];
2074
2081
  let updatedPosition;
2075
2082
  const hasNodeBuffer$1 = typeof Buffer !== 'undefined';
2076
- let textEncoder$1;
2083
+ let textEncoder$1, currentSource;
2077
2084
  try {
2078
2085
  textEncoder$1 = new TextEncoder();
2079
2086
  } catch (error) {}
@@ -2114,6 +2121,7 @@ function writeStruct(object, target, position, structures, makeRoom, pack, packr
2114
2121
  return 0;
2115
2122
  position += headerSize;
2116
2123
  let queuedReferences = [];
2124
+ let usedAscii0;
2117
2125
  let keyIndex = 0;
2118
2126
  for (let key in object) {
2119
2127
  let value = object[key];
@@ -2129,7 +2137,8 @@ function writeStruct(object, target, position, structures, makeRoom, pack, packr
2129
2137
  string16: null,
2130
2138
  object16: null,
2131
2139
  num32: null,
2132
- float64: null
2140
+ float64: null,
2141
+ date64: null
2133
2142
  };
2134
2143
  }
2135
2144
  if (position > safeEnd) {
@@ -2222,25 +2231,47 @@ function writeStruct(object, target, position, structures, makeRoom, pack, packr
2222
2231
  refPosition += encodeUtf8(target, value, refPosition);
2223
2232
  isNotAscii = refPosition - strStart > strLength;
2224
2233
  }
2225
- if (refOffset < 0x100) {
2226
- if (isNotAscii)
2227
- transition = nextTransition.string8 || createTypeTransition(nextTransition, UTF8, 1);
2228
- else
2229
- transition = nextTransition.ascii8 || createTypeTransition(nextTransition, ASCII, 1);
2234
+ if (refOffset < 0xa0 || (refOffset < 0xf6 && (nextTransition.ascii8 || nextTransition.string8))) {
2235
+ // short strings
2236
+ if (isNotAscii) {
2237
+ if (!(transition = nextTransition.string8)) {
2238
+ if (typedStructs.length > 10 && (transition = nextTransition.ascii8)) {
2239
+ // we can safely change ascii to utf8 in place since they are compatible
2240
+ transition.__type = UTF8;
2241
+ nextTransition.ascii8 = null;
2242
+ nextTransition.string8 = transition;
2243
+ pack(null, 0, true); // special call to notify that structures have been updated
2244
+ } else {
2245
+ transition = createTypeTransition(nextTransition, UTF8, 1);
2246
+ }
2247
+ }
2248
+ } else if (refOffset === 0 && !usedAscii0) {
2249
+ usedAscii0 = true;
2250
+ transition = nextTransition.ascii0 || createTypeTransition(nextTransition, ASCII, 0);
2251
+ break; // don't increment position
2252
+ }// else ascii:
2253
+ else if (!(transition = nextTransition.ascii8) && !(typedStructs.length > 10 && (transition = nextTransition.string8)))
2254
+ transition = createTypeTransition(nextTransition, ASCII, 1);
2230
2255
  target[position++] = refOffset;
2231
2256
  } else {
2232
- if (isNotAscii)
2257
+ // TODO: Enable ascii16 at some point, but get the logic right
2258
+ //if (isNotAscii)
2233
2259
  transition = nextTransition.string16 || createTypeTransition(nextTransition, UTF8, 2);
2234
- else
2235
- transition = nextTransition.ascii16 || createTypeTransition(nextTransition, ASCII, 2);
2260
+ //else
2261
+ //transition = nextTransition.ascii16 || createTypeTransition(nextTransition, ASCII, 2);
2236
2262
  targetView.setUint16(position, refOffset, true);
2237
2263
  position += 2;
2238
2264
  }
2239
2265
  break;
2240
2266
  case 'object':
2241
2267
  if (value) {
2242
- //transition = nextTransition.object16 || createTypeTransition(nextTransition, OBJECT_DATA, 2);
2243
- queuedReferences.push(key, value, keyIndex);
2268
+ if (value.constructor === Date) {
2269
+ transition = nextTransition.date64 || createTypeTransition(nextTransition, DATE, 8);
2270
+ targetView.setFloat64(position, value.getTime(), true);
2271
+ position += 8;
2272
+ } else {
2273
+ queuedReferences.push(key, value, keyIndex);
2274
+ }
2244
2275
  break;
2245
2276
  } else { // null
2246
2277
  nextTransition = anyType(nextTransition, position, targetView, -10); // match CBOR with this
@@ -2330,7 +2361,7 @@ function writeStruct(object, target, position, structures, makeRoom, pack, packr
2330
2361
  targetView.setUint32(position, refOffset, true);
2331
2362
  position += 4;
2332
2363
  }
2333
- } else {
2364
+ } else { // null or undefined
2334
2365
  transition = nextTransition.object16 || createTypeTransition(nextTransition, OBJECT_DATA, 2);
2335
2366
  targetView.setInt16(position, value === null ? -10 : -9, true);
2336
2367
  position += 2;
@@ -2458,7 +2489,8 @@ function onLoadedStructures$1(sharedData) {
2458
2489
  string16: null,
2459
2490
  object16: null,
2460
2491
  num32: null,
2461
- float64: null
2492
+ float64: null,
2493
+ date64: null,
2462
2494
  };
2463
2495
  }
2464
2496
  transition = createTypeTransition(nextTransition, type, size);
@@ -2502,12 +2534,13 @@ function readStruct$1(src, position, srcEnd, unpackr) {
2502
2534
  construct = structure.construct = function LazyObject() {
2503
2535
  };
2504
2536
  var prototype = construct.prototype;
2537
+ let properties = [];
2505
2538
  Object.defineProperty(prototype, 'toJSON', {
2506
- get() {
2539
+ value() {
2507
2540
  // return an enumerable object with own properties to JSON stringify
2508
2541
  let resolved = {};
2509
- for (let i = 0, l = structure.length; i < l; i++) {
2510
- let key = structure[i];
2542
+ for (let i = 0, l = properties.length; i < l; i++) {
2543
+ let key = properties[i].key;
2511
2544
  resolved[key] = this[key];
2512
2545
  }
2513
2546
  return resolved;
@@ -2516,7 +2549,6 @@ function readStruct$1(src, position, srcEnd, unpackr) {
2516
2549
  });
2517
2550
  let currentOffset = 0;
2518
2551
  let lastRefProperty;
2519
- let properties = [];
2520
2552
  for (let i = 0, l = structure.length; i < l; i++) {
2521
2553
  let definition = structure[i];
2522
2554
  let [ type, size, key, enumerationOffset ] = definition;
@@ -2636,7 +2668,12 @@ function readStruct$1(src, position, srcEnd, unpackr) {
2636
2668
  if (type === UTF8) {
2637
2669
  return src.toString('utf8', ref + refStart, end + refStart);
2638
2670
  } else {
2639
- return unpackr.unpack(src, { start: ref + refStart, end: end + refStart }); // could reuse this object
2671
+ currentSource = source;
2672
+ try {
2673
+ return unpackr.unpack(src, { start: ref + refStart, end: end + refStart });
2674
+ } finally {
2675
+ currentSource = null;
2676
+ }
2640
2677
  }
2641
2678
  };
2642
2679
  break;
@@ -2684,6 +2721,16 @@ function readStruct$1(src, position, srcEnd, unpackr) {
2684
2721
  };
2685
2722
  break;
2686
2723
  }
2724
+ break;
2725
+ case DATE:
2726
+ get = function () {
2727
+ let source = this[sourceSymbol];
2728
+ let src = source.src;
2729
+ let dataView = src.dataView || (src.dataView = new DataView(src.buffer, src.byteOffset, src.byteLength));
2730
+ return new Date(dataView.getFloat64(source.position + property.offset, true));
2731
+ };
2732
+ break;
2733
+
2687
2734
  }
2688
2735
  property.get = get;
2689
2736
  }
@@ -2708,14 +2755,23 @@ function toConstant(code) {
2708
2755
  }
2709
2756
  throw new Error('Unknown constant');
2710
2757
  }
2758
+
2759
+ function saveState$1() {
2760
+ if (currentSource) {
2761
+ currentSource.src = Uint8Array.prototype.slice.call(currentSource.src, currentSource.position, currentSource.srcEnd);
2762
+ currentSource.position = 0;
2763
+ currentSource.srcEnd = currentSource.src.length;
2764
+ }
2765
+ }
2711
2766
  function prepareStructures$1(structures, packr) {
2712
- if (!packr.typedStructs)
2713
- return structures;
2714
- let structMap = new Map();
2715
- structMap.set('named', structures);
2716
- structMap.set('typed', packr.typedStructs);
2767
+ if (packr.typedStructs) {
2768
+ let structMap = new Map();
2769
+ structMap.set('named', structures);
2770
+ structMap.set('typed', packr.typedStructs);
2771
+ structures = structMap;
2772
+ }
2717
2773
  let lastTypedStructuresLength = packr.lastTypedStructuresLength || 0;
2718
- structMap.isCompatible = existing => {
2774
+ structures.isCompatible = existing => {
2719
2775
  let compatible = true;
2720
2776
  if (existing instanceof Map) {
2721
2777
  let named = existing.get('named') || [];
@@ -2733,10 +2789,10 @@ function prepareStructures$1(structures, packr) {
2733
2789
  return compatible;
2734
2790
  };
2735
2791
  packr.lastTypedStructuresLength = packr.typedStructs?.length;
2736
- return structMap;
2792
+ return structures;
2737
2793
  }
2738
2794
 
2739
- setReadStruct(readStruct$1, onLoadedStructures$1);
2795
+ setReadStruct(readStruct$1, onLoadedStructures$1, saveState$1);
2740
2796
 
2741
2797
  class PackrStream extends stream.Transform {
2742
2798
  constructor(options) {