msgpackr 1.4.5 → 1.5.1

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
@@ -1,10 +1,11 @@
1
1
  # msgpackr
2
- [![license](https://img.shields.io/badge/license-MIT-brightgreen)](LICENSE)
3
2
  [![npm version](https://img.shields.io/npm/v/msgpackr.svg?style=flat-square)](https://www.npmjs.org/package/msgpackr)
3
+ [![npm version](https://img.shields.io/npm/dw/msgpackr)](https://www.npmjs.org/package/msgpackr)
4
4
  [![encode](https://img.shields.io/badge/encode-1.5GB%2Fs-yellow)](benchmark.md)
5
5
  [![decode](https://img.shields.io/badge/decode-2GB%2Fs-yellow)](benchmark.md)
6
6
  [![types](https://img.shields.io/npm/types/msgpackr)](README.md)
7
7
  [![module](https://img.shields.io/badge/module-ESM%2FCJS-blue)](README.md)
8
+ [![license](https://img.shields.io/badge/license-MIT-brightgreen)](LICENSE)
8
9
 
9
10
 
10
11
  The msgpackr package is an extremely fast MessagePack NodeJS/JavaScript implementation. Currently, it is significantly faster than any other known implementations, faster than Avro (for JS), and generally faster than native V8 JSON.stringify/parse, on NodeJS. It also includes an optional record extension (the `r` in msgpackr), for defining record structures that makes MessagePack even faster and more compact, often over twice as fast as even native JSON functions, several times faster than other JS implementations, and 15-50% more compact. See the performance section for more details. Structured cloning (with support for cyclical references) is also supported through optional extensions.
@@ -166,6 +167,8 @@ The following options properties can be provided to the Packr or Unpackr constru
166
167
  * `sequential` - Encode structures in serialized data, and reference previously encoded structures with expectation that decoder will read the encoded structures in the same order as encoded, with `unpackMultiple`.
167
168
  * `largeBigIntToFloat` - If a bigint needs to be encoded that is larger than will fit in 64-bit integers, it will be encoded as a float-64 (otherwise will throw a RangeError).
168
169
  * `encodeUndefinedAsNil` - Encodes a value of `undefined` as a MessagePack `nil`, the same as a `null`.
170
+ * `int64AsNumber` - This will decode uint64 and int64 numbers as standard JS numbers rather than as bigint numbers.
171
+ * `onInvalidDate` - This can be provided as function that will be called when an invalid date is provided. The function can throw an error, or return a value that will be encoded in place of the invalid date. If not provided, an invalid date will be encoded as an invalid timestamp (which decodes with msgpackr back to an invalid date).
169
172
 
170
173
  ### 32-bit Float Options
171
174
  By default all non-integer numbers are serialized as 64-bit float (double). This is fast, and ensures maximum precision. However, often real-world data doesn't not need 64-bits of precision, and using 32-bit encoding can be much more space efficient. There are several options that provide more efficient encodings. Using the decimal rounding options for encoding and decoding provides lossless storage of common decimal representations like 7.99, in more efficient 32-bit format (rather than 64-bit). The `useFloat32` property has several possible options, available from the module as constants:
@@ -176,13 +179,22 @@ const { ALWAYS, DECIMAL_ROUND, DECIMAL_FIT } = FLOAT32_OPTIONS;
176
179
 
177
180
  * `ALWAYS` (1) - Always will encode non-integers (absolute less than 2147483648) as 32-bit float.
178
181
  * `DECIMAL_ROUND` (3) - Always will encode non-integers as 32-bit float, and when decoding 32-bit float, round to the significant decimal digits (usually 7, but 6 or 8 digits for some ranges).
179
- * `DECIMAL_FIT` (4) - Only encode non-integers as 32-bit float if all significant digits (usually up to 7) can be unamiguously encoded as a 32-bit float, and decode/unpack with decimal rounding (same as above). This will ensure round-trip encoding/decoding without loss in precision and use 32-bit when possible.
182
+ * `DECIMAL_FIT` (4) - Only encode non-integers as 32-bit float if all significant digits (usually up to 7) can be unambiguously encoded as a 32-bit float, and decode/unpack with decimal rounding (same as above). This will ensure round-trip encoding/decoding without loss in precision and uses 32-bit when possible.
180
183
 
181
184
  Note, that the performance is decreased with decimal rounding by about 20-25%, although if only 5% of your values are floating point, that will only have about a 1% impact overall.
182
185
 
183
- In addition, msgpackr exports a `roundFloat32(number)` function that can be used to round floating point numbers to the maximum significant decimal digits that can be stored in 32-bit float, just as DECIMAL_ROUND does when encoding. This can be useful for determine how a number will be stored prior to encoding it.
186
+ In addition, msgpackr exports a `roundFloat32(number)` function that can be used to round floating point numbers to the maximum significant decimal digits that can be stored in 32-bit float, just as DECIMAL_ROUND does when decoding. This can be useful for determining how a number will be decoded prior to encoding it.
184
187
 
185
188
  ## Performance
189
+ ### Native Acceleration
190
+ Msgpackr employs an optional native node-addon to accelerate the parsing of strings. This should be automatically installed and utilized on NodeJS. However, you can verify this by checking the `isNativeAccelerationEnabled` property that is exported from msgpackr. If this is `false`, the `msgpackr-extract` package may not have been properly installed, and you may want to verify that it is installed correctly:
191
+ ```js
192
+ import { isNativeAccelerationEnabled } from 'msgpackr'
193
+ if (!isNativeAccelerationEnabled)
194
+ console.warn('Native acceleration not enabled, verify that install finished properly')
195
+ ```
196
+
197
+ ### Benchmarks
186
198
  Msgpackr is fast. Really fast. Here is comparison with the next fastest JS projects using the benchmark tool from `msgpack-lite` (and the sample data is from some clinical research data we use that has a good mix of different value types and structures). It also includes comparison to V8 native JSON functionality, and JavaScript Avro (`avsc`, a very optimized Avro implementation):
187
199
 
188
200
  operation | op | ms | op/s
package/dist/index.js CHANGED
@@ -58,8 +58,16 @@
58
58
  // this provides cached access to the data view for a buffer if it is getting reused, which is a recommend
59
59
  // technique for getting data from a database where it can be copied into an existing buffer instead of creating
60
60
  // new ones
61
- dataView = source.dataView || (source.dataView = new DataView(source.buffer, source.byteOffset, source.byteLength));
62
- if (this) {
61
+ try {
62
+ dataView = source.dataView || (source.dataView = new DataView(source.buffer, source.byteOffset, source.byteLength));
63
+ } catch(error) {
64
+ // if it doesn't have a buffer, maybe it is the wrong type of object
65
+ src = null;
66
+ if (source instanceof Uint8Array)
67
+ throw error
68
+ throw new Error('Source must be a Uint8Array or Buffer but was a ' + ((source && typeof source == 'object') ? source.constructor.name : typeof source))
69
+ }
70
+ if (this instanceof Unpackr) {
63
71
  currentUnpackr = this;
64
72
  if (this.structures) {
65
73
  currentStructures = this.structures;
@@ -291,10 +299,11 @@
291
299
  position += 4;
292
300
  return value
293
301
  case 0xcf:
294
- if (currentUnpackr.uint64AsNumber)
295
- return src[position++] * 0x100000000000000 + src[position++] * 0x1000000000000 + src[position++] * 0x10000000000 + src[position++] * 0x100000000 +
296
- src[position++] * 0x1000000 + (src[position++] << 16) + (src[position++] << 8) + src[position++]
297
- value = dataView.getBigUint64(position);
302
+ if (currentUnpackr.int64AsNumber) {
303
+ value = dataView.getUint32(position) * 0x100000000;
304
+ value += dataView.getUint32(position + 4);
305
+ } else
306
+ value = dataView.getBigUint64(position);
298
307
  position += 8;
299
308
  return value
300
309
 
@@ -310,7 +319,11 @@
310
319
  position += 4;
311
320
  return value
312
321
  case 0xd3:
313
- value = dataView.getBigInt64(position);
322
+ if (currentUnpackr.int64AsNumber) {
323
+ value = dataView.getInt32(position) * 0x100000000;
324
+ value += dataView.getUint32(position + 4);
325
+ } else
326
+ value = dataView.getBigInt64(position);
314
327
  position += 8;
315
328
  return value
316
329
 
@@ -459,6 +472,7 @@
459
472
  var readString8 = readStringJS;
460
473
  var readString16 = readStringJS;
461
474
  var readString32 = readStringJS;
475
+ let isNativeAccelerationEnabled = false;
462
476
  function readStringJS(length) {
463
477
  let result;
464
478
  if (length < 16) {
@@ -856,7 +870,7 @@
856
870
  ((data[0] << 24) + (data[1] << 16) + (data[2] << 8) + data[3]) / 1000000 +
857
871
  (((data[4] & 0x80) ? -0x1000000000000 : 0) + data[6] * 0x10000000000 + data[7] * 0x100000000 + data[8] * 0x1000000 + (data[9] << 16) + (data[10] << 8) + data[11]) * 1000)
858
872
  else
859
- throw new Error('Invalid timestamp length')
873
+ return new Date('invalid')
860
874
  }; // notepack defines extension 0 to mean undefined, so use that as the default here
861
875
  // registration of bulk record definition?
862
876
  // currentExtensions[0x52] = () =>
@@ -1101,9 +1115,9 @@
1101
1115
  // first we estimate the header size, so we can write to the correct location
1102
1116
  if (strLength < 0x20) {
1103
1117
  headerSize = 1;
1104
- } else if (strLength < 0xff) {
1118
+ } else if (strLength < 0x100) {
1105
1119
  headerSize = 2;
1106
- } else if (strLength < 0xff00) {
1120
+ } else if (strLength < 0x10000) {
1107
1121
  headerSize = 3;
1108
1122
  } else {
1109
1123
  headerSize = 5;
@@ -1516,7 +1530,7 @@
1516
1530
  if ((end - start) > MAX_BUFFER_SIZE)
1517
1531
  throw new Error('Packed buffer would be larger than maximum buffer size')
1518
1532
  newSize = Math.min(MAX_BUFFER_SIZE,
1519
- Math.round(Math.max((end - start) * (end > 0x4000000 ? 1.25 : 2), 0x1000000) / 0x1000) * 0x1000);
1533
+ Math.round(Math.max((end - start) * (end > 0x4000000 ? 1.25 : 2), 0x400000) / 0x1000) * 0x1000);
1520
1534
  } else // faster handling for smaller buffers
1521
1535
  newSize = ((Math.max((end - start) << 2, target.length - 1) >> 12) + 1) << 12;
1522
1536
  let newBuffer = new ByteArrayAllocate(newSize);
@@ -1541,7 +1555,7 @@
1541
1555
 
1542
1556
  extensionClasses = [ Date, Set, Error, RegExp, ArrayBuffer, Object.getPrototypeOf(Uint8Array.prototype).constructor /*TypedArray*/, C1Type ];
1543
1557
  extensions = [{
1544
- pack(date, allocateForWrite) {
1558
+ pack(date, allocateForWrite, pack) {
1545
1559
  let seconds = date.getTime() / 1000;
1546
1560
  if ((this.useTimestamp32 || date.getMilliseconds() === 0) && seconds >= 0 && seconds < 0x100000000) {
1547
1561
  // Timestamp 32
@@ -1556,6 +1570,14 @@
1556
1570
  target[position++] = 0xff;
1557
1571
  targetView.setUint32(position, date.getMilliseconds() * 4000000 + ((seconds / 1000 / 0x100000000) >> 0));
1558
1572
  targetView.setUint32(position + 4, seconds);
1573
+ } else if (isNaN(seconds)) {
1574
+ if (this.onInvalidDate)
1575
+ return pack(this.onInvalidDate())
1576
+ // Intentionally invalid timestamp
1577
+ let { target, targetView, position} = allocateForWrite(3);
1578
+ target[position++] = 0xd4;
1579
+ target[position++] = 0xff;
1580
+ target[position++] = 0xff;
1559
1581
  } else {
1560
1582
  // Timestamp 96
1561
1583
  let { target, targetView, position} = allocateForWrite(15);
@@ -1848,6 +1870,7 @@
1848
1870
  exports.decodeIter = decodeIter;
1849
1871
  exports.encode = encode;
1850
1872
  exports.encodeIter = encodeIter;
1873
+ exports.isNativeAccelerationEnabled = isNativeAccelerationEnabled;
1851
1874
  exports.mapsAsObjects = mapsAsObjects;
1852
1875
  exports.pack = pack;
1853
1876
  exports.roundFloat32 = roundFloat32;
package/dist/index.min.js CHANGED
@@ -7,8 +7,8 @@ case 194:return!1;case 195:return!0;case 196:// bin 8
7
7
  return m(A[G++]);case 197:return b=F.getUint16(G),G+=2,m(b);case 198:return b=F.getUint32(G),G+=4,m(b);case 199:// ext 8
8
8
  return n(A[G++]);case 200:return b=F.getUint16(G),G+=2,n(b);case 201:return b=F.getUint32(G),G+=4,n(b);case 202:if(b=F.getFloat32(G),2<H.useFloat32){// this does rounding of numbers that were encoded in 32-bit float to nearest significant decimal digit that could be preserved
9
9
  let a=_[(127&A[G])<<1|A[G+1]>>7];return G+=4,(a*b+(0<b?.5:-.5)>>0)/a}return G+=4,b;case 203:return b=F.getFloat64(G),G+=8,b;// uint handlers
10
- case 204:return A[G++];case 205:return b=F.getUint16(G),G+=2,b;case 206:return b=F.getUint32(G),G+=4,b;case 207:return H.uint64AsNumber?72057594037927940*A[G++]+281474976710656*A[G++]+1099511627776*A[G++]+4294967296*A[G++]+16777216*A[G++]+(A[G++]<<16)+(A[G++]<<8)+A[G++]:(b=F.getBigUint64(G),G+=8,b);// int handlers
11
- case 208:return F.getInt8(G++);case 209:return b=F.getInt16(G),G+=2,b;case 210:return b=F.getInt32(G),G+=4,b;case 211:return b=F.getBigInt64(G),G+=8,b;case 212:if(b=A[G++],114==b)return Y(63&A[G++]);else{let a=K[b];if(a)return a.read?(G++,a.read(e())):a.noBuffer?(G++,a()):a(A.subarray(G,++G));throw new Error("Unknown extension "+b)}case 213:return b=A[G],114==b?(G++,Y(63&A[G++],A[G++])):n(2);case 214:// fixext 4
10
+ case 204:return A[G++];case 205:return b=F.getUint16(G),G+=2,b;case 206:return b=F.getUint32(G),G+=4,b;case 207:return H.int64AsNumber?(b=4294967296*F.getUint32(G),b+=F.getUint32(G+4)):b=F.getBigUint64(G),G+=8,b;// int handlers
11
+ case 208:return F.getInt8(G++);case 209:return b=F.getInt16(G),G+=2,b;case 210:return b=F.getInt32(G),G+=4,b;case 211:return H.int64AsNumber?(b=4294967296*F.getInt32(G),b+=F.getUint32(G+4)):b=F.getBigInt64(G),G+=8,b;case 212:if(b=A[G++],114==b)return Y(63&A[G++]);else{let a=K[b];if(a)return a.read?(G++,a.read(e())):a.noBuffer?(G++,a()):a(A.subarray(G,++G));throw new Error("Unknown extension "+b)}case 213:return b=A[G],114==b?(G++,Y(63&A[G++],A[G++])):n(2);case 214:// fixext 4
12
12
  return n(4);case 215:// fixext 8
13
13
  return n(8);case 216:// fixext 16
14
14
  return n(16);case 217:return b=A[G++],J>=G?D.slice(G-I,(G+=b)-I):T(b);case 218:return b=F.getUint16(G),G+=2,J>=G?D.slice(G-I,(G+=b)-I):U(b);case 219:return b=F.getUint32(G),G+=4,J>=G?D.slice(G-I,(G+=b)-I):V(b);case 220:return b=F.getUint16(G),G+=2,i(b);case 221:return b=F.getUint32(G),G+=4,i(b);case 222:return b=F.getUint16(G),G+=2,j(b);case 223:return b=F.getUint32(G),G+=4,j(b);default:// negative int
@@ -35,21 +35,22 @@ a[g++]=214,a[g++]=105,a[g++]=f>>24,a[g++]=255&f>>16,a[g++]=255&f>>8,a[g++]=255&f
35
35
  * @param {object} [options] - unpackr options
36
36
  * @returns {IterableIterator|Promise.<AsyncIterableIterator}
37
37
  */var z;try{z=new TextDecoder}catch(a){}var A,B,C,D,E,F,G=0,H={},I=0,J=0,K=[],L={useRecords:!1,mapsAsObjects:!0};class M{}const N=new M;N.name="MessagePack 0xC1";var O=!1;class P{constructor(a){a&&(!1===a.useRecords&&a.mapsAsObjects===void 0&&(a.mapsAsObjects=!0),a.structures?a.structures.sharedLength=a.structures.length:a.getStructures&&((a.structures=[]).uninitialized=!0,a.structures.sharedLength=0)),Object.assign(this,a)}unpack(a,b){if(A)// re-entrant execution, save the state and restore it after we do this unpack
38
- return p(()=>(q(),this?this.unpack(a,b):P.prototype.unpack.call(L,a,b)));if(B=-1<b?b:a.length,G=0,J=0,D=null,A=a,F=a.dataView||(a.dataView=new DataView(a.buffer,a.byteOffset,a.byteLength)),this){if(H=this,this.structures)return C=this.structures,c();(!C||0<C.length)&&(C=[])}else H=L,(!C||0<C.length)&&(C=[]);return c()}unpackMultiple(a,b){let d,e=0;try{O=!0;let f=a.length,g=this?this.unpack(a,f):aa.unpack(a,f);if(b){for(b(g);G<f;)if(e=G,!1===b(c()))return;}else{for(d=[g];G<f;)e=G,d.push(c());return d}}catch(a){throw a.lastPosition=e,a.values=d,a}finally{O=!1,q()}}_mergeStructures(a,b){a=a||[];for(let c,d=0,e=a.length;d<e;d++)c=a[d],c&&(c.isShared=!0,32<=d&&(c.highByte=d-32>>5));for(let c in a.sharedLength=a.length,b||[])if(0<=c){let d=a[c],e=b[c];e&&(d&&((a.restoreStructures||(a.restoreStructures=[]))[c]=d),a[c]=e)}return this.structures=a}decode(a,b){return this.unpack(a,b)}}const Q=/^[a-zA-Z_$][a-zA-Z\d_$]*$/,R=(a,b)=>function(){let c=A[G++];if(0===c)return b();let d=32>a?-(a+(c<<5)):a+(c<<5),e=C[d]||g()[d];if(!e)throw new Error("Record id is not defined for "+d);return e.read||(e.read=f(e,a)),e.read()};var S=h,T=h,U=h,V=h,W=String.fromCharCode,X=Array(4096);const Y=(a,b)=>{var c=e();let d=a;void 0!==b&&(a=32>a?-((b<<5)+a):(b<<5)+a,c.highByte=b);let g=C[a];return g&&g.isShared&&((C.restoreStructures||(C.restoreStructures=[]))[a]=g),C[a]=c,c.read=f(c,d),c.read()};var Z="object"==typeof self?self:global;K[0]=()=>{},K[0].noBuffer=!0,K[101]=()=>{let a=e();return(Z[a[0]]||Error)(a[1])},K[105]=()=>{// id extension (for structured clones)
38
+ return p(()=>(q(),this?this.unpack(a,b):P.prototype.unpack.call(L,a,b)));B=-1<b?b:a.length,G=0,J=0,D=null,A=a;// this provides cached access to the data view for a buffer if it is getting reused, which is a recommend
39
+ // technique for getting data from a database where it can be copied into an existing buffer instead of creating
40
+ // new ones
41
+ try{F=a.dataView||(a.dataView=new DataView(a.buffer,a.byteOffset,a.byteLength))}catch(b){if(A=null,a instanceof Uint8Array)throw b;throw new Error("Source must be a Uint8Array or Buffer but was a "+(a&&"object"==typeof a?a.constructor.name:typeof a))}if(this instanceof P){if(H=this,this.structures)return C=this.structures,c();(!C||0<C.length)&&(C=[])}else H=L,(!C||0<C.length)&&(C=[]);return c()}unpackMultiple(a,b){let d,e=0;try{O=!0;let f=a.length,g=this?this.unpack(a,f):aa.unpack(a,f);if(b){for(b(g);G<f;)if(e=G,!1===b(c()))return;}else{for(d=[g];G<f;)e=G,d.push(c());return d}}catch(a){throw a.lastPosition=e,a.values=d,a}finally{O=!1,q()}}_mergeStructures(a,b){a=a||[];for(let c,d=0,e=a.length;d<e;d++)c=a[d],c&&(c.isShared=!0,32<=d&&(c.highByte=d-32>>5));for(let c in a.sharedLength=a.length,b||[])if(0<=c){let d=a[c],e=b[c];e&&(d&&((a.restoreStructures||(a.restoreStructures=[]))[c]=d),a[c]=e)}return this.structures=a}decode(a,b){return this.unpack(a,b)}}const Q=/^[a-zA-Z_$][a-zA-Z\d_$]*$/,R=(a,b)=>function(){let c=A[G++];if(0===c)return b();let d=32>a?-(a+(c<<5)):a+(c<<5),e=C[d]||g()[d];if(!e)throw new Error("Record id is not defined for "+d);return e.read||(e.read=f(e,a)),e.read()};var S=h,T=h,U=h,V=h;var W=String.fromCharCode,X=Array(4096);const Y=(a,b)=>{var c=e();let d=a;void 0!==b&&(a=32>a?-((b<<5)+a):(b<<5)+a,c.highByte=b);let g=C[a];return g&&g.isShared&&((C.restoreStructures||(C.restoreStructures=[]))[a]=g),C[a]=c,c.read=f(c,d),c.read()};var Z="object"==typeof self?self:global;K[0]=()=>{},K[0].noBuffer=!0,K[101]=()=>{let a=e();return(Z[a[0]]||Error)(a[1])},K[105]=()=>{// id extension (for structured clones)
39
42
  let a=F.getUint32(G-4);E||(E=new Map);let b,c=A[G];b=144<=c&&160>c||220==c||221==c?[]:{};let d={target:b};// a placeholder object
40
43
  E.set(a,d);let f=e();// read the next value as the target object to id
41
44
  return d.used?Object.assign(b,f):(d.target=f,f);// no cycle, can just use the returned read object
42
45
  },K[112]=()=>{// pointer extension (for structured clones)
43
46
  let a=F.getUint32(G-4),b=E.get(a);return b.used=!0,b.target},K[115]=()=>new Set(e());const $=["Int8","Uint8","Uint8Clamped","Int16","Uint16","Int32","Uint32","Float32","Float64","BigInt64","BigUint64"].map(a=>a+"Array");K[116]=a=>{let b=a[0],c=$[b];if(!c)throw new Error("Could not find typed array for code "+b);// we have to always slice/copy here to get a new ArrayBuffer that is word/byte aligned
44
- return new Z[c](Uint8Array.prototype.slice.call(a,1).buffer)},K[120]=()=>{let a=e();return new RegExp(a[0],a[1])},K[255]=a=>{// 32-bit date extension
45
- if(4==a.length)return new Date(1e3*(16777216*a[0]+(a[1]<<16)+(a[2]<<8)+a[3]));if(8==a.length)return new Date(((a[0]<<22)+(a[1]<<14)+(a[2]<<6)+(a[3]>>2))/1e6+1e3*(4294967296*(3&a[3])+16777216*a[4]+(a[5]<<16)+(a[6]<<8)+a[7]));if(12==a.length)// TODO: Implement support for negative
46
- return new Date(((a[0]<<24)+(a[1]<<16)+(a[2]<<8)+a[3])/1e6+1e3*((128&a[4]?-281474976710656:0)+1099511627776*a[6]+4294967296*a[7]+16777216*a[8]+(a[9]<<16)+(a[10]<<8)+a[11]));throw new Error("Invalid timestamp length")};const _=Array(147);// this is a table matching binary exponents to the multiplier to determine significant digit rounding
47
+ return new Z[c](Uint8Array.prototype.slice.call(a,1).buffer)},K[120]=()=>{let a=e();return new RegExp(a[0],a[1])},K[255]=a=>4==a.length?new Date(1e3*(16777216*a[0]+(a[1]<<16)+(a[2]<<8)+a[3])):8==a.length?new Date(((a[0]<<22)+(a[1]<<14)+(a[2]<<6)+(a[3]>>2))/1e6+1e3*(4294967296*(3&a[3])+16777216*a[4]+(a[5]<<16)+(a[6]<<8)+a[7])):12==a.length?new Date(((a[0]<<24)+(a[1]<<16)+(a[2]<<8)+a[3])/1e6+1e3*((128&a[4]?-281474976710656:0)+1099511627776*a[6]+4294967296*a[7]+16777216*a[8]+(a[9]<<16)+(a[10]<<8)+a[11])):new Date("invalid");const _=Array(147);// this is a table matching binary exponents to the multiplier to determine significant digit rounding
47
48
  for(let c=0;256>c;c++)_[c]=+("1e"+b(45.15-.30103*c));var aa=new P({useRecords:!1});const ba=aa.unpack,ca=aa.unpackMultiple,da=aa.unpack,ea={NEVER:0,ALWAYS:1,DECIMAL_ROUND:3,DECIMAL_FIT:4};let fa,ga=new Float32Array(1),ha=new Uint8Array(ga.buffer,0,4);try{fa=new TextEncoder}catch(a){}let ia,ja;const ka="undefined"!=typeof Buffer,la=ka?Buffer.allocUnsafeSlow:Uint8Array,ma=ka?Buffer:Uint8Array,na=ka?4294967296:2144337920;let oa,pa,qa,ra=0;const sa=Symbol("record-id");class ta extends P{constructor(a){super(a),this.offset=0;let b,c,d,e,f,g=0,h=ma.prototype.utf8Write?function(a,b,c){return oa.utf8Write(a,b,c)}:!!(fa&&fa.encodeInto)&&function(a,b){return fa.encodeInto(a,oa.subarray(b)).written},i=this;a||(a={});let j=a&&a.sequential,k=a.structures||a.saveStructures,l=a.maxSharedStructures;if(null==l&&(l=k?32:0),8160<l)throw new Error("Maximum maxSharedStructure is 8160");let m=a.maxOwnStructures;null==m&&(m=k?32:64),j&&!a.saveStructures&&(this.structures=[]);// two byte record ids for shared structures
48
49
  let n=32<l||64<m+l,o=l+64,p=l+m+64;if(8256<p)throw new Error("Maximum maxSharedStructure + maxOwnStructure is 8192");let q=[],r=0,s=0;this.pack=this.encode=function(a,h){if(oa||(oa=new la(8192),pa=new DataView(oa.buffer,0,8192),ra=0),qa=oa.length-10,2048>qa-ra?(oa=new la(oa.length),pa=new DataView(oa.buffer,0,oa.length),qa=oa.length-10,ra=0):ra=2147483640&ra+7,b=ra,f=i.structuredClone?new Map:null,c=i.structures,c){c.uninitialized&&(c=i._mergeStructures(i.getStructures()));let a=c.sharedLength||0;if(a>l)//if (maxSharedStructures <= 32 && sharedStructures.sharedLength > 32) // TODO: could support this, but would need to update the limit ids
49
50
  throw new Error("Shared structures is larger than maximum shared structures, try increasing maxSharedStructures to "+c.sharedLength);if(!c.transitions){c.transitions=Object.create(null);for(let b,d=0;d<a;d++){if(b=c[d],!b)continue;let a,e=c.transitions;for(let c,d=0,f=b.length;d<f;d++)c=b[d],a=e[c],a||(a=e[c]=Object.create(null)),e=a;e[sa]=d+64}g=a}j||(c.nextId=a+64)}d&&(d=!1),e=c||[];try{// update the offset so next serialization doesn't write over our buffer, but can continue writing to same buffer sequentially
50
51
  if(t(a),i.offset=ra,f&&f.idsToInsert){ra+=6*f.idsToInsert.length,ra>qa&&x(ra),i.offset=ra;let a=v(oa.subarray(b,ra),f.idsToInsert);return f=null,a}return h===Ba?(oa.start=b,oa.end=ra,oa):oa.subarray(b,ra);// position can change if we call pack again in saveStructures, so we get the buffer now
51
52
  }finally{if(c){if(10>s&&s++,1e4<r)c.transitions=null,s=0,r=0,0<q.length&&(q=[]);else if(0<q.length&&!j){for(let a=0,b=q.length;a<b;a++)q[a][sa]=0;q=[]}if(d&&i.saveStructures){let d=c.sharedLength||l;c.length>d&&(c=c.slice(0,d));// we can't rely on start/end with REUSE_BUFFER_MODE since they will (probably) change when we save
52
- let e=oa.subarray(b,ra);return!1===i.saveStructures(c,g)?(i._mergeStructures(i.getStructures()),i.pack(a)):(g=d,e)}}}};const t=a=>{ra>qa&&(oa=x(ra));var c,d=typeof a;if("string"==d){let b,d=a.length;b=32>d?1:255>d?2:65280>d?3:5;let e=3*d;if(ra+e>qa&&(oa=x(ra+e)),64>d||!h){let e,f,g,h=ra+b;for(e=0;e<d;e++)f=a.charCodeAt(e),128>f?oa[h++]=f:2048>f?(oa[h++]=192|f>>6,oa[h++]=128|63&f):55296==(64512&f)&&56320==(64512&(g=a.charCodeAt(e+1)))?(f=65536+((1023&f)<<10)+(1023&g),e++,oa[h++]=240|f>>18,oa[h++]=128|63&f>>12,oa[h++]=128|63&f>>6,oa[h++]=128|63&f):(oa[h++]=224|f>>12,oa[h++]=128|63&f>>6,oa[h++]=128|63&f);c=h-ra-b}else c=h(a,ra+b,e);32>c?oa[ra++]=160|c:256>c?(2>b&&oa.copyWithin(ra+2,ra+1,ra+1+c),oa[ra++]=217,oa[ra++]=c):65536>c?(3>b&&oa.copyWithin(ra+3,ra+2,ra+2+c),oa[ra++]=218,oa[ra++]=c>>8,oa[ra++]=255&c):(5>b&&oa.copyWithin(ra+5,ra+3,ra+3+c),oa[ra++]=219,pa.setUint32(ra,c),ra+=4),ra+=c}else if("number"===d){if(a>>>0===a)64>a?oa[ra++]=a:256>a?(oa[ra++]=204,oa[ra++]=a):65536>a?(oa[ra++]=205,oa[ra++]=a>>8,oa[ra++]=255&a):(oa[ra++]=206,pa.setUint32(ra,a),ra+=4);else if(a>>0===a)-32<=a?oa[ra++]=256+a:-128<=a?(oa[ra++]=208,oa[ra++]=a+256):-32768<=a?(oa[ra++]=209,pa.setInt16(ra,a),ra+=2):(oa[ra++]=210,pa.setInt32(ra,a),ra+=4);else{let b;if(0<(b=this.useFloat32)&&4294967296>a&&-2147483648<=a){oa[ra++]=202,pa.setFloat32(ra,a);let c;if(4>b||// this checks for rounding of numbers that were encoded in 32-bit float to nearest significant decimal digit that could be preserved
53
+ let e=oa.subarray(b,ra);return!1===i.saveStructures(c,g)?(i._mergeStructures(i.getStructures()),i.pack(a)):(g=d,e)}}}};const t=a=>{ra>qa&&(oa=x(ra));var c,d=typeof a;if("string"==d){let b,d=a.length;b=32>d?1:256>d?2:65536>d?3:5;let e=3*d;if(ra+e>qa&&(oa=x(ra+e)),64>d||!h){let e,f,g,h=ra+b;for(e=0;e<d;e++)f=a.charCodeAt(e),128>f?oa[h++]=f:2048>f?(oa[h++]=192|f>>6,oa[h++]=128|63&f):55296==(64512&f)&&56320==(64512&(g=a.charCodeAt(e+1)))?(f=65536+((1023&f)<<10)+(1023&g),e++,oa[h++]=240|f>>18,oa[h++]=128|63&f>>12,oa[h++]=128|63&f>>6,oa[h++]=128|63&f):(oa[h++]=224|f>>12,oa[h++]=128|63&f>>6,oa[h++]=128|63&f);c=h-ra-b}else c=h(a,ra+b,e);32>c?oa[ra++]=160|c:256>c?(2>b&&oa.copyWithin(ra+2,ra+1,ra+1+c),oa[ra++]=217,oa[ra++]=c):65536>c?(3>b&&oa.copyWithin(ra+3,ra+2,ra+2+c),oa[ra++]=218,oa[ra++]=c>>8,oa[ra++]=255&c):(5>b&&oa.copyWithin(ra+5,ra+3,ra+3+c),oa[ra++]=219,pa.setUint32(ra,c),ra+=4),ra+=c}else if("number"===d){if(a>>>0===a)64>a?oa[ra++]=a:256>a?(oa[ra++]=204,oa[ra++]=a):65536>a?(oa[ra++]=205,oa[ra++]=a>>8,oa[ra++]=255&a):(oa[ra++]=206,pa.setUint32(ra,a),ra+=4);else if(a>>0===a)-32<=a?oa[ra++]=256+a:-128<=a?(oa[ra++]=208,oa[ra++]=a+256):-32768<=a?(oa[ra++]=209,pa.setInt16(ra,a),ra+=2):(oa[ra++]=210,pa.setInt32(ra,a),ra+=4);else{let b;if(0<(b=this.useFloat32)&&4294967296>a&&-2147483648<=a){oa[ra++]=202,pa.setFloat32(ra,a);let c;if(4>b||// this checks for rounding of numbers that were encoded in 32-bit float to nearest significant decimal digit that could be preserved
53
54
  (c=a*_[(127&oa[ra])<<1|oa[ra+1]>>7])>>0===c)return void(ra+=4);// move back into position for writing a double
54
55
  ra--}oa[ra++]=203,pa.setFloat64(ra,a),ra+=8}}else if("object"===d){if(!a)oa[ra++]=192;else{if(f){let c=f.get(a);if(c){if(!c.id){let a=f.idsToInsert||(f.idsToInsert=[]);c.id=a.push(c)}return oa[ra++]=214,oa[ra++]=112,pa.setUint32(ra,c.id),void(ra+=4)}f.set(a,{offset:ra-b})}let d=a.constructor;if(d===Object)w(a,!0);else if(d===Array){c=a.length,16>c?oa[ra++]=144|c:65536>c?(oa[ra++]=220,oa[ra++]=c>>8,oa[ra++]=255&c):(oa[ra++]=221,pa.setUint32(ra,c),ra+=4);for(let b=0;b<c;b++)t(a[b])}else if(d===Map){c=a.size,16>c?oa[ra++]=128|c:65536>c?(oa[ra++]=222,oa[ra++]=c>>8,oa[ra++]=255&c):(oa[ra++]=223,pa.setUint32(ra,c),ra+=4);for(let[b,c]of a)t(b),t(c)}else{for(let b,c=0,d=ia.length;c<d;c++)if(b=ja[c],a instanceof b){let b=ia[c];if(b.write)return b.type&&(oa[ra++]=212,oa[ra++]=b.type,oa[ra++]=0),void t(b.write.call(this,a));let d=oa,e=pa,f=ra;oa=null;let g;try{g=b.pack.call(this,a,a=>(oa=d,d=null,ra+=a,ra>qa&&x(ra),{target:oa,targetView:pa,position:ra-a}),t)}finally{d&&(oa=d,pa=e,ra=f,qa=oa.length-10)}return void(g&&(g.length+ra>qa&&x(g.length+ra),ra=u(g,oa,ra,b.type)))}// no extension found, write as object
55
56
  w(a,!a.hasOwnProperty)}}}else if("boolean"===d)oa[ra++]=a?195:194;else if("bigint"===d){if(a<BigInt(1)<<BigInt(63)&&a>=-(BigInt(1)<<BigInt(63)))oa[ra++]=211,pa.setBigInt64(ra,a);else if(a<BigInt(1)<<BigInt(64)&&0<a)oa[ra++]=207,pa.setBigUint64(ra,a);else// overflow
@@ -97,12 +98,13 @@ let d=ra-b;ra+=2;let e=0;for(let b in a)(c||a.hasOwnProperty(b))&&(t(b),t(a[b]),
97
98
  }*/a=>{let b,c=Object.keys(a),f=e.transitions||(e.transitions=Object.create(null)),g=0;for(let d,e=0,h=c.length;e<h;e++)d=c[e],b=f[d],b||(b=f[d]=Object.create(null),g++),f=b;let h=f[sa];if(h)96<=h&&n?(oa[ra++]=(31&(h-=96))+96,oa[ra++]=h>>5):oa[ra++]=h;else{h=e.nextId,h||(h=64),h<o&&this.shouldShareStructure&&!this.shouldShareStructure(c)?(h=e.nextOwnId,!(h<p)&&(h=o),e.nextOwnId=h+1):(h>=p&&(// cycle back around
98
99
  h=o),e.nextId=h+1);let a=c.highByte=96<=h&&n?h-96>>5:-1;f[sa]=h,e[h-64]=c,h<o?(c.isShared=!0,e.sharedLength=h-63,d=!0,0<=a?(oa[ra++]=(31&h)+96,oa[ra++]=a):oa[ra++]=h):(0<=a?(oa[ra++]=213,oa[ra++]=114,oa[ra++]=(31&h)+96,oa[ra++]=a):(oa[ra++]=212,oa[ra++]=114,oa[ra++]=h),g&&(r+=s*g),q.length>=m&&(q.shift()[sa]=0),q.push(f),t(c))}// now write the values
99
100
  for(let b=0,d=c.length;b<d;b++)t(a[c[b]])},x=a=>{var c=Math.min,d=Math.round,e=Math.max;let f;if(16777216<a){// special handling for really large buffers
100
- if(a-b>na)throw new Error("Packed buffer would be larger than maximum buffer size");f=c(na,4096*d(e((a-b)*(67108864<a?1.25:2),16777216)/4096))}else// faster handling for smaller buffers
101
+ if(a-b>na)throw new Error("Packed buffer would be larger than maximum buffer size");f=c(na,4096*d(e((a-b)*(67108864<a?1.25:2),4194304)/4096))}else// faster handling for smaller buffers
101
102
  f=(e(a-b<<2,oa.length-1)>>12)+1<<12;let g=new la(f);return pa=new DataView(g.buffer,0,f),oa.copy?oa.copy(g,0,b,a):g.set(oa.slice(b,a)),ra-=b,b=0,qa=g.length-10,oa=g}}useBuffer(a){// this means we are finished using our own buffer and we can write over it safely
102
- oa=a,pa=new DataView(oa.buffer,oa.byteOffset,oa.byteLength),ra=0}}ja=[Date,Set,Error,RegExp,ArrayBuffer,Object.getPrototypeOf(Uint8Array.prototype).constructor/*TypedArray*/,M],ia=[{pack(a,c){let d=a.getTime()/1e3;if((this.useTimestamp32||0===a.getMilliseconds())&&0<=d&&4294967296>d){// Timestamp 32
103
- let{target:a,targetView:b,position:e}=c(6);a[e++]=214,a[e++]=255,b.setUint32(e,d)}else if(0<d&&17179869184>d){// Timestamp 64
104
- let{target:b,targetView:e,position:f}=c(10);b[f++]=215,b[f++]=255,e.setUint32(f,4e6*a.getMilliseconds()+(d/1e3/4294967296>>0)),e.setUint32(f+4,d)}else{// Timestamp 96
105
- let{target:e,targetView:f,position:g}=c(15);e[g++]=199,e[g++]=12,e[g++]=255,f.setUint32(g,1e6*a.getMilliseconds()),f.setBigInt64(g+4,BigInt(b(d)))}}},{pack(a,b,c){let d=Array.from(a),{target:e,position:f}=b(this.structuredClone?3:0);this.structuredClone&&(e[f++]=212,e[f++]=115,e[f++]=0),c(d)}},{pack(a,b,c){let{target:d,position:e}=b(this.structuredClone?3:0);this.structuredClone&&(d[e++]=212,d[e++]=101,d[e++]=0),c([a.name,a.message])}},{pack(a,b,c){let{target:d,position:e}=b(this.structuredClone?3:0);this.structuredClone&&(d[e++]=212,d[e++]=120,d[e++]=0),c([a.source,a.flags])}},{pack(a,b){this.structuredClone?s(a,16,b):t(ka?Buffer.from(a):new Uint8Array(a),b)}},{pack(a,b){let c=a.constructor;c!==ma&&this.structuredClone?s(a,$.indexOf(c.name),b):t(a,b)}},{pack(a,b){// specific 0xC1 object
103
+ oa=a,pa=new DataView(oa.buffer,oa.byteOffset,oa.byteLength),ra=0}}ja=[Date,Set,Error,RegExp,ArrayBuffer,Object.getPrototypeOf(Uint8Array.prototype).constructor/*TypedArray*/,M],ia=[{pack(a,c,d){let e=a.getTime()/1e3;if((this.useTimestamp32||0===a.getMilliseconds())&&0<=e&&4294967296>e){// Timestamp 32
104
+ let{target:a,targetView:b,position:d}=c(6);a[d++]=214,a[d++]=255,b.setUint32(d,e)}else if(0<e&&17179869184>e){// Timestamp 64
105
+ let{target:b,targetView:d,position:f}=c(10);b[f++]=215,b[f++]=255,d.setUint32(f,4e6*a.getMilliseconds()+(e/1e3/4294967296>>0)),d.setUint32(f+4,e)}else if(isNaN(e)){if(this.onInvalidDate)return d(this.onInvalidDate());// Intentionally invalid timestamp
106
+ let{target:a,targetView:b,position:e}=c(3);a[e++]=212,a[e++]=255,a[e++]=255}else{// Timestamp 96
107
+ let{target:d,targetView:f,position:g}=c(15);d[g++]=199,d[g++]=12,d[g++]=255,f.setUint32(g,1e6*a.getMilliseconds()),f.setBigInt64(g+4,BigInt(b(e)))}}},{pack(a,b,c){let d=Array.from(a),{target:e,position:f}=b(this.structuredClone?3:0);this.structuredClone&&(e[f++]=212,e[f++]=115,e[f++]=0),c(d)}},{pack(a,b,c){let{target:d,position:e}=b(this.structuredClone?3:0);this.structuredClone&&(d[e++]=212,d[e++]=101,d[e++]=0),c([a.name,a.message])}},{pack(a,b,c){let{target:d,position:e}=b(this.structuredClone?3:0);this.structuredClone&&(d[e++]=212,d[e++]=120,d[e++]=0),c([a.source,a.flags])}},{pack(a,b){this.structuredClone?s(a,16,b):t(ka?Buffer.from(a):new Uint8Array(a),b)}},{pack(a,b){let c=a.constructor;c!==ma&&this.structuredClone?s(a,$.indexOf(c.name),b):t(a,b)}},{pack(a,b){// specific 0xC1 object
106
108
  let{target:c,position:d}=b(1);c[d]=193}}];let ua=new ta({useRecords:!1});const va=ua.pack,wa=ua.pack,{NEVER:xa,ALWAYS:ya,DECIMAL_ROUND:za,DECIMAL_FIT:Aa}=ea,Ba=1e3;a.ALWAYS=ya,a.C1=N,a.DECIMAL_FIT=Aa,a.DECIMAL_ROUND=za,a.Decoder=P,a.Encoder=ta,a.FLOAT32_OPTIONS=ea,a.NEVER=xa,a.Packr=ta,a.REUSE_BUFFER_MODE=Ba,a.Unpackr=P,a.addExtension=w,a.clearSource=q,a.decode=da,a.decodeIter=function(a,b={}){if(!a||"object"!=typeof a)throw new Error("first argument must be an Iterable, Async Iterable, Iterator, Async Iterator, or a promise");const c=new P(b);let d;const e=a=>{let b;// if there's incomplete data from previous chunk, concatinate and try again
107
109
  d&&(a=Buffer.concat([d,a]),d=void 0);try{b=c.unpackMultiple(a)}catch(c){if(c.incomplete)d=a.slice(c.lastPosition),b=c.values;else throw c}return b};if("function"==typeof a[Symbol.iterator])return function*(){for(const b of a)yield*e(b)}();return"function"==typeof a[Symbol.asyncIterator]?async function*(){for await(const b of a)yield*e(b)}():void 0},a.encode=wa,a.encodeIter=/**
108
110
  * Given an Iterable first argument, returns an Iterable where each value is packed as a Buffer
@@ -110,4 +112,4 @@ d&&(a=Buffer.concat([d,a]),d=void 0);try{b=c.unpackMultiple(a)}catch(c){if(c.inc
110
112
  * @param {Iterable|Iterator|AsyncIterable|AsyncIterator} objectIterator - iterable source, like a Readable object stream, an array, Set, or custom object
111
113
  * @param {options} [options] - msgpackr pack options
112
114
  * @returns {IterableIterator|Promise.<AsyncIterableIterator>}
113
- */function(a,b={}){if(!a||"object"!=typeof a)throw new Error("first argument must be an Iterable, Async Iterable, or a Promise for an Async Iterable");else{if("function"==typeof a[Symbol.iterator])return x(a,b);if("function"==typeof a.then||"function"==typeof a[Symbol.asyncIterator])return y(a,b);throw new Error("first argument must be an Iterable, Async Iterable, Iterator, Async Iterator, or a Promise")}},a.mapsAsObjects=!0,a.pack=va,a.roundFloat32=function(a){ga[0]=a;let b=_[(127&ha[3])<<1|ha[2]>>7];return(b*a+(0<a?.5:-.5)>>0)/b},a.unpack=ba,a.unpackMultiple=ca,a.useRecords=!1,Object.defineProperty(a,"__esModule",{value:!0})});
115
+ */function(a,b={}){if(!a||"object"!=typeof a)throw new Error("first argument must be an Iterable, Async Iterable, or a Promise for an Async Iterable");else{if("function"==typeof a[Symbol.iterator])return x(a,b);if("function"==typeof a.then||"function"==typeof a[Symbol.asyncIterator])return y(a,b);throw new Error("first argument must be an Iterable, Async Iterable, Iterator, Async Iterator, or a Promise")}},a.isNativeAccelerationEnabled=!1,a.mapsAsObjects=!0,a.pack=va,a.roundFloat32=function(a){ga[0]=a;let b=_[(127&ha[3])<<1|ha[2]>>7];return(b*a+(0<a?.5:-.5)>>0)/b},a.unpack=ba,a.unpackMultiple=ca,a.useRecords=!1,Object.defineProperty(a,"__esModule",{value:!0})});
package/dist/node.cjs CHANGED
@@ -64,8 +64,16 @@ class Unpackr {
64
64
  // this provides cached access to the data view for a buffer if it is getting reused, which is a recommend
65
65
  // technique for getting data from a database where it can be copied into an existing buffer instead of creating
66
66
  // new ones
67
- dataView = source.dataView || (source.dataView = new DataView(source.buffer, source.byteOffset, source.byteLength));
68
- if (this) {
67
+ try {
68
+ dataView = source.dataView || (source.dataView = new DataView(source.buffer, source.byteOffset, source.byteLength));
69
+ } catch(error) {
70
+ // if it doesn't have a buffer, maybe it is the wrong type of object
71
+ src = null;
72
+ if (source instanceof Uint8Array)
73
+ throw error
74
+ throw new Error('Source must be a Uint8Array or Buffer but was a ' + ((source && typeof source == 'object') ? source.constructor.name : typeof source))
75
+ }
76
+ if (this instanceof Unpackr) {
69
77
  currentUnpackr = this;
70
78
  if (this.structures) {
71
79
  currentStructures = this.structures;
@@ -297,10 +305,11 @@ function read() {
297
305
  position += 4;
298
306
  return value
299
307
  case 0xcf:
300
- if (currentUnpackr.uint64AsNumber)
301
- return src[position++] * 0x100000000000000 + src[position++] * 0x1000000000000 + src[position++] * 0x10000000000 + src[position++] * 0x100000000 +
302
- src[position++] * 0x1000000 + (src[position++] << 16) + (src[position++] << 8) + src[position++]
303
- value = dataView.getBigUint64(position);
308
+ if (currentUnpackr.int64AsNumber) {
309
+ value = dataView.getUint32(position) * 0x100000000;
310
+ value += dataView.getUint32(position + 4);
311
+ } else
312
+ value = dataView.getBigUint64(position);
304
313
  position += 8;
305
314
  return value
306
315
 
@@ -316,7 +325,11 @@ function read() {
316
325
  position += 4;
317
326
  return value
318
327
  case 0xd3:
319
- value = dataView.getBigInt64(position);
328
+ if (currentUnpackr.int64AsNumber) {
329
+ value = dataView.getInt32(position) * 0x100000000;
330
+ value += dataView.getUint32(position + 4);
331
+ } else
332
+ value = dataView.getBigInt64(position);
320
333
  position += 8;
321
334
  return value
322
335
 
@@ -465,8 +478,10 @@ var readFixedString = readStringJS;
465
478
  var readString8 = readStringJS;
466
479
  var readString16 = readStringJS;
467
480
  var readString32 = readStringJS;
481
+ exports.isNativeAccelerationEnabled = false;
468
482
 
469
483
  function setExtractor(extractStrings) {
484
+ exports.isNativeAccelerationEnabled = true;
470
485
  readFixedString = readString(1);
471
486
  readString8 = readString(2);
472
487
  readString16 = readString(3);
@@ -898,7 +913,7 @@ currentExtensions[0xff] = (data) => {
898
913
  ((data[0] << 24) + (data[1] << 16) + (data[2] << 8) + data[3]) / 1000000 +
899
914
  (((data[4] & 0x80) ? -0x1000000000000 : 0) + data[6] * 0x10000000000 + data[7] * 0x100000000 + data[8] * 0x1000000 + (data[9] << 16) + (data[10] << 8) + data[11]) * 1000)
900
915
  else
901
- throw new Error('Invalid timestamp length')
916
+ return new Date('invalid')
902
917
  }; // notepack defines extension 0 to mean undefined, so use that as the default here
903
918
  // registration of bulk record definition?
904
919
  // currentExtensions[0x52] = () =>
@@ -1147,9 +1162,9 @@ class Packr extends Unpackr {
1147
1162
  // first we estimate the header size, so we can write to the correct location
1148
1163
  if (strLength < 0x20) {
1149
1164
  headerSize = 1;
1150
- } else if (strLength < 0xff) {
1165
+ } else if (strLength < 0x100) {
1151
1166
  headerSize = 2;
1152
- } else if (strLength < 0xff00) {
1167
+ } else if (strLength < 0x10000) {
1153
1168
  headerSize = 3;
1154
1169
  } else {
1155
1170
  headerSize = 5;
@@ -1562,7 +1577,7 @@ class Packr extends Unpackr {
1562
1577
  if ((end - start) > MAX_BUFFER_SIZE)
1563
1578
  throw new Error('Packed buffer would be larger than maximum buffer size')
1564
1579
  newSize = Math.min(MAX_BUFFER_SIZE,
1565
- Math.round(Math.max((end - start) * (end > 0x4000000 ? 1.25 : 2), 0x1000000) / 0x1000) * 0x1000);
1580
+ Math.round(Math.max((end - start) * (end > 0x4000000 ? 1.25 : 2), 0x400000) / 0x1000) * 0x1000);
1566
1581
  } else // faster handling for smaller buffers
1567
1582
  newSize = ((Math.max((end - start) << 2, target.length - 1) >> 12) + 1) << 12;
1568
1583
  let newBuffer = new ByteArrayAllocate(newSize);
@@ -1587,7 +1602,7 @@ class Packr extends Unpackr {
1587
1602
 
1588
1603
  extensionClasses = [ Date, Set, Error, RegExp, ArrayBuffer, Object.getPrototypeOf(Uint8Array.prototype).constructor /*TypedArray*/, C1Type ];
1589
1604
  extensions = [{
1590
- pack(date, allocateForWrite) {
1605
+ pack(date, allocateForWrite, pack) {
1591
1606
  let seconds = date.getTime() / 1000;
1592
1607
  if ((this.useTimestamp32 || date.getMilliseconds() === 0) && seconds >= 0 && seconds < 0x100000000) {
1593
1608
  // Timestamp 32
@@ -1602,6 +1617,14 @@ extensions = [{
1602
1617
  target[position++] = 0xff;
1603
1618
  targetView.setUint32(position, date.getMilliseconds() * 4000000 + ((seconds / 1000 / 0x100000000) >> 0));
1604
1619
  targetView.setUint32(position + 4, seconds);
1620
+ } else if (isNaN(seconds)) {
1621
+ if (this.onInvalidDate)
1622
+ return pack(this.onInvalidDate())
1623
+ // Intentionally invalid timestamp
1624
+ let { target, targetView, position} = allocateForWrite(3);
1625
+ target[position++] = 0xd4;
1626
+ target[position++] = 0xff;
1627
+ target[position++] = 0xff;
1605
1628
  } else {
1606
1629
  // Timestamp 96
1607
1630
  let { target, targetView, position} = allocateForWrite(15);
@@ -1939,9 +1962,7 @@ function tryRequire(moduleId) {
1939
1962
  let require$1 = module$1.createRequire((typeof document === 'undefined' ? new (require('u' + 'rl').URL)('file:' + __filename).href : (document.currentScript && document.currentScript.src || new URL('node.cjs', document.baseURI).href)));
1940
1963
  return require$1(moduleId)
1941
1964
  } catch (error) {
1942
- if (typeof window == 'undefined')
1943
- console.warn('Native extraction module not loaded, msgpackr will still run, but with decreased performance. ' + error.message.split('\n')[0]);
1944
- else
1965
+ if (typeof window != 'undefined')
1945
1966
  console.warn('For browser usage, directly use msgpackr/unpack or msgpackr/pack modules. ' + error.message.split('\n')[0]);
1946
1967
  }
1947
1968
  }
package/dist/str.cjs ADDED
@@ -0,0 +1,100 @@
1
+ let utfz = require('../../msgpack-benchmark/node_modules/utfz-lib')
2
+
3
+ var safeEnd = 1000000;
4
+ var b = new Uint8Array(32768)
5
+ function writeString(value, target, position) {
6
+ var length, strLength = value.length;
7
+ let headerSize;
8
+ // first we estimate the header size, so we can write to the correct location
9
+ if (strLength < 0x20) {
10
+ headerSize = 1;
11
+ } else if (strLength < 0x100) {
12
+ headerSize = 2;
13
+ } else if (strLength < 0x10000) {
14
+ headerSize = 3;
15
+ } else {
16
+ headerSize = 5;
17
+ }
18
+ let maxBytes = strLength * 3;
19
+ //if (position + maxBytes > safeEnd)
20
+ // target = makeRoom(position + maxBytes);
21
+ for (let i = 0; i < 100; i++) {
22
+ length = pack(value, strLength, target, position + headerSize);
23
+ }
24
+ if (strLength < 0x40 || !encodeUtf8) {
25
+ var strPosition = position + headerSize;
26
+ var c2 = 0;
27
+ for (let i = 0; i < strLength; i++) {
28
+ const c1 = value.charCodeAt(i);
29
+ if (c1 < 0x80) {
30
+ target[strPosition++] = c1;
31
+ } else if (c1 < 0x800) {
32
+ target[strPosition++] = c1 >> 6 | 0xc0;
33
+ target[strPosition++] = c1 & 0x3f | 0x80;
34
+ } else if (
35
+ (c1 & 0xfc00) === 0xd800 &&
36
+ ((c2 = value.charCodeAt(i + 1)) & 0xfc00) === 0xdc00
37
+ ) {
38
+ c1 = 0x10000 + ((c1 & 0x03ff) << 10) + (c2 & 0x03ff);
39
+ i++;
40
+ target[strPosition++] = c1 >> 18 | 0xf0;
41
+ target[strPosition++] = c1 >> 12 & 0x3f | 0x80;
42
+ target[strPosition++] = c1 >> 6 & 0x3f | 0x80;
43
+ target[strPosition++] = c1 & 0x3f | 0x80;
44
+ } else {
45
+ target[strPosition++] = c1 >> 12 | 0xe0;
46
+ target[strPosition++] = c1 >> 6 & 0x3f | 0x80;
47
+ target[strPosition++] = c1 & 0x3f | 0x80;
48
+ }
49
+ }
50
+ length = strPosition - position - headerSize;
51
+ } else {
52
+ length = encodeUtf8(value, position + headerSize, maxBytes);
53
+ }
54
+
55
+
56
+ if (length < 0x20) {
57
+ target[position++] = 0xa0 | length;
58
+ } else if (length < 0x100) {
59
+ if (headerSize < 2) {
60
+ target.copyWithin(position + 2, position + 1, position + 1 + length);
61
+ }
62
+ target[position++] = 0xd9;
63
+ target[position++] = length;
64
+ } else if (length < 0x10000) {
65
+ if (headerSize < 3) {
66
+ target.copyWithin(position + 3, position + 2, position + 2 + length);
67
+ }
68
+ target[position++] = 0xda;
69
+ target[position++] = length >> 8;
70
+ target[position++] = length & 0xff;
71
+ } else {
72
+ if (headerSize < 5) {
73
+ target.copyWithin(position + 5, position + 3, position + 3 + length);
74
+ }
75
+ target[position++] = 0xdb;
76
+ targetView.setUint32(position, length);
77
+ position += 4;
78
+ }
79
+ return position + length
80
+ };
81
+ const pack = (str, length, buf, offset) => {
82
+ const start = offset;
83
+ let currHigh = 0;
84
+ for (let i = 0; i < length; i++) {
85
+ const code = str.charCodeAt(i);
86
+ const high = code >> 8;
87
+ if (high !== currHigh) {
88
+ buf[i + offset++] = 0;
89
+ buf[i + offset++] = high;
90
+ currHigh = high;
91
+ }
92
+ const low = code & 0xff;
93
+ buf[i + offset] = low;
94
+ if (!low) {
95
+ buf[i + ++offset] = currHigh;
96
+ }
97
+ }
98
+ return length + offset - start;
99
+ };
100
+ module.exports = writeString;
package/dist/test.js CHANGED
@@ -660,6 +660,13 @@
660
660
  assert.deepEqual(deserialized, data);
661
661
  });
662
662
 
663
+ test('255 chars', function() {
664
+ const data = 'RRZG9A6I7xupPeOZhxcOcioFsuhszGOdyDUcbRf4Zef2kdPIfC9RaLO4jTM5JhuZvTsF09fbRHMGtqk7YAgu3vespeTe9l61ziZ6VrMnYu2CamK96wCkmz0VUXyqaiUoTPgzk414LS9yYrd5uh7w18ksJF5SlC2e91rukWvNqAZJjYN3jpkqHNOFchCwFrhbxq2Lrv1kSJPYCx9blRg2hGmYqTbElLTZHv20iNqwZeQbRMgSBPT6vnbCBPnOh1W';
665
+ var serialized = pack(data);
666
+ var deserialized = unpack(serialized);
667
+ assert.equal(deserialized, data);
668
+ });
669
+
663
670
  test('pack/unpack sample data', function(){
664
671
  var data = sampleData;
665
672
  var serialized = pack(data);
@@ -982,6 +989,7 @@
982
989
  date: new Date(1532219539733),
983
990
  farFutureDate: new Date(3532219539133),
984
991
  ancient: new Date(-3532219539133),
992
+ invalidDate: new Date('invalid')
985
993
  };
986
994
  let packr = new Packr();
987
995
  var serialized = packr.pack(data);
@@ -991,6 +999,7 @@
991
999
  assert.equal(deserialized.date.getTime(), 1532219539733);
992
1000
  assert.equal(deserialized.farFutureDate.getTime(), 3532219539133);
993
1001
  assert.equal(deserialized.ancient.getTime(), -3532219539133);
1002
+ assert.equal(deserialized.invalidDate.toString(), 'Invalid Date');
994
1003
  });
995
1004
  test('map/date with options', function(){
996
1005
  var map = new Map();
@@ -1064,7 +1073,17 @@
1064
1073
  var deserialized = packr.unpack(serialized);
1065
1074
  assert.deepEqual(deserialized, data);
1066
1075
  });
1067
-
1076
+ test('bigint to float', function() {
1077
+ var data = {
1078
+ a: 325283295382932843n
1079
+ };
1080
+ let packr = new Packr({
1081
+ int64AsNumber: true
1082
+ });
1083
+ var serialized = packr.pack(data);
1084
+ var deserialized = packr.unpack(serialized);
1085
+ assert.deepEqual(deserialized.a, 325283295382932843);
1086
+ });
1068
1087
  test('numbers', function(){
1069
1088
  var data = {
1070
1089
  bigEncodable: 48978578104322,
package/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { Unpackr, Decoder, unpack, decode, addExtension, FLOAT32_OPTIONS, clearSource, roundFloat32 } from './unpack'
1
+ export { Unpackr, Decoder, unpack, decode, addExtension, FLOAT32_OPTIONS, clearSource, roundFloat32, isNativeAccelerationEnabled } from './unpack'
2
2
  import { Options } from './unpack'
3
3
  export { Packr, Encoder, pack, encode } from './pack'
4
4
  import { Transform, Readable } from 'stream'
package/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  export { Packr, Encoder, addExtension, pack, encode, NEVER, ALWAYS, DECIMAL_ROUND, DECIMAL_FIT, REUSE_BUFFER_MODE } from './pack.js'
2
- export { Unpackr, Decoder, C1, unpack, unpackMultiple, decode, FLOAT32_OPTIONS, clearSource, roundFloat32 } from './unpack.js'
2
+ export { Unpackr, Decoder, C1, unpack, unpackMultiple, decode, FLOAT32_OPTIONS, clearSource, roundFloat32, isNativeAccelerationEnabled } from './unpack.js'
3
3
  export { decodeIter, encodeIter } from './iterators.js'
4
4
  export const useRecords = false
5
5
  export const mapsAsObjects = true
package/node-index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  export { Packr, Encoder, addExtension, pack, encode, NEVER, ALWAYS, DECIMAL_ROUND, DECIMAL_FIT } from './pack.js'
2
- export { Unpackr, Decoder, C1, unpack, unpackMultiple, decode, FLOAT32_OPTIONS, clearSource, roundFloat32 } from './unpack.js'
2
+ export { Unpackr, Decoder, C1, unpack, unpackMultiple, decode, FLOAT32_OPTIONS, clearSource, roundFloat32, isNativeAccelerationEnabled } from './unpack.js'
3
3
  export { PackrStream, UnpackrStream, PackrStream as EncoderStream, UnpackrStream as DecoderStream } from './stream.js'
4
4
  export { decodeIter, encodeIter } from './iterators.js'
5
5
  export const useRecords = false
@@ -16,9 +16,7 @@ function tryRequire(moduleId) {
16
16
  let require = createRequire(import.meta.url)
17
17
  return require(moduleId)
18
18
  } catch (error) {
19
- if (typeof window == 'undefined')
20
- console.warn('Native extraction module not loaded, msgpackr will still run, but with decreased performance. ' + error.message.split('\n')[0])
21
- else
19
+ if (typeof window != 'undefined')
22
20
  console.warn('For browser usage, directly use msgpackr/unpack or msgpackr/pack modules. ' + error.message.split('\n')[0])
23
21
  }
24
22
  }
package/pack.js CHANGED
@@ -176,9 +176,9 @@ export class Packr extends Unpackr {
176
176
  // first we estimate the header size, so we can write to the correct location
177
177
  if (strLength < 0x20) {
178
178
  headerSize = 1
179
- } else if (strLength < 0xff) {
179
+ } else if (strLength < 0x100) {
180
180
  headerSize = 2
181
- } else if (strLength < 0xff00) {
181
+ } else if (strLength < 0x10000) {
182
182
  headerSize = 3
183
183
  } else {
184
184
  headerSize = 5
@@ -591,7 +591,7 @@ export class Packr extends Unpackr {
591
591
  if ((end - start) > MAX_BUFFER_SIZE)
592
592
  throw new Error('Packed buffer would be larger than maximum buffer size')
593
593
  newSize = Math.min(MAX_BUFFER_SIZE,
594
- Math.round(Math.max((end - start) * (end > 0x4000000 ? 1.25 : 2), 0x1000000) / 0x1000) * 0x1000)
594
+ Math.round(Math.max((end - start) * (end > 0x4000000 ? 1.25 : 2), 0x400000) / 0x1000) * 0x1000)
595
595
  } else // faster handling for smaller buffers
596
596
  newSize = ((Math.max((end - start) << 2, target.length - 1) >> 12) + 1) << 12
597
597
  let newBuffer = new ByteArrayAllocate(newSize)
@@ -622,7 +622,7 @@ function copyBinary(source, target, targetOffset, offset, endOffset) {
622
622
 
623
623
  extensionClasses = [ Date, Set, Error, RegExp, ArrayBuffer, Object.getPrototypeOf(Uint8Array.prototype).constructor /*TypedArray*/, C1Type ]
624
624
  extensions = [{
625
- pack(date, allocateForWrite) {
625
+ pack(date, allocateForWrite, pack) {
626
626
  let seconds = date.getTime() / 1000
627
627
  if ((this.useTimestamp32 || date.getMilliseconds() === 0) && seconds >= 0 && seconds < 0x100000000) {
628
628
  // Timestamp 32
@@ -637,6 +637,14 @@ extensions = [{
637
637
  target[position++] = 0xff
638
638
  targetView.setUint32(position, date.getMilliseconds() * 4000000 + ((seconds / 1000 / 0x100000000) >> 0))
639
639
  targetView.setUint32(position + 4, seconds)
640
+ } else if (isNaN(seconds)) {
641
+ if (this.onInvalidDate)
642
+ return pack(this.onInvalidDate())
643
+ // Intentionally invalid timestamp
644
+ let { target, targetView, position} = allocateForWrite(3)
645
+ target[position++] = 0xd4
646
+ target[position++] = 0xff
647
+ target[position++] = 0xff
640
648
  } else {
641
649
  // Timestamp 96
642
650
  let { target, targetView, position} = allocateForWrite(15)
package/package.json CHANGED
@@ -1,11 +1,12 @@
1
1
  {
2
2
  "name": "msgpackr",
3
3
  "author": "Kris Zyp",
4
- "version": "1.4.5",
4
+ "version": "1.5.1",
5
5
  "description": "Ultra-fast MessagePack implementation with extensions for records and structured cloning",
6
6
  "license": "MIT",
7
7
  "types": "./index.d.ts",
8
- "main": "./dist/index.js",
8
+ "main": "./dist/node.cjs",
9
+ "module": "./index.js",
9
10
  "keywords": [
10
11
  "MessagePack",
11
12
  "msgpack",
package/tests/test.js CHANGED
@@ -84,6 +84,13 @@ suite('msgpackr basic tests', function(){
84
84
  assert.deepEqual(deserialized, data)
85
85
  })
86
86
 
87
+ test('255 chars', function() {
88
+ const data = 'RRZG9A6I7xupPeOZhxcOcioFsuhszGOdyDUcbRf4Zef2kdPIfC9RaLO4jTM5JhuZvTsF09fbRHMGtqk7YAgu3vespeTe9l61ziZ6VrMnYu2CamK96wCkmz0VUXyqaiUoTPgzk414LS9yYrd5uh7w18ksJF5SlC2e91rukWvNqAZJjYN3jpkqHNOFchCwFrhbxq2Lrv1kSJPYCx9blRg2hGmYqTbElLTZHv20iNqwZeQbRMgSBPT6vnbCBPnOh1W'
89
+ var serialized = pack(data)
90
+ var deserialized = unpack(serialized)
91
+ assert.equal(deserialized, data)
92
+ })
93
+
87
94
  test('pack/unpack sample data', function(){
88
95
  var data = sampleData
89
96
  let structures = []
@@ -409,6 +416,7 @@ suite('msgpackr basic tests', function(){
409
416
  date: new Date(1532219539733),
410
417
  farFutureDate: new Date(3532219539133),
411
418
  ancient: new Date(-3532219539133),
419
+ invalidDate: new Date('invalid')
412
420
  }
413
421
  let packr = new Packr()
414
422
  var serialized = packr.pack(data)
@@ -418,6 +426,7 @@ suite('msgpackr basic tests', function(){
418
426
  assert.equal(deserialized.date.getTime(), 1532219539733)
419
427
  assert.equal(deserialized.farFutureDate.getTime(), 3532219539133)
420
428
  assert.equal(deserialized.ancient.getTime(), -3532219539133)
429
+ assert.equal(deserialized.invalidDate.toString(), 'Invalid Date')
421
430
  })
422
431
  test('map/date with options', function(){
423
432
  var map = new Map()
@@ -491,7 +500,17 @@ suite('msgpackr basic tests', function(){
491
500
  var deserialized = packr.unpack(serialized)
492
501
  assert.deepEqual(deserialized, data)
493
502
  })
494
-
503
+ test('bigint to float', function() {
504
+ var data = {
505
+ a: 325283295382932843n
506
+ }
507
+ let packr = new Packr({
508
+ int64AsNumber: true
509
+ })
510
+ var serialized = packr.pack(data)
511
+ var deserialized = packr.unpack(serialized)
512
+ assert.deepEqual(deserialized.a, 325283295382932843)
513
+ })
495
514
  test('numbers', function(){
496
515
  var data = {
497
516
  bigEncodable: 48978578104322,
package/unpack.d.ts CHANGED
@@ -25,8 +25,10 @@ export interface Options {
25
25
  interface Extension {
26
26
  Class: Function
27
27
  type: number
28
- pack(value: any): Buffer | Uint8Array
29
- unpack(messagePack: Buffer | Uint8Array): any
28
+ pack?(value: any): Buffer | Uint8Array
29
+ unpack?(messagePack: Buffer | Uint8Array): any
30
+ read?(datum: any): any
31
+ write?(instance: any): any
30
32
  }
31
33
  export class Unpackr {
32
34
  constructor(options?: Options)
@@ -42,3 +44,4 @@ export function addExtension(extension: Extension): void
42
44
  export function clearSource(): void
43
45
  export function roundFloat32(float32Number: number): number
44
46
  export const C1: {}
47
+ export let isNativeAccelerationEnabled: boolean
package/unpack.js CHANGED
@@ -59,8 +59,16 @@ export class Unpackr {
59
59
  // this provides cached access to the data view for a buffer if it is getting reused, which is a recommend
60
60
  // technique for getting data from a database where it can be copied into an existing buffer instead of creating
61
61
  // new ones
62
- dataView = source.dataView || (source.dataView = new DataView(source.buffer, source.byteOffset, source.byteLength))
63
- if (this) {
62
+ try {
63
+ dataView = source.dataView || (source.dataView = new DataView(source.buffer, source.byteOffset, source.byteLength))
64
+ } catch(error) {
65
+ // if it doesn't have a buffer, maybe it is the wrong type of object
66
+ src = null
67
+ if (source instanceof Uint8Array)
68
+ throw error
69
+ throw new Error('Source must be a Uint8Array or Buffer but was a ' + ((source && typeof source == 'object') ? source.constructor.name : typeof source))
70
+ }
71
+ if (this instanceof Unpackr) {
64
72
  currentUnpackr = this
65
73
  if (this.structures) {
66
74
  currentStructures = this.structures
@@ -295,10 +303,11 @@ export function read() {
295
303
  position += 4
296
304
  return value
297
305
  case 0xcf:
298
- if (currentUnpackr.uint64AsNumber)
299
- return src[position++] * 0x100000000000000 + src[position++] * 0x1000000000000 + src[position++] * 0x10000000000 + src[position++] * 0x100000000 +
300
- src[position++] * 0x1000000 + (src[position++] << 16) + (src[position++] << 8) + src[position++]
301
- value = dataView.getBigUint64(position)
306
+ if (currentUnpackr.int64AsNumber) {
307
+ value = dataView.getUint32(position) * 0x100000000
308
+ value += dataView.getUint32(position + 4)
309
+ } else
310
+ value = dataView.getBigUint64(position)
302
311
  position += 8
303
312
  return value
304
313
 
@@ -314,7 +323,11 @@ export function read() {
314
323
  position += 4
315
324
  return value
316
325
  case 0xd3:
317
- value = dataView.getBigInt64(position)
326
+ if (currentUnpackr.int64AsNumber) {
327
+ value = dataView.getInt32(position) * 0x100000000
328
+ value += dataView.getUint32(position + 4)
329
+ } else
330
+ value = dataView.getBigInt64(position)
318
331
  position += 8
319
332
  return value
320
333
 
@@ -463,8 +476,10 @@ var readFixedString = readStringJS
463
476
  var readString8 = readStringJS
464
477
  var readString16 = readStringJS
465
478
  var readString32 = readStringJS
479
+ export let isNativeAccelerationEnabled = false
466
480
 
467
481
  export function setExtractor(extractStrings) {
482
+ isNativeAccelerationEnabled = true
468
483
  readFixedString = readString(1)
469
484
  readString8 = readString(2)
470
485
  readString16 = readString(3)
@@ -896,7 +911,7 @@ currentExtensions[0xff] = (data) => {
896
911
  ((data[0] << 24) + (data[1] << 16) + (data[2] << 8) + data[3]) / 1000000 +
897
912
  (((data[4] & 0x80) ? -0x1000000000000 : 0) + data[6] * 0x10000000000 + data[7] * 0x100000000 + data[8] * 0x1000000 + (data[9] << 16) + (data[10] << 8) + data[11]) * 1000)
898
913
  else
899
- throw new Error('Invalid timestamp length')
914
+ return new Date('invalid')
900
915
  } // notepack defines extension 0 to mean undefined, so use that as the default here
901
916
  // registration of bulk record definition?
902
917
  // currentExtensions[0x52] = () =>
@@ -951,8 +966,6 @@ export const mult10 = new Array(147) // this is a table matching binary exponent
951
966
  for (let i = 0; i < 256; i++) {
952
967
  mult10[i] = +('1e' + Math.floor(45.15 - i * 0.30103))
953
968
  }
954
- export const useRecords = false
955
- export const mapsAsObjects = true
956
969
  export const Decoder = Unpackr
957
970
  var defaultUnpackr = new Unpackr({ useRecords: false })
958
971
  export const unpack = defaultUnpackr.unpack