@adonis-agora/durable 0.49.0 → 0.50.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/CHANGELOG.md +261 -0
- package/README.md +53 -22
- package/dist/assets/spa/assets/index-DupjrK7N.js +16 -0
- package/dist/assets/spa/assets/index-DupjrK7N.js.map +1 -0
- package/dist/assets/spa/index.html +1 -1
- package/dist/commands/durable_worker.d.ts.map +1 -1
- package/dist/commands/durable_worker.js +9 -8
- package/dist/commands/durable_worker.js.map +1 -1
- package/dist/configure.d.ts.map +1 -1
- package/dist/configure.js +1 -0
- package/dist/configure.js.map +1 -1
- package/dist/providers/dashboard_provider.d.ts +2 -0
- package/dist/providers/dashboard_provider.d.ts.map +1 -1
- package/dist/providers/dashboard_provider.js +50 -6
- package/dist/providers/dashboard_provider.js.map +1 -1
- package/dist/providers/durable_provider.d.ts.map +1 -1
- package/dist/providers/durable_provider.js +143 -34
- package/dist/providers/durable_provider.js.map +1 -1
- package/dist/src/admission-redis/redis-admission-backend.d.ts.map +1 -1
- package/dist/src/admission-redis/redis-admission-backend.js +3 -1
- package/dist/src/admission-redis/redis-admission-backend.js.map +1 -1
- package/dist/src/ambient-step.d.ts +24 -0
- package/dist/src/ambient-step.d.ts.map +1 -0
- package/dist/src/ambient-step.js +42 -0
- package/dist/src/ambient-step.js.map +1 -0
- package/dist/src/base-workflow.d.ts +10 -1
- package/dist/src/base-workflow.d.ts.map +1 -1
- package/dist/src/base-workflow.js.map +1 -1
- package/dist/src/codec-state-store.d.ts +28 -2
- package/dist/src/codec-state-store.d.ts.map +1 -1
- package/dist/src/codec-state-store.js +61 -3
- package/dist/src/codec-state-store.js.map +1 -1
- package/dist/src/commands/worker.d.ts +4 -1
- package/dist/src/commands/worker.d.ts.map +1 -1
- package/dist/src/commands/worker.js +27 -3
- package/dist/src/commands/worker.js.map +1 -1
- package/dist/src/config_types.d.ts +6 -0
- package/dist/src/config_types.d.ts.map +1 -1
- package/dist/src/control-plane-redis/redis-control-plane.d.ts.map +1 -1
- package/dist/src/control-plane-redis/redis-control-plane.js +22 -6
- package/dist/src/control-plane-redis/redis-control-plane.js.map +1 -1
- package/dist/src/control-planes/factory.d.ts +6 -0
- package/dist/src/control-planes/factory.d.ts.map +1 -1
- package/dist/src/control-planes/factory.js +1 -0
- package/dist/src/control-planes/factory.js.map +1 -1
- package/dist/src/dashboard/gateway-adapter.d.ts +15 -5
- package/dist/src/dashboard/gateway-adapter.d.ts.map +1 -1
- package/dist/src/dashboard/gateway-adapter.js +71 -7
- package/dist/src/dashboard/gateway-adapter.js.map +1 -1
- package/dist/src/dashboard/handlers.d.ts +53 -1
- package/dist/src/dashboard/handlers.d.ts.map +1 -1
- package/dist/src/dashboard/handlers.js +200 -20
- package/dist/src/dashboard/handlers.js.map +1 -1
- package/dist/src/dashboard/index.d.ts +2 -2
- package/dist/src/dashboard/index.d.ts.map +1 -1
- package/dist/src/dashboard/index.js +2 -2
- package/dist/src/dashboard/index.js.map +1 -1
- package/dist/src/dashboard/openapi.d.ts.map +1 -1
- package/dist/src/dashboard/openapi.js +71 -1
- package/dist/src/dashboard/openapi.js.map +1 -1
- package/dist/src/define_config.d.ts +122 -8
- package/dist/src/define_config.d.ts.map +1 -1
- package/dist/src/define_config.js.map +1 -1
- package/dist/src/diagnostics-bridge.d.ts +16 -3
- package/dist/src/diagnostics-bridge.d.ts.map +1 -1
- package/dist/src/diagnostics-bridge.js +9 -3
- package/dist/src/diagnostics-bridge.js.map +1 -1
- package/dist/src/discovery-roots.d.ts +92 -0
- package/dist/src/discovery-roots.d.ts.map +1 -0
- package/dist/src/discovery-roots.js +150 -0
- package/dist/src/discovery-roots.js.map +1 -0
- package/dist/src/engine.d.ts +418 -20
- package/dist/src/engine.d.ts.map +1 -1
- package/dist/src/engine.js +1523 -159
- package/dist/src/engine.js.map +1 -1
- package/dist/src/entities.d.ts +36 -1
- package/dist/src/entities.d.ts.map +1 -1
- package/dist/src/entities.js +65 -4
- package/dist/src/entities.js.map +1 -1
- package/dist/src/errors.d.ts +36 -0
- package/dist/src/errors.d.ts.map +1 -1
- package/dist/src/errors.js +44 -0
- package/dist/src/errors.js.map +1 -1
- package/dist/src/event-trigger-bridge.d.ts +8 -0
- package/dist/src/event-trigger-bridge.d.ts.map +1 -1
- package/dist/src/event-trigger-bridge.js +24 -3
- package/dist/src/event-trigger-bridge.js.map +1 -1
- package/dist/src/handshake/announced.d.ts +27 -0
- package/dist/src/handshake/announced.d.ts.map +1 -1
- package/dist/src/handshake/announced.js +62 -0
- package/dist/src/handshake/announced.js.map +1 -1
- package/dist/src/handshake/directory.d.ts +92 -0
- package/dist/src/handshake/directory.d.ts.map +1 -0
- package/dist/src/handshake/directory.js +139 -0
- package/dist/src/handshake/directory.js.map +1 -0
- package/dist/src/hooks/barrel-sources.d.ts +28 -0
- package/dist/src/hooks/barrel-sources.d.ts.map +1 -0
- package/dist/src/hooks/barrel-sources.js +92 -0
- package/dist/src/hooks/barrel-sources.js.map +1 -0
- package/dist/src/hooks/steps.d.ts +12 -3
- package/dist/src/hooks/steps.d.ts.map +1 -1
- package/dist/src/hooks/steps.js +7 -11
- package/dist/src/hooks/steps.js.map +1 -1
- package/dist/src/hooks/workflows.d.ts +12 -3
- package/dist/src/hooks/workflows.d.ts.map +1 -1
- package/dist/src/hooks/workflows.js +7 -13
- package/dist/src/hooks/workflows.js.map +1 -1
- package/dist/src/index.d.ts +12 -3
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +12 -3
- package/dist/src/index.js.map +1 -1
- package/dist/src/interfaces.d.ts +309 -21
- package/dist/src/interfaces.d.ts.map +1 -1
- package/dist/src/interfaces.js +10 -0
- package/dist/src/interfaces.js.map +1 -1
- package/dist/src/metrics.d.ts.map +1 -1
- package/dist/src/metrics.js +5 -0
- package/dist/src/metrics.js.map +1 -1
- package/dist/src/namespaces.d.ts +17 -0
- package/dist/src/namespaces.d.ts.map +1 -0
- package/dist/src/namespaces.js +24 -0
- package/dist/src/namespaces.js.map +1 -0
- package/dist/src/otel/durable-metrics.d.ts.map +1 -1
- package/dist/src/otel/durable-metrics.js +5 -0
- package/dist/src/otel/durable-metrics.js.map +1 -1
- package/dist/src/otel/durable-otel.d.ts.map +1 -1
- package/dist/src/otel/durable-otel.js +5 -0
- package/dist/src/otel/durable-otel.js.map +1 -1
- package/dist/src/pollers.d.ts +10 -1
- package/dist/src/pollers.d.ts.map +1 -1
- package/dist/src/pollers.js +15 -5
- package/dist/src/pollers.js.map +1 -1
- package/dist/src/protocol.d.ts +12 -0
- package/dist/src/protocol.d.ts.map +1 -1
- package/dist/src/protocol.js +27 -1
- package/dist/src/protocol.js.map +1 -1
- package/dist/src/remote-event.d.ts +6 -0
- package/dist/src/remote-event.d.ts.map +1 -0
- package/dist/src/remote-event.js +19 -0
- package/dist/src/remote-event.js.map +1 -0
- package/dist/src/remote-workflow-executor.d.ts +34 -12
- package/dist/src/remote-workflow-executor.d.ts.map +1 -1
- package/dist/src/remote-workflow-executor.js +42 -40
- package/dist/src/remote-workflow-executor.js.map +1 -1
- package/dist/src/run-detail-summary.d.ts +90 -3
- package/dist/src/run-detail-summary.d.ts.map +1 -1
- package/dist/src/run-detail-summary.js +360 -2
- package/dist/src/run-detail-summary.js.map +1 -1
- package/dist/src/run-facets.d.ts +48 -0
- package/dist/src/run-facets.d.ts.map +1 -0
- package/dist/src/run-facets.js +100 -0
- package/dist/src/run-facets.js.map +1 -0
- package/dist/src/run-gateway/interface.d.ts +27 -1
- package/dist/src/run-gateway/interface.d.ts.map +1 -1
- package/dist/src/run-gateway/proxy-run-gateway.d.ts +32 -4
- package/dist/src/run-gateway/proxy-run-gateway.d.ts.map +1 -1
- package/dist/src/run-gateway/proxy-run-gateway.js +101 -5
- package/dist/src/run-gateway/proxy-run-gateway.js.map +1 -1
- package/dist/src/run-gateway/run-request-responder.d.ts +18 -5
- package/dist/src/run-gateway/run-request-responder.d.ts.map +1 -1
- package/dist/src/run-gateway/run-request-responder.js +155 -32
- package/dist/src/run-gateway/run-request-responder.js.map +1 -1
- package/dist/src/run-gateway/store-run-gateway.d.ts +23 -1
- package/dist/src/run-gateway/store-run-gateway.d.ts.map +1 -1
- package/dist/src/run-gateway/store-run-gateway.js +38 -0
- package/dist/src/run-gateway/store-run-gateway.js.map +1 -1
- package/dist/src/search-attributes-schema.d.ts +44 -0
- package/dist/src/search-attributes-schema.d.ts.map +1 -0
- package/dist/src/search-attributes-schema.js +51 -0
- package/dist/src/search-attributes-schema.js.map +1 -0
- package/dist/src/singleton-admission.d.ts +75 -0
- package/dist/src/singleton-admission.d.ts.map +1 -0
- package/dist/src/singleton-admission.js +156 -0
- package/dist/src/singleton-admission.js.map +1 -0
- package/dist/src/singleton-gate.d.ts +23 -8
- package/dist/src/singleton-gate.d.ts.map +1 -1
- package/dist/src/singleton-gate.js +59 -12
- package/dist/src/singleton-gate.js.map +1 -1
- package/dist/src/standard-schema.d.ts +83 -0
- package/dist/src/standard-schema.d.ts.map +1 -0
- package/dist/src/standard-schema.js +31 -0
- package/dist/src/standard-schema.js.map +1 -0
- package/dist/src/step-discovery.d.ts +21 -11
- package/dist/src/step-discovery.d.ts.map +1 -1
- package/dist/src/step-discovery.js +86 -45
- package/dist/src/step-discovery.js.map +1 -1
- package/dist/src/step-ref.d.ts +38 -12
- package/dist/src/step-ref.d.ts.map +1 -1
- package/dist/src/step-ref.js +5 -13
- package/dist/src/step-ref.js.map +1 -1
- package/dist/src/stores/factory.d.ts +6 -0
- package/dist/src/stores/factory.d.ts.map +1 -1
- package/dist/src/stores/factory.js +4 -1
- package/dist/src/stores/factory.js.map +1 -1
- package/dist/src/stores/lucid-helpers.d.ts +2 -0
- package/dist/src/stores/lucid-helpers.d.ts.map +1 -1
- package/dist/src/stores/lucid-helpers.js +7 -0
- package/dist/src/stores/lucid-helpers.js.map +1 -1
- package/dist/src/stores/lucid-mappers.d.ts +25 -0
- package/dist/src/stores/lucid-mappers.d.ts.map +1 -1
- package/dist/src/stores/lucid-mappers.js +81 -18
- package/dist/src/stores/lucid-mappers.js.map +1 -1
- package/dist/src/stores/lucid-schema.d.ts +59 -1
- package/dist/src/stores/lucid-schema.d.ts.map +1 -1
- package/dist/src/stores/lucid-schema.js +271 -25
- package/dist/src/stores/lucid-schema.js.map +1 -1
- package/dist/src/stores/lucid.d.ts +61 -2
- package/dist/src/stores/lucid.d.ts.map +1 -1
- package/dist/src/stores/lucid.js +346 -41
- package/dist/src/stores/lucid.js.map +1 -1
- package/dist/src/telescope/dashboard.d.ts.map +1 -1
- package/dist/src/telescope/dashboard.js +30 -1
- package/dist/src/telescope/dashboard.js.map +1 -1
- package/dist/src/telescope/data-providers.d.ts +19 -1
- package/dist/src/telescope/data-providers.d.ts.map +1 -1
- package/dist/src/telescope/data-providers.js +119 -3
- package/dist/src/telescope/data-providers.js.map +1 -1
- package/dist/src/telescope/extension.d.ts.map +1 -1
- package/dist/src/telescope/extension.js +2 -1
- package/dist/src/telescope/extension.js.map +1 -1
- package/dist/src/telescope/index.d.ts +1 -1
- package/dist/src/telescope/index.d.ts.map +1 -1
- package/dist/src/telescope/index.js +1 -1
- package/dist/src/telescope/index.js.map +1 -1
- package/dist/src/testing/in-memory-state-store.d.ts +44 -15
- package/dist/src/testing/in-memory-state-store.d.ts.map +1 -1
- package/dist/src/testing/in-memory-state-store.js +204 -41
- package/dist/src/testing/in-memory-state-store.js.map +1 -1
- package/dist/src/testing-kit/checkpoint-aggregation-contract.d.ts +16 -0
- package/dist/src/testing-kit/checkpoint-aggregation-contract.d.ts.map +1 -0
- package/dist/src/testing-kit/checkpoint-aggregation-contract.js +228 -0
- package/dist/src/testing-kit/checkpoint-aggregation-contract.js.map +1 -0
- package/dist/src/testing-kit/state-store-conformance.d.ts.map +1 -1
- package/dist/src/testing-kit/state-store-conformance.js +355 -3
- package/dist/src/testing-kit/state-store-conformance.js.map +1 -1
- package/dist/src/transport-pool.d.ts +15 -1
- package/dist/src/transport-pool.d.ts.map +1 -1
- package/dist/src/transport-pool.js +50 -4
- package/dist/src/transport-pool.js.map +1 -1
- package/dist/src/transports/adaptive-concurrency.d.ts +168 -0
- package/dist/src/transports/adaptive-concurrency.d.ts.map +1 -0
- package/dist/src/transports/adaptive-concurrency.js +353 -0
- package/dist/src/transports/adaptive-concurrency.js.map +1 -0
- package/dist/src/transports/bullmq/adaptive-concurrency.d.ts +1 -143
- package/dist/src/transports/bullmq/adaptive-concurrency.d.ts.map +1 -1
- package/dist/src/transports/bullmq/adaptive-concurrency.js +3 -311
- package/dist/src/transports/bullmq/adaptive-concurrency.js.map +1 -1
- package/dist/src/transports/bullmq/bullmq-transport.d.ts +49 -1
- package/dist/src/transports/bullmq/bullmq-transport.d.ts.map +1 -1
- package/dist/src/transports/bullmq/bullmq-transport.js +330 -38
- package/dist/src/transports/bullmq/bullmq-transport.js.map +1 -1
- package/dist/src/transports/bullmq/deps.d.ts +18 -2
- package/dist/src/transports/bullmq/deps.d.ts.map +1 -1
- package/dist/src/transports/bullmq/deps.js +44 -2
- package/dist/src/transports/bullmq/deps.js.map +1 -1
- package/dist/src/transports/db-helpers.d.ts +39 -0
- package/dist/src/transports/db-helpers.d.ts.map +1 -1
- package/dist/src/transports/db-helpers.js +73 -0
- package/dist/src/transports/db-helpers.js.map +1 -1
- package/dist/src/transports/db-remote.d.ts +53 -0
- package/dist/src/transports/db-remote.d.ts.map +1 -0
- package/dist/src/transports/db-remote.js +147 -0
- package/dist/src/transports/db-remote.js.map +1 -0
- package/dist/src/transports/db-schema.d.ts +44 -1
- package/dist/src/transports/db-schema.d.ts.map +1 -1
- package/dist/src/transports/db-schema.js +227 -88
- package/dist/src/transports/db-schema.js.map +1 -1
- package/dist/src/transports/db.d.ts +189 -6
- package/dist/src/transports/db.d.ts.map +1 -1
- package/dist/src/transports/db.js +1291 -137
- package/dist/src/transports/db.js.map +1 -1
- package/dist/src/transports/event-emitter.d.ts +8 -0
- package/dist/src/transports/event-emitter.d.ts.map +1 -1
- package/dist/src/transports/event-emitter.js +36 -3
- package/dist/src/transports/event-emitter.js.map +1 -1
- package/dist/src/transports/factory.d.ts +110 -5
- package/dist/src/transports/factory.d.ts.map +1 -1
- package/dist/src/transports/factory.js +56 -9
- package/dist/src/transports/factory.js.map +1 -1
- package/dist/src/transports/queue-mock-adapter.d.ts +7 -2
- package/dist/src/transports/queue-mock-adapter.d.ts.map +1 -1
- package/dist/src/transports/queue-mock-adapter.js +18 -2
- package/dist/src/transports/queue-mock-adapter.js.map +1 -1
- package/dist/src/transports/queue-remote.d.ts +146 -0
- package/dist/src/transports/queue-remote.d.ts.map +1 -0
- package/dist/src/transports/queue-remote.js +398 -0
- package/dist/src/transports/queue-remote.js.map +1 -0
- package/dist/src/transports/queue.d.ts +159 -6
- package/dist/src/transports/queue.d.ts.map +1 -1
- package/dist/src/transports/queue.js +747 -37
- package/dist/src/transports/queue.js.map +1 -1
- package/dist/src/transports/task-failure.d.ts +31 -0
- package/dist/src/transports/task-failure.d.ts.map +1 -0
- package/dist/src/transports/task-failure.js +50 -0
- package/dist/src/transports/task-failure.js.map +1 -0
- package/dist/src/workflow-als.d.ts +1 -1
- package/dist/src/workflow-als.d.ts.map +1 -1
- package/dist/src/workflow-ctx.d.ts +10 -0
- package/dist/src/workflow-ctx.d.ts.map +1 -1
- package/dist/src/workflow-ctx.js +97 -15
- package/dist/src/workflow-ctx.js.map +1 -1
- package/dist/src/workflow-discovery.d.ts +32 -41
- package/dist/src/workflow-discovery.d.ts.map +1 -1
- package/dist/src/workflow-discovery.js +65 -88
- package/dist/src/workflow-discovery.js.map +1 -1
- package/dist/src/workflow-ref.d.ts +24 -0
- package/dist/src/workflow-ref.d.ts.map +1 -1
- package/dist/src/workflow-ref.js.map +1 -1
- package/dist/stubs/config/durable.stub +6 -0
- package/dist/stubs/config/durable_dashboard.stub +7 -3
- package/dist/stubs/database/migrations/create_durable_tables.stub +2 -1
- package/dist/stubs/database/migrations/create_durable_transport_messages.stub +43 -0
- package/dist/stubs/database/migrations/create_durable_transport_tables.stub +12 -9
- package/dist/stubs/database/migrations/create_durable_transport_worker_keys.stub +1 -1
- package/dist/stubs/make/workflow/main.stub +1 -1
- package/package.json +6 -4
- package/skills/durable-cluster/SKILL.md +80 -11
- package/skills/durable-determinism/SKILL.md +11 -5
- package/skills/durable-reliability/SKILL.md +77 -37
- package/skills/durable-setup/SKILL.md +51 -22
- package/skills/durable-transports-stores/SKILL.md +130 -19
- package/skills/durable-workflows/SKILL.md +71 -18
- package/dist/assets/spa/assets/index-DdB9zxuX.js +0 -16
- package/dist/assets/spa/assets/index-DdB9zxuX.js.map +0 -1
|
@@ -1,45 +1,66 @@
|
|
|
1
|
-
import type { ChildWait, RunFacetQuery, RunQuery, RunStatus, RunValueAxis, RunValueFacetOptions, RunValueFacetRow, ScheduleQuery, ScheduleRecord, SignalWaiter, StateStore, StepCheckpoint, WorkflowRun } from '../interfaces.js';
|
|
2
|
-
/**
|
|
3
|
-
* A non-durable, in-process `StateStore` for tests and local development.
|
|
4
|
-
* The shipped `@dudousxd/nestjs-durable-store` package re-exports an equivalent.
|
|
5
|
-
*/
|
|
1
|
+
import type { CheckpointQuery, CheckpointStat, ChildWait, RunFacetQuery, RunFacetRow, RunQuery, RunStatus, RunValueAxis, RunValueFacetOptions, RunValueFacetRow, ScheduleQuery, ScheduleRecord, SignalWaiter, StateStore, StepCheckpoint, WorkflowRun } from '../interfaces.js';
|
|
6
2
|
export declare class InMemoryStateStore implements StateStore {
|
|
7
|
-
|
|
8
|
-
private
|
|
9
|
-
private
|
|
3
|
+
/** All of this store's data; shared by reference with every {@link withScope} view. */
|
|
4
|
+
private state;
|
|
5
|
+
private get runs();
|
|
6
|
+
private get checkpoints();
|
|
7
|
+
private get signalWaiters();
|
|
10
8
|
/**
|
|
11
9
|
* Normalized search-attribute side-table, the in-memory analog of the SQL stores'
|
|
12
10
|
* `durable_run_attributes`: `key -> (runId -> row)`. Maintained on every create/update so an
|
|
13
11
|
* attribute query can be pushed DOWN to a key-indexed candidate set instead of scanning every run
|
|
14
12
|
* and comparing in-process. Mirrors {@link normalizeAttributeRows} so behavior matches the SQL path.
|
|
15
13
|
*/
|
|
16
|
-
private
|
|
14
|
+
private get attributeIndex();
|
|
17
15
|
/** Test/observability hook: how many candidate runs the last attribute query's index produced. */
|
|
18
|
-
lastAttributeCandidates: number;
|
|
16
|
+
get lastAttributeCandidates(): number;
|
|
17
|
+
set lastAttributeCandidates(value: number);
|
|
19
18
|
/**
|
|
20
19
|
* Test/observability hook: how many checkpoint rows the LAST checkpoint read materialized (the rows
|
|
21
20
|
* actually returned to the caller). `listCheckpoints` returns all rows for the run; the targeted
|
|
22
21
|
* {@link getLatestCheckpointByName} / {@link listCheckpointsByNamePrefix} return only the matches —
|
|
23
22
|
* so this lets the benchmark contrast "fetch N, scan in JS" against "fetch the k that match".
|
|
24
23
|
*/
|
|
25
|
-
lastCheckpointRowsRead: number;
|
|
24
|
+
get lastCheckpointRowsRead(): number;
|
|
25
|
+
set lastCheckpointRowsRead(value: number);
|
|
26
|
+
/**
|
|
27
|
+
* Test/observability hook: checkpoint rows materialized since construction, across every
|
|
28
|
+
* checkpoint read that returns rows — what a run-detail test compares between paths.
|
|
29
|
+
*/
|
|
30
|
+
get checkpointRowsRead(): number;
|
|
31
|
+
set checkpointRowsRead(value: number);
|
|
32
|
+
/** The namespace run reads are fenced to (see {@link withScope}); undefined sees every run. */
|
|
33
|
+
private scopeNamespace;
|
|
34
|
+
/**
|
|
35
|
+
* A view of THIS store (same data) whose run reads — `getRun`, `listRuns`, the counts and the
|
|
36
|
+
* recovery/dispatch/timer scans — only see `scope.namespace`. Writes stay unscoped. Mirrors
|
|
37
|
+
* `LucidStateStore.withScope`; `{ namespace: undefined }` is the operator view.
|
|
38
|
+
*/
|
|
39
|
+
withScope(scope: {
|
|
40
|
+
namespace?: string | undefined;
|
|
41
|
+
}): InMemoryStateStore;
|
|
42
|
+
private inScope;
|
|
43
|
+
private visibleRuns;
|
|
26
44
|
private key;
|
|
27
45
|
/** Drop then re-add a run's normalized attribute rows so the index tracks its current attributes. */
|
|
28
46
|
private reindexAttributes;
|
|
29
47
|
createRun(run: WorkflowRun): Promise<void>;
|
|
30
48
|
updateRun(runId: string, patch: Partial<WorkflowRun>): Promise<void>;
|
|
31
49
|
updateRunIf(runId: string, expectedStatuses: RunStatus[], patch: Partial<WorkflowRun>): Promise<boolean>;
|
|
50
|
+
tryAdmitSingleton(runId: string, tag: string, workflow: string, limit: number, retryWakeAt?: number): Promise<boolean>;
|
|
32
51
|
getRun(runId: string): Promise<WorkflowRun | null>;
|
|
33
52
|
deleteRun(runId: string): Promise<void>;
|
|
53
|
+
deleteRuns(runIds: string[]): Promise<void>;
|
|
34
54
|
getCheckpoint(runId: string, seq: number): Promise<StepCheckpoint | null>;
|
|
35
55
|
saveCheckpoint(checkpoint: StepCheckpoint): Promise<void>;
|
|
36
56
|
saveCheckpointIfPending(checkpoint: StepCheckpoint): Promise<boolean>;
|
|
57
|
+
saveCheckpointsIfPending(checkpoints: StepCheckpoint[]): Promise<boolean[]>;
|
|
37
58
|
/** Mirror of `LucidStateStore.recordStepHeartbeat`: mutate in place, no-op when absent. */
|
|
38
59
|
recordStepHeartbeat(runId: string, seq: number, at: Date, progress?: unknown): Promise<void>;
|
|
39
60
|
listIncompleteRuns(namespace?: string): Promise<WorkflowRun[]>;
|
|
40
61
|
listPendingRuns(limit: number, namespace?: string): Promise<WorkflowRun[]>;
|
|
41
62
|
listDueTimers(nowMs: number, namespace?: string, limit?: number): Promise<WorkflowRun[]>;
|
|
42
|
-
listOrphanedRuns(nowMs: number, limit: number, namespace?: string): Promise<WorkflowRun[]>;
|
|
63
|
+
listOrphanedRuns(nowMs: number, limit: number, namespace?: string, owner?: string): Promise<WorkflowRun[]>;
|
|
43
64
|
tryLockRun(runId: string, owner: string, leaseUntilMs: number, nowMs: number): Promise<boolean>;
|
|
44
65
|
releaseRunLock(runId: string, owner?: string): Promise<void>;
|
|
45
66
|
renewRunLock(runId: string, owner: string, leaseUntilMs: number): Promise<boolean>;
|
|
@@ -55,14 +76,15 @@ export declare class InMemoryStateStore implements StateStore {
|
|
|
55
76
|
raw: unknown;
|
|
56
77
|
saveCheckpoint: (cp: StepCheckpoint) => Promise<void>;
|
|
57
78
|
}) => Promise<T>): Promise<T>;
|
|
58
|
-
private
|
|
79
|
+
private get bufferedSignals();
|
|
59
80
|
bufferSignal(token: string, payload: unknown): Promise<void>;
|
|
81
|
+
listBufferedSignalTokens(prefix: string, limit: number): Promise<string[]>;
|
|
60
82
|
takeBufferedSignal(token: string): Promise<{
|
|
61
83
|
payload: unknown;
|
|
62
84
|
} | null>;
|
|
63
85
|
/** `id -> row`, so {@link removeBufferedEvent} can delete an exact row regardless of iteration
|
|
64
86
|
* order — mirrors the SQL store's PK-by-id delete. */
|
|
65
|
-
private
|
|
87
|
+
private get bufferedEvents();
|
|
66
88
|
bufferEvent(input: {
|
|
67
89
|
name: string;
|
|
68
90
|
payload: unknown;
|
|
@@ -75,6 +97,7 @@ export declare class InMemoryStateStore implements StateStore {
|
|
|
75
97
|
publishedAt: number;
|
|
76
98
|
}>>;
|
|
77
99
|
removeBufferedEvent(id: string): Promise<boolean>;
|
|
100
|
+
pruneBufferedEvents(publishedBefore: number, limit: number): Promise<number>;
|
|
78
101
|
/**
|
|
79
102
|
* Candidate run ids satisfying ONE attribute predicate, served from {@link attributeIndex} — the
|
|
80
103
|
* pushdown step. Numeric predicates scan only `numValue` rows under the key; string/boolean ones
|
|
@@ -82,7 +105,8 @@ export declare class InMemoryStateStore implements StateStore {
|
|
|
82
105
|
*/
|
|
83
106
|
private candidatesForFilter;
|
|
84
107
|
countRuns(query: Omit<RunQuery, 'page' | 'size'>): Promise<number>;
|
|
85
|
-
|
|
108
|
+
runFacets(query: RunFacetQuery): Promise<RunFacetRow[]>;
|
|
109
|
+
private get schedules();
|
|
86
110
|
saveSchedule(record: ScheduleRecord): Promise<void>;
|
|
87
111
|
getSchedule(id: string): Promise<ScheduleRecord | null>;
|
|
88
112
|
updateSchedule(id: string, patch: Partial<Omit<ScheduleRecord, 'id' | 'createdAt'>>, expectedNextFireAt?: number | null): Promise<boolean>;
|
|
@@ -97,6 +121,11 @@ export declare class InMemoryStateStore implements StateStore {
|
|
|
97
121
|
*/
|
|
98
122
|
runValueFacets(axis: RunValueAxis, query: RunFacetQuery, opts?: RunValueFacetOptions): Promise<RunValueFacetRow[]>;
|
|
99
123
|
listCheckpoints(runId: string): Promise<StepCheckpoint[]>;
|
|
124
|
+
checkpointStats(runId: string, opts?: {
|
|
125
|
+
group?: string | undefined;
|
|
126
|
+
}): Promise<CheckpointStat[]>;
|
|
127
|
+
queryCheckpoints(runId: string, query: CheckpointQuery): Promise<StepCheckpoint[]>;
|
|
128
|
+
private runCheckpoints;
|
|
100
129
|
getLatestCheckpointByName(runId: string, name: string): Promise<StepCheckpoint | undefined>;
|
|
101
130
|
countCheckpoints(runId: string, fromSeq: number, toSeq: number, statuses: StepCheckpoint['status'][]): Promise<number>;
|
|
102
131
|
listCheckpointsByNamePrefix(runId: string, prefixes: string[]): Promise<StepCheckpoint[]>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"in-memory-state-store.d.ts","sourceRoot":"","sources":["../../../src/testing/in-memory-state-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,SAAS,EACT,aAAa,EACb,QAAQ,EACR,SAAS,EACT,YAAY,EACZ,oBAAoB,EACpB,gBAAgB,EAChB,aAAa,EACb,cAAc,EACd,YAAY,EACZ,UAAU,EACV,cAAc,EACd,WAAW,EACZ,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"in-memory-state-store.d.ts","sourceRoot":"","sources":["../../../src/testing/in-memory-state-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,30 +1,100 @@
|
|
|
1
|
+
import { namespaceMatches, normalizeNamespace } from '../namespaces.js';
|
|
2
|
+
import { checkpointStatsOf, queryCheckpointsOf } from '../run-detail-summary.js';
|
|
3
|
+
import { mergeRunFacetRows } from '../run-facets.js';
|
|
1
4
|
import { runPageWindow } from '../run-pagination.js';
|
|
2
5
|
import { scanRunValueFacets } from '../run-value-facets.js';
|
|
3
6
|
import { normalizeAttributeRows } from '../search-attributes.js';
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
7
|
+
import { settlesTerminally, singletonAdmissionDenialPatch, singletonAdmissionTags, withoutAdmission, } from '../singleton-admission.js';
|
|
8
|
+
/** A caller's copy of a stored run, with a legacy `''`/absent namespace read as `'default'`. */
|
|
9
|
+
const copyRun = (run) => ({
|
|
10
|
+
...run,
|
|
11
|
+
namespace: normalizeNamespace(run.namespace),
|
|
12
|
+
});
|
|
13
|
+
/** A run about to be stored, its namespace normalized (`''` is the default pool). */
|
|
14
|
+
const withNormalizedNamespace = (run) => run.namespace === undefined || run.namespace === '' ? copyRun(run) : run;
|
|
15
|
+
const freshState = () => ({
|
|
16
|
+
runs: new Map(),
|
|
17
|
+
checkpoints: new Map(),
|
|
18
|
+
signalWaiters: new Map(),
|
|
19
|
+
attributeIndex: new Map(),
|
|
20
|
+
bufferedSignals: new Map(),
|
|
21
|
+
bufferedEvents: new Map(),
|
|
22
|
+
schedules: new Map(),
|
|
23
|
+
stats: { lastAttributeCandidates: 0, lastCheckpointRowsRead: 0, checkpointRowsRead: 0 },
|
|
24
|
+
});
|
|
8
25
|
export class InMemoryStateStore {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
26
|
+
/** All of this store's data; shared by reference with every {@link withScope} view. */
|
|
27
|
+
state = freshState();
|
|
28
|
+
get runs() {
|
|
29
|
+
return this.state.runs;
|
|
30
|
+
}
|
|
31
|
+
get checkpoints() {
|
|
32
|
+
return this.state.checkpoints;
|
|
33
|
+
}
|
|
34
|
+
get signalWaiters() {
|
|
35
|
+
return this.state.signalWaiters;
|
|
36
|
+
}
|
|
12
37
|
/**
|
|
13
38
|
* Normalized search-attribute side-table, the in-memory analog of the SQL stores'
|
|
14
39
|
* `durable_run_attributes`: `key -> (runId -> row)`. Maintained on every create/update so an
|
|
15
40
|
* attribute query can be pushed DOWN to a key-indexed candidate set instead of scanning every run
|
|
16
41
|
* and comparing in-process. Mirrors {@link normalizeAttributeRows} so behavior matches the SQL path.
|
|
17
42
|
*/
|
|
18
|
-
attributeIndex
|
|
43
|
+
get attributeIndex() {
|
|
44
|
+
return this.state.attributeIndex;
|
|
45
|
+
}
|
|
19
46
|
/** Test/observability hook: how many candidate runs the last attribute query's index produced. */
|
|
20
|
-
lastAttributeCandidates
|
|
47
|
+
get lastAttributeCandidates() {
|
|
48
|
+
return this.state.stats.lastAttributeCandidates;
|
|
49
|
+
}
|
|
50
|
+
set lastAttributeCandidates(value) {
|
|
51
|
+
this.state.stats.lastAttributeCandidates = value;
|
|
52
|
+
}
|
|
21
53
|
/**
|
|
22
54
|
* Test/observability hook: how many checkpoint rows the LAST checkpoint read materialized (the rows
|
|
23
55
|
* actually returned to the caller). `listCheckpoints` returns all rows for the run; the targeted
|
|
24
56
|
* {@link getLatestCheckpointByName} / {@link listCheckpointsByNamePrefix} return only the matches —
|
|
25
57
|
* so this lets the benchmark contrast "fetch N, scan in JS" against "fetch the k that match".
|
|
26
58
|
*/
|
|
27
|
-
lastCheckpointRowsRead
|
|
59
|
+
get lastCheckpointRowsRead() {
|
|
60
|
+
return this.state.stats.lastCheckpointRowsRead;
|
|
61
|
+
}
|
|
62
|
+
set lastCheckpointRowsRead(value) {
|
|
63
|
+
this.state.stats.lastCheckpointRowsRead = value;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Test/observability hook: checkpoint rows materialized since construction, across every
|
|
67
|
+
* checkpoint read that returns rows — what a run-detail test compares between paths.
|
|
68
|
+
*/
|
|
69
|
+
get checkpointRowsRead() {
|
|
70
|
+
return this.state.stats.checkpointRowsRead;
|
|
71
|
+
}
|
|
72
|
+
set checkpointRowsRead(value) {
|
|
73
|
+
this.state.stats.checkpointRowsRead = value;
|
|
74
|
+
}
|
|
75
|
+
/** The namespace run reads are fenced to (see {@link withScope}); undefined sees every run. */
|
|
76
|
+
scopeNamespace;
|
|
77
|
+
/**
|
|
78
|
+
* A view of THIS store (same data) whose run reads — `getRun`, `listRuns`, the counts and the
|
|
79
|
+
* recovery/dispatch/timer scans — only see `scope.namespace`. Writes stay unscoped. Mirrors
|
|
80
|
+
* `LucidStateStore.withScope`; `{ namespace: undefined }` is the operator view.
|
|
81
|
+
*/
|
|
82
|
+
withScope(scope) {
|
|
83
|
+
// A plain store holding the SAME state object by reference (not an `Object.create(this)` child,
|
|
84
|
+
// whose own-property writes — a counter bump — would shadow the base's, and which would break on
|
|
85
|
+
// any `#private` field). Overrides of a subclass are not carried over to the view.
|
|
86
|
+
const view = new InMemoryStateStore();
|
|
87
|
+
view.state = this.state;
|
|
88
|
+
view.scopeNamespace = scope.namespace;
|
|
89
|
+
return view;
|
|
90
|
+
}
|
|
91
|
+
inScope(run) {
|
|
92
|
+
return (this.scopeNamespace === undefined || namespaceMatches(run.namespace, this.scopeNamespace));
|
|
93
|
+
}
|
|
94
|
+
visibleRuns() {
|
|
95
|
+
const runs = [...this.runs.values()];
|
|
96
|
+
return this.scopeNamespace === undefined ? runs : runs.filter((r) => this.inScope(r));
|
|
97
|
+
}
|
|
28
98
|
key(runId, seq) {
|
|
29
99
|
return `${runId}:${seq}`;
|
|
30
100
|
}
|
|
@@ -50,14 +120,18 @@ export class InMemoryStateStore {
|
|
|
50
120
|
// Normalize an undefined namespace to 'default', matching the SQL stores' column DEFAULT 'default'
|
|
51
121
|
// — so a run created directly against this store (bypassing the engine, e.g. in tests) is still
|
|
52
122
|
// reachable via a namespace='default' filter and partitions consistently.
|
|
53
|
-
this.runs.set(run.id, { ...run, namespace: run.namespace
|
|
123
|
+
this.runs.set(run.id, { ...run, namespace: normalizeNamespace(run.namespace) });
|
|
54
124
|
this.reindexAttributes(run.id, run.searchAttributes);
|
|
55
125
|
}
|
|
56
126
|
async updateRun(runId, patch) {
|
|
57
127
|
const existing = this.runs.get(runId);
|
|
58
128
|
if (!existing)
|
|
59
129
|
throw new Error(`run ${runId} not found`);
|
|
60
|
-
const next = {
|
|
130
|
+
const next = withNormalizedNamespace({
|
|
131
|
+
...existing,
|
|
132
|
+
...patch,
|
|
133
|
+
...releasedSlot(existing, patch),
|
|
134
|
+
});
|
|
61
135
|
this.runs.set(runId, next);
|
|
62
136
|
if ('searchAttributes' in patch)
|
|
63
137
|
this.reindexAttributes(runId, next.searchAttributes);
|
|
@@ -68,15 +142,33 @@ export class InMemoryStateStore {
|
|
|
68
142
|
const existing = this.runs.get(runId);
|
|
69
143
|
if (!existing || !expectedStatuses.includes(existing.status))
|
|
70
144
|
return false;
|
|
71
|
-
const next = {
|
|
145
|
+
const next = withNormalizedNamespace({
|
|
146
|
+
...existing,
|
|
147
|
+
...patch,
|
|
148
|
+
...releasedSlot(existing, patch),
|
|
149
|
+
});
|
|
72
150
|
this.runs.set(runId, next);
|
|
73
151
|
if ('searchAttributes' in patch)
|
|
74
152
|
this.reindexAttributes(runId, next.searchAttributes);
|
|
75
153
|
return true;
|
|
76
154
|
}
|
|
155
|
+
async tryAdmitSingleton(runId, tag, workflow, limit, retryWakeAt) {
|
|
156
|
+
// No `await` between the snapshot and the claim: this synchronous turn is the critical section.
|
|
157
|
+
const runs = [...this.runs.values()];
|
|
158
|
+
const tags = singletonAdmissionTags(runs, runId, tag, workflow, limit);
|
|
159
|
+
const run = this.runs.get(runId);
|
|
160
|
+
if (!tags || !run) {
|
|
161
|
+
const parked = singletonAdmissionDenialPatch(runs, runId, tag, workflow, retryWakeAt);
|
|
162
|
+
if (parked && run)
|
|
163
|
+
this.runs.set(runId, { ...run, ...parked });
|
|
164
|
+
return false;
|
|
165
|
+
}
|
|
166
|
+
this.runs.set(runId, { ...run, tags });
|
|
167
|
+
return true;
|
|
168
|
+
}
|
|
77
169
|
async getRun(runId) {
|
|
78
170
|
const run = this.runs.get(runId);
|
|
79
|
-
return run ?
|
|
171
|
+
return run && this.inScope(run) ? copyRun(run) : null;
|
|
80
172
|
}
|
|
81
173
|
async deleteRun(runId) {
|
|
82
174
|
this.runs.delete(runId);
|
|
@@ -91,6 +183,10 @@ export class InMemoryStateStore {
|
|
|
91
183
|
// Drop the run's normalized attribute rows (reindex with no attributes clears them).
|
|
92
184
|
this.reindexAttributes(runId, undefined);
|
|
93
185
|
}
|
|
186
|
+
async deleteRuns(runIds) {
|
|
187
|
+
for (const runId of runIds)
|
|
188
|
+
await this.deleteRun(runId);
|
|
189
|
+
}
|
|
94
190
|
async getCheckpoint(runId, seq) {
|
|
95
191
|
const cp = this.checkpoints.get(this.key(runId, seq));
|
|
96
192
|
return cp ? { ...cp } : null;
|
|
@@ -105,6 +201,15 @@ export class InMemoryStateStore {
|
|
|
105
201
|
this.checkpoints.set(key, { ...checkpoint });
|
|
106
202
|
return true;
|
|
107
203
|
}
|
|
204
|
+
async saveCheckpointsIfPending(checkpoints) {
|
|
205
|
+
return checkpoints.map((checkpoint) => {
|
|
206
|
+
const key = this.key(checkpoint.runId, checkpoint.seq);
|
|
207
|
+
if (this.checkpoints.get(key)?.status !== 'pending')
|
|
208
|
+
return false;
|
|
209
|
+
this.checkpoints.set(key, { ...checkpoint });
|
|
210
|
+
return true;
|
|
211
|
+
});
|
|
212
|
+
}
|
|
108
213
|
/** Mirror of `LucidStateStore.recordStepHeartbeat`: mutate in place, no-op when absent. */
|
|
109
214
|
async recordStepHeartbeat(runId, seq, at, progress) {
|
|
110
215
|
const cp = this.checkpoints.get(this.key(runId, seq));
|
|
@@ -114,34 +219,38 @@ export class InMemoryStateStore {
|
|
|
114
219
|
cp.heartbeatProgress = progress;
|
|
115
220
|
}
|
|
116
221
|
async listIncompleteRuns(namespace) {
|
|
117
|
-
return
|
|
118
|
-
.filter((r) => r.status === 'running' &&
|
|
119
|
-
|
|
222
|
+
return this.visibleRuns()
|
|
223
|
+
.filter((r) => r.status === 'running' &&
|
|
224
|
+
(namespace === undefined || namespaceMatches(r.namespace, namespace)))
|
|
225
|
+
.map(copyRun);
|
|
120
226
|
}
|
|
121
227
|
async listPendingRuns(limit, namespace) {
|
|
122
|
-
return
|
|
123
|
-
.filter((r) => r.status === 'pending' &&
|
|
228
|
+
return this.visibleRuns()
|
|
229
|
+
.filter((r) => r.status === 'pending' &&
|
|
230
|
+
(namespace === undefined || namespaceMatches(r.namespace, namespace)))
|
|
124
231
|
.sort((a, b) => a.createdAt.getTime() - b.createdAt.getTime() || a.id.localeCompare(b.id))
|
|
125
232
|
.slice(0, limit)
|
|
126
|
-
.map(
|
|
233
|
+
.map(copyRun);
|
|
127
234
|
}
|
|
128
235
|
async listDueTimers(nowMs, namespace, limit) {
|
|
129
|
-
const due =
|
|
236
|
+
const due = this.visibleRuns().filter((r) => r.status === 'suspended' &&
|
|
130
237
|
r.wakeAt !== undefined &&
|
|
131
238
|
r.wakeAt <= nowMs &&
|
|
132
|
-
(namespace === undefined || r.namespace
|
|
239
|
+
(namespace === undefined || namespaceMatches(r.namespace, namespace)));
|
|
133
240
|
// Most overdue first (mirrors the SQL stores' ORDER BY wake_at).
|
|
134
241
|
due.sort((a, b) => (a.wakeAt ?? 0) - (b.wakeAt ?? 0));
|
|
135
|
-
return (limit === undefined ? due : due.slice(0, limit)).map(
|
|
242
|
+
return (limit === undefined ? due : due.slice(0, limit)).map(copyRun);
|
|
136
243
|
}
|
|
137
|
-
async listOrphanedRuns(nowMs, limit, namespace) {
|
|
138
|
-
return
|
|
244
|
+
async listOrphanedRuns(nowMs, limit, namespace, owner) {
|
|
245
|
+
return this.visibleRuns()
|
|
139
246
|
.filter((r) => r.status === 'running' &&
|
|
140
|
-
(r.lockedUntil === undefined ||
|
|
141
|
-
|
|
247
|
+
(r.lockedUntil === undefined ||
|
|
248
|
+
r.lockedUntil <= nowMs ||
|
|
249
|
+
(owner !== undefined && r.lockedBy === owner)) &&
|
|
250
|
+
(namespace === undefined || namespaceMatches(r.namespace, namespace)))
|
|
142
251
|
.sort((a, b) => a.createdAt.getTime() - b.createdAt.getTime())
|
|
143
252
|
.slice(0, limit)
|
|
144
|
-
.map(
|
|
253
|
+
.map(copyRun);
|
|
145
254
|
}
|
|
146
255
|
async tryLockRun(runId, owner, leaseUntilMs, nowMs) {
|
|
147
256
|
const run = this.runs.get(runId);
|
|
@@ -224,12 +333,24 @@ export class InMemoryStateStore {
|
|
|
224
333
|
async transaction(work) {
|
|
225
334
|
return work({ raw: this, saveCheckpoint: (cp) => this.saveCheckpoint(cp) });
|
|
226
335
|
}
|
|
227
|
-
bufferedSignals
|
|
336
|
+
get bufferedSignals() {
|
|
337
|
+
return this.state.bufferedSignals;
|
|
338
|
+
}
|
|
228
339
|
async bufferSignal(token, payload) {
|
|
229
340
|
const queue = this.bufferedSignals.get(token) ?? [];
|
|
230
341
|
queue.push(payload);
|
|
231
342
|
this.bufferedSignals.set(token, queue);
|
|
232
343
|
}
|
|
344
|
+
async listBufferedSignalTokens(prefix, limit) {
|
|
345
|
+
const out = [];
|
|
346
|
+
for (const [token, queue] of this.bufferedSignals) {
|
|
347
|
+
if (out.length >= limit)
|
|
348
|
+
break;
|
|
349
|
+
if (token.startsWith(prefix) && queue.length > 0)
|
|
350
|
+
out.push(token);
|
|
351
|
+
}
|
|
352
|
+
return out;
|
|
353
|
+
}
|
|
233
354
|
async takeBufferedSignal(token) {
|
|
234
355
|
const queue = this.bufferedSignals.get(token);
|
|
235
356
|
if (!queue || queue.length === 0)
|
|
@@ -241,7 +362,9 @@ export class InMemoryStateStore {
|
|
|
241
362
|
}
|
|
242
363
|
/** `id -> row`, so {@link removeBufferedEvent} can delete an exact row regardless of iteration
|
|
243
364
|
* order — mirrors the SQL store's PK-by-id delete. */
|
|
244
|
-
bufferedEvents
|
|
365
|
+
get bufferedEvents() {
|
|
366
|
+
return this.state.bufferedEvents;
|
|
367
|
+
}
|
|
245
368
|
async bufferEvent(input) {
|
|
246
369
|
this.bufferedEvents.set(input.id, {
|
|
247
370
|
name: input.name,
|
|
@@ -259,6 +382,15 @@ export class InMemoryStateStore {
|
|
|
259
382
|
async removeBufferedEvent(id) {
|
|
260
383
|
return this.bufferedEvents.delete(id);
|
|
261
384
|
}
|
|
385
|
+
async pruneBufferedEvents(publishedBefore, limit) {
|
|
386
|
+
const expired = [...this.bufferedEvents.entries()]
|
|
387
|
+
.filter(([, e]) => e.publishedAt < publishedBefore)
|
|
388
|
+
.sort((a, b) => a[1].publishedAt - b[1].publishedAt)
|
|
389
|
+
.slice(0, Math.max(0, limit));
|
|
390
|
+
for (const [id] of expired)
|
|
391
|
+
this.bufferedEvents.delete(id);
|
|
392
|
+
return expired.length;
|
|
393
|
+
}
|
|
262
394
|
/**
|
|
263
395
|
* Candidate run ids satisfying ONE attribute predicate, served from {@link attributeIndex} — the
|
|
264
396
|
* pushdown step. Numeric predicates scan only `numValue` rows under the key; string/boolean ones
|
|
@@ -318,9 +450,18 @@ export class InMemoryStateStore {
|
|
|
318
450
|
async countRuns(query) {
|
|
319
451
|
return (await this.listRuns(query)).length;
|
|
320
452
|
}
|
|
321
|
-
|
|
453
|
+
async runFacets(query) {
|
|
454
|
+
const runs = await this.listRuns(query);
|
|
455
|
+
return mergeRunFacetRows(runs.map((r) => ({ status: r.status, origin: r.origin, count: 1 })));
|
|
456
|
+
}
|
|
457
|
+
get schedules() {
|
|
458
|
+
return this.state.schedules;
|
|
459
|
+
}
|
|
322
460
|
async saveSchedule(record) {
|
|
323
|
-
this.schedules.set(record.id,
|
|
461
|
+
this.schedules.set(record.id, {
|
|
462
|
+
...structuredClone(record),
|
|
463
|
+
namespace: normalizeNamespace(record.namespace),
|
|
464
|
+
});
|
|
324
465
|
}
|
|
325
466
|
async getSchedule(id) {
|
|
326
467
|
const record = this.schedules.get(id);
|
|
@@ -332,7 +473,8 @@ export class InMemoryStateStore {
|
|
|
332
473
|
return false;
|
|
333
474
|
if (expectedNextFireAt !== undefined && record.nextFireAt !== expectedNextFireAt)
|
|
334
475
|
return false;
|
|
335
|
-
|
|
476
|
+
const next = { ...record, ...structuredClone(patch) };
|
|
477
|
+
this.schedules.set(id, { ...next, namespace: normalizeNamespace(next.namespace) });
|
|
336
478
|
return true;
|
|
337
479
|
}
|
|
338
480
|
async deleteSchedule(id) {
|
|
@@ -340,7 +482,7 @@ export class InMemoryStateStore {
|
|
|
340
482
|
}
|
|
341
483
|
async listSchedules(query) {
|
|
342
484
|
const rows = [...this.schedules.values()]
|
|
343
|
-
.filter((s) => query.namespace === undefined || s.namespace
|
|
485
|
+
.filter((s) => query.namespace === undefined || namespaceMatches(s.namespace, query.namespace))
|
|
344
486
|
.filter((s) => query.workflow === undefined || s.workflow === query.workflow)
|
|
345
487
|
.filter((s) => query.tag === undefined || (s.tags ?? []).includes(query.tag))
|
|
346
488
|
.filter((s) => query.paused === undefined || s.paused === query.paused)
|
|
@@ -354,7 +496,7 @@ export class InMemoryStateStore {
|
|
|
354
496
|
.map((s) => structuredClone(s));
|
|
355
497
|
}
|
|
356
498
|
async listRuns(query) {
|
|
357
|
-
let runs =
|
|
499
|
+
let runs = this.visibleRuns();
|
|
358
500
|
if (query.workflow)
|
|
359
501
|
runs = runs.filter((r) => r.workflow === query.workflow);
|
|
360
502
|
if (query.workflows) {
|
|
@@ -363,13 +505,15 @@ export class InMemoryStateStore {
|
|
|
363
505
|
? []
|
|
364
506
|
: runs.filter((r) => query.workflows?.includes(r.workflow));
|
|
365
507
|
}
|
|
366
|
-
if (query.namespace !== undefined)
|
|
367
|
-
|
|
508
|
+
if (query.namespace !== undefined) {
|
|
509
|
+
const namespace = query.namespace;
|
|
510
|
+
runs = runs.filter((r) => namespaceMatches(r.namespace, namespace));
|
|
511
|
+
}
|
|
368
512
|
if (query.namespaces) {
|
|
369
513
|
runs =
|
|
370
514
|
query.namespaces.length === 0
|
|
371
515
|
? []
|
|
372
|
-
: runs.filter((r) =>
|
|
516
|
+
: runs.filter((r) => query.namespaces?.some((ns) => namespaceMatches(r.namespace, ns)) ?? false);
|
|
373
517
|
}
|
|
374
518
|
if (query.origin)
|
|
375
519
|
runs = runs.filter((r) => r.origin === query.origin);
|
|
@@ -425,9 +569,7 @@ export class InMemoryStateStore {
|
|
|
425
569
|
runs.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());
|
|
426
570
|
// 1-based `page`/`size` in, 0-based slice out — same resolution the SQL adapters apply.
|
|
427
571
|
const { limit, offset } = runPageWindow(query);
|
|
428
|
-
return runs
|
|
429
|
-
.slice(offset, limit === undefined ? undefined : offset + limit)
|
|
430
|
-
.map((r) => ({ ...r }));
|
|
572
|
+
return runs.slice(offset, limit === undefined ? undefined : offset + limit).map(copyRun);
|
|
431
573
|
}
|
|
432
574
|
/**
|
|
433
575
|
* The distinct values of ONE filter axis over the runs matching `query`, with counts — what a
|
|
@@ -444,8 +586,21 @@ export class InMemoryStateStore {
|
|
|
444
586
|
.sort((a, b) => a.seq - b.seq)
|
|
445
587
|
.map((cp) => ({ ...cp }));
|
|
446
588
|
this.lastCheckpointRowsRead = rows.length;
|
|
589
|
+
this.checkpointRowsRead += rows.length;
|
|
590
|
+
return rows;
|
|
591
|
+
}
|
|
592
|
+
async checkpointStats(runId, opts) {
|
|
593
|
+
return checkpointStatsOf(this.runCheckpoints(runId), opts);
|
|
594
|
+
}
|
|
595
|
+
async queryCheckpoints(runId, query) {
|
|
596
|
+
const rows = queryCheckpointsOf(this.runCheckpoints(runId), query).map((cp) => ({ ...cp }));
|
|
597
|
+
this.lastCheckpointRowsRead = rows.length;
|
|
598
|
+
this.checkpointRowsRead += rows.length;
|
|
447
599
|
return rows;
|
|
448
600
|
}
|
|
601
|
+
runCheckpoints(runId) {
|
|
602
|
+
return [...this.checkpoints.values()].filter((cp) => cp.runId === runId);
|
|
603
|
+
}
|
|
449
604
|
async getLatestCheckpointByName(runId, name) {
|
|
450
605
|
let latest;
|
|
451
606
|
for (const cp of this.checkpoints.values()) {
|
|
@@ -474,7 +629,15 @@ export class InMemoryStateStore {
|
|
|
474
629
|
.sort((a, b) => a.seq - b.seq)
|
|
475
630
|
.map((cp) => ({ ...cp }));
|
|
476
631
|
this.lastCheckpointRowsRead = rows.length;
|
|
632
|
+
this.checkpointRowsRead += rows.length;
|
|
477
633
|
return rows;
|
|
478
634
|
}
|
|
479
635
|
}
|
|
636
|
+
/** A terminal settle releases the run's singleton slot: drop the admission marker from its tags. */
|
|
637
|
+
function releasedSlot(existing, patch) {
|
|
638
|
+
if (!settlesTerminally(patch))
|
|
639
|
+
return undefined;
|
|
640
|
+
const tags = withoutAdmission('tags' in patch ? patch.tags : existing.tags);
|
|
641
|
+
return tags ? { tags } : undefined;
|
|
642
|
+
}
|
|
480
643
|
//# sourceMappingURL=in-memory-state-store.js.map
|