mongodb 6.10.0-dev.20241106.sha.dc3fe957 → 6.10.0-dev.20241108.sha.fd7acde6

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 (215) hide show
  1. package/lib/admin.js +3 -2
  2. package/lib/admin.js.map +1 -1
  3. package/lib/beta.d.ts +558 -40
  4. package/lib/bulk/common.js +4 -4
  5. package/lib/bulk/common.js.map +1 -1
  6. package/lib/change_stream.js +111 -51
  7. package/lib/change_stream.js.map +1 -1
  8. package/lib/client-side-encryption/auto_encrypter.js +8 -5
  9. package/lib/client-side-encryption/auto_encrypter.js.map +1 -1
  10. package/lib/client-side-encryption/client_encryption.js +48 -18
  11. package/lib/client-side-encryption/client_encryption.js.map +1 -1
  12. package/lib/client-side-encryption/state_machine.js +43 -29
  13. package/lib/client-side-encryption/state_machine.js.map +1 -1
  14. package/lib/cmap/auth/mongo_credentials.js +2 -1
  15. package/lib/cmap/auth/mongo_credentials.js.map +1 -1
  16. package/lib/cmap/auth/mongodb_oidc/k8s_machine_workflow.js +38 -0
  17. package/lib/cmap/auth/mongodb_oidc/k8s_machine_workflow.js.map +1 -0
  18. package/lib/cmap/auth/mongodb_oidc.js +2 -0
  19. package/lib/cmap/auth/mongodb_oidc.js.map +1 -1
  20. package/lib/cmap/connection.js +78 -6
  21. package/lib/cmap/connection.js.map +1 -1
  22. package/lib/cmap/connection_pool.js +14 -9
  23. package/lib/cmap/connection_pool.js.map +1 -1
  24. package/lib/cmap/wire_protocol/on_data.js +5 -1
  25. package/lib/cmap/wire_protocol/on_data.js.map +1 -1
  26. package/lib/cmap/wire_protocol/responses.js +30 -0
  27. package/lib/cmap/wire_protocol/responses.js.map +1 -1
  28. package/lib/collection.js +62 -3
  29. package/lib/collection.js.map +1 -1
  30. package/lib/connection_string.js +2 -0
  31. package/lib/connection_string.js.map +1 -1
  32. package/lib/cursor/abstract_cursor.js +218 -38
  33. package/lib/cursor/abstract_cursor.js.map +1 -1
  34. package/lib/cursor/aggregation_cursor.js +29 -7
  35. package/lib/cursor/aggregation_cursor.js.map +1 -1
  36. package/lib/cursor/change_stream_cursor.js +2 -2
  37. package/lib/cursor/change_stream_cursor.js.map +1 -1
  38. package/lib/cursor/client_bulk_write_cursor.js +1 -1
  39. package/lib/cursor/client_bulk_write_cursor.js.map +1 -1
  40. package/lib/cursor/find_cursor.js +18 -8
  41. package/lib/cursor/find_cursor.js.map +1 -1
  42. package/lib/cursor/list_collections_cursor.js +1 -1
  43. package/lib/cursor/list_collections_cursor.js.map +1 -1
  44. package/lib/cursor/list_indexes_cursor.js +1 -1
  45. package/lib/cursor/list_indexes_cursor.js.map +1 -1
  46. package/lib/cursor/run_command_cursor.js +6 -4
  47. package/lib/cursor/run_command_cursor.js.map +1 -1
  48. package/lib/db.js +63 -3
  49. package/lib/db.js.map +1 -1
  50. package/lib/error.js +27 -2
  51. package/lib/error.js.map +1 -1
  52. package/lib/explain.js +57 -1
  53. package/lib/explain.js.map +1 -1
  54. package/lib/gridfs/download.js +31 -3
  55. package/lib/gridfs/download.js.map +1 -1
  56. package/lib/gridfs/index.js +49 -14
  57. package/lib/gridfs/index.js.map +1 -1
  58. package/lib/gridfs/upload.js +80 -22
  59. package/lib/gridfs/upload.js.map +1 -1
  60. package/lib/index.js +9 -5
  61. package/lib/index.js.map +1 -1
  62. package/lib/mongo_client.js +70 -1
  63. package/lib/mongo_client.js.map +1 -1
  64. package/lib/operations/aggregate.js +2 -2
  65. package/lib/operations/aggregate.js.map +1 -1
  66. package/lib/operations/bulk_write.js +7 -2
  67. package/lib/operations/bulk_write.js.map +1 -1
  68. package/lib/operations/client_bulk_write/client_bulk_write.js +3 -3
  69. package/lib/operations/client_bulk_write/client_bulk_write.js.map +1 -1
  70. package/lib/operations/client_bulk_write/executor.js +14 -3
  71. package/lib/operations/client_bulk_write/executor.js.map +1 -1
  72. package/lib/operations/command.js +5 -2
  73. package/lib/operations/command.js.map +1 -1
  74. package/lib/operations/count.js +2 -2
  75. package/lib/operations/count.js.map +1 -1
  76. package/lib/operations/create_collection.js +8 -7
  77. package/lib/operations/create_collection.js.map +1 -1
  78. package/lib/operations/delete.js +6 -6
  79. package/lib/operations/delete.js.map +1 -1
  80. package/lib/operations/distinct.js +2 -2
  81. package/lib/operations/distinct.js.map +1 -1
  82. package/lib/operations/drop.js +8 -8
  83. package/lib/operations/drop.js.map +1 -1
  84. package/lib/operations/estimated_document_count.js +2 -2
  85. package/lib/operations/estimated_document_count.js.map +1 -1
  86. package/lib/operations/execute_operation.js +16 -10
  87. package/lib/operations/execute_operation.js.map +1 -1
  88. package/lib/operations/find.js +6 -3
  89. package/lib/operations/find.js.map +1 -1
  90. package/lib/operations/find_and_modify.js +2 -2
  91. package/lib/operations/find_and_modify.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 +6 -6
  95. package/lib/operations/indexes.js.map +1 -1
  96. package/lib/operations/insert.js +6 -6
  97. package/lib/operations/insert.js.map +1 -1
  98. package/lib/operations/kill_cursors.js +5 -2
  99. package/lib/operations/kill_cursors.js.map +1 -1
  100. package/lib/operations/list_collections.js +2 -2
  101. package/lib/operations/list_collections.js.map +1 -1
  102. package/lib/operations/list_databases.js +2 -2
  103. package/lib/operations/list_databases.js.map +1 -1
  104. package/lib/operations/operation.js.map +1 -1
  105. package/lib/operations/profiling_level.js +2 -2
  106. package/lib/operations/profiling_level.js.map +1 -1
  107. package/lib/operations/remove_user.js +2 -2
  108. package/lib/operations/remove_user.js.map +1 -1
  109. package/lib/operations/rename.js +2 -2
  110. package/lib/operations/rename.js.map +1 -1
  111. package/lib/operations/run_command.js +6 -4
  112. package/lib/operations/run_command.js.map +1 -1
  113. package/lib/operations/search_indexes/create.js +5 -2
  114. package/lib/operations/search_indexes/create.js.map +1 -1
  115. package/lib/operations/search_indexes/drop.js +2 -2
  116. package/lib/operations/search_indexes/drop.js.map +1 -1
  117. package/lib/operations/search_indexes/update.js +2 -2
  118. package/lib/operations/search_indexes/update.js.map +1 -1
  119. package/lib/operations/set_profiling_level.js +2 -2
  120. package/lib/operations/set_profiling_level.js.map +1 -1
  121. package/lib/operations/stats.js +2 -2
  122. package/lib/operations/stats.js.map +1 -1
  123. package/lib/operations/update.js +8 -8
  124. package/lib/operations/update.js.map +1 -1
  125. package/lib/operations/validate_collection.js +2 -2
  126. package/lib/operations/validate_collection.js.map +1 -1
  127. package/lib/sdam/common.js +0 -7
  128. package/lib/sdam/common.js.map +1 -1
  129. package/lib/sdam/server.js +4 -1
  130. package/lib/sdam/server.js.map +1 -1
  131. package/lib/sdam/server_description.js +2 -0
  132. package/lib/sdam/server_description.js.map +1 -1
  133. package/lib/sdam/topology.js +38 -15
  134. package/lib/sdam/topology.js.map +1 -1
  135. package/lib/sessions.js +145 -74
  136. package/lib/sessions.js.map +1 -1
  137. package/lib/timeout.js +217 -16
  138. package/lib/timeout.js.map +1 -1
  139. package/lib/utils.js +31 -17
  140. package/lib/utils.js.map +1 -1
  141. package/lib/write_concern.js.map +1 -1
  142. package/mongodb.d.ts +558 -40
  143. package/package.json +3 -2
  144. package/src/admin.ts +6 -2
  145. package/src/bulk/common.ts +17 -5
  146. package/src/change_stream.ts +127 -52
  147. package/src/client-side-encryption/auto_encrypter.ts +12 -5
  148. package/src/client-side-encryption/client_encryption.ts +103 -20
  149. package/src/client-side-encryption/state_machine.ts +66 -32
  150. package/src/cmap/auth/mongo_credentials.ts +3 -2
  151. package/src/cmap/auth/mongodb_oidc/k8s_machine_workflow.ts +38 -0
  152. package/src/cmap/auth/mongodb_oidc.ts +3 -1
  153. package/src/cmap/connection.ts +105 -8
  154. package/src/cmap/connection_pool.ts +14 -14
  155. package/src/cmap/wire_protocol/on_data.ts +11 -1
  156. package/src/cmap/wire_protocol/responses.ts +35 -1
  157. package/src/collection.ts +81 -9
  158. package/src/connection_string.ts +2 -0
  159. package/src/cursor/abstract_cursor.ts +286 -39
  160. package/src/cursor/aggregation_cursor.ts +54 -8
  161. package/src/cursor/change_stream_cursor.ts +6 -2
  162. package/src/cursor/client_bulk_write_cursor.ts +6 -2
  163. package/src/cursor/find_cursor.ts +40 -9
  164. package/src/cursor/list_collections_cursor.ts +1 -1
  165. package/src/cursor/list_indexes_cursor.ts +1 -1
  166. package/src/cursor/run_command_cursor.ts +50 -5
  167. package/src/db.ts +75 -7
  168. package/src/error.ts +26 -1
  169. package/src/explain.ts +85 -0
  170. package/src/gridfs/download.ts +43 -4
  171. package/src/gridfs/index.ts +64 -16
  172. package/src/gridfs/upload.ts +152 -45
  173. package/src/index.ts +27 -5
  174. package/src/mongo_client.ts +75 -3
  175. package/src/operations/aggregate.ts +10 -2
  176. package/src/operations/bulk_write.ts +9 -2
  177. package/src/operations/client_bulk_write/client_bulk_write.ts +11 -3
  178. package/src/operations/client_bulk_write/executor.ts +15 -3
  179. package/src/operations/command.ts +18 -8
  180. package/src/operations/count.ts +10 -3
  181. package/src/operations/create_collection.ts +14 -7
  182. package/src/operations/delete.ts +15 -6
  183. package/src/operations/distinct.ts +7 -2
  184. package/src/operations/drop.ts +18 -8
  185. package/src/operations/estimated_document_count.ts +7 -2
  186. package/src/operations/execute_operation.ts +22 -13
  187. package/src/operations/find.ts +17 -5
  188. package/src/operations/find_and_modify.ts +7 -2
  189. package/src/operations/get_more.ts +4 -1
  190. package/src/operations/indexes.ts +20 -7
  191. package/src/operations/insert.ts +13 -6
  192. package/src/operations/kill_cursors.ts +10 -2
  193. package/src/operations/list_collections.ts +10 -1
  194. package/src/operations/list_databases.ts +9 -2
  195. package/src/operations/operation.ts +16 -2
  196. package/src/operations/profiling_level.ts +7 -2
  197. package/src/operations/remove_user.ts +7 -2
  198. package/src/operations/rename.ts +7 -2
  199. package/src/operations/run_command.ts +23 -4
  200. package/src/operations/search_indexes/create.ts +10 -2
  201. package/src/operations/search_indexes/drop.ts +7 -2
  202. package/src/operations/search_indexes/update.ts +7 -2
  203. package/src/operations/set_profiling_level.ts +4 -2
  204. package/src/operations/stats.ts +7 -2
  205. package/src/operations/update.ts +16 -8
  206. package/src/operations/validate_collection.ts +7 -2
  207. package/src/sdam/common.ts +0 -11
  208. package/src/sdam/server.ts +14 -4
  209. package/src/sdam/server_description.ts +4 -0
  210. package/src/sdam/topology.ts +43 -27
  211. package/src/sessions.ts +193 -89
  212. package/src/timeout.ts +310 -23
  213. package/src/transactions.ts +1 -1
  214. package/src/utils.ts +42 -28
  215. package/src/write_concern.ts +6 -3
