@@ -40,6 +40,8 @@ import {
40
40
SignalWorkflowInput ,
41
41
StartChildWorkflowExecutionInput ,
42
42
TimerInput ,
43
+ UserMetadata ,
44
+ WorkflowCommandOptions ,
43
45
} from './interceptors' ;
44
46
import {
45
47
ChildWorkflowCancellationType ,
@@ -82,6 +84,27 @@ export function addDefaultWorkflowOptions<T extends Workflow>(
82
84
} ;
83
85
}
84
86
87
+ function addUserMetadata ( userMetadata ?: UserMetadata ) : temporal . api . sdk . v1 . IUserMetadata | undefined {
88
+ if ( userMetadata == null ) {
89
+ return undefined
90
+ }
91
+
92
+ const jsonConverter = new JsonPayloadConverter ( ) ;
93
+ return {
94
+ summary : jsonConverter . toPayload ( userMetadata . summary ) ,
95
+ details : jsonConverter . toPayload ( userMetadata . details ) ,
96
+ }
97
+ }
98
+
99
+ function addWorkflowCommandOptions ( cmdOpts ?: WorkflowCommandOptions ) : object {
100
+ if ( cmdOpts == null ) {
101
+ return { }
102
+ }
103
+ return {
104
+ userMetadata : addUserMetadata ( cmdOpts . userMetadata )
105
+ }
106
+ }
107
+
85
108
/**
86
109
* Push a startTimer command into state accumulator and register completion
87
110
*/
@@ -113,9 +136,7 @@ function timerNextHandler(input: TimerInput) {
113
136
seq : input . seq ,
114
137
startToFireTimeout : msToTs ( input . durationMs ) ,
115
138
} ,
116
- userMetadata : {
117
- summary : new JsonPayloadConverter ( ) . toPayload ( input . cmdOpts ?. userMetadata ?. summary )
118
- }
139
+ ...addWorkflowCommandOptions ( input . cmdOpts )
119
140
} ) ;
120
141
activator . completions . timer . set ( input . seq , {
121
142
resolve,
@@ -199,9 +220,7 @@ function scheduleActivityNextHandler({ options, args, headers, seq, activityType
199
220
doNotEagerlyExecute : ! ( options . allowEagerDispatch ?? true ) ,
200
221
versioningIntent : versioningIntentToProto ( options . versioningIntent ) ,
201
222
} ,
202
- userMetadata : {
203
- summary : new JsonPayloadConverter ( ) . toPayload ( cmdOpts ?. userMetadata ?. summary )
204
- }
223
+ ...addWorkflowCommandOptions ( cmdOpts )
205
224
} ) ;
206
225
activator . completions . activity . set ( seq , {
207
226
resolve,
@@ -268,9 +287,7 @@ async function scheduleLocalActivityNextHandler({
268
287
headers,
269
288
cancellationType : encodeActivityCancellationType ( options . cancellationType ) ,
270
289
} ,
271
- userMetadata : {
272
- summary : new JsonPayloadConverter ( ) . toPayload ( cmdOpts ?. userMetadata ?. summary )
273
- }
290
+ ...addWorkflowCommandOptions ( cmdOpts )
274
291
} ) ;
275
292
activator . completions . activity . set ( seq , {
276
293
resolve,
@@ -514,51 +531,100 @@ export type ActivityInterfaceFor<T> = {
514
531
[ K in keyof T ] : T [ K ] extends ActivityFunction ? T [ K ] : typeof NotAnActivityMethod ;
515
532
} ;
516
533
534
+ /**
535
+ * Extends ActivityInterfaceFor to include the withSummaries method
536
+ */
537
+ export type ActivityInterfaceWithSummaries < A > = ActivityInterfaceFor < A > & {
538
+ /**
539
+ * Provide descriptive summaries for activities
540
+ * @param summaries Record mapping activity names to their summary descriptions
541
+ * @returns A new proxy with the provided summaries
542
+ */
543
+ withSummaries ( summaries : Record < string , string > ) : ActivityInterfaceFor < A > ;
544
+ } ;
545
+
517
546
/**
518
547
* Configure Activity functions with given {@link ActivityOptions}.
519
548
*
520
549
* This method may be called multiple times to setup Activities with different options.
521
550
*
522
551
* @return a {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy | Proxy} for
523
552
* which each attribute is a callable Activity function
524
- */
525
- export function proxyActivities < A = UntypedActivities > ( options : ActivityOptions ) : ActivityInterfaceFor < A > ;
526
-
527
- /**
528
- * Configure Activity functions with given {@link ActivityOptions} and a summary.
529
553
*
530
- * @param options Activity options
531
- * @param summary A description of the activity's purpose, useful for debugging and monitoring
532
- * @return a {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy | Proxy} for
533
- * which each attribute is a callable Activity function with the provided summary
554
+ * @example
555
+ * ```ts
556
+ * import { proxyActivities } from '@temporalio/workflow';
557
+ * import * as activities from '../activities';
558
+ *
559
+ * // Setup Activities from module exports
560
+ * const { httpGet, otherActivity } = proxyActivities<typeof activities>({
561
+ * startToCloseTimeout: '30 minutes',
562
+ * });
563
+ *
564
+ * // Setup Activities with summaries for better observability
565
+ * const {
566
+ * httpGet,
567
+ * processData,
568
+ * saveResults
569
+ * } = proxyActivities<typeof activities>({
570
+ * startToCloseTimeout: '10m',
571
+ * }).withSummaries({
572
+ * httpGet: 'Fetches data from external API',
573
+ * processData: 'Processes the fetched data',
574
+ * saveResults: 'Saves processed results to database'
575
+ * });
576
+ *
577
+ * // Setup Activities from an explicit interface (e.g. when defined by another SDK)
578
+ * interface JavaActivities {
579
+ * httpGetFromJava(url: string): Promise<string>
580
+ * someOtherJavaActivity(arg1: number, arg2: string): Promise<string>;
581
+ * }
582
+ *
583
+ * const {
584
+ * httpGetFromJava,
585
+ * someOtherJavaActivity
586
+ * } = proxyActivities<JavaActivities>({
587
+ * taskQueue: 'java-worker-taskQueue',
588
+ * startToCloseTimeout: '5m',
589
+ * });
590
+ *
591
+ * export function execute(): Promise<void> {
592
+ * const response = await httpGet("http://example.com");
593
+ * // ...
594
+ * }
595
+ * ```
534
596
*/
535
- export function proxyActivities < A = UntypedActivities > (
536
- options : ActivityOptions ,
537
- summary : string
538
- ) : ActivityInterfaceFor < A > ;
539
-
540
597
export function proxyActivities < A = UntypedActivities > (
541
598
options : ActivityOptions ,
542
- summary ?: string
543
- ) : ActivityInterfaceFor < A > {
599
+ ) : ActivityInterfaceWithSummaries < A > {
544
600
if ( options === undefined ) {
545
601
throw new TypeError ( 'options must be defined' ) ;
546
602
}
547
603
// Validate as early as possible for immediate user feedback
548
604
validateActivityOptions ( options ) ;
549
- return new Proxy (
550
- { } ,
551
- {
552
- get ( _ , activityType ) {
553
- if ( typeof activityType !== 'string' ) {
554
- throw new TypeError ( `Only strings are supported for Activity types, got: ${ String ( activityType ) } ` ) ;
605
+
606
+ function createActivityProxy ( summaries : Record < string , string > = { } ) : ActivityInterfaceWithSummaries < A > {
607
+ return new Proxy ( { } as ActivityInterfaceWithSummaries < A > , {
608
+ get ( _ , prop ) {
609
+ if ( prop === 'withSummaries' ) {
610
+ return function withSummaries ( newSummaries : Record < string , string > ) : ActivityInterfaceFor < A > {
611
+ return createActivityProxy ( newSummaries ) ;
612
+ } ;
555
613
}
614
+
615
+ if ( typeof prop !== 'string' ) {
616
+ throw new TypeError ( `Only strings are supported for Activity types, got: ${ String ( prop ) } ` ) ;
617
+ }
618
+
556
619
return function activityProxyFunction ( ...args : unknown [ ] ) : Promise < unknown > {
557
- return scheduleActivity ( activityType , args , options , summary ) ;
620
+ const summary = summaries [ prop ] ;
621
+ return scheduleActivity ( prop , args , options , summary ) ;
558
622
} ;
559
623
} ,
560
- }
561
- ) as any ;
624
+ } ) ;
625
+ }
626
+
627
+ return createActivityProxy ( ) ;
562
628
}
563
629
564
630
/**
@@ -571,43 +637,37 @@ export function proxyActivities<A = UntypedActivities>(
571
637
*
572
638
* @see {@link proxyActivities } for examples
573
639
*/
574
- export function proxyLocalActivities < A = UntypedActivities > ( options : LocalActivityOptions ) : ActivityInterfaceFor < A > ;
575
-
576
- /**
577
- * Configure Local Activity functions with given {@link LocalActivityOptions} and a summary.
578
- *
579
- * @param options Local activity options
580
- * @param summary A description of the activity's purpose, useful for debugging and monitoring
581
- * @return a {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy | Proxy}
582
- * for which each attribute is a callable Activity function with the provided summary
583
- */
584
- export function proxyLocalActivities < A = UntypedActivities > (
585
- options : LocalActivityOptions ,
586
- summary : string
587
- ) : ActivityInterfaceFor < A > ;
588
-
589
640
export function proxyLocalActivities < A = UntypedActivities > (
590
- options : LocalActivityOptions ,
591
- summary ?: string
592
- ) : ActivityInterfaceFor < A > {
641
+ options : LocalActivityOptions
642
+ ) : ActivityInterfaceWithSummaries < A > {
593
643
if ( options === undefined ) {
594
644
throw new TypeError ( 'options must be defined' ) ;
595
645
}
596
646
// Validate as early as possible for immediate user feedback
597
647
validateLocalActivityOptions ( options ) ;
598
- return new Proxy (
599
- { } ,
600
- {
601
- get ( _ , activityType ) {
602
- if ( typeof activityType !== 'string' ) {
603
- throw new TypeError ( `Only strings are supported for Activity types, got: ${ String ( activityType ) } ` ) ;
648
+
649
+ function createLocalActivityProxy ( summaries : Record < string , string > = { } ) : ActivityInterfaceWithSummaries < A > {
650
+ return new Proxy ( { } as ActivityInterfaceWithSummaries < A > , {
651
+ get ( _ , prop ) {
652
+ if ( prop === 'withSummaries' ) {
653
+ return function withSummaries ( newSummaries : Record < string , string > ) : ActivityInterfaceFor < A > {
654
+ return createLocalActivityProxy ( newSummaries ) ;
655
+ } ;
656
+ }
657
+
658
+ if ( typeof prop !== 'string' ) {
659
+ throw new TypeError ( `Only strings are supported for Activity types, got: ${ String ( prop ) } ` ) ;
604
660
}
605
- return function localActivityProxyFunction ( ...args : unknown [ ] ) {
606
- return scheduleLocalActivity ( activityType , args , options , summary ) ;
661
+
662
+ return function localActivityProxyFunction ( ...args : unknown [ ] ) : Promise < unknown > {
663
+ const summary = summaries [ prop ] ;
664
+ return scheduleLocalActivity ( prop , args , options , summary ) ;
607
665
} ;
608
666
} ,
609
- }
610
- ) as any ;
667
+ } ) ;
668
+ }
669
+
670
+ return createLocalActivityProxy ( ) ;
611
671
}
612
672
613
673
// TODO: deprecate this patch after "enough" time has passed
@@ -977,13 +1037,13 @@ export function makeContinueAsNewFunc<F extends Workflow>(
977
1037
* @example
978
1038
*
979
1039
* ```ts
980
- *import { continueAsNew } from '@temporalio/workflow';
981
- import { SearchAttributeType } from '@temporalio/common';
1040
+ * import { continueAsNew } from '@temporalio/workflow';
1041
+ * import { SearchAttributeType } from '@temporalio/common';
982
1042
*
983
- *export async function myWorkflow(n: number): Promise<void> {
984
- * // ... Workflow logic
985
- * await continueAsNew<typeof myWorkflow>(n + 1);
986
- *}
1043
+ * export async function myWorkflow(n: number): Promise<void> {
1044
+ * // ... Workflow logic
1045
+ * await continueAsNew<typeof myWorkflow>(n + 1);
1046
+ * }
987
1047
* ```
988
1048
*/
989
1049
export function continueAsNew < F extends Workflow > ( ...args : Parameters < F > ) : Promise < never > {
0 commit comments