cbor-x 1.0.0 → 1.2.1
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 -2
- package/decode.d.ts +1 -0
- package/decode.js +59 -20
- package/dist/index.js +158 -106
- package/dist/index.js.map +1 -0
- package/dist/index.min.js +71 -109
- package/dist/node-index.js +93 -0
- package/dist/node.cjs +158 -106
- package/dist/test.js +56 -3
- package/encode.js +94 -81
- package/package.json +1 -1
package/encode.js
CHANGED
|
@@ -38,12 +38,18 @@ export class Encoder extends Decoder {
|
|
|
38
38
|
} : false
|
|
39
39
|
|
|
40
40
|
let encoder = this
|
|
41
|
-
let
|
|
41
|
+
let hasSharedStructures = options.structures || options.saveStructures
|
|
42
|
+
let maxSharedStructures = options.maxSharedStructures
|
|
43
|
+
if (maxSharedStructures == null)
|
|
44
|
+
maxSharedStructures = hasSharedStructures ? 128 : 0
|
|
45
|
+
if (maxSharedStructures > 8190)
|
|
46
|
+
throw new Error('Maximum maxSharedStructure is 8190')
|
|
42
47
|
let isSequential = options.sequential
|
|
43
48
|
if (isSequential) {
|
|
44
49
|
maxSharedStructures = 0
|
|
45
|
-
this.structures = []
|
|
46
50
|
}
|
|
51
|
+
if (!this.structures)
|
|
52
|
+
this.structures = []
|
|
47
53
|
if (this.saveStructures)
|
|
48
54
|
this.saveShared = this.saveStructures
|
|
49
55
|
let samplingPackedValues, packedObjectMap, sharedValues = options.sharedValues
|
|
@@ -91,6 +97,10 @@ export class Encoder extends Decoder {
|
|
|
91
97
|
} else if (encodeOptions === REUSE_BUFFER_MODE)
|
|
92
98
|
position = (position + 7) & 0x7ffffff8 // Word align to make any future copying of this buffer faster
|
|
93
99
|
start = position
|
|
100
|
+
if (encoder.useSelfDescribedHeader) {
|
|
101
|
+
targetView.setUint32(position, 0xd9d9f700) // tag two byte, then self-descriptive tag
|
|
102
|
+
position += 3
|
|
103
|
+
}
|
|
94
104
|
referenceMap = encoder.structuredClone ? new Map() : null
|
|
95
105
|
if (encoder.bundleStrings && typeof value !== 'string') {
|
|
96
106
|
bundledStrings = []
|
|
@@ -124,6 +134,8 @@ export class Encoder extends Decoder {
|
|
|
124
134
|
continue
|
|
125
135
|
let nextTransition, transition = sharedStructures.transitions
|
|
126
136
|
for (let j = 0, l = keys.length; j < l; j++) {
|
|
137
|
+
if (transition[RECORD_SYMBOL] === undefined)
|
|
138
|
+
transition[RECORD_SYMBOL] = i
|
|
127
139
|
let key = keys[j]
|
|
128
140
|
nextTransition = transition[key]
|
|
129
141
|
if (!nextTransition) {
|
|
@@ -131,7 +143,7 @@ export class Encoder extends Decoder {
|
|
|
131
143
|
}
|
|
132
144
|
transition = nextTransition
|
|
133
145
|
}
|
|
134
|
-
transition[RECORD_SYMBOL] = i
|
|
146
|
+
transition[RECORD_SYMBOL] = i | 0x100000
|
|
135
147
|
}
|
|
136
148
|
}
|
|
137
149
|
if (!isSequential)
|
|
@@ -183,11 +195,13 @@ export class Encoder extends Decoder {
|
|
|
183
195
|
target.end = position
|
|
184
196
|
return target
|
|
185
197
|
}
|
|
186
|
-
return target.subarray(start, position) // position can change if we call
|
|
198
|
+
return target.subarray(start, position) // position can change if we call encode again in saveShared, so we get the buffer now
|
|
187
199
|
} finally {
|
|
188
200
|
if (sharedStructures) {
|
|
189
201
|
if (serializationsSinceTransitionRebuild < 10)
|
|
190
202
|
serializationsSinceTransitionRebuild++
|
|
203
|
+
if (sharedStructures.length > maxSharedStructures)
|
|
204
|
+
sharedStructures.length = maxSharedStructures
|
|
191
205
|
if (transitionsCount > 10000) {
|
|
192
206
|
// force a rebuild occasionally after a lot of transitions so it can get cleaned up
|
|
193
207
|
sharedStructures.transitions = null
|
|
@@ -200,6 +214,7 @@ export class Encoder extends Decoder {
|
|
|
200
214
|
recordIdsToRemove[i][RECORD_SYMBOL] = undefined
|
|
201
215
|
}
|
|
202
216
|
recordIdsToRemove = []
|
|
217
|
+
//sharedStructures.nextId = maxSharedStructures
|
|
203
218
|
}
|
|
204
219
|
}
|
|
205
220
|
if (hasSharedUpdate && encoder.saveShared) {
|
|
@@ -499,7 +514,9 @@ export class Encoder extends Decoder {
|
|
|
499
514
|
let extensionClass = extensionClasses[i]
|
|
500
515
|
if (value instanceof extensionClass) {
|
|
501
516
|
let extension = extensions[i]
|
|
502
|
-
let tag = extension.tag
|
|
517
|
+
let tag = extension.tag
|
|
518
|
+
if (tag == undefined)
|
|
519
|
+
tag = extension.getTag && extension.getTag(value)
|
|
503
520
|
if (tag < 0x18) {
|
|
504
521
|
target[position++] = 0xc0 | tag
|
|
505
522
|
} else if (tag < 0x100) {
|
|
@@ -611,88 +628,74 @@ export class Encoder extends Decoder {
|
|
|
611
628
|
target[objectOffset++ + start] = size >> 8
|
|
612
629
|
target[objectOffset + start] = size & 0xff
|
|
613
630
|
} :
|
|
614
|
-
|
|
615
|
-
/* sharedStructures ? // For highly stable structures, using for-in can a little bit faster
|
|
616
631
|
(object, safePrototype) => {
|
|
617
632
|
let nextTransition, transition = structures.transitions || (structures.transitions = Object.create(null))
|
|
618
|
-
let
|
|
619
|
-
let
|
|
620
|
-
|
|
621
|
-
|
|
633
|
+
let newTransitions = 0
|
|
634
|
+
let length = 0
|
|
635
|
+
let parentRecordId
|
|
636
|
+
let keys
|
|
637
|
+
if (this.keyMap) {
|
|
638
|
+
keys = Object.keys(object).map(k => this.encodeKey(k))
|
|
639
|
+
length = keys.length
|
|
640
|
+
for (let i = 0; i < length; i++) {
|
|
641
|
+
let key = keys[i]
|
|
622
642
|
nextTransition = transition[key]
|
|
623
643
|
if (!nextTransition) {
|
|
624
644
|
nextTransition = transition[key] = Object.create(null)
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
nextTransition.__keys__ = keys.slice(0, i + 1)
|
|
636
|
-
}
|
|
645
|
+
newTransitions++
|
|
646
|
+
}
|
|
647
|
+
transition = nextTransition
|
|
648
|
+
}
|
|
649
|
+
} else {
|
|
650
|
+
for (let key in object) if (safePrototype || object.hasOwnProperty(key)) {
|
|
651
|
+
nextTransition = transition[key]
|
|
652
|
+
if (!nextTransition) {
|
|
653
|
+
if (transition[RECORD_SYMBOL] & 0x100000) {// this indicates it is a brancheable/extendable terminal node, so we will use this record id and extend it
|
|
654
|
+
parentRecordId = transition[RECORD_SYMBOL] & 0xffff
|
|
637
655
|
}
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
target.copy(target, )
|
|
641
|
-
objectOffset
|
|
656
|
+
nextTransition = transition[key] = Object.create(null)
|
|
657
|
+
newTransitions++
|
|
642
658
|
}
|
|
643
659
|
transition = nextTransition
|
|
644
|
-
|
|
645
|
-
}
|
|
646
|
-
}
|
|
647
|
-
let id = transition.id
|
|
648
|
-
if (!id) {
|
|
649
|
-
id = transition.id = structures.push(transition.__keys__) + 63
|
|
650
|
-
if (sharedStructures.onUpdate)
|
|
651
|
-
sharedStructures.onUpdate(id, transition.__keys__)
|
|
652
|
-
}
|
|
653
|
-
target[objectOffset + start] = id
|
|
654
|
-
}*/
|
|
655
|
-
(object) => {
|
|
656
|
-
let keys = Object.keys(object)
|
|
657
|
-
let vals = Object.values(object)
|
|
658
|
-
if (this.keyMap) keys = keys.map(k => this.encodeKey(k))
|
|
659
|
-
let nextTransition, transition = structures.transitions || (structures.transitions = Object.create(null))
|
|
660
|
-
let newTransitions = 0
|
|
661
|
-
let length = keys.length
|
|
662
|
-
//let parentRecordId
|
|
663
|
-
for (let i = 0; i < length; i++) {
|
|
664
|
-
//if (!parentRecordId)
|
|
665
|
-
let key = keys[i]
|
|
666
|
-
// parentRecordId = transition[RECORD_SYMBOL]
|
|
667
|
-
nextTransition = transition[key]
|
|
668
|
-
if (!nextTransition) {
|
|
669
|
-
nextTransition = transition[key] = Object.create(null)
|
|
670
|
-
newTransitions++
|
|
660
|
+
length++
|
|
671
661
|
}
|
|
672
|
-
transition = nextTransition
|
|
673
662
|
}
|
|
674
663
|
let recordId = transition[RECORD_SYMBOL]
|
|
675
664
|
if (recordId !== undefined) {
|
|
665
|
+
recordId &= 0xffff
|
|
676
666
|
target[position++] = 0xd9
|
|
677
667
|
target[position++] = (recordId >> 8) | 0xe0
|
|
678
668
|
target[position++] = recordId & 0xff
|
|
679
669
|
} else {
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
structures.nextId
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
670
|
+
if (!keys)
|
|
671
|
+
keys = transition.__keys__ || (transition.__keys__ = Object.keys(object))
|
|
672
|
+
if (parentRecordId === undefined) {
|
|
673
|
+
recordId = structures.nextId++
|
|
674
|
+
if (!recordId) {
|
|
675
|
+
recordId = 0
|
|
676
|
+
structures.nextId = 1
|
|
677
|
+
}
|
|
678
|
+
if (recordId >= MAX_STRUCTURES) {// cycle back around
|
|
679
|
+
structures.nextId = (recordId = maxSharedStructures) + 1
|
|
680
|
+
}
|
|
681
|
+
} else {
|
|
682
|
+
recordId = parentRecordId
|
|
687
683
|
}
|
|
688
|
-
transition[RECORD_SYMBOL] = recordId
|
|
689
684
|
structures[recordId] = keys
|
|
690
|
-
if (
|
|
685
|
+
if (recordId < maxSharedStructures) {
|
|
691
686
|
target[position++] = 0xd9
|
|
692
687
|
target[position++] = (recordId >> 8) | 0xe0
|
|
693
688
|
target[position++] = recordId & 0xff
|
|
689
|
+
transition = structures.transitions
|
|
690
|
+
for (let i = 0; i < length; i++) {
|
|
691
|
+
if (transition[RECORD_SYMBOL] === undefined || (transition[RECORD_SYMBOL] & 0x100000))
|
|
692
|
+
transition[RECORD_SYMBOL] = recordId
|
|
693
|
+
transition = transition[keys[i]]
|
|
694
|
+
}
|
|
695
|
+
transition[RECORD_SYMBOL] = recordId | 0x100000 // indicates it is a extendable terminal
|
|
694
696
|
hasSharedUpdate = true
|
|
695
697
|
} else {
|
|
698
|
+
transition[RECORD_SYMBOL] = recordId
|
|
696
699
|
targetView.setUint32(position, 0xd9dfff00) // tag two byte, then record definition id
|
|
697
700
|
position += 3
|
|
698
701
|
if (newTransitions)
|
|
@@ -713,7 +716,9 @@ export class Encoder extends Decoder {
|
|
|
713
716
|
} else {
|
|
714
717
|
writeArrayHeader(length)
|
|
715
718
|
}
|
|
716
|
-
for (let
|
|
719
|
+
for (let key in object)
|
|
720
|
+
if (safePrototype || object.hasOwnProperty(key))
|
|
721
|
+
encode(object[key])
|
|
717
722
|
}
|
|
718
723
|
const makeRoom = (end) => {
|
|
719
724
|
let newSize
|
|
@@ -752,15 +757,22 @@ export class Encoder extends Decoder {
|
|
|
752
757
|
updateSharedData() {
|
|
753
758
|
let lastVersion = this.sharedVersion || 0
|
|
754
759
|
this.sharedVersion = lastVersion + 1
|
|
755
|
-
let
|
|
760
|
+
let structuresCopy = this.structures.slice(0)
|
|
761
|
+
let sharedData = new SharedData(structuresCopy, this.sharedValues, this.sharedVersion)
|
|
762
|
+
let saveResults = this.saveShared(sharedData,
|
|
756
763
|
existingShared => (existingShared && existingShared.version || 0) == lastVersion)
|
|
757
764
|
if (saveResults === false) {
|
|
758
765
|
// get updated structures and try again if the update failed
|
|
759
|
-
|
|
766
|
+
sharedData = this.getShared() || {}
|
|
760
767
|
this.structures = sharedData.structures || []
|
|
761
768
|
this.sharedValues = sharedData.packedValues
|
|
762
769
|
this.sharedVersion = sharedData.version
|
|
770
|
+
this.structures.nextId = this.structures.length
|
|
771
|
+
} else {
|
|
772
|
+
// restore structures
|
|
773
|
+
structuresCopy.forEach((structure, i) => this.structures[i] = structure)
|
|
763
774
|
}
|
|
775
|
+
// saveShared may fail to write and reload, or may have reloaded to check compatibility and overwrite saved data, either way load the correct shared data
|
|
764
776
|
return saveResults
|
|
765
777
|
}
|
|
766
778
|
}
|
|
@@ -838,7 +850,7 @@ function findRepetitiveStrings(value, packedValues) {
|
|
|
838
850
|
case 'function': console.log(value)
|
|
839
851
|
}
|
|
840
852
|
}
|
|
841
|
-
|
|
853
|
+
const isLittleEndianMachine = new Uint8Array(new Uint16Array([1]).buffer)[0] == 1
|
|
842
854
|
extensionClasses = [ Date, Set, Error, RegExp, Tag, ArrayBuffer, ByteArray,
|
|
843
855
|
Uint8Array, Uint8ClampedArray, Uint16Array, Uint32Array,
|
|
844
856
|
typeof BigUint64Array == 'undefined' ? function() {} : BigUint64Array, Int8Array, Int16Array, Int32Array,
|
|
@@ -893,17 +905,17 @@ extensions = [{
|
|
|
893
905
|
encode(arrayBuffer, encode, makeRoom) {
|
|
894
906
|
writeBuffer(arrayBuffer, makeRoom)
|
|
895
907
|
}
|
|
896
|
-
}, typedArrayEncoder(64),
|
|
897
|
-
typedArrayEncoder(68),
|
|
898
|
-
typedArrayEncoder(69),
|
|
899
|
-
typedArrayEncoder(70),
|
|
900
|
-
typedArrayEncoder(71),
|
|
901
|
-
typedArrayEncoder(72),
|
|
902
|
-
typedArrayEncoder(77),
|
|
903
|
-
typedArrayEncoder(78),
|
|
904
|
-
typedArrayEncoder(79),
|
|
905
|
-
typedArrayEncoder(
|
|
906
|
-
typedArrayEncoder(
|
|
908
|
+
}, typedArrayEncoder(64, 1),
|
|
909
|
+
typedArrayEncoder(68, 1),
|
|
910
|
+
typedArrayEncoder(69, 2),
|
|
911
|
+
typedArrayEncoder(70, 4),
|
|
912
|
+
typedArrayEncoder(71, 8),
|
|
913
|
+
typedArrayEncoder(72, 1),
|
|
914
|
+
typedArrayEncoder(77, 2),
|
|
915
|
+
typedArrayEncoder(78, 4),
|
|
916
|
+
typedArrayEncoder(79, 8),
|
|
917
|
+
typedArrayEncoder(85, 4),
|
|
918
|
+
typedArrayEncoder(86, 8),
|
|
907
919
|
{
|
|
908
920
|
encode(sharedData, encode) { // write SharedData
|
|
909
921
|
let packedValues = sharedData.packedValues || []
|
|
@@ -932,8 +944,9 @@ extensions = [{
|
|
|
932
944
|
encode(new Tag(sharedData.version, 0x53687264))
|
|
933
945
|
}
|
|
934
946
|
}]
|
|
935
|
-
|
|
936
|
-
|
|
947
|
+
function typedArrayEncoder(tag, size) {
|
|
948
|
+
if (!isLittleEndianMachine && size > 1)
|
|
949
|
+
tag -= 4 // the big endian equivalents are 4 less
|
|
937
950
|
return {
|
|
938
951
|
tag: tag,
|
|
939
952
|
encode: function writeExtBuffer(typedArray, encode) {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cbor-x",
|
|
3
3
|
"author": "Kris Zyp",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.2.1",
|
|
5
5
|
"description": "Ultra-fast and conformant CBOR (RFC 8949) implementation with support for numerous tag extensions including records and structured cloning",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"types": "./index.d.ts",
|