msgpackr 1.6.2 → 1.7.0-alpha3
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/LICENSE +21 -21
- package/README.md +335 -335
- package/SECURITY.md +11 -11
- package/benchmark.md +67 -67
- package/dist/index.js +139 -100
- package/dist/index.js.map +1 -0
- package/dist/index.min.js +78 -77
- package/dist/index.min.js.map +1 -0
- package/dist/node.cjs +888 -150
- package/dist/node.cjs.map +1 -0
- package/dist/test.js +2747 -50
- package/dist/test.js.map +1 -0
- package/index.js +5 -5
- package/iterators.js +86 -86
- package/node-index.js +1 -0
- package/pack.d.ts +9 -9
- package/pack.js +37 -10
- package/package.json +83 -83
- package/rollup.config.js +49 -45
- package/stream.js +57 -57
- package/struct.js +711 -0
- package/unpack.js +50 -8
package/SECURITY.md
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
# Security Policy
|
|
2
|
-
|
|
3
|
-
## Supported Versions
|
|
4
|
-
|
|
5
|
-
| Version | Supported |
|
|
6
|
-
| ------- | ------------------ |
|
|
7
|
-
| 1.4.x | :white_check_mark: |
|
|
8
|
-
|
|
9
|
-
## Reporting a Vulnerability
|
|
10
|
-
|
|
11
|
-
Please report security vulnerabilities to kriszyp@gmail.com.
|
|
1
|
+
# Security Policy
|
|
2
|
+
|
|
3
|
+
## Supported Versions
|
|
4
|
+
|
|
5
|
+
| Version | Supported |
|
|
6
|
+
| ------- | ------------------ |
|
|
7
|
+
| 1.4.x | :white_check_mark: |
|
|
8
|
+
|
|
9
|
+
## Reporting a Vulnerability
|
|
10
|
+
|
|
11
|
+
Please report security vulnerabilities to kriszyp@gmail.com.
|
package/benchmark.md
CHANGED
|
@@ -1,67 +1,67 @@
|
|
|
1
|
-
Here are more comprehensive benchmarks. This is comparison with the next fastest JS projects using the benchmark tool from `msgpack-lite` (and 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):
|
|
2
|
-
|
|
3
|
-
operation | op | ms | op/s
|
|
4
|
-
---------------------------------------------------------- | ------: | ----: | -----:
|
|
5
|
-
buf = Buffer(JSON.stringify(obj)); | 82000 | 5004 | 16386
|
|
6
|
-
obj = JSON.parse(buf); | 88600 | 5000 | 17720
|
|
7
|
-
require("msgpackr").pack(obj); | 161500 | 5002 | 32287
|
|
8
|
-
require("msgpackr").unpack(buf); | 94600 | 5004 | 18904
|
|
9
|
-
msgpackr w/ shared structures: packr.pack(obj); | 178400 | 5002 | 35665
|
|
10
|
-
msgpackr w/ shared structures: packr.unpack(buf); | 376700 | 5000 | 75340
|
|
11
|
-
buf = require("msgpack-lite").encode(obj); | 30100 | 5012 | 6005
|
|
12
|
-
obj = require("msgpack-lite").decode(buf); | 16200 | 5001 | 3239
|
|
13
|
-
buf = require("notepack").encode(obj); | 62600 | 5005 | 12507
|
|
14
|
-
obj = require("notepack").decode(buf); | 32400 | 5007 | 6470
|
|
15
|
-
require("what-the-pack")... encoder.encode(obj); | 63500 | 5002 | 12694
|
|
16
|
-
require("what-the-pack")... encoder.decode(buf); | 32000 | 5001 | 6398
|
|
17
|
-
require("avsc")...make schema/type...type.toBuffer(obj); | 84600 | 5003 | 16909
|
|
18
|
-
require("avsc")...make schema/type...type.toBuffer(obj); | 99300 | 5001 | 19856
|
|
19
|
-
|
|
20
|
-
(`avsc` is schema-based and more comparable in style to msgpackr with shared structures).
|
|
21
|
-
|
|
22
|
-
Here is a benchmark of streaming data (again borrowed from `msgpack-lite`'s benchmarking), where msgpackr is able to take advantage of the structured record extension and really pull away from other tools:
|
|
23
|
-
|
|
24
|
-
operation (1000000 x 2) | op | ms | op/s
|
|
25
|
-
------------------------------------------------ | ------: | ----: | -----:
|
|
26
|
-
new PackrStream().write(obj); | 1000000 | 372 | 2688172
|
|
27
|
-
new UnpackrStream().write(buf); | 1000000 | 247 | 4048582
|
|
28
|
-
stream.write(msgpack.encode(obj)); | 1000000 | 2898 | 345065
|
|
29
|
-
stream.write(msgpack.decode(buf)); | 1000000 | 1969 | 507872
|
|
30
|
-
stream.write(notepack.encode(obj)); | 1000000 | 901 | 1109877
|
|
31
|
-
stream.write(notepack.decode(buf)); | 1000000 | 1012 | 988142
|
|
32
|
-
msgpack.Encoder().on("data",ondata).encode(obj); | 1000000 | 1763 | 567214
|
|
33
|
-
msgpack.createDecodeStream().write(buf); | 1000000 | 2222 | 450045
|
|
34
|
-
msgpack.createEncodeStream().write(obj); | 1000000 | 1577 | 634115
|
|
35
|
-
msgpack.Decoder().on("data",ondata).decode(buf); | 1000000 | 2246 | 445235
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
These are the benchmarks from notepack package. The larger test data for these benchmarks is very heavily weighted with large binary/buffer data and objects with extreme numbers of keys (much more than I typically see with real-world data, but YMMV):
|
|
40
|
-
|
|
41
|
-
node ./benchmarks/encode
|
|
42
|
-
|
|
43
|
-
library | tiny | small | medium | large
|
|
44
|
-
---------------- | ----------------: | --------------: | ---------------| -------:
|
|
45
|
-
notepack | 2,171,621 ops/sec | 546,905 ops/sec | 29,578 ops/sec | 265 ops/sec
|
|
46
|
-
msgpack-js | 967,682 ops/sec | 184,455 ops/sec | 20,556 ops/sec | 259 ops/sec
|
|
47
|
-
msgpackr | 2,392,826 ops/sec | 556,915 ops/sec | 70,573 ops/sec | 313 ops/sec
|
|
48
|
-
msgpack-lite | 553,143 ops/sec | 132,318 ops/sec | 11,816 ops/sec | 186 ops/sec
|
|
49
|
-
@msgpack/msgpack | 2,157,655 ops/sec | 573,236 ops/sec | 25,864 ops/sec | 90.26 ops/sec
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
node ./benchmarks/decode
|
|
53
|
-
|
|
54
|
-
library | tiny | small | medium | large
|
|
55
|
-
---------------- | ----------------: | --------------: | --------------- | -------:
|
|
56
|
-
notepack | 2,220,904 ops/sec | 560,630 ops/sec | 28,177 ops/sec | 275 ops/sec
|
|
57
|
-
msgpack-js | 965,719 ops/sec | 222,047 ops/sec | 21,431 ops/sec | 257 ops/sec
|
|
58
|
-
msgpackr | 2,320,046 ops/sec | 589,167 ops/sec | 70,299 ops/sec | 329 ops/sec
|
|
59
|
-
msgpackr records | 3,750,547 ops/sec | 912,419 ops/sec | 136,853 ops/sec | 733 ops/sec
|
|
60
|
-
msgpack-lite | 569,222 ops/sec | 129,008 ops/sec | 12,424 ops/sec | 180 ops/sec
|
|
61
|
-
@msgpack/msgpack | 2,089,697 ops/sec | 557,507 ops/sec | 20,256 ops/sec | 85.03 ops/sec
|
|
62
|
-
|
|
63
|
-
This was run by adding the msgpackr to the benchmarks for notepack.
|
|
64
|
-
|
|
65
|
-
All benchmarks were performed on Node 14.8.0 (Windows i7-4770 3.4Ghz). They can be run with:
|
|
66
|
-
npm install --no-save msgpack msgpack-js @msgpack/msgpack msgpack-lite notepack avsc
|
|
67
|
-
node tests/benchmark
|
|
1
|
+
Here are more comprehensive benchmarks. This is comparison with the next fastest JS projects using the benchmark tool from `msgpack-lite` (and 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):
|
|
2
|
+
|
|
3
|
+
operation | op | ms | op/s
|
|
4
|
+
---------------------------------------------------------- | ------: | ----: | -----:
|
|
5
|
+
buf = Buffer(JSON.stringify(obj)); | 82000 | 5004 | 16386
|
|
6
|
+
obj = JSON.parse(buf); | 88600 | 5000 | 17720
|
|
7
|
+
require("msgpackr").pack(obj); | 161500 | 5002 | 32287
|
|
8
|
+
require("msgpackr").unpack(buf); | 94600 | 5004 | 18904
|
|
9
|
+
msgpackr w/ shared structures: packr.pack(obj); | 178400 | 5002 | 35665
|
|
10
|
+
msgpackr w/ shared structures: packr.unpack(buf); | 376700 | 5000 | 75340
|
|
11
|
+
buf = require("msgpack-lite").encode(obj); | 30100 | 5012 | 6005
|
|
12
|
+
obj = require("msgpack-lite").decode(buf); | 16200 | 5001 | 3239
|
|
13
|
+
buf = require("notepack").encode(obj); | 62600 | 5005 | 12507
|
|
14
|
+
obj = require("notepack").decode(buf); | 32400 | 5007 | 6470
|
|
15
|
+
require("what-the-pack")... encoder.encode(obj); | 63500 | 5002 | 12694
|
|
16
|
+
require("what-the-pack")... encoder.decode(buf); | 32000 | 5001 | 6398
|
|
17
|
+
require("avsc")...make schema/type...type.toBuffer(obj); | 84600 | 5003 | 16909
|
|
18
|
+
require("avsc")...make schema/type...type.toBuffer(obj); | 99300 | 5001 | 19856
|
|
19
|
+
|
|
20
|
+
(`avsc` is schema-based and more comparable in style to msgpackr with shared structures).
|
|
21
|
+
|
|
22
|
+
Here is a benchmark of streaming data (again borrowed from `msgpack-lite`'s benchmarking), where msgpackr is able to take advantage of the structured record extension and really pull away from other tools:
|
|
23
|
+
|
|
24
|
+
operation (1000000 x 2) | op | ms | op/s
|
|
25
|
+
------------------------------------------------ | ------: | ----: | -----:
|
|
26
|
+
new PackrStream().write(obj); | 1000000 | 372 | 2688172
|
|
27
|
+
new UnpackrStream().write(buf); | 1000000 | 247 | 4048582
|
|
28
|
+
stream.write(msgpack.encode(obj)); | 1000000 | 2898 | 345065
|
|
29
|
+
stream.write(msgpack.decode(buf)); | 1000000 | 1969 | 507872
|
|
30
|
+
stream.write(notepack.encode(obj)); | 1000000 | 901 | 1109877
|
|
31
|
+
stream.write(notepack.decode(buf)); | 1000000 | 1012 | 988142
|
|
32
|
+
msgpack.Encoder().on("data",ondata).encode(obj); | 1000000 | 1763 | 567214
|
|
33
|
+
msgpack.createDecodeStream().write(buf); | 1000000 | 2222 | 450045
|
|
34
|
+
msgpack.createEncodeStream().write(obj); | 1000000 | 1577 | 634115
|
|
35
|
+
msgpack.Decoder().on("data",ondata).decode(buf); | 1000000 | 2246 | 445235
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
These are the benchmarks from notepack package. The larger test data for these benchmarks is very heavily weighted with large binary/buffer data and objects with extreme numbers of keys (much more than I typically see with real-world data, but YMMV):
|
|
40
|
+
|
|
41
|
+
node ./benchmarks/encode
|
|
42
|
+
|
|
43
|
+
library | tiny | small | medium | large
|
|
44
|
+
---------------- | ----------------: | --------------: | ---------------| -------:
|
|
45
|
+
notepack | 2,171,621 ops/sec | 546,905 ops/sec | 29,578 ops/sec | 265 ops/sec
|
|
46
|
+
msgpack-js | 967,682 ops/sec | 184,455 ops/sec | 20,556 ops/sec | 259 ops/sec
|
|
47
|
+
msgpackr | 2,392,826 ops/sec | 556,915 ops/sec | 70,573 ops/sec | 313 ops/sec
|
|
48
|
+
msgpack-lite | 553,143 ops/sec | 132,318 ops/sec | 11,816 ops/sec | 186 ops/sec
|
|
49
|
+
@msgpack/msgpack | 2,157,655 ops/sec | 573,236 ops/sec | 25,864 ops/sec | 90.26 ops/sec
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
node ./benchmarks/decode
|
|
53
|
+
|
|
54
|
+
library | tiny | small | medium | large
|
|
55
|
+
---------------- | ----------------: | --------------: | --------------- | -------:
|
|
56
|
+
notepack | 2,220,904 ops/sec | 560,630 ops/sec | 28,177 ops/sec | 275 ops/sec
|
|
57
|
+
msgpack-js | 965,719 ops/sec | 222,047 ops/sec | 21,431 ops/sec | 257 ops/sec
|
|
58
|
+
msgpackr | 2,320,046 ops/sec | 589,167 ops/sec | 70,299 ops/sec | 329 ops/sec
|
|
59
|
+
msgpackr records | 3,750,547 ops/sec | 912,419 ops/sec | 136,853 ops/sec | 733 ops/sec
|
|
60
|
+
msgpack-lite | 569,222 ops/sec | 129,008 ops/sec | 12,424 ops/sec | 180 ops/sec
|
|
61
|
+
@msgpack/msgpack | 2,089,697 ops/sec | 557,507 ops/sec | 20,256 ops/sec | 85.03 ops/sec
|
|
62
|
+
|
|
63
|
+
This was run by adding the msgpackr to the benchmarks for notepack.
|
|
64
|
+
|
|
65
|
+
All benchmarks were performed on Node 14.8.0 (Windows i7-4770 3.4Ghz). They can be run with:
|
|
66
|
+
npm install --no-save msgpack msgpack-js @msgpack/msgpack msgpack-lite notepack avsc
|
|
67
|
+
node tests/benchmark
|
package/dist/index.js
CHANGED
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
C1.name = 'MessagePack 0xC1';
|
|
30
30
|
var sequentialMode = false;
|
|
31
31
|
var inlineObjectReadThreshold = 2;
|
|
32
|
+
var readStruct;
|
|
32
33
|
try {
|
|
33
34
|
new Function('');
|
|
34
35
|
} catch(error) {
|
|
@@ -58,16 +59,21 @@
|
|
|
58
59
|
}
|
|
59
60
|
Object.assign(this, options);
|
|
60
61
|
}
|
|
61
|
-
unpack(source,
|
|
62
|
+
unpack(source, options) {
|
|
62
63
|
if (src) {
|
|
63
64
|
// re-entrant execution, save the state and restore it after we do this unpack
|
|
64
65
|
return saveState(() => {
|
|
65
66
|
clearSource();
|
|
66
|
-
return this ? this.unpack(source,
|
|
67
|
+
return this ? this.unpack(source, options) : Unpackr.prototype.unpack.call(defaultOptions, source, options)
|
|
67
68
|
})
|
|
68
69
|
}
|
|
69
|
-
|
|
70
|
-
|
|
70
|
+
if (typeof options === 'object') {
|
|
71
|
+
srcEnd = options.end || source.length;
|
|
72
|
+
position = options.start || 0;
|
|
73
|
+
} else {
|
|
74
|
+
position = 0;
|
|
75
|
+
srcEnd = options > -1 ? options : source.length;
|
|
76
|
+
}
|
|
71
77
|
srcStringEnd = 0;
|
|
72
78
|
srcString = null;
|
|
73
79
|
bundledStrings = null;
|
|
@@ -166,7 +172,12 @@
|
|
|
166
172
|
if (sharedLength < currentStructures.length)
|
|
167
173
|
currentStructures.length = sharedLength;
|
|
168
174
|
}
|
|
169
|
-
let result
|
|
175
|
+
let result;
|
|
176
|
+
if (currentUnpackr.randomAccessStructure && src[position] < 0x40 && src[position] >= 0x20 && readStruct) {
|
|
177
|
+
result = readStruct(src, position, srcEnd, currentUnpackr);
|
|
178
|
+
position = srcEnd;
|
|
179
|
+
} else
|
|
180
|
+
result = read();
|
|
170
181
|
if (bundledStrings) // bundled strings to skip past
|
|
171
182
|
position = bundledStrings.postBundlePosition;
|
|
172
183
|
|
|
@@ -243,6 +254,8 @@
|
|
|
243
254
|
for (let i = 0; i < token; i++) {
|
|
244
255
|
array[i] = read();
|
|
245
256
|
}
|
|
257
|
+
if (currentUnpackr.freezeData)
|
|
258
|
+
return Object.freeze(array)
|
|
246
259
|
return array
|
|
247
260
|
}
|
|
248
261
|
} else if (token < 0xc0) {
|
|
@@ -453,7 +466,8 @@
|
|
|
453
466
|
function readObject() {
|
|
454
467
|
// This initial function is quick to instantiate, but runs slower. After several iterations pay the cost to build the faster function
|
|
455
468
|
if (readObject.count++ > inlineObjectReadThreshold) {
|
|
456
|
-
let readObject = structure.read = (new Function('r', 'return function(){return
|
|
469
|
+
let readObject = structure.read = (new Function('r', 'return function(){return ' + (currentUnpackr.freezeData ? 'Object.freeze' : '') +
|
|
470
|
+
'({' + structure.map(key => validName.test(key) ? key + ':r()' : ('[' + JSON.stringify(key) + ']:r()')).join(',') + '})}'))(read);
|
|
457
471
|
if (structure.highByte === 0)
|
|
458
472
|
structure.read = createSecondByteReader(firstId, structure.read);
|
|
459
473
|
return readObject() // second byte is already read, if there is one so immediately read object
|
|
@@ -463,6 +477,8 @@
|
|
|
463
477
|
let key = structure[i];
|
|
464
478
|
object[key] = read();
|
|
465
479
|
}
|
|
480
|
+
if (currentUnpackr.freezeData)
|
|
481
|
+
return Object.freeze(object);
|
|
466
482
|
return object
|
|
467
483
|
}
|
|
468
484
|
readObject.count = 0;
|
|
@@ -561,6 +577,8 @@
|
|
|
561
577
|
for (let i = 0; i < length; i++) {
|
|
562
578
|
array[i] = read();
|
|
563
579
|
}
|
|
580
|
+
if (currentUnpackr.freezeData)
|
|
581
|
+
return Object.freeze(array)
|
|
564
582
|
return array
|
|
565
583
|
}
|
|
566
584
|
|
|
@@ -773,7 +791,15 @@
|
|
|
773
791
|
function readExt(length) {
|
|
774
792
|
let type = src[position++];
|
|
775
793
|
if (currentExtensions[type]) {
|
|
776
|
-
|
|
794
|
+
let end;
|
|
795
|
+
return currentExtensions[type](src.subarray(position, end = (position += length)), (readPosition) => {
|
|
796
|
+
position = readPosition;
|
|
797
|
+
try {
|
|
798
|
+
return read();
|
|
799
|
+
} finally {
|
|
800
|
+
position = end;
|
|
801
|
+
}
|
|
802
|
+
})
|
|
777
803
|
}
|
|
778
804
|
else
|
|
779
805
|
throw new Error('Unknown extension type ' + type)
|
|
@@ -1028,6 +1054,7 @@
|
|
|
1028
1054
|
let position$1 = 0;
|
|
1029
1055
|
let safeEnd;
|
|
1030
1056
|
let bundledStrings$1 = null;
|
|
1057
|
+
let writeStructSlots;
|
|
1031
1058
|
const MAX_BUNDLE_SIZE = 0xf000;
|
|
1032
1059
|
const hasNonLatin = /[\u0080-\uFFFF]/;
|
|
1033
1060
|
const RECORD_SYMBOL = Symbol('record-id');
|
|
@@ -1039,7 +1066,6 @@
|
|
|
1039
1066
|
let hasSharedUpdate;
|
|
1040
1067
|
let structures;
|
|
1041
1068
|
let referenceMap;
|
|
1042
|
-
let lastSharedStructuresLength = 0;
|
|
1043
1069
|
let encodeUtf8 = ByteArray.prototype.utf8Write ? function(string, position) {
|
|
1044
1070
|
return target.utf8Write(string, position, 0xffffffff)
|
|
1045
1071
|
} : (textEncoder && textEncoder.encodeInto) ?
|
|
@@ -1079,14 +1105,14 @@
|
|
|
1079
1105
|
this.pack = this.encode = function(value, encodeOptions) {
|
|
1080
1106
|
if (!target) {
|
|
1081
1107
|
target = new ByteArrayAllocate(8192);
|
|
1082
|
-
targetView = new DataView(target.buffer, 0, 8192);
|
|
1108
|
+
targetView = target.dataView = new DataView(target.buffer, 0, 8192);
|
|
1083
1109
|
position$1 = 0;
|
|
1084
1110
|
}
|
|
1085
1111
|
safeEnd = target.length - 10;
|
|
1086
1112
|
if (safeEnd - position$1 < 0x800) {
|
|
1087
1113
|
// don't start too close to the end,
|
|
1088
1114
|
target = new ByteArrayAllocate(target.length);
|
|
1089
|
-
targetView = new DataView(target.buffer, 0, target.length);
|
|
1115
|
+
targetView = target.dataView = new DataView(target.buffer, 0, target.length);
|
|
1090
1116
|
safeEnd = target.length - 10;
|
|
1091
1117
|
position$1 = 0;
|
|
1092
1118
|
} else
|
|
@@ -1125,7 +1151,7 @@
|
|
|
1125
1151
|
}
|
|
1126
1152
|
transition[RECORD_SYMBOL] = i + 0x40;
|
|
1127
1153
|
}
|
|
1128
|
-
|
|
1154
|
+
this.lastNamedStructuresLength = sharedLength;
|
|
1129
1155
|
}
|
|
1130
1156
|
if (!isSequential) {
|
|
1131
1157
|
structures.nextId = sharedLength + 0x40;
|
|
@@ -1134,7 +1160,10 @@
|
|
|
1134
1160
|
if (hasSharedUpdate)
|
|
1135
1161
|
hasSharedUpdate = false;
|
|
1136
1162
|
try {
|
|
1137
|
-
|
|
1163
|
+
if (packr.randomAccessStructure && value.constructor && value.constructor === Object)
|
|
1164
|
+
writeStruct(value);
|
|
1165
|
+
else
|
|
1166
|
+
pack(value);
|
|
1138
1167
|
if (bundledStrings$1) {
|
|
1139
1168
|
writeBundles(start, pack);
|
|
1140
1169
|
}
|
|
@@ -1177,12 +1206,13 @@
|
|
|
1177
1206
|
if (hasSharedUpdate && packr.saveStructures) {
|
|
1178
1207
|
// we can't rely on start/end with REUSE_BUFFER_MODE since they will (probably) change when we save
|
|
1179
1208
|
let returnBuffer = target.subarray(start, position$1);
|
|
1180
|
-
|
|
1209
|
+
let newSharedData = structures;
|
|
1210
|
+
if (packr.saveStructures(newSharedData, newSharedData.isCompatible || packr.lastNamedStructuresLength || 0) === false) {
|
|
1181
1211
|
// get updated structures and try again if the update failed
|
|
1182
1212
|
packr._mergeStructures(packr.getStructures());
|
|
1183
1213
|
return packr.pack(value)
|
|
1184
1214
|
}
|
|
1185
|
-
|
|
1215
|
+
packr.lastNamedStructuresLength = sharedLength;
|
|
1186
1216
|
return returnBuffer
|
|
1187
1217
|
}
|
|
1188
1218
|
}
|
|
@@ -1300,7 +1330,7 @@
|
|
|
1300
1330
|
} else if (type === 'number') {
|
|
1301
1331
|
if (value >>> 0 === value) {// positive integer, 32-bit or less
|
|
1302
1332
|
// positive uint
|
|
1303
|
-
if (value <
|
|
1333
|
+
if (value < 0x20 || (value < 0x80 && this.useRecords === false) || (value < 0x40 && !this.randomAccessStructure)) {
|
|
1304
1334
|
target[position$1++] = value;
|
|
1305
1335
|
} else if (value < 0x100) {
|
|
1306
1336
|
target[position$1++] = 0xcc;
|
|
@@ -1608,7 +1638,7 @@
|
|
|
1608
1638
|
} else // faster handling for smaller buffers
|
|
1609
1639
|
newSize = ((Math.max((end - start) << 2, target.length - 1) >> 12) + 1) << 12;
|
|
1610
1640
|
let newBuffer = new ByteArrayAllocate(newSize);
|
|
1611
|
-
targetView = new DataView(newBuffer.buffer, 0, newSize);
|
|
1641
|
+
targetView = newBuffer.dataView = new DataView(newBuffer.buffer, 0, newSize);
|
|
1612
1642
|
end = Math.min(end, target.length);
|
|
1613
1643
|
if (target.copy)
|
|
1614
1644
|
target.copy(newBuffer, 0, start, end);
|
|
@@ -1699,6 +1729,12 @@
|
|
|
1699
1729
|
target[insertionOffset + start] = keysTarget[0];
|
|
1700
1730
|
}
|
|
1701
1731
|
};
|
|
1732
|
+
const writeStruct = (object, safePrototype) => {
|
|
1733
|
+
let newPosition = writeStructSlots();
|
|
1734
|
+
if (newPosition === 0) // bail and go to a msgpack object
|
|
1735
|
+
return writeObject(object, true);
|
|
1736
|
+
position$1 = newPosition;
|
|
1737
|
+
};
|
|
1702
1738
|
}
|
|
1703
1739
|
useBuffer(buffer) {
|
|
1704
1740
|
// this means we are finished using our own buffer and we can write over it safely
|
|
@@ -1709,6 +1745,8 @@
|
|
|
1709
1745
|
clearSharedData() {
|
|
1710
1746
|
if (this.structures)
|
|
1711
1747
|
this.structures = [];
|
|
1748
|
+
if (this.typedStructs)
|
|
1749
|
+
this.typedStructs = [];
|
|
1712
1750
|
}
|
|
1713
1751
|
}
|
|
1714
1752
|
|
|
@@ -1937,92 +1975,92 @@
|
|
|
1937
1975
|
const REUSE_BUFFER_MODE = 512;
|
|
1938
1976
|
const RESET_BUFFER_MODE = 1024;
|
|
1939
1977
|
|
|
1940
|
-
/**
|
|
1941
|
-
* Given an Iterable first argument, returns an Iterable where each value is packed as a Buffer
|
|
1942
|
-
* If the argument is only Async Iterable, the return value will be an Async Iterable.
|
|
1943
|
-
* @param {Iterable|Iterator|AsyncIterable|AsyncIterator} objectIterator - iterable source, like a Readable object stream, an array, Set, or custom object
|
|
1944
|
-
* @param {options} [options] - msgpackr pack options
|
|
1945
|
-
* @returns {IterableIterator|Promise.<AsyncIterableIterator>}
|
|
1946
|
-
*/
|
|
1947
|
-
function packIter (objectIterator, options = {}) {
|
|
1948
|
-
if (!objectIterator || typeof objectIterator !== 'object') {
|
|
1949
|
-
throw new Error('first argument must be an Iterable, Async Iterable, or a Promise for an Async Iterable')
|
|
1950
|
-
} else if (typeof objectIterator[Symbol.iterator] === 'function') {
|
|
1951
|
-
return packIterSync(objectIterator, options)
|
|
1952
|
-
} else if (typeof objectIterator.then === 'function' || typeof objectIterator[Symbol.asyncIterator] === 'function') {
|
|
1953
|
-
return packIterAsync(objectIterator, options)
|
|
1954
|
-
} else {
|
|
1955
|
-
throw new Error('first argument must be an Iterable, Async Iterable, Iterator, Async Iterator, or a Promise')
|
|
1956
|
-
}
|
|
1957
|
-
}
|
|
1958
|
-
|
|
1959
|
-
function * packIterSync (objectIterator, options) {
|
|
1960
|
-
const packr = new Packr(options);
|
|
1961
|
-
for (const value of objectIterator) {
|
|
1962
|
-
yield packr.pack(value);
|
|
1963
|
-
}
|
|
1964
|
-
}
|
|
1965
|
-
|
|
1966
|
-
async function * packIterAsync (objectIterator, options) {
|
|
1967
|
-
const packr = new Packr(options);
|
|
1968
|
-
for await (const value of objectIterator) {
|
|
1969
|
-
yield packr.pack(value);
|
|
1970
|
-
}
|
|
1971
|
-
}
|
|
1972
|
-
|
|
1973
|
-
/**
|
|
1974
|
-
* Given an Iterable/Iterator input which yields buffers, returns an IterableIterator which yields sync decoded objects
|
|
1975
|
-
* Or, given an Async Iterable/Iterator which yields promises resolving in buffers, returns an AsyncIterableIterator.
|
|
1976
|
-
* @param {Iterable|Iterator|AsyncIterable|AsyncIterableIterator} bufferIterator
|
|
1977
|
-
* @param {object} [options] - unpackr options
|
|
1978
|
-
* @returns {IterableIterator|Promise.<AsyncIterableIterator}
|
|
1979
|
-
*/
|
|
1980
|
-
function unpackIter (bufferIterator, options = {}) {
|
|
1981
|
-
if (!bufferIterator || typeof bufferIterator !== 'object') {
|
|
1982
|
-
throw new Error('first argument must be an Iterable, Async Iterable, Iterator, Async Iterator, or a promise')
|
|
1983
|
-
}
|
|
1984
|
-
|
|
1985
|
-
const unpackr = new Unpackr(options);
|
|
1986
|
-
let incomplete;
|
|
1987
|
-
const parser = (chunk) => {
|
|
1988
|
-
let yields;
|
|
1989
|
-
// if there's incomplete data from previous chunk, concatinate and try again
|
|
1990
|
-
if (incomplete) {
|
|
1991
|
-
chunk = Buffer.concat([incomplete, chunk]);
|
|
1992
|
-
incomplete = undefined;
|
|
1993
|
-
}
|
|
1994
|
-
|
|
1995
|
-
try {
|
|
1996
|
-
yields = unpackr.unpackMultiple(chunk);
|
|
1997
|
-
} catch (err) {
|
|
1998
|
-
if (err.incomplete) {
|
|
1999
|
-
incomplete = chunk.slice(err.lastPosition);
|
|
2000
|
-
yields = err.values;
|
|
2001
|
-
} else {
|
|
2002
|
-
throw err
|
|
2003
|
-
}
|
|
2004
|
-
}
|
|
2005
|
-
return yields
|
|
2006
|
-
};
|
|
2007
|
-
|
|
2008
|
-
if (typeof bufferIterator[Symbol.iterator] === 'function') {
|
|
2009
|
-
return (function * iter () {
|
|
2010
|
-
for (const value of bufferIterator) {
|
|
2011
|
-
yield * parser(value);
|
|
2012
|
-
}
|
|
2013
|
-
})()
|
|
2014
|
-
} else if (typeof bufferIterator[Symbol.asyncIterator] === 'function') {
|
|
2015
|
-
return (async function * iter () {
|
|
2016
|
-
for await (const value of bufferIterator) {
|
|
2017
|
-
yield * parser(value);
|
|
2018
|
-
}
|
|
2019
|
-
})()
|
|
2020
|
-
}
|
|
2021
|
-
}
|
|
2022
|
-
const decodeIter = unpackIter;
|
|
1978
|
+
/**
|
|
1979
|
+
* Given an Iterable first argument, returns an Iterable where each value is packed as a Buffer
|
|
1980
|
+
* If the argument is only Async Iterable, the return value will be an Async Iterable.
|
|
1981
|
+
* @param {Iterable|Iterator|AsyncIterable|AsyncIterator} objectIterator - iterable source, like a Readable object stream, an array, Set, or custom object
|
|
1982
|
+
* @param {options} [options] - msgpackr pack options
|
|
1983
|
+
* @returns {IterableIterator|Promise.<AsyncIterableIterator>}
|
|
1984
|
+
*/
|
|
1985
|
+
function packIter (objectIterator, options = {}) {
|
|
1986
|
+
if (!objectIterator || typeof objectIterator !== 'object') {
|
|
1987
|
+
throw new Error('first argument must be an Iterable, Async Iterable, or a Promise for an Async Iterable')
|
|
1988
|
+
} else if (typeof objectIterator[Symbol.iterator] === 'function') {
|
|
1989
|
+
return packIterSync(objectIterator, options)
|
|
1990
|
+
} else if (typeof objectIterator.then === 'function' || typeof objectIterator[Symbol.asyncIterator] === 'function') {
|
|
1991
|
+
return packIterAsync(objectIterator, options)
|
|
1992
|
+
} else {
|
|
1993
|
+
throw new Error('first argument must be an Iterable, Async Iterable, Iterator, Async Iterator, or a Promise')
|
|
1994
|
+
}
|
|
1995
|
+
}
|
|
1996
|
+
|
|
1997
|
+
function * packIterSync (objectIterator, options) {
|
|
1998
|
+
const packr = new Packr(options);
|
|
1999
|
+
for (const value of objectIterator) {
|
|
2000
|
+
yield packr.pack(value);
|
|
2001
|
+
}
|
|
2002
|
+
}
|
|
2003
|
+
|
|
2004
|
+
async function * packIterAsync (objectIterator, options) {
|
|
2005
|
+
const packr = new Packr(options);
|
|
2006
|
+
for await (const value of objectIterator) {
|
|
2007
|
+
yield packr.pack(value);
|
|
2008
|
+
}
|
|
2009
|
+
}
|
|
2010
|
+
|
|
2011
|
+
/**
|
|
2012
|
+
* Given an Iterable/Iterator input which yields buffers, returns an IterableIterator which yields sync decoded objects
|
|
2013
|
+
* Or, given an Async Iterable/Iterator which yields promises resolving in buffers, returns an AsyncIterableIterator.
|
|
2014
|
+
* @param {Iterable|Iterator|AsyncIterable|AsyncIterableIterator} bufferIterator
|
|
2015
|
+
* @param {object} [options] - unpackr options
|
|
2016
|
+
* @returns {IterableIterator|Promise.<AsyncIterableIterator}
|
|
2017
|
+
*/
|
|
2018
|
+
function unpackIter (bufferIterator, options = {}) {
|
|
2019
|
+
if (!bufferIterator || typeof bufferIterator !== 'object') {
|
|
2020
|
+
throw new Error('first argument must be an Iterable, Async Iterable, Iterator, Async Iterator, or a promise')
|
|
2021
|
+
}
|
|
2022
|
+
|
|
2023
|
+
const unpackr = new Unpackr(options);
|
|
2024
|
+
let incomplete;
|
|
2025
|
+
const parser = (chunk) => {
|
|
2026
|
+
let yields;
|
|
2027
|
+
// if there's incomplete data from previous chunk, concatinate and try again
|
|
2028
|
+
if (incomplete) {
|
|
2029
|
+
chunk = Buffer.concat([incomplete, chunk]);
|
|
2030
|
+
incomplete = undefined;
|
|
2031
|
+
}
|
|
2032
|
+
|
|
2033
|
+
try {
|
|
2034
|
+
yields = unpackr.unpackMultiple(chunk);
|
|
2035
|
+
} catch (err) {
|
|
2036
|
+
if (err.incomplete) {
|
|
2037
|
+
incomplete = chunk.slice(err.lastPosition);
|
|
2038
|
+
yields = err.values;
|
|
2039
|
+
} else {
|
|
2040
|
+
throw err
|
|
2041
|
+
}
|
|
2042
|
+
}
|
|
2043
|
+
return yields
|
|
2044
|
+
};
|
|
2045
|
+
|
|
2046
|
+
if (typeof bufferIterator[Symbol.iterator] === 'function') {
|
|
2047
|
+
return (function * iter () {
|
|
2048
|
+
for (const value of bufferIterator) {
|
|
2049
|
+
yield * parser(value);
|
|
2050
|
+
}
|
|
2051
|
+
})()
|
|
2052
|
+
} else if (typeof bufferIterator[Symbol.asyncIterator] === 'function') {
|
|
2053
|
+
return (async function * iter () {
|
|
2054
|
+
for await (const value of bufferIterator) {
|
|
2055
|
+
yield * parser(value);
|
|
2056
|
+
}
|
|
2057
|
+
})()
|
|
2058
|
+
}
|
|
2059
|
+
}
|
|
2060
|
+
const decodeIter = unpackIter;
|
|
2023
2061
|
const encodeIter = packIter;
|
|
2024
2062
|
|
|
2025
|
-
const useRecords = false;
|
|
2063
|
+
const useRecords = false;
|
|
2026
2064
|
const mapsAsObjects = true;
|
|
2027
2065
|
|
|
2028
2066
|
exports.ALWAYS = ALWAYS;
|
|
@@ -2053,3 +2091,4 @@
|
|
|
2053
2091
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
2054
2092
|
|
|
2055
2093
|
})));
|
|
2094
|
+
//# sourceMappingURL=index.js.map
|