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.
@@ -0,0 +1,93 @@
1
+ var __create = Object.create;
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __getProtoOf = Object.getPrototypeOf;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __markAsModule = (target) => __defProp(target, "__esModule", { value: true });
8
+ var __export = (target, all) => {
9
+ __markAsModule(target);
10
+ for (var name in all)
11
+ __defProp(target, name, { get: all[name], enumerable: true });
12
+ };
13
+ var __reExport = (target, module2, desc) => {
14
+ if (module2 && typeof module2 === "object" || typeof module2 === "function") {
15
+ for (let key of __getOwnPropNames(module2))
16
+ if (!__hasOwnProp.call(target, key) && key !== "default")
17
+ __defProp(target, key, { get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable });
18
+ }
19
+ return target;
20
+ };
21
+ var __toModule = (module2) => {
22
+ return __reExport(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, "default", module2 && module2.__esModule && "default" in module2 ? { get: () => module2.default, enumerable: true } : { value: module2, enumerable: true })), module2);
23
+ };
24
+ __export(exports, {
25
+ ALWAYS: () => import_encode.ALWAYS,
26
+ DECIMAL_FIT: () => import_encode.DECIMAL_FIT,
27
+ DECIMAL_ROUND: () => import_encode.DECIMAL_ROUND,
28
+ Decoder: () => import_decode.Decoder,
29
+ DecoderStream: () => import_stream.DecoderStream,
30
+ Encoder: () => import_encode.Encoder,
31
+ EncoderStream: () => import_stream.EncoderStream,
32
+ FLOAT32_OPTIONS: () => import_decode.FLOAT32_OPTIONS,
33
+ NEVER: () => import_encode.NEVER,
34
+ REUSE_BUFFER_MODE: () => import_encode.REUSE_BUFFER_MODE,
35
+ Tag: () => import_decode.Tag,
36
+ addExtension: () => import_encode.addExtension,
37
+ clearSource: () => import_decode.clearSource,
38
+ decode: () => import_decode.decode,
39
+ decodeIter: () => import_iterators.decodeIter,
40
+ decodeMultiple: () => import_decode.decodeMultiple,
41
+ encode: () => import_encode.encode,
42
+ encodeIter: () => import_iterators.encodeIter,
43
+ isNativeAccelerationEnabled: () => import_decode.isNativeAccelerationEnabled,
44
+ mapsAsObjects: () => mapsAsObjects,
45
+ roundFloat32: () => import_decode.roundFloat32,
46
+ useRecords: () => useRecords
47
+ });
48
+ var import_encode = __toModule(require("./encode.js"));
49
+ var import_decode = __toModule(require("./decode.js"));
50
+ var import_stream = __toModule(require("./stream.js"));
51
+ var import_iterators = __toModule(require("./iterators.js"));
52
+ var import_decode2 = __toModule(require("./decode.js"));
53
+ var import_module = __toModule(require("module"));
54
+ const import_meta = {};
55
+ const useRecords = false;
56
+ const mapsAsObjects = true;
57
+ const extractor = tryRequire("cbor-extract");
58
+ if (extractor)
59
+ (0, import_decode2.setExtractor)(extractor.extractStrings);
60
+ function tryRequire(moduleId) {
61
+ try {
62
+ let require2 = (0, import_module.createRequire)(import_meta.url);
63
+ return require2(moduleId);
64
+ } catch (error) {
65
+ if (typeof window != "undefined")
66
+ console.warn("For browser usage, directly use cbor-x/decode or cbor-x/encode modules. " + error.message.split("\n")[0]);
67
+ }
68
+ }
69
+ // Annotate the CommonJS export names for ESM import in node:
70
+ 0 && (module.exports = {
71
+ ALWAYS,
72
+ DECIMAL_FIT,
73
+ DECIMAL_ROUND,
74
+ Decoder,
75
+ DecoderStream,
76
+ Encoder,
77
+ EncoderStream,
78
+ FLOAT32_OPTIONS,
79
+ NEVER,
80
+ REUSE_BUFFER_MODE,
81
+ Tag,
82
+ addExtension,
83
+ clearSource,
84
+ decode,
85
+ decodeIter,
86
+ decodeMultiple,
87
+ encode,
88
+ encodeIter,
89
+ isNativeAccelerationEnabled,
90
+ mapsAsObjects,
91
+ roundFloat32,
92
+ useRecords
93
+ });
package/dist/node.cjs CHANGED
@@ -256,7 +256,11 @@ function read() {
256
256
  position += 8;
257
257
  return value
258
258
  }
