@aikirun/workflow 0.14.0 → 0.15.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/README.md +17 -0
- package/dist/index.d.ts +78 -48
- package/dist/index.js +92 -37
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -44,6 +44,22 @@ const handle = await onboardingWorkflowV1.start(aikiClient, {
|
|
|
44
44
|
const result = await handle.waitForStatus("completed");
|
|
45
45
|
```
|
|
46
46
|
|
|
47
|
+
## Scheduling
|
|
48
|
+
|
|
49
|
+
Run workflows on a schedule using cron expressions or intervals:
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
import { schedule } from "@aikirun/workflow";
|
|
53
|
+
|
|
54
|
+
const dailyReport = schedule({
|
|
55
|
+
name: "daily-report",
|
|
56
|
+
type: "cron",
|
|
57
|
+
expression: "0 9 * * *", // Every day at 9 AM
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
await dailyReport.activate(aikiClient, onboardingWorkflowV1, { email: "daily@example.com" });
|
|
61
|
+
```
|
|
62
|
+
|
|
47
63
|
## Features
|
|
48
64
|
|
|
49
65
|
- **Durable Execution** - Workflows survive crashes and restarts
|
|
@@ -53,6 +69,7 @@ const result = await handle.waitForStatus("completed");
|
|
|
53
69
|
- **Child Workflows** - Compose workflows together
|
|
54
70
|
- **Automatic Retries** - Configurable retry strategies
|
|
55
71
|
- **Versioning** - Run multiple versions simultaneously
|
|
72
|
+
- **Scheduling** - Trigger workflows on cron or interval schedules
|
|
56
73
|
|
|
57
74
|
## Documentation
|
|
58
75
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { WorkflowName, WorkflowVersionId } from '@aikirun/types/workflow';
|
|
2
2
|
import { Client, Logger, ApiClient } from '@aikirun/types/client';
|
|
3
3
|
import { INTERNAL } from '@aikirun/types/symbols';
|
|
4
|
-
import { WorkflowRun, TerminalWorkflowRunStatus, WorkflowRunState, WorkflowRunId,
|
|
4
|
+
import { WorkflowRun, TerminalWorkflowRunStatus, WorkflowRunState, WorkflowRunId, WorkflowStartOptions, WorkflowDefinitionOptions } from '@aikirun/types/workflow-run';
|
|
5
5
|
import { StandardSchemaV1 } from '@standard-schema/spec';
|
|
6
6
|
import { DurationObject, Duration } from '@aikirun/types/duration';
|
|
7
7
|
import { SleepResult } from '@aikirun/types/sleep';
|
|
@@ -10,6 +10,7 @@ import { Serializable } from '@aikirun/types/serializable';
|
|
|
10
10
|
import { DistributiveOmit, RequireAtLeastOneProp } from '@aikirun/types/utils';
|
|
11
11
|
import { TaskId } from '@aikirun/types/task';
|
|
12
12
|
import { WorkflowRunStateRequest, WorkflowRunTransitionTaskStateRequestV1 } from '@aikirun/types/workflow-run-api';
|
|
13
|
+
import { OverlapPolicy, ScheduleName, ScheduleId } from '@aikirun/types/schedule';
|
|
13
14
|
|
|
14
15
|
type NonEmptyArray<T> = [T, ...T[]];
|
|
15
16
|
|
|
@@ -30,11 +31,11 @@ type PathFromObjectInternal<T, IncludeArrayKeys extends boolean> = And<[
|
|
|
30
31
|
type ExtractObjectType<T> = T extends object ? T : never;
|
|
31
32
|
type TypeOfValueAtPath<T extends object, Path extends PathFromObject<T>> = Path extends keyof T ? T[Path] : Path extends `${infer First}.${infer Rest}` ? First extends keyof T ? undefined extends T[First] ? Rest extends PathFromObject<ExtractObjectType<T[First]>> ? TypeOfValueAtPath<ExtractObjectType<T[First]>, Rest> | undefined : never : Rest extends PathFromObject<ExtractObjectType<T[First]>> ? TypeOfValueAtPath<ExtractObjectType<T[First]>, Rest> : never : never : never;
|
|
32
33
|
|
|
33
|
-
declare function workflowRunHandle<Input, Output, AppContext,
|
|
34
|
-
declare function workflowRunHandle<Input, Output, AppContext,
|
|
35
|
-
interface WorkflowRunHandle<Input, Output, AppContext,
|
|
34
|
+
declare function workflowRunHandle<Input, Output, AppContext, TEvents extends EventsDefinition>(client: Client<AppContext>, id: WorkflowRunId, eventsDefinition?: TEvents, logger?: Logger): Promise<WorkflowRunHandle<Input, Output, AppContext, TEvents>>;
|
|
35
|
+
declare function workflowRunHandle<Input, Output, AppContext, TEvents extends EventsDefinition>(client: Client<AppContext>, run: WorkflowRun<Input, Output>, eventsDefinition?: TEvents, logger?: Logger): Promise<WorkflowRunHandle<Input, Output, AppContext, TEvents>>;
|
|
36
|
+
interface WorkflowRunHandle<Input, Output, AppContext, TEvents extends EventsDefinition = EventsDefinition> {
|
|
36
37
|
run: Readonly<WorkflowRun<Input, Output>>;
|
|
37
|
-
events: EventSenders<
|
|
38
|
+
events: EventSenders<TEvents>;
|
|
38
39
|
refresh: () => Promise<void>;
|
|
39
40
|
/**
|
|
40
41
|
* Waits for the child workflow run to reach a terminal status by polling.
|
|
@@ -145,16 +146,16 @@ interface EventDefinition<Data> {
|
|
|
145
146
|
schema?: StandardSchemaV1<Data>;
|
|
146
147
|
}
|
|
147
148
|
type EventsDefinition = Record<string, EventDefinition<unknown>>;
|
|
148
|
-
type EventData<
|
|
149
|
-
type EventWaiters<
|
|
150
|
-
[K in keyof
|
|
149
|
+
type EventData<TEvent> = TEvent extends EventDefinition<infer Data> ? Data : never;
|
|
150
|
+
type EventWaiters<TEvents extends EventsDefinition> = {
|
|
151
|
+
[K in keyof TEvents]: EventWaiter<EventData<TEvents[K]>>;
|
|
151
152
|
};
|
|
152
153
|
interface EventWaiter<Data> {
|
|
153
154
|
wait(options?: EventWaitOptions<false>): Promise<EventWaitState<Data, false>>;
|
|
154
155
|
wait(options: EventWaitOptions<true>): Promise<EventWaitState<Data, true>>;
|
|
155
156
|
}
|
|
156
|
-
type EventSenders<
|
|
157
|
-
[K in keyof
|
|
157
|
+
type EventSenders<TEvents extends EventsDefinition> = {
|
|
158
|
+
[K in keyof TEvents]: EventSender<EventData<TEvents[K]>>;
|
|
158
159
|
};
|
|
159
160
|
interface EventSender<Data> {
|
|
160
161
|
with(): EventSenderBuilder<Data>;
|
|
@@ -164,8 +165,8 @@ interface EventSenderBuilder<Data> {
|
|
|
164
165
|
opt<Path extends PathFromObject<EventSendOptions>>(path: Path, value: TypeOfValueAtPath<EventSendOptions, Path>): EventSenderBuilder<Data>;
|
|
165
166
|
send: (...args: Data extends void ? [] : [Data]) => Promise<void>;
|
|
166
167
|
}
|
|
167
|
-
type EventMulticasters<
|
|
168
|
-
[K in keyof
|
|
168
|
+
type EventMulticasters<TEvents extends EventsDefinition> = {
|
|
169
|
+
[K in keyof TEvents]: EventMulticaster<EventData<TEvents[K]>>;
|
|
169
170
|
};
|
|
170
171
|
interface EventMulticaster<Data> {
|
|
171
172
|
with(): EventMulticasterBuilder<Data>;
|
|
@@ -175,26 +176,26 @@ interface EventMulticasterBuilder<Data> {
|
|
|
175
176
|
opt<Path extends PathFromObject<EventSendOptions>>(path: Path, value: TypeOfValueAtPath<EventSendOptions, Path>): EventMulticasterBuilder<Data>;
|
|
176
177
|
send: <AppContext>(client: Client<AppContext>, runId: string | string[], ...args: Data extends void ? [] : [Data]) => Promise<void>;
|
|
177
178
|
}
|
|
178
|
-
declare function createEventWaiters<
|
|
179
|
-
declare function createEventSenders<
|
|
179
|
+
declare function createEventWaiters<TEvents extends EventsDefinition>(handle: WorkflowRunHandle<unknown, unknown, unknown, TEvents>, eventsDefinition: TEvents, logger: Logger): EventWaiters<TEvents>;
|
|
180
|
+
declare function createEventSenders<TEvents extends EventsDefinition>(api: ApiClient, workflowRunId: string, eventsDefinition: TEvents, logger: Logger, onSend: (run: WorkflowRun<unknown, unknown>) => void): EventSenders<TEvents>;
|
|
180
181
|
|
|
181
|
-
interface WorkflowRunContext<Input, AppContext,
|
|
182
|
+
interface WorkflowRunContext<Input, AppContext, TEvents extends EventsDefinition> {
|
|
182
183
|
id: WorkflowRunId;
|
|
183
184
|
name: WorkflowName;
|
|
184
185
|
versionId: WorkflowVersionId;
|
|
185
|
-
options:
|
|
186
|
+
options: WorkflowStartOptions;
|
|
186
187
|
logger: Logger;
|
|
187
188
|
sleep: (name: string, duration: Duration) => Promise<SleepResult>;
|
|
188
|
-
events: EventWaiters<
|
|
189
|
+
events: EventWaiters<TEvents>;
|
|
189
190
|
[INTERNAL]: {
|
|
190
|
-
handle: WorkflowRunHandle<Input, unknown, AppContext,
|
|
191
|
+
handle: WorkflowRunHandle<Input, unknown, AppContext, TEvents>;
|
|
191
192
|
options: {
|
|
192
193
|
spinThresholdMs: number;
|
|
193
194
|
};
|
|
194
195
|
};
|
|
195
196
|
}
|
|
196
197
|
|
|
197
|
-
type ChildWorkflowRunHandle<Input, Output, AppContext,
|
|
198
|
+
type ChildWorkflowRunHandle<Input, Output, AppContext, TEvents extends EventsDefinition = EventsDefinition> = Omit<WorkflowRunHandle<Input, Output, AppContext, TEvents>, "waitForStatus"> & {
|
|
198
199
|
/**
|
|
199
200
|
* Waits for the child workflow run to reach a terminal status.
|
|
200
201
|
*
|
|
@@ -239,47 +240,44 @@ interface ChildWorkflowRunWaitOptions<Timed extends boolean> {
|
|
|
239
240
|
timeout?: Timed extends true ? DurationObject : never;
|
|
240
241
|
}
|
|
241
242
|
|
|
242
|
-
interface WorkflowVersionParams<Input, Output, AppContext,
|
|
243
|
-
handler: (run: Readonly<WorkflowRunContext<Input, AppContext,
|
|
244
|
-
events?:
|
|
245
|
-
opts?:
|
|
243
|
+
interface WorkflowVersionParams<Input, Output, AppContext, TEvents extends EventsDefinition> {
|
|
244
|
+
handler: (run: Readonly<WorkflowRunContext<Input, AppContext, TEvents>>, input: Input, context: AppContext) => Promise<Output>;
|
|
245
|
+
events?: TEvents;
|
|
246
|
+
opts?: WorkflowDefinitionOptions;
|
|
246
247
|
schema?: RequireAtLeastOneProp<{
|
|
247
248
|
input?: StandardSchemaV1<Input>;
|
|
248
249
|
output?: StandardSchemaV1<Output>;
|
|
249
250
|
}>;
|
|
250
251
|
}
|
|
251
|
-
interface WorkflowVersion<Input, Output, AppContext,
|
|
252
|
+
interface WorkflowVersion<Input, Output, AppContext, TEvents extends EventsDefinition = EventsDefinition> {
|
|
252
253
|
name: WorkflowName;
|
|
253
254
|
versionId: WorkflowVersionId;
|
|
254
|
-
events: EventMulticasters<
|
|
255
|
-
with(): WorkflowBuilder<Input, Output, AppContext,
|
|
256
|
-
start: (client: Client<AppContext>, ...args: Input extends void ? [] : [Input]) => Promise<WorkflowRunHandle<Input, Output, AppContext,
|
|
257
|
-
startAsChild: <ParentInput,
|
|
258
|
-
getHandleById: (client: Client<AppContext>, runId: string) => Promise<WorkflowRunHandle<Input, Output, AppContext,
|
|
259
|
-
getHandleByReferenceId: (client: Client<AppContext>, referenceId: string) => Promise<WorkflowRunHandle<Input, Output, AppContext,
|
|
255
|
+
events: EventMulticasters<TEvents>;
|
|
256
|
+
with(): WorkflowBuilder<Input, Output, AppContext, TEvents>;
|
|
257
|
+
start: (client: Client<AppContext>, ...args: Input extends void ? [] : [Input]) => Promise<WorkflowRunHandle<Input, Output, AppContext, TEvents>>;
|
|
258
|
+
startAsChild: <ParentInput, ParentEvents extends EventsDefinition>(parentRun: WorkflowRunContext<ParentInput, AppContext, ParentEvents>, ...args: Input extends void ? [] : [Input]) => Promise<ChildWorkflowRunHandle<Input, Output, AppContext, TEvents>>;
|
|
259
|
+
getHandleById: (client: Client<AppContext>, runId: string) => Promise<WorkflowRunHandle<Input, Output, AppContext, TEvents>>;
|
|
260
|
+
getHandleByReferenceId: (client: Client<AppContext>, referenceId: string) => Promise<WorkflowRunHandle<Input, Output, AppContext, TEvents>>;
|
|
260
261
|
[INTERNAL]: {
|
|
261
|
-
eventsDefinition:
|
|
262
|
-
handler: (run: WorkflowRunContext<Input, AppContext,
|
|
262
|
+
eventsDefinition: TEvents;
|
|
263
|
+
handler: (run: WorkflowRunContext<Input, AppContext, TEvents>, input: Input, context: AppContext) => Promise<void>;
|
|
263
264
|
};
|
|
264
265
|
}
|
|
265
|
-
|
|
266
|
-
opt<Path extends PathFromObject<WorkflowOptions>>(path: Path, value: TypeOfValueAtPath<WorkflowOptions, Path>): WorkflowBuilder<Input, Output, AppContext, TEventsDefinition>;
|
|
267
|
-
start: WorkflowVersion<Input, Output, AppContext, TEventsDefinition>["start"];
|
|
268
|
-
startAsChild: WorkflowVersion<Input, Output, AppContext, TEventsDefinition>["startAsChild"];
|
|
269
|
-
}
|
|
270
|
-
declare class WorkflowVersionImpl<Input, Output, AppContext, TEventsDefinition extends EventsDefinition> implements WorkflowVersion<Input, Output, AppContext, TEventsDefinition> {
|
|
266
|
+
declare class WorkflowVersionImpl<Input, Output, AppContext, TEvents extends EventsDefinition> implements WorkflowVersion<Input, Output, AppContext, TEvents> {
|
|
271
267
|
readonly name: WorkflowName;
|
|
272
268
|
readonly versionId: WorkflowVersionId;
|
|
273
269
|
private readonly params;
|
|
274
|
-
readonly events: EventMulticasters<
|
|
275
|
-
readonly [INTERNAL]: WorkflowVersion<Input, Output, AppContext,
|
|
276
|
-
constructor(name: WorkflowName, versionId: WorkflowVersionId, params: WorkflowVersionParams<Input, Output, AppContext,
|
|
277
|
-
with(): WorkflowBuilder<Input, Output, AppContext,
|
|
278
|
-
start(client: Client<AppContext>, ...args: Input extends void ? [] : [Input]): Promise<WorkflowRunHandle<Input, Output, AppContext,
|
|
279
|
-
|
|
270
|
+
readonly events: EventMulticasters<TEvents>;
|
|
271
|
+
readonly [INTERNAL]: WorkflowVersion<Input, Output, AppContext, TEvents>[typeof INTERNAL];
|
|
272
|
+
constructor(name: WorkflowName, versionId: WorkflowVersionId, params: WorkflowVersionParams<Input, Output, AppContext, TEvents>);
|
|
273
|
+
with(): WorkflowBuilder<Input, Output, AppContext, TEvents>;
|
|
274
|
+
start(client: Client<AppContext>, ...args: Input extends void ? [] : [Input]): Promise<WorkflowRunHandle<Input, Output, AppContext, TEvents>>;
|
|
275
|
+
startWithOpts(client: Client<AppContext>, startOpts: WorkflowStartOptions, ...args: Input extends void ? [] : [Input]): Promise<WorkflowRunHandle<Input, Output, AppContext, TEvents>>;
|
|
276
|
+
startAsChild(parentRun: WorkflowRunContext<unknown, AppContext, EventsDefinition>, ...args: Input extends void ? [] : [Input]): Promise<ChildWorkflowRunHandle<Input, Output, AppContext, TEvents>>;
|
|
277
|
+
startAsChildWithOpts(parentRun: WorkflowRunContext<unknown, AppContext, EventsDefinition>, startOpts: WorkflowStartOptions, ...args: Input extends void ? [] : [Input]): Promise<ChildWorkflowRunHandle<Input, Output, AppContext, TEvents>>;
|
|
280
278
|
private assertUniqueChildRunReferenceId;
|
|
281
|
-
getHandleById(client: Client<AppContext>, runId: string): Promise<WorkflowRunHandle<Input, Output, AppContext,
|
|
282
|
-
getHandleByReferenceId(client: Client<AppContext>, referenceId: string): Promise<WorkflowRunHandle<Input, Output, AppContext,
|
|
279
|
+
getHandleById(client: Client<AppContext>, runId: string): Promise<WorkflowRunHandle<Input, Output, AppContext, TEvents>>;
|
|
280
|
+
getHandleByReferenceId(client: Client<AppContext>, referenceId: string): Promise<WorkflowRunHandle<Input, Output, AppContext, TEvents>>;
|
|
283
281
|
private handler;
|
|
284
282
|
private tryExecuteWorkflow;
|
|
285
283
|
private assertRetryAllowed;
|
|
@@ -287,6 +285,11 @@ declare class WorkflowVersionImpl<Input, Output, AppContext, TEventsDefinition e
|
|
|
287
285
|
private createFailedState;
|
|
288
286
|
private createAwaitingRetryState;
|
|
289
287
|
}
|
|
288
|
+
interface WorkflowBuilder<Input, Output, AppContext, TEvents extends EventsDefinition> {
|
|
289
|
+
opt<Path extends PathFromObject<WorkflowStartOptions>>(path: Path, value: TypeOfValueAtPath<WorkflowStartOptions, Path>): WorkflowBuilder<Input, Output, AppContext, TEvents>;
|
|
290
|
+
start: WorkflowVersion<Input, Output, AppContext, TEvents>["start"];
|
|
291
|
+
startAsChild: WorkflowVersion<Input, Output, AppContext, TEvents>["startAsChild"];
|
|
292
|
+
}
|
|
290
293
|
|
|
291
294
|
declare function workflowRegistry(): WorkflowRegistry;
|
|
292
295
|
type Workflow$1 = WorkflowVersion<unknown, unknown, unknown>;
|
|
@@ -302,6 +305,33 @@ interface WorkflowRegistry {
|
|
|
302
305
|
|
|
303
306
|
declare function createSleeper(handle: WorkflowRunHandle<unknown, unknown, unknown>, logger: Logger): (name: string, duration: Duration) => Promise<SleepResult>;
|
|
304
307
|
|
|
308
|
+
interface CronScheduleParams {
|
|
309
|
+
type: "cron";
|
|
310
|
+
expression: string;
|
|
311
|
+
timezone?: string;
|
|
312
|
+
overlapPolicy?: OverlapPolicy;
|
|
313
|
+
}
|
|
314
|
+
interface IntervalScheduleParams {
|
|
315
|
+
type: "interval";
|
|
316
|
+
every: DurationObject;
|
|
317
|
+
overlapPolicy?: OverlapPolicy;
|
|
318
|
+
}
|
|
319
|
+
type ScheduleParams = CronScheduleParams | IntervalScheduleParams;
|
|
320
|
+
interface ScheduleHandle {
|
|
321
|
+
id: ScheduleId;
|
|
322
|
+
name: ScheduleName;
|
|
323
|
+
pause(): Promise<void>;
|
|
324
|
+
resume(): Promise<void>;
|
|
325
|
+
delete(): Promise<void>;
|
|
326
|
+
}
|
|
327
|
+
type ScheduleDefinition = ScheduleParams & {
|
|
328
|
+
name: ScheduleName;
|
|
329
|
+
activate<Input, Output, AppContext, TEvents extends EventsDefinition>(client: Client<AppContext>, workflow: WorkflowVersion<Input, Output, AppContext, TEvents>, ...args: Input extends void ? [] : [Input]): Promise<ScheduleHandle>;
|
|
330
|
+
};
|
|
331
|
+
declare function schedule(params: {
|
|
332
|
+
name: string;
|
|
333
|
+
} & ScheduleParams): ScheduleDefinition;
|
|
334
|
+
|
|
305
335
|
/**
|
|
306
336
|
* Defines a durable workflow with versioning and multiple task execution.
|
|
307
337
|
*
|
|
@@ -355,11 +385,11 @@ interface WorkflowParams {
|
|
|
355
385
|
}
|
|
356
386
|
interface Workflow {
|
|
357
387
|
name: WorkflowName;
|
|
358
|
-
v: <Input extends Serializable, Output extends Serializable, AppContext = null,
|
|
388
|
+
v: <Input extends Serializable, Output extends Serializable, AppContext = null, TEvents extends EventsDefinition = Record<string, never>>(versionId: string, params: WorkflowVersionParams<Input, Output, AppContext, TEvents>) => WorkflowVersion<Input, Output, AppContext, TEvents>;
|
|
359
389
|
[INTERNAL]: {
|
|
360
390
|
getAllVersions: () => WorkflowVersion<unknown, unknown, unknown>[];
|
|
361
391
|
getVersion: (versionId: WorkflowVersionId) => WorkflowVersion<unknown, unknown, unknown> | undefined;
|
|
362
392
|
};
|
|
363
393
|
}
|
|
364
394
|
|
|
365
|
-
export { type EventMulticaster, type EventMulticasters, type EventSender, type EventSenders, type EventWaiter, type EventWaiters, type Workflow, type WorkflowParams, type WorkflowRegistry, type WorkflowRunContext, type WorkflowRunHandle, type WorkflowRunWaitOptions, type WorkflowVersion, WorkflowVersionImpl, type WorkflowVersionParams, createEventSenders, createEventWaiters, createSleeper, event, workflow, workflowRegistry, workflowRunHandle };
|
|
395
|
+
export { type EventMulticaster, type EventMulticasters, type EventSender, type EventSenders, type EventWaiter, type EventWaiters, type ScheduleDefinition, type ScheduleHandle, type ScheduleParams, type Workflow, type WorkflowParams, type WorkflowRegistry, type WorkflowRunContext, type WorkflowRunHandle, type WorkflowRunWaitOptions, type WorkflowVersion, WorkflowVersionImpl, type WorkflowVersionParams, createEventSenders, createEventWaiters, createSleeper, event, schedule, workflow, workflowRegistry, workflowRunHandle };
|
package/dist/index.js
CHANGED
|
@@ -392,10 +392,9 @@ function createEventSender(api, workflowRunId, eventName, schema, logger, onSend
|
|
|
392
392
|
send: (...args) => createEventSender(api, workflowRunId, eventName, schema, logger, onSend, optsBuilder.build()).send(...args)
|
|
393
393
|
});
|
|
394
394
|
async function send(...args) {
|
|
395
|
-
|
|
396
|
-
let data = dataRaw;
|
|
395
|
+
let data = args[0];
|
|
397
396
|
if (schema) {
|
|
398
|
-
const schemaValidation = schema["~standard"].validate(
|
|
397
|
+
const schemaValidation = schema["~standard"].validate(data);
|
|
399
398
|
const schemaValidationResult = schemaValidation instanceof Promise ? await schemaValidation : schemaValidation;
|
|
400
399
|
if (schemaValidationResult.issues) {
|
|
401
400
|
logger.error("Invalid event data", { "aiki.issues": schemaValidationResult.issues });
|
|
@@ -443,10 +442,9 @@ function createEventMulticaster(workflowName, workflowVersionId, eventName, sche
|
|
|
443
442
|
)
|
|
444
443
|
});
|
|
445
444
|
async function send(client, runId, ...args) {
|
|
446
|
-
|
|
447
|
-
let data = dataRaw;
|
|
445
|
+
let data = args[0];
|
|
448
446
|
if (schema) {
|
|
449
|
-
const schemaValidation = schema["~standard"].validate(
|
|
447
|
+
const schemaValidation = schema["~standard"].validate(data);
|
|
450
448
|
const schemaValidationResult = schemaValidation instanceof Promise ? await schemaValidation : schemaValidation;
|
|
451
449
|
if (schemaValidationResult.issues) {
|
|
452
450
|
client.logger.error("Invalid event data", {
|
|
@@ -737,11 +735,59 @@ function createSleeper(handle, logger) {
|
|
|
737
735
|
};
|
|
738
736
|
}
|
|
739
737
|
|
|
738
|
+
// schedule.ts
|
|
739
|
+
function schedule(params) {
|
|
740
|
+
const { name, ...scheduleParams } = params;
|
|
741
|
+
return {
|
|
742
|
+
name,
|
|
743
|
+
...scheduleParams,
|
|
744
|
+
async activate(client, workflow2, ...args) {
|
|
745
|
+
const input = args[0];
|
|
746
|
+
let scheduleSpec;
|
|
747
|
+
if (scheduleParams.type === "interval") {
|
|
748
|
+
const { every, ...rest } = scheduleParams;
|
|
749
|
+
scheduleSpec = {
|
|
750
|
+
...rest,
|
|
751
|
+
everyMs: toMilliseconds(every)
|
|
752
|
+
};
|
|
753
|
+
} else {
|
|
754
|
+
scheduleSpec = scheduleParams;
|
|
755
|
+
}
|
|
756
|
+
const { schedule: schedule2 } = await client.api.schedule.activateV1({
|
|
757
|
+
name,
|
|
758
|
+
workflowName: workflow2.name,
|
|
759
|
+
workflowVersionId: workflow2.versionId,
|
|
760
|
+
spec: scheduleSpec,
|
|
761
|
+
input
|
|
762
|
+
});
|
|
763
|
+
client.logger.info("Schedule activated", {
|
|
764
|
+
scheduleSpec,
|
|
765
|
+
workflowName: workflow2.name,
|
|
766
|
+
workflowVersionId: workflow2.versionId
|
|
767
|
+
});
|
|
768
|
+
const scheduleId = schedule2.id;
|
|
769
|
+
return {
|
|
770
|
+
id: scheduleId,
|
|
771
|
+
name,
|
|
772
|
+
pause: async () => {
|
|
773
|
+
await client.api.schedule.pauseV1({ id: scheduleId });
|
|
774
|
+
},
|
|
775
|
+
resume: async () => {
|
|
776
|
+
await client.api.schedule.resumeV1({ id: scheduleId });
|
|
777
|
+
},
|
|
778
|
+
delete: async () => {
|
|
779
|
+
await client.api.schedule.deleteV1({ id: scheduleId });
|
|
780
|
+
}
|
|
781
|
+
};
|
|
782
|
+
}
|
|
783
|
+
};
|
|
784
|
+
}
|
|
785
|
+
|
|
740
786
|
// workflow.ts
|
|
741
787
|
import { INTERNAL as INTERNAL6 } from "@aikirun/types/symbols";
|
|
742
788
|
|
|
743
|
-
// ../../lib/
|
|
744
|
-
function
|
|
789
|
+
// ../../lib/address/index.ts
|
|
790
|
+
function getWorkflowRunAddress(name, versionId, referenceId) {
|
|
745
791
|
return `${name}/${versionId}/${referenceId}`;
|
|
746
792
|
}
|
|
747
793
|
|
|
@@ -780,7 +826,7 @@ function createStatusWaiter(handle, parentRun, logger) {
|
|
|
780
826
|
let nextWaitIndex = 0;
|
|
781
827
|
async function waitForStatus(expectedStatus, options) {
|
|
782
828
|
const parentRunHandle = parentRun[INTERNAL4].handle;
|
|
783
|
-
const waitResults = parentRunHandle.run.childWorkflowRuns[handle.run.
|
|
829
|
+
const waitResults = parentRunHandle.run.childWorkflowRuns[handle.run.address]?.statusWaitResults ?? [];
|
|
784
830
|
const waitResult = waitResults[nextWaitIndex];
|
|
785
831
|
if (waitResult) {
|
|
786
832
|
nextWaitIndex++;
|
|
@@ -849,7 +895,7 @@ function createStatusWaiter(handle, parentRun, logger) {
|
|
|
849
895
|
}
|
|
850
896
|
|
|
851
897
|
// workflow-version.ts
|
|
852
|
-
var WorkflowVersionImpl = class
|
|
898
|
+
var WorkflowVersionImpl = class {
|
|
853
899
|
constructor(name, versionId, params) {
|
|
854
900
|
this.name = name;
|
|
855
901
|
this.versionId = versionId;
|
|
@@ -864,28 +910,18 @@ var WorkflowVersionImpl = class _WorkflowVersionImpl {
|
|
|
864
910
|
events;
|
|
865
911
|
[INTERNAL5];
|
|
866
912
|
with() {
|
|
867
|
-
const
|
|
868
|
-
const
|
|
869
|
-
|
|
870
|
-
opt: (path, value) => createBuilder(optsBuilder.with(path, value)),
|
|
871
|
-
start: (client, ...args) => new _WorkflowVersionImpl(this.name, this.versionId, {
|
|
872
|
-
...this.params,
|
|
873
|
-
opts: optsBuilder.build()
|
|
874
|
-
}).start(client, ...args),
|
|
875
|
-
startAsChild: (parentRun, ...args) => new _WorkflowVersionImpl(this.name, this.versionId, {
|
|
876
|
-
...this.params,
|
|
877
|
-
opts: optsBuilder.build()
|
|
878
|
-
}).startAsChild(parentRun, ...args)
|
|
879
|
-
};
|
|
880
|
-
};
|
|
881
|
-
return createBuilder(optsOverrider());
|
|
913
|
+
const startOpts = this.params.opts ?? {};
|
|
914
|
+
const startOptsOverrider = objectOverrider(startOpts);
|
|
915
|
+
return new WorkflowBuilderImpl(this, startOptsOverrider());
|
|
882
916
|
}
|
|
883
917
|
async start(client, ...args) {
|
|
884
|
-
|
|
885
|
-
|
|
918
|
+
return this.startWithOpts(client, this.params.opts ?? {}, ...args);
|
|
919
|
+
}
|
|
920
|
+
async startWithOpts(client, startOpts, ...args) {
|
|
921
|
+
let input = args[0];
|
|
886
922
|
const schema = this.params.schema?.input;
|
|
887
923
|
if (schema) {
|
|
888
|
-
const schemaValidation = schema["~standard"].validate(
|
|
924
|
+
const schemaValidation = schema["~standard"].validate(input);
|
|
889
925
|
const schemaValidationResult = schemaValidation instanceof Promise ? await schemaValidation : schemaValidation;
|
|
890
926
|
if (schemaValidationResult.issues) {
|
|
891
927
|
client.logger.error("Invalid workflow data", { "aiki.issues": schemaValidationResult.issues });
|
|
@@ -897,7 +933,7 @@ var WorkflowVersionImpl = class _WorkflowVersionImpl {
|
|
|
897
933
|
name: this.name,
|
|
898
934
|
versionId: this.versionId,
|
|
899
935
|
input,
|
|
900
|
-
options:
|
|
936
|
+
options: startOpts
|
|
901
937
|
});
|
|
902
938
|
client.logger.info("Created workflow", {
|
|
903
939
|
"aiki.workflowName": this.name,
|
|
@@ -907,15 +943,18 @@ var WorkflowVersionImpl = class _WorkflowVersionImpl {
|
|
|
907
943
|
return workflowRunHandle(client, run, this[INTERNAL5].eventsDefinition);
|
|
908
944
|
}
|
|
909
945
|
async startAsChild(parentRun, ...args) {
|
|
946
|
+
return this.startAsChildWithOpts(parentRun, this.params.opts ?? {}, ...args);
|
|
947
|
+
}
|
|
948
|
+
async startAsChildWithOpts(parentRun, startOpts, ...args) {
|
|
910
949
|
const parentRunHandle = parentRun[INTERNAL5].handle;
|
|
911
950
|
parentRunHandle[INTERNAL5].assertExecutionAllowed();
|
|
912
951
|
const { client } = parentRunHandle[INTERNAL5];
|
|
913
|
-
const inputRaw =
|
|
952
|
+
const inputRaw = args[0];
|
|
914
953
|
const input = await this.parse(parentRunHandle, this.params.schema?.input, inputRaw, parentRun.logger);
|
|
915
954
|
const inputHash = await hashInput(input);
|
|
916
|
-
const reference =
|
|
917
|
-
const
|
|
918
|
-
const existingRunInfo = parentRunHandle.run.childWorkflowRuns[
|
|
955
|
+
const reference = startOpts.reference;
|
|
956
|
+
const address = getWorkflowRunAddress(this.name, this.versionId, reference?.id ?? inputHash);
|
|
957
|
+
const existingRunInfo = parentRunHandle.run.childWorkflowRuns[address];
|
|
919
958
|
if (existingRunInfo) {
|
|
920
959
|
await this.assertUniqueChildRunReferenceId(
|
|
921
960
|
parentRunHandle,
|
|
@@ -946,9 +985,9 @@ var WorkflowVersionImpl = class _WorkflowVersionImpl {
|
|
|
946
985
|
versionId: this.versionId,
|
|
947
986
|
input,
|
|
948
987
|
parentWorkflowRunId: parentRun.id,
|
|
949
|
-
options:
|
|
988
|
+
options: startOpts
|
|
950
989
|
});
|
|
951
|
-
parentRunHandle.run.childWorkflowRuns[
|
|
990
|
+
parentRunHandle.run.childWorkflowRuns[address] = {
|
|
952
991
|
id: newRun.id,
|
|
953
992
|
name: newRun.name,
|
|
954
993
|
versionId: newRun.versionId,
|
|
@@ -971,8 +1010,8 @@ var WorkflowVersionImpl = class _WorkflowVersionImpl {
|
|
|
971
1010
|
}
|
|
972
1011
|
async assertUniqueChildRunReferenceId(parentRunHandle, existingRunInfo, inputHash, reference, logger) {
|
|
973
1012
|
if (existingRunInfo.inputHash !== inputHash && reference) {
|
|
974
|
-
const
|
|
975
|
-
if (
|
|
1013
|
+
const conflictPolicy = reference.conflictPolicy ?? "error";
|
|
1014
|
+
if (conflictPolicy !== "error") {
|
|
976
1015
|
return;
|
|
977
1016
|
}
|
|
978
1017
|
logger.error("Reference ID already used by another child workflow", {
|
|
@@ -1123,6 +1162,21 @@ var WorkflowVersionImpl = class _WorkflowVersionImpl {
|
|
|
1123
1162
|
};
|
|
1124
1163
|
}
|
|
1125
1164
|
};
|
|
1165
|
+
var WorkflowBuilderImpl = class _WorkflowBuilderImpl {
|
|
1166
|
+
constructor(workflow2, startOptsBuilder) {
|
|
1167
|
+
this.workflow = workflow2;
|
|
1168
|
+
this.startOptsBuilder = startOptsBuilder;
|
|
1169
|
+
}
|
|
1170
|
+
opt(path, value) {
|
|
1171
|
+
return new _WorkflowBuilderImpl(this.workflow, this.startOptsBuilder.with(path, value));
|
|
1172
|
+
}
|
|
1173
|
+
start(client, ...args) {
|
|
1174
|
+
return this.workflow.startWithOpts(client, this.startOptsBuilder.build(), ...args);
|
|
1175
|
+
}
|
|
1176
|
+
startAsChild(parentRun, ...args) {
|
|
1177
|
+
return this.workflow.startAsChildWithOpts(parentRun, this.startOptsBuilder.build(), ...args);
|
|
1178
|
+
}
|
|
1179
|
+
};
|
|
1126
1180
|
|
|
1127
1181
|
// workflow.ts
|
|
1128
1182
|
function workflow(params) {
|
|
@@ -1163,6 +1217,7 @@ export {
|
|
|
1163
1217
|
createEventWaiters,
|
|
1164
1218
|
createSleeper,
|
|
1165
1219
|
event,
|
|
1220
|
+
schedule,
|
|
1166
1221
|
workflow,
|
|
1167
1222
|
workflowRegistry,
|
|
1168
1223
|
workflowRunHandle
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aikirun/workflow",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.15.0",
|
|
4
4
|
"description": "Workflow SDK for Aiki - define durable workflows with tasks, sleeps, waits, and event handling",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"build": "tsup"
|
|
19
19
|
},
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"@aikirun/types": "0.
|
|
21
|
+
"@aikirun/types": "0.15.0",
|
|
22
22
|
"@standard-schema/spec": "^1.1.0"
|
|
23
23
|
},
|
|
24
24
|
"publishConfig": {
|