msgpackr 1.7.0-alpha6 → 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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "msgpackr",
3
3
  "author": "Kris Zyp",
4
- "version": "1.7.0-alpha6",
4
+ "version": "1.7.0-alpha7",
5
5
  "description": "Ultra-fast MessagePack implementation with extensions for records and structured cloning",
6
6
  "license": "MIT",
7
7
  "types": "./index.d.ts",
package/struct.js CHANGED
@@ -41,11 +41,13 @@ const ASCII = 3; // the MIBenum from https://www.iana.org/assignments/character-
41
41
  const NUMBER = 0;
42
42
  const UTF8 = 2;
43
43
  const OBJECT_DATA = 1;
44
+ const DATE = 16;
44
45
  const TYPE_NAMES = ['num', 'object', 'string', 'ascii'];
46
+ TYPE_NAMES[DATE] = 'date';
45
47
  const float32Headers = [false, true, true, false, false, true, true, false];
46
48
  let updatedPosition;
47
49
  const hasNodeBuffer = typeof Buffer !== 'undefined'
48
- let textEncoder
50
+ let textEncoder, currentSource;
49
51
  try {
50
52
  textEncoder = new TextEncoder()
51
53
  } catch (error) {}
@@ -89,7 +91,7 @@ function writeStruct(object, target, position, structures, makeRoom, pack, packr
89
91
  return 0;
90
92
  position += headerSize;
91
93
  let queuedReferences = [];
92
- let usedLatin0;
94
+ let usedAscii0;
93
95
  let keyIndex = 0;
94
96
  for (let key in object) {
95
97
  let value = object[key];
@@ -105,7 +107,8 @@ function writeStruct(object, target, position, structures, makeRoom, pack, packr
105
107
  string16: null,
106
108
  object16: null,
107
109
  num32: null,
108
- float64: null
110
+ float64: null,
111
+ date64: null
109
112
  };
110
113
  }
111
114
  if (position > safeEnd) {
@@ -198,25 +201,47 @@ function writeStruct(object, target, position, structures, makeRoom, pack, packr
198
201
  refPosition += encodeUtf8(target, value, refPosition);
199
202
  isNotAscii = refPosition - strStart > strLength;
200
203
  }
201
- if (refOffset < 0xf6) {
202
- if (isNotAscii)
203
- transition = nextTransition.string8 || createTypeTransition(nextTransition, UTF8, 1);
204
- else
205
- transition = nextTransition.ascii8 || createTypeTransition(nextTransition, ASCII, 1);
204
+ if (refOffset < 0xa0 || (refOffset < 0xf6 && (nextTransition.ascii8 || nextTransition.string8))) {
205
+ // short strings
206
+ if (isNotAscii) {
207
+ if (!(transition = nextTransition.string8)) {
208
+ if (typedStructs.length > 10 && (transition = nextTransition.ascii8)) {
209
+ // we can safely change ascii to utf8 in place since they are compatible
210
+ transition.__type = UTF8;
211
+ nextTransition.ascii8 = null;
212
+ nextTransition.string8 = transition;
213
+ pack(null, 0, true); // special call to notify that structures have been updated
214
+ } else {
215
+ transition = createTypeTransition(nextTransition, UTF8, 1);
216
+ }
217
+ }
218
+ } else if (refOffset === 0 && !usedAscii0) {
219
+ usedAscii0 = true;
220
+ transition = nextTransition.ascii0 || createTypeTransition(nextTransition, ASCII, 0);
221
+ break; // don't increment position
222
+ }// else ascii:
223
+ else if (!(transition = nextTransition.ascii8) && !(typedStructs.length > 10 && (transition = nextTransition.string8)))
224
+ transition = createTypeTransition(nextTransition, ASCII, 1);
206
225
  target[position++] = refOffset;
207
226
  } else {
208
- if (isNotAscii)
227
+ // TODO: Enable ascii16 at some point, but get the logic right
228
+ //if (isNotAscii)
209
229
  transition = nextTransition.string16 || createTypeTransition(nextTransition, UTF8, 2);
210
- else
211
- transition = nextTransition.ascii16 || createTypeTransition(nextTransition, ASCII, 2);
230
+ //else
231
+ //transition = nextTransition.ascii16 || createTypeTransition(nextTransition, ASCII, 2);
212
232
  targetView.setUint16(position, refOffset, true);
213
233
  position += 2;
214
234
  }
215
235
  break;
216
236
  case 'object':
217
237
  if (value) {
218
- //transition = nextTransition.object16 || createTypeTransition(nextTransition, OBJECT_DATA, 2);
219
- queuedReferences.push(key, value, keyIndex);
238
+ if (value.constructor === Date) {
239
+ transition = nextTransition.date64 || createTypeTransition(nextTransition, DATE, 8);
240
+ targetView.setFloat64(position, value.getTime(), true);
241
+ position += 8;
242
+ } else {
243
+ queuedReferences.push(key, value, keyIndex);
244
+ }
220
245
  break;
221
246
  } else { // null
222
247
  nextTransition = anyType(nextTransition, position, targetView, -10); // match CBOR with this
@@ -434,7 +459,8 @@ function onLoadedStructures(sharedData) {
434
459
  string16: null,
435
460
  object16: null,
436
461
  num32: null,
437
- float64: null
462
+ float64: null,
463
+ date64: null,
438
464
  };
439
465
  }
440
466
  transition = createTypeTransition(nextTransition, type, size);
@@ -612,7 +638,12 @@ function readStruct(src, position, srcEnd, unpackr) {
612
638
  if (type === UTF8) {
613
639
  return src.toString('utf8', ref + refStart, end + refStart);
614
640
  } else {
615
- return unpackr.unpack(src, { start: ref + refStart, end: end + refStart }); // could reuse this object
641
+ currentSource = source;
642
+ try {
643
+ return unpackr.unpack(src, { start: ref + refStart, end: end + refStart });
644
+ } finally {
645
+ currentSource = null;
646
+ }
616
647
  }
617
648
  };
618
649
  break;
@@ -660,6 +691,16 @@ function readStruct(src, position, srcEnd, unpackr) {
660
691
  };
661
692
  break;
662
693
  }
694
+ break;
695
+ case DATE:
696
+ get = function () {
697
+ let source = this[sourceSymbol];
698
+ let src = source.src;
699
+ let dataView = src.dataView || (src.dataView = new DataView(src.buffer, src.byteOffset, src.byteLength));
700
+ return new Date(dataView.getFloat64(source.position + property.offset, true));
701
+ };
702
+ break;
703
+
663
704
  }
664
705
  property.get = get;
665
706
  }
