@temporalio/workflow 0.22.0 → 1.0.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@temporalio/workflow",
3
- "version": "0.22.0",
3
+ "version": "1.0.0-rc.1",
4
4
  "description": "Temporal.io SDK Workflow sub-package",
5
5
  "keywords": [
6
6
  "temporal",
@@ -15,16 +15,18 @@
15
15
  "author": "Roey Berman <roey@temporal.io>",
16
16
  "main": "lib/index.js",
17
17
  "types": "lib/index.d.ts",
18
- "files": [
19
- "lib"
20
- ],
21
18
  "scripts": {},
22
19
  "dependencies": {
23
- "@temporalio/internal-workflow-common": "^0.22.0",
24
- "@temporalio/proto": "^0.22.0"
20
+ "@temporalio/common": "^1.0.0-rc.1",
21
+ "@temporalio/internal-workflow-common": "^1.0.0-rc.1",
22
+ "@temporalio/proto": "^1.0.0-rc.1"
25
23
  },
26
24
  "publishConfig": {
27
25
  "access": "public"
28
26
  },
29
- "gitHead": "3aa1f14982bd170d21b728cbf016dc4f1b595a76"
27
+ "files": [
28
+ "src",
29
+ "lib"
30
+ ],
31
+ "gitHead": "723de0fbc7a04e68084ec99453578e7027eb3803"
30
32
  }
