@hatchet-dev/typescript-sdk 1.0.7 → 1.1.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/README.md ADDED
@@ -0,0 +1,109 @@
1
+ # Hatchet TypeScript SDK
2
+
3
+ <div align="center">
4
+
5
+ [![npm version](https://badge.fury.io/js/@hatchet-dev%2Ftypescript-sdk.svg)](https://badge.fury.io/js/@hatchet-dev%2Ftypescript-sdk)
6
+ [![Documentation](https://img.shields.io/badge/docs-hatchet.run-blue)](https://docs.hatchet.run)
7
+ [![License: MIT](https://img.shields.io/badge/License-MIT-purple.svg)](https://opensource.org/licenses/MIT)
8
+
9
+ </div>
10
+
11
+ This is the official TypeScript SDK for [Hatchet](https://hatchet.run), a distributed, fault-tolerant task queue. The SDK provides a type-safe way to integrate Hatchet's task scheduling and workflow orchestration capabilities into your TypeScript/JavaScript applications.
12
+
13
+ ## Installation
14
+
15
+ Install the SDK using npm:
16
+
17
+ ```bash
18
+ npm install @hatchet-dev/typescript-sdk
19
+ ```
20
+
21
+ Using yarn:
22
+
23
+ ```bash
24
+ yarn add @hatchet-dev/typescript-sdk
25
+ ```
26
+
27
+ Using pnpm:
28
+
29
+ ```bash
30
+ pnpm add @hatchet-dev/typescript-sdk
31
+ ```
32
+
33
+ ## Quick Start
34
+
35
+ Here's a simple example of how to use the Hatchet TypeScript SDK:
36
+
37
+ ```typescript
38
+ import { HatchetClient } from '@hatchet-dev/typescript-sdk';
39
+
40
+ export const hatchet = HatchetClient.init();
41
+
42
+ export type SimpleInput = {
43
+ Message: string;
44
+ };
45
+
46
+ export const simple = hatchet.task({
47
+ name: 'simple',
48
+ fn: (input: SimpleInput) => {
49
+ return {
50
+ TransformedMessage: input.Message.toLowerCase(),
51
+ };
52
+ },
53
+ });
54
+
55
+ async function main() {
56
+ const worker = await hatchet.worker('simple-worker', {
57
+ workflows: [simple],
58
+ slots: 100,
59
+ });
60
+
61
+ await worker.start();
62
+ }
63
+
64
+ if (require.main === module) {
65
+ main();
66
+ }
67
+ ```
68
+
69
+ ## Features
70
+
71
+ - 📝 **Type Safety**: Full TypeScript support with type inference for workflow inputs and outputs
72
+ - 🔄 **Workflow Orchestration**: Define complex workflows with dependencies and parallel execution
73
+ - 🔁 **Automatic Retries**: Configure retry policies for handling transient failures
74
+ - 📊 **Observability**: Track workflow progress and monitor execution metrics
75
+ - ⏰ **Scheduling**: Schedule workflows to run at specific times or on a recurring basis
76
+ - 🔄 **Event-Driven**: Trigger workflows based on events in your system
77
+
78
+ ## Documentation
79
+
80
+ For detailed documentation, examples, and best practices, visit:
81
+ - [Hatchet Documentation](https://docs.hatchet.run)
82
+ - [Examples](https://github.com/hatchet-dev/hatchet/tree/main/sdks/typescript/src/v1/examples)
83
+
84
+ ## Development
85
+
86
+ We use `pnpm` as our package manager. To get started with development:
87
+
88
+ 1. Install dependencies:
89
+ ```bash
90
+ pnpm install
91
+ ```
92
+
93
+ 2. Build the SDK:
94
+ ```bash
95
+ pnpm build
96
+ ```
97
+
98
+ 3. Run tests:
99
+ ```bash
100
+ pnpm test
101
+ ```
102
+
103
+ ## Contributing
104
+
105
+ We welcome contributions! Please check out our [contributing guidelines](https://docs.hatchet.run/contributing) and join our [Discord community](https://discord.gg/ZMeUafwH89) for discussions and support.
106
+
107
+ ## License
108
+
109
+ This SDK is released under the MIT License. See [LICENSE](https://github.com/hatchet-dev/hatchet/blob/main/LICENSE) for details.
@@ -51,7 +51,7 @@ export declare class V0Worker {
51
51
  registerAction<T, K>(actionId: string, action: StepRunFunction<T, K>): void;
52
52
  handleStartStepRun(action: Action): Promise<void>;
53
53
  handleStartGroupKeyRun(action: Action): Promise<void>;
54
- getStepActionEvent(action: Action, eventType: StepActionEventType, payload?: any): StepActionEvent;
54
+ getStepActionEvent(action: Action, eventType: StepActionEventType, shouldNotRetry: boolean, payload?: any): StepActionEvent;
55
55
  getGroupKeyActionEvent(action: Action, eventType: GroupKeyActionEventType, payload?: any): GroupKeyActionEvent;
56
56
  handleCancelStepRun(action: Action): Promise<void>;
57
57
  stop(): Promise<void>;
@@ -25,6 +25,7 @@ const dispatcher_1 = require("../../protoc/dispatcher");
25
25
  const hatchet_promise_1 = __importDefault(require("../../util/hatchet-promise/hatchet-promise"));
26
26
  const workflows_1 = require("../../protoc/workflows");
27
27
  const handler_1 = require("./handler");
28
+ const task_1 = require("../../v1/task");
28
29
  const transformer_1 = require("../../v1/conditions/transformer");
29
30
  const step_1 = require("../../step");
30
31
  class V0Worker {
@@ -345,13 +346,13 @@ class V0Worker {
345
346
  this.logger.info(`Step run ${action.stepRunId} succeeded`);
346
347
  try {
347
348
  // Send the action event to the dispatcher
348
- const event = this.getStepActionEvent(action, dispatcher_1.StepActionEventType.STEP_EVENT_TYPE_COMPLETED, result || null);
349
+ const event = this.getStepActionEvent(action, dispatcher_1.StepActionEventType.STEP_EVENT_TYPE_COMPLETED, false, result || null);
349
350
  yield this.client.dispatcher.sendStepActionEvent(event);
350
351
  }
351
352
  catch (actionEventError) {
352
353
  this.logger.error(`Could not send completed action event: ${actionEventError.message || actionEventError}`);
353
354
  // send a failure event
354
- const failureEvent = this.getStepActionEvent(action, dispatcher_1.StepActionEventType.STEP_EVENT_TYPE_FAILED, actionEventError.message);
355
+ const failureEvent = this.getStepActionEvent(action, dispatcher_1.StepActionEventType.STEP_EVENT_TYPE_FAILED, false, actionEventError.message);
355
356
  try {
356
357
  yield this.client.dispatcher.sendStepActionEvent(failureEvent);
357
358
  }
@@ -371,9 +372,10 @@ class V0Worker {
371
372
  if (error.stack) {
372
373
  this.logger.error(error.stack);
373
374
  }
375
+ const shouldNotRetry = error instanceof task_1.NonRetryableError;
374
376
  try {
375
377
  // Send the action event to the dispatcher
376
- const event = this.getStepActionEvent(action, dispatcher_1.StepActionEventType.STEP_EVENT_TYPE_FAILED, {
378
+ const event = this.getStepActionEvent(action, dispatcher_1.StepActionEventType.STEP_EVENT_TYPE_FAILED, shouldNotRetry, {
377
379
  message: error === null || error === void 0 ? void 0 : error.message,
378
380
  stack: error === null || error === void 0 ? void 0 : error.stack,
379
381
  });
@@ -401,7 +403,7 @@ class V0Worker {
401
403
  }))());
402
404
  this.futures[action.stepRunId] = future;
403
405
  // Send the action event to the dispatcher
404
- const event = this.getStepActionEvent(action, dispatcher_1.StepActionEventType.STEP_EVENT_TYPE_STARTED);
406
+ const event = this.getStepActionEvent(action, dispatcher_1.StepActionEventType.STEP_EVENT_TYPE_STARTED, false);
405
407
  this.client.dispatcher.sendStepActionEvent(event).catch((e) => {
406
408
  this.logger.error(`Could not send action event: ${e.message}`);
407
409
  });
@@ -487,7 +489,7 @@ class V0Worker {
487
489
  }
488
490
  });
489
491
  }
490
- getStepActionEvent(action, eventType, payload = '') {
492
+ getStepActionEvent(action, eventType, shouldNotRetry, payload = '') {
491
493
  return {
492
494
  workerId: this.name,
493
495
  jobId: action.jobId,
@@ -498,6 +500,7 @@ class V0Worker {
498
500
  eventTimestamp: new Date(),
499
501
  eventType,
500
502
  eventPayload: JSON.stringify(payload),
503
+ shouldNotRetry,
501
504
  };
502
505
  }
503
506
  getGroupKeyActionEvent(action, eventType, payload = '') {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hatchet-dev/typescript-sdk",
3
- "version": "1.0.7",
3
+ "version": "1.1.0",
4
4
  "description": "Background task orchestration & visibility for developers",
5
5
  "types": "dist/index.d.ts",
6
6
  "files": [
@@ -8,7 +8,8 @@
8
8
  "!**/*.test.js",
9
9
  "!**/*.test.d.ts",
10
10
  "!**/*.e2e.js",
11
- "!**/*.e2e.d.ts"
11
+ "!**/*.e2e.d.ts",
12
+ "README.md"
12
13
  ],
13
14
  "repository": {
14
15
  "type": "git",
@@ -60,8 +61,10 @@
60
61
  "worker:multi-workflow": "npm run exec -- ./src/examples/multi-workflow.ts",
61
62
  "worker:logger": "npm run exec -- ./src/examples/logger.ts",
62
63
  "worker:byo-logger": "npm run exec -- ./src/examples/byo-logger.ts",
64
+ "worker:no-retry": "npm run exec -- ./src/v1/examples/non_retryable/worker.ts",
65
+ "worker:no-retry:trigger": "npm run exec -- ./src/v1/examples/non_retryable/run.ts",
63
66
  "api": "npm run exec -- ./src/examples/api.ts",
64
- "prepublish": "cp package.json dist/package.json;",
67
+ "prepublish": "cp package.json dist/package.json; cp README.md dist/",
65
68
  "publish:ci": "rm -rf ./dist && npm run dump-version && npm run tsc:build && npm run prepublish && cd dist && npm publish --access public --no-git-checks",
66
69
  "publish:ci:alpha": "rm -rf ./dist && npm run dump-version && npm run tsc:build && npm run prepublish && cd dist && npm publish --access public --no-git-checks --tag alpha",
67
70
  "generate-docs": "typedoc"
@@ -207,6 +207,8 @@ export interface StepActionEvent {
207
207
  eventPayload: string;
208
208
  /** the retry count */
209
209
  retryCount?: number | undefined;
210
+ /** a flag indicating if the task should _not_ be retried */
211
+ shouldNotRetry?: boolean | undefined;
210
212
  }
211
213
  export interface ActionEventResponse {
212
214
  /** the tenant id */
@@ -1737,6 +1737,7 @@ function createBaseStepActionEvent() {
1737
1737
  eventType: 0,
1738
1738
  eventPayload: '',
1739
1739
  retryCount: undefined,
1740
+ shouldNotRetry: undefined,
1740
1741
  };
1741
1742
  }
1742
1743
  exports.StepActionEvent = {
@@ -1771,6 +1772,9 @@ exports.StepActionEvent = {
1771
1772
  if (message.retryCount !== undefined) {
1772
1773
  writer.uint32(80).int32(message.retryCount);
1773
1774
  }
1775
+ if (message.shouldNotRetry !== undefined) {
1776
+ writer.uint32(88).bool(message.shouldNotRetry);
1777
+ }
1774
1778
  return writer;
1775
1779
  },
1776
1780
  decode(input, length) {
@@ -1850,6 +1854,13 @@ exports.StepActionEvent = {
1850
1854
  message.retryCount = reader.int32();
1851
1855
  continue;
1852
1856
  }
1857
+ case 11: {
1858
+ if (tag !== 88) {
1859
+ break;
1860
+ }
1861
+ message.shouldNotRetry = reader.bool();
1862
+ continue;
1863
+ }
1853
1864
  }
1854
1865
  if ((tag & 7) === 4 || tag === 0) {
1855
1866
  break;
@@ -1872,6 +1883,9 @@ exports.StepActionEvent = {
1872
1883
  eventType: isSet(object.eventType) ? stepActionEventTypeFromJSON(object.eventType) : 0,
1873
1884
  eventPayload: isSet(object.eventPayload) ? globalThis.String(object.eventPayload) : '',
1874
1885
  retryCount: isSet(object.retryCount) ? globalThis.Number(object.retryCount) : undefined,
1886
+ shouldNotRetry: isSet(object.shouldNotRetry)
1887
+ ? globalThis.Boolean(object.shouldNotRetry)
1888
+ : undefined,
1875
1889
  };
1876
1890
  },
1877
1891
  toJSON(message) {
@@ -1906,13 +1920,16 @@ exports.StepActionEvent = {
1906
1920
  if (message.retryCount !== undefined) {
1907
1921
  obj.retryCount = Math.round(message.retryCount);
1908
1922
  }
1923
+ if (message.shouldNotRetry !== undefined) {
1924
+ obj.shouldNotRetry = message.shouldNotRetry;
1925
+ }
1909
1926
  return obj;
1910
1927
  },
1911
1928
  create(base) {
1912
1929
  return exports.StepActionEvent.fromPartial(base !== null && base !== void 0 ? base : {});
1913
1930
  },
1914
1931
  fromPartial(object) {
1915
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
1932
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
1916
1933
  const message = createBaseStepActionEvent();
1917
1934
  message.workerId = (_a = object.workerId) !== null && _a !== void 0 ? _a : '';
1918
1935
  message.jobId = (_b = object.jobId) !== null && _b !== void 0 ? _b : '';
@@ -1924,6 +1941,7 @@ exports.StepActionEvent = {
1924
1941
  message.eventType = (_h = object.eventType) !== null && _h !== void 0 ? _h : 0;
1925
1942
  message.eventPayload = (_j = object.eventPayload) !== null && _j !== void 0 ? _j : '';
1926
1943
  message.retryCount = (_k = object.retryCount) !== null && _k !== void 0 ? _k : undefined;
1944
+ message.shouldNotRetry = (_l = object.shouldNotRetry) !== null && _l !== void 0 ? _l : undefined;
1927
1945
  return message;
1928
1946
  },
1929
1947
  };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,22 @@
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
+ const workflow_1 = require("./workflow");
13
+ function main() {
14
+ return __awaiter(this, void 0, void 0, function* () {
15
+ const res = yield workflow_1.nonRetryableWorkflow.runNoWait({});
16
+ // eslint-disable-next-line no-console
17
+ console.log(res);
18
+ });
19
+ }
20
+ if (require.main === module) {
21
+ main();
22
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,24 @@
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
+ const hatchet_client_1 = require("../hatchet-client");
13
+ const workflow_1 = require("./workflow");
14
+ function main() {
15
+ return __awaiter(this, void 0, void 0, function* () {
16
+ const worker = yield hatchet_client_1.hatchet.worker('no-retry-worker', {
17
+ workflows: [workflow_1.nonRetryableWorkflow],
18
+ });
19
+ yield worker.start();
20
+ });
21
+ }
22
+ if (require.main === module) {
23
+ main();
24
+ }
@@ -0,0 +1 @@
1
+ export declare const nonRetryableWorkflow: import("../..").WorkflowDeclaration<import("../..").UnknownInputType, {}>;
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.nonRetryableWorkflow = void 0;
4
+ const task_1 = require("../../task");
5
+ const hatchet_client_1 = require("../hatchet-client");
6
+ exports.nonRetryableWorkflow = hatchet_client_1.hatchet.workflow({
7
+ name: 'no-retry-workflow',
8
+ });
9
+ // ❓ Non-retrying task
10
+ const shouldNotRetry = exports.nonRetryableWorkflow.task({
11
+ name: 'should-not-retry',
12
+ fn: () => {
13
+ throw new task_1.NonRetryableError('This task should not retry');
14
+ },
15
+ retries: 1,
16
+ });
17
+ // !!
18
+ // Create a task that should retry
19
+ const shouldRetryWrongErrorType = exports.nonRetryableWorkflow.task({
20
+ name: 'should-retry-wrong-error-type',
21
+ fn: () => {
22
+ throw new Error('This task should not retry');
23
+ },
24
+ retries: 1,
25
+ });
26
+ const shouldNotRetrySuccessfulTask = exports.nonRetryableWorkflow.task({
27
+ name: 'should-not-retry-successful-task',
28
+ fn: () => { },
29
+ });
package/v1/task.d.ts CHANGED
@@ -29,6 +29,9 @@ export type TaskConcurrency = {
29
29
  */
30
30
  limitStrategy?: ConcurrencyLimitStrategy;
31
31
  };
32
+ export declare class NonRetryableError extends Error {
33
+ constructor(message?: string);
34
+ }
32
35
  export type TaskFn<I extends InputType = UnknownInputType, O extends OutputType = void, C = Context<I>> = (input: I, ctx: C) => O | Promise<O>;
33
36
  export type DurableTaskFn<I extends InputType = UnknownInputType, O extends OutputType = void> = TaskFn<I, O, DurableContext<I>>;
34
37
  /**
package/v1/task.js CHANGED
@@ -1,2 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.NonRetryableError = void 0;
4
+ class NonRetryableError extends Error {
5
+ constructor(message) {
6
+ super(message);
7
+ this.name = 'NonRetryableError';
8
+ Object.setPrototypeOf(this, new.target.prototype);
9
+ }
10
+ }
11
+ exports.NonRetryableError = NonRetryableError;
package/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const HATCHET_VERSION = "1.0.7";
1
+ export declare const HATCHET_VERSION = "1.1.0";
package/version.js CHANGED
@@ -1,4 +1,4 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.HATCHET_VERSION = void 0;
4
- exports.HATCHET_VERSION = '1.0.7';
4
+ exports.HATCHET_VERSION = '1.1.0';