@hatchet-dev/typescript-sdk 0.14.0 → 0.15.1-alpha0

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.
@@ -12,6 +12,17 @@ type WorkflowMetricsQuery = {
12
12
  status?: WorkflowRunStatus;
13
13
  groupKey?: string;
14
14
  };
15
+ export type WorkflowRun<T = object> = {
16
+ workflowName: string;
17
+ input: T;
18
+ options?: {
19
+ parentId?: string | undefined;
20
+ parentStepRunId?: string | undefined;
21
+ childIndex?: number | undefined;
22
+ childKey?: string | undefined;
23
+ additionalMetadata?: Record<string, string> | undefined;
24
+ };
25
+ };
15
26
  /**
16
27
  * AdminClient is a client for interacting with the Hatchet Admin API. This allows you to configure, trigger,
17
28
  * and monitor workflows.
@@ -78,6 +89,24 @@ export declare class AdminClient {
78
89
  additionalMetadata?: Record<string, string> | undefined;
79
90
  desiredWorkerId?: string | undefined;
80
91
  }): WorkflowRunRef<P>;
92
+ /**
93
+ * Run multiple workflows runs with the given input and options. This will create new workflow runs and return their IDs.
94
+ * Order is preserved in the response.
95
+ * @param workflowRuns an array of objects containing the workflow name, input, and options for each workflow run
96
+ * @returns an array of workflow run references
97
+ */
98
+ runWorkflows<Q = object, P = object>(workflowRuns: Array<{
99
+ workflowName: string;
100
+ input: Q;
101
+ options?: {
102
+ parentId?: string | undefined;
103
+ parentStepRunId?: string | undefined;
104
+ childIndex?: number | undefined;
105
+ childKey?: string | undefined;
106
+ additionalMetadata?: Record<string, string> | undefined;
107
+ desiredWorkerId?: string | undefined;
108
+ };
109
+ }>): Promise<WorkflowRunRef<P>[]>;
81
110
  /**
82
111
  * @deprecated use listWorkflows instead
83
112
  */
@@ -127,6 +127,40 @@ class AdminClient {
127
127
  throw new hatchet_error_1.default(e.message);
128
128
  }
129
129
  }
130
+ /**
131
+ * Run multiple workflows runs with the given input and options. This will create new workflow runs and return their IDs.
132
+ * Order is preserved in the response.
133
+ * @param workflowRuns an array of objects containing the workflow name, input, and options for each workflow run
134
+ * @returns an array of workflow run references
135
+ */
136
+ runWorkflows(workflowRuns) {
137
+ // Prepare workflows to be triggered in bulk
138
+ const workflowRequests = workflowRuns.map(({ workflowName, input, options }) => {
139
+ let computedName = workflowName;
140
+ if (this.config.namespace && !workflowName.startsWith(this.config.namespace)) {
141
+ computedName = this.config.namespace + workflowName;
142
+ }
143
+ const inputStr = JSON.stringify(input);
144
+ return Object.assign(Object.assign({ name: computedName, input: inputStr }, options), { additionalMetadata: (options === null || options === void 0 ? void 0 : options.additionalMetadata)
145
+ ? JSON.stringify(options.additionalMetadata)
146
+ : undefined });
147
+ });
148
+ try {
149
+ // Call the bulk trigger workflow method
150
+ const bulkTriggerWorkflowResponse = this.client.bulkTriggerWorkflow(workflows_1.BulkTriggerWorkflowRequest.create({
151
+ workflows: workflowRequests,
152
+ }));
153
+ return bulkTriggerWorkflowResponse.then((res) => {
154
+ return res.workflowRunIds.map((resp, index) => {
155
+ const { options } = workflowRuns[index];
156
+ return new workflow_run_ref_1.default(resp, this.listenerClient, options === null || options === void 0 ? void 0 : options.parentId);
157
+ });
158
+ });
159
+ }
160
+ catch (e) {
161
+ throw new hatchet_error_1.default(e.message);
162
+ }
163
+ }
130
164
  /**
131
165
  * @deprecated use listWorkflows instead
132
166
  */
