@voyantjs/workflows 0.0.0
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/LICENSE +201 -0
- package/NOTICE +52 -0
- package/README.md +46 -0
- package/package.json +78 -0
- package/src/auth/index.ts +156 -0
- package/src/conditions.ts +43 -0
- package/src/handler/index.ts +361 -0
- package/src/index.ts +18 -0
- package/src/protocol/index.ts +133 -0
- package/src/rate-limit/index.ts +182 -0
- package/src/runtime/ctx.ts +838 -0
- package/src/runtime/determinism.ts +75 -0
- package/src/runtime/errors.ts +58 -0
- package/src/runtime/executor.ts +427 -0
- package/src/runtime/journal.ts +79 -0
- package/src/testing/index.ts +729 -0
- package/src/trigger.ts +146 -0
- package/src/types.ts +81 -0
- package/src/workflow.ts +306 -0
package/src/trigger.ts
ADDED
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
// Triggering workflows from server code, plus event filter declarations.
|
|
2
|
+
// Authoritative contract in docs/sdk-surface.md §6.
|
|
3
|
+
|
|
4
|
+
import type {
|
|
5
|
+
Duration,
|
|
6
|
+
EnvironmentName,
|
|
7
|
+
RunStatus,
|
|
8
|
+
} from "./types.js";
|
|
9
|
+
import type { WorkflowHandle, EnvironmentContext } from "./workflow.js";
|
|
10
|
+
|
|
11
|
+
// ---- workflows.* ----
|
|
12
|
+
|
|
13
|
+
export interface WorkflowsClient {
|
|
14
|
+
trigger<TIn, TOut>(
|
|
15
|
+
workflow: WorkflowHandle<TIn, TOut> | string,
|
|
16
|
+
input: TIn,
|
|
17
|
+
opts?: TriggerOptions,
|
|
18
|
+
): Promise<Run<TOut>>;
|
|
19
|
+
|
|
20
|
+
signal(runId: string, name: string, payload: unknown, opts?: { nonce?: string }): Promise<void>;
|
|
21
|
+
completeToken(tokenId: string, payload: unknown): Promise<void>;
|
|
22
|
+
|
|
23
|
+
cancel(runId: string, opts?: { compensate?: boolean; reason?: string }): Promise<void>;
|
|
24
|
+
retry(runId: string, opts: { mode: "re-trigger" | "resume" }): Promise<Run>;
|
|
25
|
+
replay(runId: string, opts?: { fromStepId?: string; input?: unknown }): Promise<Run>;
|
|
26
|
+
|
|
27
|
+
get(runId: string): Promise<RunDetail>;
|
|
28
|
+
list(opts?: ListRunsOptions): Promise<{ runs: RunSummary[]; nextCursor?: string }>;
|
|
29
|
+
|
|
30
|
+
mintAccessToken(opts: MintAccessTokenOptions): Promise<PublicAccessToken>;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export interface TriggerOptions {
|
|
34
|
+
idempotencyKey?: string;
|
|
35
|
+
delay?: Duration | Date;
|
|
36
|
+
debounce?: { key: string; delay: Duration; mode?: "leading" | "trailing" };
|
|
37
|
+
ttl?: Duration;
|
|
38
|
+
tags?: string[];
|
|
39
|
+
priority?: number;
|
|
40
|
+
concurrencyKey?: string;
|
|
41
|
+
lockToVersion?: string;
|
|
42
|
+
environment?: EnvironmentName;
|
|
43
|
+
issuePublicAccessToken?: boolean;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export interface Run<TOut = unknown> {
|
|
47
|
+
id: string;
|
|
48
|
+
workflowId: string;
|
|
49
|
+
status: RunStatus;
|
|
50
|
+
startedAt: number;
|
|
51
|
+
accessToken?: string;
|
|
52
|
+
/** Phantom; used only for TypeScript inference. */
|
|
53
|
+
readonly __output?: TOut;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export interface RunSummary {
|
|
57
|
+
id: string;
|
|
58
|
+
workflowId: string;
|
|
59
|
+
status: RunStatus;
|
|
60
|
+
startedAt: number;
|
|
61
|
+
completedAt?: number;
|
|
62
|
+
tags: string[];
|
|
63
|
+
environment: EnvironmentName;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export interface RunDetail<TOut = unknown> extends RunSummary {
|
|
67
|
+
version: string;
|
|
68
|
+
input: unknown;
|
|
69
|
+
output?: TOut;
|
|
70
|
+
error?: unknown;
|
|
71
|
+
durationMs?: number;
|
|
72
|
+
// ... full shape in docs/runtime-protocol.md §4.2
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export interface ListRunsOptions {
|
|
76
|
+
workflowId?: string;
|
|
77
|
+
status?: RunStatus | RunStatus[];
|
|
78
|
+
environment?: EnvironmentName;
|
|
79
|
+
tag?: string;
|
|
80
|
+
since?: Date | number;
|
|
81
|
+
until?: Date | number;
|
|
82
|
+
cursor?: string;
|
|
83
|
+
limit?: number;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export interface MintAccessTokenOptions {
|
|
87
|
+
target:
|
|
88
|
+
| { kind: "run"; runId: string }
|
|
89
|
+
| { kind: "workflow"; workflowId: string }
|
|
90
|
+
| { kind: "tag"; tag: string };
|
|
91
|
+
scope: ("read" | "trigger" | "cancel")[];
|
|
92
|
+
ttl?: Duration;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export interface PublicAccessToken {
|
|
96
|
+
token: string;
|
|
97
|
+
exp: number;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Top-level server SDK client. Resolves against the configured
|
|
102
|
+
* Voyant Cloud API key and account. The runtime implementation is
|
|
103
|
+
* installed by the cloud client package; imported alone, every
|
|
104
|
+
* method throws with guidance.
|
|
105
|
+
*/
|
|
106
|
+
export const workflows: WorkflowsClient = new Proxy({} as WorkflowsClient, {
|
|
107
|
+
get(_, method: string) {
|
|
108
|
+
return () => {
|
|
109
|
+
throw new Error(
|
|
110
|
+
`@voyantjs/workflows: workflows.${method}() requires the Voyant Cloud client. ` +
|
|
111
|
+
`Install + configure it via @voyantjs/client, or see docs/sdk-surface.md §6.`,
|
|
112
|
+
);
|
|
113
|
+
};
|
|
114
|
+
},
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
// ---- trigger.on ----
|
|
118
|
+
|
|
119
|
+
export interface EventFilterHandle {
|
|
120
|
+
readonly id: string;
|
|
121
|
+
readonly event: string;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export interface EventFilterDeclaration<T> {
|
|
125
|
+
target: WorkflowHandle<T, unknown>;
|
|
126
|
+
match?: (
|
|
127
|
+
payload: T,
|
|
128
|
+
ctx: { environment: EnvironmentContext; project: { id: string } },
|
|
129
|
+
) => boolean;
|
|
130
|
+
scope?: string;
|
|
131
|
+
input?: (payload: T) => unknown;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export interface TriggerApi {
|
|
135
|
+
on<T = unknown>(event: string, filter: EventFilterDeclaration<T>): EventFilterHandle;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
export const trigger: TriggerApi = {
|
|
139
|
+
on<T>(_event: string, _filter: EventFilterDeclaration<T>): EventFilterHandle {
|
|
140
|
+
throw new Error(
|
|
141
|
+
"@voyantjs/workflows: trigger.on() must be collected by `voyant workflows build` and " +
|
|
142
|
+
"registered with the orchestrator at deploy time; it has no runtime behavior when " +
|
|
143
|
+
"called directly. See docs/sdk-surface.md §6.2.",
|
|
144
|
+
);
|
|
145
|
+
},
|
|
146
|
+
};
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
// Core type aliases used across the SDK.
|
|
2
|
+
// Authoritative definitions in docs/sdk-surface.md §0 and §2.
|
|
3
|
+
|
|
4
|
+
export type Duration =
|
|
5
|
+
| number
|
|
6
|
+
| `${number}${"ms" | "s" | "m" | "h" | "d" | "w"}`;
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Cloudflare Container instance types — the set Voyant Cloud honors
|
|
10
|
+
* for `runtime: "node"` steps. Match the sizes published at
|
|
11
|
+
* https://developers.cloudflare.com/containers/ (as of
|
|
12
|
+
* compat-date 2026-04-01).
|
|
13
|
+
*
|
|
14
|
+
* | name | vCPU | memory | disk |
|
|
15
|
+
* | ----------- | ----- | ------- | ----- |
|
|
16
|
+
* | lite | 1/16 | 256 MiB | 2 GB |
|
|
17
|
+
* | basic | 1/4 | 1 GiB | 4 GB |
|
|
18
|
+
* | standard-1 | 1/2 | 4 GiB | 8 GB |
|
|
19
|
+
* | standard-2 | 1 | 6 GiB | 12 GB |
|
|
20
|
+
* | standard-3 | 2 | 8 GiB | 16 GB |
|
|
21
|
+
* | standard-4 | 4 | 12 GiB | 20 GB |
|
|
22
|
+
*
|
|
23
|
+
* The open `(string & {})` escape hatch accepts CF custom instance
|
|
24
|
+
* types (up to 4 vCPU / 12 GiB / 20 GB, min 3 GiB RAM per vCPU) —
|
|
25
|
+
* rendered as `"custom-<vcpu>-<ramGiB>"` by convention.
|
|
26
|
+
*/
|
|
27
|
+
export type MachineType =
|
|
28
|
+
| "lite"
|
|
29
|
+
| "basic"
|
|
30
|
+
| "standard-1"
|
|
31
|
+
| "standard-2"
|
|
32
|
+
| "standard-3"
|
|
33
|
+
| "standard-4"
|
|
34
|
+
| (string & {});
|
|
35
|
+
|
|
36
|
+
export type EnvironmentName = "production" | "preview" | "development";
|
|
37
|
+
|
|
38
|
+
export type RunStatus =
|
|
39
|
+
| "pending"
|
|
40
|
+
| "running"
|
|
41
|
+
| "waiting"
|
|
42
|
+
| "completed"
|
|
43
|
+
| "failed"
|
|
44
|
+
| "cancelled"
|
|
45
|
+
| "cancelled_by_dev_reload"
|
|
46
|
+
| "cancelled_by_version_sunset"
|
|
47
|
+
| "compensated"
|
|
48
|
+
| "compensation_failed"
|
|
49
|
+
| "timed_out";
|
|
50
|
+
|
|
51
|
+
export type ExecutionStatus =
|
|
52
|
+
| "CREATED"
|
|
53
|
+
| "QUEUED"
|
|
54
|
+
| "EXECUTING"
|
|
55
|
+
| "EXECUTING_WITH_WAITPOINTS"
|
|
56
|
+
| "SUSPENDED"
|
|
57
|
+
| "PENDING_CANCEL"
|
|
58
|
+
| "FINISHED";
|
|
59
|
+
|
|
60
|
+
export type WaitpointKind = "DATETIME" | "EVENT" | "SIGNAL" | "RUN" | "MANUAL";
|
|
61
|
+
|
|
62
|
+
export interface RetryPolicy {
|
|
63
|
+
max?: number;
|
|
64
|
+
backoff?: "exponential" | "linear" | "fixed";
|
|
65
|
+
initial?: Duration;
|
|
66
|
+
maxDelay?: Duration;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export interface RateLimitSpec {
|
|
70
|
+
key: string | ((input: unknown, ctx: { run: { id: string }; project: { id: string } }) => string);
|
|
71
|
+
limit: number | ((input: unknown) => number);
|
|
72
|
+
units?: number | ((input: unknown) => number);
|
|
73
|
+
window: Duration;
|
|
74
|
+
onLimit?: "queue" | "fail";
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export type RunTrigger =
|
|
78
|
+
| { kind: "api"; actor?: string; accessTokenId?: string }
|
|
79
|
+
| { kind: "schedule"; scheduleId: string }
|
|
80
|
+
| { kind: "event"; eventId: string; eventType: string; filterId: string }
|
|
81
|
+
| { kind: "parent"; parentRunId: string; parentStepId: string };
|
package/src/workflow.ts
ADDED
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
// Workflow declaration and the `ctx` object.
|
|
2
|
+
// Authoritative contract in docs/sdk-surface.md §2–§3.
|
|
3
|
+
|
|
4
|
+
import type {
|
|
5
|
+
Duration,
|
|
6
|
+
EnvironmentName,
|
|
7
|
+
MachineType,
|
|
8
|
+
RetryPolicy,
|
|
9
|
+
RateLimitSpec,
|
|
10
|
+
RunStatus,
|
|
11
|
+
RunTrigger,
|
|
12
|
+
} from "./types.js";
|
|
13
|
+
import type { Condition } from "./conditions.js";
|
|
14
|
+
|
|
15
|
+
// ---- Workflow ----
|
|
16
|
+
|
|
17
|
+
export interface WorkflowHandle<TInput = unknown, TOutput = unknown> {
|
|
18
|
+
readonly id: string;
|
|
19
|
+
/** Phantom; used only for TypeScript inference of `workflows.trigger(...)`. */
|
|
20
|
+
readonly __input?: TInput;
|
|
21
|
+
readonly __output?: TOutput;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface WorkflowConfig<TInput, TOutput> {
|
|
25
|
+
id: string;
|
|
26
|
+
input?: unknown;
|
|
27
|
+
output?: unknown;
|
|
28
|
+
description?: string;
|
|
29
|
+
schedule?: ScheduleDeclaration | ScheduleDeclaration[];
|
|
30
|
+
concurrency?: ConcurrencyPolicy<TInput>;
|
|
31
|
+
retry?: RetryPolicy;
|
|
32
|
+
timeout?: Duration;
|
|
33
|
+
defaultRuntime?: "edge" | "node";
|
|
34
|
+
tags?: string[];
|
|
35
|
+
run: (input: TInput, ctx: WorkflowContext<TInput>) => Promise<TOutput>;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Internal registered form of a workflow. The executor takes this
|
|
40
|
+
* plus a request and drives the body.
|
|
41
|
+
*/
|
|
42
|
+
export interface WorkflowDefinition<TInput = unknown, TOutput = unknown> extends WorkflowHandle<TInput, TOutput> {
|
|
43
|
+
readonly config: WorkflowConfig<TInput, TOutput>;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export type ScheduleDeclaration = (
|
|
47
|
+
| { cron: string }
|
|
48
|
+
| { every: Duration }
|
|
49
|
+
| { at: string | Date }
|
|
50
|
+
) & {
|
|
51
|
+
timezone?: string;
|
|
52
|
+
input?: unknown | (() => unknown | Promise<unknown>);
|
|
53
|
+
enabled?: boolean;
|
|
54
|
+
overlap?: "skip" | "queue" | "allow";
|
|
55
|
+
environments?: EnvironmentName[];
|
|
56
|
+
name?: string;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
export interface ConcurrencyPolicy<TInput> {
|
|
60
|
+
key?: string | ((input: TInput) => string);
|
|
61
|
+
limit?: number;
|
|
62
|
+
strategy?: "queue" | "cancel-in-progress" | "cancel-newest" | "round-robin";
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Process-local registry. Backed by globalThis so bundles that inline
|
|
67
|
+
* their own copy of @voyantjs/workflows still share the registry with
|
|
68
|
+
* the loader's copy (voyant build relies on this to extract the
|
|
69
|
+
* manifest from a user bundle at load-time). Module-local `const`
|
|
70
|
+
* would create a private map per bundle copy.
|
|
71
|
+
*/
|
|
72
|
+
const REGISTRY_KEY = "__voyantWorkflowRegistry" as const;
|
|
73
|
+
const globalRef = globalThis as unknown as Record<
|
|
74
|
+
typeof REGISTRY_KEY,
|
|
75
|
+
Map<string, WorkflowDefinition> | undefined
|
|
76
|
+
>;
|
|
77
|
+
const REGISTRY: Map<string, WorkflowDefinition> =
|
|
78
|
+
globalRef[REGISTRY_KEY] ??= new Map<string, WorkflowDefinition>();
|
|
79
|
+
|
|
80
|
+
/** Declare a workflow. See docs/sdk-surface.md §2.1. */
|
|
81
|
+
export function workflow<TInput = unknown, TOutput = unknown>(
|
|
82
|
+
config: WorkflowConfig<TInput, TOutput>,
|
|
83
|
+
): WorkflowDefinition<TInput, TOutput> {
|
|
84
|
+
if (REGISTRY.has(config.id)) {
|
|
85
|
+
throw new Error(`workflow id "${config.id}" is already registered`);
|
|
86
|
+
}
|
|
87
|
+
const def: WorkflowDefinition<TInput, TOutput> = {
|
|
88
|
+
id: config.id,
|
|
89
|
+
config,
|
|
90
|
+
};
|
|
91
|
+
REGISTRY.set(config.id, def as WorkflowDefinition);
|
|
92
|
+
return def;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/** Internal: look up a registered workflow by id. */
|
|
96
|
+
export function getWorkflow(id: string): WorkflowDefinition | undefined {
|
|
97
|
+
return REGISTRY.get(id);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Internal: enumerate every registered workflow. Used by the CLI to list
|
|
102
|
+
* workflows discovered from a loaded entry file. Not part of the stable
|
|
103
|
+
* public API — implementation detail of the SDK/CLI pair.
|
|
104
|
+
*/
|
|
105
|
+
export function __listRegisteredWorkflows(): WorkflowDefinition[] {
|
|
106
|
+
return [...REGISTRY.values()];
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Internal: clear the workflow registry. Called by the CLI between
|
|
111
|
+
* builds / hot-reloads to drop stale workflows before re-importing
|
|
112
|
+
* the tenant bundle, and by test suites in beforeEach to isolate
|
|
113
|
+
* runs. Not part of the stable public API.
|
|
114
|
+
*/
|
|
115
|
+
export function __resetRegistry(): void {
|
|
116
|
+
REGISTRY.clear();
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// ---- Context ----
|
|
120
|
+
|
|
121
|
+
export interface RunContext {
|
|
122
|
+
id: string;
|
|
123
|
+
number: number;
|
|
124
|
+
attempt: number;
|
|
125
|
+
triggeredBy: RunTrigger;
|
|
126
|
+
tags: readonly string[];
|
|
127
|
+
startedAt: number;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export interface EnvironmentContext {
|
|
131
|
+
name: EnvironmentName;
|
|
132
|
+
git?: {
|
|
133
|
+
commit: string;
|
|
134
|
+
branch: string;
|
|
135
|
+
pr?: { number: number; url: string };
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
export interface WorkflowContext<_TInput = unknown> {
|
|
140
|
+
readonly run: RunContext;
|
|
141
|
+
readonly workflow: { id: string; version: string };
|
|
142
|
+
readonly environment: EnvironmentContext;
|
|
143
|
+
readonly project: { id: string; slug: string };
|
|
144
|
+
readonly organization: { id: string; slug: string };
|
|
145
|
+
readonly invocationCount: number;
|
|
146
|
+
readonly signal: AbortSignal;
|
|
147
|
+
|
|
148
|
+
step: StepApi;
|
|
149
|
+
sleep: (duration: Duration) => Promise<void>;
|
|
150
|
+
waitForEvent: WaitForEventApi;
|
|
151
|
+
waitForSignal: WaitForSignalApi;
|
|
152
|
+
waitForToken: WaitForTokenApi;
|
|
153
|
+
invoke: InvokeApi;
|
|
154
|
+
parallel: ParallelApi;
|
|
155
|
+
stream: StreamApi;
|
|
156
|
+
group: GroupApi;
|
|
157
|
+
compensate: () => Promise<never>;
|
|
158
|
+
metadata: MetadataApi;
|
|
159
|
+
|
|
160
|
+
now: () => number;
|
|
161
|
+
random: () => number;
|
|
162
|
+
randomUUID: () => string;
|
|
163
|
+
|
|
164
|
+
setRetry: (policy: RetryPolicy) => void;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// ---- Step ----
|
|
168
|
+
|
|
169
|
+
export interface StepApi {
|
|
170
|
+
<T>(id: string, fn: StepFn<T>): Promise<T>;
|
|
171
|
+
<T>(id: string, opts: StepOptions<T>, fn: StepFn<T>): Promise<T>;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
export type StepFn<T> = (stepCtx: StepContext) => Promise<T>;
|
|
175
|
+
|
|
176
|
+
export interface StepContext {
|
|
177
|
+
signal: AbortSignal;
|
|
178
|
+
attempt: number;
|
|
179
|
+
log: (level: "info" | "warn" | "error", msg: string, data?: object) => void;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
export interface StepOptions<T = unknown> {
|
|
183
|
+
runtime?: "edge" | "node";
|
|
184
|
+
machine?: MachineType;
|
|
185
|
+
timeout?: Duration;
|
|
186
|
+
retry?: RetryPolicy | { max: 0 };
|
|
187
|
+
idempotencyKey?: string;
|
|
188
|
+
compensate?: (output: T) => Promise<void>;
|
|
189
|
+
rateLimit?: RateLimitSpec;
|
|
190
|
+
waitFor?: Condition;
|
|
191
|
+
cancelIf?: Condition;
|
|
192
|
+
skipIf?: Condition;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// ---- Waits ----
|
|
196
|
+
|
|
197
|
+
export interface Waitable<T> extends PromiseLike<T | null> {
|
|
198
|
+
[Symbol.asyncIterator](): AsyncIterableIterator<T>;
|
|
199
|
+
close(): void;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
export interface WaitForEventApi {
|
|
203
|
+
<T = unknown>(eventType: string, opts?: WaitForEventOptions<T>): Waitable<T>;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
export interface WaitForEventOptions<T> {
|
|
207
|
+
match?: Partial<T> | ((payload: T) => boolean);
|
|
208
|
+
timeout?: Duration;
|
|
209
|
+
lookback?: Duration;
|
|
210
|
+
bufferSize?: number;
|
|
211
|
+
onTimeout?: "null" | "throw";
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
export interface WaitForSignalApi {
|
|
215
|
+
<T = unknown>(name: string, opts?: WaitForSignalOptions<T>): Waitable<T>;
|
|
216
|
+
}
|
|
217
|
+
export interface WaitForSignalOptions<T> extends WaitForEventOptions<T> {}
|
|
218
|
+
|
|
219
|
+
export interface WaitForTokenApi {
|
|
220
|
+
<T = unknown>(opts?: WaitForTokenOptions<T>): Promise<TokenWait<T>>;
|
|
221
|
+
}
|
|
222
|
+
export interface WaitForTokenOptions<_T> {
|
|
223
|
+
tokenId?: string;
|
|
224
|
+
timeout?: Duration;
|
|
225
|
+
onTimeout?: "null" | "throw";
|
|
226
|
+
schema?: unknown;
|
|
227
|
+
}
|
|
228
|
+
export interface TokenWait<T> {
|
|
229
|
+
tokenId: string;
|
|
230
|
+
url: string;
|
|
231
|
+
wait: () => Promise<T | null>;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// ---- Invoke / parallel ----
|
|
235
|
+
|
|
236
|
+
export interface InvokeApi {
|
|
237
|
+
<TIn, TOut>(
|
|
238
|
+
workflow: WorkflowHandle<TIn, TOut>,
|
|
239
|
+
input: TIn,
|
|
240
|
+
opts?: InvokeOptions,
|
|
241
|
+
): Promise<TOut>;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
export interface InvokeOptions {
|
|
245
|
+
idempotencyKey?: string;
|
|
246
|
+
tags?: string[];
|
|
247
|
+
lockToVersion?: string;
|
|
248
|
+
detach?: boolean;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
export interface ParallelApi {
|
|
252
|
+
<T, R>(
|
|
253
|
+
items: readonly T[],
|
|
254
|
+
fn: (item: T, index: number) => Promise<R>,
|
|
255
|
+
opts?: ParallelOptions,
|
|
256
|
+
): Promise<R[]>;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
export interface ParallelOptions {
|
|
260
|
+
concurrency?: number;
|
|
261
|
+
settle?: boolean;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
// ---- Streams ----
|
|
265
|
+
|
|
266
|
+
export interface StreamApi {
|
|
267
|
+
text(streamId: string, source: AsyncIterable<string>): Promise<void>;
|
|
268
|
+
json<T>(streamId: string, source: AsyncIterable<T>): Promise<void>;
|
|
269
|
+
bytes(streamId: string, source: AsyncIterable<Uint8Array>): Promise<void>;
|
|
270
|
+
<T>(streamId: string, fn: () => AsyncGenerator<T>): Promise<void>;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
// ---- Groups (scoped compensation) ----
|
|
274
|
+
|
|
275
|
+
export interface GroupApi {
|
|
276
|
+
<T>(name: string, fn: (scope: GroupScope) => Promise<T>): Promise<T>;
|
|
277
|
+
}
|
|
278
|
+
export interface GroupScope {
|
|
279
|
+
step: StepApi;
|
|
280
|
+
compensate: () => Promise<never>;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
// ---- Metadata ----
|
|
284
|
+
|
|
285
|
+
export type MetadataValue =
|
|
286
|
+
| string
|
|
287
|
+
| number
|
|
288
|
+
| boolean
|
|
289
|
+
| null
|
|
290
|
+
| MetadataValue[]
|
|
291
|
+
| { [key: string]: MetadataValue };
|
|
292
|
+
|
|
293
|
+
export interface MetadataMutatorSubset {
|
|
294
|
+
set(key: string, value: MetadataValue): void;
|
|
295
|
+
increment(key: string, by?: number): void;
|
|
296
|
+
append<T>(key: string, value: T): void;
|
|
297
|
+
remove(key: string): void;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
export interface MetadataApi extends MetadataMutatorSubset {
|
|
301
|
+
flush(): Promise<void>;
|
|
302
|
+
parent?: MetadataMutatorSubset;
|
|
303
|
+
root?: MetadataMutatorSubset;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
export type { RunStatus };
|