cbor-x 1.3.3 → 1.4.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/index.js CHANGED
@@ -707,8 +707,6 @@
707
707
  }
708
708
  }
709
709
 
710
- let glbl = typeof self == 'object' ? self : global;
711
-
712
710
  currentExtensions[0] = (dateString) => {
713
711
  // string date extension
714
712
  return new Date(dateString)
@@ -775,7 +773,7 @@
775
773
  return bundledStrings[1].slice(bundledStrings.position1, bundledStrings.position1 += value)
776
774
  return new Tag(value, 15)
777
775
  };
778
-
776
+ let glbl = { Error, RegExp };
779
777
  currentExtensions[27] = (data) => { // http://cbor.schmorp.de/generic-object
780
778
  return (glbl[data[0]] || Error)(data[1], data[2])
781
779
  };
@@ -900,13 +898,17 @@
900
898
  });
901
899
 
902
900
  const isLittleEndianMachine = new Uint8Array(new Uint16Array([1]).buffer)[0] == 1;
903
- const typedArrays = ['Uint8', 'Uint8Clamped', 'Uint16', 'Uint32', 'BigUint64','Int8', 'Int16', 'Int32', 'BigInt64', 'Float32', 'Float64'];
901
+ const typedArrays = [Uint8Array, Uint8ClampedArray, Uint16Array, Uint32Array,
902
+ typeof BigUint64Array == 'undefined' ? { name:'BigUint64Array' } : BigUint64Array, Int8Array, Int16Array, Int32Array,
903
+ typeof BigInt64Array == 'undefined' ? { name:'BigInt64Array' } : BigInt64Array, Float32Array, Float64Array];
904
904
  const typedArrayTags = [64, 68, 69, 70, 71, 72, 77, 78, 79, 85, 86];
905
905
  for (let i = 0; i < typedArrays.length; i++) {
906
906
  registerTypedArray(typedArrays[i], typedArrayTags[i]);
907
907
  }
