@blokjs/runner 0.4.0 → 0.6.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 (163) hide show
  1. package/dist/Blok.js +32 -3
  2. package/dist/Blok.js.map +1 -1
  3. package/dist/Configuration.d.ts +41 -5
  4. package/dist/Configuration.js +215 -92
  5. package/dist/Configuration.js.map +1 -1
  6. package/dist/ForEachNode.d.ts +59 -0
  7. package/dist/ForEachNode.js +522 -0
  8. package/dist/ForEachNode.js.map +1 -0
  9. package/dist/LoopMaxIterationsError.d.ts +11 -0
  10. package/dist/LoopMaxIterationsError.js +18 -0
  11. package/dist/LoopMaxIterationsError.js.map +1 -0
  12. package/dist/LoopNode.d.ts +36 -0
  13. package/dist/LoopNode.js +182 -0
  14. package/dist/LoopNode.js.map +1 -0
  15. package/dist/Runner.d.ts +11 -1
  16. package/dist/Runner.js +9 -2
  17. package/dist/Runner.js.map +1 -1
  18. package/dist/RunnerSteps.js +419 -112
  19. package/dist/RunnerSteps.js.map +1 -1
  20. package/dist/RuntimeAdapterNode.d.ts +2 -1
  21. package/dist/RuntimeAdapterNode.js +2 -2
  22. package/dist/RuntimeAdapterNode.js.map +1 -1
  23. package/dist/RuntimeRegistry.d.ts +23 -2
  24. package/dist/RuntimeRegistry.js +31 -2
  25. package/dist/RuntimeRegistry.js.map +1 -1
  26. package/dist/SubworkflowNode.d.ts +106 -0
  27. package/dist/SubworkflowNode.js +261 -3
  28. package/dist/SubworkflowNode.js.map +1 -1
  29. package/dist/SwitchNode.d.ts +37 -0
  30. package/dist/SwitchNode.js +153 -0
  31. package/dist/SwitchNode.js.map +1 -0
  32. package/dist/TriggerBase.d.ts +50 -0
  33. package/dist/TriggerBase.js +262 -4
  34. package/dist/TriggerBase.js.map +1 -1
  35. package/dist/TryCatchNode.d.ts +32 -0
  36. package/dist/TryCatchNode.js +207 -0
  37. package/dist/TryCatchNode.js.map +1 -0
  38. package/dist/adapters/grpc/GrpcCodec.js +2 -2
  39. package/dist/adapters/grpc/GrpcRuntimeAdapter.d.ts +6 -4
  40. package/dist/adapters/grpc/GrpcRuntimeAdapter.js +6 -4
  41. package/dist/adapters/grpc/GrpcRuntimeAdapter.js.map +1 -1
  42. package/dist/adapters/grpc/types.d.ts +7 -5
  43. package/dist/adapters/grpc/types.js.map +1 -1
  44. package/dist/adapters/transport.d.ts +12 -41
  45. package/dist/adapters/transport.js +21 -70
  46. package/dist/adapters/transport.js.map +1 -1
  47. package/dist/cache/NodeResultCache.js +7 -0
  48. package/dist/cache/NodeResultCache.js.map +1 -1
  49. package/dist/concurrency/NatsKvConcurrencyBackend.js +18 -5
  50. package/dist/concurrency/NatsKvConcurrencyBackend.js.map +1 -1
  51. package/dist/concurrency/RedisConcurrencyBackend.d.ts +64 -0
  52. package/dist/concurrency/RedisConcurrencyBackend.js +374 -0
  53. package/dist/concurrency/RedisConcurrencyBackend.js.map +1 -0
  54. package/dist/concurrency/createConcurrencyBackend.d.ts +1 -0
  55. package/dist/concurrency/createConcurrencyBackend.js +5 -1
  56. package/dist/concurrency/createConcurrencyBackend.js.map +1 -1
  57. package/dist/defineNode.d.ts +8 -0
  58. package/dist/defineNode.js +25 -5
  59. package/dist/defineNode.js.map +1 -1
  60. package/dist/graphql/GraphQLSchemaGenerator.js +1 -1
  61. package/dist/graphql/GraphQLSchemaGenerator.js.map +1 -1
  62. package/dist/index.d.ts +10 -6
  63. package/dist/index.js +13 -9
  64. package/dist/index.js.map +1 -1
  65. package/dist/marketplace/RuntimeCatalog.d.ts +6 -0
  66. package/dist/marketplace/RuntimeCatalog.js.map +1 -1
  67. package/dist/marketplace/RuntimeDiscovery.d.ts +2 -2
  68. package/dist/marketplace/RuntimeDiscovery.js +18 -6
  69. package/dist/marketplace/RuntimeDiscovery.js.map +1 -1
  70. package/dist/monitoring/ConcurrencyMetrics.d.ts +26 -0
  71. package/dist/monitoring/ConcurrencyMetrics.js +36 -4
  72. package/dist/monitoring/ConcurrencyMetrics.js.map +1 -1
  73. package/dist/monitoring/ForEachWaitMetrics.d.ts +22 -0
  74. package/dist/monitoring/ForEachWaitMetrics.js +36 -0
  75. package/dist/monitoring/ForEachWaitMetrics.js.map +1 -0
  76. package/dist/openapi/OpenAPIGenerator.js +7 -2
  77. package/dist/openapi/OpenAPIGenerator.js.map +1 -1
  78. package/dist/runtime/PrimitiveStack.d.ts +64 -0
  79. package/dist/runtime/PrimitiveStack.js +92 -0
  80. package/dist/runtime/PrimitiveStack.js.map +1 -0
  81. package/dist/scheduling/DebounceBackend.d.ts +108 -0
  82. package/dist/scheduling/DebounceBackend.js +23 -0
  83. package/dist/scheduling/DebounceBackend.js.map +1 -0
  84. package/dist/scheduling/DebounceCoordinator.d.ts +65 -12
  85. package/dist/scheduling/DebounceCoordinator.js +234 -13
  86. package/dist/scheduling/DebounceCoordinator.js.map +1 -1
  87. package/dist/scheduling/DeferredRunScheduler.d.ts +28 -0
  88. package/dist/scheduling/DeferredRunScheduler.js +105 -3
  89. package/dist/scheduling/DeferredRunScheduler.js.map +1 -1
  90. package/dist/scheduling/NatsKvDebounceBackend.d.ts +53 -0
  91. package/dist/scheduling/NatsKvDebounceBackend.js +334 -0
  92. package/dist/scheduling/NatsKvDebounceBackend.js.map +1 -0
  93. package/dist/scheduling/RedisDebounceBackend.d.ts +49 -0
  94. package/dist/scheduling/RedisDebounceBackend.js +356 -0
  95. package/dist/scheduling/RedisDebounceBackend.js.map +1 -0
  96. package/dist/scheduling/createDebounceBackend.d.ts +25 -0
  97. package/dist/scheduling/createDebounceBackend.js +39 -0
  98. package/dist/scheduling/createDebounceBackend.js.map +1 -0
  99. package/dist/security/AuditLogger.js +1 -1
  100. package/dist/security/AuditLogger.js.map +1 -1
  101. package/dist/security/AuthMiddleware.d.ts +19 -20
  102. package/dist/security/AuthMiddleware.js +35 -20
  103. package/dist/security/AuthMiddleware.js.map +1 -1
  104. package/dist/security/OAuthProvider.js +2 -2
  105. package/dist/security/OAuthProvider.js.map +1 -1
  106. package/dist/security/SecretManager.js +14 -13
  107. package/dist/security/SecretManager.js.map +1 -1
  108. package/dist/security/index.d.ts +3 -1
  109. package/dist/security/index.js +3 -1
  110. package/dist/security/index.js.map +1 -1
  111. package/dist/testing/TestHarness.d.ts +27 -12
  112. package/dist/testing/TestHarness.js +19 -3
  113. package/dist/testing/TestHarness.js.map +1 -1
  114. package/dist/testing/WorkflowTestRunner.js +0 -7
  115. package/dist/testing/WorkflowTestRunner.js.map +1 -1
  116. package/dist/tracing/InMemoryRunStore.d.ts +14 -1
  117. package/dist/tracing/InMemoryRunStore.js +95 -6
  118. package/dist/tracing/InMemoryRunStore.js.map +1 -1
  119. package/dist/tracing/PostgresRunStore.d.ts +28 -2
  120. package/dist/tracing/PostgresRunStore.js +276 -3
  121. package/dist/tracing/PostgresRunStore.js.map +1 -1
  122. package/dist/tracing/RoutingDiagnostics.d.ts +55 -0
  123. package/dist/tracing/RoutingDiagnostics.js +50 -0
  124. package/dist/tracing/RoutingDiagnostics.js.map +1 -0
  125. package/dist/tracing/RunStore.d.ts +82 -1
  126. package/dist/tracing/RunTracker.d.ts +7 -1
  127. package/dist/tracing/RunTracker.js +23 -0
  128. package/dist/tracing/RunTracker.js.map +1 -1
  129. package/dist/tracing/SqliteRunStore.d.ts +57 -2
  130. package/dist/tracing/SqliteRunStore.js +408 -48
  131. package/dist/tracing/SqliteRunStore.js.map +1 -1
  132. package/dist/tracing/TraceRouter.js +380 -18
  133. package/dist/tracing/TraceRouter.js.map +1 -1
  134. package/dist/tracing/createStore.js +14 -3
  135. package/dist/tracing/createStore.js.map +1 -1
  136. package/dist/tracing/metadataFilter.d.ts +63 -0
  137. package/dist/tracing/metadataFilter.js +224 -0
  138. package/dist/tracing/metadataFilter.js.map +1 -0
  139. package/dist/tracing/types.d.ts +331 -7
  140. package/dist/utils/envAllowlist.d.ts +35 -0
  141. package/dist/utils/envAllowlist.js +113 -0
  142. package/dist/utils/envAllowlist.js.map +1 -0
  143. package/dist/version/RuntimeVersionValidator.d.ts +38 -0
  144. package/dist/version/RuntimeVersionValidator.js +121 -0
  145. package/dist/version/RuntimeVersionValidator.js.map +1 -0
  146. package/dist/visualization/WorkflowVisualizer.js +4 -4
  147. package/dist/visualization/WorkflowVisualizer.js.map +1 -1
  148. package/dist/workflow/PersistenceHelper.d.ts +18 -10
  149. package/dist/workflow/PersistenceHelper.js +35 -9
  150. package/dist/workflow/PersistenceHelper.js.map +1 -1
  151. package/dist/workflow/WorkflowNormalizer.d.ts +19 -1
  152. package/dist/workflow/WorkflowNormalizer.js +469 -19
  153. package/dist/workflow/WorkflowNormalizer.js.map +1 -1
  154. package/dist/workflow/WorkflowRegistry.d.ts +122 -0
  155. package/dist/workflow/WorkflowRegistry.js +121 -0
  156. package/dist/workflow/WorkflowRegistry.js.map +1 -1
  157. package/dist/workflow/sampleBody.d.ts +54 -0
  158. package/dist/workflow/sampleBody.js +320 -0
  159. package/dist/workflow/sampleBody.js.map +1 -0
  160. package/package.json +3 -8
  161. package/dist/adapters/HttpRuntimeAdapter.d.ts +0 -79
  162. package/dist/adapters/HttpRuntimeAdapter.js +0 -233
  163. package/dist/adapters/HttpRuntimeAdapter.js.map +0 -1