@@ -684,6 +725,14 @@ function toConstant(code) {
684
725
  }
685
726
  throw new Error('Unknown constant');
686
727
  }
728
+
729
+ function saveState() {
730
+ if (currentSource) {
731
+ currentSource.src = Uint8Array.prototype.slice.call(currentSource.src, currentSource.position, currentSource.srcEnd);
732
+ currentSource.position = 0;
733
+ currentSource.srcEnd = currentSource.src.length;
734
+ }
735
+ }
687
736
  function prepareStructures(structures, packr) {
688
737
  if (packr.typedStructs) {
689
738
  let structMap = new Map();
@@ -713,5 +762,5 @@ function prepareStructures(structures, packr) {
713
762
  return structures;
714
763
  }
715
764
 
716
- setReadStruct(readStruct, onLoadedStructures);
765
+ setReadStruct(readStruct, onLoadedStructures, saveState);
717
766
 
package/unpack.js CHANGED
@@ -28,7 +28,7 @@ export const C1 = new C1Type()
28
28
  C1.name = 'MessagePack 0xC1'
29
29
  var sequentialMode = false
30
30
  var inlineObjectReadThreshold = 2
31
- var readStruct, onLoadedStructures
31
+ var readStruct, onLoadedStructures, onSaveState
32
32
  try {
33
33
  new Function('')
34
34
  } catch(error) {
@@ -208,7 +208,7 @@ export function checkedRead(options) {
208
208
  // else more to read, but we are reading sequentially, so don't clear source yet
209
209
  return result
210
210
  } catch(error) {
211
- if (currentStructures.restoreStructures)
211
+ if (currentStructures?.restoreStructures)
212
212
  restoreStructures()
213
213
  clearSource()
214
214
  if (error instanceof RangeError || error.message.startsWith('Unexpected end of buffer') || position > srcEnd) {
@@ -1032,6 +1032,8 @@ currentExtensions[0xff] = (data) => {
1032
1032
  // currentExtensions[0x52] = () =>
1033
1033
 
1034
1034
  function saveState(callback) {
1035
+ if (onSaveState)
1036
+ onSaveState();
1035
1037
  let savedSrcEnd = srcEnd
1036
1038
  let savedPosition = position
1037
1039
  let savedStringPosition = stringPosition
@@ -1101,7 +1103,8 @@ export function roundFloat32(float32Number) {
1101
1103
  let multiplier = mult10[((u8Array[3] & 0x7f) << 1) | (u8Array[2] >> 7)]
1102
1104
  return ((multiplier * float32Number + (float32Number > 0 ? 0.5 : -0.5)) >> 0) / multiplier
1103
1105
  }
1104
- export function setReadStruct(updatedReadStruct, loadedStructs) {
1106
+ export function setReadStruct(updatedReadStruct, loadedStructs, saveState) {
1105
1107
  readStruct = updatedReadStruct;
1106
1108
  onLoadedStructures = loadedStructs;
1109
+ onSaveState = saveState;
1107
1110
  }