@@ -59,6 +59,7 @@ import {
5959 WorkflowStartUpdateOutput ,
6060 WorkflowStartUpdateWithStartInput ,
6161 WorkflowStartUpdateWithStartOutput ,
62+ WorkflowStartOutput ,
6263} from './interceptors' ;
6364import {
6465 CountWorkflowExecution ,
@@ -260,6 +261,15 @@ export interface WorkflowHandleWithFirstExecutionRunId<T extends Workflow = Work
260261 readonly firstExecutionRunId : string ;
261262}
262263
264+ /**
265+ * This interface is exactly the same as {@link WorkflowHandleWithFirstExecutionRunId} except it
266+ * includes the `eagerlyStarted` returned from {@link WorkflowClient.start}.
267+ */
268+ export interface WorkflowHandleWithStartDetails < T extends Workflow = Workflow >
269+ extends WorkflowHandleWithFirstExecutionRunId < T > {
270+ readonly eagerlyStarted : boolean ;
271+ }
272+
263273/**
264274 * This interface is exactly the same as {@link WorkflowHandle} except it
265275 * includes the `signaledRunId` returned from `signalWithStart`.
@@ -511,14 +521,22 @@ export class WorkflowClient extends BaseClient {
511521 workflowTypeOrFunc : string | T ,
512522 options : WithWorkflowArgs < T , WorkflowOptions > ,
513523 interceptors : WorkflowClientInterceptor [ ]
514- ) : Promise < string > {
524+ ) : Promise < WorkflowStartOutput > {
515525 const workflowType = extractWorkflowType ( workflowTypeOrFunc ) ;
516526 assertRequiredWorkflowOptions ( options ) ;
517527 const compiledOptions = compileWorkflowOptions ( ensureArgs ( options ) ) ;
518528
519- const start = composeInterceptors ( interceptors , 'start' , this . _startWorkflowHandler . bind ( this ) ) ;
529+ const adaptedInterceptors : WorkflowClientInterceptor [ ] = interceptors . map ( ( i ) =>
530+ i . startWithDetails ? i : { ...i , startWithDetails : ( input , next ) => next ( input ) }
531+ ) ;
532+
533+ const startWithDetails = composeInterceptors (
534+ adaptedInterceptors ,
535+ 'startWithDetails' ,
536+ this . _startWorkflowHandler . bind ( this )
537+ ) ;
520538
521- return start ( {
539+ return startWithDetails ( {
522540 options : compiledOptions ,
523541 headers : { } ,
524542 workflowType,
@@ -534,7 +552,6 @@ export class WorkflowClient extends BaseClient {
534552 const { signal, signalArgs, ...rest } = options ;
535553 assertRequiredWorkflowOptions ( rest ) ;
536554 const compiledOptions = compileWorkflowOptions ( ensureArgs ( rest ) ) ;
537-
538555 const signalWithStart = composeInterceptors (
539556 interceptors ,
540557 'signalWithStart' ,
@@ -558,22 +575,25 @@ export class WorkflowClient extends BaseClient {
558575 public async start < T extends Workflow > (
559576 workflowTypeOrFunc : string | T ,
560577 options : WorkflowStartOptions < T >
561- ) : Promise < WorkflowHandleWithFirstExecutionRunId < T > > {
578+ ) : Promise < WorkflowHandleWithStartDetails < T > > {
562579 const { workflowId } = options ;
563580 const interceptors = this . getOrMakeInterceptors ( workflowId ) ;
564- const runId = await this . _start ( workflowTypeOrFunc , { ...options , workflowId } , interceptors ) ;
581+ const wfStartOutput = await this . _start ( workflowTypeOrFunc , { ...options , workflowId } , interceptors ) ;
565582 // runId is not used in handles created with `start*` calls because these
566583 // handles should allow interacting with the workflow if it continues as new.
567- const handle = this . _createWorkflowHandle ( {
584+ const baseHandle = this . _createWorkflowHandle ( {
568585 workflowId,
569586 runId : undefined ,
570- firstExecutionRunId : runId ,
571- runIdForResult : runId ,
587+ firstExecutionRunId : wfStartOutput . runId ,
588+ runIdForResult : wfStartOutput . runId ,
572589 interceptors,
573590 followRuns : options . followRuns ?? true ,
574- } ) as WorkflowHandleWithFirstExecutionRunId < T > ; // Cast is safe because we know we add the firstExecutionRunId below
575- ( handle as any ) /* readonly */ . firstExecutionRunId = runId ;
576- return handle ;
591+ } ) ;
592+ return {
593+ ...baseHandle ,
594+ firstExecutionRunId : wfStartOutput . runId ,
595+ eagerlyStarted : wfStartOutput . eagerlyStarted ,
596+ } ;
577597 }
578598
579599 /**
@@ -1242,11 +1262,15 @@ export class WorkflowClient extends BaseClient {
12421262 *
12431263 * Used as the final function of the start interceptor chain
12441264 */
1245- protected async _startWorkflowHandler ( input : WorkflowStartInput ) : Promise < string > {
1265+ protected async _startWorkflowHandler ( input : WorkflowStartInput ) : Promise < WorkflowStartOutput > {
12461266 const req = await this . createStartWorkflowRequest ( input ) ;
12471267 const { options : opts , workflowType } = input ;
12481268 try {
1249- return ( await this . workflowService . startWorkflowExecution ( req ) ) . runId ;
1269+ const resp = await this . workflowService . startWorkflowExecution ( req ) ;
1270+ return {
1271+ runId : resp . runId ,
1272+ eagerlyStarted : resp . eagerWorkflowTask != null ,
1273+ } ;
12501274 } catch ( err : any ) {
12511275 if ( err . code === grpcStatus . ALREADY_EXISTS ) {
12521276 throw new WorkflowExecutionAlreadyStartedError (
@@ -1263,6 +1287,13 @@ export class WorkflowClient extends BaseClient {
12631287 const { options : opts , workflowType, headers } = input ;
12641288 const { identity, namespace } = this . options ;
12651289
1290+ if ( opts . requestEagerStart && ! ( 'supportsEagerStart' in this . connection && this . connection . supportsEagerStart ) ) {
1291+ throw new Error (
1292+ 'Eager workflow start requires a NativeConnection shared between client and worker. ' +
1293+ 'Pass a NativeConnection via ClientOptions.connection, or disable requestEagerStart.'
1294+ ) ;
1295+ }
1296+
12661297 return {
12671298 namespace,
12681299 identity,
@@ -1292,6 +1323,7 @@ export class WorkflowClient extends BaseClient {
12921323 header : { fields : headers } ,
12931324 priority : opts . priority ? compilePriority ( opts . priority ) : undefined ,
12941325 versioningOverride : opts . versioningOverride ?? undefined ,
1326+ requestEagerExecution : opts . requestEagerStart ,
12951327 } ;
12961328 }
12971329
0 commit comments