@powersync/web 1.21.1 → 1.22.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.
@@ -40,20 +40,31 @@ __webpack_require__.r(__webpack_exports__);
40
40
  /* harmony export */ serializeWithBufferAndIndex: () => (/* binding */ serializeWithBufferAndIndex),
41
41
  /* harmony export */ setInternalBufferSize: () => (/* binding */ setInternalBufferSize)
42
42
  /* harmony export */ });
43
- function isAnyArrayBuffer(value) {
44
- return ['[object ArrayBuffer]', '[object SharedArrayBuffer]'].includes(Object.prototype.toString.call(value));
45
- }
43
+ const TypedArrayPrototypeGetSymbolToStringTag = (() => {
44
+ const g = Object.getOwnPropertyDescriptor(Object.getPrototypeOf(Uint8Array.prototype), Symbol.toStringTag).get;
45
+ return (value) => g.call(value);
46
+ })();
46
47
  function isUint8Array(value) {
47
- return Object.prototype.toString.call(value) === '[object Uint8Array]';
48
+ return TypedArrayPrototypeGetSymbolToStringTag(value) === 'Uint8Array';
49
+ }
50
+ function isAnyArrayBuffer(value) {
51
+ return (typeof value === 'object' &&
52
+ value != null &&
53
+ Symbol.toStringTag in value &&
54
+ (value[Symbol.toStringTag] === 'ArrayBuffer' ||
55
+ value[Symbol.toStringTag] === 'SharedArrayBuffer'));
48
56
  }
