@n8n/scheduler 0.2.3 → 0.3.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 (166) hide show
  1. package/README.md +60 -23
  2. package/dist/build.tsbuildinfo +1 -1
  3. package/dist/core/errors.d.ts +6 -0
  4. package/dist/core/errors.js +15 -1
  5. package/dist/core/errors.js.map +1 -1
  6. package/dist/core/executor/backoff.js.map +1 -0
  7. package/dist/core/executor/executor.d.ts +38 -0
  8. package/dist/core/executor/executor.js +137 -0
  9. package/dist/core/executor/executor.js.map +1 -0
  10. package/dist/core/executor/index.d.ts +8 -0
  11. package/dist/core/executor/index.js +16 -0
  12. package/dist/core/executor/index.js.map +1 -0
  13. package/dist/core/executor/options.d.ts +6 -0
  14. package/dist/core/executor/options.js +10 -0
  15. package/dist/core/executor/options.js.map +1 -0
  16. package/dist/{executor → core/executor}/precision-timer.d.ts +1 -0
  17. package/dist/{executor → core/executor}/precision-timer.js +3 -0
  18. package/dist/core/executor/precision-timer.js.map +1 -0
  19. package/dist/core/executor/store.d.ts +21 -0
  20. package/dist/core/executor/store.js +3 -0
  21. package/dist/core/executor/store.js.map +1 -0
  22. package/dist/{executor → core/executor}/task-handler.d.ts +1 -1
  23. package/dist/{executor → core/executor}/task-handler.js +2 -2
  24. package/dist/core/executor/task-handler.js.map +1 -0
  25. package/dist/core/executor/tracing.d.ts +11 -0
  26. package/dist/core/executor/tracing.js +7 -0
  27. package/dist/core/executor/tracing.js.map +1 -0
  28. package/dist/core/factory.d.ts +29 -0
  29. package/dist/core/factory.js +254 -0
  30. package/dist/core/factory.js.map +1 -0
  31. package/dist/core/index.d.ts +17 -9
  32. package/dist/core/index.js +15 -17
  33. package/dist/core/index.js.map +1 -1
  34. package/dist/core/lifecycle/alarm.d.ts +8 -0
  35. package/dist/core/lifecycle/alarm.js +32 -0
  36. package/dist/core/lifecycle/alarm.js.map +1 -0
  37. package/dist/core/lifecycle/index.d.ts +5 -0
  38. package/dist/core/lifecycle/index.js +11 -0
  39. package/dist/core/lifecycle/index.js.map +1 -0
  40. package/dist/core/lifecycle/lookahead.d.ts +1 -0
  41. package/dist/core/lifecycle/lookahead.js +7 -0
  42. package/dist/core/lifecycle/lookahead.js.map +1 -0
  43. package/dist/core/lifecycle/loop.d.ts +39 -0
  44. package/dist/core/lifecycle/loop.js +86 -0
  45. package/dist/core/lifecycle/loop.js.map +1 -0
  46. package/dist/core/lifecycle/options.d.ts +15 -0
  47. package/dist/core/lifecycle/options.js +18 -0
  48. package/dist/core/lifecycle/options.js.map +1 -0
  49. package/dist/core/lifecycle/timeline.d.ts +9 -0
  50. package/dist/core/lifecycle/timeline.js +22 -0
  51. package/dist/core/lifecycle/timeline.js.map +1 -0
  52. package/dist/core/materializer/index.d.ts +2 -2
  53. package/dist/core/materializer/index.js.map +1 -1
  54. package/dist/core/materializer/materialize.d.ts +10 -2
  55. package/dist/core/materializer/materialize.js +32 -6
  56. package/dist/core/materializer/materialize.js.map +1 -1
  57. package/dist/core/materializer/options.d.ts +1 -0
  58. package/dist/core/materializer/options.js +1 -0
  59. package/dist/core/materializer/options.js.map +1 -1
  60. package/dist/core/materializer/plan.d.ts +1 -0
  61. package/dist/core/materializer/plan.js +12 -6
  62. package/dist/core/materializer/plan.js.map +1 -1
  63. package/dist/core/materializer/transaction.d.ts +18 -1
  64. package/dist/core/provisioning/index.d.ts +5 -0
  65. package/dist/core/provisioning/index.js +9 -0
  66. package/dist/core/provisioning/index.js.map +1 -0
  67. package/dist/core/provisioning/provision.d.ts +6 -0
  68. package/dist/core/provisioning/provision.js +64 -0
  69. package/dist/core/provisioning/provision.js.map +1 -0
  70. package/dist/core/provisioning/provisioner.d.ts +15 -0
  71. package/dist/core/provisioning/provisioner.js +18 -0
  72. package/dist/core/provisioning/provisioner.js.map +1 -0
  73. package/dist/core/provisioning/transaction.d.ts +13 -0
  74. package/dist/core/provisioning/transaction.js +3 -0
  75. package/dist/core/provisioning/transaction.js.map +1 -0
  76. package/dist/core/provisioning/types.d.ts +43 -0
  77. package/dist/core/provisioning/types.js +3 -0
  78. package/dist/core/provisioning/types.js.map +1 -0
  79. package/dist/core/reaper/index.d.ts +1 -0
  80. package/dist/core/reaper/index.js +7 -0
  81. package/dist/core/reaper/index.js.map +1 -0
  82. package/dist/{reaper/reaper.d.ts → core/reaper/reap.d.ts} +13 -8
  83. package/dist/core/reaper/reap.js +51 -0
  84. package/dist/core/reaper/reap.js.map +1 -0
  85. package/dist/core/recurrence/field.d.ts +2 -0
  86. package/dist/core/recurrence/field.js +12 -0
  87. package/dist/core/recurrence/field.js.map +1 -0
  88. package/dist/core/recurrence/kinds/cron.d.ts +10 -0
  89. package/dist/core/recurrence/kinds/cron.js +64 -0
  90. package/dist/core/recurrence/kinds/cron.js.map +1 -0
  91. package/dist/core/recurrence/kinds/interval.d.ts +5 -0
  92. package/dist/core/recurrence/kinds/interval.js +29 -0
  93. package/dist/core/recurrence/kinds/interval.js.map +1 -0
  94. package/dist/core/recurrence/kinds/one-off.d.ts +5 -0
  95. package/dist/core/recurrence/kinds/one-off.js +24 -0
  96. package/dist/core/recurrence/kinds/one-off.js.map +1 -0
  97. package/dist/core/recurrence/kinds/recurring-cron.d.ts +7 -0
  98. package/dist/core/recurrence/kinds/recurring-cron.js +64 -0
  99. package/dist/core/recurrence/kinds/recurring-cron.js.map +1 -0
  100. package/dist/core/recurrence/next-run.d.ts +2 -0
  101. package/dist/core/recurrence/next-run.js +37 -24
  102. package/dist/core/recurrence/next-run.js.map +1 -1
  103. package/dist/core/recurrence/periods.d.ts +2 -0
  104. package/dist/core/recurrence/periods.js +30 -0
  105. package/dist/core/recurrence/periods.js.map +1 -0
  106. package/dist/core/recurrence/resolve.d.ts +2 -0
  107. package/dist/core/recurrence/resolve.js +25 -0
  108. package/dist/core/recurrence/resolve.js.map +1 -0
  109. package/dist/core/recurrence/validate.js +9 -38
  110. package/dist/core/recurrence/validate.js.map +1 -1
  111. package/dist/core/retention/prune.d.ts +1 -1
  112. package/dist/core/retention/prune.js +11 -9
  113. package/dist/core/retention/prune.js.map +1 -1
  114. package/dist/core/retention/store.d.ts +1 -1
  115. package/dist/core/scheduler.d.ts +16 -0
  116. package/dist/core/scheduler.js +3 -0
  117. package/dist/core/scheduler.js.map +1 -0
  118. package/dist/core/types/schedule.d.ts +17 -4
  119. package/dist/core/types/task.d.ts +2 -5
  120. package/dist/observability/attributes.d.ts +41 -0
  121. package/dist/observability/attributes.js +56 -0
  122. package/dist/observability/attributes.js.map +1 -0
  123. package/dist/observability/executor-tracing.d.ts +4 -0
  124. package/dist/observability/executor-tracing.js +61 -0
  125. package/dist/observability/executor-tracing.js.map +1 -0
  126. package/dist/observability/materializer-tracing.d.ts +3 -0
  127. package/dist/observability/materializer-tracing.js +22 -0
  128. package/dist/observability/materializer-tracing.js.map +1 -0
  129. package/dist/observability/metrics.d.ts +11 -0
  130. package/dist/observability/metrics.js +14 -0
  131. package/dist/observability/metrics.js.map +1 -0
  132. package/dist/observability/pass-tracing.d.ts +2 -0
  133. package/dist/observability/pass-tracing.js +24 -0
  134. package/dist/observability/pass-tracing.js.map +1 -0
  135. package/dist/observability/provisioner-tracing.d.ts +11 -0
  136. package/dist/observability/provisioner-tracing.js +51 -0
  137. package/dist/observability/provisioner-tracing.js.map +1 -0
  138. package/dist/observability/tracer.d.ts +21 -0
  139. package/dist/observability/tracer.js +10 -0
  140. package/dist/observability/tracer.js.map +1 -0
  141. package/package.json +13 -24
  142. package/dist/core/enums.d.ts +0 -1
  143. package/dist/core/enums.js +0 -10
  144. package/dist/core/enums.js.map +0 -1
  145. package/dist/executor/backoff.js.map +0 -1
  146. package/dist/executor/executor.d.ts +0 -23
  147. package/dist/executor/executor.js +0 -133
  148. package/dist/executor/executor.js.map +0 -1
  149. package/dist/executor/precision-timer.js.map +0 -1
  150. package/dist/executor/task-handler.js.map +0 -1
  151. package/dist/reaper/reaper.js +0 -37
  152. package/dist/reaper/reaper.js.map +0 -1
  153. package/dist/storage/index.d.ts +0 -3
  154. package/dist/storage/index.js +0 -12
  155. package/dist/storage/index.js.map +0 -1
  156. package/dist/storage/mappers.d.ts +0 -6
  157. package/dist/storage/mappers.js +0 -72
  158. package/dist/storage/mappers.js.map +0 -1
  159. package/dist/storage/materializer-store.d.ts +0 -14
  160. package/dist/storage/materializer-store.js +0 -83
  161. package/dist/storage/materializer-store.js.map +0 -1
  162. package/dist/storage/scheduler.service.d.ts +0 -16
  163. package/dist/storage/scheduler.service.js +0 -70
  164. package/dist/storage/scheduler.service.js.map +0 -1
  165. /package/dist/{executor → core/executor}/backoff.d.ts +0 -0
  166. /package/dist/{executor → core/executor}/backoff.js +0 -0
