@hatchet-dev/typescript-sdk 1.3.3 → 1.3.4
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/clients/dispatcher/action-listener.d.ts +2 -0
- package/clients/dispatcher/action-listener.js +16 -0
- package/clients/worker/worker.d.ts +3 -3
- package/clients/worker/worker.js +12 -11
- package/package.json +1 -1
- package/v1/examples/migration-guides/hatchet-client.d.ts +2 -0
- package/v1/examples/migration-guides/hatchet-client.js +8 -0
- package/v1/examples/migration-guides/mergent.d.ts +23 -0
- package/v1/examples/migration-guides/mergent.js +109 -0
- package/version.d.ts +1 -1
- package/version.js +1 -1
|
@@ -9,6 +9,8 @@ declare enum ListenStrategy {
|
|
|
9
9
|
}
|
|
10
10
|
export interface Action extends AssignedAction {
|
|
11
11
|
}
|
|
12
|
+
export type ActionKey = string;
|
|
13
|
+
export declare function createActionKey(action: Action): ActionKey;
|
|
12
14
|
export declare class ActionListener {
|
|
13
15
|
config: ClientConfig;
|
|
14
16
|
client: PbDispatcherClient;
|
|
@@ -33,6 +33,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
33
33
|
};
|
|
34
34
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
35
35
|
exports.ActionListener = void 0;
|
|
36
|
+
exports.createActionKey = createActionKey;
|
|
37
|
+
const dispatcher_1 = require("../../protoc/dispatcher");
|
|
36
38
|
const nice_grpc_1 = require("nice-grpc");
|
|
37
39
|
const sleep_1 = __importDefault(require("../../util/sleep"));
|
|
38
40
|
const hatchet_error_1 = __importDefault(require("../../util/errors/hatchet-error"));
|
|
@@ -45,6 +47,20 @@ var ListenStrategy;
|
|
|
45
47
|
ListenStrategy[ListenStrategy["LISTEN_STRATEGY_V1"] = 1] = "LISTEN_STRATEGY_V1";
|
|
46
48
|
ListenStrategy[ListenStrategy["LISTEN_STRATEGY_V2"] = 2] = "LISTEN_STRATEGY_V2";
|
|
47
49
|
})(ListenStrategy || (ListenStrategy = {}));
|
|
50
|
+
function createActionKey(action) {
|
|
51
|
+
switch (action.actionType) {
|
|
52
|
+
case dispatcher_1.ActionType.START_GET_GROUP_KEY:
|
|
53
|
+
return `${action.getGroupKeyRunId}/${action.retryCount}`;
|
|
54
|
+
case dispatcher_1.ActionType.CANCEL_STEP_RUN:
|
|
55
|
+
case dispatcher_1.ActionType.START_STEP_RUN:
|
|
56
|
+
case dispatcher_1.ActionType.UNRECOGNIZED:
|
|
57
|
+
return `${action.stepRunId}/${action.retryCount}`;
|
|
58
|
+
default:
|
|
59
|
+
// eslint-disable-next-line no-case-declarations
|
|
60
|
+
const exhaustivenessCheck = action.actionType;
|
|
61
|
+
throw new Error(`Unhandled action type: ${exhaustivenessCheck}`);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
48
64
|
class ActionListener {
|
|
49
65
|
constructor(client, workerId, retryInterval = DEFAULT_ACTION_LISTENER_RETRY_INTERVAL, retryCount = DEFAULT_ACTION_LISTENER_RETRY_COUNT) {
|
|
50
66
|
this.lastConnectionAttempt = 0;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { InternalHatchetClient } from '../hatchet-client';
|
|
2
|
-
import { Action, ActionListener } from '../dispatcher/action-listener';
|
|
2
|
+
import { Action, ActionKey, ActionListener } from '../dispatcher/action-listener';
|
|
3
3
|
import { StepActionEvent, StepActionEventType, GroupKeyActionEvent, GroupKeyActionEventType } from '../../protoc/dispatcher';
|
|
4
4
|
import HatchetPromise from '../../util/hatchet-promise/hatchet-promise';
|
|
5
5
|
import { Workflow } from '../../workflow';
|
|
@@ -25,8 +25,8 @@ export declare class V0Worker {
|
|
|
25
25
|
action_registry: ActionRegistry;
|
|
26
26
|
workflow_registry: Array<WorkflowDefinition | Workflow>;
|
|
27
27
|
listener: ActionListener | undefined;
|
|
28
|
-
futures: Record<
|
|
29
|
-
contexts: Record<
|
|
28
|
+
futures: Record<ActionKey, HatchetPromise<any>>;
|
|
29
|
+
contexts: Record<ActionKey, Context<any, any>>;
|
|
30
30
|
maxRuns?: number;
|
|
31
31
|
logger: Logger;
|
|
32
32
|
registeredWorkflowPromises: Array<Promise<any>>;
|
package/clients/worker/worker.js
CHANGED
|
@@ -21,6 +21,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
21
21
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
22
|
exports.V0Worker = void 0;
|
|
23
23
|
const hatchet_error_1 = __importDefault(require("../../util/errors/hatchet-error"));
|
|
24
|
+
const action_listener_1 = require("../dispatcher/action-listener");
|
|
24
25
|
const dispatcher_1 = require("../../protoc/dispatcher");
|
|
25
26
|
const hatchet_promise_1 = __importDefault(require("../../util/hatchet-promise/hatchet-promise"));
|
|
26
27
|
const workflows_1 = require("../../protoc/workflows");
|
|
@@ -336,7 +337,7 @@ class V0Worker {
|
|
|
336
337
|
try {
|
|
337
338
|
// Note: we always use a DurableContext since its a superset of the Context class
|
|
338
339
|
const context = new step_1.DurableContext(action, this.client, this);
|
|
339
|
-
this.contexts[action
|
|
340
|
+
this.contexts[(0, action_listener_1.createActionKey)(action)] = context;
|
|
340
341
|
const step = this.action_registry[actionId];
|
|
341
342
|
if (!step) {
|
|
342
343
|
this.logger.error(`Registered actions: '${Object.keys(this.action_registry).join(', ')}'`);
|
|
@@ -367,8 +368,8 @@ class V0Worker {
|
|
|
367
368
|
}
|
|
368
369
|
finally {
|
|
369
370
|
// delete the run from the futures
|
|
370
|
-
delete this.futures[action
|
|
371
|
-
delete this.contexts[action
|
|
371
|
+
delete this.futures[(0, action_listener_1.createActionKey)(action)];
|
|
372
|
+
delete this.contexts[(0, action_listener_1.createActionKey)(action)];
|
|
372
373
|
}
|
|
373
374
|
});
|
|
374
375
|
const failure = (error) => __awaiter(this, void 0, void 0, function* () {
|
|
@@ -390,8 +391,8 @@ class V0Worker {
|
|
|
390
391
|
}
|
|
391
392
|
finally {
|
|
392
393
|
// delete the run from the futures
|
|
393
|
-
delete this.futures[action
|
|
394
|
-
delete this.contexts[action
|
|
394
|
+
delete this.futures[(0, action_listener_1.createActionKey)(action)];
|
|
395
|
+
delete this.contexts[(0, action_listener_1.createActionKey)(action)];
|
|
395
396
|
}
|
|
396
397
|
});
|
|
397
398
|
const future = new hatchet_promise_1.default((() => __awaiter(this, void 0, void 0, function* () {
|
|
@@ -405,7 +406,7 @@ class V0Worker {
|
|
|
405
406
|
}
|
|
406
407
|
yield success(result);
|
|
407
408
|
}))());
|
|
408
|
-
this.futures[action
|
|
409
|
+
this.futures[(0, action_listener_1.createActionKey)(action)] = future;
|
|
409
410
|
// Send the action event to the dispatcher
|
|
410
411
|
const event = this.getStepActionEvent(action, dispatcher_1.StepActionEventType.STEP_EVENT_TYPE_STARTED, false, undefined, action.retryCount);
|
|
411
412
|
this.client.dispatcher.sendStepActionEvent(event).catch((e) => {
|
|
@@ -428,7 +429,7 @@ class V0Worker {
|
|
|
428
429
|
const { actionId } = action;
|
|
429
430
|
try {
|
|
430
431
|
const context = new step_1.Context(action, this.client, this);
|
|
431
|
-
const key = action
|
|
432
|
+
const key = (0, action_listener_1.createActionKey)(action);
|
|
432
433
|
if (!key) {
|
|
433
434
|
this.logger.error(`No group key run id provided for action ${actionId}`);
|
|
434
435
|
return;
|
|
@@ -527,8 +528,8 @@ class V0Worker {
|
|
|
527
528
|
const { stepRunId } = action;
|
|
528
529
|
try {
|
|
529
530
|
this.logger.info(`Cancelling step run ${action.stepRunId}`);
|
|
530
|
-
const future = this.futures[
|
|
531
|
-
const context = this.contexts[
|
|
531
|
+
const future = this.futures[(0, action_listener_1.createActionKey)(action)];
|
|
532
|
+
const context = this.contexts[(0, action_listener_1.createActionKey)(action)];
|
|
532
533
|
if (context && context.controller) {
|
|
533
534
|
context.controller.abort('Cancelled by worker');
|
|
534
535
|
}
|
|
@@ -544,8 +545,8 @@ class V0Worker {
|
|
|
544
545
|
this.logger.error('Could not cancel step run: ', e);
|
|
545
546
|
}
|
|
546
547
|
finally {
|
|
547
|
-
delete this.futures[
|
|
548
|
-
delete this.contexts[
|
|
548
|
+
delete this.futures[(0, action_listener_1.createActionKey)(action)];
|
|
549
|
+
delete this.contexts[(0, action_listener_1.createActionKey)(action)];
|
|
549
550
|
}
|
|
550
551
|
});
|
|
551
552
|
}
|
package/package.json
CHANGED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.hatchet = void 0;
|
|
7
|
+
const sdk_1 = __importDefault(require("../../../sdk"));
|
|
8
|
+
exports.hatchet = sdk_1.default.init();
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export declare function processImageTask(req: {
|
|
2
|
+
body: {
|
|
3
|
+
imageUrl: string;
|
|
4
|
+
filters: string[];
|
|
5
|
+
};
|
|
6
|
+
}): Promise<{
|
|
7
|
+
success: boolean;
|
|
8
|
+
processedUrl: string;
|
|
9
|
+
}>;
|
|
10
|
+
type ImageProcessInput = {
|
|
11
|
+
imageUrl: string;
|
|
12
|
+
filters: string[];
|
|
13
|
+
};
|
|
14
|
+
type ImageProcessOutput = {
|
|
15
|
+
processedUrl: string;
|
|
16
|
+
metadata: {
|
|
17
|
+
size: number;
|
|
18
|
+
format: string;
|
|
19
|
+
appliedFilters: string[];
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
export declare const imageProcessor: import("../..").TaskWorkflowDeclaration<ImageProcessInput, ImageProcessOutput>;
|
|
23
|
+
export {};
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.imageProcessor = void 0;
|
|
13
|
+
exports.processImageTask = processImageTask;
|
|
14
|
+
const hatchet_client_1 = require("./hatchet-client");
|
|
15
|
+
function processImage(imageUrl, filters) {
|
|
16
|
+
// Do some image processing
|
|
17
|
+
return Promise.resolve({ url: imageUrl, size: 100, format: 'png' });
|
|
18
|
+
}
|
|
19
|
+
// ❓ Before (Mergent)
|
|
20
|
+
function processImageTask(req) {
|
|
21
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
22
|
+
const { imageUrl, filters } = req.body;
|
|
23
|
+
try {
|
|
24
|
+
const result = yield processImage(imageUrl, filters);
|
|
25
|
+
return { success: true, processedUrl: result.url };
|
|
26
|
+
}
|
|
27
|
+
catch (error) {
|
|
28
|
+
console.error('Image processing failed:', error);
|
|
29
|
+
throw error;
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
exports.imageProcessor = hatchet_client_1.hatchet.task({
|
|
34
|
+
name: 'image-processor',
|
|
35
|
+
retries: 3,
|
|
36
|
+
executionTimeout: '10m',
|
|
37
|
+
fn: (_a) => __awaiter(void 0, [_a], void 0, function* ({ imageUrl, filters }) {
|
|
38
|
+
// Do some image processing
|
|
39
|
+
const result = yield processImage(imageUrl, filters);
|
|
40
|
+
if (!result.url)
|
|
41
|
+
throw new Error('Processing failed to generate URL');
|
|
42
|
+
return {
|
|
43
|
+
processedUrl: result.url,
|
|
44
|
+
metadata: {
|
|
45
|
+
size: result.size,
|
|
46
|
+
format: result.format,
|
|
47
|
+
appliedFilters: filters,
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
}),
|
|
51
|
+
});
|
|
52
|
+
// !!
|
|
53
|
+
function run() {
|
|
54
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
55
|
+
// ❓ Running a task (Mergent)
|
|
56
|
+
const options = {
|
|
57
|
+
method: 'POST',
|
|
58
|
+
headers: { Authorization: 'Bearer <token>', 'Content-Type': 'application/json' },
|
|
59
|
+
body: JSON.stringify({
|
|
60
|
+
name: '4cf95241-fa19-47ef-8a67-71e483747649',
|
|
61
|
+
queue: 'default',
|
|
62
|
+
request: {
|
|
63
|
+
url: 'https://example.com',
|
|
64
|
+
headers: { Authorization: 'fake-secret-token', 'Content-Type': 'application/json' },
|
|
65
|
+
body: 'Hello, world!',
|
|
66
|
+
},
|
|
67
|
+
}),
|
|
68
|
+
};
|
|
69
|
+
fetch('https://api.mergent.co/v2/tasks', options)
|
|
70
|
+
.then((response) => response.json())
|
|
71
|
+
.then((response) => console.log(response))
|
|
72
|
+
.catch((err) => console.error(err));
|
|
73
|
+
// !!
|
|
74
|
+
// ❓ Running a task (Hatchet)
|
|
75
|
+
const result = yield exports.imageProcessor.run({
|
|
76
|
+
imageUrl: 'https://example.com/image.png',
|
|
77
|
+
filters: ['blur'],
|
|
78
|
+
});
|
|
79
|
+
// you can await fully typed results
|
|
80
|
+
console.log(result);
|
|
81
|
+
// !!
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
function schedule() {
|
|
85
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
86
|
+
// ❓ Scheduling tasks (Mergent)
|
|
87
|
+
const options = {
|
|
88
|
+
// same options as before
|
|
89
|
+
body: JSON.stringify({
|
|
90
|
+
// same body as before
|
|
91
|
+
delay: '5m',
|
|
92
|
+
}),
|
|
93
|
+
};
|
|
94
|
+
// !!
|
|
95
|
+
// ❓ Scheduling tasks (Hatchet)
|
|
96
|
+
// Schedule the task to run at a specific time
|
|
97
|
+
const runAt = new Date(Date.now() + 1000 * 60 * 60 * 24);
|
|
98
|
+
exports.imageProcessor.schedule(runAt, {
|
|
99
|
+
imageUrl: 'https://example.com/image.png',
|
|
100
|
+
filters: ['blur'],
|
|
101
|
+
});
|
|
102
|
+
// Schedule the task to run every hour
|
|
103
|
+
exports.imageProcessor.cron('run-hourly', '0 * * * *', {
|
|
104
|
+
imageUrl: 'https://example.com/image.png',
|
|
105
|
+
filters: ['blur'],
|
|
106
|
+
});
|
|
107
|
+
// !!
|
|
108
|
+
});
|
|
109
|
+
}
|
package/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const HATCHET_VERSION = "1.3.
|
|
1
|
+
export declare const HATCHET_VERSION = "1.3.4";
|
package/version.js
CHANGED