@blokjs/runner 0.4.0 → 0.6.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.
- package/dist/Blok.js +32 -3
- package/dist/Blok.js.map +1 -1
- package/dist/Configuration.d.ts +41 -5
- package/dist/Configuration.js +215 -92
- package/dist/Configuration.js.map +1 -1
- package/dist/ForEachNode.d.ts +59 -0
- package/dist/ForEachNode.js +522 -0
- package/dist/ForEachNode.js.map +1 -0
- package/dist/LoopMaxIterationsError.d.ts +11 -0
- package/dist/LoopMaxIterationsError.js +18 -0
- package/dist/LoopMaxIterationsError.js.map +1 -0
- package/dist/LoopNode.d.ts +36 -0
- package/dist/LoopNode.js +182 -0
- package/dist/LoopNode.js.map +1 -0
- package/dist/Runner.d.ts +11 -1
- package/dist/Runner.js +9 -2
- package/dist/Runner.js.map +1 -1
- package/dist/RunnerSteps.js +419 -112
- package/dist/RunnerSteps.js.map +1 -1
- package/dist/RuntimeAdapterNode.d.ts +2 -1
- package/dist/RuntimeAdapterNode.js +2 -2
- package/dist/RuntimeAdapterNode.js.map +1 -1
- package/dist/RuntimeRegistry.d.ts +23 -2
- package/dist/RuntimeRegistry.js +31 -2
- package/dist/RuntimeRegistry.js.map +1 -1
- package/dist/SubworkflowNode.d.ts +106 -0
- package/dist/SubworkflowNode.js +261 -3
- package/dist/SubworkflowNode.js.map +1 -1
- package/dist/SwitchNode.d.ts +37 -0
- package/dist/SwitchNode.js +153 -0
- package/dist/SwitchNode.js.map +1 -0
- package/dist/TriggerBase.d.ts +50 -0
- package/dist/TriggerBase.js +262 -4
- package/dist/TriggerBase.js.map +1 -1
- package/dist/TryCatchNode.d.ts +32 -0
- package/dist/TryCatchNode.js +207 -0
- package/dist/TryCatchNode.js.map +1 -0
- package/dist/adapters/grpc/GrpcCodec.js +2 -2
- package/dist/adapters/grpc/GrpcRuntimeAdapter.d.ts +6 -4
- package/dist/adapters/grpc/GrpcRuntimeAdapter.js +6 -4
- package/dist/adapters/grpc/GrpcRuntimeAdapter.js.map +1 -1
- package/dist/adapters/grpc/types.d.ts +7 -5
- package/dist/adapters/grpc/types.js.map +1 -1
- package/dist/adapters/transport.d.ts +12 -41
- package/dist/adapters/transport.js +21 -70
- package/dist/adapters/transport.js.map +1 -1
- package/dist/cache/NodeResultCache.js +7 -0
- package/dist/cache/NodeResultCache.js.map +1 -1
- package/dist/concurrency/NatsKvConcurrencyBackend.js +18 -5
- package/dist/concurrency/NatsKvConcurrencyBackend.js.map +1 -1
- package/dist/concurrency/RedisConcurrencyBackend.d.ts +64 -0
- package/dist/concurrency/RedisConcurrencyBackend.js +374 -0
- package/dist/concurrency/RedisConcurrencyBackend.js.map +1 -0
- package/dist/concurrency/createConcurrencyBackend.d.ts +1 -0
- package/dist/concurrency/createConcurrencyBackend.js +5 -1
- package/dist/concurrency/createConcurrencyBackend.js.map +1 -1
- package/dist/defineNode.d.ts +8 -0
- package/dist/defineNode.js +25 -5
- package/dist/defineNode.js.map +1 -1
- package/dist/graphql/GraphQLSchemaGenerator.js +1 -1
- package/dist/graphql/GraphQLSchemaGenerator.js.map +1 -1
- package/dist/index.d.ts +10 -6
- package/dist/index.js +13 -9
- package/dist/index.js.map +1 -1
- package/dist/marketplace/RuntimeCatalog.d.ts +6 -0
- package/dist/marketplace/RuntimeCatalog.js.map +1 -1
- package/dist/marketplace/RuntimeDiscovery.d.ts +2 -2
- package/dist/marketplace/RuntimeDiscovery.js +18 -6
- package/dist/marketplace/RuntimeDiscovery.js.map +1 -1
- package/dist/monitoring/ConcurrencyMetrics.d.ts +26 -0
- package/dist/monitoring/ConcurrencyMetrics.js +36 -4
- package/dist/monitoring/ConcurrencyMetrics.js.map +1 -1
- package/dist/monitoring/ForEachWaitMetrics.d.ts +22 -0
- package/dist/monitoring/ForEachWaitMetrics.js +36 -0
- package/dist/monitoring/ForEachWaitMetrics.js.map +1 -0
- package/dist/openapi/OpenAPIGenerator.js +7 -2
- package/dist/openapi/OpenAPIGenerator.js.map +1 -1
- package/dist/runtime/PrimitiveStack.d.ts +64 -0
- package/dist/runtime/PrimitiveStack.js +92 -0
- package/dist/runtime/PrimitiveStack.js.map +1 -0
- package/dist/scheduling/DebounceBackend.d.ts +108 -0
- package/dist/scheduling/DebounceBackend.js +23 -0
- package/dist/scheduling/DebounceBackend.js.map +1 -0
- package/dist/scheduling/DebounceCoordinator.d.ts +65 -12
- package/dist/scheduling/DebounceCoordinator.js +234 -13
- package/dist/scheduling/DebounceCoordinator.js.map +1 -1
- package/dist/scheduling/DeferredRunScheduler.d.ts +28 -0
- package/dist/scheduling/DeferredRunScheduler.js +105 -3
- package/dist/scheduling/DeferredRunScheduler.js.map +1 -1
- package/dist/scheduling/NatsKvDebounceBackend.d.ts +53 -0
- package/dist/scheduling/NatsKvDebounceBackend.js +334 -0
- package/dist/scheduling/NatsKvDebounceBackend.js.map +1 -0
- package/dist/scheduling/RedisDebounceBackend.d.ts +49 -0
- package/dist/scheduling/RedisDebounceBackend.js +356 -0
- package/dist/scheduling/RedisDebounceBackend.js.map +1 -0
- package/dist/scheduling/createDebounceBackend.d.ts +25 -0
- package/dist/scheduling/createDebounceBackend.js +39 -0
- package/dist/scheduling/createDebounceBackend.js.map +1 -0
- package/dist/security/AuditLogger.js +1 -1
- package/dist/security/AuditLogger.js.map +1 -1
- package/dist/security/AuthMiddleware.d.ts +19 -20
- package/dist/security/AuthMiddleware.js +35 -20
- package/dist/security/AuthMiddleware.js.map +1 -1
- package/dist/security/OAuthProvider.js +2 -2
- package/dist/security/OAuthProvider.js.map +1 -1
- package/dist/security/SecretManager.js +14 -13
- package/dist/security/SecretManager.js.map +1 -1
- package/dist/security/index.d.ts +3 -1
- package/dist/security/index.js +3 -1
- package/dist/security/index.js.map +1 -1
- package/dist/testing/TestHarness.d.ts +27 -12
- package/dist/testing/TestHarness.js +19 -3
- package/dist/testing/TestHarness.js.map +1 -1
- package/dist/testing/WorkflowTestRunner.js +0 -7
- package/dist/testing/WorkflowTestRunner.js.map +1 -1
- package/dist/tracing/InMemoryRunStore.d.ts +14 -1
- package/dist/tracing/InMemoryRunStore.js +95 -6
- package/dist/tracing/InMemoryRunStore.js.map +1 -1
- package/dist/tracing/PostgresRunStore.d.ts +28 -2
- package/dist/tracing/PostgresRunStore.js +276 -3
- package/dist/tracing/PostgresRunStore.js.map +1 -1
- package/dist/tracing/RoutingDiagnostics.d.ts +55 -0
- package/dist/tracing/RoutingDiagnostics.js +50 -0
- package/dist/tracing/RoutingDiagnostics.js.map +1 -0
- package/dist/tracing/RunStore.d.ts +82 -1
- package/dist/tracing/RunTracker.d.ts +7 -1
- package/dist/tracing/RunTracker.js +23 -0
- package/dist/tracing/RunTracker.js.map +1 -1
- package/dist/tracing/SqliteRunStore.d.ts +57 -2
- package/dist/tracing/SqliteRunStore.js +408 -48
- package/dist/tracing/SqliteRunStore.js.map +1 -1
- package/dist/tracing/TraceRouter.js +380 -18
- package/dist/tracing/TraceRouter.js.map +1 -1
- package/dist/tracing/createStore.js +14 -3
- package/dist/tracing/createStore.js.map +1 -1
- package/dist/tracing/metadataFilter.d.ts +63 -0
- package/dist/tracing/metadataFilter.js +224 -0
- package/dist/tracing/metadataFilter.js.map +1 -0
- package/dist/tracing/types.d.ts +331 -7
- package/dist/utils/envAllowlist.d.ts +35 -0
- package/dist/utils/envAllowlist.js +113 -0
- package/dist/utils/envAllowlist.js.map +1 -0
- package/dist/version/RuntimeVersionValidator.d.ts +38 -0
- package/dist/version/RuntimeVersionValidator.js +121 -0
- package/dist/version/RuntimeVersionValidator.js.map +1 -0
- package/dist/visualization/WorkflowVisualizer.js +4 -4
- package/dist/visualization/WorkflowVisualizer.js.map +1 -1
- package/dist/workflow/PersistenceHelper.d.ts +18 -10
- package/dist/workflow/PersistenceHelper.js +35 -9
- package/dist/workflow/PersistenceHelper.js.map +1 -1
- package/dist/workflow/WorkflowNormalizer.d.ts +19 -1
- package/dist/workflow/WorkflowNormalizer.js +469 -19
- package/dist/workflow/WorkflowNormalizer.js.map +1 -1
- package/dist/workflow/WorkflowRegistry.d.ts +122 -0
- package/dist/workflow/WorkflowRegistry.js +121 -0
- package/dist/workflow/WorkflowRegistry.js.map +1 -1
- package/dist/workflow/sampleBody.d.ts +54 -0
- package/dist/workflow/sampleBody.js +320 -0
- package/dist/workflow/sampleBody.js.map +1 -0
- package/package.json +3 -8
- package/dist/adapters/HttpRuntimeAdapter.d.ts +0 -79
- package/dist/adapters/HttpRuntimeAdapter.js +0 -233
- package/dist/adapters/HttpRuntimeAdapter.js.map +0 -1
package/dist/tracing/types.d.ts
CHANGED
|
@@ -161,6 +161,39 @@ export interface WorkflowRun {
|
|
|
161
161
|
* encountered a wait step (preserves existing semantics).
|
|
162
162
|
*/
|
|
163
163
|
lastCompletedStepIndex?: number;
|
|
164
|
+
/**
|
|
165
|
+
* v0.6 prerequisite for wait-inside-primitives Phase 2.
|
|
166
|
+
*
|
|
167
|
+
* JSON-serialized snapshot of `ctx.state` taken immediately before
|
|
168
|
+
* `RunnerSteps` throws `WaitDispatchRequest`. On `dispatchDeferred`
|
|
169
|
+
* re-entry — including the cross-process recovery path where the
|
|
170
|
+
* scheduler re-builds a fresh ctx from the persisted dispatch row —
|
|
171
|
+
* `TriggerBase.run` rehydrates `ctx.state` (and its `ctx.vars`
|
|
172
|
+
* alias) from this column so subsequent steps see the same
|
|
173
|
+
* pre-wait state regardless of process restart.
|
|
174
|
+
*
|
|
175
|
+
* Without this column, only the in-process timer-fire path would
|
|
176
|
+
* preserve state (state still lives on the original ctx). The
|
|
177
|
+
* cross-process path would resume with empty `ctx.state`, breaking
|
|
178
|
+
* Phase 2's iteration-state-persistence promise (a forEach
|
|
179
|
+
* iteration whose body fired the wait would lose its index, the
|
|
180
|
+
* loop's accumulator, etc.).
|
|
181
|
+
*
|
|
182
|
+
* Capped by `BLOK_STATE_SNAPSHOT_MAX_BYTES` (default 1MB,
|
|
183
|
+
* matching `BLOK_DISPATCH_PAYLOAD_MAX_BYTES`) — when the
|
|
184
|
+
* serialized state exceeds the cap, the runner logs a warning and
|
|
185
|
+
* skips the snapshot (the wait still defers; resumption is
|
|
186
|
+
* best-effort). Authors can opt out entirely via
|
|
187
|
+
* `BLOK_STATE_SNAPSHOT_DISABLED=1`. Sensitive keys aren't filtered
|
|
188
|
+
* here — the snapshot only persists what the workflow has already
|
|
189
|
+
* computed into `state`, so apply your own redaction in nodes that
|
|
190
|
+
* write secrets there.
|
|
191
|
+
*
|
|
192
|
+
* Undefined for runs that never threw `WaitDispatchRequest`, which
|
|
193
|
+
* is the vast majority. Persisted column is `state_snapshot`
|
|
194
|
+
* (sqlite migration v11).
|
|
195
|
+
*/
|
|
196
|
+
stateSnapshot?: string;
|
|
164
197
|
}
|
|
165
198
|
export type NodeRunStatus = "pending" | "running" | "completed" | "failed" | "skipped";
|
|
166
199
|
export interface NodeRun {
|
|
@@ -251,6 +284,24 @@ export interface NodeRun {
|
|
|
251
284
|
* visible to Studio without recomputing from outputs heuristics.
|
|
252
285
|
*/
|
|
253
286
|
wait?: boolean;
|
|
287
|
+
/**
|
|
288
|
+
* G2 (v0.6) sub-workflow dispatch strategy — only set for
|
|
289
|
+
* `nodeType === "subworkflow"`. Mirrors the step config's `dispatch`
|
|
290
|
+
* field so Studio can distinguish in-process invocations from HTTP
|
|
291
|
+
* self-call dispatches at a glance.
|
|
292
|
+
*
|
|
293
|
+
* - `"in-process"` (default; also represented by `undefined` on legacy
|
|
294
|
+
* traces) — child runs in the same Node process via the in-process
|
|
295
|
+
* `Runner`.
|
|
296
|
+
* - `"http-self"` — child is dispatched as a fresh HTTP request to
|
|
297
|
+
* `BLOK_SELF_BASE_URL`, potentially landing on a different process
|
|
298
|
+
* in a horizontally-scaled deployment.
|
|
299
|
+
*
|
|
300
|
+
* Captured at `tracker.startNode()` time alongside `wait` so the rail
|
|
301
|
+
* badge can compose them (`↳ async` orange + `http` sky for an
|
|
302
|
+
* async http-self dispatch).
|
|
303
|
+
*/
|
|
304
|
+
dispatch?: "in-process" | "http-self";
|
|
254
305
|
/**
|
|
255
306
|
* PR 5 E3 — sub-workflow nesting depth surfaced for Studio.
|
|
256
307
|
*
|
|
@@ -263,6 +314,138 @@ export interface NodeRun {
|
|
|
263
314
|
* keep top-level invocations un-cluttered.
|
|
264
315
|
*/
|
|
265
316
|
subworkflowDepth?: number;
|
|
317
|
+
/**
|
|
318
|
+
* v0.5 — origin middleware name when the trigger's
|
|
319
|
+
* `runMiddlewareChain` produced this NodeRun. The trigger sets a
|
|
320
|
+
* `_blokMiddlewareName` sentinel on ctx before dispatching each
|
|
321
|
+
* middleware; RunnerSteps reads it and propagates here so Studio's
|
|
322
|
+
* StepRail can surface a `mw:<name>` badge on the inner steps a
|
|
323
|
+
* middleware produced (otherwise indistinguishable from regular
|
|
324
|
+
* depth-1 nested steps).
|
|
325
|
+
*/
|
|
326
|
+
middleware?: string;
|
|
327
|
+
/**
|
|
328
|
+
* v0.5.3 — iteration index for steps inside a `forEach` or `loop`
|
|
329
|
+
* primitive. Set per-iteration by ForEachNode / LoopNode on the
|
|
330
|
+
* cloned child ctx (`_blokIterationIndex` sentinel); RunnerSteps
|
|
331
|
+
* reads it and propagates here. Studio's StepRail groups consecutive
|
|
332
|
+
* sibling rows that share an iterationIndex into a collapsible
|
|
333
|
+
* "iteration N" header so a 5-iteration forEach with 3 inner steps
|
|
334
|
+
* renders as 5 grouped sections instead of 15 flat rows with
|
|
335
|
+
* duplicate names. Undefined for top-level steps, for steps inside
|
|
336
|
+
* non-iteration primitives (`tryCatch`, `switch`), and for legacy
|
|
337
|
+
* traces written before v0.5.3.
|
|
338
|
+
*/
|
|
339
|
+
iterationIndex?: number;
|
|
340
|
+
/**
|
|
341
|
+
* v0.6 wait-inside-primitives — iteration cursor. Set on a primitive
|
|
342
|
+
* iterator's NodeRun (e.g. forEach, loop) by RunnerSteps when an
|
|
343
|
+
* INNER step throws `WaitDispatchRequest` mid-iteration. Read by
|
|
344
|
+
* `TriggerBase.run` on dispatchDeferred re-entry and stamped onto
|
|
345
|
+
* `ctx._blokIterationResume` so the primitive can pick it up.
|
|
346
|
+
* Persisted column is `iteration_context` (sqlite migration v12).
|
|
347
|
+
*
|
|
348
|
+
* Two encodings via a `mode` discriminator:
|
|
349
|
+
*
|
|
350
|
+
* - `mode: "sequential"` (or omitted for back-compat): the Phase 2
|
|
351
|
+
* sequential forEach + wait cursor (also reused by Phase 3 loop).
|
|
352
|
+
* Records the in-flight iteration index, the inner step index
|
|
353
|
+
* where the wait fired, and an in-order `completedResults`
|
|
354
|
+
* accumulator covering iterations `[0..iteration-1]`. ForEachNode
|
|
355
|
+
* and LoopNode read this on resume to skip the completed prefix.
|
|
356
|
+
*
|
|
357
|
+
* - `mode: "parallel"` (PR follow-up to Phase 3): the parallel
|
|
358
|
+
* forEach + wait cursor. Records which iteration's wait fired
|
|
359
|
+
* (`waitFiringIteration`), where inside its body
|
|
360
|
+
* (`innerStepIndex`), a SPARSE `completedResults` array (slot `i`
|
|
361
|
+
* populated iff iteration `i` finished before the wait fired —
|
|
362
|
+
* `null` for "ran but returned undefined", JSON-undefined hole
|
|
363
|
+
* for "not present"), and the explicit `cancelledIterations`
|
|
364
|
+
* list (in-flight + queued indices that need re-launch on
|
|
365
|
+
* resume). See `docs/c/devtools/parallel-foreach-wait-spec.mdx`
|
|
366
|
+
* for the full contract.
|
|
367
|
+
*
|
|
368
|
+
* Undefined on regular NodeRuns and on primitives that completed
|
|
369
|
+
* without ever throwing a wait.
|
|
370
|
+
*/
|
|
371
|
+
iterationContext?: IterationContext;
|
|
372
|
+
}
|
|
373
|
+
/**
|
|
374
|
+
* Discriminated union for the iteration cursor persisted into
|
|
375
|
+
* `node_runs.iteration_context`. See `NodeRun.iterationContext` for
|
|
376
|
+
* field-level semantics. The runtime selection lives in:
|
|
377
|
+
*
|
|
378
|
+
* - Write side: `core/runner/src/RunnerSteps.ts` wait-throw site
|
|
379
|
+
* (sequential) and `ForEachNode.run` parallel-branch error handler
|
|
380
|
+
* (parallel).
|
|
381
|
+
* - Read side: `TriggerBase.run` rehydrate stamps the cursor onto
|
|
382
|
+
* `ctx._blokIterationResume`; the primitive itself (ForEachNode,
|
|
383
|
+
* LoopNode) dispatches on `mode` to the right resume path.
|
|
384
|
+
*/
|
|
385
|
+
export type IterationContext = SequentialIterationContext | ParallelIterationContext | SwitchIterationContext;
|
|
386
|
+
/**
|
|
387
|
+
* Sequential forEach + wait OR loop + wait cursor. The pre-existing
|
|
388
|
+
* Phase 2/3 shape — `mode` is optional and defaults to "sequential" on
|
|
389
|
+
* read so cursors written before the discriminator landed (i.e., main
|
|
390
|
+
* before this PR) keep being interpreted correctly.
|
|
391
|
+
*/
|
|
392
|
+
export interface SequentialIterationContext {
|
|
393
|
+
mode?: "sequential";
|
|
394
|
+
/** Iteration index (0-based) the wait fired in. */
|
|
395
|
+
iteration: number;
|
|
396
|
+
/** Inner step index within iteration's body where the wait fired. */
|
|
397
|
+
innerStepIndex: number;
|
|
398
|
+
/** Accumulator for iterations [0..iteration-1]; pre-populates `results[]` on resume. */
|
|
399
|
+
completedResults: unknown[];
|
|
400
|
+
}
|
|
401
|
+
/**
|
|
402
|
+
* v0.6 Phase 4 — switch + wait cursor. Records which case arm matched
|
|
403
|
+
* (so on re-entry SwitchNode walks back into the same arm) plus the
|
|
404
|
+
* inner step within that arm where the wait fired.
|
|
405
|
+
*
|
|
406
|
+
* `caseIndex` semantics:
|
|
407
|
+
* - `>= 0` — index into the workflow's `cases[]` array.
|
|
408
|
+
* - `-1` — the `default` arm matched.
|
|
409
|
+
*
|
|
410
|
+
* `completedResults` is unused for switch (it doesn't iterate) but the
|
|
411
|
+
* field is kept on the IterationContext union for cross-schema parity.
|
|
412
|
+
* Always `[]` on switch.
|
|
413
|
+
*/
|
|
414
|
+
export interface SwitchIterationContext {
|
|
415
|
+
mode: "switch";
|
|
416
|
+
/** Resolved case index; `-1` denotes the `default` arm. */
|
|
417
|
+
caseIndex: number;
|
|
418
|
+
/** Inner step index within the matched arm where the wait fired. */
|
|
419
|
+
innerStepIndex: number;
|
|
420
|
+
/** Unused for switch; preserved at schema level for parity. Always `[]`. */
|
|
421
|
+
completedResults: never[];
|
|
422
|
+
}
|
|
423
|
+
/**
|
|
424
|
+
* Parallel forEach + wait cursor. The headline contract: persist
|
|
425
|
+
* completed iteration results, retry incomplete ones on resume. See
|
|
426
|
+
* `docs/c/devtools/parallel-foreach-wait-spec.mdx` for the full design.
|
|
427
|
+
*/
|
|
428
|
+
export interface ParallelIterationContext {
|
|
429
|
+
mode: "parallel";
|
|
430
|
+
/** Index of the iteration whose inner step threw the wait. */
|
|
431
|
+
waitFiringIteration: number;
|
|
432
|
+
/** Inner step index within the wait-firing iteration's body. */
|
|
433
|
+
innerStepIndex: number;
|
|
434
|
+
/**
|
|
435
|
+
* Sparse array indexed by iteration number. Slot `i` is populated
|
|
436
|
+
* iff iteration `i` finished before the wait fired. `null` means
|
|
437
|
+
* "ran but returned undefined" (distinct from the JSON-undefined
|
|
438
|
+
* hole = "not present in cursor, re-launch on resume").
|
|
439
|
+
*/
|
|
440
|
+
completedResults: (unknown | null)[];
|
|
441
|
+
/**
|
|
442
|
+
* Iteration indices that were in-flight OR queued at wait-throw
|
|
443
|
+
* moment. ForEachNode re-launches these from inner step 0 on
|
|
444
|
+
* resume. The wait-firing iteration is NOT in this list — it
|
|
445
|
+
* resumes via `innerStepIndex`. Sorted ascending for trace-dump
|
|
446
|
+
* readability.
|
|
447
|
+
*/
|
|
448
|
+
cancelledIterations: number[];
|
|
266
449
|
}
|
|
267
450
|
/**
|
|
268
451
|
* Stored result of a previously-successful step execution, keyed by
|
|
@@ -328,6 +511,26 @@ export interface ScheduledDispatchRow {
|
|
|
328
511
|
payload: unknown;
|
|
329
512
|
/** ms since epoch when the row was first written. */
|
|
330
513
|
createdAt: number;
|
|
514
|
+
/**
|
|
515
|
+
* Tier C #2 — cross-process scheduler coordination. Set when a
|
|
516
|
+
* process claims this dispatch during boot recovery. Unset on
|
|
517
|
+
* unclaimed rows.
|
|
518
|
+
*
|
|
519
|
+
* Multi-process PG deployments use the claim to prevent the same
|
|
520
|
+
* dispatch from being fired by two processes that both ran
|
|
521
|
+
* `recoverDispatches()` against the shared table. Single-process
|
|
522
|
+
* and per-process sqlite deployments see no observable difference
|
|
523
|
+
* (the same process always wins the claim).
|
|
524
|
+
*/
|
|
525
|
+
claimedBy?: string;
|
|
526
|
+
/**
|
|
527
|
+
* Tier C #2 — last heartbeat timestamp (ms since epoch). The
|
|
528
|
+
* holder of `claimedBy` periodically refreshes `claimedAt` while
|
|
529
|
+
* the timer is registered. Stale claims (now > claimedAt + leaseMs)
|
|
530
|
+
* are eligible for takeover by another process — protects against
|
|
531
|
+
* crashed holders blocking recovery indefinitely.
|
|
532
|
+
*/
|
|
533
|
+
claimedAt?: number;
|
|
331
534
|
}
|
|
332
535
|
export type RunEventType = "RUN_STARTED" | "RUN_COMPLETED" | "RUN_FAILED" | "NODE_STARTED" | "NODE_COMPLETED" | "NODE_FAILED" | "NODE_SKIPPED" | "VARS_UPDATED" | "LOG_ENTRY"
|
|
333
536
|
/** §17 Phase 5: streaming `Progress` frame from the SDK. */
|
|
@@ -443,6 +646,26 @@ export interface WorkflowDetail extends WorkflowSummary {
|
|
|
443
646
|
definition?: unknown;
|
|
444
647
|
nodeNames: string[];
|
|
445
648
|
runtimes: string[];
|
|
649
|
+
/**
|
|
650
|
+
* Sample-body for the Studio empty-state curl. `source` lets the
|
|
651
|
+
* UI optionally distinguish author-declared examples from the
|
|
652
|
+
* synthesized ones (it doesn't today, but could in the future).
|
|
653
|
+
* Always populated for object-shaped workflows; `body` is `{}`
|
|
654
|
+
* when no body references were detected.
|
|
655
|
+
*/
|
|
656
|
+
examples?: {
|
|
657
|
+
body: unknown;
|
|
658
|
+
/**
|
|
659
|
+
* Provenance of the body. `author` = declared in the workflow's
|
|
660
|
+
* `trigger.http.examples.body`. `recorded` = captured from the
|
|
661
|
+
* first successful run when `recordSample: true` is set on the
|
|
662
|
+
* trigger. `inferred` = synthesized from static analysis of step
|
|
663
|
+
* inputs. `empty` = no body references + no recording + no
|
|
664
|
+
* author override (the literal `{}`). Studio surfaces this in
|
|
665
|
+
* the Runs-tab empty-state curl snippet label.
|
|
666
|
+
*/
|
|
667
|
+
source: "author" | "recorded" | "inferred" | "empty";
|
|
668
|
+
};
|
|
446
669
|
}
|
|
447
670
|
export interface PaginatedResult<T> {
|
|
448
671
|
data: T[];
|
|
@@ -509,6 +732,13 @@ export interface StartNodeOptions {
|
|
|
509
732
|
* Persisted onto `NodeRun.wait` so Studio can render `↳ async` vs `↳ sub`.
|
|
510
733
|
*/
|
|
511
734
|
wait?: boolean;
|
|
735
|
+
/**
|
|
736
|
+
* G2 (v0.6) sub-workflow dispatch strategy. Only meaningful when
|
|
737
|
+
* `nodeType === "subworkflow"`. Persisted onto `NodeRun.dispatch` so
|
|
738
|
+
* Studio can render an extra `http` badge alongside `↳ async`/`↳ sub`
|
|
739
|
+
* for HTTP self-call dispatches.
|
|
740
|
+
*/
|
|
741
|
+
dispatch?: "in-process" | "http-self";
|
|
512
742
|
/**
|
|
513
743
|
* PR 5 E3 — sub-workflow nesting depth. Only meaningful when
|
|
514
744
|
* `nodeType === "subworkflow"`. The runner computes
|
|
@@ -516,6 +746,23 @@ export interface StartNodeOptions {
|
|
|
516
746
|
* passes here so Studio can render `↳ sub (N)` for N >= 2.
|
|
517
747
|
*/
|
|
518
748
|
subworkflowDepth?: number;
|
|
749
|
+
/**
|
|
750
|
+
* v0.5 — origin middleware name. Set when the parent ctx carries
|
|
751
|
+
* `_blokMiddlewareName` (HttpTrigger.runMiddlewareChain stash).
|
|
752
|
+
* Propagates onto `NodeRun.middleware` so Studio's StepRail can
|
|
753
|
+
* surface a `mw:<name>` badge.
|
|
754
|
+
*/
|
|
755
|
+
middleware?: string;
|
|
756
|
+
/**
|
|
757
|
+
* v0.5.3 — iteration index for steps inside a `forEach` or `loop`
|
|
758
|
+
* primitive. Set when the parent ctx carries `_blokIterationIndex`
|
|
759
|
+
* (ForEachNode + LoopNode stash on each per-iteration child ctx).
|
|
760
|
+
* Studio's StepRail uses this to group consecutive sibling rows
|
|
761
|
+
* into "iteration N" sections instead of showing them flat with
|
|
762
|
+
* duplicated step names. Undefined for top-level steps and for
|
|
763
|
+
* inner steps of non-iteration primitives (`tryCatch`, `switch`).
|
|
764
|
+
*/
|
|
765
|
+
iterationIndex?: number;
|
|
519
766
|
}
|
|
520
767
|
export type WidgetType = "stat-card" | "timeline" | "error-rate" | "duration-distribution" | "workflow-breakdown" | "node-performance" | "recent-runs" | "heatmap";
|
|
521
768
|
export interface DashboardWidget {
|
|
@@ -545,19 +792,96 @@ export interface Dashboard {
|
|
|
545
792
|
updatedAt: number;
|
|
546
793
|
widgets: DashboardWidget[];
|
|
547
794
|
}
|
|
795
|
+
/**
|
|
796
|
+
* E2 — server-side saved filter for the runs list. Mirrors the
|
|
797
|
+
* earlier localStorage shape (`apps/studio/src/lib/savedFilters.ts`)
|
|
798
|
+
* with `id` + timestamps added. Filter names are UNIQUE across the
|
|
799
|
+
* deployment — re-saving overwrites the existing row. Studio applies
|
|
800
|
+
* them by setting the run-list filter UI from the stored values.
|
|
801
|
+
*/
|
|
802
|
+
export interface SavedFilter {
|
|
803
|
+
id: string;
|
|
804
|
+
name: string;
|
|
805
|
+
/** Workflow run status (`""` for "all"). */
|
|
806
|
+
status: string;
|
|
807
|
+
/**
|
|
808
|
+
* Free-form tag input as the user typed it ("env:prod,team:billing").
|
|
809
|
+
* Server stores it verbatim; the run-list URL parser interprets it.
|
|
810
|
+
*/
|
|
811
|
+
tagsInput: string;
|
|
812
|
+
/**
|
|
813
|
+
* Free-form metadata input as the user typed it
|
|
814
|
+
* ("tier=premium,region__in=us,eu"). Same parsing contract as the
|
|
815
|
+
* runs-page URL — `MetadataFilter[]` once parsed.
|
|
816
|
+
*/
|
|
817
|
+
metadataInput: string;
|
|
818
|
+
createdAt: number;
|
|
819
|
+
updatedAt: number;
|
|
820
|
+
}
|
|
821
|
+
/**
|
|
822
|
+
* Sample-body recording (v0.6 follow-up to #100). When a workflow's
|
|
823
|
+
* HTTP trigger declares `recordSample: true`, the trigger captures
|
|
824
|
+
* the request body of the FIRST successful run and persists it
|
|
825
|
+
* here. Studio's `examples.body` resolution prefers a recorded
|
|
826
|
+
* sample over static inference but always defers to an author-
|
|
827
|
+
* declared `trigger.http.examples.body`.
|
|
828
|
+
*
|
|
829
|
+
* One row per workflow — re-recording is intentionally skipped
|
|
830
|
+
* after the first capture so storage stays bounded + the
|
|
831
|
+
* operator-visible example stays stable. Authors can re-trigger a
|
|
832
|
+
* recording by deleting the row (no Studio surface for this yet;
|
|
833
|
+
* call `tracker.deleteWorkflowSample(name)` from a script).
|
|
834
|
+
*/
|
|
835
|
+
export interface WorkflowSample {
|
|
836
|
+
workflowName: string;
|
|
837
|
+
body: unknown;
|
|
838
|
+
/** Run id whose request body was captured. */
|
|
839
|
+
sourceRunId: string;
|
|
840
|
+
/** Wall-clock when the sample was recorded. */
|
|
841
|
+
recordedAt: number;
|
|
842
|
+
}
|
|
843
|
+
/**
|
|
844
|
+
* F2 (v0.5) — operators accepted on metadata filters. `eq` is the
|
|
845
|
+
* default (and the only one available before v0.5). Each operator
|
|
846
|
+
* coerces values the way an operator typically would: numerical
|
|
847
|
+
* comparisons cast to number, `like` is SQL `LIKE` (with `%` /
|
|
848
|
+
* `_` wildcards), `in`/`nin` accept array values.
|
|
849
|
+
*/
|
|
850
|
+
export type MetadataOp = "eq" | "ne" | "gt" | "gte" | "lt" | "lte" | "like" | "in" | "nin";
|
|
851
|
+
/**
|
|
852
|
+
* F2 (v0.5) — operator-aware metadata filter. Combines with other
|
|
853
|
+
* filters in the same `RunQuery.metadata` array via AND semantics.
|
|
854
|
+
*
|
|
855
|
+
* `value` is `string` for scalar operators (`eq` / `ne` / `gt` / `lt` /
|
|
856
|
+
* `gte` / `lte` / `like`), `string[]` for set operators (`in` / `nin`).
|
|
857
|
+
* Numeric comparisons treat the stored metadata value as a number when
|
|
858
|
+
* possible (the underlying JSON store preserves the native type).
|
|
859
|
+
*/
|
|
860
|
+
export interface MetadataFilter {
|
|
861
|
+
key: string;
|
|
862
|
+
op: MetadataOp;
|
|
863
|
+
value: string | string[];
|
|
864
|
+
}
|
|
548
865
|
export interface RunQuery {
|
|
549
866
|
workflow?: string;
|
|
550
867
|
status?: WorkflowRunStatus;
|
|
551
868
|
tags?: string[];
|
|
552
869
|
/**
|
|
553
|
-
*
|
|
554
|
-
*
|
|
555
|
-
*
|
|
556
|
-
*
|
|
557
|
-
*
|
|
558
|
-
* `
|
|
870
|
+
* Filter by metadata key/value pairs. Multiple entries combine with
|
|
871
|
+
* AND semantics (a run matches only when every declared filter is
|
|
872
|
+
* satisfied).
|
|
873
|
+
*
|
|
874
|
+
* **Two accepted shapes** — `Record<string, string>` is back-compat
|
|
875
|
+
* sugar for an array of `{key, op: "eq", value}` filters. Pass an
|
|
876
|
+
* array to use operators beyond `=` (F2: `ne` / `gt` / `gte` / `lt`
|
|
877
|
+
* / `lte` / `like` / `in` / `nin`). Both shapes route through the
|
|
878
|
+
* same evaluator after normalisation.
|
|
879
|
+
*
|
|
880
|
+
* **Performance** — sequential JSON-extract scan by default;
|
|
881
|
+
* declare hot keys via `BLOK_INDEXED_METADATA_KEYS=tier,region` to
|
|
882
|
+
* get an indexed column + index on the SqliteRunStore side (F1).
|
|
559
883
|
*/
|
|
560
|
-
metadata?: Record<string, string
|
|
884
|
+
metadata?: Record<string, string> | MetadataFilter[];
|
|
561
885
|
limit?: number;
|
|
562
886
|
offset?: number;
|
|
563
887
|
sort?: "asc" | "desc";
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Operator-controlled allowlist for `ctx.env` exposed to user nodes.
|
|
3
|
+
*
|
|
4
|
+
* By default `ctx.env` mirrors `process.env` — every node sees every
|
|
5
|
+
* env var. Operators harden against accidental secret leakage by
|
|
6
|
+
* setting one or both of:
|
|
7
|
+
*
|
|
8
|
+
* - `BLOK_NODE_ENV_ALLOW` — comma-separated exact names. Example:
|
|
9
|
+
* `BLOK_NODE_ENV_ALLOW=DATABASE_URL,STRIPE_KEY`
|
|
10
|
+
* - `BLOK_NODE_ENV_ALLOW_PREFIX` — comma-separated prefixes. Example:
|
|
11
|
+
* `BLOK_NODE_ENV_ALLOW_PREFIX=PUBLIC_,SAFE_`
|
|
12
|
+
*
|
|
13
|
+
* When EITHER is set, `ctx.env` becomes a Proxy that returns
|
|
14
|
+
* `undefined` for keys not in the allowlist and excludes them from
|
|
15
|
+
* `Object.keys`/`for...in`/`hasOwnProperty`. When NEITHER is set,
|
|
16
|
+
* `ctx.env` is `process.env` directly (preserves v0.4.x semantics —
|
|
17
|
+
* no breaking change).
|
|
18
|
+
*
|
|
19
|
+
* Set `BLOK_SUPPRESS_ENV_ALLOW_WARNING=1` to silence the boot warning
|
|
20
|
+
* that fires when `BLOK_ENV=production` and no allowlist is configured.
|
|
21
|
+
*
|
|
22
|
+
* The allowlist is parsed on every `getEnvForCtx()` call (creating a
|
|
23
|
+
* Context). Cost is sub-microsecond — strings are small and the
|
|
24
|
+
* Proxy is allocated once per request. Tests can mutate
|
|
25
|
+
* `process.env.BLOK_NODE_ENV_ALLOW` between calls and see the change
|
|
26
|
+
* immediately (no module-load caching).
|
|
27
|
+
*/
|
|
28
|
+
/**
|
|
29
|
+
* Returns the object to assign to `ctx.env`. When no allowlist is
|
|
30
|
+
* configured, returns `process.env` (default-allow). When configured,
|
|
31
|
+
* returns a filtering Proxy. Called by `TriggerBase.createContext`.
|
|
32
|
+
*/
|
|
33
|
+
export declare function getEnvForCtx(): NodeJS.ProcessEnv;
|
|
34
|
+
/** Test-only — clears the once-per-process production warning flag. */
|
|
35
|
+
export declare function _resetEnvAllowlistForTests(): void;
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Operator-controlled allowlist for `ctx.env` exposed to user nodes.
|
|
3
|
+
*
|
|
4
|
+
* By default `ctx.env` mirrors `process.env` — every node sees every
|
|
5
|
+
* env var. Operators harden against accidental secret leakage by
|
|
6
|
+
* setting one or both of:
|
|
7
|
+
*
|
|
8
|
+
* - `BLOK_NODE_ENV_ALLOW` — comma-separated exact names. Example:
|
|
9
|
+
* `BLOK_NODE_ENV_ALLOW=DATABASE_URL,STRIPE_KEY`
|
|
10
|
+
* - `BLOK_NODE_ENV_ALLOW_PREFIX` — comma-separated prefixes. Example:
|
|
11
|
+
* `BLOK_NODE_ENV_ALLOW_PREFIX=PUBLIC_,SAFE_`
|
|
12
|
+
*
|
|
13
|
+
* When EITHER is set, `ctx.env` becomes a Proxy that returns
|
|
14
|
+
* `undefined` for keys not in the allowlist and excludes them from
|
|
15
|
+
* `Object.keys`/`for...in`/`hasOwnProperty`. When NEITHER is set,
|
|
16
|
+
* `ctx.env` is `process.env` directly (preserves v0.4.x semantics —
|
|
17
|
+
* no breaking change).
|
|
18
|
+
*
|
|
19
|
+
* Set `BLOK_SUPPRESS_ENV_ALLOW_WARNING=1` to silence the boot warning
|
|
20
|
+
* that fires when `BLOK_ENV=production` and no allowlist is configured.
|
|
21
|
+
*
|
|
22
|
+
* The allowlist is parsed on every `getEnvForCtx()` call (creating a
|
|
23
|
+
* Context). Cost is sub-microsecond — strings are small and the
|
|
24
|
+
* Proxy is allocated once per request. Tests can mutate
|
|
25
|
+
* `process.env.BLOK_NODE_ENV_ALLOW` between calls and see the change
|
|
26
|
+
* immediately (no module-load caching).
|
|
27
|
+
*/
|
|
28
|
+
function parseList(raw) {
|
|
29
|
+
if (!raw)
|
|
30
|
+
return [];
|
|
31
|
+
return raw
|
|
32
|
+
.split(",")
|
|
33
|
+
.map((s) => s.trim())
|
|
34
|
+
.filter((s) => s.length > 0);
|
|
35
|
+
}
|
|
36
|
+
function loadConfig() {
|
|
37
|
+
const allow = parseList(process.env.BLOK_NODE_ENV_ALLOW);
|
|
38
|
+
const prefixes = parseList(process.env.BLOK_NODE_ENV_ALLOW_PREFIX);
|
|
39
|
+
if (allow.length === 0 && prefixes.length === 0)
|
|
40
|
+
return null;
|
|
41
|
+
return { allow, prefixes };
|
|
42
|
+
}
|
|
43
|
+
function isAllowed(key, config) {
|
|
44
|
+
if (config.allow.includes(key))
|
|
45
|
+
return true;
|
|
46
|
+
for (const p of config.prefixes) {
|
|
47
|
+
if (key.startsWith(p))
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Build a Proxy around `process.env` that hides keys not in the
|
|
54
|
+
* allowlist. Reads of denied keys return `undefined`; iteration via
|
|
55
|
+
* `Object.keys` / `for...in` / `Object.entries` excludes them; `key
|
|
56
|
+
* in env` returns `false`. Writes pass through (operators don't lose
|
|
57
|
+
* the ability for nodes to mutate process.env if they want to — the
|
|
58
|
+
* filter is a read gate, not a sandbox).
|
|
59
|
+
*/
|
|
60
|
+
function buildProxy(config) {
|
|
61
|
+
return new Proxy(process.env, {
|
|
62
|
+
get(target, key) {
|
|
63
|
+
if (typeof key !== "string")
|
|
64
|
+
return undefined;
|
|
65
|
+
return isAllowed(key, config) ? target[key] : undefined;
|
|
66
|
+
},
|
|
67
|
+
has(target, key) {
|
|
68
|
+
if (typeof key !== "string")
|
|
69
|
+
return false;
|
|
70
|
+
return isAllowed(key, config) && key in target;
|
|
71
|
+
},
|
|
72
|
+
ownKeys(target) {
|
|
73
|
+
return Object.keys(target).filter((k) => isAllowed(k, config));
|
|
74
|
+
},
|
|
75
|
+
getOwnPropertyDescriptor(target, key) {
|
|
76
|
+
if (typeof key !== "string" || !isAllowed(key, config))
|
|
77
|
+
return undefined;
|
|
78
|
+
return Object.getOwnPropertyDescriptor(target, key);
|
|
79
|
+
},
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
let productionWarningEmitted = false;
|
|
83
|
+
function emitProductionWarning() {
|
|
84
|
+
if (productionWarningEmitted)
|
|
85
|
+
return;
|
|
86
|
+
productionWarningEmitted = true;
|
|
87
|
+
if (process.env.BLOK_SUPPRESS_ENV_ALLOW_WARNING === "1")
|
|
88
|
+
return;
|
|
89
|
+
if (process.env.BLOK_ENV !== "production")
|
|
90
|
+
return;
|
|
91
|
+
console.warn("[blok] BLOK_ENV=production but neither BLOK_NODE_ENV_ALLOW nor BLOK_NODE_ENV_ALLOW_PREFIX is set. " +
|
|
92
|
+
"Every loaded node sees every env var, including secrets. " +
|
|
93
|
+
"Configure an allowlist to harden the surface, or set " +
|
|
94
|
+
"BLOK_SUPPRESS_ENV_ALLOW_WARNING=1 to silence.");
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Returns the object to assign to `ctx.env`. When no allowlist is
|
|
98
|
+
* configured, returns `process.env` (default-allow). When configured,
|
|
99
|
+
* returns a filtering Proxy. Called by `TriggerBase.createContext`.
|
|
100
|
+
*/
|
|
101
|
+
export function getEnvForCtx() {
|
|
102
|
+
const config = loadConfig();
|
|
103
|
+
if (!config) {
|
|
104
|
+
emitProductionWarning();
|
|
105
|
+
return process.env;
|
|
106
|
+
}
|
|
107
|
+
return buildProxy(config);
|
|
108
|
+
}
|
|
109
|
+
/** Test-only — clears the once-per-process production warning flag. */
|
|
110
|
+
export function _resetEnvAllowlistForTests() {
|
|
111
|
+
productionWarningEmitted = false;
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=envAllowlist.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"envAllowlist.js","sourceRoot":"","sources":["../../src/utils/envAllowlist.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RuntimeVersionValidator — Validates node and workflow runtime version requirements.
|
|
3
|
+
*
|
|
4
|
+
* Used by the runner to check that nodes' `runtimeRequirements` are satisfied
|
|
5
|
+
* by the currently running runtime versions before executing workflows.
|
|
6
|
+
*/
|
|
7
|
+
export interface VersionValidationResult {
|
|
8
|
+
valid: boolean;
|
|
9
|
+
node: string;
|
|
10
|
+
runtime: string;
|
|
11
|
+
required: string;
|
|
12
|
+
actual: string | undefined;
|
|
13
|
+
message: string;
|
|
14
|
+
}
|
|
15
|
+
export declare class RuntimeVersionValidator {
|
|
16
|
+
private runtimeVersions;
|
|
17
|
+
constructor(runtimeVersions?: Record<string, string>);
|
|
18
|
+
setRuntimeVersion(kind: string, version: string): void;
|
|
19
|
+
getRuntimeVersion(kind: string): string | undefined;
|
|
20
|
+
/**
|
|
21
|
+
* Validate a single node's runtime requirements against known runtime versions.
|
|
22
|
+
*/
|
|
23
|
+
validateNode(node: {
|
|
24
|
+
name: string;
|
|
25
|
+
runtimeRequirements?: Partial<Record<string, string>>;
|
|
26
|
+
}): VersionValidationResult[];
|
|
27
|
+
/**
|
|
28
|
+
* Validate all nodes in a workflow against known runtime versions.
|
|
29
|
+
*/
|
|
30
|
+
validateWorkflow(nodes: Array<{
|
|
31
|
+
name: string;
|
|
32
|
+
runtimeRequirements?: Partial<Record<string, string>>;
|
|
33
|
+
}>): VersionValidationResult[];
|
|
34
|
+
/**
|
|
35
|
+
* Format validation errors into a user-friendly multi-line string.
|
|
36
|
+
*/
|
|
37
|
+
static formatErrors(results: VersionValidationResult[]): string;
|
|
38
|
+
}
|