mongodb 6.10.0 → 6.11.0-dev.20241128.sha.4842cd8a

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 (228) hide show
  1. package/README.md +2 -0
  2. package/lib/admin.js +3 -2
  3. package/lib/admin.js.map +1 -1
  4. package/lib/beta.d.ts +562 -45
  5. package/lib/bulk/common.js +4 -4
  6. package/lib/bulk/common.js.map +1 -1
  7. package/lib/change_stream.js +111 -51
  8. package/lib/change_stream.js.map +1 -1
  9. package/lib/client-side-encryption/auto_encrypter.js +8 -5
  10. package/lib/client-side-encryption/auto_encrypter.js.map +1 -1
  11. package/lib/client-side-encryption/client_encryption.js +48 -18
  12. package/lib/client-side-encryption/client_encryption.js.map +1 -1
  13. package/lib/client-side-encryption/state_machine.js +43 -29
  14. package/lib/client-side-encryption/state_machine.js.map +1 -1
  15. package/lib/cmap/auth/mongo_credentials.js +5 -2
  16. package/lib/cmap/auth/mongo_credentials.js.map +1 -1
  17. package/lib/cmap/auth/mongodb_aws.js +1 -1
  18. package/lib/cmap/auth/mongodb_aws.js.map +1 -1
  19. package/lib/cmap/auth/mongodb_oidc/k8s_machine_workflow.js +38 -0
  20. package/lib/cmap/auth/mongodb_oidc/k8s_machine_workflow.js.map +1 -0
  21. package/lib/cmap/auth/mongodb_oidc.js +2 -0
  22. package/lib/cmap/auth/mongodb_oidc.js.map +1 -1
  23. package/lib/cmap/connect.js +13 -1
  24. package/lib/cmap/connect.js.map +1 -1
  25. package/lib/cmap/connection.js +75 -17
  26. package/lib/cmap/connection.js.map +1 -1
  27. package/lib/cmap/connection_pool.js +14 -12
  28. package/lib/cmap/connection_pool.js.map +1 -1
  29. package/lib/cmap/wire_protocol/on_data.js +5 -1
  30. package/lib/cmap/wire_protocol/on_data.js.map +1 -1
  31. package/lib/cmap/wire_protocol/responses.js +30 -0
  32. package/lib/cmap/wire_protocol/responses.js.map +1 -1
  33. package/lib/collection.js +62 -3
  34. package/lib/collection.js.map +1 -1
  35. package/lib/connection_string.js +2 -0
  36. package/lib/connection_string.js.map +1 -1
  37. package/lib/cursor/abstract_cursor.js +221 -38
  38. package/lib/cursor/abstract_cursor.js.map +1 -1
  39. package/lib/cursor/aggregation_cursor.js +29 -7
  40. package/lib/cursor/aggregation_cursor.js.map +1 -1
  41. package/lib/cursor/change_stream_cursor.js +2 -2
  42. package/lib/cursor/change_stream_cursor.js.map +1 -1
  43. package/lib/cursor/client_bulk_write_cursor.js +1 -1
  44. package/lib/cursor/client_bulk_write_cursor.js.map +1 -1
  45. package/lib/cursor/find_cursor.js +18 -8
  46. package/lib/cursor/find_cursor.js.map +1 -1
  47. package/lib/cursor/list_collections_cursor.js +1 -1
  48. package/lib/cursor/list_collections_cursor.js.map +1 -1
  49. package/lib/cursor/list_indexes_cursor.js +1 -1
  50. package/lib/cursor/list_indexes_cursor.js.map +1 -1
  51. package/lib/cursor/run_command_cursor.js +6 -4
  52. package/lib/cursor/run_command_cursor.js.map +1 -1
  53. package/lib/db.js +63 -3
  54. package/lib/db.js.map +1 -1
  55. package/lib/error.js +34 -9
  56. package/lib/error.js.map +1 -1
  57. package/lib/explain.js +57 -1
  58. package/lib/explain.js.map +1 -1
  59. package/lib/gridfs/download.js +31 -3
  60. package/lib/gridfs/download.js.map +1 -1
  61. package/lib/gridfs/index.js +49 -14
  62. package/lib/gridfs/index.js.map +1 -1
  63. package/lib/gridfs/upload.js +80 -22
  64. package/lib/gridfs/upload.js.map +1 -1
  65. package/lib/index.js +9 -5
  66. package/lib/index.js.map +1 -1
  67. package/lib/mongo_client.js +70 -1
  68. package/lib/mongo_client.js.map +1 -1
  69. package/lib/operations/aggregate.js +2 -2
  70. package/lib/operations/aggregate.js.map +1 -1
  71. package/lib/operations/bulk_write.js +7 -2
  72. package/lib/operations/bulk_write.js.map +1 -1
  73. package/lib/operations/client_bulk_write/client_bulk_write.js +3 -3
  74. package/lib/operations/client_bulk_write/client_bulk_write.js.map +1 -1
  75. package/lib/operations/client_bulk_write/executor.js +14 -3
  76. package/lib/operations/client_bulk_write/executor.js.map +1 -1
  77. package/lib/operations/command.js +5 -2
  78. package/lib/operations/command.js.map +1 -1
  79. package/lib/operations/count.js +2 -2
  80. package/lib/operations/count.js.map +1 -1
  81. package/lib/operations/create_collection.js +8 -7
  82. package/lib/operations/create_collection.js.map +1 -1
  83. package/lib/operations/delete.js +6 -6
  84. package/lib/operations/delete.js.map +1 -1
  85. package/lib/operations/distinct.js +2 -2
  86. package/lib/operations/distinct.js.map +1 -1
  87. package/lib/operations/drop.js +8 -8
  88. package/lib/operations/drop.js.map +1 -1
  89. package/lib/operations/estimated_document_count.js +2 -2
  90. package/lib/operations/estimated_document_count.js.map +1 -1
  91. package/lib/operations/execute_operation.js +16 -10
  92. package/lib/operations/execute_operation.js.map +1 -1
  93. package/lib/operations/find.js +6 -3
  94. package/lib/operations/find.js.map +1 -1
  95. package/lib/operations/find_and_modify.js +2 -2
  96. package/lib/operations/find_and_modify.js.map +1 -1
  97. package/lib/operations/get_more.js +2 -1
  98. package/lib/operations/get_more.js.map +1 -1
  99. package/lib/operations/indexes.js +6 -6
  100. package/lib/operations/indexes.js.map +1 -1
  101. package/lib/operations/insert.js +6 -6
  102. package/lib/operations/insert.js.map +1 -1
  103. package/lib/operations/kill_cursors.js +5 -2
  104. package/lib/operations/kill_cursors.js.map +1 -1
  105. package/lib/operations/list_collections.js +2 -2
  106. package/lib/operations/list_collections.js.map +1 -1
  107. package/lib/operations/list_databases.js +2 -2
  108. package/lib/operations/list_databases.js.map +1 -1
  109. package/lib/operations/operation.js.map +1 -1
  110. package/lib/operations/profiling_level.js +2 -2
  111. package/lib/operations/profiling_level.js.map +1 -1
  112. package/lib/operations/remove_user.js +2 -2
  113. package/lib/operations/remove_user.js.map +1 -1
  114. package/lib/operations/rename.js +2 -2
  115. package/lib/operations/rename.js.map +1 -1
  116. package/lib/operations/run_command.js +6 -4
  117. package/lib/operations/run_command.js.map +1 -1
  118. package/lib/operations/search_indexes/create.js +5 -2
  119. package/lib/operations/search_indexes/create.js.map +1 -1
  120. package/lib/operations/search_indexes/drop.js +2 -2
  121. package/lib/operations/search_indexes/drop.js.map +1 -1
  122. package/lib/operations/search_indexes/update.js +2 -2
  123. package/lib/operations/search_indexes/update.js.map +1 -1
  124. package/lib/operations/set_profiling_level.js +2 -2
  125. package/lib/operations/set_profiling_level.js.map +1 -1
  126. package/lib/operations/stats.js +2 -2
  127. package/lib/operations/stats.js.map +1 -1
  128. package/lib/operations/update.js +8 -8
  129. package/lib/operations/update.js.map +1 -1
  130. package/lib/operations/validate_collection.js +2 -2
  131. package/lib/operations/validate_collection.js.map +1 -1
  132. package/lib/read_concern.js +1 -1
  133. package/lib/sdam/common.js +0 -7
  134. package/lib/sdam/common.js.map +1 -1
  135. package/lib/sdam/server.js +4 -1
  136. package/lib/sdam/server.js.map +1 -1
  137. package/lib/sdam/server_description.js +4 -2
  138. package/lib/sdam/server_description.js.map +1 -1
  139. package/lib/sdam/server_selection.js +5 -2
  140. package/lib/sdam/server_selection.js.map +1 -1
  141. package/lib/sdam/topology.js +38 -15
  142. package/lib/sdam/topology.js.map +1 -1
  143. package/lib/sessions.js +157 -98
  144. package/lib/sessions.js.map +1 -1
  145. package/lib/timeout.js +231 -16
  146. package/lib/timeout.js.map +1 -1
  147. package/lib/utils.js +36 -19
  148. package/lib/utils.js.map +1 -1
  149. package/lib/write_concern.js.map +1 -1
  150. package/mongodb.d.ts +562 -45
  151. package/package.json +18 -17
  152. package/src/admin.ts +6 -2
  153. package/src/bulk/common.ts +17 -5
  154. package/src/change_stream.ts +127 -52
  155. package/src/client-side-encryption/auto_encrypter.ts +12 -5
  156. package/src/client-side-encryption/client_encryption.ts +103 -20
  157. package/src/client-side-encryption/state_machine.ts +66 -32
  158. package/src/cmap/auth/mongo_credentials.ts +6 -3
  159. package/src/cmap/auth/mongodb_aws.ts +1 -1
  160. package/src/cmap/auth/mongodb_oidc/k8s_machine_workflow.ts +38 -0
  161. package/src/cmap/auth/mongodb_oidc.ts +3 -1
  162. package/src/cmap/connect.ts +18 -1
  163. package/src/cmap/connection.ts +105 -17
  164. package/src/cmap/connection_pool.ts +15 -17
  165. package/src/cmap/handshake/client_metadata.ts +1 -1
  166. package/src/cmap/wire_protocol/on_data.ts +11 -1
  167. package/src/cmap/wire_protocol/responses.ts +35 -1
  168. package/src/collection.ts +81 -9
  169. package/src/connection_string.ts +2 -0
  170. package/src/cursor/abstract_cursor.ts +287 -39
  171. package/src/cursor/aggregation_cursor.ts +54 -8
  172. package/src/cursor/change_stream_cursor.ts +6 -2
  173. package/src/cursor/client_bulk_write_cursor.ts +6 -2
  174. package/src/cursor/find_cursor.ts +40 -9
  175. package/src/cursor/list_collections_cursor.ts +1 -1
  176. package/src/cursor/list_indexes_cursor.ts +1 -1
  177. package/src/cursor/run_command_cursor.ts +50 -5
  178. package/src/db.ts +75 -7
  179. package/src/error.ts +33 -8
  180. package/src/explain.ts +85 -0
  181. package/src/gridfs/download.ts +43 -4
  182. package/src/gridfs/index.ts +64 -16
  183. package/src/gridfs/upload.ts +153 -45
  184. package/src/index.ts +27 -5
  185. package/src/mongo_client.ts +76 -4
  186. package/src/operations/aggregate.ts +10 -2
  187. package/src/operations/bulk_write.ts +9 -2
  188. package/src/operations/client_bulk_write/client_bulk_write.ts +11 -3
  189. package/src/operations/client_bulk_write/executor.ts +15 -3
  190. package/src/operations/command.ts +18 -8
  191. package/src/operations/count.ts +10 -3
  192. package/src/operations/create_collection.ts +14 -7
  193. package/src/operations/delete.ts +15 -6
  194. package/src/operations/distinct.ts +7 -2
  195. package/src/operations/drop.ts +18 -8
  196. package/src/operations/estimated_document_count.ts +7 -2
  197. package/src/operations/execute_operation.ts +22 -13
  198. package/src/operations/find.ts +17 -5
  199. package/src/operations/find_and_modify.ts +7 -2
  200. package/src/operations/get_more.ts +4 -1
  201. package/src/operations/indexes.ts +20 -7
  202. package/src/operations/insert.ts +13 -6
  203. package/src/operations/kill_cursors.ts +10 -2
  204. package/src/operations/list_collections.ts +10 -1
  205. package/src/operations/list_databases.ts +9 -2
  206. package/src/operations/operation.ts +16 -2
  207. package/src/operations/profiling_level.ts +7 -2
  208. package/src/operations/remove_user.ts +7 -2
  209. package/src/operations/rename.ts +7 -2
  210. package/src/operations/run_command.ts +23 -4
  211. package/src/operations/search_indexes/create.ts +10 -2
  212. package/src/operations/search_indexes/drop.ts +7 -2
  213. package/src/operations/search_indexes/update.ts +7 -2
  214. package/src/operations/set_profiling_level.ts +4 -2
  215. package/src/operations/stats.ts +7 -2
  216. package/src/operations/update.ts +16 -8
  217. package/src/operations/validate_collection.ts +7 -2
  218. package/src/read_concern.ts +1 -1
  219. package/src/sdam/common.ts +0 -11
  220. package/src/sdam/server.ts +14 -4
  221. package/src/sdam/server_description.ts +6 -2
  222. package/src/sdam/server_selection.ts +5 -2
  223. package/src/sdam/topology.ts +43 -27
  224. package/src/sessions.ts +206 -120
  225. package/src/timeout.ts +327 -23
  226. package/src/transactions.ts +1 -1
  227. package/src/utils.ts +47 -30
  228. package/src/write_concern.ts +6 -3
