hungry-ghost-hive 0.45.0 → 0.46.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 (113) hide show
  1. package/dist/cli/commands/cluster.d.ts.map +1 -1
  2. package/dist/cli/commands/cluster.js +348 -1
  3. package/dist/cli/commands/cluster.js.map +1 -1
  4. package/dist/cli/commands/cluster.test.js +313 -9
  5. package/dist/cli/commands/cluster.test.js.map +1 -1
  6. package/dist/cli/commands/req-spawn.test.d.ts +2 -0
  7. package/dist/cli/commands/req-spawn.test.d.ts.map +1 -0
  8. package/dist/cli/commands/req-spawn.test.js +116 -0
  9. package/dist/cli/commands/req-spawn.test.js.map +1 -0
  10. package/dist/cli/commands/req.d.ts.map +1 -1
  11. package/dist/cli/commands/req.js +21 -13
  12. package/dist/cli/commands/req.js.map +1 -1
  13. package/dist/cluster/cluster-http-server.d.ts +32 -0
  14. package/dist/cluster/cluster-http-server.d.ts.map +1 -1
  15. package/dist/cluster/cluster-http-server.js +42 -0
  16. package/dist/cluster/cluster-http-server.js.map +1 -1
  17. package/dist/cluster/distributed-runtime-coverage.test.js +9 -0
  18. package/dist/cluster/distributed-runtime-coverage.test.js.map +1 -1
  19. package/dist/cluster/distributed-system.test.js +135 -0
  20. package/dist/cluster/distributed-system.test.js.map +1 -1
  21. package/dist/cluster/events.d.ts +23 -0
  22. package/dist/cluster/events.d.ts.map +1 -1
  23. package/dist/cluster/events.js +74 -0
  24. package/dist/cluster/events.js.map +1 -1
  25. package/dist/cluster/heartbeat-manager.d.ts +2 -0
  26. package/dist/cluster/heartbeat-manager.d.ts.map +1 -1
  27. package/dist/cluster/heartbeat-manager.js +42 -6
  28. package/dist/cluster/heartbeat-manager.js.map +1 -1
  29. package/dist/cluster/membership.test.d.ts +2 -0
  30. package/dist/cluster/membership.test.d.ts.map +1 -0
  31. package/dist/cluster/membership.test.js +416 -0
  32. package/dist/cluster/membership.test.js.map +1 -0
  33. package/dist/cluster/partition-safety.test.d.ts +2 -0
  34. package/dist/cluster/partition-safety.test.d.ts.map +1 -0
  35. package/dist/cluster/partition-safety.test.js +440 -0
  36. package/dist/cluster/partition-safety.test.js.map +1 -0
  37. package/dist/cluster/raft-state-machine.d.ts +33 -1
  38. package/dist/cluster/raft-state-machine.d.ts.map +1 -1
  39. package/dist/cluster/raft-state-machine.js +65 -3
  40. package/dist/cluster/raft-state-machine.js.map +1 -1
  41. package/dist/cluster/raft-store.d.ts +26 -1
  42. package/dist/cluster/raft-store.d.ts.map +1 -1
  43. package/dist/cluster/raft-store.js +137 -0
  44. package/dist/cluster/raft-store.js.map +1 -1
  45. package/dist/cluster/replication-lag.test.d.ts +2 -0
  46. package/dist/cluster/replication-lag.test.d.ts.map +1 -0
  47. package/dist/cluster/replication-lag.test.js +239 -0
  48. package/dist/cluster/replication-lag.test.js.map +1 -0
  49. package/dist/cluster/replication.d.ts +2 -2
  50. package/dist/cluster/replication.d.ts.map +1 -1
  51. package/dist/cluster/replication.js +1 -1
  52. package/dist/cluster/replication.js.map +1 -1
  53. package/dist/cluster/runtime.d.ts +78 -0
  54. package/dist/cluster/runtime.d.ts.map +1 -1
  55. package/dist/cluster/runtime.js +400 -13
  56. package/dist/cluster/runtime.js.map +1 -1
  57. package/dist/cluster/state-recovery.test.d.ts +2 -0
  58. package/dist/cluster/state-recovery.test.d.ts.map +1 -0
  59. package/dist/cluster/state-recovery.test.js +310 -0
  60. package/dist/cluster/state-recovery.test.js.map +1 -0
  61. package/dist/cluster/types.d.ts +30 -0
  62. package/dist/cluster/types.d.ts.map +1 -1
  63. package/dist/config/schema.d.ts +48 -0
  64. package/dist/config/schema.d.ts.map +1 -1
  65. package/dist/config/schema.js +11 -0
  66. package/dist/config/schema.js.map +1 -1
  67. package/dist/context-files/generator.js +1 -1
  68. package/dist/context-files/generator.js.map +1 -1
  69. package/dist/context-files/generator.test.js +51 -0
  70. package/dist/context-files/generator.test.js.map +1 -1
  71. package/dist/orchestrator/orphan-recovery.d.ts +1 -1
  72. package/dist/orchestrator/orphan-recovery.d.ts.map +1 -1
  73. package/dist/orchestrator/orphan-recovery.js +4 -4
  74. package/dist/orchestrator/orphan-recovery.js.map +1 -1
  75. package/dist/orchestrator/prompt-templates.d.ts +3 -1
  76. package/dist/orchestrator/prompt-templates.d.ts.map +1 -1
  77. package/dist/orchestrator/prompt-templates.js +45 -8
  78. package/dist/orchestrator/prompt-templates.js.map +1 -1
  79. package/dist/orchestrator/prompt-templates.test.js +210 -0
  80. package/dist/orchestrator/prompt-templates.test.js.map +1 -1
  81. package/dist/orchestrator/scheduler.d.ts +1 -0
  82. package/dist/orchestrator/scheduler.d.ts.map +1 -1
  83. package/dist/orchestrator/scheduler.js +15 -10
  84. package/dist/orchestrator/scheduler.js.map +1 -1
  85. package/dist/orchestrator/scheduler.test.js +97 -6
  86. package/dist/orchestrator/scheduler.test.js.map +1 -1
  87. package/package.json +1 -1
  88. package/src/cli/commands/cluster.test.ts +387 -9
  89. package/src/cli/commands/cluster.ts +486 -1
  90. package/src/cli/commands/req-spawn.test.ts +153 -0
  91. package/src/cli/commands/req.ts +31 -18
  92. package/src/cluster/cluster-http-server.ts +80 -0
  93. package/src/cluster/distributed-runtime-coverage.test.ts +9 -0
  94. package/src/cluster/distributed-system.test.ts +168 -0
  95. package/src/cluster/events.ts +90 -0
  96. package/src/cluster/heartbeat-manager.ts +48 -6
  97. package/src/cluster/membership.test.ts +498 -0
  98. package/src/cluster/partition-safety.test.ts +523 -0
  99. package/src/cluster/raft-state-machine.ts +76 -4
  100. package/src/cluster/raft-store.ts +167 -1
  101. package/src/cluster/replication-lag.test.ts +284 -0
  102. package/src/cluster/replication.ts +6 -0
  103. package/src/cluster/runtime.ts +551 -12
  104. package/src/cluster/state-recovery.test.ts +420 -0
  105. package/src/cluster/types.ts +32 -0
  106. package/src/config/schema.ts +11 -0
  107. package/src/context-files/generator.test.ts +55 -0
  108. package/src/context-files/generator.ts +5 -5
  109. package/src/orchestrator/orphan-recovery.ts +32 -13
  110. package/src/orchestrator/prompt-templates.test.ts +263 -0
  111. package/src/orchestrator/prompt-templates.ts +49 -8
  112. package/src/orchestrator/scheduler.test.ts +129 -6
  113. package/src/orchestrator/scheduler.ts +46 -20
