@hatchet-dev/typescript-sdk 1.26.2 → 1.28.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.
Files changed (34) hide show
  1. package/clients/dispatcher/dispatcher-client.d.ts +6 -1
  2. package/clients/dispatcher/dispatcher-client.js +14 -0
  3. package/clients/rest/generated/Api.d.ts +2 -0
  4. package/clients/rest/generated/data-contracts.d.ts +2 -0
  5. package/clients/rest/generated/data-contracts.js +2 -0
  6. package/package.json +1 -1
  7. package/protoc/dispatcher/dispatcher.d.ts +67 -0
  8. package/protoc/dispatcher/dispatcher.js +495 -3
  9. package/protoc/events/events.js +1 -1
  10. package/protoc/google/protobuf/any.js +1 -1
  11. package/protoc/google/protobuf/timestamp.js +1 -1
  12. package/protoc/google/rpc/status.js +1 -1
  13. package/protoc/v1/dispatcher.js +1 -1
  14. package/protoc/v1/shared/condition.js +1 -1
  15. package/protoc/v1/shared/trigger.js +1 -1
  16. package/protoc/v1/workflows.d.ts +27 -1
  17. package/protoc/v1/workflows.js +235 -9
  18. package/protoc/workflows/workflows.js +1 -1
  19. package/util/workflow-run-ref.js +23 -9
  20. package/v1/client/client.d.ts +26 -1
  21. package/v1/client/client.js +6 -0
  22. package/v1/client/worker/context.js +23 -3
  23. package/v1/client/worker/worker-internal.d.ts +22 -1
  24. package/v1/client/worker/worker-internal.js +174 -3
  25. package/v1/declaration.d.ts +62 -2
  26. package/v1/declaration.js +56 -0
  27. package/v1/examples/batch_assign/workflow.d.ts +62 -0
  28. package/v1/examples/batch_assign/workflow.js +161 -0
  29. package/v1/examples/e2e-worker.js +35 -21
  30. package/v1/examples/idempotency/workflow.d.ts +3 -0
  31. package/v1/examples/idempotency/workflow.js +14 -1
  32. package/v1/task.d.ts +63 -2
  33. package/version.d.ts +1 -1
  34. 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 */
