clawsql 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 (311) hide show
  1. package/.env.example +97 -0
  2. package/README.md +372 -0
  3. package/dist/__tests__/config/settings.test.d.ts +5 -0
  4. package/dist/__tests__/config/settings.test.d.ts.map +1 -0
  5. package/dist/__tests__/config/settings.test.js +154 -0
  6. package/dist/__tests__/config/settings.test.js.map +1 -0
  7. package/dist/__tests__/core/discovery/topology.test.d.ts +5 -0
  8. package/dist/__tests__/core/discovery/topology.test.d.ts.map +1 -0
  9. package/dist/__tests__/core/discovery/topology.test.js +191 -0
  10. package/dist/__tests__/core/discovery/topology.test.js.map +1 -0
  11. package/dist/__tests__/core/failover/executor.test.d.ts +5 -0
  12. package/dist/__tests__/core/failover/executor.test.d.ts.map +1 -0
  13. package/dist/__tests__/core/failover/executor.test.js +256 -0
  14. package/dist/__tests__/core/failover/executor.test.js.map +1 -0
  15. package/dist/__tests__/core/monitoring/collector.test.d.ts +5 -0
  16. package/dist/__tests__/core/monitoring/collector.test.d.ts.map +1 -0
  17. package/dist/__tests__/core/monitoring/collector.test.js +131 -0
  18. package/dist/__tests__/core/monitoring/collector.test.js.map +1 -0
  19. package/dist/__tests__/core/monitoring/exporters.test.d.ts +5 -0
  20. package/dist/__tests__/core/monitoring/exporters.test.d.ts.map +1 -0
  21. package/dist/__tests__/core/monitoring/exporters.test.js +90 -0
  22. package/dist/__tests__/core/monitoring/exporters.test.js.map +1 -0
  23. package/dist/__tests__/core/routing/proxysql-manager.test.d.ts +5 -0
  24. package/dist/__tests__/core/routing/proxysql-manager.test.d.ts.map +1 -0
  25. package/dist/__tests__/core/routing/proxysql-manager.test.js +155 -0
  26. package/dist/__tests__/core/routing/proxysql-manager.test.js.map +1 -0
  27. package/dist/__tests__/types/index.test.d.ts +5 -0
  28. package/dist/__tests__/types/index.test.d.ts.map +1 -0
  29. package/dist/__tests__/types/index.test.js +290 -0
  30. package/dist/__tests__/types/index.test.js.map +1 -0
  31. package/dist/__tests__/utils/exceptions.test.d.ts +5 -0
  32. package/dist/__tests__/utils/exceptions.test.d.ts.map +1 -0
  33. package/dist/__tests__/utils/exceptions.test.js +142 -0
  34. package/dist/__tests__/utils/exceptions.test.js.map +1 -0
  35. package/dist/api/routes/clusters.d.ts +7 -0
  36. package/dist/api/routes/clusters.d.ts.map +1 -0
  37. package/dist/api/routes/clusters.js +123 -0
  38. package/dist/api/routes/clusters.js.map +1 -0
  39. package/dist/api/routes/config.d.ts +7 -0
  40. package/dist/api/routes/config.d.ts.map +1 -0
  41. package/dist/api/routes/config.js +65 -0
  42. package/dist/api/routes/config.js.map +1 -0
  43. package/dist/api/routes/failover.d.ts +7 -0
  44. package/dist/api/routes/failover.d.ts.map +1 -0
  45. package/dist/api/routes/failover.js +100 -0
  46. package/dist/api/routes/failover.js.map +1 -0
  47. package/dist/api/routes/instances.d.ts +11 -0
  48. package/dist/api/routes/instances.d.ts.map +1 -0
  49. package/dist/api/routes/instances.js +315 -0
  50. package/dist/api/routes/instances.js.map +1 -0
  51. package/dist/api/routes/monitoring.d.ts +7 -0
  52. package/dist/api/routes/monitoring.d.ts.map +1 -0
  53. package/dist/api/routes/monitoring.js +72 -0
  54. package/dist/api/routes/monitoring.js.map +1 -0
  55. package/dist/api/routes/webhooks.d.ts +12 -0
  56. package/dist/api/routes/webhooks.d.ts.map +1 -0
  57. package/dist/api/routes/webhooks.js +232 -0
  58. package/dist/api/routes/webhooks.js.map +1 -0
  59. package/dist/api/schemas/index.d.ts +965 -0
  60. package/dist/api/schemas/index.d.ts.map +1 -0
  61. package/dist/api/schemas/index.js +171 -0
  62. package/dist/api/schemas/index.js.map +1 -0
  63. package/dist/app.d.ts +13 -0
  64. package/dist/app.d.ts.map +1 -0
  65. package/dist/app.js +197 -0
  66. package/dist/app.js.map +1 -0
  67. package/dist/bin/clawsql.d.ts +12 -0
  68. package/dist/bin/clawsql.d.ts.map +1 -0
  69. package/dist/bin/clawsql.js +43 -0
  70. package/dist/bin/clawsql.js.map +1 -0
  71. package/dist/cli/agent/handler.d.ts +73 -0
  72. package/dist/cli/agent/handler.d.ts.map +1 -0
  73. package/dist/cli/agent/handler.js +258 -0
  74. package/dist/cli/agent/handler.js.map +1 -0
  75. package/dist/cli/agent/index.d.ts +14 -0
  76. package/dist/cli/agent/index.d.ts.map +1 -0
  77. package/dist/cli/agent/index.js +30 -0
  78. package/dist/cli/agent/index.js.map +1 -0
  79. package/dist/cli/agent/openclaw-integration.d.ts +81 -0
  80. package/dist/cli/agent/openclaw-integration.d.ts.map +1 -0
  81. package/dist/cli/agent/openclaw-integration.js +341 -0
  82. package/dist/cli/agent/openclaw-integration.js.map +1 -0
  83. package/dist/cli/agent/providers/anthropic.d.ts +27 -0
  84. package/dist/cli/agent/providers/anthropic.d.ts.map +1 -0
  85. package/dist/cli/agent/providers/anthropic.js +106 -0
  86. package/dist/cli/agent/providers/anthropic.js.map +1 -0
  87. package/dist/cli/agent/providers/base.d.ts +91 -0
  88. package/dist/cli/agent/providers/base.d.ts.map +1 -0
  89. package/dist/cli/agent/providers/base.js +24 -0
  90. package/dist/cli/agent/providers/base.js.map +1 -0
  91. package/dist/cli/agent/providers/openai.d.ts +27 -0
  92. package/dist/cli/agent/providers/openai.d.ts.map +1 -0
  93. package/dist/cli/agent/providers/openai.js +98 -0
  94. package/dist/cli/agent/providers/openai.js.map +1 -0
  95. package/dist/cli/agent/tools/index.d.ts +32 -0
  96. package/dist/cli/agent/tools/index.d.ts.map +1 -0
  97. package/dist/cli/agent/tools/index.js +263 -0
  98. package/dist/cli/agent/tools/index.js.map +1 -0
  99. package/dist/cli/commands/cleanup.d.ts +12 -0
  100. package/dist/cli/commands/cleanup.d.ts.map +1 -0
  101. package/dist/cli/commands/cleanup.js +205 -0
  102. package/dist/cli/commands/cleanup.js.map +1 -0
  103. package/dist/cli/commands/clusters.d.ts +12 -0
  104. package/dist/cli/commands/clusters.d.ts.map +1 -0
  105. package/dist/cli/commands/clusters.js +468 -0
  106. package/dist/cli/commands/clusters.js.map +1 -0
  107. package/dist/cli/commands/config.d.ts +12 -0
  108. package/dist/cli/commands/config.d.ts.map +1 -0
  109. package/dist/cli/commands/config.js +406 -0
  110. package/dist/cli/commands/config.js.map +1 -0
  111. package/dist/cli/commands/cron.d.ts +12 -0
  112. package/dist/cli/commands/cron.d.ts.map +1 -0
  113. package/dist/cli/commands/cron.js +215 -0
  114. package/dist/cli/commands/cron.js.map +1 -0
  115. package/dist/cli/commands/doctor.d.ts +13 -0
  116. package/dist/cli/commands/doctor.d.ts.map +1 -0
  117. package/dist/cli/commands/doctor.js +687 -0
  118. package/dist/cli/commands/doctor.js.map +1 -0
  119. package/dist/cli/commands/failover.d.ts +16 -0
  120. package/dist/cli/commands/failover.d.ts.map +1 -0
  121. package/dist/cli/commands/failover.js +333 -0
  122. package/dist/cli/commands/failover.js.map +1 -0
  123. package/dist/cli/commands/health.d.ts +12 -0
  124. package/dist/cli/commands/health.d.ts.map +1 -0
  125. package/dist/cli/commands/health.js +125 -0
  126. package/dist/cli/commands/health.js.map +1 -0
  127. package/dist/cli/commands/help.d.ts +12 -0
  128. package/dist/cli/commands/help.d.ts.map +1 -0
  129. package/dist/cli/commands/help.js +52 -0
  130. package/dist/cli/commands/help.js.map +1 -0
  131. package/dist/cli/commands/instances.d.ts +12 -0
  132. package/dist/cli/commands/instances.d.ts.map +1 -0
  133. package/dist/cli/commands/instances.js +801 -0
  134. package/dist/cli/commands/instances.js.map +1 -0
  135. package/dist/cli/commands/notify.d.ts +12 -0
  136. package/dist/cli/commands/notify.d.ts.map +1 -0
  137. package/dist/cli/commands/notify.js +43 -0
  138. package/dist/cli/commands/notify.js.map +1 -0
  139. package/dist/cli/commands/sql.d.ts +12 -0
  140. package/dist/cli/commands/sql.d.ts.map +1 -0
  141. package/dist/cli/commands/sql.js +90 -0
  142. package/dist/cli/commands/sql.js.map +1 -0
  143. package/dist/cli/commands/start.d.ts +12 -0
  144. package/dist/cli/commands/start.d.ts.map +1 -0
  145. package/dist/cli/commands/start.js +174 -0
  146. package/dist/cli/commands/start.js.map +1 -0
  147. package/dist/cli/commands/status.d.ts +12 -0
  148. package/dist/cli/commands/status.d.ts.map +1 -0
  149. package/dist/cli/commands/status.js +218 -0
  150. package/dist/cli/commands/status.js.map +1 -0
  151. package/dist/cli/commands/stop.d.ts +12 -0
  152. package/dist/cli/commands/stop.d.ts.map +1 -0
  153. package/dist/cli/commands/stop.js +128 -0
  154. package/dist/cli/commands/stop.js.map +1 -0
  155. package/dist/cli/commands/topology.d.ts +12 -0
  156. package/dist/cli/commands/topology.d.ts.map +1 -0
  157. package/dist/cli/commands/topology.js +106 -0
  158. package/dist/cli/commands/topology.js.map +1 -0
  159. package/dist/cli/completer.d.ts +47 -0
  160. package/dist/cli/completer.d.ts.map +1 -0
  161. package/dist/cli/completer.js +332 -0
  162. package/dist/cli/completer.js.map +1 -0
  163. package/dist/cli/formatter.d.ts +165 -0
  164. package/dist/cli/formatter.d.ts.map +1 -0
  165. package/dist/cli/formatter.js +408 -0
  166. package/dist/cli/formatter.js.map +1 -0
  167. package/dist/cli/index.d.ts +21 -0
  168. package/dist/cli/index.d.ts.map +1 -0
  169. package/dist/cli/index.js +79 -0
  170. package/dist/cli/index.js.map +1 -0
  171. package/dist/cli/raw-input.d.ts +97 -0
  172. package/dist/cli/raw-input.d.ts.map +1 -0
  173. package/dist/cli/raw-input.js +493 -0
  174. package/dist/cli/raw-input.js.map +1 -0
  175. package/dist/cli/registry.d.ts +103 -0
  176. package/dist/cli/registry.d.ts.map +1 -0
  177. package/dist/cli/registry.js +205 -0
  178. package/dist/cli/registry.js.map +1 -0
  179. package/dist/cli/repl.d.ts +83 -0
  180. package/dist/cli/repl.d.ts.map +1 -0
  181. package/dist/cli/repl.js +447 -0
  182. package/dist/cli/repl.js.map +1 -0
  183. package/dist/cli/ui/components.d.ts +144 -0
  184. package/dist/cli/ui/components.d.ts.map +1 -0
  185. package/dist/cli/ui/components.js +331 -0
  186. package/dist/cli/ui/components.js.map +1 -0
  187. package/dist/cli/ui/index.d.ts +7 -0
  188. package/dist/cli/ui/index.d.ts.map +1 -0
  189. package/dist/cli/ui/index.js +23 -0
  190. package/dist/cli/ui/index.js.map +1 -0
  191. package/dist/cli/utils/docker-files.d.ts +39 -0
  192. package/dist/cli/utils/docker-files.d.ts.map +1 -0
  193. package/dist/cli/utils/docker-files.js +223 -0
  194. package/dist/cli/utils/docker-files.js.map +1 -0
  195. package/dist/cli/utils/docker-prereq.d.ts +48 -0
  196. package/dist/cli/utils/docker-prereq.d.ts.map +1 -0
  197. package/dist/cli/utils/docker-prereq.js +203 -0
  198. package/dist/cli/utils/docker-prereq.js.map +1 -0
  199. package/dist/config/settings.d.ts +594 -0
  200. package/dist/config/settings.d.ts.map +1 -0
  201. package/dist/config/settings.js +250 -0
  202. package/dist/config/settings.js.map +1 -0
  203. package/dist/core/discovery/cluster-view.d.ts +50 -0
  204. package/dist/core/discovery/cluster-view.d.ts.map +1 -0
  205. package/dist/core/discovery/cluster-view.js +235 -0
  206. package/dist/core/discovery/cluster-view.js.map +1 -0
  207. package/dist/core/discovery/scanner.d.ts +70 -0
  208. package/dist/core/discovery/scanner.d.ts.map +1 -0
  209. package/dist/core/discovery/scanner.js +197 -0
  210. package/dist/core/discovery/scanner.js.map +1 -0
  211. package/dist/core/discovery/topology.d.ts +118 -0
  212. package/dist/core/discovery/topology.d.ts.map +1 -0
  213. package/dist/core/discovery/topology.js +550 -0
  214. package/dist/core/discovery/topology.js.map +1 -0
  215. package/dist/core/failover/candidate-selector.d.ts +46 -0
  216. package/dist/core/failover/candidate-selector.d.ts.map +1 -0
  217. package/dist/core/failover/candidate-selector.js +70 -0
  218. package/dist/core/failover/candidate-selector.js.map +1 -0
  219. package/dist/core/failover/executor.d.ts +104 -0
  220. package/dist/core/failover/executor.d.ts.map +1 -0
  221. package/dist/core/failover/executor.js +248 -0
  222. package/dist/core/failover/executor.js.map +1 -0
  223. package/dist/core/failover/operation-builder.d.ts +71 -0
  224. package/dist/core/failover/operation-builder.d.ts.map +1 -0
  225. package/dist/core/failover/operation-builder.js +157 -0
  226. package/dist/core/failover/operation-builder.js.map +1 -0
  227. package/dist/core/failover/operation-runner.d.ts +75 -0
  228. package/dist/core/failover/operation-runner.d.ts.map +1 -0
  229. package/dist/core/failover/operation-runner.js +191 -0
  230. package/dist/core/failover/operation-runner.js.map +1 -0
  231. package/dist/core/failover/promoter.d.ts +33 -0
  232. package/dist/core/failover/promoter.d.ts.map +1 -0
  233. package/dist/core/failover/promoter.js +97 -0
  234. package/dist/core/failover/promoter.js.map +1 -0
  235. package/dist/core/failover/recovery-manager.d.ts +47 -0
  236. package/dist/core/failover/recovery-manager.d.ts.map +1 -0
  237. package/dist/core/failover/recovery-manager.js +145 -0
  238. package/dist/core/failover/recovery-manager.js.map +1 -0
  239. package/dist/core/failover/types.d.ts +54 -0
  240. package/dist/core/failover/types.d.ts.map +1 -0
  241. package/dist/core/failover/types.js +8 -0
  242. package/dist/core/failover/types.js.map +1 -0
  243. package/dist/core/monitoring/collector.d.ts +25 -0
  244. package/dist/core/monitoring/collector.d.ts.map +1 -0
  245. package/dist/core/monitoring/collector.js +115 -0
  246. package/dist/core/monitoring/collector.js.map +1 -0
  247. package/dist/core/monitoring/exporters.d.ts +49 -0
  248. package/dist/core/monitoring/exporters.d.ts.map +1 -0
  249. package/dist/core/monitoring/exporters.js +126 -0
  250. package/dist/core/monitoring/exporters.js.map +1 -0
  251. package/dist/core/routing/proxysql-manager.d.ts +213 -0
  252. package/dist/core/routing/proxysql-manager.d.ts.map +1 -0
  253. package/dist/core/routing/proxysql-manager.js +632 -0
  254. package/dist/core/routing/proxysql-manager.js.map +1 -0
  255. package/dist/core/sync/replica-recovery.d.ts +40 -0
  256. package/dist/core/sync/replica-recovery.d.ts.map +1 -0
  257. package/dist/core/sync/replica-recovery.js +134 -0
  258. package/dist/core/sync/replica-recovery.js.map +1 -0
  259. package/dist/core/sync/sync-coordinator.d.ts +83 -0
  260. package/dist/core/sync/sync-coordinator.d.ts.map +1 -0
  261. package/dist/core/sync/sync-coordinator.js +254 -0
  262. package/dist/core/sync/sync-coordinator.js.map +1 -0
  263. package/dist/core/sync/topology-watcher.d.ts +76 -0
  264. package/dist/core/sync/topology-watcher.d.ts.map +1 -0
  265. package/dist/core/sync/topology-watcher.js +222 -0
  266. package/dist/core/sync/topology-watcher.js.map +1 -0
  267. package/dist/core/sync/types.d.ts +85 -0
  268. package/dist/core/sync/types.d.ts.map +1 -0
  269. package/dist/core/sync/types.js +8 -0
  270. package/dist/core/sync/types.js.map +1 -0
  271. package/dist/index.d.ts +5 -0
  272. package/dist/index.d.ts.map +1 -0
  273. package/dist/index.js +9 -0
  274. package/dist/index.js.map +1 -0
  275. package/dist/types/index.d.ts +212 -0
  276. package/dist/types/index.d.ts.map +1 -0
  277. package/dist/types/index.js +153 -0
  278. package/dist/types/index.js.map +1 -0
  279. package/dist/utils/database.d.ts +62 -0
  280. package/dist/utils/database.d.ts.map +1 -0
  281. package/dist/utils/database.js +257 -0
  282. package/dist/utils/database.js.map +1 -0
  283. package/dist/utils/exceptions.d.ts +69 -0
  284. package/dist/utils/exceptions.d.ts.map +1 -0
  285. package/dist/utils/exceptions.js +121 -0
  286. package/dist/utils/exceptions.js.map +1 -0
  287. package/dist/utils/logger.d.ts +20 -0
  288. package/dist/utils/logger.d.ts.map +1 -0
  289. package/dist/utils/logger.js +90 -0
  290. package/dist/utils/logger.js.map +1 -0
  291. package/dist/utils/mysql-client.d.ts +43 -0
  292. package/dist/utils/mysql-client.d.ts.map +1 -0
  293. package/dist/utils/mysql-client.js +125 -0
  294. package/dist/utils/mysql-client.js.map +1 -0
  295. package/docker/Dockerfile +61 -0
  296. package/docker/Dockerfile.node +41 -0
  297. package/docker/grafana/dashboards/clawsql.json +212 -0
  298. package/docker/grafana/provisioning/dashboards/dashboards.yml +13 -0
  299. package/docker/grafana/provisioning/datasources/datasources.yml +12 -0
  300. package/docker/init/primary.sql +26 -0
  301. package/docker/init/replica.sql +16 -0
  302. package/docker/orchestrator/orchestrator.conf.json +98 -0
  303. package/docker/prometheus/prometheus.yml +45 -0
  304. package/docker/proxysql/entrypoint.sh +8 -0
  305. package/docker/proxysql/init.sql.demo +30 -0
  306. package/docker/proxysql/proxysql.cnf +38 -0
  307. package/docker-compose.demo.yml +115 -0
  308. package/docker-compose.yml +217 -0
  309. package/init/primary.sql +19 -0
  310. package/init/replica.sql +13 -0
  311. package/package.json +84 -0