package/README.md CHANGED
@@ -1,28 +1,65 @@
1
1
  # @n8n/scheduler
2
2
 
3
- A durable, distributed scheduling service for n8n. It schedules recurring and
4
- one-off work and dispatches each due occurrence to a handler, coordinating through
5
- the database so every main instance participates and no occurrence is lost across a
6
- restart or failover. Scheduling (deciding that something is due) is decoupled from
7
- execution (running it), and dispatch is effectively-once.
8
-
9
- It is a general scheduling primitive, not tied to one feature: each occurrence is
10
- routed to a handler by a `task_type` key. The Schedule Trigger node is its first
11
- consumer; poll triggers, system tasks and waiting executions are intended to follow,
12
- replacing today's in-memory, leader-only scheduling. All of it sits behind
13
- `N8N_SCHEDULER_ENABLED` (default off) while the legacy engine stays in place for
14
- rollback.
15
-
16
- ## Scope
17
-
18
- - **Coordination** (the core): assign each due occurrence to a single main via
19
- claim, lease and fencing, recover work whose owner has died, and dispatch it
20
- across the cluster.
21
- - **Recurrence**: turn a cron, interval or one-off schedule definition into its next
22
- occurrence, with correct timezone and DST handling.
3
+ Durable, multi-main scheduling for n8n. Upcoming work is recorded in storage
4
+ before it runs, then claimed, fired and recovered under leases and epoch
5
+ fencing, so each occurrence executes once across the cluster and survives
6
+ restarts and failovers. Occurrences are dispatched to handlers by `taskType`;
7
+ the Schedule Trigger node is the first consumer. Everything sits behind
8
+ `N8N_SCHEDULER_ENABLED` (default off) while the legacy engine stays in place.
9
+
10
+ ## Surface
11
+
12
+ The package is pure logic, with no DI and no database. It exposes exactly two
13
+ things (plus the types their signatures reach):
14
+
15
+ - **`Scheduler`**: `registerTaskHandler` plus one accessor per pass
16
+ (`materialize`, `execute`, `reap`, `prune`, `stop`). The host drives each
17
+ pass on its own cadence.
18
+ - **`createScheduler(deps)`**: composes the internal algorithms (materializer,
19
+ executor, reaper, retention) into a `Scheduler`.
20
+
21
+ The host binds `deps`: a task store and a transaction runner (the `@n8n/db`
22
+ repositories satisfy the store contracts structurally, so no adapters are
23
+ needed), optional per-pass tuning, and an `onEvent` sink for described
24
+ incidents. In n8n that host is the cli's `DurableScheduler`
25
+ (`packages/cli/src/scheduling/`), which wires DI, config and instance identity,
26
+ and routes events to the logger.
27
+
28
+ ## Schedule kinds
29
+
30
+ A scheduled job says *when* something should run. There are four kinds:
31
+
32
+ | Kind | Meaning | Example |
33
+ |---|---|---|
34
+ | `cron` | Fires at fixed clock times, written as a cron expression. | `0 0 9 * * 1` = every Monday at 09:00 |
35
+ | `interval` | Fires every N seconds of elapsed time. | every 3600s = once an hour |
36
+ | `one_off` | Fires once, at a single instant, then never again. | fire at 2026-01-01 00:00 |
37
+ | `recurring_cron` | A cron *anchor* thinned by an "every N periods" gate, for cadences plain cron cannot express. | every 3 weeks on Monday |
38
+
39
+ ### Why `recurring_cron`?
40
+
41
+ Plain cron can say "every Monday", but not "every *third* Monday".
42
+ `recurring_cron` builds that from two parts:
43
+
44
+ - an **anchor**: a normal cron that lists candidate dates (often too many),
45
+ - a **gate**: keeps a candidate only once at least `recurrenceSize` periods of
46
+ `recurrenceUnit` (`hours` / `days` / `weeks` / `months`) have passed since the
47
+ last kept fire.
48
+
49
+ "Every 3 weeks on Monday" = anchor "every Monday" + gate "1 per 3 weeks":
50
+
51
+ ```
52
+ Anchor (every Monday): M M M M M M M
53
+ Gate (1 per 3 weeks): ✓ ✗ ✗ ✓ ✗ ✗ ✓
54
+ Fires: M M M
55
+ ```
56
+
57
+ The gate looks only at the previous fire, with no stored counter. So any
58
+ instance in the cluster can compute the next run, and a restart never loses the
59
+ cadence.
23
60
 
24
61
  ## Status
25
62
 
26
- Early foundation. Today the package ships the domain types, the schedule math and an
27
- initial storage adapter; the coordination engine (sweep, executor, reaper) lands in
28
- later milestones.
63
+ Early foundation. The algorithms, schedule math and composition surface are in
64
+ place; the driver that runs the passes on their cadences in the main process
65
+ lands in later milestones.