@@ -136,12 +143,16 @@ export interface CreateWorkflowVersionRequest {
136
143
  export interface IdempotencyConfig {
137
144
  /** a CEL expression for determining the idempotency key for workflow runs */
138
145
  expression: string;
139
- /** time-to-live for idempotency keys in milliseconds */
146
+ /** time-to-live for idempotency keys in milliseconds. if the method is `STATUS`, this is a "fallback" - the longest the key can live before it's evicted */
140
147
  ttlMs: number;
148
+ /** the method to use for idempotency, defaults to TTL */
149
+ method?: IdempotencyMethod | undefined;
141
150
  }
142
151
  export interface IdempotencyCollisionError {
143
152
  /** the external ID of the existing workflow run that caused the collision */
144
153
  existingRunExternalId: string;
154
+ /** the external ID of the workflow run that caused the collision */
155
+ collidingRunExternalId: string;
145
156
  }
146
157
  export interface BulkTriggerIdempotencyCollisionError {
147
158
  /** the external IDs of the successfully triggered workflow runs */
@@ -165,6 +176,18 @@ export interface Concurrency {
165
176
  /** (optional) the strategy to use when the concurrency limit is reached, default CANCEL_IN_PROGRESS */
166
177
  limitStrategy?: ConcurrencyLimitStrategy | undefined;
167
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
+ }
168
191
  /** CreateTaskOpts represents options to create a task. */
169
192
  export interface CreateTaskOpts {
170
193
  /** (required) the task name */
@@ -201,6 +224,8 @@ export interface CreateTaskOpts {
201
224
  slotRequests: {
202
225
  [key: string]: number;
203
226
  };
227
+ /** (optional) batch execution configuration */
228
+ batch?: TaskBatchConfig | undefined;
204
229
  }
205
230
  export interface CreateTaskOpts_WorkerLabelsEntry {
206
231
  key: string;
@@ -283,6 +308,7 @@ export declare const IdempotencyCollisionError: MessageFns<IdempotencyCollisionE
283
308
  export declare const BulkTriggerIdempotencyCollisionError: MessageFns<BulkTriggerIdempotencyCollisionError>;
284
309
  export declare const DefaultFilter: MessageFns<DefaultFilter>;
285
310
  export declare const Concurrency: MessageFns<Concurrency>;
311
+ export declare const TaskBatchConfig: MessageFns<TaskBatchConfig>;
286
312
  export declare const CreateTaskOpts: MessageFns<CreateTaskOpts>;
287
313
  export declare const CreateTaskOpts_WorkerLabelsEntry: MessageFns<CreateTaskOpts_WorkerLabelsEntry>;
288
314
  export declare const CreateTaskOpts_SlotRequestsEntry: MessageFns<CreateTaskOpts_SlotRequestsEntry>;
@@ -1,17 +1,19 @@
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.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.idempotencyMethodFromJSON = idempotencyMethodFromJSON;
16
+ exports.idempotencyMethodToJSON = idempotencyMethodToJSON;
15
17
  exports.concurrencyLimitStrategyFromJSON = concurrencyLimitStrategyFromJSON;
16
18
  exports.concurrencyLimitStrategyToJSON = concurrencyLimitStrategyToJSON;
17
19
  /* eslint-disable */
@@ -167,6 +169,37 @@ function runStatusToJSON(object) {
167
169
  return 'UNRECOGNIZED';
168
170
  }
169
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
+ }
170
203
  var ConcurrencyLimitStrategy;
171
204
  (function (ConcurrencyLimitStrategy) {
172
205
  ConcurrencyLimitStrategy[ConcurrencyLimitStrategy["CANCEL_IN_PROGRESS"] = 0] = "CANCEL_IN_PROGRESS";
@@ -1422,7 +1455,7 @@ exports.CreateWorkflowVersionRequest = {
1422
1455
  },
1423
1456
  };
1424
1457
  function createBaseIdempotencyConfig() {
1425
- return { expression: '', ttlMs: 0 };
1458
+ return { expression: '', ttlMs: 0, method: undefined };
1426
1459
  }
1427
1460
  exports.IdempotencyConfig = {
1428
1461
  encode(message, writer = new wire_1.BinaryWriter()) {
@@ -1432,6 +1465,9 @@ exports.IdempotencyConfig = {
1432
1465
  if (message.ttlMs !== 0) {
1433
1466
  writer.uint32(16).int64(message.ttlMs);
1434
1467
  }
1468
+ if (message.method !== undefined) {
1469
+ writer.uint32(24).int32(message.method);
1470
+ }
1435
1471
  return writer;
1436
1472
  },
1437
1473
  decode(input, length) {
@@ -1455,6 +1491,13 @@ exports.IdempotencyConfig = {
1455
1491
  message.ttlMs = longToNumber(reader.int64());
1456
1492
  continue;
1457
1493
  }
1494
+ case 3: {
1495
+ if (tag !== 24) {
1496
+ break;
1497
+ }
1498
+ message.method = reader.int32();
1499
+ continue;
1500
+ }
1458
1501
  }
1459
1502
  if ((tag & 7) === 4 || tag === 0) {
1460
1503
  break;
@@ -1471,6 +1514,7 @@ exports.IdempotencyConfig = {
1471
1514
  : isSet(object.ttl_ms)
1472
1515
  ? globalThis.Number(object.ttl_ms)
1473
1516
  : 0,
1517
+ method: isSet(object.method) ? idempotencyMethodFromJSON(object.method) : undefined,
1474
1518
  };
1475
1519
  },
1476
1520
  toJSON(message) {
@@ -1481,27 +1525,34 @@ exports.IdempotencyConfig = {
1481
1525
  if (message.ttlMs !== 0) {
1482
1526
  obj.ttlMs = Math.round(message.ttlMs);
1483
1527
  }
1528
+ if (message.method !== undefined) {
1529
+ obj.method = idempotencyMethodToJSON(message.method);
1530
+ }
1484
1531
  return obj;
1485
1532
  },
1486
1533
  create(base) {
1487
1534
  return exports.IdempotencyConfig.fromPartial(base !== null && base !== void 0 ? base : {});
1488
1535
  },
1489
1536
  fromPartial(object) {
1490
- var _a, _b;
1537
+ var _a, _b, _c;
1491
1538
  const message = createBaseIdempotencyConfig();
1492
1539
  message.expression = (_a = object.expression) !== null && _a !== void 0 ? _a : '';
1493
1540
  message.ttlMs = (_b = object.ttlMs) !== null && _b !== void 0 ? _b : 0;
1541
+ message.method = (_c = object.method) !== null && _c !== void 0 ? _c : undefined;
1494
1542
  return message;
1495
1543
  },
1496
1544
  };
1497
1545
  function createBaseIdempotencyCollisionError() {
1498
- return { existingRunExternalId: '' };
1546
+ return { existingRunExternalId: '', collidingRunExternalId: '' };
1499
1547
  }
1500
1548
  exports.IdempotencyCollisionError = {
1501
1549
  encode(message, writer = new wire_1.BinaryWriter()) {
1502
1550
  if (message.existingRunExternalId !== '') {
1503
1551
  writer.uint32(10).string(message.existingRunExternalId);
1504
1552
  }
1553
+ if (message.collidingRunExternalId !== '') {
1554
+ writer.uint32(18).string(message.collidingRunExternalId);
1555
+ }
1505
1556
  return writer;
1506
1557
  },
1507
1558
  decode(input, length) {
@@ -1518,6 +1569,13 @@ exports.IdempotencyCollisionError = {
1518
1569
  message.existingRunExternalId = reader.string();
1519
1570
  continue;
1520
1571
  }
1572
+ case 2: {
1573
+ if (tag !== 18) {
1574
+ break;
1575
+ }
1576
+ message.collidingRunExternalId = reader.string();
1577
+ continue;
1578
+ }
1521
1579
  }
1522
1580
  if ((tag & 7) === 4 || tag === 0) {
1523
1581
  break;
@@ -1533,6 +1591,11 @@ exports.IdempotencyCollisionError = {
1533
1591
  : isSet(object.existing_run_external_id)
1534
1592
  ? globalThis.String(object.existing_run_external_id)
1535
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
+ : '',
1536
1599
  };
1537
1600
  },
1538
1601
  toJSON(message) {
@@ -1540,15 +1603,19 @@ exports.IdempotencyCollisionError = {
1540
1603
  if (message.existingRunExternalId !== '') {
1541
1604
  obj.existingRunExternalId = message.existingRunExternalId;
1542
1605
  }
1606
+ if (message.collidingRunExternalId !== '') {
1607
+ obj.collidingRunExternalId = message.collidingRunExternalId;
1608
+ }
1543
1609
  return obj;
1544
1610
  },
1545
1611
  create(base) {
1546
1612
  return exports.IdempotencyCollisionError.fromPartial(base !== null && base !== void 0 ? base : {});
1547
1613
  },
1548
1614
  fromPartial(object) {
1549
- var _a;
1615
+ var _a, _b;
1550
1616
  const message = createBaseIdempotencyCollisionError();
1551
1617
  message.existingRunExternalId = (_a = object.existingRunExternalId) !== null && _a !== void 0 ? _a : '';
1618
+ message.collidingRunExternalId = (_b = object.collidingRunExternalId) !== null && _b !== void 0 ? _b : '';
1552
1619
  return message;
1553
1620
  },
1554
1621
  };
@@ -1621,12 +1688,12 @@ exports.BulkTriggerIdempotencyCollisionError = {
1621
1688
  return exports.BulkTriggerIdempotencyCollisionError.fromPartial(base !== null && base !== void 0 ? base : {});
1622
1689
  },
1623
1690
  fromPartial(object) {
1624
- var _a, _b, _c, _d;
1691
+ var _a, _b;
1625
1692
  const message = createBaseBulkTriggerIdempotencyCollisionError();
1626
1693
  message.successfulWorkflowRunExternalIds =
1627
- (_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)) || [];
1628
1695
  message.collisions =
1629
- (_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))) || [];
1630
1697
  return message;
1631
1698
  },
1632
1699
  };
@@ -1806,6 +1873,146 @@ exports.Concurrency = {
1806
1873
  return message;
1807
1874
  },
1808
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
+ };
1809
2016
  function createBaseCreateTaskOpts() {
1810
2017
  return {
1811
2018
  readableId: '',
@@ -1823,6 +2030,7 @@ function createBaseCreateTaskOpts() {
1823
2030
  scheduleTimeout: undefined,
1824
2031
  isDurable: false,
1825
2032
  slotRequests: {},
2033
+ batch: undefined,
1826
2034
  };
1827
2035
  }
1828
2036
  exports.CreateTaskOpts = {
@@ -1872,6 +2080,9 @@ exports.CreateTaskOpts = {
1872
2080
  globalThis.Object.entries(message.slotRequests).forEach(([key, value]) => {
1873
2081
  exports.CreateTaskOpts_SlotRequestsEntry.encode({ key: key, value }, writer.uint32(122).fork()).join();
1874
2082
  });
2083
+ if (message.batch !== undefined) {
2084
+ exports.TaskBatchConfig.encode(message.batch, writer.uint32(130).fork()).join();
2085
+ }
1875
2086
  return writer;
1876
2087
  },
1877
2088
  decode(input, length) {
@@ -1992,6 +2203,13 @@ exports.CreateTaskOpts = {
1992
2203
  }
1993
2204
  continue;
1994
2205
  }
2206
+ case 16: {
2207
+ if (tag !== 130) {
2208
+ break;
2209
+ }
2210
+ message.batch = exports.TaskBatchConfig.decode(reader, reader.uint32());
2211
+ continue;
2212
+ }
1995
2213
  }
1996
2214
  if ((tag & 7) === 4 || tag === 0) {
1997
2215
  break;
@@ -2065,6 +2283,7 @@ exports.CreateTaskOpts = {
2065
2283
  return acc;
2066
2284
  }, {})
2067
2285
  : {},
2286
+ batch: isSet(object.batch) ? exports.TaskBatchConfig.fromJSON(object.batch) : undefined,
2068
2287
  };
2069
2288
  },
2070
2289
  toJSON(message) {
@@ -2127,6 +2346,9 @@ exports.CreateTaskOpts = {
2127
2346
  });
2128
2347
  }
