mongodb 6.11.0 → 6.12.0-dev.20241212.sha.f6d7868f

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.
Files changed (55) hide show
  1. package/README.md +9 -8
  2. package/lib/beta.d.ts +43 -85
  3. package/lib/bulk/common.js +5 -7
  4. package/lib/bulk/common.js.map +1 -1
  5. package/lib/change_stream.js +16 -26
  6. package/lib/change_stream.js.map +1 -1
  7. package/lib/cmap/connect.js +15 -28
  8. package/lib/cmap/connect.js.map +1 -1
  9. package/lib/cmap/connection.js +1 -1
  10. package/lib/cmap/connection.js.map +1 -1
  11. package/lib/cmap/connection_pool.js +83 -117
  12. package/lib/cmap/connection_pool.js.map +1 -1
  13. package/lib/collection.js +3 -0
  14. package/lib/collection.js.map +1 -1
  15. package/lib/encrypter.js +5 -9
  16. package/lib/encrypter.js.map +1 -1
  17. package/lib/error.js +37 -19
  18. package/lib/error.js.map +1 -1
  19. package/lib/index.js +3 -2
  20. package/lib/index.js.map +1 -1
  21. package/lib/mongo_client.js +20 -26
  22. package/lib/mongo_client.js.map +1 -1
  23. package/lib/operations/operation.js +4 -5
  24. package/lib/operations/operation.js.map +1 -1
  25. package/lib/sdam/monitor.js +25 -31
  26. package/lib/sdam/monitor.js.map +1 -1
  27. package/lib/sdam/server.js +1 -1
  28. package/lib/sdam/server.js.map +1 -1
  29. package/lib/sdam/server_description.js +3 -0
  30. package/lib/sdam/server_description.js.map +1 -1
  31. package/lib/sdam/topology.js +13 -16
  32. package/lib/sdam/topology.js.map +1 -1
  33. package/lib/sdam/topology_description.js +9 -3
  34. package/lib/sdam/topology_description.js.map +1 -1
  35. package/lib/sessions.js +24 -48
  36. package/lib/sessions.js.map +1 -1
  37. package/mongodb.d.ts +43 -85
  38. package/package.json +5 -5
  39. package/src/bulk/common.ts +6 -9
  40. package/src/change_stream.ts +21 -33
  41. package/src/cmap/connect.ts +33 -34
  42. package/src/cmap/connection.ts +1 -1
  43. package/src/cmap/connection_pool.ts +104 -142
  44. package/src/collection.ts +3 -0
  45. package/src/encrypter.ts +6 -11
  46. package/src/error.ts +48 -25
  47. package/src/index.ts +1 -0
  48. package/src/mongo_client.ts +26 -32
  49. package/src/operations/operation.ts +5 -7
  50. package/src/sdam/monitor.ts +30 -38
  51. package/src/sdam/server.ts +2 -2
  52. package/src/sdam/server_description.ts +3 -0
  53. package/src/sdam/topology.ts +15 -19
  54. package/src/sdam/topology_description.ts +13 -4
  55. package/src/sessions.ts +37 -58
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mongodb",
3
- "version": "6.11.0",
3
+ "version": "6.12.0-dev.20241212.sha.f6d7868f",
4
4
  "description": "The official MongoDB driver for Node.js",
5
5
  "main": "lib/index.js",
6
6
  "files": [
@@ -26,12 +26,12 @@
26
26
  },
27
27
  "dependencies": {
28
28
  "@mongodb-js/saslprep": "^1.1.9",
29
- "bson": "^6.10.0",
29
+ "bson": "^6.10.1",
30
30
  "mongodb-connection-string-url": "^3.0.0"
31
31
  },
32
32
  "peerDependencies": {
33
33
  "@aws-sdk/credential-providers": "^3.188.0",
34
- "@mongodb-js/zstd": "^1.1.0",
34
+ "@mongodb-js/zstd": "^1.1.0 || ^2.0.0",
35
35
  "gcp-metadata": "^5.2.0",
36
36
  "kerberos": "^2.0.1",
37
37
  "mongodb-client-encryption": ">=6.0.0 <7",
@@ -67,7 +67,7 @@
67
67
  "@istanbuljs/nyc-config-typescript": "^1.0.2",
68
68
  "@microsoft/api-extractor": "^7.47.11",
69
69
  "@microsoft/tsdoc-config": "^0.17.0",
70
- "@mongodb-js/zstd": "^1.2.2",
70
+ "@mongodb-js/zstd": "^2.0.0",
71
71
  "@types/chai": "^4.3.17",
72
72
  "@types/chai-subset": "^1.3.5",
73
73
  "@types/express": "^4.17.21",
@@ -176,4 +176,4 @@
176
176
  "moduleResolution": "node"
177
177
  }
