@hatchet-dev/typescript-sdk 1.22.3 → 1.23.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/clients/event/event-client.js +3 -3
- package/clients/hatchet-client/client-config.d.ts +7 -1
- package/clients/hatchet-client/client-config.js +20 -0
- package/opentelemetry/instrumentor.js +78 -17
- package/opentelemetry/types.d.ts +1 -0
- package/opentelemetry/types.js +1 -0
- package/package.json +16 -5
- package/step.js +2 -3
- package/util/config-loader/config-loader.d.ts +1 -0
- package/util/config-loader/config-loader.js +20 -4
- package/util/grpc-helpers.js +16 -11
- package/util/v0-deprecation-warning.d.ts +44 -0
- package/util/v0-deprecation-warning.js +80 -0
- package/v1/client/admin.js +2 -2
- package/v1/client/features/workflows.js +2 -2
- package/v1/examples/affinity/affinity-workers.js +2 -2
- package/v1/examples/agent/agent-claude.js +39 -9
- package/v1/examples/agent/agent-openai.js +1 -5
- package/v1/examples/agent/workflow.d.ts +10 -6
- package/v1/examples/agent/workflow.js +33 -11
- package/v1/examples/aws/s3/worker.d.ts +1 -0
- package/v1/examples/aws/s3/worker.js +177 -0
- package/v1/examples/bulk_operations/workflow.js +3 -3
- package/v1/examples/cancellation/cancellation-workflow.js +3 -3
- package/v1/examples/cancellations/workflow.js +3 -3
- package/v1/examples/conditions/workflow.js +1 -1
- package/v1/examples/dag_match_condition/workflow.js +1 -1
- package/v1/examples/durable/workflow.js +6 -6
- package/v1/examples/durable-event/workflow.js +2 -2
- package/v1/examples/durable-sleep/workflow.js +2 -2
- package/v1/examples/durable_event/workflow.js +3 -3
- package/v1/examples/durable_sleep/workflow.js +2 -2
- package/v1/examples/events/workflow.js +1 -1
- package/v1/examples/middleware/client.js +3 -3
- package/v1/examples/middleware/workflow.js +5 -5
- package/v1/examples/on_event/workflow.js +1 -1
- package/v1/examples/on_failure/workflow.js +2 -2
- package/v1/examples/on_success/workflow.js +1 -1
- package/v1/examples/rate_limit/workflow.js +4 -4
- package/v1/examples/retries/workflow.js +1 -1
- package/v1/examples/support_agent_tools/agent-claude.d.ts +1 -0
- package/v1/examples/support_agent_tools/agent-claude.js +109 -0
- package/v1/examples/support_agent_tools/agent-openai.d.ts +1 -0
- package/v1/examples/support_agent_tools/agent-openai.js +73 -0
- package/v1/examples/support_agent_tools/tools.d.ts +45 -0
- package/v1/examples/support_agent_tools/tools.js +144 -0
- package/v1/examples/support_agent_tools/worker.d.ts +1 -0
- package/v1/examples/support_agent_tools/worker.js +24 -0
- package/v1/examples/webhooks/workflow.js +10 -10
- package/v1/examples/welcome_email/workflow.js +3 -3
- package/version.d.ts +1 -1
- package/version.js +1 -1
- package/workflow.js +2 -4
|
@@ -42,16 +42,12 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
42
42
|
});
|
|
43
43
|
};
|
|
44
44
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45
|
-
// eslint-disable-next-line
|
|
46
45
|
const workflow_1 = require("./workflow");
|
|
47
46
|
function main() {
|
|
48
47
|
return __awaiter(this, void 0, void 0, function* () {
|
|
49
|
-
// Generate a tool from a standalone task
|
|
50
|
-
// const temperatureTool = getTemperature.mcpTool('openai');
|
|
51
|
-
// Or from a workflow.
|
|
52
48
|
// mcpTool validates Zod v4 is installed before loading @openai/agents, so call it first
|
|
53
49
|
// to get a clear error message if the wrong Zod version is present.
|
|
54
|
-
const temperatureTool = workflow_1.
|
|
50
|
+
const temperatureTool = (0, workflow_1.createTemperatureWorkflowToolOpenai)();
|
|
55
51
|
// Dynamic import — @openai/agents crashes at load time with Zod v3, so we delay
|
|
56
52
|
// the import until after mcpTool has already verified Zod v4 is available.
|
|
57
53
|
const { Agent, run } = yield Promise.resolve().then(() => __importStar(require('@openai/agents')));
|
|
@@ -7,20 +7,24 @@ declare const TemperatureInput: z.ZodObject<{
|
|
|
7
7
|
}, z.core.$strip>;
|
|
8
8
|
}, z.core.$strip>;
|
|
9
9
|
export type TemperatureInputWithZod = z.infer<typeof TemperatureInput>;
|
|
10
|
-
export declare const
|
|
10
|
+
export declare const getTemperatureWorkflow: import("../..").WorkflowDeclaration<{
|
|
11
11
|
locationName: string;
|
|
12
12
|
coords: {
|
|
13
13
|
latitude: number;
|
|
14
14
|
longitude: number;
|
|
15
15
|
};
|
|
16
|
-
}, {
|
|
17
|
-
|
|
18
|
-
}, {}, {}, {}, {}>;
|
|
19
|
-
export declare const getTemperatureWorkflow: import("../..").WorkflowDeclaration<{
|
|
16
|
+
}, {}, {}>;
|
|
17
|
+
export declare const getTemperature: import("../..").TaskWorkflowDeclaration<{
|
|
20
18
|
locationName: string;
|
|
21
19
|
coords: {
|
|
22
20
|
latitude: number;
|
|
23
21
|
longitude: number;
|
|
24
22
|
};
|
|
25
|
-
}, {
|
|
23
|
+
}, {
|
|
24
|
+
text: string;
|
|
25
|
+
}, {}, {}, {}, {}>;
|
|
26
|
+
export declare function createTemperatureWorkflowToolClaude(): import("@anthropic-ai/claude-agent-sdk").SdkMcpToolDefinition;
|
|
27
|
+
export declare function createTemperatureWorkflowToolOpenai(): import("@openai/agents").FunctionTool;
|
|
28
|
+
export declare function createTemperatureTaskToolClaude(): import("@anthropic-ai/claude-agent-sdk").SdkMcpToolDefinition;
|
|
29
|
+
export declare function createTemperatureTaskToolOpenai(): import("@openai/agents").FunctionTool;
|
|
26
30
|
export {};
|
|
@@ -9,11 +9,15 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.
|
|
13
|
-
|
|
12
|
+
exports.getTemperature = exports.getTemperatureWorkflow = void 0;
|
|
13
|
+
exports.createTemperatureWorkflowToolClaude = createTemperatureWorkflowToolClaude;
|
|
14
|
+
exports.createTemperatureWorkflowToolOpenai = createTemperatureWorkflowToolOpenai;
|
|
15
|
+
exports.createTemperatureTaskToolClaude = createTemperatureTaskToolClaude;
|
|
16
|
+
exports.createTemperatureTaskToolOpenai = createTemperatureTaskToolOpenai;
|
|
14
17
|
const hatchet_client_1 = require("../hatchet-client");
|
|
15
18
|
const v4_1 = require("zod/v4");
|
|
16
|
-
//
|
|
19
|
+
// > Models
|
|
20
|
+
// Agent tools require a Zod v4 inputValidator so the SDK can generate the tool input schema.
|
|
17
21
|
const TemperatureCoordinates = v4_1.z.object({
|
|
18
22
|
latitude: v4_1.z.number(),
|
|
19
23
|
longitude: v4_1.z.number(),
|
|
@@ -22,20 +26,15 @@ const TemperatureInput = v4_1.z.object({
|
|
|
22
26
|
locationName: v4_1.z.string(),
|
|
23
27
|
coords: TemperatureCoordinates,
|
|
24
28
|
});
|
|
29
|
+
// !!
|
|
25
30
|
const temperatureRequest = (input) => __awaiter(void 0, void 0, void 0, function* () {
|
|
26
31
|
const response = yield fetch(`https://api.open-meteo.com/v1/forecast?latitude=${input.coords.latitude}&longitude=${input.coords.longitude}¤t=temperature_2m&temperature_unit=fahrenheit`);
|
|
27
32
|
const data = yield response.json();
|
|
28
33
|
return {
|
|
29
|
-
text: `Temperature: ${data.current.temperature_2m}°F`,
|
|
34
|
+
text: `Temperature in ${input.locationName}: ${data.current.temperature_2m}°F`,
|
|
30
35
|
};
|
|
31
36
|
});
|
|
32
|
-
|
|
33
|
-
name: 'getTemperature',
|
|
34
|
-
retries: 3,
|
|
35
|
-
fn: temperatureRequest,
|
|
36
|
-
inputValidator: TemperatureInput,
|
|
37
|
-
description: 'Get the current temperature at a location',
|
|
38
|
-
});
|
|
37
|
+
// > Workflow definition
|
|
39
38
|
exports.getTemperatureWorkflow = hatchet_client_1.hatchet.workflow({
|
|
40
39
|
name: 'getTemperatureWorkflow',
|
|
41
40
|
inputValidator: TemperatureInput,
|
|
@@ -46,3 +45,26 @@ exports.getTemperatureWorkflow.task({
|
|
|
46
45
|
fn: temperatureRequest,
|
|
47
46
|
});
|
|
48
47
|
// !!
|
|
48
|
+
// > Standalone task
|
|
49
|
+
exports.getTemperature = hatchet_client_1.hatchet.task({
|
|
50
|
+
name: 'getTemperature',
|
|
51
|
+
retries: 3,
|
|
52
|
+
fn: temperatureRequest,
|
|
53
|
+
inputValidator: TemperatureInput,
|
|
54
|
+
description: 'Get the current temperature at a location',
|
|
55
|
+
});
|
|
56
|
+
// !!
|
|
57
|
+
// > Create MCP tools
|
|
58
|
+
function createTemperatureWorkflowToolClaude() {
|
|
59
|
+
return exports.getTemperatureWorkflow.mcpTool('claude');
|
|
60
|
+
}
|
|
61
|
+
function createTemperatureWorkflowToolOpenai() {
|
|
62
|
+
return exports.getTemperatureWorkflow.mcpTool('openai');
|
|
63
|
+
}
|
|
64
|
+
function createTemperatureTaskToolClaude() {
|
|
65
|
+
return exports.getTemperature.mcpTool('claude');
|
|
66
|
+
}
|
|
67
|
+
function createTemperatureTaskToolOpenai() {
|
|
68
|
+
return exports.getTemperature.mcpTool('openai');
|
|
69
|
+
}
|
|
70
|
+
// !!
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,177 @@
|
|
|
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
|
+
var __asyncValues = (this && this.__asyncValues) || function (o) {
|
|
12
|
+
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
|
13
|
+
var m = o[Symbol.asyncIterator], i;
|
|
14
|
+
return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
|
|
15
|
+
function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
|
|
16
|
+
function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
|
|
17
|
+
};
|
|
18
|
+
var _a, _b, _c, _d;
|
|
19
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
+
const client_s3_1 = require("@aws-sdk/client-s3");
|
|
21
|
+
const v1_1 = require("../../..");
|
|
22
|
+
const hatchet_client_1 = require("../../hatchet-client");
|
|
23
|
+
const BUCKET_PREFIX = (_a = process.env.S3_WORKER_BUCKET_PREFIX) !== null && _a !== void 0 ? _a : 'bucket-';
|
|
24
|
+
const MAX_CONCURRENT_BUCKET_POLLERS = parseInt((_b = process.env.S3_WORKER_MAX_CONCURRENT_BUCKET_POLLERS) !== null && _b !== void 0 ? _b : '10');
|
|
25
|
+
const MAX_RUNS_PER_BUCKET = parseInt((_c = process.env.S3_WORKER_MAX_RUNS_PER_BUCKET) !== null && _c !== void 0 ? _c : '20');
|
|
26
|
+
const SLOTS = parseInt((_d = process.env.S3_WORKER_SLOTS) !== null && _d !== void 0 ? _d : '40');
|
|
27
|
+
// > Client Setup
|
|
28
|
+
const s3 = new client_s3_1.S3Client({ forcePathStyle: true });
|
|
29
|
+
// !!
|
|
30
|
+
// > Fetch S3 Buckets
|
|
31
|
+
const fetchBucketsWorkflow = hatchet_client_1.hatchet.workflow({
|
|
32
|
+
name: 'fetch_s3_buckets',
|
|
33
|
+
on: {
|
|
34
|
+
cron: '* * * * *',
|
|
35
|
+
},
|
|
36
|
+
concurrency: {
|
|
37
|
+
expression: "'singleton'",
|
|
38
|
+
maxRuns: 1,
|
|
39
|
+
limitStrategy: v1_1.ConcurrencyLimitStrategy.CANCEL_NEWEST,
|
|
40
|
+
},
|
|
41
|
+
});
|
|
42
|
+
// !!
|
|
43
|
+
// > Fetch S3 Objects
|
|
44
|
+
const fetchObjectsWorkflow = hatchet_client_1.hatchet.workflow({
|
|
45
|
+
name: 'fetch_s3_objects',
|
|
46
|
+
concurrency: [
|
|
47
|
+
{
|
|
48
|
+
expression: 'input.bucket',
|
|
49
|
+
maxRuns: 1,
|
|
50
|
+
limitStrategy: v1_1.ConcurrencyLimitStrategy.CANCEL_NEWEST,
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
expression: "'constant'",
|
|
54
|
+
maxRuns: MAX_CONCURRENT_BUCKET_POLLERS,
|
|
55
|
+
limitStrategy: v1_1.ConcurrencyLimitStrategy.GROUP_ROUND_ROBIN,
|
|
56
|
+
},
|
|
57
|
+
],
|
|
58
|
+
});
|
|
59
|
+
// !!
|
|
60
|
+
// > Process S3 Objects
|
|
61
|
+
const processObjectWorkflow = hatchet_client_1.hatchet.workflow({
|
|
62
|
+
name: 'process_object',
|
|
63
|
+
concurrency: {
|
|
64
|
+
expression: 'input.bucket',
|
|
65
|
+
maxRuns: MAX_RUNS_PER_BUCKET,
|
|
66
|
+
limitStrategy: v1_1.ConcurrencyLimitStrategy.GROUP_ROUND_ROBIN,
|
|
67
|
+
},
|
|
68
|
+
});
|
|
69
|
+
// !!
|
|
70
|
+
// > Fetch S3 Buckets Task
|
|
71
|
+
fetchBucketsWorkflow.task({
|
|
72
|
+
name: 'fetch_buckets',
|
|
73
|
+
fn: () => __awaiter(void 0, void 0, void 0, function* () {
|
|
74
|
+
var _a, e_1, _b, _c;
|
|
75
|
+
var _d;
|
|
76
|
+
try {
|
|
77
|
+
for (var _e = true, _f = __asyncValues((0, client_s3_1.paginateListBuckets)({ client: s3, pageSize: 10 }, { Prefix: BUCKET_PREFIX })), _g; _g = yield _f.next(), _a = _g.done, !_a; _e = true) {
|
|
78
|
+
_c = _g.value;
|
|
79
|
+
_e = false;
|
|
80
|
+
const page = _c;
|
|
81
|
+
const items = ((_d = page.Buckets) !== null && _d !== void 0 ? _d : [])
|
|
82
|
+
.filter((bucket) => bucket.Name !== undefined)
|
|
83
|
+
.map((bucket) => ({
|
|
84
|
+
input: { bucket: bucket.Name },
|
|
85
|
+
opts: {
|
|
86
|
+
childKey: bucket.Name,
|
|
87
|
+
additionalMetadata: { 'bucket-name': bucket.Name },
|
|
88
|
+
},
|
|
89
|
+
}));
|
|
90
|
+
if (items.length > 0) {
|
|
91
|
+
yield fetchObjectsWorkflow.runManyNoWait(items);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
96
|
+
finally {
|
|
97
|
+
try {
|
|
98
|
+
if (!_e && !_a && (_b = _f.return)) yield _b.call(_f);
|
|
99
|
+
}
|
|
100
|
+
finally { if (e_1) throw e_1.error; }
|
|
101
|
+
}
|
|
102
|
+
return {};
|
|
103
|
+
}),
|
|
104
|
+
});
|
|
105
|
+
// !!
|
|
106
|
+
// > Fetch S3 Objects Task
|
|
107
|
+
fetchObjectsWorkflow.task({
|
|
108
|
+
name: 'fetch_objects',
|
|
109
|
+
fn: (input) => __awaiter(void 0, void 0, void 0, function* () {
|
|
110
|
+
var _a, e_2, _b, _c;
|
|
111
|
+
var _d;
|
|
112
|
+
try {
|
|
113
|
+
for (var _e = true, _f = __asyncValues((0, client_s3_1.paginateListObjectsV2)({ client: s3, pageSize: 100 }, { Bucket: input.bucket })), _g; _g = yield _f.next(), _a = _g.done, !_a; _e = true) {
|
|
114
|
+
_c = _g.value;
|
|
115
|
+
_e = false;
|
|
116
|
+
const page = _c;
|
|
117
|
+
const items = ((_d = page.Contents) !== null && _d !== void 0 ? _d : [])
|
|
118
|
+
.filter((obj) => obj.Key !== undefined)
|
|
119
|
+
.map((obj) => ({
|
|
120
|
+
input: { bucket: input.bucket, key: obj.Key },
|
|
121
|
+
opts: {
|
|
122
|
+
childKey: `${input.bucket}/${obj.Key}`,
|
|
123
|
+
},
|
|
124
|
+
}));
|
|
125
|
+
if (items.length > 0) {
|
|
126
|
+
yield processObjectWorkflow.runManyNoWait(items);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
catch (e_2_1) { e_2 = { error: e_2_1 }; }
|
|
131
|
+
finally {
|
|
132
|
+
try {
|
|
133
|
+
if (!_e && !_a && (_b = _f.return)) yield _b.call(_f);
|
|
134
|
+
}
|
|
135
|
+
finally { if (e_2) throw e_2.error; }
|
|
136
|
+
}
|
|
137
|
+
return {};
|
|
138
|
+
}),
|
|
139
|
+
});
|
|
140
|
+
// !!
|
|
141
|
+
// > Download and Process S3 Objects Task
|
|
142
|
+
processObjectWorkflow.task({
|
|
143
|
+
name: 'process_object',
|
|
144
|
+
fn: (input, ctx) => __awaiter(void 0, void 0, void 0, function* () {
|
|
145
|
+
let body;
|
|
146
|
+
try {
|
|
147
|
+
const response = yield s3.send(new client_s3_1.GetObjectCommand({ Bucket: input.bucket, Key: input.key }));
|
|
148
|
+
if (!response.Body) {
|
|
149
|
+
return {};
|
|
150
|
+
}
|
|
151
|
+
body = Buffer.from(yield response.Body.transformToByteArray());
|
|
152
|
+
}
|
|
153
|
+
catch (err) {
|
|
154
|
+
if (err instanceof client_s3_1.NoSuchKey || err instanceof client_s3_1.NoSuchBucket) {
|
|
155
|
+
yield ctx.log(`skipping ${input.bucket}/${input.key}: not found`);
|
|
156
|
+
return {};
|
|
157
|
+
}
|
|
158
|
+
throw err;
|
|
159
|
+
}
|
|
160
|
+
// TODO: actual image processing here
|
|
161
|
+
yield s3.send(new client_s3_1.DeleteObjectCommand({ Bucket: input.bucket, Key: input.key }));
|
|
162
|
+
return {};
|
|
163
|
+
}),
|
|
164
|
+
});
|
|
165
|
+
// !!
|
|
166
|
+
function main() {
|
|
167
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
168
|
+
const worker = yield hatchet_client_1.hatchet.worker('s3-worker', {
|
|
169
|
+
workflows: [fetchBucketsWorkflow, fetchObjectsWorkflow, processObjectWorkflow],
|
|
170
|
+
slots: SLOTS,
|
|
171
|
+
});
|
|
172
|
+
yield worker.start();
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
if (require.main === module) {
|
|
176
|
+
main();
|
|
177
|
+
}
|
|
@@ -15,7 +15,7 @@ exports.bulkReplayTest1 = hatchet_client_1.hatchet.task({
|
|
|
15
15
|
name: 'bulk-replay-test-1',
|
|
16
16
|
retries: 1,
|
|
17
17
|
fn: (_input, ctx) => __awaiter(void 0, void 0, void 0, function* () {
|
|
18
|
-
|
|
18
|
+
ctx.logger.info('retrying bulk replay test task', { retryCount: ctx.retryCount() });
|
|
19
19
|
if (ctx.retryCount() === 0) {
|
|
20
20
|
throw new Error('This is a test error to trigger a retry.');
|
|
21
21
|
}
|
|
@@ -25,7 +25,7 @@ exports.bulkReplayTest2 = hatchet_client_1.hatchet.task({
|
|
|
25
25
|
name: 'bulk-replay-test-2',
|
|
26
26
|
retries: 1,
|
|
27
27
|
fn: (_input, ctx) => __awaiter(void 0, void 0, void 0, function* () {
|
|
28
|
-
|
|
28
|
+
ctx.logger.info('retrying bulk replay test task', { retryCount: ctx.retryCount() });
|
|
29
29
|
if (ctx.retryCount() === 0) {
|
|
30
30
|
throw new Error('This is a test error to trigger a retry.');
|
|
31
31
|
}
|
|
@@ -35,7 +35,7 @@ exports.bulkReplayTest3 = hatchet_client_1.hatchet.task({
|
|
|
35
35
|
name: 'bulk-replay-test-3',
|
|
36
36
|
retries: 1,
|
|
37
37
|
fn: (_input, ctx) => __awaiter(void 0, void 0, void 0, function* () {
|
|
38
|
-
|
|
38
|
+
ctx.logger.info('retrying bulk replay test task', { retryCount: ctx.retryCount() });
|
|
39
39
|
if (ctx.retryCount() === 0) {
|
|
40
40
|
throw new Error('This is a test error to trigger a retry.');
|
|
41
41
|
}
|
|
@@ -47,17 +47,17 @@ exports.cancellationWorkflow.task({
|
|
|
47
47
|
// > Abort Signal
|
|
48
48
|
exports.abortSignal = hatchet_client_1.hatchet.task({
|
|
49
49
|
name: 'abort-signal',
|
|
50
|
-
fn: (
|
|
50
|
+
fn: (_, ctx) => __awaiter(void 0, void 0, void 0, function* () {
|
|
51
51
|
try {
|
|
52
52
|
const response = yield axios_1.default.get('https://api.example.com/data', {
|
|
53
|
-
signal: abortController.signal,
|
|
53
|
+
signal: ctx.abortController.signal,
|
|
54
54
|
});
|
|
55
55
|
// Handle the response
|
|
56
56
|
}
|
|
57
57
|
catch (error) {
|
|
58
58
|
if (axios_1.default.isCancel(error)) {
|
|
59
59
|
// Request was canceled
|
|
60
|
-
|
|
60
|
+
ctx.logger.info('Request canceled');
|
|
61
61
|
}
|
|
62
62
|
else {
|
|
63
63
|
// Handle other errors
|
|
@@ -33,17 +33,17 @@ exports.cancellation = hatchet_client_1.hatchet.task({
|
|
|
33
33
|
// > Abort Signal
|
|
34
34
|
exports.abortSignal = hatchet_client_1.hatchet.task({
|
|
35
35
|
name: 'abort-signal',
|
|
36
|
-
fn: (
|
|
36
|
+
fn: (_, ctx) => __awaiter(void 0, void 0, void 0, function* () {
|
|
37
37
|
try {
|
|
38
38
|
const response = yield axios_1.default.get('https://api.example.com/data', {
|
|
39
|
-
signal: abortController.signal,
|
|
39
|
+
signal: ctx.abortController.signal,
|
|
40
40
|
});
|
|
41
41
|
// Handle the response
|
|
42
42
|
}
|
|
43
43
|
catch (error) {
|
|
44
44
|
if (axios_1.default.isCancel(error)) {
|
|
45
45
|
// Request was canceled
|
|
46
|
-
|
|
46
|
+
ctx.logger.info('Request canceled');
|
|
47
47
|
}
|
|
48
48
|
else {
|
|
49
49
|
// Handle other errors
|
|
@@ -33,7 +33,7 @@ exports.dagWithConditions.task({
|
|
|
33
33
|
parents: [firstTask],
|
|
34
34
|
waitFor: (0, conditions_1.Or)({ eventKey: 'user:event' }, { sleepFor: '10s' }),
|
|
35
35
|
fn: (_, ctx) => __awaiter(void 0, void 0, void 0, function* () {
|
|
36
|
-
|
|
36
|
+
ctx.logger.info('triggered by condition', { triggers: ctx.triggers() });
|
|
37
37
|
return {
|
|
38
38
|
Completed: true,
|
|
39
39
|
};
|
|
@@ -33,7 +33,7 @@ exports.dagWithConditions.task({
|
|
|
33
33
|
parents: [firstTask],
|
|
34
34
|
waitFor: (0, conditions_1.Or)({ eventKey: 'user:event' }, { sleepFor: '10s' }),
|
|
35
35
|
fn: (_, ctx) => __awaiter(void 0, void 0, void 0, function* () {
|
|
36
|
-
|
|
36
|
+
ctx.logger.info('triggered by condition', { triggers: ctx.triggers() });
|
|
37
37
|
return {
|
|
38
38
|
Completed: true,
|
|
39
39
|
};
|
|
@@ -29,20 +29,20 @@ exports.durableWorkflow = hatchet_client_1.hatchet.workflow({
|
|
|
29
29
|
// !!
|
|
30
30
|
exports.durableWorkflow.task({
|
|
31
31
|
name: 'ephemeral_task',
|
|
32
|
-
fn: () => __awaiter(void 0, void 0, void 0, function* () {
|
|
33
|
-
|
|
32
|
+
fn: (_, ctx) => __awaiter(void 0, void 0, void 0, function* () {
|
|
33
|
+
ctx.logger.info('Running non-durable task');
|
|
34
34
|
}),
|
|
35
35
|
});
|
|
36
36
|
exports.durableWorkflow.durableTask({
|
|
37
37
|
name: 'durable_task',
|
|
38
38
|
executionTimeout: '10m',
|
|
39
39
|
fn: (_input, ctx) => __awaiter(void 0, void 0, void 0, function* () {
|
|
40
|
-
|
|
40
|
+
ctx.logger.info('Waiting for sleep');
|
|
41
41
|
const sleepResult = yield ctx.sleepFor(exports.SLEEP_TIME, { label: 'waiting for sleep' });
|
|
42
|
-
|
|
43
|
-
|
|
42
|
+
ctx.logger.info('Sleep finished');
|
|
43
|
+
ctx.logger.info('Waiting for event');
|
|
44
44
|
const event = yield ctx.waitForEvent(exports.EVENT_KEY, 'true');
|
|
45
|
-
|
|
45
|
+
ctx.logger.info('Event received');
|
|
46
46
|
return {
|
|
47
47
|
status: 'success',
|
|
48
48
|
event: event,
|
|
@@ -18,7 +18,7 @@ exports.durableEvent = hatchet_client_1.hatchet.durableTask({
|
|
|
18
18
|
executionTimeout: '10m',
|
|
19
19
|
fn: (_, ctx) => __awaiter(void 0, void 0, void 0, function* () {
|
|
20
20
|
const res = yield ctx.waitForEvent('user:update');
|
|
21
|
-
|
|
21
|
+
ctx.logger.info('res', { res });
|
|
22
22
|
return {
|
|
23
23
|
Value: 'done',
|
|
24
24
|
};
|
|
@@ -32,7 +32,7 @@ exports.durableEventWithFilter = hatchet_client_1.hatchet.durableTask({
|
|
|
32
32
|
// > Durable Event With Filter
|
|
33
33
|
const res = yield ctx.waitForEvent('user:update', "input.userId == '1234'");
|
|
34
34
|
// !!
|
|
35
|
-
|
|
35
|
+
ctx.logger.info('res', { res });
|
|
36
36
|
return {
|
|
37
37
|
Value: 'done',
|
|
38
38
|
};
|
|
@@ -20,9 +20,9 @@ exports.durableSleep.durableTask({
|
|
|
20
20
|
name: 'durable-sleep',
|
|
21
21
|
executionTimeout: '10m',
|
|
22
22
|
fn: (_, ctx) => __awaiter(void 0, void 0, void 0, function* () {
|
|
23
|
-
|
|
23
|
+
ctx.logger.info('sleeping for 5s');
|
|
24
24
|
const sleepRes = yield ctx.sleepFor('5s');
|
|
25
|
-
|
|
25
|
+
ctx.logger.info('done sleeping for 5s', { sleepRes });
|
|
26
26
|
return {
|
|
27
27
|
Value: 'done',
|
|
28
28
|
};
|
|
@@ -19,7 +19,7 @@ exports.durableEvent = hatchet_client_1.hatchet.durableTask({
|
|
|
19
19
|
executionTimeout: '10m',
|
|
20
20
|
fn: (_, ctx) => __awaiter(void 0, void 0, void 0, function* () {
|
|
21
21
|
const res = yield ctx.waitForEvent(exports.EVENT_KEY);
|
|
22
|
-
|
|
22
|
+
ctx.logger.info('res', { res });
|
|
23
23
|
return {
|
|
24
24
|
Value: 'done',
|
|
25
25
|
};
|
|
@@ -33,7 +33,7 @@ exports.durableEventWithFilter = hatchet_client_1.hatchet.durableTask({
|
|
|
33
33
|
// > Durable Event With Filter
|
|
34
34
|
const res = yield ctx.waitForEvent(exports.EVENT_KEY, "input.userId == '1234'");
|
|
35
35
|
// !!
|
|
36
|
-
|
|
36
|
+
ctx.logger.info('res', { res });
|
|
37
37
|
return {
|
|
38
38
|
Value: 'done',
|
|
39
39
|
};
|
|
@@ -46,7 +46,7 @@ exports.durableEventWithLookback = hatchet_client_1.hatchet.durableTask({
|
|
|
46
46
|
executionTimeout: '10m',
|
|
47
47
|
fn: (_, ctx) => __awaiter(void 0, void 0, void 0, function* () {
|
|
48
48
|
const res = yield ctx.waitForEvent(exports.EVENT_KEY, undefined, undefined, exports.SCOPE, '1m');
|
|
49
|
-
|
|
49
|
+
ctx.logger.info('res', { res });
|
|
50
50
|
return {
|
|
51
51
|
Value: 'done',
|
|
52
52
|
};
|
|
@@ -20,9 +20,9 @@ exports.durableSleep.durableTask({
|
|
|
20
20
|
name: 'durable-sleep',
|
|
21
21
|
executionTimeout: '10m',
|
|
22
22
|
fn: (_, ctx) => __awaiter(void 0, void 0, void 0, function* () {
|
|
23
|
-
|
|
23
|
+
ctx.logger.info('sleeping for 5s');
|
|
24
24
|
const sleepRes = yield ctx.sleepFor('5s');
|
|
25
|
-
|
|
25
|
+
ctx.logger.info('done sleeping for 5s', { sleepRes });
|
|
26
26
|
return {
|
|
27
27
|
Value: 'done',
|
|
28
28
|
};
|
|
@@ -5,7 +5,7 @@ exports.hatchetWithMiddlewareChaining = exports.hatchetWithMiddleware = void 0;
|
|
|
5
5
|
const v1_1 = require("../..");
|
|
6
6
|
const myMiddleware = {
|
|
7
7
|
before: (input, ctx) => {
|
|
8
|
-
|
|
8
|
+
ctx.logger.info('before', { first: input.first });
|
|
9
9
|
return Object.assign(Object.assign({}, input), { dependency: 'abc-123' });
|
|
10
10
|
},
|
|
11
11
|
after: (output, ctx, input) => {
|
|
@@ -17,7 +17,7 @@ exports.hatchetWithMiddleware = v1_1.HatchetClient.init().withMiddleware(myMiddl
|
|
|
17
17
|
// > Chaining middleware
|
|
18
18
|
const firstMiddleware = {
|
|
19
19
|
before: (input, ctx) => {
|
|
20
|
-
|
|
20
|
+
ctx.logger.info('before', { first: input.first });
|
|
21
21
|
return Object.assign(Object.assign({}, input), { dependency: 'abc-123' });
|
|
22
22
|
},
|
|
23
23
|
after: (output, ctx, input) => {
|
|
@@ -26,7 +26,7 @@ const firstMiddleware = {
|
|
|
26
26
|
};
|
|
27
27
|
const secondMiddleware = {
|
|
28
28
|
before: (input, ctx) => {
|
|
29
|
-
|
|
29
|
+
ctx.logger.info('before', { dependency: input.dependency }); // available from previous middleware
|
|
30
30
|
return Object.assign(Object.assign({}, input), { anotherDep: true });
|
|
31
31
|
},
|
|
32
32
|
after: (output, ctx, input) => {
|
|
@@ -4,11 +4,11 @@ exports.taskWithMiddleware = void 0;
|
|
|
4
4
|
const client_1 = require("./client");
|
|
5
5
|
exports.taskWithMiddleware = client_1.hatchetWithMiddleware.task({
|
|
6
6
|
name: 'task-with-middleware',
|
|
7
|
-
fn: (input,
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
fn: (input, ctx) => {
|
|
8
|
+
ctx.logger.info('task', { message: input.message }); // string (from TaskInput)
|
|
9
|
+
ctx.logger.info('task', { first: input.first }); // number (from GlobalInputType)
|
|
10
|
+
ctx.logger.info('task', { second: input.second }); // number (from GlobalInputType)
|
|
11
|
+
ctx.logger.info('task', { dependency: input.dependency }); // string (from Pre Middleware)
|
|
12
12
|
return {
|
|
13
13
|
message: input.message,
|
|
14
14
|
extra: 1,
|
|
@@ -28,8 +28,8 @@ exports.failureWorkflow.task({
|
|
|
28
28
|
exports.failureWorkflow.onFailure({
|
|
29
29
|
name: 'on_failure',
|
|
30
30
|
fn: (_input, ctx) => __awaiter(void 0, void 0, void 0, function* () {
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
ctx.logger.info(`onFailure for run: ${ctx.workflowRunId()}`);
|
|
32
|
+
ctx.logger.info('upstream errors', { errors: ctx.errors() });
|
|
33
33
|
return {
|
|
34
34
|
status: 'success',
|
|
35
35
|
};
|
|
@@ -34,7 +34,7 @@ exports.onSuccessDag.task({
|
|
|
34
34
|
// 👀 onSuccess handler will run if all tasks in the workflow succeed
|
|
35
35
|
exports.onSuccessDag.onSuccess({
|
|
36
36
|
fn: (_, ctx) => {
|
|
37
|
-
|
|
37
|
+
ctx.logger.info(`onSuccess for run: ${ctx.workflowRunId()}`);
|
|
38
38
|
return {
|
|
39
39
|
'on-success': 'success',
|
|
40
40
|
};
|
|
@@ -19,16 +19,16 @@ const task1 = hatchet_client_1.hatchet.task({
|
|
|
19
19
|
units: 1,
|
|
20
20
|
},
|
|
21
21
|
],
|
|
22
|
-
fn: (
|
|
23
|
-
|
|
22
|
+
fn: (_input, ctx) => {
|
|
23
|
+
ctx.logger.info('executed task1');
|
|
24
24
|
},
|
|
25
25
|
});
|
|
26
26
|
// !!
|
|
27
27
|
// > Dynamic
|
|
28
28
|
const task2 = hatchet_client_1.hatchet.task({
|
|
29
29
|
name: 'task2',
|
|
30
|
-
fn: (input) => {
|
|
31
|
-
|
|
30
|
+
fn: (input, ctx) => {
|
|
31
|
+
ctx.logger.info(`executed task2 for user: ${input.userId}`);
|
|
32
32
|
},
|
|
33
33
|
rateLimits: [
|
|
34
34
|
{
|
|
@@ -27,7 +27,7 @@ exports.retriesWithCount = hatchet_client_1.hatchet.task({
|
|
|
27
27
|
fn: (_, ctx) => __awaiter(void 0, void 0, void 0, function* () {
|
|
28
28
|
// > Get the current retry count
|
|
29
29
|
const retryCount = ctx.retryCount();
|
|
30
|
-
|
|
30
|
+
ctx.logger.info(`Retry count: ${retryCount}`);
|
|
31
31
|
if (retryCount < 2) {
|
|
32
32
|
throw new Error('intentional failure');
|
|
33
33
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|