@@ -5,6 +5,7 @@ import { type TODO_NODE_3286 } from '../mongo_types';
5
5
  import type { ReadPreferenceLike } from '../read_preference';
6
6
  import type { Server } from '../sdam/server';
7
7
  import type { ClientSession } from '../sessions';
8
+ import { type TimeoutContext } from '../timeout';
8
9
  import { MongoDBNamespace } from '../utils';
9
10
  import { AbstractOperation } from './operation';
10
11
 
@@ -14,6 +15,13 @@ export type RunCommandOptions = {
14
15
  session?: ClientSession;
15
16
  /** The read preference */
16
17
  readPreference?: ReadPreferenceLike;
18
+ /**
19
+ * @experimental
20
+ * Specifies the time an operation will run until it throws a timeout error
21
+ */
22
+ timeoutMS?: number;
23
+ /** @internal */
24
+ omitMaxTimeMS?: boolean;
17
25
  } & BSONSerializeOptions;
18
26
 
19
27
  /** @internal */
@@ -31,7 +39,11 @@ export class RunCommandOperation<T = Document> extends AbstractOperation<T> {
31
39
  return 'runCommand' as const;
32
40
  }
33
41
 
34
- override async execute(server: Server, session: ClientSession | undefined): Promise<T> {
42
+ override async execute(
43
+ server: Server,
44
+ session: ClientSession | undefined,
45
+ timeoutContext: TimeoutContext
46
+ ): Promise<T> {
35
47
  this.server = server;
36
48
  const res: TODO_NODE_3286 = await server.command(
37
49
  this.ns,
@@ -39,10 +51,12 @@ export class RunCommandOperation<T = Document> extends AbstractOperation<T> {
39
51
  {
40
52
  ...this.options,
41
53
  readPreference: this.readPreference,
42
- session
54
+ session,
55
+ timeoutContext
43
56
  },
44
57
  this.options.responseType
45
58
  );
59
+
46
60
  return res;
47
61
  }
48
62
  }
@@ -63,12 +77,17 @@ export class RunAdminCommandOperation<T = Document> extends AbstractOperation<T>
63
77
  return 'runCommand' as const;
64
78
  }
