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/test.js CHANGED
@@ -29,7 +29,7 @@
29
29
  C1.name = 'MessagePack 0xC1';
30
30
  var sequentialMode = false;
31
31
  var inlineObjectReadThreshold = 2;
32
- var readStruct, onLoadedStructures;
32
+ var readStruct, onLoadedStructures, onSaveState;
33
33
  try {
34
34
  new Function('');
35
35
  } catch(error) {
@@ -204,7 +204,7 @@
204
204
  // else more to read, but we are reading sequentially, so don't clear source yet
205
205
  return result
206
206
  } catch(error) {
207
- if (currentStructures.restoreStructures)
207
+ if (currentStructures?.restoreStructures)
208
208
  restoreStructures();
209
209
  clearSource();
210
210
  if (error instanceof RangeError || error.message.startsWith('Unexpected end of buffer') || position > srcEnd) {
@@ -886,7 +886,16 @@
886
886
 
887
887
  // the registration of the record definition extension (as "r")
888
888
  const recordDefinition = (id, highByte) => {
889
- var structure = read();
889
+ let structure;
890
+ if (currentUnpackr.freezeData) {
891
+ currentUnpackr.freezeData = false;
892
+ try {
893
+ structure = read();
894
+ } finally {
895
+ currentUnpackr.freezeData = true;
896
+ }
897
+ } else
898
+ structure = read();
890
899
  let firstByte = id;
891
900
  if (highByte !== undefined) {
892
901
  id = id < 32 ? -((highByte << 5) + id) : ((highByte << 5) + id);
@@ -988,6 +997,8 @@
988
997
  // currentExtensions[0x52] = () =>
989
998
 
990
999
  function saveState(callback) {
1000
+ if (onSaveState)
1001
+ onSaveState();
991
1002
  let savedSrcEnd = srcEnd;
992
1003
  let savedPosition = position;
993
1004
  let savedSrcStringStart = srcStringStart;
@@ -1029,9 +1040,10 @@
1029
1040
  mult10[i] = +('1e' + Math.floor(45.15 - i * 0.30103));
1030
1041
  }
1031
1042
  var defaultUnpackr = new Unpackr({ useRecords: false });
1032
- function setReadStruct(updatedReadStruct, loadedStructs) {
1043
+ function setReadStruct(updatedReadStruct, loadedStructs, saveState) {
1033
1044
  readStruct = updatedReadStruct;
1034
1045
  onLoadedStructures = loadedStructs;
1046
+ onSaveState = saveState;
1035
1047
  }
1036
1048
 
1037
1049
  let textEncoder;
@@ -1981,11 +1993,13 @@
1981
1993
  const NUMBER = 0;
1982
1994
  const UTF8 = 2;
1983
1995
  const OBJECT_DATA = 1;
1996
+ const DATE = 16;
1984
1997
  const TYPE_NAMES = ['num', 'object', 'string', 'ascii'];
1998
+ TYPE_NAMES[DATE] = 'date';
1985
1999
  const float32Headers = [false, true, true, false, false, true, true, false];
1986
2000
  let updatedPosition;
1987
2001
  const hasNodeBuffer$1 = typeof Buffer !== 'undefined';
1988
- let textEncoder$1;
2002
+ let textEncoder$1, currentSource;
1989
2003
  try {
1990
2004
  textEncoder$1 = new TextEncoder();
1991
2005
  } catch (error) {}
@@ -2026,6 +2040,7 @@
2026
2040
  return 0;
2027
2041
  position += headerSize;
2028
2042
  let queuedReferences = [];
2043
+ let usedAscii0;
2029
2044
  let keyIndex = 0;
2030
2045
  for (let key in object) {
2031
2046
  let value = object[key];
@@ -2041,7 +2056,8 @@
2041
2056
  string16: null,
2042
2057
  object16: null,
2043
2058
  num32: null,
2044
- float64: null
2059
+ float64: null,
2060
+ date64: null
2045
2061
  };
2046
2062
  }
2047
2063
  if (position > safeEnd) {
@@ -2134,25 +2150,47 @@
2134
2150
  refPosition += encodeUtf8(target, value, refPosition);
2135
2151
  isNotAscii = refPosition - strStart > strLength;
2136
2152
  }
2137
- if (refOffset < 0x100) {
2138
- if (isNotAscii)
2139
- transition = nextTransition.string8 || createTypeTransition(nextTransition, UTF8, 1);
2140
- else
2141
- transition = nextTransition.ascii8 || createTypeTransition(nextTransition, ASCII, 1);
2153
+ if (refOffset < 0xa0 || (refOffset < 0xf6 && (nextTransition.ascii8 || nextTransition.string8))) {
2154
+ // short strings
2155
+ if (isNotAscii) {
2156
+ if (!(transition = nextTransition.string8)) {
2157
+ if (typedStructs.length > 10 && (transition = nextTransition.ascii8)) {
2158
+ // we can safely change ascii to utf8 in place since they are compatible
2159
+ transition.__type = UTF8;
2160
+ nextTransition.ascii8 = null;
2161
+ nextTransition.string8 = transition;
2162
+ pack(null, 0, true); // special call to notify that structures have been updated
2163
+ } else {
2164
+ transition = createTypeTransition(nextTransition, UTF8, 1);
2165
+ }
2166
+ }
2167
+ } else if (refOffset === 0 && !usedAscii0) {
2168
+ usedAscii0 = true;
2169
+ transition = nextTransition.ascii0 || createTypeTransition(nextTransition, ASCII, 0);
2170
+ break; // don't increment position
2171
+ }// else ascii:
2172
+ else if (!(transition = nextTransition.ascii8) && !(typedStructs.length > 10 && (transition = nextTransition.string8)))
2173
+ transition = createTypeTransition(nextTransition, ASCII, 1);
2142
2174
  target[position++] = refOffset;
2143
2175
  } else {
2144
- if (isNotAscii)
2176
+ // TODO: Enable ascii16 at some point, but get the logic right
2177
+ //if (isNotAscii)
2145
2178
  transition = nextTransition.string16 || createTypeTransition(nextTransition, UTF8, 2);
2146
- else
2147
- transition = nextTransition.ascii16 || createTypeTransition(nextTransition, ASCII, 2);
2179
+ //else
2180
+ //transition = nextTransition.ascii16 || createTypeTransition(nextTransition, ASCII, 2);
2148
2181
  targetView.setUint16(position, refOffset, true);
2149
2182
  position += 2;
2150
2183
  }
2151
2184
  break;
2152
2185
  case 'object':
2153
2186
  if (value) {
2154
- //transition = nextTransition.object16 || createTypeTransition(nextTransition, OBJECT_DATA, 2);
2155
- queuedReferences.push(key, value, keyIndex);
2187
+ if (value.constructor === Date) {
2188
+ transition = nextTransition.date64 || createTypeTransition(nextTransition, DATE, 8);
2189
+ targetView.setFloat64(position, value.getTime(), true);
2190
+ position += 8;
2191
+ } else {
2192
+ queuedReferences.push(key, value, keyIndex);
2193
+ }
2156
2194
  break;
2157
2195
  } else { // null
2158
2196
  nextTransition = anyType(nextTransition, position, targetView, -10); // match CBOR with this
@@ -2242,7 +2280,7 @@
2242
2280
  targetView.setUint32(position, refOffset, true);
2243
2281
  position += 4;
2244
2282
  }
2245
- } else {
2283
+ } else { // null or undefined
2246
2284
  transition = nextTransition.object16 || createTypeTransition(nextTransition, OBJECT_DATA, 2);
2247
2285
  targetView.setInt16(position, value === null ? -10 : -9, true);
2248
2286
  position += 2;
@@ -2370,7 +2408,8 @@
2370
2408
  string16: null,
2371
2409
  object16: null,
2372
2410
  num32: null,
2373
- float64: null
2411
+ float64: null,
2412
+ date64: null,
2374
2413
  };
2375
2414
  }
2376
2415
  transition = createTypeTransition(nextTransition, type, size);
@@ -2382,9 +2421,8 @@
2382
2421
  this.lastTypedStructuresLength = typed.length;
2383
2422
  return named;
2384
2423
  }
2385
- var sourceSymbol = Symbol('source');
2424
+ var sourceSymbol = Symbol.for('source');
2386
2425
  function readStruct$1(src, position, srcEnd, unpackr) {
2387
- // var stringLength = (src[position++] << 8) | src[position++];
2388
2426
  let recordId = src[position++] - 0x20;
2389
2427
  if (recordId >= 24) {
2390
2428
  switch(recordId) {
@@ -2445,13 +2483,13 @@
2445
2483
  case 0: getRef = () => 0; break;
2446
2484
  case 1:
2447
2485
  getRef = (source, position) => {
2448
- let ref = source.src[position + property.offset];
2486
+ let ref = source.bytes[position + property.offset];
2449
2487
  return ref >= 0xf6 ? toConstant(ref) : ref;
2450
2488
  };
2451
2489
  break;
2452
2490
  case 2:
2453
2491
  getRef = (source, position) => {
2454
- let src = source.src;
2492
+ let src = source.bytes;
2455
2493
  let dataView = src.dataView || (src.dataView = new DataView(src.buffer, src.byteOffset, src.byteLength));
2456
2494
  let ref = dataView.getUint16(position + property.offset, true);
2457
2495
  return ref >= 0xff00 ? toConstant(ref & 0xff) : ref;
@@ -2459,7 +2497,7 @@
2459
2497
  break;
2460
2498
  case 4:
2461
2499
  getRef = (source, position) => {
2462
- let src = source.src;
2500
+ let src = source.bytes;
2463
2501
  let dataView = src.dataView || (src.dataView = new DataView(src.buffer, src.byteOffset, src.byteLength));
2464
2502
  let ref = dataView.getUint32(position + property.offset, true);
2465
2503
  return ref >= 0xffffff00 ? toConstant(ref & 0xff) : ref;
@@ -2477,7 +2515,7 @@
2477
2515
  property.multiGetCount = 0;
2478
2516
  get = function() {
2479
2517
  let source = this[sourceSymbol];
2480
- let src = source.src;
2518
+ let src = source.bytes;
2481
2519
  let position = source.position;
2482
2520
  let refStart = currentOffset + position;
2483
2521
  let ref = getRef(source, position);
@@ -2493,7 +2531,7 @@
2493
2531
  next = next.next;
2494
2532
  }
2495
2533
  if (end == null)
2496
- end = source.srcEnd - refStart;
2534
+ end = source.bytesEnd - refStart;
2497
2535
  if (source.srcString) {
2498
2536
  return source.srcString.slice(ref, end);
2499
2537
  }
@@ -2509,7 +2547,7 @@
2509
2547
  asciiEnd = null;
2510
2548
  } while((next = next.next));
2511
2549
  if (asciiEnd == null)
2512
- asciiEnd = source.srcEnd - refStart
2550
+ asciiEnd = source.bytesEnd - refStart
2513
2551
  source.srcString = src.toString('latin1', refStart, refStart + asciiEnd);
2514
2552
  return source.srcString.slice(ref, end);
2515
2553
  }
@@ -2533,7 +2571,7 @@
2533
2571
  let refStart = currentOffset + position;
2534
2572
  let ref = getRef(source, position);
2535
2573
  if (typeof ref !== 'number') return ref;
2536
- let src = source.src;
2574
+ let src = source.bytes;
2537
2575
  let end, next = property.next;
2538
2576
  while(next) {
2539
2577
  end = next.getRef(source, position);
@@ -2544,11 +2582,16 @@
2544
2582
  next = next.next;
2545
2583
  }
2546
2584
  if (end == null)
2547
- end = source.srcEnd - refStart;
2585
+ end = source.bytesEnd - refStart;
2548
2586
  if (type === UTF8) {
2549
2587
  return src.toString('utf8', ref + refStart, end + refStart);
2550
2588
  } else {
2551
- return unpackr.unpack(src, { start: ref + refStart, end: end + refStart }); // could reuse this object
2589
+ currentSource = source;
2590
+ try {
2591
+ return unpackr.unpack(src, { start: ref + refStart, end: end + refStart });
2592
+ } finally {
2593
+ currentSource = null;
2594
+ }
2552
2595
  }
2553
2596
  };
2554
2597
  break;
@@ -2557,7 +2600,7 @@
2557
2600
  case 4:
2558
2601
  get = function () {
2559
2602
  let source = this[sourceSymbol];
2560
- let src = source.src;
2603
+ let src = source.bytes;
2561
2604
  let dataView = src.dataView || (src.dataView = new DataView(src.buffer, src.byteOffset, src.byteLength));
2562
2605
  let position = source.position + property.offset;
2563
2606
  let value = dataView.getInt32(position, true);
@@ -2576,7 +2619,7 @@
2576
2619
  case 8:
2577
2620
  get = function () {
2578
2621
  let source = this[sourceSymbol];
2579
- let src = source.src;
2622
+ let src = source.bytes;
2580
2623
  let dataView = src.dataView || (src.dataView = new DataView(src.buffer, src.byteOffset, src.byteLength));
2581
2624
  let value = dataView.getFloat64(source.position + property.offset, true);
2582
2625
  if (isNaN(value)) {
@@ -2590,12 +2633,22 @@
2590
2633
  case 1:
2591
2634
  get = function () {
2592
2635
  let source = this[sourceSymbol];
2593
- let src = source.src;
2636
+ let src = source.bytes;
2594
2637
  let value = src[source.position + property.offset];
2595
2638
  return value < 0xf6 ? value : toConstant(value);
2596
2639
  };
2597
2640
  break;
2598
2641
  }
2642
+ break;
2643
+ case DATE:
2644
+ get = function () {
2645
+ let source = this[sourceSymbol];
2646
+ let src = source.bytes;
2647
+ let dataView = src.dataView || (src.dataView = new DataView(src.buffer, src.byteOffset, src.byteLength));
2648
+ return new Date(dataView.getFloat64(source.position + property.offset, true));
2649
+ };
2650
+ break;
2651
+
2599
2652
  }
2600
2653
  property.get = get;
2601
2654
  }
@@ -2604,10 +2657,10 @@
2604
2657
  }
2605
2658
  var instance = new construct();
2606
2659
  instance[sourceSymbol] = {
2607
- src,
2660
+ bytes: src,
2608
2661
  position,
2609
2662
  srcString: '',
2610
- srcEnd
2663
+ bytesEnd: srcEnd
2611
2664
  };
2612
2665
  return instance;
2613
2666
  }
@@ -2620,6 +2673,14 @@
2620
2673
  }
2621
2674
  throw new Error('Unknown constant');
2622
2675
  }
