@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/README.md +2 -2
- package/lib/cancellation-scope.js +6 -2
- package/lib/cancellation-scope.js.map +1 -1
- package/lib/errors.js +9 -5
- package/lib/errors.js.map +1 -1
- package/lib/index.d.ts +18 -12
- package/lib/index.js +16 -13
- package/lib/index.js.map +1 -1
- package/lib/interceptors.d.ts +3 -1
- package/lib/interfaces.d.ts +129 -13
- package/lib/interfaces.js +44 -0
- package/lib/interfaces.js.map +1 -1
- package/lib/internals.d.ts +17 -2
- package/lib/internals.js +45 -12
- package/lib/internals.js.map +1 -1
- package/lib/sinks.d.ts +2 -1
- package/lib/stack-helpers.d.ts +4 -0
- package/lib/stack-helpers.js +15 -0
- package/lib/stack-helpers.js.map +1 -0
- package/lib/trigger.d.ts +5 -4
- package/lib/trigger.js +10 -7
- package/lib/trigger.js.map +1 -1
- package/lib/worker-interface.d.ts +5 -2
- package/lib/worker-interface.js +17 -11
- package/lib/worker-interface.js.map +1 -1
- package/lib/workflow-handle.d.ts +5 -2
- package/lib/workflow.d.ts +120 -42
- package/lib/workflow.js +164 -78
- package/lib/workflow.js.map +1 -1
- package/package.json +9 -7
- package/src/alea.ts +88 -0
- package/src/cancellation-scope.ts +205 -0
- package/src/errors.ts +30 -0
- package/src/index.ts +91 -0
- package/src/interceptors.ts +239 -0
- package/src/interfaces.ts +272 -0
- package/src/internals.ts +621 -0
- package/src/sinks.ts +41 -0
- package/src/stack-helpers.ts +11 -0
- package/src/trigger.ts +49 -0
- package/src/worker-interface.ts +283 -0
- package/src/workflow-handle.ts +63 -0
- package/src/workflow.ts +1265 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@temporalio/workflow",
|
|
3
|
-
"version": "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/
|
|
24
|
-
"@temporalio/
|
|
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
|
-
"
|
|
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;
|