@hatchet-dev/typescript-sdk 1.23.1 → 1.24.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.
@@ -37,6 +37,8 @@ export interface DurableTaskEventLogEntryResult {
37
37
  durableTaskExternalId: string;
38
38
  nodeId: number;
39
39
  payload: Record<string, unknown> | undefined;
40
+ isFailure: boolean;
41
+ errorMessage: string | undefined;
40
42
  }
41
43
  export interface WaitForEvent {
42
44
  kind: 'waitFor';
@@ -95,13 +95,15 @@ const WORKER_STATUS_POLL_INTERVAL_MS = 1000;
95
95
  function eventLogEntryResultFromProto(proto) {
96
96
  var _a, _b, _c, _d;
97
97
  let payload;
98
- if (proto.payload && proto.payload.length > 0) {
98
+ if (!proto.isFailure && proto.payload && proto.payload.length > 0) {
99
99
  payload = JSON.parse(new TextDecoder().decode(proto.payload));
100
100
  }
101
101
  return {
102
102
  durableTaskExternalId: (_b = (_a = proto.ref) === null || _a === void 0 ? void 0 : _a.durableTaskExternalId) !== null && _b !== void 0 ? _b : '',
103
103
  nodeId: (_d = (_c = proto.ref) === null || _c === void 0 ? void 0 : _c.nodeId) !== null && _d !== void 0 ? _d : 0,
104
104
  payload,
105
+ isFailure: proto.isFailure,
106
+ errorMessage: proto.errorMessage,
105
107
  };
106
108
  }
107
109
  function ackKey(taskExtId, invocationCount) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hatchet-dev/typescript-sdk",
3
- "version": "1.23.1",
3
+ "version": "1.24.1",
4
4
  "description": "Background task orchestration & visibility for developers",
5
5
  "types": "dist/index.d.ts",
6
6
  "files": [
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  // Code generated by protoc-gen-ts_proto. DO NOT EDIT.
3
3
  // versions:
4
- // protoc-gen-ts_proto v2.11.6
4
+ // protoc-gen-ts_proto v2.11.8
5
5
  // protoc v3.19.1
6
6
  // source: dispatcher/dispatcher.proto
7
7
  Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  // Code generated by protoc-gen-ts_proto. DO NOT EDIT.
3
3
  // versions:
4
- // protoc-gen-ts_proto v2.11.6
4
+ // protoc-gen-ts_proto v2.11.8
5
5
  // protoc v3.19.1
6
6
  // source: events/events.proto
7
7
  Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  // Code generated by protoc-gen-ts_proto. DO NOT EDIT.
3
3
  // versions:
4
- // protoc-gen-ts_proto v2.11.6
4
+ // protoc-gen-ts_proto v2.11.8
5
5
  // protoc v3.19.1
6
6
  // source: google/protobuf/timestamp.proto
7
7
  Object.defineProperty(exports, "__esModule", { value: true });
@@ -43,6 +43,8 @@ export interface DurableTaskEventWaitForAckResponse {
43
43
  export interface DurableTaskEventLogEntryCompletedResponse {
44
44
  ref: DurableEventLogEntryRef | undefined;
45
45
  payload: Uint8Array;
46
+ isFailure: boolean;
47
+ errorMessage?: string | undefined;
46
48
  }
47
49
  export interface DurableTaskEvictInvocationRequest {
48
50
  invocationCount: number;
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  // Code generated by protoc-gen-ts_proto. DO NOT EDIT.
3
3
  // versions:
4
- // protoc-gen-ts_proto v2.11.6
4
+ // protoc-gen-ts_proto v2.11.8
5
5
  // protoc v3.19.1
6
6
  // source: v1/dispatcher.proto
7
7
  Object.defineProperty(exports, "__esModule", { value: true });
@@ -619,7 +619,7 @@ exports.DurableTaskEventWaitForAckResponse = {
619
619
  },
620
620
  };
621
621
  function createBaseDurableTaskEventLogEntryCompletedResponse() {
622
- return { ref: undefined, payload: new Uint8Array(0) };
622
+ return { ref: undefined, payload: new Uint8Array(0), isFailure: false, errorMessage: undefined };
623
623
  }
624
624
  exports.DurableTaskEventLogEntryCompletedResponse = {
625
625
  encode(message, writer = new wire_1.BinaryWriter()) {
@@ -629,6 +629,12 @@ exports.DurableTaskEventLogEntryCompletedResponse = {
629
629
  if (message.payload.length !== 0) {
630
630
  writer.uint32(18).bytes(message.payload);
631
631
  }
632
+ if (message.isFailure !== false) {
633
+ writer.uint32(24).bool(message.isFailure);
634
+ }
635
+ if (message.errorMessage !== undefined) {
636
+ writer.uint32(34).string(message.errorMessage);
637
+ }
632
638
  return writer;
633
639
  },
634
640
  decode(input, length) {
@@ -652,6 +658,20 @@ exports.DurableTaskEventLogEntryCompletedResponse = {
652
658
  message.payload = reader.bytes();
653
659
  continue;
654
660
  }
661
+ case 3: {
662
+ if (tag !== 24) {
663
+ break;
664
+ }
665
+ message.isFailure = reader.bool();
666
+ continue;
667
+ }
668
+ case 4: {
669
+ if (tag !== 34) {
670
+ break;
671
+ }
672
+ message.errorMessage = reader.string();
673
+ continue;
674
+ }
655
675
  }
656
676
  if ((tag & 7) === 4 || tag === 0) {
657
677
  break;
@@ -664,6 +684,16 @@ exports.DurableTaskEventLogEntryCompletedResponse = {
664
684
  return {
665
685
  ref: isSet(object.ref) ? exports.DurableEventLogEntryRef.fromJSON(object.ref) : undefined,
666
686
  payload: isSet(object.payload) ? bytesFromBase64(object.payload) : new Uint8Array(0),
687
+ isFailure: isSet(object.isFailure)
688
+ ? globalThis.Boolean(object.isFailure)
689
+ : isSet(object.is_failure)
690
+ ? globalThis.Boolean(object.is_failure)
691
+ : false,
692
+ errorMessage: isSet(object.errorMessage)
693
+ ? globalThis.String(object.errorMessage)
694
+ : isSet(object.error_message)
695
+ ? globalThis.String(object.error_message)
696
+ : undefined,
667
697
  };
668
698
  },
669
699
  toJSON(message) {
@@ -674,19 +704,27 @@ exports.DurableTaskEventLogEntryCompletedResponse = {
674
704
  if (message.payload.length !== 0) {
675
705
  obj.payload = base64FromBytes(message.payload);
676
706
  }
707
+ if (message.isFailure !== false) {
708
+ obj.isFailure = message.isFailure;
709
+ }
710
+ if (message.errorMessage !== undefined) {
711
+ obj.errorMessage = message.errorMessage;
712
+ }
677
713
  return obj;
678
714
  },
679
715
  create(base) {
680
716
  return exports.DurableTaskEventLogEntryCompletedResponse.fromPartial(base !== null && base !== void 0 ? base : {});
681
717
  },
682
718
  fromPartial(object) {
683
- var _a;
719
+ var _a, _b, _c;
684
720
  const message = createBaseDurableTaskEventLogEntryCompletedResponse();
685
721
  message.ref =
686
722
  object.ref !== undefined && object.ref !== null
687
723
  ? exports.DurableEventLogEntryRef.fromPartial(object.ref)
688
724
  : undefined;
689
725
  message.payload = (_a = object.payload) !== null && _a !== void 0 ? _a : new Uint8Array(0);
726
+ message.isFailure = (_b = object.isFailure) !== null && _b !== void 0 ? _b : false;
727
+ message.errorMessage = (_c = object.errorMessage) !== null && _c !== void 0 ? _c : undefined;
690
728
  return message;
691
729
  },
692
730
  };
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  // Code generated by protoc-gen-ts_proto. DO NOT EDIT.
3
3
  // versions:
4
- // protoc-gen-ts_proto v2.11.6
4
+ // protoc-gen-ts_proto v2.11.8
5
5
  // protoc v3.19.1
6
6
  // source: v1/shared/condition.proto
7
7
  Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  // Code generated by protoc-gen-ts_proto. DO NOT EDIT.
3
3
  // versions:
4
- // protoc-gen-ts_proto v2.11.6
4
+ // protoc-gen-ts_proto v2.11.8
5
5
  // protoc v3.19.1
6
6
  // source: v1/shared/trigger.proto
7
7
  Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  // Code generated by protoc-gen-ts_proto. DO NOT EDIT.
3
3
  // versions:
4
- // protoc-gen-ts_proto v2.11.6
4
+ // protoc-gen-ts_proto v2.11.8
5
5
  // protoc v3.19.1
6
6
  // source: v1/workflows.proto
7
7
  Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  // Code generated by protoc-gen-ts_proto. DO NOT EDIT.
3
3
  // versions:
4
- // protoc-gen-ts_proto v2.11.6
4
+ // protoc-gen-ts_proto v2.11.8
5
5
  // protoc v3.19.1
6
6
  // source: workflows/workflows.proto
7
7
  Object.defineProperty(exports, "__esModule", { value: true });
@@ -3,6 +3,24 @@ import { V1TaskStatus } from '../../../clients/rest/generated/data-contracts';
3
3
  import { RunListenerClient } from '../../../clients/listeners/run-listener/child-listener-client';
4
4
  import { WorkflowsClient } from './workflows';
5
5
  import { HatchetClient } from '../client';
6
+ import { runStatusToJSON } from '../../../protoc/v1/workflows';
7
+ export type RunDetail = {
8
+ status: V1TaskStatus;
9
+ done: boolean;
10
+ input: unknown;
11
+ additionalMetadata: unknown;
12
+ isEvicted: boolean;
13
+ taskRuns: Record<string, TaskRunDetail>;
14
+ };
15
+ export type TaskRunDetail = {
16
+ externalId: string;
17
+ readableId: string;
18
+ status: V1TaskStatus;
19
+ output: unknown;
20
+ error?: string;
21
+ isEvicted: boolean;
22
+ };
23
+ export { runStatusToJSON };
6
24
  export type RunFilter = {
7
25
  since?: Date;
8
26
  until?: Date;
@@ -72,7 +90,10 @@ export declare class RunsClient {
72
90
  tenantId: string;
73
91
  workflows: WorkflowsClient;
74
92
  listener: RunListenerClient;
93
+ private _config;
94
+ private _adminGrpc;
75
95
  constructor(client: HatchetClient);
96
+ private get adminGrpc();
76
97
  /**
77
98
  * Gets a task or workflow run by its ID.
78
99
  * @param run - The ID of the run to get.
@@ -85,6 +106,12 @@ export declare class RunsClient {
85
106
  * @returns A promise that resolves to the status of the run.
86
107
  */
87
108
  get_status<T = any>(run: string | WorkflowRunRef<T>): Promise<V1TaskStatus>;
109
+ /**
110
+ * Gets run details
111
+ * @param run - The workflow run ID (string) or a WorkflowRunRef.
112
+ * @returns A promise resolving to GetRunDetailsResponse with task run statuses and outputs.
113
+ */
114
+ getDetails<T = any>(run: string | WorkflowRunRef<T>): Promise<RunDetail>;
88
115
  /**
89
116
  * Lists all task and workflow runs for the current tenant.
90
117
  * @param opts - The options for the list operation.
@@ -32,9 +32,57 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
32
32
  return (mod && mod.__esModule) ? mod : { "default": mod };
33
33
  };
34
34
  Object.defineProperty(exports, "__esModule", { value: true });
35
- exports.RunsClient = void 0;
35
+ exports.RunsClient = exports.runStatusToJSON = void 0;
36
36
  const workflow_run_ref_1 = __importDefault(require("../../../util/workflow-run-ref"));
37
+ const data_contracts_1 = require("../../../clients/rest/generated/data-contracts");
37
38
  const child_listener_client_1 = require("../../../clients/listeners/run-listener/child-listener-client");
39
+ const workflows_1 = require("../../../protoc/v1/workflows");
40
+ Object.defineProperty(exports, "runStatusToJSON", { enumerable: true, get: function () { return workflows_1.runStatusToJSON; } });
41
+ const grpc_helpers_1 = require("../../../util/grpc-helpers");
42
+ // EVICTED is not in V1TaskStatus; treat as RUNNING per the proto comment.
43
+ const PROTO_STATUS_MAP = {
44
+ [workflows_1.RunStatus.QUEUED]: data_contracts_1.V1TaskStatus.QUEUED,
45
+ [workflows_1.RunStatus.RUNNING]: data_contracts_1.V1TaskStatus.RUNNING,
46
+ [workflows_1.RunStatus.COMPLETED]: data_contracts_1.V1TaskStatus.COMPLETED,
47
+ [workflows_1.RunStatus.FAILED]: data_contracts_1.V1TaskStatus.FAILED,
48
+ [workflows_1.RunStatus.CANCELLED]: data_contracts_1.V1TaskStatus.CANCELLED,
49
+ [workflows_1.RunStatus.EVICTED]: data_contracts_1.V1TaskStatus.RUNNING,
50
+ [workflows_1.RunStatus.UNRECOGNIZED]: data_contracts_1.V1TaskStatus.RUNNING,
51
+ };
52
+ function decodeBytes(b) {
53
+ if (!(b === null || b === void 0 ? void 0 : b.length))
54
+ return null;
55
+ try {
56
+ return JSON.parse(new TextDecoder().decode(b));
57
+ }
58
+ catch (_a) {
59
+ return null;
60
+ }
61
+ }
62
+ function toRunDetail(raw) {
63
+ var _a;
64
+ return {
65
+ status: (_a = PROTO_STATUS_MAP[raw.status]) !== null && _a !== void 0 ? _a : data_contracts_1.V1TaskStatus.RUNNING,
66
+ done: raw.done,
67
+ input: decodeBytes(raw.input),
68
+ additionalMetadata: decodeBytes(raw.additionalMetadata),
69
+ isEvicted: raw.isEvicted,
70
+ taskRuns: Object.fromEntries(Object.entries(raw.taskRuns).map(([id, tr]) => {
71
+ var _a;
72
+ return [
73
+ id,
74
+ {
75
+ externalId: tr.externalId,
76
+ readableId: tr.readableId,
77
+ status: (_a = PROTO_STATUS_MAP[tr.status]) !== null && _a !== void 0 ? _a : data_contracts_1.V1TaskStatus.RUNNING,
78
+ output: decodeBytes(tr.output),
79
+ error: tr.error,
80
+ isEvicted: tr.isEvicted,
81
+ },
82
+ ];
83
+ })),
84
+ };
85
+ }
38
86
  /**
39
87
  * The runs client is a client for interacting with task and workflow runs within Hatchet.
40
88
  */
@@ -44,6 +92,14 @@ class RunsClient {
44
92
  this.tenantId = client.tenantId;
45
93
  this.workflows = client.workflows;
46
94
  this.listener = client._listener;
95
+ this._config = client.config;
96
+ }
97
+ get adminGrpc() {
98
+ if (!this._adminGrpc) {
99
+ const { client } = (0, grpc_helpers_1.createGrpcClient)(this._config, workflows_1.AdminServiceDefinition);
100
+ this._adminGrpc = client;
101
+ }
102
+ return this._adminGrpc;
47
103
  }
48
104
  /**
49
105
  * Gets a task or workflow run by its ID.
@@ -69,6 +125,17 @@ class RunsClient {
69
125
  return data;
70
126
  });
71
127
  }
128
+ /**
129
+ * Gets run details
130
+ * @param run - The workflow run ID (string) or a WorkflowRunRef.
131
+ * @returns A promise resolving to GetRunDetailsResponse with task run statuses and outputs.
132
+ */
133
+ getDetails(run) {
134
+ return __awaiter(this, void 0, void 0, function* () {
135
+ const runId = typeof run === 'string' ? run : yield run.getWorkflowRunId();
136
+ return toRunDetail(yield this.adminGrpc.getRunDetails({ externalId: runId }));
137
+ });
138
+ }
72
139
  /**
73
140
  * Lists all task and workflow runs for the current tenant.
74
141
  * @param opts - The options for the list operation.
@@ -894,6 +894,9 @@ class DurableContext extends Context {
894
894
  });
895
895
  const results = yield Promise.all(ack.runEntries.map((entry) => this.withEvictionWait('runChild', `workflow:bulk-child`, () => __awaiter(this, void 0, void 0, function* () {
896
896
  const result = yield this._durableListener.waitForCallback(this.action.taskRunExternalId, this.invocationCount, entry.branchId, entry.nodeId, { signal: this.abortController.signal });
897
+ if (result.isFailure) {
898
+ throw new hatchet_error_1.default(result.errorMessage || 'child task failed');
899
+ }
897
900
  return (result.payload || {});
898
901
  }))));
899
902
  return results;
@@ -82,6 +82,17 @@ export declare const memoNowCaching: import("../..").TaskWorkflowDeclaration<imp
82
82
  start_time: string;
83
83
  }, {}, {}, {}, {}>;
84
84
  export declare const dagChildWorkflow: import("../..").WorkflowDeclaration<import("../..").UnknownInputType, {}, {}>;
85
+ export declare const errorRaisingTask: import("../..").TaskWorkflowDeclaration<{
86
+ error_message: string;
87
+ }, never, {}, {}, {}, {}>;
88
+ export declare const errorRaisingDurableParent: import("../..").TaskWorkflowDeclaration<{
89
+ error_message: string;
90
+ }, {
91
+ child_raised: boolean;
92
+ child_error_str: string | null;
93
+ child_run_external_id: string;
94
+ parent_run_external_id: string;
95
+ }, {}, {}, {}, {}>;
85
96
  export declare const durableSpawnDag: import("../..").TaskWorkflowDeclaration<import("../..").JsonObject, {
86
97
  sleep_duration: number;
87
98
  sleep_duration_ms: number;
@@ -12,7 +12,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
12
12
  return (mod && mod.__esModule) ? mod : { "default": mod };
13
13
  };
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
- exports.durableSpawnDag = exports.dagChildWorkflow = exports.memoNowCaching = exports.waitForTwoEventsSecondPushedFirst = exports.waitForOrEventLookback = exports.waitForEventLookback = exports.LOOKBACK_WINDOW = exports.durableReplayReset = exports.REPLAY_RESET_MEMOIZED_MAX_SECONDS = exports.REPLAY_RESET_SLEEP_SECONDS = exports.durableNonDeterminism = exports.durableWithExplicitSpawn = exports.durableSleepEventSpawn = exports.durableWithBulkSpawn = exports.durableWithSpawn = exports.spawnChildTask = exports.waitForSleepTwice = exports.durableWorkflow = exports.SLEEP_TIME = exports.SLEEP_TIME_SECONDS = exports.EVENT_KEY = void 0;
15
+ exports.durableSpawnDag = exports.errorRaisingDurableParent = exports.errorRaisingTask = exports.dagChildWorkflow = exports.memoNowCaching = exports.waitForTwoEventsSecondPushedFirst = exports.waitForOrEventLookback = exports.waitForEventLookback = exports.LOOKBACK_WINDOW = exports.durableReplayReset = exports.REPLAY_RESET_MEMOIZED_MAX_SECONDS = exports.REPLAY_RESET_SLEEP_SECONDS = exports.durableNonDeterminism = exports.durableWithExplicitSpawn = exports.durableSleepEventSpawn = exports.durableWithBulkSpawn = exports.durableWithSpawn = exports.spawnChildTask = exports.waitForSleepTwice = exports.durableWorkflow = exports.SLEEP_TIME = exports.SLEEP_TIME_SECONDS = exports.EVENT_KEY = void 0;
16
16
  const v4_1 = require("zod/v4");
17
17
  const conditions_1 = require("../../conditions");
18
18
  const non_determinism_error_1 = require("../../../util/errors/non-determinism-error");
@@ -301,6 +301,35 @@ exports.dagChildWorkflow.task({
301
301
  return { result: 'child2' };
302
302
  }),
303
303
  });
304
+ // --- Error propagation test ---
305
+ exports.errorRaisingTask = hatchet_client_1.hatchet.task({
306
+ name: 'error-raising-task',
307
+ fn: (input) => __awaiter(void 0, void 0, void 0, function* () {
308
+ throw new Error(input.error_message);
309
+ }),
310
+ });
311
+ exports.errorRaisingDurableParent = hatchet_client_1.hatchet.durableTask({
312
+ name: 'error-raising-durable-parent',
313
+ executionTimeout: '30s',
314
+ fn: (input, ctx) => __awaiter(void 0, void 0, void 0, function* () {
315
+ let childRaised = false;
316
+ let childErrorStr = null;
317
+ const ref = yield exports.errorRaisingTask.runNoWait(input);
318
+ try {
319
+ yield ref.output;
320
+ }
321
+ catch (e) {
322
+ childRaised = true;
323
+ childErrorStr = e instanceof Error ? e.message : String(e);
324
+ }
325
+ return {
326
+ child_raised: childRaised,
327
+ child_error_str: childErrorStr,
328
+ child_run_external_id: yield ref.runId,
329
+ parent_run_external_id: ctx.workflowRunId(),
330
+ };
331
+ }),
332
+ });
304
333
  exports.durableSpawnDag = hatchet_client_1.hatchet.durableTask({
305
334
  name: 'durable-spawn-dag',
306
335
  executionTimeout: '10s',
@@ -70,6 +70,8 @@ const workflows = [
70
70
  workflow_8.waitForEventLookback,
71
71
  workflow_8.waitForOrEventLookback,
72
72
  workflow_8.waitForTwoEventsSecondPushedFirst,
73
+ workflow_8.errorRaisingTask,
74
+ workflow_8.errorRaisingDurableParent,
73
75
  workflow_9.durableEvent,
74
76
  workflow_9.durableEventWithFilter,
75
77
  workflow_11.durableSleep,
package/v1/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  export * from './client/client';
2
2
  export * from './client/features';
3
+ export type { RunDetail, TaskRunDetail } from './client/features/runs';
3
4
  export * from './client/worker/worker';
4
5
  export * from './declaration';
5
6
  export * from './conditions';
package/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const HATCHET_VERSION = "1.23.1";
1
+ export declare const HATCHET_VERSION = "1.24.1";
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.23.1';
4
+ exports.HATCHET_VERSION = '1.24.1';