@@ -0,0 +1,239 @@
1
+ // Licensed under the Hungry Ghost Hive License. See LICENSE.
2
+ import { mkdirSync, mkdtempSync, rmSync } from 'fs';
3
+ import { createServer } from 'net';
4
+ import { tmpdir } from 'os';
5
+ import { join } from 'path';
6
+ import { afterEach, describe, expect, it } from 'vitest';
7
+ import { createDatabase } from '../db/client.js';
8
+ import { ClusterRuntime, fetchReplicationLag } from './runtime.js';
9
+ const tempRoots = [];
10
+ afterEach(() => {
11
+ for (const root of tempRoots.splice(0)) {
12
+ rmSync(root, { recursive: true, force: true });
13
+ }
14
+ });
15
+ describe('replication lag tracking', () => {
16
+ it('returns null when cluster is disabled', async () => {
17
+ const result = await fetchReplicationLag({
18
+ enabled: false,
19
+ node_id: 'node-test',
20
+ listen_host: '127.0.0.1',
21
+ listen_port: 9999,
22
+ public_url: 'http://127.0.0.1:9999',
23
+ peers: [],
24
+ heartbeat_interval_ms: 2000,
25
+ election_timeout_min_ms: 3000,
26
+ election_timeout_max_ms: 6000,
27
+ sync_interval_ms: 5000,
28
+ request_timeout_ms: 5000,
29
+ story_similarity_threshold: 0.92,
30
+ });
31
+ expect(result).toBeNull();
32
+ });
33
+ it('getReplicationLag returns empty peers when no peers configured', async () => {
34
+ if (!(await canListenOnLocalhost()))
35
+ return;
36
+ const root = mkdtempSync(join(tmpdir(), 'hive-repl-lag-'));
37
+ tempRoots.push(root);
38
+ const hiveDir = join(root, '.hive');
39
+ mkdirSync(hiveDir, { recursive: true });
40
+ const { runtime } = await startRuntimeWithRetries(hiveDir, {
41
+ enabled: true,
42
+ node_id: 'node-lag-test',
43
+ listen_host: '127.0.0.1',
44
+ peers: [],
45
+ heartbeat_interval_ms: 100,
46
+ election_timeout_min_ms: 150,
47
+ election_timeout_max_ms: 250,
48
+ sync_interval_ms: 200,
49
+ request_timeout_ms: 500,
50
+ story_similarity_threshold: 0.92,
51
+ });
52
+ const lag = runtime.getReplicationLag();
53
+ expect(lag.node_id).toBe('node-lag-test');
54
+ expect(lag.peers).toEqual([]);
55
+ expect(lag.last_sync_at).toBeNull();
56
+ expect(lag.total_local_events).toBe(0);
57
+ expect(lag.version_vector).toEqual({});
58
+ await runtime.stop();
59
+ });
60
+ it('tracks peer lag after sync with unreachable peer', async () => {
61
+ if (!(await canListenOnLocalhost()))
62
+ return;
63
+ const root = mkdtempSync(join(tmpdir(), 'hive-repl-lag-unreach-'));
64
+ tempRoots.push(root);
65
+ const hiveDir = join(root, '.hive');
66
+ mkdirSync(hiveDir, { recursive: true });
67
+ const db = await createDatabase(join(hiveDir, 'hive.db'));
68
+ const { runtime } = await startRuntimeWithRetries(hiveDir, {
69
+ enabled: true,
70
+ node_id: 'node-lag-unreach',
71
+ listen_host: '127.0.0.1',
72
+ peers: [
73
+ { id: 'node-lag-unreach', url: 'http://127.0.0.1:1' },
74
+ { id: 'peer-ghost', url: 'http://127.0.0.1:19999' },
75
+ ],
76
+ heartbeat_interval_ms: 100,
77
+ election_timeout_min_ms: 150,
78
+ election_timeout_max_ms: 250,
79
+ sync_interval_ms: 200,
80
+ request_timeout_ms: 500,
81
+ story_similarity_threshold: 0.92,
82
+ });
83
+ await runtime.sync(db.db);
84
+ const lag = runtime.getReplicationLag();
85
+ expect(lag.node_id).toBe('node-lag-unreach');
86
+ expect(lag.peers).toHaveLength(1);
87
+ expect(lag.peers[0].peer_id).toBe('peer-ghost');
88
+ expect(lag.peers[0].reachable).toBe(false);
89
+ expect(lag.peers[0].last_sync_at).not.toBeNull();
90
+ expect(lag.peers[0].last_sync_duration_ms).toBeGreaterThanOrEqual(0);
91
+ expect(lag.last_sync_at).not.toBeNull();
92
+ await runtime.stop();
93
+ db.close();
94
+ });
95
+ it('serves replication-lag via HTTP endpoint', async () => {
96
+ if (!(await canListenOnLocalhost()))
97
+ return;
98
+ const root = mkdtempSync(join(tmpdir(), 'hive-repl-lag-http-'));
99
+ tempRoots.push(root);
100
+ const hiveDir = join(root, '.hive');
101
+ mkdirSync(hiveDir, { recursive: true });
102
+ const { runtime, config } = await startRuntimeWithRetries(hiveDir, {
103
+ enabled: true,
104
+ node_id: 'node-lag-http',
105
+ listen_host: '127.0.0.1',
106
+ peers: [],
107
+ heartbeat_interval_ms: 100,
108
+ election_timeout_min_ms: 150,
109
+ election_timeout_max_ms: 250,
110
+ sync_interval_ms: 200,
111
+ request_timeout_ms: 500,
112
+ story_similarity_threshold: 0.92,
113
+ });
114
+ const url = `http://127.0.0.1:${config.listen_port}/cluster/v1/replication-lag`;
115
+ const response = await fetch(url);
116
+ expect(response.ok).toBe(true);
117
+ const body = (await response.json());
118
+ expect(body.node_id).toBe('node-lag-http');
119
+ expect(body.peers).toEqual([]);
120
+ expect(body.last_sync_at).toBeNull();
121
+ await runtime.stop();
122
+ });
123
+ it('tracks lag for reachable peer with events', async () => {
124
+ if (!(await canListenOnLocalhost()))
125
+ return;
126
+ const root = mkdtempSync(join(tmpdir(), 'hive-repl-lag-two-'));
127
+ tempRoots.push(root);
128
+ const hiveDirA = join(root, '.hive-a');
129
+ const hiveDirB = join(root, '.hive-b');
130
+ mkdirSync(hiveDirA, { recursive: true });
131
+ mkdirSync(hiveDirB, { recursive: true });
132
+ const dbA = await createDatabase(join(hiveDirA, 'hive.db'));
133
+ const dbB = await createDatabase(join(hiveDirB, 'hive.db'));
134
+ // Start node B first (the peer)
135
+ const { runtime: runtimeB, config: configB } = await startRuntimeWithRetries(hiveDirB, {
136
+ enabled: true,
137
+ node_id: 'node-b',
138
+ listen_host: '127.0.0.1',
139
+ peers: [],
140
+ heartbeat_interval_ms: 100,
141
+ election_timeout_min_ms: 150,
142
+ election_timeout_max_ms: 250,
143
+ sync_interval_ms: 200,
144
+ request_timeout_ms: 500,
145
+ story_similarity_threshold: 0.92,
146
+ });
147
+ // Insert data on node B and sync so it has events in cache
148
+ dbB.db.run(`INSERT INTO stories (id, requirement_id, team_id, title, description, status, created_at, updated_at)
149
+ VALUES ('STORY-B1', NULL, NULL, 'Story from B', 'Test story', 'planned', ?, ?)`, [new Date().toISOString(), new Date().toISOString()]);
150
+ await runtimeB.sync(dbB.db);
151
+ dbB.save();
152
+ // Start node A with node B as a peer
153
+ const { runtime: runtimeA } = await startRuntimeWithRetries(hiveDirA, {
154
+ enabled: true,
155
+ node_id: 'node-a',
156
+ listen_host: '127.0.0.1',
157
+ peers: [
158
+ { id: 'node-a', url: 'http://127.0.0.1:1' },
159
+ { id: 'node-b', url: `http://127.0.0.1:${configB.listen_port}` },
160
+ ],
161
+ heartbeat_interval_ms: 100,
162
+ election_timeout_min_ms: 150,
163
+ election_timeout_max_ms: 250,
164
+ sync_interval_ms: 200,
165
+ request_timeout_ms: 500,
166
+ story_similarity_threshold: 0.92,
167
+ });
168
+ // Sync node A - it should pull events from B
169
+ await runtimeA.sync(dbA.db);
170
+ const lag = runtimeA.getReplicationLag();
171
+ expect(lag.node_id).toBe('node-a');
172
+ expect(lag.peers).toHaveLength(1);
173
+ expect(lag.peers[0].peer_id).toBe('node-b');
174
+ expect(lag.peers[0].reachable).toBe(true);
175
+ expect(lag.peers[0].events_behind).toBeGreaterThanOrEqual(0);
176
+ expect(lag.peers[0].last_sync_at).not.toBeNull();
177
+ expect(lag.peers[0].last_sync_duration_ms).toBeGreaterThanOrEqual(0);
178
+ expect(lag.last_sync_at).not.toBeNull();
179
+ await runtimeA.stop();
180
+ await runtimeB.stop();
181
+ dbA.close();
182
+ dbB.close();
183
+ });
184
+ });
185
+ async function getFreePort() {
186
+ return new Promise((resolve, reject) => {
187
+ const server = createServer();
188
+ server.once('error', reject);
189
+ server.listen(0, '127.0.0.1', () => {
190
+ const address = server.address();
191
+ if (!address || typeof address === 'string') {
192
+ server.close(() => reject(new Error('Failed to allocate free port')));
193
+ return;
194
+ }
195
+ const port = address.port;
196
+ server.close(err => {
197
+ if (err) {
198
+ reject(err);
199
+ return;
200
+ }
201
+ resolve(port);
202
+ });
203
+ });
204
+ });
205
+ }
206
+ async function canListenOnLocalhost() {
207
+ try {
208
+ await getFreePort();
209
+ return true;
210
+ }
211
+ catch {
212
+ return false;
213
+ }
214
+ }
215
+ async function startRuntimeWithRetries(hiveDir, baseConfig, attempts = 5) {
216
+ let lastError;
217
+ for (let i = 0; i < attempts; i++) {
218
+ const port = await getFreePort();
219
+ const config = {
220
+ ...baseConfig,
221
+ listen_port: port,
222
+ public_url: `http://127.0.0.1:${port}`,
223
+ };
224
+ const runtime = new ClusterRuntime(config, { hiveDir });
225
+ try {
226
+ await runtime.start();
227
+ return { runtime, config };
228
+ }
229
+ catch (error) {
230
+ lastError = error;
231
+ const err = error;
232
+ if (err.code !== 'EADDRINUSE') {
233
+ throw error;
234
+ }
235
+ }
236
+ }
237
+ throw lastError instanceof Error ? lastError : new Error('Failed to start cluster runtime');
238
+ }
239
+ //# sourceMappingURL=replication-lag.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"replication-lag.test.js","sourceRoot":"","sources":["../../src/cluster/replication-lag.test.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
- export type { ClusterEvent, ClusterEventVersion, ReplicatedTable, ReplicationOp, VersionVector, } from './types.js';
2
- export { ensureClusterTables, getAllClusterEvents, getDeltaEvents, getVersionVector, } from './events.js';
1
+ export type { ClusterEvent, ClusterEventVersion, RaftSnapshot, ReplicatedTable, ReplicationOp, VersionVector, } from './types.js';
2
+ export { ensureClusterTables, getAllClusterEvents, getClusterEventCount, getDeltaEvents, getEffectiveVersionVector, getSnapshotVersionVector, getVersionVector, pruneClusterEvents, setSnapshotVersionVector, } from './events.js';
3
3
  export { applyRemoteEvents, scanLocalChanges } from './sync.js';
