mongodb 6.5.0 → 6.6.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.
Files changed (207) hide show
  1. package/README.md +9 -9
  2. package/lib/admin.js +9 -9
  3. package/lib/admin.js.map +1 -1
  4. package/lib/bson.js +33 -22
  5. package/lib/bson.js.map +1 -1
  6. package/lib/bulk/common.js +13 -12
  7. package/lib/bulk/common.js.map +1 -1
  8. package/lib/change_stream.js +28 -18
  9. package/lib/change_stream.js.map +1 -1
  10. package/lib/client-side-encryption/auto_encrypter.js +2 -2
  11. package/lib/client-side-encryption/auto_encrypter.js.map +1 -1
  12. package/lib/client-side-encryption/client_encryption.js +6 -6
  13. package/lib/client-side-encryption/client_encryption.js.map +1 -1
  14. package/lib/client-side-encryption/providers/aws.js +13 -10
  15. package/lib/client-side-encryption/providers/aws.js.map +1 -1
  16. package/lib/client-side-encryption/providers/azure.js +6 -3
  17. package/lib/client-side-encryption/providers/azure.js.map +1 -1
  18. package/lib/cmap/auth/aws_temporary_credentials.js +140 -0
  19. package/lib/cmap/auth/aws_temporary_credentials.js.map +1 -0
  20. package/lib/cmap/auth/gssapi.js +7 -6
  21. package/lib/cmap/auth/gssapi.js.map +1 -1
  22. package/lib/cmap/auth/mongodb_aws.js +8 -101
  23. package/lib/cmap/auth/mongodb_aws.js.map +1 -1
  24. package/lib/cmap/auth/mongodb_oidc/aws_service_workflow.js +1 -1
  25. package/lib/cmap/auth/mongodb_oidc/aws_service_workflow.js.map +1 -1
  26. package/lib/cmap/auth/mongodb_oidc/callback_lock_cache.js +2 -1
  27. package/lib/cmap/auth/mongodb_oidc/callback_lock_cache.js.map +1 -1
  28. package/lib/cmap/auth/mongodb_oidc/service_workflow.js +1 -1
  29. package/lib/cmap/auth/mongodb_oidc/service_workflow.js.map +1 -1
  30. package/lib/cmap/auth/scram.js +2 -2
  31. package/lib/cmap/auth/scram.js.map +1 -1
  32. package/lib/cmap/commands.js +24 -111
  33. package/lib/cmap/commands.js.map +1 -1
  34. package/lib/cmap/connect.js +4 -4
  35. package/lib/cmap/connect.js.map +1 -1
  36. package/lib/cmap/connection.js +61 -36
  37. package/lib/cmap/connection.js.map +1 -1
  38. package/lib/cmap/connection_pool.js +22 -13
  39. package/lib/cmap/connection_pool.js.map +1 -1
  40. package/lib/cmap/handshake/client_metadata.js +2 -2
  41. package/lib/cmap/handshake/client_metadata.js.map +1 -1
  42. package/lib/cmap/wire_protocol/compression.js +8 -8
  43. package/lib/cmap/wire_protocol/compression.js.map +1 -1
  44. package/lib/cmap/wire_protocol/on_demand/document.js +218 -0
  45. package/lib/cmap/wire_protocol/on_demand/document.js.map +1 -0
  46. package/lib/cmap/wire_protocol/responses.js +184 -0
  47. package/lib/cmap/wire_protocol/responses.js.map +1 -0
  48. package/lib/collection.js +42 -38
  49. package/lib/collection.js.map +1 -1
  50. package/lib/connection_string.js +4 -6
  51. package/lib/connection_string.js.map +1 -1
  52. package/lib/cursor/abstract_cursor.js +76 -43
  53. package/lib/cursor/abstract_cursor.js.map +1 -1
  54. package/lib/cursor/aggregation_cursor.js +16 -33
  55. package/lib/cursor/aggregation_cursor.js.map +1 -1
  56. package/lib/cursor/find_cursor.js +36 -18
  57. package/lib/cursor/find_cursor.js.map +1 -1
  58. package/lib/cursor/run_command_cursor.js +3 -2
  59. package/lib/cursor/run_command_cursor.js.map +1 -1
  60. package/lib/db.js +15 -19
  61. package/lib/db.js.map +1 -1
  62. package/lib/deps.js +31 -26
  63. package/lib/deps.js.map +1 -1
  64. package/lib/encrypter.js +14 -5
  65. package/lib/encrypter.js.map +1 -1
  66. package/lib/error.js +4 -3
  67. package/lib/error.js.map +1 -1
  68. package/lib/gridfs/download.js +19 -14
  69. package/lib/gridfs/download.js.map +1 -1
  70. package/lib/gridfs/index.js.map +1 -1
  71. package/lib/gridfs/upload.js +6 -1
  72. package/lib/gridfs/upload.js.map +1 -1
  73. package/lib/index.js.map +1 -1
  74. package/lib/mongo_client.js +11 -7
  75. package/lib/mongo_client.js.map +1 -1
  76. package/lib/mongo_logger.js +3 -0
  77. package/lib/mongo_logger.js.map +1 -1
  78. package/lib/operations/aggregate.js +2 -1
  79. package/lib/operations/aggregate.js.map +1 -1
  80. package/lib/operations/command.js +1 -1
  81. package/lib/operations/command.js.map +1 -1
  82. package/lib/operations/create_collection.js +1 -1
  83. package/lib/operations/create_collection.js.map +1 -1
  84. package/lib/operations/delete.js +4 -3
  85. package/lib/operations/delete.js.map +1 -1
  86. package/lib/operations/drop.js +1 -1
  87. package/lib/operations/drop.js.map +1 -1
  88. package/lib/operations/execute_operation.js +23 -8
  89. package/lib/operations/execute_operation.js.map +1 -1
  90. package/lib/operations/find.js +4 -4
  91. package/lib/operations/find.js.map +1 -1
  92. package/lib/operations/get_more.js +2 -1
  93. package/lib/operations/get_more.js.map +1 -1
  94. package/lib/operations/indexes.js +29 -121
  95. package/lib/operations/indexes.js.map +1 -1
  96. package/lib/operations/insert.js +3 -3
  97. package/lib/operations/insert.js.map +1 -1
  98. package/lib/operations/kill_cursors.js +3 -1
  99. package/lib/operations/kill_cursors.js.map +1 -1
  100. package/lib/operations/list_collections.js +1 -1
  101. package/lib/operations/list_collections.js.map +1 -1
  102. package/lib/operations/list_databases.js +1 -1
  103. package/lib/operations/list_databases.js.map +1 -1
  104. package/lib/operations/operation.js.map +1 -1
  105. package/lib/operations/run_command.js +4 -2
  106. package/lib/operations/run_command.js.map +1 -1
  107. package/lib/operations/search_indexes/create.js.map +1 -1
  108. package/lib/operations/stats.js +1 -1
  109. package/lib/operations/stats.js.map +1 -1
  110. package/lib/operations/update.js +1 -1
  111. package/lib/operations/update.js.map +1 -1
  112. package/lib/sdam/common.js.map +1 -1
  113. package/lib/sdam/monitor.js +139 -42
  114. package/lib/sdam/monitor.js.map +1 -1
  115. package/lib/sdam/server.js +5 -15
  116. package/lib/sdam/server.js.map +1 -1
  117. package/lib/sdam/server_description.js +1 -0
  118. package/lib/sdam/server_description.js.map +1 -1
  119. package/lib/sdam/server_selection.js +1 -1
  120. package/lib/sdam/server_selection.js.map +1 -1
  121. package/lib/sdam/srv_polling.js +2 -1
  122. package/lib/sdam/srv_polling.js.map +1 -1
  123. package/lib/sdam/topology.js +67 -54
  124. package/lib/sdam/topology.js.map +1 -1
  125. package/lib/sdam/topology_description.js +10 -0
  126. package/lib/sdam/topology_description.js.map +1 -1
  127. package/lib/sessions.js +133 -93
  128. package/lib/sessions.js.map +1 -1
  129. package/lib/timeout.js +77 -0
  130. package/lib/timeout.js.map +1 -0
  131. package/lib/utils.js +61 -28
  132. package/lib/utils.js.map +1 -1
  133. package/mongodb.d.ts +150 -38
  134. package/package.json +16 -13
  135. package/src/admin.ts +9 -9
  136. package/src/bson.ts +14 -0
  137. package/src/bulk/common.ts +3 -2
  138. package/src/change_stream.ts +39 -30
  139. package/src/client-side-encryption/auto_encrypter.ts +2 -2
  140. package/src/client-side-encryption/client_encryption.ts +6 -6
  141. package/src/client-side-encryption/providers/aws.ts +17 -10
  142. package/src/client-side-encryption/providers/azure.ts +5 -3
  143. package/src/cmap/auth/aws_temporary_credentials.ts +169 -0
  144. package/src/cmap/auth/gssapi.ts +9 -11
  145. package/src/cmap/auth/mongodb_aws.ts +19 -126
  146. package/src/cmap/auth/mongodb_oidc/aws_service_workflow.ts +1 -1
  147. package/src/cmap/auth/mongodb_oidc/callback_lock_cache.ts +2 -1
  148. package/src/cmap/auth/mongodb_oidc/service_workflow.ts +1 -1
  149. package/src/cmap/auth/scram.ts +2 -2
  150. package/src/cmap/commands.ts +28 -132
  151. package/src/cmap/connect.ts +4 -4
  152. package/src/cmap/connection.ts +107 -43
  153. package/src/cmap/connection_pool.ts +32 -29
  154. package/src/cmap/handshake/client_metadata.ts +2 -5
  155. package/src/cmap/wire_protocol/compression.ts +11 -13
  156. package/src/cmap/wire_protocol/on_demand/document.ts +338 -0
  157. package/src/cmap/wire_protocol/responses.ts +237 -0
  158. package/src/collection.ts +87 -58
  159. package/src/connection_string.ts +9 -7
  160. package/src/cursor/abstract_cursor.ts +102 -38
  161. package/src/cursor/aggregation_cursor.ts +32 -34
  162. package/src/cursor/find_cursor.ts +33 -21
  163. package/src/cursor/list_search_indexes_cursor.ts +1 -1
  164. package/src/cursor/run_command_cursor.ts +3 -2
  165. package/src/db.ts +42 -21
  166. package/src/deps.ts +52 -40
  167. package/src/encrypter.ts +14 -5
  168. package/src/error.ts +9 -3
  169. package/src/gridfs/download.ts +19 -31
  170. package/src/gridfs/index.ts +2 -0
  171. package/src/gridfs/upload.ts +11 -8
  172. package/src/index.ts +13 -5
  173. package/src/mongo_client.ts +21 -15
  174. package/src/mongo_logger.ts +3 -0
  175. package/src/mongo_types.ts +1 -1
  176. package/src/operations/aggregate.ts +2 -1
  177. package/src/operations/command.ts +1 -1
  178. package/src/operations/create_collection.ts +7 -2
  179. package/src/operations/delete.ts +4 -3
  180. package/src/operations/drop.ts +1 -1
  181. package/src/operations/execute_operation.ts +29 -10
  182. package/src/operations/find.ts +13 -14
  183. package/src/operations/get_more.ts +9 -1
  184. package/src/operations/indexes.ts +103 -176
  185. package/src/operations/insert.ts +2 -2
  186. package/src/operations/kill_cursors.ts +3 -2
  187. package/src/operations/list_collections.ts +5 -1
  188. package/src/operations/list_databases.ts +1 -1
  189. package/src/operations/operation.ts +3 -0
  190. package/src/operations/run_command.ts +6 -4
  191. package/src/operations/search_indexes/create.ts +4 -1
  192. package/src/operations/stats.ts +1 -1
  193. package/src/operations/update.ts +7 -7
  194. package/src/sdam/common.ts +8 -2
  195. package/src/sdam/monitor.ts +178 -61
  196. package/src/sdam/server.ts +27 -20
  197. package/src/sdam/server_description.ts +8 -3
  198. package/src/sdam/server_selection.ts +2 -3
  199. package/src/sdam/srv_polling.ts +3 -2
  200. package/src/sdam/topology.ts +114 -117
  201. package/src/sdam/topology_description.ts +14 -4
  202. package/src/sessions.ts +168 -148
  203. package/src/timeout.ts +96 -0
  204. package/src/utils.ts +85 -32
  205. package/lib/operations/common_functions.js +0 -38
  206. package/lib/operations/common_functions.js.map +0 -1
  207. package/src/operations/common_functions.ts +0 -79