259
- if (currentDecoder.int64AsNumber) {
259
+ if (majorType > 1) {
260
+ if (dataView.getUint32(position) > 0)
261
+ throw new Error('JavaScript does not support arrays, maps, or strings with length over 4294967295')
262
+ token = dataView.getUint32(position + 4);
263
+ } else if (currentDecoder.int64AsNumber) {
260
264
  token = dataView.getUint32(position) * 0x100000000;
261
265
  token += dataView.getUint32(position + 4);
262
266
  } else
@@ -436,21 +440,30 @@ function createStructureReader(structure) {
436
440
  }
437
441
  }
438
442
  // This initial function is quick to instantiate, but runs slower. After several iterations pay the cost to build the faster function
439
- if (this.objectLiteralSize === length) // we have a fast object literal reader, use it (assuming it is the right length)
440
- return this.objectLiteral(read)
441
- if (this.count++ == 3) { // create a fast reader
442
- this.objectLiteralSize = length;
443
- this.objectLiteral = currentDecoder.keyMap
444
- ? new Function('r', 'return {' + this.map(k => currentDecoder.decodeKey(k)).map(k => validName.test(k) ? k + ':r()' : ('[' + JSON.stringify(k) + ']:r()')).join(',') + '}')
445
- : new Function('r', 'return {' + this.map(key => validName.test(key) ? key + ':r()' : ('[' + JSON.stringify(key) + ']:r()')).join(',') + '}');
446
- return this.objectLiteral(read)
443
+ let compiledReader = this.compiledReader; // first look to see if we have the fast compiled function
444
+ while(compiledReader) {
445
+ // we have a fast compiled object literal reader
446
+ if (compiledReader.propertyCount === length)
447
+ return compiledReader(read) // with the right length, so we use it
448
+ compiledReader = compiledReader.next; // see if there is another reader with the right length
449
+ }
450
+ if (this.slowReads++ >= 3) { // create a fast compiled reader
451
+ let array = this.length == length ? this : this.slice(0, length);
452
+ compiledReader = currentDecoder.keyMap
453
+ ? new Function('r', 'return {' + array.map(k => currentDecoder.decodeKey(k)).map(k => validName.test(k) ? k + ':r()' : ('[' + JSON.stringify(k) + ']:r()')).join(',') + '}')
454
+ : new Function('r', 'return {' + array.map(key => validName.test(key) ? key + ':r()' : ('[' + JSON.stringify(key) + ']:r()')).join(',') + '}');
455
+ if (this.compiledReader)
456
+ compiledReader.next = this.compiledReader; // if there is an existing one, we store multiple readers as a linked list because it is usually pretty rare to have multiple readers (of different length) for the same structure
457
+ compiledReader.propertyCount = length;
458
+ this.compiledReader = compiledReader;
459
+ return compiledReader(read)
447
460
  }
448
461
  let object = {};
449
462
  if (currentDecoder.keyMap) for (let i = 0; i < length; i++) object[currentDecoder.decodeKey(this[i])] = read();
450
463
  else for (let i = 0; i < length; i++) object[this[i]] = read();
451
464
  return object
452
465
  }
453
- structure.count = 0;
466
+ structure.slowReads = 0;
454
467
  return readObject
455
468
  }
456
469
 
