msgpackr 1.11.2 → 1.11.3
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 +1 -0
- package/dist/index-no-eval.cjs +116 -45
- package/dist/index-no-eval.cjs.map +1 -1
- package/dist/index-no-eval.min.js +1 -1
- package/dist/index-no-eval.min.js.map +1 -1
- package/dist/index.js +116 -45
- package/dist/index.js.map +1 -1
- package/dist/index.min.js +1 -1
- package/dist/index.min.js.map +1 -1
- package/dist/node.cjs +123 -48
- package/dist/node.cjs.map +1 -1
- package/dist/test.js +206 -58
- package/dist/test.js.map +1 -1
- package/dist/unpack-no-eval.cjs +67 -27
- package/dist/unpack-no-eval.cjs.map +1 -1
- package/index.d.cts +1 -0
- package/index.d.ts +1 -0
- package/pack.js +50 -19
- package/package.json +5 -1
- package/struct.js +7 -3
- package/unpack.js +67 -27
package/dist/test.js
CHANGED
|
@@ -967,7 +967,10 @@
|
|
|
967
967
|
if (typeof property === 'string') return property;
|
|
968
968
|
if (typeof property === 'number' || typeof property === 'boolean' || typeof property === 'bigint') return property.toString();
|
|
969
969
|
if (property == null) return property + '';
|
|
970
|
-
|
|
970
|
+
if (currentUnpackr.allowArraysInMapKeys && Array.isArray(property) && property.flat().every(item => ['string', 'number', 'boolean', 'bigint'].includes(typeof item))) {
|
|
971
|
+
return property.flat().toString();
|
|
972
|
+
}
|
|
973
|
+
throw new Error(`Invalid property type for record: ${typeof property}`);
|
|
971
974
|
}
|
|
972
975
|
// the registration of the record definition extension (as "r")
|
|
973
976
|
const recordDefinition = (id, highByte) => {
|
|
@@ -992,21 +995,47 @@
|
|
|
992
995
|
currentExtensions[0] = () => {}; // notepack defines extension 0 to mean undefined, so use that as the default here
|
|
993
996
|
currentExtensions[0].noBuffer = true;
|
|
994
997
|
|
|
995
|
-
currentExtensions[0x42] =
|
|
996
|
-
|
|
997
|
-
let
|
|
998
|
-
let
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
998
|
+
currentExtensions[0x42] = data => {
|
|
999
|
+
let headLength = (data.byteLength % 8) || 8;
|
|
1000
|
+
let head = BigInt(data[0] & 0x80 ? data[0] - 0x100 : data[0]);
|
|
1001
|
+
for (let i = 1; i < headLength; i++) {
|
|
1002
|
+
head <<= BigInt(8);
|
|
1003
|
+
head += BigInt(data[i]);
|
|
1004
|
+
}
|
|
1005
|
+
if (data.byteLength !== headLength) {
|
|
1006
|
+
let view = new DataView(data.buffer, data.byteOffset, data.byteLength);
|
|
1007
|
+
let decode = (start, end) => {
|
|
1008
|
+
let length = end - start;
|
|
1009
|
+
if (length <= 40) {
|
|
1010
|
+
let out = view.getBigUint64(start);
|
|
1011
|
+
for (let i = start + 8; i < end; i += 8) {
|
|
1012
|
+
out <<= BigInt(64n);
|
|
1013
|
+
out |= view.getBigUint64(i);
|
|
1014
|
+
}
|
|
1015
|
+
return out
|
|
1016
|
+
}
|
|
1017
|
+
// if (length === 8) return view.getBigUint64(start)
|
|
1018
|
+
let middle = start + (length >> 4 << 3);
|
|
1019
|
+
let left = decode(start, middle);
|
|
1020
|
+
let right = decode(middle, end);
|
|
1021
|
+
return (left << BigInt((end - middle) * 8)) | right
|
|
1022
|
+
};
|
|
1023
|
+
head = (head << BigInt((view.byteLength - headLength) * 8)) | decode(headLength, view.byteLength);
|
|
1002
1024
|
}
|
|
1003
|
-
return
|
|
1025
|
+
return head
|
|
1004
1026
|
};
|
|
1005
1027
|
|
|
1006
|
-
let errors = {
|
|
1028
|
+
let errors = {
|
|
1029
|
+
Error, EvalError, RangeError, ReferenceError, SyntaxError, TypeError, URIError, AggregateError: typeof AggregateError === 'function' ? AggregateError : null,
|
|
1030
|
+
};
|
|
1007
1031
|
currentExtensions[0x65] = () => {
|
|
1008
1032
|
let data = read();
|
|
1009
|
-
|
|
1033
|
+
if (!errors[data[0]]) {
|
|
1034
|
+
let error = Error(data[1], { cause: data[2] });
|
|
1035
|
+
error.name = data[0];
|
|
1036
|
+
return error
|
|
1037
|
+
}
|
|
1038
|
+
return errors[data[0]](data[1], { cause: data[2] })
|
|
1010
1039
|
};
|
|
1011
1040
|
|
|
1012
1041
|
currentExtensions[0x69] = (data) => {
|
|
@@ -1017,20 +1046,33 @@
|
|
|
1017
1046
|
referenceMap = new Map();
|
|
1018
1047
|
let token = src[position$1];
|
|
1019
1048
|
let target;
|
|
1020
|
-
// TODO: handle
|
|
1021
|
-
// ahead past references to record structure definitions
|
|
1049
|
+
// TODO: handle any other types that can cycle and make the code more robust if there are other extensions
|
|
1022
1050
|
if (token >= 0x90 && token < 0xa0 || token == 0xdc || token == 0xdd)
|
|
1023
1051
|
target = [];
|
|
1052
|
+
else if (token >= 0x80 && token < 0x90 || token == 0xde || token == 0xdf)
|
|
1053
|
+
target = new Map();
|
|
1054
|
+
else if ((token >= 0xc7 && token <= 0xc9 || token >= 0xd4 && token <= 0xd8) && src[position$1 + 1] === 0x73)
|
|
1055
|
+
target = new Set();
|
|
1024
1056
|
else
|
|
1025
1057
|
target = {};
|
|
1026
1058
|
|
|
1027
1059
|
let refEntry = { target }; // a placeholder object
|
|
1028
1060
|
referenceMap.set(id, refEntry);
|
|
1029
1061
|
let targetProperties = read(); // read the next value as the target object to id
|
|
1030
|
-
if (refEntry.used)
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1062
|
+
if (!refEntry.used) {
|
|
1063
|
+
// no cycle, can just use the returned read object
|
|
1064
|
+
return refEntry.target = targetProperties // replace the placeholder with the real one
|
|
1065
|
+
} else {
|
|
1066
|
+
// there is a cycle, so we have to assign properties to original target
|
|
1067
|
+
Object.assign(target, targetProperties);
|
|
1068
|
+
}
|
|
1069
|
+
|
|
1070
|
+
// copy over map/set entries if we're able to
|
|
1071
|
+
if (target instanceof Map)
|
|
1072
|
+
for (let [k, v] of targetProperties.entries()) target.set(k, v);
|
|
1073
|
+
if (target instanceof Set)
|
|
1074
|
+
for (let i of Array.from(targetProperties)) target.add(i);
|
|
1075
|
+
return target
|
|
1034
1076
|
};
|
|
1035
1077
|
|
|
1036
1078
|
currentExtensions[0x70] = (data) => {
|
|
@@ -1049,18 +1091,16 @@
|
|
|
1049
1091
|
let glbl = typeof globalThis === 'object' ? globalThis : window;
|
|
1050
1092
|
currentExtensions[0x74] = (data) => {
|
|
1051
1093
|
let typeCode = data[0];
|
|
1094
|
+
// we always have to slice to get a new ArrayBuffer that is aligned
|
|
1095
|
+
let buffer = Uint8Array.prototype.slice.call(data, 1).buffer;
|
|
1096
|
+
|
|
1052
1097
|
let typedArrayName = typedArrays[typeCode];
|
|
1053
1098
|
if (!typedArrayName) {
|
|
1054
|
-
if (typeCode === 16)
|
|
1055
|
-
|
|
1056
|
-
let u8 = new Uint8Array(ab);
|
|
1057
|
-
u8.set(data.subarray(1));
|
|
1058
|
-
return ab;
|
|
1059
|
-
}
|
|
1099
|
+
if (typeCode === 16) return buffer
|
|
1100
|
+
if (typeCode === 17) return new DataView(buffer)
|
|
1060
1101
|
throw new Error('Could not find typed array for code ' + typeCode)
|
|
1061
1102
|
}
|
|
1062
|
-
|
|
1063
|
-
return new glbl[typedArrayName](Uint8Array.prototype.slice.call(data, 1).buffer)
|
|
1103
|
+
return new glbl[typedArrayName](buffer)
|
|
1064
1104
|
};
|
|
1065
1105
|
currentExtensions[0x78] = () => {
|
|
1066
1106
|
let data = read();
|
|
@@ -1088,13 +1128,13 @@
|
|
|
1088
1128
|
return new Date(
|
|
1089
1129
|
((data[0] << 22) + (data[1] << 14) + (data[2] << 6) + (data[3] >> 2)) / 1000000 +
|
|
1090
1130
|
((data[3] & 0x3) * 0x100000000 + data[4] * 0x1000000 + (data[5] << 16) + (data[6] << 8) + data[7]) * 1000)
|
|
1091
|
-
else if (data.length == 12)
|
|
1131
|
+
else if (data.length == 12)
|
|
1092
1132
|
return new Date(
|
|
1093
1133
|
((data[0] << 24) + (data[1] << 16) + (data[2] << 8) + data[3]) / 1000000 +
|
|
1094
1134
|
(((data[4] & 0x80) ? -0x1000000000000 : 0) + data[6] * 0x10000000000 + data[7] * 0x100000000 + data[8] * 0x1000000 + (data[9] << 16) + (data[10] << 8) + data[11]) * 1000)
|
|
1095
1135
|
else
|
|
1096
1136
|
return new Date('invalid')
|
|
1097
|
-
};
|
|
1137
|
+
};
|
|
1098
1138
|
// registration of bulk record definition?
|
|
1099
1139
|
// currentExtensions[0x52] = () =>
|
|
1100
1140
|
|
|
@@ -1698,11 +1738,11 @@
|
|
|
1698
1738
|
} else if (type === 'boolean') {
|
|
1699
1739
|
target[position++] = value ? 0xc3 : 0xc2;
|
|
1700
1740
|
} else if (type === 'bigint') {
|
|
1701
|
-
if (value <
|
|
1741
|
+
if (value < 0x8000000000000000 && value >= -0x8000000000000000) {
|
|
1702
1742
|
// use a signed int as long as it fits
|
|
1703
1743
|
target[position++] = 0xd3;
|
|
1704
1744
|
targetView.setBigInt64(position, value);
|
|
1705
|
-
} else if (value <
|
|
1745
|
+
} else if (value < 0x10000000000000000 && value > 0) {
|
|
1706
1746
|
// if we can fit an unsigned int, use that
|
|
1707
1747
|
target[position++] = 0xcf;
|
|
1708
1748
|
targetView.setBigUint64(position, value);
|
|
@@ -1713,22 +1753,46 @@
|
|
|
1713
1753
|
targetView.setFloat64(position, Number(value));
|
|
1714
1754
|
} else if (this.largeBigIntToString) {
|
|
1715
1755
|
return pack(value.toString());
|
|
1716
|
-
} else if (this.useBigIntExtension
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
value
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1756
|
+
} else if (this.useBigIntExtension || this.moreTypes) {
|
|
1757
|
+
let empty = value < 0 ? BigInt(-1) : BigInt(0);
|
|
1758
|
+
|
|
1759
|
+
let array;
|
|
1760
|
+
if (value >> BigInt(0x10000) === empty) {
|
|
1761
|
+
let mask = BigInt(0x10000000000000000) - BigInt(1); // literal would overflow
|
|
1762
|
+
let chunks = [];
|
|
1763
|
+
do {
|
|
1764
|
+
chunks.push(value & mask);
|
|
1765
|
+
value >>= BigInt(64);
|
|
1766
|
+
} while (value !== empty)
|
|
1767
|
+
|
|
1768
|
+
array = new Uint8Array(new BigUint64Array(chunks).buffer);
|
|
1769
|
+
array.reverse();
|
|
1770
|
+
} else {
|
|
1771
|
+
let invert = value < 0;
|
|
1772
|
+
let string = (invert ? ~value : value).toString(16);
|
|
1773
|
+
if (string.length % 2) {
|
|
1774
|
+
string = '0' + string;
|
|
1775
|
+
} else if (parseInt(string.charAt(0), 16) >= 8) {
|
|
1776
|
+
string = '00' + string;
|
|
1777
|
+
}
|
|
1778
|
+
|
|
1779
|
+
if (hasNodeBuffer$1) {
|
|
1780
|
+
array = Buffer.from(string, 'hex');
|
|
1781
|
+
} else {
|
|
1782
|
+
array = new Uint8Array(string.length / 2);
|
|
1783
|
+
for (let i = 0; i < array.length; i++) {
|
|
1784
|
+
array[i] = parseInt(string.slice(i * 2, i * 2 + 2), 16);
|
|
1785
|
+
}
|
|
1786
|
+
}
|
|
1787
|
+
|
|
1788
|
+
if (invert) {
|
|
1789
|
+
for (let i = 0; i < array.length; i++) array[i] = ~array[i];
|
|
1790
|
+
}
|
|
1731
1791
|
}
|
|
1792
|
+
|
|
1793
|
+
if (array.length + position > safeEnd)
|
|
1794
|
+
makeRoom(array.length + position);
|
|
1795
|
+
position = writeExtensionData(array, target, position, 0x42);
|
|
1732
1796
|
return
|
|
1733
1797
|
} else {
|
|
1734
1798
|
throw new RangeError(value + ' was too large to fit in MessagePack 64-bit integer format, use' +
|
|
@@ -2032,7 +2096,7 @@
|
|
|
2032
2096
|
}
|
|
2033
2097
|
};
|
|
2034
2098
|
|
|
2035
|
-
extensionClasses = [ Date, Set, Error, RegExp, ArrayBuffer, Object.getPrototypeOf(Uint8Array.prototype).constructor /*TypedArray*/, C1Type ];
|
|
2099
|
+
extensionClasses = [ Date, Set, Error, RegExp, ArrayBuffer, Object.getPrototypeOf(Uint8Array.prototype).constructor /*TypedArray*/, DataView, C1Type ];
|
|
2036
2100
|
extensions = [{
|
|
2037
2101
|
pack(date, allocateForWrite, pack) {
|
|
2038
2102
|
let seconds = date.getTime() / 1000;
|
|
@@ -2119,6 +2183,13 @@
|
|
|
2119
2183
|
else
|
|
2120
2184
|
writeBuffer(typedArray, allocateForWrite);
|
|
2121
2185
|
}
|
|
2186
|
+
}, {
|
|
2187
|
+
pack(arrayBuffer, allocateForWrite) {
|
|
2188
|
+
if (this.moreTypes)
|
|
2189
|
+
writeExtBuffer(arrayBuffer, 0x11, allocateForWrite);
|
|
2190
|
+
else
|
|
2191
|
+
writeBuffer(hasNodeBuffer$1 ? Buffer.from(arrayBuffer) : new Uint8Array(arrayBuffer), allocateForWrite);
|
|
2192
|
+
}
|
|
2122
2193
|
}, {
|
|
2123
2194
|
pack(c1, allocateForWrite) { // specific 0xC1 object
|
|
2124
2195
|
let { target, position} = allocateForWrite(1);
|
|
@@ -2749,10 +2820,14 @@
|
|
|
2749
2820
|
throw new Error('Could not find typed structure ' + recordId);
|
|
2750
2821
|
}
|
|
2751
2822
|
var construct = structure.construct;
|
|
2823
|
+
var fullConstruct = structure.fullConstruct;
|
|
2752
2824
|
if (!construct) {
|
|
2753
2825
|
construct = structure.construct = function LazyObject() {
|
|
2754
2826
|
};
|
|
2755
|
-
|
|
2827
|
+
fullConstruct = structure.fullConstruct = function LoadedObject() {
|
|
2828
|
+
};
|
|
2829
|
+
fullConstruct.prototype = unpackr.structPrototype ?? {};
|
|
2830
|
+
var prototype = construct.prototype = unpackr.structPrototype ? Object.create(unpackr.structPrototype) : {};
|
|
2756
2831
|
let properties = [];
|
|
2757
2832
|
let currentOffset = 0;
|
|
2758
2833
|
let lastRefProperty;
|
|
@@ -2953,12 +3028,12 @@
|
|
|
2953
3028
|
Object.defineProperty(prototype, property.key, { get: withSource(property.get), enumerable: true });
|
|
2954
3029
|
let valueFunction = 'v' + i++;
|
|
2955
3030
|
args.push(valueFunction);
|
|
2956
|
-
objectLiteralProperties.push('[' + JSON.stringify(property.key) + ']
|
|
3031
|
+
objectLiteralProperties.push('o[' + JSON.stringify(property.key) + ']=' + valueFunction + '(s)');
|
|
2957
3032
|
}
|
|
2958
3033
|
if (hasInheritedProperties) {
|
|
2959
3034
|
objectLiteralProperties.push('__proto__:this');
|
|
2960
3035
|
}
|
|
2961
|
-
let toObject = (new Function(...args, 'return function(s){
|
|
3036
|
+
let toObject = (new Function(...args, 'var c=this;return function(s){var o=new c();' + objectLiteralProperties.join(';') + ';return o;}')).apply(fullConstruct, properties.map(prop => prop.get));
|
|
2962
3037
|
Object.defineProperty(prototype, 'toJSON', {
|
|
2963
3038
|
value(omitUnderscoredProperties) {
|
|
2964
3039
|
return toObject.call(this, this[sourceSymbol]);
|
|
@@ -3292,7 +3367,7 @@
|
|
|
3292
3367
|
{id: 2, type: 1, labels: {b: 1, c: 2}},
|
|
3293
3368
|
{id: 3, type: 1, labels: {d: 1, e: 2}}
|
|
3294
3369
|
];
|
|
3295
|
-
|
|
3370
|
+
|
|
3296
3371
|
var alternatives = [
|
|
3297
3372
|
{useRecords: false}, // 88 bytes
|
|
3298
3373
|
{useRecords: true}, // 58 bytes
|
|
@@ -3304,7 +3379,7 @@
|
|
|
3304
3379
|
let packr = new Packr(o);
|
|
3305
3380
|
var serialized = packr.pack(data);
|
|
3306
3381
|
var deserialized = packr.unpack(serialized);
|
|
3307
|
-
assert.deepEqual(deserialized, data);
|
|
3382
|
+
assert.deepEqual(deserialized, data);
|
|
3308
3383
|
}
|
|
3309
3384
|
});
|
|
3310
3385
|
|
|
@@ -3426,7 +3501,7 @@
|
|
|
3426
3501
|
});
|
|
3427
3502
|
|
|
3428
3503
|
test('BigInt', function() {
|
|
3429
|
-
let packr = new Packr({useBigIntExtension: true});
|
|
3504
|
+
let packr = new Packr({ useBigIntExtension: true });
|
|
3430
3505
|
let data = {
|
|
3431
3506
|
a: 3333333333333333333333333333n,
|
|
3432
3507
|
b: 1234567890123456789012345678901234567890n,
|
|
@@ -3434,7 +3509,21 @@
|
|
|
3434
3509
|
d: -352523523642364364364264264264264264262642642n,
|
|
3435
3510
|
e: 0xffffffffffffffffffffffffffn,
|
|
3436
3511
|
f: -0xffffffffffffffffffffffffffn,
|
|
3512
|
+
g: (1234n << 123n) ^ (5678n << 56n) ^ 890n,
|
|
3513
|
+
h: (-1234n << 123n) ^ (5678n << 56n) ^ 890n,
|
|
3514
|
+
i: (1234n << 1234n) ^ (5678n << 567n) ^ 890n,
|
|
3515
|
+
j: (-1234n << 1234n) ^ (5678n << 567n) ^ 890n,
|
|
3516
|
+
k: 0xdeadn << 0xbeefn,
|
|
3517
|
+
l: -0xdeadn << 0xbeefn,
|
|
3518
|
+
m: 11n << 0x11111n ^ 111n,
|
|
3519
|
+
n: -11n << 0x11111n ^ 111n,
|
|
3520
|
+
array: [],
|
|
3437
3521
|
};
|
|
3522
|
+
|
|
3523
|
+
for (let n = 7n; n.toString(16).length * 4 < 150000; n *= n) {
|
|
3524
|
+
data.array.push(n, -n);
|
|
3525
|
+
}
|
|
3526
|
+
|
|
3438
3527
|
let serialized = packr.pack(data);
|
|
3439
3528
|
let deserialized = packr.unpack(serialized);
|
|
3440
3529
|
assert.deepEqual(data, deserialized);
|
|
@@ -3661,7 +3750,7 @@
|
|
|
3661
3750
|
|
|
3662
3751
|
test('extended class pack/unpack proxied', function(){
|
|
3663
3752
|
function Extended() {
|
|
3664
|
-
|
|
3753
|
+
|
|
3665
3754
|
}
|
|
3666
3755
|
Extended.prototype.__call__ = function(){
|
|
3667
3756
|
return this.value * 4
|
|
@@ -3672,7 +3761,7 @@
|
|
|
3672
3761
|
|
|
3673
3762
|
var instance = function() { instance.__call__();/* callable stuff */ };
|
|
3674
3763
|
Object.setPrototypeOf(instance,Extended.prototype);
|
|
3675
|
-
|
|
3764
|
+
|
|
3676
3765
|
instance.value = 4;
|
|
3677
3766
|
var data = instance;
|
|
3678
3767
|
|
|
@@ -3750,10 +3839,12 @@
|
|
|
3750
3839
|
}
|
|
3751
3840
|
});
|
|
3752
3841
|
|
|
3753
|
-
test('
|
|
3842
|
+
test('moreTypes: Error with causes', function() {
|
|
3754
3843
|
const object = {
|
|
3755
3844
|
error: new Error('test'),
|
|
3756
|
-
errorWithCause: new Error('test-1', { cause: new Error('test-2')}),
|
|
3845
|
+
errorWithCause: new Error('test-1', { cause: new Error('test-2') }),
|
|
3846
|
+
type: new TypeError(),
|
|
3847
|
+
range: new RangeError('test', { cause: [1, 2] }),
|
|
3757
3848
|
};
|
|
3758
3849
|
const packr = new Packr({
|
|
3759
3850
|
moreTypes: true,
|
|
@@ -3766,6 +3857,12 @@
|
|
|
3766
3857
|
assert.equal(deserialized.errorWithCause.message, object.errorWithCause.message);
|
|
3767
3858
|
assert.equal(deserialized.errorWithCause.cause.message, object.errorWithCause.cause.message);
|
|
3768
3859
|
assert.equal(deserialized.errorWithCause.cause.cause, object.errorWithCause.cause.cause);
|
|
3860
|
+
assert.equal(deserialized.type.message, object.type.message);
|
|
3861
|
+
assert.equal(deserialized.range.message, object.range.message);
|
|
3862
|
+
assert.deepEqual(deserialized.range.cause, object.range.cause);
|
|
3863
|
+
assert(deserialized.error instanceof Error);
|
|
3864
|
+
assert(deserialized.type instanceof TypeError);
|
|
3865
|
+
assert(deserialized.range instanceof RangeError);
|
|
3769
3866
|
});
|
|
3770
3867
|
|
|
3771
3868
|
test('structured cloning: self reference', function() {
|
|
@@ -3800,6 +3897,39 @@
|
|
|
3800
3897
|
assert.equal(u8[1], 2);
|
|
3801
3898
|
});
|
|
3802
3899
|
|
|
3900
|
+
test('structured cloning: self reference with more types', function() {
|
|
3901
|
+
let set = new Set();
|
|
3902
|
+
set.add(['hello', 1, 2, { map: new Map([[set, set], ['a', 'b']]) }]);
|
|
3903
|
+
|
|
3904
|
+
let packr = new Packr({
|
|
3905
|
+
moreTypes: true,
|
|
3906
|
+
structuredClone: true,
|
|
3907
|
+
});
|
|
3908
|
+
let serialized = packr.pack(set);
|
|
3909
|
+
let deserialized = packr.unpack(serialized);
|
|
3910
|
+
assert.equal(deserialized.constructor.name, 'Set');
|
|
3911
|
+
let map = Array.from(deserialized)[0][3].map;
|
|
3912
|
+
assert.equal(map.get(deserialized), deserialized);
|
|
3913
|
+
|
|
3914
|
+
let sizeTestMap = new Map();
|
|
3915
|
+
for (let i = 0; i < 50; i++) {
|
|
3916
|
+
sizeTestMap.set(i || sizeTestMap, sizeTestMap);
|
|
3917
|
+
let deserialized = packr.unpack(packr.pack(sizeTestMap));
|
|
3918
|
+
assert.equal(deserialized.size, i + 1);
|
|
3919
|
+
assert(deserialized.has(deserialized));
|
|
3920
|
+
assert(deserialized.has(i || deserialized));
|
|
3921
|
+
}
|
|
3922
|
+
|
|
3923
|
+
let sizeTestSet = new Set();
|
|
3924
|
+
for (let i = 0; i < 50; i++) {
|
|
3925
|
+
sizeTestSet.add(i || sizeTestSet);
|
|
3926
|
+
let deserialized = packr.unpack(packr.pack(sizeTestSet));
|
|
3927
|
+
assert.equal(deserialized.size, i + 1);
|
|
3928
|
+
assert(deserialized.has(deserialized));
|
|
3929
|
+
assert(deserialized.has(i || deserialized));
|
|
3930
|
+
}
|
|
3931
|
+
});
|
|
3932
|
+
|
|
3803
3933
|
test('structured cloning: types', function() {
|
|
3804
3934
|
let b = typeof Buffer != 'undefined' ? Buffer.alloc(20) : new Uint8Array(20);
|
|
3805
3935
|
let fa = new Float32Array(b.buffer, 8, 2);
|
|
@@ -3810,7 +3940,9 @@
|
|
|
3810
3940
|
set: new Set(['a', 'b']),
|
|
3811
3941
|
regexp: /test/gi,
|
|
3812
3942
|
float32Array: fa,
|
|
3813
|
-
uint16Array: new Uint16Array([3,4])
|
|
3943
|
+
uint16Array: new Uint16Array([3, 4]),
|
|
3944
|
+
arrayBuffer: new Uint8Array([0xde, 0xad]).buffer,
|
|
3945
|
+
dataView: new DataView(new Uint8Array([0xbe, 0xef]).buffer),
|
|
3814
3946
|
};
|
|
3815
3947
|
let packr = new Packr({
|
|
3816
3948
|
moreTypes: true,
|
|
@@ -3827,6 +3959,10 @@
|
|
|
3827
3959
|
assert.equal(deserialized.uint16Array.constructor.name, 'Uint16Array');
|
|
3828
3960
|
assert.equal(deserialized.uint16Array[0], 3);
|
|
3829
3961
|
assert.equal(deserialized.uint16Array[1], 4);
|
|
3962
|
+
assert.equal(deserialized.arrayBuffer.constructor.name, 'ArrayBuffer');
|
|
3963
|
+
assert.equal(new DataView(deserialized.arrayBuffer).getUint16(), 0xdead);
|
|
3964
|
+
assert.equal(deserialized.dataView.constructor.name, 'DataView');
|
|
3965
|
+
assert.equal(deserialized.dataView.getUint16(), 0xbeef);
|
|
3830
3966
|
});
|
|
3831
3967
|
test('big bundledStrings', function() {
|
|
3832
3968
|
const MSGPACK_OPTIONS = {bundleStrings: true};
|
|
@@ -3955,7 +4091,7 @@
|
|
|
3955
4091
|
getStructures() {
|
|
3956
4092
|
return structures
|
|
3957
4093
|
},
|
|
3958
|
-
saveStructures(structures) {
|
|
4094
|
+
saveStructures(structures) {
|
|
3959
4095
|
},
|
|
3960
4096
|
maxSharedStructures: 100
|
|
3961
4097
|
});
|
|
@@ -3963,7 +4099,7 @@
|
|
|
3963
4099
|
getStructures() {
|
|
3964
4100
|
return structures2
|
|
3965
4101
|
},
|
|
3966
|
-
saveStructures(structures) {
|
|
4102
|
+
saveStructures(structures) {
|
|
3967
4103
|
},
|
|
3968
4104
|
maxSharedStructures: 100
|
|
3969
4105
|
});
|
|
@@ -4245,6 +4381,18 @@
|
|
|
4245
4381
|
assert.deepEqual(deserialized, data);
|
|
4246
4382
|
});
|
|
4247
4383
|
|
|
4384
|
+
test('arrays in map keys', function() {
|
|
4385
|
+
const msgpackr = new Packr({ mapsAsObjects: true, allowArraysInMapKeys: true });
|
|
4386
|
+
|
|
4387
|
+
const map = new Map();
|
|
4388
|
+
map.set([1, 2, 3], 1);
|
|
4389
|
+
map.set([1, 2, ['foo', 3.14]], 2);
|
|
4390
|
+
|
|
4391
|
+
const packed = msgpackr.pack(map);
|
|
4392
|
+
const unpacked = msgpackr.unpack(packed);
|
|
4393
|
+
assert.deepEqual(unpacked, { '1,2,3': 1, '1,2,foo,3.14': 2 });
|
|
4394
|
+
});
|
|
4395
|
+
|
|
4248
4396
|
test('utf16 causing expansion', function() {
|
|
4249
4397
|
this.timeout(10000);
|
|
4250
4398
|
let data = {fixstr: 'ᾐᾑᾒᾓᾔᾕᾖᾗᾘᾙᾚᾛᾜᾝ', str8:'ᾐᾑᾒᾓᾔᾕᾖᾗᾘᾙᾚᾛᾜᾝᾐᾑᾒᾓᾔᾕᾖᾗᾘᾙᾚᾛᾜᾝᾐᾑᾒᾓᾔᾕᾖᾗᾘᾙᾚᾛᾜᾝᾐᾑᾒᾓᾔᾕᾖᾗᾘᾙᾚᾛᾜᾝᾐᾑᾒᾓᾔᾕᾖᾗᾘᾙᾚᾛᾜᾝᾐᾑᾒᾓᾔᾕᾖᾗᾘᾙᾚᾛᾜᾝᾐᾑᾒᾓᾔᾕᾖᾗᾘᾙᾚᾛᾜᾝᾐᾑᾒᾓᾔᾕᾖᾗᾘᾙᾚᾛᾜᾝᾐᾑᾒᾓᾔᾕᾖᾗᾘᾙᾚᾛᾜᾝᾐᾑᾒᾓᾔᾕᾖᾗᾘᾙᾚᾛᾜᾝᾐᾑᾒᾓᾔᾕᾖᾗᾘᾙᾚᾛᾜᾝᾐᾑᾒᾓᾔᾕᾖᾗᾘᾙᾚᾛᾜᾝᾐᾑᾒᾓᾔᾕᾖᾗᾘᾙᾚᾛᾜᾝᾐᾑᾒᾓᾔᾕᾖᾗᾘᾙᾚᾛᾜᾝᾐᾑᾒᾓᾔᾕᾖᾗᾘᾙᾚᾛᾜᾝᾐᾑᾒᾓᾔᾕᾖᾗᾘᾙᾚᾛᾜᾝ'};
|