msgpackr 1.11.2 → 1.11.4

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/index.js CHANGED
@@ -915,7 +915,10 @@
915
915
  if (typeof property === 'string') return property;
916
916
  if (typeof property === 'number' || typeof property === 'boolean' || typeof property === 'bigint') return property.toString();
917
917
  if (property == null) return property + '';
918
- throw new Error('Invalid property type for record', typeof property);
918
+ if (currentUnpackr.allowArraysInMapKeys && Array.isArray(property) && property.flat().every(item => ['string', 'number', 'boolean', 'bigint'].includes(typeof item))) {
919
+ return property.flat().toString();
920
+ }
921
+ throw new Error(`Invalid property type for record: ${typeof property}`);
919
922
  }
920
923
  // the registration of the record definition extension (as "r")
921
924
  const recordDefinition = (id, highByte) => {
@@ -965,20 +968,33 @@
965
968
  referenceMap = new Map();
966
969
  let token = src[position$1];
967
970
  let target;
968
- // TODO: handle Maps, Sets, and other types that can cycle; this is complicated, because you potentially need to read
969
- // ahead past references to record structure definitions
971
+ // TODO: handle any other types that can cycle and make the code more robust if there are other extensions
970
972
  if (token >= 0x90 && token < 0xa0 || token == 0xdc || token == 0xdd)
971
973
  target = [];
974
+ else if (token >= 0x80 && token < 0x90 || token == 0xde || token == 0xdf)
975
+ target = new Map();
976
+ else if ((token >= 0xc7 && token <= 0xc9 || token >= 0xd4 && token <= 0xd8) && src[position$1 + 1] === 0x73)
977
+ target = new Set();
972
978
  else
973
979
  target = {};
974
980
 
975
981
  let refEntry = { target }; // a placeholder object
976
982
  referenceMap.set(id, refEntry);
977
983
  let targetProperties = read(); // read the next value as the target object to id
978
- if (refEntry.used) // there is a cycle, so we have to assign properties to original target
979
- return Object.assign(target, targetProperties)
980
- refEntry.target = targetProperties; // the placeholder wasn't used, replace with the deserialized one
981
- return targetProperties // no cycle, can just use the returned read object
984
+ if (!refEntry.used) {
985
+ // no cycle, can just use the returned read object
986
+ return refEntry.target = targetProperties // replace the placeholder with the real one
987
+ } else {
988
+ // there is a cycle, so we have to assign properties to original target
989
+ Object.assign(target, targetProperties);
990
+ }
991
+
992
+ // copy over map/set entries if we're able to
993
+ if (target instanceof Map)
994
+ for (let [k, v] of targetProperties.entries()) target.set(k, v);
995
+ if (target instanceof Set)
996
+ for (let i of Array.from(targetProperties)) target.add(i);
997
+ return target
982
998
  };
983
999
 
984
1000
  currentExtensions[0x70] = (data) => {
@@ -997,18 +1013,16 @@
997
1013
  let glbl = typeof globalThis === 'object' ? globalThis : window;
998
1014
  currentExtensions[0x74] = (data) => {
999
1015
  let typeCode = data[0];
1016
+ // we always have to slice to get a new ArrayBuffer that is aligned
1017
+ let buffer = Uint8Array.prototype.slice.call(data, 1).buffer;
1018
+
1000
1019
  let typedArrayName = typedArrays[typeCode];
1001
1020
  if (!typedArrayName) {
1002
- if (typeCode === 16) {
1003
- let ab = new ArrayBuffer(data.length - 1);
1004
- let u8 = new Uint8Array(ab);
1005
- u8.set(data.subarray(1));
1006
- return ab;
1007
- }
1021
+ if (typeCode === 16) return buffer
1022
+ if (typeCode === 17) return new DataView(buffer)
1008
1023
  throw new Error('Could not find typed array for code ' + typeCode)
1009
1024
  }
1010
- // we have to always slice/copy here to get a new ArrayBuffer that is word/byte aligned
1011
- return new glbl[typedArrayName](Uint8Array.prototype.slice.call(data, 1).buffer)
1025
+ return new glbl[typedArrayName](buffer)
1012
1026
  };
1013
1027
  currentExtensions[0x78] = () => {
1014
1028
  let data = read();
@@ -1036,13 +1050,13 @@
1036
1050
  return new Date(
1037
1051
  ((data[0] << 22) + (data[1] << 14) + (data[2] << 6) + (data[3] >> 2)) / 1000000 +
1038
1052
  ((data[3] & 0x3) * 0x100000000 + data[4] * 0x1000000 + (data[5] << 16) + (data[6] << 8) + data[7]) * 1000)
1039
- else if (data.length == 12)// TODO: Implement support for negative
1053
+ else if (data.length == 12)
1040
1054
  return new Date(
1041
1055
  ((data[0] << 24) + (data[1] << 16) + (data[2] << 8) + data[3]) / 1000000 +
1042
1056
  (((data[4] & 0x80) ? -0x1000000000000 : 0) + data[6] * 0x10000000000 + data[7] * 0x100000000 + data[8] * 0x1000000 + (data[9] << 16) + (data[10] << 8) + data[11]) * 1000)
1043
1057
  else
1044
1058
  return new Date('invalid')
1045
- }; // notepack defines extension 0 to mean undefined, so use that as the default here
1059
+ };
1046
1060
  // registration of bulk record definition?
