@hatchet-dev/typescript-sdk 1.27.0 → 1.28.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.
Files changed (46) hide show
  1. package/clients/dispatcher/action-listener.js +11 -2
  2. package/clients/dispatcher/dispatcher-client.d.ts +6 -1
  3. package/clients/dispatcher/dispatcher-client.js +14 -0
  4. package/clients/dispatcher/heartbeat/heartbeat-controller.d.ts +13 -4
  5. package/clients/dispatcher/heartbeat/heartbeat-controller.js +11 -1
  6. package/clients/dispatcher/heartbeat/heartbeat-severity.d.ts +3 -0
  7. package/clients/dispatcher/heartbeat/heartbeat-severity.js +11 -0
  8. package/clients/dispatcher/heartbeat/heartbeat-worker.js +11 -4
  9. package/clients/dispatcher/listener-severity.d.ts +3 -0
  10. package/clients/dispatcher/listener-severity.js +11 -0
  11. package/clients/listeners/durable-listener/durable-listener-client.d.ts +1 -0
  12. package/clients/listeners/durable-listener/durable-listener-client.js +20 -2
  13. package/clients/rest/generated/Api.d.ts +2 -0
  14. package/clients/rest/generated/data-contracts.d.ts +2 -0
  15. package/clients/rest/generated/data-contracts.js +2 -0
  16. package/package.json +3 -3
  17. package/protoc/dispatcher/dispatcher.d.ts +67 -0
  18. package/protoc/dispatcher/dispatcher.js +495 -3
  19. package/protoc/events/events.js +1 -1
  20. package/protoc/google/protobuf/any.js +1 -1
  21. package/protoc/google/protobuf/timestamp.js +1 -1
  22. package/protoc/google/rpc/status.js +1 -1
  23. package/protoc/v1/dispatcher.js +1 -1
  24. package/protoc/v1/shared/condition.js +1 -1
  25. package/protoc/v1/shared/trigger.js +1 -1
  26. package/protoc/v1/workflows.d.ts +24 -7
  27. package/protoc/v1/workflows.js +218 -40
  28. package/protoc/workflows/workflows.js +1 -1
  29. package/util/failure-severity.d.ts +2 -0
  30. package/util/failure-severity.js +15 -0
  31. package/util/grpc-error.d.ts +6 -0
  32. package/util/grpc-error.js +11 -0
  33. package/util/workflow-run-ref.js +23 -9
  34. package/v1/client/client.d.ts +26 -1
  35. package/v1/client/client.js +6 -0
  36. package/v1/client/worker/context.js +23 -3
  37. package/v1/client/worker/worker-internal.d.ts +22 -1
  38. package/v1/client/worker/worker-internal.js +167 -2
  39. package/v1/declaration.d.ts +62 -2
  40. package/v1/declaration.js +56 -0
  41. package/v1/examples/batch_assign/workflow.d.ts +62 -0
  42. package/v1/examples/batch_assign/workflow.js +161 -0
  43. package/v1/examples/e2e-worker.js +35 -21
  44. package/v1/task.d.ts +50 -1
  45. package/version.d.ts +1 -1
  46. package/version.js +1 -1
@@ -33,6 +33,13 @@ export declare enum RunStatus {
33
33
  }
34
34
  export declare function runStatusFromJSON(object: any): RunStatus;
35
35
  export declare function runStatusToJSON(object: RunStatus): string;
