msgpackr 1.7.0 → 1.7.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +45 -25
- package/dist/index.js.map +1 -1
- package/dist/index.min.js +49 -48
- package/dist/index.min.js.map +1 -1
- package/dist/node.cjs +47 -27
- package/dist/node.cjs.map +1 -1
- package/dist/test.js +88 -27
- package/dist/test.js.map +1 -1
- package/pack.js +40 -12
- package/package.json +1 -1
- package/struct.js +2 -2
- package/unpack.js +5 -14
package/dist/test.js
CHANGED
|
@@ -190,7 +190,7 @@
|
|
|
190
190
|
|
|
191
191
|
if (position == srcEnd) {
|
|
192
192
|
// finished reading this source, cleanup references
|
|
193
|
-
if (currentStructures
|
|
193
|
+
if (currentStructures && currentStructures.restoreStructures)
|
|
194
194
|
restoreStructures();
|
|
195
195
|
currentStructures = null;
|
|
196
196
|
src = null;
|
|
@@ -205,7 +205,7 @@
|
|
|
205
205
|
// else more to read, but we are reading sequentially, so don't clear source yet
|
|
206
206
|
return result
|
|
207
207
|
} catch(error) {
|
|
208
|
-
if (currentStructures
|
|
208
|
+
if (currentStructures && currentStructures.restoreStructures)
|
|
209
209
|
restoreStructures();
|
|
210
210
|
clearSource();
|
|
211
211
|
if (error instanceof RangeError || error.message.startsWith('Unexpected end of buffer') || position > srcEnd) {
|
|
@@ -826,7 +826,7 @@
|
|
|
826
826
|
})
|
|
827
827
|
}
|
|
828
828
|
else
|
|
829
|
-
throw new Error('Unknown extension type ' + type)
|
|
829
|
+
throw new Error('Unknown extension type ' + type)``
|
|
830
830
|
}
|
|
831
831
|
|
|
832
832
|
var keyCache = new Array(4096);
|
|
@@ -841,7 +841,7 @@
|
|
|
841
841
|
return readFixedString(length)
|
|
842
842
|
} else { // not cacheable, go back and do a standard read
|
|
843
843
|
position--;
|
|
844
|
-
return read()
|
|
844
|
+
return read().toString()
|
|
845
845
|
}
|
|
846
846
|
let key = ((length << 5) ^ (length > 1 ? dataView.getUint16(position) : length > 0 ? src[position] : 0)) & 0xfff;
|
|
847
847
|
let entry = keyCache[key];
|
|
@@ -895,16 +895,7 @@
|
|
|
895
895
|
|
|
896
896
|
// the registration of the record definition extension (as "r")
|
|
897
897
|
const recordDefinition = (id, highByte) => {
|
|
898
|
-
let structure;
|
|
899
|
-
if (currentUnpackr.freezeData) {
|
|
900
|
-
currentUnpackr.freezeData = false;
|
|
901
|
-
try {
|
|
902
|
-
structure = read();
|
|
903
|
-
} finally {
|
|
904
|
-
currentUnpackr.freezeData = true;
|
|
905
|
-
}
|
|
906
|
-
} else
|
|
907
|
-
structure = read();
|
|
898
|
+
let structure = read().map(property => property.toString()); // ensure that all keys are strings and that the array is mutable
|
|
908
899
|
let firstByte = id;
|
|
909
900
|
if (highByte !== undefined) {
|
|
910
901
|
id = id < 32 ? -((highByte << 5) + id) : ((highByte << 5) + id);
|
|
@@ -1180,19 +1171,45 @@
|
|
|
1180
1171
|
writeStruct(value);
|
|
1181
1172
|
else
|
|
1182
1173
|
pack(value);
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
packr.offset = position$1; // update the offset so next serialization doesn't write over our buffer, but can continue writing to same buffer sequentially
|
|
1174
|
+
let lastBundle = bundledStrings$1;
|
|
1175
|
+
if (bundledStrings$1)
|
|
1176
|
+
writeBundles(start, pack, 0);
|
|
1187
1177
|
if (referenceMap && referenceMap.idsToInsert) {
|
|
1188
|
-
|
|
1178
|
+
let idsToInsert = referenceMap.idsToInsert.sort((a, b) => a.offset > b.offset ? 1 : -1);
|
|
1179
|
+
let i = idsToInsert.length;
|
|
1180
|
+
let incrementPosition = -1;
|
|
1181
|
+
while (lastBundle && i > 0) {
|
|
1182
|
+
let insertionPoint = idsToInsert[--i].offset + start;
|
|
1183
|
+
if (insertionPoint < (lastBundle.stringsPosition + start) && incrementPosition === -1)
|
|
1184
|
+
incrementPosition = 0;
|
|
1185
|
+
if (insertionPoint > (lastBundle.position + start)) {
|
|
1186
|
+
if (incrementPosition >= 0)
|
|
1187
|
+
incrementPosition += 6;
|
|
1188
|
+
} else {
|
|
1189
|
+
if (incrementPosition >= 0) {
|
|
1190
|
+
// update the bundle reference now
|
|
1191
|
+
targetView.setUint32(lastBundle.position + start,
|
|
1192
|
+
targetView.getUint32(lastBundle.position + start) + incrementPosition);
|
|
1193
|
+
incrementPosition = -1; // reset
|
|
1194
|
+
}
|
|
1195
|
+
lastBundle = lastBundle.previous;
|
|
1196
|
+
i++;
|
|
1197
|
+
}
|
|
1198
|
+
}
|
|
1199
|
+
if (incrementPosition >= 0 && lastBundle) {
|
|
1200
|
+
// update the bundle reference now
|
|
1201
|
+
targetView.setUint32(lastBundle.position + start,
|
|
1202
|
+
targetView.getUint32(lastBundle.position + start) + incrementPosition);
|
|
1203
|
+
}
|
|
1204
|
+
position$1 += idsToInsert.length * 6;
|
|
1189
1205
|
if (position$1 > safeEnd)
|
|
1190
1206
|
makeRoom(position$1);
|
|
1191
1207
|
packr.offset = position$1;
|
|
1192
|
-
let serialized = insertIds(target.subarray(start, position$1),
|
|
1208
|
+
let serialized = insertIds(target.subarray(start, position$1), idsToInsert);
|
|
1193
1209
|
referenceMap = null;
|
|
1194
1210
|
return serialized
|
|
1195
1211
|
}
|
|
1212
|
+
packr.offset = position$1; // update the offset so next serialization doesn't write over our buffer, but can continue writing to same buffer sequentially
|
|
1196
1213
|
if (encodeOptions & REUSE_BUFFER_MODE) {
|
|
1197
1214
|
target.start = start;
|
|
1198
1215
|
target.end = position$1;
|
|
@@ -1249,13 +1266,15 @@
|
|
|
1249
1266
|
let maxBytes = (bundledStrings$1[0] ? bundledStrings$1[0].length * 3 + bundledStrings$1[1].length : 0) + 10;
|
|
1250
1267
|
if (position$1 + maxBytes > safeEnd)
|
|
1251
1268
|
target = makeRoom(position$1 + maxBytes);
|
|
1252
|
-
|
|
1269
|
+
let lastBundle;
|
|
1270
|
+
if (bundledStrings$1.position) { // here we use the 0x62 extension to write the last bundle and reserve space for the reference pointer to the next/current bundle
|
|
1271
|
+
lastBundle = bundledStrings$1;
|
|
1253
1272
|
target[position$1] = 0xc8; // ext 16
|
|
1254
1273
|
position$1 += 3; // reserve for the writing bundle size
|
|
1255
1274
|
target[position$1++] = 0x62; // 'b'
|
|
1256
1275
|
extStart = position$1 - start;
|
|
1257
1276
|
position$1 += 4; // reserve for writing bundle reference
|
|
1258
|
-
writeBundles(start, pack); // write the last bundles
|
|
1277
|
+
writeBundles(start, pack, 0); // write the last bundles
|
|
1259
1278
|
targetView.setUint16(extStart + start - 3, position$1 - start - extStart);
|
|
1260
1279
|
} else { // here we use the 0x62 extension just to reserve the space for the reference pointer to the bundle (will be updated once the bundle is written)
|
|
1261
1280
|
target[position$1++] = 0xd6; // fixext 4
|
|
@@ -1264,6 +1283,7 @@
|
|
|
1264
1283
|
position$1 += 4; // reserve for writing bundle reference
|
|
1265
1284
|
}
|
|
1266
1285
|
bundledStrings$1 = ['', '']; // create new ones
|
|
1286
|
+
bundledStrings$1.previous = lastBundle;
|
|
1267
1287
|
bundledStrings$1.size = 0;
|
|
1268
1288
|
bundledStrings$1.position = extStart;
|
|
1269
1289
|
}
|
|
@@ -1953,7 +1973,6 @@
|
|
|
1953
1973
|
let nextId;
|
|
1954
1974
|
let distanceToMove = idsToInsert.length * 6;
|
|
1955
1975
|
let lastEnd = serialized.length - distanceToMove;
|
|
1956
|
-
idsToInsert.sort((a, b) => a.offset > b.offset ? 1 : -1);
|
|
1957
1976
|
while (nextId = idsToInsert.pop()) {
|
|
1958
1977
|
let offset = nextId.offset;
|
|
1959
1978
|
let id = nextId.id;
|
|
@@ -1971,9 +1990,10 @@
|
|
|
1971
1990
|
return serialized
|
|
1972
1991
|
}
|
|
1973
1992
|
|
|
1974
|
-
function writeBundles(start, pack) {
|
|
1993
|
+
function writeBundles(start, pack, incrementPosition) {
|
|
1975
1994
|
if (bundledStrings$1.length > 0) {
|
|
1976
|
-
targetView.setUint32(bundledStrings$1.position + start, position$1 - bundledStrings$1.position - start);
|
|
1995
|
+
targetView.setUint32(bundledStrings$1.position + start, position$1 + incrementPosition - bundledStrings$1.position - start);
|
|
1996
|
+
bundledStrings$1.stringsPosition = position$1 - start;
|
|
1977
1997
|
let writeStrings = bundledStrings$1;
|
|
1978
1998
|
bundledStrings$1 = null;
|
|
1979
1999
|
pack(writeStrings[0]);
|
|
@@ -2450,7 +2470,7 @@
|
|
|
2450
2470
|
case 27: recordId = src[position++] + (src[position++] << 8) + (src[position++] << 16) + (src[position++] << 24); break;
|
|
2451
2471
|
}
|
|
2452
2472
|
}
|
|
2453
|
-
let structure = unpackr.typedStructs
|
|
2473
|
+
let structure = unpackr.typedStructs && unpackr.typedStructs[recordId];
|
|
2454
2474
|
if (!structure) {
|
|
2455
2475
|
// copy src buffer because getStructures will override it
|
|
2456
2476
|
src = Uint8Array.prototype.slice.call(src, position, srcEnd);
|
|
@@ -2742,7 +2762,7 @@
|
|
|
2742
2762
|
packr._mergeStructures(existing);
|
|
2743
2763
|
return compatible;
|
|
2744
2764
|
};
|
|
2745
|
-
packr.lastTypedStructuresLength = packr.typedStructs
|
|
2765
|
+
packr.lastTypedStructuresLength = packr.typedStructs && packr.typedStructs.length;
|
|
2746
2766
|
return structures;
|
|
2747
2767
|
}
|
|
2748
2768
|
|
|
@@ -3159,6 +3179,47 @@
|
|
|
3159
3179
|
assert.equal(deserialized.uint16Array[0], 3);
|
|
3160
3180
|
assert.equal(deserialized.uint16Array[1], 4);
|
|
3161
3181
|
});
|
|
3182
|
+
test('big bundledStrings', function() {
|
|
3183
|
+
const MSGPACK_OPTIONS = {bundleStrings: true};
|
|
3184
|
+
const packer = new Packr$1(MSGPACK_OPTIONS);
|
|
3185
|
+
const unpacker = new Unpackr$1(MSGPACK_OPTIONS);
|
|
3186
|
+
|
|
3187
|
+
const payload = {
|
|
3188
|
+
output: [
|
|
3189
|
+
{
|
|
3190
|
+
url: 'https://www.example.com/',
|
|
3191
|
+
},
|
|
3192
|
+
],
|
|
3193
|
+
};
|
|
3194
|
+
|
|
3195
|
+
for (let i = 0; i < 10000; i++) {
|
|
3196
|
+
payload.output.push(payload.output[0]);
|
|
3197
|
+
}
|
|
3198
|
+
let deserialized = unpacker.unpack(packer.pack(payload));
|
|
3199
|
+
assert.equal(deserialized.output[0].url, payload.output[0].url);
|
|
3200
|
+
});
|
|
3201
|
+
test('structured clone with bundled strings', function() {
|
|
3202
|
+
const packer = new Packr$1({
|
|
3203
|
+
structuredClone: true, // both options must be enabled
|
|
3204
|
+
bundleStrings: true,
|
|
3205
|
+
});
|
|
3206
|
+
|
|
3207
|
+
const v = {};
|
|
3208
|
+
|
|
3209
|
+
let shared = {
|
|
3210
|
+
name1: v,
|
|
3211
|
+
name2: v,
|
|
3212
|
+
};
|
|
3213
|
+
|
|
3214
|
+
let deserialized = packer.unpack(packer.pack(shared));
|
|
3215
|
+
assert.equal(deserialized.name1, deserialized.name2);
|
|
3216
|
+
|
|
3217
|
+
shared = {};
|
|
3218
|
+
shared.aaaa = shared; // key length >= 4
|
|
3219
|
+
|
|
3220
|
+
deserialized = packer.unpack(packer.pack(shared));
|
|
3221
|
+
assert.equal(deserialized.aaaa, deserialized);
|
|
3222
|
+
});
|
|
3162
3223
|
|
|
3163
3224
|
test('object without prototype', function(){
|
|
3164
3225
|
var data = Object.create(null);
|