4
4
  export { mergeSimilarStories } from './story-merge.js';
5
5
  //# sourceMappingURL=replication.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"replication.d.ts","sourceRoot":"","sources":["../../src/cluster/replication.ts"],"names":[],"mappings":"AAGA,YAAY,EACV,YAAY,EACZ,mBAAmB,EACnB,eAAe,EACf,aAAa,EACb,aAAa,GACd,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,mBAAmB,EACnB,mBAAmB,EACnB,cAAc,EACd,gBAAgB,GACjB,MAAM,aAAa,CAAC;AAGrB,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAGhE,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC"}
1
+ {"version":3,"file":"replication.d.ts","sourceRoot":"","sources":["../../src/cluster/replication.ts"],"names":[],"mappings":"AAGA,YAAY,EACV,YAAY,EACZ,mBAAmB,EACnB,YAAY,EACZ,eAAe,EACf,aAAa,EACb,aAAa,GACd,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,mBAAmB,EACnB,mBAAmB,EACnB,oBAAoB,EACpB,cAAc,EACd,yBAAyB,EACzB,wBAAwB,EACxB,gBAAgB,EAChB,kBAAkB,EAClB,wBAAwB,GACzB,MAAM,aAAa,CAAC;AAGrB,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAGhE,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC"}
@@ -1,6 +1,6 @@
1
1
  // Licensed under the Hungry Ghost Hive License. See LICENSE.