36
+ export declare enum IdempotencyMethod {
37
+ TTL = 0,
38
+ STATUS = 1,
39
+ UNRECOGNIZED = -1
40
+ }
41
+ export declare function idempotencyMethodFromJSON(object: any): IdempotencyMethod;
42
+ export declare function idempotencyMethodToJSON(object: IdempotencyMethod): string;
36
43
  export declare enum ConcurrencyLimitStrategy {
37
44
  CANCEL_IN_PROGRESS = 0,
38
45
  /** DROP_NEWEST - deprecated */
@@ -45,13 +52,6 @@ export declare enum ConcurrencyLimitStrategy {
45
52
  }
46
53
  export declare function concurrencyLimitStrategyFromJSON(object: any): ConcurrencyLimitStrategy;
47
54
  export declare function concurrencyLimitStrategyToJSON(object: ConcurrencyLimitStrategy): string;
48
- export declare enum IdempotencyMethod {
49
- TTL = 0,
50
- STATUS = 1,
51
- UNRECOGNIZED = -1
52
- }
53
- export declare function idempotencyMethodFromJSON(object: any): IdempotencyMethod;
54
- export declare function idempotencyMethodToJSON(object: IdempotencyMethod): string;
55
55
  export interface CancelTasksRequest {
56
56
  /** a list of external UUIDs */
57
57
  externalIds: string[];
@@ -151,6 +151,8 @@ export interface IdempotencyConfig {
151
151
  export interface IdempotencyCollisionError {
152
152
  /** the external ID of the existing workflow run that caused the collision */
153
153
  existingRunExternalId: string;
154
+ /** the external ID of the workflow run that caused the collision */
155
+ collidingRunExternalId: string;
154
156
  }
155
157
  export interface BulkTriggerIdempotencyCollisionError {
156
158
  /** the external IDs of the successfully triggered workflow runs */
@@ -174,6 +176,18 @@ export interface Concurrency {
174
176
  /** (optional) the strategy to use when the concurrency limit is reached, default CANCEL_IN_PROGRESS */
175
177
  limitStrategy?: ConcurrencyLimitStrategy | undefined;
176
178
  }
179
+ export interface TaskBatchConfig {
180
+ /** (required) maximum items per batch */
181
+ batchMaxSize: number;
182
+ /** (optional) time before batch flushes (milliseconds) */
183
+ batchMaxIntervalMs?: number | undefined;
184
+ /** (optional) partition key for fairness (prevents mixing tenants) */
185
+ batchGroupKey?: string | undefined;
186
+ /** (optional) concurrent batches per group */
187
+ batchGroupMaxRuns?: number | undefined;
188
+ /** (optional) when true, the handler returns one value broadcast to all callers; when false (default), the handler returns a dict keyed by step run id */
189
+ broadcastOutput?: boolean | undefined;
190
+ }
177
191
  /** CreateTaskOpts represents options to create a task. */
178
192
  export interface CreateTaskOpts {
179
193
  /** (required) the task name */
@@ -210,6 +224,8 @@ export interface CreateTaskOpts {
210
224
  slotRequests: {
211
225
  [key: string]: number;
212
226
  };
227
+ /** (optional) batch execution configuration */
228
+ batch?: TaskBatchConfig | undefined;
213
229
  }
214
230
  export interface CreateTaskOpts_WorkerLabelsEntry {
215
231
  key: string;
@@ -292,6 +308,7 @@ export declare const IdempotencyCollisionError: MessageFns<IdempotencyCollisionE
292
308
  export declare const BulkTriggerIdempotencyCollisionError: MessageFns<BulkTriggerIdempotencyCollisionError>;
293
309
  export declare const DefaultFilter: MessageFns<DefaultFilter>;
294
310
  export declare const Concurrency: MessageFns<Concurrency>;
311
+ export declare const TaskBatchConfig: MessageFns<TaskBatchConfig>;
295
312
  export declare const CreateTaskOpts: MessageFns<CreateTaskOpts>;
296
313
  export declare const CreateTaskOpts_WorkerLabelsEntry: MessageFns<CreateTaskOpts_WorkerLabelsEntry>;
297
314
  export declare const CreateTaskOpts_SlotRequestsEntry: MessageFns<CreateTaskOpts_SlotRequestsEntry>;
@@ -1,21 +1,21 @@
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.8
4
+ // protoc-gen-ts_proto v2.12.0
5
5
  // protoc v3.19.1
6
6
  // source: v1/workflows.proto
7
7
  Object.defineProperty(exports, "__esModule", { value: true });
8
- exports.AdminServiceDefinition = exports.GetRunDetailsResponse_TaskRunsEntry = exports.GetRunDetailsResponse = exports.TaskRunDetail = exports.GetRunDetailsRequest = exports.CreateWorkflowVersionResponse = exports.CreateTaskRateLimit = exports.CreateTaskOpts_SlotRequestsEntry = exports.CreateTaskOpts_WorkerLabelsEntry = exports.CreateTaskOpts = exports.Concurrency = exports.DefaultFilter = exports.BulkTriggerIdempotencyCollisionError = exports.IdempotencyCollisionError = exports.IdempotencyConfig = exports.CreateWorkflowVersionRequest = exports.BranchDurableTaskResponse = exports.BranchDurableTaskRequest = exports.TriggerWorkflowRunResponse = exports.TriggerWorkflowRunRequest_DesiredWorkerLabelsEntry = exports.TriggerWorkflowRunRequest = exports.ReplayTasksResponse = exports.CancelTasksResponse = exports.TasksFilter = exports.ReplayTasksRequest = exports.CancelTasksRequest = exports.IdempotencyMethod = exports.ConcurrencyLimitStrategy = exports.RunStatus = exports.RateLimitDuration = exports.StickyStrategy = exports.protobufPackage = void 0;
8
+ exports.AdminServiceDefinition = exports.GetRunDetailsResponse_TaskRunsEntry = exports.GetRunDetailsResponse = exports.TaskRunDetail = exports.GetRunDetailsRequest = exports.CreateWorkflowVersionResponse = exports.CreateTaskRateLimit = exports.CreateTaskOpts_SlotRequestsEntry = exports.CreateTaskOpts_WorkerLabelsEntry = exports.CreateTaskOpts = exports.TaskBatchConfig = exports.Concurrency = exports.DefaultFilter = exports.BulkTriggerIdempotencyCollisionError = exports.IdempotencyCollisionError = exports.IdempotencyConfig = exports.CreateWorkflowVersionRequest = exports.BranchDurableTaskResponse = exports.BranchDurableTaskRequest = exports.TriggerWorkflowRunResponse = exports.TriggerWorkflowRunRequest_DesiredWorkerLabelsEntry = exports.TriggerWorkflowRunRequest = exports.ReplayTasksResponse = exports.CancelTasksResponse = exports.TasksFilter = exports.ReplayTasksRequest = exports.CancelTasksRequest = exports.ConcurrencyLimitStrategy = exports.IdempotencyMethod = exports.RunStatus = exports.RateLimitDuration = exports.StickyStrategy = exports.protobufPackage = void 0;
9
9
  exports.stickyStrategyFromJSON = stickyStrategyFromJSON;
10
10
  exports.stickyStrategyToJSON = stickyStrategyToJSON;
11
11
  exports.rateLimitDurationFromJSON = rateLimitDurationFromJSON;
12
12
  exports.rateLimitDurationToJSON = rateLimitDurationToJSON;
13
13
  exports.runStatusFromJSON = runStatusFromJSON;
14
14
  exports.runStatusToJSON = runStatusToJSON;
15
- exports.concurrencyLimitStrategyFromJSON = concurrencyLimitStrategyFromJSON;
16
- exports.concurrencyLimitStrategyToJSON = concurrencyLimitStrategyToJSON;
17
15
  exports.idempotencyMethodFromJSON = idempotencyMethodFromJSON;
18
16
  exports.idempotencyMethodToJSON = idempotencyMethodToJSON;
17
+ exports.concurrencyLimitStrategyFromJSON = concurrencyLimitStrategyFromJSON;
18
+ exports.concurrencyLimitStrategyToJSON = concurrencyLimitStrategyToJSON;
19
19
  /* eslint-disable */
20
20
  const wire_1 = require("@bufbuild/protobuf/wire");
21
21
  const timestamp_1 = require("../google/protobuf/timestamp");
@@ -169,6 +169,37 @@ function runStatusToJSON(object) {
169
169
  return 'UNRECOGNIZED';
170
170
  }
171
171
  }
172
+ var IdempotencyMethod;
173
+ (function (IdempotencyMethod) {
174
+ IdempotencyMethod[IdempotencyMethod["TTL"] = 0] = "TTL";
175
+ IdempotencyMethod[IdempotencyMethod["STATUS"] = 1] = "STATUS";
176
+ IdempotencyMethod[IdempotencyMethod["UNRECOGNIZED"] = -1] = "UNRECOGNIZED";
177
+ })(IdempotencyMethod || (exports.IdempotencyMethod = IdempotencyMethod = {}));
178
+ function idempotencyMethodFromJSON(object) {
179
+ switch (object) {
180
+ case 0:
181
+ case 'TTL':
182
+ return IdempotencyMethod.TTL;
183
+ case 1:
184
+ case 'STATUS':
185
+ return IdempotencyMethod.STATUS;
186
+ case -1:
187
+ case 'UNRECOGNIZED':
188
+ default:
189
+ return IdempotencyMethod.UNRECOGNIZED;
190
+ }
191
+ }
192
+ function idempotencyMethodToJSON(object) {
193
+ switch (object) {
194
+ case IdempotencyMethod.TTL:
195
+ return 'TTL';
196
+ case IdempotencyMethod.STATUS:
197
+ return 'STATUS';
198
+ case IdempotencyMethod.UNRECOGNIZED:
199
+ default:
200
+ return 'UNRECOGNIZED';
201
+ }
202
+ }
172
203
  var ConcurrencyLimitStrategy;
173
204
  (function (ConcurrencyLimitStrategy) {
174
205
  ConcurrencyLimitStrategy[ConcurrencyLimitStrategy["CANCEL_IN_PROGRESS"] = 0] = "CANCEL_IN_PROGRESS";
@@ -220,37 +251,6 @@ function concurrencyLimitStrategyToJSON(object) {
220
251
  return 'UNRECOGNIZED';
221
252
  }
222
253
  }
223
- var IdempotencyMethod;
224
- (function (IdempotencyMethod) {
225
- IdempotencyMethod[IdempotencyMethod["TTL"] = 0] = "TTL";
226
- IdempotencyMethod[IdempotencyMethod["STATUS"] = 1] = "STATUS";
227
- IdempotencyMethod[IdempotencyMethod["UNRECOGNIZED"] = -1] = "UNRECOGNIZED";
228
- })(IdempotencyMethod || (exports.IdempotencyMethod = IdempotencyMethod = {}));
229
- function idempotencyMethodFromJSON(object) {
230
- switch (object) {
231
- case 0:
232
- case 'TTL':
233
- return IdempotencyMethod.TTL;
234
- case 1:
235
- case 'STATUS':
236
- return IdempotencyMethod.STATUS;
237
- case -1:
238
- case 'UNRECOGNIZED':
239
- default:
240
- return IdempotencyMethod.UNRECOGNIZED;
241
- }
242
- }
243
- function idempotencyMethodToJSON(object) {
244
- switch (object) {
245
- case IdempotencyMethod.TTL:
246
- return 'TTL';
247
- case IdempotencyMethod.STATUS:
248
- return 'STATUS';
249
- case IdempotencyMethod.UNRECOGNIZED:
250
- default:
251
- return 'UNRECOGNIZED';
252
- }
253
- }
254
254
  function createBaseCancelTasksRequest() {
255
255
  return { externalIds: [], filter: undefined };
256
256
  }
@@ -1543,13 +1543,16 @@ exports.IdempotencyConfig = {
1543
1543
  },
1544
1544
  };
1545
1545
  function createBaseIdempotencyCollisionError() {
1546
- return { existingRunExternalId: '' };
1546
+ return { existingRunExternalId: '', collidingRunExternalId: '' };
1547
1547
  }
1548
1548
  exports.IdempotencyCollisionError = {
1549
1549
  encode(message, writer = new wire_1.BinaryWriter()) {
1550
1550
  if (message.existingRunExternalId !== '') {
1551
1551
  writer.uint32(10).string(message.existingRunExternalId);
1552
1552
  }
1553
+ if (message.collidingRunExternalId !== '') {
1554
+ writer.uint32(18).string(message.collidingRunExternalId);
1555
+ }
1553
1556
  return writer;
1554
1557
  },
1555
1558
  decode(input, length) {
@@ -1566,6 +1569,13 @@ exports.IdempotencyCollisionError = {
1566
1569
  message.existingRunExternalId = reader.string();
1567
1570
  continue;
1568
1571
  }
1572
+ case 2: {
1573
+ if (tag !== 18) {
1574
+ break;
1575
+ }
1576
+ message.collidingRunExternalId = reader.string();
1577
+ continue;
1578
+ }
1569
1579
  }
1570
1580
  if ((tag & 7) === 4 || tag === 0) {
1571
1581
  break;
@@ -1581,6 +1591,11 @@ exports.IdempotencyCollisionError = {
1581
1591
  : isSet(object.existing_run_external_id)
1582
1592
  ? globalThis.String(object.existing_run_external_id)
1583
1593
  : '',
1594
+ collidingRunExternalId: isSet(object.collidingRunExternalId)
1595
+ ? globalThis.String(object.collidingRunExternalId)
1596
+ : isSet(object.colliding_run_external_id)
1597
+ ? globalThis.String(object.colliding_run_external_id)
1598
+ : '',
1584
1599
  };
1585
1600
  },
1586
1601
  toJSON(message) {
@@ -1588,15 +1603,19 @@ exports.IdempotencyCollisionError = {
1588
1603
  if (message.existingRunExternalId !== '') {
1589
1604
  obj.existingRunExternalId = message.existingRunExternalId;
1590
1605
  }
1606
+ if (message.collidingRunExternalId !== '') {
1607
+ obj.collidingRunExternalId = message.collidingRunExternalId;
1608
+ }
1591
1609
  return obj;
1592
1610
  },
1593
1611
  create(base) {
1594
1612
  return exports.IdempotencyCollisionError.fromPartial(base !== null && base !== void 0 ? base : {});
1595
1613
  },
1596
1614
  fromPartial(object) {
1597
- var _a;
1615
+ var _a, _b;
1598
1616
  const message = createBaseIdempotencyCollisionError();
1599
1617
  message.existingRunExternalId = (_a = object.existingRunExternalId) !== null && _a !== void 0 ? _a : '';
1618
+ message.collidingRunExternalId = (_b = object.collidingRunExternalId) !== null && _b !== void 0 ? _b : '';
1600
1619
  return message;
1601
1620
  },
1602
1621
  };
@@ -1669,12 +1688,12 @@ exports.BulkTriggerIdempotencyCollisionError = {
1669
1688
  return exports.BulkTriggerIdempotencyCollisionError.fromPartial(base !== null && base !== void 0 ? base : {});
1670
1689
  },
1671
1690
  fromPartial(object) {
1672
- var _a, _b, _c, _d;
1691
+ var _a, _b;
1673
1692
  const message = createBaseBulkTriggerIdempotencyCollisionError();
1674
1693
  message.successfulWorkflowRunExternalIds =
1675
- (_b = (_a = object.successfulWorkflowRunExternalIds) === null || _a === void 0 ? void 0 : _a.map((e) => e)) !== null && _b !== void 0 ? _b : [];
1694
+ ((_a = object.successfulWorkflowRunExternalIds) === null || _a === void 0 ? void 0 : _a.map((e) => e)) || [];
1676
1695
  message.collisions =
1677
- (_d = (_c = object.collisions) === null || _c === void 0 ? void 0 : _c.map((e) => exports.IdempotencyCollisionError.fromPartial(e))) !== null && _d !== void 0 ? _d : [];
1696
+ ((_b = object.collisions) === null || _b === void 0 ? void 0 : _b.map((e) => exports.IdempotencyCollisionError.fromPartial(e))) || [];
1678
1697
  return message;
1679
1698
  },
1680
1699
  };
@@ -1854,6 +1873,146 @@ exports.Concurrency = {
1854
1873
  return message;
1855
1874
  },
1856
1875
  };
1876
+ function createBaseTaskBatchConfig() {
1877
+ return {
1878
+ batchMaxSize: 0,
1879
+ batchMaxIntervalMs: undefined,
1880
+ batchGroupKey: undefined,
1881
+ batchGroupMaxRuns: undefined,
1882
+ broadcastOutput: undefined,
1883
+ };
1884
+ }
1885
+ exports.TaskBatchConfig = {
1886
+ encode(message, writer = new wire_1.BinaryWriter()) {
1887
+ if (message.batchMaxSize !== 0) {
1888
+ writer.uint32(8).int32(message.batchMaxSize);
1889
+ }
1890
+ if (message.batchMaxIntervalMs !== undefined) {
1891
+ writer.uint32(16).int32(message.batchMaxIntervalMs);
1892
+ }
1893
+ if (message.batchGroupKey !== undefined) {
1894
+ writer.uint32(26).string(message.batchGroupKey);
1895
+ }
1896
+ if (message.batchGroupMaxRuns !== undefined) {
1897
+ writer.uint32(32).int32(message.batchGroupMaxRuns);
1898
+ }
1899
+ if (message.broadcastOutput !== undefined) {
1900
+ writer.uint32(40).bool(message.broadcastOutput);
1901
+ }
1902
+ return writer;
1903
+ },
1904
+ decode(input, length) {
1905
+ const reader = input instanceof wire_1.BinaryReader ? input : new wire_1.BinaryReader(input);
1906
+ const end = length === undefined ? reader.len : reader.pos + length;
1907
+ const message = createBaseTaskBatchConfig();
1908
+ while (reader.pos < end) {
1909
+ const tag = reader.uint32();
1910
+ switch (tag >>> 3) {
1911
+ case 1: {
1912
+ if (tag !== 8) {
1913
+ break;
1914
+ }
1915
+ message.batchMaxSize = reader.int32();
1916
+ continue;
1917
+ }
1918
+ case 2: {
1919
+ if (tag !== 16) {
1920
+ break;
1921
+ }
1922
+ message.batchMaxIntervalMs = reader.int32();
1923
+ continue;
1924
+ }
1925
+ case 3: {
1926
+ if (tag !== 26) {
1927
+ break;
1928
+ }
1929
+ message.batchGroupKey = reader.string();
1930
+ continue;
1931
+ }
1932
+ case 4: {
1933
+ if (tag !== 32) {
1934
+ break;
1935
+ }
1936
+ message.batchGroupMaxRuns = reader.int32();
1937
+ continue;
1938
+ }
1939
+ case 5: {
1940
+ if (tag !== 40) {
1941
+ break;
1942
+ }
1943
+ message.broadcastOutput = reader.bool();
1944
+ continue;
1945
+ }
1946
+ }
1947
+ if ((tag & 7) === 4 || tag === 0) {
1948
+ break;
1949
+ }
1950
+ reader.skip(tag & 7);
1951
+ }
1952
+ return message;
1953
+ },
1954
+ fromJSON(object) {
1955
+ return {
1956
+ batchMaxSize: isSet(object.batchMaxSize)
1957
+ ? globalThis.Number(object.batchMaxSize)
1958
+ : isSet(object.batch_max_size)
1959
+ ? globalThis.Number(object.batch_max_size)
1960
+ : 0,
1961
+ batchMaxIntervalMs: isSet(object.batchMaxIntervalMs)
1962
+ ? globalThis.Number(object.batchMaxIntervalMs)
1963
+ : isSet(object.batch_max_interval_ms)
1964
+ ? globalThis.Number(object.batch_max_interval_ms)
1965
+ : undefined,
1966
+ batchGroupKey: isSet(object.batchGroupKey)
1967
+ ? globalThis.String(object.batchGroupKey)
1968
+ : isSet(object.batch_group_key)
1969
+ ? globalThis.String(object.batch_group_key)
1970
+ : undefined,
1971
+ batchGroupMaxRuns: isSet(object.batchGroupMaxRuns)
1972
+ ? globalThis.Number(object.batchGroupMaxRuns)
1973
+ : isSet(object.batch_group_max_runs)
1974
+ ? globalThis.Number(object.batch_group_max_runs)
1975
+ : undefined,
1976
+ broadcastOutput: isSet(object.broadcastOutput)
1977
+ ? globalThis.Boolean(object.broadcastOutput)
1978
+ : isSet(object.broadcast_output)
1979
+ ? globalThis.Boolean(object.broadcast_output)
1980
+ : undefined,
1981
+ };
1982
+ },
1983
+ toJSON(message) {
1984
+ const obj = {};
1985
+ if (message.batchMaxSize !== 0) {
1986
+ obj.batchMaxSize = Math.round(message.batchMaxSize);
1987
+ }
1988
+ if (message.batchMaxIntervalMs !== undefined) {
1989
+ obj.batchMaxIntervalMs = Math.round(message.batchMaxIntervalMs);
1990
+ }
1991
+ if (message.batchGroupKey !== undefined) {
1992
+ obj.batchGroupKey = message.batchGroupKey;
1993
+ }
1994
+ if (message.batchGroupMaxRuns !== undefined) {
1995
+ obj.batchGroupMaxRuns = Math.round(message.batchGroupMaxRuns);
1996
+ }
1997
+ if (message.broadcastOutput !== undefined) {
1998
+ obj.broadcastOutput = message.broadcastOutput;
1999
+ }
2000
+ return obj;
2001
+ },
2002
+ create(base) {
2003
+ return exports.TaskBatchConfig.fromPartial(base !== null && base !== void 0 ? base : {});
2004
+ },
2005
+ fromPartial(object) {
2006
+ var _a, _b, _c, _d, _e;
2007
+ const message = createBaseTaskBatchConfig();
2008
+ message.batchMaxSize = (_a = object.batchMaxSize) !== null && _a !== void 0 ? _a : 0;
2009
+ message.batchMaxIntervalMs = (_b = object.batchMaxIntervalMs) !== null && _b !== void 0 ? _b : undefined;
2010
+ message.batchGroupKey = (_c = object.batchGroupKey) !== null && _c !== void 0 ? _c : undefined;
2011
+ message.batchGroupMaxRuns = (_d = object.batchGroupMaxRuns) !== null && _d !== void 0 ? _d : undefined;
2012
+ message.broadcastOutput = (_e = object.broadcastOutput) !== null && _e !== void 0 ? _e : undefined;
2013
+ return message;
2014
+ },
2015
+ };
1857
2016
  function createBaseCreateTaskOpts() {
1858
2017
  return {
1859
2018
  readableId: '',
@@ -1871,6 +2030,7 @@ function createBaseCreateTaskOpts() {
1871
2030
  scheduleTimeout: undefined,
1872
2031
  isDurable: false,
1873
2032
  slotRequests: {},
2033
+ batch: undefined,
1874
2034
  };
1875
2035
  }
1876
2036
  exports.CreateTaskOpts = {
@@ -1920,6 +2080,9 @@ exports.CreateTaskOpts = {
1920
2080
  globalThis.Object.entries(message.slotRequests).forEach(([key, value]) => {
1921
2081
  exports.CreateTaskOpts_SlotRequestsEntry.encode({ key: key, value }, writer.uint32(122).fork()).join();
1922
2082
  });
2083
+ if (message.batch !== undefined) {
2084
+ exports.TaskBatchConfig.encode(message.batch, writer.uint32(130).fork()).join();
2085
+ }
1923
2086
  return writer;
1924
2087
  },
1925
2088
  decode(input, length) {
@@ -2040,6 +2203,13 @@ exports.CreateTaskOpts = {
2040
2203
  }
2041
2204
  continue;
2042
2205
  }
2206
+ case 16: {
2207
+ if (tag !== 130) {
2208
+ break;
2209
+ }
2210
+ message.batch = exports.TaskBatchConfig.decode(reader, reader.uint32());
2211
+ continue;
2212
+ }
2043
2213
  }
2044
2214
  if ((tag & 7) === 4 || tag === 0) {
2045
2215
  break;
@@ -2113,6 +2283,7 @@ exports.CreateTaskOpts = {
2113
2283
  return acc;
2114
2284
  }, {})
2115
2285
  : {},
2286
+ batch: isSet(object.batch) ? exports.TaskBatchConfig.fromJSON(object.batch) : undefined,
2116
2287
  };
2117
2288
  },
2118
2289
  toJSON(message) {
@@ -2175,6 +2346,9 @@ exports.CreateTaskOpts = {
2175
2346
  });
2176
2347
  }
2177
2348
  }
2349
+ if (message.batch !== undefined) {
2350
+ obj.batch = exports.TaskBatchConfig.toJSON(message.batch);
2351
+ }
2178
2352
  return obj;
2179
2353
  },
