@adonis-agora/durable 0.1.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/LICENSE +21 -0
- package/README.md +29 -0
- package/dist/assets/dashboard.html +446 -0
- package/dist/commands/main.d.ts +15 -0
- package/dist/commands/main.d.ts.map +1 -0
- package/dist/commands/main.js +15 -0
- package/dist/commands/main.js.map +1 -0
- package/dist/commands/retry.d.ts +16 -0
- package/dist/commands/retry.d.ts.map +1 -0
- package/dist/commands/retry.js +34 -0
- package/dist/commands/retry.js.map +1 -0
- package/dist/commands/runs.d.ts +17 -0
- package/dist/commands/runs.d.ts.map +1 -0
- package/dist/commands/runs.js +40 -0
- package/dist/commands/runs.js.map +1 -0
- package/dist/commands/work.d.ts +18 -0
- package/dist/commands/work.d.ts.map +1 -0
- package/dist/commands/work.js +58 -0
- package/dist/commands/work.js.map +1 -0
- package/dist/configure.d.ts +15 -0
- package/dist/configure.d.ts.map +1 -0
- package/dist/configure.js +26 -0
- package/dist/configure.js.map +1 -0
- package/dist/providers/dashboard_provider.d.ts +27 -0
- package/dist/providers/dashboard_provider.d.ts.map +1 -0
- package/dist/providers/dashboard_provider.js +94 -0
- package/dist/providers/dashboard_provider.js.map +1 -0
- package/dist/providers/durable_provider.d.ts +36 -0
- package/dist/providers/durable_provider.d.ts.map +1 -0
- package/dist/providers/durable_provider.js +113 -0
- package/dist/providers/durable_provider.js.map +1 -0
- package/dist/src/admission-redis/index.d.ts +2 -0
- package/dist/src/admission-redis/index.d.ts.map +1 -0
- package/dist/src/admission-redis/index.js +2 -0
- package/dist/src/admission-redis/index.js.map +1 -0
- package/dist/src/admission-redis/redis-admission-backend.d.ts +83 -0
- package/dist/src/admission-redis/redis-admission-backend.d.ts.map +1 -0
- package/dist/src/admission-redis/redis-admission-backend.js +200 -0
- package/dist/src/admission-redis/redis-admission-backend.js.map +1 -0
- package/dist/src/admission.d.ts +49 -0
- package/dist/src/admission.d.ts.map +1 -0
- package/dist/src/admission.js +30 -0
- package/dist/src/admission.js.map +1 -0
- package/dist/src/backoff.d.ts +5 -0
- package/dist/src/backoff.d.ts.map +1 -0
- package/dist/src/backoff.js +11 -0
- package/dist/src/backoff.js.map +1 -0
- package/dist/src/checkpoints.d.ts +42 -0
- package/dist/src/checkpoints.d.ts.map +1 -0
- package/dist/src/checkpoints.js +57 -0
- package/dist/src/checkpoints.js.map +1 -0
- package/dist/src/codec-state-store.d.ts +60 -0
- package/dist/src/codec-state-store.d.ts.map +1 -0
- package/dist/src/codec-state-store.js +129 -0
- package/dist/src/codec-state-store.js.map +1 -0
- package/dist/src/commands/index.d.ts +3 -0
- package/dist/src/commands/index.d.ts.map +1 -0
- package/dist/src/commands/index.js +3 -0
- package/dist/src/commands/index.js.map +1 -0
- package/dist/src/commands/runs.d.ts +24 -0
- package/dist/src/commands/runs.d.ts.map +1 -0
- package/dist/src/commands/runs.js +39 -0
- package/dist/src/commands/runs.js.map +1 -0
- package/dist/src/commands/worker.d.ts +61 -0
- package/dist/src/commands/worker.d.ts.map +1 -0
- package/dist/src/commands/worker.js +74 -0
- package/dist/src/commands/worker.js.map +1 -0
- package/dist/src/completion.d.ts +15 -0
- package/dist/src/completion.d.ts.map +1 -0
- package/dist/src/completion.js +10 -0
- package/dist/src/completion.js.map +1 -0
- package/dist/src/dashboard/define_config.d.ts +48 -0
- package/dist/src/dashboard/define_config.d.ts.map +1 -0
- package/dist/src/dashboard/define_config.js +57 -0
- package/dist/src/dashboard/define_config.js.map +1 -0
- package/dist/src/dashboard/handlers.d.ts +47 -0
- package/dist/src/dashboard/handlers.d.ts.map +1 -0
- package/dist/src/dashboard/handlers.js +163 -0
- package/dist/src/dashboard/handlers.js.map +1 -0
- package/dist/src/dashboard/html.d.ts +7 -0
- package/dist/src/dashboard/html.d.ts.map +1 -0
- package/dist/src/dashboard/html.js +24 -0
- package/dist/src/dashboard/html.js.map +1 -0
- package/dist/src/dashboard/index.d.ts +8 -0
- package/dist/src/dashboard/index.d.ts.map +1 -0
- package/dist/src/dashboard/index.js +6 -0
- package/dist/src/dashboard/index.js.map +1 -0
- package/dist/src/define_config.d.ts +72 -0
- package/dist/src/define_config.d.ts.map +1 -0
- package/dist/src/define_config.js +8 -0
- package/dist/src/define_config.js.map +1 -0
- package/dist/src/diagnostics-bridge.d.ts +22 -0
- package/dist/src/diagnostics-bridge.d.ts.map +1 -0
- package/dist/src/diagnostics-bridge.js +25 -0
- package/dist/src/diagnostics-bridge.js.map +1 -0
- package/dist/src/duration.d.ts +6 -0
- package/dist/src/duration.d.ts.map +1 -0
- package/dist/src/duration.js +39 -0
- package/dist/src/duration.js.map +1 -0
- package/dist/src/engine.d.ts +583 -0
- package/dist/src/engine.d.ts.map +1 -0
- package/dist/src/engine.js +1894 -0
- package/dist/src/engine.js.map +1 -0
- package/dist/src/entities.d.ts +44 -0
- package/dist/src/entities.d.ts.map +1 -0
- package/dist/src/entities.js +64 -0
- package/dist/src/entities.js.map +1 -0
- package/dist/src/errors.d.ts +68 -0
- package/dist/src/errors.d.ts.map +1 -0
- package/dist/src/errors.js +102 -0
- package/dist/src/errors.js.map +1 -0
- package/dist/src/event-accumulators.d.ts +39 -0
- package/dist/src/event-accumulators.d.ts.map +1 -0
- package/dist/src/event-accumulators.js +70 -0
- package/dist/src/event-accumulators.js.map +1 -0
- package/dist/src/events.d.ts +9 -0
- package/dist/src/events.d.ts.map +1 -0
- package/dist/src/events.js +35 -0
- package/dist/src/events.js.map +1 -0
- package/dist/src/index.d.ts +36 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +37 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/interfaces.d.ts +909 -0
- package/dist/src/interfaces.d.ts.map +1 -0
- package/dist/src/interfaces.js +2 -0
- package/dist/src/interfaces.js.map +1 -0
- package/dist/src/metrics.d.ts +44 -0
- package/dist/src/metrics.d.ts.map +1 -0
- package/dist/src/metrics.js +78 -0
- package/dist/src/metrics.js.map +1 -0
- package/dist/src/otel/durable-metrics.d.ts +42 -0
- package/dist/src/otel/durable-metrics.d.ts.map +1 -0
- package/dist/src/otel/durable-metrics.js +75 -0
- package/dist/src/otel/durable-metrics.js.map +1 -0
- package/dist/src/otel/durable-otel.d.ts +20 -0
- package/dist/src/otel/durable-otel.d.ts.map +1 -0
- package/dist/src/otel/durable-otel.js +74 -0
- package/dist/src/otel/durable-otel.js.map +1 -0
- package/dist/src/otel/index.d.ts +4 -0
- package/dist/src/otel/index.d.ts.map +1 -0
- package/dist/src/otel/index.js +4 -0
- package/dist/src/otel/index.js.map +1 -0
- package/dist/src/otel/traceparent.d.ts +17 -0
- package/dist/src/otel/traceparent.d.ts.map +1 -0
- package/dist/src/otel/traceparent.js +21 -0
- package/dist/src/otel/traceparent.js.map +1 -0
- package/dist/src/pollers.d.ts +33 -0
- package/dist/src/pollers.d.ts.map +1 -0
- package/dist/src/pollers.js +76 -0
- package/dist/src/pollers.js.map +1 -0
- package/dist/src/protocol.d.ts +17 -0
- package/dist/src/protocol.d.ts.map +1 -0
- package/dist/src/protocol.js +47 -0
- package/dist/src/protocol.js.map +1 -0
- package/dist/src/queue.d.ts +113 -0
- package/dist/src/queue.d.ts.map +1 -0
- package/dist/src/queue.js +128 -0
- package/dist/src/queue.js.map +1 -0
- package/dist/src/remote-step-factory.d.ts +15 -0
- package/dist/src/remote-step-factory.d.ts.map +1 -0
- package/dist/src/remote-step-factory.js +12 -0
- package/dist/src/remote-step-factory.js.map +1 -0
- package/dist/src/remote-workflow-executor.d.ts +24 -0
- package/dist/src/remote-workflow-executor.d.ts.map +1 -0
- package/dist/src/remote-workflow-executor.js +70 -0
- package/dist/src/remote-workflow-executor.js.map +1 -0
- package/dist/src/scheduler.d.ts +67 -0
- package/dist/src/scheduler.d.ts.map +1 -0
- package/dist/src/scheduler.js +111 -0
- package/dist/src/scheduler.js.map +1 -0
- package/dist/src/search-attributes.d.ts +48 -0
- package/dist/src/search-attributes.d.ts.map +1 -0
- package/dist/src/search-attributes.js +98 -0
- package/dist/src/search-attributes.js.map +1 -0
- package/dist/src/singleton-gate.d.ts +44 -0
- package/dist/src/singleton-gate.d.ts.map +1 -0
- package/dist/src/singleton-gate.js +90 -0
- package/dist/src/singleton-gate.js.map +1 -0
- package/dist/src/step-logger.d.ts +9 -0
- package/dist/src/step-logger.d.ts.map +1 -0
- package/dist/src/step-logger.js +89 -0
- package/dist/src/step-logger.js.map +1 -0
- package/dist/src/stores/factory.d.ts +42 -0
- package/dist/src/stores/factory.d.ts.map +1 -0
- package/dist/src/stores/factory.js +29 -0
- package/dist/src/stores/factory.js.map +1 -0
- package/dist/src/stores/lucid-helpers.d.ts +11 -0
- package/dist/src/stores/lucid-helpers.d.ts.map +1 -0
- package/dist/src/stores/lucid-helpers.js +38 -0
- package/dist/src/stores/lucid-helpers.js.map +1 -0
- package/dist/src/stores/lucid-mappers.d.ts +58 -0
- package/dist/src/stores/lucid-mappers.d.ts.map +1 -0
- package/dist/src/stores/lucid-mappers.js +174 -0
- package/dist/src/stores/lucid-mappers.js.map +1 -0
- package/dist/src/stores/lucid-schema.d.ts +28 -0
- package/dist/src/stores/lucid-schema.d.ts.map +1 -0
- package/dist/src/stores/lucid-schema.js +115 -0
- package/dist/src/stores/lucid-schema.js.map +1 -0
- package/dist/src/stores/lucid.d.ts +69 -0
- package/dist/src/stores/lucid.d.ts.map +1 -0
- package/dist/src/stores/lucid.js +342 -0
- package/dist/src/stores/lucid.js.map +1 -0
- package/dist/src/telescope/dashboard.d.ts +15 -0
- package/dist/src/telescope/dashboard.d.ts.map +1 -0
- package/dist/src/telescope/dashboard.js +113 -0
- package/dist/src/telescope/dashboard.js.map +1 -0
- package/dist/src/telescope/data-providers.d.ts +20 -0
- package/dist/src/telescope/data-providers.d.ts.map +1 -0
- package/dist/src/telescope/data-providers.js +322 -0
- package/dist/src/telescope/data-providers.js.map +1 -0
- package/dist/src/telescope/extension.d.ts +22 -0
- package/dist/src/telescope/extension.d.ts.map +1 -0
- package/dist/src/telescope/extension.js +38 -0
- package/dist/src/telescope/extension.js.map +1 -0
- package/dist/src/telescope/index.d.ts +5 -0
- package/dist/src/telescope/index.d.ts.map +1 -0
- package/dist/src/telescope/index.js +4 -0
- package/dist/src/telescope/index.js.map +1 -0
- package/dist/src/telescope/telescope-sdk.d.ts +123 -0
- package/dist/src/telescope/telescope-sdk.d.ts.map +1 -0
- package/dist/src/telescope/telescope-sdk.js +12 -0
- package/dist/src/telescope/telescope-sdk.js.map +1 -0
- package/dist/src/test-helpers.d.ts +11 -0
- package/dist/src/test-helpers.d.ts.map +1 -0
- package/dist/src/test-helpers.js +12 -0
- package/dist/src/test-helpers.js.map +1 -0
- package/dist/src/testing/in-memory-state-store.d.ts +64 -0
- package/dist/src/testing/in-memory-state-store.d.ts.map +1 -0
- package/dist/src/testing/in-memory-state-store.js +259 -0
- package/dist/src/testing/in-memory-state-store.js.map +1 -0
- package/dist/src/testing/in-memory-transport.d.ts +25 -0
- package/dist/src/testing/in-memory-transport.d.ts.map +1 -0
- package/dist/src/testing/in-memory-transport.js +49 -0
- package/dist/src/testing/in-memory-transport.js.map +1 -0
- package/dist/src/testing-kit/admission-backend-conformance.d.ts +18 -0
- package/dist/src/testing-kit/admission-backend-conformance.d.ts.map +1 -0
- package/dist/src/testing-kit/admission-backend-conformance.js +81 -0
- package/dist/src/testing-kit/admission-backend-conformance.js.map +1 -0
- package/dist/src/testing-kit/assertions.d.ts +10 -0
- package/dist/src/testing-kit/assertions.d.ts.map +1 -0
- package/dist/src/testing-kit/assertions.js +41 -0
- package/dist/src/testing-kit/assertions.js.map +1 -0
- package/dist/src/testing-kit/harness.d.ts +28 -0
- package/dist/src/testing-kit/harness.d.ts.map +1 -0
- package/dist/src/testing-kit/harness.js +42 -0
- package/dist/src/testing-kit/harness.js.map +1 -0
- package/dist/src/testing-kit/index.d.ts +8 -0
- package/dist/src/testing-kit/index.d.ts.map +1 -0
- package/dist/src/testing-kit/index.js +8 -0
- package/dist/src/testing-kit/index.js.map +1 -0
- package/dist/src/testing-kit/replay.d.ts +22 -0
- package/dist/src/testing-kit/replay.d.ts.map +1 -0
- package/dist/src/testing-kit/replay.js +38 -0
- package/dist/src/testing-kit/replay.js.map +1 -0
- package/dist/src/testing-kit/state-store-conformance.d.ts +51 -0
- package/dist/src/testing-kit/state-store-conformance.d.ts.map +1 -0
- package/dist/src/testing-kit/state-store-conformance.js +430 -0
- package/dist/src/testing-kit/state-store-conformance.js.map +1 -0
- package/dist/src/testing-kit/steps.d.ts +5 -0
- package/dist/src/testing-kit/steps.d.ts.map +1 -0
- package/dist/src/testing-kit/steps.js +15 -0
- package/dist/src/testing-kit/steps.js.map +1 -0
- package/dist/src/testing-kit/transport-conformance.d.ts +16 -0
- package/dist/src/testing-kit/transport-conformance.d.ts.map +1 -0
- package/dist/src/testing-kit/transport-conformance.js +64 -0
- package/dist/src/testing-kit/transport-conformance.js.map +1 -0
- package/dist/src/tokens.d.ts +18 -0
- package/dist/src/tokens.d.ts.map +1 -0
- package/dist/src/tokens.js +18 -0
- package/dist/src/tokens.js.map +1 -0
- package/dist/src/transport-pool.d.ts +30 -0
- package/dist/src/transport-pool.d.ts.map +1 -0
- package/dist/src/transport-pool.js +82 -0
- package/dist/src/transport-pool.js.map +1 -0
- package/dist/src/transports/db-helpers.d.ts +10 -0
- package/dist/src/transports/db-helpers.d.ts.map +1 -0
- package/dist/src/transports/db-helpers.js +33 -0
- package/dist/src/transports/db-helpers.js.map +1 -0
- package/dist/src/transports/db-schema.d.ts +28 -0
- package/dist/src/transports/db-schema.d.ts.map +1 -0
- package/dist/src/transports/db-schema.js +98 -0
- package/dist/src/transports/db-schema.js.map +1 -0
- package/dist/src/transports/db.d.ts +81 -0
- package/dist/src/transports/db.d.ts.map +1 -0
- package/dist/src/transports/db.js +340 -0
- package/dist/src/transports/db.js.map +1 -0
- package/dist/src/transports/factory.d.ts +79 -0
- package/dist/src/transports/factory.d.ts.map +1 -0
- package/dist/src/transports/factory.js +57 -0
- package/dist/src/transports/factory.js.map +1 -0
- package/dist/src/transports/queue-mock-adapter.d.ts +39 -0
- package/dist/src/transports/queue-mock-adapter.d.ts.map +1 -0
- package/dist/src/transports/queue-mock-adapter.js +86 -0
- package/dist/src/transports/queue-mock-adapter.js.map +1 -0
- package/dist/src/transports/queue.d.ts +84 -0
- package/dist/src/transports/queue.d.ts.map +1 -0
- package/dist/src/transports/queue.js +210 -0
- package/dist/src/transports/queue.js.map +1 -0
- package/dist/src/workflow-ctx.d.ts +64 -0
- package/dist/src/workflow-ctx.d.ts.map +1 -0
- package/dist/src/workflow-ctx.js +457 -0
- package/dist/src/workflow-ctx.js.map +1 -0
- package/dist/src/workflow-ref.d.ts +34 -0
- package/dist/src/workflow-ref.d.ts.map +1 -0
- package/dist/src/workflow-ref.js +28 -0
- package/dist/src/workflow-ref.js.map +1 -0
- package/dist/stubs/config/durable.stub +49 -0
- package/dist/stubs/config/durable_dashboard.stub +17 -0
- package/dist/stubs/database/migrations/create_durable_tables.stub +87 -0
- package/dist/stubs/database/migrations/create_durable_transport_tables.stub +75 -0
- package/dist/stubs/main.d.ts +3 -0
- package/dist/stubs/main.d.ts.map +1 -0
- package/dist/stubs/main.js +4 -0
- package/dist/stubs/main.js.map +1 -0
- package/package.json +154 -0
|
@@ -0,0 +1,342 @@
|
|
|
1
|
+
import { attributeColumnFor, attributeOperand, normalizeAttributeRows, sqlComparator, } from '../search-attributes.js';
|
|
2
|
+
import { checkpointToRow, rowToCheckpoint, rowToRun, runPatchToRow, runToRow, } from './lucid-mappers.js';
|
|
3
|
+
import { DURABLE_TABLES, createDurableTables } from './lucid-schema.js';
|
|
4
|
+
/**
|
|
5
|
+
* A production-grade, persistent `StateStore` backed by AdonisJS **Lucid** (Knex). Runs, checkpoints,
|
|
6
|
+
* timers, signal waiters, run attributes and recovery leases live in SQL, so durable state survives
|
|
7
|
+
* restarts and works across processes — the behavioral twin of core's `InMemoryStateStore`.
|
|
8
|
+
*
|
|
9
|
+
* Portable across SQLite / Postgres / MySQL: JSON payloads are stored as TEXT (serialized here) and
|
|
10
|
+
* all timestamps are epoch-ms integers, so there's no dependency on a dialect's native JSON/date type.
|
|
11
|
+
*
|
|
12
|
+
* Usually you don't construct this directly: `config/durable.ts` selects it via
|
|
13
|
+
* `stores.lucid({ ... })` and the provider builds it for you.
|
|
14
|
+
*/
|
|
15
|
+
export class LucidStateStore {
|
|
16
|
+
db;
|
|
17
|
+
connectionName;
|
|
18
|
+
constructor(db, options = {}) {
|
|
19
|
+
this.db = db;
|
|
20
|
+
this.connectionName = options.connectionName;
|
|
21
|
+
}
|
|
22
|
+
/** The base query client (or a named connection's), used unless an explicit tx client is passed. */
|
|
23
|
+
client() {
|
|
24
|
+
return this.connectionName ? this.db.connection(this.connectionName) : this.db.connection();
|
|
25
|
+
}
|
|
26
|
+
/** Idempotently provision the durable tables (called on boot when `autoSchema` is on). */
|
|
27
|
+
async ensureSchema() {
|
|
28
|
+
await createDurableTables(this.db);
|
|
29
|
+
}
|
|
30
|
+
// --- runs ---------------------------------------------------------------
|
|
31
|
+
async createRun(run) {
|
|
32
|
+
await this.db.transaction(async (trx) => {
|
|
33
|
+
await trx.table(DURABLE_TABLES.runs).insert(runToRow(run));
|
|
34
|
+
await this.reindexAttributes(trx, run.id, run.searchAttributes);
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
async updateRun(runId, patch) {
|
|
38
|
+
const row = runPatchToRow(patch);
|
|
39
|
+
await this.db.transaction(async (trx) => {
|
|
40
|
+
// Knex throws on an empty `.update({})`; skip the UPDATE when no mapped column changed.
|
|
41
|
+
if (Object.keys(row).length) {
|
|
42
|
+
await trx.from(DURABLE_TABLES.runs).where('id', runId).update(row);
|
|
43
|
+
}
|
|
44
|
+
if ('searchAttributes' in patch) {
|
|
45
|
+
await this.reindexAttributes(trx, runId, patch.searchAttributes);
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
async getRun(runId) {
|
|
50
|
+
const row = await this.client().from(DURABLE_TABLES.runs).where('id', runId).first();
|
|
51
|
+
return row ? rowToRun(row) : null;
|
|
52
|
+
}
|
|
53
|
+
async deleteRun(runId) {
|
|
54
|
+
// Child rows first, then the run — checkpoints, signal waiters, attribute rows — all in one
|
|
55
|
+
// transaction so a crash can't leave a half-deleted run. (Buffered signals are token-keyed,
|
|
56
|
+
// not run-scoped, so they are not swept here.)
|
|
57
|
+
await this.client().transaction(async (trx) => {
|
|
58
|
+
await trx.from(DURABLE_TABLES.checkpoints).where('run_id', runId).delete();
|
|
59
|
+
await trx.from(DURABLE_TABLES.signalWaiters).where('run_id', runId).delete();
|
|
60
|
+
await trx.from(DURABLE_TABLES.attributes).where('run_id', runId).delete();
|
|
61
|
+
await trx.from(DURABLE_TABLES.runs).where('id', runId).delete();
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
// --- checkpoints --------------------------------------------------------
|
|
65
|
+
async getCheckpoint(runId, seq) {
|
|
66
|
+
const row = await this.client()
|
|
67
|
+
.from(DURABLE_TABLES.checkpoints)
|
|
68
|
+
.where('run_id', runId)
|
|
69
|
+
.andWhere('seq', seq)
|
|
70
|
+
.first();
|
|
71
|
+
return row ? rowToCheckpoint(row) : null;
|
|
72
|
+
}
|
|
73
|
+
async saveCheckpoint(checkpoint) {
|
|
74
|
+
await this.upsertCheckpoint(this.client(), checkpoint);
|
|
75
|
+
}
|
|
76
|
+
/** Upsert a checkpoint keyed by `(run_id, seq)`, portable across dialects (read-then-write in a tx). */
|
|
77
|
+
async upsertCheckpoint(client, checkpoint) {
|
|
78
|
+
const row = checkpointToRow(checkpoint);
|
|
79
|
+
const run = () => client.transaction(async (trx) => {
|
|
80
|
+
const existing = await trx
|
|
81
|
+
.from(DURABLE_TABLES.checkpoints)
|
|
82
|
+
.where('run_id', row.run_id)
|
|
83
|
+
.andWhere('seq', row.seq)
|
|
84
|
+
.first();
|
|
85
|
+
if (existing) {
|
|
86
|
+
await trx
|
|
87
|
+
.from(DURABLE_TABLES.checkpoints)
|
|
88
|
+
.where('run_id', row.run_id)
|
|
89
|
+
.andWhere('seq', row.seq)
|
|
90
|
+
.update(row);
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
await trx.table(DURABLE_TABLES.checkpoints).insert(row);
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
// If we're already inside a transaction client, reuse it (Lucid nests via savepoints); otherwise
|
|
97
|
+
// open one on the base client.
|
|
98
|
+
await run();
|
|
99
|
+
}
|
|
100
|
+
// --- recovery / dispatch queries ----------------------------------------
|
|
101
|
+
async listIncompleteRuns() {
|
|
102
|
+
const rows = await this.client().from(DURABLE_TABLES.runs).where('status', 'running');
|
|
103
|
+
return rows.map(rowToRun);
|
|
104
|
+
}
|
|
105
|
+
async listPendingRuns(limit) {
|
|
106
|
+
const rows = await this.client()
|
|
107
|
+
.from(DURABLE_TABLES.runs)
|
|
108
|
+
.where('status', 'pending')
|
|
109
|
+
.orderBy('created_at', 'asc') // FIFO dispatch
|
|
110
|
+
.orderBy('id', 'asc') // stable tiebreak, mirrors the in-memory store
|
|
111
|
+
.limit(limit);
|
|
112
|
+
return rows.map(rowToRun);
|
|
113
|
+
}
|
|
114
|
+
async listDueTimers(nowMs) {
|
|
115
|
+
const rows = await this.client()
|
|
116
|
+
.from(DURABLE_TABLES.runs)
|
|
117
|
+
.where('status', 'suspended')
|
|
118
|
+
.whereNotNull('wake_at')
|
|
119
|
+
.andWhere('wake_at', '<=', nowMs);
|
|
120
|
+
return rows.map(rowToRun);
|
|
121
|
+
}
|
|
122
|
+
// --- recovery lease (atomic) --------------------------------------------
|
|
123
|
+
async tryLockRun(runId, owner, leaseUntilMs, nowMs) {
|
|
124
|
+
// Atomic compare-and-set: acquire ONLY if currently unlocked or the lease has expired. The single
|
|
125
|
+
// conditional UPDATE is the concurrency guard — two instances racing can never both report `true`.
|
|
126
|
+
const affected = await this.client()
|
|
127
|
+
.from(DURABLE_TABLES.runs)
|
|
128
|
+
.where('id', runId)
|
|
129
|
+
.andWhere((q) => {
|
|
130
|
+
q.whereNull('locked_until').orWhere('locked_until', '<=', nowMs);
|
|
131
|
+
})
|
|
132
|
+
.update({ locked_by: owner, locked_until: leaseUntilMs });
|
|
133
|
+
return rowsAffected(affected) === 1;
|
|
134
|
+
}
|
|
135
|
+
async releaseRunLock(runId) {
|
|
136
|
+
await this.client()
|
|
137
|
+
.from(DURABLE_TABLES.runs)
|
|
138
|
+
.where('id', runId)
|
|
139
|
+
.update({ locked_by: null, locked_until: null });
|
|
140
|
+
}
|
|
141
|
+
async renewRunLock(runId, owner, leaseUntilMs) {
|
|
142
|
+
// Extend ONLY if `owner` still holds the lease — a dead worker's lease still expires & is reclaimed.
|
|
143
|
+
const affected = await this.client()
|
|
144
|
+
.from(DURABLE_TABLES.runs)
|
|
145
|
+
.where('id', runId)
|
|
146
|
+
.andWhere('locked_by', owner)
|
|
147
|
+
.update({ locked_until: leaseUntilMs });
|
|
148
|
+
return rowsAffected(affected) === 1;
|
|
149
|
+
}
|
|
150
|
+
// --- signal waiters -----------------------------------------------------
|
|
151
|
+
async putSignalWaiter(waiter) {
|
|
152
|
+
await this.client().transaction(async (trx) => {
|
|
153
|
+
const existing = await trx
|
|
154
|
+
.from(DURABLE_TABLES.signalWaiters)
|
|
155
|
+
.where('token', waiter.token)
|
|
156
|
+
.first();
|
|
157
|
+
if (existing) {
|
|
158
|
+
await trx
|
|
159
|
+
.from(DURABLE_TABLES.signalWaiters)
|
|
160
|
+
.where('token', waiter.token)
|
|
161
|
+
.update({ run_id: waiter.runId, seq: waiter.seq });
|
|
162
|
+
}
|
|
163
|
+
else {
|
|
164
|
+
await trx
|
|
165
|
+
.table(DURABLE_TABLES.signalWaiters)
|
|
166
|
+
.insert({ token: waiter.token, run_id: waiter.runId, seq: waiter.seq });
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
async takeSignalWaiter(token) {
|
|
171
|
+
// Atomically take-and-remove: delete by token, returning the row only if WE deleted it. Done in a
|
|
172
|
+
// transaction so a concurrent take can't hand the same waiter to two callers.
|
|
173
|
+
return this.client().transaction(async (trx) => {
|
|
174
|
+
const row = await trx.from(DURABLE_TABLES.signalWaiters).where('token', token).first();
|
|
175
|
+
if (!row)
|
|
176
|
+
return null;
|
|
177
|
+
const deleted = await trx.from(DURABLE_TABLES.signalWaiters).where('token', token).delete();
|
|
178
|
+
if (rowsAffected(deleted) !== 1)
|
|
179
|
+
return null;
|
|
180
|
+
const r = row;
|
|
181
|
+
return { token: r.token, runId: r.run_id, seq: Number(r.seq) };
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
async listSignalWaiters(prefix) {
|
|
185
|
+
const rows = await this.client()
|
|
186
|
+
.from(DURABLE_TABLES.signalWaiters)
|
|
187
|
+
.where('token', 'like', `${prefix}%`);
|
|
188
|
+
return rows.map((r) => ({
|
|
189
|
+
token: r.token,
|
|
190
|
+
runId: r.run_id,
|
|
191
|
+
seq: Number(r.seq),
|
|
192
|
+
}));
|
|
193
|
+
}
|
|
194
|
+
// --- buffered signals (FIFO per token) ----------------------------------
|
|
195
|
+
async bufferSignal(token, payload) {
|
|
196
|
+
await this.client()
|
|
197
|
+
.table(DURABLE_TABLES.bufferedSignals)
|
|
198
|
+
.insert({ token, payload: payload === undefined ? null : JSON.stringify(payload) });
|
|
199
|
+
}
|
|
200
|
+
async takeBufferedSignal(token) {
|
|
201
|
+
return this.client().transaction(async (trx) => {
|
|
202
|
+
const row = await trx
|
|
203
|
+
.from(DURABLE_TABLES.bufferedSignals)
|
|
204
|
+
.where('token', token)
|
|
205
|
+
.orderBy('id', 'asc')
|
|
206
|
+
.first();
|
|
207
|
+
if (!row)
|
|
208
|
+
return null;
|
|
209
|
+
const r = row;
|
|
210
|
+
const deleted = await trx.from(DURABLE_TABLES.bufferedSignals).where('id', r.id).delete();
|
|
211
|
+
if (rowsAffected(deleted) !== 1)
|
|
212
|
+
return null;
|
|
213
|
+
return { payload: r.payload == null ? undefined : JSON.parse(r.payload) };
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
// --- transaction (exactly-once business write + checkpoint) -------------
|
|
217
|
+
async transaction(work) {
|
|
218
|
+
return this.client().transaction(async (trx) => work({
|
|
219
|
+
raw: trx,
|
|
220
|
+
saveCheckpoint: async (cp) => {
|
|
221
|
+
const row = checkpointToRow(cp);
|
|
222
|
+
const existing = await trx
|
|
223
|
+
.from(DURABLE_TABLES.checkpoints)
|
|
224
|
+
.where('run_id', row.run_id)
|
|
225
|
+
.andWhere('seq', row.seq)
|
|
226
|
+
.first();
|
|
227
|
+
if (existing) {
|
|
228
|
+
await trx
|
|
229
|
+
.from(DURABLE_TABLES.checkpoints)
|
|
230
|
+
.where('run_id', row.run_id)
|
|
231
|
+
.andWhere('seq', row.seq)
|
|
232
|
+
.update(row);
|
|
233
|
+
}
|
|
234
|
+
else {
|
|
235
|
+
await trx.table(DURABLE_TABLES.checkpoints).insert(row);
|
|
236
|
+
}
|
|
237
|
+
},
|
|
238
|
+
}));
|
|
239
|
+
}
|
|
240
|
+
// --- dashboard queries --------------------------------------------------
|
|
241
|
+
async listRuns(query) {
|
|
242
|
+
const q = this.client().from(DURABLE_TABLES.runs);
|
|
243
|
+
if (query.workflow)
|
|
244
|
+
q.where('workflow', query.workflow);
|
|
245
|
+
if (query.status)
|
|
246
|
+
q.where('status', query.status);
|
|
247
|
+
if (query.statuses) {
|
|
248
|
+
// `status IN (...)`; an empty set matches nothing (mirrors the in-memory store).
|
|
249
|
+
if (query.statuses.length)
|
|
250
|
+
q.whereIn('status', query.statuses);
|
|
251
|
+
else
|
|
252
|
+
q.whereRaw('1 = 0');
|
|
253
|
+
}
|
|
254
|
+
// `tags` is stored as a JSON array string; match the quoted token so `etl` doesn't match `etl-foo`.
|
|
255
|
+
if (query.tag)
|
|
256
|
+
q.where('tags', 'like', `%"${query.tag}"%`);
|
|
257
|
+
// Typed/range attribute predicates push DOWN into SQL via one EXISTS per filter against the
|
|
258
|
+
// normalized side-table — so the DB filters AND paginates, no full scan + in-process filter.
|
|
259
|
+
if (query.attributes?.length) {
|
|
260
|
+
for (const f of query.attributes)
|
|
261
|
+
this.applyAttributeExists(q, f);
|
|
262
|
+
}
|
|
263
|
+
q.orderBy('created_at', 'desc'); // newest first — recent runs on top in the dashboard
|
|
264
|
+
if (query.limit !== undefined)
|
|
265
|
+
q.limit(query.limit);
|
|
266
|
+
if (query.offset !== undefined)
|
|
267
|
+
q.offset(query.offset);
|
|
268
|
+
const rows = await q;
|
|
269
|
+
return rows.map(rowToRun);
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* Add one attribute predicate as a correlated EXISTS subquery on the side-table. `<>` (ne) also
|
|
273
|
+
* excludes runs where the attribute is absent (the missing-key-never-matches contract): EXISTS
|
|
274
|
+
* already requires the key row present, so EXISTS(... <> ...) is exactly ne-with-present. Numeric
|
|
275
|
+
* operands compare `num_value`, everything else `str_value`.
|
|
276
|
+
*/
|
|
277
|
+
applyAttributeExists(q, f) {
|
|
278
|
+
const col = attributeColumnFor(f) === 'numValue' ? 'num_value' : 'str_value';
|
|
279
|
+
const cmp = sqlComparator(f.op);
|
|
280
|
+
const operand = attributeOperand(f);
|
|
281
|
+
q.whereExists((sub) => {
|
|
282
|
+
sub
|
|
283
|
+
.from(DURABLE_TABLES.attributes)
|
|
284
|
+
.whereRaw(`${DURABLE_TABLES.attributes}.run_id = ${DURABLE_TABLES.runs}.id`)
|
|
285
|
+
.andWhere(`${DURABLE_TABLES.attributes}.key`, f.key)
|
|
286
|
+
.andWhere(`${DURABLE_TABLES.attributes}.${col}`, cmp, operand);
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
async listCheckpoints(runId) {
|
|
290
|
+
const rows = await this.client()
|
|
291
|
+
.from(DURABLE_TABLES.checkpoints)
|
|
292
|
+
.where('run_id', runId)
|
|
293
|
+
.orderBy('seq', 'asc');
|
|
294
|
+
return rows.map(rowToCheckpoint);
|
|
295
|
+
}
|
|
296
|
+
async getLatestCheckpointByName(runId, name) {
|
|
297
|
+
const row = await this.client()
|
|
298
|
+
.from(DURABLE_TABLES.checkpoints)
|
|
299
|
+
.where('run_id', runId)
|
|
300
|
+
.andWhere('name', name)
|
|
301
|
+
.orderBy('seq', 'desc')
|
|
302
|
+
.first();
|
|
303
|
+
return row ? rowToCheckpoint(row) : undefined;
|
|
304
|
+
}
|
|
305
|
+
async listCheckpointsByNamePrefix(runId, prefixes) {
|
|
306
|
+
if (prefixes.length === 0)
|
|
307
|
+
return [];
|
|
308
|
+
const rows = await this.client()
|
|
309
|
+
.from(DURABLE_TABLES.checkpoints)
|
|
310
|
+
.where('run_id', runId)
|
|
311
|
+
.andWhere((q) => {
|
|
312
|
+
for (const p of prefixes)
|
|
313
|
+
q.orWhere('name', 'like', `${p}%`);
|
|
314
|
+
})
|
|
315
|
+
.orderBy('seq', 'asc');
|
|
316
|
+
return rows.map(rowToCheckpoint);
|
|
317
|
+
}
|
|
318
|
+
// --- internals ----------------------------------------------------------
|
|
319
|
+
/** Rewrite a run's normalized attribute rows: delete the old set, insert the current one. Mirrors
|
|
320
|
+
* the in-memory store's reindex so the side-table always reflects the run's live searchAttributes. */
|
|
321
|
+
async reindexAttributes(client, runId, attributes) {
|
|
322
|
+
await client.from(DURABLE_TABLES.attributes).where('run_id', runId).delete();
|
|
323
|
+
const rows = normalizeAttributeRows(runId, attributes);
|
|
324
|
+
if (rows.length) {
|
|
325
|
+
await client.table(DURABLE_TABLES.attributes).multiInsert(rows.map((r) => ({
|
|
326
|
+
run_id: r.runId,
|
|
327
|
+
key: r.key,
|
|
328
|
+
str_value: r.strValue,
|
|
329
|
+
num_value: r.numValue,
|
|
330
|
+
})));
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
/** Knex `.update()` / `.delete()` return the affected row count as a number across dialects. */
|
|
335
|
+
function rowsAffected(result) {
|
|
336
|
+
if (typeof result === 'number')
|
|
337
|
+
return result;
|
|
338
|
+
if (Array.isArray(result))
|
|
339
|
+
return result.length;
|
|
340
|
+
return 0;
|
|
341
|
+
}
|
|
342
|
+
//# sourceMappingURL=lucid.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lucid.js","sourceRoot":"","sources":["../../../src/stores/lucid.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { DashboardSpec } from './telescope-sdk.js';
|
|
2
|
+
/** Options for the durable "Workflows" dashboard. */
|
|
3
|
+
export interface DurableDashboardOptions {
|
|
4
|
+
/** URL template for deep-linking a run to the durable dashboard. Default `/durable/runs/{runId}`. */
|
|
5
|
+
runHref?: string;
|
|
6
|
+
/** Window (ms) bounding the "Stuck runs" table. Default 24h; pass `0` to show all. */
|
|
7
|
+
recentFailuresWindowMs?: number;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* The "Workflows" health dashboard — a golden-signals layout (success rate / latency / backlog /
|
|
11
|
+
* throughput up top, then what-needs-attention, then trends). Pure data: panels bind to the
|
|
12
|
+
* `durable.*` data providers by name.
|
|
13
|
+
*/
|
|
14
|
+
export declare function durableDashboard(opts?: DurableDashboardOptions): DashboardSpec;
|
|
15
|
+
//# sourceMappingURL=dashboard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dashboard.d.ts","sourceRoot":"","sources":["../../../src/telescope/dashboard.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAExD,qDAAqD;AACrD,MAAM,WAAW,uBAAuB;IACtC,qGAAqG;IACrG,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,sFAAsF;IACtF,sBAAsB,CAAC,EAAE,MAAM,CAAC;CACjC;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,GAAE,uBAA4B,GAAG,aAAa,CA0GlF"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The "Workflows" health dashboard — a golden-signals layout (success rate / latency / backlog /
|
|
3
|
+
* throughput up top, then what-needs-attention, then trends). Pure data: panels bind to the
|
|
4
|
+
* `durable.*` data providers by name.
|
|
5
|
+
*/
|
|
6
|
+
export function durableDashboard(opts = {}) {
|
|
7
|
+
const runHref = opts.runHref ?? '/durable/runs/{runId}';
|
|
8
|
+
const windowMs = opts.recentFailuresWindowMs ?? 24 * 60 * 60 * 1000;
|
|
9
|
+
return {
|
|
10
|
+
id: 'durable.workflows',
|
|
11
|
+
label: 'Workflows',
|
|
12
|
+
panels: [],
|
|
13
|
+
sections: [
|
|
14
|
+
{
|
|
15
|
+
title: 'Health',
|
|
16
|
+
cols: 4,
|
|
17
|
+
panels: [
|
|
18
|
+
{
|
|
19
|
+
kind: 'gauge',
|
|
20
|
+
title: 'Success rate',
|
|
21
|
+
data: { provider: 'durable.successRate' },
|
|
22
|
+
max: 1,
|
|
23
|
+
format: 'percent',
|
|
24
|
+
thresholds: { warn: 0.98, bad: 0.95, direction: 'down-bad' },
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
kind: 'stat',
|
|
28
|
+
title: 'Duration p95',
|
|
29
|
+
data: { provider: 'durable.duration', query: { metric: 'p95' } },
|
|
30
|
+
format: 'duration',
|
|
31
|
+
spark: false,
|
|
32
|
+
thresholds: { warn: 2000, bad: 5000, direction: 'up-bad' },
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
kind: 'stat',
|
|
36
|
+
title: 'Backlog',
|
|
37
|
+
data: { provider: 'durable.state', query: { status: 'pending' } },
|
|
38
|
+
spark: false,
|
|
39
|
+
thresholds: { warn: 50, bad: 200, direction: 'up-bad' },
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
kind: 'stat',
|
|
43
|
+
title: 'Throughput',
|
|
44
|
+
data: { provider: 'durable.throughput' },
|
|
45
|
+
format: 'rate',
|
|
46
|
+
spark: true,
|
|
47
|
+
},
|
|
48
|
+
],
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
title: 'Needs attention',
|
|
52
|
+
cols: 3,
|
|
53
|
+
panels: [
|
|
54
|
+
{
|
|
55
|
+
kind: 'topN',
|
|
56
|
+
title: 'Top failing workflows',
|
|
57
|
+
data: { provider: 'durable.timeseries', query: { metric: 'topFailures' } },
|
|
58
|
+
limit: 8,
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
kind: 'table',
|
|
62
|
+
title: 'Stuck runs',
|
|
63
|
+
data: { provider: 'durable.recentFailures', query: { windowMs } },
|
|
64
|
+
columns: [
|
|
65
|
+
{ key: 'updatedAt', label: 'Updated' },
|
|
66
|
+
{ key: 'workflow', label: 'Workflow' },
|
|
67
|
+
{ key: 'runId', label: 'Run', link: { href: runHref } },
|
|
68
|
+
{ key: 'error', label: 'Error' },
|
|
69
|
+
],
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
kind: 'table',
|
|
73
|
+
title: 'Starved worker groups',
|
|
74
|
+
data: { provider: 'durable.workerHealth' },
|
|
75
|
+
columns: [
|
|
76
|
+
{ key: 'group', label: 'Group' },
|
|
77
|
+
{ key: 'queued', label: 'Queued' },
|
|
78
|
+
{ key: 'liveWorkers', label: 'Workers' },
|
|
79
|
+
{ key: 'status', label: 'Status' },
|
|
80
|
+
],
|
|
81
|
+
},
|
|
82
|
+
],
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
title: 'Trends',
|
|
86
|
+
cols: 3,
|
|
87
|
+
panels: [
|
|
88
|
+
{
|
|
89
|
+
kind: 'timeseries',
|
|
90
|
+
title: 'Runs over time',
|
|
91
|
+
data: { provider: 'durable.runsOverTime' },
|
|
92
|
+
series: ['done', 'failed'],
|
|
93
|
+
style: 'stacked',
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
kind: 'distribution',
|
|
97
|
+
title: 'Duration distribution',
|
|
98
|
+
data: { provider: 'durable.duration' },
|
|
99
|
+
markers: ['p50', 'p95', 'p99'],
|
|
100
|
+
format: 'duration',
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
kind: 'breakdown',
|
|
104
|
+
title: 'Runs by state',
|
|
105
|
+
data: { provider: 'durable.stateBreakdown' },
|
|
106
|
+
style: 'donut',
|
|
107
|
+
},
|
|
108
|
+
],
|
|
109
|
+
},
|
|
110
|
+
],
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=dashboard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dashboard.js","sourceRoot":"","sources":["../../../src/telescope/dashboard.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { DataProvider } from './telescope-sdk.js';
|
|
2
|
+
/** A current-state count from the engine. `query.status` selects which (default 'dead'). */
|
|
3
|
+
export declare function durableStateProvider(): DataProvider;
|
|
4
|
+
/** Recent failed + dead runs as table rows (newest first), bounded by `query.windowMs` (default 24h). */
|
|
5
|
+
export declare function durableRecentFailuresProvider(): DataProvider;
|
|
6
|
+
/** Per-group worker health from the engine; `query.metric: 'starvedCount'` returns a stat. */
|
|
7
|
+
export declare function durableWorkerHealthProvider(): DataProvider;
|
|
8
|
+
/** Pie/donut segments: a count per status from the engine. */
|
|
9
|
+
export declare function durableStateBreakdownProvider(): DataProvider;
|
|
10
|
+
/** Rollups from captured run.* entries. `query.metric`: successRate | failed | total | topFailures. */
|
|
11
|
+
export declare function durableTimeseriesProvider(): DataProvider;
|
|
12
|
+
/** Duration percentiles + a ~8-bucket histogram, from `payload.durationMs` (or run.started pairing). */
|
|
13
|
+
export declare function durableDurationProvider(): DataProvider;
|
|
14
|
+
/** `done`/`failed` counts bucketed into `query.buckets ?? 24` equal time buckets. */
|
|
15
|
+
export declare function durableRunsOverTimeProvider(): DataProvider;
|
|
16
|
+
/** Success rate over `query.windowMs` (default 24h), with `delta` vs the prior window + an 8-pt spark. */
|
|
17
|
+
export declare function durableSuccessRateProvider(): DataProvider;
|
|
18
|
+
/** Completed runs per hour over `query.windowMs` (default 24h), with `delta` + an 8-pt spark. */
|
|
19
|
+
export declare function durableThroughputProvider(): DataProvider;
|
|
20
|
+
//# sourceMappingURL=data-providers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"data-providers.d.ts","sourceRoot":"","sources":["../../../src/telescope/data-providers.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAwC,MAAM,oBAAoB,CAAC;AAwE7F,4FAA4F;AAC5F,wBAAgB,oBAAoB,IAAI,YAAY,CAUnD;AAED,yGAAyG;AACzG,wBAAgB,6BAA6B,IAAI,YAAY,CAyB5D;AAED,8FAA8F;AAC9F,wBAAgB,2BAA2B,IAAI,YAAY,CAuB1D;AAKD,8DAA8D;AAC9D,wBAAgB,6BAA6B,IAAI,YAAY,CAkB5D;AAID,uGAAuG;AACvG,wBAAgB,yBAAyB,IAAI,YAAY,CAgCxD;AAED,wGAAwG;AACxG,wBAAgB,uBAAuB,IAAI,YAAY,CA+CtD;AAED,qFAAqF;AACrF,wBAAgB,2BAA2B,IAAI,YAAY,CA+B1D;AAED,0GAA0G;AAC1G,wBAAgB,0BAA0B,IAAI,YAAY,CAwBzD;AAED,iGAAiG;AACjG,wBAAgB,yBAAyB,IAAI,YAAY,CA6BxD"}
|