2129
2348
  }
2349
+ if (message.batch !== undefined) {
2350
+ obj.batch = exports.TaskBatchConfig.toJSON(message.batch);
2351
+ }
2130
2352
  return obj;
2131
2353
  },
2132
2354
  create(base) {
@@ -2163,6 +2385,10 @@ exports.CreateTaskOpts = {
2163
2385
  }
2164
2386
  return acc;
2165
2387
  }, {});
2388
+ message.batch =
2389
+ object.batch !== undefined && object.batch !== null
2390
+ ? exports.TaskBatchConfig.fromPartial(object.batch)
2391
+ : undefined;
2166
2392
  return message;
2167
2393
  },
2168
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 });
@@ -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
  */
@@ -29,6 +29,7 @@ const parse_1 = require("../../../util/parse");
29
29
  const conditions_1 = require("../../conditions");
30
30
  const transformer_1 = require("../../conditions/transformer");
31
31
  const condition_1 = require("../../../protoc/v1/shared/condition");
32
+ const dispatcher_1 = require("../../../protoc/dispatcher");
32
33
  const apply_namespace_1 = require("../../../util/apply-namespace");
33
34
  const abort_error_1 = require("../../../util/abort-error");
34
35
  const parent_run_context_vars_1 = require("../../parent-run-context-vars");