2180
2354
  create(base) {
@@ -2211,6 +2385,10 @@ exports.CreateTaskOpts = {
2211
2385
  }
2212
2386
  return acc;
2213
2387
  }, {});
2388
+ message.batch =
2389
+ object.batch !== undefined && object.batch !== null
2390
+ ? exports.TaskBatchConfig.fromPartial(object.batch)
2391
+ : undefined;
2214
2392
  return message;
2215
2393
  },
2216
2394
  };
@@ -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.8
4
+ // protoc-gen-ts_proto v2.12.0
5
5
  // protoc v3.19.1
6
6
  // source: workflows/workflows.proto
7
7
  Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,2 @@
1
+ export type FailureSeverity = 'silent' | 'warn' | 'error';
2
+ export declare function classifyRepeatedFailure(isTransient: boolean, attempt: number, threshold: number): FailureSeverity;
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.classifyRepeatedFailure = classifyRepeatedFailure;
4
+ function classifyRepeatedFailure(isTransient, attempt, threshold) {
5
+ if (!isTransient) {
6
+ return 'error';
7
+ }
8
+ if (attempt >= threshold) {
9
+ return 'error';
10
+ }
11
+ if (attempt > 1) {
12
+ return 'warn';
13
+ }
14
+ return 'silent';
15
+ }
@@ -1,3 +1,9 @@
1
+ /**
2
+ * gRPC codes that typically indicate a transient connectivity problem
3
+ * (server unreachable/restarting) rather than an application-level error.
4
+ */
5
+ export declare const CONNECTION_ERROR_CODES: number[];
6
+ export declare function isConnectionError(code: number | undefined): boolean;
1
7
  /**
2
8
  * Returns the gRPC status code from an unknown value (e.g. from a catch block).
3
9
  * Used for checking Status.CANCELLED, Status.UNAVAILABLE, etc.
@@ -1,7 +1,18 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CONNECTION_ERROR_CODES = void 0;
4
+ exports.isConnectionError = isConnectionError;
3
5
  exports.getGrpcErrorCode = getGrpcErrorCode;
4
6
  exports.getGrpcErrorDetails = getGrpcErrorDetails;
7
+ const nice_grpc_1 = require("nice-grpc");
8
+ /**
9
+ * gRPC codes that typically indicate a transient connectivity problem
10
+ * (server unreachable/restarting) rather than an application-level error.
11
+ */
12
+ exports.CONNECTION_ERROR_CODES = [nice_grpc_1.Status.UNAVAILABLE, nice_grpc_1.Status.FAILED_PRECONDITION];
13
+ function isConnectionError(code) {
14
+ return code !== undefined && exports.CONNECTION_ERROR_CODES.includes(code);
15
+ }
5
16
  /**
6
17
  * Returns the gRPC status code from an unknown value (e.g. from a catch block).
7
18
  * Used for checking Status.CANCELLED, Status.UNAVAILABLE, etc.
@@ -90,17 +90,21 @@ class WorkflowRunRef {
90
90
  return new Promise((resolve, reject) => {
91
91
  (() => __awaiter(this, void 0, void 0, function* () {
92
92
  var _a, e_1, _b, _c;
93
- var _d, _e;
93
+ var _d, _e, _f;
94
94
  const signal = this.defaultSignal;
95
95
  try {
96
- for (var _f = true, _g = __asyncValues(streamable.stream({ signal })), _h; _h = yield _g.next(), _a = _h.done, !_a; _f = true) {
97
- _c = _h.value;
98
- _f = false;
96
+ for (var _g = true, _h = __asyncValues(streamable.stream({ signal })), _j; _j = yield _h.next(), _a = _j.done, !_a; _g = true) {
97
+ _c = _j.value;
98
+ _g = false;
99
99
  const event = _c;
100
100
  if (event.eventType === dispatcher_1.WorkflowRunEventType.WORKFLOW_RUN_EVENT_TYPE_FINISHED) {
101
- if (event.results.some((r) => r.error !== undefined)) {
102
- // HACK: this might replace intentional empty errors but this is the more common case
103
- const errors = event.results.map((r) => r.error !== '' ? r.error : 'task was cancelled');
101
+ // A present-but-empty error field is ambiguous (e.g. a batch member that was
102
+ // explicitly cancelled via ctx.cancel() and resolved with no further error);
103
+ // only a non-empty message is treated as a genuine failure here.
104
+ if (event.results.some((r) => r.error !== undefined && r.error !== '')) {
105
+ const errors = event.results
106
+ .filter((r) => r.error !== undefined && r.error !== '')
107
+ .map((r) => r.error);
104
108
  reject(errors);
105
109
  return;
106
110
  }
@@ -111,8 +115,18 @@ class WorkflowRunRef {
111
115
  reject(new Error('No job runs found'));
112
116
  return;
113
117
  }
118
+ // A task run that fails before ever being dispatched (e.g. a batch group-key
119
+ // CEL expression that fails to parse) never gets a StepRunResult in the
120
+ // WORKFLOW_RUN_EVENT_TYPE_FINISHED event, so `event.results` above is empty.
121
+ // Check step statuses here too, or this codepath would resolve as if the run
122
+ // had succeeded.
123
+ const failedStepRun = (_e = mostRecentJobRun.stepRuns) === null || _e === void 0 ? void 0 : _e.find((stepRun) => stepRun.status === 'FAILED' || stepRun.status === 'CANCELLED');
124
+ if (failedStepRun) {
125
+ reject(new Error(failedStepRun.error || failedStepRun.cancelledReason || 'task failed'));
126
+ return;
127
+ }
114
128
  const outputs = {};
115
- (_e = mostRecentJobRun.stepRuns) === null || _e === void 0 ? void 0 : _e.forEach((stepRun) => {
129
+ (_f = mostRecentJobRun.stepRuns) === null || _f === void 0 ? void 0 : _f.forEach((stepRun) => {
116
130
  var _a, _b;
117
131
  const readable = (_b = (_a = mostRecentJobRun.job) === null || _a === void 0 ? void 0 : _a.steps) === null || _b === void 0 ? void 0 : _b.find((step) => step.metadata.id === stepRun.stepId);
118
132
  const readableStepName = `${readable === null || readable === void 0 ? void 0 : readable.readableId}`;
@@ -143,7 +157,7 @@ class WorkflowRunRef {
143
157
  catch (e_1_1) { e_1 = { error: e_1_1 }; }
144
158
  finally {
145
159
  try {
146
- if (!_f && !_a && (_b = _g.return)) yield _b.call(_g);
160
+ if (!_g && !_a && (_b = _h.return)) yield _b.call(_h);
147
161
  }
148
162
  finally { if (e_1) throw e_1.error; }
149
163
  }
@@ -13,7 +13,8 @@ import { DispatcherClient } from '../../clients/dispatcher/dispatcher-client';
13
13
  import { Logger } from '../../util/logger';
14
14
  import { RunListenerClient } from '../../clients/listeners/run-listener/child-listener-client';
15
15
  import { DurableListenerClient } from '../../clients/listeners/durable-listener/durable-listener-client';
16
- import { CreateTaskWorkflowOpts, CreateWorkflowOpts, RunOpts, BaseWorkflowDeclaration, WorkflowDeclaration, TaskWorkflowDeclaration, CreateDurableTaskWorkflowOpts } from '../declaration';
16
+ import { CreateTaskWorkflowOpts, CreateWorkflowOpts, RunOpts, BaseWorkflowDeclaration, WorkflowDeclaration, TaskWorkflowDeclaration, CreateDurableTaskWorkflowOpts, CreateBatchTaskWorkflowOpts } from '../declaration';
17
+ import { BatchTaskFn } from '../task';
17
18
  import type { LegacyWorkflow } from '../../legacy/legacy-transformer';
18
19
  import { IHatchetClient } from './client.interface';
19
20
  import { CreateWorkerOpts, Worker } from './worker/worker';
@@ -103,6 +104,30 @@ export declare class HatchetClient<GlobalInput extends Record<string, any> = {},
103
104
  task<Fn extends (input: I, ctx?: any) => O | Promise<O>, I extends InputType = Parameters<Fn>[0] | UnknownInputType, O extends OutputType = ReturnType<Fn> extends Promise<infer P> ? P extends OutputType ? P : void : ReturnType<Fn> extends OutputType ? ReturnType<Fn> : void>(options: {
104
105
  fn: Fn;
105
106
  } & Omit<CreateTaskWorkflowOpts<I, O>, 'fn'>): TaskWorkflowDeclaration<I, O, GlobalInput, GlobalOutput, MiddlewareBefore, MiddlewareAfter>;
107
+ /**
108
+ * Creates a new batch task workflow. Batch tasks buffer concurrent runs until Hatchet
109
+ * flushes the batch (size reached or flush interval), then invoke the handler once with
110
+ * all buffered inputs keyed by each run's task-run external id. The handler must return
111
+ * a Record mapping each id to its output, or set `batch.broadcastOutput` to return the
112
+ * same result to all callers. retries is always forced to 0 for batch tasks.
113
+ *
114
+ * Preview: batch tasks are in beta and may change in future releases.
115
+ * @template I The input type for the batch task
116
+ * @template O The output type of the batch task
117
+ * @param options Batch task configuration options
118
+ * @returns A TaskWorkflowDeclaration instance
119
+ */
120
+ batchTask<I extends InputType = UnknownInputType, O extends OutputType = void>(options: CreateBatchTaskWorkflowOpts<I & Resolved<GlobalInput, MiddlewareBefore>, MergeIfNonEmpty<O, GlobalOutput>>): TaskWorkflowDeclaration<I, O, GlobalInput, GlobalOutput, MiddlewareBefore, MiddlewareAfter>;
121
+ /**
122
+ * Creates a new batch task workflow with types inferred from the function parameter.
123
+ * @template Fn The type of the batch task function
124
+ * @param options Batch task configuration options with function that defines types
125
+ * @returns A TaskWorkflowDeclaration instance with inferred types
126
+ */
127
+ batchTask<Fn extends BatchTaskFn<I, O>, I extends InputType = Parameters<Fn>[0] extends Record<string, infer II> ? II extends InputType ? II : UnknownInputType : UnknownInputType, O extends OutputType = ReturnType<Fn> extends Promise<infer P> ? P extends OutputType ? P : void : ReturnType<Fn> extends OutputType ? ReturnType<Fn> : void>(options: {
128
+ fn: Fn;
129
+ batch: CreateBatchTaskWorkflowOpts<I, O>['batch'];
130
+ } & Omit<CreateBatchTaskWorkflowOpts<I, O>, 'fn' | 'batch'>): TaskWorkflowDeclaration<I, O, GlobalInput, GlobalOutput, MiddlewareBefore, MiddlewareAfter>;
106
131
  /**
107
132
  * Creates a new durable task workflow.
108
133
  * Types can be explicitly specified as generics or inferred from the function signature.
@@ -166,6 +166,12 @@ class HatchetClient {
166
166
  task(options) {
167
167
  return (0, declaration_1.CreateTaskWorkflow)(options, this);
168
168
  }
169
+ /**
170
+ * Implementation of the batchTask method.
171
+ */
172
+ batchTask(options) {
173
+ return (0, declaration_1.CreateBatchTaskWorkflow)(options, this);
174
+ }
169
175
  /**
170
176
  * Implementation of the durableTask method.
171
177
  */