2
2
  // Re-export event functions
3
- export { ensureClusterTables, getAllClusterEvents, getDeltaEvents, getVersionVector, } from './events.js';
3
+ export { ensureClusterTables, getAllClusterEvents, getClusterEventCount, getDeltaEvents, getEffectiveVersionVector, getSnapshotVersionVector, getVersionVector, pruneClusterEvents, setSnapshotVersionVector, } from './events.js';
4
4
  // Re-export sync functions
5
5
  export { applyRemoteEvents, scanLocalChanges } from './sync.js';
6
6
  // Re-export story merge function
@@ -1 +1 @@
1
- {"version":3,"file":"replication.js","sourceRoot":"","sources":["../../src/cluster/replication.ts"],"names":[],"mappings":"AAAA,6DAA6D;AAW7D,4BAA4B;AAC5B,OAAO,EACL,mBAAmB,EACnB,mBAAmB,EACnB,cAAc,EACd,gBAAgB,GACjB,MAAM,aAAa,CAAC;AAErB,2BAA2B;AAC3B,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAEhE,iCAAiC;AACjC,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC"}
1
+ {"version":3,"file":"replication.js","sourceRoot":"","sources":["../../src/cluster/replication.ts"],"names":[],"mappings":"AAAA,6DAA6D;AAY7D,4BAA4B;AAC5B,OAAO,EACL,mBAAmB,EACnB,mBAAmB,EACnB,oBAAoB,EACpB,cAAc,EACd,yBAAyB,EACzB,wBAAwB,EACxB,gBAAgB,EAChB,kBAAkB,EAClB,wBAAwB,GACzB,MAAM,aAAa,CAAC;AAErB,2BAA2B;AAC3B,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAEhE,iCAAiC;AACjC,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC"}
@@ -1,5 +1,7 @@
1
1
  import type { Database } from 'sql.js';