49
- function isRegExp(d) {
50
- return Object.prototype.toString.call(d) === '[object RegExp]';
57
+ function isRegExp(regexp) {
58
+ return regexp instanceof RegExp || Object.prototype.toString.call(regexp) === '[object RegExp]';
51
59
  }
52
- function isMap(d) {
53
- return Object.prototype.toString.call(d) === '[object Map]';
60
+ function isMap(value) {
61
+ return (typeof value === 'object' &&
62
+ value != null &&
63
+ Symbol.toStringTag in value &&
64
+ value[Symbol.toStringTag] === 'Map');
54
65
  }
55
- function isDate(d) {
56
- return Object.prototype.toString.call(d) === '[object Date]';
66
+ function isDate(date) {
67
+ return date instanceof Date || Object.prototype.toString.call(date) === '[object Date]';
57
68
  }
58
69
  function defaultInspect(x, _options) {
59
70
  return JSON.stringify(x, (k, v) => {
@@ -77,8 +88,9 @@ function getStylizeFunction(options) {
77
88
  }
78
89
 
79
90
  const BSON_MAJOR_VERSION = 6;
91
+ const BSON_VERSION_SYMBOL = Symbol.for('@@mdb.bson.version');
80
92
  const BSON_INT32_MAX = 0x7fffffff;
81
- const BSON_INT32_MIN = -0x80000000;
93
+ const BSON_INT32_MIN = -2147483648;
82
94
  const BSON_INT64_MAX = Math.pow(2, 63) - 1;
83
95
  const BSON_INT64_MIN = -Math.pow(2, 63);
84
96
  const JS_INT_MAX = Math.pow(2, 53);
@@ -269,7 +281,7 @@ const nodeJsByteUtils = {
269
281
  stringTag === '[object SharedArrayBuffer]') {
270
282
  return Buffer.from(potentialBuffer);
271
283
  }
272
- throw new BSONError(`Cannot create Buffer from ${String(potentialBuffer)}`);
284
+ throw new BSONError(`Cannot create Buffer from the passed potentialBuffer.`);
273
285
  },
274
286
  allocate(size) {
275
287
  return Buffer.alloc(size);
@@ -327,7 +339,10 @@ const nodeJsByteUtils = {
327
339
  }
328
340
  return nodeJsByteUtils.toLocalBufferType(buffer).write(source, byteOffset, undefined, 'utf8');
329
341
  },
330
- randomBytes: nodejsRandomBytes
342
+ randomBytes: nodejsRandomBytes,
343
+ swap32(buffer) {
344
+ return nodeJsByteUtils.toLocalBufferType(buffer).swap32();
345
+ }
331
346
  };
332
347
 
333
348
  function isReactNative() {
@@ -372,7 +387,7 @@ const webByteUtils = {
372
387
  stringTag === '[object SharedArrayBuffer]') {
373
388
  return new Uint8Array(potentialUint8array);
374
389
  }
375
- throw new BSONError(`Cannot make a Uint8Array from ${String(potentialUint8array)}`);
390
+ throw new BSONError(`Cannot make a Uint8Array from passed potentialBuffer.`);
376
391
  },
377
392
  allocate(size) {
378
393
  if (typeof size !== 'number') {
@@ -444,14 +459,30 @@ const webByteUtils = {
444
459
  uint8array.set(bytes, byteOffset);
445
460
  return bytes.byteLength;
446
461
  },
447
- randomBytes: webRandomBytes
462
+ randomBytes: webRandomBytes,
463
+ swap32(buffer) {
464
+ if (buffer.length % 4 !== 0) {
465
+ throw new RangeError('Buffer size must be a multiple of 32-bits');
466
+ }
467
+ for (let i = 0; i < buffer.length; i += 4) {
468
+ const byte0 = buffer[i];
469
+ const byte1 = buffer[i + 1];
470
+ const byte2 = buffer[i + 2];
471
+ const byte3 = buffer[i + 3];
472
+ buffer[i] = byte3;
473
+ buffer[i + 1] = byte2;
474
+ buffer[i + 2] = byte1;
475
+ buffer[i + 3] = byte0;
476
+ }
477
+ return buffer;
478
+ }
448
479
  };
449
480
 
450
481
  const hasGlobalBuffer = typeof Buffer === 'function' && Buffer.prototype?._isBuffer !== true;
451
482
  const ByteUtils = hasGlobalBuffer ? nodeJsByteUtils : webByteUtils;
452
483
 
453
484
  class BSONValue {
454
- get [Symbol.for('@@mdb.bson.version')]() {
485
+ get [BSON_VERSION_SYMBOL]() {
455
486
  return BSON_MAJOR_VERSION;
456
487
  }
457
488
  [Symbol.for('nodejs.util.inspect.custom')](depth, options, inspect) {
@@ -459,6 +490,140 @@ class BSONValue {
459
490
  }
460
491
  }
461
492
 
493
+ const FLOAT = new Float64Array(1);
494
+ const FLOAT_BYTES = new Uint8Array(FLOAT.buffer, 0, 8);
495
+ FLOAT[0] = -1;
496
+ const isBigEndian = FLOAT_BYTES[7] === 0;
497
+ const NumberUtils = {
498
+ isBigEndian,
499
+ getNonnegativeInt32LE(source, offset) {
500
+ if (source[offset + 3] > 127) {
501
+ throw new RangeError(`Size cannot be negative at offset: ${offset}`);
502
+ }
503
+ return (source[offset] |
504
+ (source[offset + 1] << 8) |
505
+ (source[offset + 2] << 16) |
506
+ (source[offset + 3] << 24));
507
+ },
508
+ getInt32LE(source, offset) {
509
+ return (source[offset] |
510
+ (source[offset + 1] << 8) |
511
+ (source[offset + 2] << 16) |
512
+ (source[offset + 3] << 24));
513
+ },
514
+ getUint32LE(source, offset) {
515
+ return (source[offset] +
516
+ source[offset + 1] * 256 +
517
+ source[offset + 2] * 65536 +
518
+ source[offset + 3] * 16777216);
519
+ },
520
+ getUint32BE(source, offset) {
521
+ return (source[offset + 3] +
522
+ source[offset + 2] * 256 +
523
+ source[offset + 1] * 65536 +
524
+ source[offset] * 16777216);
525
+ },
526
+ getBigInt64LE(source, offset) {
527
+ const hi = BigInt(source[offset + 4] +
528
+ source[offset + 5] * 256 +
529
+ source[offset + 6] * 65536 +
530
+ (source[offset + 7] << 24));
531
+ const lo = BigInt(source[offset] +
532
+ source[offset + 1] * 256 +
533
+ source[offset + 2] * 65536 +
534
+ source[offset + 3] * 16777216);
535
+ return (hi << BigInt(32)) + lo;
536
+ },
537
+ getFloat64LE: isBigEndian
538
+ ? (source, offset) => {
539
+ FLOAT_BYTES[7] = source[offset];
540
+ FLOAT_BYTES[6] = source[offset + 1];
541
+ FLOAT_BYTES[5] = source[offset + 2];
542
+ FLOAT_BYTES[4] = source[offset + 3];
543
+ FLOAT_BYTES[3] = source[offset + 4];
544
+ FLOAT_BYTES[2] = source[offset + 5];
545
+ FLOAT_BYTES[1] = source[offset + 6];
546
+ FLOAT_BYTES[0] = source[offset + 7];
547
+ return FLOAT[0];
548
+ }
549
+ : (source, offset) => {
550
+ FLOAT_BYTES[0] = source[offset];
551
+ FLOAT_BYTES[1] = source[offset + 1];
552
+ FLOAT_BYTES[2] = source[offset + 2];
553
+ FLOAT_BYTES[3] = source[offset + 3];
554
+ FLOAT_BYTES[4] = source[offset + 4];
555
+ FLOAT_BYTES[5] = source[offset + 5];
556
+ FLOAT_BYTES[6] = source[offset + 6];
557
+ FLOAT_BYTES[7] = source[offset + 7];
558
+ return FLOAT[0];
559
+ },
560
+ setInt32BE(destination, offset, value) {
561
+ destination[offset + 3] = value;
562
+ value >>>= 8;
563
+ destination[offset + 2] = value;
564
+ value >>>= 8;
565
+ destination[offset + 1] = value;
566
+ value >>>= 8;
567
+ destination[offset] = value;
568
+ return 4;
569
+ },
570
+ setInt32LE(destination, offset, value) {
571
+ destination[offset] = value;
572
+ value >>>= 8;
573
+ destination[offset + 1] = value;
574
+ value >>>= 8;
575
+ destination[offset + 2] = value;
576
+ value >>>= 8;
577
+ destination[offset + 3] = value;
578
+ return 4;
579
+ },
580
+ setBigInt64LE(destination, offset, value) {
581
+ const mask32bits = BigInt(0xffff_ffff);
582
+ let lo = Number(value & mask32bits);
583
+ destination[offset] = lo;
584
+ lo >>= 8;
585
+ destination[offset + 1] = lo;
586
+ lo >>= 8;
587
+ destination[offset + 2] = lo;
588
+ lo >>= 8;
589
+ destination[offset + 3] = lo;
590
+ let hi = Number((value >> BigInt(32)) & mask32bits);
591
+ destination[offset + 4] = hi;
592
+ hi >>= 8;
593
+ destination[offset + 5] = hi;
594
+ hi >>= 8;
595
+ destination[offset + 6] = hi;
596
+ hi >>= 8;
597
+ destination[offset + 7] = hi;
598
+ return 8;
599
+ },
600
+ setFloat64LE: isBigEndian
601
+ ? (destination, offset, value) => {
602
+ FLOAT[0] = value;
603
+ destination[offset] = FLOAT_BYTES[7];
604
+ destination[offset + 1] = FLOAT_BYTES[6];
605
+ destination[offset + 2] = FLOAT_BYTES[5];
606
+ destination[offset + 3] = FLOAT_BYTES[4];
607
+ destination[offset + 4] = FLOAT_BYTES[3];
608
+ destination[offset + 5] = FLOAT_BYTES[2];
609
+ destination[offset + 6] = FLOAT_BYTES[1];
610
+ destination[offset + 7] = FLOAT_BYTES[0];
611
+ return 8;
612
+ }
613
+ : (destination, offset, value) => {
614
+ FLOAT[0] = value;
615
+ destination[offset] = FLOAT_BYTES[0];
616
+ destination[offset + 1] = FLOAT_BYTES[1];
617
+ destination[offset + 2] = FLOAT_BYTES[2];
618
+ destination[offset + 3] = FLOAT_BYTES[3];
619
+ destination[offset + 4] = FLOAT_BYTES[4];
620
+ destination[offset + 5] = FLOAT_BYTES[5];
621
+ destination[offset + 6] = FLOAT_BYTES[6];
622
+ destination[offset + 7] = FLOAT_BYTES[7];
623
+ return 8;
624
+ }
625
+ };
626
+
462
627
  class Binary extends BSONValue {
463
628
  get _bsontype() {
464
629
  return 'Binary';
@@ -531,7 +696,8 @@ class Binary extends BSONValue {
531
696
  }
532
697
  read(position, length) {
533
698
  length = length && length > 0 ? length : this.position;
534
- return this.buffer.slice(position, position + length);
699
+ const end = position + length;
700
+ return this.buffer.subarray(position, end > this.position ? this.position : end);
535
701
  }
536
702
  value() {
537
703
  return this.buffer.length === this.position
@@ -555,6 +721,9 @@ class Binary extends BSONValue {
555
721
  }
556
722
  toExtendedJSON(options) {
557
723
  options = options || {};
724
+ if (this.sub_type === Binary.SUBTYPE_VECTOR) {
725
+ validateBinaryVector(this);
726
+ }
558
727
  const base64String = ByteUtils.toBase64(this.buffer);
559
728
  const subType = Number(this.sub_type).toString(16);
560
729
  if (options.legacy) {
@@ -572,7 +741,7 @@ class Binary extends BSONValue {
572
741
  }
573
742
  toUUID() {
574
743
  if (this.sub_type === Binary.SUBTYPE_UUID) {
575
- return new UUID(this.buffer.slice(0, this.position));
744
+ return new UUID(this.buffer.subarray(0, this.position));
576
745
  }
577
746
  throw new BSONError(`Binary sub_type "${this.sub_type}" is not supported for converting to UUID. Only "${Binary.SUBTYPE_UUID}" is currently supported.`);
578
747
  }
@@ -614,6 +783,99 @@ class Binary extends BSONValue {
614
783
  const subTypeArg = inspect(this.sub_type, options);
615
784
  return `Binary.createFromBase64(${base64Arg}, ${subTypeArg})`;
616
785
  }
786
+ toInt8Array() {
787
+ if (this.sub_type !== Binary.SUBTYPE_VECTOR) {
788
+ throw new BSONError('Binary sub_type is not Vector');
789
+ }
790
+ if (this.buffer[0] !== Binary.VECTOR_TYPE.Int8) {
791
+ throw new BSONError('Binary datatype field is not Int8');
792
+ }
793
+ return new Int8Array(this.buffer.buffer.slice(this.buffer.byteOffset + 2, this.buffer.byteOffset + this.position));
794
+ }
795
+ toFloat32Array() {
796
+ if (this.sub_type !== Binary.SUBTYPE_VECTOR) {
797
+ throw new BSONError('Binary sub_type is not Vector');
798
+ }
799
+ if (this.buffer[0] !== Binary.VECTOR_TYPE.Float32) {
800
+ throw new BSONError('Binary datatype field is not Float32');
801
+ }
802
+ const floatBytes = new Uint8Array(this.buffer.buffer.slice(this.buffer.byteOffset + 2, this.buffer.byteOffset + this.position));
803
+ if (NumberUtils.isBigEndian)
804
+ ByteUtils.swap32(floatBytes);
805
+ return new Float32Array(floatBytes.buffer);
806
+ }
807
+ toPackedBits() {
808
+ if (this.sub_type !== Binary.SUBTYPE_VECTOR) {
809
+ throw new BSONError('Binary sub_type is not Vector');
810
+ }
811
+ if (this.buffer[0] !== Binary.VECTOR_TYPE.PackedBit) {
812
+ throw new BSONError('Binary datatype field is not packed bit');
813
+ }
814
+ return new Uint8Array(this.buffer.buffer.slice(this.buffer.byteOffset + 2, this.buffer.byteOffset + this.position));
815
+ }
816
+ toBits() {
817
+ if (this.sub_type !== Binary.SUBTYPE_VECTOR) {
818
+ throw new BSONError('Binary sub_type is not Vector');
819
+ }
820
+ if (this.buffer[0] !== Binary.VECTOR_TYPE.PackedBit) {
821
+ throw new BSONError('Binary datatype field is not packed bit');
822
+ }
823
+ const byteCount = this.length() - 2;
824
+ const bitCount = byteCount * 8 - this.buffer[1];
825
+ const bits = new Int8Array(bitCount);
826
+ for (let bitOffset = 0; bitOffset < bits.length; bitOffset++) {
827
+ const byteOffset = (bitOffset / 8) | 0;
828
+ const byte = this.buffer[byteOffset + 2];
829
+ const shift = 7 - (bitOffset % 8);
830
+ const bit = (byte >> shift) & 1;
831
+ bits[bitOffset] = bit;
832
+ }
833
+ return bits;
834
+ }
835
+ static fromInt8Array(array) {
836
+ const buffer = ByteUtils.allocate(array.byteLength + 2);
837
+ buffer[0] = Binary.VECTOR_TYPE.Int8;
838
+ buffer[1] = 0;
839
+ const intBytes = new Uint8Array(array.buffer, array.byteOffset, array.byteLength);
840
+ buffer.set(intBytes, 2);
841
+ return new this(buffer, this.SUBTYPE_VECTOR);
842
+ }
843
+ static fromFloat32Array(array) {
844
+ const binaryBytes = ByteUtils.allocate(array.byteLength + 2);
845
+ binaryBytes[0] = Binary.VECTOR_TYPE.Float32;
846
+ binaryBytes[1] = 0;
847
+ const floatBytes = new Uint8Array(array.buffer, array.byteOffset, array.byteLength);
848
+ binaryBytes.set(floatBytes, 2);
849
+ if (NumberUtils.isBigEndian)
850
+ ByteUtils.swap32(new Uint8Array(binaryBytes.buffer, 2));
851
+ return new this(binaryBytes, this.SUBTYPE_VECTOR);
852
+ }
853
+ static fromPackedBits(array, padding = 0) {
854
+ const buffer = ByteUtils.allocate(array.byteLength + 2);
855
+ buffer[0] = Binary.VECTOR_TYPE.PackedBit;
856
+ buffer[1] = padding;
857
+ buffer.set(array, 2);
858
+ return new this(buffer, this.SUBTYPE_VECTOR);
859
+ }
860
+ static fromBits(bits) {
861
+ const byteLength = (bits.length + 7) >>> 3;
862
+ const bytes = new Uint8Array(byteLength + 2);
863
+ bytes[0] = Binary.VECTOR_TYPE.PackedBit;
864
+ const remainder = bits.length % 8;
865
+ bytes[1] = remainder === 0 ? 0 : 8 - remainder;
866
+ for (let bitOffset = 0; bitOffset < bits.length; bitOffset++) {
867
+ const byteOffset = bitOffset >>> 3;
868
+ const bit = bits[bitOffset];
869
+ if (bit !== 0 && bit !== 1) {
870
+ throw new BSONError(`Invalid bit value at ${bitOffset}: must be 0 or 1, found ${bits[bitOffset]}`);
871
+ }
872
+ if (bit === 0)
873
+ continue;
874
+ const shift = 7 - (bitOffset % 8);
875
+ bytes[byteOffset + 2] |= bit << shift;
876
+ }
877
+ return new this(bytes, Binary.SUBTYPE_VECTOR);
878
+ }
617
879
  }
618
880
  Binary.BSON_BINARY_SUBTYPE_DEFAULT = 0;
619
881
  Binary.BUFFER_SIZE = 256;
@@ -626,7 +888,30 @@ Binary.SUBTYPE_MD5 = 5;
626
888
  Binary.SUBTYPE_ENCRYPTED = 6;
627
889
  Binary.SUBTYPE_COLUMN = 7;
628
890
  Binary.SUBTYPE_SENSITIVE = 8;
891
+ Binary.SUBTYPE_VECTOR = 9;
629
892
  Binary.SUBTYPE_USER_DEFINED = 128;
893
+ Binary.VECTOR_TYPE = Object.freeze({
894
+ Int8: 0x03,
895
+ Float32: 0x27,
896
+ PackedBit: 0x10
897
+ });
898
+ function validateBinaryVector(vector) {
899
+ if (vector.sub_type !== Binary.SUBTYPE_VECTOR)
900
+ return;
901
+ const size = vector.position;
902
+ const datatype = vector.buffer[0];
903
+ const padding = vector.buffer[1];
904
+ if ((datatype === Binary.VECTOR_TYPE.Float32 || datatype === Binary.VECTOR_TYPE.Int8) &&
905
+ padding !== 0) {
906
+ throw new BSONError('Invalid Vector: padding must be zero for int8 and float32 vectors');
907
+ }
908
+ if (datatype === Binary.VECTOR_TYPE.PackedBit && padding !== 0 && size === 2) {
909
+ throw new BSONError('Invalid Vector: padding must be zero for packed bit vectors that are empty');
910
+ }
911
+ if (datatype === Binary.VECTOR_TYPE.PackedBit && padding > 7) {
912
+ throw new BSONError(`Invalid Vector: padding must be a value between 0 and 7. found: ${padding}`);
913
+ }
914
+ }
630
915
  const UUID_BYTE_LENGTH = 16;
631
916
  const UUID_WITHOUT_DASHES = /^[0-9A-F]{32}$/i;
632
917
  const UUID_WITH_DASHES = /^[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}$/i;
@@ -948,7 +1233,7 @@ class Long extends BSONValue {
948
1233
  return Long.MAX_UNSIGNED_VALUE;
949
1234
  }
950
1235
  else {
951
- if (value <= -TWO_PWR_63_DBL)
1236
+ if (value <= -9223372036854776e3)
952
1237
  return Long.MIN_VALUE;
953
1238
  if (value + 1 >= TWO_PWR_63_DBL)
954
1239
  return Long.MAX_VALUE;
@@ -1107,7 +1392,7 @@ class Long extends BSONValue {
1107
1392
  throw new BSONError('division by zero');
1108
1393
  if (wasm) {
1109
1394
  if (!this.unsigned &&
1110
- this.high === -0x80000000 &&
1395
+ this.high === -2147483648 &&
1111
1396
  divisor.low === -1 &&
1112
1397
  divisor.high === -1) {
1113
1398
  return this;
@@ -1628,7 +1913,7 @@ class Decimal128 extends BSONValue {
1628
1913
  if (typeof bytes === 'string') {
1629
1914
  this.bytes = Decimal128.fromString(bytes).bytes;
1630
1915
  }
1631
- else if (isUint8Array(bytes)) {
1916
+ else if (bytes instanceof Uint8Array || isUint8Array(bytes)) {
1632
1917
  if (bytes.byteLength !== 16) {
1633
1918
  throw new BSONError('Decimal128 must take a Buffer of 16 bytes');
1634
1919
  }
@@ -2238,135 +2523,8 @@ class MinKey extends BSONValue {
2238
2523
  }
2239
2524
  }
2240
2525
 
2241
- const FLOAT = new Float64Array(1);
2242
- const FLOAT_BYTES = new Uint8Array(FLOAT.buffer, 0, 8);
2243
- FLOAT[0] = -1;
2244
- const isBigEndian = FLOAT_BYTES[7] === 0;
2245
- const NumberUtils = {
2246
- getNonnegativeInt32LE(source, offset) {
2247
- if (source[offset + 3] > 127) {
2248
- throw new RangeError(`Size cannot be negative at offset: ${offset}`);
2249
- }
2250
- return (source[offset] |
2251
- (source[offset + 1] << 8) |
2252
- (source[offset + 2] << 16) |
2253
- (source[offset + 3] << 24));
2254
- },
2255
- getInt32LE(source, offset) {
2256
- return (source[offset] |
2257
- (source[offset + 1] << 8) |
2258
- (source[offset + 2] << 16) |
2259
- (source[offset + 3] << 24));
2260
- },
2261
- getUint32LE(source, offset) {
2262
- return (source[offset] +
2263
- source[offset + 1] * 256 +
2264
- source[offset + 2] * 65536 +
2265
- source[offset + 3] * 16777216);
2266
- },
2267
- getUint32BE(source, offset) {
2268
- return (source[offset + 3] +
2269
- source[offset + 2] * 256 +
2270
- source[offset + 1] * 65536 +
2271
- source[offset] * 16777216);
2272
- },
2273
- getBigInt64LE(source, offset) {
2274
- const lo = NumberUtils.getUint32LE(source, offset);
2275
- const hi = NumberUtils.getUint32LE(source, offset + 4);
2276
- return (BigInt(hi) << BigInt(32)) + BigInt(lo);
2277
- },
2278
- getFloat64LE: isBigEndian
2279
- ? (source, offset) => {
2280
- FLOAT_BYTES[7] = source[offset];
2281
- FLOAT_BYTES[6] = source[offset + 1];
2282
- FLOAT_BYTES[5] = source[offset + 2];
2283
- FLOAT_BYTES[4] = source[offset + 3];
2284
- FLOAT_BYTES[3] = source[offset + 4];
2285
- FLOAT_BYTES[2] = source[offset + 5];
2286
- FLOAT_BYTES[1] = source[offset + 6];
2287
- FLOAT_BYTES[0] = source[offset + 7];
2288
- return FLOAT[0];
2289
- }
2290
- : (source, offset) => {
2291
- FLOAT_BYTES[0] = source[offset];
2292
- FLOAT_BYTES[1] = source[offset + 1];
2293
- FLOAT_BYTES[2] = source[offset + 2];
2294
- FLOAT_BYTES[3] = source[offset + 3];
2295
- FLOAT_BYTES[4] = source[offset + 4];
2296
- FLOAT_BYTES[5] = source[offset + 5];
2297
- FLOAT_BYTES[6] = source[offset + 6];
2298
- FLOAT_BYTES[7] = source[offset + 7];
2299
- return FLOAT[0];
2300
- },
2301
- setInt32BE(destination, offset, value) {
2302
- destination[offset + 3] = value;
2303
- value >>>= 8;
2304
- destination[offset + 2] = value;
2305
- value >>>= 8;
2306
- destination[offset + 1] = value;
2307
- value >>>= 8;
2308
- destination[offset] = value;
2309
- return 4;
2310
- },
2311
- setInt32LE(destination, offset, value) {
2312
- destination[offset] = value;
2313
- value >>>= 8;
2314
- destination[offset + 1] = value;
2315
- value >>>= 8;
2316
- destination[offset + 2] = value;
2317
- value >>>= 8;
2318
- destination[offset + 3] = value;
2319
- return 4;
2320
- },
2321
- setBigInt64LE(destination, offset, value) {
2322
- const mask32bits = BigInt(4294967295);
2323
- let lo = Number(value & mask32bits);
2324
- destination[offset] = lo;
2325
- lo >>= 8;
2326
- destination[offset + 1] = lo;
2327
- lo >>= 8;
2328
- destination[offset + 2] = lo;
2329
- lo >>= 8;
2330
- destination[offset + 3] = lo;
2331
- let hi = Number((value >> BigInt(32)) & mask32bits);
2332
- destination[offset + 4] = hi;
2333
- hi >>= 8;
2334
- destination[offset + 5] = hi;
2335
- hi >>= 8;
2336
- destination[offset + 6] = hi;
2337
- hi >>= 8;
2338
- destination[offset + 7] = hi;
2339
- return 8;
2340
- },
2341
- setFloat64LE: isBigEndian
2342
- ? (destination, offset, value) => {
2343
- FLOAT[0] = value;
2344
- destination[offset] = FLOAT_BYTES[7];
2345
- destination[offset + 1] = FLOAT_BYTES[6];
2346
- destination[offset + 2] = FLOAT_BYTES[5];
2347
- destination[offset + 3] = FLOAT_BYTES[4];
2348
- destination[offset + 4] = FLOAT_BYTES[3];
2349
- destination[offset + 5] = FLOAT_BYTES[2];
2350
- destination[offset + 6] = FLOAT_BYTES[1];
2351
- destination[offset + 7] = FLOAT_BYTES[0];
2352
- return 8;
2353
- }
2354
- : (destination, offset, value) => {
2355
- FLOAT[0] = value;
2356
- destination[offset] = FLOAT_BYTES[0];
2357
- destination[offset + 1] = FLOAT_BYTES[1];
2358
- destination[offset + 2] = FLOAT_BYTES[2];
2359
- destination[offset + 3] = FLOAT_BYTES[3];
2360
- destination[offset + 4] = FLOAT_BYTES[4];
2361
- destination[offset + 5] = FLOAT_BYTES[5];
2362
- destination[offset + 6] = FLOAT_BYTES[6];
2363
- destination[offset + 7] = FLOAT_BYTES[7];
2364
- return 8;
2365
- }
2366
- };
2367
-
2368
- const checkForHexRegExp = new RegExp('^[0-9a-fA-F]{24}$');
2369
2526
  let PROCESS_UNIQUE = null;
2527
+ const __idCache = new WeakMap();
2370
2528
  class ObjectId extends BSONValue {
2371
2529
  get _bsontype() {
2372
2530
  return 'ObjectId';
@@ -2395,8 +2553,11 @@ class ObjectId extends BSONValue {
2395
2553
  this.buffer = ByteUtils.toLocalBufferType(workingId);
2396
2554
  }
2397
2555
  else if (typeof workingId === 'string') {
2398
- if (workingId.length === 24 && checkForHexRegExp.test(workingId)) {
2556
+ if (ObjectId.validateHexString(workingId)) {
2399
2557
  this.buffer = ByteUtils.fromHex(workingId);
2558
+ if (ObjectId.cacheHexString) {
2559
+ __idCache.set(this, workingId);
2560
+ }
2400
2561
  }
2401
2562
  else {
2402
2563
  throw new BSONError('input must be a 24 character hex string, 12 byte Uint8Array, or an integer');
@@ -2405,9 +2566,6 @@ class ObjectId extends BSONValue {
2405
2566
  else {
2406
2567
  throw new BSONError('Argument passed in does not match the accepted types');
2407
2568
  }
2408
- if (ObjectId.cacheHexString) {
2409
- this.__id = ByteUtils.toHex(this.id);
2410
- }
2411
2569
  }
2412
2570
  get id() {
2413
2571
  return this.buffer;
@@ -2415,16 +2573,32 @@ class ObjectId extends BSONValue {
2415
2573
  set id(value) {
2416
2574
  this.buffer = value;
2417
2575
  if (ObjectId.cacheHexString) {
2418
- this.__id = ByteUtils.toHex(value);
2576
+ __idCache.set(this, ByteUtils.toHex(value));
2577
+ }
2578
+ }
2579
+ static validateHexString(string) {
2580
+ if (string?.length !== 24)
2581
+ return false;
2582
+ for (let i = 0; i < 24; i++) {
2583
+ const char = string.charCodeAt(i);
2584
+ if ((char >= 48 && char <= 57) ||
2585
+ (char >= 97 && char <= 102) ||
2586
+ (char >= 65 && char <= 70)) {
2587
+ continue;
2588
+ }
2589
+ return false;
2419
2590
  }
2591
+ return true;
2420
2592
  }
2421
2593
  toHexString() {
2422
- if (ObjectId.cacheHexString && this.__id) {
2423
- return this.__id;
2594
+ if (ObjectId.cacheHexString) {
2595
+ const __id = __idCache.get(this);
2596
+ if (__id)
2597
+ return __id;
2424
2598
  }
2425
2599
  const hexString = ByteUtils.toHex(this.id);
2426
- if (ObjectId.cacheHexString && !this.__id) {
2427
- this.__id = hexString;
2600
+ if (ObjectId.cacheHexString) {
2601
+ __idCache.set(this, hexString);
2428
2602
  }
2429
2603
  return hexString;
2430
2604
  }
@@ -2530,6 +2704,8 @@ class ObjectId extends BSONValue {
2530
2704
  static isValid(id) {
2531
2705
  if (id == null)
2532
2706
  return false;
2707
+ if (typeof id === 'string')
2708
+ return ObjectId.validateHexString(id);
2533
2709
  try {
2534
2710
  new ObjectId(id);
2535
2711
  return true;
@@ -2546,6 +2722,9 @@ class ObjectId extends BSONValue {
2546
2722
  static fromExtendedJSON(doc) {
2547
2723
  return new ObjectId(doc.$oid);
2548
2724
  }
2725
+ isCached() {
2726
+ return ObjectId.cacheHexString && __idCache.has(this);
2727
+ }
2549
2728
  inspect(depth, options, inspect) {
2550
2729
  inspect ??= defaultInspect;
2551
2730
  return `new ObjectId(${inspect(this.toHexString(), options)})`;
@@ -2600,7 +2779,7 @@ function calculateElement(name, value, serializeFunctions = false, isArray = fal
2600
2779
  case 'object':
2601
2780
  if (value != null &&
2602
2781
  typeof value._bsontype === 'string' &&
2603
- value[Symbol.for('@@mdb.bson.version')] !== BSON_MAJOR_VERSION) {
2782
+ value[BSON_VERSION_SYMBOL] !== BSON_MAJOR_VERSION) {
2604
2783
  throw new BSONVersionError();
2605
2784
  }
2606
2785
  else if (value == null || value._bsontype === 'MinKey' || value._bsontype === 'MaxKey') {
@@ -2703,8 +2882,14 @@ function calculateElement(name, value, serializeFunctions = false, isArray = fal
2703
2882
  ByteUtils.utf8ByteLength(value.toString()) +
2704
2883
  1);
2705
2884
  }
2885
+ return 0;
2886
+ case 'bigint':
2887
+ return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + (8 + 1);
2888
+ case 'symbol':
2889
+ return 0;
2890
+ default:
2891
+ throw new BSONError(`Unrecognized JS type: ${typeof value}`);
2706
2892
  }
2707
- return 0;
2708
2893
  }
2709
2894
 
2710
2895
  function alphabetize(str) {
@@ -2804,6 +2989,12 @@ class Timestamp extends LongWithoutOverridesClass {
2804
2989
  get _bsontype() {
2805
2990
  return 'Timestamp';
2806
2991
  }
2992
+ get i() {
2993
+ return this.low >>> 0;
2994
+ }
2995
+ get t() {
2996
+ return this.high >>> 0;
2997
+ }
2807
2998
  constructor(low) {
2808
2999
  if (low == null) {
2809
3000
  super(0, 0, true);
@@ -2829,10 +3020,10 @@ class Timestamp extends LongWithoutOverridesClass {
2829
3020
  if (i < 0 || Number.isNaN(i)) {
2830
3021
  throw new BSONError('Timestamp constructed from { t, i } must provide a positive i');
2831
3022
  }
2832
- if (t > 4294967295) {
3023
+ if (t > 0xffff_ffff) {
2833
3024
  throw new BSONError('Timestamp constructed from { t, i } must provide t equal or less than uint32 max');
2834
3025
  }
2835
- if (i > 4294967295) {
3026
+ if (i > 0xffff_ffff) {
2836
3027
  throw new BSONError('Timestamp constructed from { t, i } must provide i equal or less than uint32 max');
2837
3028
  }
2838
3029
  super(i, t, true);
@@ -2859,7 +3050,7 @@ class Timestamp extends LongWithoutOverridesClass {
2859
3050
  return new Timestamp(Long.fromString(str, true, optRadix));
2860
3051
  }
2861
3052
  toExtendedJSON() {
2862
- return { $timestamp: { t: this.high >>> 0, i: this.low >>> 0 } };
3053
+ return { $timestamp: { t: this.t, i: this.i } };
2863
3054
  }
2864
3055
  static fromExtendedJSON(doc) {
2865
3056
  const i = Long.isLong(doc.$timestamp.i)
@@ -2872,8 +3063,8 @@ class Timestamp extends LongWithoutOverridesClass {
2872
3063
  }
2873
3064
  inspect(depth, options, inspect) {
2874
3065
  inspect ??= defaultInspect;
2875
- const t = inspect(this.high >>> 0, options);
2876
- const i = inspect(this.low >>> 0, options);
3066
+ const t = inspect(this.t, options);
3067
+ const i = inspect(this.i, options);
2877
3068
  return `new Timestamp({ t: ${t}, i: ${i} })`;
2878
3069
  }
2879
3070
  }
@@ -2956,9 +3147,8 @@ function deserializeObject(buffer, index, options, isArray = false) {
2956
3147
  throw new BSONError('corrupt bson message');
2957
3148
  const object = isArray ? [] : {};
2958
3149
  let arrayIndex = 0;
2959
- const done = false;
2960
3150
  let isPossibleDBRef = isArray ? false : null;
2961
- while (!done) {
3151
+ while (true) {
2962
3152
  const elementType = buffer[index++];
2963
3153
  if (elementType === 0)
2964
3154
  break;
@@ -3030,7 +3220,7 @@ function deserializeObject(buffer, index, options, isArray = false) {
3030
3220
  if (objectSize <= 0 || objectSize > buffer.length - index)
3031
3221
  throw new BSONError('bad embedded document length in bson');
3032
3222
  if (raw) {
3033
- value = buffer.slice(index, index + objectSize);
3223
+ value = buffer.subarray(index, index + objectSize);
3034
3224
  }
3035
3225
  else {
3036
3226
  let objectOptions = options;
@@ -3102,49 +3292,23 @@ function deserializeObject(buffer, index, options, isArray = false) {
3102
3292
  throw new BSONError('Negative binary type element size found');
3103
3293
  if (binarySize > buffer.byteLength)
3104
3294
  throw new BSONError('Binary type size larger than document size');
3105
- if (buffer['slice'] != null) {
3106
- if (subType === Binary.SUBTYPE_BYTE_ARRAY) {
3107
- binarySize = NumberUtils.getInt32LE(buffer, index);
3108
- index += 4;
3109
- if (binarySize < 0)
3110
- throw new BSONError('Negative binary type element size found for subtype 0x02');
3111
- if (binarySize > totalBinarySize - 4)
3112
- throw new BSONError('Binary type with subtype 0x02 contains too long binary size');
3113
- if (binarySize < totalBinarySize - 4)
3114
- throw new BSONError('Binary type with subtype 0x02 contains too short binary size');
3115
- }
3116
- if (promoteBuffers && promoteValues) {
3117
- value = ByteUtils.toLocalBufferType(buffer.slice(index, index + binarySize));
3118
- }
3119
- else {
3120
- value = new Binary(buffer.slice(index, index + binarySize), subType);
3121
- if (subType === BSON_BINARY_SUBTYPE_UUID_NEW && UUID.isValid(value)) {
3122
- value = value.toUUID();
3123
- }
3124
- }
3295
+ if (subType === Binary.SUBTYPE_BYTE_ARRAY) {
3296
+ binarySize = NumberUtils.getInt32LE(buffer, index);
3297
+ index += 4;
3298
+ if (binarySize < 0)
3299
+ throw new BSONError('Negative binary type element size found for subtype 0x02');
3300
+ if (binarySize > totalBinarySize - 4)
3301
+ throw new BSONError('Binary type with subtype 0x02 contains too long binary size');
3302
+ if (binarySize < totalBinarySize - 4)
3303
+ throw new BSONError('Binary type with subtype 0x02 contains too short binary size');
3304
+ }
3305
+ if (promoteBuffers && promoteValues) {
3306
+ value = ByteUtils.toLocalBufferType(buffer.subarray(index, index + binarySize));
3125
3307
  }
3126
3308
  else {
3127
- if (subType === Binary.SUBTYPE_BYTE_ARRAY) {
3128
- binarySize = NumberUtils.getInt32LE(buffer, index);
3129
- index += 4;
3130
- if (binarySize < 0)
3131
- throw new BSONError('Negative binary type element size found for subtype 0x02');
3132
- if (binarySize > totalBinarySize - 4)
3133
- throw new BSONError('Binary type with subtype 0x02 contains too long binary size');
3134
- if (binarySize < totalBinarySize - 4)
3135
- throw new BSONError('Binary type with subtype 0x02 contains too short binary size');
3136
- }
3137
- if (promoteBuffers && promoteValues) {
3138
- value = ByteUtils.allocateUnsafe(binarySize);
3139
- for (i = 0; i < binarySize; i++) {
3140
- value[i] = buffer[index + i];
3141
- }
3142
- }
3143
- else {
3144
- value = new Binary(buffer.slice(index, index + binarySize), subType);
3145
- if (subType === BSON_BINARY_SUBTYPE_UUID_NEW && UUID.isValid(value)) {
3146
- value = value.toUUID();
3147
- }
3309
+ value = new Binary(buffer.subarray(index, index + binarySize), subType);
3310
+ if (subType === BSON_BINARY_SUBTYPE_UUID_NEW && UUID.isValid(value)) {
3311
+ value = value.toUUID();
3148
3312
  }
3149
3313
  }
3150
3314
  index = index + binarySize;
@@ -3566,6 +3730,9 @@ function serializeBinary(buffer, key, value, index) {
3566
3730
  size = size - 4;
3567
3731
  index += NumberUtils.setInt32LE(buffer, index, size);
3568
3732
  }
3733
+ if (value.sub_type === Binary.SUBTYPE_VECTOR) {
3734
+ validateBinaryVector(value);
3735
+ }
3569
3736
  if (size <= 16) {
3570
3737
  for (let i = 0; i < size; i++)
3571
3738
  buffer[index + i] = data[i];
@@ -3642,79 +3809,83 @@ function serializeInto(buffer, object, checkKeys, startingIndex, depth, serializ
3642
3809
  if (typeof value?.toBSON === 'function') {
3643
3810
  value = value.toBSON();
3644
3811
  }
3645
- if (typeof value === 'string') {
3646
- index = serializeString(buffer, key, value, index);
3647
- }
3648
- else if (typeof value === 'number') {
3649
- index = serializeNumber(buffer, key, value, index);
3650
- }
3651
- else if (typeof value === 'bigint') {
3652
- index = serializeBigInt(buffer, key, value, index);
3653
- }
3654
- else if (typeof value === 'boolean') {
3655
- index = serializeBoolean(buffer, key, value, index);
3656
- }
3657
- else if (value instanceof Date || isDate(value)) {
3658
- index = serializeDate(buffer, key, value, index);
3659
- }
3660
- else if (value === undefined) {
3812
+ const type = typeof value;
3813
+ if (value === undefined) {
3661
3814
  index = serializeNull(buffer, key, value, index);
3662
3815
  }
3663
3816
  else if (value === null) {
3664
3817
  index = serializeNull(buffer, key, value, index);
3665
3818
  }
3666
- else if (isUint8Array(value)) {
3667
- index = serializeBuffer(buffer, key, value, index);
3668
- }
3669
- else if (value instanceof RegExp || isRegExp(value)) {
3670
- index = serializeRegExp(buffer, key, value, index);
3671
- }
3672
- else if (typeof value === 'object' && value._bsontype == null) {
3673
- index = serializeObject(buffer, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, path);
3819
+ else if (type === 'string') {
3820
+ index = serializeString(buffer, key, value, index);
3674
3821
  }
3675
- else if (typeof value === 'object' &&
3676
- value[Symbol.for('@@mdb.bson.version')] !== BSON_MAJOR_VERSION) {
3677
- throw new BSONVersionError();
3822
+ else if (type === 'number') {
3823
+ index = serializeNumber(buffer, key, value, index);
3678
3824
  }
3679
- else if (value._bsontype === 'ObjectId') {
3680
- index = serializeObjectId(buffer, key, value, index);
3825
+ else if (type === 'bigint') {
3826
+ index = serializeBigInt(buffer, key, value, index);
3681
3827
  }
3682
- else if (value._bsontype === 'Decimal128') {
3683
- index = serializeDecimal128(buffer, key, value, index);
3828
+ else if (type === 'boolean') {
3829
+ index = serializeBoolean(buffer, key, value, index);
3684
3830
  }
3685
- else if (value._bsontype === 'Long' || value._bsontype === 'Timestamp') {
3686
- index = serializeLong(buffer, key, value, index);
3831
+ else if (type === 'object' && value._bsontype == null) {
3832
+ if (value instanceof Date || isDate(value)) {
3833
+ index = serializeDate(buffer, key, value, index);
3834
+ }
3835
+ else if (value instanceof Uint8Array || isUint8Array(value)) {
3836
+ index = serializeBuffer(buffer, key, value, index);
3837
+ }
3838
+ else if (value instanceof RegExp || isRegExp(value)) {
3839
+ index = serializeRegExp(buffer, key, value, index);
3840
+ }
3841
+ else {
3842
+ index = serializeObject(buffer, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, path);
3843
+ }
3687
3844
  }
3688
- else if (value._bsontype === 'Double') {
3689
- index = serializeDouble(buffer, key, value, index);
3845
+ else if (type === 'object') {
3846
+ if (value[BSON_VERSION_SYMBOL] !== BSON_MAJOR_VERSION) {
3847
+ throw new BSONVersionError();
3848
+ }
3849
+ else if (value._bsontype === 'ObjectId') {
3850
+ index = serializeObjectId(buffer, key, value, index);
3851
+ }
3852
+ else if (value._bsontype === 'Decimal128') {
3853
+ index = serializeDecimal128(buffer, key, value, index);
3854
+ }
3855
+ else if (value._bsontype === 'Long' || value._bsontype === 'Timestamp') {
3856
+ index = serializeLong(buffer, key, value, index);
3857
+ }
3858
+ else if (value._bsontype === 'Double') {
3859
+ index = serializeDouble(buffer, key, value, index);
3860
+ }
3861
+ else if (value._bsontype === 'Code') {
3862
+ index = serializeCode(buffer, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, path);
3863
+ }
3864
+ else if (value._bsontype === 'Binary') {
3865
+ index = serializeBinary(buffer, key, value, index);
3866
+ }
3867
+ else if (value._bsontype === 'BSONSymbol') {
3868
+ index = serializeSymbol(buffer, key, value, index);
3869
+ }
3870
+ else if (value._bsontype === 'DBRef') {
3871
+ index = serializeDBRef(buffer, key, value, index, depth, serializeFunctions, path);
3872
+ }
3873
+ else if (value._bsontype === 'BSONRegExp') {
3874
+ index = serializeBSONRegExp(buffer, key, value, index);
3875
+ }
3876
+ else if (value._bsontype === 'Int32') {
3877
+ index = serializeInt32(buffer, key, value, index);
3878
+ }
3879
+ else if (value._bsontype === 'MinKey' || value._bsontype === 'MaxKey') {
3880
+ index = serializeMinMax(buffer, key, value, index);
3881
+ }
3882
+ else if (typeof value._bsontype !== 'undefined') {
3883
+ throw new BSONError(`Unrecognized or invalid _bsontype: ${String(value._bsontype)}`);
3884
+ }
3690
3885
  }
3691
- else if (typeof value === 'function' && serializeFunctions) {
3886
+ else if (type === 'function' && serializeFunctions) {
3692
3887
  index = serializeFunction(buffer, key, value, index);
3693
3888
  }
3694
- else if (value._bsontype === 'Code') {
3695
- index = serializeCode(buffer, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, path);
3696
- }
3697
- else if (value._bsontype === 'Binary') {
3698
- index = serializeBinary(buffer, key, value, index);
3699
- }
3700
- else if (value._bsontype === 'BSONSymbol') {
3701
- index = serializeSymbol(buffer, key, value, index);
3702
- }
3703
- else if (value._bsontype === 'DBRef') {
3704
- index = serializeDBRef(buffer, key, value, index, depth, serializeFunctions, path);
3705
- }
3706
- else if (value._bsontype === 'BSONRegExp') {
3707
- index = serializeBSONRegExp(buffer, key, value, index);
3708
- }
3709
- else if (value._bsontype === 'Int32') {
3710
- index = serializeInt32(buffer, key, value, index);
3711
- }
3712
- else if (value._bsontype === 'MinKey' || value._bsontype === 'MaxKey') {
3713
- index = serializeMinMax(buffer, key, value, index);
3714
- }
3715
- else if (typeof value._bsontype !== 'undefined') {
3716
- throw new BSONError(`Unrecognized or invalid _bsontype: ${String(value._bsontype)}`);
3717
- }
3718
3889
  }
3719
3890
  }
3720
3891
  else if (object instanceof Map || isMap(object)) {
@@ -3725,8 +3896,8 @@ function serializeInto(buffer, object, checkKeys, startingIndex, depth, serializ
3725
3896
  done = !!entry.done;
3726
3897
  if (done)
3727
3898
  continue;
3728
- const key = entry.value[0];
3729
- let value = entry.value[1];
3899
+ const key = entry.value ? entry.value[0] : undefined;
3900
+ let value = entry.value ? entry.value[1] : undefined;
3730
3901
  if (typeof value?.toBSON === 'function') {
3731
3902
  value = value.toBSON();
3732
3903
  }
@@ -3744,7 +3915,14 @@ function serializeInto(buffer, object, checkKeys, startingIndex, depth, serializ
3744
3915
  }
3745
3916
  }
3746
3917
  }
3747
- if (type === 'string') {
3918
+ if (value === undefined) {
3919
+ if (ignoreUndefined === false)
3920
+ index = serializeNull(buffer, key, value, index);
3921
+ }
3922
+ else if (value === null) {
3923
+ index = serializeNull(buffer, key, value, index);
3924
+ }
3925
+ else if (type === 'string') {
3748
3926
  index = serializeString(buffer, key, value, index);
3749
3927
  }
3750
3928
  else if (type === 'number') {
@@ -3756,64 +3934,64 @@ function serializeInto(buffer, object, checkKeys, startingIndex, depth, serializ
3756
3934
  else if (type === 'boolean') {
3757
3935
  index = serializeBoolean(buffer, key, value, index);
3758
3936
  }
3759
- else if (value instanceof Date || isDate(value)) {
3760
- index = serializeDate(buffer, key, value, index);
3761
- }
3762
- else if (value === null || (value === undefined && ignoreUndefined === false)) {
3763
- index = serializeNull(buffer, key, value, index);
3764
- }
3765
- else if (isUint8Array(value)) {
3766
- index = serializeBuffer(buffer, key, value, index);
3767
- }
3768
- else if (value instanceof RegExp || isRegExp(value)) {
3769
- index = serializeRegExp(buffer, key, value, index);
3770
- }
3771
3937
  else if (type === 'object' && value._bsontype == null) {
3772
- index = serializeObject(buffer, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, path);
3773
- }
3774
- else if (typeof value === 'object' &&
3775
- value[Symbol.for('@@mdb.bson.version')] !== BSON_MAJOR_VERSION) {
3776
- throw new BSONVersionError();
3777
- }
3778
- else if (value._bsontype === 'ObjectId') {
3779
- index = serializeObjectId(buffer, key, value, index);
3780
- }
3781
- else if (type === 'object' && value._bsontype === 'Decimal128') {
3782
- index = serializeDecimal128(buffer, key, value, index);
3783
- }
3784
- else if (value._bsontype === 'Long' || value._bsontype === 'Timestamp') {
3785
- index = serializeLong(buffer, key, value, index);
3786
- }
3787
- else if (value._bsontype === 'Double') {
3788
- index = serializeDouble(buffer, key, value, index);
3938
+ if (value instanceof Date || isDate(value)) {
3939
+ index = serializeDate(buffer, key, value, index);
3940
+ }
3941
+ else if (value instanceof Uint8Array || isUint8Array(value)) {
3942
+ index = serializeBuffer(buffer, key, value, index);
3943
+ }
3944
+ else if (value instanceof RegExp || isRegExp(value)) {
3945
+ index = serializeRegExp(buffer, key, value, index);
3946
+ }
3947
+ else {
3948
+ index = serializeObject(buffer, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, path);
3949
+ }
3789
3950
  }
3790
- else if (value._bsontype === 'Code') {
3791
- index = serializeCode(buffer, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, path);
3951
+ else if (type === 'object') {
3952
+ if (value[BSON_VERSION_SYMBOL] !== BSON_MAJOR_VERSION) {
3953
+ throw new BSONVersionError();
3954
+ }
3955
+ else if (value._bsontype === 'ObjectId') {
3956
+ index = serializeObjectId(buffer, key, value, index);
3957
+ }
3958
+ else if (value._bsontype === 'Decimal128') {
3959
+ index = serializeDecimal128(buffer, key, value, index);
3960
+ }
3961
+ else if (value._bsontype === 'Long' || value._bsontype === 'Timestamp') {
3962
+ index = serializeLong(buffer, key, value, index);
3963
+ }
3964
+ else if (value._bsontype === 'Double') {
3965
+ index = serializeDouble(buffer, key, value, index);
3966
+ }
3967
+ else if (value._bsontype === 'Code') {
3968
+ index = serializeCode(buffer, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, path);
3969
+ }
3970
+ else if (value._bsontype === 'Binary') {
3971
+ index = serializeBinary(buffer, key, value, index);
3972
+ }
3973
+ else if (value._bsontype === 'BSONSymbol') {
3974
+ index = serializeSymbol(buffer, key, value, index);
3975
+ }
3976
+ else if (value._bsontype === 'DBRef') {
3977
+ index = serializeDBRef(buffer, key, value, index, depth, serializeFunctions, path);
3978
+ }
3979
+ else if (value._bsontype === 'BSONRegExp') {
3980
+ index = serializeBSONRegExp(buffer, key, value, index);
3981
+ }
3982
+ else if (value._bsontype === 'Int32') {
3983
+ index = serializeInt32(buffer, key, value, index);
3984
+ }
3985
+ else if (value._bsontype === 'MinKey' || value._bsontype === 'MaxKey') {
3986
+ index = serializeMinMax(buffer, key, value, index);
3987
+ }
3988
+ else if (typeof value._bsontype !== 'undefined') {
3989
+ throw new BSONError(`Unrecognized or invalid _bsontype: ${String(value._bsontype)}`);
3990
+ }
3792
3991
  }
3793
- else if (typeof value === 'function' && serializeFunctions) {
3992
+ else if (type === 'function' && serializeFunctions) {
3794
3993
  index = serializeFunction(buffer, key, value, index);
3795
3994
  }
3796
- else if (value._bsontype === 'Binary') {
3797
- index = serializeBinary(buffer, key, value, index);
3798
- }
3799
- else if (value._bsontype === 'BSONSymbol') {
3800
- index = serializeSymbol(buffer, key, value, index);
3801
- }
3802
- else if (value._bsontype === 'DBRef') {
3803
- index = serializeDBRef(buffer, key, value, index, depth, serializeFunctions, path);
3804
- }
3805
- else if (value._bsontype === 'BSONRegExp') {
3806
- index = serializeBSONRegExp(buffer, key, value, index);
3807
- }
3808
- else if (value._bsontype === 'Int32') {
3809
- index = serializeInt32(buffer, key, value, index);
3810
- }
3811
- else if (value._bsontype === 'MinKey' || value._bsontype === 'MaxKey') {
3812
- index = serializeMinMax(buffer, key, value, index);
3813
- }
3814
- else if (typeof value._bsontype !== 'undefined') {
3815
- throw new BSONError(`Unrecognized or invalid _bsontype: ${String(value._bsontype)}`);
3816
- }
3817
3995
  }
3818
3996
  }
3819
3997
  else {
@@ -3842,7 +4020,14 @@ function serializeInto(buffer, object, checkKeys, startingIndex, depth, serializ
3842
4020
  }
3843
4021
  }
3844
4022
  }
3845
- if (type === 'string') {
4023
+ if (value === undefined) {
4024
+ if (ignoreUndefined === false)
4025
+ index = serializeNull(buffer, key, value, index);
4026
+ }
4027
+ else if (value === null) {
4028
+ index = serializeNull(buffer, key, value, index);
4029
+ }
4030
+ else if (type === 'string') {
3846
4031
  index = serializeString(buffer, key, value, index);
3847
4032
  }
3848
4033
  else if (type === 'number') {
@@ -3854,68 +4039,64 @@ function serializeInto(buffer, object, checkKeys, startingIndex, depth, serializ
3854
4039
  else if (type === 'boolean') {
3855
4040
  index = serializeBoolean(buffer, key, value, index);
3856
4041
  }
3857
- else if (value instanceof Date || isDate(value)) {
3858
- index = serializeDate(buffer, key, value, index);
3859
- }
3860
- else if (value === undefined) {
3861
- if (ignoreUndefined === false)
3862
- index = serializeNull(buffer, key, value, index);
3863
- }
3864
- else if (value === null) {
3865
- index = serializeNull(buffer, key, value, index);
3866
- }
3867
- else if (isUint8Array(value)) {
3868
- index = serializeBuffer(buffer, key, value, index);
3869
- }
3870
- else if (value instanceof RegExp || isRegExp(value)) {
3871
- index = serializeRegExp(buffer, key, value, index);
3872
- }
3873
4042
  else if (type === 'object' && value._bsontype == null) {
3874
- index = serializeObject(buffer, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, path);
3875
- }
3876
- else if (typeof value === 'object' &&
3877
- value[Symbol.for('@@mdb.bson.version')] !== BSON_MAJOR_VERSION) {
3878
- throw new BSONVersionError();
3879
- }
3880
- else if (value._bsontype === 'ObjectId') {
3881
- index = serializeObjectId(buffer, key, value, index);
3882
- }
3883
- else if (type === 'object' && value._bsontype === 'Decimal128') {
3884
- index = serializeDecimal128(buffer, key, value, index);
3885
- }
3886
- else if (value._bsontype === 'Long' || value._bsontype === 'Timestamp') {
3887
- index = serializeLong(buffer, key, value, index);
3888
- }
3889
- else if (value._bsontype === 'Double') {
3890
- index = serializeDouble(buffer, key, value, index);
4043
+ if (value instanceof Date || isDate(value)) {
4044
+ index = serializeDate(buffer, key, value, index);
4045
+ }
4046
+ else if (value instanceof Uint8Array || isUint8Array(value)) {
4047
+ index = serializeBuffer(buffer, key, value, index);
4048
+ }
4049
+ else if (value instanceof RegExp || isRegExp(value)) {
4050
+ index = serializeRegExp(buffer, key, value, index);
4051
+ }
4052
+ else {
4053
+ index = serializeObject(buffer, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, path);
4054
+ }
3891
4055
  }
3892
- else if (value._bsontype === 'Code') {
3893
- index = serializeCode(buffer, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, path);
4056
+ else if (type === 'object') {
4057
+ if (value[BSON_VERSION_SYMBOL] !== BSON_MAJOR_VERSION) {
4058
+ throw new BSONVersionError();
4059
+ }
4060
+ else if (value._bsontype === 'ObjectId') {
4061
+ index = serializeObjectId(buffer, key, value, index);
4062
+ }
4063
+ else if (value._bsontype === 'Decimal128') {
4064
+ index = serializeDecimal128(buffer, key, value, index);
4065
+ }
4066
+ else if (value._bsontype === 'Long' || value._bsontype === 'Timestamp') {
4067
+ index = serializeLong(buffer, key, value, index);
4068
+ }
4069
+ else if (value._bsontype === 'Double') {
4070
+ index = serializeDouble(buffer, key, value, index);
4071
+ }
4072
+ else if (value._bsontype === 'Code') {
4073
+ index = serializeCode(buffer, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, path);
4074
+ }
4075
+ else if (value._bsontype === 'Binary') {
4076
+ index = serializeBinary(buffer, key, value, index);
4077
+ }
4078
+ else if (value._bsontype === 'BSONSymbol') {
4079
+ index = serializeSymbol(buffer, key, value, index);
4080
+ }
4081
+ else if (value._bsontype === 'DBRef') {
4082
+ index = serializeDBRef(buffer, key, value, index, depth, serializeFunctions, path);
4083
+ }
4084
+ else if (value._bsontype === 'BSONRegExp') {
4085
+ index = serializeBSONRegExp(buffer, key, value, index);
4086
+ }
4087
+ else if (value._bsontype === 'Int32') {
4088
+ index = serializeInt32(buffer, key, value, index);
4089
+ }
4090
+ else if (value._bsontype === 'MinKey' || value._bsontype === 'MaxKey') {
4091
+ index = serializeMinMax(buffer, key, value, index);
4092
+ }
4093
+ else if (typeof value._bsontype !== 'undefined') {
4094
+ throw new BSONError(`Unrecognized or invalid _bsontype: ${String(value._bsontype)}`);
4095
+ }
3894
4096
  }
3895
- else if (typeof value === 'function' && serializeFunctions) {
4097
+ else if (type === 'function' && serializeFunctions) {
3896
4098
  index = serializeFunction(buffer, key, value, index);
3897
4099
  }
3898
- else if (value._bsontype === 'Binary') {
3899
- index = serializeBinary(buffer, key, value, index);
3900
- }
3901
- else if (value._bsontype === 'BSONSymbol') {
3902
- index = serializeSymbol(buffer, key, value, index);
3903
- }
3904
- else if (value._bsontype === 'DBRef') {
3905
- index = serializeDBRef(buffer, key, value, index, depth, serializeFunctions, path);
3906
- }
3907
- else if (value._bsontype === 'BSONRegExp') {
3908
- index = serializeBSONRegExp(buffer, key, value, index);
3909
- }
3910
- else if (value._bsontype === 'Int32') {
3911
- index = serializeInt32(buffer, key, value, index);
3912
- }
3913
- else if (value._bsontype === 'MinKey' || value._bsontype === 'MaxKey') {
3914
- index = serializeMinMax(buffer, key, value, index);
3915
- }
3916
- else if (typeof value._bsontype !== 'undefined') {
3917
- throw new BSONError(`Unrecognized or invalid _bsontype: ${String(value._bsontype)}`);
3918
- }
3919
4100
  }
3920
4101
  }
3921
4102
  path.delete(object);
@@ -4167,7 +4348,7 @@ function serializeDocument(doc, options) {
4167
4348
  else if (doc != null &&
4168
4349
  typeof doc === 'object' &&
4169
4350
  typeof doc._bsontype === 'string' &&
4170
- doc[Symbol.for('@@mdb.bson.version')] !== BSON_MAJOR_VERSION) {
4351
+ doc[BSON_VERSION_SYMBOL] !== BSON_MAJOR_VERSION) {
4171
4352
  throw new BSONVersionError();
4172
4353
  }
4173
4354
  else if (isBSONType(doc)) {