@@ -2,10 +2,12 @@ import type { ObjectId } from '../bson';
2
2
  import type { Collection } from '../collection';
3
3
  import type { FindCursor } from '../cursor/find_cursor';
4
4
  import type { Db } from '../db';
5
- import { MongoRuntimeError } from '../error';
5
+ import { MongoOperationTimeoutError, MongoRuntimeError } from '../error';
6
6
  import { type Filter, TypedEventEmitter } from '../mongo_types';
7
7
  import type { ReadPreference } from '../read_preference';
8
8
  import type { Sort } from '../sort';
9
+ import { CSOTTimeoutContext } from '../timeout';
10
+ import { resolveOptions } from '../utils';
9
11
  import { WriteConcern, type WriteConcernOptions } from '../write_concern';
10
12
  import type { FindOptions } from './../operations/find';
11
13
  import {
@@ -36,7 +38,11 @@ export interface GridFSBucketOptions extends WriteConcernOptions {
36
38
  chunkSizeBytes?: number;
37
39
  /** Read preference to be passed to read operations */
38
40
  readPreference?: ReadPreference;
39
- /** @internal TODO(NODE-5688): make this public */
41
+ /**
42
+ * @experimental
43
+ * Specifies the lifetime duration of a gridFS stream. If any async operations are in progress
44
+ * when this timeout expires, the stream will throw a timeout error.
45
+ */
40
46
  timeoutMS?: number;
41
47
  }
42
48
 
@@ -48,6 +54,7 @@ export interface GridFSBucketPrivate {
48
54
  chunkSizeBytes: number;
49
55
  readPreference?: ReadPreference;
50
56
  writeConcern: WriteConcern | undefined;
57
+ timeoutMS?: number;
51
58
  };
52
59
  _chunksCollection: Collection<GridFSChunk>;
53
60
  _filesCollection: Collection<GridFSFile>;
@@ -81,11 +88,11 @@ export class GridFSBucket extends TypedEventEmitter<GridFSBucketEvents> {
81
88
  constructor(db: Db, options?: GridFSBucketOptions) {
82
89
  super();
83
90
  this.setMaxListeners(0);
84
- const privateOptions = {
91
+ const privateOptions = resolveOptions(db, {
85
92
  ...DEFAULT_GRIDFS_BUCKET_OPTIONS,
86
93
  ...options,
87
94
  writeConcern: WriteConcern.fromOptions(options)
88
- };
95
+ });
89
96
  this.s = {
90
97
  db,
91
98
  options: privateOptions,
@@ -109,7 +116,10 @@ export class GridFSBucket extends TypedEventEmitter<GridFSBucketEvents> {
109
116
  filename: string,
110
117
  options?: GridFSBucketWriteStreamOptions
111
118
  ): GridFSBucketWriteStream {
112
- return new GridFSBucketWriteStream(this, filename, options);
119
+ return new GridFSBucketWriteStream(this, filename, {
120
+ timeoutMS: this.s.options.timeoutMS,
121
+ ...options
122
+ });
113
123
  }
114
124
 
115
125
  /**
@@ -122,7 +132,11 @@ export class GridFSBucket extends TypedEventEmitter<GridFSBucketEvents> {
122
132
  filename: string,
123
133
  options?: GridFSBucketWriteStreamOptions
124
134
  ): GridFSBucketWriteStream {
125
- return new GridFSBucketWriteStream(this, filename, { ...options, id });
135
+ return new GridFSBucketWriteStream(this, filename, {
136
+ timeoutMS: this.s.options.timeoutMS,
137
+ ...options,
138
+ id
139
+ });
126
140
  }
127
141
 
128
142
  /** Returns a readable stream (GridFSBucketReadStream) for streaming file data from GridFS. */
@@ -135,7 +149,7 @@ export class GridFSBucket extends TypedEventEmitter<GridFSBucketEvents> {
135
149
  this.s._filesCollection,
136
150
  this.s.options.readPreference,
137
151
  { _id: id },
138
- options
152
+ { timeoutMS: this.s.options.timeoutMS, ...options }
139
153
  );
140
154
  }
141
155
 
@@ -144,11 +158,27 @@ export class GridFSBucket extends TypedEventEmitter<GridFSBucketEvents> {
144
158
  *
145
159
  * @param id - The id of the file doc
146
160
  */
147
- async delete(id: ObjectId): Promise<void> {
148
- const { deletedCount } = await this.s._filesCollection.deleteOne({ _id: id });
161
+ async delete(id: ObjectId, options?: { timeoutMS: number }): Promise<void> {
162
+ const { timeoutMS } = resolveOptions(this.s.db, options);
163
+ let timeoutContext: CSOTTimeoutContext | undefined = undefined;
149
164
 
165
+ if (timeoutMS) {
166
+ timeoutContext = new CSOTTimeoutContext({
167
+ timeoutMS,
168
+ serverSelectionTimeoutMS: this.s.db.client.s.options.serverSelectionTimeoutMS
169
+ });
170
+ }
171
+
172
+ const { deletedCount } = await this.s._filesCollection.deleteOne(
173
+ { _id: id },
174
+ { timeoutMS: timeoutContext?.remainingTimeMS }
175
+ );
176
+
177
+ const remainingTimeMS = timeoutContext?.remainingTimeMS;
178
+ if (remainingTimeMS != null && remainingTimeMS <= 0)
179
+ throw new MongoOperationTimeoutError(`Timed out after ${timeoutMS}ms`);
150
180
  // Delete orphaned chunks before returning FileNotFound
151
- await this.s._chunksCollection.deleteMany({ files_id: id });
181
+ await this.s._chunksCollection.deleteMany({ files_id: id }, { timeoutMS: remainingTimeMS });
152
182
 
153
183
  if (deletedCount === 0) {
154
184
  // TODO(NODE-3483): Replace with more appropriate error
@@ -188,7 +218,7 @@ export class GridFSBucket extends TypedEventEmitter<GridFSBucketEvents> {
188
218
  this.s._filesCollection,
189
219
  this.s.options.readPreference,
190
220
  { filename },
191
- { ...options, sort, skip }
221
+ { timeoutMS: this.s.options.timeoutMS, ...options, sort, skip }
192
222
  );
193
223
  }
194
224
 
@@ -198,18 +228,36 @@ export class GridFSBucket extends TypedEventEmitter<GridFSBucketEvents> {
198
228
  * @param id - the id of the file to rename
199
229
  * @param filename - new name for the file
200
230
  */
201
- async rename(id: ObjectId, filename: string): Promise<void> {
231
+ async rename(id: ObjectId, filename: string, options?: { timeoutMS: number }): Promise<void> {
202
232
  const filter = { _id: id };
203
233
  const update = { $set: { filename } };
204
- const { matchedCount } = await this.s._filesCollection.updateOne(filter, update);
234
+ const { matchedCount } = await this.s._filesCollection.updateOne(filter, update, options);
205
235
  if (matchedCount === 0) {
206
236
  throw new MongoRuntimeError(`File with id ${id} not found`);
207
237
  }
208
238
  }
209
239
 
210
240
  /** Removes this bucket's files collection, followed by its chunks collection. */
211
- async drop(): Promise<void> {
212
- await this.s._filesCollection.drop();
213
- await this.s._chunksCollection.drop();
241
+ async drop(options?: { timeoutMS: number }): Promise<void> {
242
+ const { timeoutMS } = resolveOptions(this.s.db, options);
243
+ let timeoutContext: CSOTTimeoutContext | undefined = undefined;
244
+
245
+ if (timeoutMS) {
246
+ timeoutContext = new CSOTTimeoutContext({
247
+ timeoutMS,
248
+ serverSelectionTimeoutMS: this.s.db.client.s.options.serverSelectionTimeoutMS
249
+ });
250
+ }
251
+
252
+ if (timeoutContext) {
253
+ await this.s._filesCollection.drop({ timeoutMS: timeoutContext.remainingTimeMS });
254
+ const remainingTimeMS = timeoutContext.getRemainingTimeMSOrThrow(
255
+ `Timed out after ${timeoutMS}ms`
256
+ );
257
+ await this.s._chunksCollection.drop({ timeoutMS: remainingTimeMS });
258
+ } else {
259
+ await this.s._filesCollection.drop();
260
+ await this.s._chunksCollection.drop();
261
+ }
214
262
  }
215
263
  }
@@ -2,8 +2,15 @@ import { Writable } from 'stream';
2
2
 
3
3
  import { type Document, ObjectId } from '../bson';
4
4
  import type { Collection } from '../collection';
5
- import { MongoAPIError, MONGODB_ERROR_CODES, MongoError } from '../error';
6
- import { type Callback, squashError } from '../utils';
5
+ import { CursorTimeoutMode } from '../cursor/abstract_cursor';
6
+ import {
7
+ MongoAPIError,
8
+ MONGODB_ERROR_CODES,
9
+ MongoError,
10
+ MongoOperationTimeoutError
11
+ } from '../error';
12
+ import { CSOTTimeoutContext } from '../timeout';
13
+ import { type Callback, resolveTimeoutOptions, squashError } from '../utils';
7
14
  import type { WriteConcernOptions } from '../write_concern';
8
15
  import { WriteConcern } from './../write_concern';
9
16
  import type { GridFSFile } from './download';
@@ -35,7 +42,10 @@ export interface GridFSBucketWriteStreamOptions extends WriteConcernOptions {
35
42
  * @deprecated Will be removed in the next major version. Add an aliases field to the metadata document instead.
36
43
  */
37
44
  aliases?: string[];
38
- /** @internal TODO(NODE-5688): make this public */
45
+ /**
46
+ * @experimental
47
+ * Specifies the time an operation will run until it throws a timeout error
48
+ */
39
49
  timeoutMS?: number;
40
50
  }
41
51
 
@@ -97,6 +107,8 @@ export class GridFSBucketWriteStream extends Writable {
97
107
  * ```
98
108
  */
99
109
  gridFSFile: GridFSFile | null = null;
110
+ /** @internal */
111
+ timeoutContext?: CSOTTimeoutContext;
100
112
 
101
113
  /**
102
114
  * @param bucket - Handle for this stream's corresponding bucket
@@ -131,14 +143,12 @@ export class GridFSBucketWriteStream extends Writable {
131
143
  aborted: false
132
144
  };
133
145
 
134
- if (!this.bucket.s.calledOpenUploadStream) {
135
- this.bucket.s.calledOpenUploadStream = true;
136
-
137
- checkIndexes(this).then(() => {
138
- this.bucket.s.checkedIndexes = true;
139
- this.bucket.emit('index');
140
- }, squashError);
141
- }
146
+ if (options.timeoutMS != null)
147
+ this.timeoutContext = new CSOTTimeoutContext({
148
+ timeoutMS: options.timeoutMS,
149
+ serverSelectionTimeoutMS: resolveTimeoutOptions(this.bucket.s.db.client, {})
150
+ .serverSelectionTimeoutMS
151
+ });
142
152
  }
143
153
 
144
154
  /**
@@ -147,10 +157,26 @@ export class GridFSBucketWriteStream extends Writable {
147
157
  * The stream is considered constructed when the indexes are done being created
148
158
  */
149
159
  override _construct(callback: (error?: Error | null) => void): void {
150
- if (this.bucket.s.checkedIndexes) {
160
+ if (!this.bucket.s.calledOpenUploadStream) {
161
+ this.bucket.s.calledOpenUploadStream = true;
162
+
163
+ checkIndexes(this).then(
164
+ () => {
165
+ this.bucket.s.checkedIndexes = true;
166
+ this.bucket.emit('index');
167
+ callback();
168
+ },
169
+ error => {
170
+ if (error instanceof MongoOperationTimeoutError) {
171
+ return handleError(this, error, callback);
172
+ }
173
+ squashError(error);
174
+ callback();
175
+ }
176
+ );
177
+ } else {
151
178
  return process.nextTick(callback);
152
179
  }
153
- this.bucket.once('index', callback);
154
180
  }
155
181
 
156
182
  /**
@@ -194,7 +220,10 @@ export class GridFSBucketWriteStream extends Writable {
194
220
  }
195
221
 
196
222
  this.state.aborted = true;
197
- await this.chunks.deleteMany({ files_id: this.id });
223
+ const remainingTimeMS = this.timeoutContext?.getRemainingTimeMSOrThrow(
224
+ `Upload timed out after ${this.timeoutContext?.timeoutMS}ms`
225
+ );
226
+ await this.chunks.deleteMany({ files_id: this.id, timeoutMS: remainingTimeMS });
198
227
  }
199
228
  }
200
229
 
@@ -219,9 +248,19 @@ function createChunkDoc(filesId: ObjectId, n: number, data: Buffer): GridFSChunk
219
248
  async function checkChunksIndex(stream: GridFSBucketWriteStream): Promise<void> {
220
249
  const index = { files_id: 1, n: 1 };
221
250
 
251
+ let remainingTimeMS;
252
+ remainingTimeMS = stream.timeoutContext?.getRemainingTimeMSOrThrow(
253
+ `Upload timed out after ${stream.timeoutContext?.timeoutMS}ms`
254
+ );
255
+
222
256
  let indexes;
223
257
  try {
224
- indexes = await stream.chunks.listIndexes().toArray();
258
+ indexes = await stream.chunks
259
+ .listIndexes({
260
+ timeoutMode: remainingTimeMS != null ? CursorTimeoutMode.LIFETIME : undefined,
261
+ timeoutMS: remainingTimeMS
262
+ })
263
+ .toArray();
225
264
  } catch (error) {
226
265
  if (error instanceof MongoError && error.code === MONGODB_ERROR_CODES.NamespaceNotFound) {
227
266
  indexes = [];
@@ -239,10 +278,14 @@ async function checkChunksIndex(stream: GridFSBucketWriteStream): Promise<void>
239
278
  });
240
279
 
241
280
  if (!hasChunksIndex) {
281
+ remainingTimeMS = stream.timeoutContext?.getRemainingTimeMSOrThrow(
282
+ `Upload timed out after ${stream.timeoutContext?.timeoutMS}ms`
283
+ );
242
284
  await stream.chunks.createIndex(index, {
243
285
  ...stream.writeConcern,
244
286
  background: true,
245
- unique: true
287
+ unique: true,
288
+ timeoutMS: remainingTimeMS
246
289
  });
247
290
  }
248
291
  }
@@ -270,13 +313,28 @@ function checkDone(stream: GridFSBucketWriteStream, callback: Callback): void {
270
313
  return;
271
314
  }
272
315
 
273
- stream.files.insertOne(gridFSFile, { writeConcern: stream.writeConcern }).then(
274
- () => {
275
- stream.gridFSFile = gridFSFile;
276
- callback();
277
- },
278
- error => handleError(stream, error, callback)
279
- );
316
+ const remainingTimeMS = stream.timeoutContext?.remainingTimeMS;
317
+ if (remainingTimeMS != null && remainingTimeMS <= 0) {
318
+ return handleError(
319
+ stream,
320
+ new MongoOperationTimeoutError(
321
+ `Upload timed out after ${stream.timeoutContext?.timeoutMS}ms`
322
+ ),
323
+ callback
324
+ );
325
+ }
326
+
327
+ stream.files
328
+ .insertOne(gridFSFile, { writeConcern: stream.writeConcern, timeoutMS: remainingTimeMS })
329
+ .then(
330
+ () => {
331
+ stream.gridFSFile = gridFSFile;
332
+ callback();
333
+ },
334
+ error => {
335
+ return handleError(stream, error, callback);
336
+ }
337
+ );
280
338
  return;
281
339
  }
282
340
 
@@ -284,7 +342,16 @@ function checkDone(stream: GridFSBucketWriteStream, callback: Callback): void {
284
342
  }
285
343
 
286
344
  async function checkIndexes(stream: GridFSBucketWriteStream): Promise<void> {
287
- const doc = await stream.files.findOne({}, { projection: { _id: 1 } });
345
+ let remainingTimeMS = stream.timeoutContext?.getRemainingTimeMSOrThrow(
346
+ `Upload timed out after ${stream.timeoutContext?.timeoutMS}ms`
347
+ );
348
+ const doc = await stream.files.findOne(
349
+ {},
350
+ {
351
+ projection: { _id: 1 },
352
+ timeoutMS: remainingTimeMS
353
+ }
354
+ );
288
355
  if (doc != null) {
289
356
  // If at least one document exists assume the collection has the required index
290
357
  return;
@@ -293,8 +360,15 @@ async function checkIndexes(stream: GridFSBucketWriteStream): Promise<void> {
293
360
  const index = { filename: 1, uploadDate: 1 };
294
361
 
295
362
  let indexes;
363
+ remainingTimeMS = stream.timeoutContext?.getRemainingTimeMSOrThrow(
364
+ `Upload timed out after ${stream.timeoutContext?.timeoutMS}ms`
365
+ );
366
+ const listIndexesOptions = {
367
+ timeoutMode: remainingTimeMS != null ? CursorTimeoutMode.LIFETIME : undefined,
368
+ timeoutMS: remainingTimeMS
369
+ };
296
370
  try {
297
- indexes = await stream.files.listIndexes().toArray();
371
+ indexes = await stream.files.listIndexes(listIndexesOptions).toArray();
298
372
  } catch (error) {
299
373
  if (error instanceof MongoError && error.code === MONGODB_ERROR_CODES.NamespaceNotFound) {
300
374
  indexes = [];
@@ -312,7 +386,11 @@ async function checkIndexes(stream: GridFSBucketWriteStream): Promise<void> {
312
386
  });
313
387
 
314
388
  if (!hasFileIndex) {
315
- await stream.files.createIndex(index, { background: false });
389
+ remainingTimeMS = stream.timeoutContext?.getRemainingTimeMSOrThrow(
390
+ `Upload timed out after ${stream.timeoutContext?.timeoutMS}ms`
391
+ );
392
+
393
+ await stream.files.createIndex(index, { background: false, timeoutMS: remainingTimeMS });
316
394
  }
317
395
 
318
396
  await checkChunksIndex(stream);
@@ -386,6 +464,18 @@ function doWrite(
386
464
  let doc: GridFSChunk;
387
465
  if (spaceRemaining === 0) {
388
466
  doc = createChunkDoc(stream.id, stream.n, Buffer.from(stream.bufToStore));
467
+
468
+ const remainingTimeMS = stream.timeoutContext?.remainingTimeMS;
469
+ if (remainingTimeMS != null && remainingTimeMS <= 0) {
470
+ return handleError(
471
+ stream,
472
+ new MongoOperationTimeoutError(
473
+ `Upload timed out after ${stream.timeoutContext?.timeoutMS}ms`
474
+ ),
475
+ callback
476
+ );
477
+ }
478
+
389
479
  ++stream.state.outstandingRequests;
390
480
  ++outstandingRequests;
391
481
 
@@ -393,17 +483,21 @@ function doWrite(
393
483
  return;
394
484
  }
395
485
 
396
- stream.chunks.insertOne(doc, { writeConcern: stream.writeConcern }).then(
397
- () => {
398
- --stream.state.outstandingRequests;
399
- --outstandingRequests;
400
-
401
- if (!outstandingRequests) {
402
- checkDone(stream, callback);
486
+ stream.chunks
487
+ .insertOne(doc, { writeConcern: stream.writeConcern, timeoutMS: remainingTimeMS })
488
+ .then(
489
+ () => {
490
+ --stream.state.outstandingRequests;
491
+ --outstandingRequests;
492
+
493
+ if (!outstandingRequests) {
494
+ checkDone(stream, callback);
495
+ }
496
+ },
497
+ error => {
498
+ return handleError(stream, error, callback);
403
499
  }
404
- },
405
- error => handleError(stream, error, callback)
406
- );
500
+ );
407
501
 
408
502
  spaceRemaining = stream.chunkSizeBytes;
409
503
  stream.pos = 0;
@@ -420,8 +514,6 @@ function writeRemnant(stream: GridFSBucketWriteStream, callback: Callback): void
420
514
  return checkDone(stream, callback);
421
515
  }
422
516
 
423
- ++stream.state.outstandingRequests;
424
-
425
517
  // Create a new buffer to make sure the buffer isn't bigger than it needs
426
518
  // to be.
427
519
  const remnant = Buffer.alloc(stream.pos);
@@ -433,13 +525,28 @@ function writeRemnant(stream: GridFSBucketWriteStream, callback: Callback): void
433
525
  return;
434
526
  }
435
527
 
436
- stream.chunks.insertOne(doc, { writeConcern: stream.writeConcern }).then(
437
- () => {
438
- --stream.state.outstandingRequests;
439
- checkDone(stream, callback);
440
- },
441
- error => handleError(stream, error, callback)
442
- );
528
+ const remainingTimeMS = stream.timeoutContext?.remainingTimeMS;
529
+ if (remainingTimeMS != null && remainingTimeMS <= 0) {
530
+ return handleError(
531
+ stream,
532
+ new MongoOperationTimeoutError(
533
+ `Upload timed out after ${stream.timeoutContext?.timeoutMS}ms`
534
+ ),
535
+ callback
536
+ );
537
+ }
538
+ ++stream.state.outstandingRequests;
539
+ stream.chunks
540
+ .insertOne(doc, { writeConcern: stream.writeConcern, timeoutMS: remainingTimeMS })
541
+ .then(
542
+ () => {
543
+ --stream.state.outstandingRequests;
544
+ checkDone(stream, callback);
545
+ },
546
+ error => {
547
+ return handleError(stream, error, callback);
548
+ }
549
+ );
443
550
  }
444
551
 
445
552
  function isAborted(stream: GridFSBucketWriteStream, callback: Callback<void>): boolean {
package/src/index.ts CHANGED
@@ -10,6 +10,7 @@ import { ListCollectionsCursor } from './cursor/list_collections_cursor';
10
10
  import { ListIndexesCursor } from './cursor/list_indexes_cursor';
11
11
  import type { RunCommandCursor } from './cursor/run_command_cursor';
12
12
  import { Db } from './db';
13
+ import { ExplainableCursor } from './explain';
13
14
  import { GridFSBucket } from './gridfs';
14
15
  import { GridFSBucketReadStream } from './gridfs/download';
15
16
  import { GridFSBucketWriteStream } from './gridfs/upload';
@@ -36,7 +37,11 @@ export {
36
37
  Timestamp,
37
38
  UUID
38
39
  } from './bson';
39
- export { AnyBulkWriteOperation, BulkWriteOptions, MongoBulkWriteError } from './bulk/common';
40
+ export {
41
+ type AnyBulkWriteOperation,
42
+ type BulkWriteOptions,
43
+ MongoBulkWriteError
44
+ } from './bulk/common';
40
45
  export { ClientEncryption } from './client-side-encryption/client_encryption';
41
46
  export { ChangeStreamCursor } from './cursor/change_stream_cursor';
42
47
  export {
@@ -66,6 +71,7 @@ export {
66
71
  MongoNetworkTimeoutError,
67
72
  MongoNotConnectedError,
68
73
  MongoOIDCError,
74
+ MongoOperationTimeoutError,
69
75
  MongoParseError,
70
76
  MongoRuntimeError,
71
77
  MongoServerClosedError,
@@ -90,6 +96,7 @@ export {
90
96
  ClientSession,
91
97
  Collection,
92
98
  Db,
99
+ ExplainableCursor,
93
100
  FindCursor,
94
101
  GridFSBucket,
95
102
  GridFSBucketReadStream,
@@ -108,7 +115,7 @@ export { AutoEncryptionLoggerLevel } from './client-side-encryption/auto_encrypt
108
115
  export { GSSAPICanonicalizationValue } from './cmap/auth/gssapi';
109
116
  export { AuthMechanism } from './cmap/auth/providers';
110
117
  export { Compressor } from './cmap/wire_protocol/compression';
111
- export { CURSOR_FLAGS } from './cursor/abstract_cursor';
118
+ export { CURSOR_FLAGS, CursorTimeoutMode } from './cursor/abstract_cursor';
112
119
  export { MongoErrorLabel } from './error';
113
120
  export { ExplainVerbosity } from './explain';
114
121
  export { ServerApiVersion } from './mongo_client';
@@ -358,6 +365,7 @@ export type {
358
365
  CursorStreamOptions
359
366
  } from './cursor/abstract_cursor';
360
367
  export type {
368
+ CursorTimeoutContext,
361
369
  InitialCursorResponse,
362
370
  InternalAbstractCursorOptions
363
371
  } from './cursor/abstract_cursor';
@@ -553,7 +561,7 @@ export type {
553
561
  ReadPreferenceOptions
554
562
  } from './read_preference';
555
563
  export type { AsyncDisposable } from './resource_management';
556
- export type { ClusterTime, TimerQueue } from './sdam/common';
564
+ export type { ClusterTime } from './sdam/common';
557
565
  export type {
558
566
  Monitor,
559
567
  MonitorEvents,
@@ -566,7 +574,13 @@ export type {
566
574
  RTTSampler,
567
575
  ServerMonitoringMode
568
576
  } from './sdam/monitor';
569
- export type { Server, ServerEvents, ServerOptions, ServerPrivate } from './sdam/server';
577
+ export type {
578
+ Server,
579
+ ServerCommandOptions,
580
+ ServerEvents,
581
+ ServerOptions,
582
+ ServerPrivate
583
+ } from './sdam/server';
570
584
  export type {
571
585
  ServerDescription,
572
586
  ServerDescriptionOptions,
@@ -597,7 +611,15 @@ export type {
597
611
  WithTransactionCallback
598
612
  } from './sessions';
599
613
  export type { Sort, SortDirection, SortDirectionForCmd, SortForCmd } from './sort';
600
- export type { Timeout } from './timeout';
614
+ export type {
615
+ CSOTTimeoutContext,
616
+ CSOTTimeoutContextOptions,
617
+ LegacyTimeoutContext,
618
+ LegacyTimeoutContextOptions,
619
+ Timeout,
620
+ TimeoutContext,
621
+ TimeoutContextOptions
622
+ } from './timeout';
601
623
  export type { Transaction, TransactionOptions, TxnState } from './transactions';
602
624
  export type {
603
625
  BufferPool,