@@ -296,42 +296,32 @@ export type TypedWorkflowHandle<TWorkflow extends AnyWorkflowDefinition> = {
296296 readonly firstExecutionRunId : string | undefined ;
297297
298298 /**
299- * Type-safe queries based on workflow definition with Result pattern
300- * Each query returns AsyncResult<T, Error> instead of Promise<T>
299+ * Type-safe queries based on workflow definition with Result pattern.
300+ * Each query returns
301+ * `AsyncResult<T, QueryValidationError | WorkflowExecutionNotFoundError>`
302+ * instead of `Promise<T>` — the error union is carried by
303+ * {@link ClientInferWorkflowQueries} directly.
301304 */
302- queries : {
303- [ K in keyof ClientInferWorkflowQueries < TWorkflow > ] : ClientInferWorkflowQueries < TWorkflow > [ K ] extends (
304- ...args : infer Args
305- ) => AsyncResult < infer R , Error >
306- ? ( ...args : Args ) => AsyncResult < R , QueryValidationError | WorkflowExecutionNotFoundError >
307- : never ;
308- } ;
305+ queries : ClientInferWorkflowQueries < TWorkflow > ;
309306
310307 /**
311- * Type-safe signals based on workflow definition with Result pattern
312- * Each signal returns AsyncResult<void, Error> instead of Promise<void>
308+ * Type-safe signals based on workflow definition with Result pattern.
309+ * Each signal returns
310+ * `AsyncResult<void, SignalValidationError | WorkflowExecutionNotFoundError>`
311+ * instead of `Promise<void>` — the error union is carried by
312+ * {@link ClientInferWorkflowSignals} directly.
313313 */
314- signals : {
315- [ K in keyof ClientInferWorkflowSignals < TWorkflow > ] : ClientInferWorkflowSignals < TWorkflow > [ K ] extends (
316- ...args : infer Args
317- ) => AsyncResult < void , Error >
318- ? ( ...args : Args ) => AsyncResult < void , SignalValidationError | WorkflowExecutionNotFoundError >
319- : never ;
320- } ;
314+ signals : ClientInferWorkflowSignals < TWorkflow > ;
321315
322316 /**
323317 * Type-safe updates based on workflow definition with Result pattern.
324318 * Each update starts the update AND waits for its result (Temporal's
325- * `executeUpdate`); use {@link startUpdate} to obtain an update handle
326- * without waiting for completion.
319+ * `executeUpdate`), returning
320+ * `AsyncResult<T, UpdateValidationError | WorkflowExecutionNotFoundError>`;
321+ * use {@link startUpdate} to obtain an update handle without waiting for
322+ * completion.
327323 */
328- updates : {
329- [ K in keyof ClientInferWorkflowUpdates < TWorkflow > ] : ClientInferWorkflowUpdates < TWorkflow > [ K ] extends (
330- ...args : infer Args
331- ) => AsyncResult < infer R , Error >
332- ? ( ...args : Args ) => AsyncResult < R , UpdateValidationError | WorkflowExecutionNotFoundError >
333- : never ;
334- } ;
324+ updates : ClientInferWorkflowUpdates < TWorkflow > ;
335325
336326 /**
337327 * Start an update without waiting for its completion — Temporal's
@@ -433,7 +423,7 @@ type ResolvedWorkflow<TWorkflow extends AnyWorkflowDefinition> = {
433423 * extended error classification) stay at the call site — those are the
434424 * differentiators that make each method distinct.
435425 */
436- async function resolveDefinitionAndValidateInput <
426+ function resolveDefinitionAndValidateInput <
437427 TContract extends ContractDefinition ,
438428 TWorkflowName extends keyof TContract [ "workflows" ] & string ,
439429> (
@@ -442,31 +432,40 @@ async function resolveDefinitionAndValidateInput<
442432 workflowId : string ,
443433 args : unknown ,
444434 searchAttributes : Record < string , unknown > | undefined ,
445- ) : Promise <
446- Result <
435+ ) : AsyncResult <
436+ ResolvedWorkflow < TContract [ "workflows" ] [ TWorkflowName ] > ,
437+ WorkflowNotInContractError | WorkflowValidationError
438+ > {
439+ return makeAsyncResult <
447440 ResolvedWorkflow < TContract [ "workflows" ] [ TWorkflowName ] > ,
448441 WorkflowNotInContractError | WorkflowValidationError
449- >
450- > {
451- const definition = contract . workflows [ workflowName ] ;
452- if ( ! definition ) {
453- return Err ( createWorkflowNotInContractError ( workflowName , contract ) ) ;
454- }
442+ > ( async ( ) => {
443+ const definition = contract . workflows [ workflowName ] ;
444+ if ( ! definition ) {
445+ return Err ( createWorkflowNotInContractError ( workflowName , contract ) ) ;
446+ }
455447
456- const inputResult = await definition . input [ "~standard" ] . validate ( args ) ;
457- if ( inputResult . issues ) {
458- return Err ( new WorkflowValidationError ( workflowName , "input" , inputResult . issues , workflowId ) ) ;
459- }
448+ const inputResult = await definition . input [ "~standard" ] . validate ( args ) ;
449+ if ( inputResult . issues ) {
450+ return Err (
451+ new WorkflowValidationError ( workflowName , "input" , inputResult . issues , workflowId ) ,
452+ ) ;
453+ }
460454
461- // `toTypedSearchAttributes` throws a `RuntimeClientError` on an undeclared
462- // key or a value that doesn't match the declared kind — a technical
463- // misconfiguration routed to the defect channel by the enclosing
464- // `makeAsyncResult` work thunk (never a modeled Err).
465- const typedSearchAttributes = toTypedSearchAttributes ( definition , workflowName , searchAttributes ) ;
455+ // `toTypedSearchAttributes` throws a `RuntimeClientError` on an undeclared
456+ // key or a value that doesn't match the declared kind — a technical
457+ // misconfiguration captured as a defect (never a modeled Err) and
458+ // re-thrown into the caller's throw→defect net by `assertNoDefect`.
459+ const typedSearchAttributes = toTypedSearchAttributes (
460+ definition ,
461+ workflowName ,
462+ searchAttributes ,
463+ ) ;
466464
467- return Ok ( {
468- definition : definition as TContract [ "workflows" ] [ TWorkflowName ] ,
469- typedSearchAttributes,
465+ return Ok ( {
466+ definition : definition as TContract [ "workflows" ] [ TWorkflowName ] ,
467+ typedSearchAttributes,
468+ } ) ;
470469 } ) ;
471470}
472471
@@ -552,7 +551,7 @@ export class TypedClient {
552551 * ```
553552 */
554553 static create ( { client, interceptors } : CreateClientOptions ) : AsyncResult < TypedClient , never > {
555- const work = async ( ) : Promise < Result < TypedClient , never > > => {
554+ const work = async ( ) => {
556555 // `client.schedule` is the ScheduleClient wired into Temporal's
557556 // top-level `Client` since 1.16. The peer dep allows all of `^1`, so a
558557 // consumer can be on an older version — fail early with a clear
@@ -741,15 +740,16 @@ export class ContractClient<TContract extends ContractDefinition> {
741740 type Ok = TypedWorkflowHandle < TContract [ "workflows" ] [ TWorkflowName ] > ;
742741 type Err = WorkflowNotInContractError | WorkflowValidationError | WorkflowAlreadyStartedError ;
743742 const runPipeline = ( currentInput : unknown ) : AsyncResult < Ok , Err > => {
744- const work = async ( ) : Promise < Result < Ok , Err > > => {
743+ const work = async ( ) => {
745744 const resolved = await resolveDefinitionAndValidateInput (
746745 this . contract ,
747746 workflowName ,
748747 temporalOptions . workflowId ,
749748 currentInput ,
750749 searchAttributes as Record < string , unknown > | undefined ,
751750 ) ;
752- // The resolver only ever builds ok/err; assert away the impossible defect.
751+ // A technical throw inside the resolver is captured as a defect;
752+ // re-throw it here so it rides this thunk's throw→defect net.
753753 assertNoDefect ( resolved ) ;
754754 if ( resolved . isErr ( ) ) return Err ( resolved . error ) ;
755755 const { definition, typedSearchAttributes } = resolved . value ;
@@ -778,7 +778,7 @@ export class ContractClient<TContract extends ContractDefinition> {
778778 throw new RuntimeClientError ( "startWorkflow" , error ) ;
779779 }
780780 } ;
781- return makeAsyncResult ( work ) ;
781+ return makeAsyncResult < Ok , Err > ( work ) ;
782782 } ;
783783
784784 // Interceptors wrap the whole pipeline (outside validation), so a
@@ -869,15 +869,16 @@ export class ContractClient<TContract extends ContractDefinition> {
869869 currentInput : unknown ,
870870 currentSignalInput : unknown ,
871871 ) : AsyncResult < Ok , Err > => {
872- const work = async ( ) : Promise < Result < Ok , Err > > => {
872+ const work = async ( ) => {
873873 const resolved = await resolveDefinitionAndValidateInput (
874874 this . contract ,
875875 workflowName ,
876876 temporalOptions . workflowId ,
877877 currentInput ,
878878 searchAttributes as Record < string , unknown > | undefined ,
879879 ) ;
880- // The resolver only ever builds ok/err; assert away the impossible defect.
880+ // A technical throw inside the resolver is captured as a defect;
881+ // re-throw it here so it rides this thunk's throw→defect net.
881882 assertNoDefect ( resolved ) ;
882883 if ( resolved . isErr ( ) ) return Err ( resolved . error ) ;
883884 const { definition, typedSearchAttributes } = resolved . value ;
@@ -929,7 +930,7 @@ export class ContractClient<TContract extends ContractDefinition> {
929930 throw new RuntimeClientError ( "signalWithStart" , error ) ;
930931 }
931932 } ;
932- return makeAsyncResult ( work ) ;
933+ return makeAsyncResult < Ok , Err > ( work ) ;
933934 } ;
934935
935936 if ( this . interceptors . length === 0 ) return runPipeline ( args , signalArgs ) ;
@@ -1007,15 +1008,16 @@ export class ContractClient<TContract extends ContractDefinition> {
10071008 | WorkflowFailedError
10081009 | WorkflowExecutionNotFoundError ;
10091010 const runPipeline = ( currentInput : unknown ) : AsyncResult < Ok , Err > => {
1010- const work = async ( ) : Promise < Result < Ok , Err > > => {
1011+ const work = async ( ) => {
10111012 const resolved = await resolveDefinitionAndValidateInput (
10121013 this . contract ,
10131014 workflowName ,
10141015 temporalOptions . workflowId ,
10151016 currentInput ,
10161017 searchAttributes as Record < string , unknown > | undefined ,
10171018 ) ;
1018- // The resolver only ever builds ok/err; assert away the impossible defect.
1019+ // A technical throw inside the resolver is captured as a defect;
1020+ // re-throw it here so it rides this thunk's throw→defect net.
10191021 assertNoDefect ( resolved ) ;
10201022 if ( resolved . isErr ( ) ) return Err ( resolved . error ) ;
10211023 const { definition, typedSearchAttributes } = resolved . value ;
@@ -1065,7 +1067,7 @@ export class ContractClient<TContract extends ContractDefinition> {
10651067 throw new RuntimeClientError ( "executeWorkflow" , error ) ;
10661068 }
10671069 } ;
1068- return makeAsyncResult ( work ) ;
1070+ return makeAsyncResult < Ok , Err > ( work ) ;
10691071 } ;
10701072
10711073 if ( this . interceptors . length === 0 ) return runPipeline ( args ) ;
@@ -1194,7 +1196,7 @@ export class ContractClient<TContract extends ContractDefinition> {
11941196 workflowId : updateHandle . workflowId ,
11951197 workflowRunId : updateHandle . workflowRunId ,
11961198 result : ( ) : AsyncResult < unknown , StartUpdateErr > => {
1197- const work = async ( ) : Promise < Result < unknown , StartUpdateErr > > => {
1199+ const work = async ( ) => {
11981200 try {
11991201 const raw = await updateHandle . result ( ) ;
12001202 // Receive side of the update-result boundary: the handler
@@ -1211,7 +1213,7 @@ export class ContractClient<TContract extends ContractDefinition> {
12111213 throw new RuntimeClientError ( "update.result" , error ) ;
12121214 }
12131215 } ;
1214- return makeAsyncResult ( work ) ;
1216+ return makeAsyncResult < unknown , StartUpdateErr > ( work ) ;
12151217 } ,
12161218 } ) ;
12171219
@@ -1220,7 +1222,7 @@ export class ContractClient<TContract extends ContractDefinition> {
12201222 options ?: { args ?: unknown ; updateId ?: string ; waitForStage ?: "ACCEPTED" } ,
12211223 ) : AsyncResult < unknown , StartUpdateErr > => {
12221224 const runPipeline = ( currentInput : unknown ) : AsyncResult < unknown , StartUpdateErr > => {
1223- const work = async ( ) : Promise < Result < unknown , StartUpdateErr > > => {
1225+ const work = async ( ) => {
12241226 const updateDef = ( definition . updates as Record < string , UpdateDefinition > | undefined ) ?. [
12251227 updateName
12261228 ] ;
@@ -1256,7 +1258,7 @@ export class ContractClient<TContract extends ContractDefinition> {
12561258 throw new RuntimeClientError ( "startUpdate" , error ) ;
12571259 }
12581260 } ;
1259- return makeAsyncResult ( work ) ;
1261+ return makeAsyncResult < unknown , StartUpdateErr > ( work ) ;
12601262 } ;
12611263
12621264 // Interceptors wrap the whole pipeline (outside validation), same
@@ -1296,7 +1298,7 @@ export class ContractClient<TContract extends ContractDefinition> {
12961298 | WorkflowValidationError
12971299 | WorkflowFailedError
12981300 | WorkflowExecutionNotFoundError ;
1299- const work = async ( ) : Promise < Result < Ok , Err > > => {
1301+ const work = async ( ) => {
13001302 try {
13011303 const result = await workflowHandle . result ( ) ;
13021304 const outputResult = await definition . output [ "~standard" ] . validate ( result ) ;
@@ -1326,7 +1328,7 @@ export class ContractClient<TContract extends ContractDefinition> {
13261328 throw new RuntimeClientError ( "result" , error ) ;
13271329 }
13281330 } ;
1329- return makeAsyncResult ( work ) ;
1331+ return makeAsyncResult < Ok , Err > ( work ) ;
13301332 } ,
13311333 terminate : ( reason ?: string ) : AsyncResult < void , WorkflowExecutionNotFoundError > =>
13321334 fromPromise (
@@ -1436,7 +1438,7 @@ function buildValidatedProxy<TDef extends DefWithInput, TValidationError extends
14361438
14371439 for ( const [ name , def ] of Object . entries ( defs ) ) {
14381440 const runPipeline = ( currentInput : unknown ) : AsyncResult < unknown , ProxyError > => {
1439- const work = async ( ) : Promise < Result < unknown , ProxyError > > => {
1441+ const work = async ( ) => {
14401442 const inputResult = await def . input [ "~standard" ] . validate ( currentInput ) ;
14411443 if ( inputResult . issues ) {
14421444 return Err ( makeValidationError ( name , "input" , inputResult . issues ) ) ;
@@ -1461,7 +1463,7 @@ function buildValidatedProxy<TDef extends DefWithInput, TValidationError extends
14611463 throw new RuntimeClientError ( operation , error ) ;
14621464 }
14631465 } ;
1464- return makeAsyncResult ( work ) ;
1466+ return makeAsyncResult < unknown , ProxyError > ( work ) ;
14651467 } ;
14661468
14671469 proxy [ name ] = ( args ) => {
0 commit comments