cbor-x 0.8.0 → 0.9.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/dist/node.cjs CHANGED
@@ -25,10 +25,12 @@ let srcStringEnd = 0;
25
25
  let referenceMap;
26
26
  let currentExtensions = [];
27
27
  let dataView;
28
+ let restoreMapsAsObject;
28
29
  let defaultOptions = {
29
30
  useRecords: false,
30
31
  mapsAsObjects: true
31
32
  };
33
+ let sequentialMode = false;
32
34
 
33
35
  class Decoder {
34
36
  constructor(options) {
@@ -40,12 +42,12 @@ class Decoder {
40
42
  }
41
43
  Object.assign(this, options);
42
44
  }
43
- decode(source, end, continueReading) {
45
+ decode(source, end) {
44
46
  if (src) {
45
47
  // re-entrant execution, save the state and restore it after we do this decode
46
48
  return saveState(() => {
47
49
  clearSource();
48
- return this ? this.decode(source, end, continueReading) : Decoder.prototype.decode.call(defaultOptions, source, end, continueReading)
50
+ return this ? this.decode(source, end) : Decoder.prototype.decode.call(defaultOptions, source, end)
49
51
  })
50
52
  }
51
53
  srcEnd = end > -1 ? end : source.length;
@@ -63,17 +65,7 @@ class Decoder {
63
65
  currentDecoder = this;
64
66
  if (this.structures) {
65
67
  currentStructures = this.structures;
66
- try {
67
- return read()
68
- } finally {
69
- if (position >= srcEnd || !continueReading) {
70
- // finished reading this source, cleanup references
71
- currentStructures = null;
72
- src = null;
73
- if (referenceMap)
74
- referenceMap = null;
75
- }
76
- }
68
+ return checkedRead()
77
69
  } else if (!currentStructures || currentStructures.length > 0) {
78
70
  currentStructures = [];
79
71
  }
@@ -82,26 +74,19 @@ class Decoder {
82
74
  if (!currentStructures || currentStructures.length > 0)
83
75
  currentStructures = [];
84
76
  }
85
- try {
86
- return read()
87
- } finally {
88
- if (position >= srcEnd || !continueReading) {
89
- src = null;
90
- if (referenceMap)
91
- referenceMap = null;
92
- }
93
- }
77
+ return checkedRead()
94
78
  }
95
79
  decodeMultiple(source, forEach) {
80
+ let values, lastPosition = 0;
96
81
  try {
97
- let decoder = this;
98
82
  let size = source.length;
99
- let value = this ? this.decode(source, size, true) : defaultDecoder.decode(source, size, true);
100
- let values;
83
+ sequentialMode = true;
84
+ let value = this ? this.decode(source, size) : defaultDecoder.decode(source, size);
101
85
  if (forEach) {
102
86
  forEach(value);
103
87
  while(position < size) {
104
- if (forEach(read()) === false) {
88
+ lastPosition = position;
89
+ if (forEach(checkedRead()) === false) {
105
90
  return
106
91
  }
107
92
  }
@@ -109,17 +94,47 @@ class Decoder {
109
94
  else {
110
95
  values = [ value ];
111
96
  while(position < size) {
112
- values.push(read());
97
+ lastPosition = position;
98
+ values.push(checkedRead());
113
99
  }
114
100
  return values
115
101
  }
102
+ } catch(error) {
103
+ error.lastPosition = lastPosition;
104
+ error.values = values;
105
+ throw error
116
106
  } finally {
107
+ sequentialMode = false;
117
108
  clearSource();
118
109
  }
119
110
  }
120
111
  }
121
- function getPosition() {
122
- return position
112
+ function checkedRead() {
113
+ try {
114
+ let result = read();
115
+ if (position == srcEnd) {
116
+ // finished reading this source, cleanup references
117
+ currentStructures = null;
118
+ src = null;
119
+ if (referenceMap)
120
+ referenceMap = null;
121
+ } else if (position > srcEnd) {
122
+ // over read
123
+ let error = new Error('Unexpected end of CBOR data');
124
+ error.incomplete = true;
125
+ throw error
126
+ } else if (!sequentialMode) {
127
+ throw new Error('Data read, but end of buffer not reached')
128
+ }
129
+ // else more to read, but we are reading sequentially, so don't clear source yet
130
+ return result
131
+ } catch(error) {
132
+ clearSource();
133
+ if (error instanceof RangeError || error.message.startsWith('Unexpected end of buffer')) {
134
+ error.incomplete = true;
135
+ }
136
+ throw error
137
+ }
123
138
  }
124
139
 
125
140
  function read() {
@@ -185,6 +200,10 @@ function read() {
185
200
  object[key] = read();
186
201
  return object
187
202
  } else {
203
+ if (restoreMapsAsObject) {
204
+ currentDecoder.mapsAsObjects = true;
205
+ restoreMapsAsObject = false;
206
+ }
188
207
  let map = new Map();
189
208
  while ((key = read()) != STOP_CODE)
190
209
  map.set(key, read());
@@ -231,6 +250,10 @@ function read() {
231
250
  }
232
251
  return object
233
252
  } else {
253
+ if (restoreMapsAsObject) {
254
+ currentDecoder.mapsAsObjects = true;
255
+ restoreMapsAsObject = false;
256
+ }
234
257
  let map = new Map();
235
258
  for (let i = 0; i < token; i++) {
236
259
  map.set(read(), read());
@@ -338,10 +361,18 @@ function setExtractor(extractStrings) {
338
361
  return function readString(length) {
339
362
  let string = strings[stringPosition++];
340
363
  if (string == null) {
341
- strings = extractStrings(position, srcEnd, length, src);
342
- stringPosition = 0;
343
- srcStringEnd = 1; // even if a utf-8 string was decoded, must indicate we are in the midst of extracted strings and can't skip strings
344
- string = strings[stringPosition++];
364
+ let extraction = extractStrings(position, srcEnd, length, src);
365
+ if (typeof extraction == 'string') {
366
+ string = extraction;
367
+ strings = EMPTY_ARRAY;
368
+ } else {
369
+ strings = extraction;
370
+ stringPosition = 1;
371
+ srcStringEnd = 1; // even if a utf-8 string was decoded, must indicate we are in the midst of extracted strings and can't skip strings
372
+ string = strings[0];
373
+ if (string === undefined)
374
+ throw new Error('Unexpected end of buffer')
375
+ }
345
376
  }
346
377
  let srcStringLength = string.length;
347
378
  if (srcStringLength <= length) {
@@ -727,6 +758,16 @@ currentExtensions[40010] = (id) => {
727
758
  };
728
759
 
729
760
  currentExtensions[258] = (array) => new Set(array); // https://github.com/input-output-hk/cbor-sets-spec/blob/master/CBOR_SETS.md
761
+ (currentExtensions[259] = (read) => {
762
+ // https://github.com/shanewholloway/js-cbor-codec/blob/master/docs/CBOR-259-spec
763
+ // for decoding as a standard Map
764
+ if (currentDecoder.mapsAsObjects) {
765
+ currentDecoder.mapsAsObjects = false;
766
+ restoreMapsAsObject = true;
767
+ }
768
+ return read()
769
+ }).handlesRead = true;
770
+
730
771
 
731
772
  const typedArrays = ['Uint8', 'Uint8Clamped', 'Uint16', 'Uint32', 'BigUint64','Int8', 'Int16', 'Int32', 'BigInt64', 'Float32', 'Float64'].map(type => type + 'Array');
732
773
  const typedArrayTags = [64, 68, 69, 70, 71, 72, 77, 78, 79, 81, 82];
@@ -755,6 +796,7 @@ function saveState(callback) {
755
796
  let savedSrc = new Uint8Array(src.slice(0, srcEnd)); // we copy the data in case it changes while external data is processed
756
797
  let savedStructures = currentStructures;
757
798
  let savedDecoder = currentDecoder;
799
+ let savedSequentialMode = sequentialMode;
758
800
  let value = callback();
759
801
  srcEnd = savedSrcEnd;
760
802
  position = savedPosition;
@@ -765,6 +807,7 @@ function saveState(callback) {
765
807
  strings = savedStrings;
766
808
  referenceMap = savedReferenceMap;
767
809
  src = savedSrc;
810
+ sequentialMode = savedSequentialMode;
768
811
  currentStructures = savedStructures;
769
812
  currentDecoder = savedDecoder;
770
813
  dataView = new DataView(src.buffer, src.byteOffset, src.byteLength);
@@ -780,7 +823,7 @@ function addExtension(extension) {
780
823
  currentExtensions[extension.tag] = extension.decode;
781
824
  }
782
825
 
783
- let mult10 = new Array(147); // this is a table matching binary exponents to the multiplier to determine significant digit rounding
826
+ const mult10 = new Array(147); // this is a table matching binary exponents to the multiplier to determine significant digit rounding
784
827
  for (let i = 0; i < 256; i++) {
785
828
  mult10[i] = +('1e' + Math.floor(45.15 - i * 0.30103));
786
829
  }
@@ -792,7 +835,14 @@ const FLOAT32_OPTIONS = {
792
835
  ALWAYS: 1,
793
836
  DECIMAL_ROUND: 3,
794
837
  DECIMAL_FIT: 4
795
- };
838
+ };
839
+ let f32Array = new Float32Array(1);
840
+ let u8Array = new Uint8Array(f32Array.buffer, 0, 4);
841
+ function roundFloat32(float32Number) {
842
+ f32Array[0] = float32Number;
843
+ let multiplier = mult10[((u8Array[3] & 0x7f) << 1) | (u8Array[2] >> 7)];
844
+ return ((multiplier * float32Number + (float32Number > 0 ? 0.5 : -0.5)) >> 0) / multiplier
845
+ }
796
846
 
797
847
  let textEncoder;
798
848
  try {
@@ -837,11 +887,8 @@ class Encoder extends Decoder {
837
887
  let recordIdsToRemove = [];
838
888
  let transitionsCount = 0;
839
889
  let serializationsSinceTransitionRebuild = 0;
840
- if (this.structures && this.structures.length > maxSharedStructures) {
841
- throw new Error('Too many shared structures')
842
- }
843
890
 
844
- this.encode = function(value) {
891
+ this.encode = function(value, encodeOptions) {
845
892
  if (!target) {
846
893
  target = new ByteArrayAllocate(8192);
847
894
  targetView = new DataView(target.buffer, 0, 8192);
@@ -854,7 +901,8 @@ class Encoder extends Decoder {
854
901
  targetView = new DataView(target.buffer, 0, target.length);
855
902
  safeEnd = target.length - 10;
856
903
  position$1 = 0;
857
- }
904
+ } else if (encodeOptions === REUSE_BUFFER_MODE)
905
+ position$1 = (position$1 + 7) & 0x7ffffff8; // Word align to make any future copying of this buffer faster
858
906
  start = position$1;
859
907
  referenceMap = encoder.structuredClone ? new Map() : null;
860
908
  sharedStructures = encoder.structures;
@@ -862,7 +910,7 @@ class Encoder extends Decoder {
862
910
  if (sharedStructures.uninitialized)
863
911
  encoder.structures = sharedStructures = encoder.getStructures();
864
912
  let sharedStructuresLength = sharedStructures.length;
865
- if (sharedStructuresLength > maxSharedStructures && !isSequential)
913
+ if (sharedStructuresLength > maxSharedStructures && !isSequential)
866
914
  sharedStructuresLength = maxSharedStructures;
867
915
  if (!sharedStructures.transitions) {
868
916
  // rebuild our structure transitions
@@ -872,8 +920,8 @@ class Encoder extends Decoder {
872
920
  if (!keys)
873
921
  continue
874
922
  let nextTransition, transition = sharedStructures.transitions;
875
- for (let i =0, l = keys.length; i < l; i++) {
876
- let key = keys[i];
923
+ for (let j = 0, l = keys.length; j < l; j++) {
924
+ let key = keys[j];
877
925
  nextTransition = transition[key];
878
926
  if (!nextTransition) {
879
927
  nextTransition = transition[key] = Object.create(null);
@@ -902,7 +950,12 @@ class Encoder extends Decoder {
902
950
  referenceMap = null;
903
951
  return serialized
904
952
  }
905
- return target.subarray(start, position$1) // position can change if we call encode again in saveStructures, so we get the buffer now
953
+ if (encodeOptions === REUSE_BUFFER_MODE) {
954
+ target.start = start;
955
+ target.end = position$1;
956
+ return target
957
+ }
958
+ return target.subarray(start, position$1) // position can change if we call pack again in saveStructures, so we get the buffer now
906
959
  } finally {
907
960
  if (sharedStructures) {
908
961
  if (serializationsSinceTransitionRebuild < 10)
@@ -916,7 +969,7 @@ class Encoder extends Decoder {
916
969
  recordIdsToRemove = [];
917
970
  } else if (recordIdsToRemove.length > 0 && !isSequential) {
918
971
  for (let i = 0, l = recordIdsToRemove.length; i < l; i++) {
919
- recordIdsToRemove[i][RECORD_SYMBOL] = 0;
972
+ recordIdsToRemove[i][RECORD_SYMBOL] = undefined;
920
973
  }
921
974
  recordIdsToRemove = [];
922
975
  }
@@ -924,13 +977,15 @@ class Encoder extends Decoder {
924
977
  if (encoder.structures.length > maxSharedStructures) {
925
978
  encoder.structures = encoder.structures.slice(0, maxSharedStructures);
926
979
  }
927
-
980
+ // we can't rely on start/end with REUSE_BUFFER_MODE since they will (probably) change when we save
981
+ let returnBuffer = target.subarray(start, position$1);
928
982
  if (encoder.saveStructures(encoder.structures, lastSharedStructuresLength) === false) {
929
983
  // get updated structures and try again if the update failed
930
984
  encoder.structures = encoder.getStructures() || [];
931
985
  return encoder.encode(value)
932
986
  }
933
987
  lastSharedStructuresLength = encoder.structures.length;
988
+ return returnBuffer
934
989
  }
935
990
  }
936
991
  }
@@ -1051,7 +1106,7 @@ class Encoder extends Decoder {
1051
1106
  targetView.setFloat32(position$1, value);
1052
1107
  let xShifted;
1053
1108
  if (useFloat32 < 4 ||
1054
- // this checks for rounding of numbers that were encoded in 32-bit float to nearest significant decimal digit that could be preserved
1109
+ // this checks for rounding of numbers that were encoded in 32-bit float to nearest significant decimal digit that could be preserved
1055
1110
  ((xShifted = value * mult10[((target[position$1] & 0x7f) << 1) | (target[position$1 + 1] >> 7)]) >> 0) === xShifted) {
1056
1111
  position$1 += 4;
1057
1112
  return
@@ -1097,6 +1152,12 @@ class Encoder extends Decoder {
1097
1152
  encode(value[i]);
1098
1153
  }
1099
1154
  } else if (constructor === Map) {
1155
+ if (this.mapsAsObjects ? this.useTag259ForMaps !== false : this.useTag259ForMaps) {
1156
+ // use Tag 259 (https://github.com/shanewholloway/js-cbor-codec/blob/master/docs/CBOR-259-spec--explicit-maps.md) for maps if the user wants it that way
1157
+ target[position$1++] = 0xd9;
1158
+ target[position$1++] = 1;
1159
+ target[position$1++] = 3;
1160
+ }
1100
1161
  length = value.size;
1101
1162
  if (length < 0x18) {
1102
1163
  target[position$1++] = 0xa0 | length;
@@ -1174,10 +1235,9 @@ class Encoder extends Decoder {
1174
1235
  }
1175
1236
  position$1 += 8;
1176
1237
  } else if (type === 'undefined') {
1177
- //target[position++] = 0xc1 // this is the "never-used" byte
1178
1238
  target[position$1++] = 0xf7;
1179
1239
  } else {
1180
- throw new Error('Unknown type ' + type)
1240
+ throw new Error('Unknown type: ' + type)
1181
1241
  }
1182
1242
  };
1183
1243
 
@@ -1266,7 +1326,7 @@ class Encoder extends Decoder {
1266
1326
  let nextTransition, transition = structures.transitions || (structures.transitions = Object.create(null));
1267
1327
  let newTransitions = 0;
1268
1328
  let length = keys.length;
1269
- for (let i =0; i < length; i++) {
1329
+ for (let i = 0; i < length; i++) {
1270
1330
  let key = keys[i];
1271
1331
  nextTransition = transition[key];
1272
1332
  if (!nextTransition) {
@@ -1276,7 +1336,7 @@ class Encoder extends Decoder {
1276
1336
  transition = nextTransition;
1277
1337
  }
1278
1338
  let recordId = transition[RECORD_SYMBOL];
1279
- if (recordId) {
1339
+ if (recordId !== undefined) {
1280
1340
  target[position$1++] = 0xd9; // tag two byte
1281
1341
  target[position$1++] = RECORD_STARTING_ID_PREFIX;
1282
1342
  target[position$1++] = recordId;
@@ -1303,7 +1363,7 @@ class Encoder extends Decoder {
1303
1363
  transitionsCount += serializationsSinceTransitionRebuild * newTransitions;
1304
1364
  // record the removal of the id, we can maintain our shared structure
1305
1365
  if (recordIdsToRemove.length >= MAX_STRUCTURES - maxSharedStructures)
1306
- recordIdsToRemove.shift()[RECORD_SYMBOL] = 0; // we are cycling back through, and have to remove old ones
1366
+ recordIdsToRemove.shift()[RECORD_SYMBOL] = undefined; // we are cycling back through, and have to remove old ones
1307
1367
  recordIdsToRemove.push(transition);
1308
1368
  if (length < 0x16)
1309
1369
  target[position$1++] = 0x82 + length; // array header, length of values + 2
@@ -1443,7 +1503,9 @@ function typedArrayEncoder(tag) {
1443
1503
  }
1444
1504
  function writeBuffer(buffer, makeRoom) {
1445
1505
  let length = buffer.byteLength;
1446
- if (length < 0x100) {
1506
+ if (length < 0x18) {
1507
+ target[position$1++] = 0x40 + length;
1508
+ } else if (length < 0x100) {
1447
1509
  target[position$1++] = 0x58;
1448
1510
  target[position$1++] = length;
1449
1511
  } else if (length < 0x10000) {
@@ -1498,24 +1560,21 @@ function addExtension$1(extension) {
1498
1560
  }
1499
1561
  let defaultEncoder = new Encoder({ useRecords: false });
1500
1562
  const encode = defaultEncoder.encode;
1501
- const { NEVER, ALWAYS, DECIMAL_ROUND, DECIMAL_FIT } = FLOAT32_OPTIONS;
1563
+ const { NEVER, ALWAYS, DECIMAL_ROUND, DECIMAL_FIT } = FLOAT32_OPTIONS;
1564
+ const REUSE_BUFFER_MODE = 1000;
1502
1565
 
1503
1566
  class EncoderStream extends stream.Transform {
1504
1567
  constructor(options) {
1505
1568
  if (!options)
1506
1569
  options = {};
1570
+ options.writableObjectMode = true;
1507
1571
  super(options);
1508
1572
  options.sequential = true;
1509
- this.encoder = new Encoder(options);
1573
+ this.encoder = options.encoder || new Encoder(options);
1510
1574
  }
1511
- write(value) {
1575
+ _transform(value, encoding, callback) {
1512
1576
  this.push(this.encoder.encode(value));
1513
- }
1514
-
1515
- end(value) {
1516
- if (value != null)
1517
- this.push(this.encoder.encode(value));
1518
- this.push(null);
1577
+ callback();
1519
1578
  }
1520
1579
  }
1521
1580
 
@@ -1526,53 +1585,136 @@ class DecoderStream extends stream.Transform {
1526
1585
  options.objectMode = true;
1527
1586
  super(options);
1528
1587
  options.structures = [];
1529
- this.decoder = new Decoder(options);
1588
+ this.decoder = options.decoder || new Decoder(options);
1530
1589
  }
1531
1590
  _transform(chunk, encoding, callback) {
1532
1591
  if (this.incompleteBuffer) {
1533
1592
  chunk = Buffer.concat([this.incompleteBuffer, chunk]);
1534
1593
  this.incompleteBuffer = null;
1535
1594
  }
1536
- let position = 0;
1537
- let size = chunk.length;
1595
+ let values;
1538
1596
  try {
1539
- this.push(this.decoder.decode(chunk, size, true));
1540
- position = getPosition();
1541
- while (position < size) {
1542
- let value = read();
1543
- this.push(value);
1544
- position = getPosition();
1545
- }
1597
+ values = this.decoder.decodeMultiple(chunk);
1546
1598
  } catch(error) {
1547
- if (error.incomplete)
1548
- this.incompleteBuffer = chunk.slice(position);
1599
+ if (error.incomplete) {
1600
+ this.incompleteBuffer = chunk.slice(error.lastPosition);
1601
+ values = error.values;
1602
+ }
1549
1603
  else
1550
1604
  throw error
1551
1605
  } finally {
1552
- clearSource();
1606
+ for (let value of values || []) {
1607
+ if (value === null)
1608
+ value = this.getNullValue();
1609
+ this.push(value);
1610
+ }
1553
1611
  }
1554
1612
  if (callback) callback();
1555
1613
  }
1614
+ getNullValue() {
1615
+ return Symbol.for(null)
1616
+ }
1617
+ }
1618
+
1619
+ /**
1620
+ * Given an Iterable first argument, returns an Iterable where each value is encoded as a Buffer
1621
+ * If the argument is only Async Iterable, the return value will be an Async Iterable.
1622
+ * @param {Iterable|Iterator|AsyncIterable|AsyncIterator} objectIterator - iterable source, like a Readable object stream, an array, Set, or custom object
1623
+ * @param {options} [options] - cbor-x Encoder options
1624
+ * @returns {IterableIterator|Promise.<AsyncIterableIterator>}
1625
+ */
1626
+ function encodeIter (objectIterator, options = {}) {
1627
+ if (!objectIterator || typeof objectIterator !== 'object') {
1628
+ throw new Error('first argument must be an Iterable, Async Iterable, or a Promise for an Async Iterable')
1629
+ } else if (typeof objectIterator[Symbol.iterator] === 'function') {
1630
+ return encodeIterSync(objectIterator, options)
1631
+ } else if (typeof objectIterator.then === 'function' || typeof objectIterator[Symbol.asyncIterator] === 'function') {
1632
+ return encodeIterAsync(objectIterator, options)
1633
+ } else {
1634
+ throw new Error('first argument must be an Iterable, Async Iterable, Iterator, Async Iterator, or a Promise')
1635
+ }
1636
+ }
1637
+
1638
+ function * encodeIterSync (objectIterator, options) {
1639
+ const encoder = new Encoder(options);
1640
+ for (const value of objectIterator) {
1641
+ yield encoder.encode(value);
1642
+ }
1643
+ }
1644
+
1645
+ async function * encodeIterAsync (objectIterator, options) {
1646
+ const encoder = new Encoder(options);
1647
+ for await (const value of objectIterator) {
1648
+ yield encoder.encode(value);
1649
+ }
1650
+ }
1651
+
1652
+ /**
1653
+ * Given an Iterable/Iterator input which yields buffers, returns an IterableIterator which yields sync decoded objects
1654
+ * Or, given an Async Iterable/Iterator which yields promises resolving in buffers, returns an AsyncIterableIterator.
1655
+ * @param {Iterable|Iterator|AsyncIterable|AsyncIterableIterator} bufferIterator
1656
+ * @param {object} [options] - Decoder options
1657
+ * @returns {IterableIterator|Promise.<AsyncIterableIterator}
1658
+ */
1659
+ function decodeIter (bufferIterator, options = {}) {
1660
+ if (!bufferIterator || typeof bufferIterator !== 'object') {
1661
+ throw new Error('first argument must be an Iterable, Async Iterable, Iterator, Async Iterator, or a promise')
1662
+ }
1663
+
1664
+ const decoder = new Decoder(options);
1665
+ let incomplete;
1666
+ const parser = (chunk) => {
1667
+ let yields;
1668
+ // if there's incomplete data from previous chunk, concatinate and try again
1669
+ if (incomplete) {
1670
+ chunk = Buffer.concat([incomplete, chunk]);
1671
+ incomplete = undefined;
1672
+ }
1673
+
1674
+ try {
1675
+ yields = decoder.decodeMultiple(chunk);
1676
+ } catch (err) {
1677
+ if (err.incomplete) {
1678
+ incomplete = chunk.slice(err.lastPosition);
1679
+ yields = err.values;
1680
+ } else {
1681
+ throw err
1682
+ }
1683
+ }
1684
+ return yields
1685
+ };
1686
+
1687
+ if (typeof bufferIterator[Symbol.iterator] === 'function') {
1688
+ return (function * iter () {
1689
+ for (const value of bufferIterator) {
1690
+ yield * parser(value);
1691
+ }
1692
+ })()
1693
+ } else if (typeof bufferIterator[Symbol.asyncIterator] === 'function') {
1694
+ return (async function * iter () {
1695
+ for await (const value of bufferIterator) {
1696
+ yield * parser(value);
1697
+ }
1698
+ })()
1699
+ }
1556
1700
  }
1557
1701
 
1558
1702
  const useRecords = false;
1559
1703
  const mapsAsObjects = true;
1560
1704
 
1561
- const extractor = tryRequire('msgpackr-extract');
1705
+ const extractor = tryRequire('cbor-extract');
1562
1706
  if (extractor)
1563
1707
  setExtractor(extractor.extractStrings);
1564
- /*
1565
- Object.assign(exports, unpackModule.FLOAT32_OPTIONS)
1566
- */
1708
+
1567
1709
  function tryRequire(moduleId) {
1568
1710
  try {
1569
1711
  let require$1 = module$1.createRequire((typeof document === 'undefined' ? new (require('u' + 'rl').URL)('file:' + __filename).href : (document.currentScript && document.currentScript.src || new URL('node.cjs', document.baseURI).href)));
1570
1712
  return require$1(moduleId)
1571
1713
  } catch (error) {
1572
1714
  if (typeof window == 'undefined')
1573
- console.warn('Native extraction module not loaded, msgpackr will still run, but with decreased performance. ' + error.message.split('\n')[0]);
1715
+ console.warn('Native extraction module not loaded, cbor-x will still run, but with decreased performance. ' + error.message.split('\n')[0]);
1574
1716
  else
1575
- console.warn('For browser usage, directly use msgpackr/unpack or msgpackr/pack modules. ' + error.message.split('\n')[0]);
1717
+ console.warn('For browser usage, directly use cbor-x/decode or cbor-x/encode modules. ' + error.message.split('\n')[0]);
1576
1718
  }
1577
1719
  }
1578
1720
 
@@ -1585,10 +1727,15 @@ exports.Encoder = Encoder;
1585
1727
  exports.EncoderStream = EncoderStream;
1586
1728
  exports.FLOAT32_OPTIONS = FLOAT32_OPTIONS;
1587
1729
  exports.NEVER = NEVER;
1730
+ exports.REUSE_BUFFER_MODE = REUSE_BUFFER_MODE;
1588
1731
  exports.Tag = Tag;
1589
1732
  exports.addExtension = addExtension$1;
1733
+ exports.clearSource = clearSource;
1590
1734
  exports.decode = decode;
1735
+ exports.decodeIter = decodeIter;
1591
1736
  exports.decodeMultiple = decodeMultiple;
1592
1737
  exports.encode = encode;
1738
+ exports.encodeIter = encodeIter;
1593
1739
  exports.mapsAsObjects = mapsAsObjects;
1740
+ exports.roundFloat32 = roundFloat32;
1594
1741
  exports.useRecords = useRecords;
package/dist/test.js CHANGED
@@ -581,7 +581,7 @@
581
581
  outcomesScore: outcomesScore
582
582
  };
583
583
 
584
- //import inspector from 'inspector'; inspector.open(9330, null, true); debugger
584
+ //import inspector from 'inspector'; inspector.open(9229, null, true); debugger
585
585
  function tryRequire(module) {
586
586
  try {
587
587
  return require(module)
@@ -659,6 +659,13 @@
659
659
  assert.deepEqual(deserialized, data);
660
660
  });
661
661
 
662
+ test('255 chars', function() {
663
+ const data = 'RRZG9A6I7xupPeOZhxcOcioFsuhszGOdyDUcbRf4Zef2kdPIfC9RaLO4jTM5JhuZvTsF09fbRHMGtqk7YAgu3vespeTe9l61ziZ6VrMnYu2CamK96wCkmz0VUXyqaiUoTPgzk414LS9yYrd5uh7w18ksJF5SlC2e91rukWvNqAZJjYN3jpkqHNOFchCwFrhbxq2Lrv1kSJPYCx9blRg2hGmYqTbElLTZHv20iNqwZeQbRMgSBPT6vnbCBPnOh1W';
664
+ var serialized = CBOR.encode(data);
665
+ var deserialized = CBOR.decode(serialized);
666
+ assert.equal(deserialized, data);
667
+ });
668
+
662
669
  test('encode/decode sample data', function(){
663
670
  var data = sampleData;
664
671
  var serialized = CBOR.encode(data);
@@ -787,10 +794,13 @@
787
794
  let fa = new Float32Array(b.buffer, 8, 2);
788
795
  fa[0] = 2.25;
789
796
  fa[1] = 6;
797
+ let map = new Map();
798
+ map.set('key', 'value');
790
799
  let object = {
791
800
  error: new Error('test'),
792
801
  set: new Set(['a', 'b']),
793
802
  regexp: /test/gi,
803
+ map,
794
804
  float32Array: fa,
795
805
  uint16Array: new Uint16Array([3,4])
796
806
  };
@@ -800,6 +810,7 @@
800
810
  var serialized = encoder.encode(object);
801
811
  var deserialized = encoder.decode(serialized);
802
812
  assert.deepEqual(Array.from(deserialized.set), Array.from(object.set));
813
+ assert.equal(deserialized.map.get('key'), 'value');
803
814
  assert.equal(deserialized.error.message, object.error.message);
804
815
  assert.equal(deserialized.regexp.test('TEST'), true);
805
816
  assert.equal(deserialized.float32Array.constructor.name, 'Float32Array');
@@ -810,6 +821,19 @@
810
821
  assert.equal(deserialized.uint16Array[1], 4);
811
822
  });
812
823
 
824
+ test('explicit maps and sets', function () {
825
+ let map = new Map();
826
+ map.set('key', { inside: 'value'});
827
+ let object = {
828
+ set: new Set(['a', 'b']),
829
+ map,
830
+ };
831
+ var serialized = encode(object); // default encoder
832
+ var deserialized = decode(serialized);
833
+ assert.deepEqual(Array.from(deserialized.set), Array.from(object.set));
834
+ assert.equal(deserialized.map.get('key').inside, 'value');
835
+ });
836
+
813
837
  test('object without prototype', function(){
814
838
  var data = Object.create(null);
815
839
  data.test = 3;
@@ -825,6 +849,13 @@
825
849
  var decoded = decode(encoded);
826
850
  assert.equal(decoded.length, size);
827
851
  });
852
+ test('little buffer', function() {
853
+ var data = typeof Buffer == 'undefined' ? new Uint8Array(0) : Buffer.alloc(0);
854
+ var encoded = encode(data);
855
+ assert.equal(encoded.length, 1); // make sure to use canonical form
856
+ var decoded = decode(encoded);
857
+ assert.equal(decoded.length, 0);
858
+ });
828
859
 
829
860
  test('random strings', function(){
830
861
  var data = [];
@@ -872,6 +903,7 @@
872
903
  let encoder = new Encoder({
873
904
  mapsAsObjects: true,
874
905
  useTimestamp32: true,
906
+ useTag259ForMaps: false,
875
907
  });
876
908
  var serialized = encoder.encode(data);
877
909
  var deserialized = encoder.decode(serialized);
package/encode.d.ts ADDED
@@ -0,0 +1,6 @@
1
+ import { Decoder } from './decode'
2
+ export { addExtension, FLOAT32_OPTIONS } from './unpack'
3
+ export class Encoder extends Decoder {
4
+ encode(value: any): Buffer
5
+ }
6
+ export function encode(value: any): Buffer