@@ -1,5 +1,3 @@
1
- import { promisify } from 'util';
2
-
3
1
  import type { BSONSerializeOptions, Document } from '../bson';
4
2
  import type { MongoCredentials } from '../cmap/auth/mongo_credentials';
5
3
  import type { ConnectionEvents } from '../cmap/connection';
@@ -35,6 +33,7 @@ import { MongoLoggableComponent, type MongoLogger, SeverityLevel } from '../mong
35
33
  import { TypedEventEmitter } from '../mongo_types';
36
34
  import { ReadPreference, type ReadPreferenceLike } from '../read_preference';
37
35
  import type { ClientSession } from '../sessions';
36
+ import { Timeout, TimeoutError } from '../timeout';
38
37
  import type { Transaction } from '../transactions';
39
38
  import {
40
39
  type Callback,
@@ -44,8 +43,8 @@ import {
44
43
  makeStateMachine,
45
44
  now,
46
45
  ns,
47
- shuffle,
48
- TimeoutController
46
+ promiseWithResolvers,
47
+ shuffle
49
48
  } from '../utils';
50
49
  import {
51
50
  _advanceClusterTime,
@@ -105,9 +104,10 @@ export interface ServerSelectionRequest {
105
104
  mongoLogger: MongoLogger | undefined;
106
105
  transaction?: Transaction;
107
106
  startTime: number;
108
- callback: ServerSelectionCallback;
107
+ resolve: (server: Server) => void;
108
+ reject: (error: MongoError) => void;
109
109
  [kCancelled]?: boolean;
110
- timeoutController: TimeoutController;
110
+ timeout: Timeout;
111
111
  operationName: string;
112
112
  waitingLogged: boolean;
113
113
  previousServer?: ServerDescription;
@@ -178,6 +178,8 @@ export interface SelectServerOptions {
178
178
  session?: ClientSession;
179
179
  operationName: string;
180
180
  previousServer?: ServerDescription;
181
+ /** @internal*/
182
+ timeout?: Timeout;
181
183
  }
182
184
 
183
185
  /** @public */
@@ -215,6 +217,9 @@ export class Topology extends TypedEventEmitter<TopologyEvents> {
215
217
 
216
218
  client!: MongoClient;
217
219
 
220
+ /** @internal */
221
+ private connectionLock?: Promise<Topology>;
222
+
218
223
  /** @event */
219
224
  static readonly SERVER_OPENING = SERVER_OPENING;
220
225
  /** @event */
@@ -238,11 +243,6 @@ export class Topology extends TypedEventEmitter<TopologyEvents> {
238
243
  /** @event */
239
244
  static readonly TIMEOUT = TIMEOUT;
240
245
 
241
- selectServerAsync: (
242
- selector: string | ReadPreference | ServerSelector,
243
- options: SelectServerOptions
244
- ) => Promise<Server>;
245
-
246
246
  /**
247
247
  * @param seedlist - a list of HostAddress instances to connect to
248
248
  */
@@ -254,14 +254,6 @@ export class Topology extends TypedEventEmitter<TopologyEvents> {
254
254
  super();
255
255
 
256
256
  this.client = client;
257
- this.selectServerAsync = promisify(
258
- (
259
- selector: string | ReadPreference | ServerSelector,
260
- options: SelectServerOptions,
261
- callback: (e: Error, r: Server) => void
262
- ) => this.selectServer(selector, options, callback as any)
263
- );
264
-
265
257
  // Options should only be undefined in tests, MongoClient will always have defined options
266
258
  options = options ?? {
267
259
  hosts: [HostAddress.fromString('localhost:27017')],
@@ -351,6 +343,7 @@ export class Topology extends TypedEventEmitter<TopologyEvents> {
351
343
 
352
344
  this.on(Topology.TOPOLOGY_DESCRIPTION_CHANGED, this.s.detectShardedTopology);
353
345
  }
346
+ this.connectionLock = undefined;
354
347
  }
355
348
 
356
349
  private detectShardedTopology(event: TopologyDescriptionChangedEvent) {
@@ -411,17 +404,22 @@ export class Topology extends TypedEventEmitter<TopologyEvents> {
411
404
  }
412
405
 
413
406
  /** Initiate server connect */
414
- connect(callback: Callback): void;
415
- connect(options: ConnectOptions, callback: Callback): void;
416
- connect(options?: ConnectOptions | Callback, callback?: Callback): void {
417
- if (typeof options === 'function') (callback = options), (options = {});
407
+ async connect(options?: ConnectOptions): Promise<Topology> {
408
+ this.connectionLock ??= this._connect(options);
409
+ try {
410
+ await this.connectionLock;
411
+ return this;
412
+ } finally {
413
+ this.connectionLock = undefined;
414
+ }
415
+
416
+ return this;
417
+ }
418
+
419
+ private async _connect(options?: ConnectOptions): Promise<Topology> {
418
420
  options = options ?? {};
419
421
  if (this.s.state === STATE_CONNECTED) {
420
- if (typeof callback === 'function') {
421
- callback();
422
- }
423
-
424
- return;
422
+ return this;
425
423
  }
426
424
 
427
425
  stateTransition(this, STATE_CONNECTING);
@@ -459,40 +457,33 @@ export class Topology extends TypedEventEmitter<TopologyEvents> {
459
457
  }
460
458
  }
461
459
 
462
- const exitWithError = (error: Error) =>
463
- callback ? callback(error) : this.emit(Topology.ERROR, error);
464
-
465
460
  const readPreference = options.readPreference ?? ReadPreference.primary;
466
461
  const selectServerOptions = { operationName: 'ping', ...options };
467
- this.selectServer(
468
- readPreferenceServerSelector(readPreference),
469
- selectServerOptions,
470
- (err, server) => {
471
- if (err) {
472
- this.close();
473
- return exitWithError(err);
474
- }
475
-
476
- const skipPingOnConnect = this.s.options[Symbol.for('@@mdb.skipPingOnConnect')] === true;
477
- if (!skipPingOnConnect && server && this.s.credentials) {
478
- server.command(ns('admin.$cmd'), { ping: 1 }, {}).then(() => {
479
- stateTransition(this, STATE_CONNECTED);
480
- this.emit(Topology.OPEN, this);
481
- this.emit(Topology.CONNECT, this);
482
-
483
- callback?.(undefined, this);
484
- }, exitWithError);
485
-
486
- return;
487
- }
462
+ try {
463
+ const server = await this.selectServer(
464
+ readPreferenceServerSelector(readPreference),
465
+ selectServerOptions
466
+ );
488
467
 
468
+ const skipPingOnConnect = this.s.options[Symbol.for('@@mdb.skipPingOnConnect')] === true;
469
+ if (!skipPingOnConnect && server && this.s.credentials) {
470
+ await server.command(ns('admin.$cmd'), { ping: 1 }, {});
489
471
  stateTransition(this, STATE_CONNECTED);
490
472
  this.emit(Topology.OPEN, this);
491
473
  this.emit(Topology.CONNECT, this);
492
474
 
493
- callback?.(undefined, this);
475
+ return this;
494
476
  }
495
- );
477
+
478
+ stateTransition(this, STATE_CONNECTED);
479
+ this.emit(Topology.OPEN, this);
480
+ this.emit(Topology.CONNECT, this);
481
+
482
+ return this;
483
+ } catch (error) {
484
+ this.close();
485
+ throw error;
486
+ }
496
487
  }
497
488
 
498
489
  /** Close this topology */
@@ -533,11 +524,10 @@ export class Topology extends TypedEventEmitter<TopologyEvents> {
533
524
  * @param callback - The callback used to indicate success or failure
534
525
  * @returns An instance of a `Server` meeting the criteria of the predicate provided
535
526
  */
536
- selectServer(
527
+ async selectServer(
537
528
  selector: string | ReadPreference | ServerSelector,
538
- options: SelectServerOptions,
539
- callback: Callback<Server>
540
- ): void {
529
+ options: SelectServerOptions
530
+ ): Promise<Server> {
541
531
  let serverSelector;
542
532
  if (typeof selector !== 'function') {
543
533
  if (typeof selector === 'string') {
@@ -588,53 +578,62 @@ export class Topology extends TypedEventEmitter<TopologyEvents> {
588
578
  )
589
579
  );
590
580
  }
591
- callback(undefined, transaction.server);
592
- return;
581
+ return transaction.server;
593
582
  }
594
583
 
584
+ const { promise: serverPromise, resolve, reject } = promiseWithResolvers<Server>();
585
+ const timeout = Timeout.expires(options.serverSelectionTimeoutMS ?? 0);
595
586
  const waitQueueMember: ServerSelectionRequest = {
596
587
  serverSelector,
597
588
  topologyDescription: this.description,
598
589
  mongoLogger: this.client.mongoLogger,
599
590
  transaction,
600
- callback,
601
- timeoutController: new TimeoutController(options.serverSelectionTimeoutMS),
591
+ resolve,
592
+ reject,
593
+ timeout,
602
594
  startTime: now(),
603
595
  operationName: options.operationName,
604
596
  waitingLogged: false,
605
597
  previousServer: options.previousServer
606
598
  };
607
599
 
608
- waitQueueMember.timeoutController.signal.addEventListener('abort', () => {
609
- waitQueueMember[kCancelled] = true;
610
- waitQueueMember.timeoutController.clear();
611
- const timeoutError = new MongoServerSelectionError(
612
- `Server selection timed out after ${options.serverSelectionTimeoutMS} ms`,
613
- this.description
614
- );
615
- if (
616
- this.client.mongoLogger?.willLog(
617
- MongoLoggableComponent.SERVER_SELECTION,
618
- SeverityLevel.DEBUG
619
- )
620
- ) {
621
- this.client.mongoLogger?.debug(
622
- MongoLoggableComponent.SERVER_SELECTION,
623
- new ServerSelectionFailedEvent(
624
- selector,
625
- this.description,
626
- timeoutError,
627
- options.operationName
628
- )
629
- );
630
- }
631
- waitQueueMember.callback(timeoutError);
632
- });
633
-
634
600
  this[kWaitQueue].push(waitQueueMember);
635
601
  processWaitQueue(this);
636
- }
637
602
 
603
+ try {
604
+ return await Promise.race([serverPromise, waitQueueMember.timeout]);
605
+ } catch (error) {
606
+ if (TimeoutError.is(error)) {
607
+ // Timeout
608
+ waitQueueMember[kCancelled] = true;
609
+ timeout.clear();
610
+ const timeoutError = new MongoServerSelectionError(
611
+ `Server selection timed out after ${options.serverSelectionTimeoutMS} ms`,
612
+ this.description
613
+ );
614
+ if (
615
+ this.client.mongoLogger?.willLog(
616
+ MongoLoggableComponent.SERVER_SELECTION,
617
+ SeverityLevel.DEBUG
618
+ )
619
+ ) {
620
+ this.client.mongoLogger?.debug(
621
+ MongoLoggableComponent.SERVER_SELECTION,
622
+ new ServerSelectionFailedEvent(
623
+ selector,
624
+ this.description,
625
+ timeoutError,
626
+ options.operationName
627
+ )
628
+ );
629
+ }
630
+
631
+ throw timeoutError;
632
+ }
633
+ // Other server selection error
634
+ throw error;
635
+ }
636
+ }
638
637
  /**
639
638
  * Update the internal TopologyDescription with a ServerDescription
640
639
  *
@@ -883,35 +882,33 @@ function updateServers(topology: Topology, incomingServerDescription?: ServerDes
883
882
  }
884
883
  }
885
884
 
886
- function drainWaitQueue(queue: List<ServerSelectionRequest>, err?: MongoDriverError) {
885
+ function drainWaitQueue(queue: List<ServerSelectionRequest>, drainError: MongoDriverError) {
887
886
  while (queue.length) {
888
887
  const waitQueueMember = queue.shift();
889
888
  if (!waitQueueMember) {
890
889
  continue;
891
890
  }
892
891
 
893
- waitQueueMember.timeoutController.clear();
892
+ waitQueueMember.timeout.clear();
894
893
 
895
894
  if (!waitQueueMember[kCancelled]) {
896
- if (err) {
897
- if (
898
- waitQueueMember.mongoLogger?.willLog(
899
- MongoLoggableComponent.SERVER_SELECTION,
900
- SeverityLevel.DEBUG
895
+ if (
896
+ waitQueueMember.mongoLogger?.willLog(
897
+ MongoLoggableComponent.SERVER_SELECTION,
898
+ SeverityLevel.DEBUG
899
+ )
900
+ ) {
901
+ waitQueueMember.mongoLogger?.debug(
902
+ MongoLoggableComponent.SERVER_SELECTION,
903
+ new ServerSelectionFailedEvent(
904
+ waitQueueMember.serverSelector,
905
+ waitQueueMember.topologyDescription,
906
+ drainError,
907
+ waitQueueMember.operationName
901
908
  )
902
- ) {
903
- waitQueueMember.mongoLogger?.debug(
904
- MongoLoggableComponent.SERVER_SELECTION,
905
- new ServerSelectionFailedEvent(
906
- waitQueueMember.serverSelector,
907
- waitQueueMember.topologyDescription,
908
- err,
909
- waitQueueMember.operationName
910
- )
911
- );
912
- }
909
+ );
913
910
  }
914
- waitQueueMember.callback(err);
911
+ waitQueueMember.reject(drainError);
915
912
  }
916
913
  }
917
914
  }
@@ -946,8 +943,8 @@ function processWaitQueue(topology: Topology) {
946
943
  previousServer ? [previousServer] : []
947
944
  )
948
945
  : serverDescriptions;
949
- } catch (e) {
950
- waitQueueMember.timeoutController.clear();
946
+ } catch (selectorError) {
947
+ waitQueueMember.timeout.clear();
951
948
  if (
952
949
  topology.client.mongoLogger?.willLog(
953
950
  MongoLoggableComponent.SERVER_SELECTION,
@@ -959,12 +956,12 @@ function processWaitQueue(topology: Topology) {
959
956
  new ServerSelectionFailedEvent(
960
957
  waitQueueMember.serverSelector,
961
958
  topology.description,
962
- e,
959
+ selectorError,
963
960
  waitQueueMember.operationName
964
961
  )
965
962
  );
966
963
  }
967
- waitQueueMember.callback(e);
964
+ waitQueueMember.reject(selectorError);
968
965
  continue;
969
966
  }
970
967
 
@@ -1007,7 +1004,7 @@ function processWaitQueue(topology: Topology) {
1007
1004
  }
1008
1005
 
1009
1006
  if (!selectedServer) {
1010
- const error = new MongoServerSelectionError(
1007
+ const serverSelectionError = new MongoServerSelectionError(
1011
1008
  'server selection returned a server description but the server was not found in the topology',
1012
1009
  topology.description
1013
1010
  );
@@ -1022,12 +1019,12 @@ function processWaitQueue(topology: Topology) {
1022
1019
  new ServerSelectionFailedEvent(
1023
1020
  waitQueueMember.serverSelector,
1024
1021
  topology.description,
1025
- error,
1022
+ serverSelectionError,
1026
1023
  waitQueueMember.operationName
1027
1024
  )
1028
1025
  );
1029
1026
  }
1030
- waitQueueMember.callback(error);
1027
+ waitQueueMember.reject(serverSelectionError);
1031
1028
  return;
1032
1029
  }
1033
1030
  const transaction = waitQueueMember.transaction;
@@ -1035,7 +1032,7 @@ function processWaitQueue(topology: Topology) {
1035
1032
  transaction.pinServer(selectedServer);
1036
1033
  }
1037
1034
 
1038
- waitQueueMember.timeoutController.clear();
1035
+ waitQueueMember.timeout.clear();
1039
1036
 
1040
1037
  if (
1041
1038
  topology.client.mongoLogger?.willLog(
@@ -1053,7 +1050,7 @@ function processWaitQueue(topology: Topology) {
1053
1050
  )
1054
1051
  );
1055
1052
  }
1056
- waitQueueMember.callback(undefined, selectedServer);
1053
+ waitQueueMember.resolve(selectedServer);
1057
1054
  }
1058
1055
 
1059
1056
  if (topology[kWaitQueue].length > 0) {
@@ -1,6 +1,6 @@
1
- import type { ObjectId } from '../bson';
1
+ import { EJSON, type ObjectId } from '../bson';
2
2
  import * as WIRE_CONSTANTS from '../cmap/wire_protocol/constants';
3
- import { MongoRuntimeError, type MongoServerError } from '../error';
3
+ import { type MongoError, MongoRuntimeError } from '../error';
4
4
  import { compareObjectId, shuffle } from '../utils';
5
5
  import { ServerType, TopologyType } from './common';
6
6
  import { ServerDescription } from './server_description';
@@ -307,13 +307,13 @@ export class TopologyDescription {
307
307
  );
308
308
  }
309
309
 
310
- get error(): MongoServerError | null {
310
+ get error(): MongoError | null {
311
311
  const descriptionsWithError = Array.from(this.servers.values()).filter(
312
312
  (sd: ServerDescription) => sd.error
313
313
  );
314
314
 
315
315
  if (descriptionsWithError.length > 0) {
316
- return descriptionsWithError[0].error as MongoServerError;
316
+ return descriptionsWithError[0].error;
317
317
  }
318
318
 
319
319
  return null;
@@ -342,6 +342,16 @@ export class TopologyDescription {
342
342
  hasServer(address: string): boolean {
343
343
  return this.servers.has(address);
344
344
  }
345
+
346
+ /**
347
+ * Returns a JSON-serializable representation of the TopologyDescription. This is primarily
348
+ * intended for use with JSON.stringify().
349
+ *
350
+ * This method will not throw.
351
+ */
352
+ toJSON() {
353
+ return EJSON.serialize(this);
354
+ }
345
355
  }
346
356
 
347
357
  function topologyTypeForServerType(serverType: ServerType): TopologyType {