@@ -0,0 +1,222 @@
1
+ "use strict";
2
+ /**
3
+ * ClawSQL - Topology Watcher
4
+ *
5
+ * Polls Orchestrator for topology changes and triggers ProxySQL sync.
6
+ * Acts as a fallback mechanism when webhooks are not received.
7
+ * Also attempts to recover replicas stuck in maintenance state.
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.TopologyWatcher = void 0;
11
+ exports.getTopologyWatcher = getTopologyWatcher;
12
+ exports.resetTopologyWatcher = resetTopologyWatcher;
13
+ const logger_js_1 = require("../../utils/logger.js");
14
+ const index_js_1 = require("../../types/index.js");
15
+ const topology_js_1 = require("../discovery/topology.js");
16
+ const sync_coordinator_js_1 = require("./sync-coordinator.js");
17
+ const replica_recovery_js_1 = require("./replica-recovery.js");
18
+ const settings_js_1 = require("../../config/settings.js");
19
+ const logger = (0, logger_js_1.getLogger)('sync');
20
+ /**
21
+ * Topology Watcher
22
+ * Periodically checks for topology changes and syncs ProxySQL.
23
+ */
24
+ class TopologyWatcher {
25
+ interval = null;
26
+ running = false;
27
+ lastTopologyHashes = new Map();
28
+ pollIntervalMs;
29
+ enabled;
30
+ constructor(options) {
31
+ this.pollIntervalMs = options?.pollIntervalMs ?? 30000;
32
+ this.enabled = options?.enabled ?? true;
33
+ }
34
+ /**
35
+ * Start watching for topology changes
36
+ */
37
+ async start() {
38
+ if (this.running || !this.enabled) {
39
+ logger.debug({ running: this.running, enabled: this.enabled }, 'Topology watcher not started');
40
+ return;
41
+ }
42
+ this.running = true;
43
+ logger.info({ pollIntervalMs: this.pollIntervalMs }, 'Topology watcher started');
44
+ // Do initial poll
45
+ await this.poll();
46
+ // Schedule periodic polls
47
+ this.interval = setInterval(() => { void this.poll(); }, this.pollIntervalMs);
48
+ // Don't keep the process alive just for this timer
49
+ this.interval.unref();
50
+ }
51
+ /**
52
+ * Stop watching for topology changes
53
+ */
54
+ stop() {
55
+ if (this.interval) {
56
+ clearInterval(this.interval);
57
+ this.interval = null;
58
+ }
59
+ this.running = false;
60
+ logger.info('Topology watcher stopped');
61
+ }
62
+ /**
63
+ * Check if the watcher is running
64
+ */
65
+ isRunning() {
66
+ return this.running;
67
+ }
68
+ /**
69
+ * Perform a single poll of all clusters
70
+ */
71
+ async poll() {
72
+ logger.debug('Polling for topology changes');
73
+ try {
74
+ const orchestrator = (0, topology_js_1.getOrchestratorClient)();
75
+ const syncCoordinator = (0, sync_coordinator_js_1.getSyncCoordinator)();
76
+ // Get all clusters
77
+ const clusters = await orchestrator.getClusters();
78
+ for (const clusterName of clusters) {
79
+ try {
80
+ const topology = await orchestrator.getTopology(clusterName);
81
+ if (!topology) {
82
+ logger.debug({ clusterName }, 'Could not get topology for cluster');
83
+ continue;
84
+ }
85
+ const hash = this.computeTopologyHash(topology);
86
+ const lastHash = this.lastTopologyHashes.get(topology.clusterId);
87
+ // Check if topology changed
88
+ if (lastHash !== hash) {
89
+ logger.info({ clusterId: topology.clusterId, oldHash: lastHash, newHash: hash }, 'Topology change detected');
90
+ // Attempt to recover replicas in maintenance state (non-blocking)
91
+ // This handles cases where webhook recovery failed or was skipped
92
+ if (topology.primary) {
93
+ this.attemptReplicaRecovery(topology, orchestrator);
94
+ }
95
+ // Sync ProxySQL
96
+ await syncCoordinator.sync(topology, 'poll');
97
+ // Update hash
98
+ this.lastTopologyHashes.set(topology.clusterId, hash);
99
+ }
100
+ else {
101
+ // Even if topology hasn't changed, check for replicas needing recovery
102
+ // This handles cases where recovery was deferred earlier
103
+ if (topology.primary && this.hasReplicasNeedingRecovery(topology)) {
104
+ logger.info({ clusterId: topology.clusterId }, 'Checking for replicas needing recovery');
105
+ this.attemptReplicaRecovery(topology, orchestrator);
106
+ }
107
+ logger.debug({ clusterId: topology.clusterId }, 'No topology change detected');
108
+ }
109
+ }
110
+ catch (error) {
111
+ logger.error({ error, clusterName }, 'Error polling cluster topology');
112
+ }
113
+ }
114
+ }
115
+ catch (error) {
116
+ logger.error({ error }, 'Error during topology poll');
117
+ }
118
+ }
119
+ /**
120
+ * Compute a hash of the cluster topology
121
+ */
122
+ computeTopologyHash(cluster) {
123
+ const parts = [
124
+ cluster.clusterId,
125
+ cluster.primary
126
+ ? `${cluster.primary.host}:${cluster.primary.port}:${cluster.primary.state}`
127
+ : 'null',
128
+ ...cluster.replicas
129
+ .map(r => `${r.host}:${r.port}:${r.state}:${r.replicationLag ?? 0}`)
130
+ .sort(),
131
+ ];
132
+ return parts.join('|');
133
+ }
134
+ /**
135
+ * Force a poll cycle
136
+ */
137
+ async forcePoll() {
138
+ await this.poll();
139
+ }
140
+ /**
141
+ * Clear cached topology hashes
142
+ */
143
+ clearCache() {
144
+ this.lastTopologyHashes.clear();
145
+ logger.debug('Topology cache cleared');
146
+ }
147
+ /**
148
+ * Get the current poll interval
149
+ */
150
+ getPollInterval() {
151
+ return this.pollIntervalMs;
152
+ }
153
+ /**
154
+ * Update the poll interval
155
+ */
156
+ setPollInterval(intervalMs) {
157
+ this.pollIntervalMs = intervalMs;
158
+ if (this.running && this.interval) {
159
+ clearInterval(this.interval);
160
+ this.interval = setInterval(() => { void this.poll(); }, this.pollIntervalMs);
161
+ this.interval.unref();
162
+ logger.info({ pollIntervalMs: this.pollIntervalMs }, 'Poll interval updated');
163
+ }
164
+ }
165
+ /**
166
+ * Check if any replicas need recovery (maintenance or offline state)
167
+ */
168
+ hasReplicasNeedingRecovery(cluster) {
169
+ return cluster.replicas.some(r => r.state === index_js_1.InstanceState.MAINTENANCE || r.state === index_js_1.InstanceState.OFFLINE);
170
+ }
171
+ /**
172
+ * Attempt to recover replicas in maintenance state (non-blocking)
173
+ * If recovery succeeds, invalidates cache to trigger re-sync on next poll
174
+ */
175
+ attemptReplicaRecovery(cluster, orchestrator) {
176
+ if (!cluster.primary)
177
+ return;
178
+ const replicasNeedingRecovery = cluster.replicas.filter(r => r.state === index_js_1.InstanceState.MAINTENANCE || r.state === index_js_1.InstanceState.OFFLINE);
179
+ if (replicasNeedingRecovery.length === 0)
180
+ return;
181
+ // Attempt recovery in background (non-blocking)
182
+ for (const replica of replicasNeedingRecovery) {
183
+ (0, replica_recovery_js_1.recoverReplica)(replica, cluster.primary, orchestrator)
184
+ .then(result => {
185
+ if (result.recovered) {
186
+ logger.info({ instanceId: `${replica.host}:${replica.port}` }, 'Replica auto-recovered during poll');
187
+ // Invalidate cache to force re-sync on next poll
188
+ this.lastTopologyHashes.delete(cluster.clusterId);
189
+ }
190
+ })
191
+ .catch(error => {
192
+ logger.debug({ error, instanceId: `${replica.host}:${replica.port}` }, 'Recovery attempt failed (will retry)');
193
+ });
194
+ }
195
+ }
196
+ }
197
+ exports.TopologyWatcher = TopologyWatcher;
198
+ // Singleton instance
199
+ let topologyWatcher = null;
200
+ /**
201
+ * Get the topology watcher instance
202
+ */
203
+ function getTopologyWatcher() {
204
+ if (!topologyWatcher) {
205
+ const settings = (0, settings_js_1.getSettings)();
206
+ topologyWatcher = new TopologyWatcher({
207
+ pollIntervalMs: settings.sync?.pollIntervalMs ?? 30000,
208
+ enabled: settings.sync?.enabled ?? true,
209
+ });
210
+ }
211
+ return topologyWatcher;
212
+ }
213
+ /**
214
+ * Reset the topology watcher (for testing)
215
+ */
216
+ function resetTopologyWatcher() {
217
+ if (topologyWatcher) {
218
+ topologyWatcher.stop();
219
+ }
220
+ topologyWatcher = null;
221
+ }
222
+ //# sourceMappingURL=topology-watcher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"topology-watcher.js","sourceRoot":"","sources":["../../../src/core/sync/topology-watcher.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,85 @@
1
+ /**
2
+ * ClawSQL - Sync Types
3
+ *
4
+ * Type definitions for synchronization operations.
5
+ */
6
+ import { MySQLCluster } from '../../types/index.js';
7
+ /**
8
+ * Orchestrator failover webhook payload
9
+ * Sent by Orchestrator after failover completion
10
+ */
11
+ export interface OrchestratorFailoverPayload {
12
+ /** Cluster alias/name */
13
+ cluster: string;
14
+ /** Old master (host:port) */
15
+ master: string;
16
+ /** New master (host:port) */
17
+ successor: string;
18
+ /** New master hostname */
19
+ successorHost?: string;
20
+ /** New master port */
21
+ successorPort?: number;
22
+ /** Whether the failover succeeded */
23
+ isSuccessful: boolean;
24
+ /** Type of failover */
25
+ failoverType: 'master' | 'intermediate-master';
26
+ /** Reason for failover */
27
+ reason?: string;
28
+ /** Timestamp of the event */
29
+ timestamp?: string;
30
+ }
31
+ /**
32
+ * Sync result
33
+ */
34
+ export interface SyncResult {
35
+ /** Whether the sync was skipped */
36
+ skipped: boolean;
37
+ /** Reason for skipping (if applicable) */
38
+ reason?: 'cooldown' | 'disabled' | 'no_change' | 'failed' | 'invalid_input';
39
+ /** Cluster ID that was synced */
40
+ clusterId?: string;
41
+ /** Number of servers synced */
42
+ serversSynced?: number;
43
+ /** Error message if sync failed */
44
+ error?: string;
45
+ /** Source of the sync trigger */
46
+ source?: 'webhook' | 'poll' | 'manual';
47
+ }
48
+ /**
49
+ * Topology hash for change detection
50
+ */
51
+ export interface TopologyHash {
52
+ clusterId: string;
53
+ hash: string;
54
+ updatedAt: Date;
55
+ }
56
+ /**
57
+ * Sync context passed through the sync pipeline
58
+ */
59
+ export interface SyncContext {
60
+ cluster: MySQLCluster;
61
+ source: 'webhook' | 'poll' | 'manual';
62
+ webhookPayload?: OrchestratorFailoverPayload;
63
+ force?: boolean;
64
+ }
65
+ /**
66
+ * Sync coordinator stats
67
+ */
68
+ export interface SyncStats {
69
+ totalSyncs: number;
70
+ successfulSyncs: number;
71
+ failedSyncs: number;
72
+ skippedSyncs: number;
73
+ lastSyncAt?: Date;
74
+ lastSyncCluster?: string;
75
+ }
76
+ /**
77
+ * Webhook handler result
78
+ */
79
+ export interface WebhookResult {
80
+ received: boolean;
81
+ processed: boolean;
82
+ message?: string;
83
+ syncResult?: SyncResult;
84
+ }
85
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/core/sync/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEpD;;;GAGG;AACH,MAAM,WAAW,2BAA2B;IAC1C,yBAAyB;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,6BAA6B;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,6BAA6B;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,0BAA0B;IAC1B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,sBAAsB;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,qCAAqC;IACrC,YAAY,EAAE,OAAO,CAAC;IACtB,uBAAuB;IACvB,YAAY,EAAE,QAAQ,GAAG,qBAAqB,CAAC;IAC/C,0BAA0B;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,6BAA6B;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,mCAAmC;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,0CAA0C;IAC1C,MAAM,CAAC,EAAE,UAAU,GAAG,UAAU,GAAG,WAAW,GAAG,QAAQ,GAAG,eAAe,CAAC;IAC5E,iCAAiC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,+BAA+B;IAC/B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,mCAAmC;IACnC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iCAAiC;IACjC,MAAM,CAAC,EAAE,SAAS,GAAG,MAAM,GAAG,QAAQ,CAAC;CACxC;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,IAAI,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,YAAY,CAAC;IACtB,MAAM,EAAE,SAAS,GAAG,MAAM,GAAG,QAAQ,CAAC;IACtC,cAAc,CAAC,EAAE,2BAA2B,CAAC;IAC7C,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,IAAI,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,UAAU,CAAC;CACzB"}
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ /**
3
+ * ClawSQL - Sync Types
4
+ *
5
+ * Type definitions for synchronization operations.
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/core/sync/types.ts"],"names":[],"mappings":";AAAA;;;;GAIG"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * ClawSQL - Main Entry Point
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG"}
package/dist/index.js ADDED
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ /**
3
+ * ClawSQL - Main Entry Point
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const app_js_1 = require("./app.js");
7
+ // Start the server
8
+ (0, app_js_1.startServer)();
9
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;GAEG;;AAEH,qCAAuC;AAEvC,mBAAmB;AACnB,IAAA,oBAAW,GAAE,CAAC"}
@@ -0,0 +1,212 @@
1
+ /**
2
+ * ClawSQL - Core Types and Models
3
+ *
4
+ * TypeScript interfaces and enums converted from Python dataclasses.
5
+ */
6
+ /** MySQL instance role in the cluster */
7
+ export declare enum InstanceRole {
8
+ PRIMARY = "primary",
9
+ REPLICA = "replica",
10
+ UNKNOWN = "unknown"
11
+ }
12
+ /** MySQL instance operational state */
13
+ export declare enum InstanceState {
14
+ ONLINE = "online",
15
+ OFFLINE = "offline",
16
+ RECOVERING = "recovering",
17
+ FAILED = "failed",
18
+ MAINTENANCE = "maintenance"
19
+ }
20
+ /** Health status for instances and clusters */
21
+ export declare enum HealthStatus {
22
+ HEALTHY = "healthy",
23
+ DEGRADED = "degraded",
24
+ UNHEALTHY = "unhealthy",
25
+ UNKNOWN = "unknown"
26
+ }
27
+ /** Alert severity levels */
28
+ export declare enum AlertSeverity {
29
+ INFO = "info",
30
+ WARNING = "warning",
31
+ CRITICAL = "critical"
32
+ }
33
+ /** Failover operation states */
34
+ export declare enum FailoverState {
35
+ IDLE = "idle",
36
+ DETECTING = "detecting",
37
+ CANDIDATE_SELECTION = "candidate_selection",
38
+ PROMOTING = "promoting",
39
+ RECONFIGURING = "reconfiguring",
40
+ COMPLETED = "completed",
41
+ FAILED = "failed"
42
+ }
43
+ /** Types of failures that can be detected */
44
+ export declare enum FailureType {
45
+ PRIMARY_UNREACHABLE = "primary_unreachable",
46
+ PRIMARY_NOT_WRITING = "primary_not_writing",
47
+ REPLICATION_STOPPED = "replication_stopped",
48
+ REPLICATION_LAG_HIGH = "replication_lag_high",
49
+ DISK_FULL = "disk_full",
50
+ MEMORY_EXHAUSTED = "memory_exhausted"
51
+ }
52
+ /** Represents a discovered MySQL instance */
53
+ export interface MySQLInstance {
54
+ host: string;
55
+ port: number;
56
+ serverId?: number;
57
+ role: InstanceRole;
58
+ state: InstanceState;
59
+ version?: string;
60
+ replicationLag?: number;
61
+ lastSeen: Date;
62
+ clusterId?: string;
63
+ labels: Record<string, string>;
64
+ extra: Record<string, unknown>;
65
+ }
66
+ /** Represents a MySQL cluster topology */
67
+ export interface MySQLCluster {
68
+ clusterId: string;
69
+ name: string;
70
+ primary?: MySQLInstance;
71
+ replicas: MySQLInstance[];
72
+ createdAt: Date;
73
+ updatedAt: Date;
74
+ description?: string;
75
+ }
76
+ /** Failover operation record */
77
+ export interface FailoverOperation {
78
+ operationId: string;
79
+ clusterId: string;
80
+ oldPrimaryId: string;
81
+ newPrimaryId?: string;
82
+ state: FailoverState;
83
+ startedAt?: Date;
84
+ completedAt?: Date;
85
+ steps: string[];
86
+ error?: string;
87
+ manual: boolean;
88
+ reason: string;
89
+ triggeredBy?: string;
90
+ }
91
+ /** Failure event detected by the system */
92
+ export interface FailureEvent {
93
+ eventId: string;
94
+ failureType: FailureType;
95
+ instanceId: string;
96
+ clusterId: string;
97
+ detectedAt: Date;
98
+ confirmed: boolean;
99
+ confirmationCount: number;
100
+ details: Record<string, unknown>;
101
+ }
102
+ /** Alert generated by the monitoring system */
103
+ export interface Alert {
104
+ alertId: string;
105
+ severity: AlertSeverity;
106
+ instanceId?: string;
107
+ clusterId?: string;
108
+ message: string;
109
+ details: Record<string, unknown>;
110
+ createdAt: Date;
111
+ acknowledged: boolean;
112
+ acknowledgedAt?: Date;
113
+ acknowledgedBy?: string;
114
+ }
115
+ /** Instance metrics collected from MySQL */
116
+ export interface InstanceMetrics {
117
+ instanceId: string;
118
+ timestamp: Date;
119
+ replicationLagSeconds?: number;
120
+ replicationIoRunning: boolean;
121
+ replicationSqlRunning: boolean;
122
+ connectionsCurrent: number;
123
+ connectionsMax: number;
124
+ queriesPerSecond: number;
125
+ innodbBufferPoolHitRate: number;
126
+ uptimeSeconds: number;
127
+ diskUsagePercent?: number;
128
+ memoryUsagePercent?: number;
129
+ }
130
+ /** Health check result */
131
+ export interface HealthCheckResult {
132
+ checkName: string;
133
+ status: HealthStatus;
134
+ value: number;
135
+ message: string;
136
+ threshold?: number;
137
+ }
138
+ /** Create a unique instance ID from host and port */
139
+ export declare function createInstanceId(host: string, port: number): string;
140
+ /** Create a default MySQL instance */
141
+ export declare function createMySQLInstance(host: string, port: number, overrides?: Partial<MySQLInstance>): MySQLInstance;
142
+ /** Create a default MySQL cluster */
143
+ export declare function createMySQLCluster(clusterId: string, name: string, overrides?: Partial<MySQLCluster>): MySQLCluster;
144
+ /** Check if instance is a primary */
145
+ export declare function isPrimary(instance: MySQLInstance): boolean;
146
+ /** Check if instance is a replica */
147
+ export declare function isReplica(instance: MySQLInstance): boolean;
148
+ /** Check if instance is online */
149
+ export declare function isOnline(instance: MySQLInstance): boolean;
150
+ /** Check if instance is healthy */
151
+ export declare function isHealthy(instance: MySQLInstance): boolean;
152
+ /** Get instance count for a cluster */
153
+ export declare function getInstanceCount(cluster: MySQLCluster): number;
154
+ /** Get healthy instance count for a cluster */
155
+ export declare function getHealthyCount(cluster: MySQLCluster): number;
156
+ /** Get overall cluster health status */
157
+ export declare function getClusterHealthStatus(cluster: MySQLCluster): HealthStatus;
158
+ /** Instance with merged Orchestrator and ProxySQL data */
159
+ export interface MergedInstanceInfo {
160
+ host: string;
161
+ port: number;
162
+ state: InstanceState;
163
+ role: InstanceRole;
164
+ version?: string;
165
+ serverId?: number;
166
+ replicationLag?: number;
167
+ /** ProxySQL hostgroup (10=writer, 20=reader) */
168
+ hostgroup?: number;
169
+ /** ProxySQL server status (ONLINE, OFFLINE_SOFT, etc.) */
170
+ proxysqlStatus?: string;
171
+ /** Active connections from ProxySQL connection pool */
172
+ connections?: number;
173
+ }
174
+ /** ProxySQL endpoint information */
175
+ export interface ProxySQLEndpoint {
176
+ host: string;
177
+ port: number;
178
+ }
179
+ /** Hostgroup routing configuration */
180
+ export interface HostgroupConfig {
181
+ writer: number;
182
+ reader: number;
183
+ }
184
+ /** Sync warning type */
185
+ export interface SyncWarning {
186
+ /** Warning type: missing_in_proxysql, wrong_hostgroup, unknown_in_orchestrator */
187
+ type: 'missing_in_proxysql' | 'wrong_hostgroup' | 'unknown_in_orchestrator';
188
+ /** Instance identifier */
189
+ instance: string;
190
+ /** Human-readable description */
191
+ message: string;
192
+ }
193
+ /** Merged cluster view combining Orchestrator topology with ProxySQL routing */
194
+ export interface MergedClusterView {
195
+ /** Cluster identifier from Orchestrator */
196
+ clusterId: string;
197
+ /** User-friendly cluster name */
198
+ displayName: string;
199
+ /** ProxySQL endpoint for client connections */
200
+ endpoint?: ProxySQLEndpoint;
201
+ /** Hostgroup routing configuration */
202
+ hostgroups?: HostgroupConfig;
203
+ /** Primary instance with merged data */
204
+ primary: MergedInstanceInfo | null;
205
+ /** Replica instances with merged data */
206
+ replicas: MergedInstanceInfo[];
207
+ /** Overall cluster health */
208
+ health: HealthStatus;
209
+ /** Sync warnings when ProxySQL and Orchestrator are out of sync */
210
+ syncWarnings?: SyncWarning[];
211
+ }
212
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"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"}