908
- function registerTypedArray(typedArrayId, tag, littleEndian) {
909
- let TypedArray = glbl[typedArrayId + 'Array'];
908
+ function registerTypedArray(TypedArray, tag) {
909
+ let dvMethod = 'get' + TypedArray.name.slice(0, -5);
910
+ if (typeof TypedArray !== 'function')
911
+ TypedArray = null;
910
912
  let bytesPerElement = TypedArray.BYTES_PER_ELEMENT;
911
913
  for (let littleEndian = 0; littleEndian < 2; littleEndian++) {
912
914
  if (!littleEndian && bytesPerElement == 1)
@@ -923,7 +925,7 @@
923
925
  let dv = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);
924
926
  let elements = buffer.length >> sizeShift;
925
927
  let ta = new TypedArray(elements);
926
- let method = dv['get' + typedArrayId];
928
+ let method = dv[dvMethod];
927
929
  for (let i = 0; i < elements; i++) {
928
930
  ta[i] = method.call(dv, i << sizeShift, littleEndian);
929
931
  }
@@ -1047,1113 +1049,1121 @@
1047
1049
  return ((multiplier * float32Number + (float32Number > 0 ? 0.5 : -0.5)) >> 0) / multiplier
1048
1050
  }
1049
1051
 
1050
- let textEncoder;
1051
- try {
1052
- textEncoder = new TextEncoder();
1053
- } catch (error) {}
1054
- let extensions, extensionClasses;
1055
- const hasNodeBuffer = typeof Buffer !== 'undefined';
1056
- const ByteArrayAllocate = hasNodeBuffer ? Buffer.allocUnsafeSlow : Uint8Array;
1057
- const ByteArray = hasNodeBuffer ? Buffer : Uint8Array;
1058
- const MAX_STRUCTURES = 0x100;
1059
- const MAX_BUFFER_SIZE = hasNodeBuffer ? 0x100000000 : 0x7fd00000;
1060
- let target;
1061
- let targetView;
1062
- let position$1 = 0;
1063
- let safeEnd;
1064
- let bundledStrings$1 = null;
1065
- const MAX_BUNDLE_SIZE = 0xf000;
1066
- const hasNonLatin = /[\u0080-\uFFFF]/;
1067
- const RECORD_SYMBOL = Symbol('record-id');
1068
- class Encoder extends Decoder {
1069
- constructor(options) {
1070
- super(options);
1071
- this.offset = 0;
1072
- let start;
1073
- let sharedStructures;
1074
- let hasSharedUpdate;
1075
- let structures;
1076
- let referenceMap;
1077
- options = options || {};
1078
- let encodeUtf8 = ByteArray.prototype.utf8Write ? function(string, position, maxBytes) {
1079
- return target.utf8Write(string, position, maxBytes)
1080
- } : (textEncoder && textEncoder.encodeInto) ?
1081
- function(string, position) {
1082
- return textEncoder.encodeInto(string, target.subarray(position)).written
1083
- } : false;
1084
-
1085
- let encoder = this;
1086
- let hasSharedStructures = options.structures || options.saveStructures;
1087
- let maxSharedStructures = options.maxSharedStructures;
1088
- if (maxSharedStructures == null)
1089
- maxSharedStructures = hasSharedStructures ? 128 : 0;
1090
- if (maxSharedStructures > 8190)
1091
- throw new Error('Maximum maxSharedStructure is 8190')
1092
- let isSequential = options.sequential;
1093
- if (isSequential) {
1094
- maxSharedStructures = 0;
1095
- }
1096
- if (!this.structures)
1097
- this.structures = [];
1098
- if (this.saveStructures)
1099
- this.saveShared = this.saveStructures;
1100
- let samplingPackedValues, packedObjectMap, sharedValues = options.sharedValues;
1101
- let sharedPackedObjectMap;
1102
- if (sharedValues) {
1103
- sharedPackedObjectMap = Object.create(null);
1104
- for (let i = 0, l = sharedValues.length; i < l; i++) {
1105
- sharedPackedObjectMap[sharedValues[i]] = i;
1106
- }
1107
- }
1108
- let recordIdsToRemove = [];
1109
- let transitionsCount = 0;
1110
- let serializationsSinceTransitionRebuild = 0;
1111
-
1112
- this.mapEncode = function(value, encodeOptions) {
1113
- // Experimental support for premapping keys using _keyMap instad of keyMap - not optiimised yet)
1114
- if (this._keyMap && !this._mapped) {
1115
- //console.log('encoding ', value)
1116
- switch (value.constructor.name) {
1117
- case 'Array':
1118
- value = value.map(r => this.encodeKeys(r));
1119
- break
1120
- //case 'Map':
1121
- // value = this.encodeKeys(value)
1122
- // break
1123
- }
1124
- //this._mapped = true
1125
- }
1126
- return this.encode(value, encodeOptions)
1127
- };
1128
-
1129
- this.encode = function(value, encodeOptions) {
1130
- if (!target) {
1131
- target = new ByteArrayAllocate(8192);
1132
- targetView = new DataView(target.buffer, 0, 8192);
1133
- position$1 = 0;
1134
- }
1135
- safeEnd = target.length - 10;
1136
- if (safeEnd - position$1 < 0x800) {
1137
- // don't start too close to the end,
1138
- target = new ByteArrayAllocate(target.length);
1139
- targetView = new DataView(target.buffer, 0, target.length);
1140
- safeEnd = target.length - 10;
1141
- position$1 = 0;
1142
- } else if (encodeOptions === REUSE_BUFFER_MODE)
1143
- position$1 = (position$1 + 7) & 0x7ffffff8; // Word align to make any future copying of this buffer faster
1144
- start = position$1;
1145
- if (encoder.useSelfDescribedHeader) {
1146
- targetView.setUint32(position$1, 0xd9d9f700); // tag two byte, then self-descriptive tag
1147
- position$1 += 3;
1148
- }
1149
- referenceMap = encoder.structuredClone ? new Map() : null;
1150
- if (encoder.bundleStrings && typeof value !== 'string') {
1151
- bundledStrings$1 = [];
1152
- bundledStrings$1.size = Infinity; // force a new bundle start on first string
1153
- } else
1154
- bundledStrings$1 = null;
1155
-
1156
- sharedStructures = encoder.structures;
1157
- if (sharedStructures) {
1158
- if (sharedStructures.uninitialized) {
1159
- let sharedData = encoder.getShared() || {};
1160
- encoder.structures = sharedStructures = sharedData.structures || [];
1161
- encoder.sharedVersion = sharedData.version;
1162
- let sharedValues = encoder.sharedValues = sharedData.packedValues;
1163
- if (sharedValues) {
1164
- sharedPackedObjectMap = {};
1165
- for (let i = 0, l = sharedValues.length; i < l; i++)
1166
- sharedPackedObjectMap[sharedValues[i]] = i;
1167
- }
1168
- }
1169
- let sharedStructuresLength = sharedStructures.length;
1170
- if (sharedStructuresLength > maxSharedStructures && !isSequential)
1171
- sharedStructuresLength = maxSharedStructures;
1172
- if (!sharedStructures.transitions) {
1173
- // rebuild our structure transitions
1174
- sharedStructures.transitions = Object.create(null);
1175
- for (let i = 0; i < sharedStructuresLength; i++) {
1176
- let keys = sharedStructures[i];
1177
- //console.log('shared struct keys:', keys)
1178
- if (!keys)
1179
- continue
1180
- let nextTransition, transition = sharedStructures.transitions;
1181
- for (let j = 0, l = keys.length; j < l; j++) {
1182
- if (transition[RECORD_SYMBOL] === undefined)
1183
- transition[RECORD_SYMBOL] = i;
1184
- let key = keys[j];
1185
- nextTransition = transition[key];
1186
- if (!nextTransition) {
1187
- nextTransition = transition[key] = Object.create(null);
1188
- }
1189
- transition = nextTransition;
1190
- }
1191
- transition[RECORD_SYMBOL] = i | 0x100000;
1192
- }
1193
- }
1194
- if (!isSequential)
1195
- sharedStructures.nextId = sharedStructuresLength;
1196
- }
1197
- if (hasSharedUpdate)
1198
- hasSharedUpdate = false;
1199
- structures = sharedStructures || [];
1200
- packedObjectMap = sharedPackedObjectMap;
1201
- if (options.pack) {
1202
- let packedValues = new Map();
1203
- packedValues.values = [];
1204
- packedValues.encoder = encoder;
1205
- packedValues.maxValues = options.maxPrivatePackedValues || (sharedPackedObjectMap ? 16 : Infinity);
1206
- packedValues.objectMap = sharedPackedObjectMap || false;
1207
- packedValues.samplingPackedValues = samplingPackedValues;
1208
- findRepetitiveStrings(value, packedValues);
1209
- if (packedValues.values.length > 0) {
1210
- target[position$1++] = 0xd8; // one-byte tag
1211
- target[position$1++] = 51; // tag 51 for packed shared structures https://www.potaroo.net/ietf/ids/draft-ietf-cbor-packed-03.txt
1212
- writeArrayHeader(4);
1213
- let valuesArray = packedValues.values;
1214
- encode(valuesArray);
1215
- writeArrayHeader(0); // prefixes
1216
- writeArrayHeader(0); // suffixes
1217
- packedObjectMap = Object.create(sharedPackedObjectMap || null);
1218
- for (let i = 0, l = valuesArray.length; i < l; i++) {
1219
- packedObjectMap[valuesArray[i]] = i;
1220
- }
1221
- }
1222
- }
1223
- try {
1224
- encode(value);
1225
- if (bundledStrings$1) {
1226
- writeBundles(start, encode);
1227
- }
1228
- encoder.offset = position$1; // update the offset so next serialization doesn't write over our buffer, but can continue writing to same buffer sequentially
1229
- if (referenceMap && referenceMap.idsToInsert) {
1230
- position$1 += referenceMap.idsToInsert.length * 2;
1231
- if (position$1 > safeEnd)
1232
- makeRoom(position$1);
1233
- encoder.offset = position$1;
1234
- let serialized = insertIds(target.subarray(start, position$1), referenceMap.idsToInsert);
1235
- referenceMap = null;
1236
- return serialized
1237
- }
1238
- if (encodeOptions & REUSE_BUFFER_MODE) {
1239
- target.start = start;
1240
- target.end = position$1;
1241
- return target
1242
- }
1243
- return target.subarray(start, position$1) // position can change if we call encode again in saveShared, so we get the buffer now
1244
- } finally {
1245
- if (sharedStructures) {
1246
- if (serializationsSinceTransitionRebuild < 10)
1247
- serializationsSinceTransitionRebuild++;
1248
- if (sharedStructures.length > maxSharedStructures)
1249
- sharedStructures.length = maxSharedStructures;
1250
- if (transitionsCount > 10000) {
1251
- // force a rebuild occasionally after a lot of transitions so it can get cleaned up
1252
- sharedStructures.transitions = null;
1253
- serializationsSinceTransitionRebuild = 0;
1254
- transitionsCount = 0;
1255
- if (recordIdsToRemove.length > 0)
1256
- recordIdsToRemove = [];
1257
- } else if (recordIdsToRemove.length > 0 && !isSequential) {
1258
- for (let i = 0, l = recordIdsToRemove.length; i < l; i++) {
1259
- recordIdsToRemove[i][RECORD_SYMBOL] = undefined;
1260
- }
1261
- recordIdsToRemove = [];
1262
- //sharedStructures.nextId = maxSharedStructures
1263
- }
1264
- }
1265
- if (hasSharedUpdate && encoder.saveShared) {
1266
- if (encoder.structures.length > maxSharedStructures) {
1267
- encoder.structures = encoder.structures.slice(0, maxSharedStructures);
1268
- }
1269
- // we can't rely on start/end with REUSE_BUFFER_MODE since they will (probably) change when we save
1270
- let returnBuffer = target.subarray(start, position$1);
1271
- if (encoder.updateSharedData() === false)
1272
- return encoder.encode(value) // re-encode if it fails
1273
- return returnBuffer
1274
- }
1275
- if (encodeOptions & RESET_BUFFER_MODE)
1276
- position$1 = start;
1277
- }
1278
- };
1279
- this.findCommonStringsToPack = () => {
1280
- samplingPackedValues = new Map();
1281
- if (!sharedPackedObjectMap)
1282
- sharedPackedObjectMap = Object.create(null);
1283
- return (options) => {
1284
- let threshold = options && options.threshold || 4;
1285
- let position = this.pack ? options.maxPrivatePackedValues || 16 : 0;
1286
- if (!sharedValues)
1287
- sharedValues = this.sharedValues = [];
1288
- for (let [ key, status ] of samplingPackedValues) {
1289
- if (status.count > threshold) {
1290
- sharedPackedObjectMap[key] = position++;
1291
- sharedValues.push(key);
1292
- hasSharedUpdate = true;
1293
- }
1294
- }
1295
- while (this.saveShared && this.updateSharedData() === false) {}
1296
- samplingPackedValues = null;
1297
- }
1298
- };
1299
- const encode = (value) => {
1300
- if (position$1 > safeEnd)
1301
- target = makeRoom(position$1);
1302
-
1303
- var type = typeof value;
1304
- var length;
1305
- if (type === 'string') {
1306
- if (packedObjectMap) {
1307
- let packedPosition = packedObjectMap[value];
1308
- if (packedPosition >= 0) {
1309
- if (packedPosition < 16)
1310
- target[position$1++] = packedPosition + 0xe0; // simple values, defined in https://www.potaroo.net/ietf/ids/draft-ietf-cbor-packed-03.txt
1311
- else {
1312
- target[position$1++] = 0xc6; // tag 6 defined in https://www.potaroo.net/ietf/ids/draft-ietf-cbor-packed-03.txt
1313
- if (packedPosition & 1)
1314
- encode((15 - packedPosition) >> 1);
1315
- else
1316
- encode((packedPosition - 16) >> 1);
1317
- }
1318
- return
1319
- /* } else if (packedStatus.serializationId != serializationId) {
1320
- packedStatus.serializationId = serializationId
1321
- packedStatus.count = 1
1322
- if (options.sharedPack) {
1323
- let sharedCount = packedStatus.sharedCount = (packedStatus.sharedCount || 0) + 1
1324
- if (shareCount > (options.sharedPack.threshold || 5)) {
1325
- let sharedPosition = packedStatus.position = packedStatus.nextSharedPosition
1326
- hasSharedUpdate = true
1327
- if (sharedPosition < 16)
1328
- target[position++] = sharedPosition + 0xc0
1329
-
1330
- }
1331
- }
1332
- } // else any in-doc incrementation?*/
1333
- } else if (samplingPackedValues && !options.pack) {
1334
- let status = samplingPackedValues.get(value);
1335
- if (status)
1336
- status.count++;
1337
- else
1338
- samplingPackedValues.set(value, {
1339
- count: 1,
1340
- });
1341
- }
1342
- }
1343
- let strLength = value.length;
1344
- if (bundledStrings$1 && strLength >= 4 && strLength < 0x400) {
1345
- if ((bundledStrings$1.size += strLength) > MAX_BUNDLE_SIZE) {
1346
- let extStart;
1347
- let maxBytes = (bundledStrings$1[0] ? bundledStrings$1[0].length * 3 + bundledStrings$1[1].length : 0) + 10;
1348
- if (position$1 + maxBytes > safeEnd)
1349
- target = makeRoom(position$1 + maxBytes);
1350
- target[position$1++] = 0xd9; // tag 16-bit
1351
- target[position$1++] = 0xdf; // tag 0xdff9
1352
- target[position$1++] = 0xf9;
1353
- // TODO: If we only have one bundle with any string data, only write one string bundle
1354
- target[position$1++] = bundledStrings$1.position ? 0x84 : 0x82; // array of 4 or 2 elements depending on if we write bundles
1355
- target[position$1++] = 0x1a; // 32-bit unsigned int
1356
- extStart = position$1 - start;
1357
- position$1 += 4; // reserve for writing bundle reference
1358
- if (bundledStrings$1.position) {
1359
- writeBundles(start, encode); // write the last bundles
1360
- }
1361
- bundledStrings$1 = ['', '']; // create new ones
1362
- bundledStrings$1.size = 0;
1363
- bundledStrings$1.position = extStart;
1364
- }
1365
- let twoByte = hasNonLatin.test(value);
1366
- bundledStrings$1[twoByte ? 0 : 1] += value;
1367
- target[position$1++] = twoByte ? 0xce : 0xcf;
1368
- encode(strLength);
1369
- return
1370
- }
1371
- let headerSize;
1372
- // first we estimate the header size, so we can write to the correct location
1373
- if (strLength < 0x20) {
1374
- headerSize = 1;
1375
- } else if (strLength < 0x100) {
1376
- headerSize = 2;
1377
- } else if (strLength < 0x10000) {
1378
- headerSize = 3;
1379
- } else {
1380
- headerSize = 5;
1381
- }
1382
- let maxBytes = strLength * 3;
1383
- if (position$1 + maxBytes > safeEnd)
1384
- target = makeRoom(position$1 + maxBytes);
1385
-
1386
- if (strLength < 0x40 || !encodeUtf8) {
1387
- let i, c1, c2, strPosition = position$1 + headerSize;
1388
- for (i = 0; i < strLength; i++) {
1389
- c1 = value.charCodeAt(i);
1390
- if (c1 < 0x80) {
1391
- target[strPosition++] = c1;
1392
- } else if (c1 < 0x800) {
1393
- target[strPosition++] = c1 >> 6 | 0xc0;
1394
- target[strPosition++] = c1 & 0x3f | 0x80;
1395
- } else if (
1396
- (c1 & 0xfc00) === 0xd800 &&
1397
- ((c2 = value.charCodeAt(i + 1)) & 0xfc00) === 0xdc00
1398
- ) {
1399
- c1 = 0x10000 + ((c1 & 0x03ff) << 10) + (c2 & 0x03ff);
1400
- i++;
1401
- target[strPosition++] = c1 >> 18 | 0xf0;
1402
- target[strPosition++] = c1 >> 12 & 0x3f | 0x80;
1403
- target[strPosition++] = c1 >> 6 & 0x3f | 0x80;
1404
- target[strPosition++] = c1 & 0x3f | 0x80;
1405
- } else {
1406
- target[strPosition++] = c1 >> 12 | 0xe0;
1407
- target[strPosition++] = c1 >> 6 & 0x3f | 0x80;
1408
- target[strPosition++] = c1 & 0x3f | 0x80;
1409
- }
1410
- }
1411
- length = strPosition - position$1 - headerSize;
1412
- } else {
1413
- length = encodeUtf8(value, position$1 + headerSize, maxBytes);
1414
- }
1415
-
1416
- if (length < 0x18) {
1417
- target[position$1++] = 0x60 | length;
1418
- } else if (length < 0x100) {
1419
- if (headerSize < 2) {
1420
- target.copyWithin(position$1 + 2, position$1 + 1, position$1 + 1 + length);
1421
- }
1422
- target[position$1++] = 0x78;
1423
- target[position$1++] = length;
1424
- } else if (length < 0x10000) {
1425
- if (headerSize < 3) {
1426
- target.copyWithin(position$1 + 3, position$1 + 2, position$1 + 2 + length);
1427
- }
1428
- target[position$1++] = 0x79;
1429
- target[position$1++] = length >> 8;
1430
- target[position$1++] = length & 0xff;
1431
- } else {
1432
- if (headerSize < 5) {
1433
- target.copyWithin(position$1 + 5, position$1 + 3, position$1 + 3 + length);
1434
- }
1435
- target[position$1++] = 0x7a;
1436
- targetView.setUint32(position$1, length);
1437
- position$1 += 4;
1438
- }
1439
- position$1 += length;
1440
- } else if (type === 'number') {
1441
- if (value >>> 0 === value) {// positive integer, 32-bit or less
1442
- // positive uint
1443
- if (value < 0x18) {
1444
- target[position$1++] = value;
1445
- } else if (value < 0x100) {
1446
- target[position$1++] = 0x18;
1447
- target[position$1++] = value;
1448
- } else if (value < 0x10000) {
1449
- target[position$1++] = 0x19;
1450
- target[position$1++] = value >> 8;
1451
- target[position$1++] = value & 0xff;
1452
- } else {
1453
- target[position$1++] = 0x1a;
1454
- targetView.setUint32(position$1, value);
1455
- position$1 += 4;
1456
- }
1457
- } else if (value >> 0 === value) { // negative integer
1458
- if (value >= -0x18) {
1459
- target[position$1++] = 0x1f - value;
1460
- } else if (value >= -0x100) {
1461
- target[position$1++] = 0x38;
1462
- target[position$1++] = ~value;
1463
- } else if (value >= -0x10000) {
1464
- target[position$1++] = 0x39;
1465
- targetView.setUint16(position$1, ~value);
1466
- position$1 += 2;
1467
- } else {
1468
- target[position$1++] = 0x3a;
1469
- targetView.setUint32(position$1, ~value);
1470
- position$1 += 4;
1471
- }
1472
- } else {
1473
- let useFloat32;
1474
- if ((useFloat32 = this.useFloat32) > 0 && value < 0x100000000 && value >= -0x80000000) {
1475
- target[position$1++] = 0xfa;
1476
- targetView.setFloat32(position$1, value);
1477
- let xShifted;
1478
- if (useFloat32 < 4 ||
1479
- // this checks for rounding of numbers that were encoded in 32-bit float to nearest significant decimal digit that could be preserved
1480
- ((xShifted = value * mult10[((target[position$1] & 0x7f) << 1) | (target[position$1 + 1] >> 7)]) >> 0) === xShifted) {
1481
- position$1 += 4;
1482
- return
1483
- } else
1484
- position$1--; // move back into position for writing a double
1485
- }
1486
- target[position$1++] = 0xfb;
1487
- targetView.setFloat64(position$1, value);
1488
- position$1 += 8;
1489
- }
1490
- } else if (type === 'object') {
1491
- if (!value)
1492
- target[position$1++] = 0xf6;
1493
- else {
1494
- if (referenceMap) {
1495
- let referee = referenceMap.get(value);
1496
- if (referee) {
1497
- target[position$1++] = 0xd8;
1498
- target[position$1++] = 29; // http://cbor.schmorp.de/value-sharing
1499
- target[position$1++] = 0x19; // 16-bit uint
1500
- if (!referee.references) {
1501
- let idsToInsert = referenceMap.idsToInsert || (referenceMap.idsToInsert = []);
1502
- referee.references = [];
1503
- idsToInsert.push(referee);
1504
- }
1505
- referee.references.push(position$1 - start);
1506
- position$1 += 2; // TODO: also support 32-bit
1507
- return
1508
- } else
1509
- referenceMap.set(value, { offset: position$1 - start });
1510
- }
1511
- let constructor = value.constructor;
1512
- if (constructor === Object) {
1513
- writeObject(value, true);
1514
- } else if (constructor === Array) {
1515
- length = value.length;
1516
- if (length < 0x18) {
1517
- target[position$1++] = 0x80 | length;
1518
- } else {
1519
- writeArrayHeader(length);
1520
- }
1521
- for (let i = 0; i < length; i++) {
1522
- encode(value[i]);
1523
- }
1524
- } else if (constructor === Map) {
1525
- if (this.mapsAsObjects ? this.useTag259ForMaps !== false : this.useTag259ForMaps) {
1526
- // 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
1527
- target[position$1++] = 0xd9;
1528
- target[position$1++] = 1;
1529
- target[position$1++] = 3;
1530
- }
1531
- length = value.size;
1532
- if (length < 0x18) {
1533
- target[position$1++] = 0xa0 | length;
1534
- } else if (length < 0x100) {
1535
- target[position$1++] = 0xb8;
1536
- target[position$1++] = length;
1537
- } else if (length < 0x10000) {
1538
- target[position$1++] = 0xb9;
1539
- target[position$1++] = length >> 8;
1540
- target[position$1++] = length & 0xff;
1541
- } else {
1542
- target[position$1++] = 0xba;
1543
- targetView.setUint32(position$1, length);
1544
- position$1 += 4;
1545
- }
1546
- if (encoder.keyMap) {
1547
- for (let [ key, entryValue ] of value) {
1548
- encode(encoder.encodeKey(key));
1549
- encode(entryValue);
1550
- }
1551
- } else {
1552
- for (let [ key, entryValue ] of value) {
1553
- encode(key);
1554
- encode(entryValue);
1555
- }
1556
- }
1557
- } else {
1558
- for (let i = 0, l = extensions.length; i < l; i++) {
1559
- let extensionClass = extensionClasses[i];
1560
- if (value instanceof extensionClass) {
1561
- let extension = extensions[i];
1562
- let tag = extension.tag;
1563
- if (tag == undefined)
1564
- tag = extension.getTag && extension.getTag(value);
1565
- if (tag < 0x18) {
1566
- target[position$1++] = 0xc0 | tag;
1567
- } else if (tag < 0x100) {
1568
- target[position$1++] = 0xd8;
1569
- target[position$1++] = tag;
1570
- } else if (tag < 0x10000) {
1571
- target[position$1++] = 0xd9;
1572
- target[position$1++] = tag >> 8;
1573
- target[position$1++] = tag & 0xff;
1574
- } else if (tag > -1) {
1575
- target[position$1++] = 0xda;
1576
- targetView.setUint32(position$1, tag);
1577
- position$1 += 4;
1578
- } // else undefined, don't write tag
1579
- extension.encode.call(this, value, encode, makeRoom);
1580
- return
1581
- }
1582
- }
1583
- if (value[Symbol.iterator]) {
1584
- target[position$1++] = 0x9f; // indefinite length array
1585
- for (let entry of value) {
1586
- encode(entry);
1587
- }
1588
- target[position$1++] = 0xff; // stop-code
1589
- return
1590
- }
1591
- // no extension found, write as object
1592
- writeObject(value, !value.hasOwnProperty); // if it doesn't have hasOwnProperty, don't do hasOwnProperty checks
1593
- }
1594
- }
1595
- } else if (type === 'boolean') {
1596
- target[position$1++] = value ? 0xf5 : 0xf4;
1597
- } else if (type === 'bigint') {
1598
- if (value < (BigInt(1)<<BigInt(64)) && value >= 0) {
1599
- // use an unsigned int as long as it fits
1600
- target[position$1++] = 0x1b;
1601
- targetView.setBigUint64(position$1, value);
1602
- } else if (value > -(BigInt(1)<<BigInt(64)) && value < 0) {
1603
- // if we can fit an unsigned int, use that
1604
- target[position$1++] = 0x3b;
1605
- targetView.setBigUint64(position$1, -value - BigInt(1));
1606
- } else {
1607
- // overflow
1608
- if (this.largeBigIntToFloat) {
1609
- target[position$1++] = 0xfb;
1610
- targetView.setFloat64(position$1, Number(value));
1611
- } else {
1612
- throw new RangeError(value + ' was too large to fit in CBOR 64-bit integer format, set largeBigIntToFloat to convert to float-64')
1613
- }
1614
- }
1615
- position$1 += 8;
1616
- } else if (type === 'undefined') {
1617
- target[position$1++] = 0xf7;
1618
- } else {
1619
- throw new Error('Unknown type: ' + type)
1620
- }
1621
- };
1622
-
1623
- const writeObject = this.useRecords === false ? this.variableMapSize ? (object) => {
1624
- // this method is slightly slower, but generates "preferred serialization" (optimally small for smaller objects)
1625
- let keys = Object.keys(object);
1626
- let vals = Object.values(object);
1627
- let length = keys.length;
1628
- if (length < 0x18) {
1629
- target[position$1++] = 0xa0 | length;
1630
- } else if (length < 0x100) {
1631
- target[position$1++] = 0xb8;
1632
- target[position$1++] = length;
1633
- } else if (length < 0x10000) {
1634
- target[position$1++] = 0xb9;
1635
- target[position$1++] = length >> 8;
1636
- target[position$1++] = length & 0xff;
1637
- } else {
1638
- target[position$1++] = 0xba;
1639
- targetView.setUint32(position$1, length);
1640
- position$1 += 4;
1641
- }
1642
- if (encoder.keyMap) {
1643
- for (let i = 0; i < length; i++) {
1644
- encode(encodeKey(keys[i]));
1645
- encode(vals[i]);
1646
- }
1647
- } else {
1648
- for (let i = 0; i < length; i++) {
1649
- encode(keys[i]);
1650
- encode(vals[i]);
1651
- }
1652
- }
1653
- } :
1654
- (object, safePrototype) => {
1655
- target[position$1++] = 0xb9; // always use map 16, so we can preallocate and set the length afterwards
1656
- let objectOffset = position$1 - start;
1657
- position$1 += 2;
1658
- let size = 0;
1659
- if (encoder.keyMap) {
1660
- for (let key in object) if (safePrototype || object.hasOwnProperty(key)) {
1661
- encode(encoder.encodeKey(key));
1662
- encode(object[key]);
1663
- size++;
1664
- }
1665
- } else {
1666
- for (let key in object) if (safePrototype || object.hasOwnProperty(key)) {
1667
- encode(key);
1668
- encode(object[key]);
1669
- size++;
1670
- }
1671
- }
1672
- target[objectOffset++ + start] = size >> 8;
1673
- target[objectOffset + start] = size & 0xff;
1674
- } :
1675
- (object, safePrototype) => {
1676
- let nextTransition, transition = structures.transitions || (structures.transitions = Object.create(null));
1677
- let newTransitions = 0;
1678
- let length = 0;
1679
- let parentRecordId;
1680
- let keys;
1681
- if (this.keyMap) {
1682
- keys = Object.keys(object).map(k => this.encodeKey(k));
1683
- length = keys.length;
1684
- for (let i = 0; i < length; i++) {
1685
- let key = keys[i];
1686
- nextTransition = transition[key];
1687
- if (!nextTransition) {
1688
- nextTransition = transition[key] = Object.create(null);
1689
- newTransitions++;
1690
- }
1691
- transition = nextTransition;
1692
- }
1693
- } else {
1694
- for (let key in object) if (safePrototype || object.hasOwnProperty(key)) {
1695
- nextTransition = transition[key];
1696
- if (!nextTransition) {
1697
- if (transition[RECORD_SYMBOL] & 0x100000) {// this indicates it is a brancheable/extendable terminal node, so we will use this record id and extend it
1698
- parentRecordId = transition[RECORD_SYMBOL] & 0xffff;
1699
- }
1700
- nextTransition = transition[key] = Object.create(null);
1701
- newTransitions++;
1702
- }
1703
- transition = nextTransition;
1704
- length++;
1705
- }
1706
- }
1707
- let recordId = transition[RECORD_SYMBOL];
1708
- if (recordId !== undefined) {
1709
- recordId &= 0xffff;
1710
- target[position$1++] = 0xd9;
1711
- target[position$1++] = (recordId >> 8) | 0xe0;
1712
- target[position$1++] = recordId & 0xff;
1713
- } else {
1714
- if (!keys)
1715
- keys = transition.__keys__ || (transition.__keys__ = Object.keys(object));
1716
- if (parentRecordId === undefined) {
1717
- recordId = structures.nextId++;
1718
- if (!recordId) {
1719
- recordId = 0;
1720
- structures.nextId = 1;
1721
- }
1722
- if (recordId >= MAX_STRUCTURES) {// cycle back around
1723
- structures.nextId = (recordId = maxSharedStructures) + 1;
1724
- }
1725
- } else {
1726
- recordId = parentRecordId;
1727
- }
1728
- structures[recordId] = keys;
1729
- if (recordId < maxSharedStructures) {
1730
- target[position$1++] = 0xd9;
1731
- target[position$1++] = (recordId >> 8) | 0xe0;
1732
- target[position$1++] = recordId & 0xff;
1733
- transition = structures.transitions;
1734
- for (let i = 0; i < length; i++) {
1735
- if (transition[RECORD_SYMBOL] === undefined || (transition[RECORD_SYMBOL] & 0x100000))
1736
- transition[RECORD_SYMBOL] = recordId;
1737
- transition = transition[keys[i]];
1738
- }
1739
- transition[RECORD_SYMBOL] = recordId | 0x100000; // indicates it is a extendable terminal
1740
- hasSharedUpdate = true;
1741
- } else {
1742
- transition[RECORD_SYMBOL] = recordId;
1743
- targetView.setUint32(position$1, 0xd9dfff00); // tag two byte, then record definition id
1744
- position$1 += 3;
1745
- if (newTransitions)
1746
- transitionsCount += serializationsSinceTransitionRebuild * newTransitions;
1747
- // record the removal of the id, we can maintain our shared structure
1748
- if (recordIdsToRemove.length >= MAX_STRUCTURES - maxSharedStructures)
1749
- recordIdsToRemove.shift()[RECORD_SYMBOL] = undefined; // we are cycling back through, and have to remove old ones
1750
- recordIdsToRemove.push(transition);
1751
- writeArrayHeader(length + 2);
1752
- encode(0xe000 + recordId);
1753
- encode(keys);
1754
- for (let v of Object.values(object)) encode(v);
1755
- return
1756
- }
1757
- }
1758
- if (length < 0x18) { // write the array header
1759
- target[position$1++] = 0x80 | length;
1760
- } else {
1761
- writeArrayHeader(length);
1762
- }
1763
- for (let key in object)
1764
- if (safePrototype || object.hasOwnProperty(key))
1765
- encode(object[key]);
1766
- };
1767
- const makeRoom = (end) => {
1768
- let newSize;
1769
- if (end > 0x1000000) {
1770
- // special handling for really large buffers
1771
- if ((end - start) > MAX_BUFFER_SIZE)
1772
- throw new Error('Encoded buffer would be larger than maximum buffer size')
1773
- newSize = Math.min(MAX_BUFFER_SIZE,
1774
- Math.round(Math.max((end - start) * (end > 0x4000000 ? 1.25 : 2), 0x400000) / 0x1000) * 0x1000);
1775
- } else // faster handling for smaller buffers
1776
- newSize = ((Math.max((end - start) << 2, target.length - 1) >> 12) + 1) << 12;
1777
- let newBuffer = new ByteArrayAllocate(newSize);
1778
- targetView = new DataView(newBuffer.buffer, 0, newSize);
1779
- if (target.copy)
1780
- target.copy(newBuffer, 0, start, end);
1781
- else
1782
- newBuffer.set(target.slice(start, end));
1783
- position$1 -= start;
1784
- start = 0;
1785
- safeEnd = newBuffer.length - 10;
1786
- return target = newBuffer
1787
- };
1788
- }
1789
- useBuffer(buffer) {
1790
- // this means we are finished using our own buffer and we can write over it safely
1791
- target = buffer;
1792
- targetView = new DataView(target.buffer, target.byteOffset, target.byteLength);
1793
- position$1 = 0;
1794
- }
1795
- clearSharedData() {
1796
- if (this.structures)
1797
- this.structures = [];
1798
- if (this.sharedValues)
1799
- this.sharedValues = undefined;
1800
- }
1801
- updateSharedData() {
1802
- let lastVersion = this.sharedVersion || 0;
1803
- this.sharedVersion = lastVersion + 1;
1804
- let structuresCopy = this.structures.slice(0);
1805
- let sharedData = new SharedData(structuresCopy, this.sharedValues, this.sharedVersion);
1806
- let saveResults = this.saveShared(sharedData,
1807
- existingShared => (existingShared && existingShared.version || 0) == lastVersion);
1808
- if (saveResults === false) {
1809
- // get updated structures and try again if the update failed
1810
- sharedData = this.getShared() || {};
1811
- this.structures = sharedData.structures || [];
1812
- this.sharedValues = sharedData.packedValues;
1813
- this.sharedVersion = sharedData.version;
1814
- this.structures.nextId = this.structures.length;
1815
- } else {
1816
- // restore structures
1817
- structuresCopy.forEach((structure, i) => this.structures[i] = structure);
1818
- }
1819
- // 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
1820
- return saveResults
1821
- }
1822
- }
1823
- class SharedData {
1824
- constructor(structures, values, version) {
1825
- this.structures = structures;
1826
- this.packedValues = values;
1827
- this.version = version;
1828
- }
1829
- }
1830
-
1831
- function writeArrayHeader(length) {
1832
- if (length < 0x18)
1833
- target[position$1++] = 0x80 | length;
1834
- else if (length < 0x100) {
1835
- target[position$1++] = 0x98;
1836
- target[position$1++] = length;
1837
- } else if (length < 0x10000) {
1838
- target[position$1++] = 0x99;
1839
- target[position$1++] = length >> 8;
1840
- target[position$1++] = length & 0xff;
1841
- } else {
1842
- target[position$1++] = 0x9a;
1843
- targetView.setUint32(position$1, length);
1844
- position$1 += 4;
1845
- }
1846
- }
1847
-
1848
- function findRepetitiveStrings(value, packedValues) {
1849
- switch(typeof value) {
1850
- case 'string':
1851
- if (value.length > 3) {
1852
- if (packedValues.objectMap[value] > -1 || packedValues.values.length >= packedValues.maxValues)
1853
- return
1854
- let packedStatus = packedValues.get(value);
1855
- if (packedStatus) {
1856
- if (++packedStatus.count == 2) {
1857
- packedValues.values.push(value);
1858
- }
1859
- } else {
1860
- packedValues.set(value, {
1861
- count: 1,
1862
- });
1863
- if (packedValues.samplingPackedValues) {
1864
- let status = packedValues.samplingPackedValues.get(value);
1865
- if (status)
1866
- status.count++;
1867
- else
1868
- packedValues.samplingPackedValues.set(value, {
1869
- count: 1,
1870
- });
1871
- }
1872
- }
1873
- }
1874
- break
1875
- case 'object':
1876
- if (value) {
1877
- if (value instanceof Array) {
1878
- for (let i = 0, l = value.length; i < l; i++) {
1879
- findRepetitiveStrings(value[i], packedValues);
1880
- }
1881
-
1882
- } else {
1883
- let includeKeys = !packedValues.encoder.useRecords;
1884
- for (var key in value) {
1885
- if (value.hasOwnProperty(key)) {
1886
- if (includeKeys)
1887
- findRepetitiveStrings(key, packedValues);
1888
- findRepetitiveStrings(value[key], packedValues);
1889
- }
1890
- }
1891
- }
1892
- }
1893
- break
1894
- case 'function': console.log(value);
1895
- }
1896
- }
1897
- const isLittleEndianMachine$1 = new Uint8Array(new Uint16Array([1]).buffer)[0] == 1;
1898
- extensionClasses = [ Date, Set, Error, RegExp, Tag, ArrayBuffer, ByteArray,
1899
- Uint8Array, Uint8ClampedArray, Uint16Array, Uint32Array,
1900
- typeof BigUint64Array == 'undefined' ? function() {} : BigUint64Array, Int8Array, Int16Array, Int32Array,
1901
- typeof BigInt64Array == 'undefined' ? function() {} : BigInt64Array,
1902
- Float32Array, Float64Array, SharedData];
1903
-
1904
- //Object.getPrototypeOf(Uint8Array.prototype).constructor /*TypedArray*/
1905
- extensions = [{
1906
- tag: 1,
1907
- encode(date, encode) {
1908
- let seconds = date.getTime() / 1000;
1909
- if ((this.useTimestamp32 || date.getMilliseconds() === 0) && seconds >= 0 && seconds < 0x100000000) {
1910
- // Timestamp 32
1911
- target[position$1++] = 0x1a;
1912
- targetView.setUint32(position$1, seconds);
1913
- position$1 += 4;
1914
- } else {
1915
- // Timestamp float64
1916
- target[position$1++] = 0xfb;
1917
- targetView.setFloat64(position$1, seconds);
1918
- position$1 += 8;
1919
- }
1920
- }
1921
- }, {
1922
- tag: 258, // https://github.com/input-output-hk/cbor-sets-spec/blob/master/CBOR_SETS.md
1923
- encode(set, encode) {
1924
- let array = Array.from(set);
1925
- encode(array);
1926
- }
1927
- }, {
1928
- tag: 27, // http://cbor.schmorp.de/generic-object
1929
- encode(error, encode) {
1930
- encode([ error.name, error.message ]);
1931
- }
1932
- }, {
1933
- tag: 27, // http://cbor.schmorp.de/generic-object
1934
- encode(regex, encode) {
1935
- encode([ 'RegExp', regex.source, regex.flags ]);
1936
- }
1937
- }, {
1938
- getTag(tag) {
1939
- return tag.tag
1940
- },
1941
- encode(tag, encode) {
1942
- encode(tag.value);
1943
- }
1944
- }, {
1945
- encode(arrayBuffer, encode, makeRoom) {
1946
- writeBuffer(arrayBuffer, makeRoom);
1947
- }
1948
- }, {
1949
- encode(arrayBuffer, encode, makeRoom) {
1950
- writeBuffer(arrayBuffer, makeRoom);
1951
- }
1952
- }, typedArrayEncoder(64, 1),
1953
- typedArrayEncoder(68, 1),
1954
- typedArrayEncoder(69, 2),
1955
- typedArrayEncoder(70, 4),
1956
- typedArrayEncoder(71, 8),
1957
- typedArrayEncoder(72, 1),
1958
- typedArrayEncoder(77, 2),
1959
- typedArrayEncoder(78, 4),
1960
- typedArrayEncoder(79, 8),
1961
- typedArrayEncoder(85, 4),
1962
- typedArrayEncoder(86, 8),
1963
- {
1964
- encode(sharedData, encode) { // write SharedData
1965
- let packedValues = sharedData.packedValues || [];
1966
- let sharedStructures = sharedData.structures || [];
1967
- if (packedValues.values.length > 0) {
1968
- target[position$1++] = 0xd8; // one-byte tag
1969
- target[position$1++] = 51; // tag 51 for packed shared structures https://www.potaroo.net/ietf/ids/draft-ietf-cbor-packed-03.txt
1970
- writeArrayHeader(4);
1971
- let valuesArray = packedValues.values;
1972
- encode(valuesArray);
1973
- writeArrayHeader(0); // prefixes
1974
- writeArrayHeader(0); // suffixes
1975
- packedObjectMap = Object.create(sharedPackedObjectMap || null);
1976
- for (let i = 0, l = valuesArray.length; i < l; i++) {
1977
- packedObjectMap[valuesArray[i]] = i;
1978
- }
1979
- }
1980
- if (sharedStructures) {
1981
- targetView.setUint32(position$1, 0xd9dffe00);
1982
- position$1 += 3;
1983
- let definitions = sharedStructures.slice(0);
1984
- definitions.unshift(0xe000);
1985
- definitions.push(new Tag(sharedData.version, 0x53687264));
1986
- encode(definitions);
1987
- } else
1988
- encode(new Tag(sharedData.version, 0x53687264));
1989
- }
1990
- }];
1991
- function typedArrayEncoder(tag, size) {
1992
- if (!isLittleEndianMachine$1 && size > 1)
1993
- tag -= 4; // the big endian equivalents are 4 less
1994
- return {
1995
- tag: tag,
1996
- encode: function writeExtBuffer(typedArray, encode) {
1997
- let length = typedArray.byteLength;
1998
- let offset = typedArray.byteOffset || 0;
1999
- let buffer = typedArray.buffer || typedArray;
2000
- encode(hasNodeBuffer ? Buffer.from(buffer, offset, length) :
2001
- new Uint8Array(buffer, offset, length));
2002
- }
2003
- }
2004
- }
2005
- function writeBuffer(buffer, makeRoom) {
2006
- let length = buffer.byteLength;
2007
- if (length < 0x18) {
2008
- target[position$1++] = 0x40 + length;
2009
- } else if (length < 0x100) {
2010
- target[position$1++] = 0x58;
2011
- target[position$1++] = length;
2012
- } else if (length < 0x10000) {
2013
- target[position$1++] = 0x59;
2014
- target[position$1++] = length >> 8;
2015
- target[position$1++] = length & 0xff;
2016
- } else {
2017
- target[position$1++] = 0x5a;
2018
- targetView.setUint32(position$1, length);
2019
- position$1 += 4;
2020
- }
2021
- if (position$1 + length >= target.length) {
2022
- makeRoom(position$1 + length);
2023
- }
2024
- target.set(buffer, position$1);
2025
- position$1 += length;
2026
- }
2027
-
2028
- function insertIds(serialized, idsToInsert) {
2029
- // insert the ids that need to be referenced for structured clones
2030
- let nextId;
2031
- let distanceToMove = idsToInsert.length * 2;
2032
- let lastEnd = serialized.length - distanceToMove;
2033
- idsToInsert.sort((a, b) => a.offset > b.offset ? 1 : -1);
2034
- for (let id = 0; id < idsToInsert.length; id++) {
2035
- let referee = idsToInsert[id];
2036
- referee.id = id;
2037
- for (let position of referee.references) {
2038
- serialized[position++] = id >> 8;
2039
- serialized[position] = id & 0xff;
2040
- }
2041
- }
2042
- while (nextId = idsToInsert.pop()) {
2043
- let offset = nextId.offset;
2044
- serialized.copyWithin(offset + distanceToMove, offset, lastEnd);
2045
- distanceToMove -= 2;
2046
- let position = offset + distanceToMove;
2047
- serialized[position++] = 0xd8;
2048
- serialized[position++] = 28; // http://cbor.schmorp.de/value-sharing
2049
- lastEnd = offset;
2050
- }
2051
- return serialized
2052
- }
2053
- function writeBundles(start, encode) {
2054
- targetView.setUint32(bundledStrings$1.position + start, position$1 - bundledStrings$1.position - start + 1); // the offset to bundle
2055
- let writeStrings = bundledStrings$1;
2056
- bundledStrings$1 = null;
2057
- encode(writeStrings[0]);
2058
- encode(writeStrings[1]);
2059
- }
2060
-
2061
- function addExtension$1(extension) {
2062
- if (extension.Class) {
2063
- if (!extension.encode)
2064
- throw new Error('Extension has no encode function')
2065
- extensionClasses.unshift(extension.Class);
2066
- extensions.unshift(extension);
2067
- }
2068
- addExtension(extension);
2069
- }
2070
- let defaultEncoder = new Encoder({ useRecords: false });
2071
- const encode = defaultEncoder.encode;
2072
- const { NEVER, ALWAYS, DECIMAL_ROUND, DECIMAL_FIT } = FLOAT32_OPTIONS;
2073
- const REUSE_BUFFER_MODE = 512;
1052
+ let textEncoder;
1053
+ try {
1054
+ textEncoder = new TextEncoder();
1055
+ } catch (error) {}
1056
+ let extensions, extensionClasses;
1057
+ const hasNodeBuffer = typeof Buffer !== 'undefined';
1058
+ const ByteArrayAllocate = hasNodeBuffer ? Buffer.allocUnsafeSlow : Uint8Array;
1059
+ const ByteArray = hasNodeBuffer ? Buffer : Uint8Array;
1060
+ const MAX_STRUCTURES = 0x100;
1061
+ const MAX_BUFFER_SIZE = hasNodeBuffer ? 0x100000000 : 0x7fd00000;
1062
+ let target;
1063
+ let targetView;
1064
+ let position$1 = 0;
1065
+ let safeEnd;
1066
+ let bundledStrings$1 = null;
1067
+ const MAX_BUNDLE_SIZE = 0xf000;
1068
+ const hasNonLatin = /[\u0080-\uFFFF]/;
1069
+ const RECORD_SYMBOL = Symbol('record-id');
1070
+ class Encoder extends Decoder {
1071
+ constructor(options) {
1072
+ super(options);
1073
+ this.offset = 0;
1074
+ let start;
1075
+ let sharedStructures;
1076
+ let hasSharedUpdate;
1077
+ let structures;
1078
+ let referenceMap;
1079
+ options = options || {};
1080
+ let encodeUtf8 = ByteArray.prototype.utf8Write ? function(string, position, maxBytes) {
1081
+ return target.utf8Write(string, position, maxBytes)
1082
+ } : (textEncoder && textEncoder.encodeInto) ?
1083
+ function(string, position) {
1084
+ return textEncoder.encodeInto(string, target.subarray(position)).written
1085
+ } : false;
1086
+
1087
+ let encoder = this;
1088
+ let hasSharedStructures = options.structures || options.saveStructures;
1089
+ let maxSharedStructures = options.maxSharedStructures;
1090
+ if (maxSharedStructures == null)
1091
+ maxSharedStructures = hasSharedStructures ? 128 : 0;
1092
+ if (maxSharedStructures > 8190)
1093
+ throw new Error('Maximum maxSharedStructure is 8190')
1094
+ let isSequential = options.sequential;
1095
+ if (isSequential) {
1096
+ maxSharedStructures = 0;
1097
+ }
1098
+ if (!this.structures)
1099
+ this.structures = [];
1100
+ if (this.saveStructures)
1101
+ this.saveShared = this.saveStructures;
1102
+ let samplingPackedValues, packedObjectMap, sharedValues = options.sharedValues;
1103
+ let sharedPackedObjectMap;
1104
+ if (sharedValues) {
1105
+ sharedPackedObjectMap = Object.create(null);
1106
+ for (let i = 0, l = sharedValues.length; i < l; i++) {
1107
+ sharedPackedObjectMap[sharedValues[i]] = i;
1108
+ }
1109
+ }
1110
+ let recordIdsToRemove = [];
1111
+ let transitionsCount = 0;
1112
+ let serializationsSinceTransitionRebuild = 0;
1113
+
1114
+ this.mapEncode = function(value, encodeOptions) {
1115
+ // Experimental support for premapping keys using _keyMap instad of keyMap - not optiimised yet)
1116
+ if (this._keyMap && !this._mapped) {
1117
+ //console.log('encoding ', value)
1118
+ switch (value.constructor.name) {
1119
+ case 'Array':
1120
+ value = value.map(r => this.encodeKeys(r));
1121
+ break
1122
+ //case 'Map':
1123
+ // value = this.encodeKeys(value)
1124
+ // break
1125
+ }
1126
+ //this._mapped = true
1127
+ }
1128
+ return this.encode(value, encodeOptions)
1129
+ };
1130
+
1131
+ this.encode = function(value, encodeOptions) {
1132
+ if (!target) {
1133
+ target = new ByteArrayAllocate(8192);
1134
+ targetView = new DataView(target.buffer, 0, 8192);
1135
+ position$1 = 0;
1136
+ }
1137
+ safeEnd = target.length - 10;
1138
+ if (safeEnd - position$1 < 0x800) {
1139
+ // don't start too close to the end,
1140
+ target = new ByteArrayAllocate(target.length);
1141
+ targetView = new DataView(target.buffer, 0, target.length);
1142
+ safeEnd = target.length - 10;
1143
+ position$1 = 0;
1144
+ } else if (encodeOptions === REUSE_BUFFER_MODE)
1145
+ position$1 = (position$1 + 7) & 0x7ffffff8; // Word align to make any future copying of this buffer faster
1146
+ start = position$1;
1147
+ if (encoder.useSelfDescribedHeader) {
1148
+ targetView.setUint32(position$1, 0xd9d9f700); // tag two byte, then self-descriptive tag
1149
+ position$1 += 3;
1150
+ }
1151
+ referenceMap = encoder.structuredClone ? new Map() : null;
1152
+ if (encoder.bundleStrings && typeof value !== 'string') {
1153
+ bundledStrings$1 = [];
1154
+ bundledStrings$1.size = Infinity; // force a new bundle start on first string
1155
+ } else
1156
+ bundledStrings$1 = null;
1157
+
1158
+ sharedStructures = encoder.structures;
1159
+ if (sharedStructures) {
1160
+ if (sharedStructures.uninitialized) {
1161
+ let sharedData = encoder.getShared() || {};
1162
+ encoder.structures = sharedStructures = sharedData.structures || [];
1163
+ encoder.sharedVersion = sharedData.version;
1164
+ let sharedValues = encoder.sharedValues = sharedData.packedValues;
1165
+ if (sharedValues) {
1166
+ sharedPackedObjectMap = {};
1167
+ for (let i = 0, l = sharedValues.length; i < l; i++)
1168
+ sharedPackedObjectMap[sharedValues[i]] = i;
1169
+ }
1170
+ }
1171
+ let sharedStructuresLength = sharedStructures.length;
1172
+ if (sharedStructuresLength > maxSharedStructures && !isSequential)
1173
+ sharedStructuresLength = maxSharedStructures;
1174
+ if (!sharedStructures.transitions) {
1175
+ // rebuild our structure transitions
1176
+ sharedStructures.transitions = Object.create(null);
1177
+ for (let i = 0; i < sharedStructuresLength; i++) {
1178
+ let keys = sharedStructures[i];
1179
+ //console.log('shared struct keys:', keys)
1180
+ if (!keys)
1181
+ continue
1182
+ let nextTransition, transition = sharedStructures.transitions;
1183
+ for (let j = 0, l = keys.length; j < l; j++) {
1184
+ if (transition[RECORD_SYMBOL] === undefined)
1185
+ transition[RECORD_SYMBOL] = i;
1186
+ let key = keys[j];
1187
+ nextTransition = transition[key];
1188
+ if (!nextTransition) {
1189
+ nextTransition = transition[key] = Object.create(null);
1190
+ }
1191
+ transition = nextTransition;
1192
+ }
1193
+ transition[RECORD_SYMBOL] = i | 0x100000;
1194
+ }
1195
+ }
1196
+ if (!isSequential)
1197
+ sharedStructures.nextId = sharedStructuresLength;
1198
+ }
1199
+ if (hasSharedUpdate)
1200
+ hasSharedUpdate = false;
1201
+ structures = sharedStructures || [];
1202
+ packedObjectMap = sharedPackedObjectMap;
1203
+ if (options.pack) {
1204
+ let packedValues = new Map();
1205
+ packedValues.values = [];
1206
+ packedValues.encoder = encoder;
1207
+ packedValues.maxValues = options.maxPrivatePackedValues || (sharedPackedObjectMap ? 16 : Infinity);
1208
+ packedValues.objectMap = sharedPackedObjectMap || false;
1209
+ packedValues.samplingPackedValues = samplingPackedValues;
1210
+ findRepetitiveStrings(value, packedValues);
1211
+ if (packedValues.values.length > 0) {
1212
+ target[position$1++] = 0xd8; // one-byte tag
1213
+ target[position$1++] = 51; // tag 51 for packed shared structures https://www.potaroo.net/ietf/ids/draft-ietf-cbor-packed-03.txt
1214
+ writeArrayHeader(4);
1215
+ let valuesArray = packedValues.values;
1216
+ encode(valuesArray);
1217
+ writeArrayHeader(0); // prefixes
1218
+ writeArrayHeader(0); // suffixes
1219
+ packedObjectMap = Object.create(sharedPackedObjectMap || null);
1220
+ for (let i = 0, l = valuesArray.length; i < l; i++) {
1221
+ packedObjectMap[valuesArray[i]] = i;
1222
+ }
1223
+ }
1224
+ }
1225
+ try {
1226
+ encode(value);
1227
+ if (bundledStrings$1) {
1228
+ writeBundles(start, encode);
1229
+ }
1230
+ encoder.offset = position$1; // update the offset so next serialization doesn't write over our buffer, but can continue writing to same buffer sequentially
1231
+ if (referenceMap && referenceMap.idsToInsert) {
1232
+ position$1 += referenceMap.idsToInsert.length * 2;
1233
+ if (position$1 > safeEnd)
1234
+ makeRoom(position$1);
1235
+ encoder.offset = position$1;
1236
+ let serialized = insertIds(target.subarray(start, position$1), referenceMap.idsToInsert);
1237
+ referenceMap = null;
1238
+ return serialized
1239
+ }
1240
+ if (encodeOptions & REUSE_BUFFER_MODE) {
1241
+ target.start = start;
1242
+ target.end = position$1;
1243
+ return target
1244
+ }
1245
+ return target.subarray(start, position$1) // position can change if we call encode again in saveShared, so we get the buffer now
1246
+ } finally {
1247
+ if (sharedStructures) {
1248
+ if (serializationsSinceTransitionRebuild < 10)
1249
+ serializationsSinceTransitionRebuild++;
1250
+ if (sharedStructures.length > maxSharedStructures)
1251
+ sharedStructures.length = maxSharedStructures;
1252
+ if (transitionsCount > 10000) {
1253
+ // force a rebuild occasionally after a lot of transitions so it can get cleaned up
1254
+ sharedStructures.transitions = null;
1255
+ serializationsSinceTransitionRebuild = 0;
1256
+ transitionsCount = 0;
1257
+ if (recordIdsToRemove.length > 0)
1258
+ recordIdsToRemove = [];
1259
+ } else if (recordIdsToRemove.length > 0 && !isSequential) {
1260
+ for (let i = 0, l = recordIdsToRemove.length; i < l; i++) {
1261
+ recordIdsToRemove[i][RECORD_SYMBOL] = undefined;
1262
+ }
1263
+ recordIdsToRemove = [];
1264
+ //sharedStructures.nextId = maxSharedStructures
1265
+ }
1266
+ }
1267
+ if (hasSharedUpdate && encoder.saveShared) {
1268
+ if (encoder.structures.length > maxSharedStructures) {
1269
+ encoder.structures = encoder.structures.slice(0, maxSharedStructures);
1270
+ }
1271
+ // we can't rely on start/end with REUSE_BUFFER_MODE since they will (probably) change when we save
1272
+ let returnBuffer = target.subarray(start, position$1);
1273
+ if (encoder.updateSharedData() === false)
1274
+ return encoder.encode(value) // re-encode if it fails
1275
+ return returnBuffer
1276
+ }
1277
+ if (encodeOptions & RESET_BUFFER_MODE)
1278
+ position$1 = start;
1279
+ }
1280
+ };
1281
+ this.findCommonStringsToPack = () => {
1282
+ samplingPackedValues = new Map();
1283
+ if (!sharedPackedObjectMap)
1284
+ sharedPackedObjectMap = Object.create(null);
1285
+ return (options) => {
1286
+ let threshold = options && options.threshold || 4;
1287
+ let position = this.pack ? options.maxPrivatePackedValues || 16 : 0;
1288
+ if (!sharedValues)
1289
+ sharedValues = this.sharedValues = [];
1290
+ for (let [ key, status ] of samplingPackedValues) {
1291
+ if (status.count > threshold) {
1292
+ sharedPackedObjectMap[key] = position++;
1293
+ sharedValues.push(key);
1294
+ hasSharedUpdate = true;
1295
+ }
1296
+ }
1297
+ while (this.saveShared && this.updateSharedData() === false) {}
1298
+ samplingPackedValues = null;
1299
+ }
1300
+ };
1301
+ const encode = (value) => {
1302
+ if (position$1 > safeEnd)
1303
+ target = makeRoom(position$1);
1304
+
1305
+ var type = typeof value;
1306
+ var length;
1307
+ if (type === 'string') {
1308
+ if (packedObjectMap) {
1309
+ let packedPosition = packedObjectMap[value];
1310
+ if (packedPosition >= 0) {
1311
+ if (packedPosition < 16)
1312
+ target[position$1++] = packedPosition + 0xe0; // simple values, defined in https://www.potaroo.net/ietf/ids/draft-ietf-cbor-packed-03.txt
1313
+ else {
1314
+ target[position$1++] = 0xc6; // tag 6 defined in https://www.potaroo.net/ietf/ids/draft-ietf-cbor-packed-03.txt
1315
+ if (packedPosition & 1)
1316
+ encode((15 - packedPosition) >> 1);
1317
+ else
1318
+ encode((packedPosition - 16) >> 1);
1319
+ }
1320
+ return
1321
+ /* } else if (packedStatus.serializationId != serializationId) {
1322
+ packedStatus.serializationId = serializationId
1323
+ packedStatus.count = 1
1324
+ if (options.sharedPack) {
1325
+ let sharedCount = packedStatus.sharedCount = (packedStatus.sharedCount || 0) + 1
1326
+ if (shareCount > (options.sharedPack.threshold || 5)) {
1327
+ let sharedPosition = packedStatus.position = packedStatus.nextSharedPosition
1328
+ hasSharedUpdate = true
1329
+ if (sharedPosition < 16)
1330
+ target[position++] = sharedPosition + 0xc0
1331
+
1332
+ }
1333
+ }
1334
+ } // else any in-doc incrementation?*/
1335
+ } else if (samplingPackedValues && !options.pack) {
1336
+ let status = samplingPackedValues.get(value);
1337
+ if (status)
1338
+ status.count++;
1339
+ else
1340
+ samplingPackedValues.set(value, {
1341
+ count: 1,
1342
+ });
1343
+ }
1344
+ }
1345
+ let strLength = value.length;
1346
+ if (bundledStrings$1 && strLength >= 4 && strLength < 0x400) {
1347
+ if ((bundledStrings$1.size += strLength) > MAX_BUNDLE_SIZE) {
1348
+ let extStart;
1349
+ let maxBytes = (bundledStrings$1[0] ? bundledStrings$1[0].length * 3 + bundledStrings$1[1].length : 0) + 10;
1350
+ if (position$1 + maxBytes > safeEnd)
1351
+ target = makeRoom(position$1 + maxBytes);
1352
+ target[position$1++] = 0xd9; // tag 16-bit
1353
+ target[position$1++] = 0xdf; // tag 0xdff9
1354
+ target[position$1++] = 0xf9;
1355
+ // TODO: If we only have one bundle with any string data, only write one string bundle
1356
+ target[position$1++] = bundledStrings$1.position ? 0x84 : 0x82; // array of 4 or 2 elements depending on if we write bundles
1357
+ target[position$1++] = 0x1a; // 32-bit unsigned int
1358
+ extStart = position$1 - start;
1359
+ position$1 += 4; // reserve for writing bundle reference
1360
+ if (bundledStrings$1.position) {
1361
+ writeBundles(start, encode); // write the last bundles
1362
+ }
1363
+ bundledStrings$1 = ['', '']; // create new ones
1364
+ bundledStrings$1.size = 0;
1365
+ bundledStrings$1.position = extStart;
1366
+ }
1367
+ let twoByte = hasNonLatin.test(value);
1368
+ bundledStrings$1[twoByte ? 0 : 1] += value;
1369
+ target[position$1++] = twoByte ? 0xce : 0xcf;
1370
+ encode(strLength);
1371
+ return
1372
+ }
1373
+ let headerSize;
1374
+ // first we estimate the header size, so we can write to the correct location
1375
+ if (strLength < 0x20) {
1376
+ headerSize = 1;
1377
+ } else if (strLength < 0x100) {
1378
+ headerSize = 2;
1379
+ } else if (strLength < 0x10000) {
1380
+ headerSize = 3;
1381
+ } else {
1382
+ headerSize = 5;
1383
+ }
1384
+ let maxBytes = strLength * 3;
1385
+ if (position$1 + maxBytes > safeEnd)
1386
+ target = makeRoom(position$1 + maxBytes);
1387
+
1388
+ if (strLength < 0x40 || !encodeUtf8) {
1389
+ let i, c1, c2, strPosition = position$1 + headerSize;
1390
+ for (i = 0; i < strLength; i++) {
1391
+ c1 = value.charCodeAt(i);
1392
+ if (c1 < 0x80) {
1393
+ target[strPosition++] = c1;
1394
+ } else if (c1 < 0x800) {
1395
+ target[strPosition++] = c1 >> 6 | 0xc0;
1396
+ target[strPosition++] = c1 & 0x3f | 0x80;
1397
+ } else if (
1398
+ (c1 & 0xfc00) === 0xd800 &&
1399
+ ((c2 = value.charCodeAt(i + 1)) & 0xfc00) === 0xdc00
1400
+ ) {
1401
+ c1 = 0x10000 + ((c1 & 0x03ff) << 10) + (c2 & 0x03ff);
1402
+ i++;
1403
+ target[strPosition++] = c1 >> 18 | 0xf0;
1404
+ target[strPosition++] = c1 >> 12 & 0x3f | 0x80;
1405
+ target[strPosition++] = c1 >> 6 & 0x3f | 0x80;
1406
+ target[strPosition++] = c1 & 0x3f | 0x80;
1407
+ } else {
1408
+ target[strPosition++] = c1 >> 12 | 0xe0;
1409
+ target[strPosition++] = c1 >> 6 & 0x3f | 0x80;
1410
+ target[strPosition++] = c1 & 0x3f | 0x80;
1411
+ }
1412
+ }
1413
+ length = strPosition - position$1 - headerSize;
1414
+ } else {
1415
+ length = encodeUtf8(value, position$1 + headerSize, maxBytes);
1416
+ }
1417
+
1418
+ if (length < 0x18) {
1419
+ target[position$1++] = 0x60 | length;
1420
+ } else if (length < 0x100) {
1421
+ if (headerSize < 2) {
1422
+ target.copyWithin(position$1 + 2, position$1 + 1, position$1 + 1 + length);
1423
+ }
1424
+ target[position$1++] = 0x78;
1425
+ target[position$1++] = length;
1426
+ } else if (length < 0x10000) {
1427
+ if (headerSize < 3) {
1428
+ target.copyWithin(position$1 + 3, position$1 + 2, position$1 + 2 + length);
1429
+ }
1430
+ target[position$1++] = 0x79;
1431
+ target[position$1++] = length >> 8;
1432
+ target[position$1++] = length & 0xff;
1433
+ } else {
1434
+ if (headerSize < 5) {
1435
+ target.copyWithin(position$1 + 5, position$1 + 3, position$1 + 3 + length);
1436
+ }
1437
+ target[position$1++] = 0x7a;
1438
+ targetView.setUint32(position$1, length);
1439
+ position$1 += 4;
1440
+ }
1441
+ position$1 += length;
1442
+ } else if (type === 'number') {
1443
+ if (value >>> 0 === value) {// positive integer, 32-bit or less
1444
+ // positive uint
1445
+ if (value < 0x18) {
1446
+ target[position$1++] = value;
1447
+ } else if (value < 0x100) {
1448
+ target[position$1++] = 0x18;
1449
+ target[position$1++] = value;
1450
+ } else if (value < 0x10000) {
1451
+ target[position$1++] = 0x19;
1452
+ target[position$1++] = value >> 8;
1453
+ target[position$1++] = value & 0xff;
1454
+ } else {
1455
+ target[position$1++] = 0x1a;
1456
+ targetView.setUint32(position$1, value);
1457
+ position$1 += 4;
1458
+ }
1459
+ } else if (value >> 0 === value) { // negative integer
1460
+ if (value >= -0x18) {
1461
+ target[position$1++] = 0x1f - value;
1462
+ } else if (value >= -0x100) {
1463
+ target[position$1++] = 0x38;
1464
+ target[position$1++] = ~value;
1465
+ } else if (value >= -0x10000) {
1466
+ target[position$1++] = 0x39;
1467
+ targetView.setUint16(position$1, ~value);
1468
+ position$1 += 2;
1469
+ } else {
1470
+ target[position$1++] = 0x3a;
1471
+ targetView.setUint32(position$1, ~value);
1472
+ position$1 += 4;
1473
+ }
1474
+ } else {
1475
+ let useFloat32;
1476
+ if ((useFloat32 = this.useFloat32) > 0 && value < 0x100000000 && value >= -0x80000000) {
1477
+ target[position$1++] = 0xfa;
1478
+ targetView.setFloat32(position$1, value);
1479
+ let xShifted;
1480
+ if (useFloat32 < 4 ||
1481
+ // this checks for rounding of numbers that were encoded in 32-bit float to nearest significant decimal digit that could be preserved
1482
+ ((xShifted = value * mult10[((target[position$1] & 0x7f) << 1) | (target[position$1 + 1] >> 7)]) >> 0) === xShifted) {
1483
+ position$1 += 4;
1484
+ return
1485
+ } else
1486
+ position$1--; // move back into position for writing a double
1487
+ }
1488
+ target[position$1++] = 0xfb;
1489
+ targetView.setFloat64(position$1, value);
1490
+ position$1 += 8;
1491
+ }
1492
+ } else if (type === 'object') {
1493
+ if (!value)
1494
+ target[position$1++] = 0xf6;
1495
+ else {
1496
+ if (referenceMap) {
1497
+ let referee = referenceMap.get(value);
1498
+ if (referee) {
1499
+ target[position$1++] = 0xd8;
1500
+ target[position$1++] = 29; // http://cbor.schmorp.de/value-sharing
1501
+ target[position$1++] = 0x19; // 16-bit uint
1502
+ if (!referee.references) {
1503
+ let idsToInsert = referenceMap.idsToInsert || (referenceMap.idsToInsert = []);
1504
+ referee.references = [];
1505
+ idsToInsert.push(referee);
1506
+ }
1507
+ referee.references.push(position$1 - start);
1508
+ position$1 += 2; // TODO: also support 32-bit
1509
+ return
1510
+ } else
1511
+ referenceMap.set(value, { offset: position$1 - start });
1512
+ }
1513
+ let constructor = value.constructor;
1514
+ if (constructor === Object) {
1515
+ writeObject(value, true);
1516
+ } else if (constructor === Array) {
1517
+ length = value.length;
1518
+ if (length < 0x18) {
1519
+ target[position$1++] = 0x80 | length;
1520
+ } else {
1521
+ writeArrayHeader(length);
1522
+ }
1523
+ for (let i = 0; i < length; i++) {
1524
+ encode(value[i]);
1525
+ }
1526
+ } else if (constructor === Map) {
1527
+ if (this.mapsAsObjects ? this.useTag259ForMaps !== false : this.useTag259ForMaps) {
1528
+ // 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
1529
+ target[position$1++] = 0xd9;
1530
+ target[position$1++] = 1;
1531
+ target[position$1++] = 3;
1532
+ }
1533
+ length = value.size;
1534
+ if (length < 0x18) {
1535
+ target[position$1++] = 0xa0 | length;
1536
+ } else if (length < 0x100) {
1537
+ target[position$1++] = 0xb8;
1538
+ target[position$1++] = length;
1539
+ } else if (length < 0x10000) {
1540
+ target[position$1++] = 0xb9;
1541
+ target[position$1++] = length >> 8;
1542
+ target[position$1++] = length & 0xff;
1543
+ } else {
1544
+ target[position$1++] = 0xba;
1545
+ targetView.setUint32(position$1, length);
1546
+ position$1 += 4;
1547
+ }
1548
+ if (encoder.keyMap) {
1549
+ for (let [ key, entryValue ] of value) {
1550
+ encode(encoder.encodeKey(key));
1551
+ encode(entryValue);
1552
+ }
1553
+ } else {
1554
+ for (let [ key, entryValue ] of value) {
1555
+ encode(key);
1556
+ encode(entryValue);
1557
+ }
1558
+ }
1559
+ } else {
1560
+ for (let i = 0, l = extensions.length; i < l; i++) {
1561
+ let extensionClass = extensionClasses[i];
1562
+ if (value instanceof extensionClass) {
1563
+ let extension = extensions[i];
1564
+ let tag = extension.tag;
1565
+ if (tag == undefined)
1566
+ tag = extension.getTag && extension.getTag.call(this, value);
1567
+ if (tag < 0x18) {
1568
+ target[position$1++] = 0xc0 | tag;
1569
+ } else if (tag < 0x100) {
1570
+ target[position$1++] = 0xd8;
1571
+ target[position$1++] = tag;
1572
+ } else if (tag < 0x10000) {
1573
+ target[position$1++] = 0xd9;
1574
+ target[position$1++] = tag >> 8;
1575
+ target[position$1++] = tag & 0xff;
1576
+ } else if (tag > -1) {
1577
+ target[position$1++] = 0xda;
1578
+ targetView.setUint32(position$1, tag);
1579
+ position$1 += 4;
1580
+ } // else undefined, don't write tag
1581
+ extension.encode.call(this, value, encode, makeRoom);
1582
+ return
1583
+ }
1584
+ }
1585
+ if (value[Symbol.iterator]) {
1586
+ target[position$1++] = 0x9f; // indefinite length array
1587
+ for (let entry of value) {
1588
+ encode(entry);
1589
+ }
1590
+ target[position$1++] = 0xff; // stop-code
1591
+ return
1592
+ }
1593
+ // no extension found, write as object
1594
+ writeObject(value, !value.hasOwnProperty); // if it doesn't have hasOwnProperty, don't do hasOwnProperty checks
1595
+ }
1596
+ }
1597
+ } else if (type === 'boolean') {
1598
+ target[position$1++] = value ? 0xf5 : 0xf4;
1599
+ } else if (type === 'bigint') {
1600
+ if (value < (BigInt(1)<<BigInt(64)) && value >= 0) {
1601
+ // use an unsigned int as long as it fits
1602
+ target[position$1++] = 0x1b;
1603
+ targetView.setBigUint64(position$1, value);
1604
+ } else if (value > -(BigInt(1)<<BigInt(64)) && value < 0) {
1605
+ // if we can fit an unsigned int, use that
1606
+ target[position$1++] = 0x3b;
1607
+ targetView.setBigUint64(position$1, -value - BigInt(1));
1608
+ } else {
1609
+ // overflow
1610
+ if (this.largeBigIntToFloat) {
1611
+ target[position$1++] = 0xfb;
1612
+ targetView.setFloat64(position$1, Number(value));
1613
+ } else {
1614
+ throw new RangeError(value + ' was too large to fit in CBOR 64-bit integer format, set largeBigIntToFloat to convert to float-64')
1615
+ }
1616
+ }
1617
+ position$1 += 8;
1618
+ } else if (type === 'undefined') {
1619
+ target[position$1++] = 0xf7;
1620
+ } else {
1621
+ throw new Error('Unknown type: ' + type)
1622
+ }
1623
+ };
1624
+
1625
+ const writeObject = this.useRecords === false ? this.variableMapSize ? (object) => {
1626
+ // this method is slightly slower, but generates "preferred serialization" (optimally small for smaller objects)
1627
+ let keys = Object.keys(object);
1628
+ let vals = Object.values(object);
1629
+ let length = keys.length;
1630
+ if (length < 0x18) {
1631
+ target[position$1++] = 0xa0 | length;
1632
+ } else if (length < 0x100) {
1633
+ target[position$1++] = 0xb8;
1634
+ target[position$1++] = length;
1635
+ } else if (length < 0x10000) {
1636
+ target[position$1++] = 0xb9;
1637
+ target[position$1++] = length >> 8;
1638
+ target[position$1++] = length & 0xff;
1639
+ } else {
1640
+ target[position$1++] = 0xba;
1641
+ targetView.setUint32(position$1, length);
1642
+ position$1 += 4;
1643
+ }
1644
+ if (encoder.keyMap) {
1645
+ for (let i = 0; i < length; i++) {
1646
+ encode(encodeKey(keys[i]));
1647
+ encode(vals[i]);
1648
+ }
1649
+ } else {
1650
+ for (let i = 0; i < length; i++) {
1651
+ encode(keys[i]);
1652
+ encode(vals[i]);
1653
+ }
1654
+ }
1655
+ } :
1656
+ (object, safePrototype) => {
1657
+ target[position$1++] = 0xb9; // always use map 16, so we can preallocate and set the length afterwards
1658
+ let objectOffset = position$1 - start;
1659
+ position$1 += 2;
1660
+ let size = 0;
1661
+ if (encoder.keyMap) {
1662
+ for (let key in object) if (safePrototype || object.hasOwnProperty(key)) {
1663
+ encode(encoder.encodeKey(key));
1664
+ encode(object[key]);
1665
+ size++;
1666
+ }
1667
+ } else {
1668
+ for (let key in object) if (safePrototype || object.hasOwnProperty(key)) {
1669
+ encode(key);
1670
+ encode(object[key]);
1671
+ size++;
1672
+ }
1673
+ }
1674
+ target[objectOffset++ + start] = size >> 8;
1675
+ target[objectOffset + start] = size & 0xff;
1676
+ } :
1677
+ (object, safePrototype) => {
1678
+ let nextTransition, transition = structures.transitions || (structures.transitions = Object.create(null));
1679
+ let newTransitions = 0;
1680
+ let length = 0;
1681
+ let parentRecordId;
1682
+ let keys;
1683
+ if (this.keyMap) {
1684
+ keys = Object.keys(object).map(k => this.encodeKey(k));
1685
+ length = keys.length;
1686
+ for (let i = 0; i < length; i++) {
1687
+ let key = keys[i];
1688
+ nextTransition = transition[key];
1689
+ if (!nextTransition) {
1690
+ nextTransition = transition[key] = Object.create(null);
1691
+ newTransitions++;
1692
+ }
1693
+ transition = nextTransition;
1694
+ }
1695
+ } else {
1696
+ for (let key in object) if (safePrototype || object.hasOwnProperty(key)) {
1697
+ nextTransition = transition[key];
1698
+ if (!nextTransition) {
1699
+ if (transition[RECORD_SYMBOL] & 0x100000) {// this indicates it is a brancheable/extendable terminal node, so we will use this record id and extend it
1700
+ parentRecordId = transition[RECORD_SYMBOL] & 0xffff;
1701
+ }
1702
+ nextTransition = transition[key] = Object.create(null);
1703
+ newTransitions++;
1704
+ }
1705
+ transition = nextTransition;
1706
+ length++;
1707
+ }
1708
+ }
1709
+ let recordId = transition[RECORD_SYMBOL];
1710
+ if (recordId !== undefined) {
1711
+ recordId &= 0xffff;
1712
+ target[position$1++] = 0xd9;
1713
+ target[position$1++] = (recordId >> 8) | 0xe0;
1714
+ target[position$1++] = recordId & 0xff;
1715
+ } else {
1716
+ if (!keys)
1717
+ keys = transition.__keys__ || (transition.__keys__ = Object.keys(object));
1718
+ if (parentRecordId === undefined) {
1719
+ recordId = structures.nextId++;
1720
+ if (!recordId) {
1721
+ recordId = 0;
1722
+ structures.nextId = 1;
1723
+ }
1724
+ if (recordId >= MAX_STRUCTURES) {// cycle back around
1725
+ structures.nextId = (recordId = maxSharedStructures) + 1;
1726
+ }
1727
+ } else {
1728
+ recordId = parentRecordId;
1729
+ }
1730
+ structures[recordId] = keys;
1731
+ if (recordId < maxSharedStructures) {
1732
+ target[position$1++] = 0xd9;
1733
+ target[position$1++] = (recordId >> 8) | 0xe0;
1734
+ target[position$1++] = recordId & 0xff;
1735
+ transition = structures.transitions;
1736
+ for (let i = 0; i < length; i++) {
1737
+ if (transition[RECORD_SYMBOL] === undefined || (transition[RECORD_SYMBOL] & 0x100000))
1738
+ transition[RECORD_SYMBOL] = recordId;
1739
+ transition = transition[keys[i]];
1740
+ }
1741
+ transition[RECORD_SYMBOL] = recordId | 0x100000; // indicates it is a extendable terminal
1742
+ hasSharedUpdate = true;
1743
+ } else {
1744
+ transition[RECORD_SYMBOL] = recordId;
1745
+ targetView.setUint32(position$1, 0xd9dfff00); // tag two byte, then record definition id
1746
+ position$1 += 3;
1747
+ if (newTransitions)
1748
+ transitionsCount += serializationsSinceTransitionRebuild * newTransitions;
1749
+ // record the removal of the id, we can maintain our shared structure
1750
+ if (recordIdsToRemove.length >= MAX_STRUCTURES - maxSharedStructures)
1751
+ recordIdsToRemove.shift()[RECORD_SYMBOL] = undefined; // we are cycling back through, and have to remove old ones
1752
+ recordIdsToRemove.push(transition);
1753
+ writeArrayHeader(length + 2);
1754
+ encode(0xe000 + recordId);
1755
+ encode(keys);
1756
+ for (let v of Object.values(object)) encode(v);
1757
+ return
1758
+ }
1759
+ }
1760
+ if (length < 0x18) { // write the array header
1761
+ target[position$1++] = 0x80 | length;
1762
+ } else {
1763
+ writeArrayHeader(length);
1764
+ }
1765
+ for (let key in object)
1766
+ if (safePrototype || object.hasOwnProperty(key))
1767
+ encode(object[key]);
1768
+ };
1769
+ const makeRoom = (end) => {
1770
+ let newSize;
1771
+ if (end > 0x1000000) {
1772
+ // special handling for really large buffers
1773
+ if ((end - start) > MAX_BUFFER_SIZE)
1774
+ throw new Error('Encoded buffer would be larger than maximum buffer size')
1775
+ newSize = Math.min(MAX_BUFFER_SIZE,
1776
+ Math.round(Math.max((end - start) * (end > 0x4000000 ? 1.25 : 2), 0x400000) / 0x1000) * 0x1000);
1777
+ } else // faster handling for smaller buffers
1778
+ newSize = ((Math.max((end - start) << 2, target.length - 1) >> 12) + 1) << 12;
1779
+ let newBuffer = new ByteArrayAllocate(newSize);
1780
+ targetView = new DataView(newBuffer.buffer, 0, newSize);
1781
+ if (target.copy)
1782
+ target.copy(newBuffer, 0, start, end);
1783
+ else
1784
+ newBuffer.set(target.slice(start, end));
1785
+ position$1 -= start;
1786
+ start = 0;
1787
+ safeEnd = newBuffer.length - 10;
1788
+ return target = newBuffer
1789
+ };
1790
+ }
1791
+ useBuffer(buffer) {
1792
+ // this means we are finished using our own buffer and we can write over it safely
1793
+ target = buffer;
1794
+ targetView = new DataView(target.buffer, target.byteOffset, target.byteLength);
1795
+ position$1 = 0;
1796
+ }
1797
+ clearSharedData() {
1798
+ if (this.structures)
1799
+ this.structures = [];
1800
+ if (this.sharedValues)
1801
+ this.sharedValues = undefined;
1802
+ }
1803
+ updateSharedData() {
1804
+ let lastVersion = this.sharedVersion || 0;
1805
+ this.sharedVersion = lastVersion + 1;
1806
+ let structuresCopy = this.structures.slice(0);
1807
+ let sharedData = new SharedData(structuresCopy, this.sharedValues, this.sharedVersion);
1808
+ let saveResults = this.saveShared(sharedData,
1809
+ existingShared => (existingShared && existingShared.version || 0) == lastVersion);
1810
+ if (saveResults === false) {
1811
+ // get updated structures and try again if the update failed
1812
+ sharedData = this.getShared() || {};
1813
+ this.structures = sharedData.structures || [];
1814
+ this.sharedValues = sharedData.packedValues;
1815
+ this.sharedVersion = sharedData.version;
1816
+ this.structures.nextId = this.structures.length;
1817
+ } else {
1818
+ // restore structures
1819
+ structuresCopy.forEach((structure, i) => this.structures[i] = structure);
1820
+ }
1821
+ // 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
1822
+ return saveResults
1823
+ }
1824
+ }
1825
+ class SharedData {
1826
+ constructor(structures, values, version) {
1827
+ this.structures = structures;
1828
+ this.packedValues = values;
1829
+ this.version = version;
1830
+ }
1831
+ }
1832
+
1833
+ function writeArrayHeader(length) {
1834
+ if (length < 0x18)
1835
+ target[position$1++] = 0x80 | length;
1836
+ else if (length < 0x100) {
1837
+ target[position$1++] = 0x98;
1838
+ target[position$1++] = length;
1839
+ } else if (length < 0x10000) {
1840
+ target[position$1++] = 0x99;
1841
+ target[position$1++] = length >> 8;
1842
+ target[position$1++] = length & 0xff;
1843
+ } else {
1844
+ target[position$1++] = 0x9a;
1845
+ targetView.setUint32(position$1, length);
1846
+ position$1 += 4;
1847
+ }
1848
+ }
1849
+
1850
+ function findRepetitiveStrings(value, packedValues) {
1851
+ switch(typeof value) {
1852
+ case 'string':
1853
+ if (value.length > 3) {
1854
+ if (packedValues.objectMap[value] > -1 || packedValues.values.length >= packedValues.maxValues)
1855
+ return
1856
+ let packedStatus = packedValues.get(value);
1857
+ if (packedStatus) {
1858
+ if (++packedStatus.count == 2) {
1859
+ packedValues.values.push(value);
1860
+ }
1861
+ } else {
1862
+ packedValues.set(value, {
1863
+ count: 1,
1864
+ });
1865
+ if (packedValues.samplingPackedValues) {
1866
+ let status = packedValues.samplingPackedValues.get(value);
1867
+ if (status)
1868
+ status.count++;
1869
+ else
1870
+ packedValues.samplingPackedValues.set(value, {
1871
+ count: 1,
1872
+ });
1873
+ }
1874
+ }
1875
+ }
1876
+ break
1877
+ case 'object':
1878
+ if (value) {
1879
+ if (value instanceof Array) {
1880
+ for (let i = 0, l = value.length; i < l; i++) {
1881
+ findRepetitiveStrings(value[i], packedValues);
1882
+ }
1883
+
1884
+ } else {
1885
+ let includeKeys = !packedValues.encoder.useRecords;
1886
+ for (var key in value) {
1887
+ if (value.hasOwnProperty(key)) {
1888
+ if (includeKeys)
1889
+ findRepetitiveStrings(key, packedValues);
1890
+ findRepetitiveStrings(value[key], packedValues);
1891
+ }
1892
+ }
1893
+ }
1894
+ }
1895
+ break
1896
+ case 'function': console.log(value);
1897
+ }
1898
+ }
1899
+ const isLittleEndianMachine$1 = new Uint8Array(new Uint16Array([1]).buffer)[0] == 1;
1900
+ extensionClasses = [ Date, Set, Error, RegExp, Tag, ArrayBuffer,
1901
+ Uint8Array, Uint8ClampedArray, Uint16Array, Uint32Array,
1902
+ typeof BigUint64Array == 'undefined' ? function() {} : BigUint64Array, Int8Array, Int16Array, Int32Array,
1903
+ typeof BigInt64Array == 'undefined' ? function() {} : BigInt64Array,
1904
+ Float32Array, Float64Array, SharedData ];
1905
+
1906
+ //Object.getPrototypeOf(Uint8Array.prototype).constructor /*TypedArray*/
1907
+ extensions = [{ // Date
1908
+ tag: 1,
1909
+ encode(date, encode) {
1910
+ let seconds = date.getTime() / 1000;
1911
+ if ((this.useTimestamp32 || date.getMilliseconds() === 0) && seconds >= 0 && seconds < 0x100000000) {
1912
+ // Timestamp 32
1913
+ target[position$1++] = 0x1a;
1914
+ targetView.setUint32(position$1, seconds);
1915
+ position$1 += 4;
1916
+ } else {
1917
+ // Timestamp float64
1918
+ target[position$1++] = 0xfb;
1919
+ targetView.setFloat64(position$1, seconds);
1920
+ position$1 += 8;
1921
+ }
1922
+ }
1923
+ }, { // Set
1924
+ tag: 258, // https://github.com/input-output-hk/cbor-sets-spec/blob/master/CBOR_SETS.md
1925
+ encode(set, encode) {
1926
+ let array = Array.from(set);
1927
+ encode(array);
1928
+ }
1929
+ }, { // Error
1930
+ tag: 27, // http://cbor.schmorp.de/generic-object
1931
+ encode(error, encode) {
1932
+ encode([ error.name, error.message ]);
1933
+ }
1934
+ }, { // RegExp
1935
+ tag: 27, // http://cbor.schmorp.de/generic-object
1936
+ encode(regex, encode) {
1937
+ encode([ 'RegExp', regex.source, regex.flags ]);
1938
+ }
1939
+ }, { // Tag
1940
+ getTag(tag) {
1941
+ return tag.tag
1942
+ },
1943
+ encode(tag, encode) {
1944
+ encode(tag.value);
1945
+ }
1946
+ }, { // ArrayBuffer
1947
+ encode(arrayBuffer, encode, makeRoom) {
1948
+ writeBuffer(arrayBuffer, makeRoom);
1949
+ }
1950
+ }, { // Uint8Array
1951
+ getTag(typedArray) {
1952
+ if (typedArray.constructor === Uint8Array) {
1953
+ if (this.tagUint8Array || hasNodeBuffer && this.tagUint8Array !== false)
1954
+ return 64;
1955
+ } // else no tag
1956
+ },
1957
+ encode(typedArray, encode, makeRoom) {
1958
+ writeBuffer(typedArray, makeRoom);
1959
+ }
1960
+ },
1961
+ typedArrayEncoder(68, 1),
1962
+ typedArrayEncoder(69, 2),
1963
+ typedArrayEncoder(70, 4),
1964
+ typedArrayEncoder(71, 8),
1965
+ typedArrayEncoder(72, 1),
1966
+ typedArrayEncoder(77, 2),
1967
+ typedArrayEncoder(78, 4),
1968
+ typedArrayEncoder(79, 8),
1969
+ typedArrayEncoder(85, 4),
1970
+ typedArrayEncoder(86, 8),
1971
+ {
1972
+ encode(sharedData, encode) { // write SharedData
1973
+ let packedValues = sharedData.packedValues || [];
1974
+ let sharedStructures = sharedData.structures || [];
1975
+ if (packedValues.values.length > 0) {
1976
+ target[position$1++] = 0xd8; // one-byte tag
1977
+ target[position$1++] = 51; // tag 51 for packed shared structures https://www.potaroo.net/ietf/ids/draft-ietf-cbor-packed-03.txt
1978
+ writeArrayHeader(4);
1979
+ let valuesArray = packedValues.values;
1980
+ encode(valuesArray);
1981
+ writeArrayHeader(0); // prefixes
1982
+ writeArrayHeader(0); // suffixes
1983
+ packedObjectMap = Object.create(sharedPackedObjectMap || null);
1984
+ for (let i = 0, l = valuesArray.length; i < l; i++) {
1985
+ packedObjectMap[valuesArray[i]] = i;
1986
+ }
1987
+ }
1988
+ if (sharedStructures) {
1989
+ targetView.setUint32(position$1, 0xd9dffe00);
1990
+ position$1 += 3;
1991
+ let definitions = sharedStructures.slice(0);
1992
+ definitions.unshift(0xe000);
1993
+ definitions.push(new Tag(sharedData.version, 0x53687264));
1994
+ encode(definitions);
1995
+ } else
1996
+ encode(new Tag(sharedData.version, 0x53687264));
1997
+ }
1998
+ }];
1999
+ function typedArrayEncoder(tag, size) {
2000
+ if (!isLittleEndianMachine$1 && size > 1)
2001
+ tag -= 4; // the big endian equivalents are 4 less
2002
+ return {
2003
+ tag: tag,
2004
+ encode: function writeExtBuffer(typedArray, encode) {
2005
+ let length = typedArray.byteLength;
2006
+ let offset = typedArray.byteOffset || 0;
2007
+ let buffer = typedArray.buffer || typedArray;
2008
+ encode(hasNodeBuffer ? Buffer.from(buffer, offset, length) :
2009
+ new Uint8Array(buffer, offset, length));
2010
+ }
2011
+ }
2012
+ }
2013
+ function writeBuffer(buffer, makeRoom) {
2014
+ let length = buffer.byteLength;
2015
+ if (length < 0x18) {
2016
+ target[position$1++] = 0x40 + length;
2017
+ } else if (length < 0x100) {
2018
+ target[position$1++] = 0x58;
2019
+ target[position$1++] = length;
2020
+ } else if (length < 0x10000) {
2021
+ target[position$1++] = 0x59;
2022
+ target[position$1++] = length >> 8;
2023
+ target[position$1++] = length & 0xff;
2024
+ } else {
2025
+ target[position$1++] = 0x5a;
2026
+ targetView.setUint32(position$1, length);
2027
+ position$1 += 4;
2028
+ }
2029
+ if (position$1 + length >= target.length) {
2030
+ makeRoom(position$1 + length);
2031
+ }
2032
+ // if it is already a typed array (has an ArrayBuffer), use that, but if it is an ArrayBuffer itself,
2033
+ // must wrap it to set it.
2034
+ target.set(buffer.buffer ? buffer : new Uint8Array(buffer), position$1);
2035
+ position$1 += length;
2036
+ }
2037
+
2038
+ function insertIds(serialized, idsToInsert) {
2039
+ // insert the ids that need to be referenced for structured clones
2040
+ let nextId;
2041
+ let distanceToMove = idsToInsert.length * 2;
2042
+ let lastEnd = serialized.length - distanceToMove;
2043
+ idsToInsert.sort((a, b) => a.offset > b.offset ? 1 : -1);
2044
+ for (let id = 0; id < idsToInsert.length; id++) {
2045
+ let referee = idsToInsert[id];
2046
+ referee.id = id;
2047
+ for (let position of referee.references) {
2048
+ serialized[position++] = id >> 8;
2049
+ serialized[position] = id & 0xff;
2050
+ }
2051
+ }
2052
+ while (nextId = idsToInsert.pop()) {
2053
+ let offset = nextId.offset;
2054
+ serialized.copyWithin(offset + distanceToMove, offset, lastEnd);
2055
+ distanceToMove -= 2;
2056
+ let position = offset + distanceToMove;
2057
+ serialized[position++] = 0xd8;
2058
+ serialized[position++] = 28; // http://cbor.schmorp.de/value-sharing
2059
+ lastEnd = offset;
2060
+ }
2061
+ return serialized
2062
+ }
2063
+ function writeBundles(start, encode) {
2064
+ targetView.setUint32(bundledStrings$1.position + start, position$1 - bundledStrings$1.position - start + 1); // the offset to bundle
2065
+ let writeStrings = bundledStrings$1;
2066
+ bundledStrings$1 = null;
2067
+ encode(writeStrings[0]);
2068
+ encode(writeStrings[1]);
2069
+ }
2070
+
2071
+ function addExtension$1(extension) {
2072
+ if (extension.Class) {
2073
+ if (!extension.encode)
2074
+ throw new Error('Extension has no encode function')
2075
+ extensionClasses.unshift(extension.Class);
2076
+ extensions.unshift(extension);
2077
+ }
2078
+ addExtension(extension);
2079
+ }
2080
+ let defaultEncoder = new Encoder({ useRecords: false });
2081
+ const encode = defaultEncoder.encode;
2082
+ const { NEVER, ALWAYS, DECIMAL_ROUND, DECIMAL_FIT } = FLOAT32_OPTIONS;
2083
+ const REUSE_BUFFER_MODE = 512;
2074
2084
  const RESET_BUFFER_MODE = 1024;
2075
2085
 
2076
- /**
2077
- * Given an Iterable first argument, returns an Iterable where each value is encoded as a Buffer
2078
- * If the argument is only Async Iterable, the return value will be an Async Iterable.
2079
- * @param {Iterable|Iterator|AsyncIterable|AsyncIterator} objectIterator - iterable source, like a Readable object stream, an array, Set, or custom object
2080
- * @param {options} [options] - cbor-x Encoder options
2081
- * @returns {IterableIterator|Promise.<AsyncIterableIterator>}
2082
- */
2083
- function encodeIter (objectIterator, options = {}) {
2084
- if (!objectIterator || typeof objectIterator !== 'object') {
2085
- throw new Error('first argument must be an Iterable, Async Iterable, or a Promise for an Async Iterable')
2086
- } else if (typeof objectIterator[Symbol.iterator] === 'function') {
2087
- return encodeIterSync(objectIterator, options)
2088
- } else if (typeof objectIterator.then === 'function' || typeof objectIterator[Symbol.asyncIterator] === 'function') {
2089
- return encodeIterAsync(objectIterator, options)
2090
- } else {
2091
- throw new Error('first argument must be an Iterable, Async Iterable, Iterator, Async Iterator, or a Promise')
2092
- }
2093
- }
2094
-
2095
- function * encodeIterSync (objectIterator, options) {
2096
- const encoder = new Encoder(options);
2097
- for (const value of objectIterator) {
2098
- yield encoder.encode(value);
2099
- }
2100
- }
2101
-
2102
- async function * encodeIterAsync (objectIterator, options) {
2103
- const encoder = new Encoder(options);
2104
- for await (const value of objectIterator) {
2105
- yield encoder.encode(value);
2106
- }
2107
- }
2108
-
2109
- /**
2110
- * Given an Iterable/Iterator input which yields buffers, returns an IterableIterator which yields sync decoded objects
2111
- * Or, given an Async Iterable/Iterator which yields promises resolving in buffers, returns an AsyncIterableIterator.
2112
- * @param {Iterable|Iterator|AsyncIterable|AsyncIterableIterator} bufferIterator
2113
- * @param {object} [options] - Decoder options
2114
- * @returns {IterableIterator|Promise.<AsyncIterableIterator}
2115
- */
2116
- function decodeIter (bufferIterator, options = {}) {
2117
- if (!bufferIterator || typeof bufferIterator !== 'object') {
2118
- throw new Error('first argument must be an Iterable, Async Iterable, Iterator, Async Iterator, or a promise')
2119
- }
2120
-
2121
- const decoder = new Decoder(options);
2122
- let incomplete;
2123
- const parser = (chunk) => {
2124
- let yields;
2125
- // if there's incomplete data from previous chunk, concatinate and try again
2126
- if (incomplete) {
2127
- chunk = Buffer.concat([incomplete, chunk]);
2128
- incomplete = undefined;
2129
- }
2130
-
2131
- try {
2132
- yields = decoder.decodeMultiple(chunk);
2133
- } catch (err) {
2134
- if (err.incomplete) {
2135
- incomplete = chunk.slice(err.lastPosition);
2136
- yields = err.values;
2137
- } else {
2138
- throw err
2139
- }
2140
- }
2141
- return yields
2142
- };
2143
-
2144
- if (typeof bufferIterator[Symbol.iterator] === 'function') {
2145
- return (function * iter () {
2146
- for (const value of bufferIterator) {
2147
- yield * parser(value);
2148
- }
2149
- })()
2150
- } else if (typeof bufferIterator[Symbol.asyncIterator] === 'function') {
2151
- return (async function * iter () {
2152
- for await (const value of bufferIterator) {
2153
- yield * parser(value);
2154
- }
2155
- })()
2156
- }
2086
+ /**
2087
+ * Given an Iterable first argument, returns an Iterable where each value is encoded as a Buffer
2088
+ * If the argument is only Async Iterable, the return value will be an Async Iterable.
2089
+ * @param {Iterable|Iterator|AsyncIterable|AsyncIterator} objectIterator - iterable source, like a Readable object stream, an array, Set, or custom object
2090
+ * @param {options} [options] - cbor-x Encoder options
2091
+ * @returns {IterableIterator|Promise.<AsyncIterableIterator>}
2092
+ */
2093
+ function encodeIter (objectIterator, options = {}) {
2094
+ if (!objectIterator || typeof objectIterator !== 'object') {
2095
+ throw new Error('first argument must be an Iterable, Async Iterable, or a Promise for an Async Iterable')
2096
+ } else if (typeof objectIterator[Symbol.iterator] === 'function') {
2097
+ return encodeIterSync(objectIterator, options)
2098
+ } else if (typeof objectIterator.then === 'function' || typeof objectIterator[Symbol.asyncIterator] === 'function') {
2099
+ return encodeIterAsync(objectIterator, options)
2100
+ } else {
2101
+ throw new Error('first argument must be an Iterable, Async Iterable, Iterator, Async Iterator, or a Promise')
2102
+ }
2103
+ }
2104
+
2105
+ function * encodeIterSync (objectIterator, options) {
2106
+ const encoder = new Encoder(options);
2107
+ for (const value of objectIterator) {
2108
+ yield encoder.encode(value);
2109
+ }
2110
+ }
2111
+
2112
+ async function * encodeIterAsync (objectIterator, options) {
2113
+ const encoder = new Encoder(options);
2114
+ for await (const value of objectIterator) {
2115
+ yield encoder.encode(value);
2116
+ }
2117
+ }
2118
+
2119
+ /**
2120
+ * Given an Iterable/Iterator input which yields buffers, returns an IterableIterator which yields sync decoded objects
2121
+ * Or, given an Async Iterable/Iterator which yields promises resolving in buffers, returns an AsyncIterableIterator.
2122
+ * @param {Iterable|Iterator|AsyncIterable|AsyncIterableIterator} bufferIterator
2123
+ * @param {object} [options] - Decoder options
2124
+ * @returns {IterableIterator|Promise.<AsyncIterableIterator}
2125
+ */
2126
+ function decodeIter (bufferIterator, options = {}) {
2127
+ if (!bufferIterator || typeof bufferIterator !== 'object') {
2128
+ throw new Error('first argument must be an Iterable, Async Iterable, Iterator, Async Iterator, or a promise')
2129
+ }
2130
+
2131
+ const decoder = new Decoder(options);
2132
+ let incomplete;
2133
+ const parser = (chunk) => {
2134
+ let yields;
2135
+ // if there's incomplete data from previous chunk, concatinate and try again
2136
+ if (incomplete) {
2137
+ chunk = Buffer.concat([incomplete, chunk]);
2138
+ incomplete = undefined;
2139
+ }
2140
+
2141
+ try {
2142
+ yields = decoder.decodeMultiple(chunk);
2143
+ } catch (err) {
2144
+ if (err.incomplete) {
2145
+ incomplete = chunk.slice(err.lastPosition);
2146
+ yields = err.values;
2147
+ } else {
2148
+ throw err
2149
+ }
2150
+ }
2151
+ return yields
2152
+ };
2153
+
2154
+ if (typeof bufferIterator[Symbol.iterator] === 'function') {
2155
+ return (function * iter () {
2156
+ for (const value of bufferIterator) {
2157
+ yield * parser(value);
2158
+ }
2159
+ })()
2160
+ } else if (typeof bufferIterator[Symbol.asyncIterator] === 'function') {
2161
+ return (async function * iter () {
2162
+ for await (const value of bufferIterator) {
2163
+ yield * parser(value);
2164
+ }
2165
+ })()
2166
+ }
2157
2167
  }
2158
2168
 
2159
2169
  exports.ALWAYS = ALWAYS;