msgpackr 1.7.0-alpha2 → 1.7.0-alpha5
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 +128 -102
- package/dist/index.js.map +1 -1
- package/dist/index.min.js +78 -77
- package/dist/index.min.js.map +1 -1
- package/dist/node.cjs +803 -319
- package/dist/node.cjs.map +1 -1
- package/dist/test.js +719 -189
- package/dist/test.js.map +1 -1
- package/index.js +5 -5
- package/iterators.js +86 -86
- package/pack.d.ts +9 -9
- package/pack.js +25 -12
- package/package.json +1 -1
- package/rollup.config.js +49 -49
- package/stream.js +57 -57
- package/struct.js +645 -190
- package/unpack.js +44 -15
- package/dist/str.cjs +0 -100
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
|
@@ -59,16 +59,21 @@
|
|
|
59
59
|
}
|
|
60
60
|
Object.assign(this, options);
|
|
61
61
|
}
|
|
62
|
-
unpack(source,
|
|
62
|
+
unpack(source, options) {
|
|
63
63
|
if (src) {
|
|
64
64
|
// re-entrant execution, save the state and restore it after we do this unpack
|
|
65
65
|
return saveState(() => {
|
|
66
66
|
clearSource();
|
|
67
|
-
return this ? this.unpack(source,
|
|
67
|
+
return this ? this.unpack(source, options) : Unpackr.prototype.unpack.call(defaultOptions, source, options)
|
|
68
68
|
})
|
|
69
69
|
}
|
|
70
|
-
|
|
71
|
-
|
|
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
|
+
}
|
|
72
77
|
srcStringEnd = 0;
|
|
73
78
|
srcString = null;
|
|
74
79
|
bundledStrings = null;
|
|
@@ -89,7 +94,7 @@
|
|
|
89
94
|
currentUnpackr = this;
|
|
90
95
|
if (this.structures) {
|
|
91
96
|
currentStructures = this.structures;
|
|
92
|
-
return checkedRead()
|
|
97
|
+
return checkedRead(options)
|
|
93
98
|
} else if (!currentStructures || currentStructures.length > 0) {
|
|
94
99
|
currentStructures = [];
|
|
95
100
|
}
|
|
@@ -98,7 +103,7 @@
|
|
|
98
103
|
if (!currentStructures || currentStructures.length > 0)
|
|
99
104
|
currentStructures = [];
|
|
100
105
|
}
|
|
101
|
-
return checkedRead()
|
|
106
|
+
return checkedRead(options)
|
|
102
107
|
}
|
|
103
108
|
unpackMultiple(source, forEach) {
|
|
104
109
|
let values, lastPosition = 0;
|
|
@@ -134,6 +139,8 @@
|
|
|
134
139
|
}
|
|
135
140
|
_mergeStructures(loadedStructures, existingStructures) {
|
|
136
141
|
loadedStructures = loadedStructures || [];
|
|
142
|
+
if (Object.isFrozen(loadedStructures))
|
|
143
|
+
loadedStructures = loadedStructures.map(structure => structure.slice(0));
|
|
137
144
|
for (let i = 0, l = loadedStructures.length; i < l; i++) {
|
|
138
145
|
let structure = loadedStructures[i];
|
|
139
146
|
if (structure) {
|
|
@@ -160,7 +167,7 @@
|
|
|
160
167
|
return this.unpack(source, end)
|
|
161
168
|
}
|
|
162
169
|
}
|
|
163
|
-
function checkedRead() {
|
|
170
|
+
function checkedRead(options) {
|
|
164
171
|
try {
|
|
165
172
|
if (!currentUnpackr.trusted && !sequentialMode) {
|
|
166
173
|
let sharedLength = currentStructures.sharedLength || 0;
|
|
@@ -168,9 +175,10 @@
|
|
|
168
175
|
currentStructures.length = sharedLength;
|
|
169
176
|
}
|
|
170
177
|
let result;
|
|
171
|
-
if (currentUnpackr.randomAccessStructure && src[position] < 0x40 && readStruct) {
|
|
172
|
-
|
|
173
|
-
|
|
178
|
+
if (currentUnpackr.randomAccessStructure && src[position] < 0x40 && src[position] >= 0x20 && readStruct) {
|
|
179
|
+
result = readStruct(src, position, srcEnd, currentUnpackr);
|
|
180
|
+
if (!(options && options.lazy) && result)
|
|
181
|
+
result = result.toJSON();
|
|
174
182
|
position = srcEnd;
|
|
175
183
|
} else
|
|
176
184
|
result = read();
|
|
@@ -787,7 +795,15 @@
|
|
|
787
795
|
function readExt(length) {
|
|
788
796
|
let type = src[position++];
|
|
789
797
|
if (currentExtensions[type]) {
|
|
790
|
-
|
|
798
|
+
let end;
|
|
799
|
+
return currentExtensions[type](src.subarray(position, end = (position += length)), (readPosition) => {
|
|
800
|
+
position = readPosition;
|
|
801
|
+
try {
|
|
802
|
+
return read();
|
|
803
|
+
} finally {
|
|
804
|
+
position = end;
|
|
805
|
+
}
|
|
806
|
+
})
|
|
791
807
|
}
|
|
792
808
|
else
|
|
793
809
|
throw new Error('Unknown extension type ' + type)
|
|
@@ -1054,7 +1070,6 @@
|
|
|
1054
1070
|
let hasSharedUpdate;
|
|
1055
1071
|
let structures;
|
|
1056
1072
|
let referenceMap;
|
|
1057
|
-
let lastSharedStructuresLength = 0;
|
|
1058
1073
|
let encodeUtf8 = ByteArray.prototype.utf8Write ? function(string, position) {
|
|
1059
1074
|
return target.utf8Write(string, position, 0xffffffff)
|
|
1060
1075
|
} : (textEncoder && textEncoder.encodeInto) ?
|
|
@@ -1140,7 +1155,7 @@
|
|
|
1140
1155
|
}
|
|
1141
1156
|
transition[RECORD_SYMBOL] = i + 0x40;
|
|
1142
1157
|
}
|
|
1143
|
-
|
|
1158
|
+
this.lastNamedStructuresLength = sharedLength;
|
|
1144
1159
|
}
|
|
1145
1160
|
if (!isSequential) {
|
|
1146
1161
|
structures.nextId = sharedLength + 0x40;
|
|
@@ -1176,7 +1191,7 @@
|
|
|
1176
1191
|
if (structures) {
|
|
1177
1192
|
if (serializationsSinceTransitionRebuild < 10)
|
|
1178
1193
|
serializationsSinceTransitionRebuild++;
|
|
1179
|
-
let sharedLength = structures.sharedLength ||
|
|
1194
|
+
let sharedLength = structures.sharedLength || 0;
|
|
1180
1195
|
if (structures.length > sharedLength)
|
|
1181
1196
|
structures.length = sharedLength;
|
|
1182
1197
|
if (transitionsCount > 10000) {
|
|
@@ -1195,12 +1210,12 @@
|
|
|
1195
1210
|
if (hasSharedUpdate && packr.saveStructures) {
|
|
1196
1211
|
// we can't rely on start/end with REUSE_BUFFER_MODE since they will (probably) change when we save
|
|
1197
1212
|
let returnBuffer = target.subarray(start, position$1);
|
|
1198
|
-
|
|
1213
|
+
let newSharedData = prepareStructures(structures, packr);
|
|
1214
|
+
if (packr.saveStructures(newSharedData, newSharedData.isCompatible) === false) {
|
|
1199
1215
|
// get updated structures and try again if the update failed
|
|
1200
|
-
packr._mergeStructures(packr.getStructures());
|
|
1201
1216
|
return packr.pack(value)
|
|
1202
1217
|
}
|
|
1203
|
-
|
|
1218
|
+
packr.lastNamedStructuresLength = sharedLength;
|
|
1204
1219
|
return returnBuffer
|
|
1205
1220
|
}
|
|
1206
1221
|
}
|
|
@@ -1318,7 +1333,7 @@
|
|
|
1318
1333
|
} else if (type === 'number') {
|
|
1319
1334
|
if (value >>> 0 === value) {// positive integer, 32-bit or less
|
|
1320
1335
|
// positive uint
|
|
1321
|
-
if (value <
|
|
1336
|
+
if (value < 0x20 || (value < 0x80 && this.useRecords === false) || (value < 0x40 && !this.randomAccessStructure)) {
|
|
1322
1337
|
target[position$1++] = value;
|
|
1323
1338
|
} else if (value < 0x100) {
|
|
1324
1339
|
target[position$1++] = 0xcc;
|
|
@@ -1733,6 +1748,8 @@
|
|
|
1733
1748
|
clearSharedData() {
|
|
1734
1749
|
if (this.structures)
|
|
1735
1750
|
this.structures = [];
|
|
1751
|
+
if (this.typedStructs)
|
|
1752
|
+
this.typedStructs = [];
|
|
1736
1753
|
}
|
|
1737
1754
|
}
|
|
1738
1755
|
|
|
@@ -1952,6 +1969,15 @@
|
|
|
1952
1969
|
}
|
|
1953
1970
|
addExtension(extension);
|
|
1954
1971
|
}
|
|
1972
|
+
function prepareStructures(structures, packr) {
|
|
1973
|
+
structures.isCompatible = (existingStructures) => {
|
|
1974
|
+
let compatible = !existingStructures || ((packr.lastNamedStructuresLength || 0) === existingStructures.length);
|
|
1975
|
+
if (!compatible) // we want to merge these existing structures immediately since we already have it and we are in the right transaction
|
|
1976
|
+
packr._mergeStructures(existingStructures);
|
|
1977
|
+
return compatible;
|
|
1978
|
+
};
|
|
1979
|
+
return structures
|
|
1980
|
+
}
|
|
1955
1981
|
|
|
1956
1982
|
let defaultPackr = new Packr({ useRecords: false });
|
|
1957
1983
|
const pack = defaultPackr.pack;
|
|
@@ -1961,92 +1987,92 @@
|
|
|
1961
1987
|
const REUSE_BUFFER_MODE = 512;
|
|
1962
1988
|
const RESET_BUFFER_MODE = 1024;
|
|
1963
1989
|
|
|
1964
|
-
/**
|
|
1965
|
-
* Given an Iterable first argument, returns an Iterable where each value is packed as a Buffer
|
|
1966
|
-
* If the argument is only Async Iterable, the return value will be an Async Iterable.
|
|
1967
|
-
* @param {Iterable|Iterator|AsyncIterable|AsyncIterator} objectIterator - iterable source, like a Readable object stream, an array, Set, or custom object
|
|
1968
|
-
* @param {options} [options] - msgpackr pack options
|
|
1969
|
-
* @returns {IterableIterator|Promise.<AsyncIterableIterator>}
|
|
1970
|
-
*/
|
|
1971
|
-
function packIter (objectIterator, options = {}) {
|
|
1972
|
-
if (!objectIterator || typeof objectIterator !== 'object') {
|
|
1973
|
-
throw new Error('first argument must be an Iterable, Async Iterable, or a Promise for an Async Iterable')
|
|
1974
|
-
} else if (typeof objectIterator[Symbol.iterator] === 'function') {
|
|
1975
|
-
return packIterSync(objectIterator, options)
|
|
1976
|
-
} else if (typeof objectIterator.then === 'function' || typeof objectIterator[Symbol.asyncIterator] === 'function') {
|
|
1977
|
-
return packIterAsync(objectIterator, options)
|
|
1978
|
-
} else {
|
|
1979
|
-
throw new Error('first argument must be an Iterable, Async Iterable, Iterator, Async Iterator, or a Promise')
|
|
1980
|
-
}
|
|
1981
|
-
}
|
|
1982
|
-
|
|
1983
|
-
function * packIterSync (objectIterator, options) {
|
|
1984
|
-
const packr = new Packr(options);
|
|
1985
|
-
for (const value of objectIterator) {
|
|
1986
|
-
yield packr.pack(value);
|
|
1987
|
-
}
|
|
1988
|
-
}
|
|
1989
|
-
|
|
1990
|
-
async function * packIterAsync (objectIterator, options) {
|
|
1991
|
-
const packr = new Packr(options);
|
|
1992
|
-
for await (const value of objectIterator) {
|
|
1993
|
-
yield packr.pack(value);
|
|
1994
|
-
}
|
|
1995
|
-
}
|
|
1996
|
-
|
|
1997
|
-
/**
|
|
1998
|
-
* Given an Iterable/Iterator input which yields buffers, returns an IterableIterator which yields sync decoded objects
|
|
1999
|
-
* Or, given an Async Iterable/Iterator which yields promises resolving in buffers, returns an AsyncIterableIterator.
|
|
2000
|
-
* @param {Iterable|Iterator|AsyncIterable|AsyncIterableIterator} bufferIterator
|
|
2001
|
-
* @param {object} [options] - unpackr options
|
|
2002
|
-
* @returns {IterableIterator|Promise.<AsyncIterableIterator}
|
|
2003
|
-
*/
|
|
2004
|
-
function unpackIter (bufferIterator, options = {}) {
|
|
2005
|
-
if (!bufferIterator || typeof bufferIterator !== 'object') {
|
|
2006
|
-
throw new Error('first argument must be an Iterable, Async Iterable, Iterator, Async Iterator, or a promise')
|
|
2007
|
-
}
|
|
2008
|
-
|
|
2009
|
-
const unpackr = new Unpackr(options);
|
|
2010
|
-
let incomplete;
|
|
2011
|
-
const parser = (chunk) => {
|
|
2012
|
-
let yields;
|
|
2013
|
-
// if there's incomplete data from previous chunk, concatinate and try again
|
|
2014
|
-
if (incomplete) {
|
|
2015
|
-
chunk = Buffer.concat([incomplete, chunk]);
|
|
2016
|
-
incomplete = undefined;
|
|
2017
|
-
}
|
|
2018
|
-
|
|
2019
|
-
try {
|
|
2020
|
-
yields = unpackr.unpackMultiple(chunk);
|
|
2021
|
-
} catch (err) {
|
|
2022
|
-
if (err.incomplete) {
|
|
2023
|
-
incomplete = chunk.slice(err.lastPosition);
|
|
2024
|
-
yields = err.values;
|
|
2025
|
-
} else {
|
|
2026
|
-
throw err
|
|
2027
|
-
}
|
|
2028
|
-
}
|
|
2029
|
-
return yields
|
|
2030
|
-
};
|
|
2031
|
-
|
|
2032
|
-
if (typeof bufferIterator[Symbol.iterator] === 'function') {
|
|
2033
|
-
return (function * iter () {
|
|
2034
|
-
for (const value of bufferIterator) {
|
|
2035
|
-
yield * parser(value);
|
|
2036
|
-
}
|
|
2037
|
-
})()
|
|
2038
|
-
} else if (typeof bufferIterator[Symbol.asyncIterator] === 'function') {
|
|
2039
|
-
return (async function * iter () {
|
|
2040
|
-
for await (const value of bufferIterator) {
|
|
2041
|
-
yield * parser(value);
|
|
2042
|
-
}
|
|
2043
|
-
})()
|
|
2044
|
-
}
|
|
2045
|
-
}
|
|
2046
|
-
const decodeIter = unpackIter;
|
|
1990
|
+
/**
|
|
1991
|
+
* Given an Iterable first argument, returns an Iterable where each value is packed as a Buffer
|
|
1992
|
+
* If the argument is only Async Iterable, the return value will be an Async Iterable.
|
|
1993
|
+
* @param {Iterable|Iterator|AsyncIterable|AsyncIterator} objectIterator - iterable source, like a Readable object stream, an array, Set, or custom object
|
|
1994
|
+
* @param {options} [options] - msgpackr pack options
|
|
1995
|
+
* @returns {IterableIterator|Promise.<AsyncIterableIterator>}
|
|
1996
|
+
*/
|
|
1997
|
+
function packIter (objectIterator, options = {}) {
|
|
1998
|
+
if (!objectIterator || typeof objectIterator !== 'object') {
|
|
1999
|
+
throw new Error('first argument must be an Iterable, Async Iterable, or a Promise for an Async Iterable')
|
|
2000
|
+
} else if (typeof objectIterator[Symbol.iterator] === 'function') {
|
|
2001
|
+
return packIterSync(objectIterator, options)
|
|
2002
|
+
} else if (typeof objectIterator.then === 'function' || typeof objectIterator[Symbol.asyncIterator] === 'function') {
|
|
2003
|
+
return packIterAsync(objectIterator, options)
|
|
2004
|
+
} else {
|
|
2005
|
+
throw new Error('first argument must be an Iterable, Async Iterable, Iterator, Async Iterator, or a Promise')
|
|
2006
|
+
}
|
|
2007
|
+
}
|
|
2008
|
+
|
|
2009
|
+
function * packIterSync (objectIterator, options) {
|
|
2010
|
+
const packr = new Packr(options);
|
|
2011
|
+
for (const value of objectIterator) {
|
|
2012
|
+
yield packr.pack(value);
|
|
2013
|
+
}
|
|
2014
|
+
}
|
|
2015
|
+
|
|
2016
|
+
async function * packIterAsync (objectIterator, options) {
|
|
2017
|
+
const packr = new Packr(options);
|
|
2018
|
+
for await (const value of objectIterator) {
|
|
2019
|
+
yield packr.pack(value);
|
|
2020
|
+
}
|
|
2021
|
+
}
|
|
2022
|
+
|
|
2023
|
+
/**
|
|
2024
|
+
* Given an Iterable/Iterator input which yields buffers, returns an IterableIterator which yields sync decoded objects
|
|
2025
|
+
* Or, given an Async Iterable/Iterator which yields promises resolving in buffers, returns an AsyncIterableIterator.
|
|
2026
|
+
* @param {Iterable|Iterator|AsyncIterable|AsyncIterableIterator} bufferIterator
|
|
2027
|
+
* @param {object} [options] - unpackr options
|
|
2028
|
+
* @returns {IterableIterator|Promise.<AsyncIterableIterator}
|
|
2029
|
+
*/
|
|
2030
|
+
function unpackIter (bufferIterator, options = {}) {
|
|
2031
|
+
if (!bufferIterator || typeof bufferIterator !== 'object') {
|
|
2032
|
+
throw new Error('first argument must be an Iterable, Async Iterable, Iterator, Async Iterator, or a promise')
|
|
2033
|
+
}
|
|
2034
|
+
|
|
2035
|
+
const unpackr = new Unpackr(options);
|
|
2036
|
+
let incomplete;
|
|
2037
|
+
const parser = (chunk) => {
|
|
2038
|
+
let yields;
|
|
2039
|
+
// if there's incomplete data from previous chunk, concatinate and try again
|
|
2040
|
+
if (incomplete) {
|
|
2041
|
+
chunk = Buffer.concat([incomplete, chunk]);
|
|
2042
|
+
incomplete = undefined;
|
|
2043
|
+
}
|
|
2044
|
+
|
|
2045
|
+
try {
|
|
2046
|
+
yields = unpackr.unpackMultiple(chunk);
|
|
2047
|
+
} catch (err) {
|
|
2048
|
+
if (err.incomplete) {
|
|
2049
|
+
incomplete = chunk.slice(err.lastPosition);
|
|
2050
|
+
yields = err.values;
|
|
2051
|
+
} else {
|
|
2052
|
+
throw err
|
|
2053
|
+
}
|
|
2054
|
+
}
|
|
2055
|
+
return yields
|
|
2056
|
+
};
|
|
2057
|
+
|
|
2058
|
+
if (typeof bufferIterator[Symbol.iterator] === 'function') {
|
|
2059
|
+
return (function * iter () {
|
|
2060
|
+
for (const value of bufferIterator) {
|
|
2061
|
+
yield * parser(value);
|
|
2062
|
+
}
|
|
2063
|
+
})()
|
|
2064
|
+
} else if (typeof bufferIterator[Symbol.asyncIterator] === 'function') {
|
|
2065
|
+
return (async function * iter () {
|
|
2066
|
+
for await (const value of bufferIterator) {
|
|
2067
|
+
yield * parser(value);
|
|
2068
|
+
}
|
|
2069
|
+
})()
|
|
2070
|
+
}
|
|
2071
|
+
}
|
|
2072
|
+
const decodeIter = unpackIter;
|
|
2047
2073
|
const encodeIter = packIter;
|
|
2048
2074
|
|
|
2049
|
-
const useRecords = false;
|
|
2075
|
+
const useRecords = false;
|
|
2050
2076
|
const mapsAsObjects = true;
|
|
2051
2077
|
|
|
2052
2078
|
exports.ALWAYS = ALWAYS;
|