@nestjs/workflows 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (265) hide show
  1. package/LICENSE +23 -0
  2. package/README.md +50 -0
  3. package/dist/cli.d.ts +2 -0
  4. package/dist/cli.js +8 -0
  5. package/dist/core/codecs/aes-gcm-payload.codec.d.ts +42 -0
  6. package/dist/core/codecs/aes-gcm-payload.codec.js +119 -0
  7. package/dist/core/codecs/index.d.ts +2 -0
  8. package/dist/core/codecs/index.js +2 -0
  9. package/dist/core/codecs/payload-codecs.d.ts +59 -0
  10. package/dist/core/codecs/payload-codecs.js +130 -0
  11. package/dist/core/index.d.ts +16 -0
  12. package/dist/core/index.js +21 -0
  13. package/dist/core/interfaces/clock.interface.d.ts +18 -0
  14. package/dist/core/interfaces/clock.interface.js +1 -0
  15. package/dist/core/interfaces/index.d.ts +9 -0
  16. package/dist/core/interfaces/index.js +9 -0
  17. package/dist/core/interfaces/leased-worker-options.interface.d.ts +94 -0
  18. package/dist/core/interfaces/leased-worker-options.interface.js +1 -0
  19. package/dist/core/interfaces/limits.interface.d.ts +92 -0
  20. package/dist/core/interfaces/limits.interface.js +1 -0
  21. package/dist/core/interfaces/payload-codec.interface.d.ts +64 -0
  22. package/dist/core/interfaces/payload-codec.interface.js +1 -0
  23. package/dist/core/interfaces/result-waiter-options.interface.d.ts +52 -0
  24. package/dist/core/interfaces/result-waiter-options.interface.js +1 -0
  25. package/dist/core/interfaces/retry-settings.interface.d.ts +71 -0
  26. package/dist/core/interfaces/retry-settings.interface.js +1 -0
  27. package/dist/core/interfaces/schedule-store.interface.d.ts +143 -0
  28. package/dist/core/interfaces/schedule-store.interface.js +1 -0
  29. package/dist/core/interfaces/schedule.interface.d.ts +106 -0
  30. package/dist/core/interfaces/schedule.interface.js +1 -0
  31. package/dist/core/interfaces/scheduler-options.interface.d.ts +152 -0
  32. package/dist/core/interfaces/scheduler-options.interface.js +1 -0
  33. package/dist/core/limits/index.d.ts +1 -0
  34. package/dist/core/limits/index.js +1 -0
  35. package/dist/core/limits/limits.d.ts +61 -0
  36. package/dist/core/limits/limits.js +130 -0
  37. package/dist/core/results/index.d.ts +1 -0
  38. package/dist/core/results/index.js +1 -0
  39. package/dist/core/results/result-waiter.d.ts +54 -0
  40. package/dist/core/results/result-waiter.js +140 -0
  41. package/dist/core/retries/index.d.ts +1 -0
  42. package/dist/core/retries/index.js +1 -0
  43. package/dist/core/retries/retry.d.ts +60 -0
  44. package/dist/core/retries/retry.js +107 -0
  45. package/dist/core/scheduling/cron.util.d.ts +52 -0
  46. package/dist/core/scheduling/cron.util.js +262 -0
  47. package/dist/core/scheduling/encoded-schedule.store.d.ts +26 -0
  48. package/dist/core/scheduling/encoded-schedule.store.js +54 -0
  49. package/dist/core/scheduling/in-memory-schedule.store.d.ts +20 -0
  50. package/dist/core/scheduling/in-memory-schedule.store.js +90 -0
  51. package/dist/core/scheduling/index.d.ts +3 -0
  52. package/dist/core/scheduling/index.js +3 -0
  53. package/dist/core/scheduling/rrule.util.d.ts +55 -0
  54. package/dist/core/scheduling/rrule.util.js +371 -0
  55. package/dist/core/scheduling/schedule-spec.d.ts +57 -0
  56. package/dist/core/scheduling/schedule-spec.js +233 -0
  57. package/dist/core/scheduling/scheduler.d.ts +134 -0
  58. package/dist/core/scheduling/scheduler.js +450 -0
  59. package/dist/core/scheduling/time-zone.util.d.ts +18 -0
  60. package/dist/core/scheduling/time-zone.util.js +88 -0
  61. package/dist/core/time/clock.d.ts +28 -0
  62. package/dist/core/time/clock.js +35 -0
  63. package/dist/core/time/duration.d.ts +21 -0
  64. package/dist/core/time/duration.js +30 -0
  65. package/dist/core/time/index.d.ts +2 -0
  66. package/dist/core/time/index.js +2 -0
  67. package/dist/core/utils/canonical.util.d.ts +2 -0
  68. package/dist/core/utils/canonical.util.js +4 -0
  69. package/dist/core/utils/maybe.util.d.ts +8 -0
  70. package/dist/core/utils/maybe.util.js +14 -0
  71. package/dist/core/utils/payload-place.util.d.ts +10 -0
  72. package/dist/core/utils/payload-place.util.js +32 -0
  73. package/dist/core/workers/index.d.ts +1 -0
  74. package/dist/core/workers/index.js +1 -0
  75. package/dist/core/workers/leased-worker.d.ts +86 -0
  76. package/dist/core/workers/leased-worker.js +280 -0
  77. package/dist/cqrs/decorators/index.d.ts +2 -0
  78. package/dist/cqrs/decorators/index.js +2 -0
  79. package/dist/cqrs/decorators/signal-on.decorator.d.ts +18 -0
  80. package/dist/cqrs/decorators/signal-on.decorator.js +34 -0
  81. package/dist/cqrs/decorators/start-on.decorator.d.ts +18 -0
  82. package/dist/cqrs/decorators/start-on.decorator.js +49 -0
  83. package/dist/cqrs/index.d.ts +3 -0
  84. package/dist/cqrs/index.js +5 -0
  85. package/dist/cqrs/interfaces/index.d.ts +4 -0
  86. package/dist/cqrs/interfaces/index.js +4 -0
  87. package/dist/cqrs/interfaces/signal-on-options.interface.d.ts +22 -0
  88. package/dist/cqrs/interfaces/signal-on-options.interface.js +1 -0
  89. package/dist/cqrs/interfaces/start-on-options.interface.d.ts +23 -0
  90. package/dist/cqrs/interfaces/start-on-options.interface.js +1 -0
  91. package/dist/cqrs/interfaces/workflow-dispatcher-context.interface.d.ts +10 -0
  92. package/dist/cqrs/interfaces/workflow-dispatcher-context.interface.js +1 -0
  93. package/dist/cqrs/interfaces/workflow-event-route.interface.d.ts +20 -0
  94. package/dist/cqrs/interfaces/workflow-event-route.interface.js +1 -0
  95. package/dist/cqrs/utils/event-routes.util.d.ts +7 -0
  96. package/dist/cqrs/utils/event-routes.util.js +22 -0
  97. package/dist/cqrs/workflow-event.publisher.d.ts +52 -0
  98. package/dist/cqrs/workflow-event.publisher.js +257 -0
  99. package/dist/cqrs/workflow-events.explorer.d.ts +27 -0
  100. package/dist/cqrs/workflow-events.explorer.js +92 -0
  101. package/dist/cqrs/workflows-cqrs.module.d.ts +10 -0
  102. package/dist/cqrs/workflows-cqrs.module.js +27 -0
  103. package/dist/decorators/index.d.ts +1 -0
  104. package/dist/decorators/index.js +1 -0
  105. package/dist/decorators/workflow.decorator.d.ts +7 -0
  106. package/dist/decorators/workflow.decorator.js +52 -0
  107. package/dist/errors/child-workflow-failed.error.d.ts +13 -0
  108. package/dist/errors/child-workflow-failed.error.js +14 -0
  109. package/dist/errors/index.d.ts +13 -0
  110. package/dist/errors/index.js +13 -0
  111. package/dist/errors/non-retryable-step.error.d.ts +4 -0
  112. package/dist/errors/non-retryable-step.error.js +7 -0
  113. package/dist/errors/step-failed.error.d.ts +15 -0
  114. package/dist/errors/step-failed.error.js +16 -0
  115. package/dist/errors/step-timeout.error.d.ts +5 -0
  116. package/dist/errors/step-timeout.error.js +8 -0
  117. package/dist/errors/workflow-definition.error.d.ts +10 -0
  118. package/dist/errors/workflow-definition.error.js +13 -0
  119. package/dist/errors/workflow-failed.error.d.ts +20 -0
  120. package/dist/errors/workflow-failed.error.js +17 -0
  121. package/dist/errors/workflow-id-conflict.error.d.ts +6 -0
  122. package/dist/errors/workflow-id-conflict.error.js +9 -0
  123. package/dist/errors/workflow-interrupt.error.d.ts +32 -0
  124. package/dist/errors/workflow-interrupt.error.js +19 -0
  125. package/dist/errors/workflow-non-determinism.error.d.ts +4 -0
  126. package/dist/errors/workflow-non-determinism.error.js +7 -0
  127. package/dist/errors/workflow-not-found.error.d.ts +10 -0
  128. package/dist/errors/workflow-not-found.error.js +13 -0
  129. package/dist/errors/workflow-result-timeout.error.d.ts +11 -0
  130. package/dist/errors/workflow-result-timeout.error.js +13 -0
  131. package/dist/errors/workflow-state.error.d.ts +11 -0
  132. package/dist/errors/workflow-state.error.js +14 -0
  133. package/dist/errors/workflow.error.d.ts +7 -0
  134. package/dist/errors/workflow.error.js +7 -0
  135. package/dist/events/index.d.ts +3 -0
  136. package/dist/events/index.js +3 -0
  137. package/dist/events/workflow-events.interface.d.ts +145 -0
  138. package/dist/events/workflow-events.interface.js +1 -0
  139. package/dist/events/workflow-events.service.d.ts +17 -0
  140. package/dist/events/workflow-events.service.js +38 -0
  141. package/dist/events/workflows.channels.d.ts +3 -0
  142. package/dist/events/workflows.channels.js +9 -0
  143. package/dist/index.d.ts +20 -0
  144. package/dist/index.js +23 -0
  145. package/dist/interfaces/index.d.ts +13 -0
  146. package/dist/interfaces/index.js +13 -0
  147. package/dist/interfaces/serialized-workflow-error.interface.d.ts +6 -0
  148. package/dist/interfaces/serialized-workflow-error.interface.js +1 -0
  149. package/dist/interfaces/workflow-client.interface.d.ts +156 -0
  150. package/dist/interfaces/workflow-client.interface.js +1 -0
  151. package/dist/interfaces/workflow-clock.interface.d.ts +7 -0
  152. package/dist/interfaces/workflow-clock.interface.js +1 -0
  153. package/dist/interfaces/workflow-context.interface.d.ts +241 -0
  154. package/dist/interfaces/workflow-context.interface.js +1 -0
  155. package/dist/interfaces/workflow-decorator-options.interface.d.ts +101 -0
  156. package/dist/interfaces/workflow-decorator-options.interface.js +1 -0
  157. package/dist/interfaces/workflow-instance.interface.d.ts +83 -0
  158. package/dist/interfaces/workflow-instance.interface.js +1 -0
  159. package/dist/interfaces/workflow-payload-codec.interface.d.ts +32 -0
  160. package/dist/interfaces/workflow-payload-codec.interface.js +1 -0
  161. package/dist/interfaces/workflow-retry-options.interface.d.ts +9 -0
  162. package/dist/interfaces/workflow-retry-options.interface.js +1 -0
  163. package/dist/interfaces/workflow-runner.interface.d.ts +11 -0
  164. package/dist/interfaces/workflow-runner.interface.js +1 -0
  165. package/dist/interfaces/workflow-schedule.interface.d.ts +104 -0
  166. package/dist/interfaces/workflow-schedule.interface.js +1 -0
  167. package/dist/interfaces/workflow-storage.interface.d.ts +4 -0
  168. package/dist/interfaces/workflow-storage.interface.js +1 -0
  169. package/dist/interfaces/workflow-store.interface.d.ts +488 -0
  170. package/dist/interfaces/workflow-store.interface.js +1 -0
  171. package/dist/interfaces/workflows-module-options.interface.d.ts +80 -0
  172. package/dist/interfaces/workflows-module-options.interface.js +1 -0
  173. package/dist/mysql/index.d.ts +5 -0
  174. package/dist/mysql/index.js +8 -0
  175. package/dist/mysql/interfaces/index.d.ts +1 -0
  176. package/dist/mysql/interfaces/index.js +1 -0
  177. package/dist/mysql/interfaces/mysql-workflow-store-options.interface.d.ts +25 -0
  178. package/dist/mysql/interfaces/mysql-workflow-store-options.interface.js +1 -0
  179. package/dist/mysql/key-limits.d.ts +30 -0
  180. package/dist/mysql/key-limits.js +41 -0
  181. package/dist/mysql/migrations/index.d.ts +7 -0
  182. package/dist/mysql/migrations/index.js +16 -0
  183. package/dist/mysql/migrations/initial.migration.d.ts +9 -0
  184. package/dist/mysql/migrations/initial.migration.js +104 -0
  185. package/dist/mysql/mysql-workflow.store.d.ts +197 -0
  186. package/dist/mysql/mysql-workflow.store.js +828 -0
  187. package/dist/postgres/errors/index.d.ts +1 -0
  188. package/dist/postgres/errors/index.js +2 -0
  189. package/dist/postgres/index.d.ts +5 -0
  190. package/dist/postgres/index.js +8 -0
  191. package/dist/postgres/interfaces/index.d.ts +1 -0
  192. package/dist/postgres/interfaces/index.js +1 -0
  193. package/dist/postgres/interfaces/postgres-workflow-store-options.interface.d.ts +22 -0
  194. package/dist/postgres/interfaces/postgres-workflow-store-options.interface.js +1 -0
  195. package/dist/postgres/migrations/index.d.ts +6 -0
  196. package/dist/postgres/migrations/index.js +15 -0
  197. package/dist/postgres/migrations/initial.migration.d.ts +6 -0
  198. package/dist/postgres/migrations/initial.migration.js +106 -0
  199. package/dist/postgres/postgres-workflow.store.d.ts +132 -0
  200. package/dist/postgres/postgres-workflow.store.js +586 -0
  201. package/dist/services/index.d.ts +6 -0
  202. package/dist/services/index.js +6 -0
  203. package/dist/services/workflow-client.service.d.ts +146 -0
  204. package/dist/services/workflow-client.service.js +436 -0
  205. package/dist/services/workflow-execution.service.d.ts +267 -0
  206. package/dist/services/workflow-execution.service.js +1076 -0
  207. package/dist/services/workflow-registry.service.d.ts +56 -0
  208. package/dist/services/workflow-registry.service.js +172 -0
  209. package/dist/services/workflow-scheduler.service.d.ts +54 -0
  210. package/dist/services/workflow-scheduler.service.js +173 -0
  211. package/dist/services/workflow-schedules.service.d.ts +60 -0
  212. package/dist/services/workflow-schedules.service.js +193 -0
  213. package/dist/services/workflow-worker.service.d.ts +92 -0
  214. package/dist/services/workflow-worker.service.js +468 -0
  215. package/dist/signals/index.d.ts +1 -0
  216. package/dist/signals/index.js +1 -0
  217. package/dist/signals/workflow.signal.d.ts +17 -0
  218. package/dist/signals/workflow.signal.js +28 -0
  219. package/dist/sql/rate-windows.d.ts +41 -0
  220. package/dist/sql/rate-windows.js +53 -0
  221. package/dist/sql/workflow-rows.d.ts +16 -0
  222. package/dist/sql/workflow-rows.js +102 -0
  223. package/dist/sql/workflow-schema.error.d.ts +21 -0
  224. package/dist/sql/workflow-schema.error.js +15 -0
  225. package/dist/storage/encoded-workflow.store.d.ts +71 -0
  226. package/dist/storage/encoded-workflow.store.js +201 -0
  227. package/dist/storage/index.d.ts +1 -0
  228. package/dist/storage/index.js +1 -0
  229. package/dist/storage/workflow.storage.d.ts +55 -0
  230. package/dist/storage/workflow.storage.js +159 -0
  231. package/dist/stores/in-memory-workflow.store.d.ts +75 -0
  232. package/dist/stores/in-memory-workflow.store.js +380 -0
  233. package/dist/stores/index.d.ts +1 -0
  234. package/dist/stores/index.js +1 -0
  235. package/dist/testing/assertions.d.ts +10 -0
  236. package/dist/testing/assertions.js +72 -0
  237. package/dist/testing/index.d.ts +38 -0
  238. package/dist/testing/index.js +1089 -0
  239. package/dist/testing/schedule-store.contract.d.ts +33 -0
  240. package/dist/testing/schedule-store.contract.js +161 -0
  241. package/dist/utils/index.d.ts +7 -0
  242. package/dist/utils/index.js +7 -0
  243. package/dist/utils/journal-limits.util.d.ts +6 -0
  244. package/dist/utils/journal-limits.util.js +25 -0
  245. package/dist/utils/new-instance.util.d.ts +26 -0
  246. package/dist/utils/new-instance.util.js +87 -0
  247. package/dist/utils/normalize.util.d.ts +5 -0
  248. package/dist/utils/normalize.util.js +11 -0
  249. package/dist/utils/run-timeout.util.d.ts +3 -0
  250. package/dist/utils/run-timeout.util.js +15 -0
  251. package/dist/utils/schedule-spec.util.d.ts +16 -0
  252. package/dist/utils/schedule-spec.util.js +9 -0
  253. package/dist/utils/schedule-store.util.d.ts +15 -0
  254. package/dist/utils/schedule-store.util.js +44 -0
  255. package/dist/utils/serialize-error.util.d.ts +7 -0
  256. package/dist/utils/serialize-error.util.js +22 -0
  257. package/dist/utils/step-scope.util.d.ts +16 -0
  258. package/dist/utils/step-scope.util.js +38 -0
  259. package/dist/workflows.constants.d.ts +10 -0
  260. package/dist/workflows.constants.js +10 -0
  261. package/dist/workflows.module-definition.d.ts +4 -0
  262. package/dist/workflows.module-definition.js +6 -0
  263. package/dist/workflows.module.d.ts +24 -0
  264. package/dist/workflows.module.js +68 -0
  265. package/package.json +123 -0
