msgpackr 1.7.0-alpha4 → 1.7.0-alpha7
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 +6 -4
- package/dist/index.js.map +1 -1
- package/dist/index.min.js +59 -59
- package/dist/index.min.js.map +1 -1
- package/dist/node.cjs +89 -33
- package/dist/node.cjs.map +1 -1
- package/dist/test.js +95 -35
- package/dist/test.js.map +1 -1
- package/package.json +1 -1
- package/struct.js +78 -28
- package/unpack.js +11 -6
package/package.json
CHANGED
package/struct.js
CHANGED
|
@@ -41,11 +41,13 @@ const ASCII = 3; // the MIBenum from https://www.iana.org/assignments/character-
|
|
|
41
41
|
const NUMBER = 0;
|
|
42
42
|
const UTF8 = 2;
|
|
43
43
|
const OBJECT_DATA = 1;
|
|
44
|
+
const DATE = 16;
|
|
44
45
|
const TYPE_NAMES = ['num', 'object', 'string', 'ascii'];
|
|
46
|
+
TYPE_NAMES[DATE] = 'date';
|
|
45
47
|
const float32Headers = [false, true, true, false, false, true, true, false];
|
|
46
48
|
let updatedPosition;
|
|
47
49
|
const hasNodeBuffer = typeof Buffer !== 'undefined'
|
|
48
|
-
let textEncoder
|
|
50
|
+
let textEncoder, currentSource;
|
|
49
51
|
try {
|
|
50
52
|
textEncoder = new TextEncoder()
|
|
51
53
|
} catch (error) {}
|
|
@@ -89,7 +91,7 @@ function writeStruct(object, target, position, structures, makeRoom, pack, packr
|
|
|
89
91
|
return 0;
|
|
90
92
|
position += headerSize;
|
|
91
93
|
let queuedReferences = [];
|
|
92
|
-
let
|
|
94
|
+
let usedAscii0;
|
|
93
95
|
let keyIndex = 0;
|
|
94
96
|
for (let key in object) {
|
|
95
97
|
let value = object[key];
|
|
@@ -105,7 +107,8 @@ function writeStruct(object, target, position, structures, makeRoom, pack, packr
|
|
|
105
107
|
string16: null,
|
|
106
108
|
object16: null,
|
|
107
109
|
num32: null,
|
|
108
|
-
float64: null
|
|
110
|
+
float64: null,
|
|
111
|
+
date64: null
|
|
109
112
|
};
|
|
110
113
|
}
|
|
111
114
|
if (position > safeEnd) {
|
|
@@ -198,25 +201,47 @@ function writeStruct(object, target, position, structures, makeRoom, pack, packr
|
|
|
198
201
|
refPosition += encodeUtf8(target, value, refPosition);
|
|
199
202
|
isNotAscii = refPosition - strStart > strLength;
|
|
200
203
|
}
|
|
201
|
-
if (refOffset <
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
204
|
+
if (refOffset < 0xa0 || (refOffset < 0xf6 && (nextTransition.ascii8 || nextTransition.string8))) {
|
|
205
|
+
// short strings
|
|
206
|
+
if (isNotAscii) {
|
|
207
|
+
if (!(transition = nextTransition.string8)) {
|
|
208
|
+
if (typedStructs.length > 10 && (transition = nextTransition.ascii8)) {
|
|
209
|
+
// we can safely change ascii to utf8 in place since they are compatible
|
|
210
|
+
transition.__type = UTF8;
|
|
211
|
+
nextTransition.ascii8 = null;
|
|
212
|
+
nextTransition.string8 = transition;
|
|
213
|
+
pack(null, 0, true); // special call to notify that structures have been updated
|
|
214
|
+
} else {
|
|
215
|
+
transition = createTypeTransition(nextTransition, UTF8, 1);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
} else if (refOffset === 0 && !usedAscii0) {
|
|
219
|
+
usedAscii0 = true;
|
|
220
|
+
transition = nextTransition.ascii0 || createTypeTransition(nextTransition, ASCII, 0);
|
|
221
|
+
break; // don't increment position
|
|
222
|
+
}// else ascii:
|
|
223
|
+
else if (!(transition = nextTransition.ascii8) && !(typedStructs.length > 10 && (transition = nextTransition.string8)))
|
|
224
|
+
transition = createTypeTransition(nextTransition, ASCII, 1);
|
|
206
225
|
target[position++] = refOffset;
|
|
207
226
|
} else {
|
|
208
|
-
|
|
227
|
+
// TODO: Enable ascii16 at some point, but get the logic right
|
|
228
|
+
//if (isNotAscii)
|
|
209
229
|
transition = nextTransition.string16 || createTypeTransition(nextTransition, UTF8, 2);
|
|
210
|
-
else
|
|
211
|
-
transition = nextTransition.ascii16 || createTypeTransition(nextTransition, ASCII, 2);
|
|
230
|
+
//else
|
|
231
|
+
//transition = nextTransition.ascii16 || createTypeTransition(nextTransition, ASCII, 2);
|
|
212
232
|
targetView.setUint16(position, refOffset, true);
|
|
213
233
|
position += 2;
|
|
214
234
|
}
|
|
215
235
|
break;
|
|
216
236
|
case 'object':
|
|
217
237
|
if (value) {
|
|
218
|
-
|
|
219
|
-
|
|
238
|
+
if (value.constructor === Date) {
|
|
239
|
+
transition = nextTransition.date64 || createTypeTransition(nextTransition, DATE, 8);
|
|
240
|
+
targetView.setFloat64(position, value.getTime(), true);
|
|
241
|
+
position += 8;
|
|
242
|
+
} else {
|
|
243
|
+
queuedReferences.push(key, value, keyIndex);
|
|
244
|
+
}
|
|
220
245
|
break;
|
|
221
246
|
} else { // null
|
|
222
247
|
nextTransition = anyType(nextTransition, position, targetView, -10); // match CBOR with this
|
|
@@ -306,7 +331,7 @@ function writeStruct(object, target, position, structures, makeRoom, pack, packr
|
|
|
306
331
|
targetView.setUint32(position, refOffset, true);
|
|
307
332
|
position += 4;
|
|
308
333
|
}
|
|
309
|
-
} else {
|
|
334
|
+
} else { // null or undefined
|
|
310
335
|
transition = nextTransition.object16 || createTypeTransition(nextTransition, OBJECT_DATA, 2);
|
|
311
336
|
targetView.setInt16(position, value === null ? -10 : -9, true);
|
|
312
337
|
position += 2;
|
|
@@ -434,7 +459,8 @@ function onLoadedStructures(sharedData) {
|
|
|
434
459
|
string16: null,
|
|
435
460
|
object16: null,
|
|
436
461
|
num32: null,
|
|
437
|
-
float64: null
|
|
462
|
+
float64: null,
|
|
463
|
+
date64: null,
|
|
438
464
|
};
|
|
439
465
|
}
|
|
440
466
|
transition = createTypeTransition(nextTransition, type, size);
|
|
@@ -478,12 +504,13 @@ function readStruct(src, position, srcEnd, unpackr) {
|
|
|
478
504
|
construct = structure.construct = function LazyObject() {
|
|
479
505
|
}
|
|
480
506
|
var prototype = construct.prototype;
|
|
507
|
+
let properties = [];
|
|
481
508
|
Object.defineProperty(prototype, 'toJSON', {
|
|
482
|
-
|
|
509
|
+
value() {
|
|
483
510
|
// return an enumerable object with own properties to JSON stringify
|
|
484
511
|
let resolved = {};
|
|
485
|
-
for (let i = 0, l =
|
|
486
|
-
let key =
|
|
512
|
+
for (let i = 0, l = properties.length; i < l; i++) {
|
|
513
|
+
let key = properties[i].key;
|
|
487
514
|
resolved[key] = this[key];
|
|
488
515
|
}
|
|
489
516
|
return resolved;
|
|
@@ -492,7 +519,6 @@ function readStruct(src, position, srcEnd, unpackr) {
|
|
|
492
519
|
});
|
|
493
520
|
let currentOffset = 0;
|
|
494
521
|
let lastRefProperty;
|
|
495
|
-
let properties = [];
|
|
496
522
|
for (let i = 0, l = structure.length; i < l; i++) {
|
|
497
523
|
let definition = structure[i];
|
|
498
524
|
let [ type, size, key, enumerationOffset ] = definition;
|
|
@@ -612,7 +638,12 @@ function readStruct(src, position, srcEnd, unpackr) {
|
|
|
612
638
|
if (type === UTF8) {
|
|
613
639
|
return src.toString('utf8', ref + refStart, end + refStart);
|
|
614
640
|
} else {
|
|
615
|
-
|
|
641
|
+
currentSource = source;
|
|
642
|
+
try {
|
|
643
|
+
return unpackr.unpack(src, { start: ref + refStart, end: end + refStart });
|
|
644
|
+
} finally {
|
|
645
|
+
currentSource = null;
|
|
646
|
+
}
|
|
616
647
|
}
|
|
617
648
|
};
|
|
618
649
|
break;
|
|
@@ -660,6 +691,16 @@ function readStruct(src, position, srcEnd, unpackr) {
|
|
|
660
691
|
};
|
|
661
692
|
break;
|
|
662
693
|
}
|
|
694
|
+
break;
|
|
695
|
+
case DATE:
|
|
696
|
+
get = function () {
|
|
697
|
+
let source = this[sourceSymbol];
|
|
698
|
+
let src = source.src;
|
|
699
|
+
let dataView = src.dataView || (src.dataView = new DataView(src.buffer, src.byteOffset, src.byteLength));
|
|
700
|
+
return new Date(dataView.getFloat64(source.position + property.offset, true));
|
|
701
|
+
};
|
|
702
|
+
break;
|
|
703
|
+
|
|
663
704
|
}
|
|
664
705
|
property.get = get;
|
|
665
706
|
}
|
|
@@ -684,14 +725,23 @@ function toConstant(code) {
|
|
|
684
725
|
}
|
|
685
726
|
throw new Error('Unknown constant');
|
|
686
727
|
}
|
|
728
|
+
|
|
729
|
+
function saveState() {
|
|
730
|
+
if (currentSource) {
|
|
731
|
+
currentSource.src = Uint8Array.prototype.slice.call(currentSource.src, currentSource.position, currentSource.srcEnd);
|
|
732
|
+
currentSource.position = 0;
|
|
733
|
+
currentSource.srcEnd = currentSource.src.length;
|
|
734
|
+
}
|
|
735
|
+
}
|
|
687
736
|
function prepareStructures(structures, packr) {
|
|
688
|
-
if (
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
737
|
+
if (packr.typedStructs) {
|
|
738
|
+
let structMap = new Map();
|
|
739
|
+
structMap.set('named', structures);
|
|
740
|
+
structMap.set('typed', packr.typedStructs);
|
|
741
|
+
structures = structMap;
|
|
742
|
+
}
|
|
693
743
|
let lastTypedStructuresLength = packr.lastTypedStructuresLength || 0;
|
|
694
|
-
|
|
744
|
+
structures.isCompatible = existing => {
|
|
695
745
|
let compatible = true;
|
|
696
746
|
if (existing instanceof Map) {
|
|
697
747
|
let named = existing.get('named') || [];
|
|
@@ -709,8 +759,8 @@ function prepareStructures(structures, packr) {
|
|
|
709
759
|
return compatible;
|
|
710
760
|
};
|
|
711
761
|
packr.lastTypedStructuresLength = packr.typedStructs?.length;
|
|
712
|
-
return
|
|
762
|
+
return structures;
|
|
713
763
|
}
|
|
714
764
|
|
|
715
|
-
setReadStruct(readStruct, onLoadedStructures);
|
|
765
|
+
setReadStruct(readStruct, onLoadedStructures, saveState);
|
|
716
766
|
|
package/unpack.js
CHANGED
|
@@ -28,7 +28,7 @@ export const C1 = new C1Type()
|
|
|
28
28
|
C1.name = 'MessagePack 0xC1'
|
|
29
29
|
var sequentialMode = false
|
|
30
30
|
var inlineObjectReadThreshold = 2
|
|
31
|
-
var readStruct, onLoadedStructures
|
|
31
|
+
var readStruct, onLoadedStructures, onSaveState
|
|
32
32
|
try {
|
|
33
33
|
new Function('')
|
|
34
34
|
} catch(error) {
|
|
@@ -95,7 +95,7 @@ export class Unpackr {
|
|
|
95
95
|
currentUnpackr = this
|
|
96
96
|
if (this.structures) {
|
|
97
97
|
currentStructures = this.structures
|
|
98
|
-
return checkedRead()
|
|
98
|
+
return checkedRead(options)
|
|
99
99
|
} else if (!currentStructures || currentStructures.length > 0) {
|
|
100
100
|
currentStructures = []
|
|
101
101
|
}
|
|
@@ -104,7 +104,7 @@ export class Unpackr {
|
|
|
104
104
|
if (!currentStructures || currentStructures.length > 0)
|
|
105
105
|
currentStructures = []
|
|
106
106
|
}
|
|
107
|
-
return checkedRead()
|
|
107
|
+
return checkedRead(options)
|
|
108
108
|
}
|
|
109
109
|
unpackMultiple(source, forEach) {
|
|
110
110
|
let values, lastPosition = 0
|
|
@@ -173,7 +173,7 @@ export class Unpackr {
|
|
|
173
173
|
export function getPosition() {
|
|
174
174
|
return position
|
|
175
175
|
}
|
|
176
|
-
export function checkedRead() {
|
|
176
|
+
export function checkedRead(options) {
|
|
177
177
|
try {
|
|
178
178
|
if (!currentUnpackr.trusted && !sequentialMode) {
|
|
179
179
|
let sharedLength = currentStructures.sharedLength || 0
|
|
@@ -183,6 +183,8 @@ export function checkedRead() {
|
|
|
183
183
|
let result
|
|
184
184
|
if (currentUnpackr.randomAccessStructure && src[position] < 0x40 && src[position] >= 0x20 && readStruct) {
|
|
185
185
|
result = readStruct(src, position, srcEnd, currentUnpackr)
|
|
186
|
+
if (!(options && options.lazy) && result)
|
|
187
|
+
result = result.toJSON()
|
|
186
188
|
position = srcEnd
|
|
187
189
|
} else
|
|
188
190
|
result = read()
|
|
@@ -206,7 +208,7 @@ export function checkedRead() {
|
|
|
206
208
|
// else more to read, but we are reading sequentially, so don't clear source yet
|
|
207
209
|
return result
|
|
208
210
|
} catch(error) {
|
|
209
|
-
if (currentStructures
|
|
211
|
+
if (currentStructures?.restoreStructures)
|
|
210
212
|
restoreStructures()
|
|
211
213
|
clearSource()
|
|
212
214
|
if (error instanceof RangeError || error.message.startsWith('Unexpected end of buffer') || position > srcEnd) {
|
|
@@ -1030,6 +1032,8 @@ currentExtensions[0xff] = (data) => {
|
|
|
1030
1032
|
// currentExtensions[0x52] = () =>
|
|
1031
1033
|
|
|
1032
1034
|
function saveState(callback) {
|
|
1035
|
+
if (onSaveState)
|
|
1036
|
+
onSaveState();
|
|
1033
1037
|
let savedSrcEnd = srcEnd
|
|
1034
1038
|
let savedPosition = position
|
|
1035
1039
|
let savedStringPosition = stringPosition
|
|
@@ -1099,7 +1103,8 @@ export function roundFloat32(float32Number) {
|
|
|
1099
1103
|
let multiplier = mult10[((u8Array[3] & 0x7f) << 1) | (u8Array[2] >> 7)]
|
|
1100
1104
|
return ((multiplier * float32Number + (float32Number > 0 ? 0.5 : -0.5)) >> 0) / multiplier
|
|
1101
1105
|
}
|
|
1102
|
-
export function setReadStruct(updatedReadStruct, loadedStructs) {
|
|
1106
|
+
export function setReadStruct(updatedReadStruct, loadedStructs, saveState) {
|
|
1103
1107
|
readStruct = updatedReadStruct;
|
|
1104
1108
|
onLoadedStructures = loadedStructs;
|
|
1109
|
+
onSaveState = saveState;
|
|
1105
1110
|
}
|