mongodb 7.0.0 → 7.1.0-dev.20260205.sha.d2ad07f2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/bson.js +2 -1
- package/lib/bson.js.map +1 -1
- package/lib/change_stream.js +3 -1
- package/lib/change_stream.js.map +1 -1
- package/lib/client-side-encryption/state_machine.js +1 -0
- package/lib/client-side-encryption/state_machine.js.map +1 -1
- package/lib/cmap/auth/aws4.js +161 -0
- package/lib/cmap/auth/aws4.js.map +1 -0
- package/lib/cmap/auth/aws_temporary_credentials.js +1 -0
- package/lib/cmap/auth/aws_temporary_credentials.js.map +1 -1
- package/lib/cmap/auth/gssapi.js +2 -4
- package/lib/cmap/auth/gssapi.js.map +1 -1
- package/lib/cmap/auth/mongo_credentials.js +2 -1
- package/lib/cmap/auth/mongo_credentials.js.map +1 -1
- package/lib/cmap/auth/mongodb_aws.js +9 -14
- package/lib/cmap/auth/mongodb_aws.js.map +1 -1
- package/lib/cmap/auth/mongodb_oidc/k8s_machine_workflow.js +1 -0
- package/lib/cmap/auth/mongodb_oidc/k8s_machine_workflow.js.map +1 -1
- package/lib/cmap/auth/mongodb_oidc/token_machine_workflow.js +1 -0
- package/lib/cmap/auth/mongodb_oidc/token_machine_workflow.js.map +1 -1
- package/lib/cmap/connect.js +15 -0
- package/lib/cmap/connect.js.map +1 -1
- package/lib/cmap/connection.js +3 -3
- package/lib/cmap/connection.js.map +1 -1
- package/lib/cmap/connection_pool.js +8 -8
- package/lib/cmap/connection_pool.js.map +1 -1
- package/lib/cmap/connection_pool_events.js +3 -3
- package/lib/cmap/connection_pool_events.js.map +1 -1
- package/lib/cmap/handshake/client_metadata.js +7 -7
- package/lib/cmap/handshake/client_metadata.js.map +1 -1
- package/lib/cmap/wire_protocol/compression.js +18 -3
- package/lib/cmap/wire_protocol/compression.js.map +1 -1
- package/lib/connection_string.js +6 -0
- package/lib/connection_string.js.map +1 -1
- package/lib/db.js +0 -1
- package/lib/db.js.map +1 -1
- package/lib/deps.js +0 -13
- package/lib/deps.js.map +1 -1
- package/lib/error.js +5 -8
- package/lib/error.js.map +1 -1
- package/lib/gridfs/upload.js +8 -8
- package/lib/gridfs/upload.js.map +1 -1
- package/lib/mongo_client.js +1 -1
- package/lib/mongo_client.js.map +1 -1
- package/lib/mongo_logger.js +11 -5
- package/lib/mongo_logger.js.map +1 -1
- package/lib/operations/execute_operation.js +5 -4
- package/lib/operations/execute_operation.js.map +1 -1
- package/lib/operations/rename.js.map +1 -1
- package/lib/runtime_adapters.js +16 -0
- package/lib/runtime_adapters.js.map +1 -0
- package/lib/sdam/monitor.js +8 -8
- package/lib/sdam/monitor.js.map +1 -1
- package/lib/sdam/server.js +41 -29
- package/lib/sdam/server.js.map +1 -1
- package/lib/sdam/server_description.js +1 -1
- package/lib/sdam/server_description.js.map +1 -1
- package/lib/sdam/server_selection.js +135 -72
- package/lib/sdam/server_selection.js.map +1 -1
- package/lib/sdam/topology.js +9 -7
- package/lib/sdam/topology.js.map +1 -1
- package/lib/sdam/topology_description.js +1 -1
- package/lib/sdam/topology_description.js.map +1 -1
- package/lib/sessions.js +87 -23
- package/lib/sessions.js.map +1 -1
- package/lib/utils.js +21 -47
- package/lib/utils.js.map +1 -1
- package/mongodb.d.ts +39 -2
- package/package.json +10 -12
- package/src/bson.ts +1 -0
- package/src/change_stream.ts +3 -1
- package/src/client-side-encryption/state_machine.ts +1 -0
- package/src/cmap/auth/aws4.ts +207 -0
- package/src/cmap/auth/aws_temporary_credentials.ts +2 -0
- package/src/cmap/auth/gssapi.ts +8 -4
- package/src/cmap/auth/mongo_credentials.ts +2 -1
- package/src/cmap/auth/mongodb_aws.ts +10 -17
- package/src/cmap/auth/mongodb_oidc/k8s_machine_workflow.ts +1 -0
- package/src/cmap/auth/mongodb_oidc/token_machine_workflow.ts +1 -0
- package/src/cmap/connect.ts +19 -0
- package/src/cmap/connection.ts +7 -4
- package/src/cmap/connection_pool.ts +9 -9
- package/src/cmap/connection_pool_events.ts +4 -4
- package/src/cmap/handshake/client_metadata.ts +10 -9
- package/src/cmap/wire_protocol/compression.ts +17 -3
- package/src/connection_string.ts +7 -0
- package/src/db.ts +0 -1
- package/src/deps.ts +0 -60
- package/src/error.ts +4 -8
- package/src/gridfs/upload.ts +8 -8
- package/src/index.ts +2 -1
- package/src/mongo_client.ts +12 -2
- package/src/mongo_logger.ts +11 -6
- package/src/operations/execute_operation.ts +6 -5
- package/src/operations/rename.ts +6 -1
- package/src/runtime_adapters.ts +49 -0
- package/src/sdam/monitor.ts +10 -10
- package/src/sdam/server.ts +50 -32
- package/src/sdam/server_description.ts +8 -2
- package/src/sdam/server_selection.ts +188 -96
- package/src/sdam/topology.ts +20 -16
- package/src/sdam/topology_description.ts +1 -1
- package/src/sessions.ts +114 -30
- package/src/utils.ts +17 -74
|
@@ -36,7 +36,7 @@ import {
|
|
|
36
36
|
List,
|
|
37
37
|
makeCounter,
|
|
38
38
|
noop,
|
|
39
|
-
|
|
39
|
+
processTimeMS,
|
|
40
40
|
promiseWithResolvers
|
|
41
41
|
} from '../utils';
|
|
42
42
|
import { connect } from './connect';
|
|
@@ -231,7 +231,7 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
|
|
|
231
231
|
this.mongoLogger = this.server.topology.client?.mongoLogger;
|
|
232
232
|
this.component = 'connection';
|
|
233
233
|
|
|
234
|
-
|
|
234
|
+
queueMicrotask(() => {
|
|
235
235
|
this.emitAndLog(ConnectionPool.CONNECTION_POOL_CREATED, new ConnectionPoolCreatedEvent(this));
|
|
236
236
|
});
|
|
237
237
|
}
|
|
@@ -319,7 +319,7 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
|
|
|
319
319
|
* explicitly destroyed by the new owner.
|
|
320
320
|
*/
|
|
321
321
|
async checkOut(options: { timeoutContext: TimeoutContext } & Abortable): Promise<Connection> {
|
|
322
|
-
const checkoutTime =
|
|
322
|
+
const checkoutTime = processTimeMS();
|
|
323
323
|
this.emitAndLog(
|
|
324
324
|
ConnectionPool.CONNECTION_CHECK_OUT_STARTED,
|
|
325
325
|
new ConnectionCheckOutStartedEvent(this)
|
|
@@ -342,7 +342,7 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
|
|
|
342
342
|
});
|
|
343
343
|
|
|
344
344
|
this.waitQueue.push(waitQueueMember);
|
|
345
|
-
|
|
345
|
+
queueMicrotask(() => this.processWaitQueue());
|
|
346
346
|
|
|
347
347
|
try {
|
|
348
348
|
timeout?.throwIfExpired();
|
|
@@ -405,7 +405,7 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
|
|
|
405
405
|
this.destroyConnection(connection, reason);
|
|
406
406
|
}
|
|
407
407
|
|
|
408
|
-
|
|
408
|
+
queueMicrotask(() => this.processWaitQueue());
|
|
409
409
|
}
|
|
410
410
|
|
|
411
411
|
/**
|
|
@@ -461,7 +461,7 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
|
|
|
461
461
|
}
|
|
462
462
|
|
|
463
463
|
if (interruptInUseConnections) {
|
|
464
|
-
|
|
464
|
+
queueMicrotask(() => this.interruptInUseConnections(oldGeneration));
|
|
465
465
|
}
|
|
466
466
|
|
|
467
467
|
this.processWaitQueue();
|
|
@@ -616,7 +616,7 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
|
|
|
616
616
|
|
|
617
617
|
this.pending++;
|
|
618
618
|
// This is our version of a "virtual" no-I/O connection as the spec requires
|
|
619
|
-
const connectionCreatedTime =
|
|
619
|
+
const connectionCreatedTime = processTimeMS();
|
|
620
620
|
this.emitAndLog(
|
|
621
621
|
ConnectionPool.CONNECTION_CREATED,
|
|
622
622
|
new ConnectionCreatedEvent(this, { id: connectOptions.id })
|
|
@@ -702,7 +702,7 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
|
|
|
702
702
|
this.createConnection((err, connection) => {
|
|
703
703
|
if (!err && connection) {
|
|
704
704
|
this.connections.push(connection);
|
|
705
|
-
|
|
705
|
+
queueMicrotask(() => this.processWaitQueue());
|
|
706
706
|
}
|
|
707
707
|
if (this.poolState === PoolState.ready) {
|
|
708
708
|
clearTimeout(this.minPoolSizeTimer);
|
|
@@ -809,7 +809,7 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
|
|
|
809
809
|
waitQueueMember.resolve(connection);
|
|
810
810
|
}
|
|
811
811
|
}
|
|
812
|
-
|
|
812
|
+
queueMicrotask(() => this.processWaitQueue());
|
|
813
813
|
});
|
|
814
814
|
}
|
|
815
815
|
this.processingWaitQueue = false;
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
CONNECTION_READY
|
|
14
14
|
} from '../constants';
|
|
15
15
|
import type { MongoError } from '../error';
|
|
16
|
-
import {
|
|
16
|
+
import { processTimeMS } from '../utils';
|
|
17
17
|
import type { Connection } from './connection';
|
|
18
18
|
import type { ConnectionPool, ConnectionPoolOptions } from './connection_pool';
|
|
19
19
|
|
|
@@ -145,7 +145,7 @@ export class ConnectionReadyEvent extends ConnectionPoolMonitoringEvent {
|
|
|
145
145
|
/** @internal */
|
|
146
146
|
constructor(pool: ConnectionPool, connection: Connection, connectionCreatedEventTime: number) {
|
|
147
147
|
super(pool);
|
|
148
|
-
this.durationMS =
|
|
148
|
+
this.durationMS = processTimeMS() - connectionCreatedEventTime;
|
|
149
149
|
this.connectionId = connection.id;
|
|
150
150
|
}
|
|
151
151
|
}
|
|
@@ -224,7 +224,7 @@ export class ConnectionCheckOutFailedEvent extends ConnectionPoolMonitoringEvent
|
|
|
224
224
|
error?: MongoError
|
|
225
225
|
) {
|
|
226
226
|
super(pool);
|
|
227
|
-
this.durationMS =
|
|
227
|
+
this.durationMS = processTimeMS() - checkoutTime;
|
|
228
228
|
this.reason = reason;
|
|
229
229
|
this.error = error;
|
|
230
230
|
}
|
|
@@ -252,7 +252,7 @@ export class ConnectionCheckedOutEvent extends ConnectionPoolMonitoringEvent {
|
|
|
252
252
|
/** @internal */
|
|
253
253
|
constructor(pool: ConnectionPool, connection: Connection, checkoutTime: number) {
|
|
254
254
|
super(pool);
|
|
255
|
-
this.durationMS =
|
|
255
|
+
this.durationMS = processTimeMS() - checkoutTime;
|
|
256
256
|
this.connectionId = connection.id;
|
|
257
257
|
}
|
|
258
258
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import * as os from 'os';
|
|
2
1
|
import * as process from 'process';
|
|
3
2
|
|
|
4
|
-
import { BSON, type Document, Int32 } from '../../bson';
|
|
3
|
+
import { BSON, type Document, Int32, NumberUtils } from '../../bson';
|
|
5
4
|
import { MongoInvalidArgumentError } from '../../error';
|
|
6
5
|
import type { DriverInfo, MongoOptions } from '../../mongo_client';
|
|
7
6
|
import { fileIsAccessible } from '../../utils';
|
|
@@ -96,7 +95,8 @@ export class LimitedSizeDocument {
|
|
|
96
95
|
}
|
|
97
96
|
}
|
|
98
97
|
|
|
99
|
-
type MakeClientMetadataOptions = Pick<MongoOptions, 'appName'>;
|
|
98
|
+
type MakeClientMetadataOptions = Pick<MongoOptions, 'appName' | 'runtime'>;
|
|
99
|
+
|
|
100
100
|
/**
|
|
101
101
|
* From the specs:
|
|
102
102
|
* Implementors SHOULD cumulatively update fields in the following order until the document is under the size limit:
|
|
@@ -107,7 +107,7 @@ type MakeClientMetadataOptions = Pick<MongoOptions, 'appName'>;
|
|
|
107
107
|
*/
|
|
108
108
|
export async function makeClientMetadata(
|
|
109
109
|
driverInfoList: DriverInfo[],
|
|
110
|
-
{ appName = '' }: MakeClientMetadataOptions
|
|
110
|
+
{ appName = '', runtime: { os } }: MakeClientMetadataOptions
|
|
111
111
|
): Promise<ClientMetadata> {
|
|
112
112
|
const metadataDocument = new LimitedSizeDocument(512);
|
|
113
113
|
|
|
@@ -157,8 +157,8 @@ export async function makeClientMetadata(
|
|
|
157
157
|
|
|
158
158
|
// Note: order matters, os.type is last so it will be removed last if we're at maxSize
|
|
159
159
|
const osInfo = new Map()
|
|
160
|
-
.set('name',
|
|
161
|
-
.set('architecture',
|
|
160
|
+
.set('name', os.platform())
|
|
161
|
+
.set('architecture', os.arch())
|
|
162
162
|
.set('version', os.release())
|
|
163
163
|
.set('type', os.type());
|
|
164
164
|
|
|
@@ -336,17 +336,18 @@ declare const Bun: { (): void; version?: string } | undefined;
|
|
|
336
336
|
* with a future change to these global objects.
|
|
337
337
|
*/
|
|
338
338
|
function getRuntimeInfo(): string {
|
|
339
|
+
const endianness = NumberUtils.isBigEndian ? 'BE' : 'LE';
|
|
339
340
|
if ('Deno' in globalThis) {
|
|
340
341
|
const version = typeof Deno?.version?.deno === 'string' ? Deno?.version?.deno : '0.0.0-unknown';
|
|
341
342
|
|
|
342
|
-
return `Deno v${version}, ${
|
|
343
|
+
return `Deno v${version}, ${endianness}`;
|
|
343
344
|
}
|
|
344
345
|
|
|
345
346
|
if ('Bun' in globalThis) {
|
|
346
347
|
const version = typeof Bun?.version === 'string' ? Bun?.version : '0.0.0-unknown';
|
|
347
348
|
|
|
348
|
-
return `Bun v${version}, ${
|
|
349
|
+
return `Bun v${version}, ${endianness}`;
|
|
349
350
|
}
|
|
350
351
|
|
|
351
|
-
return `Node.js ${process.version}, ${
|
|
352
|
+
return `Node.js ${process.version}, ${endianness}`;
|
|
352
353
|
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { promisify } from 'util';
|
|
2
1
|
import * as zlib from 'zlib';
|
|
3
2
|
|
|
4
3
|
import { LEGACY_HELLO_COMMAND } from '../../constants';
|
|
@@ -43,8 +42,23 @@ export const uncompressibleCommands = new Set([
|
|
|
43
42
|
|
|
44
43
|
const ZSTD_COMPRESSION_LEVEL = 3;
|
|
45
44
|
|
|
46
|
-
const zlibInflate =
|
|
47
|
-
|
|
45
|
+
const zlibInflate = (buf: zlib.InputType) => {
|
|
46
|
+
return new Promise<Buffer>((resolve, reject) => {
|
|
47
|
+
zlib.inflate(buf, (error, result) => {
|
|
48
|
+
if (error) return reject(error);
|
|
49
|
+
resolve(result);
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
const zlibDeflate = (buf: zlib.InputType, options: zlib.ZlibOptions) => {
|
|
55
|
+
return new Promise<Buffer>((resolve, reject) => {
|
|
56
|
+
zlib.deflate(buf, options, (error, result) => {
|
|
57
|
+
if (error) return reject(error);
|
|
58
|
+
resolve(result);
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
};
|
|
48
62
|
|
|
49
63
|
let zstd: ZStandard;
|
|
50
64
|
let Snappy: SnappyLib | null = null;
|
package/src/connection_string.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as dns from 'dns';
|
|
2
2
|
import ConnectionString from 'mongodb-connection-string-url';
|
|
3
|
+
import * as process from 'process';
|
|
3
4
|
import { URLSearchParams } from 'url';
|
|
4
5
|
|
|
5
6
|
import type { Document } from './bson';
|
|
@@ -19,6 +20,7 @@ import {
|
|
|
19
20
|
import { MongoLoggableComponent, MongoLogger, SeverityLevel } from './mongo_logger';
|
|
20
21
|
import { ReadConcern, type ReadConcernLevel } from './read_concern';
|
|
21
22
|
import { ReadPreference, type ReadPreferenceMode } from './read_preference';
|
|
23
|
+
import { resolveRuntimeAdapters } from './runtime_adapters';
|
|
22
24
|
import { ServerMonitoringMode } from './sdam/monitor';
|
|
23
25
|
import type { TagSet } from './sdam/server_description';
|
|
24
26
|
import {
|
|
@@ -537,6 +539,8 @@ export function parseOptions(
|
|
|
537
539
|
}
|
|
538
540
|
);
|
|
539
541
|
|
|
542
|
+
mongoOptions.runtime = resolveRuntimeAdapters(options);
|
|
543
|
+
|
|
540
544
|
return mongoOptions;
|
|
541
545
|
}
|
|
542
546
|
|
|
@@ -1060,6 +1064,9 @@ export const OPTIONS = {
|
|
|
1060
1064
|
default: true,
|
|
1061
1065
|
type: 'boolean'
|
|
1062
1066
|
},
|
|
1067
|
+
runtimeAdapters: {
|
|
1068
|
+
type: 'record'
|
|
1069
|
+
},
|
|
1063
1070
|
serializeFunctions: {
|
|
1064
1071
|
type: 'boolean'
|
|
1065
1072
|
},
|
package/src/db.ts
CHANGED
package/src/deps.ts
CHANGED
|
@@ -203,66 +203,6 @@ export function getSocks(): SocksLib | { kModuleError: MongoMissingDependencyErr
|
|
|
203
203
|
}
|
|
204
204
|
}
|
|
205
205
|
|
|
206
|
-
interface AWS4 {
|
|
207
|
-
/**
|
|
208
|
-
* Created these inline types to better assert future usage of this API
|
|
209
|
-
* @param options - options for request
|
|
210
|
-
* @param credentials - AWS credential details, sessionToken should be omitted entirely if its false-y
|
|
211
|
-
*/
|
|
212
|
-
sign(
|
|
213
|
-
this: void,
|
|
214
|
-
options: {
|
|
215
|
-
path: '/';
|
|
216
|
-
body: string;
|
|
217
|
-
host: string;
|
|
218
|
-
method: 'POST';
|
|
219
|
-
headers: {
|
|
220
|
-
'Content-Type': 'application/x-www-form-urlencoded';
|
|
221
|
-
'Content-Length': number;
|
|
222
|
-
'X-MongoDB-Server-Nonce': string;
|
|
223
|
-
'X-MongoDB-GS2-CB-Flag': 'n';
|
|
224
|
-
};
|
|
225
|
-
service: string;
|
|
226
|
-
region: string;
|
|
227
|
-
},
|
|
228
|
-
credentials:
|
|
229
|
-
| {
|
|
230
|
-
accessKeyId: string;
|
|
231
|
-
secretAccessKey: string;
|
|
232
|
-
sessionToken: string;
|
|
233
|
-
}
|
|
234
|
-
| {
|
|
235
|
-
accessKeyId: string;
|
|
236
|
-
secretAccessKey: string;
|
|
237
|
-
}
|
|
238
|
-
| undefined
|
|
239
|
-
): {
|
|
240
|
-
headers: {
|
|
241
|
-
Authorization: string;
|
|
242
|
-
'X-Amz-Date': string;
|
|
243
|
-
};
|
|
244
|
-
};
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
export const aws4: AWS4 | { kModuleError: MongoMissingDependencyError } = loadAws4();
|
|
248
|
-
|
|
249
|
-
function loadAws4() {
|
|
250
|
-
let aws4: AWS4 | { kModuleError: MongoMissingDependencyError };
|
|
251
|
-
try {
|
|
252
|
-
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
253
|
-
aws4 = require('aws4');
|
|
254
|
-
} catch (error) {
|
|
255
|
-
aws4 = makeErrorModule(
|
|
256
|
-
new MongoMissingDependencyError(
|
|
257
|
-
'Optional module `aws4` not found. Please install it to enable AWS authentication',
|
|
258
|
-
{ cause: error, dependencyName: 'aws4' }
|
|
259
|
-
)
|
|
260
|
-
);
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
return aws4;
|
|
264
|
-
}
|
|
265
|
-
|
|
266
206
|
/** A utility function to get the instance of mongodb-client-encryption, if it exists. */
|
|
267
207
|
export function getMongoDBClientEncryption():
|
|
268
208
|
| typeof import('mongodb-client-encryption')
|
package/src/error.ts
CHANGED
|
@@ -99,7 +99,9 @@ export const MongoErrorLabel = Object.freeze({
|
|
|
99
99
|
ResetPool: 'ResetPool',
|
|
100
100
|
PoolRequestedRetry: 'PoolRequestedRetry',
|
|
101
101
|
InterruptInUseConnections: 'InterruptInUseConnections',
|
|
102
|
-
NoWritesPerformed: 'NoWritesPerformed'
|
|
102
|
+
NoWritesPerformed: 'NoWritesPerformed',
|
|
103
|
+
RetryableError: 'RetryableError',
|
|
104
|
+
SystemOverloadedError: 'SystemOverloadedError'
|
|
103
105
|
} as const);
|
|
104
106
|
|
|
105
107
|
/** @public */
|
|
@@ -1528,13 +1530,7 @@ export function isNodeShuttingDownError(err: MongoError): boolean {
|
|
|
1528
1530
|
*
|
|
1529
1531
|
* @see https://github.com/mongodb/specifications/blob/master/source/server-discovery-and-monitoring/server-discovery-and-monitoring.md#not-writable-primary-and-node-is-recovering
|
|
1530
1532
|
*/
|
|
1531
|
-
export function
|
|
1532
|
-
// NOTE: null check is here for a strictly pre-CMAP world, a timeout or
|
|
1533
|
-
// close event are considered unrecoverable
|
|
1534
|
-
if (error instanceof MongoParseError || error == null) {
|
|
1535
|
-
return true;
|
|
1536
|
-
}
|
|
1537
|
-
|
|
1533
|
+
export function isStateChangeError(error: MongoError): boolean {
|
|
1538
1534
|
return isRecoveringError(error) || isNotWritablePrimaryError(error);
|
|
1539
1535
|
}
|
|
1540
1536
|
|
package/src/gridfs/upload.ts
CHANGED
|
@@ -165,7 +165,7 @@ export class GridFSBucketWriteStream extends Writable {
|
|
|
165
165
|
}
|
|
166
166
|
);
|
|
167
167
|
} else {
|
|
168
|
-
return
|
|
168
|
+
return queueMicrotask(callback);
|
|
169
169
|
}
|
|
170
170
|
}
|
|
171
171
|
|
|
@@ -188,7 +188,7 @@ export class GridFSBucketWriteStream extends Writable {
|
|
|
188
188
|
/** @internal */
|
|
189
189
|
override _final(callback: (error?: Error | null) => void): void {
|
|
190
190
|
if (this.state.streamEnd) {
|
|
191
|
-
return
|
|
191
|
+
return queueMicrotask(callback);
|
|
192
192
|
}
|
|
193
193
|
this.state.streamEnd = true;
|
|
194
194
|
writeRemnant(this, callback);
|
|
@@ -220,11 +220,11 @@ export class GridFSBucketWriteStream extends Writable {
|
|
|
220
220
|
|
|
221
221
|
function handleError(stream: GridFSBucketWriteStream, error: Error, callback: Callback): void {
|
|
222
222
|
if (stream.state.errored) {
|
|
223
|
-
|
|
223
|
+
queueMicrotask(callback);
|
|
224
224
|
return;
|
|
225
225
|
}
|
|
226
226
|
stream.state.errored = true;
|
|
227
|
-
|
|
227
|
+
queueMicrotask(() => callback(error));
|
|
228
228
|
}
|
|
229
229
|
|
|
230
230
|
function createChunkDoc(filesId: ObjectId, n: number, data: Buffer): GridFSChunk {
|
|
@@ -283,7 +283,7 @@ async function checkChunksIndex(stream: GridFSBucketWriteStream): Promise<void>
|
|
|
283
283
|
|
|
284
284
|
function checkDone(stream: GridFSBucketWriteStream, callback: Callback): void {
|
|
285
285
|
if (stream.done) {
|
|
286
|
-
return
|
|
286
|
+
return queueMicrotask(callback);
|
|
287
287
|
}
|
|
288
288
|
|
|
289
289
|
if (stream.state.streamEnd && stream.state.outstandingRequests === 0 && !stream.state.errored) {
|
|
@@ -327,7 +327,7 @@ function checkDone(stream: GridFSBucketWriteStream, callback: Callback): void {
|
|
|
327
327
|
return;
|
|
328
328
|
}
|
|
329
329
|
|
|
330
|
-
|
|
330
|
+
queueMicrotask(callback);
|
|
331
331
|
}
|
|
332
332
|
|
|
333
333
|
async function checkIndexes(stream: GridFSBucketWriteStream): Promise<void> {
|
|
@@ -425,7 +425,7 @@ function doWrite(
|
|
|
425
425
|
if (stream.pos + inputBuf.length < stream.chunkSizeBytes) {
|
|
426
426
|
inputBuf.copy(stream.bufToStore, stream.pos);
|
|
427
427
|
stream.pos += inputBuf.length;
|
|
428
|
-
|
|
428
|
+
queueMicrotask(callback);
|
|
429
429
|
return;
|
|
430
430
|
}
|
|
431
431
|
|
|
@@ -530,7 +530,7 @@ function writeRemnant(stream: GridFSBucketWriteStream, callback: Callback): void
|
|
|
530
530
|
|
|
531
531
|
function isAborted(stream: GridFSBucketWriteStream, callback: Callback<void>): boolean {
|
|
532
532
|
if (stream.state.aborted) {
|
|
533
|
-
|
|
533
|
+
queueMicrotask(() => callback(new MongoAPIError('Stream has been aborted')));
|
|
534
534
|
return true;
|
|
535
535
|
}
|
|
536
536
|
return false;
|
package/src/index.ts
CHANGED
|
@@ -562,6 +562,7 @@ export type {
|
|
|
562
562
|
ReadPreferenceLikeOptions,
|
|
563
563
|
ReadPreferenceOptions
|
|
564
564
|
} from './read_preference';
|
|
565
|
+
export type { OsAdapter, Runtime, RuntimeAdapters } from './runtime_adapters';
|
|
565
566
|
export type { ClusterTime } from './sdam/common';
|
|
566
567
|
export type {
|
|
567
568
|
Monitor,
|
|
@@ -588,7 +589,7 @@ export type {
|
|
|
588
589
|
TagSet,
|
|
589
590
|
TopologyVersion
|
|
590
591
|
} from './sdam/server_description';
|
|
591
|
-
export type { ServerSelector } from './sdam/server_selection';
|
|
592
|
+
export type { DeprioritizedServers, ServerSelector } from './sdam/server_selection';
|
|
592
593
|
export type { SrvPoller, SrvPollerEvents, SrvPollerOptions } from './sdam/srv_polling';
|
|
593
594
|
export type {
|
|
594
595
|
ConnectOptions,
|
package/src/mongo_client.ts
CHANGED
|
@@ -46,9 +46,10 @@ import { EndSessionsOperation } from './operations/end_sessions';
|
|
|
46
46
|
import { executeOperation } from './operations/execute_operation';
|
|
47
47
|
import type { ReadConcern, ReadConcernLevel, ReadConcernLike } from './read_concern';
|
|
48
48
|
import { ReadPreference, type ReadPreferenceMode } from './read_preference';
|
|
49
|
+
import { type Runtime, type RuntimeAdapters } from './runtime_adapters';
|
|
49
50
|
import type { ServerMonitoringMode } from './sdam/monitor';
|
|
50
51
|
import type { TagSet } from './sdam/server_description';
|
|
51
|
-
import { readPreferenceServerSelector } from './sdam/server_selection';
|
|
52
|
+
import { DeprioritizedServers, readPreferenceServerSelector } from './sdam/server_selection';
|
|
52
53
|
import type { SrvPoller } from './sdam/srv_polling';
|
|
53
54
|
import { Topology, type TopologyEvents } from './sdam/topology';
|
|
54
55
|
import { ClientSession, type ClientSessionOptions, ServerSessionPool } from './sessions';
|
|
@@ -318,6 +319,12 @@ export interface MongoClientOptions extends BSONSerializeOptions, SupportedNodeC
|
|
|
318
319
|
connectionType?: typeof Connection;
|
|
319
320
|
/** @internal */
|
|
320
321
|
__skipPingOnConnect?: boolean;
|
|
322
|
+
/**
|
|
323
|
+
* @experimental
|
|
324
|
+
*
|
|
325
|
+
* If provided, any adapters provided will be used in place of the corresponding Node.js module.
|
|
326
|
+
*/
|
|
327
|
+
runtimeAdapters?: RuntimeAdapters;
|
|
321
328
|
}
|
|
322
329
|
|
|
323
330
|
/** @public */
|
|
@@ -789,7 +796,7 @@ export class MongoClient extends TypedEventEmitter<MongoClientEvents> implements
|
|
|
789
796
|
// to avoid the server selection timeout.
|
|
790
797
|
const selector = readPreferenceServerSelector(ReadPreference.primaryPreferred);
|
|
791
798
|
const serverDescriptions = Array.from(topologyDescription.servers.values());
|
|
792
|
-
const servers = selector(topologyDescription, serverDescriptions);
|
|
799
|
+
const servers = selector(topologyDescription, serverDescriptions, new DeprioritizedServers());
|
|
793
800
|
if (servers.length !== 0) {
|
|
794
801
|
const endSessions = Array.from(client.s.sessionPool.sessions, ({ id }) => id);
|
|
795
802
|
if (endSessions.length !== 0) {
|
|
@@ -1152,4 +1159,7 @@ export interface MongoOptions
|
|
|
1152
1159
|
timeoutMS?: number;
|
|
1153
1160
|
/** @internal */
|
|
1154
1161
|
__skipPingOnConnect?: boolean;
|
|
1162
|
+
|
|
1163
|
+
/** @internal */
|
|
1164
|
+
runtime: Runtime;
|
|
1155
1165
|
}
|
package/src/mongo_logger.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as process from 'process';
|
|
2
|
+
import { inspect } from 'util';
|
|
2
3
|
|
|
3
4
|
import {
|
|
4
5
|
type Binary,
|
|
@@ -240,11 +241,15 @@ export function createStdioLogger(stream: {
|
|
|
240
241
|
write: NodeJS.WriteStream['write'];
|
|
241
242
|
}): MongoDBLogWritable {
|
|
242
243
|
return {
|
|
243
|
-
write:
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
244
|
+
write: (log: Log): Promise<unknown> => {
|
|
245
|
+
return new Promise((resolve, reject) => {
|
|
246
|
+
const logLine = inspect(log, { compact: true, breakLength: Infinity });
|
|
247
|
+
stream.write(`${logLine}\n`, 'utf-8', error => {
|
|
248
|
+
if (error) return reject(error);
|
|
249
|
+
resolve(true);
|
|
250
|
+
});
|
|
251
|
+
});
|
|
252
|
+
}
|
|
248
253
|
};
|
|
249
254
|
}
|
|
250
255
|
|
|
@@ -17,8 +17,8 @@ import {
|
|
|
17
17
|
} from '../error';
|
|
18
18
|
import type { MongoClient } from '../mongo_client';
|
|
19
19
|
import { ReadPreference } from '../read_preference';
|
|
20
|
-
import type { ServerDescription } from '../sdam/server_description';
|
|
21
20
|
import {
|
|
21
|
+
DeprioritizedServers,
|
|
22
22
|
sameServerSelector,
|
|
23
23
|
secondaryWritableServerSelector,
|
|
24
24
|
type ServerSelector
|
|
@@ -207,7 +207,8 @@ async function tryOperation<T extends AbstractOperation, TResult = ResultTypeFro
|
|
|
207
207
|
session,
|
|
208
208
|
operationName: operation.commandName,
|
|
209
209
|
timeoutContext,
|
|
210
|
-
signal: operation.options.signal
|
|
210
|
+
signal: operation.options.signal,
|
|
211
|
+
deprioritizedServers: new DeprioritizedServers()
|
|
211
212
|
});
|
|
212
213
|
|
|
213
214
|
const hasReadAspect = operation.hasAspect(Aspect.READ_OPERATION);
|
|
@@ -234,7 +235,7 @@ async function tryOperation<T extends AbstractOperation, TResult = ResultTypeFro
|
|
|
234
235
|
|
|
235
236
|
const maxTries = willRetry ? (timeoutContext.csotEnabled() ? Infinity : 2) : 1;
|
|
236
237
|
let previousOperationError: MongoError | undefined;
|
|
237
|
-
|
|
238
|
+
const deprioritizedServers = new DeprioritizedServers();
|
|
238
239
|
|
|
239
240
|
for (let tries = 0; tries < maxTries; tries++) {
|
|
240
241
|
if (previousOperationError) {
|
|
@@ -270,7 +271,7 @@ async function tryOperation<T extends AbstractOperation, TResult = ResultTypeFro
|
|
|
270
271
|
server = await topology.selectServer(selector, {
|
|
271
272
|
session,
|
|
272
273
|
operationName: operation.commandName,
|
|
273
|
-
|
|
274
|
+
deprioritizedServers,
|
|
274
275
|
signal: operation.options.signal
|
|
275
276
|
});
|
|
276
277
|
|
|
@@ -303,7 +304,7 @@ async function tryOperation<T extends AbstractOperation, TResult = ResultTypeFro
|
|
|
303
304
|
) {
|
|
304
305
|
throw previousOperationError;
|
|
305
306
|
}
|
|
306
|
-
|
|
307
|
+
deprioritizedServers.add(server.description);
|
|
307
308
|
previousOperationError = operationError;
|
|
308
309
|
|
|
309
310
|
// Reset timeouts
|
package/src/operations/rename.ts
CHANGED
|
@@ -11,7 +11,12 @@ import { Aspect, defineAspects } from './operation';
|
|
|
11
11
|
export interface RenameOptions extends Omit<CommandOperationOptions, 'rawData'> {
|
|
12
12
|
/** Drop the target name collection if it previously exists. */
|
|
13
13
|
dropTarget?: boolean;
|
|
14
|
-
/**
|
|
14
|
+
/**
|
|
15
|
+
* @deprecated
|
|
16
|
+
*
|
|
17
|
+
* This option has been dead code since at least Node driver version 4.x. It will
|
|
18
|
+
* be removed in a future major release.
|
|
19
|
+
*/
|
|
15
20
|
new_collection?: boolean;
|
|
16
21
|
}
|
|
17
22
|
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/* eslint-disable no-restricted-imports, @typescript-eslint/no-require-imports */
|
|
2
|
+
|
|
3
|
+
// We squash the restricted import errors here because we are using type-only imports, which
|
|
4
|
+
// do not impact the driver's actual runtime dependencies.
|
|
5
|
+
// We also allow restricted imports in this file, because we expect this file to be the only place actually importing restricted Node APIs.
|
|
6
|
+
|
|
7
|
+
import type * as os from 'os';
|
|
8
|
+
|
|
9
|
+
import { type MongoClientOptions } from './mongo_client';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @public
|
|
13
|
+
* @experimental
|
|
14
|
+
*
|
|
15
|
+
* Represents the set of dependencies that the driver uses from the [Node.js OS module](https://nodejs.org/api/os.html).
|
|
16
|
+
*/
|
|
17
|
+
export type OsAdapter = Pick<typeof os, 'release' | 'platform' | 'arch' | 'type'>;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* @public
|
|
21
|
+
* @experimental
|
|
22
|
+
*
|
|
23
|
+
* This type represents the set of dependencies that the driver needs from the Javascript runtime in order to function.
|
|
24
|
+
*/
|
|
25
|
+
export interface RuntimeAdapters {
|
|
26
|
+
os?: OsAdapter;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* @internal
|
|
31
|
+
*
|
|
32
|
+
* Represents a complete, parsed set of runtime adapters. After options parsing, all adapters
|
|
33
|
+
* are always present (either using the user's provided adapter, or defaulting to the Node.js module).
|
|
34
|
+
*/
|
|
35
|
+
export interface Runtime {
|
|
36
|
+
os: OsAdapter;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* @internal
|
|
41
|
+
*
|
|
42
|
+
* Given a MongoClientOptions, this function resolves the set of runtime options, providing Nodejs implementations if
|
|
43
|
+
* not provided by in `options`, and returns a `Runtime`.
|
|
44
|
+
*/
|
|
45
|
+
export function resolveRuntimeAdapters(options: MongoClientOptions): Runtime {
|
|
46
|
+
return {
|
|
47
|
+
os: options.runtimeAdapters?.os ?? require('os')
|
|
48
|
+
};
|
|
49
|
+
}
|