@headless-lms/adapter-workflow-hatchet 0.2.0 → 0.2.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.
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { APIContracts } from "@hatchet-dev/typescript-sdk/clients/rest/index.js";
2
2
  import { ConcurrencyLimitStrategy } from "@hatchet-dev/typescript-sdk/v1/index.js";
3
- import { AutomationActionResult, AutomationDispatch, AutomationEngine, AutomationExecutor, DeliveryDispatch, JsonValue, Logger, ScheduledAutomation } from "@headless-lms/core/types";
3
+ import { AutomationActionResult, AutomationDispatch, AutomationEngine, AutomationExecutor, DeliveryDispatch, DeliveryExecutor, JsonValue, Logger, ScheduledAutomation } from "@headless-lms/core/types";
4
4
  import { RecurringJob, ScheduledJob, Scheduler } from "@headless-lms/core/shared/ports";
5
5
  //#region src/index.d.ts
6
6
  interface ActionTaskInput {
@@ -99,6 +99,7 @@ declare class HatchetAutomationEngine implements AutomationEngine, Scheduler {
99
99
  private readonly logger?;
100
100
  private readonly reconcileEveryMs;
101
101
  private executor;
102
+ private deliveries;
102
103
  private jobs;
103
104
  private recurring;
104
105
  private worker;
@@ -113,6 +114,7 @@ declare class HatchetAutomationEngine implements AutomationEngine, Scheduler {
113
114
  private readonly client;
114
115
  constructor(client?: HatchetClientLike, logger?: Logger | undefined, reconcileEveryMs?: number);
115
116
  register(executor: AutomationExecutor): void;
117
+ registerDeliveries(executor: DeliveryExecutor): void;
116
118
  registerJobs(handlers: ScheduledJob[], recurring: RecurringJob[]): void;
117
119
  at(job: string, runAt: Date, key: string, payload: JsonValue): Promise<void>;
118
120
  private pendingRuns;
package/dist/index.js CHANGED
@@ -59,6 +59,7 @@ var HatchetAutomationEngine = class {
59
59
  logger;
60
60
  reconcileEveryMs;
61
61
  executor;
62
+ deliveries;
62
63
  jobs = /* @__PURE__ */ new Map();
63
64
  recurring = [];
64
65
  worker;
@@ -114,6 +115,9 @@ var HatchetAutomationEngine = class {
114
115
  register(executor) {
115
116
  this.executor = executor;
116
117
  }
118
+ registerDeliveries(executor) {
119
+ this.deliveries = executor;
120
+ }
117
121
  registerJobs(handlers, recurring) {
118
122
  this.jobs = new Map(handlers.map((handler) => [handler.job, handler]));
119
123
  this.recurring = [...recurring];
@@ -154,7 +158,7 @@ var HatchetAutomationEngine = class {
154
158
  await this.automationRunTask.runNoWait(d);
155
159
  }
156
160
  async deliver(d) {
157
- if (!this.executor) throw new Error("HatchetAutomationEngine.deliver called before register()");
161
+ if (!this.deliveries) throw new Error("HatchetAutomationEngine.deliver called before registerDeliveries()");
158
162
  await this.deliveryTask.runNoWait(d);
159
163
  }
160
164
  async start() {
@@ -300,9 +304,9 @@ var HatchetAutomationEngine = class {
300
304
  }
301
305
  }
302
306
  async runDelivery(input, ctx) {
303
- if (!this.executor) throw new Error("HatchetAutomationEngine: notification-delivery invoked before register()");
307
+ if (!this.deliveries) throw new Error("HatchetAutomationEngine: notification-delivery invoked before registerDeliveries()");
304
308
  const lastAttempt = (ctx?.retryCount?.() ?? 0) >= ACTION_RETRIES;
305
- await this.executor.runDelivery(input, lastAttempt);
309
+ await this.deliveries.runDelivery(input, lastAttempt);
306
310
  }
307
311
  async runSchedule(input) {
308
312
  if (!this.executor?.fireSchedule) throw new Error("HatchetAutomationEngine: automation-schedule invoked before register()");
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["Hatchet"],"sources":["../src/index.ts"],"sourcesContent":["import type {\n Logger,\n AutomationDispatch,\n AutomationExecutor,\n AutomationEngine,\n AutomationActionResult,\n DeliveryDispatch,\n ScheduledAutomation,\n JsonValue,\n} from \"@headless-lms/core/types\";\nimport type { RecurringJob, ScheduledJob, Scheduler } from \"@headless-lms/core/shared/ports\";\nimport { APIContracts } from \"@hatchet-dev/typescript-sdk/clients/rest/index.js\";\nimport {\n ConcurrencyLimitStrategy,\n HatchetClient as Hatchet,\n} from \"@hatchet-dev/typescript-sdk/v1/index.js\";\nimport type { LogConstructor } from \"@hatchet-dev/typescript-sdk/clients/hatchet-client/client-config.js\";\nimport {\n ACTION_FAILED,\n ActionFailedError,\n actionFailureMessage,\n} from \"@headless-lms/core/automations\";\n\nconst WORKFLOW_NAME = \"automation-run\";\nconst ACTION_TASK_NAME = \"automation-run-action\";\nconst SCHEDULE_TASK_NAME = \"automation-schedule\";\nconst JOB_TASK_NAME = \"scheduled-job\";\nconst DELIVERY_TASK_NAME = \"notification-delivery\";\nconst WORKER_NAME = \"automation-run-worker\";\nconst CRON_PREFIX = \"hlms-schedule:\";\nconst JOB_CRON_PREFIX = \"hlms-job:\";\nconst RECONCILE_EVERY_MS = 5 * 60_000;\nconst ACTION_RETRIES = 3;\nconst JOB_RETRIES = 3;\nconst RETRY_BACKOFF = { factor: 5, maxSeconds: 300 };\n\ninterface ActionTaskInput {\n dispatch: AutomationDispatch;\n index: number;\n}\n\ninterface ScheduleTaskInput {\n orgId: string;\n automationId: string;\n}\n\ninterface JobTaskInput {\n job: string;\n key: string;\n payload: JsonValue;\n}\n\ninterface TaskCtxLike {\n retryCount?(): number;\n}\n\ninterface JobCtxLike {\n workflowRunId(): string;\n}\n\ninterface DurableCtxLike {\n spawnChild(\n task: unknown,\n input: ActionTaskInput,\n options?: Record<string, unknown>,\n ): Promise<AutomationActionResult>;\n}\n\ninterface RunnableTask<I> {\n runNoWait(input: I): Promise<unknown>;\n}\n\ninterface HatchetWorkerLike {\n start(): Promise<void>;\n stop(): Promise<void>;\n}\n\nexport interface HatchetCronLike {\n metadata: { id: string };\n name?: string;\n cron: string;\n}\n\nexport interface HatchetCronClientLike {\n create(\n workflow: unknown,\n cron: { name: string; expression: string; input?: Record<string, unknown> },\n ): Promise<HatchetCronLike>;\n delete(cron: string | HatchetCronLike): Promise<void>;\n list(query: { workflow?: unknown; limit?: number; offset?: number }): Promise<{\n rows?: HatchetCronLike[];\n }>;\n}\n\nexport interface HatchetScheduledRunLike {\n metadata: { id: string };\n}\n\nexport interface HatchetScheduledClientLike {\n list(query: {\n workflow?: unknown;\n additionalMetadata?: string[];\n statuses?: APIContracts.ScheduledRunStatus[];\n }): Promise<{ rows?: HatchetScheduledRunLike[] }>;\n update(scheduledRun: string, update: { triggerAt: Date }): Promise<unknown>;\n bulkDelete(opts: {\n scheduledRuns?: string[];\n filter?: { additionalMetadata?: string[] };\n }): Promise<unknown>;\n}\n\nexport interface HatchetTaskLike<I> {\n runNoWait(input: I): Promise<unknown>;\n schedule(\n enqueueAt: Date,\n input: I,\n options?: { additionalMetadata?: Record<string, string> },\n ): Promise<unknown>;\n}\n\nexport interface HatchetClientLike {\n task<I>(opts: {\n name: string;\n retries?: number;\n backoff?: { factor?: number; maxSeconds?: number };\n concurrency?: {\n expression: string;\n maxRuns?: number;\n limitStrategy?: ConcurrencyLimitStrategy;\n };\n fn: (input: I, ctx: unknown) => Promise<unknown> | unknown;\n }): HatchetTaskLike<I>;\n durableTask(opts: {\n name: string;\n fn: (input: AutomationDispatch, ctx: DurableCtxLike) => Promise<void>;\n }): RunnableTask<AutomationDispatch>;\n worker(\n name: string,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- bridges to the SDK's own workflow union type without importing it\n opts: { workflows: any[]; handleKill?: boolean },\n ): Promise<HatchetWorkerLike>;\n crons: HatchetCronClientLike;\n scheduled: HatchetScheduledClientLike;\n}\n\nfunction floorMinute(at: Date): Date {\n const copy = new Date(at);\n copy.setUTCSeconds(0, 0);\n return copy;\n}\n\nexport function cronName(schedule: ScheduledAutomation): string {\n return `${CRON_PREFIX}${schedule.orgId}:${schedule.automationId}:${schedule.cron}`;\n}\n\nfunction jobMetadata(job: string, key: string): { job: string; key: string } {\n return { job: encodeURIComponent(job), key: encodeURIComponent(key) };\n}\n\nfunction jobMetadataFilter(job: string, key: string): string[] {\n const metadata = jobMetadata(job, key);\n return [`job:${metadata.job}`, `key:${metadata.key}`];\n}\n\nfunction sdkLogger(logger: Logger): LogConstructor {\n return (context) => {\n const log = logger.child({ hatchet: context });\n const failure = (error?: Error, extra?: object) => ({ ...extra, ...(error && { err: error }) });\n return {\n debug: (message, extra) => log.debug(message, extra),\n info: (message, extra) => log.info(message, extra),\n green: (message, extra) => log.info(message, extra),\n warn: (message, error, extra) => log.warn(message, failure(error, extra)),\n error: (message, error, extra) => log.error(message, failure(error, extra)),\n util: (key, message, extra) => log.debug(message, { ...extra, key }),\n };\n };\n}\n\nexport class HatchetAutomationEngine implements AutomationEngine, Scheduler {\n private executor: AutomationExecutor | undefined;\n private jobs = new Map<string, ScheduledJob>();\n private recurring: RecurringJob[] = [];\n private worker: HatchetWorkerLike | undefined;\n private syncing: Promise<void> | undefined;\n private syncingJobs: Promise<void> | undefined;\n private reconcileTimer: ReturnType<typeof setInterval> | undefined;\n private readonly actionTask: unknown;\n private readonly scheduleTask: unknown;\n private readonly jobTask: HatchetTaskLike<JobTaskInput>;\n private readonly deliveryTask: HatchetTaskLike<DeliveryDispatch>;\n private readonly automationRunTask: RunnableTask<AutomationDispatch>;\n\n private readonly client: HatchetClientLike;\n\n constructor(\n client?: HatchetClientLike,\n private readonly logger?: Logger,\n private readonly reconcileEveryMs: number = RECONCILE_EVERY_MS,\n ) {\n this.client =\n client ??\n (new Hatchet(logger ? { logger: sdkLogger(logger) } : {}) as unknown as HatchetClientLike);\n this.actionTask = this.client.task<ActionTaskInput>({\n name: ACTION_TASK_NAME,\n retries: ACTION_RETRIES,\n fn: async (input, ctx) => this.runAction(input, ctx as TaskCtxLike | undefined),\n });\n\n this.scheduleTask = this.client.task<ScheduleTaskInput>({\n name: SCHEDULE_TASK_NAME,\n fn: async (input) => this.runSchedule(input),\n });\n\n this.jobTask = this.client.task<JobTaskInput>({\n name: JOB_TASK_NAME,\n retries: JOB_RETRIES,\n backoff: RETRY_BACKOFF,\n concurrency: {\n expression: \"input.job + ':' + input.key\",\n maxRuns: 1,\n limitStrategy: ConcurrencyLimitStrategy.GROUP_ROUND_ROBIN,\n },\n fn: async (input, ctx) => this.runJob(input, ctx as JobCtxLike),\n });\n\n this.deliveryTask = this.client.task<DeliveryDispatch>({\n name: DELIVERY_TASK_NAME,\n retries: ACTION_RETRIES,\n backoff: RETRY_BACKOFF,\n concurrency: {\n expression: \"input.deliveryId\",\n maxRuns: 1,\n limitStrategy: ConcurrencyLimitStrategy.GROUP_ROUND_ROBIN,\n },\n fn: async (input, ctx) => this.runDelivery(input, ctx as TaskCtxLike | undefined),\n });\n\n this.automationRunTask = this.client.durableTask({\n name: WORKFLOW_NAME,\n fn: async (dispatch, ctx) => this.runDispatch(dispatch, ctx),\n });\n }\n\n register(executor: AutomationExecutor): void {\n this.executor = executor;\n }\n\n registerJobs(handlers: ScheduledJob[], recurring: RecurringJob[]): void {\n this.jobs = new Map(handlers.map((handler) => [handler.job, handler]));\n this.recurring = [...recurring];\n }\n\n async at(job: string, runAt: Date, key: string, payload: JsonValue): Promise<void> {\n const [found, ...extra] = await this.pendingRuns(job, key);\n if (!found) {\n await this.scheduleJob(job, runAt, key, payload);\n return;\n }\n try {\n await this.client.scheduled.update(found.metadata.id, { triggerAt: runAt });\n } catch (err) {\n const pending = await this.pendingRuns(job, key);\n if (pending.some((run) => run.metadata.id === found.metadata.id)) {\n throw err;\n }\n await this.scheduleJob(job, runAt, key, payload);\n }\n if (extra.length > 0) {\n await this.client.scheduled.bulkDelete({\n scheduledRuns: extra.map((run) => run.metadata.id),\n });\n }\n }\n\n private async pendingRuns(job: string, key: string): Promise<HatchetScheduledRunLike[]> {\n const page = await this.client.scheduled.list({\n workflow: this.jobTask,\n additionalMetadata: jobMetadataFilter(job, key),\n statuses: [APIContracts.ScheduledRunStatus.SCHEDULED],\n });\n return page.rows ?? [];\n }\n\n private async scheduleJob(\n job: string,\n runAt: Date,\n key: string,\n payload: JsonValue,\n ): Promise<void> {\n await this.jobTask.schedule(\n runAt,\n { job, key, payload },\n { additionalMetadata: jobMetadata(job, key) },\n );\n }\n\n async cancel(job: string, key: string): Promise<void> {\n await this.client.scheduled.bulkDelete({\n filter: { additionalMetadata: jobMetadataFilter(job, key) },\n });\n }\n\n async dispatch(d: AutomationDispatch): Promise<void> {\n if (!this.executor) {\n throw new Error(\"HatchetAutomationEngine.dispatch called before register()\");\n }\n await this.automationRunTask.runNoWait(d);\n }\n\n async deliver(d: DeliveryDispatch): Promise<void> {\n if (!this.executor) {\n throw new Error(\"HatchetAutomationEngine.deliver called before register()\");\n }\n await this.deliveryTask.runNoWait(d);\n }\n\n async start(): Promise<void> {\n if (!this.executor) {\n throw new Error(\"HatchetAutomationEngine.start called before register()\");\n }\n this.worker = await this.client.worker(WORKER_NAME, {\n handleKill: false,\n workflows: [\n this.actionTask,\n this.automationRunTask,\n this.scheduleTask,\n this.jobTask,\n this.deliveryTask,\n ],\n });\n await this.reconcileJobsLogged();\n void this.worker.start().catch((err: unknown) => {\n this.logger?.error(\"hatchet worker stopped unexpectedly\", { err });\n });\n if (this.reconcileTimer) {\n clearInterval(this.reconcileTimer);\n }\n this.reconcileTimer = setInterval(() => void this.reconcileAll(), this.reconcileEveryMs);\n this.reconcileTimer.unref?.();\n await this.syncLogged();\n }\n\n async stop(): Promise<void> {\n if (this.reconcileTimer) {\n clearInterval(this.reconcileTimer);\n }\n this.reconcileTimer = undefined;\n if (!this.worker) {\n return;\n }\n await this.worker.stop();\n this.worker = undefined;\n this.logger?.info(\"hatchet worker stopped\");\n }\n\n private async reconcileAll(): Promise<void> {\n await this.reconcileJobsLogged();\n await this.syncLogged();\n }\n\n private async reconcileJobsLogged(): Promise<void> {\n if (this.syncingJobs) {\n return this.syncingJobs;\n }\n this.syncingJobs = this.reconcileJobs()\n .catch((err: unknown) => {\n this.logger?.error(\"hatchet job crons not reconciled\", { err });\n })\n .finally(() => {\n this.syncingJobs = undefined;\n });\n return this.syncingJobs;\n }\n\n private async syncLogged(): Promise<void> {\n try {\n await this.syncSchedules();\n } catch (err) {\n this.logger?.error(\"hatchet schedules not reconciled\", { err });\n }\n }\n\n async syncSchedules(): Promise<void> {\n if (this.syncing) {\n await this.syncing;\n return this.syncSchedules();\n }\n this.syncing = this.reconcile().finally(() => {\n this.syncing = undefined;\n });\n await this.syncing;\n }\n\n private async reconcile(): Promise<void> {\n if (!this.executor?.listSchedules) {\n return;\n }\n const wanted = new Map<string, ScheduledAutomation>();\n for (const schedule of await this.executor.listSchedules()) {\n wanted.set(cronName(schedule), schedule);\n }\n const existing = await this.listCrons(this.scheduleTask);\n const seen = new Set<string>();\n for (const cron of existing) {\n if (!cron.name?.startsWith(CRON_PREFIX)) {\n continue;\n }\n const schedule = wanted.get(cron.name);\n if (schedule && schedule.cron === cron.cron && !seen.has(cron.name)) {\n seen.add(cron.name);\n continue;\n }\n await this.client.crons.delete(cron);\n }\n for (const [name, schedule] of wanted) {\n if (seen.has(name)) {\n continue;\n }\n await this.client.crons.create(this.scheduleTask, {\n name,\n expression: schedule.cron,\n input: { orgId: schedule.orgId, automationId: schedule.automationId },\n });\n }\n this.logger?.info(\"hatchet schedules synced\", { count: wanted.size });\n }\n\n private async reconcileJobs(): Promise<void> {\n const wanted = new Map<string, RecurringJob>();\n for (const recurring of this.recurring) {\n wanted.set(`${JOB_CRON_PREFIX}${recurring.job}`, recurring);\n }\n const existing = await this.listCrons(this.jobTask);\n const seen = new Set<string>();\n for (const cron of existing) {\n if (!cron.name?.startsWith(JOB_CRON_PREFIX)) {\n continue;\n }\n const recurring = wanted.get(cron.name);\n if (recurring && recurring.cron === cron.cron && !seen.has(cron.name)) {\n seen.add(cron.name);\n continue;\n }\n await this.client.crons.delete(cron);\n }\n for (const [name, recurring] of wanted) {\n if (seen.has(name)) {\n continue;\n }\n await this.client.crons.create(this.jobTask, {\n name,\n expression: recurring.cron,\n input: { job: recurring.job, key: recurring.job, payload: null },\n });\n }\n this.logger?.info(\"hatchet job crons synced\", { count: wanted.size });\n }\n\n private async runJob(input: JobTaskInput, ctx: JobCtxLike): Promise<void> {\n const handler = this.jobs.get(input.job);\n if (!handler) {\n this.logger?.error(\"scheduled job has no handler\", { job: input.job, key: input.key });\n return;\n }\n await handler.run(input.payload, { id: ctx.workflowRunId(), startedAt: new Date() });\n }\n\n private async listCrons(workflow: unknown): Promise<HatchetCronLike[]> {\n const rows: HatchetCronLike[] = [];\n const limit = 100;\n for (let offset = 0; ; offset += limit) {\n const page = await this.client.crons.list({ workflow, limit, offset });\n const batch = page.rows ?? [];\n rows.push(...batch);\n if (batch.length < limit) {\n return rows;\n }\n }\n }\n\n private async runDelivery(input: DeliveryDispatch, ctx: TaskCtxLike | undefined): Promise<void> {\n if (!this.executor) {\n throw new Error(\"HatchetAutomationEngine: notification-delivery invoked before register()\");\n }\n const lastAttempt = (ctx?.retryCount?.() ?? 0) >= ACTION_RETRIES;\n await this.executor.runDelivery(input, lastAttempt);\n }\n\n private async runSchedule(input: ScheduleTaskInput): Promise<void> {\n if (!this.executor?.fireSchedule) {\n throw new Error(\"HatchetAutomationEngine: automation-schedule invoked before register()\");\n }\n await this.executor.fireSchedule(input.orgId, input.automationId, floorMinute(new Date()));\n }\n\n private async runAction(\n input: ActionTaskInput,\n ctx: TaskCtxLike | undefined,\n ): Promise<AutomationActionResult> {\n if (!this.executor) {\n throw new Error(\"HatchetAutomationEngine: automation-run-action invoked before register()\");\n }\n const { dispatch, index } = input;\n try {\n return await this.executor.runAction(dispatch, index);\n } catch (err) {\n if ((ctx?.retryCount?.() ?? ACTION_RETRIES) < ACTION_RETRIES) {\n throw err;\n }\n if (!(err instanceof ActionFailedError)) {\n this.logActionError(dispatch, index, err);\n }\n return {\n index,\n type: dispatch.actions[index]!.type,\n status: \"failed\",\n error: actionFailureMessage(err),\n };\n }\n }\n\n private logActionError(dispatch: AutomationDispatch, index: number, err: unknown): void {\n this.logger?.error(\"automation action failed\", {\n orgId: dispatch.orgId,\n automationId: dispatch.automationId,\n runId: dispatch.runId,\n index,\n err,\n });\n }\n\n private async runDispatch(dispatch: AutomationDispatch, ctx: DurableCtxLike): Promise<void> {\n if (!this.executor) {\n throw new Error(\"HatchetAutomationEngine: automation-run invoked before register()\");\n }\n const executor = this.executor;\n\n const results: AutomationActionResult[] = [];\n for (let index = 0; index < dispatch.actions.length; index++) {\n let result: AutomationActionResult;\n try {\n result = await ctx.spawnChild(this.actionTask, { dispatch, index });\n } catch (err) {\n this.logActionError(dispatch, index, err);\n result = {\n index,\n type: dispatch.actions[index]!.type,\n status: \"failed\",\n error: ACTION_FAILED,\n };\n }\n results.push(result);\n if (result.status === \"failed\") {\n break;\n }\n }\n\n await executor.finalize(dispatch, results);\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["Hatchet"],"sources":["../src/index.ts"],"sourcesContent":["import type {\n Logger,\n AutomationDispatch,\n AutomationExecutor,\n AutomationEngine,\n AutomationActionResult,\n DeliveryDispatch,\n DeliveryExecutor,\n ScheduledAutomation,\n JsonValue,\n} from \"@headless-lms/core/types\";\nimport type { RecurringJob, ScheduledJob, Scheduler } from \"@headless-lms/core/shared/ports\";\nimport { APIContracts } from \"@hatchet-dev/typescript-sdk/clients/rest/index.js\";\nimport {\n ConcurrencyLimitStrategy,\n HatchetClient as Hatchet,\n} from \"@hatchet-dev/typescript-sdk/v1/index.js\";\nimport type { LogConstructor } from \"@hatchet-dev/typescript-sdk/clients/hatchet-client/client-config.js\";\nimport {\n ACTION_FAILED,\n ActionFailedError,\n actionFailureMessage,\n} from \"@headless-lms/core/automations\";\n\nconst WORKFLOW_NAME = \"automation-run\";\nconst ACTION_TASK_NAME = \"automation-run-action\";\nconst SCHEDULE_TASK_NAME = \"automation-schedule\";\nconst JOB_TASK_NAME = \"scheduled-job\";\nconst DELIVERY_TASK_NAME = \"notification-delivery\";\nconst WORKER_NAME = \"automation-run-worker\";\nconst CRON_PREFIX = \"hlms-schedule:\";\nconst JOB_CRON_PREFIX = \"hlms-job:\";\nconst RECONCILE_EVERY_MS = 5 * 60_000;\nconst ACTION_RETRIES = 3;\nconst JOB_RETRIES = 3;\nconst RETRY_BACKOFF = { factor: 5, maxSeconds: 300 };\n\ninterface ActionTaskInput {\n dispatch: AutomationDispatch;\n index: number;\n}\n\ninterface ScheduleTaskInput {\n orgId: string;\n automationId: string;\n}\n\ninterface JobTaskInput {\n job: string;\n key: string;\n payload: JsonValue;\n}\n\ninterface TaskCtxLike {\n retryCount?(): number;\n}\n\ninterface JobCtxLike {\n workflowRunId(): string;\n}\n\ninterface DurableCtxLike {\n spawnChild(\n task: unknown,\n input: ActionTaskInput,\n options?: Record<string, unknown>,\n ): Promise<AutomationActionResult>;\n}\n\ninterface RunnableTask<I> {\n runNoWait(input: I): Promise<unknown>;\n}\n\ninterface HatchetWorkerLike {\n start(): Promise<void>;\n stop(): Promise<void>;\n}\n\nexport interface HatchetCronLike {\n metadata: { id: string };\n name?: string;\n cron: string;\n}\n\nexport interface HatchetCronClientLike {\n create(\n workflow: unknown,\n cron: { name: string; expression: string; input?: Record<string, unknown> },\n ): Promise<HatchetCronLike>;\n delete(cron: string | HatchetCronLike): Promise<void>;\n list(query: { workflow?: unknown; limit?: number; offset?: number }): Promise<{\n rows?: HatchetCronLike[];\n }>;\n}\n\nexport interface HatchetScheduledRunLike {\n metadata: { id: string };\n}\n\nexport interface HatchetScheduledClientLike {\n list(query: {\n workflow?: unknown;\n additionalMetadata?: string[];\n statuses?: APIContracts.ScheduledRunStatus[];\n }): Promise<{ rows?: HatchetScheduledRunLike[] }>;\n update(scheduledRun: string, update: { triggerAt: Date }): Promise<unknown>;\n bulkDelete(opts: {\n scheduledRuns?: string[];\n filter?: { additionalMetadata?: string[] };\n }): Promise<unknown>;\n}\n\nexport interface HatchetTaskLike<I> {\n runNoWait(input: I): Promise<unknown>;\n schedule(\n enqueueAt: Date,\n input: I,\n options?: { additionalMetadata?: Record<string, string> },\n ): Promise<unknown>;\n}\n\nexport interface HatchetClientLike {\n task<I>(opts: {\n name: string;\n retries?: number;\n backoff?: { factor?: number; maxSeconds?: number };\n concurrency?: {\n expression: string;\n maxRuns?: number;\n limitStrategy?: ConcurrencyLimitStrategy;\n };\n fn: (input: I, ctx: unknown) => Promise<unknown> | unknown;\n }): HatchetTaskLike<I>;\n durableTask(opts: {\n name: string;\n fn: (input: AutomationDispatch, ctx: DurableCtxLike) => Promise<void>;\n }): RunnableTask<AutomationDispatch>;\n worker(\n name: string,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- bridges to the SDK's own workflow union type without importing it\n opts: { workflows: any[]; handleKill?: boolean },\n ): Promise<HatchetWorkerLike>;\n crons: HatchetCronClientLike;\n scheduled: HatchetScheduledClientLike;\n}\n\nfunction floorMinute(at: Date): Date {\n const copy = new Date(at);\n copy.setUTCSeconds(0, 0);\n return copy;\n}\n\nexport function cronName(schedule: ScheduledAutomation): string {\n return `${CRON_PREFIX}${schedule.orgId}:${schedule.automationId}:${schedule.cron}`;\n}\n\nfunction jobMetadata(job: string, key: string): { job: string; key: string } {\n return { job: encodeURIComponent(job), key: encodeURIComponent(key) };\n}\n\nfunction jobMetadataFilter(job: string, key: string): string[] {\n const metadata = jobMetadata(job, key);\n return [`job:${metadata.job}`, `key:${metadata.key}`];\n}\n\nfunction sdkLogger(logger: Logger): LogConstructor {\n return (context) => {\n const log = logger.child({ hatchet: context });\n const failure = (error?: Error, extra?: object) => ({ ...extra, ...(error && { err: error }) });\n return {\n debug: (message, extra) => log.debug(message, extra),\n info: (message, extra) => log.info(message, extra),\n green: (message, extra) => log.info(message, extra),\n warn: (message, error, extra) => log.warn(message, failure(error, extra)),\n error: (message, error, extra) => log.error(message, failure(error, extra)),\n util: (key, message, extra) => log.debug(message, { ...extra, key }),\n };\n };\n}\n\nexport class HatchetAutomationEngine implements AutomationEngine, Scheduler {\n private executor: AutomationExecutor | undefined;\n private deliveries: DeliveryExecutor | undefined;\n private jobs = new Map<string, ScheduledJob>();\n private recurring: RecurringJob[] = [];\n private worker: HatchetWorkerLike | undefined;\n private syncing: Promise<void> | undefined;\n private syncingJobs: Promise<void> | undefined;\n private reconcileTimer: ReturnType<typeof setInterval> | undefined;\n private readonly actionTask: unknown;\n private readonly scheduleTask: unknown;\n private readonly jobTask: HatchetTaskLike<JobTaskInput>;\n private readonly deliveryTask: HatchetTaskLike<DeliveryDispatch>;\n private readonly automationRunTask: RunnableTask<AutomationDispatch>;\n\n private readonly client: HatchetClientLike;\n\n constructor(\n client?: HatchetClientLike,\n private readonly logger?: Logger,\n private readonly reconcileEveryMs: number = RECONCILE_EVERY_MS,\n ) {\n this.client =\n client ??\n (new Hatchet(logger ? { logger: sdkLogger(logger) } : {}) as unknown as HatchetClientLike);\n this.actionTask = this.client.task<ActionTaskInput>({\n name: ACTION_TASK_NAME,\n retries: ACTION_RETRIES,\n fn: async (input, ctx) => this.runAction(input, ctx as TaskCtxLike | undefined),\n });\n\n this.scheduleTask = this.client.task<ScheduleTaskInput>({\n name: SCHEDULE_TASK_NAME,\n fn: async (input) => this.runSchedule(input),\n });\n\n this.jobTask = this.client.task<JobTaskInput>({\n name: JOB_TASK_NAME,\n retries: JOB_RETRIES,\n backoff: RETRY_BACKOFF,\n concurrency: {\n expression: \"input.job + ':' + input.key\",\n maxRuns: 1,\n limitStrategy: ConcurrencyLimitStrategy.GROUP_ROUND_ROBIN,\n },\n fn: async (input, ctx) => this.runJob(input, ctx as JobCtxLike),\n });\n\n this.deliveryTask = this.client.task<DeliveryDispatch>({\n name: DELIVERY_TASK_NAME,\n retries: ACTION_RETRIES,\n backoff: RETRY_BACKOFF,\n concurrency: {\n expression: \"input.deliveryId\",\n maxRuns: 1,\n limitStrategy: ConcurrencyLimitStrategy.GROUP_ROUND_ROBIN,\n },\n fn: async (input, ctx) => this.runDelivery(input, ctx as TaskCtxLike | undefined),\n });\n\n this.automationRunTask = this.client.durableTask({\n name: WORKFLOW_NAME,\n fn: async (dispatch, ctx) => this.runDispatch(dispatch, ctx),\n });\n }\n\n register(executor: AutomationExecutor): void {\n this.executor = executor;\n }\n\n registerDeliveries(executor: DeliveryExecutor): void {\n this.deliveries = executor;\n }\n\n registerJobs(handlers: ScheduledJob[], recurring: RecurringJob[]): void {\n this.jobs = new Map(handlers.map((handler) => [handler.job, handler]));\n this.recurring = [...recurring];\n }\n\n async at(job: string, runAt: Date, key: string, payload: JsonValue): Promise<void> {\n const [found, ...extra] = await this.pendingRuns(job, key);\n if (!found) {\n await this.scheduleJob(job, runAt, key, payload);\n return;\n }\n try {\n await this.client.scheduled.update(found.metadata.id, { triggerAt: runAt });\n } catch (err) {\n const pending = await this.pendingRuns(job, key);\n if (pending.some((run) => run.metadata.id === found.metadata.id)) {\n throw err;\n }\n await this.scheduleJob(job, runAt, key, payload);\n }\n if (extra.length > 0) {\n await this.client.scheduled.bulkDelete({\n scheduledRuns: extra.map((run) => run.metadata.id),\n });\n }\n }\n\n private async pendingRuns(job: string, key: string): Promise<HatchetScheduledRunLike[]> {\n const page = await this.client.scheduled.list({\n workflow: this.jobTask,\n additionalMetadata: jobMetadataFilter(job, key),\n statuses: [APIContracts.ScheduledRunStatus.SCHEDULED],\n });\n return page.rows ?? [];\n }\n\n private async scheduleJob(\n job: string,\n runAt: Date,\n key: string,\n payload: JsonValue,\n ): Promise<void> {\n await this.jobTask.schedule(\n runAt,\n { job, key, payload },\n { additionalMetadata: jobMetadata(job, key) },\n );\n }\n\n async cancel(job: string, key: string): Promise<void> {\n await this.client.scheduled.bulkDelete({\n filter: { additionalMetadata: jobMetadataFilter(job, key) },\n });\n }\n\n async dispatch(d: AutomationDispatch): Promise<void> {\n if (!this.executor) {\n throw new Error(\"HatchetAutomationEngine.dispatch called before register()\");\n }\n await this.automationRunTask.runNoWait(d);\n }\n\n async deliver(d: DeliveryDispatch): Promise<void> {\n if (!this.deliveries) {\n throw new Error(\"HatchetAutomationEngine.deliver called before registerDeliveries()\");\n }\n await this.deliveryTask.runNoWait(d);\n }\n\n async start(): Promise<void> {\n if (!this.executor) {\n throw new Error(\"HatchetAutomationEngine.start called before register()\");\n }\n this.worker = await this.client.worker(WORKER_NAME, {\n handleKill: false,\n workflows: [\n this.actionTask,\n this.automationRunTask,\n this.scheduleTask,\n this.jobTask,\n this.deliveryTask,\n ],\n });\n await this.reconcileJobsLogged();\n void this.worker.start().catch((err: unknown) => {\n this.logger?.error(\"hatchet worker stopped unexpectedly\", { err });\n });\n if (this.reconcileTimer) {\n clearInterval(this.reconcileTimer);\n }\n this.reconcileTimer = setInterval(() => void this.reconcileAll(), this.reconcileEveryMs);\n this.reconcileTimer.unref?.();\n await this.syncLogged();\n }\n\n async stop(): Promise<void> {\n if (this.reconcileTimer) {\n clearInterval(this.reconcileTimer);\n }\n this.reconcileTimer = undefined;\n if (!this.worker) {\n return;\n }\n await this.worker.stop();\n this.worker = undefined;\n this.logger?.info(\"hatchet worker stopped\");\n }\n\n private async reconcileAll(): Promise<void> {\n await this.reconcileJobsLogged();\n await this.syncLogged();\n }\n\n private async reconcileJobsLogged(): Promise<void> {\n if (this.syncingJobs) {\n return this.syncingJobs;\n }\n this.syncingJobs = this.reconcileJobs()\n .catch((err: unknown) => {\n this.logger?.error(\"hatchet job crons not reconciled\", { err });\n })\n .finally(() => {\n this.syncingJobs = undefined;\n });\n return this.syncingJobs;\n }\n\n private async syncLogged(): Promise<void> {\n try {\n await this.syncSchedules();\n } catch (err) {\n this.logger?.error(\"hatchet schedules not reconciled\", { err });\n }\n }\n\n async syncSchedules(): Promise<void> {\n if (this.syncing) {\n await this.syncing;\n return this.syncSchedules();\n }\n this.syncing = this.reconcile().finally(() => {\n this.syncing = undefined;\n });\n await this.syncing;\n }\n\n private async reconcile(): Promise<void> {\n if (!this.executor?.listSchedules) {\n return;\n }\n const wanted = new Map<string, ScheduledAutomation>();\n for (const schedule of await this.executor.listSchedules()) {\n wanted.set(cronName(schedule), schedule);\n }\n const existing = await this.listCrons(this.scheduleTask);\n const seen = new Set<string>();\n for (const cron of existing) {\n if (!cron.name?.startsWith(CRON_PREFIX)) {\n continue;\n }\n const schedule = wanted.get(cron.name);\n if (schedule && schedule.cron === cron.cron && !seen.has(cron.name)) {\n seen.add(cron.name);\n continue;\n }\n await this.client.crons.delete(cron);\n }\n for (const [name, schedule] of wanted) {\n if (seen.has(name)) {\n continue;\n }\n await this.client.crons.create(this.scheduleTask, {\n name,\n expression: schedule.cron,\n input: { orgId: schedule.orgId, automationId: schedule.automationId },\n });\n }\n this.logger?.info(\"hatchet schedules synced\", { count: wanted.size });\n }\n\n private async reconcileJobs(): Promise<void> {\n const wanted = new Map<string, RecurringJob>();\n for (const recurring of this.recurring) {\n wanted.set(`${JOB_CRON_PREFIX}${recurring.job}`, recurring);\n }\n const existing = await this.listCrons(this.jobTask);\n const seen = new Set<string>();\n for (const cron of existing) {\n if (!cron.name?.startsWith(JOB_CRON_PREFIX)) {\n continue;\n }\n const recurring = wanted.get(cron.name);\n if (recurring && recurring.cron === cron.cron && !seen.has(cron.name)) {\n seen.add(cron.name);\n continue;\n }\n await this.client.crons.delete(cron);\n }\n for (const [name, recurring] of wanted) {\n if (seen.has(name)) {\n continue;\n }\n await this.client.crons.create(this.jobTask, {\n name,\n expression: recurring.cron,\n input: { job: recurring.job, key: recurring.job, payload: null },\n });\n }\n this.logger?.info(\"hatchet job crons synced\", { count: wanted.size });\n }\n\n private async runJob(input: JobTaskInput, ctx: JobCtxLike): Promise<void> {\n const handler = this.jobs.get(input.job);\n if (!handler) {\n this.logger?.error(\"scheduled job has no handler\", { job: input.job, key: input.key });\n return;\n }\n await handler.run(input.payload, { id: ctx.workflowRunId(), startedAt: new Date() });\n }\n\n private async listCrons(workflow: unknown): Promise<HatchetCronLike[]> {\n const rows: HatchetCronLike[] = [];\n const limit = 100;\n for (let offset = 0; ; offset += limit) {\n const page = await this.client.crons.list({ workflow, limit, offset });\n const batch = page.rows ?? [];\n rows.push(...batch);\n if (batch.length < limit) {\n return rows;\n }\n }\n }\n\n private async runDelivery(input: DeliveryDispatch, ctx: TaskCtxLike | undefined): Promise<void> {\n if (!this.deliveries) {\n throw new Error(\n \"HatchetAutomationEngine: notification-delivery invoked before registerDeliveries()\",\n );\n }\n const lastAttempt = (ctx?.retryCount?.() ?? 0) >= ACTION_RETRIES;\n await this.deliveries.runDelivery(input, lastAttempt);\n }\n\n private async runSchedule(input: ScheduleTaskInput): Promise<void> {\n if (!this.executor?.fireSchedule) {\n throw new Error(\"HatchetAutomationEngine: automation-schedule invoked before register()\");\n }\n await this.executor.fireSchedule(input.orgId, input.automationId, floorMinute(new Date()));\n }\n\n private async runAction(\n input: ActionTaskInput,\n ctx: TaskCtxLike | undefined,\n ): Promise<AutomationActionResult> {\n if (!this.executor) {\n throw new Error(\"HatchetAutomationEngine: automation-run-action invoked before register()\");\n }\n const { dispatch, index } = input;\n try {\n return await this.executor.runAction(dispatch, index);\n } catch (err) {\n if ((ctx?.retryCount?.() ?? ACTION_RETRIES) < ACTION_RETRIES) {\n throw err;\n }\n if (!(err instanceof ActionFailedError)) {\n this.logActionError(dispatch, index, err);\n }\n return {\n index,\n type: dispatch.actions[index]!.type,\n status: \"failed\",\n error: actionFailureMessage(err),\n };\n }\n }\n\n private logActionError(dispatch: AutomationDispatch, index: number, err: unknown): void {\n this.logger?.error(\"automation action failed\", {\n orgId: dispatch.orgId,\n automationId: dispatch.automationId,\n runId: dispatch.runId,\n index,\n err,\n });\n }\n\n private async runDispatch(dispatch: AutomationDispatch, ctx: DurableCtxLike): Promise<void> {\n if (!this.executor) {\n throw new Error(\"HatchetAutomationEngine: automation-run invoked before register()\");\n }\n const executor = this.executor;\n\n const results: AutomationActionResult[] = [];\n for (let index = 0; index < dispatch.actions.length; index++) {\n let result: AutomationActionResult;\n try {\n result = await ctx.spawnChild(this.actionTask, { dispatch, index });\n } catch (err) {\n this.logActionError(dispatch, index, err);\n result = {\n index,\n type: dispatch.actions[index]!.type,\n status: \"failed\",\n error: ACTION_FAILED,\n };\n }\n results.push(result);\n if (result.status === \"failed\") {\n break;\n }\n }\n\n await executor.finalize(dispatch, results);\n }\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@headless-lms/adapter-workflow-hatchet",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -12,8 +12,8 @@
12
12
  },
13
13
  "dependencies": {
14
14
  "@hatchet-dev/typescript-sdk": "^1.28.0",
15
- "@headless-lms/adapter-defaults": "0.5.0",
16
- "@headless-lms/core": "0.5.0"
15
+ "@headless-lms/adapter-defaults": "0.5.2",
16
+ "@headless-lms/core": "0.7.0"
17
17
  },
18
18
  "devDependencies": {
19
19
  "@types/node": "^22.10.2",