@aikirun/task 0.23.1 → 0.24.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/dist/index.d.ts CHANGED
@@ -1,8 +1,12 @@
1
+ import { DistributiveOmit, RequireAtLeastOneProp } from '@aikirun/types/property';
1
2
  import { Serializable } from '@aikirun/types/serializable';
2
- import { TaskName, TaskStartOptions, TaskDefinitionOptions } from '@aikirun/types/task';
3
- import { WorkflowRunContext } from '@aikirun/workflow';
3
+ import { TaskInfo, TaskName, TaskStartOptions, TaskDefinitionOptions } from '@aikirun/types/task';
4
4
  import { StandardSchemaV1 } from '@standard-schema/spec';
5
- import { RequireAtLeastOneProp } from '@aikirun/types/utils';
5
+ import { Logger } from '@aikirun/types/logger';
6
+ import { ReplayManifest } from '@aikirun/types/replay-manifest';
7
+ import { INTERNAL } from '@aikirun/types/symbols';
8
+ import { WorkflowRunId, WorkflowRun } from '@aikirun/types/workflow-run';
9
+ import { WorkflowRunStateRequest, WorkflowRunTransitionTaskStateRequestV1 } from '@aikirun/types/workflow-run-api';
6
10
 
7
11
  type NonEmptyArray<T> = [T, ...T[]];
8
12
 
