bson 6.9.0 → 6.10.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/bson.cjs CHANGED
@@ -1,45 +1,30 @@
1
1
  'use strict';
2
2
 
3
- const map = new WeakMap();
4
- const TYPES = {
5
- ArrayBuffer: '[object ArrayBuffer]',
6
- SharedArrayBuffer: '[object SharedArrayBuffer]',
7
- Uint8Array: '[object Uint8Array]',
8
- BigInt64Array: '[object BigInt64Array]',
9
- BigUint64Array: '[object BigUint64Array]',
10
- RegExp: '[object RegExp]',
11
- Map: '[object Map]',
12
- Date: '[object Date]'
13
- };
14
- function getPrototypeString(value) {
15
- let str = map.get(value);
16
- if (!str) {
17
- str = Object.prototype.toString.call(value);
18
- if (value !== null && typeof value === 'object') {
19
- map.set(value, str);
20
- }
21
- }
22
- return str;
3
+ const TypedArrayPrototypeGetSymbolToStringTag = (() => {
4
+ const g = Object.getOwnPropertyDescriptor(Object.getPrototypeOf(Uint8Array.prototype), Symbol.toStringTag).get;
5
+ return (value) => g.call(value);
6
+ })();
7
+ function isUint8Array(value) {
8
+ return TypedArrayPrototypeGetSymbolToStringTag(value) === 'Uint8Array';
23
9
  }
24
10
  function isAnyArrayBuffer(value) {
25
- const type = getPrototypeString(value);
26
- return type === TYPES.ArrayBuffer || type === TYPES.SharedArrayBuffer;
11
+ return (typeof value === 'object' &&
12
+ value != null &&
13
+ Symbol.toStringTag in value &&
14
+ (value[Symbol.toStringTag] === 'ArrayBuffer' ||
15
+ value[Symbol.toStringTag] === 'SharedArrayBuffer'));
27
16
  }
28
- function isUint8Array(value) {
29
- const type = getPrototypeString(value);
30
- return type === TYPES.Uint8Array;
31
- }
32
- function isRegExp(d) {
33
- const type = getPrototypeString(d);
34
- return type === TYPES.RegExp;
17
+ function isRegExp(regexp) {
18
+ return regexp instanceof RegExp || Object.prototype.toString.call(regexp) === '[object RegExp]';
35
19
  }
36
- function isMap(d) {
37
- const type = getPrototypeString(d);
38
- return type === TYPES.Map;
20
+ function isMap(value) {
21
+ return (typeof value === 'object' &&
22
+ value != null &&
23
+ Symbol.toStringTag in value &&
24
+ value[Symbol.toStringTag] === 'Map');
39
25
  }
40
- function isDate(d) {
41
- const type = getPrototypeString(d);
42
- return type === TYPES.Date;
26
+ function isDate(date) {
27
+ return date instanceof Date || Object.prototype.toString.call(date) === '[object Date]';
43
28
  }
44
29
  function defaultInspect(x, _options) {
45
30
  return JSON.stringify(x, (k, v) => {
@@ -256,7 +241,7 @@ const nodeJsByteUtils = {
256
241
  stringTag === '[object SharedArrayBuffer]') {
257
242
  return Buffer.from(potentialBuffer);
258
243
  }
259
- throw new BSONError(`Cannot create Buffer from ${String(potentialBuffer)}`);
244
+ throw new BSONError(`Cannot create Buffer from the passed potentialBuffer.`);
260
245
  },
261
246
  allocate(size) {
262
247
  return Buffer.alloc(size);
@@ -314,7 +299,10 @@ const nodeJsByteUtils = {
314
299
  }
315
300
  return nodeJsByteUtils.toLocalBufferType(buffer).write(source, byteOffset, undefined, 'utf8');
316
301
  },
317
- randomBytes: nodejsRandomBytes
302
+ randomBytes: nodejsRandomBytes,
303
+ swap32(buffer) {
304
+ return nodeJsByteUtils.toLocalBufferType(buffer).swap32();
305
+ }
318
306
  };
319
307
 
320
308
  function isReactNative() {
@@ -359,7 +347,7 @@ const webByteUtils = {
359
347
  stringTag === '[object SharedArrayBuffer]') {
360
348
  return new Uint8Array(potentialUint8array);
361
349
  }
362
- throw new BSONError(`Cannot make a Uint8Array from ${String(potentialUint8array)}`);
350
+ throw new BSONError(`Cannot make a Uint8Array from passed potentialBuffer.`);
363
351
  },
364
352
  allocate(size) {
365
353
  if (typeof size !== 'number') {
@@ -431,7 +419,23 @@ const webByteUtils = {
431
419
  uint8array.set(bytes, byteOffset);
432
420
  return bytes.byteLength;
433
421
  },
434
- randomBytes: webRandomBytes
422
+ randomBytes: webRandomBytes,
423
+ swap32(buffer) {
424
+ if (buffer.length % 4 !== 0) {
425
+ throw new RangeError('Buffer size must be a multiple of 32-bits');
426
+ }
427
+ for (let i = 0; i < buffer.length; i += 4) {
428
+ const byte0 = buffer[i];
429
+ const byte1 = buffer[i + 1];
430
+ const byte2 = buffer[i + 2];
431
+ const byte3 = buffer[i + 3];
432
+ buffer[i] = byte3;
433
+ buffer[i + 1] = byte2;
434
+ buffer[i + 2] = byte1;
435
+ buffer[i + 3] = byte0;
436
+ }
437
+ return buffer;
438
+ }
435
439
  };
436
440
 
437
441
  const hasGlobalBuffer = typeof Buffer === 'function' && Buffer.prototype?._isBuffer !== true;
@@ -446,6 +450,134 @@ class BSONValue {
446
450
  }
447
451
  }
448
452
 
453
+ const FLOAT = new Float64Array(1);
454
+ const FLOAT_BYTES = new Uint8Array(FLOAT.buffer, 0, 8);
455
+ FLOAT[0] = -1;
456
+ const isBigEndian = FLOAT_BYTES[7] === 0;
457
+ const NumberUtils = {
458
+ isBigEndian,
459
+ getNonnegativeInt32LE(source, offset) {
460
+ if (source[offset + 3] > 127) {
461
+ throw new RangeError(`Size cannot be negative at offset: ${offset}`);
462
+ }
463
+ return (source[offset] |
464
+ (source[offset + 1] << 8) |
465
+ (source[offset + 2] << 16) |
466
+ (source[offset + 3] << 24));
467
+ },
468
+ getInt32LE(source, offset) {
469
+ return (source[offset] |
470
+ (source[offset + 1] << 8) |
471
+ (source[offset + 2] << 16) |
472
+ (source[offset + 3] << 24));
473
+ },
474
+ getUint32LE(source, offset) {
475
+ return (source[offset] +
476
+ source[offset + 1] * 256 +
477
+ source[offset + 2] * 65536 +
478
+ source[offset + 3] * 16777216);
479
+ },
480
+ getUint32BE(source, offset) {
481
+ return (source[offset + 3] +
482
+ source[offset + 2] * 256 +
483
+ source[offset + 1] * 65536 +
484
+ source[offset] * 16777216);
485
+ },
486
+ getBigInt64LE(source, offset) {
487
+ const lo = NumberUtils.getUint32LE(source, offset);
488
+ const hi = NumberUtils.getUint32LE(source, offset + 4);
489
+ return (BigInt(hi) << BigInt(32)) + BigInt(lo);
490
+ },
491
+ getFloat64LE: isBigEndian
492
+ ? (source, offset) => {
493
+ FLOAT_BYTES[7] = source[offset];
494
+ FLOAT_BYTES[6] = source[offset + 1];
495
+ FLOAT_BYTES[5] = source[offset + 2];
496
+ FLOAT_BYTES[4] = source[offset + 3];
497
+ FLOAT_BYTES[3] = source[offset + 4];
498
+ FLOAT_BYTES[2] = source[offset + 5];
499
+ FLOAT_BYTES[1] = source[offset + 6];
500
+ FLOAT_BYTES[0] = source[offset + 7];
501
+ return FLOAT[0];
502
+ }
503
+ : (source, offset) => {
504
+ FLOAT_BYTES[0] = source[offset];
505
+ FLOAT_BYTES[1] = source[offset + 1];
506
+ FLOAT_BYTES[2] = source[offset + 2];
507
+ FLOAT_BYTES[3] = source[offset + 3];
508
+ FLOAT_BYTES[4] = source[offset + 4];
509
+ FLOAT_BYTES[5] = source[offset + 5];
510
+ FLOAT_BYTES[6] = source[offset + 6];
511
+ FLOAT_BYTES[7] = source[offset + 7];
512
+ return FLOAT[0];
513
+ },
514
+ setInt32BE(destination, offset, value) {
515
+ destination[offset + 3] = value;
516
+ value >>>= 8;
517
+ destination[offset + 2] = value;
518
+ value >>>= 8;
519
+ destination[offset + 1] = value;
520
+ value >>>= 8;
521
+ destination[offset] = value;
522
+ return 4;
523
+ },
524
+ setInt32LE(destination, offset, value) {
525
+ destination[offset] = value;
526
+ value >>>= 8;
527
+ destination[offset + 1] = value;
528
+ value >>>= 8;
529
+ destination[offset + 2] = value;
530
+ value >>>= 8;
531
+ destination[offset + 3] = value;
532
+ return 4;
533
+ },
534
+ setBigInt64LE(destination, offset, value) {
535
+ const mask32bits = BigInt(0xffff_ffff);
536
+ let lo = Number(value & mask32bits);
537
+ destination[offset] = lo;
538
+ lo >>= 8;
539
+ destination[offset + 1] = lo;
540
+ lo >>= 8;
541
+ destination[offset + 2] = lo;
542
+ lo >>= 8;
543
+ destination[offset + 3] = lo;
544
+ let hi = Number((value >> BigInt(32)) & mask32bits);
545
+ destination[offset + 4] = hi;
546
+ hi >>= 8;
547
+ destination[offset + 5] = hi;
548
+ hi >>= 8;
549
+ destination[offset + 6] = hi;
550
+ hi >>= 8;
551
+ destination[offset + 7] = hi;
552
+ return 8;
553
+ },
554
+ setFloat64LE: isBigEndian
555
+ ? (destination, offset, value) => {
556
+ FLOAT[0] = value;
557
+ destination[offset] = FLOAT_BYTES[7];
558
+ destination[offset + 1] = FLOAT_BYTES[6];
559
+ destination[offset + 2] = FLOAT_BYTES[5];
560
+ destination[offset + 3] = FLOAT_BYTES[4];
561
+ destination[offset + 4] = FLOAT_BYTES[3];
562
+ destination[offset + 5] = FLOAT_BYTES[2];
563
+ destination[offset + 6] = FLOAT_BYTES[1];
564
+ destination[offset + 7] = FLOAT_BYTES[0];
565
+ return 8;
566
+ }
567
+ : (destination, offset, value) => {
568
+ FLOAT[0] = value;
569
+ destination[offset] = FLOAT_BYTES[0];
570
+ destination[offset + 1] = FLOAT_BYTES[1];
571
+ destination[offset + 2] = FLOAT_BYTES[2];
572
+ destination[offset + 3] = FLOAT_BYTES[3];
573
+ destination[offset + 4] = FLOAT_BYTES[4];
574
+ destination[offset + 5] = FLOAT_BYTES[5];
575
+ destination[offset + 6] = FLOAT_BYTES[6];
576
+ destination[offset + 7] = FLOAT_BYTES[7];
577
+ return 8;
578
+ }
579
+ };
580
+
449
581
  class Binary extends BSONValue {
450
582
  get _bsontype() {
451
583
  return 'Binary';
@@ -518,7 +650,8 @@ class Binary extends BSONValue {
518
650
  }
519
651
  read(position, length) {
520
652
  length = length && length > 0 ? length : this.position;
521
- return this.buffer.slice(position, position + length);
653
+ const end = position + length;
654
+ return this.buffer.subarray(position, end > this.position ? this.position : end);
522
655
  }
523
656
  value() {
524
657
  return this.buffer.length === this.position
@@ -542,6 +675,9 @@ class Binary extends BSONValue {
542
675
  }
543
676
  toExtendedJSON(options) {
544
677
  options = options || {};
678
+ if (this.sub_type === Binary.SUBTYPE_VECTOR) {
679
+ validateBinaryVector(this);
680
+ }
545
681
  const base64String = ByteUtils.toBase64(this.buffer);
546
682
  const subType = Number(this.sub_type).toString(16);
547
683
  if (options.legacy) {
@@ -559,7 +695,7 @@ class Binary extends BSONValue {
559
695
  }
560
696
  toUUID() {
561
697
  if (this.sub_type === Binary.SUBTYPE_UUID) {
562
- return new UUID(this.buffer.slice(0, this.position));
698
+ return new UUID(this.buffer.subarray(0, this.position));
563
699
  }
564
700
  throw new BSONError(`Binary sub_type "${this.sub_type}" is not supported for converting to UUID. Only "${Binary.SUBTYPE_UUID}" is currently supported.`);
565
701
  }
@@ -601,6 +737,99 @@ class Binary extends BSONValue {
601
737
  const subTypeArg = inspect(this.sub_type, options);
602
738
  return `Binary.createFromBase64(${base64Arg}, ${subTypeArg})`;
603
739
  }
740
+ toInt8Array() {
741
+ if (this.sub_type !== Binary.SUBTYPE_VECTOR) {
742
+ throw new BSONError('Binary sub_type is not Vector');
743
+ }
744
+ if (this.buffer[0] !== Binary.VECTOR_TYPE.Int8) {
745
+ throw new BSONError('Binary datatype field is not Int8');
746
+ }
747
+ return new Int8Array(this.buffer.buffer.slice(this.buffer.byteOffset + 2, this.buffer.byteOffset + this.position));
748
+ }
749
+ toFloat32Array() {
750
+ if (this.sub_type !== Binary.SUBTYPE_VECTOR) {
751
+ throw new BSONError('Binary sub_type is not Vector');
752
+ }
753
+ if (this.buffer[0] !== Binary.VECTOR_TYPE.Float32) {
754
+ throw new BSONError('Binary datatype field is not Float32');
755
+ }
756
+ const floatBytes = new Uint8Array(this.buffer.buffer.slice(this.buffer.byteOffset + 2, this.buffer.byteOffset + this.position));
757
+ if (NumberUtils.isBigEndian)
758
+ ByteUtils.swap32(floatBytes);
759
+ return new Float32Array(floatBytes.buffer);
760
+ }
761
+ toPackedBits() {
762
+ if (this.sub_type !== Binary.SUBTYPE_VECTOR) {
763
+ throw new BSONError('Binary sub_type is not Vector');
764
+ }
765
+ if (this.buffer[0] !== Binary.VECTOR_TYPE.PackedBit) {
766
+ throw new BSONError('Binary datatype field is not packed bit');
767
+ }
768
+ return new Uint8Array(this.buffer.buffer.slice(this.buffer.byteOffset + 2, this.buffer.byteOffset + this.position));
769
+ }
770
+ toBits() {
771
+ if (this.sub_type !== Binary.SUBTYPE_VECTOR) {
772
+ throw new BSONError('Binary sub_type is not Vector');
773
+ }
774
+ if (this.buffer[0] !== Binary.VECTOR_TYPE.PackedBit) {
775
+ throw new BSONError('Binary datatype field is not packed bit');
776
+ }
777
+ const byteCount = this.length() - 2;
778
+ const bitCount = byteCount * 8 - this.buffer[1];
779
+ const bits = new Int8Array(bitCount);
780
+ for (let bitOffset = 0; bitOffset < bits.length; bitOffset++) {
781
+ const byteOffset = (bitOffset / 8) | 0;
782
+ const byte = this.buffer[byteOffset + 2];
783
+ const shift = 7 - (bitOffset % 8);
784
+ const bit = (byte >> shift) & 1;
785
+ bits[bitOffset] = bit;
786
+ }
787
+ return bits;
788
+ }
789
+ static fromInt8Array(array) {
790
+ const buffer = ByteUtils.allocate(array.byteLength + 2);
791
+ buffer[0] = Binary.VECTOR_TYPE.Int8;
792
+ buffer[1] = 0;
793
+ const intBytes = new Uint8Array(array.buffer, array.byteOffset, array.byteLength);
794
+ buffer.set(intBytes, 2);
795
+ return new this(buffer, this.SUBTYPE_VECTOR);
796
+ }
797
+ static fromFloat32Array(array) {
798
+ const binaryBytes = ByteUtils.allocate(array.byteLength + 2);
799
+ binaryBytes[0] = Binary.VECTOR_TYPE.Float32;
800
+ binaryBytes[1] = 0;
801
+ const floatBytes = new Uint8Array(array.buffer, array.byteOffset, array.byteLength);
802
+ binaryBytes.set(floatBytes, 2);
803
+ if (NumberUtils.isBigEndian)
804
+ ByteUtils.swap32(new Uint8Array(binaryBytes.buffer, 2));
805
+ return new this(binaryBytes, this.SUBTYPE_VECTOR);
806
+ }
807
+ static fromPackedBits(array, padding = 0) {
808
+ const buffer = ByteUtils.allocate(array.byteLength + 2);
809
+ buffer[0] = Binary.VECTOR_TYPE.PackedBit;
810
+ buffer[1] = padding;
811
+ buffer.set(array, 2);
812
+ return new this(buffer, this.SUBTYPE_VECTOR);
813
+ }
814
+ static fromBits(bits) {
815
+ const byteLength = (bits.length + 7) >>> 3;
816
+ const bytes = new Uint8Array(byteLength + 2);
817
+ bytes[0] = Binary.VECTOR_TYPE.PackedBit;
818
+ const remainder = bits.length % 8;
819
+ bytes[1] = remainder === 0 ? 0 : 8 - remainder;
820
+ for (let bitOffset = 0; bitOffset < bits.length; bitOffset++) {
821
+ const byteOffset = bitOffset >>> 3;
822
+ const bit = bits[bitOffset];
823
+ if (bit !== 0 && bit !== 1) {
824
+ throw new BSONError(`Invalid bit value at ${bitOffset}: must be 0 or 1, found ${bits[bitOffset]}`);
825
+ }
826
+ if (bit === 0)
827
+ continue;
828
+ const shift = 7 - (bitOffset % 8);
829
+ bytes[byteOffset + 2] |= bit << shift;
830
+ }
831
+ return new this(bytes, Binary.SUBTYPE_VECTOR);
832
+ }
604
833
  }
605
834
  Binary.BSON_BINARY_SUBTYPE_DEFAULT = 0;
606
835
  Binary.BUFFER_SIZE = 256;
@@ -613,7 +842,30 @@ Binary.SUBTYPE_MD5 = 5;
613
842
  Binary.SUBTYPE_ENCRYPTED = 6;
614
843
  Binary.SUBTYPE_COLUMN = 7;
615
844
  Binary.SUBTYPE_SENSITIVE = 8;
845
+ Binary.SUBTYPE_VECTOR = 9;
616
846
  Binary.SUBTYPE_USER_DEFINED = 128;
847
+ Binary.VECTOR_TYPE = Object.freeze({
848
+ Int8: 0x03,
849
+ Float32: 0x27,
850
+ PackedBit: 0x10
851
+ });
852
+ function validateBinaryVector(vector) {
853
+ if (vector.sub_type !== Binary.SUBTYPE_VECTOR)
854
+ return;
855
+ const size = vector.position;
856
+ const datatype = vector.buffer[0];
857
+ const padding = vector.buffer[1];
858
+ if ((datatype === Binary.VECTOR_TYPE.Float32 || datatype === Binary.VECTOR_TYPE.Int8) &&
859
+ padding !== 0) {
860
+ throw new BSONError('Invalid Vector: padding must be zero for int8 and float32 vectors');
861
+ }
862
+ if (datatype === Binary.VECTOR_TYPE.PackedBit && padding !== 0 && size === 2) {
863
+ throw new BSONError('Invalid Vector: padding must be zero for packed bit vectors that are empty');
864
+ }
865
+ if (datatype === Binary.VECTOR_TYPE.PackedBit && padding > 7) {
866
+ throw new BSONError(`Invalid Vector: padding must be a value between 0 and 7. found: ${padding}`);
867
+ }
868
+ }
617
869
  const UUID_BYTE_LENGTH = 16;
618
870
  const UUID_WITHOUT_DASHES = /^[0-9A-F]{32}$/i;
619
871
  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;
@@ -2225,134 +2477,8 @@ class MinKey extends BSONValue {
2225
2477
  }
2226
2478
  }
2227
2479
 
2228
- const FLOAT = new Float64Array(1);
2229
- const FLOAT_BYTES = new Uint8Array(FLOAT.buffer, 0, 8);
2230
- FLOAT[0] = -1;
2231
- const isBigEndian = FLOAT_BYTES[7] === 0;
2232
- const NumberUtils = {
2233
- getNonnegativeInt32LE(source, offset) {
2234
- if (source[offset + 3] > 127) {
2235
- throw new RangeError(`Size cannot be negative at offset: ${offset}`);
2236
- }
2237
- return (source[offset] |
2238
- (source[offset + 1] << 8) |
2239
- (source[offset + 2] << 16) |
2240
- (source[offset + 3] << 24));
2241
- },
2242
- getInt32LE(source, offset) {
2243
- return (source[offset] |
2244
- (source[offset + 1] << 8) |
2245
- (source[offset + 2] << 16) |
2246
- (source[offset + 3] << 24));
2247
- },
2248
- getUint32LE(source, offset) {
2249
- return (source[offset] +
2250
- source[offset + 1] * 256 +
2251
- source[offset + 2] * 65536 +
2252
- source[offset + 3] * 16777216);
2253
- },
2254
- getUint32BE(source, offset) {
2255
- return (source[offset + 3] +
2256
- source[offset + 2] * 256 +
2257
- source[offset + 1] * 65536 +
2258
- source[offset] * 16777216);
2259
- },
2260
- getBigInt64LE(source, offset) {
2261
- const lo = NumberUtils.getUint32LE(source, offset);
2262
- const hi = NumberUtils.getUint32LE(source, offset + 4);
2263
- return (BigInt(hi) << BigInt(32)) + BigInt(lo);
2264
- },
2265
- getFloat64LE: isBigEndian
2266
- ? (source, offset) => {
2267
- FLOAT_BYTES[7] = source[offset];
2268
- FLOAT_BYTES[6] = source[offset + 1];
2269
- FLOAT_BYTES[5] = source[offset + 2];
2270
- FLOAT_BYTES[4] = source[offset + 3];
2271
- FLOAT_BYTES[3] = source[offset + 4];
2272
- FLOAT_BYTES[2] = source[offset + 5];
2273
- FLOAT_BYTES[1] = source[offset + 6];
2274
- FLOAT_BYTES[0] = source[offset + 7];
2275
- return FLOAT[0];
2276
- }
2277
- : (source, offset) => {
2278
- FLOAT_BYTES[0] = source[offset];
2279
- FLOAT_BYTES[1] = source[offset + 1];
2280
- FLOAT_BYTES[2] = source[offset + 2];
2281
- FLOAT_BYTES[3] = source[offset + 3];
2282
- FLOAT_BYTES[4] = source[offset + 4];
2283
- FLOAT_BYTES[5] = source[offset + 5];
2284
- FLOAT_BYTES[6] = source[offset + 6];
2285
- FLOAT_BYTES[7] = source[offset + 7];
2286
- return FLOAT[0];
2287
- },
2288
- setInt32BE(destination, offset, value) {
2289
- destination[offset + 3] = value;
2290
- value >>>= 8;
2291
- destination[offset + 2] = value;
2292
- value >>>= 8;
2293
- destination[offset + 1] = value;
2294
- value >>>= 8;
2295
- destination[offset] = value;
2296
- return 4;
2297
- },
2298
- setInt32LE(destination, offset, value) {
2299
- destination[offset] = value;
2300
- value >>>= 8;
2301
- destination[offset + 1] = value;
2302
- value >>>= 8;
2303
- destination[offset + 2] = value;
2304
- value >>>= 8;
2305
- destination[offset + 3] = value;
2306
- return 4;
2307
- },
2308
- setBigInt64LE(destination, offset, value) {
2309
- const mask32bits = BigInt(0xffff_ffff);
2310
- let lo = Number(value & mask32bits);
2311
- destination[offset] = lo;
2312
- lo >>= 8;
2313
- destination[offset + 1] = lo;
2314
- lo >>= 8;
2315
- destination[offset + 2] = lo;
2316
- lo >>= 8;
2317
- destination[offset + 3] = lo;
2318
- let hi = Number((value >> BigInt(32)) & mask32bits);
2319
- destination[offset + 4] = hi;
2320
- hi >>= 8;
2321
- destination[offset + 5] = hi;
2322
- hi >>= 8;
2323
- destination[offset + 6] = hi;
2324
- hi >>= 8;
2325
- destination[offset + 7] = hi;
2326
- return 8;
2327
- },
2328
- setFloat64LE: isBigEndian
2329
- ? (destination, offset, value) => {
2330
- FLOAT[0] = value;
2331
- destination[offset] = FLOAT_BYTES[7];
2332
- destination[offset + 1] = FLOAT_BYTES[6];
2333
- destination[offset + 2] = FLOAT_BYTES[5];
2334
- destination[offset + 3] = FLOAT_BYTES[4];
2335
- destination[offset + 4] = FLOAT_BYTES[3];
2336
- destination[offset + 5] = FLOAT_BYTES[2];
2337
- destination[offset + 6] = FLOAT_BYTES[1];
2338
- destination[offset + 7] = FLOAT_BYTES[0];
2339
- return 8;
2340
- }
2341
- : (destination, offset, value) => {
2342
- FLOAT[0] = value;
2343
- destination[offset] = FLOAT_BYTES[0];
2344
- destination[offset + 1] = FLOAT_BYTES[1];
2345
- destination[offset + 2] = FLOAT_BYTES[2];
2346
- destination[offset + 3] = FLOAT_BYTES[3];
2347
- destination[offset + 4] = FLOAT_BYTES[4];
2348
- destination[offset + 5] = FLOAT_BYTES[5];
2349
- destination[offset + 6] = FLOAT_BYTES[6];
2350
- destination[offset + 7] = FLOAT_BYTES[7];
2351
- return 8;
2352
- }
2353
- };
2354
-
2355
2480
  let PROCESS_UNIQUE = null;
2481
+ const __idCache = new WeakMap();
2356
2482
  class ObjectId extends BSONValue {
2357
2483
  get _bsontype() {
2358
2484
  return 'ObjectId';
@@ -2383,6 +2509,9 @@ class ObjectId extends BSONValue {
2383
2509
  else if (typeof workingId === 'string') {
2384
2510
  if (ObjectId.validateHexString(workingId)) {
2385
2511
  this.buffer = ByteUtils.fromHex(workingId);
2512
+ if (ObjectId.cacheHexString) {
2513
+ __idCache.set(this, workingId);
2514
+ }
2386
2515
  }
2387
2516
  else {
2388
2517
  throw new BSONError('input must be a 24 character hex string, 12 byte Uint8Array, or an integer');
@@ -2391,9 +2520,6 @@ class ObjectId extends BSONValue {
2391
2520
  else {
2392
2521
  throw new BSONError('Argument passed in does not match the accepted types');
2393
2522
  }
2394
- if (ObjectId.cacheHexString) {
2395
- this.__id = ByteUtils.toHex(this.id);
2396
- }
2397
2523
  }
2398
2524
  get id() {
2399
2525
  return this.buffer;
@@ -2401,7 +2527,7 @@ class ObjectId extends BSONValue {
2401
2527
  set id(value) {
2402
2528
  this.buffer = value;
2403
2529
  if (ObjectId.cacheHexString) {
2404
- this.__id = ByteUtils.toHex(value);
2530
+ __idCache.set(this, ByteUtils.toHex(value));
2405
2531
  }
2406
2532
  }
2407
2533
  static validateHexString(string) {
@@ -2419,12 +2545,14 @@ class ObjectId extends BSONValue {
2419
2545
  return true;
2420
2546
  }
2421
2547
  toHexString() {
2422
- if (ObjectId.cacheHexString && this.__id) {
2423
- return this.__id;
2548
+ if (ObjectId.cacheHexString) {
2549
+ const __id = __idCache.get(this);
2550
+ if (__id)
2551
+ return __id;
2424
2552
  }
2425
2553
  const hexString = ByteUtils.toHex(this.id);
2426
- if (ObjectId.cacheHexString && !this.__id) {
2427
- this.__id = hexString;
2554
+ if (ObjectId.cacheHexString) {
2555
+ __idCache.set(this, hexString);
2428
2556
  }
2429
2557
  return hexString;
2430
2558
  }
@@ -2548,6 +2676,9 @@ class ObjectId extends BSONValue {
2548
2676
  static fromExtendedJSON(doc) {
2549
2677
  return new ObjectId(doc.$oid);
2550
2678
  }
2679
+ isCached() {
2680
+ return ObjectId.cacheHexString && __idCache.has(this);
2681
+ }
2551
2682
  inspect(depth, options, inspect) {
2552
2683
  inspect ??= defaultInspect;
2553
2684
  return `new ObjectId(${inspect(this.toHexString(), options)})`;
@@ -3038,7 +3169,7 @@ function deserializeObject(buffer, index, options, isArray = false) {
3038
3169
  if (objectSize <= 0 || objectSize > buffer.length - index)
3039
3170
  throw new BSONError('bad embedded document length in bson');
3040
3171
  if (raw) {
3041
- value = buffer.slice(index, index + objectSize);
3172
+ value = buffer.subarray(index, index + objectSize);
3042
3173
  }
3043
3174
  else {
3044
3175
  let objectOptions = options;
@@ -3110,49 +3241,23 @@ function deserializeObject(buffer, index, options, isArray = false) {
3110
3241
  throw new BSONError('Negative binary type element size found');
3111
3242
  if (binarySize > buffer.byteLength)
3112
3243
  throw new BSONError('Binary type size larger than document size');
3113
- if (buffer['slice'] != null) {
3114
- if (subType === Binary.SUBTYPE_BYTE_ARRAY) {
3115
- binarySize = NumberUtils.getInt32LE(buffer, index);
3116
- index += 4;
3117
- if (binarySize < 0)
3118
- throw new BSONError('Negative binary type element size found for subtype 0x02');
3119
- if (binarySize > totalBinarySize - 4)
3120
- throw new BSONError('Binary type with subtype 0x02 contains too long binary size');
3121
- if (binarySize < totalBinarySize - 4)
3122
- throw new BSONError('Binary type with subtype 0x02 contains too short binary size');
3123
- }
3124
- if (promoteBuffers && promoteValues) {
3125
- value = ByteUtils.toLocalBufferType(buffer.slice(index, index + binarySize));
3126
- }
3127
- else {
3128
- value = new Binary(buffer.slice(index, index + binarySize), subType);
3129
- if (subType === BSON_BINARY_SUBTYPE_UUID_NEW && UUID.isValid(value)) {
3130
- value = value.toUUID();
3131
- }
3132
- }
3244
+ if (subType === Binary.SUBTYPE_BYTE_ARRAY) {
3245
+ binarySize = NumberUtils.getInt32LE(buffer, index);
3246
+ index += 4;
3247
+ if (binarySize < 0)
3248
+ throw new BSONError('Negative binary type element size found for subtype 0x02');
3249
+ if (binarySize > totalBinarySize - 4)
3250
+ throw new BSONError('Binary type with subtype 0x02 contains too long binary size');
3251
+ if (binarySize < totalBinarySize - 4)
3252
+ throw new BSONError('Binary type with subtype 0x02 contains too short binary size');
3253
+ }
3254
+ if (promoteBuffers && promoteValues) {
3255
+ value = ByteUtils.toLocalBufferType(buffer.subarray(index, index + binarySize));
3133
3256
  }
3134
3257
  else {
3135
- if (subType === Binary.SUBTYPE_BYTE_ARRAY) {
3136
- binarySize = NumberUtils.getInt32LE(buffer, index);
3137
- index += 4;
3138
- if (binarySize < 0)
3139
- throw new BSONError('Negative binary type element size found for subtype 0x02');
3140
- if (binarySize > totalBinarySize - 4)
3141
- throw new BSONError('Binary type with subtype 0x02 contains too long binary size');
3142
- if (binarySize < totalBinarySize - 4)
3143
- throw new BSONError('Binary type with subtype 0x02 contains too short binary size');
3144
- }
3145
- if (promoteBuffers && promoteValues) {
3146
- value = ByteUtils.allocateUnsafe(binarySize);
3147
- for (i = 0; i < binarySize; i++) {
3148
- value[i] = buffer[index + i];
3149
- }
3150
- }
3151
- else {
3152
- value = new Binary(buffer.slice(index, index + binarySize), subType);
3153
- if (subType === BSON_BINARY_SUBTYPE_UUID_NEW && UUID.isValid(value)) {
3154
- value = value.toUUID();
3155
- }
3258
+ value = new Binary(buffer.subarray(index, index + binarySize), subType);
3259
+ if (subType === BSON_BINARY_SUBTYPE_UUID_NEW && UUID.isValid(value)) {
3260
+ value = value.toUUID();
3156
3261
  }
3157
3262
  }
3158
3263
  index = index + binarySize;
@@ -3574,6 +3679,9 @@ function serializeBinary(buffer, key, value, index) {
3574
3679
  size = size - 4;
3575
3680
  index += NumberUtils.setInt32LE(buffer, index, size);
3576
3681
  }
3682
+ if (value.sub_type === Binary.SUBTYPE_VECTOR) {
3683
+ validateBinaryVector(value);
3684
+ }
3577
3685
  if (size <= 16) {
3578
3686
  for (let i = 0; i < size; i++)
3579
3687
  buffer[index + i] = data[i];