@@ -11,7 +11,6 @@ export declare class Streamable {
11
11
  export declare class GrpcPooledListener {
12
12
  listener: AsyncIterable<WorkflowRunEvent> | undefined;
13
13
  requestEmitter: EventEmitter<[never]>;
14
- signal: AbortController;
15
14
  client: ListenerClient;
16
15
  subscribers: Record<string, Streamable>;
17
16
  onFinish: () => void;
@@ -38,7 +38,7 @@ const events_1 = require("events");
38
38
  const dispatcher_1 = require("../../protoc/dispatcher");
39
39
  const abort_controller_x_1 = require("abort-controller-x");
40
40
  const sleep_1 = __importDefault(require("../../util/sleep"));
41
- const DEFAULT_EVENT_LISTENER_RETRY_INTERVAL = 5; // seconds
41
+ const DEFAULT_EVENT_LISTENER_RETRY_INTERVAL = 0.5; // seconds
42
42
  const DEFAULT_EVENT_LISTENER_RETRY_COUNT = 20;
43
43
  class Streamable {
44
44
  constructor(listener, id) {
@@ -61,7 +61,6 @@ exports.Streamable = Streamable;
61
61
  class GrpcPooledListener {
62
62
  constructor(client, onFinish) {
63
63
  this.requestEmitter = new events_1.EventEmitter();
64
- this.signal = new AbortController();
65
64
  this.subscribers = {};
66
65
  this.onFinish = () => { };
67
66
  this.client = client;
@@ -79,9 +78,7 @@ class GrpcPooledListener {
79
78
  }
80
79
  try {
81
80
  this.client.logger.debug('Initializing child-listener');
82
- this.listener = this.client.client.subscribeToWorkflowRuns(this.request(), {
83
- signal: this.signal.signal,
84
- });
81
+ this.listener = this.client.client.subscribeToWorkflowRuns(this.request(), {});
85
82
  if (retries > 0)
86
83
  setTimeout(() => this.replayRequests(), 100);
87
84
  try {
@@ -97,8 +94,7 @@ class GrpcPooledListener {
97
94
  if (Object.keys(this.subscribers).length === 0) {
98
95
  // FIXME it would be better to cleanup on parent complete
99
96
  this.client.logger.debug('All subscriptions finished, cleaning up listener');
100
- this.signal.abort();
101
- this.onFinish();
97
+ break;
102
98
  }
103
99
  }
104
100
  }
@@ -113,13 +109,14 @@ class GrpcPooledListener {
113
109
  }
114
110
  }
115
111
  catch (e) {
116
- if ((0, abort_controller_x_1.isAbortError)(e)) {
117
- this.client.logger.debug('Child Listener aborted');
112
+ if (!(0, abort_controller_x_1.isAbortError)(e)) {
113
+ this.client.logger.error(`Error in child-listener: ${e.message}`);
114
+ this.init(retries + 1);
118
115
  return;
119
116
  }
120
- this.client.logger.error(`Error in child-listener: ${e.message}`);
121
- this.init(retries + 1);
117
+ this.client.logger.debug('Child Listener aborted');
122
118
  }
119
+ this.onFinish();
123
120
  });
124
121
  }
125
122
  subscribe(request) {
@@ -1,4 +1,4 @@
1
- import { AcceptInviteRequest, APIErrors, APIMeta, BulkCreateEventRequest, BulkCreateEventResponse, CancelEventRequest, CreateAPITokenRequest, CreateAPITokenResponse, CreateEventRequest, CreateSNSIntegrationRequest, CreateTenantAlertEmailGroupRequest, CreateTenantInviteRequest, CreateTenantRequest, Event, EventData, EventKey, EventKeyList, EventList, EventOrderByDirection, EventOrderByField, EventSearch, ListAPIMetaIntegration, ListAPITokensResponse, ListSlackWebhooks, ListSNSIntegrations, LogLineLevelField, LogLineList, LogLineOrderByDirection, LogLineOrderByField, LogLineSearch, RateLimitList, RateLimitOrderByDirection, RateLimitOrderByField, RejectInviteRequest, ReplayEventRequest, ReplayWorkflowRunsRequest, ReplayWorkflowRunsResponse, RerunStepRunRequest, SNSIntegration, StepRun, StepRunArchiveList, StepRunEventList, Tenant, TenantAlertEmailGroup, TenantAlertEmailGroupList, TenantAlertingSettings, TenantInvite, TenantInviteList, TenantMember, TenantMemberList, TenantQueueMetrics, TenantResourcePolicy, TriggerWorkflowRunRequest, UpdateTenantAlertEmailGroupRequest, UpdateTenantInviteRequest, UpdateTenantRequest, UpdateWorkerRequest, User, UserChangePasswordRequest, UserLoginRequest, UserRegisterRequest, UserTenantMembershipsList, WebhookWorkerCreated, WebhookWorkerCreateRequest, WebhookWorkerListResponse, WebhookWorkerRequestListResponse, Worker, WorkerList, Workflow, WorkflowID, WorkflowKindList, WorkflowList, WorkflowMetrics, WorkflowRun, WorkflowRunList, WorkflowRunOrderByDirection, WorkflowRunOrderByField, WorkflowRunsCancelRequest, WorkflowRunShape, WorkflowRunsMetrics, WorkflowRunStatus, WorkflowRunStatusList, WorkflowUpdateRequest, WorkflowVersion, WorkflowWorkersCount } from './data-contracts';
1
+ import { AcceptInviteRequest, APIErrors, APIMeta, BulkCreateEventRequest, BulkCreateEventResponse, CancelEventRequest, CreateAPITokenRequest, CreateAPITokenResponse, CreateEventRequest, CreateSNSIntegrationRequest, CreateTenantAlertEmailGroupRequest, CreateTenantInviteRequest, CreateTenantRequest, Event, EventData, EventKey, EventKeyList, EventList, EventOrderByDirection, EventOrderByField, EventSearch, ListAPIMetaIntegration, ListAPITokensResponse, ListSlackWebhooks, ListSNSIntegrations, LogLineLevelField, LogLineList, LogLineOrderByDirection, LogLineOrderByField, LogLineSearch, RateLimitList, RateLimitOrderByDirection, RateLimitOrderByField, RejectInviteRequest, ReplayEventRequest, ReplayWorkflowRunsRequest, ReplayWorkflowRunsResponse, RerunStepRunRequest, SNSIntegration, StepRun, StepRunArchiveList, StepRunEventList, Tenant, TenantAlertEmailGroup, TenantAlertEmailGroupList, TenantAlertingSettings, TenantInvite, TenantInviteList, TenantMember, TenantMemberList, TenantQueueMetrics, TenantResourcePolicy, TenantStepRunQueueMetrics, TriggerWorkflowRunRequest, UpdateTenantAlertEmailGroupRequest, UpdateTenantInviteRequest, UpdateTenantRequest, UpdateWorkerRequest, User, UserChangePasswordRequest, UserLoginRequest, UserRegisterRequest, UserTenantMembershipsList, WebhookWorkerCreated, WebhookWorkerCreateRequest, WebhookWorkerListResponse, WebhookWorkerRequestListResponse, Worker, WorkerList, Workflow, WorkflowID, WorkflowKindList, WorkflowList, WorkflowMetrics, WorkflowRun, WorkflowRunList, WorkflowRunOrderByDirection, WorkflowRunOrderByField, WorkflowRunsCancelRequest, WorkflowRunShape, WorkflowRunsMetrics, WorkflowRunStatus, WorkflowRunStatusList, WorkflowUpdateRequest, WorkflowVersion, WorkflowWorkersCount } from './data-contracts';
2
2
  import { HttpClient, RequestParams } from './http-client';
3
3
  export declare class Api<SecurityDataType = unknown> extends HttpClient<SecurityDataType> {
4
4
  /**
@@ -416,6 +416,16 @@ export declare class Api<SecurityDataType = unknown> extends HttpClient<Security
416
416
  */
417
417
  additionalMetadata?: string[];
418
418
  }, params?: RequestParams) => Promise<import("axios").AxiosResponse<TenantQueueMetrics, any>>;
419
+ /**
420
+ * @description Get the queue metrics for the tenant
421
+ *
422
+ * @tags Tenant
423
+ * @name TenantGetStepRunQueueMetrics
424
+ * @summary Get step run metrics
425
+ * @request GET:/api/v1/tenants/{tenant}/step-run-queue-metrics
426
+ * @secure
427
+ */
428
+ tenantGetStepRunQueueMetrics: (tenant: string, params?: RequestParams) => Promise<import("axios").AxiosResponse<TenantStepRunQueueMetrics, any>>;
419
429
  /**
420
430
  * @description Lists all events for a tenant.
421
431
  *
@@ -422,6 +422,16 @@ class Api extends http_client_1.HttpClient {
422
422
  * @secure
423
423
  */
424
424
  this.tenantGetQueueMetrics = (tenant, query, params = {}) => this.request(Object.assign({ path: `/api/v1/tenants/${tenant}/queue-metrics`, method: 'GET', query: query, secure: true, format: 'json' }, params));
425
+ /**
426
+ * @description Get the queue metrics for the tenant
427
+ *
428
+ * @tags Tenant
429
+ * @name TenantGetStepRunQueueMetrics
430
+ * @summary Get step run metrics
431
+ * @request GET:/api/v1/tenants/{tenant}/step-run-queue-metrics
432
+ * @secure
433
+ */
434
+ this.tenantGetStepRunQueueMetrics = (tenant, params = {}) => this.request(Object.assign({ path: `/api/v1/tenants/${tenant}/step-run-queue-metrics`, method: 'GET', secure: true, format: 'json' }, params));
425
435
  /**
426
436
  * @description Lists all events for a tenant.
427
437
  *
@@ -316,6 +316,9 @@ export interface TenantQueueMetrics {
316
316
  workflow?: Record<string, QueueMetrics>;
317
317
  queues?: Record<string, number>;
318
318
  }
319
+ export interface TenantStepRunQueueMetrics {
320
+ queues?: Record<string, number>;
321
+ }
319
322
  export interface AcceptInviteRequest {
320
323
  /**
321
324
  * @minLength 36
@@ -792,6 +795,7 @@ export declare enum StepRunEventReason {
792
795
  SCHEDULING_TIMED_OUT = "SCHEDULING_TIMED_OUT",
793
796
  ASSIGNED = "ASSIGNED",
794
797
  STARTED = "STARTED",
798
+ ACKNOWLEDGED = "ACKNOWLEDGED",
795
799
  FINISHED = "FINISHED",
796
800
  FAILED = "FAILED",
797
801
  RETRYING = "RETRYING",
@@ -98,6 +98,7 @@ var StepRunEventReason;
98
98
  StepRunEventReason["SCHEDULING_TIMED_OUT"] = "SCHEDULING_TIMED_OUT";
99
99
  StepRunEventReason["ASSIGNED"] = "ASSIGNED";
100
100
  StepRunEventReason["STARTED"] = "STARTED";
101
+ StepRunEventReason["ACKNOWLEDGED"] = "ACKNOWLEDGED";
101
102
  StepRunEventReason["FINISHED"] = "FINISHED";
102
103
  StepRunEventReason["FAILED"] = "FAILED";
103
104
  StepRunEventReason["RETRYING"] = "RETRYING";
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,74 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __asyncValues = (this && this.__asyncValues) || function (o) {
12
+ if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
13
+ var m = o[Symbol.asyncIterator], i;
14
+ return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
15
+ function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
16
+ function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
17
+ };
18
+ var __importDefault = (this && this.__importDefault) || function (mod) {
19
+ return (mod && mod.__esModule) ? mod : { "default": mod };
20
+ };
21
+ Object.defineProperty(exports, "__esModule", { value: true });
22
+ const sdk_1 = __importDefault(require("../sdk"));
23
+ const hatchet = sdk_1.default.init();
24
+ function main() {
25
+ return __awaiter(this, void 0, void 0, function* () {
26
+ const workflowRuns = [];
27
+ workflowRuns[0] = {
28
+ workflowName: 'bulk-parent-workflow',
29
+ input: {},
30
+ options: {
31
+ additionalMetadata: {
32
+ key: 'value',
33
+ },
34
+ },
35
+ };
36
+ workflowRuns[1] = {
37
+ workflowName: 'bulk-parent-workflow',
38
+ input: { second: 'second' },
39
+ options: {
40
+ additionalMetadata: {
41
+ key: 'value',
42
+ },
43
+ },
44
+ };
45
+ try {
46
+ const workflowRunResponse = hatchet.admin.runWorkflows(workflowRuns);
47
+ const result = yield workflowRunResponse;
48
+ console.log('result', result);
49
+ result.forEach((workflowRun) => __awaiter(this, void 0, void 0, function* () {
50
+ var _a, e_1, _b, _c;
51
+ const stream = yield workflowRun.stream();
52
+ try {
53
+ for (var _d = true, stream_1 = __asyncValues(stream), stream_1_1; stream_1_1 = yield stream_1.next(), _a = stream_1_1.done, !_a; _d = true) {
54
+ _c = stream_1_1.value;
55
+ _d = false;
56
+ const event = _c;
57
+ console.log('event received', event);
58
+ }
59
+ }
60
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
61
+ finally {
62
+ try {
63
+ if (!_d && !_a && (_b = stream_1.return)) yield _b.call(stream_1);
64
+ }
65
+ finally { if (e_1) throw e_1.error; }
66
+ }
67
+ }));
68
+ }
69
+ catch (error) {
70
+ console.log('error', error);
71
+ }
72
+ });
73
+ }
74
+ main();
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ const sdk_1 = __importDefault(require("../sdk"));
16
+ const hatchet = sdk_1.default.init();
17
+ const parentWorkflow = {
18
+ id: 'bulk-parent-workflow',
19
+ description: 'simple example for spawning child workflows',
20
+ on: {
21
+ event: 'bulk:fanout:create',
22
+ },
23
+ steps: [
24
+ {
25
+ name: 'parent-spawn',
26
+ timeout: '70s',
27
+ run: (ctx) => __awaiter(void 0, void 0, void 0, function* () {
28
+ // Prepare the workflows to spawn
29
+ const workflowRequests = Array.from({ length: 300 }, (_, i) => ({
30
+ workflow: 'child-workflow',
31
+ input: { input: `child-input-${i}` },
32
+ options: { additionalMetadata: { childKey: 'childValue' } },
33
+ }));
34
+ const spawnedWorkflows = yield ctx.spawnWorkflows(workflowRequests);
35
+ const results = yield Promise.all(spawnedWorkflows.map((workflowRef) => workflowRef.result().then((result) => {
36
+ ctx.log('spawned workflow result:');
37
+ return result;
38
+ })));
39
+ console.log('spawned workflow results:', results);
40
+ console.log('number of spawned workflows:', results.length);
41
+ return { spawned: results.length };
42
+ }),
43
+ },
44
+ ],
45
+ };
46
+ const childWorkflow = {
47
+ id: 'child-workflow',
48
+ description: 'simple example for spawning child workflows',
49
+ on: {
50
+ event: 'child:create',
51
+ },
52
+ steps: [
53
+ {
54
+ name: 'child-work',
55
+ run: (ctx) => __awaiter(void 0, void 0, void 0, function* () {
56
+ const { input } = ctx.workflowInput();
57
+ // throw new Error('child error');
58
+ return { 'child-output': 'sm' };
59
+ }),
60
+ },
61
+ {
62
+ name: 'child-work2',
63
+ run: (ctx) => __awaiter(void 0, void 0, void 0, function* () {
64
+ const { input } = ctx.workflowInput();
65
+ // Perform CPU-bound work
66
+ // throw new Error('child error');
67
+ console.log('child workflow input:', input);
68
+ // Generate a large amount of garbage data
69
+ const garbageData = 'garbage'; // Print a snippet of the garbage data
70
+ return { 'child-output': garbageData };
71
+ }),
72
+ },
73
+ {
74
+ name: 'child-work3',
75
+ parents: ['child-work'],
76
+ run: (ctx) => __awaiter(void 0, void 0, void 0, function* () {
77
+ const { input } = ctx.workflowInput();
78
+ // throw new Error('child error');
79
+ const garbageData = 'child garbage';
80
+ return { 'child-output': garbageData };
81
+ }),
82
+ },
83
+ ],
84
+ };
85
+ function main() {
86
+ return __awaiter(this, void 0, void 0, function* () {
87
+ const worker = yield hatchet.worker('fanout-worker', { maxRuns: 1000 });
88
+ yield worker.registerWorkflow(parentWorkflow);
89
+ yield worker.registerWorkflow(childWorkflow);
90
+ worker.start();
91
+ });
92
+ }
93
+ main();
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,63 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __asyncValues = (this && this.__asyncValues) || function (o) {
12
+ if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
13
+ var m = o[Symbol.asyncIterator], i;
14
+ return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
15
+ function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
16
+ function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
17
+ };
18
+ var __importDefault = (this && this.__importDefault) || function (mod) {
19
+ return (mod && mod.__esModule) ? mod : { "default": mod };
20
+ };
21
+ Object.defineProperty(exports, "__esModule", { value: true });
22
+ const sdk_1 = __importDefault(require("../sdk"));
23
+ const hatchet = sdk_1.default.init();
24
+ function main() {
25
+ return __awaiter(this, void 0, void 0, function* () {
26
+ const workflowRuns = [];
27
+ for (let i = 0; i < 100; i += 1) {
28
+ workflowRuns.push({
29
+ workflowName: 'simple-workflow',
30
+ input: {},
31
+ options: {
32
+ additionalMetadata: {
33
+ key: 'value',
34
+ dedupe: 'key',
35
+ },
36
+ },
37
+ });
38
+ }
39
+ const workflowRunResponse = hatchet.admin.runWorkflows(workflowRuns);
40
+ const result = yield workflowRunResponse;
41
+ console.log('result', result);
42
+ result.forEach((workflowRun) => __awaiter(this, void 0, void 0, function* () {
43
+ var _a, e_1, _b, _c;
44
+ const stream = yield workflowRun.stream();
45
+ try {
46
+ for (var _d = true, stream_1 = __asyncValues(stream), stream_1_1; stream_1_1 = yield stream_1.next(), _a = stream_1_1.done, !_a; _d = true) {
47
+ _c = stream_1_1.value;
48
+ _d = false;
49
+ const event = _c;
50
+ console.log('event received', event);
51
+ }
52
+ }
53
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
54
+ finally {
55
+ try {
56
+ if (!_d && !_a && (_b = stream_1.return)) yield _b.call(stream_1);
57
+ }
58
+ finally { if (e_1) throw e_1.error; }
59
+ }
60
+ }));
61
+ });
62
+ }
63
+ main();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hatchet-dev/typescript-sdk",
3
- "version": "0.14.0",
3
+ "version": "0.15.1-alpha0",
4
4
  "description": "Background task orchestration & visibility for developers",
5
5
  "types": "dist/index.d.ts",
6
6
  "files": [
@@ -43,6 +43,9 @@
43
43
  "worker:on-failure": "npm run exec -- ./src/examples/on-failure.ts",
44
44
  "manual:trigger": "npm run exec -- ./src/examples/manual-trigger.ts",
45
45
  "manual:meta": "npm run exec -- ./src/examples/stream-by-additional-meta.ts",
46
+ "bulk:trigger": "npm run exec -- ./src/examples/bulk-trigger.ts",
47
+ "bulk:fanout:worker": "npm run exec -- ./src/examples/bulk-fanout-worker.ts",
48
+ "bulk:fanout:trigger": "npm run exec -- ./src/examples/bulk-fanout-trigger.ts",
46
49
  "worker:dag": "npm run exec -- ./src/examples/dag-worker.ts",
47
50
  "worker:concurrency": "npm run exec -- ./src/examples/concurrency/cancel-in-progress/concurrency-worker.ts",
48
51
  "event:concurrency": "npm run exec -- ./src/examples/concurrency/cancel-in-progress/concurrency-event.ts",
@@ -55,6 +58,7 @@
55
58
  "api": "npm run exec -- ./src/examples/api.ts",
56
59
  "prepublish": "cp package.json dist/package.json;",
57
60
  "publish:ci": "rm -rf ./dist && npm run tsc:build && npm run prepublish && cd dist && npm publish --access public --no-git-checks",
61
+ "publish:ci:alpha": "rm -rf ./dist && npm run tsc:build && npm run prepublish && cd dist && npm publish --access public --no-git-checks --tag alpha",
58
62
  "generate-docs": "typedoc"
59
63
  },
60
64
  "keywords": [],
@@ -23,6 +23,7 @@ export declare enum StepActionEventType {
23
23
  STEP_EVENT_TYPE_STARTED = 1,
24
24
  STEP_EVENT_TYPE_COMPLETED = 2,
25
25
  STEP_EVENT_TYPE_FAILED = 3,
26
+ STEP_EVENT_TYPE_ACKNOWLEDGED = 4,
26
27
  UNRECOGNIZED = -1
27
28
  }
28
29
  export declare function stepActionEventTypeFromJSON(object: any): StepActionEventType;
@@ -108,6 +108,7 @@ var StepActionEventType;
108
108
  StepActionEventType[StepActionEventType["STEP_EVENT_TYPE_STARTED"] = 1] = "STEP_EVENT_TYPE_STARTED";
109
109
  StepActionEventType[StepActionEventType["STEP_EVENT_TYPE_COMPLETED"] = 2] = "STEP_EVENT_TYPE_COMPLETED";
110
110
  StepActionEventType[StepActionEventType["STEP_EVENT_TYPE_FAILED"] = 3] = "STEP_EVENT_TYPE_FAILED";
111
+ StepActionEventType[StepActionEventType["STEP_EVENT_TYPE_ACKNOWLEDGED"] = 4] = "STEP_EVENT_TYPE_ACKNOWLEDGED";
111
112
  StepActionEventType[StepActionEventType["UNRECOGNIZED"] = -1] = "UNRECOGNIZED";
112
113
  })(StepActionEventType || (exports.StepActionEventType = StepActionEventType = {}));
113
114
  function stepActionEventTypeFromJSON(object) {
@@ -124,6 +125,9 @@ function stepActionEventTypeFromJSON(object) {
124
125
  case 3:
125
126
  case 'STEP_EVENT_TYPE_FAILED':
126
127
  return StepActionEventType.STEP_EVENT_TYPE_FAILED;
128
+ case 4:
129
+ case 'STEP_EVENT_TYPE_ACKNOWLEDGED':
130
+ return StepActionEventType.STEP_EVENT_TYPE_ACKNOWLEDGED;
127
131
  case -1:
128
132
  case 'UNRECOGNIZED':
129
133
  default:
@@ -140,6 +144,8 @@ function stepActionEventTypeToJSON(object) {
140
144
  return 'STEP_EVENT_TYPE_COMPLETED';
141
145
  case StepActionEventType.STEP_EVENT_TYPE_FAILED:
142
146
  return 'STEP_EVENT_TYPE_FAILED';
147
+ case StepActionEventType.STEP_EVENT_TYPE_ACKNOWLEDGED:
148
+ return 'STEP_EVENT_TYPE_ACKNOWLEDGED';
143
149
  case StepActionEventType.UNRECOGNIZED:
144
150
  default:
145
151
  return 'UNRECOGNIZED';
@@ -206,6 +206,12 @@ export interface WorkflowTriggerCronRef {
206
206
  parentId: string;
207
207
  cron: string;
208
208
  }
209
+ export interface BulkTriggerWorkflowRequest {
210
+ workflows: TriggerWorkflowRequest[];
211
+ }
212
+ export interface BulkTriggerWorkflowResponse {
213
+ workflowRunIds: string[];
214
+ }
209
215
  export interface TriggerWorkflowRequest {
210
216
  name: string;
211
217
  /** (optional) the input data for the workflow */
@@ -262,6 +268,8 @@ export declare const ScheduleWorkflowRequest: MessageFns<ScheduleWorkflowRequest
262
268
  export declare const WorkflowVersion: MessageFns<WorkflowVersion>;
263
269
  export declare const WorkflowTriggerEventRef: MessageFns<WorkflowTriggerEventRef>;
264
270
  export declare const WorkflowTriggerCronRef: MessageFns<WorkflowTriggerCronRef>;
271
+ export declare const BulkTriggerWorkflowRequest: MessageFns<BulkTriggerWorkflowRequest>;
272
+ export declare const BulkTriggerWorkflowResponse: MessageFns<BulkTriggerWorkflowResponse>;
265
273
  export declare const TriggerWorkflowRequest: MessageFns<TriggerWorkflowRequest>;
266
274
  export declare const TriggerWorkflowResponse: MessageFns<TriggerWorkflowResponse>;
267
275
  export declare const PutRateLimitRequest: MessageFns<PutRateLimitRequest>;
@@ -296,6 +304,14 @@ export declare const WorkflowServiceDefinition: {
296
304
  readonly responseStream: false;
297
305
  readonly options: {};
298
306
  };
307
+ readonly bulkTriggerWorkflow: {
308
+ readonly name: "BulkTriggerWorkflow";
309
+ readonly requestType: MessageFns<BulkTriggerWorkflowRequest>;
310
+ readonly requestStream: false;
311
+ readonly responseType: MessageFns<BulkTriggerWorkflowResponse>;
312
+ readonly responseStream: false;
313
+ readonly options: {};
314
+ };
299
315
  readonly putRateLimit: {
300
316
  readonly name: "PutRateLimit";
301
317
  readonly requestType: MessageFns<PutRateLimitRequest>;
@@ -310,12 +326,14 @@ export interface WorkflowServiceImplementation<CallContextExt = {}> {
310
326
  putWorkflow(request: PutWorkflowRequest, context: CallContext & CallContextExt): Promise<DeepPartial<WorkflowVersion>>;
311
327
  scheduleWorkflow(request: ScheduleWorkflowRequest, context: CallContext & CallContextExt): Promise<DeepPartial<WorkflowVersion>>;
312
328
  triggerWorkflow(request: TriggerWorkflowRequest, context: CallContext & CallContextExt): Promise<DeepPartial<TriggerWorkflowResponse>>;
329
+ bulkTriggerWorkflow(request: BulkTriggerWorkflowRequest, context: CallContext & CallContextExt): Promise<DeepPartial<BulkTriggerWorkflowResponse>>;
313
330
  putRateLimit(request: PutRateLimitRequest, context: CallContext & CallContextExt): Promise<DeepPartial<PutRateLimitResponse>>;
314
331
  }
315
332
  export interface WorkflowServiceClient<CallOptionsExt = {}> {
316
333
  putWorkflow(request: DeepPartial<PutWorkflowRequest>, options?: CallOptions & CallOptionsExt): Promise<WorkflowVersion>;
317
334
  scheduleWorkflow(request: DeepPartial<ScheduleWorkflowRequest>, options?: CallOptions & CallOptionsExt): Promise<WorkflowVersion>;
318
335
  triggerWorkflow(request: DeepPartial<TriggerWorkflowRequest>, options?: CallOptions & CallOptionsExt): Promise<TriggerWorkflowResponse>;
336
+ bulkTriggerWorkflow(request: DeepPartial<BulkTriggerWorkflowRequest>, options?: CallOptions & CallOptionsExt): Promise<BulkTriggerWorkflowResponse>;
319
337
  putRateLimit(request: DeepPartial<PutRateLimitRequest>, options?: CallOptions & CallOptionsExt): Promise<PutRateLimitResponse>;
320
338
  }
321
339
  type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined;
@@ -5,7 +5,7 @@
5
5
  // protoc v3.19.1
6
6
  // source: workflows/workflows.proto
7
7
  Object.defineProperty(exports, "__esModule", { value: true });
8
- exports.WorkflowServiceDefinition = exports.PutRateLimitResponse = exports.PutRateLimitRequest = exports.TriggerWorkflowResponse = exports.TriggerWorkflowRequest = exports.WorkflowTriggerCronRef = exports.WorkflowTriggerEventRef = exports.WorkflowVersion = exports.ScheduleWorkflowRequest = exports.ListWorkflowsRequest = exports.CreateStepRateLimit = exports.CreateWorkflowStepOpts_WorkerLabelsEntry = exports.CreateWorkflowStepOpts = exports.DesiredWorkerLabels = exports.CreateWorkflowJobOpts = exports.WorkflowConcurrencyOpts = exports.CreateWorkflowVersionOpts = exports.PutWorkflowRequest = exports.RateLimitDuration = exports.WorkerLabelComparator = exports.ConcurrencyLimitStrategy = exports.WorkflowKind = exports.StickyStrategy = exports.protobufPackage = void 0;
8
+ exports.WorkflowServiceDefinition = exports.PutRateLimitResponse = exports.PutRateLimitRequest = exports.TriggerWorkflowResponse = exports.TriggerWorkflowRequest = exports.BulkTriggerWorkflowResponse = exports.BulkTriggerWorkflowRequest = exports.WorkflowTriggerCronRef = exports.WorkflowTriggerEventRef = exports.WorkflowVersion = exports.ScheduleWorkflowRequest = exports.ListWorkflowsRequest = exports.CreateStepRateLimit = exports.CreateWorkflowStepOpts_WorkerLabelsEntry = exports.CreateWorkflowStepOpts = exports.DesiredWorkerLabels = exports.CreateWorkflowJobOpts = exports.WorkflowConcurrencyOpts = exports.CreateWorkflowVersionOpts = exports.PutWorkflowRequest = exports.RateLimitDuration = exports.WorkerLabelComparator = exports.ConcurrencyLimitStrategy = exports.WorkflowKind = exports.StickyStrategy = exports.protobufPackage = void 0;
9
9
  exports.stickyStrategyFromJSON = stickyStrategyFromJSON;
10
10
  exports.stickyStrategyToJSON = stickyStrategyToJSON;
11
11
  exports.workflowKindFromJSON = workflowKindFromJSON;
@@ -1725,6 +1725,118 @@ exports.WorkflowTriggerCronRef = {
1725
1725
  return message;
1726
1726
  },
1727
1727
  };
1728
+ function createBaseBulkTriggerWorkflowRequest() {
1729
+ return { workflows: [] };
1730
+ }
1731
+ exports.BulkTriggerWorkflowRequest = {
1732
+ encode(message, writer = new wire_1.BinaryWriter()) {
1733
+ for (const v of message.workflows) {
1734
+ exports.TriggerWorkflowRequest.encode(v, writer.uint32(10).fork()).join();
1735
+ }
1736
+ return writer;
1737
+ },
1738
+ decode(input, length) {
1739
+ const reader = input instanceof wire_1.BinaryReader ? input : new wire_1.BinaryReader(input);
1740
+ let end = length === undefined ? reader.len : reader.pos + length;
1741
+ const message = createBaseBulkTriggerWorkflowRequest();
1742
+ while (reader.pos < end) {
1743
+ const tag = reader.uint32();
1744
+ switch (tag >>> 3) {
1745
+ case 1:
1746
+ if (tag !== 10) {
1747
+ break;
1748
+ }
1749
+ message.workflows.push(exports.TriggerWorkflowRequest.decode(reader, reader.uint32()));
1750
+ continue;
1751
+ }
1752
+ if ((tag & 7) === 4 || tag === 0) {
1753
+ break;
1754
+ }
1755
+ reader.skip(tag & 7);
1756
+ }
1757
+ return message;
1758
+ },
1759
+ fromJSON(object) {
1760
+ return {
1761
+ workflows: globalThis.Array.isArray(object === null || object === void 0 ? void 0 : object.workflows)
1762
+ ? object.workflows.map((e) => exports.TriggerWorkflowRequest.fromJSON(e))
1763
+ : [],
1764
+ };
1765
+ },
1766
+ toJSON(message) {
1767
+ var _a;
1768
+ const obj = {};
1769
+ if ((_a = message.workflows) === null || _a === void 0 ? void 0 : _a.length) {
1770
+ obj.workflows = message.workflows.map((e) => exports.TriggerWorkflowRequest.toJSON(e));
1771
+ }
1772
+ return obj;
1773
+ },
1774
+ create(base) {
1775
+ return exports.BulkTriggerWorkflowRequest.fromPartial(base !== null && base !== void 0 ? base : {});
1776
+ },
1777
+ fromPartial(object) {
1778
+ var _a;
1779
+ const message = createBaseBulkTriggerWorkflowRequest();
1780
+ message.workflows = ((_a = object.workflows) === null || _a === void 0 ? void 0 : _a.map((e) => exports.TriggerWorkflowRequest.fromPartial(e))) || [];
1781
+ return message;
1782
+ },
1783
+ };
1784
+ function createBaseBulkTriggerWorkflowResponse() {
1785
+ return { workflowRunIds: [] };
1786
+ }
1787
+ exports.BulkTriggerWorkflowResponse = {
1788
+ encode(message, writer = new wire_1.BinaryWriter()) {
1789
+ for (const v of message.workflowRunIds) {
1790
+ writer.uint32(10).string(v);
1791
+ }
1792
+ return writer;
1793
+ },
1794
+ decode(input, length) {
1795
+ const reader = input instanceof wire_1.BinaryReader ? input : new wire_1.BinaryReader(input);
1796
+ let end = length === undefined ? reader.len : reader.pos + length;
1797
+ const message = createBaseBulkTriggerWorkflowResponse();
1798
+ while (reader.pos < end) {
1799
+ const tag = reader.uint32();
1800
+ switch (tag >>> 3) {
1801
+ case 1:
1802
+ if (tag !== 10) {
1803
+ break;
1804
+ }
1805
+ message.workflowRunIds.push(reader.string());
1806
+ continue;
1807
+ }
1808
+ if ((tag & 7) === 4 || tag === 0) {
1809
+ break;
1810
+ }
1811
+ reader.skip(tag & 7);
1812
+ }
1813
+ return message;
1814
+ },
1815
+ fromJSON(object) {
1816
+ return {
1817
+ workflowRunIds: globalThis.Array.isArray(object === null || object === void 0 ? void 0 : object.workflowRunIds)
1818
+ ? object.workflowRunIds.map((e) => globalThis.String(e))
1819
+ : [],
1820
+ };
1821
+ },
1822
+ toJSON(message) {
1823
+ var _a;
1824
+ const obj = {};
1825
+ if ((_a = message.workflowRunIds) === null || _a === void 0 ? void 0 : _a.length) {
1826
+ obj.workflowRunIds = message.workflowRunIds;
1827
+ }
1828
+ return obj;
1829
+ },
1830
+ create(base) {
1831
+ return exports.BulkTriggerWorkflowResponse.fromPartial(base !== null && base !== void 0 ? base : {});
1832
+ },
1833
+ fromPartial(object) {
1834
+ var _a;
1835
+ const message = createBaseBulkTriggerWorkflowResponse();
1836
+ message.workflowRunIds = ((_a = object.workflowRunIds) === null || _a === void 0 ? void 0 : _a.map((e) => e)) || [];
1837
+ return message;
1838
+ },
1839
+ };
1728
1840
  function createBaseTriggerWorkflowRequest() {
1729
1841
  return {
1730
1842
  name: '',
@@ -2105,6 +2217,14 @@ exports.WorkflowServiceDefinition = {
2105
2217
  responseStream: false,
2106
2218
  options: {},
2107
2219
  },
2220
+ bulkTriggerWorkflow: {
2221
+ name: 'BulkTriggerWorkflow',
2222
+ requestType: exports.BulkTriggerWorkflowRequest,
2223
+ requestStream: false,
2224
+ responseType: exports.BulkTriggerWorkflowResponse,
2225
+ responseStream: false,
2226
+ options: {},
2227
+ },
2108
2228
  putRateLimit: {
2109
2229
  name: 'PutRateLimit',
2110
2230
  requestType: exports.PutRateLimitRequest,
package/step.d.ts CHANGED
@@ -183,6 +183,21 @@ export declare class Context<T, K = {}> {
183
183
  refreshTimeout(incrementBy: string): Promise<void>;
184
184
  releaseSlot(): Promise<void>;
185
185
  putStream(data: string | Uint8Array): Promise<void>;
186
+ /**
187
+ * Spawns multiple workflows.
188
+ *
189
+ * @param workflows an array of objects containing the workflow name, input data, and options for each workflow
190
+ * @returns a list of references to the spawned workflow runs
191
+ */
192
+ spawnWorkflows<Q = JsonValue, P = JsonValue>(workflows: Array<{
193
+ workflow: string | Workflow;
194
+ input: Q;
195
+ options?: {
196
+ key?: string;
197
+ sticky?: boolean;
198
+ additionalMetadata?: Record<string, string>;
199
+ };
200
+ }>): Promise<WorkflowRunRef<P>[]>;
186
201
  /**
187
202
  * Spawns a new workflow.
188
203
  *
package/step.js CHANGED
@@ -48,7 +48,7 @@ exports.CreateRateLimitSchema = z.object({
48
48
  key: z.string().optional(),
49
49
  staticKey: z.string().optional(),
50
50
  dynamicKey: z.string().optional(),
51
- units: z.union([z.number().min(1), z.string()]),
51
+ units: z.union([z.number().min(0), z.string()]),
52
52
  limit: z.union([z.number().min(1), z.string()]).optional(),
53
53
  duration: z.nativeEnum(workflows_1.RateLimitDuration).optional(),
54
54
  });
@@ -205,6 +205,57 @@ class Context {
205
205
  yield this.client.event.putStream(stepRunId, data);
206
206
  });
207
207
  }
208
+ /**
209
+ * Spawns multiple workflows.
210
+ *
211
+ * @param workflows an array of objects containing the workflow name, input data, and options for each workflow
212
+ * @returns a list of references to the spawned workflow runs
213
+ */
214
+ spawnWorkflows(workflows) {
215
+ const { workflowRunId, stepRunId } = this.action;
216
+ const workflowRuns = workflows.map(({ workflow, input, options }) => {
217
+ let workflowName;
218
+ if (typeof workflow === 'string') {
219
+ workflowName = workflow;
220
+ }
221
+ else {
222
+ workflowName = workflow.id;
223
+ }
224
+ const name = this.client.config.namespace + workflowName;
225
+ let key;
226
+ let sticky = false;
227
+ let metadata;
228
+ if (options) {
229
+ key = options.key;
230
+ sticky = options.sticky;
231
+ metadata = options.additionalMetadata;
232
+ }
233
+ if (sticky && !this.worker.hasWorkflow(name)) {
234
+ throw new hatchet_error_1.default(`Cannot run with sticky: workflow ${name} is not registered on the worker`);
235
+ }
236
+ const resp = {
237
+ workflowName: name,
238
+ input,
239
+ options: {
240
+ parentId: workflowRunId,
241
+ parentStepRunId: stepRunId,
242
+ childKey: key,
243
+ childIndex: this.spawnIndex,
244
+ desiredWorkerId: sticky ? this.worker.id() : undefined,
245
+ additionalMetadata: metadata,
246
+ },
247
+ };
248
+ this.spawnIndex += 1;
249
+ return resp;
250
+ });
251
+ try {
252
+ const resp = this.client.admin.runWorkflows(workflowRuns);
253
+ return resp;
254
+ }
255
+ catch (e) {
256
+ throw new hatchet_error_1.default(e.message);
257
+ }
258
+ }
208
259
  /**
209
260
  * Spawns a new workflow.
210
261
  *