@hatchet-dev/typescript-sdk 1.33.0 → 1.33.2

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.
@@ -26,6 +26,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
26
26
  exports.AdminClient = void 0;
27
27
  const workflows_1 = require("../../protoc/workflows");
28
28
  const hatchet_error_1 = require("../../util/errors/hatchet-error");
29
+ const v0_deprecation_warning_1 = require("../../util/v0-deprecation-warning");
29
30
  const retrier_1 = require("../../util/retrier");
30
31
  const workflow_run_ref_1 = __importDefault(require("../../util/workflow-run-ref"));
31
32
  const workflows_2 = require("../../protoc/v1/workflows");
@@ -68,6 +69,9 @@ class AdminClient {
68
69
  */
69
70
  putWorkflow(workflow) {
70
71
  return __awaiter(this, void 0, void 0, function* () {
72
+ // a v0 workflow definition sent straight to the engine, the one v0 use that never
73
+ // reaches the legacy transformer
74
+ (0, v0_deprecation_warning_1.emitV0RemovedWarning)('workflow');
71
75
  try {
72
76
  return yield (0, retrier_1.retrier)(() => __awaiter(this, void 0, void 0, function* () { return this.client.putWorkflow({ opts: workflow }); }), this.logger);
73
77
  }
@@ -6,7 +6,8 @@ export type { Workflow as LegacyWorkflow } from './workflow';
6
6
  */
7
7
  export declare function isLegacyWorkflow(workflow: unknown): workflow is Workflow;
8
8
  /**
9
- * Emits a deprecation warning for legacy workflow usage.
9
+ * Warns once per process that a v0 workflow is in use: the banner for the terminal and a
10
+ * DeprecationWarning with a stable code that Node's warning flags and handlers can filter.
10
11
  */
11
12
  export declare function warnLegacyWorkflow(): void;
12
13
  /**
@@ -6,6 +6,7 @@ exports.transformLegacyWorkflow = transformLegacyWorkflow;
6
6
  exports.normalizeWorkflow = normalizeWorkflow;
7
7
  exports.normalizeWorkflows = normalizeWorkflows;
8
8
  exports.getWorkflowName = getWorkflowName;
9
+ const v0_deprecation_warning_1 = require("../util/v0-deprecation-warning");
9
10
  const step_1 = require("./step");
10
11
  const declaration_1 = require("../v1/declaration");
11
12
  const LEGACY_WORKFLOW_WARNING = [
@@ -34,8 +35,18 @@ function isLegacyWorkflow(workflow) {
34
35
  /**
35
36
  * Emits a deprecation warning for legacy workflow usage.
36
37
  */
38
+ let warnedLegacyWorkflow = false;
39
+ /**
40
+ * Warns once per process that a v0 workflow is in use: the banner for the terminal and a
41
+ * DeprecationWarning with a stable code that Node's warning flags and handlers can filter.
42
+ */
37
43
  function warnLegacyWorkflow() {
44
+ if (warnedLegacyWorkflow) {
45
+ return;
46
+ }
47
+ warnedLegacyWorkflow = true;
38
48
  console.warn(LEGACY_WORKFLOW_WARNING);
49
+ (0, v0_deprecation_warning_1.emitV0RemovedWarning)('workflow');
39
50
  }
40
51
  /**
41
52
  * Transforms a legacy v0 Workflow into a v1 WorkflowDeclaration.
@@ -1,5 +1,5 @@
1
1
  import * as z from 'zod/v4';
2
- import { CreateStep } from '../step';
2
+ import { CreateStep } from './step';
3
3
  import { ConcurrencyLimitStrategy as PbConcurrencyLimitStrategy, StickyStrategy as PbStickyStrategy } from '../protoc/v1/workflows';
4
4
  declare const StepsSchema: z.ZodArray<z.ZodObject<{
5
5
  name: z.ZodString;
@@ -35,7 +35,7 @@ var __importStar = (this && this.__importStar) || (function () {
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.CreateWorkflowSchema = exports.StickyStrategy = exports.HatchetTimeoutSchema = exports.WorkflowConcurrency = exports.ConcurrencyLimitStrategy = void 0;
37
37
  const z = __importStar(require("zod/v4"));
38
- const step_1 = require("../step");
38
+ const step_1 = require("./step");
39
39
  const workflows_1 = require("../protoc/v1/workflows");
40
40
  const CronConfigSchema = z.object({
41
41
  cron: z.string(),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hatchet-dev/typescript-sdk",
3
- "version": "1.33.0",
3
+ "version": "1.33.2",
4
4
  "engines": {
5
5
  "node": ">=20"
6
6
  },
@@ -194,6 +194,8 @@ export interface AssignedAction {
194
194
  batchStartPayload?: BatchStartPayload | undefined;
195
195
  /** (optional) the partition key used for batching */
196
196
  batchKey?: string | undefined;
197
+ /** (optional) inserted_at of the assigned task. The DAG operator uses this to prune durable log partitions. */
198
+ taskInsertedAt?: Date | undefined;
197
199
  }
198
200
  export interface BatchStartPayload {
199
201
  triggerReason: string;
@@ -1281,6 +1281,7 @@ function createBaseAssignedAction() {
1281
1281
  batchIndex: undefined,
1282
1282
  batchStartPayload: undefined,
1283
1283
  batchKey: undefined,
1284
+ taskInsertedAt: undefined,
1284
1285
  };
1285
1286
  }
1286
1287
  exports.AssignedAction = {
@@ -1369,6 +1370,9 @@ exports.AssignedAction = {
1369
1370
  if (message.batchKey !== undefined) {
1370
1371
  writer.uint32(226).string(message.batchKey);
1371
1372
  }
1373
+ if (message.taskInsertedAt !== undefined) {
1374
+ timestamp_1.Timestamp.encode(toTimestamp(message.taskInsertedAt), writer.uint32(234).fork()).join();
1375
+ }
1372
1376
  return writer;
1373
1377
  },
1374
1378
  decode(input, length) {
@@ -1574,6 +1578,13 @@ exports.AssignedAction = {
1574
1578
  message.batchKey = reader.string();
1575
1579
  continue;
1576
1580
  }
1581
+ case 29: {
1582
+ if (tag !== 234) {
1583
+ break;
1584
+ }
1585
+ message.taskInsertedAt = fromTimestamp(timestamp_1.Timestamp.decode(reader, reader.uint32()));
1586
+ continue;
1587
+ }
1577
1588
  }
1578
1589
  if ((tag & 7) === 4 || tag === 0) {
1579
1590
  break;
@@ -1702,6 +1713,11 @@ exports.AssignedAction = {
1702
1713
  ? exports.BatchStartPayload.fromJSON(object.batchStartPayload)
1703
1714
  : undefined,
1704
1715
  batchKey: isSet(object.batchKey) ? globalThis.String(object.batchKey) : undefined,
1716
+ taskInsertedAt: isSet(object.taskInsertedAt)
1717
+ ? fromJsonTimestamp(object.taskInsertedAt)
1718
+ : isSet(object.task_inserted_at)
1719
+ ? fromJsonTimestamp(object.task_inserted_at)
1720
+ : undefined,
1705
1721
  };
1706
1722
  },
1707
1723
  toJSON(message) {
@@ -1790,13 +1806,16 @@ exports.AssignedAction = {
1790
1806
  if (message.batchKey !== undefined) {
1791
1807
  obj.batchKey = message.batchKey;
1792
1808
  }
1809
+ if (message.taskInsertedAt !== undefined) {
1810
+ obj.taskInsertedAt = message.taskInsertedAt.toISOString();
1811
+ }
1793
1812
  return obj;
1794
1813
  },
1795
1814
  create(base) {
1796
1815
  return exports.AssignedAction.fromPartial(base !== null && base !== void 0 ? base : {});
1797
1816
  },
1798
1817
  fromPartial(object) {
1799
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2;
1818
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3;
1800
1819
  const message = createBaseAssignedAction();
1801
1820
  message.tenantId = (_a = object.tenantId) !== null && _a !== void 0 ? _a : '';
1802
1821
  message.workflowRunId = (_b = object.workflowRunId) !== null && _b !== void 0 ? _b : '';
@@ -1829,6 +1848,7 @@ exports.AssignedAction = {
1829
1848
  ? exports.BatchStartPayload.fromPartial(object.batchStartPayload)
1830
1849
  : undefined;
1831
1850
  message.batchKey = (_2 = object.batchKey) !== null && _2 !== void 0 ? _2 : undefined;
1851
+ message.taskInsertedAt = (_3 = object.taskInsertedAt) !== null && _3 !== void 0 ? _3 : undefined;
1832
1852
  return message;
1833
1853
  },
1834
1854
  };
package/step.js CHANGED
@@ -14,6 +14,4 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- const v0_deprecation_warning_1 = require("./util/v0-deprecation-warning");
18
17
  __exportStar(require("./legacy/step"), exports);
19
- (0, v0_deprecation_warning_1.emitV0RemovedWarning)('step');
@@ -1,18 +1,11 @@
1
1
  /**
2
- * v0 SDK root-import deprecation warnings.
2
+ * The v0 SDK deprecation warning, emitted when a v0 workflow is actually used (registered on a
3
+ * worker or put to the engine), never when a module is merely imported: the root entry still
4
+ * re-exports the v0 `workflow` and `step` modules for consumers that only use v1 APIs, and
5
+ * loading them must stay silent.
3
6
  *
4
- * The legacy `workflow` and `step` re-exports under the root specifier need
5
- * to keep nagging consumers to migrate to v1, but the original implementation
6
- * used `console.warn` at module evaluation time, which:
7
- * - cannot be silenced by Node's standard `--no-deprecation`,
8
- * `--no-warnings`, or `--no-warnings=DeprecationWarning` flags;
9
- * - has no stable `code` for `process.on('warning', ...)` handlers; and
10
- * - is duplicated when both submodules are loaded (which happens for
11
- * anyone importing from the root, since `index.ts` re-exports both).
12
- *
13
- * Switching to `process.emitWarning` with a fixed code makes the warnings
14
- * filterable, dedupable, and consistent with the rest of Node's deprecation
15
- * surface, while still being visible by default.
7
+ * `process.emitWarning` with a fixed code keeps the warning filterable with Node's standard
8
+ * `--no-deprecation` and `--no-warnings` flags and addressable from `process.on('warning')`.
16
9
  */
17
10
  export declare const V0_DEPRECATION_CODE = "HATCHET_V0_REMOVED";
18
11
  /** Reset hook for tests. Not part of the public API. */
@@ -1,19 +1,12 @@
1
1
  "use strict";
2
2
  /**
3
- * v0 SDK root-import deprecation warnings.
3
+ * The v0 SDK deprecation warning, emitted when a v0 workflow is actually used (registered on a
4
+ * worker or put to the engine), never when a module is merely imported: the root entry still
5
+ * re-exports the v0 `workflow` and `step` modules for consumers that only use v1 APIs, and
6
+ * loading them must stay silent.
4
7
  *
5
- * The legacy `workflow` and `step` re-exports under the root specifier need
6
- * to keep nagging consumers to migrate to v1, but the original implementation
7
- * used `console.warn` at module evaluation time, which:
8
- * - cannot be silenced by Node's standard `--no-deprecation`,
9
- * `--no-warnings`, or `--no-warnings=DeprecationWarning` flags;
10
- * - has no stable `code` for `process.on('warning', ...)` handlers; and
11
- * - is duplicated when both submodules are loaded (which happens for
12
- * anyone importing from the root, since `index.ts` re-exports both).
13
- *
14
- * Switching to `process.emitWarning` with a fixed code makes the warnings
15
- * filterable, dedupable, and consistent with the rest of Node's deprecation
16
- * surface, while still being visible by default.
8
+ * `process.emitWarning` with a fixed code keeps the warning filterable with Node's standard
9
+ * `--no-deprecation` and `--no-warnings` flags and addressable from `process.on('warning')`.
17
10
  */
18
11
  Object.defineProperty(exports, "__esModule", { value: true });
19
12
  exports.V0_DEPRECATION_CODE = void 0;
@@ -1,6 +1,6 @@
1
1
  import { ScheduledWorkflows, ScheduledWorkflowsBulkDeleteFilter, ScheduledWorkflowsBulkDeleteResponse, ScheduledWorkflowsBulkUpdateResponse, ScheduledWorkflowsList } from '../../../clients/rest/generated/data-contracts';
2
2
  import { z } from 'zod/v4';
3
- import { Workflow } from '../../../workflow';
3
+ import type { Workflow } from '../../../legacy/workflow';
4
4
  import { BaseWorkflowDeclaration, WorkflowDefinition } from '../..';
5
5
  import { HatchetClient } from '../client';
6
6
  import { WorkflowsClient } from './workflows';
package/v1/embedded.js CHANGED
@@ -83,6 +83,46 @@ const net_1 = require("net");
83
83
  const promises_1 = require("stream/promises");
84
84
  const REPO_URL = 'https://github.com/hatchet-dev/hatchet-embedded';
85
85
  const DEFAULT_READY_TIMEOUT_MS = 300000;
86
+ const SLOW_NOTICE_DELAY_MS = 2000;
87
+ const HEARTBEAT_INTERVAL_MS = 30000;
88
+ // first-contact progress goes to stderr (like the engine's own output) so it
89
+ // never corrupts program output; warm starts print at most one line
90
+ function logProgress(message) {
91
+ process.stderr.write(`hatchet embedded: ${message}\n`);
92
+ }
93
+ // prints startMsg only if fn is still running after SLOW_NOTICE_DELAY_MS (and
94
+ // doneMsg once it finishes), so fast warm-start network calls stay quiet while
95
+ // a blocked one explains what the process is waiting on
96
+ function withSlowNotice(startMsg, doneMsg, fn) {
97
+ return __awaiter(this, void 0, void 0, function* () {
98
+ var _a;
99
+ let noticed = false;
100
+ let finished = false;
101
+ const timer = setTimeout(() => {
102
+ // guards a callback already queued when fn settles, so a stale start
103
+ // message can never print after completion
104
+ if (finished) {
105
+ return;
106
+ }
107
+ noticed = true;
108
+ logProgress(startMsg);
109
+ }, SLOW_NOTICE_DELAY_MS);
110
+ (_a = timer.unref) === null || _a === void 0 ? void 0 : _a.call(timer);
111
+ let result;
112
+ try {
113
+ result = yield fn();
114
+ }
115
+ finally {
116
+ finished = true;
117
+ clearTimeout(timer);
118
+ }
119
+ // only reached when fn succeeded
120
+ if (noticed) {
121
+ logProgress(doneMsg);
122
+ }
123
+ return result;
124
+ });
125
+ }
86
126
  function sidecarAssetName() {
87
127
  const platform = { darwin: 'darwin', linux: 'linux' }[process.platform];
88
128
  const arch = { x64: 'amd64', arm64: 'arm64' }[process.arch];
@@ -168,17 +208,18 @@ function resolveExpectedChecksum(tag, asset, binPath) {
168
208
  }
169
209
  function ensureSidecarBinary(version, checksum) {
170
210
  return __awaiter(this, void 0, void 0, function* () {
171
- const tag = yield resolveVersion(version);
211
+ const tag = yield withSlowNotice(`resolving the latest hatchet-embedded release from ${REPO_URL}`, 'resolved the latest hatchet-embedded release', () => resolveVersion(version));
172
212
  const asset = sidecarAssetName();
173
213
  const binPath = path.join(os.homedir(), '.hatchet', 'embedded', tag, asset);
174
214
  yield fs.mkdir(path.dirname(binPath), { recursive: true });
175
215
  // verified on every start, not just at download; a cached binary that no
176
216
  // longer matches the expected checksum is re-downloaded
177
- const expected = checksum !== null && checksum !== void 0 ? checksum : (yield resolveExpectedChecksum(tag, asset, binPath));
217
+ const expected = checksum !== null && checksum !== void 0 ? checksum : (yield withSlowNotice(`resolving the expected checksum for ${tag} (the cached checksum is used if the release cannot be reached)`, 'expected checksum resolved', () => resolveExpectedChecksum(tag, asset, binPath)));
178
218
  const cached = yield fs.access(binPath).then(() => true, () => false);
179
219
  if (cached && (yield sha256File(binPath)) === expected) {
180
220
  return binPath;
181
221
  }
222
+ logProgress(`downloading the embedded engine sidecar ${tag} to ${binPath} (tens of MB, cached for later runs)`);
182
223
  const url = `${REPO_URL}/releases/download/${tag}/${asset}`;
183
224
  const res = yield fetch(url);
184
225
  if (!res.ok || !res.body) {
@@ -199,12 +240,15 @@ function ensureSidecarBinary(version, checksum) {
199
240
  finally {
200
241
  yield fs.rm(tmpPath, { force: true });
201
242
  }
243
+ logProgress(`sidecar ${tag} downloaded`);
202
244
  return binPath;
203
245
  });
204
246
  }
205
247
  function waitForHandshake(child, handshakePath, timeoutMs) {
206
248
  return __awaiter(this, void 0, void 0, function* () {
207
- const deadline = Date.now() + timeoutMs;
249
+ const start = Date.now();
250
+ const deadline = start + timeoutMs;
251
+ let nextHeartbeat = start + HEARTBEAT_INTERVAL_MS;
208
252
  let exited;
209
253
  child.once('exit', (code) => {
210
254
  exited = new Error(`hatchet embedded sidecar exited with code ${code} before becoming ready`);
@@ -213,6 +257,11 @@ function waitForHandshake(child, handshakePath, timeoutMs) {
213
257
  if (exited) {
214
258
  throw exited;
215
259
  }
260
+ if (Date.now() >= nextHeartbeat) {
261
+ const elapsed = Math.round((Date.now() - start) / 1000);
262
+ logProgress(`still waiting for the embedded engine (${elapsed}s elapsed)`);
263
+ nextHeartbeat += HEARTBEAT_INTERVAL_MS;
264
+ }
216
265
  try {
217
266
  const handshake = JSON.parse(yield fs.readFile(handshakePath, 'utf8'));
218
267
  if (handshake.token) {
@@ -232,6 +281,8 @@ function waitForHandshake(child, handshakePath, timeoutMs) {
232
281
  }
233
282
  // sidecars started in this process that have not been stopped yet
234
283
  const activeSidecars = new Set();
284
+ // the ambient-token warning is printed at most once per process
285
+ let warnedAmbientToken = false;
235
286
  /**
236
287
  * Gracefully stops every sidecar started in this process by
237
288
  * `HatchetEmbeddedClient.init()` (or `startEmbeddedSidecar`) and resolves once
@@ -254,6 +305,10 @@ function stopEmbeddedSidecar() {
254
305
  function startEmbeddedSidecar() {
255
306
  return __awaiter(this, arguments, void 0, function* (opts = {}) {
256
307
  var _a, _b;
308
+ if (process.env.HATCHET_CLIENT_TOKEN && !warnedAmbientToken) {
309
+ warnedAmbientToken = true;
310
+ logProgress('warning: HATCHET_CLIENT_TOKEN is set in the environment. Hatchet clients created with the standard constructor in this process will NOT use the embedded engine; unset HATCHET_CLIENT_TOKEN for embedded runs.');
311
+ }
257
312
  const suppliedPath = (_a = opts.binaryPath) !== null && _a !== void 0 ? _a : process.env.HATCHET_CLIENT_EMBEDDED_BINARY_PATH;
258
313
  let binPath;
259
314
  if (suppliedPath) {
@@ -299,6 +354,9 @@ function startEmbeddedSidecar() {
299
354
  const child = (0, child_process_1.spawn)(binPath, args, { stdio: ['pipe', 'ignore', 'inherit'] });
300
355
  const killChild = () => child.kill();
301
356
  process.once('exit', killChild);
357
+ logProgress(opts.databaseUrl
358
+ ? 'starting the embedded engine'
359
+ : 'starting the embedded engine (first run initializes a bundled Postgres and can take a minute)');
302
360
  let handshake;
303
361
  try {
304
362
  handshake = yield waitForHandshake(child, handshakePath, (_b = opts.readyTimeoutMs) !== null && _b !== void 0 ? _b : DEFAULT_READY_TIMEOUT_MS);
@@ -10,7 +10,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.multipleConcurrencyKeys = exports.simpleConcurrency = void 0;
13
- const workflow_1 = require("../../../workflow");
13
+ const v1_1 = require("../..");
14
14
  const hatchet_client_1 = require("../hatchet-client");
15
15
  const sleep = (ms) => new Promise((resolve) => {
16
16
  setTimeout(resolve, ms);
@@ -20,7 +20,7 @@ exports.simpleConcurrency = hatchet_client_1.hatchet.workflow({
20
20
  name: 'simple-concurrency',
21
21
  concurrency: {
22
22
  maxRuns: 1,
23
- limitStrategy: workflow_1.ConcurrencyLimitStrategy.GROUP_ROUND_ROBIN,
23
+ limitStrategy: v1_1.ConcurrencyLimitStrategy.GROUP_ROUND_ROBIN,
24
24
  expression: 'input.GroupKey',
25
25
  },
26
26
  });
@@ -40,12 +40,12 @@ exports.multipleConcurrencyKeys = hatchet_client_1.hatchet.workflow({
40
40
  concurrency: [
41
41
  {
42
42
  maxRuns: 1,
43
- limitStrategy: workflow_1.ConcurrencyLimitStrategy.GROUP_ROUND_ROBIN,
43
+ limitStrategy: v1_1.ConcurrencyLimitStrategy.GROUP_ROUND_ROBIN,
44
44
  expression: 'input.Tier',
45
45
  },
46
46
  {
47
47
  maxRuns: 1,
48
- limitStrategy: workflow_1.ConcurrencyLimitStrategy.GROUP_ROUND_ROBIN,
48
+ limitStrategy: v1_1.ConcurrencyLimitStrategy.GROUP_ROUND_ROBIN,
49
49
  expression: 'input.Account',
50
50
  },
51
51
  ],
package/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const HATCHET_VERSION = "1.33.0";
1
+ export declare const HATCHET_VERSION = "1.33.2";
package/version.js CHANGED
@@ -1,4 +1,4 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.HATCHET_VERSION = void 0;
4
- exports.HATCHET_VERSION = '1.33.0';
4
+ exports.HATCHET_VERSION = '1.33.2';
package/workflow.js CHANGED
@@ -18,6 +18,4 @@ exports.StickyStrategy = exports.ConcurrencyLimitStrategy = void 0;
18
18
  const v1_1 = require("./v1");
19
19
  Object.defineProperty(exports, "ConcurrencyLimitStrategy", { enumerable: true, get: function () { return v1_1.ConcurrencyLimitStrategy; } });
20
20
  Object.defineProperty(exports, "StickyStrategy", { enumerable: true, get: function () { return v1_1.StickyStrategy; } });
21
- const v0_deprecation_warning_1 = require("./util/v0-deprecation-warning");
22
21
  __exportStar(require("./legacy/workflow"), exports);
23
- (0, v0_deprecation_warning_1.emitV0RemovedWarning)('workflow', 'ConcurrencyLimitStrategy and StickyStrategy have been moved to @hatchet-dev/typescript-sdk/v1.');