msgpackr 1.9.2 → 1.9.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/README.md CHANGED
@@ -172,7 +172,7 @@ unpackMultiple(data, (value,start,end) => {
172
172
  ## Options
173
173
  The following options properties can be provided to the Packr or Unpackr constructor:
174
174
 
175
- * `useRecords` - Setting this to `false` disables the record extension and stores JavaScript objects as MessagePack maps, and unpacks maps as JavaScript `Object`s, which ensures compatibilty with other decoders.
175
+ * `useRecords` - Setting this to `false` disables the record extension and stores JavaScript objects as MessagePack maps, and unpacks maps as JavaScript `Object`s, which ensures compatibilty with other decoders. Setting this to a function will use records for objects where `useRecords(object)` returns `true`.
176
176
  * `structures` - Provides the array of structures that is to be used for record extension, if you want the structures saved and used again. This array will be modified in place with new record structures that are serialized (if less than 32 structures are in the array).
177
177
  * `moreTypes` - Enable serialization of additional built-in types/classes including typed arrays, `Set`s, `Map`s, and `Error`s.
178
178
  * `structuredClone` - This enables the structured cloning extensions that will encode object/cyclic references. `moreTypes` is enabled by default when this is enabled.
@@ -933,10 +933,10 @@
933
933
  currentExtensions[0] = () => {}; // notepack defines extension 0 to mean undefined, so use that as the default here
934
934
  currentExtensions[0].noBuffer = true;
935
935
 
936
- let glbl = typeof globalThis === 'object' ? globalThis : window;
936
+ let errors = { Error, TypeError, ReferenceError };
937
937
  currentExtensions[0x65] = () => {
938
938
  let data = read();
939
- return (glbl[data[0]] || Error)(data[1])
939
+ return (errors[data[0]] || Error)(data[1])
940
940
  };
941
941
 
942
942
  currentExtensions[0x69] = (data) => {
@@ -974,6 +974,7 @@
974
974
 
975
975
  const typedArrays = ['Int8','Uint8','Uint8Clamped','Int16','Uint16','Int32','Uint32','Float32','Float64','BigInt64','BigUint64'].map(type => type + 'Array');
976
976
 
977
+ let glbl = typeof globalThis === 'object' ? globalThis : window;
977
978
  currentExtensions[0x74] = (data) => {
978
979
  let typeCode = data[0];
979
980
  let typedArrayName = typedArrays[typeCode];
@@ -1468,7 +1469,7 @@
1468
1469
  targetView.setFloat64(position, value);
1469
1470
  position += 8;
1470
1471
  }
1471
- } else if (type === 'object') {
1472
+ } else if (type === 'object' || type === 'function') {
1472
1473
  if (!value)
1473
1474
  target[position++] = 0xc0;
1474
1475
  else {
@@ -1575,6 +1576,11 @@
1575
1576
  } else {
1576
1577
  if (value.toJSON) // use this as an alternate mechanism for expressing how to serialize
1577
1578
  return pack(value.toJSON());
1579
+
1580
+ // if there is a writeFunction, use it, otherwise just encode as undefined
1581
+ if (type === 'function')
1582
+ return pack(this.writeFunction && this.writeFunction(value));
1583
+
1578
1584
  // no extension found, write as object
1579
1585
  writeObject(value, !value.hasOwnProperty); // if it doesn't have hasOwnProperty, don't do hasOwnProperty checks
1580
1586
  }
@@ -1609,14 +1615,12 @@
1609
1615
  target[position++] = 0;
1610
1616
  target[position++] = 0;
1611
1617
  }
1612
- } else if (type === 'function') {
1613
- pack(this.writeFunction && this.writeFunction()); // if there is a writeFunction, use it, otherwise just encode as undefined
1614
1618
  } else {
1615
1619
  throw new Error('Unknown type: ' + type)
1616
1620
  }
1617
1621
  };
1618
1622
 
1619
- const writeObject = this.useRecords === false ? this.variableMapSize ? (object) => {
1623
+ const writePlainObject = (this.variableMapSize || this.coercibleKeyAsNumber) ? (object) => {
1620
1624
  // this method is slightly slower, but generates "preferred serialization" (optimally small for smaller objects)
1621
1625
  let keys = Object.keys(object);
1622
1626
  let length = keys.length;
@@ -1632,9 +1636,19 @@
1632
1636
  position += 4;
1633
1637
  }
1634
1638
  let key;
1635
- for (let i = 0; i < length; i++) {
1636
- pack(key = keys[i]);
1637
- pack(object[key]);
1639
+ if (this.coercibleKeyAsNumber) {
1640
+ for (let i = 0; i < length; i++) {
1641
+ key = keys[i];
1642
+ let num = Number(key);
1643
+ pack(isNaN(num) ? key : num);
1644
+ pack(object[key]);
1645
+ }
1646
+
1647
+ } else {
1648
+ for (let i = 0; i < length; i++) {
1649
+ pack(key = keys[i]);
1650
+ pack(object[key]);
1651
+ }
1638
1652
  }
1639
1653
  } :
1640
1654
  (object, safePrototype) => {
@@ -1651,7 +1665,9 @@
1651
1665
  }
1652
1666
  target[objectOffset++ + start] = size >> 8;
1653
1667
  target[objectOffset + start] = size & 0xff;
1654
- } :
1668
+ };
1669
+
1670
+ const writeRecord = this.useRecords === false ? writePlainObject :
1655
1671
  (options.progressiveRecords && !useTwoByteRecords) ? // this is about 2% faster for highly stable structures, since it only requires one for-in loop (but much more expensive when new structure needs to be written)
1656
1672
  (object, safePrototype) => {
1657
1673
  let nextTransition, transition = structures.transitions || (structures.transitions = Object.create(null));
@@ -1723,6 +1739,14 @@
1723
1739
  if (safePrototype || object.hasOwnProperty(key))
1724
1740
  pack(object[key]);
1725
1741
  };
1742
+
1743
+ // craete reference to useRecords if useRecords is a function
1744
+ const checkUseRecords = typeof this.useRecords == 'function' && this.useRecords;
1745
+
1746
+ const writeObject = checkUseRecords ? (object, safePrototype) => {
1747
+ checkUseRecords(object) ? writeRecord(object,safePrototype) : writePlainObject(object,safePrototype);
1748
+ } : writeRecord;
1749
+
1726
1750
  const makeRoom = (end) => {
1727
1751
  let newSize;
1728
1752
  if (end > 0x1000000) {