1047
1061
  // currentExtensions[0x52] = () =>
1048
1062
 
@@ -1636,11 +1650,11 @@
1636
1650
  } else if (type === 'boolean') {
1637
1651
  target[position++] = value ? 0xc3 : 0xc2;
1638
1652
  } else if (type === 'bigint') {
1639
- if (value < (BigInt(1)<<BigInt(63)) && value >= -(BigInt(1)<<BigInt(63))) {
1653
+ if (value < 0x8000000000000000 && value >= -0x8000000000000000) {
1640
1654
  // use a signed int as long as it fits
1641
1655
  target[position++] = 0xd3;
1642
1656
  targetView.setBigInt64(position, value);
1643
- } else if (value < (BigInt(1)<<BigInt(64)) && value > 0) {
1657
+ } else if (value < 0x10000000000000000 && value > 0) {
1644
1658
  // if we can fit an unsigned int, use that
1645
1659
  target[position++] = 0xcf;
1646
1660
  targetView.setBigUint64(position, value);
@@ -1651,7 +1665,7 @@
1651
1665
  targetView.setFloat64(position, Number(value));
1652
1666
  } else if (this.largeBigIntToString) {
1653
1667
  return pack(value.toString());
1654
- } else if (this.useBigIntExtension && value < BigInt(2)**BigInt(1023) && value > -(BigInt(2)**BigInt(1023))) {
1668
+ } else if ((this.useBigIntExtension || this.moreTypes) && value < BigInt(2)**BigInt(1023) && value > -(BigInt(2)**BigInt(1023))) {
1655
1669
  target[position++] = 0xc7;
1656
1670
  position++;
1657
1671
  target[position++] = 0x42; // "B" for BigInt
@@ -1970,7 +1984,7 @@
1970
1984
  }
1971
1985
  }
1972
1986
 
1973
- extensionClasses = [ Date, Set, Error, RegExp, ArrayBuffer, Object.getPrototypeOf(Uint8Array.prototype).constructor /*TypedArray*/, C1Type ];
1987
+ extensionClasses = [ Date, Set, Error, RegExp, ArrayBuffer, Object.getPrototypeOf(Uint8Array.prototype).constructor /*TypedArray*/, DataView, C1Type ];
1974
1988
  extensions = [{
1975
1989
  pack(date, allocateForWrite, pack) {
1976
1990
  let seconds = date.getTime() / 1000;
@@ -2057,6 +2071,13 @@
2057
2071
  else
2058
2072
  writeBuffer(typedArray, allocateForWrite);
2059
2073
  }
2074
+ }, {
2075
+ pack(arrayBuffer, allocateForWrite) {
2076
+ if (this.moreTypes)
2077
+ writeExtBuffer(arrayBuffer, 0x11, allocateForWrite);
2078
+ else
2079
+ writeBuffer(hasNodeBuffer ? Buffer.from(arrayBuffer) : new Uint8Array(arrayBuffer), allocateForWrite);
2080
+ }
2060
2081
  }, {
2061
2082
  pack(c1, allocateForWrite) { // specific 0xC1 object
2062
2083
  let { target, position} = allocateForWrite(1);