2
2
  import type { ClusterConfig } from '../config/schema.js';
3
+ import { type MembershipJoinRequest, type MembershipJoinResponse, type MembershipLeaveRequest, type MembershipLeaveResponse } from './cluster-http-server.js';
4
+ import { type ClusterEvent, type VersionVector } from './replication.js';
3
5
  type NodeRole = 'leader' | 'follower' | 'candidate';
4
6
  interface ClusterRuntimeOptions {
5
7
  hiveDir?: string;
@@ -17,6 +19,9 @@ export interface ClusterStatus {
17
19
  is_leader: boolean;
18
20
  leader_id: string | null;
19
21
  leader_url: string | null;
22
+ fencing_token: number;
23
+ leader_lease_valid: boolean;
24
+ leader_lease_duration_ms: number;
20
25
  raft_commit_index: number;
21
26
  raft_last_applied: number;
22
27
  raft_last_log_index: number;
@@ -24,12 +29,38 @@ export interface ClusterStatus {
24
29
  id: string;
25
30
  url: string;
26
31
  }>;
32
+ /** True while the node is performing snapshot-based catch-up and not yet election-eligible. */
33
+ is_catching_up: boolean;
27
34
  }
28
35
  export interface ClusterSyncResult {
29
36
  local_events_emitted: number;
30
37
  imported_events_applied: number;
31
38
  merged_duplicate_stories: number;
32
39
  durable_log_entries_appended: number;
40
+ log_entries_compacted: number;
41
+ cluster_events_pruned: number;
42
+ /** True when this sync triggered snapshot-based recovery rather than delta sync. */
43
+ used_snapshot_recovery: boolean;
44
+ /** Number of rows applied from the snapshot (0 when delta sync was used). */
45
+ catch_up_applied: number;
46
+ /** Total rows in the snapshot (0 when delta sync was used). */
47
+ catch_up_total: number;
48
+ }
49
+ export interface PeerReplicationLag {
50
+ peer_id: string;
51
+ peer_url: string;
52
+ reachable: boolean;
53
+ events_behind: number;
54
+ last_sync_at: string | null;
55
+ last_sync_duration_ms: number | null;
56
+ last_sync_events_applied: number;
57
+ }
58
+ export interface ReplicationLagSummary {
59
+ node_id: string;
60
+ total_local_events: number;
61
+ version_vector: VersionVector;
62
+ peers: PeerReplicationLag[];
63
+ last_sync_at: string | null;
33
64
  }
34
65
  export declare class ClusterRuntime {
35
66
  private readonly config;
@@ -38,6 +69,11 @@ export declare class ClusterRuntime {
38
69
  private stopping;
39
70
  private eventCache;
40
71
  private versionVectorCache;
72
+ private lastCompactionAt;
73
+ private peerLagMap;
74
+ private lastSyncAt;
75
+ /** Cached full snapshot refreshed on every sync, served to recovering nodes. */
76
+ private cachedSnapshot;
41
77
  private readonly raft;
42
78
  private readonly heartbeat;
43
79
  private readonly httpServer;
@@ -46,16 +82,58 @@ export declare class ClusterRuntime {
46
82
  stop(): Promise<void>;
47
83
  isEnabled(): boolean;
48
84
  isLeader(): boolean;
85
+ getReplicationLag(): ReplicationLagSummary;
49
86
  getStatus(): ClusterStatus;
50
87
  sync(db: Database): Promise<ClusterSyncResult>;
88
+ handleMembershipJoin(request: MembershipJoinRequest): MembershipJoinResponse;
89
+ handleMembershipLeave(request: MembershipLeaveRequest): MembershipLeaveResponse;
90
+ private maybeCompact;
51
91
  private refreshCache;
52
92
  private pullEventsFromPeers;
93
+ /**
94
+ * Returns true when the delta response is missing events the peer should have.
95
+ * This happens when the peer's event cache has been truncated (log compaction)
96
+ * and can no longer provide all events since our last known version.
97
+ */
98
+ private isDeltaInsufficient;
99
+ /**
100
+ * Requests a full snapshot from the given peer and applies it locally.
101
+ * Marks the node as no longer catching up once complete.
102
+ * Returns { applied, total } on success, null on failure.
103
+ */
104
+ private recoverFromSnapshot;
105
+ /**
106
+ * Applies a snapshot to the local database, upserting all rows from all tables.
107
+ * Stores the snapshot's version vector so future delta requests start from here.
108
+ */
109
+ private applySnapshot;
110
+ /**
111
+ * Builds a full snapshot of all replicated tables from the current db state.
112
+ * Called during sync to keep cachedSnapshot fresh for the HTTP endpoint.
113
+ */
114
+ private buildSnapshot;
53
115
  private requestDelta;
116
+ private requestSnapshot;
54
117
  private getDeltaFromCache;
55
118
  private postJson;
119
+ private getJson;
56
120
  private handleBackgroundError;
57
121
  private validateNetworkSecurity;
58
122
  }
123
+ export declare function fetchReplicationLag(config: ClusterConfig): Promise<ReplicationLagSummary | null>;
124
+ /**
125
+ * Fetches recent cluster events from the local runtime via the delta endpoint.
126
+ * Uses an empty version vector to request recent events up to the given limit.
127
+ */
128
+ export declare function fetchLocalClusterEvents(config: ClusterConfig, limit?: number): Promise<ClusterEvent[] | null>;
129
+ /**
130
+ * POSTs to the local cluster runtime at the given path.
131
+ */
132
+ export declare function postToLocalCluster<T>(config: ClusterConfig, path: string, body: unknown): Promise<T | null>;
133
+ /**
134
+ * POSTs to a peer cluster node at the given URL and path.
135
+ */
136
+ export declare function postToPeerCluster<T>(peerUrl: string, path: string, body: unknown, options: ClusterStatusFetchOptions): Promise<T | null>;
59
137
  export declare function fetchLocalClusterStatus(config: ClusterConfig): Promise<ClusterStatus | null>;
60
138
  export declare function fetchClusterStatusFromUrl(url: string, options: ClusterStatusFetchOptions): Promise<ClusterStatus | null>;
61
139
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../src/cluster/runtime.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AACvC,OAAO,KAAK,EAAE,aAAa,EAAqB,MAAM,qBAAqB,CAAC;AAe5E,KAAK,QAAQ,GAAG,QAAQ,GAAG,UAAU,GAAG,WAAW,CAAC;AAEpD,UAAU,qBAAqB;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,UAAU,yBAAyB;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB;AAOD,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,QAAQ,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,KAAK,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC3C;AAED,MAAM,WAAW,iBAAiB;IAChC,oBAAoB,EAAE,MAAM,CAAC;IAC7B,uBAAuB,EAAE,MAAM,CAAC;IAChC,wBAAwB,EAAE,MAAM,CAAC;IACjC,4BAA4B,EAAE,MAAM,CAAC;CACtC;AAED,qBAAa,cAAc;IAYvB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAZ1B,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,QAAQ,CAAS;IAEzB,OAAO,CAAC,UAAU,CAAsB;IACxC,OAAO,CAAC,kBAAkB,CAAqB;IAE/C,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAmB;IACxC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAmB;IAC7C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAoB;gBAG5B,MAAM,EAAE,aAAa,EACrB,OAAO,GAAE,qBAA0B;IAwBhD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAoBtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAiB3B,SAAS,IAAI,OAAO;IAIpB,QAAQ,IAAI,OAAO;IAKnB,SAAS,IAAI,aAAa;IAmBpB,IAAI,CAAC,EAAE,EAAE,QAAQ,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAmCpD,OAAO,CAAC,YAAY;YAKN,mBAAmB;YAkBnB,YAAY;IAW1B,OAAO,CAAC,iBAAiB;YASX,QAAQ;IAmBtB,OAAO,CAAC,qBAAqB;IAO7B,OAAO,CAAC,uBAAuB;CAQhC;AAED,wBAAsB,uBAAuB,CAC3C,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAyB/B;AAED,wBAAsB,yBAAyB,CAC7C,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,yBAAyB,GACjC,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAa/B"}
1
+ {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../src/cluster/runtime.ts"],"names":[],"mappings":"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"}