@@ -737,7 +750,7 @@ currentExtensions[0] = (dateString) => {
737
750
 
738
751
  currentExtensions[1] = (epochSec) => {
739
752
  // numeric date extension
740
- return new Date(epochSec * 1000)
753
+ return new Date(Math.round(epochSec * 1000))
741
754
  };
742
755
 
743
756
  currentExtensions[2] = (buffer) => {
@@ -763,11 +776,16 @@ currentExtensions[5] = (fraction) => {
763
776
  return fraction[1] * Math.exp(fraction[0] * Math.log(2))
764
777
  };
765
778
 
766
- // the registration of the record definition extension (tag 105)
779
+ // the registration of the record definition extension
767
780
  const recordDefinition = (definition) => {
768
781
  let id = definition[0] - 0xe000;
769
782
  let structure = definition[1];
783
+ let existingStructure = currentStructures[id];
784
+ if (existingStructure && existingStructure.isShared) {
785
+ (currentStructures.restoreStructures || (currentStructures.restoreStructures = []))[id] = existingStructure;
786
+ }
770
787
  currentStructures[id] = structure;
788
+
771
789
  structure.read = createStructureReader(structure);
772
790
  let object = {};
773
791
  if (currentDecoder.keyMap) for (let i = 2,l = definition.length; i < l; i++) {
@@ -911,20 +929,41 @@ currentExtensionRanges.push((tag, input) => {
911
929
  version: input,
912
930
  }
913
931
  }
932
+ if (tag == 55799) // self-descriptive CBOR tag, just return input value
933
+ return input
914
934
  });
915
935
 
916
- const typedArrays = ['Uint8', 'Uint8Clamped', 'Uint16', 'Uint32', 'BigUint64','Int8', 'Int16', 'Int32', 'BigInt64', 'Float32', 'Float64'].map(type => type + 'Array');
917
- const typedArrayTags = [64, 68, 69, 70, 71, 72, 77, 78, 79, 81, 82];
936
+ const isLittleEndianMachine = new Uint8Array(new Uint16Array([1]).buffer)[0] == 1;
937
+ const typedArrays = ['Uint8', 'Uint8Clamped', 'Uint16', 'Uint32', 'BigUint64','Int8', 'Int16', 'Int32', 'BigInt64', 'Float32', 'Float64'];
938
+ const typedArrayTags = [64, 68, 69, 70, 71, 72, 77, 78, 79, 85, 86];
918
939
  for (let i = 0; i < typedArrays.length; i++) {
919
940
  registerTypedArray(typedArrays[i], typedArrayTags[i]);
920
941
  }
921
- function registerTypedArray(typedArrayName, tag) {
922
- currentExtensions[tag] = (buffer) => {
923
- if (!typedArrayName)
924
- throw new Error('Could not find typed array for code ' + typeCode)
925
- // we have to always slice/copy here to get a new ArrayBuffer that is word/byte aligned
926
- return new glbl[typedArrayName](Uint8Array.prototype.slice.call(buffer, 0).buffer)
927
- };
942
+ function registerTypedArray(typedArrayId, tag, littleEndian) {
943
+ let TypedArray = glbl[typedArrayId + 'Array'];
944
+ let bytesPerElement = TypedArray.BYTES_PER_ELEMENT;
945
+ for (let littleEndian = 0; littleEndian < 2; littleEndian++) {
946
+ if (!littleEndian && bytesPerElement == 1)
947
+ continue
948
+ let sizeShift = bytesPerElement == 2 ? 1 : bytesPerElement == 4 ? 2 : 3;
949
+ currentExtensions[littleEndian ? tag : (tag - 4)] = (bytesPerElement == 1 || littleEndian == isLittleEndianMachine) ? (buffer) => {
950
+ if (!TypedArray)
951
+ throw new Error('Could not find typed array for code ' + tag)
952
+ // we have to always slice/copy here to get a new ArrayBuffer that is word/byte aligned
953
+ return new TypedArray(Uint8Array.prototype.slice.call(buffer, 0).buffer)
954
+ } : buffer => {
955
+ if (!TypedArray)
956
+ throw new Error('Could not find typed array for code ' + tag)
957
+ let dv = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);
958
+ let elements = buffer.length >> sizeShift;
959
+ let ta = new TypedArray(elements);
960
+ let method = dv['get' + typedArrayId];
961
+ for (let i = 0; i < elements; i++) {
962
+ ta[i] = method.call(dv, i << sizeShift, littleEndian);
963
+ }
964
+ return ta
965
+ };
966
+ }
928
967
  }
929
968
 
930
969
  function readBundleExt() {
@@ -1082,12 +1121,18 @@ class Encoder extends Decoder {
1082
1121
  } : false;
1083
1122
 
1084
1123
  let encoder = this;
1085
- let maxSharedStructures = options.maxSharedStructures || 128;
1124
+ let hasSharedStructures = options.structures || options.saveStructures;
1125
+ let maxSharedStructures = options.maxSharedStructures;
1126
+ if (maxSharedStructures == null)
1127
+ maxSharedStructures = hasSharedStructures ? 128 : 0;
1128
+ if (maxSharedStructures > 8190)
1129
+ throw new Error('Maximum maxSharedStructure is 8190')
1086
1130
  let isSequential = options.sequential;
1087
1131
  if (isSequential) {
1088
1132
  maxSharedStructures = 0;
1089
- this.structures = [];
1090
1133
  }
1134
+ if (!this.structures)
1135
+ this.structures = [];
1091
1136
  if (this.saveStructures)
1092
1137
  this.saveShared = this.saveStructures;
1093
1138
  let samplingPackedValues, packedObjectMap, sharedValues = options.sharedValues;
@@ -1135,6 +1180,10 @@ class Encoder extends Decoder {
1135
1180
  } else if (encodeOptions === REUSE_BUFFER_MODE)
1136
1181
  position$1 = (position$1 + 7) & 0x7ffffff8; // Word align to make any future copying of this buffer faster
1137
1182
  start = position$1;
1183
+ if (encoder.useSelfDescribedHeader) {
1184
+ targetView.setUint32(position$1, 0xd9d9f700); // tag two byte, then self-descriptive tag
1185
+ position$1 += 3;
1186
+ }
1138
1187
  referenceMap = encoder.structuredClone ? new Map() : null;
1139
1188
  if (encoder.bundleStrings && typeof value !== 'string') {
1140
1189
  bundledStrings$1 = [];
@@ -1168,6 +1217,8 @@ class Encoder extends Decoder {
1168
1217
  continue
1169
1218
  let nextTransition, transition = sharedStructures.transitions;
1170
1219
  for (let j = 0, l = keys.length; j < l; j++) {
1220
+ if (transition[RECORD_SYMBOL] === undefined)
1221
+ transition[RECORD_SYMBOL] = i;
1171
1222
  let key = keys[j];
1172
1223
  nextTransition = transition[key];
1173
1224
  if (!nextTransition) {
@@ -1175,7 +1226,7 @@ class Encoder extends Decoder {
1175
1226
  }
1176
1227
  transition = nextTransition;
1177
1228
  }
1178
- transition[RECORD_SYMBOL] = i;
1229
+ transition[RECORD_SYMBOL] = i | 0x100000;
1179
1230
  }
1180
1231
  }
1181
1232
  if (!isSequential)
@@ -1227,11 +1278,13 @@ class Encoder extends Decoder {
1227
1278
  target.end = position$1;
1228
1279
  return target
1229
1280
  }
1230
- return target.subarray(start, position$1) // position can change if we call pack again in saveShared, so we get the buffer now
1281
+ return target.subarray(start, position$1) // position can change if we call encode again in saveShared, so we get the buffer now
1231
1282
  } finally {
1232
1283
  if (sharedStructures) {
1233
1284
  if (serializationsSinceTransitionRebuild < 10)
1234
1285
  serializationsSinceTransitionRebuild++;
1286
+ if (sharedStructures.length > maxSharedStructures)
1287
+ sharedStructures.length = maxSharedStructures;
1235
1288
  if (transitionsCount > 10000) {
1236
1289
  // force a rebuild occasionally after a lot of transitions so it can get cleaned up
1237
1290
  sharedStructures.transitions = null;
@@ -1244,6 +1297,7 @@ class Encoder extends Decoder {
1244
1297
  recordIdsToRemove[i][RECORD_SYMBOL] = undefined;
1245
1298
  }
1246
1299
  recordIdsToRemove = [];
1300
+ //sharedStructures.nextId = maxSharedStructures
1247
1301
  }
1248
1302
  }
1249
1303
  if (hasSharedUpdate && encoder.saveShared) {
@@ -1543,7 +1597,9 @@ class Encoder extends Decoder {
1543
1597
  let extensionClass = extensionClasses[i];
1544
1598
  if (value instanceof extensionClass) {
1545
1599
  let extension = extensions[i];
1546
- let tag = extension.tag || extension.getTag && extension.getTag(value);
1600
+ let tag = extension.tag;
1601
+ if (tag == undefined)
1602
+ tag = extension.getTag && extension.getTag(value);
1547
1603
  if (tag < 0x18) {
1548
1604
  target[position$1++] = 0xc0 | tag;
1549
1605
  } else if (tag < 0x100) {
@@ -1654,88 +1710,74 @@ class Encoder extends Decoder {
1654
1710
  target[objectOffset++ + start] = size >> 8;
1655
1711
  target[objectOffset + start] = size & 0xff;
1656
1712
  } :
1657
-
1658
- /* sharedStructures ? // For highly stable structures, using for-in can a little bit faster
1659
1713
  (object, safePrototype) => {
1660
- let nextTransition, transition = structures.transitions || (structures.transitions = Object.create(null))
1661
- let objectOffset = position++ - start
1662
- let wroteKeys
1663
- for (let key in object) {
1664
- if (safePrototype || object.hasOwnProperty(key)) {
1665
- nextTransition = transition[key]
1714
+ let nextTransition, transition = structures.transitions || (structures.transitions = Object.create(null));
1715
+ let newTransitions = 0;
1716
+ let length = 0;
1717
+ let parentRecordId;
1718
+ let keys;
1719
+ if (this.keyMap) {
1720
+ keys = Object.keys(object).map(k => this.encodeKey(k));
1721
+ length = keys.length;
1722
+ for (let i = 0; i < length; i++) {
1723
+ let key = keys[i];
1724
+ nextTransition = transition[key];
1666
1725
  if (!nextTransition) {
1667
- nextTransition = transition[key] = Object.create(null)
1668
- nextTransition.__keys__ = (transition.__keys__ || []).concat([key])
1669
- /*let keys = Object.keys(object)
1670
- if
1671
- let size = 0
1672
- let startBranch = transition.__keys__ ? transition.__keys__.length : 0
1673
- for (let i = 0, l = keys.length; i++) {
1674
- let key = keys[i]
1675
- size += key.length << 2
1676
- if (i >= startBranch) {
1677
- nextTransition = nextTransition[key] = Object.create(null)
1678
- nextTransition.__keys__ = keys.slice(0, i + 1)
1679
- }
1726
+ nextTransition = transition[key] = Object.create(null);
1727
+ newTransitions++;
1728
+ }
1729
+ transition = nextTransition;
1730
+ }
1731
+ } else {
1732
+ for (let key in object) if (safePrototype || object.hasOwnProperty(key)) {
1733
+ nextTransition = transition[key];
1734
+ if (!nextTransition) {
1735
+ if (transition[RECORD_SYMBOL] & 0x100000) {// this indicates it is a brancheable/extendable terminal node, so we will use this record id and extend it
1736
+ parentRecordId = transition[RECORD_SYMBOL] & 0xffff;
1680
1737
  }
1681
- makeRoom(position + size)
1682
- nextTransition = transition[key]
1683
- target.copy(target, )
1684
- objectOffset
1738
+ nextTransition = transition[key] = Object.create(null);
1739
+ newTransitions++;
1685
1740
  }
1686
- transition = nextTransition
1687
- encode(object[key])
1741
+ transition = nextTransition;
1742
+ length++;
1688
1743
  }
1689
1744
  }
1690
- let id = transition.id
1691
- if (!id) {
1692
- id = transition.id = structures.push(transition.__keys__) + 63
1693
- if (sharedStructures.onUpdate)
1694
- sharedStructures.onUpdate(id, transition.__keys__)
1695
- }
1696
- target[objectOffset + start] = id
1697
- }*/
1698
- (object) => {
1699
- let keys = Object.keys(object);
1700
- let vals = Object.values(object);
1701
- if (this.keyMap) keys = keys.map(k => this.encodeKey(k));
1702
- let nextTransition, transition = structures.transitions || (structures.transitions = Object.create(null));
1703
- let newTransitions = 0;
1704
- let length = keys.length;
1705
- //let parentRecordId
1706
- for (let i = 0; i < length; i++) {
1707
- //if (!parentRecordId)
1708
- let key = keys[i];
1709
- // parentRecordId = transition[RECORD_SYMBOL]
1710
- nextTransition = transition[key];
1711
- if (!nextTransition) {
1712
- nextTransition = transition[key] = Object.create(null);
1713
- newTransitions++;
1714
- }
1715
- transition = nextTransition;
1716
- }
1717
1745
  let recordId = transition[RECORD_SYMBOL];
1718
1746
  if (recordId !== undefined) {
1747
+ recordId &= 0xffff;
1719
1748
  target[position$1++] = 0xd9;
1720
1749
  target[position$1++] = (recordId >> 8) | 0xe0;
1721
1750
  target[position$1++] = recordId & 0xff;
1722
1751
  } else {
1723
- recordId = structures.nextId++;
1724
- if (!recordId) {
1725
- recordId = 0;
1726
- structures.nextId = 1;
1727
- }
1728
- if (recordId >= MAX_STRUCTURES) {// cycle back around
1729
- structures.nextId = (recordId = maxSharedStructures) + 1;
1752
+ if (!keys)
1753
+ keys = transition.__keys__ || (transition.__keys__ = Object.keys(object));
1754
+ if (parentRecordId === undefined) {
1755
+ recordId = structures.nextId++;
1756
+ if (!recordId) {
1757
+ recordId = 0;
1758
+ structures.nextId = 1;
1759
+ }
1760
+ if (recordId >= MAX_STRUCTURES) {// cycle back around
1761
+ structures.nextId = (recordId = maxSharedStructures) + 1;
1762
+ }
1763
+ } else {
1764
+ recordId = parentRecordId;
1730
1765
  }
1731
- transition[RECORD_SYMBOL] = recordId;
1732
1766
  structures[recordId] = keys;
1733
- if (sharedStructures && sharedStructures.length <= maxSharedStructures) {
1767
+ if (recordId < maxSharedStructures) {
1734
1768
  target[position$1++] = 0xd9;
1735
1769
  target[position$1++] = (recordId >> 8) | 0xe0;
1736
1770
  target[position$1++] = recordId & 0xff;
1771
+ transition = structures.transitions;
1772
+ for (let i = 0; i < length; i++) {
1773
+ if (transition[RECORD_SYMBOL] === undefined || (transition[RECORD_SYMBOL] & 0x100000))
1774
+ transition[RECORD_SYMBOL] = recordId;
1775
+ transition = transition[keys[i]];
1776
+ }
1777
+ transition[RECORD_SYMBOL] = recordId | 0x100000; // indicates it is a extendable terminal
1737
1778
  hasSharedUpdate = true;
1738
1779
  } else {
1780
+ transition[RECORD_SYMBOL] = recordId;
1739
1781
  targetView.setUint32(position$1, 0xd9dfff00); // tag two byte, then record definition id
1740
1782
  position$1 += 3;
1741
1783
  if (newTransitions)
@@ -1756,7 +1798,9 @@ class Encoder extends Decoder {
1756
1798
  } else {
1757
1799
  writeArrayHeader(length);
1758
1800
  }
1759
- for (let i =0; i < length; i++) encode(vals[i]);
1801
+ for (let key in object)
1802
+ if (safePrototype || object.hasOwnProperty(key))
1803
+ encode(object[key]);
1760
1804
  };
1761
1805
  const makeRoom = (end) => {
1762
1806
  let newSize;
@@ -1795,15 +1839,22 @@ class Encoder extends Decoder {
1795
1839
  updateSharedData() {
1796
1840
  let lastVersion = this.sharedVersion || 0;
1797
1841
  this.sharedVersion = lastVersion + 1;
1798
- let saveResults = this.saveShared(new SharedData(this.structures, this.sharedValues, this.sharedVersion),
1842
+ let structuresCopy = this.structures.slice(0);
1843
+ let sharedData = new SharedData(structuresCopy, this.sharedValues, this.sharedVersion);
1844
+ let saveResults = this.saveShared(sharedData,
1799
1845
  existingShared => (existingShared && existingShared.version || 0) == lastVersion);
1800
1846
  if (saveResults === false) {
1801
1847
  // get updated structures and try again if the update failed
1802
- let sharedData = this.getShared() || {};
1848
+ sharedData = this.getShared() || {};
1803
1849
  this.structures = sharedData.structures || [];
1804
1850
  this.sharedValues = sharedData.packedValues;
1805
1851
  this.sharedVersion = sharedData.version;
1852
+ this.structures.nextId = this.structures.length;
1853
+ } else {
1854
+ // restore structures
1855
+ structuresCopy.forEach((structure, i) => this.structures[i] = structure);
1806
1856
  }
1857
+ // 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
1807
1858
  return saveResults
1808
1859
  }
1809
1860
  }
@@ -1881,7 +1932,7 @@ function findRepetitiveStrings(value, packedValues) {
1881
1932
  case 'function': console.log(value);
1882
1933
  }
1883
1934
  }
1884
-
1935
+ const isLittleEndianMachine$1 = new Uint8Array(new Uint16Array([1]).buffer)[0] == 1;
1885
1936
  extensionClasses = [ Date, Set, Error, RegExp, Tag, ArrayBuffer, ByteArray,
1886
1937
  Uint8Array, Uint8ClampedArray, Uint16Array, Uint32Array,
1887
1938
  typeof BigUint64Array == 'undefined' ? function() {} : BigUint64Array, Int8Array, Int16Array, Int32Array,
@@ -1936,17 +1987,17 @@ extensions = [{
1936
1987
  encode(arrayBuffer, encode, makeRoom) {
1937
1988
  writeBuffer(arrayBuffer, makeRoom);
1938
1989
  }
1939
- }, typedArrayEncoder(64),
1940
- typedArrayEncoder(68),
1941
- typedArrayEncoder(69),
1942
- typedArrayEncoder(70),
1943
- typedArrayEncoder(71),
1944
- typedArrayEncoder(72),
1945
- typedArrayEncoder(77),
1946
- typedArrayEncoder(78),
1947
- typedArrayEncoder(79),
1948
- typedArrayEncoder(81),
1949
- typedArrayEncoder(82),
1990
+ }, typedArrayEncoder(64, 1),
1991
+ typedArrayEncoder(68, 1),
1992
+ typedArrayEncoder(69, 2),
1993
+ typedArrayEncoder(70, 4),
1994
+ typedArrayEncoder(71, 8),
1995
+ typedArrayEncoder(72, 1),
1996
+ typedArrayEncoder(77, 2),
1997
+ typedArrayEncoder(78, 4),
1998
+ typedArrayEncoder(79, 8),
1999
+ typedArrayEncoder(85, 4),
2000
+ typedArrayEncoder(86, 8),
1950
2001
  {
1951
2002
  encode(sharedData, encode) { // write SharedData
1952
2003
  let packedValues = sharedData.packedValues || [];
@@ -1975,8 +2026,9 @@ extensions = [{
1975
2026
  encode(new Tag(sharedData.version, 0x53687264));
1976
2027
  }
1977
2028
  }];
1978
-
1979
- function typedArrayEncoder(tag) {
2029
+ function typedArrayEncoder(tag, size) {
2030
+ if (!isLittleEndianMachine$1 && size > 1)
2031
+ tag -= 4; // the big endian equivalents are 4 less
1980
2032
  return {
1981
2033
  tag: tag,
1982
2034
  encode: function writeExtBuffer(typedArray, encode) {
package/dist/test.js CHANGED
@@ -592,7 +592,6 @@
592
592
 
593
593
  const senmlKeys = { bs: -6, bv: -5, bu: -4, bt: -3, bn: -2, n: 0, u: 1, v: 2, vs: 3, t: 6, ut: 7, vd: 8 };
594
594
 
595
-
596
595
  //import inspector from 'inspector'; inspector.open(9229, null, true); debugger
597
596
  function tryRequire(module) {
598
597
  try {
@@ -666,10 +665,42 @@
666
665
  let structures = [];
667
666
  let encoder = new Encoder({ structures });
668
667
  var serialized = encoder.encode(data);
668
+ serialized = encoder.encode(data);
669
669
  var deserialized = encoder.decode(serialized);
670
670
  assert.deepEqual(deserialized, data);
671
671
  });
672
672
 
673
+ test('mixed structures, shared', function(){
674
+ let data1 = { a: 1, b: 2, c: 3 };
675
+ let data2 = { a: 1, b: 2, d: 4 };
676
+ let data3 = { a: 1, b: 2, e: 5 };
677
+ let structures = [];
678
+ let encoder = new Encoder({ structures });
679
+ var serialized = encoder.encode(data1);
680
+ var deserialized = encoder.decode(serialized);
681
+ assert.deepEqual(deserialized, data1);
682
+ var serialized = encoder.encode(data2);
683
+ var deserialized = encoder.decode(serialized);
684
+ assert.deepEqual(deserialized, data2);
685
+ var serialized = encoder.encode(data3);
686
+ var deserialized = encoder.decode(serialized);
687
+ assert.deepEqual(deserialized, data3);
688
+ });
689
+
690
+ test('mixed structures, unshared', function(){
691
+ let data = [];
692
+ let encoder = new Encoder({ });
693
+ for (let i = 0; i< 1000; i++) {
694
+ data.push({a: 1, ['test' + i]: i});
695
+ }
696
+ var serialized = encoder.encode(data);
697
+ var deserialized = encoder.decode(serialized);
698
+ assert.deepEqual(deserialized, data);
699
+ serialized = encoder.encode(data);
700
+ deserialized = encoder.decode(serialized);
701
+ assert.deepEqual(deserialized, data);
702
+ });
703
+
673
704
  test('mixed array', function(){
674
705
  var data = [
675
706
  'one',
@@ -772,6 +803,16 @@
772
803
  var deserialized = encoder.decode(serialized);
773
804
  assert.deepEqual(deserialized, data);
774
805
  });
806
+ test('pack/unpack sample data with self-descriptive header', function(){
807
+ var data = sampleData;
808
+ let encoder = new Encoder({ useSelfDescribedHeader: true });
809
+ var serialized = encoder.encode(data);
810
+ var deserialized = encoder.decode(serialized);
811
+ assert.deepEqual(deserialized, data);
812
+ assert.equal(serialized[0], 0xd9);
813
+ assert.equal(serialized[1], 0xd9);
814
+ assert.equal(serialized[2], 0xf7);
815
+ });
775
816
  if (typeof Buffer != 'undefined')
776
817
  test('replace data', function(){
777
818
  var data1 = {
@@ -883,6 +924,7 @@
883
924
  let fa = new Float32Array(b.buffer, 8, 2);
884
925
  fa[0] = 2.25;
885
926
  fa[1] = 6;
927
+ let f64a = new Float64Array([2.3, 4.7]);
886
928
  let map = new Map();
887
929
  map.set('key', 'value');
888
930
  let object = {
@@ -891,6 +933,7 @@
891
933
  regexp: /test/gi,
892
934
  map,
893
935
  float32Array: fa,
936
+ float64Array: f64a,
894
937
  uint16Array: new Uint16Array([3,4])
895
938
  };
896
939
  let encoder = new Encoder({
@@ -905,6 +948,8 @@
905
948
  assert.equal(deserialized.float32Array.constructor.name, 'Float32Array');
906
949
  assert.equal(deserialized.float32Array[0], 2.25);
907
950
  assert.equal(deserialized.float32Array[1], 6);
951
+ assert.equal(deserialized.float64Array[0], 2.3);
952
+ assert.equal(deserialized.float64Array[1], 4.7);
908
953
  assert.equal(deserialized.uint16Array.constructor.name, 'Uint16Array');
909
954
  assert.equal(deserialized.uint16Array[0], 3);
910
955
  assert.equal(deserialized.uint16Array[1], 4);
@@ -964,13 +1009,16 @@
964
1009
  var map = new Map();
965
1010
  map.set(4, 'four');
966
1011
  map.set('three', 3);
967
-
1012
+ let year2039 = new Date('2039-07-05T16:22:35.792Z');
1013
+ let year2038 = new Date('2038-08-06T00:19:02.911Z');
968
1014
 
969
1015
  var data = {
970
1016
  map: map,
971
1017
  date: new Date(1532219539733),
972
1018
  farFutureDate: new Date(3532219539133),
973
1019
  ancient: new Date(-3532219539133),
1020
+ year2038,
1021
+ year2039,
974
1022
  invalidDate: new Date('invalid')
975
1023
  };
976
1024
  let encoder = new Encoder();
@@ -981,6 +1029,8 @@
981
1029
  assert.equal(deserialized.date.getTime(), 1532219539733);
982
1030
  assert.equal(deserialized.farFutureDate.getTime(), 3532219539133);
983
1031
  assert.equal(deserialized.ancient.getTime(), -3532219539133);
1032
+ assert.equal(deserialized.year2038.getTime(), year2038.getTime());
1033
+ assert.equal(deserialized.year2039.getTime(), year2039.getTime());
984
1034
  assert.equal(deserialized.invalidDate.toString(), 'Invalid Date');
985
1035
  });
986
1036
  test('map/date with options', function(){
@@ -1162,7 +1212,10 @@
1162
1212
  CBOR.decodeMultiple(new Uint8Array([1, 2, 3, 4]), value => values.push(value));
1163
1213
  assert.deepEqual(values, [1, 2, 3, 4]);
1164
1214
  });
1165
-
1215
+ test('bad input', function() {
1216
+ let badInput = Buffer.from('7b2273657269616c6e6f223a2265343a30222c226970223a223139322e3136382e312e3335222c226b6579223a226770735f736563726574227d', 'hex');
1217
+ assert.throws(function(){ decode(badInput); }); // should throw, not crash
1218
+ });
1166
1219
  });
1167
1220
  suite('CBOR performance tests', function(){
1168
1221
  test('performance JSON.parse', function() {