@blokjs/runner 0.2.1 → 0.4.0

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 (159) hide show
  1. package/dist/Blok.js +11 -11
  2. package/dist/Blok.js.map +1 -1
  3. package/dist/Configuration.d.ts +39 -2
  4. package/dist/Configuration.js +337 -28
  5. package/dist/Configuration.js.map +1 -1
  6. package/dist/ConfigurationResolver.d.ts +9 -0
  7. package/dist/ConfigurationResolver.js +17 -1
  8. package/dist/ConfigurationResolver.js.map +1 -1
  9. package/dist/PayloadTooLargeError.d.ts +19 -0
  10. package/dist/PayloadTooLargeError.js +29 -0
  11. package/dist/PayloadTooLargeError.js.map +1 -0
  12. package/dist/RunCancelledError.d.ts +17 -0
  13. package/dist/RunCancelledError.js +25 -0
  14. package/dist/RunCancelledError.js.map +1 -0
  15. package/dist/RunnerSteps.js +363 -23
  16. package/dist/RunnerSteps.js.map +1 -1
  17. package/dist/RuntimeAdapterNode.d.ts +32 -2
  18. package/dist/RuntimeAdapterNode.js +122 -27
  19. package/dist/RuntimeAdapterNode.js.map +1 -1
  20. package/dist/SubworkflowNode.d.ts +75 -0
  21. package/dist/SubworkflowNode.js +221 -0
  22. package/dist/SubworkflowNode.js.map +1 -0
  23. package/dist/TriggerBase.d.ts +128 -0
  24. package/dist/TriggerBase.js +808 -6
  25. package/dist/TriggerBase.js.map +1 -1
  26. package/dist/WaitDispatchRequest.d.ts +38 -0
  27. package/dist/WaitDispatchRequest.js +13 -0
  28. package/dist/WaitDispatchRequest.js.map +1 -0
  29. package/dist/WaitNode.d.ts +23 -0
  30. package/dist/WaitNode.js +26 -0
  31. package/dist/WaitNode.js.map +1 -0
  32. package/dist/adapters/BunRuntimeAdapter.d.ts +1 -0
  33. package/dist/adapters/BunRuntimeAdapter.js +1 -0
  34. package/dist/adapters/BunRuntimeAdapter.js.map +1 -1
  35. package/dist/adapters/DockerRuntimeAdapter.d.ts +2 -1
  36. package/dist/adapters/DockerRuntimeAdapter.js +10 -1
  37. package/dist/adapters/DockerRuntimeAdapter.js.map +1 -1
  38. package/dist/adapters/HttpRuntimeAdapter.d.ts +26 -5
  39. package/dist/adapters/HttpRuntimeAdapter.js +97 -16
  40. package/dist/adapters/HttpRuntimeAdapter.js.map +1 -1
  41. package/dist/adapters/NodeJsRuntimeAdapter.d.ts +1 -0
  42. package/dist/adapters/NodeJsRuntimeAdapter.js +1 -0
  43. package/dist/adapters/NodeJsRuntimeAdapter.js.map +1 -1
  44. package/dist/adapters/RuntimeAdapter.d.ts +17 -0
  45. package/dist/adapters/WasmRuntimeAdapter.d.ts +1 -0
  46. package/dist/adapters/WasmRuntimeAdapter.js +1 -0
  47. package/dist/adapters/WasmRuntimeAdapter.js.map +1 -1
  48. package/dist/adapters/grpc/GrpcChannelOptions.d.ts +31 -0
  49. package/dist/adapters/grpc/GrpcChannelOptions.js +68 -0
  50. package/dist/adapters/grpc/GrpcChannelOptions.js.map +1 -0
  51. package/dist/adapters/grpc/GrpcClientPool.d.ts +43 -0
  52. package/dist/adapters/grpc/GrpcClientPool.js +89 -0
  53. package/dist/adapters/grpc/GrpcClientPool.js.map +1 -0
  54. package/dist/adapters/grpc/GrpcCodec.d.ts +226 -0
  55. package/dist/adapters/grpc/GrpcCodec.js +275 -0
  56. package/dist/adapters/grpc/GrpcCodec.js.map +1 -0
  57. package/dist/adapters/grpc/GrpcErrors.d.ts +59 -0
  58. package/dist/adapters/grpc/GrpcErrors.js +190 -0
  59. package/dist/adapters/grpc/GrpcErrors.js.map +1 -0
  60. package/dist/adapters/grpc/GrpcHealthChecker.d.ts +69 -0
  61. package/dist/adapters/grpc/GrpcHealthChecker.js +96 -0
  62. package/dist/adapters/grpc/GrpcHealthChecker.js.map +1 -0
  63. package/dist/adapters/grpc/GrpcRuntimeAdapter.d.ts +98 -0
  64. package/dist/adapters/grpc/GrpcRuntimeAdapter.js +478 -0
  65. package/dist/adapters/grpc/GrpcRuntimeAdapter.js.map +1 -0
  66. package/dist/adapters/grpc/index.d.ts +13 -0
  67. package/dist/adapters/grpc/index.js +14 -0
  68. package/dist/adapters/grpc/index.js.map +1 -0
  69. package/dist/adapters/grpc/proto/blok/runtime/v1/runtime.proto +302 -0
  70. package/dist/adapters/grpc/types.d.ts +97 -0
  71. package/dist/adapters/grpc/types.js +41 -0
  72. package/dist/adapters/grpc/types.js.map +1 -0
  73. package/dist/adapters/transport.d.ts +108 -0
  74. package/dist/adapters/transport.js +196 -0
  75. package/dist/adapters/transport.js.map +1 -0
  76. package/dist/concurrency/ConcurrencyBackend.d.ts +61 -0
  77. package/dist/concurrency/ConcurrencyBackend.js +20 -0
  78. package/dist/concurrency/ConcurrencyBackend.js.map +1 -0
  79. package/dist/concurrency/ConcurrencyLimitError.d.ts +37 -0
  80. package/dist/concurrency/ConcurrencyLimitError.js +16 -0
  81. package/dist/concurrency/ConcurrencyLimitError.js.map +1 -0
  82. package/dist/concurrency/NatsKvConcurrencyBackend.d.ts +64 -0
  83. package/dist/concurrency/NatsKvConcurrencyBackend.js +297 -0
  84. package/dist/concurrency/NatsKvConcurrencyBackend.js.map +1 -0
  85. package/dist/concurrency/QueueExpiredError.d.ts +40 -0
  86. package/dist/concurrency/QueueExpiredError.js +15 -0
  87. package/dist/concurrency/QueueExpiredError.js.map +1 -0
  88. package/dist/concurrency/createConcurrencyBackend.d.ts +23 -0
  89. package/dist/concurrency/createConcurrencyBackend.js +34 -0
  90. package/dist/concurrency/createConcurrencyBackend.js.map +1 -0
  91. package/dist/concurrency/readConcurrencyConfig.d.ts +60 -0
  92. package/dist/concurrency/readConcurrencyConfig.js +60 -0
  93. package/dist/concurrency/readConcurrencyConfig.js.map +1 -0
  94. package/dist/idempotency/resolveIdempotencyKey.d.ts +20 -0
  95. package/dist/idempotency/resolveIdempotencyKey.js +37 -0
  96. package/dist/idempotency/resolveIdempotencyKey.js.map +1 -0
  97. package/dist/index.d.ts +35 -3
  98. package/dist/index.js +61 -2
  99. package/dist/index.js.map +1 -1
  100. package/dist/monitoring/ConcurrencyMetrics.d.ts +56 -0
  101. package/dist/monitoring/ConcurrencyMetrics.js +107 -0
  102. package/dist/monitoring/ConcurrencyMetrics.js.map +1 -0
  103. package/dist/monitoring/JanitorMetrics.d.ts +27 -0
  104. package/dist/monitoring/JanitorMetrics.js +48 -0
  105. package/dist/monitoring/JanitorMetrics.js.map +1 -0
  106. package/dist/scheduling/DebounceCoordinator.d.ts +88 -0
  107. package/dist/scheduling/DebounceCoordinator.js +141 -0
  108. package/dist/scheduling/DebounceCoordinator.js.map +1 -0
  109. package/dist/scheduling/DeferredDispatchSignal.d.ts +50 -0
  110. package/dist/scheduling/DeferredDispatchSignal.js +14 -0
  111. package/dist/scheduling/DeferredDispatchSignal.js.map +1 -0
  112. package/dist/scheduling/DeferredRunScheduler.d.ts +68 -0
  113. package/dist/scheduling/DeferredRunScheduler.js +154 -0
  114. package/dist/scheduling/DeferredRunScheduler.js.map +1 -0
  115. package/dist/scheduling/readSchedulingConfig.d.ts +24 -0
  116. package/dist/scheduling/readSchedulingConfig.js +52 -0
  117. package/dist/scheduling/readSchedulingConfig.js.map +1 -0
  118. package/dist/testing/WorkflowTestRunner.js +12 -0
  119. package/dist/testing/WorkflowTestRunner.js.map +1 -1
  120. package/dist/timeouts/StepTimeoutError.d.ts +22 -0
  121. package/dist/timeouts/StepTimeoutError.js +31 -0
  122. package/dist/timeouts/StepTimeoutError.js.map +1 -0
  123. package/dist/tracing/InMemoryRunStore.d.ts +28 -1
  124. package/dist/tracing/InMemoryRunStore.js +150 -0
  125. package/dist/tracing/InMemoryRunStore.js.map +1 -1
  126. package/dist/tracing/Janitor.d.ts +70 -0
  127. package/dist/tracing/Janitor.js +150 -0
  128. package/dist/tracing/Janitor.js.map +1 -0
  129. package/dist/tracing/PostgresRunStore.d.ts +30 -0
  130. package/dist/tracing/PostgresRunStore.js +435 -3
  131. package/dist/tracing/PostgresRunStore.js.map +1 -1
  132. package/dist/tracing/RunStore.d.ts +100 -1
  133. package/dist/tracing/RunTracker.d.ts +261 -11
  134. package/dist/tracing/RunTracker.js +691 -11
  135. package/dist/tracing/RunTracker.js.map +1 -1
  136. package/dist/tracing/SqliteRunStore.d.ts +23 -1
  137. package/dist/tracing/SqliteRunStore.js +421 -6
  138. package/dist/tracing/SqliteRunStore.js.map +1 -1
  139. package/dist/tracing/TraceRouter.d.ts +20 -2
  140. package/dist/tracing/TraceRouter.js +494 -9
  141. package/dist/tracing/TraceRouter.js.map +1 -1
  142. package/dist/tracing/sanitize.d.ts +11 -0
  143. package/dist/tracing/sanitize.js +29 -0
  144. package/dist/tracing/sanitize.js.map +1 -1
  145. package/dist/tracing/types.d.ts +429 -11
  146. package/dist/types/GlobalOptions.d.ts +9 -2
  147. package/dist/utils/createChildContext.d.ts +32 -0
  148. package/dist/utils/createChildContext.js +113 -0
  149. package/dist/utils/createChildContext.js.map +1 -0
  150. package/dist/workflow/PersistenceHelper.d.ts +46 -0
  151. package/dist/workflow/PersistenceHelper.js +57 -0
  152. package/dist/workflow/PersistenceHelper.js.map +1 -0
  153. package/dist/workflow/WorkflowNormalizer.d.ts +79 -0
  154. package/dist/workflow/WorkflowNormalizer.js +486 -0
  155. package/dist/workflow/WorkflowNormalizer.js.map +1 -0
  156. package/dist/workflow/WorkflowRegistry.d.ts +64 -0
  157. package/dist/workflow/WorkflowRegistry.js +81 -0
  158. package/dist/workflow/WorkflowRegistry.js.map +1 -0
  159. package/package.json +10 -7
