@hunterzhu/pulse-runtime 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.
Files changed (93) hide show
  1. package/dist/context/builder.d.ts +68 -0
  2. package/dist/context/builder.js +127 -0
  3. package/dist/context/index.d.ts +2 -0
  4. package/dist/context/index.js +2 -0
  5. package/dist/context/merger.d.ts +25 -0
  6. package/dist/context/merger.js +125 -0
  7. package/dist/core/actions.d.ts +1 -0
  8. package/dist/core/actions.js +1 -0
  9. package/dist/core/errors.d.ts +8 -0
  10. package/dist/core/errors.js +36 -0
  11. package/dist/core/events.d.ts +10 -0
  12. package/dist/core/events.js +24 -0
  13. package/dist/core/factory.d.ts +35 -0
  14. package/dist/core/factory.js +27 -0
  15. package/dist/core/inbox.d.ts +119 -0
  16. package/dist/core/inbox.js +217 -0
  17. package/dist/core/mutations.d.ts +80 -0
  18. package/dist/core/mutations.js +127 -0
  19. package/dist/core/records.d.ts +1 -0
  20. package/dist/core/records.js +1 -0
  21. package/dist/core/types.d.ts +615 -0
  22. package/dist/core/types.js +109 -0
  23. package/dist/dependencies/graph.d.ts +25 -0
  24. package/dist/dependencies/graph.js +92 -0
  25. package/dist/dependencies/index.d.ts +1 -0
  26. package/dist/dependencies/index.js +1 -0
  27. package/dist/dsl/context-proxy.d.ts +20 -0
  28. package/dist/dsl/context-proxy.js +64 -0
  29. package/dist/dsl/index.d.ts +4 -0
  30. package/dist/dsl/index.js +4 -0
  31. package/dist/dsl/program.d.ts +314 -0
  32. package/dist/dsl/program.js +756 -0
  33. package/dist/dsl/session.d.ts +45 -0
  34. package/dist/dsl/session.js +93 -0
  35. package/dist/dsl/templates-index.d.ts +1 -0
  36. package/dist/dsl/templates-index.js +1 -0
  37. package/dist/dsl/templates.d.ts +85 -0
  38. package/dist/dsl/templates.js +110 -0
  39. package/dist/index.d.ts +15 -0
  40. package/dist/index.js +15 -0
  41. package/dist/lifecycle/index.d.ts +2 -0
  42. package/dist/lifecycle/index.js +2 -0
  43. package/dist/lifecycle/scopes.d.ts +38 -0
  44. package/dist/lifecycle/scopes.js +50 -0
  45. package/dist/lifecycle/watchdog.d.ts +16 -0
  46. package/dist/lifecycle/watchdog.js +66 -0
  47. package/dist/models/actions.d.ts +10 -0
  48. package/dist/models/actions.js +68 -0
  49. package/dist/models/index.d.ts +2 -0
  50. package/dist/models/index.js +2 -0
  51. package/dist/models/router.d.ts +187 -0
  52. package/dist/models/router.js +353 -0
  53. package/dist/scheduler/clock.d.ts +45 -0
  54. package/dist/scheduler/clock.js +92 -0
  55. package/dist/scheduler/decision.d.ts +72 -0
  56. package/dist/scheduler/decision.js +63 -0
  57. package/dist/scheduler/index.d.ts +6 -0
  58. package/dist/scheduler/index.js +6 -0
  59. package/dist/scheduler/locks.d.ts +18 -0
  60. package/dist/scheduler/locks.js +106 -0
  61. package/dist/scheduler/ready-queue.d.ts +32 -0
  62. package/dist/scheduler/ready-queue.js +40 -0
  63. package/dist/scheduler/runtime.d.ts +486 -0
  64. package/dist/scheduler/runtime.js +3445 -0
  65. package/dist/scheduler/telemetry.d.ts +111 -0
  66. package/dist/scheduler/telemetry.js +177 -0
  67. package/dist/scheduler/worker.d.ts +158 -0
  68. package/dist/scheduler/worker.js +744 -0
  69. package/dist/storage/artifacts.d.ts +17 -0
  70. package/dist/storage/artifacts.js +90 -0
  71. package/dist/storage/findings.d.ts +12 -0
  72. package/dist/storage/findings.js +70 -0
  73. package/dist/storage/index.d.ts +8 -0
  74. package/dist/storage/index.js +8 -0
  75. package/dist/storage/memory.d.ts +11 -0
  76. package/dist/storage/memory.js +21 -0
  77. package/dist/storage/mutation-log.d.ts +41 -0
  78. package/dist/storage/mutation-log.js +140 -0
  79. package/dist/storage/outbox.d.ts +30 -0
  80. package/dist/storage/outbox.js +59 -0
  81. package/dist/storage/persistence.d.ts +183 -0
  82. package/dist/storage/persistence.js +999 -0
  83. package/dist/storage/policy.d.ts +80 -0
  84. package/dist/storage/policy.js +268 -0
  85. package/dist/storage/session.d.ts +140 -0
  86. package/dist/storage/session.js +447 -0
  87. package/dist/tools/registry.d.ts +125 -0
  88. package/dist/tools/registry.js +308 -0
  89. package/dist/transitions/index.d.ts +2 -0
  90. package/dist/transitions/index.js +1 -0
  91. package/dist/transitions/validate.d.ts +4 -0
  92. package/dist/transitions/validate.js +1118 -0
  93. package/package.json +21 -0