2676
+
2677
+ function saveState$1() {
2678
+ if (currentSource) {
2679
+ currentSource.bytes = Uint8Array.prototype.slice.call(currentSource.bytes, currentSource.position, currentSource.bytesEnd);
2680
+ currentSource.position = 0;
2681
+ currentSource.bytesEnd = currentSource.bytes.length;
2682
+ }
2683
+ }
2623
2684
  function prepareStructures$1(structures, packr) {
2624
2685
  if (packr.typedStructs) {
2625
2686
  let structMap = new Map();
@@ -2649,12 +2710,17 @@
2649
2710
  return structures;
2650
2711
  }
2651
2712
 
2652
- setReadStruct(readStruct$1, onLoadedStructures$1);
2713
+ setReadStruct(readStruct$1, onLoadedStructures$1, saveState$1);
2653
2714
 
2654
2715
  let allSampleData = [];
2655
2716
  for (let i = 1; i < 6; i++) {
2656
2717
  allSampleData.push(JSON.parse(fs.readFileSync(new URL(`./example${i > 1 ? i : ''}.json`, (document.currentScript && document.currentScript.src || new URL('test.js', document.baseURI).href)))));
2657
2718
  }
2719
+ allSampleData.push({
2720
+ name: 'some other types',
2721
+ date: new Date(),
2722
+ empty: '',
2723
+ });
2658
2724
  const sampleData = allSampleData[3];
2659
2725
  function tryRequire(module) {
2660
2726
  try {
@@ -2833,7 +2899,6 @@
2833
2899
  var deserialized = packr.unpack(serialized);
2834
2900
  assert.deepEqual(deserialized, data);
2835
2901
  });
2836
- break;
2837
2902
  }
2838
2903
 
2839
2904
  test('pack/unpack empty data with bundled strings', function(){