@@ -20,11 +24,25 @@ type PathFromObjectInternal<T, IncludeArrayKeys extends boolean> = And<[IsSubtyp
20
24
  type ExtractObjectType<T> = T extends object ? T : never;
21
25
  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;
22
26
 
23
- interface EventDefinition<Data> {
24
- _type: Data;
25
- schema?: StandardSchemaV1<Data>;
27
+ interface WorkflowRunContext {
28
+ id: WorkflowRunId;
29
+ logger: Logger;
30
+ [INTERNAL]: {
31
+ handle: WorkflowRunHandle;
32
+ replayManifest: ReplayManifest;
33
+ options: {
34
+ spinThresholdMs: number;
35
+ };
36
+ };
37
+ }
38
+ interface WorkflowRunHandle {
39
+ run: Readonly<WorkflowRun>;
40
+ [INTERNAL]: {
41
+ transitionState: (state: WorkflowRunStateRequest) => Promise<void>;
42
+ transitionTaskState: (request: DistributiveOmit<WorkflowRunTransitionTaskStateRequestV1, "id" | "expectedWorkflowRunRevision">) => Promise<TaskInfo>;
43
+ assertExecutionAllowed: () => void;
44
+ };
26
45
  }
27
- type EventsDefinition = Record<string, EventDefinition<unknown>>;
28
46
 
29
47
  /**
30
48
  * Defines a durable task with deterministic execution and automatic retries.
@@ -56,7 +74,7 @@ type EventsDefinition = Record<string, EventDefinition<unknown>>;
56
74
  * handler(input: { cardId: string; amount: number }) {
57
75
  * return paymentService.charge(input.cardId, input.amount);
58
76
  * },
59
- * opts: {
77
+ * options: {
60
78
  * retry: {
61
79
  * type: "fixed",
62
80
  * maxAttempts: 3,
@@ -73,7 +91,7 @@ declare function task<Input extends Serializable, Output extends Serializable>(p
73
91
  interface TaskParams<Input, Output> {
74
92
  name: string;
75
93
  handler: (input: Input) => Promise<Output>;
76
- opts?: TaskDefinitionOptions;
94
+ options?: TaskDefinitionOptions;
77
95
  schema?: RequireAtLeastOneProp<{
78
96
  input?: StandardSchemaV1<Input>;
79
97
  output?: StandardSchemaV1<Output>;
@@ -82,7 +100,7 @@ interface TaskParams<Input, Output> {
82
100
  interface Task<Input, Output> {
83
101
  name: TaskName;
84
102
  with(): TaskBuilder<Input, Output>;
85
- start: (run: WorkflowRunContext<unknown, unknown, EventsDefinition>, ...args: Input extends void ? [] : [Input]) => Promise<Output>;
103
+ start: (run: WorkflowRunContext, ...args: Input extends void ? [] : [Input]) => Promise<Output>;
86
104
  }
87
105
  interface TaskBuilder<Input, Output> {
88
106
  opt<Path extends PathFromObject<TaskStartOptions>>(path: Path, value: TypeOfValueAtPath<TaskStartOptions, Path>): TaskBuilder<Input, Output>;
package/dist/index.js CHANGED
@@ -154,13 +154,13 @@ function getRetryParams(attempts, strategy) {
154
154
 
155
155
  // task.ts
156
156
  import { INTERNAL } from "@aikirun/types/symbols";
157
- import { TaskFailedError } from "@aikirun/types/task";
157
+ import { TaskFailedError } from "@aikirun/types/task-error";
158
158
  import {
159
159
  NonDeterminismError,
160
160
  WorkflowRunFailedError,
161
161
  WorkflowRunRevisionConflictError,
162
162
  WorkflowRunSuspendedError
163
- } from "@aikirun/types/workflow-run";
163
+ } from "@aikirun/types/workflow-run-error";
164
164
  function task(params) {
165
165
  return new TaskImpl(params);
166
166
  }
@@ -171,14 +171,14 @@ var TaskImpl = class {
171
171
  }
172
172
  name;
173
173
  with() {
174
- const startOpts = this.params.opts ?? {};
175
- const startOptsOverrider = objectOverrider(startOpts);
176
- return new TaskBuilderImpl(this, startOptsOverrider());
174
+ const startOptions = this.params.options ?? {};
175
+ const startOptionsOverrider = objectOverrider(startOptions);
176
+ return new TaskBuilderImpl(this, startOptionsOverrider());
177
177
  }
178
178
  async start(run, ...args) {
179
- return this.startWithOpts(run, this.params.opts ?? {}, ...args);
179
+ return this.startWithOptions(run, this.params.options ?? {}, ...args);
180
180
  }
181
- async startWithOpts(run, startOpts, ...args) {
181
+ async startWithOptions(run, startOptions, ...args) {
182
182
  const handle = run[INTERNAL].handle;
183
183
  handle[INTERNAL].assertExecutionAllowed();
184
184
  const inputRaw = args[0];
@@ -189,20 +189,19 @@ var TaskImpl = class {
189
189
  if (replayManifest.hasUnconsumedEntries()) {
190
190
  const existingTaskInfo = replayManifest.consumeNextTask(address);
191
191
  if (existingTaskInfo) {
192
- return this.getExistingTaskResult(run, handle, startOpts, input, existingTaskInfo);
192
+ return this.getExistingTaskResult(run, handle, startOptions, input, existingTaskInfo);
193
193
  }
194
- await this.throwNonDeterminismError(run, handle, inputHash, replayManifest);
194
+ await this.throwNonDeterminismError(run, handle, inputHash, replayManifest.getUnconsumedEntries());
195
195
  }
196
196
  const attempts = 1;
197
- const retryStrategy = startOpts.retry ?? { type: "never" };
197
+ const retryStrategy = startOptions.retry ?? { type: "never" };
198
198
  const taskInfo = await handle[INTERNAL].transitionTaskState({
199
199
  type: "create",
200
200
  taskName: this.name,
201
- options: startOpts,
201
+ options: startOptions,
202
202
  taskState: { status: "running", attempts, input }
203
203
  });
204
204
  const logger = run.logger.child({
205
- "aiki.component": "task-execution",
206
205
  "aiki.taskName": this.name,
207
206
  "aiki.taskId": taskInfo.id
208
207
  });
@@ -223,7 +222,7 @@ var TaskImpl = class {
223
222
  logger.info("Task complete", { "aiki.attempts": lastAttempt });
224
223
  return output;
225
224
  }
226
- async getExistingTaskResult(run, handle, startOpts, input, existingTaskInfo) {
225
+ async getExistingTaskResult(run, handle, startOptions, input, existingTaskInfo) {
227
226
  const existingTaskState = existingTaskInfo.state;
228
227
  if (existingTaskState.status === "completed") {
229
228
  return this.parse(handle, this.params.schema?.output, existingTaskState.output, run.logger);
@@ -237,7 +236,7 @@ var TaskImpl = class {
237
236
  }
238
237
  existingTaskState.status;
239
238
  const attempts = existingTaskState.attempts;
240
- const retryStrategy = startOpts.retry ?? { type: "never" };
239
+ const retryStrategy = startOptions.retry ?? { type: "never" };
241
240
  this.assertRetryAllowed(existingTaskInfo.id, attempts, retryStrategy, run.logger);
242
241
  run.logger.debug("Retrying task", {
243
242
  "aiki.taskName": this.name,
@@ -245,10 +244,9 @@ var TaskImpl = class {
245
244
  "aiki.attempts": attempts,
246
245
  "aiki.taskStatus": existingTaskState.status
247
246
  });
248
- return this.retryAndExecute(run, handle, input, existingTaskInfo.id, startOpts, retryStrategy, attempts);
247
+ return this.retryAndExecute(run, handle, input, existingTaskInfo.id, startOptions, retryStrategy, attempts);
249
248
  }
250
- async throwNonDeterminismError(run, handle, inputHash, manifest) {
251
- const unconsumedManifestEntries = manifest.getUnconsumedEntries();
249
+ async throwNonDeterminismError(run, handle, inputHash, unconsumedManifestEntries) {
252
250
  run.logger.error("Replay divergence", {
253
251
  "aiki.taskName": this.name,
254
252
  "aiki.inputHash": inputHash,
@@ -262,16 +260,15 @@ var TaskImpl = class {
262
260
  });
263
261
  throw error;
264
262
  }
265
- async retryAndExecute(run, handle, input, taskId, startOpts, retryStrategy, previousAttempts) {
263
+ async retryAndExecute(run, handle, input, taskId, startOptions, retryStrategy, previousAttempts) {
266
264
  const attempts = previousAttempts + 1;
267
265
  const taskInfo = await handle[INTERNAL].transitionTaskState({
268
266
  type: "retry",
269
267
  taskId,
270
- options: startOpts,
268
+ options: startOptions,
271
269
  taskState: { status: "running", attempts, input }
272
270
  });
273
271
  const logger = run.logger.child({
274
- "aiki.component": "task-execution",
275
272
  "aiki.taskName": this.name,
276
273
  "aiki.taskId": taskInfo.id
277
274
  });
@@ -372,15 +369,15 @@ var TaskImpl = class {
372
369
  }
373
370
  };
374
371
  var TaskBuilderImpl = class _TaskBuilderImpl {
375
- constructor(task2, startOptsBuilder) {
372
+ constructor(task2, startOptionsBuilder) {
376
373
  this.task = task2;
377
- this.startOptsBuilder = startOptsBuilder;
374
+ this.startOptionsBuilder = startOptionsBuilder;
378
375
  }
379
376
  opt(path, value) {
380
- return new _TaskBuilderImpl(this.task, this.startOptsBuilder.with(path, value));
377
+ return new _TaskBuilderImpl(this.task, this.startOptionsBuilder.with(path, value));
381
378
  }
382
379
  start(run, ...args) {
383
- return this.task.startWithOpts(run, this.startOptsBuilder.build(), ...args);
380
+ return this.task.startWithOptions(run, this.startOptionsBuilder.build(), ...args);
384
381
  }
385
382
  };
386
383
  export {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aikirun/task",
3
- "version": "0.23.1",
3
+ "version": "0.24.1",
4
4
  "description": "Task SDK for Aiki - define reliable tasks with automatic retries, idempotency, and error handling",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -18,8 +18,7 @@
18
18
  "build": "tsup"
19
19
  },
20
20
  "dependencies": {
21
- "@aikirun/types": "0.23.1",
22
- "@aikirun/workflow": "0.23.1",
21
+ "@aikirun/types": "0.24.1",
23
22
  "@standard-schema/spec": "^1.1.0"
24
23
  },
25
24
  "publishConfig": {