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 +12 -1
- package/dist/index.js +23 -8
- package/dist/index.min.js +8 -5
- package/dist/node.cjs +24 -11
- package/dist/test.js +11 -1
- package/index.d.ts +1 -1
- package/index.js +1 -1
- package/node-index.js +2 -4
- package/pack.js +1 -1
- package/package.json +1 -1
- package/tests/test.js +11 -1
- package/unpack.d.ts +1 -0
- package/unpack.js +22 -9
package/README.md
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
# msgpackr
|
|
2
|
-
[](LICENSE)
|
|
3
2
|
[](https://www.npmjs.org/package/msgpackr)
|
|
3
|
+
[](https://www.npmjs.org/package/msgpackr)
|
|
4
4
|
[](benchmark.md)
|
|
5
5
|
[](benchmark.md)
|
|
6
6
|
[](README.md)
|
|
7
7
|
[](README.md)
|
|
8
|
+
[](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
|
-
|
|
62
|
-
|
|
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.
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
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
|
-
|
|
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),
|
|
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.
|
|
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)));
|
|
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),
|
|
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
|
-
|
|
68
|
-
|
|
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.
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
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
|
-
|
|
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),
|
|
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
|
|
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
|
|
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),
|
|
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
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
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
|
-
|
|
63
|
-
|
|
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.
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
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
|
-
|
|
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
|