package/src/alea.ts ADDED
@@ -0,0 +1,88 @@
1
+ // A port of an algorithm by Johannes Baagøe <baagoe@baagoe.com>, 2010
2
+ // http://baagoe.com/en/RandomMusings/javascript/
3
+ // https://github.com/nquinlan/better-random-numbers-for-javascript-mirror
4
+ // Original work is under MIT license -
5
+
6
+ // Copyright (C) 2010 by Johannes Baagøe <baagoe@baagoe.org>
7
+ //
8
+ // Permission is hereby granted, free of charge, to any person obtaining a copy
9
+ // of this software and associated documentation files (the "Software"), to deal
10
+ // in the Software without restriction, including without limitation the rights
11
+ // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12
+ // copies of the Software, and to permit persons to whom the Software is
13
+ // furnished to do so, subject to the following conditions:
14
+ //
15
+ // The above copyright notice and this permission notice shall be included in
16
+ // all copies or substantial portions of the Software.
17
+ //
18
+ // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
+ // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
+ // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
+ // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
+ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
+ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24
+ // THE SOFTWARE.
25
+
26
+ // Taken and modified from https://github.com/davidbau/seedrandom/blob/released/lib/alea.js
27
+
28
+ class Alea {
29
+ public c: number;
30
+ public s0: number;
31
+ public s1: number;
32
+ public s2: number;
33
+
34
+ constructor(seed: number[]) {
35
+ const mash = new Mash();
36
+ // Apply the seeding algorithm from Baagoe.
37
+ this.c = 1;
38
+ this.s0 = mash.mash([32]);
39
+ this.s1 = mash.mash([32]);
40
+ this.s2 = mash.mash([32]);
41
+ this.s0 -= mash.mash(seed);
42
+ if (this.s0 < 0) {
43
+ this.s0 += 1;
44
+ }
45
+ this.s1 -= mash.mash(seed);
46
+ if (this.s1 < 0) {
47
+ this.s1 += 1;
48
+ }
49
+ this.s2 -= mash.mash(seed);
50
+ if (this.s2 < 0) {
51
+ this.s2 += 1;
52
+ }
53
+ }
54
+
55
+ public next(): number {
56
+ const t = 2091639 * this.s0 + this.c * 2.3283064365386963e-10; // 2^-32
57
+ this.s0 = this.s1;
58
+ this.s1 = this.s2;
59
+ return (this.s2 = t - (this.c = t | 0));
60
+ }
61
+ }
62
+
63
+ export type RNG = () => number;
64
+
65
+ export function alea(seed: number[]): RNG {
66
+ const xg = new Alea(seed);
67
+ return xg.next.bind(xg);
68
+ }
69
+
70
+ export class Mash {
71
+ private n = 0xefc8249d;
72
+
73
+ public mash(data: number[]): number {
74
+ let { n } = this;
75
+ for (let i = 0; i < data.length; i++) {
76
+ n += data[i];
77
+ let h = 0.02519603282416938 * n;
78
+ n = h >>> 0;
79
+ h -= n;
80
+ h *= n;
81
+ n = h >>> 0;
82
+ h -= n;
83
+ n += h * 0x100000000; // 2^32
84
+ }
85
+ this.n = n;
86
+ return (n >>> 0) * 2.3283064365386963e-10; // 2^-32
87
+ }
88
+ }
@@ -0,0 +1,205 @@
1
+ import { CancelledFailure, IllegalStateError } from '@temporalio/common';
2
+ import type { AsyncLocalStorage as ALS } from 'async_hooks';
3
+ import { untrackPromise } from './stack-helpers';
4
+
5
+ // AsyncLocalStorage is injected via vm module into global scope.
6
+ // In case Workflow code is imported in Node.js context, replace with an empty class.
7
+ export const AsyncLocalStorage: new <T>() => ALS<T> = (globalThis as any).AsyncLocalStorage ?? class {};
8
+
9
+ /** Magic symbol used to create the root scope - intentionally not exported */
10
+ const NO_PARENT = Symbol('NO_PARENT');
11
+
12
+ /**
13
+ * Option for constructing a CancellationScope
14
+ */
15
+ export interface CancellationScopeOptions {
16
+ /**
17
+ * Time in milliseconds before the scope cancellation is automatically requested
18
+ */
19
+ timeout?: number;
20
+
21
+ /**
22
+ * If false, prevent outer cancellation from propagating to inner scopes, Activities, timers, and Triggers, defaults to true.
23
+ * (Scope still propagates CancelledFailure thrown from within).
24
+ */
25
+ cancellable: boolean;
26
+ /**
27
+ * An optional CancellationScope (useful for running background tasks).
28
+ * The `NO_PARENT` symbol is reserved for the root scope.
29
+ */
30
+ parent?: CancellationScope | typeof NO_PARENT;
31
+ }
32
+
33
+ /**
34
+ * In the SDK, Workflows are represented internally by a tree of scopes where the `execute` function runs in the root scope.
35
+ * Cancellation propagates from outer scopes to inner ones and is handled by catching {@link CancelledFailure}s
36
+ * thrown by cancellable operations (see below).
37
+ *
38
+ * Scopes are created using the `CancellationScope` constructor or the static helper methods
39
+ * {@link cancellable}, {@link nonCancellable} and {@link withTimeout}.
40
+ *
41
+ * When a `CancellationScope` is cancelled, it will propagate cancellation any child scopes and any cancellable
42
+ * operations created within it, such as:
43
+ *
44
+ * - Activities
45
+ * - Child Workflows
46
+ * - Timers (created with the {@link sleep} function)
47
+ * - {@link Trigger}s
48
+ *
49
+ * @example
50
+ *
51
+ * ```ts
52
+ * await CancellationScope.cancellable(async () => {
53
+ * const promise = someActivity();
54
+ * CancellationScope.current().cancel(); // Cancels the activity
55
+ * await promise; // Throws `ActivityFailure` with `cause` set to `CancelledFailure`
56
+ * });
57
+ * ```
58
+ *
59
+ * @example
60
+ *
61
+ * ```ts
62
+ * const scope = new CancellationScope();
63
+ * const promise = scope.run(someActivity);
64
+ * scope.cancel(); // Cancels the activity
65
+ * await promise; // Throws `ActivityFailure` with `cause` set to `CancelledFailure`
66
+ * ```
67
+ */
68
+ export class CancellationScope {
69
+ /**
70
+ * Time in milliseconds before the scope cancellation is automatically requested
71
+ */
72
+ protected readonly timeout?: number;
73
+
74
+ /**
75
+ * If false, prevent outer cancellation from propagating to inner scopes, Activities, timers, and Triggers, defaults to true.
76
+ * (Scope still propagates CancelledFailure thrown from within)
77
+ */
78
+ public readonly cancellable: boolean;
79
+ /**
80
+ * An optional CancellationScope (useful for running background tasks), defaults to {@link CancellationScope.current}()
81
+ */
82
+ public readonly parent?: CancellationScope;
83
+
84
+ /**
85
+ * Rejected when scope cancellation is requested
86
+ */
87
+ public readonly cancelRequested: Promise<never>;
88
+
89
+ #cancelRequested = false;
90
+
91
+ // Typescript does not understand that the Promise executor runs synchronously in the constructor
92
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
93
+ // @ts-ignore
94
+ protected readonly reject: (reason?: any) => void;
95
+
96
+ constructor(options?: CancellationScopeOptions) {
97
+ this.timeout = options?.timeout;
98
+ this.cancellable = options?.cancellable ?? true;
99
+ this.cancelRequested = new Promise((_, reject) => {
100
+ // Typescript does not understand that the Promise executor runs synchronously
101
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
102
+ // @ts-ignore
103
+ this.reject = (err) => {
104
+ this.#cancelRequested = true;
105
+ reject(err);
106
+ };
107
+ });
108
+ untrackPromise(this.cancelRequested);
109
+ // Avoid unhandled rejections
110
+ untrackPromise(this.cancelRequested.catch(() => undefined));
111
+ if (options?.parent !== NO_PARENT) {
112
+ this.parent = options?.parent || CancellationScope.current();
113
+ this.#cancelRequested = this.parent.#cancelRequested;
114
+ this.parent.cancelRequested.catch((err) => {
115
+ this.reject(err);
116
+ });
117
+ }
118
+ }
119
+
120
+ public get consideredCancelled(): boolean {
121
+ return this.#cancelRequested && this.cancellable;
122
+ }
123
+ /**
124
+ * Activate the scope as current and run `fn`
125
+ *
126
+ * Any timers, Activities, Triggers and CancellationScopes created in the body of `fn`
127
+ * automatically link their cancellation to this scope.
128
+ *
129
+ * @return the result of `fn`
130
+ */
131
+ run<T>(fn: () => Promise<T>): Promise<T> {
132
+ return storage.run(this, this.runInContext.bind(this, fn) as () => Promise<T>);
133
+ }
134
+
135
+ /**
136
+ * Method that runs a function in AsyncLocalStorage context.
137
+ *
138
+ * Could have been written as anonymous function, made into a method for improved stack traces.
139
+ */
140
+ protected async runInContext<T>(fn: () => Promise<T>): Promise<T> {
141
+ if (this.timeout) {
142
+ untrackPromise(
143
+ sleep(this.timeout).then(
144
+ () => this.cancel(),
145
+ () => {
146
+ // scope was already cancelled, ignore
147
+ }
148
+ )
149
+ );
150
+ }
151
+ return await fn();
152
+ }
153
+
154
+ /**
155
+ * Request to cancel the scope and linked children
156
+ */
157
+ cancel(): void {
158
+ this.reject(new CancelledFailure('Cancellation scope cancelled'));
159
+ }
160
+
161
+ /**
162
+ * Get the current "active" scope
163
+ */
164
+ static current(): CancellationScope {
165
+ return storage.getStore() ?? ROOT_SCOPE;
166
+ }
167
+
168
+ /** Alias to `new CancellationScope({ cancellable: true }).run(fn)` */
169
+ static cancellable<T>(fn: () => Promise<T>): Promise<T> {
170
+ return new this({ cancellable: true }).run(fn);
171
+ }
172
+
173
+ /** Alias to `new CancellationScope({ cancellable: false }).run(fn)` */
174
+ static nonCancellable<T>(fn: () => Promise<T>): Promise<T> {
175
+ return new this({ cancellable: false }).run(fn);
176
+ }
177
+
178
+ /** Alias to `new CancellationScope({ cancellable: true, timeout }).run(fn)` */
179
+ static withTimeout<T>(timeout: number, fn: () => Promise<T>): Promise<T> {
180
+ return new this({ cancellable: true, timeout }).run(fn);
181
+ }
182
+ }
183
+
184
+ /**
185
+ * This is exported so it can be disposed in the worker interface
186
+ */
187
+ export const storage = new AsyncLocalStorage<CancellationScope>();
188
+
189
+ export class RootCancellationScope extends CancellationScope {
190
+ cancel(): void {
191
+ this.reject(new CancelledFailure('Workflow cancelled'));
192
+ }
193
+ }
194
+
195
+ /** There can only be one of these */
196
+ export const ROOT_SCOPE = new RootCancellationScope({ cancellable: true, parent: NO_PARENT });
197
+
198
+ /** This function is here to avoid a circular dependency between this module and workflow.ts */
199
+ let sleep = (_: number | string): Promise<void> => {
200
+ throw new IllegalStateError('Workflow has not been properly initialized');
201
+ };
202
+
203
+ export function registerSleepImplementation(fn: typeof sleep): void {
204
+ sleep = fn;
205
+ }
package/src/errors.ts ADDED
@@ -0,0 +1,30 @@
1
+ export { WorkflowExecutionAlreadyStartedError } from '@temporalio/common';
2
+
3
+ /**
4
+ * Base class for all workflow errors
5
+ */
6
+ export class WorkflowError extends Error {
7
+ public readonly name: string = 'WorkflowError';
8
+ }
9
+
10
+ /**
11
+ * Thrown in workflow when it tries to do something that non-deterministic such as construct a WeakMap()
12
+ */
13
+ export class DeterminismViolationError extends WorkflowError {
14
+ public readonly name: string = 'DeterminismViolationError';
15
+ }
16
+
17
+ function looksLikeError(err: unknown): err is { name: string; cause?: unknown } {
18
+ return typeof err === 'object' && err != null && Object.prototype.hasOwnProperty.call(err, 'name');
19
+ }
20
+
21
+ /**
22
+ * Returns whether provided `err` is caused by cancellation
23
+ */
24
+ export function isCancellation(err: unknown): boolean {
25
+ if (!looksLikeError(err)) return false;
26
+ return (
27
+ err.name === 'CancelledFailure' ||
28
+ ((err.name === 'ActivityFailure' || err.name === 'ChildWorkflowFailure') && isCancellation(err.cause))
29
+ );
30
+ }
package/src/index.ts ADDED
@@ -0,0 +1,91 @@
1
+ /**
2
+ * This library provides tools required for authoring workflows.
3
+ *
4
+ * ## Usage
5
+ * See the {@link https://docs.temporal.io/typescript/hello-world#workflows | tutorial} for writing your first workflow.
6
+ *
7
+ * ### Timers
8
+ *
9
+ * The recommended way of scheduling timers is by using the {@link sleep} function. We've replaced `setTimeout` and
10
+ * `clearTimeout` with deterministic versions so these are also usable but have a limitation that they don't play well
11
+ * with {@link https://docs.temporal.io/typescript/workflow-scopes-and-cancellation | cancellation scopes}.
12
+ *
13
+ * <!--SNIPSTART typescript-sleep-workflow-->
14
+ * <!--SNIPEND-->
15
+ *
16
+ * ### Activities
17
+ *
18
+ * To schedule Activities, use {@link proxyActivities} to obtain an Activity function and call.
19
+ *
20
+ * <!--SNIPSTART typescript-schedule-activity-workflow-->
21
+ * <!--SNIPEND-->
22
+ *
23
+ * ### Signals and Queries
24
+ *
25
+ * To add signal handlers to a Workflow, add a signals property to the exported `workflow` object. Signal handlers can
26
+ * return either `void` or `Promise<void>`, you may schedule activities and timers from a signal handler.
27
+ *
28
+ * To add query handlers to a Workflow, add a queries property to the exported `workflow` object. Query handlers must
29
+ * **not** mutate any variables or generate any commands (like Activities or Timers), they run synchronously and thus
30
+ * **must** return a `Promise`.
31
+ *
32
+ * #### Implementation
33
+ *
34
+ * <!--SNIPSTART typescript-workflow-signal-implementation-->
35
+ * <!--SNIPEND-->
36
+ *
37
+ * ### Deterministic built-ins
38
+ * It is safe to call `Math.random()` and `Date()` in workflow code as they are replaced with deterministic versions. We
39
+ * also provide a deterministic {@link uuid4} function for convenience.
40
+ *
41
+ * ### [Cancellation and scopes](https://docs.temporal.io/typescript/workflow-scopes-and-cancellation)
42
+ * - {@link CancellationScope}
43
+ * - {@link Trigger}
44
+ *
45
+ * ### [Sinks](https://docs.temporal.io/typescript/sinks)
46
+ * - {@link Sinks}
47
+ *
48
+ * @module
49
+ */
50
+
51
+ export {
52
+ ActivityFailure,
53
+ ApplicationFailure,
54
+ CancelledFailure,
55
+ ChildWorkflowFailure,
56
+ defaultPayloadConverter,
57
+ PayloadConverter,
58
+ rootCause,
59
+ ServerFailure,
60
+ TemporalFailure,
61
+ TerminatedFailure,
62
+ TimeoutFailure,
63
+ } from '@temporalio/common';
64
+ export {
65
+ ActivityCancellationType,
66
+ ActivityFunction,
67
+ ActivityInterface, // eslint-disable-line deprecation/deprecation
68
+ ActivityOptions,
69
+ RetryPolicy,
70
+ UntypedActivities,
71
+ } from '@temporalio/internal-workflow-common';
72
+ export * from '@temporalio/internal-workflow-common/lib/errors';
73
+ export * from '@temporalio/internal-workflow-common/lib/interfaces';
74
+ export * from '@temporalio/internal-workflow-common/lib/workflow-handle';
75
+ export * from '@temporalio/internal-workflow-common/lib/workflow-options';
76
+ export { AsyncLocalStorage, CancellationScope, CancellationScopeOptions, ROOT_SCOPE } from './cancellation-scope';
77
+ export * from './errors';
78
+ export * from './interceptors';
79
+ export {
80
+ ChildWorkflowCancellationType,
81
+ ChildWorkflowOptions,
82
+ ContinueAsNew,
83
+ ContinueAsNewOptions,
84
+ ParentClosePolicy,
85
+ ParentWorkflowInfo,
86
+ WorkflowInfo,
87
+ } from './interfaces';
88
+ export { Sink, SinkCall, SinkFunction, Sinks } from './sinks';
89
+ export { Trigger } from './trigger';
90
+ export * from './workflow';
91
+ export { ChildWorkflowHandle, ExternalWorkflowHandle } from './workflow-handle';
@@ -0,0 +1,239 @@
1
+ /**
2
+ * Type definitions and generic helpers for interceptors.
3
+ *
4
+ * The Workflow specific interceptors are defined here.
5
+ *
6
+ * @module
7
+ */
8
+
9
+ import { WorkflowExecution } from '@temporalio/common';
10
+ import { ActivityOptions, Headers, LocalActivityOptions, Next, Timestamp } from '@temporalio/internal-workflow-common';
11
+ import type { coresdk } from '@temporalio/proto';
12
+ import { ChildWorkflowOptionsWithDefaults, ContinueAsNewOptions } from './interfaces';
13
+
14
+ export { Next, Headers };
15
+
16
+ /** Input for WorkflowInboundCallsInterceptor.execute */
17
+ export interface WorkflowExecuteInput {
18
+ readonly args: unknown[];
19
+ readonly headers: Headers;
20
+ }
21
+
22
+ /** Input for WorkflowInboundCallsInterceptor.handleSignal */
23
+ export interface SignalInput {
24
+ readonly signalName: string;
25
+ readonly args: unknown[];
26
+ readonly headers: Headers;
27
+ }
28
+
29
+ /** Input for WorkflowInboundCallsInterceptor.handleQuery */
30
+ export interface QueryInput {
31
+ readonly queryId: string;
32
+ readonly queryName: string;
33
+ readonly args: unknown[];
34
+ readonly headers: Headers;
35
+ }
36
+
37
+ /**
38
+ * Implement any of these methods to intercept Workflow inbound calls like execution, and signal and query handling.
39
+ */
40
+ export interface WorkflowInboundCallsInterceptor {
41
+ /**
42
+ * Called when Workflow execute method is called
43
+ *
44
+ * @return result of the Workflow execution
45
+ */
46
+ execute?: (input: WorkflowExecuteInput, next: Next<this, 'execute'>) => Promise<unknown>;
47
+
48
+ /** Called when signal is delivered to a Workflow execution */
49
+ handleSignal?: (input: SignalInput, next: Next<this, 'handleSignal'>) => Promise<void>;
50
+
51
+ /**
52
+ * Called when a Workflow is queried
53
+ *
54
+ * @return result of the query
55
+ */
56
+ handleQuery?: (input: QueryInput, next: Next<this, 'handleQuery'>) => Promise<unknown>;
57
+ }
58
+
59
+ /** Input for WorkflowOutboundCallsInterceptor.scheduleActivity */
60
+ export interface ActivityInput {
61
+ readonly activityType: string;
62
+ readonly args: unknown[];
63
+ readonly options: ActivityOptions;
64
+ readonly headers: Headers;
65
+ readonly seq: number;
66
+ }
67
+
68
+ /** Input for WorkflowOutboundCallsInterceptor.scheduleLocalActivity */
69
+ export interface LocalActivityInput {
70
+ readonly activityType: string;
71
+ readonly args: unknown[];
72
+ readonly options: LocalActivityOptions;
73
+ readonly headers: Headers;
74
+ readonly seq: number;
75
+ readonly originalScheduleTime?: Timestamp;
76
+ readonly attempt: number;
77
+ }
78
+
79
+ /** Input for WorkflowOutboundCallsInterceptor.startChildWorkflowExecution */
80
+ export interface StartChildWorkflowExecutionInput {
81
+ readonly workflowType: string;
82
+ readonly options: ChildWorkflowOptionsWithDefaults;
83
+ readonly headers: Headers;
84
+ readonly seq: number;
85
+ }
86
+
87
+ /** Input for WorkflowOutboundCallsInterceptor.startTimer */
88
+ export interface TimerInput {
89
+ readonly durationMs: number;
90
+ readonly seq: number;
91
+ }
92
+
93
+ /**
94
+ * Same as ContinueAsNewOptions but workflowType must be defined
95
+ */
96
+ export type ContinueAsNewInputOptions = ContinueAsNewOptions & Required<Pick<ContinueAsNewOptions, 'workflowType'>>;
97
+
98
+ /** Input for WorkflowOutboundCallsInterceptor.continueAsNew */
99
+ export interface ContinueAsNewInput {
100
+ readonly args: unknown[];
101
+ readonly headers: Headers;
102
+ readonly options: ContinueAsNewInputOptions;
103
+ }
104
+
105
+ /** Input for WorkflowOutboundCallsInterceptor.signalWorkflow */
106
+ export interface SignalWorkflowInput {
107
+ readonly seq: number;
108
+ readonly signalName: string;
109
+ readonly args: unknown[];
110
+ readonly headers: Headers;
111
+ readonly target:
112
+ | {
113
+ readonly type: 'external';
114
+ readonly workflowExecution: WorkflowExecution;
115
+ }
116
+ | {
117
+ readonly type: 'child';
118
+ readonly childWorkflowId: string;
119
+ };
120
+ }
121
+
122
+ /**
123
+ * Implement any of these methods to intercept Workflow code calls to the Temporal APIs, like scheduling an activity and starting a timer
124
+ */
125
+ export interface WorkflowOutboundCallsInterceptor {
126
+ /**
127
+ * Called when Workflow schedules an Activity
128
+ *
129
+ * @return result of the activity execution
130
+ */
131
+ scheduleActivity?: (input: ActivityInput, next: Next<this, 'scheduleActivity'>) => Promise<unknown>;
132
+
133
+ /**
134
+ * Called when Workflow schedules a local Activity
135
+ *
136
+ * @return result of the activity execution
137
+ */
138
+ scheduleLocalActivity?: (input: LocalActivityInput, next: Next<this, 'scheduleLocalActivity'>) => Promise<unknown>;
139
+
140
+ /**
141
+ * Called when Workflow starts a timer
142
+ */
143
+ startTimer?: (input: TimerInput, next: Next<this, 'startTimer'>) => Promise<void>;
144
+
145
+ /**
146
+ * Called when Workflow calls continueAsNew
147
+ */
148
+ continueAsNew?: (input: ContinueAsNewInput, next: Next<this, 'continueAsNew'>) => Promise<never>;
149
+
150
+ /**
151
+ * Called when Workflow signals a child or external Workflow
152
+ */
153
+ signalWorkflow?: (input: SignalWorkflowInput, next: Next<this, 'signalWorkflow'>) => Promise<void>;
154
+
155
+ /**
156
+ * Called when Workflow starts a child workflow execution, the interceptor function returns 2 promises:
157
+ *
158
+ * - The first resolves with the `runId` when the child workflow has started or rejects if failed to start.
159
+ * - The second resolves with the workflow result when the child workflow completes or rejects on failure.
160
+ */
161
+ startChildWorkflowExecution?: (
162
+ input: StartChildWorkflowExecutionInput,
163
+ next: Next<this, 'startChildWorkflowExecution'>
164
+ ) => Promise<[Promise<string>, Promise<unknown>]>;
165
+ }
166
+
167
+ /** Input for WorkflowInternalsInterceptor.concludeActivation */
168
+ export interface ConcludeActivationInput {
169
+ commands: coresdk.workflow_commands.IWorkflowCommand[];
170
+ }
171
+
172
+ /** Output for WorkflowInternalsInterceptor.concludeActivation */
173
+ export type ConcludeActivationOutput = ConcludeActivationInput;
174
+
175
+ /** Input for WorkflowInternalsInterceptor.activate */
176
+ export interface ActivateInput {
177
+ activation: coresdk.workflow_activation.IWorkflowActivation;
178
+ batchIndex: number;
179
+ }
180
+
181
+ /** Input for WorkflowInternalsInterceptor.dispose */
182
+ // eslint-disable-next-line @typescript-eslint/no-empty-interface
183
+ export interface DisposeInput {}
184
+
185
+ /**
186
+ * Interceptor for the internals of the Workflow runtime.
187
+ *
188
+ * Use to manipulate or trace Workflow activations.
189
+ *
190
+ * @experimental
191
+ */
192
+ export interface WorkflowInternalsInterceptor {
193
+ /**
194
+ * Called when the Workflow runtime runs a WorkflowActivationJob.
195
+ */
196
+ activate?(input: ActivateInput, next: Next<this, 'activate'>): void;
197
+
198
+ /**
199
+ * Called after all `WorkflowActivationJob`s have been processed for an activation.
200
+ *
201
+ * Can manipulate the commands generated by the Workflow
202
+ */
203
+ concludeActivation?(input: ConcludeActivationInput, next: Next<this, 'concludeActivation'>): ConcludeActivationOutput;
204
+
205
+ /**
206
+ * Called before disposing the Workflow isolate context.
207
+ *
208
+ * Implement this method to perform any resource cleanup.
209
+ */
210
+ dispose?(input: DisposeInput, next: Next<this, 'dispose'>): Promise<void>;
211
+ }
212
+
213
+ /**
214
+ * A mapping from interceptor type to an optional list of interceptor implementations
215
+ */
216
+ export interface WorkflowInterceptors {
217
+ inbound?: WorkflowInboundCallsInterceptor[];
218
+ outbound?: WorkflowOutboundCallsInterceptor[];
219
+ internals?: WorkflowInternalsInterceptor[];
220
+ }
221
+
222
+ /**
223
+ * A function that returns {@link WorkflowInterceptors} and takes no arguments.
224
+ *
225
+ * Workflow interceptor modules should export an `interceptors` function of this type.
226
+ *
227
+ * @example
228
+ *
229
+ * ```ts
230
+ * export function interceptors(): WorkflowInterceptors {
231
+ * return {
232
+ * inbound: [], // Populate with list of interceptor implementations
233
+ * outbound: [], // Populate with list of interceptor implementations
234
+ * internals: [], // Populate with list of interceptor implementations
235
+ * };
236
+ * }
237
+ * ```
238
+ */
239
+ export type WorkflowInterceptorsFactory = () => WorkflowInterceptors;