@@ -0,0 +1,111 @@
1
+ import type { JsonValue, RuntimeState } from '../core/types.js';
2
+ export interface RuntimeTelemetryAttempt {
3
+ effectId: string;
4
+ agentId: string | null;
5
+ laneId: string | null;
6
+ attemptId: string;
7
+ attemptNo: number;
8
+ modelId: string;
9
+ providerId: string;
10
+ slotWaitMs?: number;
11
+ usage?: JsonValue;
12
+ }
13
+ export interface RuntimeTelemetrySnapshot {
14
+ eventCounts: Record<string, number>;
15
+ agents: {
16
+ total: number;
17
+ byState: Record<string, number>;
18
+ };
19
+ lanes: {
20
+ total: number;
21
+ byStatus: Record<string, number>;
22
+ };
23
+ effects: {
24
+ total: number;
25
+ byState: Record<string, number>;
26
+ byKind: Record<string, number>;
27
+ };
28
+ llm: {
29
+ effects: number;
30
+ metadataEvents: number;
31
+ attempts: RuntimeTelemetryAttempt[];
32
+ routeRejections: Record<string, number>;
33
+ usage: {
34
+ inputTokens: number;
35
+ outputTokens: number;
36
+ cachedInputTokens: number;
37
+ uncachedInputTokens: number;
38
+ latencyMs: number;
39
+ costByCurrency: Record<string, number>;
40
+ };
41
+ };
42
+ }
43
+ export interface RuntimeTelemetryEnvelope {
44
+ schemaVersion: 1;
45
+ timestamp: number;
46
+ snapshot: RuntimeTelemetrySnapshot;
47
+ }
48
+ export interface RuntimeTelemetryExporter {
49
+ publish(envelope: RuntimeTelemetryEnvelope): Promise<void> | void;
50
+ }
51
+ export interface RuntimeTelemetryAlertRule {
52
+ id: string;
53
+ metric: string;
54
+ threshold: number;
55
+ direction: 'above' | 'below';
56
+ cooldownMs?: number;
57
+ }
58
+ export interface RuntimeTelemetryAlert {
59
+ ruleId: string;
60
+ metric: string;
61
+ value: number;
62
+ threshold: number;
63
+ direction: RuntimeTelemetryAlertRule['direction'];
64
+ timestamp: number;
65
+ }
66
+ export interface RuntimeTelemetryAggregateSnapshot {
67
+ schemaVersion: 1;
68
+ sampleCount: number;
69
+ firstTimestamp?: number;
70
+ lastTimestamp?: number;
71
+ latest?: RuntimeTelemetryEnvelope;
72
+ peaks: Record<string, number>;
73
+ alerts: RuntimeTelemetryAlert[];
74
+ }
75
+ /** Aggregates exported samples without retaining the full telemetry stream in Runtime state. */
76
+ export declare class RuntimeTelemetryAggregator {
77
+ readonly rules: readonly RuntimeTelemetryAlertRule[];
78
+ private sampleCount;
79
+ private firstTimestamp;
80
+ private lastTimestamp;
81
+ private latest;
82
+ private readonly peaks;
83
+ private readonly alerts;
84
+ private readonly lastAlertAt;
85
+ constructor(rules?: readonly RuntimeTelemetryAlertRule[]);
86
+ ingest(envelope: RuntimeTelemetryEnvelope): RuntimeTelemetryAlert[];
87
+ snapshot(): RuntimeTelemetryAggregateSnapshot;
88
+ }
89
+ /** A durable, append-only exporter suitable for a local host or sidecar collector. */
90
+ export declare class FileRuntimeTelemetryExporter implements RuntimeTelemetryExporter {
91
+ readonly filePath: string;
92
+ private pending;
93
+ constructor(filePath: string);
94
+ publish(envelope: RuntimeTelemetryEnvelope): Promise<void>;
95
+ }
96
+ export interface HttpRuntimeTelemetryExporterOptions {
97
+ endpoint: string;
98
+ headers?: Record<string, string>;
99
+ timeoutMs?: number;
100
+ fetch?: typeof globalThis.fetch;
101
+ }
102
+ /** Sends complete envelopes to an external collector without changing Runtime state. */
103
+ export declare class HttpRuntimeTelemetryExporter implements RuntimeTelemetryExporter {
104
+ private readonly endpoint;
105
+ private readonly headers;
106
+ private readonly timeoutMs;
107
+ private readonly fetcher;
108
+ constructor(options: HttpRuntimeTelemetryExporterOptions);
109
+ publish(envelope: RuntimeTelemetryEnvelope): Promise<void>;
110
+ }
111
+ export declare function collectRuntimeTelemetry(state: RuntimeState): RuntimeTelemetrySnapshot;
@@ -0,0 +1,177 @@
1
+ import { mkdir, open } from 'node:fs/promises';
2
+ import { dirname } from 'node:path';
3
+ function metricValue(snapshot, path) {
4
+ let current = snapshot;
5
+ for (const segment of path.split('.')) {
6
+ if (!current || typeof current !== 'object' || Array.isArray(current))
7
+ return undefined;
8
+ current = current[segment];
9
+ }
10
+ return typeof current === 'number' && Number.isFinite(current) ? current : undefined;
11
+ }
12
+ /** Aggregates exported samples without retaining the full telemetry stream in Runtime state. */
13
+ export class RuntimeTelemetryAggregator {
14
+ rules;
15
+ sampleCount = 0;
16
+ firstTimestamp;
17
+ lastTimestamp;
18
+ latest;
19
+ peaks = new Map();
20
+ alerts = [];
21
+ lastAlertAt = new Map();
22
+ constructor(rules = []) {
23
+ this.rules = rules;
24
+ }
25
+ ingest(envelope) {
26
+ if (envelope.schemaVersion !== 1 || !Number.isFinite(envelope.timestamp))
27
+ throw new Error('INVALID_TELEMETRY_ENVELOPE');
28
+ const emitted = [];
29
+ this.sampleCount++;
30
+ this.firstTimestamp ??= envelope.timestamp;
31
+ this.lastTimestamp = envelope.timestamp;
32
+ this.latest = structuredClone(envelope);
33
+ for (const rule of this.rules) {
34
+ const value = metricValue(envelope.snapshot, rule.metric);
35
+ if (value === undefined)
36
+ continue;
37
+ this.peaks.set(rule.metric, Math.max(this.peaks.get(rule.metric) ?? Number.NEGATIVE_INFINITY, value));
38
+ const matched = rule.direction === 'above' ? value >= rule.threshold : value <= rule.threshold;
39
+ const last = this.lastAlertAt.get(rule.id);
40
+ if (!matched || (last !== undefined && envelope.timestamp - last < (rule.cooldownMs ?? 0)))
41
+ continue;
42
+ const alert = { ruleId: rule.id, metric: rule.metric, value, threshold: rule.threshold, direction: rule.direction, timestamp: envelope.timestamp };
43
+ this.lastAlertAt.set(rule.id, envelope.timestamp);
44
+ this.alerts.push(alert);
45
+ emitted.push(alert);
46
+ }
47
+ return emitted;
48
+ }
49
+ snapshot() {
50
+ return { schemaVersion: 1, sampleCount: this.sampleCount, ...(this.firstTimestamp === undefined ? {} : { firstTimestamp: this.firstTimestamp }), ...(this.lastTimestamp === undefined ? {} : { lastTimestamp: this.lastTimestamp }), ...(this.latest === undefined ? {} : { latest: structuredClone(this.latest) }), peaks: Object.fromEntries(this.peaks.entries()), alerts: structuredClone(this.alerts) };
51
+ }
52
+ }
53
+ /** A durable, append-only exporter suitable for a local host or sidecar collector. */
54
+ export class FileRuntimeTelemetryExporter {
55
+ filePath;
56
+ pending = Promise.resolve();
57
+ constructor(filePath) {
58
+ this.filePath = filePath;
59
+ }
60
+ async publish(envelope) {
61
+ const operation = this.pending.then(async () => {
62
+ await mkdir(dirname(this.filePath), { recursive: true });
63
+ const handle = await open(this.filePath, 'a', 0o600);
64
+ try {
65
+ await handle.writeFile(`${JSON.stringify(envelope)}\n`, 'utf8');
66
+ await handle.sync();
67
+ }
68
+ finally {
69
+ await handle.close();
70
+ }
71
+ });
72
+ this.pending = operation.catch(() => undefined);
73
+ await operation;
74
+ }
75
+ }
76
+ /** Sends complete envelopes to an external collector without changing Runtime state. */
77
+ export class HttpRuntimeTelemetryExporter {
78
+ endpoint;
79
+ headers;
80
+ timeoutMs;
81
+ fetcher;
82
+ constructor(options) {
83
+ if (!options.endpoint)
84
+ throw new Error('TELEMETRY_ENDPOINT_REQUIRED');
85
+ this.endpoint = options.endpoint;
86
+ this.headers = { 'content-type': 'application/json', ...(options.headers ?? {}) };
87
+ this.timeoutMs = options.timeoutMs ?? 10_000;
88
+ if (!Number.isFinite(this.timeoutMs) || this.timeoutMs <= 0)
89
+ throw new Error('INVALID_TELEMETRY_TIMEOUT');
90
+ this.fetcher = options.fetch ?? globalThis.fetch;
91
+ }
92
+ async publish(envelope) {
93
+ const controller = new AbortController();
94
+ const timer = setTimeout(() => controller.abort(), this.timeoutMs);
95
+ try {
96
+ const response = await this.fetcher(this.endpoint, { method: 'POST', headers: this.headers, body: JSON.stringify(envelope), signal: controller.signal });
97
+ if (!response.ok)
98
+ throw new Error(`TELEMETRY_HTTP_${response.status}`);
99
+ }
100
+ catch (cause) {
101
+ if (controller.signal.aborted)
102
+ throw new Error('TELEMETRY_HTTP_TIMEOUT');
103
+ throw cause;
104
+ }
105
+ finally {
106
+ clearTimeout(timer);
107
+ }
108
+ }
109
+ }
110
+ function count(target, key) { target[key] = (target[key] ?? 0) + 1; }
111
+ function numberField(value, key) {
112
+ if (!value || typeof value !== 'object' || Array.isArray(value))
113
+ return undefined;
114
+ const field = value[key];
115
+ return typeof field === 'number' && Number.isFinite(field) ? field : undefined;
116
+ }
117
+ export function collectRuntimeTelemetry(state) {
118
+ const eventCounts = {};
119
+ for (const event of state.events)
120
+ count(eventCounts, event.type);
121
+ const agentStates = {};
122
+ for (const agent of state.agents.values())
123
+ count(agentStates, agent.state ?? 'unknown');
124
+ const laneStatuses = {};
125
+ for (const lane of state.lanes.values())
126
+ count(laneStatuses, lane.status);
127
+ const effectStates = {};
128
+ const effectKinds = {};
129
+ for (const effect of state.effects.values()) {
130
+ count(effectStates, effect.state);
131
+ count(effectKinds, effect.kind);
132
+ }
133
+ const attempts = [];
134
+ const routeRejections = {};
135
+ const usage = { inputTokens: 0, outputTokens: 0, cachedInputTokens: 0, uncachedInputTokens: 0, latencyMs: 0, costByCurrency: {} };
136
+ let metadataEvents = 0;
137
+ for (const event of state.events) {
138
+ if (event.type !== 'effect.execution_metadata' || !event.effectId)
139
+ continue;
140
+ metadataEvents++;
141
+ const metadata = event.data && typeof event.data === 'object' && !Array.isArray(event.data) ? event.data : {};
142
+ const routeList = Array.isArray(metadata.routes) ? metadata.routes : [];
143
+ for (const route of routeList) {
144
+ if (!route || typeof route !== 'object' || Array.isArray(route))
145
+ continue;
146
+ const item = route;
147
+ if (item.accepted === false && Array.isArray(item.reasons))
148
+ for (const reason of item.reasons)
149
+ if (typeof reason === 'string')
150
+ count(routeRejections, reason);
151
+ }
152
+ const recorded = Array.isArray(metadata.attempts) ? metadata.attempts : [];
153
+ const effect = state.effects.get(event.effectId);
154
+ for (const item of recorded) {
155
+ if (!item || typeof item !== 'object' || Array.isArray(item))
156
+ continue;
157
+ const value = item;
158
+ if (typeof value.attemptId !== 'string' || typeof value.attemptNo !== 'number' || typeof value.modelId !== 'string' || typeof value.providerId !== 'string')
159
+ continue;
160
+ const attempt = { effectId: event.effectId, agentId: effect?.agentId ?? null, laneId: effect?.ownerLaneId ?? null, attemptId: value.attemptId, attemptNo: value.attemptNo, modelId: value.modelId, providerId: value.providerId, ...(typeof value.slotWaitMs === 'number' ? { slotWaitMs: value.slotWaitMs } : {}), ...(value.usage === undefined ? {} : { usage: value.usage }) };
161
+ attempts.push(attempt);
162
+ const attemptUsage = value.usage;
163
+ for (const field of ['inputTokens', 'outputTokens', 'cachedInputTokens', 'uncachedInputTokens', 'latencyMs'])
164
+ usage[field] += numberField(attemptUsage, field) ?? 0;
165
+ if (attemptUsage && typeof attemptUsage === 'object' && !Array.isArray(attemptUsage)) {
166
+ const cost = attemptUsage.cost;
167
+ if (cost && typeof cost === 'object' && !Array.isArray(cost)) {
168
+ const amount = numberField(cost, 'amount');
169
+ const currency = cost.currency;
170
+ if (amount !== undefined && typeof currency === 'string')
171
+ usage.costByCurrency[currency] = (usage.costByCurrency[currency] ?? 0) + amount;
172
+ }
173
+ }
174
+ }
175
+ }
176
+ return { eventCounts, agents: { total: state.agents.size, byState: agentStates }, lanes: { total: state.lanes.size, byStatus: laneStatuses }, effects: { total: state.effects.size, byState: effectStates, byKind: effectKinds }, llm: { effects: [...state.effects.values()].filter((effect) => effect.kind === 'llm').length, metadataEvents, attempts, routeRejections, usage } };
177
+ }
@@ -0,0 +1,158 @@
1
+ import type { EffectExecution } from './runtime.js';
2
+ import type { EffectRecord, JsonValue, RuntimeError } from '../core/types.js';
3
+ export interface WorkerTaskRecord {
4
+ id: string;
5
+ payload: JsonValue;
6
+ state: 'queued' | 'leased' | 'succeeded' | 'failed' | 'cancelled';
7
+ attempt: number;
8
+ leaseId?: string;
9
+ workerId?: string;
10
+ leaseExpiresAt?: number;
11
+ leaseMs?: number;
12
+ idempotencyKey?: string;
13
+ result?: JsonValue;
14
+ error?: RuntimeError;
15
+ }
16
+ export interface WorkerLease {
17
+ task: WorkerTaskRecord;
18
+ workerId: string;
19
+ leaseId: string;
20
+ }
21
+ export interface WorkerCoordinatorSnapshot {
22
+ schemaVersion: 1;
23
+ sequence: number;
24
+ tasks: WorkerTaskRecord[];
25
+ idempotency: Record<string, string>;
26
+ integrity?: {
27
+ algorithm: 'sha256';
28
+ digest: string;
29
+ };
30
+ }
31
+ export interface WorkerPersistenceBackend {
32
+ load(): Promise<WorkerCoordinatorSnapshot | undefined>;
33
+ save(snapshot: WorkerCoordinatorSnapshot, expectedDigest?: string): Promise<void>;
34
+ }
35
+ export declare class FileWorkerPersistenceBackend implements WorkerPersistenceBackend {
36
+ readonly filePath: string;
37
+ private pending;
38
+ constructor(filePath: string);
39
+ load(): Promise<WorkerCoordinatorSnapshot | undefined>;
40
+ save(snapshot: WorkerCoordinatorSnapshot, expectedDigest?: string): Promise<void>;
41
+ }
42
+ /** Durable SQLite snapshot backend for sharing WorkerCoordinator state between processes. */
43
+ export declare class SqliteWorkerPersistenceBackend implements WorkerPersistenceBackend {
44
+ readonly filePath: string;
45
+ private database;
46
+ private tail;
47
+ constructor(filePath: string);
48
+ load(): Promise<WorkerCoordinatorSnapshot | undefined>;
49
+ save(snapshot: WorkerCoordinatorSnapshot, expectedDigest?: string): Promise<void>;
50
+ close(): Promise<void>;
51
+ private open;
52
+ private enqueue;
53
+ }
54
+ export type WorkerHandler = (payload: JsonValue, signal: AbortSignal) => Promise<JsonValue>;
55
+ export interface WorkerSubmitOptions {
56
+ taskId?: string;
57
+ idempotencyKey?: string;
58
+ leaseMs?: number;
59
+ signal?: AbortSignal;
60
+ }
61
+ export interface WorkerCoordinatorOptions {
62
+ persistenceBackend?: WorkerPersistenceBackend;
63
+ }
64
+ export interface WorkerCoordinatorContract {
65
+ submit(payload: JsonValue, options?: WorkerSubmitOptions): Promise<JsonValue>;
66
+ register(workerId: string, handler: WorkerHandler): () => void;
67
+ registerRemote(workerId: string): () => void;
68
+ unregister(workerId: string): void;
69
+ claim(workerId: string, now?: number): WorkerLease | undefined;
70
+ renewLease(workerId: string, leaseId: string, now?: number, leaseMs?: number): number | undefined;
71
+ completeRemote(workerId: string, leaseId: string, value: JsonValue, now?: number): boolean;
72
+ failRemote(workerId: string, leaseId: string, error: RuntimeError, now?: number): boolean;
73
+ get(taskId: string): WorkerTaskRecord | undefined;
74
+ cancel(taskId: string, reason?: string): boolean;
75
+ recoverExpired(now?: number): string[];
76
+ }
77
+ /** A lease-based worker coordinator. A network transport can implement the same claim/complete contract. */
78
+ export declare class WorkerCoordinator implements WorkerCoordinatorContract {
79
+ private readonly tasks;
80
+ private readonly deferreds;
81
+ private readonly idempotency;
82
+ private readonly handlers;
83
+ private readonly remoteWorkers;
84
+ private readonly activeLeases;
85
+ private readonly persistenceBackend;
86
+ private persistenceDigest;
87
+ private persistencePending;
88
+ private sequence;
89
+ constructor(options?: WorkerCoordinatorOptions);
90
+ static restore(snapshot: WorkerCoordinatorSnapshot, options?: WorkerCoordinatorOptions): WorkerCoordinator;
91
+ static fromPersistence(backend: WorkerPersistenceBackend): Promise<WorkerCoordinator>;
92
+ flushPersistence(): Promise<void>;
93
+ register(workerId: string, handler: WorkerHandler): () => void;
94
+ registerRemote(workerId: string): () => void;
95
+ unregister(workerId: string): void;
96
+ submit(payload: JsonValue, options?: WorkerSubmitOptions): Promise<JsonValue>;
97
+ recoverExpired(now?: number): string[];
98
+ claim(workerId: string, now?: number): WorkerLease | undefined;
99
+ renewLease(workerId: string, leaseId: string, now?: number, leaseMs?: number): number | undefined;
100
+ completeRemote(workerId: string, leaseId: string, value: JsonValue, _now?: number): boolean;
101
+ failRemote(workerId: string, leaseId: string, error: RuntimeError, _now?: number): boolean;
102
+ get(taskId: string): WorkerTaskRecord | undefined;
103
+ snapshot(): WorkerCoordinatorSnapshot;
104
+ cancel(taskId: string, reason?: string): boolean;
105
+ inspect(): WorkerTaskRecord[];
106
+ private schedulePersistence;
107
+ private requeue;
108
+ private ensureDeferred;
109
+ private promiseFor;
110
+ private pump;
111
+ private assign;
112
+ private taskForLease;
113
+ private settleRemote;
114
+ private completeTask;
115
+ private failTask;
116
+ }
117
+ /**
118
+ * A WorkerCoordinator whose lease transitions are owned by SQLite transactions.
119
+ * Separate processes may open the same database and race safely on the same queue.
120
+ */
121
+ export declare class SqliteDistributedWorkerCoordinator implements WorkerCoordinatorContract {
122
+ readonly filePath: string;
123
+ private database;
124
+ private readonly deferreds;
125
+ private readonly watchers;
126
+ private readonly handlers;
127
+ private readonly remoteWorkers;
128
+ private readonly activeLeases;
129
+ constructor(filePath: string);
130
+ register(workerId: string, handler: WorkerHandler): () => void;
131
+ registerRemote(workerId: string): () => void;
132
+ unregister(workerId: string): void;
133
+ submit(payload: JsonValue, options?: WorkerSubmitOptions): Promise<JsonValue>;
134
+ claim(workerId: string, now?: number): WorkerLease | undefined;
135
+ renewLease(workerId: string, leaseId: string, now?: number, leaseMs?: number): number | undefined;
136
+ completeRemote(workerId: string, leaseId: string, value: JsonValue, now?: number): boolean;
137
+ failRemote(workerId: string, leaseId: string, error: RuntimeError, now?: number): boolean;
138
+ get(taskId: string): WorkerTaskRecord | undefined;
139
+ inspect(): WorkerTaskRecord[];
140
+ cancel(taskId: string, reason?: string): boolean;
141
+ recoverExpired(now?: number): string[];
142
+ close(): void;
143
+ private pump;
144
+ private ensureDeferred;
145
+ private watch;
146
+ private taskIdForLease;
147
+ private getByLease;
148
+ private requeueWorker;
149
+ private nextId;
150
+ private leaseMs;
151
+ private rowToTask;
152
+ private changedRows;
153
+ private open;
154
+ private withTransaction;
155
+ }
156
+ export declare function createWorkerEffectExecutor(coordinator: Pick<WorkerCoordinatorContract, 'submit'>, options?: {
157
+ leaseMs?: number;
158
+ }): (effect: Readonly<EffectRecord>, signal: AbortSignal) => Promise<EffectExecution>;