65
79
 
66
- override async execute(server: Server, session: ClientSession | undefined): Promise<T> {
80
+ override async execute(
81
+ server: Server,
82
+ session: ClientSession | undefined,
83
+ timeoutContext: TimeoutContext
84
+ ): Promise<T> {
67
85
  this.server = server;
68
86
  const res: TODO_NODE_3286 = await server.command(this.ns, this.command, {
69
87
  ...this.options,
70
88
  readPreference: this.readPreference,
71
- session
89
+ session,
90
+ timeoutContext
72
91
  });
73
92
  return res;
74
93
  }
@@ -2,6 +2,7 @@ import type { Document } from '../../bson';
2
2
  import type { Collection } from '../../collection';
3
3
  import type { Server } from '../../sdam/server';
4
4
  import type { ClientSession } from '../../sessions';
5
+ import { type TimeoutContext } from '../../timeout';
5
6
  import { AbstractOperation } from '../operation';
6
7
 
7
8
  /**
@@ -31,14 +32,21 @@ export class CreateSearchIndexesOperation extends AbstractOperation<string[]> {
31
32
  return 'createSearchIndexes' as const;
32
33
  }
33
34
 
34
- override async execute(server: Server, session: ClientSession | undefined): Promise<string[]> {
35
+ override async execute(
36
+ server: Server,
37
+ session: ClientSession | undefined,
38
+ timeoutContext: TimeoutContext
39
+ ): Promise<string[]> {
35
40
  const namespace = this.collection.fullNamespace;
36
41
  const command = {
37
42
  createSearchIndexes: namespace.collection,
38
43
  indexes: this.descriptions
39
44
  };
40
45
 
41
- const res = await server.command(namespace, command, { session });
46
+ const res = await server.command(namespace, command, {
47
+ session,
48
+ timeoutContext
49
+ });
42
50
 
43
51
  const indexesCreated: Array<{ name: string }> = res?.indexesCreated ?? [];
44
52
  return indexesCreated.map(({ name }) => name);
@@ -3,6 +3,7 @@ import type { Collection } from '../../collection';
3
3
  import { MONGODB_ERROR_CODES, MongoServerError } from '../../error';
4
4
  import type { Server } from '../../sdam/server';
5
5
  import type { ClientSession } from '../../sessions';
6
+ import { type TimeoutContext } from '../../timeout';
6
7
  import { AbstractOperation } from '../operation';
7
8
 
8
9
  /** @internal */
@@ -18,7 +19,11 @@ export class DropSearchIndexOperation extends AbstractOperation<void> {
18
19
  return 'dropSearchIndex' as const;
19
20
  }
20
21
 
21
- override async execute(server: Server, session: ClientSession | undefined): Promise<void> {
22
+ override async execute(
23
+ server: Server,
24
+ session: ClientSession | undefined,
25
+ timeoutContext: TimeoutContext
26
+ ): Promise<void> {
22
27
  const namespace = this.collection.fullNamespace;
23
28
 
24
29
  const command: Document = {
@@ -30,7 +35,7 @@ export class DropSearchIndexOperation extends AbstractOperation<void> {
30
35
  }
31
36
 
32
37
  try {
33
- await server.command(namespace, command, { session });
38
+ await server.command(namespace, command, { session, timeoutContext });
34
39
  } catch (error) {
35
40
  const isNamespaceNotFoundError =
36
41
  error instanceof MongoServerError && error.code === MONGODB_ERROR_CODES.NamespaceNotFound;
@@ -2,6 +2,7 @@ import type { Document } from '../../bson';
2
2
  import type { Collection } from '../../collection';
3
3
  import type { Server } from '../../sdam/server';
4
4
  import type { ClientSession } from '../../sessions';
5
+ import { type TimeoutContext } from '../../timeout';
5
6
  import { AbstractOperation } from '../operation';
6
7
 
7
8
  /** @internal */
@@ -18,7 +19,11 @@ export class UpdateSearchIndexOperation extends AbstractOperation<void> {
18
19
  return 'updateSearchIndex' as const;
19
20
  }
20
21
 
21
- override async execute(server: Server, session: ClientSession | undefined): Promise<void> {
22
+ override async execute(
23
+ server: Server,
24
+ session: ClientSession | undefined,
25
+ timeoutContext: TimeoutContext
26
+ ): Promise<void> {
22
27
  const namespace = this.collection.fullNamespace;
23
28
  const command = {
24
29
  updateSearchIndex: namespace.collection,
@@ -26,7 +31,7 @@ export class UpdateSearchIndexOperation extends AbstractOperation<void> {
26
31
  definition: this.definition
27
32
  };
28
33
 
29
- await server.command(namespace, command, { session });
34
+ await server.command(namespace, command, { session, timeoutContext });
30
35
  return;
31
36
  }
32
37
  }
@@ -2,6 +2,7 @@ import type { Db } from '../db';
2
2
  import { MongoInvalidArgumentError } from '../error';
3
3
  import type { Server } from '../sdam/server';
4
4
  import type { ClientSession } from '../sessions';
5
+ import { type TimeoutContext } from '../timeout';
5
6
  import { enumToString } from '../utils';
6
7
  import { CommandOperation, type CommandOperationOptions } from './command';
7
8
 
@@ -53,7 +54,8 @@ export class SetProfilingLevelOperation extends CommandOperation<ProfilingLevel>
53
54
 
54
55
  override async execute(
55
56
  server: Server,
56
- session: ClientSession | undefined
57
+ session: ClientSession | undefined,
58
+ timeoutContext: TimeoutContext
57
59
  ): Promise<ProfilingLevel> {
58
60
  const level = this.level;
59
61
 
@@ -64,7 +66,7 @@ export class SetProfilingLevelOperation extends CommandOperation<ProfilingLevel>
64
66
  }
65
67
 
66
68
  // TODO(NODE-3483): Determine error to put here
67
- await super.executeCommand(server, session, { profile: this.profile });
69
+ await super.executeCommand(server, session, { profile: this.profile }, timeoutContext);
68
70
  return level;
69
71
  }
70
72
  }
@@ -2,6 +2,7 @@ import type { Document } from '../bson';
2
2
  import type { Db } from '../db';
3
3
  import type { Server } from '../sdam/server';
4
4
  import type { ClientSession } from '../sessions';
5
+ import { type TimeoutContext } from '../timeout';
5
6
  import { CommandOperation, type CommandOperationOptions } from './command';
6
7
  import { Aspect, defineAspects } from './operation';
7
8
 
@@ -24,13 +25,17 @@ export class DbStatsOperation extends CommandOperation<Document> {
24
25
  return 'dbStats' as const;
25
26
  }
26
27
 
27
- override async execute(server: Server, session: ClientSession | undefined): Promise<Document> {
28
+ override async execute(
29
+ server: Server,
30
+ session: ClientSession | undefined,
31
+ timeoutContext: TimeoutContext
32
+ ): Promise<Document> {
28
33
  const command: Document = { dbStats: true };
29
34
  if (this.options.scale != null) {
30
35
  command.scale = this.options.scale;
31
36
  }
32
37
 
33
- return await super.executeCommand(server, session, command);
38
+ return await super.executeCommand(server, session, command, timeoutContext);
34
39
  }
35
40
  }
36
41
 
@@ -4,6 +4,7 @@ import { MongoCompatibilityError, MongoInvalidArgumentError, MongoServerError }
4
4
  import type { InferIdType, TODO_NODE_3286 } from '../mongo_types';
5
5
  import type { Server } from '../sdam/server';
6
6
  import type { ClientSession } from '../sessions';
7
+ import { type TimeoutContext } from '../timeout';
7
8
  import { hasAtomicOperators, type MongoDBNamespace } from '../utils';
8
9
  import { type CollationOptions, CommandOperation, type CommandOperationOptions } from './command';
9
10
  import { Aspect, defineAspects, type Hint } from './operation';
@@ -91,7 +92,11 @@ export class UpdateOperation extends CommandOperation<Document> {
91
92
  return this.statements.every(op => op.multi == null || op.multi === false);
92
93
  }
93
94
 
94
- override async execute(server: Server, session: ClientSession | undefined): Promise<Document> {
95
+ override async execute(
96
+ server: Server,
97
+ session: ClientSession | undefined,
98
+ timeoutContext: TimeoutContext
99
+ ): Promise<Document> {
95
100
  const options = this.options ?? {};
96
101
  const ordered = typeof options.ordered === 'boolean' ? options.ordered : true;
97
102
  const command: Document = {
@@ -122,7 +127,7 @@ export class UpdateOperation extends CommandOperation<Document> {
122
127
  }
123
128
  }
124
129
 
125
- const res = await super.executeCommand(server, session, command);
130
+ const res = await super.executeCommand(server, session, command, timeoutContext);
126
131
  return res;
127
132
  }
128
133
  }
@@ -143,9 +148,10 @@ export class UpdateOneOperation extends UpdateOperation {
143
148
 
144
149
  override async execute(
145
150
  server: Server,
146
- session: ClientSession | undefined
151
+ session: ClientSession | undefined,
152
+ timeoutContext: TimeoutContext
147
153
  ): Promise<UpdateResult> {
148
- const res: TODO_NODE_3286 = await super.execute(server, session);
154
+ const res: TODO_NODE_3286 = await super.execute(server, session, timeoutContext);
149
155
  if (this.explain != null) return res;
150
156
  if (res.code) throw new MongoServerError(res);
151
157
  if (res.writeErrors) throw new MongoServerError(res.writeErrors[0]);
@@ -177,9 +183,10 @@ export class UpdateManyOperation extends UpdateOperation {
177
183
 
178
184
  override async execute(
179
185
  server: Server,
180
- session: ClientSession | undefined
186
+ session: ClientSession | undefined,
187
+ timeoutContext: TimeoutContext
181
188
  ): Promise<UpdateResult> {
182
- const res: TODO_NODE_3286 = await super.execute(server, session);
189
+ const res: TODO_NODE_3286 = await super.execute(server, session, timeoutContext);
183
190
  if (this.explain != null) return res;
184
191
  if (res.code) throw new MongoServerError(res);
185
192
  if (res.writeErrors) throw new MongoServerError(res.writeErrors[0]);
@@ -230,9 +237,10 @@ export class ReplaceOneOperation extends UpdateOperation {
230
237
 
231
238
  override async execute(
232
239
  server: Server,
233
- session: ClientSession | undefined
240
+ session: ClientSession | undefined,
241
+ timeoutContext: TimeoutContext
234
242
  ): Promise<UpdateResult> {
235
- const res: TODO_NODE_3286 = await super.execute(server, session);
243
+ const res: TODO_NODE_3286 = await super.execute(server, session, timeoutContext);
236
244
  if (this.explain != null) return res;
237
245
  if (res.code) throw new MongoServerError(res);
238
246
  if (res.writeErrors) throw new MongoServerError(res.writeErrors[0]);
@@ -3,6 +3,7 @@ import type { Document } from '../bson';
3
3
  import { MongoUnexpectedServerResponseError } from '../error';
4
4
  import type { Server } from '../sdam/server';
5
5
  import type { ClientSession } from '../sessions';
6
+ import { type TimeoutContext } from '../timeout';
6
7
  import { CommandOperation, type CommandOperationOptions } from './command';
7
8
 
8
9
  /** @public */
@@ -37,10 +38,14 @@ export class ValidateCollectionOperation extends CommandOperation<Document> {
37
38
  return 'validate' as const;
38
39
  }
39
40
 
40
- override async execute(server: Server, session: ClientSession | undefined): Promise<Document> {
41
+ override async execute(
42
+ server: Server,
43
+ session: ClientSession | undefined,
44
+ timeoutContext: TimeoutContext
45
+ ): Promise<Document> {
41
46
  const collectionName = this.collectionName;
42
47
 
43
- const doc = await super.executeCommand(server, session, this.command);
48
+ const doc = await super.executeCommand(server, session, this.command, timeoutContext);
44
49
  if (doc.result != null && typeof doc.result !== 'string')
45
50
  throw new MongoUnexpectedServerResponseError('Error with validation data');
46
51
  if (doc.result != null && doc.result.match(/exception|corrupt/) != null)
@@ -31,7 +31,7 @@ export class ReadConcern {
31
31
  * A spec test exists that allows level to be any string.
32
32
  * "invalid readConcern with out stage"
33
33
  * @see ./test/spec/crud/v2/aggregate-out-readConcern.json
34
- * @see https://github.com/mongodb/specifications/blob/master/source/read-write-concern/read-write-concern.rst#unknown-levels-and-additional-options-for-string-based-readconcerns
34
+ * @see https://github.com/mongodb/specifications/blob/master/source/read-write-concern/read-write-concern.md#unknown-levels-and-additional-options-for-string-based-readconcerns
35
35
  */
36
36
  this.level = ReadConcernLevel[level] ?? level;
37
37
  }
@@ -1,5 +1,3 @@
1
- import { clearTimeout } from 'timers';
2
-
3
1
  import type { Binary, Long, Timestamp } from '../bson';
4
2
  import type { ClientSession } from '../sessions';
5
3
  import type { Topology } from './topology';
@@ -46,15 +44,6 @@ export const ServerType = Object.freeze({
46
44
  /** @public */
47
45
  export type ServerType = (typeof ServerType)[keyof typeof ServerType];
48
46
 
49
- /** @internal */
50
- export type TimerQueue = Set<NodeJS.Timeout>;
51
-
52
- /** @internal */
53
- export function drainTimerQueue(queue: TimerQueue): void {
54
- queue.forEach(clearTimeout);
55
- queue.clear();
56
- }
57
-
58
47
  /**
59
48
  * @public
60
49
  * Gossiped in component for the cluster time tracking the state of user databases
@@ -40,6 +40,7 @@ import type { ServerApi } from '../mongo_client';
40
40
  import { TypedEventEmitter } from '../mongo_types';
41
41
  import type { GetMoreOptions } from '../operations/get_more';
42
42
  import type { ClientSession } from '../sessions';
43
+ import { type TimeoutContext } from '../timeout';
43
44
  import { isTransactionCommand } from '../transactions';
44
45
  import {
45
46
  type EventEmitterWithState,
@@ -104,6 +105,11 @@ export type ServerEvents = {
104
105
  } & ConnectionPoolEvents &
105
106
  EventEmitterWithState;
106
107
 
108
+ /** @internal */
109
+ export type ServerCommandOptions = Omit<CommandOptions, 'timeoutContext' | 'socketTimeoutMS'> & {
110
+ timeoutContext: TimeoutContext;
111
+ };
112
+
107
113
  /** @internal */
108
114
  export class Server extends TypedEventEmitter<ServerEvents> {
109
115
  /** @internal */
@@ -267,20 +273,20 @@ export class Server extends TypedEventEmitter<ServerEvents> {
267
273
  public async command<T extends MongoDBResponseConstructor>(
268
274
  ns: MongoDBNamespace,
269
275
  command: Document,
270
- options: CommandOptions | undefined,
276
+ options: ServerCommandOptions,
271
277
  responseType: T | undefined
272
278
  ): Promise<typeof responseType extends undefined ? Document : InstanceType<T>>;
273
279
 
274
280
  public async command(
275
281
  ns: MongoDBNamespace,
276
282
  command: Document,
277
- options?: CommandOptions
283
+ options: ServerCommandOptions
278
284
  ): Promise<Document>;
279
285
 
280
286
  public async command(
281
287
  ns: MongoDBNamespace,
282
288
  cmd: Document,
283
- options: CommandOptions,
289
+ options: ServerCommandOptions,
284
290
  responseType?: MongoDBResponseConstructor
285
291
  ): Promise<Document> {
286
292
  if (ns.db == null || typeof ns === 'string') {
@@ -305,13 +311,17 @@ export class Server extends TypedEventEmitter<ServerEvents> {
305
311
  delete finalOptions.readPreference;
306
312
  }
307
313
 
314
+ if (this.description.iscryptd) {
315
+ finalOptions.omitMaxTimeMS = true;
316
+ }
317
+
308
318
  const session = finalOptions.session;
309
319
  let conn = session?.pinnedConnection;
310
320
 
311
321
  this.incrementOperationCount();
312
322
  if (conn == null) {
313
323
  try {
314
- conn = await this.pool.checkOut();
324
+ conn = await this.pool.checkOut(options);
315
325
  if (this.loadBalanced && isPinnableCommand(cmd, session)) {
316
326
  session?.pin(conn);
317
327
  }
@@ -75,6 +75,8 @@ export class ServerDescription {
75
75
  maxWriteBatchSize: number | null;
76
76
  /** The max bson object size. */
77
77
  maxBsonObjectSize: number | null;
78
+ /** Indicates server is a mongocryptd instance. */
79
+ iscryptd: boolean;
78
80
 
79
81
  // NOTE: does this belong here? It seems we should gossip the cluster time at the CMAP level
80
82
  $clusterTime?: ClusterTime;
@@ -123,6 +125,7 @@ export class ServerDescription {
123
125
  this.primary = hello?.primary ?? null;
124
126
  this.me = hello?.me?.toLowerCase() ?? null;
125
127
  this.$clusterTime = hello?.$clusterTime ?? null;
128
+ this.iscryptd = Boolean(hello?.iscryptd);
126
129
  }
127
130
 
128
131
  get hostAddress(): HostAddress {
@@ -159,8 +162,8 @@ export class ServerDescription {
159
162
  }
160
163
 
161
164
  /**
162
- * Determines if another `ServerDescription` is equal to this one per the rules defined
163
- * in the {@link https://github.com/mongodb/specifications/blob/master/source/server-discovery-and-monitoring/server-discovery-and-monitoring.rst#serverdescription|SDAM spec}
165
+ * Determines if another `ServerDescription` is equal to this one per the rules defined in the SDAM specification.
166
+ * @see https://github.com/mongodb/specifications/blob/master/source/server-discovery-and-monitoring/server-discovery-and-monitoring.md
164
167
  */
165
168
  equals(other?: ServerDescription | null): boolean {
166
169
  // Despite using the comparator that would determine a nullish topologyVersion as greater than
@@ -176,6 +179,7 @@ export class ServerDescription {
176
179
 
177
180
  return (
178
181
  other != null &&
182
+ other.iscryptd === this.iscryptd &&
179
183
  errorStrictEqual(this.error, other.error) &&
180
184
  this.type === other.type &&
181
185
  this.minWireVersion === other.minWireVersion &&
@@ -75,7 +75,9 @@ export function secondaryWritableServerSelector(
75
75
 
76
76
  /**
77
77
  * Reduces the passed in array of servers by the rules of the "Max Staleness" specification
78
- * found here: https://github.com/mongodb/specifications/blob/master/source/max-staleness/max-staleness.rst
78
+ * found here:
79
+ *
80
+ * @see https://github.com/mongodb/specifications/blob/master/source/max-staleness/max-staleness.md
79
81
  *
80
82
  * @param readPreference - The read preference providing max staleness guidance
81
83
  * @param topologyDescription - The topology description
@@ -212,7 +214,8 @@ function tagSetReducer(
212
214
  /**
213
215
  * Reduces a list of servers to ensure they fall within an acceptable latency window. This is
214
216
  * further specified in the "Server Selection" specification, found here:
215
- * https://github.com/mongodb/specifications/blob/master/source/server-selection/server-selection.rst
217
+ *
218
+ * @see https://github.com/mongodb/specifications/blob/master/source/server-selection/server-selection.md
216
219
  *
217
220
  * @param topologyDescription - The topology description
218
221
  * @param servers - The list of servers to reduce
@@ -24,6 +24,7 @@ import {
24
24
  type MongoDriverError,
25
25
  MongoError,
26
26
  MongoErrorLabel,
27
+ MongoOperationTimeoutError,
27
28
  MongoRuntimeError,
28
29
  MongoServerSelectionError,
29
30
  MongoTopologyClosedError
@@ -33,7 +34,7 @@ import { MongoLoggableComponent, type MongoLogger, SeverityLevel } from '../mong
33
34
  import { TypedEventEmitter } from '../mongo_types';
34
35
  import { ReadPreference, type ReadPreferenceLike } from '../read_preference';
35
36
  import type { ClientSession } from '../sessions';
36
- import { Timeout, TimeoutError } from '../timeout';
37
+ import { Timeout, TimeoutContext, TimeoutError } from '../timeout';
37
38
  import type { Transaction } from '../transactions';
38
39
  import {
39
40
  type Callback,
@@ -49,13 +50,11 @@ import {
49
50
  import {
50
51
  _advanceClusterTime,
51
52
  type ClusterTime,
52
- drainTimerQueue,
53
53
  ServerType,
54
54
  STATE_CLOSED,
55
55
  STATE_CLOSING,
56
56
  STATE_CONNECTED,
57
57
  STATE_CONNECTING,
58
- type TimerQueue,
59
58
  TopologyType
60
59
  } from './common';
61
60
  import {
@@ -107,7 +106,6 @@ export interface ServerSelectionRequest {
107
106
  resolve: (server: Server) => void;
108
107
  reject: (error: MongoError) => void;
109
108
  [kCancelled]?: boolean;
110
- timeout: Timeout;
111
109
  operationName: string;
112
110
  waitingLogged: boolean;
113
111
  previousServer?: ServerDescription;
@@ -132,8 +130,6 @@ export interface TopologyPrivate {
132
130
  servers: Map<string, Server>;
133
131
  credentials?: MongoCredentials;
134
132
  clusterTime?: ClusterTime;
135
- /** timers created for the initial connect to a server */
136
- connectionTimers: TimerQueue;
137
133
 
138
134
  /** related to srv polling */
139
135
  srvPoller?: SrvPoller;
@@ -178,8 +174,11 @@ export interface SelectServerOptions {
178
174
  session?: ClientSession;
179
175
  operationName: string;
180
176
  previousServer?: ServerDescription;
181
- /** @internal*/
182
- timeout?: Timeout;
177
+ /**
178
+ * @internal
179
+ * TODO(NODE-6496): Make this required by making ChangeStream use LegacyTimeoutContext
180
+ * */
181
+ timeoutContext?: TimeoutContext;
183
182
  }
184
183
 
185
184
  /** @public */
@@ -322,8 +321,6 @@ export class Topology extends TypedEventEmitter<TopologyEvents> {
322
321
  credentials: options?.credentials,
323
322
  clusterTime: undefined,
324
323
 
325
- // timer management
326
- connectionTimers: new Set<NodeJS.Timeout>(),
327
324
  detectShardedTopology: ev => this.detectShardedTopology(ev),
328
325
  detectSrvRecords: ev => this.detectSrvRecords(ev)
329
326
  };
@@ -412,8 +409,6 @@ export class Topology extends TypedEventEmitter<TopologyEvents> {
412
409
  } finally {
413
410
  this.connectionLock = undefined;
414
411
  }
415
-
416
- return this;
417
412
  }
418
413
 
419
414
  private async _connect(options?: ConnectOptions): Promise<Topology> {
@@ -457,17 +452,28 @@ export class Topology extends TypedEventEmitter<TopologyEvents> {
457
452
  }
458
453
  }
459
454
 
455
+ const serverSelectionTimeoutMS = this.client.s.options.serverSelectionTimeoutMS;
460
456
  const readPreference = options.readPreference ?? ReadPreference.primary;
461
- const selectServerOptions = { operationName: 'ping', ...options };
457
+ const timeoutContext = TimeoutContext.create({
458
+ // TODO(NODE-6448): auto-connect ignores timeoutMS; potential future feature
459
+ timeoutMS: undefined,
460
+ serverSelectionTimeoutMS,
461
+ waitQueueTimeoutMS: this.client.s.options.waitQueueTimeoutMS
462
+ });
463
+ const selectServerOptions = {
464
+ operationName: 'ping',
465
+ ...options,
466
+ timeoutContext
467
+ };
468
+
462
469
  try {
463
470
  const server = await this.selectServer(
464
471
  readPreferenceServerSelector(readPreference),
465
472
  selectServerOptions
466
473
  );
467
-
468
474
  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 }, {});
475
+ if (!skipPingOnConnect && this.s.credentials) {
476
+ await server.command(ns('admin.$cmd'), { ping: 1 }, { timeoutContext });
471
477
  stateTransition(this, STATE_CONNECTED);
472
478
  this.emit(Topology.OPEN, this);
473
479
  this.emit(Topology.CONNECT, this);
@@ -501,7 +507,6 @@ export class Topology extends TypedEventEmitter<TopologyEvents> {
501
507
  stateTransition(this, STATE_CLOSING);
502
508
 
503
509
  drainWaitQueue(this[kWaitQueue], new MongoTopologyClosedError());
504
- drainTimerQueue(this.s.connectionTimers);
505
510
 
506
511
  if (this.s.srvPoller) {
507
512
  this.s.srvPoller.stop();
@@ -556,6 +561,11 @@ export class Topology extends TypedEventEmitter<TopologyEvents> {
556
561
  new ServerSelectionStartedEvent(selector, this.description, options.operationName)
557
562
  );
558
563
  }
564
+ let timeout;
565
+ if (options.timeoutContext) timeout = options.timeoutContext.serverSelectionTimeout;
566
+ else {
567
+ timeout = Timeout.expires(options.serverSelectionTimeoutMS ?? 0);
568
+ }
559
569
 
560
570
  const isSharded = this.description.type === TopologyType.Sharded;
561
571
  const session = options.session;
@@ -578,11 +588,12 @@ export class Topology extends TypedEventEmitter<TopologyEvents> {
578
588
  )
579
589
  );
580
590
  }
591
+ if (options.timeoutContext?.clearServerSelectionTimeout) timeout?.clear();
581
592
  return transaction.server;
582
593
  }
583
594
 
584
595
  const { promise: serverPromise, resolve, reject } = promiseWithResolvers<Server>();
585
- const timeout = Timeout.expires(options.serverSelectionTimeoutMS ?? 0);
596
+
586
597
  const waitQueueMember: ServerSelectionRequest = {
587
598
  serverSelector,
588
599
  topologyDescription: this.description,
@@ -590,7 +601,6 @@ export class Topology extends TypedEventEmitter<TopologyEvents> {
590
601
  transaction,
591
602
  resolve,
592
603
  reject,
593
- timeout,
594
604
  startTime: now(),
595
605
  operationName: options.operationName,
596
606
  waitingLogged: false,
@@ -601,14 +611,18 @@ export class Topology extends TypedEventEmitter<TopologyEvents> {
601
611
  processWaitQueue(this);
602
612
 
603
613
  try {
604
- return await Promise.race([serverPromise, waitQueueMember.timeout]);
614
+ timeout?.throwIfExpired();
615
+ const server = await (timeout ? Promise.race([serverPromise, timeout]) : serverPromise);
616
+ if (options.timeoutContext?.csotEnabled() && server.description.minRoundTripTime !== 0) {
617
+ options.timeoutContext.minRoundTripTime = server.description.minRoundTripTime;
618
+ }
619
+ return server;
605
620
  } catch (error) {
606
621
  if (TimeoutError.is(error)) {
607
622
  // Timeout
608
623
  waitQueueMember[kCancelled] = true;
609
- timeout.clear();
610
624
  const timeoutError = new MongoServerSelectionError(
611
- `Server selection timed out after ${options.serverSelectionTimeoutMS} ms`,
625
+ `Server selection timed out after ${timeout?.duration} ms`,
612
626
  this.description
613
627
  );
614
628
  if (
@@ -628,10 +642,17 @@ export class Topology extends TypedEventEmitter<TopologyEvents> {
628
642
  );
629
643
  }
630
644
 
645
+ if (options.timeoutContext?.csotEnabled()) {
646
+ throw new MongoOperationTimeoutError('Timed out during server selection', {
647
+ cause: timeoutError
648
+ });
649
+ }
631
650
  throw timeoutError;
632
651
  }
633
652
  // Other server selection error
634
653
  throw error;
654
+ } finally {
655
+ if (options.timeoutContext?.clearServerSelectionTimeout) timeout?.clear();
635
656
  }
636
657
  }
637
658
  /**
@@ -889,8 +910,6 @@ function drainWaitQueue(queue: List<ServerSelectionRequest>, drainError: MongoDr
889
910
  continue;
890
911
  }
891
912
 
892
- waitQueueMember.timeout.clear();
893
-
894
913
  if (!waitQueueMember[kCancelled]) {
895
914
  if (
896
915
  waitQueueMember.mongoLogger?.willLog(
@@ -944,7 +963,6 @@ function processWaitQueue(topology: Topology) {
944
963
  )
945
964
  : serverDescriptions;
946
965
  } catch (selectorError) {
947
- waitQueueMember.timeout.clear();
948
966
  if (
949
967
  topology.client.mongoLogger?.willLog(
950
968
  MongoLoggableComponent.SERVER_SELECTION,
@@ -1032,8 +1050,6 @@ function processWaitQueue(topology: Topology) {
1032
1050
  transaction.pinServer(selectedServer);
1033
1051
  }
1034
1052
 
1035
- waitQueueMember.timeout.clear();
1036
-
1037
1053
  if (
1038
1054
  topology.client.mongoLogger?.willLog(
1039
1055
  MongoLoggableComponent.SERVER_SELECTION,