178
178
  }
179
- }
179
+ }
@@ -30,9 +30,6 @@ import {
30
30
  } from '../utils';
31
31
  import { WriteConcern } from '../write_concern';
32
32
 
33
- /** @internal */
34
- const kServerError = Symbol('serverError');
35
-
36
33
  /** @public */
37
34
  export const BatchType = Object.freeze({
38
35
  INSERT: 1,
@@ -315,29 +312,29 @@ export interface WriteConcernErrorData {
315
312
  */
316
313
  export class WriteConcernError {
317
314
  /** @internal */
318
- [kServerError]: WriteConcernErrorData;
315
+ private serverError: WriteConcernErrorData;
319
316
 
320
317
  constructor(error: WriteConcernErrorData) {
321
- this[kServerError] = error;
318
+ this.serverError = error;
322
319
  }
323
320
 
324
321
  /** Write concern error code. */
325
322
  get code(): number | undefined {
326
- return this[kServerError].code;
323
+ return this.serverError.code;
327
324
  }
328
325
 
329
326
  /** Write concern error message. */
330
327
  get errmsg(): string | undefined {
331
- return this[kServerError].errmsg;
328
+ return this.serverError.errmsg;
332
329
  }
333
330
 
334
331
  /** Write concern error info. */
335
332
  get errInfo(): Document | undefined {
336
- return this[kServerError].errInfo;
333
+ return this.serverError.errInfo;
337
334
  }
338
335
 
339
336
  toJSON(): WriteConcernErrorData {
340
- return this[kServerError];
337
+ return this.serverError;
341
338
  }
342
339
 
343
340
  toString(): string {
@@ -24,13 +24,6 @@ import type { ServerSessionId } from './sessions';
24
24
  import { CSOTTimeoutContext, type TimeoutContext } from './timeout';
25
25
  import { filterOptions, getTopology, type MongoDBNamespace, squashError } from './utils';
26
26
 
27
- /** @internal */
28
- const kCursorStream = Symbol('cursorStream');
29
- /** @internal */
30
- const kClosed = Symbol('closed');
31
- /** @internal */
32
- const kMode = Symbol('mode');
33
-
34
27
  const CHANGE_STREAM_OPTIONS = [
35
28
  'resumeAfter',
36
29
  'startAfter',
@@ -584,14 +577,14 @@ export class ChangeStream<
584
577
  namespace: MongoDBNamespace;
585
578
  type: symbol;
586
579
  /** @internal */
587
- cursor: ChangeStreamCursor<TSchema, TChange>;
580
+ private cursor: ChangeStreamCursor<TSchema, TChange>;
588
581
  streamOptions?: CursorStreamOptions;
589
582
  /** @internal */
590
- [kCursorStream]?: Readable & AsyncIterable<TChange>;
583
+ private cursorStream?: Readable & AsyncIterable<TChange>;
591
584
  /** @internal */
592
- [kClosed]: boolean;
585
+ private isClosed: boolean;
593
586
  /** @internal */
594
- [kMode]: false | 'iterator' | 'emitter';
587
+ private mode: false | 'iterator' | 'emitter';
595
588
 
596
589
  /** @event */
597
590
  static readonly RESPONSE = RESPONSE;
@@ -668,8 +661,8 @@ export class ChangeStream<
668
661
  // Create contained Change Stream cursor
669
662
  this.cursor = this._createChangeStreamCursor(options);
670
663
 
671
- this[kClosed] = false;
672
- this[kMode] = false;
664
+ this.isClosed = false;
665
+ this.mode = false;
673
666
 
674
667
  // Listen for any `change` listeners being added to ChangeStream
675
668
  this.on('newListener', eventName => {
@@ -680,7 +673,7 @@ export class ChangeStream<
680
673
 
681
674
  this.on('removeListener', eventName => {
682
675
  if (eventName === 'change' && this.listenerCount('change') === 0 && this.cursor) {
683
- this[kCursorStream]?.removeAllListeners('data');
676
+ this.cursorStream?.removeAllListeners('data');
684
677
  }
685
678
  });
686
679
 
@@ -692,11 +685,6 @@ export class ChangeStream<
692
685
  }
693
686
  }
694
687
 
695
- /** @internal */
696
- get cursorStream(): (Readable & AsyncIterable<TChange>) | undefined {
697
- return this[kCursorStream];
698
- }
699
-
700
688
  /** The cached resume token that is used to resume after the most recently returned change. */
701
689
  get resumeToken(): ResumeToken {
702
690
  return this.cursor?.resumeToken;
@@ -826,8 +814,8 @@ export class ChangeStream<
826
814
  }
827
815
 
828
816
  /** Is the cursor closed */
829
- get closed(): boolean {
830
- return this[kClosed] || this.cursor.closed;
817
+ public get closed(): boolean {
818
+ return this.isClosed || this.cursor.closed;
831
819
  }
832
820
 
833
821
  /**
@@ -836,7 +824,7 @@ export class ChangeStream<
836
824
  async close(): Promise<void> {
837
825
  this.timeoutContext?.clear();
838
826
  this.timeoutContext = undefined;
839
- this[kClosed] = true;
827
+ this.isClosed = true;
840
828
 
841
829
  const cursor = this.cursor;
842
830
  try {
@@ -865,24 +853,24 @@ export class ChangeStream<
865
853
 
866
854
  /** @internal */
867
855
  private _setIsEmitter(): void {
868
- if (this[kMode] === 'iterator') {
856
+ if (this.mode === 'iterator') {
869
857
  // TODO(NODE-3485): Replace with MongoChangeStreamModeError
870
858
  throw new MongoAPIError(
871
859
  'ChangeStream cannot be used as an EventEmitter after being used as an iterator'
872
860
  );
873
861
  }
874
- this[kMode] = 'emitter';
862
+ this.mode = 'emitter';
875
863
  }
876
864
 
877
865
  /** @internal */
878
866
  private _setIsIterator(): void {
879
- if (this[kMode] === 'emitter') {
867
+ if (this.mode === 'emitter') {
880
868
  // TODO(NODE-3485): Replace with MongoChangeStreamModeError
881
869
  throw new MongoAPIError(
882
870
  'ChangeStream cannot be used as an iterator after being used as an EventEmitter'
883
871
  );
884
872
  }
885
- this[kMode] = 'iterator';
873
+ this.mode = 'iterator';
886
874
  }
887
875
 
888
876
  /**
@@ -947,8 +935,8 @@ export class ChangeStream<
947
935
  /** @internal */
948
936
  private _streamEvents(cursor: ChangeStreamCursor<TSchema, TChange>): void {
949
937
  this._setIsEmitter();
950
- const stream = this[kCursorStream] ?? cursor.stream();
951
- this[kCursorStream] = stream;
938
+ const stream = this.cursorStream ?? cursor.stream();
939
+ this.cursorStream = stream;
952
940
  stream.on('data', change => {
953
941
  try {
954
942
  const processedChange = this._processChange(change);
@@ -963,18 +951,18 @@ export class ChangeStream<
963
951
 
964
952
  /** @internal */
965
953
  private _endStream(): void {
966
- const cursorStream = this[kCursorStream];
954
+ const cursorStream = this.cursorStream;
967
955
  if (cursorStream) {
968
956
  ['data', 'close', 'end', 'error'].forEach(event => cursorStream.removeAllListeners(event));
969
957
  cursorStream.destroy();
970
958
  }
971
959
 
972
- this[kCursorStream] = undefined;
960
+ this.cursorStream = undefined;
973
961
  }
974
962
 
975
963
  /** @internal */
976
964
  private _processChange(change: TChange | null): TChange {
977
- if (this[kClosed]) {
965
+ if (this.isClosed) {
978
966
  // TODO(NODE-3485): Replace with MongoChangeStreamClosedError
979
967
  throw new MongoAPIError(CHANGESTREAM_CLOSED_ERROR);
980
968
  }
@@ -1002,7 +990,7 @@ export class ChangeStream<
1002
990
  /** @internal */
1003
991
  private _processErrorStreamMode(changeStreamError: AnyError, cursorInitialized: boolean) {
1004
992
  // If the change stream has been closed explicitly, do not process error.
1005
- if (this[kClosed]) return;
993
+ if (this.isClosed) return;
1006
994
 
1007
995
  if (
1008
996
  cursorInitialized &&
@@ -1034,7 +1022,7 @@ export class ChangeStream<
1034
1022
 
1035
1023
  /** @internal */
1036
1024
  private async _processErrorIteratorMode(changeStreamError: AnyError, cursorInitialized: boolean) {
1037
- if (this[kClosed]) {
1025
+ if (this.isClosed) {
1038
1026
  // TODO(NODE-3485): Replace with MongoChangeStreamClosedError
1039
1027
  throw new MongoAPIError(CHANGESTREAM_CLOSED_ERROR);
1040
1028
  }
@@ -386,15 +386,35 @@ export async function makeSocket(options: MakeConnectionOptions): Promise<Stream
386
386
  if (existingSocket) {
387
387
  resolve(socket);
388
388
  } else {
389
+ const start = performance.now();
389
390
  const connectEvent = useTLS ? 'secureConnect' : 'connect';
390
391
  socket
391
392
  .once(connectEvent, () => resolve(socket))
392
- .once('error', error => reject(connectionFailureError('error', error)))
393
- .once('timeout', () => reject(connectionFailureError('timeout')))
394
- .once('close', () => reject(connectionFailureError('close')));
393
+ .once('error', cause =>
394
+ reject(new MongoNetworkError(MongoError.buildErrorMessage(cause), { cause }))
395
+ )
396
+ .once('timeout', () => {
397
+ reject(
398
+ new MongoNetworkTimeoutError(
399
+ `Socket '${connectEvent}' timed out after ${(performance.now() - start) | 0}ms (connectTimeoutMS: ${connectTimeoutMS})`
400
+ )
401
+ );
402
+ })
403
+ .once('close', () =>
404
+ reject(
405
+ new MongoNetworkError(
406
+ `Socket closed after ${(performance.now() - start) | 0} during connection establishment`
407
+ )
408
+ )
409
+ );
395
410
 
396
411
  if (options.cancellationToken != null) {
397
- cancellationHandler = () => reject(connectionFailureError('cancel'));
412
+ cancellationHandler = () =>
413
+ reject(
414
+ new MongoNetworkError(
415
+ `Socket connection establishment was cancelled after ${(performance.now() - start) | 0}`
416
+ )
417
+ );
398
418
  options.cancellationToken.once('cancel', cancellationHandler);
399
419
  }
400
420
  }
@@ -447,9 +467,11 @@ async function makeSocks5Connection(options: MakeConnectionOptions): Promise<Str
447
467
 
448
468
  socks ??= loadSocks();
449
469
 
470
+ let existingSocket: Stream;
471
+
450
472
  try {
451
473
  // Then, establish the Socks5 proxy connection:
452
- const { socket } = await socks.SocksClient.createConnection({
474
+ const connection = await socks.SocksClient.createConnection({
453
475
  existing_socket: rawSocket,
454
476
  timeout: options.connectTimeoutMS,
455
477
  command: 'connect',
@@ -466,35 +488,12 @@ async function makeSocks5Connection(options: MakeConnectionOptions): Promise<Str
466
488
  password: options.proxyPassword || undefined
467
489
  }
468
490
  });
469
-
470
- // Finally, now treat the resulting duplex stream as the
471
- // socket over which we send and receive wire protocol messages:
472
- return await makeSocket({
473
- ...options,
474
- existingSocket: socket,
475
- proxyHost: undefined
476
- });
477
- } catch (error) {
478
- throw connectionFailureError('error', error);
491
+ existingSocket = connection.socket;
492
+ } catch (cause) {
493
+ throw new MongoNetworkError(MongoError.buildErrorMessage(cause), { cause });
479
494
  }
480
- }
481
495
 
482
- function connectionFailureError(type: 'error', cause: Error): MongoNetworkError;
483
- function connectionFailureError(type: 'close' | 'timeout' | 'cancel'): MongoNetworkError;
484
- function connectionFailureError(
485
- type: 'error' | 'close' | 'timeout' | 'cancel',
486
- cause?: Error
487
- ): MongoNetworkError {
488
- switch (type) {
489
- case 'error':
490
- return new MongoNetworkError(MongoError.buildErrorMessage(cause), { cause });
491
- case 'timeout':
492
- return new MongoNetworkTimeoutError('connection timed out');
493
- case 'close':
494
- return new MongoNetworkError('connection closed');
495
- case 'cancel':
496
- return new MongoNetworkError('connection establishment was cancelled');
497
- default:
498
- return new MongoNetworkError('unknown network error');
499
- }
496
+ // Finally, now treat the resulting duplex stream as the
497
+ // socket over which we send and receive wire protocol messages:
498
+ return await makeSocket({ ...options, existingSocket, proxyHost: undefined });
500
499
  }
@@ -769,7 +769,7 @@ export class SizedMessageTransform extends Transform {
769
769
  connection: Connection;
770
770
 
771
771
  constructor({ connection }: { connection: Connection }) {
772
- super({ objectMode: false });
772
+ super({ writableObjectMode: false, readableObjectMode: true });
773
773
  this.bufferPool = new BufferPool();
774
774
  this.connection = connection;
775
775
  }