@@ -0,0 +1,356 @@
1
+ /**
2
+ * Tier C #1 · Redis-backed debounce backend.
3
+ *
4
+ * Coordinates per-(workflow, debounceKey) window state across processes
5
+ * via a single Redis string key per bucket. Atomicity comes from
6
+ * server-side **Lua scripts** — `registerPing` / `finalize` /
7
+ * `cancel` / `purgeExpired` each run as a single `EVAL` with no OCC
8
+ * retry loop (Lua runs single-threaded against the keyspace).
9
+ *
10
+ * Storage shape: one JSON document per `(workflowName, debounceKey)`
11
+ * bucket. Owner identity is encoded in the doc itself as
12
+ * `(activeRunId, ownerProcessId, ownerLeaseExpiresAt)`; lease handoff
13
+ * happens atomically when a ping arrives after the lease expired.
14
+ *
15
+ * **Owner-local payload**: this backend tracks `pingCount`,
16
+ * `lastPingAt`, and `scheduledAt` only — payloads do NOT travel across
17
+ * processes. The owning process's local `onFire` closure fires when
18
+ * its timer elapses.
19
+ */
20
+ const DEFAULT_KEY_PREFIX = "blok-debounce";
21
+ /**
22
+ * Atomic registerPing. Reads the current doc (if any), decides
23
+ * ownership, writes back the next state, and returns
24
+ * `{outcome, activeRunId, scheduledAt, pingCount}`.
25
+ *
26
+ * KEYS[1] = bucket key
27
+ * ARGV[1] = mode ("leading" | "trailing")
28
+ * ARGV[2] = delayMs
29
+ * ARGV[3] = maxDelayMs ("-1" when unset)
30
+ * ARGV[4] = runId
31
+ * ARGV[5] = processId
32
+ * ARGV[6] = ownerLeaseMs
33
+ * ARGV[7] = now
34
+ *
35
+ * Returns: { outcome ("owner-new" | "owner-extend" | "coalesce"),
36
+ * activeRunId, scheduledAt, pingCount }
37
+ */
38
+ const REGISTER_PING_LUA = `
39
+ local raw = redis.call('GET', KEYS[1])
40
+ local existing = nil
41
+ if raw and raw ~= '' then
42
+ local ok, parsed = pcall(cjson.decode, raw)
43
+ if ok and type(parsed) == 'table' then
44
+ existing = parsed
45
+ end
46
+ end
47
+
48
+ local mode = ARGV[1]
49
+ local delayMs = tonumber(ARGV[2])
50
+ local maxDelayMsRaw = tonumber(ARGV[3])
51
+ local maxDelayMs
52
+ if maxDelayMsRaw and maxDelayMsRaw >= 0 then maxDelayMs = maxDelayMsRaw end
53
+ local runId = ARGV[4]
54
+ local processId = ARGV[5]
55
+ local ownerLeaseMs = tonumber(ARGV[6])
56
+ local now = tonumber(ARGV[7])
57
+
58
+ local function compute_scheduled_at(existing_doc, now_)
59
+ local naive = now_ + delayMs
60
+ local deadline
61
+ if existing_doc and existing_doc.maxDelayDeadline then
62
+ deadline = tonumber(existing_doc.maxDelayDeadline)
63
+ elseif maxDelayMs then
64
+ deadline = now_ + maxDelayMs
65
+ end
66
+ if deadline and deadline < naive then return deadline end
67
+ return naive
68
+ end
69
+
70
+ local ownerActive = existing ~= nil and tonumber(existing.ownerLeaseExpiresAt) and tonumber(existing.ownerLeaseExpiresAt) > now
71
+
72
+ if not existing or not ownerActive then
73
+ local first_ping_at = (existing and existing.firstPingAt) and tonumber(existing.firstPingAt) or now
74
+ local max_delay_deadline
75
+ if existing and existing.maxDelayDeadline then
76
+ max_delay_deadline = tonumber(existing.maxDelayDeadline)
77
+ elseif maxDelayMs then
78
+ max_delay_deadline = now + maxDelayMs
79
+ end
80
+ local prev_count = (existing and existing.pingCount) and tonumber(existing.pingCount) or 0
81
+ local doc = {
82
+ mode = mode,
83
+ delayMs = delayMs,
84
+ maxDelayMs = maxDelayMs,
85
+ maxDelayDeadline = max_delay_deadline,
86
+ firstPingAt = first_ping_at,
87
+ lastPingAt = now,
88
+ pingCount = prev_count + 1,
89
+ activeRunId = runId,
90
+ ownerProcessId = processId,
91
+ ownerLeaseExpiresAt = now + ownerLeaseMs,
92
+ scheduledAt = compute_scheduled_at(existing, now),
93
+ }
94
+ redis.call('SET', KEYS[1], cjson.encode(doc))
95
+ return { "owner-new", doc.activeRunId, tostring(doc.scheduledAt), tostring(doc.pingCount) }
96
+ end
97
+
98
+ if tostring(existing.ownerProcessId) == processId then
99
+ -- We still own — extend window.
100
+ existing.lastPingAt = now
101
+ existing.pingCount = (tonumber(existing.pingCount) or 0) + 1
102
+ existing.ownerLeaseExpiresAt = now + ownerLeaseMs
103
+ existing.scheduledAt = compute_scheduled_at(existing, now)
104
+ redis.call('SET', KEYS[1], cjson.encode(existing))
105
+ return { "owner-extend", tostring(existing.activeRunId), tostring(existing.scheduledAt), tostring(existing.pingCount) }
106
+ end
107
+
108
+ -- Different process owns — coalesce.
109
+ existing.lastPingAt = now
110
+ existing.pingCount = (tonumber(existing.pingCount) or 0) + 1
111
+ existing.scheduledAt = compute_scheduled_at(existing, now)
112
+ redis.call('SET', KEYS[1], cjson.encode(existing))
113
+ return { "coalesce", tostring(existing.activeRunId), tostring(existing.scheduledAt), tostring(existing.pingCount) }
114
+ `;
115
+ /**
116
+ * Atomic finalize. The owning process calls this on local timer fire.
117
+ *
118
+ * KEYS[1] = bucket key
119
+ * ARGV[1] = runId (the OWNING runId from the caller's perspective)
120
+ * ARGV[2] = now
121
+ *
122
+ * Returns:
123
+ * { "fire" } — caller still owns AND silence elapsed; DELETE done.
124
+ * { "reschedule", "<scheduledAt>" } — coalesce pings pushed scheduledAt forward.
125
+ * { "abandoned" } — caller no longer owns OR bucket gone.
126
+ */
127
+ const FINALIZE_LUA = `
128
+ local raw = redis.call('GET', KEYS[1])
129
+ if not raw or raw == '' then return { "abandoned" } end
130
+
131
+ local ok, doc = pcall(cjson.decode, raw)
132
+ if not ok or type(doc) ~= 'table' then return { "abandoned" } end
133
+
134
+ if tostring(doc.activeRunId) ~= ARGV[1] then return { "abandoned" } end
135
+
136
+ local now = tonumber(ARGV[2])
137
+ local scheduled = tonumber(doc.scheduledAt) or 0
138
+ if now < scheduled then
139
+ return { "reschedule", tostring(scheduled) }
140
+ end
141
+
142
+ redis.call('DEL', KEYS[1])
143
+ return { "fire" }
144
+ `;
145
+ export function readRedisDebounceConfigFromEnv() {
146
+ const url = process.env.BLOK_DEBOUNCE_REDIS_URL?.trim() || undefined;
147
+ const host = process.env.BLOK_DEBOUNCE_REDIS_HOST?.trim() || undefined;
148
+ const portRaw = process.env.BLOK_DEBOUNCE_REDIS_PORT?.trim();
149
+ const port = portRaw && /^\d+$/.test(portRaw) ? Number(portRaw) : undefined;
150
+ const dbRaw = process.env.BLOK_DEBOUNCE_REDIS_DB?.trim();
151
+ const db = dbRaw && /^\d+$/.test(dbRaw) ? Number(dbRaw) : undefined;
152
+ const tls = process.env.BLOK_DEBOUNCE_REDIS_TLS === "1" || process.env.BLOK_DEBOUNCE_REDIS_TLS === "true";
153
+ return {
154
+ url,
155
+ host,
156
+ port,
157
+ password: process.env.BLOK_DEBOUNCE_REDIS_PASSWORD,
158
+ username: process.env.BLOK_DEBOUNCE_REDIS_USERNAME,
159
+ db,
160
+ tls,
161
+ keyPrefix: process.env.BLOK_DEBOUNCE_REDIS_KEY_PREFIX?.trim() || DEFAULT_KEY_PREFIX,
162
+ };
163
+ }
164
+ export class RedisDebounceBackend {
165
+ name = "redis";
166
+ client = null;
167
+ config;
168
+ connected = false;
169
+ constructor(config) {
170
+ const env = readRedisDebounceConfigFromEnv();
171
+ this.config = {
172
+ url: config?.url ?? env.url,
173
+ host: config?.host ?? env.host,
174
+ port: config?.port ?? env.port,
175
+ password: config?.password ?? env.password,
176
+ username: config?.username ?? env.username,
177
+ db: config?.db ?? env.db,
178
+ tls: config?.tls ?? env.tls,
179
+ keyPrefix: config?.keyPrefix ?? env.keyPrefix,
180
+ };
181
+ }
182
+ async connect() {
183
+ if (this.connected)
184
+ return;
185
+ const blokEnv = process.env.BLOK_ENV;
186
+ const nodeEnv = process.env.NODE_ENV;
187
+ const isProd = blokEnv === "production" || nodeEnv === "production";
188
+ if (isProd && this.config.keyPrefix === DEFAULT_KEY_PREFIX) {
189
+ throw new Error(`[blok] Redis debounce backend refuses to start in production with the default key prefix ('${DEFAULT_KEY_PREFIX}'). Set BLOK_DEBOUNCE_REDIS_KEY_PREFIX to a deployment-unique value (e.g. 'blok-debounce-acme-prod') to prevent cross-deployment collision on a shared Redis instance.`);
190
+ }
191
+ let ioredisModule;
192
+ try {
193
+ ioredisModule = (await import("ioredis"));
194
+ }
195
+ catch (err) {
196
+ throw new Error(`RedisDebounceBackend requires the 'ioredis' package. Install it: \`bun add ioredis\` or \`npm install ioredis\`. Underlying error: ${err instanceof Error ? err.message : String(err)}`);
197
+ }
198
+ const IORedisCtor = ioredisModule.default ?? ioredisModule.Redis;
199
+ if (!IORedisCtor) {
200
+ throw new Error("RedisDebounceBackend could not locate the ioredis constructor on the imported module. Reinstall ioredis or report this issue.");
201
+ }
202
+ // Same fail-fast posture as RedisConcurrencyBackend.
203
+ const failFastDefaults = {
204
+ connectTimeout: 5_000,
205
+ maxRetriesPerRequest: 0,
206
+ enableOfflineQueue: false,
207
+ lazyConnect: true,
208
+ };
209
+ if (this.config.url) {
210
+ this.client = new IORedisCtor(this.config.url);
211
+ }
212
+ else {
213
+ const opts = { ...failFastDefaults };
214
+ if (this.config.host)
215
+ opts.host = this.config.host;
216
+ if (this.config.port)
217
+ opts.port = this.config.port;
218
+ if (this.config.username)
219
+ opts.username = this.config.username;
220
+ if (this.config.password)
221
+ opts.password = this.config.password;
222
+ if (typeof this.config.db === "number")
223
+ opts.db = this.config.db;
224
+ if (this.config.tls)
225
+ opts.tls = {};
226
+ this.client = new IORedisCtor(opts);
227
+ }
228
+ this.client.on("error", (err) => {
229
+ console.warn(`[blok][debounce][redis] client error: ${err.message}`);
230
+ });
231
+ await this.client.ping();
232
+ this.connected = true;
233
+ }
234
+ async disconnect() {
235
+ if (!this.connected)
236
+ return;
237
+ try {
238
+ await this.client?.quit();
239
+ }
240
+ catch {
241
+ // best-effort
242
+ }
243
+ finally {
244
+ this.client = null;
245
+ this.connected = false;
246
+ }
247
+ }
248
+ bucketKey(workflowName, debounceKey) {
249
+ return `${this.config.keyPrefix}:${this.encodeSegment(workflowName)}__${this.encodeSegment(debounceKey)}`;
250
+ }
251
+ encodeSegment(s) {
252
+ return s.replace(/[^-_=.a-zA-Z0-9]/g, (ch) => `_${ch.codePointAt(0)?.toString(16)}_`);
253
+ }
254
+ requireClient() {
255
+ if (!this.client) {
256
+ throw new Error("RedisDebounceBackend not connected — call connect() first.");
257
+ }
258
+ return this.client;
259
+ }
260
+ async registerPing(opts) {
261
+ const client = this.requireClient();
262
+ const key = this.bucketKey(opts.workflowName, opts.debounceKey);
263
+ const raw = await client.eval(REGISTER_PING_LUA, 1, key, opts.mode, String(opts.delayMs), opts.maxDelayMs !== undefined ? String(opts.maxDelayMs) : "-1", opts.runId, opts.processId, String(opts.ownerLeaseMs), String(opts.now));
264
+ return this.parseRegisterResult(raw);
265
+ }
266
+ async finalize(workflowName, debounceKey, runId, now) {
267
+ const client = this.requireClient();
268
+ const key = this.bucketKey(workflowName, debounceKey);
269
+ const raw = await client.eval(FINALIZE_LUA, 1, key, runId, String(now));
270
+ return this.parseFinalizeResult(raw);
271
+ }
272
+ async cancel(workflowName, debounceKey) {
273
+ const client = this.requireClient();
274
+ const key = this.bucketKey(workflowName, debounceKey);
275
+ const deleted = await client.del(key);
276
+ return deleted > 0;
277
+ }
278
+ async purgeExpired(now) {
279
+ const client = this.requireClient();
280
+ const pattern = `${this.config.keyPrefix}:*`;
281
+ let cursor = "0";
282
+ let purged = 0;
283
+ do {
284
+ let res;
285
+ try {
286
+ res = await client.scan(cursor, "MATCH", pattern, "COUNT", 100);
287
+ }
288
+ catch {
289
+ return purged;
290
+ }
291
+ const [nextCursor, keys] = res;
292
+ cursor = nextCursor;
293
+ for (const key of keys) {
294
+ try {
295
+ const raw = await client.eval(PURGE_EXPIRED_BUCKET_LUA, 1, key, String(now));
296
+ const count = typeof raw === "number" ? raw : Number(raw);
297
+ if (!Number.isNaN(count))
298
+ purged += count;
299
+ }
300
+ catch {
301
+ // best-effort
302
+ }
303
+ }
304
+ } while (cursor !== "0");
305
+ return purged;
306
+ }
307
+ parseRegisterResult(raw) {
308
+ if (!Array.isArray(raw) || raw.length < 4) {
309
+ throw new Error(`Unexpected Lua result shape for registerPing: ${JSON.stringify(raw)}`);
310
+ }
311
+ const outcome = String(raw[0]);
312
+ if (outcome !== "owner-new" && outcome !== "owner-extend" && outcome !== "coalesce") {
313
+ throw new Error(`Unexpected outcome in Lua result: ${outcome}`);
314
+ }
315
+ return {
316
+ outcome,
317
+ activeRunId: String(raw[1]),
318
+ scheduledAt: Number(raw[2]),
319
+ pingCount: Number(raw[3]),
320
+ };
321
+ }
322
+ parseFinalizeResult(raw) {
323
+ if (!Array.isArray(raw) || raw.length < 1)
324
+ return { finalize: "abandoned" };
325
+ const tag = String(raw[0]);
326
+ if (tag === "fire")
327
+ return { finalize: "fire" };
328
+ if (tag === "reschedule")
329
+ return { finalize: "reschedule", scheduledAt: Number(raw[1]) };
330
+ return { finalize: "abandoned" };
331
+ }
332
+ }
333
+ /**
334
+ * Per-bucket purge. Deletes the bucket iff the owner-lease has expired
335
+ * AND scheduledAt has elapsed (no active owner with a pending fire).
336
+ *
337
+ * KEYS[1] = bucket key
338
+ * ARGV[1] = now
339
+ *
340
+ * Returns: 1 if deleted, 0 otherwise.
341
+ */
342
+ const PURGE_EXPIRED_BUCKET_LUA = `
343
+ local raw = redis.call('GET', KEYS[1])
344
+ if not raw or raw == '' then return 0 end
345
+ local ok, doc = pcall(cjson.decode, raw)
346
+ if not ok or type(doc) ~= 'table' then return 0 end
347
+ local now = tonumber(ARGV[1])
348
+ local lease = tonumber(doc.ownerLeaseExpiresAt) or 0
349
+ local sched = tonumber(doc.scheduledAt) or 0
350
+ if lease <= now and sched <= now then
351
+ redis.call('DEL', KEYS[1])
352
+ return 1
353
+ end
354
+ return 0
355
+ `;
356
+ //# sourceMappingURL=RedisDebounceBackend.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RedisDebounceBackend.js","sourceRoot":"","sources":["../../src/scheduling/RedisDebounceBackend.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAoBH,MAAM,kBAAkB,GAAG,eAAe,CAAC;AAgB3C;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,iBAAiB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4EzB,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,MAAM,YAAY,GAAG;;;;;;;;;;;;;;;;;CAiBpB,CAAC;AAEF,MAAM,UAAU,8BAA8B;IAC7C,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,uBAAuB,EAAE,IAAI,EAAE,IAAI,SAAS,CAAC;IACrE,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,wBAAwB,EAAE,IAAI,EAAE,IAAI,SAAS,CAAC;IACvE,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,wBAAwB,EAAE,IAAI,EAAE,CAAC;IAC7D,MAAM,IAAI,GAAG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC5E,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,sBAAsB,EAAE,IAAI,EAAE,CAAC;IACzD,MAAM,EAAE,GAAG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACpE,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,uBAAuB,KAAK,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC,uBAAuB,KAAK,MAAM,CAAC;IAC1G,OAAO;QACN,GAAG;QACH,IAAI;QACJ,IAAI;QACJ,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,4BAA4B;QAClD,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,4BAA4B;QAClD,EAAE;QACF,GAAG;QACH,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,8BAA8B,EAAE,IAAI,EAAE,IAAI,kBAAkB;KACnF,CAAC;AACH,CAAC;AAED,MAAM,OAAO,oBAAoB;IACvB,IAAI,GAAG,OAAO,CAAC;IAEhB,MAAM,GAAuB,IAAI,CAAC;IACzB,MAAM,CAAsB;IACrC,SAAS,GAAG,KAAK,CAAC;IAE1B,YAAY,MAAqC;QAChD,MAAM,GAAG,GAAG,8BAA8B,EAAE,CAAC;QAC7C,IAAI,CAAC,MAAM,GAAG;YACb,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI,GAAG,CAAC,GAAG;YAC3B,IAAI,EAAE,MAAM,EAAE,IAAI,IAAI,GAAG,CAAC,IAAI;YAC9B,IAAI,EAAE,MAAM,EAAE,IAAI,IAAI,GAAG,CAAC,IAAI;YAC9B,QAAQ,EAAE,MAAM,EAAE,QAAQ,IAAI,GAAG,CAAC,QAAQ;YAC1C,QAAQ,EAAE,MAAM,EAAE,QAAQ,IAAI,GAAG,CAAC,QAAQ;YAC1C,EAAE,EAAE,MAAM,EAAE,EAAE,IAAI,GAAG,CAAC,EAAE;YACxB,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI,GAAG,CAAC,GAAG;YAC3B,SAAS,EAAE,MAAM,EAAE,SAAS,IAAI,GAAG,CAAC,SAAS;SAC7C,CAAC;IACH,CAAC;IAED,KAAK,CAAC,OAAO;QACZ,IAAI,IAAI,CAAC,SAAS;YAAE,OAAO;QAE3B,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC;QACrC,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC;QACrC,MAAM,MAAM,GAAG,OAAO,KAAK,YAAY,IAAI,OAAO,KAAK,YAAY,CAAC;QACpE,IAAI,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,SAAS,KAAK,kBAAkB,EAAE,CAAC;YAC5D,MAAM,IAAI,KAAK,CACd,8FAA8F,kBAAkB,wKAAwK,CACxR,CAAC;QACH,CAAC;QAED,IAAI,aAA4B,CAAC;QACjC,IAAI,CAAC;YACJ,aAAa,GAAG,CAAC,MAAM,MAAM,CAAC,SAAS,CAAC,CAA6B,CAAC;QACvE,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACd,MAAM,IAAI,KAAK,CACd,sIAAsI,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CACxL,CAAC;QACH,CAAC;QAED,MAAM,WAAW,GAAG,aAAa,CAAC,OAAO,IAAI,aAAa,CAAC,KAAK,CAAC;QACjE,IAAI,CAAC,WAAW,EAAE,CAAC;YAClB,MAAM,IAAI,KAAK,CACd,+HAA+H,CAC/H,CAAC;QACH,CAAC;QAED,qDAAqD;QACrD,MAAM,gBAAgB,GAA4B;YACjD,cAAc,EAAE,KAAK;YACrB,oBAAoB,EAAE,CAAC;YACvB,kBAAkB,EAAE,KAAK;YACzB,WAAW,EAAE,IAAI;SACjB,CAAC;QAEF,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;YACrB,IAAI,CAAC,MAAM,GAAG,IAAI,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAChD,CAAC;aAAM,CAAC;YACP,MAAM,IAAI,GAA4B,EAAE,GAAG,gBAAgB,EAAE,CAAC;YAC9D,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI;gBAAE,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;YACnD,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI;gBAAE,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;YACnD,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ;gBAAE,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC;YAC/D,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ;gBAAE,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC;YAC/D,IAAI,OAAO,IAAI,CAAC,MAAM,CAAC,EAAE,KAAK,QAAQ;gBAAE,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;YACjE,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG;gBAAE,IAAI,CAAC,GAAG,GAAG,EAAE,CAAC;YACnC,IAAI,CAAC,MAAM,GAAG,IAAI,WAAW,CAAC,IAAI,CAAC,CAAC;QACrC,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAU,EAAE,EAAE;YACtC,OAAO,CAAC,IAAI,CAAC,yCAAyC,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QACtE,CAAC,CAAC,CAAC;QAEH,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;QACzB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;IACvB,CAAC;IAED,KAAK,CAAC,UAAU;QACf,IAAI,CAAC,IAAI,CAAC,SAAS;YAAE,OAAO;QAC5B,IAAI,CAAC;YACJ,MAAM,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC;QAC3B,CAAC;QAAC,MAAM,CAAC;YACR,cAAc;QACf,CAAC;gBAAS,CAAC;YACV,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;YACnB,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;QACxB,CAAC;IACF,CAAC;IAEO,SAAS,CAAC,YAAoB,EAAE,WAAmB;QAC1D,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,IAAI,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,KAAK,IAAI,CAAC,aAAa,CAAC,WAAW,CAAC,EAAE,CAAC;IAC3G,CAAC;IAEO,aAAa,CAAC,CAAS;QAC9B,OAAO,CAAC,CAAC,OAAO,CAAC,mBAAmB,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;IACvF,CAAC;IAEO,aAAa;QACpB,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YAClB,MAAM,IAAI,KAAK,CAAC,4DAA4D,CAAC,CAAC;QAC/E,CAAC;QACD,OAAO,IAAI,CAAC,MAAM,CAAC;IACpB,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,IAAiC;QACnD,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;QACpC,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;QAEhE,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,IAAI,CAC5B,iBAAiB,EACjB,CAAC,EACD,GAAG,EACH,IAAI,CAAC,IAAI,EACT,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,EACpB,IAAI,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,EAC9D,IAAI,CAAC,KAAK,EACV,IAAI,CAAC,SAAS,EACd,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,EACzB,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAChB,CAAC;QACF,OAAO,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC;IACtC,CAAC;IAED,KAAK,CAAC,QAAQ,CACb,YAAoB,EACpB,WAAmB,EACnB,KAAa,EACb,GAAW;QAEX,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;QACpC,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC;QACtD,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;QACxE,OAAO,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC;IACtC,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,YAAoB,EAAE,WAAmB;QACrD,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;QACpC,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC;QACtD,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACtC,OAAO,OAAO,GAAG,CAAC,CAAC;IACpB,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,GAAW;QAC7B,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;QACpC,MAAM,OAAO,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,IAAI,CAAC;QAC7C,IAAI,MAAM,GAAG,GAAG,CAAC;QACjB,IAAI,MAAM,GAAG,CAAC,CAAC;QAEf,GAAG,CAAC;YACH,IAAI,GAAuB,CAAC;YAC5B,IAAI,CAAC;gBACJ,GAAG,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC;YACjE,CAAC;YAAC,MAAM,CAAC;gBACR,OAAO,MAAM,CAAC;YACf,CAAC;YACD,MAAM,CAAC,UAAU,EAAE,IAAI,CAAC,GAAG,GAAG,CAAC;YAC/B,MAAM,GAAG,UAAU,CAAC;YACpB,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;gBACxB,IAAI,CAAC;oBACJ,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,wBAAwB,EAAE,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;oBAC7E,MAAM,KAAK,GAAG,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;oBAC1D,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC;wBAAE,MAAM,IAAI,KAAK,CAAC;gBAC3C,CAAC;gBAAC,MAAM,CAAC;oBACR,cAAc;gBACf,CAAC;YACF,CAAC;QACF,CAAC,QAAQ,MAAM,KAAK,GAAG,EAAE;QAEzB,OAAO,MAAM,CAAC;IACf,CAAC;IAEO,mBAAmB,CAAC,GAAY;QACvC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC3C,MAAM,IAAI,KAAK,CAAC,iDAAiD,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACzF,CAAC;QACD,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/B,IAAI,OAAO,KAAK,WAAW,IAAI,OAAO,KAAK,cAAc,IAAI,OAAO,KAAK,UAAU,EAAE,CAAC;YACrF,MAAM,IAAI,KAAK,CAAC,qCAAqC,OAAO,EAAE,CAAC,CAAC;QACjE,CAAC;QACD,OAAO;YACN,OAAO;YACP,WAAW,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YAC3B,WAAW,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YAC3B,SAAS,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;SACzB,CAAC;IACH,CAAC;IAEO,mBAAmB,CAAC,GAAY;QACvC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC;YAAE,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAC;QAC5E,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAC3B,IAAI,GAAG,KAAK,MAAM;YAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;QAChD,IAAI,GAAG,KAAK,YAAY;YAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACzF,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAC;IAClC,CAAC;CACD;AAED;;;;;;;;GAQG;AACH,MAAM,wBAAwB,GAAG;;;;;;;;;;;;;CAahC,CAAC"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Tier C #1 · Debounce backend factory.
3
+ *
4
+ * Reads `BLOK_DEBOUNCE_BACKEND` and returns the matching backend
5
+ * instance, or `null` when the operator wants the default in-process
6
+ * coordinator (no cross-process coordination).
7
+ *
8
+ * Trigger packages call this in `listen()` and pass the result to
9
+ * `DebounceCoordinator.getInstance().setBackend(backend)`.
10
+ */
11
+ import type { DebounceBackend } from "./DebounceBackend";
12
+ /**
13
+ * Returns a configured `DebounceBackend` based on
14
+ * `BLOK_DEBOUNCE_BACKEND`, or `null` for the default in-memory coordinator.
15
+ *
16
+ * Recognized values:
17
+ * - unset / `""` / `"memory"` / `"in-process"` — null (use default in-memory)
18
+ * - `"nats-kv"` — NATS KV backend (requires `nats` package + reachable NATS server)
19
+ * - `"redis"` — Redis backend (requires `ioredis` package + reachable Redis server)
20
+ *
21
+ * Unknown values throw at startup with a clear error message — silently
22
+ * falling back would be dangerous (operator thinks they configured
23
+ * cross-process debounce but they didn't).
24
+ */
25
+ export declare function createDebounceBackend(): DebounceBackend | null;
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Tier C #1 · Debounce backend factory.
3
+ *
4
+ * Reads `BLOK_DEBOUNCE_BACKEND` and returns the matching backend
5
+ * instance, or `null` when the operator wants the default in-process
6
+ * coordinator (no cross-process coordination).
7
+ *
8
+ * Trigger packages call this in `listen()` and pass the result to
9
+ * `DebounceCoordinator.getInstance().setBackend(backend)`.
10
+ */
11
+ import { NatsKvDebounceBackend } from "./NatsKvDebounceBackend";
12
+ import { RedisDebounceBackend } from "./RedisDebounceBackend";
13
+ /**
14
+ * Returns a configured `DebounceBackend` based on
15
+ * `BLOK_DEBOUNCE_BACKEND`, or `null` for the default in-memory coordinator.
16
+ *
17
+ * Recognized values:
18
+ * - unset / `""` / `"memory"` / `"in-process"` — null (use default in-memory)
19
+ * - `"nats-kv"` — NATS KV backend (requires `nats` package + reachable NATS server)
20
+ * - `"redis"` — Redis backend (requires `ioredis` package + reachable Redis server)
21
+ *
22
+ * Unknown values throw at startup with a clear error message — silently
23
+ * falling back would be dangerous (operator thinks they configured
24
+ * cross-process debounce but they didn't).
25
+ */
26
+ export function createDebounceBackend() {
27
+ const kind = (process.env.BLOK_DEBOUNCE_BACKEND ?? "").trim().toLowerCase();
28
+ if (!kind || kind === "memory" || kind === "in-process")
29
+ return null;
30
+ switch (kind) {
31
+ case "nats-kv":
32
+ return new NatsKvDebounceBackend();
33
+ case "redis":
34
+ return new RedisDebounceBackend();
35
+ default:
36
+ throw new Error(`Unknown BLOK_DEBOUNCE_BACKEND='${kind}'. Expected one of: 'memory' (default), 'nats-kv', 'redis'.`);
37
+ }
38
+ }
39
+ //# sourceMappingURL=createDebounceBackend.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createDebounceBackend.js","sourceRoot":"","sources":["../../src/scheduling/createDebounceBackend.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAE9D;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,qBAAqB;IACpC,MAAM,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,qBAAqB,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC5E,IAAI,CAAC,IAAI,IAAI,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,YAAY;QAAE,OAAO,IAAI,CAAC;IAErE,QAAQ,IAAI,EAAE,CAAC;QACd,KAAK,SAAS;YACb,OAAO,IAAI,qBAAqB,EAAE,CAAC;QACpC,KAAK,OAAO;YACX,OAAO,IAAI,oBAAoB,EAAE,CAAC;QACnC;YACC,MAAM,IAAI,KAAK,CACd,kCAAkC,IAAI,6DAA6D,CACnG,CAAC;IACJ,CAAC;AACF,CAAC"}
@@ -264,7 +264,7 @@ export class FileAuditSink {
264
264
  await mkdir(dirname(this.filePath), { recursive: true });
265
265
  this.initialized = true;
266
266
  }
