@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 +3 -3
- package/dist/index.js +35 -33
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Serializable } from '@aikirun/types/serializable';
|
|
2
|
-
import { TaskName,
|
|
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?:
|
|
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<
|
|
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/
|
|
2
|
-
function
|
|
3
|
-
return
|
|
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
|
|
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
|
|
176
|
-
const
|
|
177
|
-
|
|
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 =
|
|
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 =
|
|
189
|
-
const
|
|
190
|
-
const existingTaskInfo = handle.run.tasks[
|
|
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 =
|
|
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
|
-
|
|
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":
|
|
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
|
|
303
|
-
if (
|
|
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,
|
|
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.
|
|
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.
|
|
22
|
-
"@aikirun/workflow": "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": {
|