@@ -0,0 +1,193 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
11
+ return function (target, key) { decorator(target, key, paramIndex); }
12
+ };
13
+ import { Inject, Injectable } from '@nestjs/common';
14
+ import { assertScheduleId, nextOccurrences, parseSchedule } from '../core/scheduling/schedule-spec.js';
15
+ import { systemClock } from '../core/time/clock.js';
16
+ import { WorkflowNotFoundError } from '../errors/workflow-not-found.error.js';
17
+ import { WorkflowStateError } from '../errors/workflow-state.error.js';
18
+ import { normalize } from '../utils/normalize.util.js';
19
+ import { scheduleSpec } from '../utils/schedule-spec.util.js';
20
+ import { WORKFLOWS_MODULE_OPTIONS } from '../workflows.module-definition.js';
21
+ import { WorkflowRegistry } from './workflow-registry.service.js';
22
+ import { WorkflowScheduler } from './workflow-scheduler.service.js';
23
+ import { WorkflowWorker } from './workflow-worker.service.js';
24
+ /**
25
+ * Schedules that start workflow instances: a cron expression, an interval or an RFC 5545 rule, in a time zone.
26
+ * Declare them with `@Workflow(name, { schedules })`, or save them at runtime with `upsert()`; every worker that
27
+ * runs the workflow starts their occurrences, each exactly once. Also `WorkflowClient.schedules`.
28
+ */
29
+ let WorkflowSchedules = class WorkflowSchedules {
30
+ constructor(options, registry, scheduler, worker) {
31
+ this.registry = registry;
32
+ this.scheduler = scheduler;
33
+ this.worker = worker;
34
+ this.clock = options.clock ?? systemClock;
35
+ }
36
+ /** The core's engine of schedules, over the registered store's. */
37
+ get engine() {
38
+ return this.scheduler.engine;
39
+ }
40
+ /**
41
+ * Creates or replaces the schedule with this id, and returns it. A schedule whose timing (`cron`, `every`,
42
+ * `rrule`, `tz`, `startAt`, `endAt`) changes starts over from now, with its first occurrence after now; one
43
+ * whose timing doesn't keeps its next occurrence, whatever else changes. Its runs, and whether it is paused,
44
+ * carry over. Throws `WorkflowStateError` for a schedule a workflow declares (change it in the code), and a
45
+ * `TypeError` for invalid options.
46
+ */
47
+ async upsert(id, schedule) {
48
+ assertScheduleId(id);
49
+ const owner = `Schedule "${id}"`;
50
+ if (schedule === null || typeof schedule !== 'object') {
51
+ throw new TypeError(`${owner}: expected options with workflow and cron, every or rrule.`);
52
+ }
53
+ const workflow = this.registry.resolve(schedule.workflow, schedule.version);
54
+ const spec = scheduleSpec(owner, schedule, { version: schedule.version ?? null, inputFn: false });
55
+ if (typeof schedule.input === 'function') {
56
+ throw new TypeError(`${owner}: upsert() stores its input, so it can't be a function. Pass a value; a declared schedule (@Workflow(name, { schedules })) can compute it.`);
57
+ }
58
+ let input;
59
+ try {
60
+ input = normalize(schedule.input) ?? null;
61
+ }
62
+ catch (error) {
63
+ throw new TypeError(`${owner}: its input is not JSON-serializable: ${error.message}`);
64
+ }
65
+ const saved = await this.engine.save(id, (current) => {
66
+ if (current?.declared) {
67
+ throw declaredError(current);
68
+ }
69
+ return this.engine.changed(current, { target: workflow.name, declared: false, spec, payload: input });
70
+ }, { replacing: true });
71
+ this.worker.kick();
72
+ return this.scheduler.view(saved);
73
+ }
74
+ /** The schedule, or `null` for an unknown id. */
75
+ async get(id) {
76
+ const record = await this.engine.read(id);
77
+ return record ? this.scheduler.view(record) : null;
78
+ }
79
+ /** Schedules by id, all or a workflow's; at most `limit` (default 100). */
80
+ async list(filter = {}) {
81
+ const limit = filter.limit ?? 100;
82
+ const offset = filter.offset ?? 0;
83
+ if (!Number.isSafeInteger(limit) || limit < 0 || !Number.isSafeInteger(offset) || offset < 0) {
84
+ throw new TypeError(`schedules.list(): limit (${limit}) and offset (${offset}) must be non-negative integers.`);
85
+ }
86
+ if (limit === 0) {
87
+ return [];
88
+ }
89
+ // Read as stored, then decoded one by one: one whose input no codec can read any more doesn't hide the others.
90
+ const records = await this.engine.store.listSchedules({ limit, offset, ...(filter.workflow !== undefined ? { target: filter.workflow } : {}) });
91
+ return Promise.all(records.map((record) => this.scheduler.readableView(record)));
92
+ }
93
+ /**
94
+ * Deletes the schedule, and returns whether it existed. The instances it started keep running. Throws
95
+ * `WorkflowStateError` for a schedule a workflow declares: remove it from the code, or `pause()` it.
96
+ */
97
+ async remove(id) {
98
+ const record = await this.engine.store.getSchedule(id);
99
+ if (!record) {
100
+ return false;
101
+ }
102
+ if (record.declared) {
103
+ throw declaredError(record);
104
+ }
105
+ return this.engine.store.deleteSchedule(id);
106
+ }
107
+ /**
108
+ * Stops starting occurrences until `resume()`, at once: a worker that is starting the schedule's occurrences at
109
+ * that moment starts only those it had already decided on. The instances it started keep running. A declared
110
+ * schedule stays paused across deploys. Throws `WorkflowNotFoundError` for an unknown id.
111
+ */
112
+ async pause(id) {
113
+ const saved = await this.engine.pause(id);
114
+ if (!saved) {
115
+ throw notFound(id);
116
+ }
117
+ return this.scheduler.readableView(saved);
118
+ }
119
+ /**
120
+ * Starts occurrences again, from the first one after now: those due while it was paused are passed over,
121
+ * whatever `missed` says. Throws `WorkflowNotFoundError` for an unknown id.
122
+ */
123
+ async resume(id) {
124
+ const saved = await this.engine.resume(id);
125
+ if (!saved) {
126
+ throw notFound(id);
127
+ }
128
+ this.worker.kick();
129
+ return this.scheduler.readableView(saved);
130
+ }
131
+ /**
132
+ * Starts an instance of the schedule now, whatever its `overlap`, even while it is paused, and outside its
133
+ * `limit`; its id is `<schedule id>@<ISO time of now>`, and it counts as the schedule's for the overlap of the
134
+ * occurrences after it. Throws `WorkflowNotFoundError` for an unknown id.
135
+ */
136
+ async trigger(id) {
137
+ const record = await this.engine.read(id);
138
+ if (!record) {
139
+ throw notFound(id);
140
+ }
141
+ const spec = record.spec;
142
+ const declared = record.declared ? this.scheduler.declaration(id) : undefined;
143
+ if (spec.inputFn && !declared) {
144
+ throw new TypeError(`Schedule "${id}" computes its input with a function, which this process doesn't declare: trigger it from one that registers workflow "${record.target}".`);
145
+ }
146
+ const workflow = this.registry.resolve(record.target, spec.version ?? undefined);
147
+ const now = this.clock.now();
148
+ const { instance, created } = (await this.scheduler.startOccurrence(record, spec, declared, workflow, now, now, true));
149
+ if (created) {
150
+ this.worker.kick();
151
+ }
152
+ return { id: instance.id, workflow: instance.workflow, version: instance.version, created, status: instance.status };
153
+ }
154
+ /**
155
+ * The times (epoch milliseconds) of the next occurrences after `from` (default: now), at most `count` (default
156
+ * 10), as a schedule saved at `from` would start them: of a stored schedule (by id, within what its `limit` has
157
+ * left, paused or not), or of a spec, which isn't saved. Throws `WorkflowNotFoundError` for an unknown id.
158
+ */
159
+ async preview(schedule, options = {}) {
160
+ const count = options.count ?? 10;
161
+ if (!Number.isSafeInteger(count) || count < 1 || count > 1_000) {
162
+ throw new TypeError(`schedules.preview(): count (${count}) must be an integer from 1 to 1000.`);
163
+ }
164
+ const from = options.from === undefined ? this.clock.now() : options.from instanceof Date ? options.from.getTime() : options.from;
165
+ if (typeof from !== 'number' || !Number.isFinite(from)) {
166
+ throw new TypeError(`schedules.preview(): invalid from ${String(options.from)}. Pass a valid Date or a timestamp in milliseconds.`);
167
+ }
168
+ if (typeof schedule !== 'string') {
169
+ const { cron, every, rrule, tz, startAt, endAt, limit } = schedule;
170
+ return nextOccurrences(parseSchedule({ cron, every, rrule, tz, startAt, endAt, limit }, 'schedules.preview()'), { from, count }, 'schedules.preview()');
171
+ }
172
+ const record = await this.engine.store.getSchedule(schedule);
173
+ if (!record) {
174
+ throw notFound(schedule);
175
+ }
176
+ return nextOccurrences(record.spec, { from, count, runs: this.engine.progress(record).runs }, 'schedules.preview()');
177
+ }
178
+ };
179
+ WorkflowSchedules = __decorate([
180
+ Injectable(),
181
+ __param(0, Inject(WORKFLOWS_MODULE_OPTIONS)),
182
+ __metadata("design:paramtypes", [Object, WorkflowRegistry,
183
+ WorkflowScheduler,
184
+ WorkflowWorker])
185
+ ], WorkflowSchedules);
186
+ export { WorkflowSchedules };
187
+ function notFound(id) {
188
+ return new WorkflowNotFoundError(`No workflow schedule with id "${id}".`);
189
+ }
190
+ function declaredError(record) {
191
+ return new WorkflowStateError(`Schedule "${record.id}" is declared by workflow "${record.target}" (@Workflow(name, { schedules })): change or remove it there. ` +
192
+ 'pause(), resume() and trigger() work on it.');
193
+ }
@@ -0,0 +1,92 @@
1
+ import { type OnApplicationBootstrap, type OnApplicationShutdown, type OnModuleDestroy } from '@nestjs/common';
2
+ import { WorkflowEvents } from '../events/workflow-events.service.js';
3
+ import { WorkflowStorage } from '../storage/workflow.storage.js';
4
+ import { WorkflowRegistry } from './workflow-registry.service.js';
5
+ import { WorkflowScheduler } from './workflow-scheduler.service.js';
6
+ import type { WorkflowsModuleOptions } from '../interfaces/workflows-module-options.interface.js';
7
+ /**
8
+ * Claims due instances under a lease, executes them and records the outcome.
9
+ * Any number of processes can run a worker against the same store. Inject it
10
+ * for `drain()`, which runs due instances on demand (tests, scripts).
11
+ */
12
+ export declare class WorkflowWorker implements OnApplicationBootstrap, OnModuleDestroy, OnApplicationShutdown {
13
+ private readonly storage;
14
+ private readonly registry;
15
+ private readonly events;
16
+ private readonly scheduler;
17
+ /** Shown as `leaseOwner` on the instances this worker runs. */
18
+ readonly id: string;
19
+ private readonly logger;
20
+ private readonly clock;
21
+ private readonly deps;
22
+ private readonly enabled;
23
+ /** The claim-execute loop: polling, concurrency, lease renewals, the drain at shutdown. */
24
+ private readonly leased;
25
+ constructor(storage: WorkflowStorage, options: WorkflowsModuleOptions, registry: WorkflowRegistry, events: WorkflowEvents, scheduler: WorkflowScheduler);
26
+ onApplicationBootstrap(): void;
27
+ /** Read at each use, never in the constructor: sources register while providers are created. */
28
+ private get store();
29
+ onModuleDestroy(): Promise<void>;
30
+ /** Stops the worker if `onModuleDestroy` didn't run (an application closed before it initialized). */
31
+ onApplicationShutdown(): Promise<void>;
32
+ /** @internal Look for work now instead of at the next poll (after a local start or signal). */
33
+ kick(): void;
34
+ /**
35
+ * @internal After an accepted `WorkflowClient.cancel()` or `terminate()` in this process: an
36
+ * execution of the instance running here stops at its next `ctx` call now,
37
+ * instead of when its next heartbeat reads the flag.
38
+ */
39
+ noticeCancel(id: string, terminate?: boolean): void;
40
+ /**
41
+ * Executes every due instance, repeatedly, until none is left that its workflow's concurrency and rate
42
+ * limits let start. Returns the number of executions. For tests (with a `ManualWorkflowClock` and
43
+ * `worker: false`), scripts and cron-driven workers.
44
+ */
45
+ drain(options?: {
46
+ maxRounds?: number;
47
+ }): Promise<number>;
48
+ /** After a production of the schedules' occurrences: cancels its executions of the instances it cancelled. */
49
+ private produced;
50
+ /**
51
+ * @internal Called on application shutdown. Stops claiming, asks running
52
+ * executions to stop (their steps see `signal.aborted`), and waits up to
53
+ * `shutdownTimeout`. Executions that stopped are handed back at once; the
54
+ * rest keep their lease until it expires, because their step may still be running.
55
+ */
56
+ shutdown(): Promise<void>;
57
+ /** Leases due instances of the workflow versions this process runs, under their limits. */
58
+ private claim;
59
+ /** Extends an instance's lease, and hands its execution the cancel and terminate requests the renewal read. */
60
+ private renew;
61
+ private execute;
62
+ /**
63
+ * The claimed instance with its journal, or `null` when that can't be read (a codec whose key is gone wrote part of
64
+ * the journal, as after a key rotation that was rolled back): then it is handed back, as a claim hands back an
65
+ * instance whose own payloads can't be read, instead of holding its lease and its concurrency slot until the lease
66
+ * expires, and going first at every claim after that.
67
+ */
68
+ private claimed;
69
+ private conclude;
70
+ private compensate;
71
+ /**
72
+ * Applies each child's `parentClose` to the children of this instance that are still running:
73
+ * cancels or terminates them. At least once: it runs again after a crash, and a request that
74
+ * was already accepted is refused, changing nothing.
75
+ */
76
+ private closeChildren;
77
+ /** Ends the instance as `cancelled` without running (more of) its compensations. */
78
+ private terminate;
79
+ /**
80
+ * Handles executions that must not record an outcome. Returns true if
81
+ * handled. A run that finished cleanly during shutdown is still recorded;
82
+ * one that was cut short is handed back, and whatever it was doing is
83
+ * re-derived by the next execution.
84
+ */
85
+ private interrupted;
86
+ private finish;
87
+ /** A fenced write under the execution's lease, stamped with the clock, with the custom status if it changed. */
88
+ private write;
89
+ private release;
90
+ private leaseLostWarning;
91
+ private emit;
92
+ }