@@ -135,9 +136,28 @@ class Context {
135
136
  }
136
137
  cancel() {
137
138
  return __awaiter(this, void 0, void 0, function* () {
138
- yield this.v1.runs.cancel({
139
- ids: [this.action.taskRunExternalId],
140
- });
139
+ var _a, _b;
140
+ if (this.action.batchId) {
141
+ // Batch tasks share one context across every buffered member, so there is no single
142
+ // task-run id to cancel — cancel every member of the batch instead. `this.data` is
143
+ // the raw batch-items map for a START_BATCH action, keyed by each member's
144
+ // task-run external id.
145
+ const memberIds = Object.keys((_a = this.data) !== null && _a !== void 0 ? _a : {});
146
+ yield this.v1.dispatcher.sendBatchActionEvent({
147
+ workerId: (_b = this.worker.id()) !== null && _b !== void 0 ? _b : '',
148
+ jobId: this.action.jobId,
149
+ actionId: this.action.actionId,
150
+ batchId: this.action.batchId,
151
+ eventTimestamp: new Date(),
152
+ eventType: dispatcher_1.StepActionEventType.STEP_EVENT_TYPE_CANCELLED,
153
+ items: memberIds.map((id) => ({ taskRunExternalId: id, eventPayload: '' })),
154
+ });
155
+ }
156
+ else {
157
+ yield this.v1.runs.cancel({
158
+ ids: [this.action.taskRunExternalId],
159
+ });
160
+ }
141
161
  // optimistically abort the run
142
162
  this.controller.abort();
143
163
  });