UNPKG

@temporalio/workflow

Version:
580 lines (579 loc) 25.7 kB
import { ActivityFunction, ActivityOptions, LocalActivityOptions, QueryDefinition, SearchAttributes, SignalDefinition, UntypedActivities, UpdateDefinition, WithWorkflowArgs, Workflow, WorkflowResultType, WorkflowReturnType, SearchAttributeUpdatePair, WorkflowDefinitionOptionsOrGetter } from '@temporalio/common'; import { Duration } from '@temporalio/common/lib/time'; import { temporal } from '@temporalio/proto'; import { TimerOptions } from './interceptors'; import { ChildWorkflowOptions, ChildWorkflowOptionsWithDefaults, ContinueAsNewOptions, DefaultSignalHandler, EnhancedStackTrace, Handler, QueryHandlerOptions, SignalHandlerOptions, UpdateHandlerOptions, WorkflowInfo, UpdateInfo, DefaultUpdateHandler, DefaultQueryHandler } from './interfaces'; import { ChildWorkflowHandle, ExternalWorkflowHandle } from './workflow-handle'; /** * Adds default values of `workflowId` and `cancellationType` to given workflow options. */ export declare function addDefaultWorkflowOptions<T extends Workflow>(opts: WithWorkflowArgs<T, ChildWorkflowOptions>): ChildWorkflowOptionsWithDefaults; /** * Asynchronous sleep. * * Schedules a timer on the Temporal service. * * @param ms sleep duration - number of milliseconds or {@link https://www.npmjs.com/package/ms | ms-formatted string}. * If given a negative number or 0, value will be set to 1. * @param options optional timer options for additional configuration */ export declare function sleep(ms: Duration, options?: TimerOptions): Promise<void>; /** * Schedule an activity and run outbound interceptors * @hidden */ export declare function scheduleActivity<R>(activityType: string, args: any[], options: ActivityOptions): Promise<R>; /** * Schedule an activity and run outbound interceptors * @hidden */ export declare function scheduleLocalActivity<R>(activityType: string, args: any[], options: LocalActivityOptions): Promise<R>; /** * Symbol used in the return type of proxy methods to mark that an attribute on the source type is not a method. * * @see {@link ActivityInterfaceFor} * @see {@link proxyActivities} * @see {@link proxyLocalActivities} */ export declare const NotAnActivityMethod: unique symbol; /** * Type helper that takes a type `T` and transforms attributes that are not {@link ActivityFunction} to * {@link NotAnActivityMethod}. * * @example * * Used by {@link proxyActivities} to get this compile-time error: * * ```ts * interface MyActivities { * valid(input: number): Promise<number>; * invalid(input: number): number; * } * * const act = proxyActivities<MyActivities>({ startToCloseTimeout: '5m' }); * * await act.valid(true); * await act.invalid(); * // ^ TS complains with: * // (property) invalidDefinition: typeof NotAnActivityMethod * // This expression is not callable. * // Type 'Symbol' has no call signatures.(2349) * ``` */ export type ActivityInterfaceFor<T> = { [K in keyof T]: T[K] extends ActivityFunction ? ActivityFunctionWithOptions<T[K]> : typeof NotAnActivityMethod; }; export type ActivityFunctionWithOptions<T extends ActivityFunction> = T & { /** * Execute the activity, overriding its existing options with the * provided options. * * @param options ActivityOptions * @param args: list of arguments * @returns return value of the activity * * @experimental executeWithOptions is a new method to provide call-site options and is subject to change */ executeWithOptions(options: ActivityOptions, args: Parameters<T>): Promise<Awaited<ReturnType<T>>>; }; /** * The local activity counterpart to {@link ActivityInterfaceFor} */ export type LocalActivityInterfaceFor<T> = { [K in keyof T]: T[K] extends ActivityFunction ? LocalActivityFunctionWithOptions<T[K]> : typeof NotAnActivityMethod; }; export type LocalActivityFunctionWithOptions<T extends ActivityFunction> = T & { /** * Run the local activity, overriding its existing options with the * provided options. * * @param options LocalActivityOptions * @param args: list of arguments * @returns return value of the activity * * @experimental executeWithOptions is a new method to provide call-site options and is subject to change */ executeWithOptions(options: LocalActivityOptions, args: Parameters<T>): Promise<Awaited<ReturnType<T>>>; }; /** * Configure Activity functions with given {@link ActivityOptions}. * * This method may be called multiple times to setup Activities with different options. * * @return a {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy | Proxy} for * which each attribute is a callable Activity function * * @example * ```ts * import { proxyActivities } from '@temporalio/workflow'; * import * as activities from '../activities'; * * // Setup Activities from module exports * const { httpGet, otherActivity } = proxyActivities<typeof activities>({ * startToCloseTimeout: '30 minutes', * }); * * // Use activities with default options * const result1 = await httpGet('http://example.com'); * * // Override options for specific activity calls * const result2 = await httpGet.executeWithOptions({ * staticSummary: 'Fetches data from external API', * scheduleToCloseTimeout: '5m' * }, ['http://api.example.com']); * * const result3 = await otherActivity.executeWithOptions({ * staticSummary: 'Processes the fetched data', * taskQueue: 'special-task-queue' * }, [data]); * * // Setup Activities from an explicit interface (e.g. when defined by another SDK) * interface JavaActivities { * httpGetFromJava(url: string): Promise<string> * someOtherJavaActivity(arg1: number, arg2: string): Promise<string>; * } * * const { * httpGetFromJava, * someOtherJavaActivity * } = proxyActivities<JavaActivities>({ * taskQueue: 'java-worker-taskQueue', * startToCloseTimeout: '5m', * }); * * export function execute(): Promise<void> { * const response = await httpGet("http://example.com"); * // Or with custom options: * const response2 = await httpGetFromJava.executeWithOptions({ * staticSummary: 'Java HTTP call with timeout override', * startToCloseTimeout: '2m' * }, ["http://fast-api.example.com"]); * // ... * } * ``` */ export declare function proxyActivities<A = UntypedActivities>(options: ActivityOptions): ActivityInterfaceFor<A>; /** * Configure Local Activity functions with given {@link LocalActivityOptions}. * * This method may be called multiple times to setup Activities with different options. * * @return a {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy | Proxy} * for which each attribute is a callable Activity function * * @see {@link proxyActivities} for examples */ export declare function proxyLocalActivities<A = UntypedActivities>(options: LocalActivityOptions): LocalActivityInterfaceFor<A>; /** * Returns a client-side handle that can be used to signal and cancel an existing Workflow execution. * It takes a Workflow ID and optional run ID. */ export declare function getExternalWorkflowHandle(workflowId: string, runId?: string): ExternalWorkflowHandle; /** * Start a child Workflow execution * * - Returns a client-side handle that implements a child Workflow interface. * - By default, a child will be scheduled on the same task queue as its parent. * * A child Workflow handle supports awaiting completion, signaling and cancellation via {@link CancellationScope}s. * In order to query the child, use a {@link WorkflowClient} from an Activity. */ export declare function startChild<T extends Workflow>(workflowType: string, options: WithWorkflowArgs<T, ChildWorkflowOptions>): Promise<ChildWorkflowHandle<T>>; /** * Start a child Workflow execution * * - Returns a client-side handle that implements a child Workflow interface. * - Deduces the Workflow type and signature from provided Workflow function. * - By default, a child will be scheduled on the same task queue as its parent. * * A child Workflow handle supports awaiting completion, signaling and cancellation via {@link CancellationScope}s. * In order to query the child, use a {@link WorkflowClient} from an Activity. */ export declare function startChild<T extends Workflow>(workflowFunc: T, options: WithWorkflowArgs<T, ChildWorkflowOptions>): Promise<ChildWorkflowHandle<T>>; /** * Start a child Workflow execution * * **Override for Workflows that accept no arguments**. * * - Returns a client-side handle that implements a child Workflow interface. * - The child will be scheduled on the same task queue as its parent. * * A child Workflow handle supports awaiting completion, signaling and cancellation via {@link CancellationScope}s. * In order to query the child, use a {@link WorkflowClient} from an Activity. */ export declare function startChild<T extends () => Promise<any>>(workflowType: string): Promise<ChildWorkflowHandle<T>>; /** * Start a child Workflow execution * * **Override for Workflows that accept no arguments**. * * - Returns a client-side handle that implements a child Workflow interface. * - Deduces the Workflow type and signature from provided Workflow function. * - The child will be scheduled on the same task queue as its parent. * * A child Workflow handle supports awaiting completion, signaling and cancellation via {@link CancellationScope}s. * In order to query the child, use a {@link WorkflowClient} from an Activity. */ export declare function startChild<T extends () => Promise<any>>(workflowFunc: T): Promise<ChildWorkflowHandle<T>>; /** * Start a child Workflow execution and await its completion. * * - By default, a child will be scheduled on the same task queue as its parent. * - This operation is cancellable using {@link CancellationScope}s. * * @return The result of the child Workflow. */ export declare function executeChild<T extends Workflow>(workflowType: string, options: WithWorkflowArgs<T, ChildWorkflowOptions>): Promise<WorkflowResultType<T>>; /** * Start a child Workflow execution and await its completion. * * - By default, a child will be scheduled on the same task queue as its parent. * - Deduces the Workflow type and signature from provided Workflow function. * - This operation is cancellable using {@link CancellationScope}s. * * @return The result of the child Workflow. */ export declare function executeChild<T extends Workflow>(workflowFunc: T, options: WithWorkflowArgs<T, ChildWorkflowOptions>): Promise<WorkflowResultType<T>>; /** * Start a child Workflow execution and await its completion. * * **Override for Workflows that accept no arguments**. * * - The child will be scheduled on the same task queue as its parent. * - This operation is cancellable using {@link CancellationScope}s. * * @return The result of the child Workflow. */ export declare function executeChild<T extends () => WorkflowReturnType>(workflowType: string): Promise<WorkflowResultType<T>>; /** * Start a child Workflow execution and await its completion. * * **Override for Workflows that accept no arguments**. * * - The child will be scheduled on the same task queue as its parent. * - Deduces the Workflow type and signature from provided Workflow function. * - This operation is cancellable using {@link CancellationScope}s. * * @return The result of the child Workflow. */ export declare function executeChild<T extends () => WorkflowReturnType>(workflowFunc: T): Promise<WorkflowResultType<T>>; /** * Get information about the current Workflow. * * WARNING: This function returns a frozen copy of WorkflowInfo, at the point where this method has been called. * Changes happening at later point in workflow execution will not be reflected in the returned object. * * For this reason, we recommend calling `workflowInfo()` on every access to {@link WorkflowInfo}'s fields, * rather than caching the `WorkflowInfo` object (or part of it) in a local variable. For example: * * ```ts * // GOOD * function myWorkflow() { * doSomething(workflowInfo().searchAttributes) * ... * doSomethingElse(workflowInfo().searchAttributes) * } * ``` * * vs * * ```ts * // BAD * function myWorkflow() { * const attributes = workflowInfo().searchAttributes * doSomething(attributes) * ... * doSomethingElse(attributes) * } * ``` */ export declare function workflowInfo(): WorkflowInfo; /** * Get information about the current update if any. * * @return Info for the current update handler the code calling this is executing * within if any. */ export declare function currentUpdateInfo(): UpdateInfo | undefined; /** * Returns whether or not code is executing in workflow context */ export declare function inWorkflowContext(): boolean; /** * Returns a function `f` that will cause the current Workflow to ContinueAsNew when called. * * `f` takes the same arguments as the Workflow function supplied to typeparam `F`. * * Once `f` is called, Workflow Execution immediately completes. */ export declare function makeContinueAsNewFunc<F extends Workflow>(options?: ContinueAsNewOptions): (...args: Parameters<F>) => Promise<never>; /** * {@link https://docs.temporal.io/concepts/what-is-continue-as-new/ | Continues-As-New} the current Workflow Execution * with default options. * * Shorthand for `makeContinueAsNewFunc<F>()(...args)`. (See: {@link makeContinueAsNewFunc}.) * * @example * * ```ts * import { continueAsNew } from '@temporalio/workflow'; * import { SearchAttributeType } from '@temporalio/common'; * * export async function myWorkflow(n: number): Promise<void> { * // ... Workflow logic * await continueAsNew<typeof myWorkflow>(n + 1); * } * ``` */ export declare function continueAsNew<F extends Workflow>(...args: Parameters<F>): Promise<never>; /** * Generate an RFC compliant V4 uuid. * Uses the workflow's deterministic PRNG making it safe for use within a workflow. * This function is cryptographically insecure. * See the {@link https://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid | stackoverflow discussion}. */ export declare function uuid4(): string; /** * Patch or upgrade workflow code by checking or stating that this workflow has a certain patch. * * See {@link https://docs.temporal.io/typescript/versioning | docs page} for info. * * If the workflow is replaying an existing history, then this function returns true if that * history was produced by a worker which also had a `patched` call with the same `patchId`. * If the history was produced by a worker *without* such a call, then it will return false. * * If the workflow is not currently replaying, then this call *always* returns true. * * Your workflow code should run the "new" code if this returns true, if it returns false, you * should run the "old" code. By doing this, you can maintain determinism. * * @param patchId An identifier that should be unique to this patch. It is OK to use multiple * calls with the same ID, which means all such calls will always return the same value. */ export declare function patched(patchId: string): boolean; /** * Indicate that a patch is being phased out. * * See {@link https://docs.temporal.io/typescript/versioning | docs page} for info. * * Workflows with this call may be deployed alongside workflows with a {@link patched} call, but * they must *not* be deployed while any workers still exist running old code without a * {@link patched} call, or any runs with histories produced by such workers exist. If either kind * of worker encounters a history produced by the other, their behavior is undefined. * * Once all live workflow runs have been produced by workers with this call, you can deploy workers * which are free of either kind of patch call for this ID. Workers with and without this call * may coexist, as long as they are both running the "new" code. * * @param patchId An identifier that should be unique to this patch. It is OK to use multiple * calls with the same ID, which means all such calls will always return the same value. */ export declare function deprecatePatch(patchId: string): void; /** * Returns a Promise that resolves when `fn` evaluates to `true` or `timeout` expires, providing * options to configure the timer (i.e. provide metadata) * * @param timeout number of milliseconds or {@link https://www.npmjs.com/package/ms | ms-formatted string} * * @returns a boolean indicating whether the condition was true before the timeout expires * * @experimental TimerOptions is a new addition and subject to change */ export declare function condition(fn: () => boolean, timeout: Duration, options: TimerOptions): Promise<boolean>; /** * Returns a Promise that resolves when `fn` evaluates to `true` or `timeout` expires. * * @param timeout number of milliseconds or {@link https://www.npmjs.com/package/ms | ms-formatted string} * * @returns a boolean indicating whether the condition was true before the timeout expires */ export declare function condition(fn: () => boolean, timeout: Duration): Promise<boolean>; /** * Returns a Promise that resolves when `fn` evaluates to `true`. */ export declare function condition(fn: () => boolean): Promise<void>; /** * Define an update method for a Workflow. * * A definition is used to register a handler in the Workflow via {@link setHandler} and to update a Workflow using a {@link WorkflowHandle}, {@link ChildWorkflowHandle} or {@link ExternalWorkflowHandle}. * A definition can be reused in multiple Workflows. */ export declare function defineUpdate<Ret, Args extends any[] = [], Name extends string = string>(name: Name): UpdateDefinition<Ret, Args, Name>; /** * Define a signal method for a Workflow. * * A definition is used to register a handler in the Workflow via {@link setHandler} and to signal a Workflow using a {@link WorkflowHandle}, {@link ChildWorkflowHandle} or {@link ExternalWorkflowHandle}. * A definition can be reused in multiple Workflows. */ export declare function defineSignal<Args extends any[] = [], Name extends string = string>(name: Name): SignalDefinition<Args, Name>; /** * Define a query method for a Workflow. * * A definition is used to register a handler in the Workflow via {@link setHandler} and to query a Workflow using a {@link WorkflowHandle}. * A definition can be reused in multiple Workflows. */ export declare function defineQuery<Ret, Args extends any[] = [], Name extends string = string>(name: Name): QueryDefinition<Ret, Args, Name>; /** * Set a handler function for a Workflow update, signal, or query. * * If this function is called multiple times for a given update, signal, or query name the last handler will overwrite any previous calls. * * @param def an {@link UpdateDefinition}, {@link SignalDefinition}, or {@link QueryDefinition} as returned by {@link defineUpdate}, {@link defineSignal}, or {@link defineQuery} respectively. * @param handler a compatible handler function for the given definition or `undefined` to unset the handler. * @param options an optional `description` of the handler and an optional update `validator` function. */ export declare function setHandler<Ret, Args extends any[], T extends QueryDefinition<Ret, Args>>(def: T, handler: Handler<Ret, Args, T> | undefined, options?: QueryHandlerOptions): void; export declare function setHandler<Ret, Args extends any[], T extends SignalDefinition<Args>>(def: T, handler: Handler<Ret, Args, T> | undefined, options?: SignalHandlerOptions): void; export declare function setHandler<Ret, Args extends any[], T extends UpdateDefinition<Ret, Args>>(def: T, handler: Handler<Ret, Args, T> | undefined, options?: UpdateHandlerOptions<Args>): void; /** * Set a signal handler function that will handle signals calls for non-registered signal names. * * Signals are dispatched to the default signal handler in the order that they were accepted by the server. * * If this function is called multiple times for a given signal name the last handler will overwrite any previous calls. * * @param handler a function that will handle signals for non-registered signal names, or `undefined` to unset the handler. */ export declare function setDefaultSignalHandler(handler: DefaultSignalHandler | undefined): void; /** * Set a update handler function that will handle updates calls for non-registered update names. * * Updates are dispatched to the default update handler in the order that they were accepted by the server. * * If this function is called multiple times for a given update name the last handler will overwrite any previous calls. * * @param handler a function that will handle updates for non-registered update names, or `undefined` to unset the handler. */ export declare function setDefaultUpdateHandler(handler: DefaultUpdateHandler | undefined): void; /** * Set a query handler function that will handle query calls for non-registered query names. * * Queries are dispatched to the default query handler in the order that they were accepted by the server. * * If this function is called multiple times for a given query name the last handler will overwrite any previous calls. * * @param handler a function that will handle queries for non-registered query names, or `undefined` to unset the handler. */ export declare function setDefaultQueryHandler(handler: DefaultQueryHandler | undefined): void; /** * Updates this Workflow's Search Attributes by merging the provided `searchAttributes` with the existing Search * Attributes, `workflowInfo().searchAttributes`. * * Search attributes can be upserted using either SearchAttributes (deprecated) or SearchAttributeUpdatePair[] (preferred) * * Upserting a workflow's search attributes using SearchAttributeUpdatePair[]: * * ```ts * const intKey = defineSearchKey('CustomIntField', 'INT'); * const boolKey = defineSearchKey('CustomBoolField', 'BOOL'); * const keywordListKey = defineSearchKey('CustomKeywordField', 'KEYWORD_LIST'); * * upsertSearchAttributes([ * defineSearchAttribute(intKey, 1), * defineSearchAttribute(boolKey, true) * ]); * upsertSearchAttributes([ * defineSearchAttribute(intKey, 42), * defineSearchAttribute(keywordListKey, ['durable code', 'is great']) * ]); * ``` * * Would result in the Workflow having these Search Attributes: * * ```ts * { * CustomIntField: [42], * CustomBoolField: [true], * CustomKeywordField: ['durable code', 'is great'] * } * ``` * * @param searchAttributes The Record to merge. * If using SearchAttributeUpdatePair[] (preferred), set a value to null to remove the search attribute. * If using SearchAttributes (deprecated), set a value to undefined or an empty list to remove the search attribute. */ export declare function upsertSearchAttributes(searchAttributes: SearchAttributes | SearchAttributeUpdatePair[]): void; /** * Updates this Workflow's Memos by merging the provided `memo` with existing * Memos (as returned by `workflowInfo().memo`). * * New memo is merged by replacing properties of the same name _at the first * level only_. Setting a property to value `undefined` or `null` clears that * key from the Memo. * * For example: * * ```ts * upsertMemo({ * key1: value, * key3: { subkey1: value } * key4: value, * }); * upsertMemo({ * key2: value * key3: { subkey2: value } * key4: undefined, * }); * ``` * * would result in the Workflow having these Memo: * * ```ts * { * key1: value, * key2: value, * key3: { subkey2: value } // Note this object was completely replaced * // Note that key4 was completely removed * } * ``` * * @param memo The Record to merge. */ export declare function upsertMemo(memo: Record<string, unknown>): void; /** * Whether update and signal handlers have finished executing. * * Consider waiting on this condition before workflow return or continue-as-new, to prevent * interruption of in-progress handlers by workflow exit: * * ```ts * await workflow.condition(workflow.allHandlersFinished) * ``` * * @returns true if there are no in-progress update or signal handler executions. */ export declare function allHandlersFinished(): boolean; /** * Can be used to alter workflow functions with certain options specified at definition time. * * @example * For example: * ```ts * setWorkflowOptions({ versioningBehavior: 'PINNED' }, myWorkflow); * export async function myWorkflow(): Promise<string> { * // Workflow code here * return "hi"; * } * ``` * * @example * To annotate a default or dynamic workflow: * ```ts * export default async function (): Promise<string> { * // Workflow code here * return "hi"; * } * setWorkflowOptions({ versioningBehavior: 'PINNED' }, module.exports.default); * ``` * * @param options Options for the workflow defintion, or a function that returns options. If a * function is provided, it will be called once just before the workflow function is called for the * first time. It is safe to call {@link workflowInfo} inside such a function. * @param fn The workflow function. */ export declare function setWorkflowOptions<A extends any[], RT>(options: WorkflowDefinitionOptionsOrGetter, fn: (...args: A) => Promise<RT>): void; export declare const stackTraceQuery: QueryDefinition<string, [], string>; export declare const enhancedStackTraceQuery: QueryDefinition<EnhancedStackTrace, [], string>; export declare const workflowMetadataQuery: QueryDefinition<temporal.api.sdk.v1.IWorkflowMetadata, [], string>; export declare function getCurrentDetails(): string; export declare function setCurrentDetails(details: string): void;