@@ -12,6 +12,20 @@ import { RateLimiter } from "./monitoring/RateLimiter";
12
12
  import type { RateLimitConfig, RateLimitResult } from "./monitoring/RateLimiter";
13
13
  import { TriggerMetricsCollector } from "./monitoring/TriggerMetricsCollector";
14
14
  import type TriggerResponse from "./types/TriggerResponse";
15
+ /**
16
+ * Tier 2 quick-wins follow-up · structural logger interface used by
17
+ * `installCrashHandlers` and `recoverOrphanedRuns`. Both `error` and
18
+ * `log` are optional so callers can pass a `DefaultLogger`, the Hono
19
+ * `console` shim, a custom logger, or omit it entirely.
20
+ *
21
+ * Single-arg calls (one pre-formatted string) are intentional — Node's
22
+ * `process.on("uncaughtException")` handlers can't await, and the
23
+ * `DefaultLogger` interface only takes `(message: string)`.
24
+ */
25
+ interface CrashAutoflipLogger {
26
+ error?: (message: string) => void;
27
+ log?: (message: string) => void;
28
+ }
15
29
  export default abstract class TriggerBase extends Trigger {
16
30
  configuration: Configuration;
17
31
  /** Health check instance for this trigger */
@@ -32,6 +46,94 @@ export default abstract class TriggerBase extends Trigger {
32
46
  abstract listen(): Promise<number>;
33
47
  getConfiguration(): Configuration;
34
48
  getRunner(): Runner;
49
+ /**
50
+ * Tier 2 #5+#7 follow-up — durable scheduler hook.
51
+ *
52
+ * When a trigger supports re-firing deferred dispatches across process
53
+ * restarts, it overrides this method to extract a JSON-serializable
54
+ * subset of `ctx` sufficient for `restoreDispatch(payload)` (defined
55
+ * by the trigger) to reconstruct an equivalent ctx and re-enter
56
+ * `dispatchDeferred`.
57
+ *
58
+ * Returns `null` (default) when the trigger does NOT support
59
+ * cross-restart durability — the scheduler then runs purely in-memory
60
+ * for that trigger (existing pre-follow-up behaviour).
61
+ *
62
+ * Override in `HttpTrigger` to return `{method, path, headers, body,
63
+ * params, query, workflowPath}` (with sensitive header keys stripped).
64
+ * Worker triggers don't override — broker handles delay durability.
65
+ */
66
+ protected extractDispatchPayload(_ctx: Context): unknown | null;
67
+ /**
68
+ * Returns the trigger type string used to tag persisted scheduled
69
+ * dispatch rows (`scheduled_dispatches.trigger_type`). Mirrors the
70
+ * convention from `tracker.startRun({triggerType})`. Override when
71
+ * the class name doesn't naturally produce the right tag.
72
+ */
73
+ protected getTriggerType(): string;
74
+ /** Flag — set true after `installCrashHandlers` has run once in this process. */
75
+ private static crashHandlersInstalled;
76
+ /**
77
+ * Tier 2 quick-wins follow-up — install process-level handlers for
78
+ * `uncaughtException` and `unhandledRejection`. When fired, flip
79
+ * every in-flight `running` run to `"crashed"` (with the captured
80
+ * error) BEFORE re-throwing / letting Node's default behavior take
81
+ * over. Idempotent — safe to call from every trigger's `listen()`;
82
+ * only the first call installs handlers.
83
+ *
84
+ * Kill-switch: `BLOK_CRASH_AUTOFLIP_DISABLED=1`.
85
+ *
86
+ * Why sync: `process.on("uncaughtException")` handlers can't await.
87
+ * `markAllRunningRunsAsCrashed` is sync (sqlite + in-memory writes
88
+ * complete before the handler returns).
89
+ */
90
+ static installCrashHandlers(logger?: CrashAutoflipLogger): void;
91
+ /** Test-only — reset the install flag so tests can re-install handlers. */
92
+ static resetCrashHandlersInstalled(): void;
93
+ /** Flag — set true after `installShutdownHandlers` has run once in this process. */
94
+ private static shutdownHandlersInstalled;
95
+ /**
96
+ * Install SIGTERM + SIGINT handlers that drain process resources
97
+ * cleanly before exit. Mirrors the `installCrashHandlers` pattern —
98
+ * idempotent + opt-out via `BLOK_GRACEFUL_SHUTDOWN_DISABLED=1`.
99
+ *
100
+ * Drain order:
101
+ * 1. Stop accepting new work — calls `trigger.stop()` if available
102
+ * (HttpTrigger drains in-flight requests + closes the server).
103
+ * 2. Stop the periodic janitor sweep so it doesn't fire mid-drain.
104
+ * 3. Cancel pending deferred dispatches in the in-memory scheduler.
105
+ * (Persisted rows in `scheduled_dispatches` survive — the next
106
+ * boot recovers them.)
107
+ * 4. Disconnect the cross-process concurrency backend (NATS KV)
108
+ * so locks held by this process release on the broker side.
109
+ * 5. `process.exit(0)`.
110
+ *
111
+ * Errors during drain are caught + logged; the process still exits
112
+ * (cleanup is best-effort; the operator wants a clean exit).
113
+ *
114
+ * Why this is a `static` method: shutdown handlers must be installed
115
+ * once per process, regardless of how many trigger subclasses
116
+ * coexist. Subclasses pass `this` so the handler can call their
117
+ * specific `stop()`.
118
+ */
119
+ static installShutdownHandlers(trigger: TriggerBase, logger?: CrashAutoflipLogger): void;
120
+ /** Test-only — reset the install flag so tests can re-install handlers. */
121
+ static resetShutdownHandlersInstalled(): void;
122
+ /**
123
+ * Tier 2 quick-wins follow-up — boot recovery for orphaned `running`
124
+ * runs. Scans the store for runs in `running` status whose
125
+ * `startedAt` is older than `thresholdMs` ago (default 2 minutes,
126
+ * override via `BLOK_ORPHAN_THRESHOLD_MS` env var). Flips each to
127
+ * `"crashed"` with `Error("Orphaned — process restarted before run completed")`.
128
+ *
129
+ * Catches the case where the previous process died via SIGKILL or
130
+ * OOM and the `installCrashHandlers` path never ran. Returns the
131
+ * count flipped for observability + tests.
132
+ *
133
+ * Idempotent — safe to call multiple times; runs are flipped to
134
+ * a terminal status so a second pass finds none.
135
+ */
136
+ static recoverOrphanedRuns(thresholdMs?: number, logger?: CrashAutoflipLogger): number;
35
137
  /**
36
138
  * Enable hot reload for this trigger. Only active in development
37
139
  * (NODE_ENV !== 'production') unless BLOK_HMR=true is explicitly set.
@@ -67,6 +169,31 @@ export default abstract class TriggerBase extends Trigger {
67
169
  */
68
170
  destroyHmr(): Promise<void>;
69
171
  run(ctx: Context): Promise<TriggerResponse>;
172
+ /**
173
+ * Tier 2 #5 + #7 — evaluate the scheduling gates and either return a
174
+ * `DeferredDispatchSignal` (the caller throws it) or null (the caller
175
+ * proceeds with immediate dispatch).
176
+ *
177
+ * Order: debounce → delay. They DON'T compose in a single PR (a
178
+ * trigger may use one or the other; both at once would be unusual).
179
+ * If both are configured, debounce takes precedence — the debounce
180
+ * coordinator handles its own scheduling (the `delay` field is
181
+ * effectively ignored on debounced triggers).
182
+ */
183
+ private maybeDeferRun;
184
+ /**
185
+ * Tier 2 #5 + #7 — re-enter the dispatch pipeline for a deferred run.
186
+ *
187
+ * Called by the `DeferredRunScheduler` timer (delay) or
188
+ * `DebounceCoordinator.onFire` (debounce trailing) when the wait
189
+ * window closes. Checks TTL, transitions the run to `running`, and
190
+ * re-enters `run(ctx)` with the `_blokDispatchReentry` flag so the
191
+ * scheduling gates are skipped on the second pass.
192
+ *
193
+ * The re-entered `run(ctx)` reuses the existing `traceRunId` (already
194
+ * stashed on `ctx._traceRunId` from the first pass).
195
+ */
196
+ protected dispatchDeferred(ctx: Context, traceRunId: string, expiresAt: number | undefined): Promise<void>;
70
197
  /**
71
198
  * Build a human-readable trigger summary for trace display.
72
199
  */
@@ -117,3 +244,4 @@ export default abstract class TriggerBase extends Trigger {
117
244
  */
118
245
  destroyMonitoring(): void;
119
246
  }
247
+ export {};