@aikirun/workflow 0.17.0 → 0.19.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 +1 -0
- package/dist/index.d.ts +24 -12
- package/dist/index.js +240 -146
- package/package.json +2 -2
package/README.md
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
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, WorkflowStartOptions, WorkflowDefinitionOptions } from '@aikirun/types/workflow-run';
|
|
4
|
+
import { WorkflowRun, TerminalWorkflowRunStatus, WorkflowRunState, WorkflowRunId, WorkflowRunAddress, ChildWorkflowRunInfo, 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';
|
|
8
8
|
import { EventSendOptions, EventWaitOptions, EventWaitResult } from '@aikirun/types/event';
|
|
9
9
|
import { Serializable } from '@aikirun/types/serializable';
|
|
10
10
|
import { DistributiveOmit, RequireAtLeastOneProp } from '@aikirun/types/utils';
|
|
11
|
-
import {
|
|
11
|
+
import { TaskInfo, TaskAddress } from '@aikirun/types/task';
|
|
12
12
|
import { WorkflowRunStateRequest, WorkflowRunTransitionTaskStateRequestV1 } from '@aikirun/types/workflow-run-api';
|
|
13
13
|
import { ScheduleOverlapPolicy, ScheduleActivateOptions, ScheduleId } from '@aikirun/types/schedule';
|
|
14
14
|
|
|
@@ -19,10 +19,7 @@ type IsSubtype<SubT, SuperT> = SubT extends SuperT ? true : false;
|
|
|
19
19
|
type And<T extends NonEmptyArray<boolean>> = T extends [infer First, ...infer Rest] ? false extends First ? false : Rest extends NonEmptyArray<boolean> ? And<Rest> : true : never;
|
|
20
20
|
type Or<T extends NonEmptyArray<boolean>> = T extends [infer First, ...infer Rest] ? true extends First ? true : Rest extends NonEmptyArray<boolean> ? Or<Rest> : false : never;
|
|
21
21
|
type PathFromObject<T, IncludeArrayKeys extends boolean = false> = T extends T ? PathFromObjectInternal<T, IncludeArrayKeys> : never;
|
|
22
|
-
type PathFromObjectInternal<T, IncludeArrayKeys extends boolean> = And<[
|
|
23
|
-
IsSubtype<T, object>,
|
|
24
|
-
Or<[IncludeArrayKeys, NonArrayObject<T> extends never ? false : true]>
|
|
25
|
-
]> extends true ? {
|
|
22
|
+
type PathFromObjectInternal<T, IncludeArrayKeys extends boolean> = And<[IsSubtype<T, object>, Or<[IncludeArrayKeys, NonArrayObject<T> extends never ? false : true]>]> extends true ? {
|
|
26
23
|
[K in Exclude<keyof T, symbol>]-?: And<[
|
|
27
24
|
IsSubtype<NonNullable<T[K]>, object>,
|
|
28
25
|
Or<[IncludeArrayKeys, NonArrayObject<NonNullable<T[K]>> extends never ? false : true]>
|
|
@@ -93,9 +90,7 @@ interface WorkflowRunHandle<Input, Output, AppContext, TEvents extends EventsDef
|
|
|
93
90
|
[INTERNAL]: {
|
|
94
91
|
client: Client<AppContext>;
|
|
95
92
|
transitionState: (state: WorkflowRunStateRequest) => Promise<void>;
|
|
96
|
-
transitionTaskState: (request: DistributiveOmit<WorkflowRunTransitionTaskStateRequestV1, "id" | "
|
|
97
|
-
taskId: TaskId;
|
|
98
|
-
}>;
|
|
93
|
+
transitionTaskState: (request: DistributiveOmit<WorkflowRunTransitionTaskStateRequestV1, "id" | "expectedWorkflowRunRevision">) => Promise<TaskInfo>;
|
|
99
94
|
assertExecutionAllowed: () => void;
|
|
100
95
|
};
|
|
101
96
|
}
|
|
@@ -171,13 +166,29 @@ type EventMulticasters<TEvents extends EventsDefinition> = {
|
|
|
171
166
|
interface EventMulticaster<Data> {
|
|
172
167
|
with(): EventMulticasterBuilder<Data>;
|
|
173
168
|
send: <AppContext>(client: Client<AppContext>, runId: string | string[], ...args: Data extends void ? [] : [Data]) => Promise<void>;
|
|
169
|
+
sendByReferenceId: <AppContext>(client: Client<AppContext>, referenceId: string | string[], ...args: Data extends void ? [] : [Data]) => Promise<void>;
|
|
174
170
|
}
|
|
175
171
|
interface EventMulticasterBuilder<Data> {
|
|
176
172
|
opt<Path extends PathFromObject<EventSendOptions>>(path: Path, value: TypeOfValueAtPath<EventSendOptions, Path>): EventMulticasterBuilder<Data>;
|
|
177
173
|
send: <AppContext>(client: Client<AppContext>, runId: string | string[], ...args: Data extends void ? [] : [Data]) => Promise<void>;
|
|
174
|
+
sendByReferenceId: <AppContext>(client: Client<AppContext>, referenceId: string | string[], ...args: Data extends void ? [] : [Data]) => Promise<void>;
|
|
178
175
|
}
|
|
179
176
|
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
|
|
177
|
+
declare function createEventSenders<TEvents extends EventsDefinition>(api: ApiClient, workflowRunId: string, eventsDefinition: TEvents, logger: Logger): EventSenders<TEvents>;
|
|
178
|
+
|
|
179
|
+
/** biome-ignore-all lint/style/noNonNullAssertion: Manifest boundaries are tracked, hence, we never exceed array boundaries */
|
|
180
|
+
|
|
181
|
+
interface ReplayManifest {
|
|
182
|
+
consumeNextTask(address: TaskAddress): TaskInfo | undefined;
|
|
183
|
+
consumeNextChildWorkflowRun(address: WorkflowRunAddress): ChildWorkflowRunInfo | undefined;
|
|
184
|
+
hasUnconsumedEntries(): boolean;
|
|
185
|
+
getUnconsumedEntries(): UnconsumedManifestEntries;
|
|
186
|
+
}
|
|
187
|
+
interface UnconsumedManifestEntries {
|
|
188
|
+
taskIds: string[];
|
|
189
|
+
childWorkflowRunIds: string[];
|
|
190
|
+
}
|
|
191
|
+
declare function createReplayManifest(run: WorkflowRun): ReplayManifest;
|
|
181
192
|
|
|
182
193
|
interface WorkflowRunContext<Input, AppContext, TEvents extends EventsDefinition> {
|
|
183
194
|
id: WorkflowRunId;
|
|
@@ -189,6 +200,7 @@ interface WorkflowRunContext<Input, AppContext, TEvents extends EventsDefinition
|
|
|
189
200
|
events: EventWaiters<TEvents>;
|
|
190
201
|
[INTERNAL]: {
|
|
191
202
|
handle: WorkflowRunHandle<Input, unknown, AppContext, TEvents>;
|
|
203
|
+
replayManifest: ReplayManifest;
|
|
192
204
|
options: {
|
|
193
205
|
spinThresholdMs: number;
|
|
194
206
|
};
|
|
@@ -275,7 +287,7 @@ declare class WorkflowVersionImpl<Input, Output, AppContext, TEvents extends Eve
|
|
|
275
287
|
startWithOpts(client: Client<AppContext>, startOpts: WorkflowStartOptions, ...args: Input extends void ? [] : [Input]): Promise<WorkflowRunHandle<Input, Output, AppContext, TEvents>>;
|
|
276
288
|
startAsChild(parentRun: WorkflowRunContext<unknown, AppContext, EventsDefinition>, ...args: Input extends void ? [] : [Input]): Promise<ChildWorkflowRunHandle<Input, Output, AppContext, TEvents>>;
|
|
277
289
|
startAsChildWithOpts(parentRun: WorkflowRunContext<unknown, AppContext, EventsDefinition>, startOpts: WorkflowStartOptions, ...args: Input extends void ? [] : [Input]): Promise<ChildWorkflowRunHandle<Input, Output, AppContext, TEvents>>;
|
|
278
|
-
private
|
|
290
|
+
private throwNonDeterminismError;
|
|
279
291
|
getHandleById(client: Client<AppContext>, runId: string): Promise<WorkflowRunHandle<Input, Output, AppContext, TEvents>>;
|
|
280
292
|
getHandleByReferenceId(client: Client<AppContext>, referenceId: string): Promise<WorkflowRunHandle<Input, Output, AppContext, TEvents>>;
|
|
281
293
|
private handler;
|
|
@@ -393,4 +405,4 @@ interface Workflow {
|
|
|
393
405
|
};
|
|
394
406
|
}
|
|
395
407
|
|
|
396
|
-
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 };
|
|
408
|
+
export { type EventDefinition, type EventMulticaster, type EventMulticasters, type EventSender, type EventSenders, type EventWaiter, type EventWaiters, type ReplayManifest, 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, createReplayManifest, createSleeper, event, schedule, workflow, workflowRegistry, workflowRunHandle };
|
package/dist/index.js
CHANGED
|
@@ -11,7 +11,7 @@ var WorkflowRegistryImpl = class {
|
|
|
11
11
|
return this;
|
|
12
12
|
}
|
|
13
13
|
if (workflows.has(workflow2.versionId)) {
|
|
14
|
-
throw new Error(`Workflow "${workflow2.name}
|
|
14
|
+
throw new Error(`Workflow "${workflow2.name}:${workflow2.versionId}" is already registered`);
|
|
15
15
|
}
|
|
16
16
|
workflows.set(workflow2.versionId, workflow2);
|
|
17
17
|
return this;
|
|
@@ -55,7 +55,7 @@ var WorkflowRegistryImpl = class {
|
|
|
55
55
|
|
|
56
56
|
// ../../lib/array/utils.ts
|
|
57
57
|
function isNonEmptyArray(value) {
|
|
58
|
-
return value.length > 0;
|
|
58
|
+
return value !== void 0 && value.length > 0;
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
// ../../lib/async/delay.ts
|
|
@@ -320,20 +320,20 @@ function createEventWaiters(handle, eventsDefinition, logger) {
|
|
|
320
320
|
return waiters;
|
|
321
321
|
}
|
|
322
322
|
function createEventWaiter(handle, eventName, schema, logger) {
|
|
323
|
-
let
|
|
323
|
+
let nextIndex = 0;
|
|
324
324
|
async function wait(options) {
|
|
325
325
|
await handle.refresh();
|
|
326
326
|
const eventWaits = handle.run.eventWaitQueues[eventName]?.eventWaits ?? [];
|
|
327
|
-
const
|
|
328
|
-
if (
|
|
329
|
-
|
|
330
|
-
if (
|
|
327
|
+
const existingEventWait = eventWaits[nextIndex];
|
|
328
|
+
if (existingEventWait) {
|
|
329
|
+
nextIndex++;
|
|
330
|
+
if (existingEventWait.status === "timeout") {
|
|
331
331
|
logger.debug("Timed out waiting for event");
|
|
332
332
|
return { timeout: true };
|
|
333
333
|
}
|
|
334
|
-
let data =
|
|
334
|
+
let data = existingEventWait.data;
|
|
335
335
|
if (schema) {
|
|
336
|
-
const schemaValidation = schema["~standard"].validate(
|
|
336
|
+
const schemaValidation = schema["~standard"].validate(existingEventWait.data);
|
|
337
337
|
const schemaValidationResult = schemaValidation instanceof Promise ? await schemaValidation : schemaValidation;
|
|
338
338
|
if (!schemaValidationResult.issues) {
|
|
339
339
|
data = schemaValidationResult.value;
|
|
@@ -373,7 +373,7 @@ function createEventWaiter(handle, eventName, schema, logger) {
|
|
|
373
373
|
}
|
|
374
374
|
return { wait };
|
|
375
375
|
}
|
|
376
|
-
function createEventSenders(api, workflowRunId, eventsDefinition, logger
|
|
376
|
+
function createEventSenders(api, workflowRunId, eventsDefinition, logger) {
|
|
377
377
|
const senders = {};
|
|
378
378
|
for (const [eventName, eventDefinition] of Object.entries(eventsDefinition)) {
|
|
379
379
|
const sender = createEventSender(
|
|
@@ -381,18 +381,17 @@ function createEventSenders(api, workflowRunId, eventsDefinition, logger, onSend
|
|
|
381
381
|
workflowRunId,
|
|
382
382
|
eventName,
|
|
383
383
|
eventDefinition.schema,
|
|
384
|
-
logger.child({ "aiki.eventName": eventName })
|
|
385
|
-
onSend
|
|
384
|
+
logger.child({ "aiki.eventName": eventName })
|
|
386
385
|
);
|
|
387
386
|
senders[eventName] = sender;
|
|
388
387
|
}
|
|
389
388
|
return senders;
|
|
390
389
|
}
|
|
391
|
-
function createEventSender(api, workflowRunId, eventName, schema, logger,
|
|
390
|
+
function createEventSender(api, workflowRunId, eventName, schema, logger, options) {
|
|
392
391
|
const optsOverrider = objectOverrider(options ?? {});
|
|
393
392
|
const createBuilder = (optsBuilder) => ({
|
|
394
393
|
opt: (path, value) => createBuilder(optsBuilder.with(path, value)),
|
|
395
|
-
send: (...args) => createEventSender(api, workflowRunId, eventName, schema, logger,
|
|
394
|
+
send: (...args) => createEventSender(api, workflowRunId, eventName, schema, logger, optsBuilder.build()).send(...args)
|
|
396
395
|
});
|
|
397
396
|
async function send(...args) {
|
|
398
397
|
let data = args[0];
|
|
@@ -405,13 +404,12 @@ function createEventSender(api, workflowRunId, eventName, schema, logger, onSend
|
|
|
405
404
|
}
|
|
406
405
|
data = schemaValidationResult.value;
|
|
407
406
|
}
|
|
408
|
-
|
|
407
|
+
await api.workflowRun.sendEventV1({
|
|
409
408
|
id: workflowRunId,
|
|
410
409
|
eventName,
|
|
411
410
|
data,
|
|
412
411
|
options
|
|
413
412
|
});
|
|
414
|
-
onSend(run);
|
|
415
413
|
logger.info("Sent event to workflow", {
|
|
416
414
|
...options?.reference ? { "aiki.referenceId": options.reference.id } : {}
|
|
417
415
|
});
|
|
@@ -442,6 +440,11 @@ function createEventMulticaster(workflowName, workflowVersionId, eventName, sche
|
|
|
442
440
|
client,
|
|
443
441
|
runId,
|
|
444
442
|
...args
|
|
443
|
+
),
|
|
444
|
+
sendByReferenceId: (client, referenceId, ...args) => createEventMulticaster(workflowName, workflowVersionId, eventName, schema, optsBuilder.build()).sendByReferenceId(
|
|
445
|
+
client,
|
|
446
|
+
referenceId,
|
|
447
|
+
...args
|
|
445
448
|
)
|
|
446
449
|
});
|
|
447
450
|
async function send(client, runId, ...args) {
|
|
@@ -475,12 +478,51 @@ function createEventMulticaster(workflowName, workflowVersionId, eventName, sche
|
|
|
475
478
|
"aiki.workflowVersionId": workflowVersionId,
|
|
476
479
|
"aiki.workflowRunIds": runIds,
|
|
477
480
|
"aiki.eventName": eventName,
|
|
478
|
-
...options?.reference ? { "aiki.
|
|
481
|
+
...options?.reference ? { "aiki.eventReferenceId": options.reference.id } : {}
|
|
482
|
+
});
|
|
483
|
+
}
|
|
484
|
+
async function sendByReferenceId(client, referenceId, ...args) {
|
|
485
|
+
let data = args[0];
|
|
486
|
+
if (schema) {
|
|
487
|
+
const schemaValidation = schema["~standard"].validate(data);
|
|
488
|
+
const schemaValidationResult = schemaValidation instanceof Promise ? await schemaValidation : schemaValidation;
|
|
489
|
+
if (schemaValidationResult.issues) {
|
|
490
|
+
client.logger.error("Invalid event data", {
|
|
491
|
+
"aiki.workflowName": workflowName,
|
|
492
|
+
"aiki.workflowVersionId": workflowVersionId,
|
|
493
|
+
"aiki.eventName": eventName,
|
|
494
|
+
"aiki.issues": schemaValidationResult.issues
|
|
495
|
+
});
|
|
496
|
+
throw new SchemaValidationError("Invalid event data", schemaValidationResult.issues);
|
|
497
|
+
}
|
|
498
|
+
data = schemaValidationResult.value;
|
|
499
|
+
}
|
|
500
|
+
const referenceIds = Array.isArray(referenceId) ? referenceId : [referenceId];
|
|
501
|
+
if (!isNonEmptyArray(referenceIds)) {
|
|
502
|
+
return;
|
|
503
|
+
}
|
|
504
|
+
await client.api.workflowRun.multicastEventByReferenceV1({
|
|
505
|
+
references: referenceIds.map((referenceId2) => ({
|
|
506
|
+
name: workflowName,
|
|
507
|
+
versionId: workflowVersionId,
|
|
508
|
+
referenceId: referenceId2
|
|
509
|
+
})),
|
|
510
|
+
eventName,
|
|
511
|
+
data,
|
|
512
|
+
options
|
|
513
|
+
});
|
|
514
|
+
client.logger.info("Multicasted event by reference", {
|
|
515
|
+
"aiki.workflowName": workflowName,
|
|
516
|
+
"aiki.workflowVersionId": workflowVersionId,
|
|
517
|
+
"aiki.referenceIds": referenceIds,
|
|
518
|
+
"aiki.eventName": eventName,
|
|
519
|
+
...options?.reference ? { "aiki.eventReferenceId": options.reference.id } : {}
|
|
479
520
|
});
|
|
480
521
|
}
|
|
481
522
|
return {
|
|
482
523
|
with: () => createBuilder(optsOverrider()),
|
|
483
|
-
send
|
|
524
|
+
send,
|
|
525
|
+
sendByReferenceId
|
|
484
526
|
};
|
|
485
527
|
}
|
|
486
528
|
|
|
@@ -509,9 +551,7 @@ var WorkflowRunHandleImpl = class {
|
|
|
509
551
|
this._run = _run;
|
|
510
552
|
this.logger = logger;
|
|
511
553
|
this.api = client.api;
|
|
512
|
-
this.events = createEventSenders(client.api, this._run.id, eventsDefinition, this.logger
|
|
513
|
-
this._run = run;
|
|
514
|
-
});
|
|
554
|
+
this.events = createEventSenders(client.api, this._run.id, eventsDefinition, this.logger);
|
|
515
555
|
this[INTERNAL2] = {
|
|
516
556
|
client,
|
|
517
557
|
transitionState: this.transitionState.bind(this),
|
|
@@ -607,24 +647,26 @@ var WorkflowRunHandleImpl = class {
|
|
|
607
647
|
}
|
|
608
648
|
async transitionState(targetState) {
|
|
609
649
|
try {
|
|
650
|
+
let response;
|
|
610
651
|
if (targetState.status === "scheduled" && (targetState.reason === "new" || targetState.reason === "resume" || targetState.reason === "awake_early") || targetState.status === "paused" || targetState.status === "cancelled") {
|
|
611
|
-
|
|
652
|
+
response = await this.api.workflowRun.transitionStateV1({
|
|
612
653
|
type: "pessimistic",
|
|
613
654
|
id: this.run.id,
|
|
614
655
|
state: targetState
|
|
615
656
|
});
|
|
616
|
-
|
|
617
|
-
|
|
657
|
+
} else {
|
|
658
|
+
response = await this.api.workflowRun.transitionStateV1({
|
|
659
|
+
type: "optimistic",
|
|
660
|
+
id: this.run.id,
|
|
661
|
+
state: targetState,
|
|
662
|
+
expectedRevision: this.run.revision
|
|
663
|
+
});
|
|
618
664
|
}
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
state: targetState,
|
|
623
|
-
expectedRevision: this.run.revision
|
|
624
|
-
});
|
|
625
|
-
this._run = run;
|
|
665
|
+
this._run.revision = response.revision;
|
|
666
|
+
this._run.state = response.state;
|
|
667
|
+
this._run.attempts = response.attempts;
|
|
626
668
|
} catch (error) {
|
|
627
|
-
if (
|
|
669
|
+
if (isWorkflowRunRevisionConflictError(error)) {
|
|
628
670
|
throw new WorkflowRunRevisionConflictError2(this.run.id);
|
|
629
671
|
}
|
|
630
672
|
throw error;
|
|
@@ -632,15 +674,14 @@ var WorkflowRunHandleImpl = class {
|
|
|
632
674
|
}
|
|
633
675
|
async transitionTaskState(request) {
|
|
634
676
|
try {
|
|
635
|
-
const {
|
|
677
|
+
const { taskInfo } = await this.api.workflowRun.transitionTaskStateV1({
|
|
636
678
|
...request,
|
|
637
679
|
id: this.run.id,
|
|
638
|
-
|
|
680
|
+
expectedWorkflowRunRevision: this.run.revision
|
|
639
681
|
});
|
|
640
|
-
|
|
641
|
-
return { taskId };
|
|
682
|
+
return taskInfo;
|
|
642
683
|
} catch (error) {
|
|
643
|
-
if (
|
|
684
|
+
if (isWorkflowRunRevisionConflictError(error)) {
|
|
644
685
|
throw new WorkflowRunRevisionConflictError2(this.run.id);
|
|
645
686
|
}
|
|
646
687
|
throw error;
|
|
@@ -653,8 +694,73 @@ var WorkflowRunHandleImpl = class {
|
|
|
653
694
|
}
|
|
654
695
|
}
|
|
655
696
|
};
|
|
656
|
-
function
|
|
657
|
-
return error != null && typeof error === "object" && "code" in error && error.code === "
|
|
697
|
+
function isWorkflowRunRevisionConflictError(error) {
|
|
698
|
+
return error != null && typeof error === "object" && "code" in error && error.code === "WORKFLOW_RUN_REVISION_CONFLICT";
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
// run/replay-manifest.ts
|
|
702
|
+
function createReplayManifest(run) {
|
|
703
|
+
const { taskQueues, childWorkflowRunQueues } = run;
|
|
704
|
+
let totalEntries = 0;
|
|
705
|
+
const taskCountByAddress = {};
|
|
706
|
+
const childWorkflowRunCountByAddress = {};
|
|
707
|
+
for (const [address, queue] of Object.entries(taskQueues)) {
|
|
708
|
+
taskCountByAddress[address] = queue.tasks.length;
|
|
709
|
+
totalEntries += queue.tasks.length;
|
|
710
|
+
}
|
|
711
|
+
for (const [address, queue] of Object.entries(childWorkflowRunQueues)) {
|
|
712
|
+
childWorkflowRunCountByAddress[address] = queue.childWorkflowRuns.length;
|
|
713
|
+
totalEntries += queue.childWorkflowRuns.length;
|
|
714
|
+
}
|
|
715
|
+
const nextTaskIndexByAddress = {};
|
|
716
|
+
const nextChildWorkflowRunIndexByAddress = {};
|
|
717
|
+
let consumedEntries = 0;
|
|
718
|
+
return {
|
|
719
|
+
consumeNextTask(address) {
|
|
720
|
+
const taskCount = taskCountByAddress[address] ?? 0;
|
|
721
|
+
const nextIndex = nextTaskIndexByAddress[address] ?? 0;
|
|
722
|
+
if (nextIndex >= taskCount) {
|
|
723
|
+
return void 0;
|
|
724
|
+
}
|
|
725
|
+
const task = taskQueues[address].tasks[nextIndex];
|
|
726
|
+
nextTaskIndexByAddress[address] = nextIndex + 1;
|
|
727
|
+
consumedEntries++;
|
|
728
|
+
return task;
|
|
729
|
+
},
|
|
730
|
+
consumeNextChildWorkflowRun(address) {
|
|
731
|
+
const childWorkflowRunCount = childWorkflowRunCountByAddress[address] ?? 0;
|
|
732
|
+
const nextIndex = nextChildWorkflowRunIndexByAddress[address] ?? 0;
|
|
733
|
+
if (nextIndex >= childWorkflowRunCount) {
|
|
734
|
+
return void 0;
|
|
735
|
+
}
|
|
736
|
+
const childWorkflowRun = childWorkflowRunQueues[address].childWorkflowRuns[nextIndex];
|
|
737
|
+
nextChildWorkflowRunIndexByAddress[address] = nextIndex + 1;
|
|
738
|
+
consumedEntries++;
|
|
739
|
+
return childWorkflowRun;
|
|
740
|
+
},
|
|
741
|
+
hasUnconsumedEntries() {
|
|
742
|
+
return consumedEntries < totalEntries;
|
|
743
|
+
},
|
|
744
|
+
getUnconsumedEntries() {
|
|
745
|
+
const taskIds = [];
|
|
746
|
+
const childWorkflowRunIds = [];
|
|
747
|
+
for (const [address, taskCount] of Object.entries(taskCountByAddress)) {
|
|
748
|
+
const tasks = taskQueues[address].tasks;
|
|
749
|
+
const nextIndex = nextTaskIndexByAddress[address] ?? 0;
|
|
750
|
+
for (let i = nextIndex; i < taskCount; i++) {
|
|
751
|
+
taskIds.push(tasks[i].id);
|
|
752
|
+
}
|
|
753
|
+
}
|
|
754
|
+
for (const [address, childWorkflowRunCount] of Object.entries(childWorkflowRunCountByAddress)) {
|
|
755
|
+
const childWorkflowRuns = childWorkflowRunQueues[address].childWorkflowRuns;
|
|
756
|
+
const nextIndex = nextChildWorkflowRunIndexByAddress[address] ?? 0;
|
|
757
|
+
for (let i = nextIndex; i < childWorkflowRunCount; i++) {
|
|
758
|
+
childWorkflowRunIds.push(childWorkflowRuns[i].id);
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
return { taskIds, childWorkflowRunIds };
|
|
762
|
+
}
|
|
763
|
+
};
|
|
658
764
|
}
|
|
659
765
|
|
|
660
766
|
// run/sleeper.ts
|
|
@@ -666,17 +772,17 @@ import {
|
|
|
666
772
|
var MAX_SLEEP_YEARS = 10;
|
|
667
773
|
var MAX_SLEEP_MS = MAX_SLEEP_YEARS * 365 * 24 * 60 * 60 * 1e3;
|
|
668
774
|
function createSleeper(handle, logger) {
|
|
669
|
-
const
|
|
775
|
+
const nextIndexBySleepName = {};
|
|
670
776
|
return async (name, duration) => {
|
|
671
777
|
const sleepName = name;
|
|
672
778
|
let durationMs = toMilliseconds(duration);
|
|
673
779
|
if (durationMs > MAX_SLEEP_MS) {
|
|
674
780
|
throw new Error(`Sleep duration ${durationMs}ms exceeds maximum of ${MAX_SLEEP_YEARS} years`);
|
|
675
781
|
}
|
|
676
|
-
const
|
|
677
|
-
const sleepQueue = handle.run.
|
|
678
|
-
const
|
|
679
|
-
if (!
|
|
782
|
+
const nextIndex = nextIndexBySleepName[sleepName] ?? 0;
|
|
783
|
+
const sleepQueue = handle.run.sleepQueues[sleepName] ?? { sleeps: [] };
|
|
784
|
+
const existingSleep = sleepQueue.sleeps[nextIndex];
|
|
785
|
+
if (!existingSleep) {
|
|
680
786
|
try {
|
|
681
787
|
await handle[INTERNAL3].transitionState({ status: "sleeping", sleepName, durationMs });
|
|
682
788
|
logger.info("Going to sleep", {
|
|
@@ -691,37 +797,37 @@ function createSleeper(handle, logger) {
|
|
|
691
797
|
}
|
|
692
798
|
throw new WorkflowRunSuspendedError2(handle.run.id);
|
|
693
799
|
}
|
|
694
|
-
if (
|
|
800
|
+
if (existingSleep.status === "sleeping") {
|
|
695
801
|
logger.debug("Already sleeping", {
|
|
696
802
|
"aiki.sleepName": sleepName,
|
|
697
|
-
"aiki.awakeAt":
|
|
803
|
+
"aiki.awakeAt": existingSleep.awakeAt
|
|
698
804
|
});
|
|
699
805
|
throw new WorkflowRunSuspendedError2(handle.run.id);
|
|
700
806
|
}
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
if (
|
|
807
|
+
existingSleep.status;
|
|
808
|
+
nextIndexBySleepName[sleepName] = nextIndex + 1;
|
|
809
|
+
if (existingSleep.status === "cancelled") {
|
|
704
810
|
logger.debug("Sleep cancelled", {
|
|
705
811
|
"aiki.sleepName": sleepName,
|
|
706
|
-
"aiki.cancelledAt":
|
|
812
|
+
"aiki.cancelledAt": existingSleep.cancelledAt
|
|
707
813
|
});
|
|
708
814
|
return { cancelled: true };
|
|
709
815
|
}
|
|
710
|
-
if (durationMs ===
|
|
816
|
+
if (durationMs === existingSleep.durationMs) {
|
|
711
817
|
logger.debug("Sleep completed", {
|
|
712
818
|
"aiki.sleepName": sleepName,
|
|
713
819
|
"aiki.durationMs": durationMs,
|
|
714
|
-
"aiki.completedAt":
|
|
820
|
+
"aiki.completedAt": existingSleep.completedAt
|
|
715
821
|
});
|
|
716
822
|
return { cancelled: false };
|
|
717
823
|
}
|
|
718
|
-
if (durationMs >
|
|
824
|
+
if (durationMs > existingSleep.durationMs) {
|
|
719
825
|
logger.warn("Higher sleep duration encountered during replay. Sleeping for remaining duration", {
|
|
720
826
|
"aiki.sleepName": sleepName,
|
|
721
|
-
"aiki.historicDurationMs":
|
|
827
|
+
"aiki.historicDurationMs": existingSleep.durationMs,
|
|
722
828
|
"aiki.latestDurationMs": durationMs
|
|
723
829
|
});
|
|
724
|
-
durationMs -=
|
|
830
|
+
durationMs -= existingSleep.durationMs;
|
|
725
831
|
} else {
|
|
726
832
|
return { cancelled: false };
|
|
727
833
|
}
|
|
@@ -815,6 +921,7 @@ import { INTERNAL as INTERNAL5 } from "@aikirun/types/symbols";
|
|
|
815
921
|
import { TaskFailedError } from "@aikirun/types/task";
|
|
816
922
|
import { SchemaValidationError as SchemaValidationError2 } from "@aikirun/types/validator";
|
|
817
923
|
import {
|
|
924
|
+
NonDeterminismError,
|
|
818
925
|
WorkflowRunFailedError as WorkflowRunFailedError2,
|
|
819
926
|
WorkflowRunRevisionConflictError as WorkflowRunRevisionConflictError5,
|
|
820
927
|
WorkflowRunSuspendedError as WorkflowRunSuspendedError4
|
|
@@ -827,13 +934,13 @@ import {
|
|
|
827
934
|
WorkflowRunRevisionConflictError as WorkflowRunRevisionConflictError4,
|
|
828
935
|
WorkflowRunSuspendedError as WorkflowRunSuspendedError3
|
|
829
936
|
} from "@aikirun/types/workflow-run";
|
|
830
|
-
async function childWorkflowRunHandle(client, run, parentRun, logger, eventsDefinition) {
|
|
937
|
+
async function childWorkflowRunHandle(client, run, parentRun, childWorkflowRunWaitQueues, logger, eventsDefinition) {
|
|
831
938
|
const handle = await workflowRunHandle(client, run, eventsDefinition, logger);
|
|
832
939
|
return {
|
|
833
940
|
run: handle.run,
|
|
834
941
|
events: handle.events,
|
|
835
942
|
refresh: handle.refresh.bind(handle),
|
|
836
|
-
waitForStatus: createStatusWaiter(handle, parentRun, logger),
|
|
943
|
+
waitForStatus: createStatusWaiter(handle, parentRun, childWorkflowRunWaitQueues, logger),
|
|
837
944
|
cancel: handle.cancel.bind(handle),
|
|
838
945
|
pause: handle.pause.bind(handle),
|
|
839
946
|
resume: handle.resume.bind(handle),
|
|
@@ -841,15 +948,21 @@ async function childWorkflowRunHandle(client, run, parentRun, logger, eventsDefi
|
|
|
841
948
|
[INTERNAL4]: handle[INTERNAL4]
|
|
842
949
|
};
|
|
843
950
|
}
|
|
844
|
-
function createStatusWaiter(handle, parentRun, logger) {
|
|
845
|
-
|
|
951
|
+
function createStatusWaiter(handle, parentRun, childWorkflowRunWaitQueues, logger) {
|
|
952
|
+
const nextIndexByStatus = {
|
|
953
|
+
cancelled: 0,
|
|
954
|
+
completed: 0,
|
|
955
|
+
failed: 0
|
|
956
|
+
};
|
|
846
957
|
async function waitForStatus(expectedStatus, options) {
|
|
847
958
|
const parentRunHandle = parentRun[INTERNAL4].handle;
|
|
848
|
-
const
|
|
849
|
-
const
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
959
|
+
const nextIndex = nextIndexByStatus[expectedStatus];
|
|
960
|
+
const { run } = handle;
|
|
961
|
+
const childWorkflowRunWaits = childWorkflowRunWaitQueues[expectedStatus].childWorkflowRunWaits;
|
|
962
|
+
const existingChildWorkflowRunWait = childWorkflowRunWaits[nextIndex];
|
|
963
|
+
if (existingChildWorkflowRunWait) {
|
|
964
|
+
nextIndexByStatus[expectedStatus] = nextIndex + 1;
|
|
965
|
+
if (existingChildWorkflowRunWait.status === "timeout") {
|
|
853
966
|
logger.debug("Timed out waiting for child workflow status", {
|
|
854
967
|
"aiki.childWorkflowExpectedStatus": expectedStatus
|
|
855
968
|
});
|
|
@@ -858,43 +971,29 @@ function createStatusWaiter(handle, parentRun, logger) {
|
|
|
858
971
|
cause: "timeout"
|
|
859
972
|
};
|
|
860
973
|
}
|
|
861
|
-
|
|
974
|
+
const childWorkflowRunStatus = existingChildWorkflowRunWait.childWorkflowRunState.status;
|
|
975
|
+
if (childWorkflowRunStatus === expectedStatus) {
|
|
862
976
|
return {
|
|
863
977
|
success: true,
|
|
864
|
-
state:
|
|
978
|
+
state: existingChildWorkflowRunWait.childWorkflowRunState
|
|
865
979
|
};
|
|
866
980
|
}
|
|
867
|
-
if (isTerminalWorkflowRunStatus2(
|
|
981
|
+
if (isTerminalWorkflowRunStatus2(childWorkflowRunStatus)) {
|
|
868
982
|
logger.debug("Child workflow run reached termnial state", {
|
|
869
|
-
"aiki.childWorkflowTerminalStatus":
|
|
983
|
+
"aiki.childWorkflowTerminalStatus": childWorkflowRunStatus
|
|
870
984
|
});
|
|
871
985
|
return {
|
|
872
986
|
success: false,
|
|
873
987
|
cause: "run_terminated"
|
|
874
988
|
};
|
|
875
989
|
}
|
|
876
|
-
|
|
877
|
-
const { state } = handle.run;
|
|
878
|
-
if (state.status === expectedStatus) {
|
|
879
|
-
return {
|
|
880
|
-
success: true,
|
|
881
|
-
state
|
|
882
|
-
};
|
|
883
|
-
}
|
|
884
|
-
if (isTerminalWorkflowRunStatus2(state.status)) {
|
|
885
|
-
logger.debug("Child workflow run reached termnial state", {
|
|
886
|
-
"aiki.childWorkflowTerminalStatus": state.status
|
|
887
|
-
});
|
|
888
|
-
return {
|
|
889
|
-
success: false,
|
|
890
|
-
cause: "run_terminated"
|
|
891
|
-
};
|
|
990
|
+
childWorkflowRunStatus;
|
|
892
991
|
}
|
|
893
992
|
const timeoutInMs = options?.timeout && toMilliseconds(options.timeout);
|
|
894
993
|
try {
|
|
895
994
|
await parentRunHandle[INTERNAL4].transitionState({
|
|
896
995
|
status: "awaiting_child_workflow",
|
|
897
|
-
childWorkflowRunId:
|
|
996
|
+
childWorkflowRunId: run.id,
|
|
898
997
|
childWorkflowRunStatus: expectedStatus,
|
|
899
998
|
timeoutInMs
|
|
900
999
|
});
|
|
@@ -948,7 +1047,7 @@ var WorkflowVersionImpl = class {
|
|
|
948
1047
|
}
|
|
949
1048
|
input = schemaValidationResult.value;
|
|
950
1049
|
}
|
|
951
|
-
const {
|
|
1050
|
+
const { id } = await client.api.workflowRun.createV1({
|
|
952
1051
|
name: this.name,
|
|
953
1052
|
versionId: this.versionId,
|
|
954
1053
|
input,
|
|
@@ -957,9 +1056,9 @@ var WorkflowVersionImpl = class {
|
|
|
957
1056
|
client.logger.info("Created workflow", {
|
|
958
1057
|
"aiki.workflowName": this.name,
|
|
959
1058
|
"aiki.workflowVersionId": this.versionId,
|
|
960
|
-
"aiki.workflowRunId":
|
|
1059
|
+
"aiki.workflowRunId": id
|
|
961
1060
|
});
|
|
962
|
-
return workflowRunHandle(client,
|
|
1061
|
+
return workflowRunHandle(client, id, this[INTERNAL5].eventsDefinition);
|
|
963
1062
|
}
|
|
964
1063
|
async startAsChild(parentRun, ...args) {
|
|
965
1064
|
return this.startAsChildWithOpts(parentRun, this.params.opts ?? {}, ...args);
|
|
@@ -971,48 +1070,41 @@ var WorkflowVersionImpl = class {
|
|
|
971
1070
|
const inputRaw = args[0];
|
|
972
1071
|
const input = await this.parse(parentRunHandle, this.params.schema?.input, inputRaw, parentRun.logger);
|
|
973
1072
|
const inputHash = await hashInput(input);
|
|
974
|
-
const
|
|
975
|
-
const address = getWorkflowRunAddress(this.name, this.versionId,
|
|
976
|
-
const
|
|
977
|
-
if (
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
existingRunInfo
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
1073
|
+
const referenceId = startOpts.reference?.id;
|
|
1074
|
+
const address = getWorkflowRunAddress(this.name, this.versionId, referenceId ?? inputHash);
|
|
1075
|
+
const replayManifest = parentRun[INTERNAL5].replayManifest;
|
|
1076
|
+
if (replayManifest.hasUnconsumedEntries()) {
|
|
1077
|
+
const existingRunInfo = replayManifest.consumeNextChildWorkflowRun(address);
|
|
1078
|
+
if (existingRunInfo) {
|
|
1079
|
+
const { run: existingRun } = await client.api.workflowRun.getByIdV1({ id: existingRunInfo.id });
|
|
1080
|
+
if (existingRun.state.status === "completed") {
|
|
1081
|
+
await this.parse(parentRunHandle, this.params.schema?.output, existingRun.state.output, parentRun.logger);
|
|
1082
|
+
}
|
|
1083
|
+
const logger2 = parentRun.logger.child({
|
|
1084
|
+
"aiki.childWorkflowName": existingRun.name,
|
|
1085
|
+
"aiki.childWorkflowVersionId": existingRun.versionId,
|
|
1086
|
+
"aiki.childWorkflowRunId": existingRun.id
|
|
1087
|
+
});
|
|
1088
|
+
return childWorkflowRunHandle(
|
|
1089
|
+
client,
|
|
1090
|
+
existingRun,
|
|
1091
|
+
parentRun,
|
|
1092
|
+
existingRunInfo.childWorkflowRunWaitQueues,
|
|
1093
|
+
logger2,
|
|
1094
|
+
this[INTERNAL5].eventsDefinition
|
|
1095
|
+
);
|
|
988
1096
|
}
|
|
989
|
-
|
|
990
|
-
"aiki.childWorkflowName": existingRun.name,
|
|
991
|
-
"aiki.childWorkflowVersionId": existingRun.versionId,
|
|
992
|
-
"aiki.childWorkflowRunId": existingRun.id
|
|
993
|
-
});
|
|
994
|
-
return childWorkflowRunHandle(
|
|
995
|
-
client,
|
|
996
|
-
existingRun,
|
|
997
|
-
parentRun,
|
|
998
|
-
logger2,
|
|
999
|
-
this[INTERNAL5].eventsDefinition
|
|
1000
|
-
);
|
|
1097
|
+
await this.throwNonDeterminismError(parentRun, parentRunHandle, inputHash, referenceId, replayManifest);
|
|
1001
1098
|
}
|
|
1002
|
-
const
|
|
1099
|
+
const shard = parentRun.options.shard;
|
|
1100
|
+
const { id: newRunId } = await client.api.workflowRun.createV1({
|
|
1003
1101
|
name: this.name,
|
|
1004
1102
|
versionId: this.versionId,
|
|
1005
1103
|
input,
|
|
1006
1104
|
parentWorkflowRunId: parentRun.id,
|
|
1007
|
-
options: startOpts
|
|
1105
|
+
options: shard === void 0 ? startOpts : { ...startOpts, shard }
|
|
1008
1106
|
});
|
|
1009
|
-
|
|
1010
|
-
id: newRun.id,
|
|
1011
|
-
name: newRun.name,
|
|
1012
|
-
versionId: newRun.versionId,
|
|
1013
|
-
inputHash,
|
|
1014
|
-
statusWaitResults: []
|
|
1015
|
-
};
|
|
1107
|
+
const { run: newRun } = await client.api.workflowRun.getByIdV1({ id: newRunId });
|
|
1016
1108
|
const logger = parentRun.logger.child({
|
|
1017
1109
|
"aiki.childWorkflowName": newRun.name,
|
|
1018
1110
|
"aiki.childWorkflowVersionId": newRun.versionId,
|
|
@@ -1023,32 +1115,33 @@ var WorkflowVersionImpl = class {
|
|
|
1023
1115
|
client,
|
|
1024
1116
|
newRun,
|
|
1025
1117
|
parentRun,
|
|
1118
|
+
{
|
|
1119
|
+
cancelled: { childWorkflowRunWaits: [] },
|
|
1120
|
+
completed: { childWorkflowRunWaits: [] },
|
|
1121
|
+
failed: { childWorkflowRunWaits: [] }
|
|
1122
|
+
},
|
|
1026
1123
|
logger,
|
|
1027
1124
|
this[INTERNAL5].eventsDefinition
|
|
1028
1125
|
);
|
|
1029
1126
|
}
|
|
1030
|
-
async
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
});
|
|
1040
|
-
const error = new WorkflowRunFailedError2(
|
|
1041
|
-
parentRunHandle.run.id,
|
|
1042
|
-
parentRunHandle.run.attempts,
|
|
1043
|
-
`Reference ID "${reference.id}" already used by another child workflow run ${existingRunInfo.id}`
|
|
1044
|
-
);
|
|
1045
|
-
await parentRunHandle[INTERNAL5].transitionState({
|
|
1046
|
-
status: "failed",
|
|
1047
|
-
cause: "self",
|
|
1048
|
-
error: createSerializableError(error)
|
|
1049
|
-
});
|
|
1050
|
-
throw error;
|
|
1127
|
+
async throwNonDeterminismError(parentRun, parentRunHandle, inputHash, referenceId, manifest) {
|
|
1128
|
+
const unconsumedManifestEntries = manifest.getUnconsumedEntries();
|
|
1129
|
+
const logMeta = {
|
|
1130
|
+
"aiki.workflowName": this.name,
|
|
1131
|
+
"aiki.inputHash": inputHash,
|
|
1132
|
+
"aiki.unconsumedManifestEntries": unconsumedManifestEntries
|
|
1133
|
+
};
|
|
1134
|
+
if (referenceId !== void 0) {
|
|
1135
|
+
logMeta["aiki.referenceId"] = referenceId;
|
|
1051
1136
|
}
|
|
1137
|
+
parentRun.logger.error("Replay divergence", logMeta);
|
|
1138
|
+
const error = new NonDeterminismError(parentRun.id, parentRunHandle.run.attempts, unconsumedManifestEntries);
|
|
1139
|
+
await parentRunHandle[INTERNAL5].transitionState({
|
|
1140
|
+
status: "failed",
|
|
1141
|
+
cause: "self",
|
|
1142
|
+
error: createSerializableError(error)
|
|
1143
|
+
});
|
|
1144
|
+
throw error;
|
|
1052
1145
|
}
|
|
1053
1146
|
async getHandleById(client, runId) {
|
|
1054
1147
|
return workflowRunHandle(client, runId, this[INTERNAL5].eventsDefinition);
|
|
@@ -1084,7 +1177,7 @@ var WorkflowVersionImpl = class {
|
|
|
1084
1177
|
const output = await this.parse(handle, this.params.schema?.output, outputRaw, run.logger);
|
|
1085
1178
|
return output;
|
|
1086
1179
|
} catch (error) {
|
|
1087
|
-
if (error instanceof WorkflowRunSuspendedError4 || error instanceof WorkflowRunFailedError2 || error instanceof WorkflowRunRevisionConflictError5) {
|
|
1180
|
+
if (error instanceof WorkflowRunSuspendedError4 || error instanceof WorkflowRunFailedError2 || error instanceof WorkflowRunRevisionConflictError5 || error instanceof NonDeterminismError) {
|
|
1088
1181
|
throw error;
|
|
1089
1182
|
}
|
|
1090
1183
|
const attempts = handle.run.attempts;
|
|
@@ -1214,7 +1307,7 @@ var WorkflowImpl = class {
|
|
|
1214
1307
|
}
|
|
1215
1308
|
v(versionId, params) {
|
|
1216
1309
|
if (this.workflowVersions.has(versionId)) {
|
|
1217
|
-
throw new Error(`Workflow "${this.name}
|
|
1310
|
+
throw new Error(`Workflow "${this.name}:${versionId}" already exists`);
|
|
1218
1311
|
}
|
|
1219
1312
|
const workflowVersion = new WorkflowVersionImpl(this.name, versionId, params);
|
|
1220
1313
|
this.workflowVersions.set(
|
|
@@ -1234,6 +1327,7 @@ export {
|
|
|
1234
1327
|
WorkflowVersionImpl,
|
|
1235
1328
|
createEventSenders,
|
|
1236
1329
|
createEventWaiters,
|
|
1330
|
+
createReplayManifest,
|
|
1237
1331
|
createSleeper,
|
|
1238
1332
|
event,
|
|
1239
1333
|
schedule,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aikirun/workflow",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.19.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.19.0",
|
|
22
22
|
"@standard-schema/spec": "^1.1.0"
|
|
23
23
|
},
|
|
24
24
|
"publishConfig": {
|