msgpackr 1.5.1 → 1.5.2
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 +3 -2
- package/dist/index.js +61 -4
- package/dist/index.min.js +52 -51
- package/dist/node.cjs +61 -4
- package/dist/test.js +13 -2
- package/pack.js +32 -3
- package/package.json +7 -1
- package/unpack.d.ts +2 -0
- package/unpack.js +29 -1
- package/.vscode/launch.json +0 -23
- package/tests/benchmark-stream.cjs +0 -282
- package/tests/benchmark.cjs +0 -199
- package/tests/example.json +0 -52
- package/tests/example2.json +0 -26
- package/tests/example3.json +0 -22
- package/tests/example4.json +0 -1
- package/tests/example5.json +0 -12
- package/tests/floats.json +0 -1
- package/tests/index.html +0 -28
- package/tests/sample-large.json +0 -231
- package/tests/strings2.json +0 -1
- package/tests/test-compatibility.cjs +0 -64
- package/tests/test-incomplete.js +0 -41
- package/tests/test-node-iterators.js +0 -72
- package/tests/test-node-stream.js +0 -76
- package/tests/test.js +0 -652
package/README.md
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
[](LICENSE)
|
|
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.
|
|
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.<img align="right" src="./assets/performance.png" width="380"/>
|
|
12
12
|
|
|
13
13
|
## Basic Usage
|
|
14
14
|
|
|
@@ -53,7 +53,7 @@ receivingStream.on('data', (data) => {
|
|
|
53
53
|
The `PackrStream` and `UnpackrStream` instances will have also the record structure extension enabled by default (see below).
|
|
54
54
|
|
|
55
55
|
## Deno Usage
|
|
56
|
-
Msgpackr modules are standard ESM modules and can be loaded directly from
|
|
56
|
+
Msgpackr modules are standard ESM modules and can be loaded directly from the [deno.land registry for msgpackr](https://deno.land/x/msgpackr) for use in Deno. The standard pack/encode and unpack/decode functionality is available on Deno, like other platforms.
|
|
57
57
|
|
|
58
58
|
## Browser Usage
|
|
59
59
|
Msgpackr works as standalone JavaScript as well, and runs on modern browsers. It includes a bundled script, at `dist/index.js` for ease of direct loading:
|
|
@@ -162,6 +162,7 @@ The following options properties can be provided to the Packr or Unpackr constru
|
|
|
162
162
|
* `mapsAsObjects` - If `true`, this will decode MessagePack maps and JS `Object`s with the map entries decoded to object properties. If `false`, maps are decoded as JavaScript `Map`s. This is disabled by default if `useRecords` is enabled (which allows `Map`s to be preserved), and is enabled by default if `useRecords` is disabled.
|
|
163
163
|
* `useFloat32` - This will enable msgpackr to encode non-integer numbers as `float32`. See next section for possible values.
|
|
164
164
|
* `variableMapSize` - This will use varying map size definition (fixmap, map16, map32) based on the number of keys when encoding objects, which yields slightly more compact encodings (for small objects), but is typically 5-10% slower during encoding. This is necessary if you need to use objects with more than 65535 keys. This is only relevant when record extension is disabled.
|
|
165
|
+
* `bundleStrings` - If `true` this uses a custom extension that bundles strings together, so that they can be decoded more quickly on browsers and Deno that do not have access to the NodeJS addon. This a custom extension, so both encoder and decoder need to support this. This can yield significant decoding performance increases on browsers (30%-50%).
|
|
165
166
|
* `copyBuffers` - When decoding a MessagePack with binary data (Buffers are encoded as binary data), copy the buffer rather than providing a slice/view of the buffer. If you want your input data to be collected or modified while the decoded embedded buffer continues to live on, you can use this option (there is extra overhead to copying).
|
|
166
167
|
* `useTimestamp32` - Encode JS `Date`s in 32-bit format when possible by dropping the milliseconds. This is a more efficient encoding of dates. You can also cause dates to use 32-bit format by manually setting the milliseconds to zero (`date.setMilliseconds(0)`).
|
|
167
168
|
* `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`.
|
package/dist/index.js
CHANGED
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
var srcString;
|
|
17
17
|
var srcStringStart = 0;
|
|
18
18
|
var srcStringEnd = 0;
|
|
19
|
+
var bundledStrings;
|
|
19
20
|
var referenceMap;
|
|
20
21
|
var currentExtensions = [];
|
|
21
22
|
var dataView;
|
|
@@ -54,6 +55,7 @@
|
|
|
54
55
|
position = 0;
|
|
55
56
|
srcStringEnd = 0;
|
|
56
57
|
srcString = null;
|
|
58
|
+
bundledStrings = null;
|
|
57
59
|
src = source;
|
|
58
60
|
// this provides cached access to the data view for a buffer if it is getting reused, which is a recommend
|
|
59
61
|
// technique for getting data from a database where it can be copied into an existing buffer instead of creating
|
|
@@ -244,7 +246,15 @@
|
|
|
244
246
|
let value;
|
|
245
247
|
switch (token) {
|
|
246
248
|
case 0xc0: return null
|
|
247
|
-
case 0xc1:
|
|
249
|
+
case 0xc1:
|
|
250
|
+
if (bundledStrings) {
|
|
251
|
+
value = read(); // followed by the length of the string in characters (not bytes!)
|
|
252
|
+
if (value > 0)
|
|
253
|
+
return bundledStrings[1].slice(bundledStrings.position1, bundledStrings.position1 += value)
|
|
254
|
+
else
|
|
255
|
+
return bundledStrings[0].slice(bundledStrings.position0, bundledStrings.position0 -= value)
|
|
256
|
+
}
|
|
257
|
+
return C1; // "never-used", return special object to denote that
|
|
248
258
|
case 0xc2: return false
|
|
249
259
|
case 0xc3: return true
|
|
250
260
|
case 0xc4:
|
|
@@ -857,6 +867,22 @@
|
|
|
857
867
|
return new RegExp(data[0], data[1])
|
|
858
868
|
};
|
|
859
869
|
|
|
870
|
+
currentExtensions[0x62] = (data) => {
|
|
871
|
+
let dataSize = (data[0] << 24) + (data[1] << 16) + (data[2] << 8) + data[3];
|
|
872
|
+
let dataPosition = position;
|
|
873
|
+
position += dataSize - 4;
|
|
874
|
+
bundledStrings = [read(), read()];
|
|
875
|
+
bundledStrings.position0 = 0;
|
|
876
|
+
bundledStrings.position1 = 0;
|
|
877
|
+
let postBundlePosition = position;
|
|
878
|
+
position = dataPosition;
|
|
879
|
+
try {
|
|
880
|
+
return read()
|
|
881
|
+
} finally {
|
|
882
|
+
position = postBundlePosition;
|
|
883
|
+
}
|
|
884
|
+
};
|
|
885
|
+
|
|
860
886
|
currentExtensions[0xff] = (data) => {
|
|
861
887
|
// 32-bit date extension
|
|
862
888
|
if (data.length == 4)
|
|
@@ -882,6 +908,7 @@
|
|
|
882
908
|
let savedSrcStringEnd = srcStringEnd;
|
|
883
909
|
let savedSrcString = srcString;
|
|
884
910
|
let savedReferenceMap = referenceMap;
|
|
911
|
+
let savedBundledStrings = bundledStrings;
|
|
885
912
|
|
|
886
913
|
// TODO: We may need to revisit this if we do more external calls to user code (since it could be slow)
|
|
887
914
|
let savedSrc = new Uint8Array(src.slice(0, srcEnd)); // we copy the data in case it changes while external data is processed
|
|
@@ -896,6 +923,7 @@
|
|
|
896
923
|
srcStringEnd = savedSrcStringEnd;
|
|
897
924
|
srcString = savedSrcString;
|
|
898
925
|
referenceMap = savedReferenceMap;
|
|
926
|
+
bundledStrings = savedBundledStrings;
|
|
899
927
|
src = savedSrc;
|
|
900
928
|
sequentialMode = savedSequentialMode;
|
|
901
929
|
currentStructures = savedStructures;
|
|
@@ -953,6 +981,8 @@
|
|
|
953
981
|
let targetView;
|
|
954
982
|
let position$1 = 0;
|
|
955
983
|
let safeEnd;
|
|
984
|
+
let bundledStrings$1 = null;
|
|
985
|
+
const hasNonLatin = /[\u0080-\uFFFF]/;
|
|
956
986
|
const RECORD_SYMBOL = Symbol('record-id');
|
|
957
987
|
class Packr extends Unpackr {
|
|
958
988
|
constructor(options) {
|
|
@@ -1014,6 +1044,14 @@
|
|
|
1014
1044
|
position$1 = (position$1 + 7) & 0x7ffffff8; // Word align to make any future copying of this buffer faster
|
|
1015
1045
|
start = position$1;
|
|
1016
1046
|
referenceMap = packr.structuredClone ? new Map() : null;
|
|
1047
|
+
if (packr.bundleStrings) {
|
|
1048
|
+
bundledStrings$1 = ['', ''];
|
|
1049
|
+
target[position$1++] = 0xd6;
|
|
1050
|
+
target[position$1++] = 0x62; // 'b'
|
|
1051
|
+
bundledStrings$1.position = position$1 - start;
|
|
1052
|
+
position$1 += 4;
|
|
1053
|
+
} else
|
|
1054
|
+
bundledStrings$1 = null;
|
|
1017
1055
|
sharedStructures = packr.structures;
|
|
1018
1056
|
if (sharedStructures) {
|
|
1019
1057
|
if (sharedStructures.uninitialized)
|
|
@@ -1052,6 +1090,13 @@
|
|
|
1052
1090
|
structures = sharedStructures || [];
|
|
1053
1091
|
try {
|
|
1054
1092
|
pack(value);
|
|
1093
|
+
if (bundledStrings$1) {
|
|
1094
|
+
targetView.setUint32(bundledStrings$1.position + start, position$1 - bundledStrings$1.position - start);
|
|
1095
|
+
let writeStrings = bundledStrings$1;
|
|
1096
|
+
bundledStrings$1 = null;
|
|
1097
|
+
pack(writeStrings[0]);
|
|
1098
|
+
pack(writeStrings[1]);
|
|
1099
|
+
}
|
|
1055
1100
|
packr.offset = position$1; // update the offset so next serialization doesn't write over our buffer, but can continue writing to same buffer sequentially
|
|
1056
1101
|
if (referenceMap && referenceMap.idsToInsert) {
|
|
1057
1102
|
position$1 += referenceMap.idsToInsert.length * 6;
|
|
@@ -1062,7 +1107,7 @@
|
|
|
1062
1107
|
referenceMap = null;
|
|
1063
1108
|
return serialized
|
|
1064
1109
|
}
|
|
1065
|
-
if (encodeOptions
|
|
1110
|
+
if (encodeOptions & REUSE_BUFFER_MODE) {
|
|
1066
1111
|
target.start = start;
|
|
1067
1112
|
target.end = position$1;
|
|
1068
1113
|
return target
|
|
@@ -1101,6 +1146,8 @@
|
|
|
1101
1146
|
return returnBuffer
|
|
1102
1147
|
}
|
|
1103
1148
|
}
|
|
1149
|
+
if (encodeOptions & RESET_BUFFER_MODE)
|
|
1150
|
+
position$1 = start;
|
|
1104
1151
|
}
|
|
1105
1152
|
};
|
|
1106
1153
|
const pack = (value) => {
|
|
@@ -1111,6 +1158,13 @@
|
|
|
1111
1158
|
var length;
|
|
1112
1159
|
if (type === 'string') {
|
|
1113
1160
|
let strLength = value.length;
|
|
1161
|
+
if (bundledStrings$1 && strLength >= 8 && strLength < 0x1000) {
|
|
1162
|
+
let twoByte = hasNonLatin.test(value);
|
|
1163
|
+
bundledStrings$1[twoByte ? 0 : 1] += value;
|
|
1164
|
+
target[position$1++] = 0xc1;
|
|
1165
|
+
pack(twoByte ? -strLength : strLength);
|
|
1166
|
+
return
|
|
1167
|
+
}
|
|
1114
1168
|
let headerSize;
|
|
1115
1169
|
// first we estimate the header size, so we can write to the correct location
|
|
1116
1170
|
if (strLength < 0x20) {
|
|
@@ -1571,8 +1625,10 @@
|
|
|
1571
1625
|
targetView.setUint32(position, date.getMilliseconds() * 4000000 + ((seconds / 1000 / 0x100000000) >> 0));
|
|
1572
1626
|
targetView.setUint32(position + 4, seconds);
|
|
1573
1627
|
} else if (isNaN(seconds)) {
|
|
1574
|
-
if (this.onInvalidDate)
|
|
1628
|
+
if (this.onInvalidDate) {
|
|
1629
|
+
allocateForWrite(0);
|
|
1575
1630
|
return pack(this.onInvalidDate())
|
|
1631
|
+
}
|
|
1576
1632
|
// Intentionally invalid timestamp
|
|
1577
1633
|
let { target, targetView, position} = allocateForWrite(3);
|
|
1578
1634
|
target[position++] = 0xd4;
|
|
@@ -1763,7 +1819,8 @@
|
|
|
1763
1819
|
const encode = defaultPackr.pack;
|
|
1764
1820
|
const Encoder = Packr;
|
|
1765
1821
|
const { NEVER, ALWAYS, DECIMAL_ROUND, DECIMAL_FIT } = FLOAT32_OPTIONS;
|
|
1766
|
-
const REUSE_BUFFER_MODE =
|
|
1822
|
+
const REUSE_BUFFER_MODE = 512;
|
|
1823
|
+
const RESET_BUFFER_MODE = 1024;
|
|
1767
1824
|
|
|
1768
1825
|
/**
|
|
1769
1826
|
* Given an Iterable first argument, returns an Iterable where each value is packed as a Buffer
|
package/dist/index.min.js
CHANGED
|
@@ -1,62 +1,63 @@
|
|
|
1
|
-
(function(a,b){"object"==typeof exports&&"undefined"!=typeof module?b(exports):"function"==typeof define&&define.amd?define(["exports"],b):(a=a||self,b(a.msgpackr={}))})(this,function(a){'use strict';var b=Math.floor;function c(){try{if(!
|
|
2
|
-
let a=new Error("Unexpected end of MessagePack data");throw a.incomplete=!0,a}else if(!
|
|
3
|
-
return a}catch(a){throw C.restoreStructures&&d(),q(),(a instanceof RangeError||a.message.startsWith("Unexpected end of buffer"))&&(a.incomplete=!0),a}}function d(){for(let a in C.restoreStructures)C[a]=C.restoreStructures[a];C.restoreStructures=null}function e(){let a=A[
|
|
4
|
-
let b=a-160;if(
|
|
5
|
-
let a=16>b?l(b):k(b);if(null!=a)return a}return
|
|
1
|
+
(function(a,b){"object"==typeof exports&&"undefined"!=typeof module?b(exports):"function"==typeof define&&define.amd?define(["exports"],b):(a=a||self,b(a.msgpackr={}))})(this,function(a){'use strict';var b=Math.floor;function c(){try{if(!I.trusted&&!P){let a=C.sharedLength||0;a<C.length&&(C.length=a)}let a=e();if(H==B)C.restoreStructures&&d(),C=null,A=null,F&&(F=null);else if(H>B){// over read
|
|
2
|
+
let a=new Error("Unexpected end of MessagePack data");throw a.incomplete=!0,a}else if(!P)throw new Error("Data read, but end of buffer not reached");// else more to read, but we are reading sequentially, so don't clear source yet
|
|
3
|
+
return a}catch(a){throw C.restoreStructures&&d(),q(),(a instanceof RangeError||a.message.startsWith("Unexpected end of buffer"))&&(a.incomplete=!0),a}}function d(){for(let a in C.restoreStructures)C[a]=C.restoreStructures[a];C.restoreStructures=null}function e(){let a=A[H++];if(160>a){if(!(128>a)){if(!(144>a)){a-=144;let b=Array(a);for(let c=0;c<a;c++)b[c]=e();return b}if(a-=128,I.mapsAsObjects){let b={};for(let c=0;c<a;c++)b[o()]=e();return b}else{let b=new Map;for(let c=0;c<a;c++)b.set(e(),e());return b}}else if(64>a)return a;else{let b=C[63&a]||I.getStructures&&g()[63&a];return b?(b.read||(b.read=f(b,63&a)),b.read()):a}}else if(192>a){// fixstr
|
|
4
|
+
let b=a-160;if(K>=H)return D.slice(H-J,(H+=b)-J);if(0==K&&140>B){// for small blocks, avoiding the overhead of the extract call is helpful
|
|
5
|
+
let a=16>b?l(b):k(b);if(null!=a)return a}return T(b)}else{let b;switch(a){case 192:return null;case 193:return E?(b=e(),0<b?E[1].slice(E.position1,E.position1+=b):E[0].slice(E.position0,E.position0-=b)):O;// "never-used", return special object to denote that
|
|
6
6
|
case 194:return!1;case 195:return!0;case 196:// bin 8
|
|
7
|
-
return m(A[
|
|
8
|
-
return n(A[
|
|
9
|
-
let a=
|
|
10
|
-
case 204:return A[
|
|
11
|
-
case 208:return
|
|
7
|
+
return m(A[H++]);case 197:return b=G.getUint16(H),H+=2,m(b);case 198:return b=G.getUint32(H),H+=4,m(b);case 199:// ext 8
|
|
8
|
+
return n(A[H++]);case 200:return b=G.getUint16(H),H+=2,n(b);case 201:return b=G.getUint32(H),H+=4,n(b);case 202:if(b=G.getFloat32(H),2<I.useFloat32){// this does rounding of numbers that were encoded in 32-bit float to nearest significant decimal digit that could be preserved
|
|
9
|
+
let a=aa[(127&A[H])<<1|A[H+1]>>7];return H+=4,(a*b+(0<b?.5:-.5)>>0)/a}return H+=4,b;case 203:return b=G.getFloat64(H),H+=8,b;// uint handlers
|
|
10
|
+
case 204:return A[H++];case 205:return b=G.getUint16(H),H+=2,b;case 206:return b=G.getUint32(H),H+=4,b;case 207:return I.int64AsNumber?(b=4294967296*G.getUint32(H),b+=G.getUint32(H+4)):b=G.getBigUint64(H),H+=8,b;// int handlers
|
|
11
|
+
case 208:return G.getInt8(H++);case 209:return b=G.getInt16(H),H+=2,b;case 210:return b=G.getInt32(H),H+=4,b;case 211:return I.int64AsNumber?(b=4294967296*G.getInt32(H),b+=G.getUint32(H+4)):b=G.getBigInt64(H),H+=8,b;case 212:if(b=A[H++],114==b)return Z(63&A[H++]);else{let a=L[b];if(a)return a.read?(H++,a.read(e())):a.noBuffer?(H++,a()):a(A.subarray(H,++H));throw new Error("Unknown extension "+b)}case 213:return b=A[H],114==b?(H++,Z(63&A[H++],A[H++])):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
|
-
return n(16);case 217:return b=A[
|
|
14
|
+
return n(16);case 217:return b=A[H++],K>=H?D.slice(H-J,(H+=b)-J):U(b);case 218:return b=G.getUint16(H),H+=2,K>=H?D.slice(H-J,(H+=b)-J):V(b);case 219:return b=G.getUint32(H),H+=4,K>=H?D.slice(H-J,(H+=b)-J):W(b);case 220:return b=G.getUint16(H),H+=2,i(b);case 221:return b=G.getUint32(H),H+=4,i(b);case 222:return b=G.getUint16(H),H+=2,j(b);case 223:return b=G.getUint32(H),H+=4,j(b);default:// negative int
|
|
15
15
|
if(224<=a)return a-256;if(void 0===a){let a=new Error("Unexpected end of MessagePack data");throw a.incomplete=!0,a}throw new Error("Unknown MessagePack token "+a);}}}function f(a,b){function c(){// This initial function is quick to instantiate, but runs slower. After several iterations pay the cost to build the faster function
|
|
16
|
-
if(2<c.count++){let c=a.read=new Function("r","return function(){return {"+a.map(a=>
|
|
17
|
-
}let d={};for(let b,c=0,f=a.length;c<f;c++)b=a[c],d[b]=e();return d}return c.count=0,0===a.highByte?
|
|
18
|
-
const b=63&A[
|
|
19
|
-
const b=63&A[
|
|
20
|
-
const b=63&A[
|
|
21
|
-
Uint8Array.prototype.slice.call(A,
|
|
22
|
-
return D.slice(
|
|
23
|
-
let j=16>a?l(a):k(a);return null==j?d.string=
|
|
16
|
+
if(2<c.count++){let c=a.read=new Function("r","return function(){return {"+a.map(a=>R.test(a)?a+":r()":"["+JSON.stringify(a)+"]:r()").join(",")+"}}")(e);return 0===a.highByte&&(a.read=S(b,a.read)),c();// second byte is already read, if there is one so immediately read object
|
|
17
|
+
}let d={};for(let b,c=0,f=a.length;c<f;c++)b=a[c],d[b]=e();return d}return c.count=0,0===a.highByte?S(b,c):c}function g(){let a=p(()=>(A=null,I.getStructures()));return C=I._mergeStructures(a,C)}function h(a){let b;if(16>a&&(b=l(a)))return b;if(64<a&&z)return z.decode(A.subarray(H,H+=a));const c=H+a,d=[];for(b="";H<c;){const a=A[H++];if(0==(128&a))d.push(a);else if(192==(224&a)){// 2 bytes
|
|
18
|
+
const b=63&A[H++];d.push((31&a)<<6|b)}else if(224==(240&a)){// 3 bytes
|
|
19
|
+
const b=63&A[H++],c=63&A[H++];d.push((31&a)<<12|b<<6|c)}else if(240==(248&a)){// 4 bytes
|
|
20
|
+
const b=63&A[H++],c=63&A[H++],e=63&A[H++];let f=(7&a)<<18|b<<12|c<<6|e;65535<f&&(f-=65536,d.push(55296|1023&f>>>10),f=56320|1023&f),d.push(f)}else d.push(a);4096<=d.length&&(b+=X.apply(String,d),d.length=0)}return 0<d.length&&(b+=X.apply(String,d)),b}function i(a){let b=Array(a);for(let c=0;c<a;c++)b[c]=e();return b}function j(a){if(I.mapsAsObjects){let b={};for(let c=0;c<a;c++)b[o()]=e();return b}else{let b=new Map;for(let c=0;c<a;c++)b.set(e(),e());return b}}function k(a){let b=H,c=Array(a);for(let d=0;d<a;d++){const a=A[H++];if(0<(128&a))return void(H=b);c[d]=a}return X.apply(String,c)}function l(p){if(4>p){if(!(2>p)){let d=A[H++],a=A[H++];if(0<(128&d)||0<(128&a))return void(H-=2);if(3>p)return X(d,a);let b=A[H++];return 0<(128&b)?void(H-=3):X(d,a,b)}if(0===p)return"";else{let b=A[H++];return 1<(128&b)?void(H-=1):X(b)}}else{let q=A[H++],a=A[H++],b=A[H++],c=A[H++];if(0<(128&q)||0<(128&a)||0<(128&b)||0<(128&c))return void(H-=4);if(6>p){if(4===p)return X(q,a,b,c);else{let d=A[H++];return 0<(128&d)?void(H-=5):X(q,a,b,c,d)}}else if(8>p){let d=A[H++],e=A[H++];if(0<(128&d)||0<(128&e))return void(H-=6);if(7>p)return X(q,a,b,c,d,e);let f=A[H++];return 0<(128&f)?void(H-=7):X(q,a,b,c,d,e,f)}else{let d=A[H++],e=A[H++],f=A[H++],g=A[H++];if(0<(128&d)||0<(128&e)||0<(128&f)||0<(128&g))return void(H-=8);if(10>p){if(8===p)return X(q,a,b,c,d,e,f,g);else{let h=A[H++];return 0<(128&h)?void(H-=9):X(q,a,b,c,d,e,f,g,h)}}else if(12>p){let h=A[H++],i=A[H++];if(0<(128&h)||0<(128&i))return void(H-=10);if(11>p)return X(q,a,b,c,d,e,f,g,h,i);let j=A[H++];return 0<(128&j)?void(H-=11):X(q,a,b,c,d,e,f,g,h,i,j)}else{let h=A[H++],i=A[H++],j=A[H++],k=A[H++];if(0<(128&h)||0<(128&i)||0<(128&j)||0<(128&k))return void(H-=12);if(!(14>p)){let l=A[H++],m=A[H++];if(0<(128&l)||0<(128&m))return void(H-=14);if(15>p)return X(q,a,b,c,d,e,f,g,h,i,j,k,l,m);let n=A[H++];return 0<(128&n)?void(H-=15):X(q,a,b,c,d,e,f,g,h,i,j,k,l,m,n)}if(12===p)return X(q,a,b,c,d,e,f,g,h,i,j,k);else{let l=A[H++];return 0<(128&l)?void(H-=13):X(q,a,b,c,d,e,f,g,h,i,j,k,l)}}}}}function m(a){return I.copyBuffers?// specifically use the copying slice (not the node one)
|
|
21
|
+
Uint8Array.prototype.slice.call(A,H,H+=a):A.subarray(H,H+=a)}function n(a){let b=A[H++];if(L[b])return L[b](A.subarray(H,H+=a));throw new Error("Unknown extension type "+b)}function o(){let a=A[H++];if(160<=a&&192>a){if(a-=160,K>=H)// if it has been extracted, must use it (and faster anyway)
|
|
22
|
+
return D.slice(H-J,(H+=a)-J);if(!(0==K&&180>B))return T(a)}else return H--,e();let b,c=4095&(a<<5^(1<a?G.getUint16(H):0<a?A[H]:0)),d=Y[c],f=H,g=H+a-3,h=0;if(d&&d.bytes==a){for(;f<g;){if(b=G.getUint32(f),b!=d[h++]){f=1879048192;break}f+=4}for(g+=3;f<g;)if(b=A[f++],b!=d[h++]){f=1879048192;break}if(f===g)return H=f,d.string;g-=3,f=H}for(d=[],Y[c]=d,d.bytes=a;f<g;)b=G.getUint32(f),d.push(b),f+=4;for(g+=3;f<g;)b=A[f++],d.push(b);// for small blocks, avoiding the overhead of the extract call is helpful
|
|
23
|
+
let j=16>a?l(a):k(a);return null==j?d.string=T(a):d.string=j}// the registration of the record definition extension (as "r")
|
|
24
24
|
// notepack defines extension 0 to mean undefined, so use that as the default here
|
|
25
25
|
// registration of bulk record definition?
|
|
26
26
|
// currentExtensions[0x52] = () =>
|
|
27
|
-
function p(a){let b=B,c=
|
|
27
|
+
function p(a){let b=B,c=H,d=J,e=K,f=D,g=F,h=E,i=new Uint8Array(A.slice(0,B)),j=C,k=C.slice(0,C.length),l=I,m=P,n=a();return B=b,H=c,J=d,K=e,D=f,F=g,E=h,A=i,P=m,C=j,C.splice(0,C.length,...k),I=l,G=new DataView(A.buffer,A.byteOffset,A.byteLength),n}function q(){A=null,F=null,C=null}function r(a){L[a.type]=a.unpack?a.unpack:a}function s(a,b,c){let d=a.byteLength;if(256>d+1){var{target:e,position:f}=c(4+d);e[f++]=199,e[f++]=d+1}else if(65536>d+1){var{target:e,position:f}=c(5+d);e[f++]=200,e[f++]=d+1>>8,e[f++]=255&d+1}else{var{target:e,position:f,targetView:g}=c(7+d);// plus one for the type byte
|
|
28
28
|
e[f++]=201,g.setUint32(f,d+1),f+=4}// "t" for typed array
|
|
29
29
|
e[f++]=116,e[f++]=b,e.set(new Uint8Array(a.buffer,a.byteOffset,a.byteLength),f)}function t(a,b){let c=a.byteLength;var d,e;if(256>c){var{target:d,position:e}=b(c+2);d[e++]=196,d[e++]=c}else if(65536>c){var{target:d,position:e}=b(c+3);d[e++]=197,d[e++]=c>>8,d[e++]=255&c}else{var{target:d,position:e,targetView:f}=b(c+5);d[e++]=198,f.setUint32(e,c),e+=4}d.set(a,e)}function u(a,b,c,d){let e=a.length;return 1===e?b[c++]=212:2===e?b[c++]=213:4===e?b[c++]=214:8===e?b[c++]=215:16===e?b[c++]=216:256>e?(b[c++]=199,b[c++]=e):65536>e?(b[c++]=200,b[c++]=e>>8,b[c++]=255&e):(b[c++]=201,b[c++]=e>>24,b[c++]=255&e>>16,b[c++]=255&e>>8,b[c++]=255&e),b[c++]=d,b.set(a,c),c+=e,c}function v(a,b){// insert the ids that need to be referenced for structured clones
|
|
30
30
|
let c,d=6*b.length,e=a.length-d;for(b.sort((c,a)=>c.offset>a.offset?1:-1);c=b.pop();){let b=c.offset,f=c.id;a.copyWithin(b+d,b,e),d-=6;let g=b+d;// 'i'
|
|
31
|
-
a[g++]=214,a[g++]=105,a[g++]=f>>24,a[g++]=255&f>>16,a[g++]=255&f>>8,a[g++]=255&f,e=b}return a}function w(a){if(a.Class){if(!a.pack&&!a.write)throw new Error("Extension has no pack or write function");if(a.pack&&!a.type)throw new Error("Extension has no type (numeric code to identify the extension)");
|
|
31
|
+
a[g++]=214,a[g++]=105,a[g++]=f>>24,a[g++]=255&f>>16,a[g++]=255&f>>8,a[g++]=255&f,e=b}return a}function w(a){if(a.Class){if(!a.pack&&!a.write)throw new Error("Extension has no pack or write function");if(a.pack&&!a.type)throw new Error("Extension has no type (numeric code to identify the extension)");ka.unshift(a.Class),ja.unshift(a)}r(a)}function*x(a,b){const c=new va(b);for(const d of a)yield c.pack(d)}async function*y(a,b){const c=new va(b);for await(const d of a)yield c.pack(d)}/**
|
|
32
32
|
* Given an Iterable/Iterator input which yields buffers, returns an IterableIterator which yields sync decoded objects
|
|
33
33
|
* Or, given an Async Iterable/Iterator which yields promises resolving in buffers, returns an AsyncIterableIterator.
|
|
34
34
|
* @param {Iterable|Iterator|AsyncIterable|AsyncIterableIterator} bufferIterator
|
|
35
35
|
* @param {object} [options] - unpackr options
|
|
36
36
|
* @returns {IterableIterator|Promise.<AsyncIterableIterator}
|
|
37
|
-
*/var z;try{z=new TextDecoder}catch(a){}var A,B,C,D,E,F,G=0,
|
|
38
|
-
return p(()=>(q(),this?this.unpack(a,b):
|
|
37
|
+
*/var z;try{z=new TextDecoder}catch(a){}var A,B,C,D,E,F,G,H=0,I={},J=0,K=0,L=[],M={useRecords:!1,mapsAsObjects:!0};class N{}const O=new N;O.name="MessagePack 0xC1";var P=!1;class Q{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):Q.prototype.unpack.call(M,a,b)));B=-1<b?b:a.length,H=0,K=0,D=null,E=null,A=a;// this provides cached access to the data view for a buffer if it is getting reused, which is a recommend
|
|
39
39
|
// technique for getting data from a database where it can be copied into an existing buffer instead of creating
|
|
40
40
|
// new ones
|
|
41
|
-
try{
|
|
42
|
-
let a=
|
|
43
|
-
|
|
41
|
+
try{G=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 Q){if(I=this,this.structures)return C=this.structures,c();(!C||0<C.length)&&(C=[])}else I=M,(!C||0<C.length)&&(C=[]);return c()}unpackMultiple(a,b){let d,e=0;try{P=!0;let f=a.length,g=this?this.unpack(a,f):ba.unpack(a,f);if(b){for(b(g);H<f;)if(e=H,!1===b(c()))return;}else{for(d=[g];H<f;)e=H,d.push(c());return d}}catch(a){throw a.lastPosition=e,a.values=d,a}finally{P=!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 R=/^[a-zA-Z_$][a-zA-Z\d_$]*$/,S=(a,b)=>function(){let c=A[H++];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 T=h,U=h,V=h,W=h;var X=String.fromCharCode,Y=Array(4096);const Z=(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 $="object"==typeof self?self:global;L[0]=()=>{},L[0].noBuffer=!0,L[101]=()=>{let a=e();return($[a[0]]||Error)(a[1])},L[105]=()=>{// id extension (for structured clones)
|
|
42
|
+
let a=G.getUint32(H-4);F||(F=new Map);let b,c=A[H];b=144<=c&&160>c||220==c||221==c?[]:{};let d={target:b};// a placeholder object
|
|
43
|
+
F.set(a,d);let f=e();// read the next value as the target object to id
|
|
44
44
|
return d.used?Object.assign(b,f):(d.target=f,f);// no cycle, can just use the returned read object
|
|
45
|
-
},
|
|
46
|
-
let a=
|
|
47
|
-
return new
|
|
48
|
-
for(let c=0;256>c;c++)
|
|
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(
|
|
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[
|
|
51
|
-
if(
|
|
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][
|
|
53
|
-
let e=
|
|
54
|
-
(
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
let
|
|
45
|
+
},L[112]=()=>{// pointer extension (for structured clones)
|
|
46
|
+
let a=G.getUint32(H-4),b=F.get(a);return b.used=!0,b.target},L[115]=()=>new Set(e());const _=["Int8","Uint8","Uint8Clamped","Int16","Uint16","Int32","Uint32","Float32","Float64","BigInt64","BigUint64"].map(a=>a+"Array");L[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
|
|
47
|
+
return new $[c](Uint8Array.prototype.slice.call(a,1).buffer)},L[120]=()=>{let a=e();return new RegExp(a[0],a[1])},L[98]=a=>{let b=(a[0]<<24)+(a[1]<<16)+(a[2]<<8)+a[3],c=H;H+=b-4,E=[e(),e()],E.position0=0,E.position1=0;let d=H;H=c;try{return e()}finally{H=d}},L[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 aa=Array(147);// this is a table matching binary exponents to the multiplier to determine significant digit rounding
|
|
48
|
+
for(let c=0;256>c;c++)aa[c]=+("1e"+b(45.15-.30103*c));var ba=new Q({useRecords:!1});const ca=ba.unpack,da=ba.unpackMultiple,ea=ba.unpack,fa={NEVER:0,ALWAYS:1,DECIMAL_ROUND:3,DECIMAL_FIT:4};let ga,ha=new Float32Array(1),ia=new Uint8Array(ha.buffer,0,4);try{ga=new TextEncoder}catch(a){}let ja,ka;const la="undefined"!=typeof Buffer,ma=la?Buffer.allocUnsafeSlow:Uint8Array,na=la?Buffer:Uint8Array,oa=la?4294967296:2144337920;let pa,qa,ra,sa=0,ta=null;const ua=Symbol("record-id");class va extends Q{constructor(a){super(a),this.offset=0;let b,c,d,e,f,g=0,h=na.prototype.utf8Write?function(a,b,c){return pa.utf8Write(a,b,c)}:!!(ga&&ga.encodeInto)&&function(a,b){return ga.encodeInto(a,pa.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
|
|
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(pa||(pa=new ma(8192),qa=new DataView(pa.buffer,0,8192),sa=0),ra=pa.length-10,2048>ra-sa?(pa=new ma(pa.length),qa=new DataView(pa.buffer,0,pa.length),ra=pa.length-10,sa=0):sa=2147483640&sa+7,b=sa,f=i.structuredClone?new Map:null,i.bundleStrings?(ta=["",""],pa[sa++]=214,pa[sa++]=98,ta.position=sa-b,sa+=4):ta=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
|
|
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[ua]=d+64}g=a}j||(c.nextId=a+64)}d&&(d=!1),e=c||[];try{if(t(a),ta){qa.setUint32(ta.position+b,sa-ta.position-b);let a=ta;ta=null,t(a[0]),t(a[1])}// update the offset so next serialization doesn't write over our buffer, but can continue writing to same buffer sequentially
|
|
51
|
+
if(i.offset=sa,f&&f.idsToInsert){sa+=6*f.idsToInsert.length,sa>ra&&x(sa),i.offset=sa;let a=v(pa.subarray(b,sa),f.idsToInsert);return f=null,a}return h&Da?(pa.start=b,pa.end=sa,pa):pa.subarray(b,sa);// position can change if we call pack again in saveStructures, so we get the buffer now
|
|
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][ua]=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
|
|
53
|
+
let e=pa.subarray(b,sa);return!1===i.saveStructures(c,g)?(i._mergeStructures(i.getStructures()),i.pack(a)):(g=d,e)}}h&Ea&&(sa=b)}};const t=a=>{sa>ra&&(pa=x(sa));var c,d=typeof a;if("string"==d){let b=a.length;if(ta&&8<=b&&4096>b){let c=/[\u0080-\uFFFF]/.test(a);return ta[c?0:1]+=a,pa[sa++]=193,void t(c?-b:b)}let d=32>b?1:256>b?2:65536>b?3:5;// first we estimate the header size, so we can write to the correct location
|
|
54
|
+
let e=3*b;if(sa+e>ra&&(pa=x(sa+e)),64>b||!h){let e,f,g,h=sa+d;for(e=0;e<b;e++)f=a.charCodeAt(e),128>f?pa[h++]=f:2048>f?(pa[h++]=192|f>>6,pa[h++]=128|63&f):55296==(64512&f)&&56320==(64512&(g=a.charCodeAt(e+1)))?(f=65536+((1023&f)<<10)+(1023&g),e++,pa[h++]=240|f>>18,pa[h++]=128|63&f>>12,pa[h++]=128|63&f>>6,pa[h++]=128|63&f):(pa[h++]=224|f>>12,pa[h++]=128|63&f>>6,pa[h++]=128|63&f);c=h-sa-d}else c=h(a,sa+d,e);32>c?pa[sa++]=160|c:256>c?(2>d&&pa.copyWithin(sa+2,sa+1,sa+1+c),pa[sa++]=217,pa[sa++]=c):65536>c?(3>d&&pa.copyWithin(sa+3,sa+2,sa+2+c),pa[sa++]=218,pa[sa++]=c>>8,pa[sa++]=255&c):(5>d&&pa.copyWithin(sa+5,sa+3,sa+3+c),pa[sa++]=219,qa.setUint32(sa,c),sa+=4),sa+=c}else if("number"===d){if(a>>>0===a)64>a?pa[sa++]=a:256>a?(pa[sa++]=204,pa[sa++]=a):65536>a?(pa[sa++]=205,pa[sa++]=a>>8,pa[sa++]=255&a):(pa[sa++]=206,qa.setUint32(sa,a),sa+=4);else if(a>>0===a)-32<=a?pa[sa++]=256+a:-128<=a?(pa[sa++]=208,pa[sa++]=a+256):-32768<=a?(pa[sa++]=209,qa.setInt16(sa,a),sa+=2):(pa[sa++]=210,qa.setInt32(sa,a),sa+=4);else{let b;if(0<(b=this.useFloat32)&&4294967296>a&&-2147483648<=a){pa[sa++]=202,qa.setFloat32(sa,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
|
|
55
|
+
(c=a*aa[(127&pa[sa])<<1|pa[sa+1]>>7])>>0===c)return void(sa+=4);// move back into position for writing a double
|
|
56
|
+
sa--}pa[sa++]=203,qa.setFloat64(sa,a),sa+=8}}else if("object"===d){if(!a)pa[sa++]=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 pa[sa++]=214,pa[sa++]=112,qa.setUint32(sa,c.id),void(sa+=4)}f.set(a,{offset:sa-b})}let d=a.constructor;if(d===Object)w(a,!0);else if(d===Array){c=a.length,16>c?pa[sa++]=144|c:65536>c?(pa[sa++]=220,pa[sa++]=c>>8,pa[sa++]=255&c):(pa[sa++]=221,qa.setUint32(sa,c),sa+=4);for(let b=0;b<c;b++)t(a[b])}else if(d===Map){c=a.size,16>c?pa[sa++]=128|c:65536>c?(pa[sa++]=222,pa[sa++]=c>>8,pa[sa++]=255&c):(pa[sa++]=223,qa.setUint32(sa,c),sa+=4);for(let[b,c]of a)t(b),t(c)}else{for(let b,c=0,d=ja.length;c<d;c++)if(b=ka[c],a instanceof b){let b=ja[c];if(b.write)return b.type&&(pa[sa++]=212,pa[sa++]=b.type,pa[sa++]=0),void t(b.write.call(this,a));let d=pa,e=qa,f=sa;pa=null;let g;try{g=b.pack.call(this,a,a=>(pa=d,d=null,sa+=a,sa>ra&&x(sa),{target:pa,targetView:qa,position:sa-a}),t)}finally{d&&(pa=d,qa=e,sa=f,ra=pa.length-10)}return void(g&&(g.length+sa>ra&&x(g.length+sa),sa=u(g,pa,sa,b.type)))}// no extension found, write as object
|
|
57
|
+
w(a,!a.hasOwnProperty)}}}else if("boolean"===d)pa[sa++]=a?195:194;else if("bigint"===d){if(a<BigInt(1)<<BigInt(63)&&a>=-(BigInt(1)<<BigInt(63)))pa[sa++]=211,qa.setBigInt64(sa,a);else if(a<BigInt(1)<<BigInt(64)&&0<a)pa[sa++]=207,qa.setBigUint64(sa,a);else// overflow
|
|
58
|
+
if(this.largeBigIntToFloat)pa[sa++]=203,qa.setFloat64(sa,+a);else throw new RangeError(a+" was too large to fit in MessagePack 64-bit integer format, set largeBigIntToFloat to convert to float-64");sa+=8}else if("undefined"===d)this.encodeUndefinedAsNil?pa[sa++]=192:(pa[sa++]=212,pa[sa++]=0,pa[sa++]=0);else if("function"===d)t(this.writeFunction&&this.writeFunction());else throw new Error("Unknown type: "+d)},w=!1===this.useRecords?this.variableMapSize?a=>{// this method is slightly slower, but generates "preferred serialization" (optimally small for smaller objects)
|
|
59
|
+
let b=Object.keys(a),c=b.length;16>c?pa[sa++]=128|c:65536>c?(pa[sa++]=222,pa[sa++]=c>>8,pa[sa++]=255&c):(pa[sa++]=223,qa.setUint32(sa,c),sa+=4);let d;for(let e=0;e<c;e++)t(d=b[e]),t(a[d])}:(a,c)=>{pa[sa++]=222;// always using map 16, so we can preallocate and set the length afterwards
|
|
60
|
+
let d=sa-b;sa+=2;let e=0;for(let b in a)(c||a.hasOwnProperty(b))&&(t(b),t(a[b]),e++);pa[d++ +b]=e>>8,pa[d+b]=255&e}:/* sharedStructures ? // For highly stable structures, using for-in can a little bit faster
|
|
60
61
|
(object, safePrototype) => {
|
|
61
62
|
let nextTransition, transition = structures.transitions || (structures.transitions = Object.create(null))
|
|
62
63
|
let objectOffset = position++ - start
|
|
@@ -95,21 +96,21 @@ let d=ra-b;ra+=2;let e=0;for(let b in a)(c||a.hasOwnProperty(b))&&(t(b),t(a[b]),
|
|
|
95
96
|
sharedStructures.onUpdate(id, transition.__keys__)
|
|
96
97
|
}
|
|
97
98
|
target[objectOffset + start] = id
|
|
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[
|
|
99
|
-
h=o),e.nextId=h+1);let a=c.highByte=96<=h&&n?h-96>>5:-1;f[
|
|
99
|
+
}*/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[ua];if(h)96<=h&&n?(pa[sa++]=(31&(h-=96))+96,pa[sa++]=h>>5):pa[sa++]=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
|
|
100
|
+
h=o),e.nextId=h+1);let a=c.highByte=96<=h&&n?h-96>>5:-1;f[ua]=h,e[h-64]=c,h<o?(c.isShared=!0,e.sharedLength=h-63,d=!0,0<=a?(pa[sa++]=(31&h)+96,pa[sa++]=a):pa[sa++]=h):(0<=a?(pa[sa++]=213,pa[sa++]=114,pa[sa++]=(31&h)+96,pa[sa++]=a):(pa[sa++]=212,pa[sa++]=114,pa[sa++]=h),g&&(r+=s*g),q.length>=m&&(q.shift()[ua]=0),q.push(f),t(c))}// now write the values
|
|
100
101
|
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
|
|
101
|
-
if(a-b>
|
|
102
|
-
f=(e(a-b<<2,
|
|
103
|
-
|
|
102
|
+
if(a-b>oa)throw new Error("Packed buffer would be larger than maximum buffer size");f=c(oa,4096*d(e((a-b)*(67108864<a?1.25:2),4194304)/4096))}else// faster handling for smaller buffers
|
|
103
|
+
f=(e(a-b<<2,pa.length-1)>>12)+1<<12;let g=new ma(f);return qa=new DataView(g.buffer,0,f),pa.copy?pa.copy(g,0,b,a):g.set(pa.slice(b,a)),sa-=b,b=0,ra=g.length-10,pa=g}}useBuffer(a){// this means we are finished using our own buffer and we can write over it safely
|
|
104
|
+
pa=a,qa=new DataView(pa.buffer,pa.byteOffset,pa.byteLength),sa=0}}ka=[Date,Set,Error,RegExp,ArrayBuffer,Object.getPrototypeOf(Uint8Array.prototype).constructor/*TypedArray*/,N],ja=[{pack(a,c,d){let e=a.getTime()/1e3;if((this.useTimestamp32||0===a.getMilliseconds())&&0<=e&&4294967296>e){// Timestamp 32
|
|
104
105
|
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: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 c(0),d(this.onInvalidDate());// Intentionally invalid timestamp
|
|
106
107
|
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(
|
|
108
|
-
let{target:c,position:d}=b(1);c[d]=193}}];let
|
|
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=
|
|
108
|
+
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(la?Buffer.from(a):new Uint8Array(a),b)}},{pack(a,b){let c=a.constructor;c!==na&&this.structuredClone?s(a,_.indexOf(c.name),b):t(a,b)}},{pack(a,b){// specific 0xC1 object
|
|
109
|
+
let{target:c,position:d}=b(1);c[d]=193}}];let wa=new va({useRecords:!1});const xa=wa.pack,ya=wa.pack,{NEVER:za,ALWAYS:Aa,DECIMAL_ROUND:Ba,DECIMAL_FIT:Ca}=fa,Da=512,Ea=1024;a.ALWAYS=Aa,a.C1=O,a.DECIMAL_FIT=Ca,a.DECIMAL_ROUND=Ba,a.Decoder=Q,a.Encoder=va,a.FLOAT32_OPTIONS=fa,a.NEVER=za,a.Packr=va,a.REUSE_BUFFER_MODE=Da,a.Unpackr=Q,a.addExtension=w,a.clearSource=q,a.decode=ea,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 Q(b);let d;const e=a=>{let b;// if there's incomplete data from previous chunk, concatinate and try again
|
|
110
|
+
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=ya,a.encodeIter=/**
|
|
110
111
|
* Given an Iterable first argument, returns an Iterable where each value is packed as a Buffer
|
|
111
112
|
* If the argument is only Async Iterable, the return value will be an Async Iterable.
|
|
112
113
|
* @param {Iterable|Iterator|AsyncIterable|AsyncIterator} objectIterator - iterable source, like a Readable object stream, an array, Set, or custom object
|
|
113
114
|
* @param {options} [options] - msgpackr pack options
|
|
114
115
|
* @returns {IterableIterator|Promise.<AsyncIterableIterator>}
|
|
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=
|
|
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=xa,a.roundFloat32=function(a){ha[0]=a;let b=aa[(127&ia[3])<<1|ia[2]>>7];return(b*a+(0<a?.5:-.5)>>0)/b},a.unpack=ca,a.unpackMultiple=da,a.useRecords=!1,Object.defineProperty(a,"__esModule",{value:!0})});
|
package/dist/node.cjs
CHANGED
|
@@ -20,6 +20,7 @@ var currentStructures;
|
|
|
20
20
|
var srcString;
|
|
21
21
|
var srcStringStart = 0;
|
|
22
22
|
var srcStringEnd = 0;
|
|
23
|
+
var bundledStrings;
|
|
23
24
|
var referenceMap;
|
|
24
25
|
var currentExtensions = [];
|
|
25
26
|
var dataView;
|
|
@@ -60,6 +61,7 @@ class Unpackr {
|
|
|
60
61
|
srcStringEnd = 0;
|
|
61
62
|
srcString = null;
|
|
62
63
|
strings = EMPTY_ARRAY;
|
|
64
|
+
bundledStrings = null;
|
|
63
65
|
src = source;
|
|
64
66
|
// this provides cached access to the data view for a buffer if it is getting reused, which is a recommend
|
|
65
67
|
// technique for getting data from a database where it can be copied into an existing buffer instead of creating
|
|
@@ -250,7 +252,15 @@ function read() {
|
|
|
250
252
|
let value;
|
|
251
253
|
switch (token) {
|
|
252
254
|
case 0xc0: return null
|
|
253
|
-
case 0xc1:
|
|
255
|
+
case 0xc1:
|
|
256
|
+
if (bundledStrings) {
|
|
257
|
+
value = read(); // followed by the length of the string in characters (not bytes!)
|
|
258
|
+
if (value > 0)
|
|
259
|
+
return bundledStrings[1].slice(bundledStrings.position1, bundledStrings.position1 += value)
|
|
260
|
+
else
|
|
261
|
+
return bundledStrings[0].slice(bundledStrings.position0, bundledStrings.position0 -= value)
|
|
262
|
+
}
|
|
263
|
+
return C1; // "never-used", return special object to denote that
|
|
254
264
|
case 0xc2: return false
|
|
255
265
|
case 0xc3: return true
|
|
256
266
|
case 0xc4:
|
|
@@ -900,6 +910,22 @@ currentExtensions[0x78] = () => {
|
|
|
900
910
|
return new RegExp(data[0], data[1])
|
|
901
911
|
};
|
|
902
912
|
|
|
913
|
+
currentExtensions[0x62] = (data) => {
|
|
914
|
+
let dataSize = (data[0] << 24) + (data[1] << 16) + (data[2] << 8) + data[3];
|
|
915
|
+
let dataPosition = position;
|
|
916
|
+
position += dataSize - 4;
|
|
917
|
+
bundledStrings = [read(), read()];
|
|
918
|
+
bundledStrings.position0 = 0;
|
|
919
|
+
bundledStrings.position1 = 0;
|
|
920
|
+
let postBundlePosition = position;
|
|
921
|
+
position = dataPosition;
|
|
922
|
+
try {
|
|
923
|
+
return read()
|
|
924
|
+
} finally {
|
|
925
|
+
position = postBundlePosition;
|
|
926
|
+
}
|
|
927
|
+
};
|
|
928
|
+
|
|
903
929
|
currentExtensions[0xff] = (data) => {
|
|
904
930
|
// 32-bit date extension
|
|
905
931
|
if (data.length == 4)
|
|
@@ -927,6 +953,7 @@ function saveState(callback) {
|
|
|
927
953
|
let savedSrcString = srcString;
|
|
928
954
|
let savedStrings = strings;
|
|
929
955
|
let savedReferenceMap = referenceMap;
|
|
956
|
+
let savedBundledStrings = bundledStrings;
|
|
930
957
|
|
|
931
958
|
// TODO: We may need to revisit this if we do more external calls to user code (since it could be slow)
|
|
932
959
|
let savedSrc = new Uint8Array(src.slice(0, srcEnd)); // we copy the data in case it changes while external data is processed
|
|
@@ -943,6 +970,7 @@ function saveState(callback) {
|
|
|
943
970
|
srcString = savedSrcString;
|
|
944
971
|
strings = savedStrings;
|
|
945
972
|
referenceMap = savedReferenceMap;
|
|
973
|
+
bundledStrings = savedBundledStrings;
|
|
946
974
|
src = savedSrc;
|
|
947
975
|
sequentialMode = savedSequentialMode;
|
|
948
976
|
currentStructures = savedStructures;
|
|
@@ -1000,6 +1028,8 @@ let target;
|
|
|
1000
1028
|
let targetView;
|
|
1001
1029
|
let position$1 = 0;
|
|
1002
1030
|
let safeEnd;
|
|
1031
|
+
let bundledStrings$1 = null;
|
|
1032
|
+
const hasNonLatin = /[\u0080-\uFFFF]/;
|
|
1003
1033
|
const RECORD_SYMBOL = Symbol('record-id');
|
|
1004
1034
|
class Packr extends Unpackr {
|
|
1005
1035
|
constructor(options) {
|
|
@@ -1061,6 +1091,14 @@ class Packr extends Unpackr {
|
|
|
1061
1091
|
position$1 = (position$1 + 7) & 0x7ffffff8; // Word align to make any future copying of this buffer faster
|
|
1062
1092
|
start = position$1;
|
|
1063
1093
|
referenceMap = packr.structuredClone ? new Map() : null;
|
|
1094
|
+
if (packr.bundleStrings) {
|
|
1095
|
+
bundledStrings$1 = ['', ''];
|
|
1096
|
+
target[position$1++] = 0xd6;
|
|
1097
|
+
target[position$1++] = 0x62; // 'b'
|
|
1098
|
+
bundledStrings$1.position = position$1 - start;
|
|
1099
|
+
position$1 += 4;
|
|
1100
|
+
} else
|
|
1101
|
+
bundledStrings$1 = null;
|
|
1064
1102
|
sharedStructures = packr.structures;
|
|
1065
1103
|
if (sharedStructures) {
|
|
1066
1104
|
if (sharedStructures.uninitialized)
|
|
@@ -1099,6 +1137,13 @@ class Packr extends Unpackr {
|
|
|
1099
1137
|
structures = sharedStructures || [];
|
|
1100
1138
|
try {
|
|
1101
1139
|
pack(value);
|
|
1140
|
+
if (bundledStrings$1) {
|
|
1141
|
+
targetView.setUint32(bundledStrings$1.position + start, position$1 - bundledStrings$1.position - start);
|
|
1142
|
+
let writeStrings = bundledStrings$1;
|
|
1143
|
+
bundledStrings$1 = null;
|
|
1144
|
+
pack(writeStrings[0]);
|
|
1145
|
+
pack(writeStrings[1]);
|
|
1146
|
+
}
|
|
1102
1147
|
packr.offset = position$1; // update the offset so next serialization doesn't write over our buffer, but can continue writing to same buffer sequentially
|
|
1103
1148
|
if (referenceMap && referenceMap.idsToInsert) {
|
|
1104
1149
|
position$1 += referenceMap.idsToInsert.length * 6;
|
|
@@ -1109,7 +1154,7 @@ class Packr extends Unpackr {
|
|
|
1109
1154
|
referenceMap = null;
|
|
1110
1155
|
return serialized
|
|
1111
1156
|
}
|
|
1112
|
-
if (encodeOptions
|
|
1157
|
+
if (encodeOptions & REUSE_BUFFER_MODE) {
|
|
1113
1158
|
target.start = start;
|
|
1114
1159
|
target.end = position$1;
|
|
1115
1160
|
return target
|
|
@@ -1148,6 +1193,8 @@ class Packr extends Unpackr {
|
|
|
1148
1193
|
return returnBuffer
|
|
1149
1194
|
}
|
|
1150
1195
|
}
|
|
1196
|
+
if (encodeOptions & RESET_BUFFER_MODE)
|
|
1197
|
+
position$1 = start;
|
|
1151
1198
|
}
|
|
1152
1199
|
};
|
|
1153
1200
|
const pack = (value) => {
|
|
@@ -1158,6 +1205,13 @@ class Packr extends Unpackr {
|
|
|
1158
1205
|
var length;
|
|
1159
1206
|
if (type === 'string') {
|
|
1160
1207
|
let strLength = value.length;
|
|
1208
|
+
if (bundledStrings$1 && strLength >= 8 && strLength < 0x1000) {
|
|
1209
|
+
let twoByte = hasNonLatin.test(value);
|
|
1210
|
+
bundledStrings$1[twoByte ? 0 : 1] += value;
|
|
1211
|
+
target[position$1++] = 0xc1;
|
|
1212
|
+
pack(twoByte ? -strLength : strLength);
|
|
1213
|
+
return
|
|
1214
|
+
}
|
|
1161
1215
|
let headerSize;
|
|
1162
1216
|
// first we estimate the header size, so we can write to the correct location
|
|
1163
1217
|
if (strLength < 0x20) {
|
|
@@ -1618,8 +1672,10 @@ extensions = [{
|
|
|
1618
1672
|
targetView.setUint32(position, date.getMilliseconds() * 4000000 + ((seconds / 1000 / 0x100000000) >> 0));
|
|
1619
1673
|
targetView.setUint32(position + 4, seconds);
|
|
1620
1674
|
} else if (isNaN(seconds)) {
|
|
1621
|
-
if (this.onInvalidDate)
|
|
1675
|
+
if (this.onInvalidDate) {
|
|
1676
|
+
allocateForWrite(0);
|
|
1622
1677
|
return pack(this.onInvalidDate())
|
|
1678
|
+
}
|
|
1623
1679
|
// Intentionally invalid timestamp
|
|
1624
1680
|
let { target, targetView, position} = allocateForWrite(3);
|
|
1625
1681
|
target[position++] = 0xd4;
|
|
@@ -1810,7 +1866,8 @@ const pack = defaultPackr.pack;
|
|
|
1810
1866
|
const encode = defaultPackr.pack;
|
|
1811
1867
|
const Encoder = Packr;
|
|
1812
1868
|
const { NEVER, ALWAYS, DECIMAL_ROUND, DECIMAL_FIT } = FLOAT32_OPTIONS;
|
|
1813
|
-
const REUSE_BUFFER_MODE =
|
|
1869
|
+
const REUSE_BUFFER_MODE = 512;
|
|
1870
|
+
const RESET_BUFFER_MODE = 1024;
|
|
1814
1871
|
|
|
1815
1872
|
class PackrStream extends stream.Transform {
|
|
1816
1873
|
constructor(options) {
|