@aikirun/task 0.13.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/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { Serializable } from '@aikirun/types/serializable';
2
- import { TaskName, TaskOptions } from '@aikirun/types/task';
2
+ import { TaskName, TaskStartOptions, TaskDefinitionOptions } from '@aikirun/types/task';
3
3
  import { WorkflowRunContext } from '@aikirun/workflow';
4
4
  import { StandardSchemaV1 } from '@standard-schema/spec';
5
5
  import { RequireAtLeastOneProp } from '@aikirun/types/utils';
@@ -76,7 +76,7 @@ declare function task<Input extends Serializable, Output extends Serializable>(p
76
76
  interface TaskParams<Input, Output> {
77
77
  name: string;
78
78
  handler: (input: Input) => Promise<Output>;
79
- opts?: TaskOptions;
79
+ opts?: TaskDefinitionOptions;
80
80
  schema?: RequireAtLeastOneProp<{
81
81
  input?: StandardSchemaV1<Input>;
82
82
  output?: StandardSchemaV1<Output>;
@@ -88,7 +88,7 @@ interface Task<Input, Output> {
88
88
  start: (run: WorkflowRunContext<unknown, unknown, EventsDefinition>, ...args: Input extends void ? [] : [Input]) => Promise<Output>;
89
89
  }
90
90
  interface TaskBuilder<Input, Output> {
91
- opt<Path extends PathFromObject<TaskOptions>>(path: Path, value: TypeOfValueAtPath<TaskOptions, Path>): TaskBuilder<Input, Output>;
91
+ opt<Path extends PathFromObject<TaskStartOptions>>(path: Path, value: TypeOfValueAtPath<TaskStartOptions, Path>): TaskBuilder<Input, Output>;
92
92
  start: Task<Input, Output>["start"];
93
93
  }
94
94
 
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
- // ../../lib/array/utils.ts
2
- function isNonEmptyArray(value) {
3
- return value.length > 0;
1
+ // ../../lib/address/index.ts
2
+ function getTaskAddress(name, referenceId) {
3
+ return `${name}/${referenceId}`;
4
4
  }
5
5
 
6
6
  // ../../lib/async/delay.ts
@@ -101,11 +101,6 @@ var objectOverrider = (defaultObj) => (obj) => {
101
101
  return createBuilder([]);
102
102
  };
103
103
 
104
- // ../../lib/path/index.ts
105
- function getTaskPath(name, referenceId) {
106
- return `${name}/${referenceId}`;
107
- }
108
-
109
104
  // ../../lib/retry/strategy.ts
110
105
  function getRetryParams(attempts, strategy) {
111
106
  const strategyType = strategy.type;
@@ -165,29 +160,29 @@ import {
165
160
  function task(params) {
166
161
  return new TaskImpl(params);
167
162
  }
168
- var TaskImpl = class _TaskImpl {
163
+ var TaskImpl = class {
169
164
  constructor(params) {
170
165
  this.params = params;
171
166
  this.name = params.name;
172
167
  }
173
168
  name;
174
169
  with() {
175
- const optsOverrider = objectOverrider(this.params.opts ?? {});
176
- const createBuilder = (optsBuilder) => ({
177
- opt: (path, value) => createBuilder(optsBuilder.with(path, value)),
178
- start: (run, ...args) => new _TaskImpl({ ...this.params, opts: optsBuilder.build() }).start(run, ...args)
179
- });
180
- return createBuilder(optsOverrider());
170
+ const startOpts = this.params.opts ?? {};
171
+ const startOptsOverrider = objectOverrider(startOpts);
172
+ return new TaskBuilderImpl(this, startOptsOverrider());
181
173
  }
182
174
  async start(run, ...args) {
175
+ return this.startWithOpts(run, this.params.opts ?? {}, ...args);
176
+ }
177
+ async startWithOpts(run, startOpts, ...args) {
183
178
  const handle = run[INTERNAL].handle;
184
179
  handle[INTERNAL].assertExecutionAllowed();
185
- const inputRaw = isNonEmptyArray(args) ? args[0] : void 0;
180
+ const inputRaw = args[0];
186
181
  const input = await this.parse(handle, this.params.schema?.input, inputRaw, run.logger);
187
182
  const inputHash = await hashInput(input);
188
- const reference = this.params.opts?.reference;
189
- const path = getTaskPath(this.name, reference?.id ?? inputHash);
190
- const existingTaskInfo = handle.run.tasks[path];
183
+ const reference = startOpts.reference;
184
+ const address = getTaskAddress(this.name, reference?.id ?? inputHash);
185
+ const existingTaskInfo = handle.run.tasks[address];
191
186
  if (existingTaskInfo) {
192
187
  await this.assertUniqueTaskReferenceId(handle, existingTaskInfo, inputHash, reference, run.logger);
193
188
  }
@@ -199,33 +194,29 @@ var TaskImpl = class _TaskImpl {
199
194
  throw new TaskFailedError(existingTaskInfo.id, state.attempts, state.error.message);
200
195
  }
201
196
  let attempts = 0;
202
- const retryStrategy = this.params.opts?.retry ?? { type: "never" };
197
+ const retryStrategy = startOpts.retry ?? { type: "never" };
203
198
  if (existingTaskInfo?.state) {
204
199
  const taskId2 = existingTaskInfo.id;
205
200
  const state = existingTaskInfo?.state;
206
- this.assertRetryAllowed(taskId2, state, retryStrategy, run.logger);
201
+ attempts = state.attempts;
202
+ this.assertRetryAllowed(taskId2, attempts, retryStrategy, run.logger);
207
203
  run.logger.debug("Retrying task", {
208
204
  "aiki.taskName": this.name,
209
205
  "aiki.taskId": taskId2,
210
- "aiki.attempts": state.attempts,
206
+ "aiki.attempts": attempts,
211
207
  "aiki.taskStatus": state.status
212
208
  });
213
- attempts = state.attempts;
214
- if (state.status === "awaiting_retry" && handle.run.state.status === "running") {
215
- throw new WorkflowRunSuspendedError(run.id);
216
- }
217
209
  }
218
210
  attempts++;
219
- const options = { retry: retryStrategy, reference };
220
211
  const { taskId } = existingTaskInfo ? await handle[INTERNAL].transitionTaskState({
221
212
  type: "retry",
222
213
  taskId: existingTaskInfo.id,
223
- options,
214
+ options: startOpts,
224
215
  taskState: { status: "running", attempts, input }
225
216
  }) : await handle[INTERNAL].transitionTaskState({
226
217
  type: "create",
227
218
  taskName: this.name,
228
- options,
219
+ options: startOpts,
229
220
  taskState: { status: "running", attempts, input }
230
221
  });
231
222
  const logger = run.logger.child({
@@ -299,8 +290,8 @@ var TaskImpl = class _TaskImpl {
299
290
  }
300
291
  async assertUniqueTaskReferenceId(handle, existingTaskInfo, inputHash, reference, logger) {
301
292
  if (existingTaskInfo.inputHash !== inputHash && reference) {
302
- const onConflict = reference.onConflict ?? "error";
303
- if (onConflict !== "error") {
293
+ const conflictPolicy = reference.conflictPolicy ?? "error";
294
+ if (conflictPolicy !== "error") {
304
295
  return;
305
296
  }
306
297
  logger.error("Reference ID already used by another task", {
@@ -321,8 +312,7 @@ var TaskImpl = class _TaskImpl {
321
312
  throw error;
322
313
  }
323
314
  }
324
- assertRetryAllowed(taskId, state, retryStrategy, logger) {
325
- const { attempts } = state;
315
+ assertRetryAllowed(taskId, attempts, retryStrategy, logger) {
326
316
  const retryParams = getRetryParams(attempts, retryStrategy);
327
317
  if (!retryParams.retriesLeft) {
328
318
  logger.error("Task retry not allowed", {
@@ -354,6 +344,18 @@ var TaskImpl = class _TaskImpl {
354
344
  throw new WorkflowRunFailedError(handle.run.id, handle.run.attempts);
355
345
  }
356
346
  };
347
+ var TaskBuilderImpl = class _TaskBuilderImpl {
348
+ constructor(task2, startOptsBuilder) {
349
+ this.task = task2;
350
+ this.startOptsBuilder = startOptsBuilder;
351
+ }
352
+ opt(path, value) {
353
+ return new _TaskBuilderImpl(this.task, this.startOptsBuilder.with(path, value));
354
+ }
355
+ start(run, ...args) {
356
+ return this.task.startWithOpts(run, this.startOptsBuilder.build(), ...args);
357
+ }
358
+ };
357
359
  export {
358
360
  task
359
361
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aikirun/task",
3
- "version": "0.13.0",
3
+ "version": "0.15.0",
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,8 @@
18
18
  "build": "tsup"
19
19
  },
20
20
  "dependencies": {
21
- "@aikirun/types": "0.13.0",
22
- "@aikirun/workflow": "0.13.0",
21
+ "@aikirun/types": "0.15.0",
22
+ "@aikirun/workflow": "0.15.0",
23
23
  "@standard-schema/spec": "^1.1.0"
24
24
  },
25
25
  "publishConfig": {