msgpackr 1.11.2 → 1.11.4
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 +42 -21
- 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 +42 -21
- 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 +49 -24
- package/dist/node.cjs.map +1 -1
- package/dist/test.js +105 -26
- package/dist/test.js.map +1 -1
- package/dist/unpack-no-eval.cjs +31 -17
- package/dist/unpack-no-eval.cjs.map +1 -1
- package/index.d.cts +1 -0
- package/index.d.ts +1 -0
- package/pack.js +11 -4
- package/package.json +5 -1
- package/struct.js +7 -3
- package/unpack.js +31 -17
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) => {
|
|
@@ -1017,20 +1020,33 @@
|
|
|
1017
1020
|
referenceMap = new Map();
|
|
1018
1021
|
let token = src[position$1];
|
|
1019
1022
|
let target;
|
|
1020
|
-
// TODO: handle
|
|
1021
|
-
// ahead past references to record structure definitions
|
|
1023
|
+
// TODO: handle any other types that can cycle and make the code more robust if there are other extensions
|
|
1022
1024
|
if (token >= 0x90 && token < 0xa0 || token == 0xdc || token == 0xdd)
|
|
1023
1025
|
target = [];
|
|
1026
|
+
else if (token >= 0x80 && token < 0x90 || token == 0xde || token == 0xdf)
|
|
1027
|
+
target = new Map();
|
|
1028
|
+
else if ((token >= 0xc7 && token <= 0xc9 || token >= 0xd4 && token <= 0xd8) && src[position$1 + 1] === 0x73)
|
|
1029
|
+
target = new Set();
|
|
1024
1030
|
else
|
|
1025
1031
|
target = {};
|
|
1026
1032
|
|
|
1027
1033
|
let refEntry = { target }; // a placeholder object
|
|
1028
1034
|
referenceMap.set(id, refEntry);
|
|
1029
1035
|
let targetProperties = read(); // read the next value as the target object to id
|
|
1030
|
-
if (refEntry.used)
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1036
|
+
if (!refEntry.used) {
|
|
1037
|
+
// no cycle, can just use the returned read object
|
|
1038
|
+
return refEntry.target = targetProperties // replace the placeholder with the real one
|
|
1039
|
+
} else {
|
|
1040
|
+
// there is a cycle, so we have to assign properties to original target
|
|
1041
|
+
Object.assign(target, targetProperties);
|
|
1042
|
+
}
|
|
1043
|
+
|
|
1044
|
+
// copy over map/set entries if we're able to
|
|
1045
|
+
if (target instanceof Map)
|
|
1046
|
+
for (let [k, v] of targetProperties.entries()) target.set(k, v);
|
|
1047
|
+
if (target instanceof Set)
|
|
1048
|
+
for (let i of Array.from(targetProperties)) target.add(i);
|
|
1049
|
+
return target
|
|
1034
1050
|
};
|
|
1035
1051
|
|
|
1036
1052
|
currentExtensions[0x70] = (data) => {
|
|
@@ -1049,18 +1065,16 @@
|
|
|
1049
1065
|
let glbl = typeof globalThis === 'object' ? globalThis : window;
|
|
1050
1066
|
currentExtensions[0x74] = (data) => {
|
|
1051
1067
|
let typeCode = data[0];
|
|
1068
|
+
// we always have to slice to get a new ArrayBuffer that is aligned
|
|
1069
|
+
let buffer = Uint8Array.prototype.slice.call(data, 1).buffer;
|
|
1070
|
+
|
|
1052
1071
|
let typedArrayName = typedArrays[typeCode];
|
|
1053
1072
|
if (!typedArrayName) {
|
|
1054
|
-
if (typeCode === 16)
|
|
1055
|
-
|
|
1056
|
-
let u8 = new Uint8Array(ab);
|
|
1057
|
-
u8.set(data.subarray(1));
|
|
1058
|
-
return ab;
|
|
1059
|
-
}
|
|
1073
|
+
if (typeCode === 16) return buffer
|
|
1074
|
+
if (typeCode === 17) return new DataView(buffer)
|
|
1060
1075
|
throw new Error('Could not find typed array for code ' + typeCode)
|
|
1061
1076
|
}
|
|
1062
|
-
|
|
1063
|
-
return new glbl[typedArrayName](Uint8Array.prototype.slice.call(data, 1).buffer)
|
|
1077
|
+
return new glbl[typedArrayName](buffer)
|
|
1064
1078
|
};
|
|
1065
1079
|
currentExtensions[0x78] = () => {
|
|
1066
1080
|
let data = read();
|
|
@@ -1088,13 +1102,13 @@
|
|
|
1088
1102
|
return new Date(
|
|
1089
1103
|
((data[0] << 22) + (data[1] << 14) + (data[2] << 6) + (data[3] >> 2)) / 1000000 +
|
|
1090
1104
|
((data[3] & 0x3) * 0x100000000 + data[4] * 0x1000000 + (data[5] << 16) + (data[6] << 8) + data[7]) * 1000)
|
|
1091
|
-
else if (data.length == 12)
|
|
1105
|
+
else if (data.length == 12)
|
|
1092
1106
|
return new Date(
|
|
1093
1107
|
((data[0] << 24) + (data[1] << 16) + (data[2] << 8) + data[3]) / 1000000 +
|
|
1094
1108
|
(((data[4] & 0x80) ? -0x1000000000000 : 0) + data[6] * 0x10000000000 + data[7] * 0x100000000 + data[8] * 0x1000000 + (data[9] << 16) + (data[10] << 8) + data[11]) * 1000)
|
|
1095
1109
|
else
|
|
1096
1110
|
return new Date('invalid')
|
|
1097
|
-
};
|
|
1111
|
+
};
|
|
1098
1112
|
// registration of bulk record definition?
|
|
1099
1113
|
// currentExtensions[0x52] = () =>
|
|
1100
1114
|
|
|
@@ -1698,11 +1712,11 @@
|
|
|
1698
1712
|
} else if (type === 'boolean') {
|
|
1699
1713
|
target[position++] = value ? 0xc3 : 0xc2;
|
|
1700
1714
|
} else if (type === 'bigint') {
|
|
1701
|
-
if (value <
|
|
1715
|
+
if (value < 0x8000000000000000 && value >= -0x8000000000000000) {
|
|
1702
1716
|
// use a signed int as long as it fits
|
|
1703
1717
|
target[position++] = 0xd3;
|
|
1704
1718
|
targetView.setBigInt64(position, value);
|
|
1705
|
-
} else if (value <
|
|
1719
|
+
} else if (value < 0x10000000000000000 && value > 0) {
|
|
1706
1720
|
// if we can fit an unsigned int, use that
|
|
1707
1721
|
target[position++] = 0xcf;
|
|
1708
1722
|
targetView.setBigUint64(position, value);
|
|
@@ -1713,7 +1727,7 @@
|
|
|
1713
1727
|
targetView.setFloat64(position, Number(value));
|
|
1714
1728
|
} else if (this.largeBigIntToString) {
|
|
1715
1729
|
return pack(value.toString());
|
|
1716
|
-
} else if (this.useBigIntExtension && value < BigInt(2)**BigInt(1023) && value > -(BigInt(2)**BigInt(1023))) {
|
|
1730
|
+
} else if ((this.useBigIntExtension || this.moreTypes) && value < BigInt(2)**BigInt(1023) && value > -(BigInt(2)**BigInt(1023))) {
|
|
1717
1731
|
target[position++] = 0xc7;
|
|
1718
1732
|
position++;
|
|
1719
1733
|
target[position++] = 0x42; // "B" for BigInt
|
|
@@ -2032,7 +2046,7 @@
|
|
|
2032
2046
|
}
|
|
2033
2047
|
};
|
|
2034
2048
|
|
|
2035
|
-
extensionClasses = [ Date, Set, Error, RegExp, ArrayBuffer, Object.getPrototypeOf(Uint8Array.prototype).constructor /*TypedArray*/, C1Type ];
|
|
2049
|
+
extensionClasses = [ Date, Set, Error, RegExp, ArrayBuffer, Object.getPrototypeOf(Uint8Array.prototype).constructor /*TypedArray*/, DataView, C1Type ];
|
|
2036
2050
|
extensions = [{
|
|
2037
2051
|
pack(date, allocateForWrite, pack) {
|
|
2038
2052
|
let seconds = date.getTime() / 1000;
|
|
@@ -2119,6 +2133,13 @@
|
|
|
2119
2133
|
else
|
|
2120
2134
|
writeBuffer(typedArray, allocateForWrite);
|
|
2121
2135
|
}
|
|
2136
|
+
}, {
|
|
2137
|
+
pack(arrayBuffer, allocateForWrite) {
|
|
2138
|
+
if (this.moreTypes)
|
|
2139
|
+
writeExtBuffer(arrayBuffer, 0x11, allocateForWrite);
|
|
2140
|
+
else
|
|
2141
|
+
writeBuffer(hasNodeBuffer$1 ? Buffer.from(arrayBuffer) : new Uint8Array(arrayBuffer), allocateForWrite);
|
|
2142
|
+
}
|
|
2122
2143
|
}, {
|
|
2123
2144
|
pack(c1, allocateForWrite) { // specific 0xC1 object
|
|
2124
2145
|
let { target, position} = allocateForWrite(1);
|
|
@@ -2749,10 +2770,14 @@
|
|
|
2749
2770
|
throw new Error('Could not find typed structure ' + recordId);
|
|
2750
2771
|
}
|
|
2751
2772
|
var construct = structure.construct;
|
|
2773
|
+
var fullConstruct = structure.fullConstruct;
|
|
2752
2774
|
if (!construct) {
|
|
2753
2775
|
construct = structure.construct = function LazyObject() {
|
|
2754
2776
|
};
|
|
2755
|
-
|
|
2777
|
+
fullConstruct = structure.fullConstruct = function LoadedObject() {
|
|
2778
|
+
};
|
|
2779
|
+
fullConstruct.prototype = unpackr.structPrototype ?? {};
|
|
2780
|
+
var prototype = construct.prototype = unpackr.structPrototype ? Object.create(unpackr.structPrototype) : {};
|
|
2756
2781
|
let properties = [];
|
|
2757
2782
|
let currentOffset = 0;
|
|
2758
2783
|
let lastRefProperty;
|
|
@@ -2953,12 +2978,12 @@
|
|
|
2953
2978
|
Object.defineProperty(prototype, property.key, { get: withSource(property.get), enumerable: true });
|
|
2954
2979
|
let valueFunction = 'v' + i++;
|
|
2955
2980
|
args.push(valueFunction);
|
|
2956
|
-
objectLiteralProperties.push('[' + JSON.stringify(property.key) + ']
|
|
2981
|
+
objectLiteralProperties.push('o[' + JSON.stringify(property.key) + ']=' + valueFunction + '(s)');
|
|
2957
2982
|
}
|
|
2958
2983
|
if (hasInheritedProperties) {
|
|
2959
2984
|
objectLiteralProperties.push('__proto__:this');
|
|
2960
2985
|
}
|
|
2961
|
-
let toObject = (new Function(...args, 'return function(s){
|
|
2986
|
+
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
2987
|
Object.defineProperty(prototype, 'toJSON', {
|
|
2963
2988
|
value(omitUnderscoredProperties) {
|
|
2964
2989
|
return toObject.call(this, this[sourceSymbol]);
|
|
@@ -3434,7 +3459,10 @@
|
|
|
3434
3459
|
d: -352523523642364364364264264264264264262642642n,
|
|
3435
3460
|
e: 0xffffffffffffffffffffffffffn,
|
|
3436
3461
|
f: -0xffffffffffffffffffffffffffn,
|
|
3462
|
+
o: -12345678901234567890n,
|
|
3463
|
+
array: [],
|
|
3437
3464
|
};
|
|
3465
|
+
|
|
3438
3466
|
let serialized = packr.pack(data);
|
|
3439
3467
|
let deserialized = packr.unpack(serialized);
|
|
3440
3468
|
assert.deepEqual(data, deserialized);
|
|
@@ -3750,7 +3778,7 @@
|
|
|
3750
3778
|
}
|
|
3751
3779
|
});
|
|
3752
3780
|
|
|
3753
|
-
test('
|
|
3781
|
+
test('moreTypes: Error with causes', function() {
|
|
3754
3782
|
const object = {
|
|
3755
3783
|
error: new Error('test'),
|
|
3756
3784
|
errorWithCause: new Error('test-1', { cause: new Error('test-2')}),
|
|
@@ -3800,6 +3828,39 @@
|
|
|
3800
3828
|
assert.equal(u8[1], 2);
|
|
3801
3829
|
});
|
|
3802
3830
|
|
|
3831
|
+
test('structured cloning: self reference with more types', function() {
|
|
3832
|
+
let set = new Set();
|
|
3833
|
+
set.add(['hello', 1, 2, { map: new Map([[set, set], ['a', 'b']]) }]);
|
|
3834
|
+
|
|
3835
|
+
let packr = new Packr({
|
|
3836
|
+
moreTypes: true,
|
|
3837
|
+
structuredClone: true,
|
|
3838
|
+
});
|
|
3839
|
+
let serialized = packr.pack(set);
|
|
3840
|
+
let deserialized = packr.unpack(serialized);
|
|
3841
|
+
assert.equal(deserialized.constructor.name, 'Set');
|
|
3842
|
+
let map = Array.from(deserialized)[0][3].map;
|
|
3843
|
+
assert.equal(map.get(deserialized), deserialized);
|
|
3844
|
+
|
|
3845
|
+
let sizeTestMap = new Map();
|
|
3846
|
+
for (let i = 0; i < 50; i++) {
|
|
3847
|
+
sizeTestMap.set(i || sizeTestMap, sizeTestMap);
|
|
3848
|
+
let deserialized = packr.unpack(packr.pack(sizeTestMap));
|
|
3849
|
+
assert.equal(deserialized.size, i + 1);
|
|
3850
|
+
assert(deserialized.has(deserialized));
|
|
3851
|
+
assert(deserialized.has(i || deserialized));
|
|
3852
|
+
}
|
|
3853
|
+
|
|
3854
|
+
let sizeTestSet = new Set();
|
|
3855
|
+
for (let i = 0; i < 50; i++) {
|
|
3856
|
+
sizeTestSet.add(i || sizeTestSet);
|
|
3857
|
+
let deserialized = packr.unpack(packr.pack(sizeTestSet));
|
|
3858
|
+
assert.equal(deserialized.size, i + 1);
|
|
3859
|
+
assert(deserialized.has(deserialized));
|
|
3860
|
+
assert(deserialized.has(i || deserialized));
|
|
3861
|
+
}
|
|
3862
|
+
});
|
|
3863
|
+
|
|
3803
3864
|
test('structured cloning: types', function() {
|
|
3804
3865
|
let b = typeof Buffer != 'undefined' ? Buffer.alloc(20) : new Uint8Array(20);
|
|
3805
3866
|
let fa = new Float32Array(b.buffer, 8, 2);
|
|
@@ -3810,7 +3871,9 @@
|
|
|
3810
3871
|
set: new Set(['a', 'b']),
|
|
3811
3872
|
regexp: /test/gi,
|
|
3812
3873
|
float32Array: fa,
|
|
3813
|
-
uint16Array: new Uint16Array([3,4])
|
|
3874
|
+
uint16Array: new Uint16Array([3, 4]),
|
|
3875
|
+
arrayBuffer: new Uint8Array([0xde, 0xad]).buffer,
|
|
3876
|
+
dataView: new DataView(new Uint8Array([0xbe, 0xef]).buffer),
|
|
3814
3877
|
};
|
|
3815
3878
|
let packr = new Packr({
|
|
3816
3879
|
moreTypes: true,
|
|
@@ -3827,6 +3890,10 @@
|
|
|
3827
3890
|
assert.equal(deserialized.uint16Array.constructor.name, 'Uint16Array');
|
|
3828
3891
|
assert.equal(deserialized.uint16Array[0], 3);
|
|
3829
3892
|
assert.equal(deserialized.uint16Array[1], 4);
|
|
3893
|
+
assert.equal(deserialized.arrayBuffer.constructor.name, 'ArrayBuffer');
|
|
3894
|
+
assert.equal(new DataView(deserialized.arrayBuffer).getUint16(), 0xdead);
|
|
3895
|
+
assert.equal(deserialized.dataView.constructor.name, 'DataView');
|
|
3896
|
+
assert.equal(deserialized.dataView.getUint16(), 0xbeef);
|
|
3830
3897
|
});
|
|
3831
3898
|
test('big bundledStrings', function() {
|
|
3832
3899
|
const MSGPACK_OPTIONS = {bundleStrings: true};
|
|
@@ -4245,6 +4312,18 @@
|
|
|
4245
4312
|
assert.deepEqual(deserialized, data);
|
|
4246
4313
|
});
|
|
4247
4314
|
|
|
4315
|
+
test('arrays in map keys', function() {
|
|
4316
|
+
const msgpackr = new Packr({ mapsAsObjects: true, allowArraysInMapKeys: true });
|
|
4317
|
+
|
|
4318
|
+
const map = new Map();
|
|
4319
|
+
map.set([1, 2, 3], 1);
|
|
4320
|
+
map.set([1, 2, ['foo', 3.14]], 2);
|
|
4321
|
+
|
|
4322
|
+
const packed = msgpackr.pack(map);
|
|
4323
|
+
const unpacked = msgpackr.unpack(packed);
|
|
4324
|
+
assert.deepEqual(unpacked, { '1,2,3': 1, '1,2,foo,3.14': 2 });
|
|
4325
|
+
});
|
|
4326
|
+
|
|
4248
4327
|
test('utf16 causing expansion', function() {
|
|
4249
4328
|
this.timeout(10000);
|
|
4250
4329
|
let data = {fixstr: 'ᾐᾑᾒᾓᾔᾕᾖᾗᾘᾙᾚᾛᾜᾝ', str8:'ᾐᾑᾒᾓᾔᾕᾖᾗᾘᾙᾚᾛᾜᾝᾐᾑᾒᾓᾔᾕᾖᾗᾘᾙᾚᾛᾜᾝᾐᾑᾒᾓᾔᾕᾖᾗᾘᾙᾚᾛᾜᾝᾐᾑᾒᾓᾔᾕᾖᾗᾘᾙᾚᾛᾜᾝᾐᾑᾒᾓᾔᾕᾖᾗᾘᾙᾚᾛᾜᾝᾐᾑᾒᾓᾔᾕᾖᾗᾘᾙᾚᾛᾜᾝᾐᾑᾒᾓᾔᾕᾖᾗᾘᾙᾚᾛᾜᾝᾐᾑᾒᾓᾔᾕᾖᾗᾘᾙᾚᾛᾜᾝᾐᾑᾒᾓᾔᾕᾖᾗᾘᾙᾚᾛᾜᾝᾐᾑᾒᾓᾔᾕᾖᾗᾘᾙᾚᾛᾜᾝᾐᾑᾒᾓᾔᾕᾖᾗᾘᾙᾚᾛᾜᾝᾐᾑᾒᾓᾔᾕᾖᾗᾘᾙᾚᾛᾜᾝᾐᾑᾒᾓᾔᾕᾖᾗᾘᾙᾚᾛᾜᾝᾐᾑᾒᾓᾔᾕᾖᾗᾘᾙᾚᾛᾜᾝᾐᾑᾒᾓᾔᾕᾖᾗᾘᾙᾚᾛᾜᾝᾐᾑᾒᾓᾔᾕᾖᾗᾘᾙᾚᾛᾜᾝ'};
|