msgpackr 1.9.8 → 1.10.0
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 -7
- 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 -7
- 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 +64 -26
- package/dist/node.cjs.map +1 -1
- package/dist/test.js +93 -26
- package/dist/test.js.map +1 -1
- package/dist/unpack-no-eval.cjs +11 -0
- package/dist/unpack-no-eval.cjs.map +1 -1
- package/index.d.cts +1 -0
- package/index.d.ts +1 -0
- package/pack.js +31 -7
- package/package.json +1 -1
- package/struct.js +22 -19
- package/test-worker.js +3 -0
- package/unpack.js +11 -0
package/README.md
CHANGED
|
@@ -184,6 +184,7 @@ The following options properties can be provided to the Packr or Unpackr constru
|
|
|
184
184
|
* `useTimestamp32` - Encode JS `Date`s in 32-bit format when possible by dropping the milliseconds. This is a more efficient encoding of dates. You can also cause dates to use 32-bit format by manually setting the milliseconds to zero (`date.setMilliseconds(0)`).
|
|
185
185
|
* `sequential` - Encode structures in serialized data, and reference previously encoded structures with expectation that decoder will read the encoded structures in the same order as encoded, with `unpackMultiple`.
|
|
186
186
|
* `largeBigIntToFloat` - If a bigint needs to be encoded that is larger than will fit in 64-bit integers, it will be encoded as a float-64 (otherwise will throw a RangeError).
|
|
187
|
+
* `useBigIntExtension` - If a bigint needs to be encoded that is larger than will fit in 64-bit integers, it will be encoded using a custom extension that supports up to about 1000-bits of integer precision.
|
|
187
188
|
* `encodeUndefinedAsNil` - Encodes a value of `undefined` as a MessagePack `nil`, the same as a `null`.
|
|
188
189
|
* `int64AsType` - This will decode uint64 and int64 numbers as the specified type. The type can be `bigint` (default), `number`, `string`, or `auto` (where range [-2^53...2^53] is represented by number and everything else by a bigint).
|
|
189
190
|
* `onInvalidDate` - This can be provided as function that will be called when an invalid date is provided. The function can throw an error, or return a value that will be encoded in place of the invalid date. If not provided, an invalid date will be encoded as an invalid timestamp (which decodes with msgpackr back to an invalid date).
|
package/dist/index-no-eval.cjs
CHANGED
|
@@ -933,6 +933,17 @@
|
|
|
933
933
|
currentExtensions[0] = () => {}; // notepack defines extension 0 to mean undefined, so use that as the default here
|
|
934
934
|
currentExtensions[0].noBuffer = true;
|
|
935
935
|
|
|
936
|
+
currentExtensions[0x42] = (data) => {
|
|
937
|
+
// decode bigint
|
|
938
|
+
let length = data.length;
|
|
939
|
+
let value = BigInt(data[0] & 0x80 ? data[0] - 0x100 : data[0]);
|
|
940
|
+
for (let i = 1; i < length; i++) {
|
|
941
|
+
value <<= 8n;
|
|
942
|
+
value += BigInt(data[i]);
|
|
943
|
+
}
|
|
944
|
+
return value;
|
|
945
|
+
};
|
|
946
|
+
|
|
936
947
|
let errors = { Error, TypeError, ReferenceError };
|
|
937
948
|
currentExtensions[0x65] = () => {
|
|
938
949
|
let data = read();
|
|
@@ -1207,6 +1218,7 @@
|
|
|
1207
1218
|
}
|
|
1208
1219
|
if (hasSharedUpdate)
|
|
1209
1220
|
hasSharedUpdate = false;
|
|
1221
|
+
let encodingError;
|
|
1210
1222
|
try {
|
|
1211
1223
|
if (packr.randomAccessStructure && value && value.constructor && value.constructor === Object)
|
|
1212
1224
|
writeStruct(value);
|
|
@@ -1257,6 +1269,9 @@
|
|
|
1257
1269
|
return target
|
|
1258
1270
|
}
|
|
1259
1271
|
return target.subarray(start, position) // position can change if we call pack again in saveStructures, so we get the buffer now
|
|
1272
|
+
} catch(error) {
|
|
1273
|
+
encodingError = error;
|
|
1274
|
+
throw error;
|
|
1260
1275
|
} finally {
|
|
1261
1276
|
if (structures) {
|
|
1262
1277
|
resetStructures();
|
|
@@ -1265,12 +1280,14 @@
|
|
|
1265
1280
|
// we can't rely on start/end with REUSE_BUFFER_MODE since they will (probably) change when we save
|
|
1266
1281
|
let returnBuffer = target.subarray(start, position);
|
|
1267
1282
|
let newSharedData = prepareStructures(structures, packr);
|
|
1268
|
-
if (
|
|
1269
|
-
|
|
1270
|
-
|
|
1283
|
+
if (!encodingError) { // TODO: If there is an encoding error, should make the structures as uninitialized so they get rebuilt next time
|
|
1284
|
+
if (packr.saveStructures(newSharedData, newSharedData.isCompatible) === false) {
|
|
1285
|
+
// get updated structures and try again if the update failed
|
|
1286
|
+
return packr.pack(value, encodeOptions)
|
|
1287
|
+
}
|
|
1288
|
+
packr.lastNamedStructuresLength = sharedLength;
|
|
1289
|
+
return returnBuffer
|
|
1271
1290
|
}
|
|
1272
|
-
packr.lastNamedStructuresLength = sharedLength;
|
|
1273
|
-
return returnBuffer
|
|
1274
1291
|
}
|
|
1275
1292
|
}
|
|
1276
1293
|
if (encodeOptions & RESET_BUFFER_MODE)
|
|
@@ -1612,8 +1629,26 @@
|
|
|
1612
1629
|
if (this.largeBigIntToFloat) {
|
|
1613
1630
|
target[position++] = 0xcb;
|
|
1614
1631
|
targetView.setFloat64(position, Number(value));
|
|
1632
|
+
} else if (this.useBigIntExtension && value < 2n**(1023n) && value > -(2n**(1023n))) {
|
|
1633
|
+
target[position++] = 0xc7;
|
|
1634
|
+
position++;
|
|
1635
|
+
target[position++] = 0x42; // "B" for BigInt
|
|
1636
|
+
let bytes = [];
|
|
1637
|
+
let alignedSign;
|
|
1638
|
+
do {
|
|
1639
|
+
let byte = value & 0xffn;
|
|
1640
|
+
alignedSign = (byte & 0x80n) === (value < 0n ? 0x80n : 0n);
|
|
1641
|
+
bytes.push(byte);
|
|
1642
|
+
value >>= 8n;
|
|
1643
|
+
} while (!((value === 0n || value === -1n) && alignedSign));
|
|
1644
|
+
target[position-2] = bytes.length;
|
|
1645
|
+
for (let i = bytes.length; i > 0;) {
|
|
1646
|
+
target[position++] = Number(bytes[--i]);
|
|
1647
|
+
}
|
|
1648
|
+
return
|
|
1615
1649
|
} else {
|
|
1616
|
-
throw new RangeError(value + ' was too large to fit in MessagePack 64-bit integer format,
|
|
1650
|
+
throw new RangeError(value + ' was too large to fit in MessagePack 64-bit integer format, use' +
|
|
1651
|
+
' useBigIntExtension or set largeBigIntToFloat to convert to float-64')
|
|
1617
1652
|
}
|
|
1618
1653
|
}
|
|
1619
1654
|
position += 8;
|
|
@@ -1861,7 +1896,7 @@
|
|
|
1861
1896
|
}
|
|
1862
1897
|
};
|
|
1863
1898
|
const writeStruct = (object, safePrototype) => {
|
|
1864
|
-
let newPosition = writeStructSlots(object, target, position, structures, makeRoom, (value, newPosition, notifySharedUpdate) => {
|
|
1899
|
+
let newPosition = writeStructSlots(object, target, start, position, structures, makeRoom, (value, newPosition, notifySharedUpdate) => {
|
|
1865
1900
|
if (notifySharedUpdate)
|
|
1866
1901
|
return hasSharedUpdate = true;
|
|
1867
1902
|
position = newPosition;
|