11import { type Document } from '../bson' ;
22import { CursorResponse } from '../cmap/wire_protocol/responses' ;
3- import { MongoInvalidArgumentError , MongoTailableCursorError } from '../error' ;
4- import { type ExplainCommandOptions , type ExplainVerbosityLike } from '../explain' ;
3+ import { MongoAPIError , MongoInvalidArgumentError , MongoTailableCursorError } from '../error' ;
4+ import {
5+ Explain ,
6+ ExplainableCursor ,
7+ type ExplainCommandOptions ,
8+ type ExplainVerbosityLike ,
9+ validateExplainTimeoutOptions
10+ } from '../explain' ;
511import type { MongoClient } from '../mongo_client' ;
612import type { CollationOptions } from '../operations/command' ;
713import { CountOperation , type CountOptions } from '../operations/count' ;
@@ -11,7 +17,7 @@ import type { Hint } from '../operations/operation';
1117import type { ClientSession } from '../sessions' ;
1218import { formatSort , type Sort , type SortDirection } from '../sort' ;
1319import { emitWarningOnce , mergeOptions , type MongoDBNamespace , squashError } from '../utils' ;
14- import { AbstractCursor , type InitialCursorResponse } from './abstract_cursor' ;
20+ import { type InitialCursorResponse } from './abstract_cursor' ;
1521
1622/** @public Flags allowed for cursor */
1723export const FLAGS = [
@@ -24,7 +30,7 @@ export const FLAGS = [
2430] as const ;
2531
2632/** @public */
27- export class FindCursor < TSchema = any > extends AbstractCursor < TSchema > {
33+ export class FindCursor < TSchema = any > extends ExplainableCursor < TSchema > {
2834 /** @internal */
2935 private cursorFilter : Document ;
3036 /** @internal */
@@ -63,11 +69,21 @@ export class FindCursor<TSchema = any> extends AbstractCursor<TSchema> {
6369
6470 /** @internal */
6571 async _initialize ( session : ClientSession ) : Promise < InitialCursorResponse > {
66- const findOperation = new FindOperation ( this . namespace , this . cursorFilter , {
72+ const options = {
6773 ...this . findOptions , // NOTE: order matters here, we may need to refine this
6874 ...this . cursorOptions ,
6975 session
70- } ) ;
76+ } ;
77+
78+ try {
79+ validateExplainTimeoutOptions ( options , Explain . fromOptions ( options ) ) ;
80+ } catch {
81+ throw new MongoAPIError (
82+ 'timeoutMS cannot be used with explain when explain is specified in findOptions'
83+ ) ;
84+ }
85+
86+ const findOperation = new FindOperation ( this . namespace , this . cursorFilter , options ) ;
7187
7288 const response = await executeOperation ( this . client , findOperation , this . timeoutContext ) ;
7389
@@ -133,14 +149,27 @@ export class FindCursor<TSchema = any> extends AbstractCursor<TSchema> {
133149 }
134150
135151 /** Execute the explain for the cursor */
136- async explain ( verbosity ?: ExplainVerbosityLike | ExplainCommandOptions ) : Promise < Document > {
152+ async explain ( ) : Promise < Document > ;
153+ async explain ( verbosity : ExplainVerbosityLike | ExplainCommandOptions ) : Promise < Document > ;
154+ async explain ( options : { timeoutMS ?: number } ) : Promise < Document > ;
155+ async explain (
156+ verbosity : ExplainVerbosityLike | ExplainCommandOptions ,
157+ options : { timeoutMS ?: number }
158+ ) : Promise < Document > ;
159+ async explain (
160+ verbosity ?: ExplainVerbosityLike | ExplainCommandOptions | { timeoutMS ?: number } ,
161+ options ?: { timeoutMS ?: number }
162+ ) : Promise < Document > {
163+ const { explain, timeout } = this . resolveExplainTimeoutOptions ( verbosity , options ) ;
164+
137165 return (
138166 await executeOperation (
139167 this . client ,
140168 new FindOperation ( this . namespace , this . cursorFilter , {
141169 ...this . findOptions , // NOTE: order matters here, we may need to refine this
142170 ...this . cursorOptions ,
143- explain : verbosity ?? true
171+ ...timeout ,
172+ explain : explain ?? true
144173 } )
145174 )
146175 ) . shift ( this . deserializationOptions ) ;
0 commit comments