msgpackr 1.4.7 → 1.5.0

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,7 @@ 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.
169
171
 
170
172
  ### 32-bit Float Options
171
173
  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:
@@ -183,6 +185,15 @@ Note, that the performance is decreased with decimal rounding by about 20-25%, a
183
185
  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
186
 
185
187
  ## Performance
188
+ ### Native Acceleration
189
+ 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:
190
+ ```js
191
+ import { isNativeAccelerationEnabled } from 'msgpackr'
192
+ if (!isNativeAccelerationEnabled)
193
+ console.warn('Native acceleration not enabled, verify that install finished properly')
194
+ ```
195
+
196
+ ### Benchmarks
186
197
  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
198
 
188
199
  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) {
@@ -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);
@@ -1848,6 +1862,7 @@
1848
1862
  exports.decodeIter = decodeIter;
1849
1863
  exports.encode = encode;
1850
1864
  exports.encodeIter = encodeIter;
1865
+ exports.isNativeAccelerationEnabled = isNativeAccelerationEnabled;
1851
1866
  exports.mapsAsObjects = mapsAsObjects;
1852
1867
  exports.pack = pack;
1853
1868
  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,7 +35,10 @@ 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
@@ -97,7 +100,7 @@ let d=ra-b;ra+=2;let e=0;for(let b in a)(c||a.hasOwnProperty(b))&&(t(b),t(a[b]),
97
100
  }*/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
101
  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
102
  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
103
+ 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
104
  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
105
  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
106
  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
@@ -110,4 +113,4 @@ d&&(a=Buffer.concat([d,a]),d=void 0);try{b=c.unpackMultiple(a)}catch(c){if(c.inc
110
113
  * @param {Iterable|Iterator|AsyncIterable|AsyncIterator} objectIterator - iterable source, like a Readable object stream, an array, Set, or custom object
111
114
  * @param {options} [options] - msgpackr pack options
112
115
  * @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})});
116
+ */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);
@@ -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);
@@ -1939,9 +1954,7 @@ function tryRequire(moduleId) {
1939
1954
  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
1955
  return require$1(moduleId)
1941
1956
  } 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
1957
+ if (typeof window != 'undefined')
1945
1958
  console.warn('For browser usage, directly use msgpackr/unpack or msgpackr/pack modules. ' + error.message.split('\n')[0]);
1946
1959
  }
1947
1960
  }
package/dist/test.js CHANGED
@@ -1071,7 +1071,17 @@
1071
1071
  var deserialized = packr.unpack(serialized);
1072
1072
  assert.deepEqual(deserialized, data);
1073
1073
  });
1074
-
1074
+ test('bigint to float', function() {
1075
+ var data = {
1076
+ a: 325283295382932843n
1077
+ };
1078
+ let packr = new Packr({
1079
+ int64AsNumber: true
1080
+ });
1081
+ var serialized = packr.pack(data);
1082
+ var deserialized = packr.unpack(serialized);
1083
+ assert.deepEqual(deserialized.a, 325283295382932843);
1084
+ });
1075
1085
  test('numbers', function(){
1076
1086
  var data = {
1077
1087
  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
@@ -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)
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "msgpackr",
3
3
  "author": "Kris Zyp",
4
- "version": "1.4.7",
4
+ "version": "1.5.0",
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/tests/test.js CHANGED
@@ -498,7 +498,17 @@ suite('msgpackr basic tests', function(){
498
498
  var deserialized = packr.unpack(serialized)
499
499
  assert.deepEqual(deserialized, data)
500
500
  })
501
-
501
+ test('bigint to float', function() {
502
+ var data = {
503
+ a: 325283295382932843n
504
+ }
505
+ let packr = new Packr({
506
+ int64AsNumber: true
507
+ })
508
+ var serialized = packr.pack(data)
509
+ var deserialized = packr.unpack(serialized)
510
+ assert.deepEqual(deserialized.a, 325283295382932843)
511
+ })
502
512
  test('numbers', function(){
503
513
  var data = {
504
514
  bigEncodable: 48978578104322,
package/unpack.d.ts CHANGED
@@ -44,3 +44,4 @@ export function addExtension(extension: Extension): void
44
44
  export function clearSource(): void
45
45
  export function roundFloat32(float32Number: number): number
46
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)
@@ -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