267
- const data = this.buffer.join("\n") + "\n";
267
+ const data = `${this.buffer.join("\n")}\n`;
268
268
  this.buffer = [];
269
269
  await appendFile(this.filePath, data, "utf-8");
270
270
  }
@@ -1 +1 @@
1
- {"version":3,"file":"AuditLogger.js","sourceRoot":"","sources":["../../src/security/AuditLogger.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"AuditLogger.js","sourceRoot":"","sources":["../../src/security/AuditLogger.ts"],"names":[],"mappings":"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"}
@@ -1,29 +1,19 @@
1
1
  /**
2
2
  * Authentication Middleware for Blok Triggers
3
3
  *
4
- * Provides pluggable authentication for all trigger types:
5
- * - JWT Bearer token verification (RS256, HS256)
6
- * - API Key verification (header, query param)
7
- * - Custom auth provider support
8
- *
9
- * Integrates with TriggerBase via composition.
4
+ * @deprecated Since v0.4.1. Will be removed in v0.5. This class ships as
5
+ * example-grade code (HS256-only JWT verification, no JWKS, no key
6
+ * rotation, non-constant-time API-key lookup) and is not wired into any
7
+ * trigger. Production deployments should compose auth from a hardened
8
+ * library (`jose`, `hono/jwt`, `node-jsonwebtoken`) at the trigger or
9
+ * workflow layer instead. See `docs/d/security/cookbook.mdx` for the
10
+ * recommended patterns.
10
11
  *
11
12
  * @example
12
13
  * ```typescript
13
- * const auth = new AuthMiddleware({
14
- * providers: [
15
- * new JWTAuthProvider({ secret: process.env.JWT_SECRET! }),
16
- * new APIKeyAuthProvider({
17
- * keys: new Map([["my-api-key", { name: "service-a", roles: ["admin"] }]]),
18
- * }),
19
- * ],
20
- * });
21
- *
22
- * // In Express middleware
23
- * app.use(auth.expressMiddleware());
24
- *
25
- * // Or manually
26
- * const identity = await auth.authenticate(request);
14
+ * // Recommended (jose):
15
+ * import { jwtVerify } from "jose";
16
+ * const { payload } = await jwtVerify(token, secret, { issuer, audience });
27
17
  * ```
28
18
  */
29
19
  export interface AuthIdentity {
@@ -75,6 +65,9 @@ export interface AuthMiddlewareConfig {
75
65
  /** Custom error handler */
76
66
  onAuthFailure?: (result: AuthResult, request: AuthRequest) => void;
77
67
  }
68
+ /**
69
+ * @deprecated Since v0.4.1. See file-level JSDoc; will be removed in v0.5.
70
+ */
78
71
  export declare class AuthMiddleware {
79
72
  private config;
80
73
  constructor(config: AuthMiddlewareConfig);
@@ -119,6 +112,9 @@ export interface JWTAuthProviderConfig {
119
112
  /** Map JWT claims to roles (claim name → role mapping function) */
120
113
  rolesClaim?: string;
121
114
  }
115
+ /**
116
+ * @deprecated Since v0.4.1. See file-level JSDoc; will be removed in v0.5.
117
+ */
122
118
  export declare class JWTAuthProvider implements AuthProvider {
123
119
  readonly name = "jwt";
124
120
  private config;
@@ -154,6 +150,9 @@ export interface APIKeyAuthProviderConfig {
154
150
  /** Custom key validation function (e.g., for database lookups) */
155
151
  validate?: (key: string) => Promise<APIKeyInfo | null>;
156
152
  }
153
+ /**
154
+ * @deprecated Since v0.4.1. See file-level JSDoc; will be removed in v0.5.
155
+ */
157
156
  export declare class APIKeyAuthProvider implements AuthProvider {
158
157
  readonly name = "api-key";
159
158
  private config;
@@ -1,32 +1,38 @@
1
1
  /**
2
2
  * Authentication Middleware for Blok Triggers
3
3
  *
4
- * Provides pluggable authentication for all trigger types:
5
- * - JWT Bearer token verification (RS256, HS256)
6
- * - API Key verification (header, query param)
7
- * - Custom auth provider support
8
- *
9
- * Integrates with TriggerBase via composition.
4
+ * @deprecated Since v0.4.1. Will be removed in v0.5. This class ships as
5
+ * example-grade code (HS256-only JWT verification, no JWKS, no key
6
+ * rotation, non-constant-time API-key lookup) and is not wired into any
7
+ * trigger. Production deployments should compose auth from a hardened
8
+ * library (`jose`, `hono/jwt`, `node-jsonwebtoken`) at the trigger or
9
+ * workflow layer instead. See `docs/d/security/cookbook.mdx` for the
10
+ * recommended patterns.
10
11
  *
11
12
  * @example
12
13
  * ```typescript
13
- * const auth = new AuthMiddleware({
14
- * providers: [
15
- * new JWTAuthProvider({ secret: process.env.JWT_SECRET! }),
16
- * new APIKeyAuthProvider({
17
- * keys: new Map([["my-api-key", { name: "service-a", roles: ["admin"] }]]),
18
- * }),
19
- * ],
20
- * });
21
- *
22
- * // In Express middleware
23
- * app.use(auth.expressMiddleware());
24
- *
25
- * // Or manually
26
- * const identity = await auth.authenticate(request);
14
+ * // Recommended (jose):
15
+ * import { jwtVerify } from "jose";
16
+ * const { payload } = await jwtVerify(token, secret, { issuer, audience });
27
17
  * ```
28
18
  */
29
19
  import { createHmac, timingSafeEqual } from "node:crypto";
20
+ let authMiddlewareWarningEmitted = false;
21
+ function emitAuthMiddlewareDeprecationWarning() {
22
+ if (authMiddlewareWarningEmitted)
23
+ return;
24
+ authMiddlewareWarningEmitted = true;
25
+ if (process.env.BLOK_SUPPRESS_AUTHMIDDLEWARE_WARNING === "1")
26
+ return;
27
+ console.warn("[blok] AuthMiddleware (and JWTAuthProvider, APIKeyAuthProvider) is deprecated and will be removed in v0.5. " +
28
+ "It ships as example-grade code, not production auth. " +
29
+ "Use `jose`, `hono/jwt`, or `node-jsonwebtoken` at the trigger or workflow layer instead. " +
30
+ "See docs/d/security/cookbook.mdx. " +
31
+ "Set BLOK_SUPPRESS_AUTHMIDDLEWARE_WARNING=1 to silence.");
32
+ }
33
+ /**
34
+ * @deprecated Since v0.4.1. See file-level JSDoc; will be removed in v0.5.
35
+ */
30
36
  export class AuthMiddleware {
31
37
  config;
32
38
  constructor(config) {
@@ -35,6 +41,7 @@ export class AuthMiddleware {
35
41
  required: true,
36
42
  ...config,
37
43
  };
44
+ emitAuthMiddlewareDeprecationWarning();
38
45
  }
39
46
  /**
40
47
  * Authenticate a request against all registered providers.
@@ -108,6 +115,9 @@ export class AuthMiddleware {
108
115
  return (this.config.excludePaths || []).some((excluded) => path === excluded || path.startsWith(`${excluded}/`));
109
116
  }
110
117
  }
118
+ /**
119
+ * @deprecated Since v0.4.1. See file-level JSDoc; will be removed in v0.5.
120
+ */
111
121
  export class JWTAuthProvider {
112
122
  name = "jwt";
113
123
  config;
@@ -118,6 +128,7 @@ export class JWTAuthProvider {
118
128
  rolesClaim: "roles",
119
129
  ...config,
120
130
  };
131
+ emitAuthMiddlewareDeprecationWarning();
121
132
  }
122
133
  async authenticate(request) {
123
134
  const headerValue = request.headers[this.config.headerName || "authorization"];
@@ -213,6 +224,9 @@ export class JWTAuthProvider {
213
224
  }
214
225
  }
215
226
  }
227
+ /**
228
+ * @deprecated Since v0.4.1. See file-level JSDoc; will be removed in v0.5.
229
+ */
216
230
  export class APIKeyAuthProvider {
217
231
  name = "api-key";
218
232
  config;
@@ -222,6 +236,7 @@ export class APIKeyAuthProvider {
222
236
  queryParam: "api_key",
223
237
  ...config,
224
238
  };
239
+ emitAuthMiddlewareDeprecationWarning();
225
240
  }
226
241
  async authenticate(request) {
227
242
  // Try header first