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,70 @@
1
+ "use strict";
2
+ /**
3
+ * ClawSQL - Candidate Selector
4
+ *
5
+ * Selects the best candidate for promotion during failover.
6
+ * Implements the Strategy Pattern for different selection strategies.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.candidateSelector = exports.CandidateSelector = exports.LowestLagStrategy = void 0;
10
+ const index_js_1 = require("../../types/index.js");
11
+ /**
12
+ * Default selection strategy
13
+ * Selects the replica with lowest replication lag among healthy instances.
14
+ */
15
+ class LowestLagStrategy {
16
+ select(replicas) {
17
+ const healthyReplicas = replicas.filter(r => this.isHealthy(r));
18
+ if (healthyReplicas.length === 0) {
19
+ return null;
20
+ }
21
+ // Sort by replication lag (prefer lowest)
22
+ const sorted = [...healthyReplicas].sort((a, b) => {
23
+ const lagA = a.replicationLag ?? Infinity;
24
+ const lagB = b.replicationLag ?? Infinity;
25
+ return lagA - lagB;
26
+ });
27
+ return sorted[0];
28
+ }
29
+ isHealthy(instance) {
30
+ return instance.state === index_js_1.InstanceState.ONLINE;
31
+ }
32
+ }
33
+ exports.LowestLagStrategy = LowestLagStrategy;
34
+ /**
35
+ * Candidate Selector
36
+ * Handles the selection of the best replica to promote.
37
+ */
38
+ class CandidateSelector {
39
+ strategy;
40
+ constructor(strategy) {
41
+ this.strategy = strategy || new LowestLagStrategy();
42
+ }
43
+ /**
44
+ * Select the best candidate from cluster replicas
45
+ */
46
+ select(cluster) {
47
+ if (!cluster.replicas.length) {
48
+ return null;
49
+ }
50
+ return this.strategy.select(cluster.replicas);
51
+ }
52
+ /**
53
+ * Find a specific replica by ID
54
+ */
55
+ static findReplica(cluster, targetId) {
56
+ return cluster.replicas.find(r => `${r.host}:${r.port}` === targetId || r.host === targetId);
57
+ }
58
+ /**
59
+ * Get instance ID string
60
+ */
61
+ static getInstanceId(instance) {
62
+ return `${instance.host}:${instance.port}`;
63
+ }
64
+ }
65
+ exports.CandidateSelector = CandidateSelector;
66
+ /**
67
+ * Default selector instance
68
+ */
69
+ exports.candidateSelector = new CandidateSelector();
70
+ //# sourceMappingURL=candidate-selector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"candidate-selector.js","sourceRoot":"","sources":["../../../src/core/failover/candidate-selector.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAEH,mDAAkF;AASlF;;;GAGG;AACH,MAAa,iBAAiB;IAC5B,MAAM,CAAC,QAAyB;QAC9B,MAAM,eAAe,GAAG,QAAQ,CAAC,MAAM,CACrC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CACvB,CAAC;QAEF,IAAI,eAAe,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACjC,OAAO,IAAI,CAAC;QACd,CAAC;QAED,0CAA0C;QAC1C,MAAM,MAAM,GAAG,CAAC,GAAG,eAAe,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;YAChD,MAAM,IAAI,GAAG,CAAC,CAAC,cAAc,IAAI,QAAQ,CAAC;YAC1C,MAAM,IAAI,GAAG,CAAC,CAAC,cAAc,IAAI,QAAQ,CAAC;YAC1C,OAAO,IAAI,GAAG,IAAI,CAAC;QACrB,CAAC,CAAC,CAAC;QAEH,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC;IACnB,CAAC;IAEO,SAAS,CAAC,QAAuB;QACvC,OAAO,QAAQ,CAAC,KAAK,KAAK,wBAAa,CAAC,MAAM,CAAC;IACjD,CAAC;CACF;AAvBD,8CAuBC;AAED;;;GAGG;AACH,MAAa,iBAAiB;IACpB,QAAQ,CAAoB;IAEpC,YAAY,QAA4B;QACtC,IAAI,CAAC,QAAQ,GAAG,QAAQ,IAAI,IAAI,iBAAiB,EAAE,CAAC;IACtD,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,OAAqB;QAC1B,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;YAC7B,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAChD,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,WAAW,CAAC,OAAqB,EAAE,QAAgB;QACxD,OAAO,OAAO,CAAC,QAAQ,CAAC,IAAI,CAC1B,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,QAAQ,IAAI,CAAC,CAAC,IAAI,KAAK,QAAQ,CAC/D,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,aAAa,CAAC,QAAuB;QAC1C,OAAO,GAAG,QAAQ,CAAC,IAAI,IAAI,QAAQ,CAAC,IAAI,EAAE,CAAC;IAC7C,CAAC;CACF;AAhCD,8CAgCC;AAED;;GAEG;AACU,QAAA,iBAAiB,GAAG,IAAI,iBAAiB,EAAE,CAAC"}
@@ -0,0 +1,104 @@
1
+ /**
2
+ * ClawSQL - Failover Executor
3
+ *
4
+ * Main orchestrator for failover operations.
5
+ * Coordinates switchover, failover, and recovery operations.
6
+ *
7
+ * Terminology:
8
+ * - Switchover: Planned operation when primary is healthy. Promotes a replica and fixes replication.
9
+ * - Failover: Emergency operation when primary is down. Promotes a replica automatically.
10
+ * - Manual Failover: User-initiated when primary is down. User selects which replica to promote.
11
+ */
12
+ import { MySQLCluster, FailoverOperation, FailureEvent } from '../../types/index.js';
13
+ import { OrchestratorClient } from '../discovery/topology.js';
14
+ import { ProxySQLManager } from '../routing/proxysql-manager.js';
15
+ import { FailoverHook, PendingRecovery, RecoveryResult, BatchRecoveryResult } from './types.js';
16
+ /**
17
+ * Failover Executor
18
+ * Main entry point for all failover operations.
19
+ */
20
+ export declare class FailoverExecutor {
21
+ private orchestrator;
22
+ private proxysql;
23
+ private promoter;
24
+ private recoveryManager;
25
+ private operationRunner;
26
+ private currentOperation;
27
+ private operationHistory;
28
+ static readonly MAX_FAILOVER_TIME = 30;
29
+ constructor(orchestrator?: OrchestratorClient, proxysql?: ProxySQLManager);
30
+ /**
31
+ * Register a pre-failover hook
32
+ */
33
+ registerPreFailoverHook(hook: FailoverHook): void;
34
+ /**
35
+ * Register a post-failover hook
36
+ */
37
+ registerPostFailoverHook(hook: FailoverHook): void;
38
+ /**
39
+ * Execute automatic failover
40
+ */
41
+ executeAutomaticFailover(failureEvent: FailureEvent, cluster: MySQLCluster): Promise<FailoverOperation>;
42
+ /**
43
+ * Execute switchover (planned, primary is healthy)
44
+ * Promotes a replica to primary and starts replication on the old primary.
45
+ */
46
+ executeSwitchover(cluster: MySQLCluster, targetPrimaryId?: string, reason?: string): Promise<FailoverOperation>;
47
+ /**
48
+ * Execute manual failover (primary is down, user selects replica)
49
+ */
50
+ executeManualFailover(cluster: MySQLCluster, targetPrimaryId?: string, reason?: string): Promise<FailoverOperation>;
51
+ /**
52
+ * Get all pending recoveries
53
+ */
54
+ getPendingRecoveries(): PendingRecovery[];
55
+ /**
56
+ * Check if an instance is pending recovery
57
+ */
58
+ isPendingRecovery(instanceId: string): boolean;
59
+ /**
60
+ * Recover an old primary instance
61
+ */
62
+ recoverInstance(instanceId: string): Promise<RecoveryResult>;
63
+ /**
64
+ * Check all pending recoveries and recover instances that are back online
65
+ */
66
+ checkAndRecoverAll(): Promise<BatchRecoveryResult>;
67
+ /**
68
+ * Clear a pending recovery (manual override)
69
+ */
70
+ clearPendingRecovery(instanceId: string): boolean;
71
+ /**
72
+ * Get current operation
73
+ */
74
+ getCurrentOperation(): FailoverOperation | null;
75
+ /**
76
+ * Get operation history
77
+ */
78
+ getOperationHistory(clusterId?: string, limit?: number): FailoverOperation[];
79
+ /**
80
+ * Get operation by ID
81
+ */
82
+ getOperation(operationId: string): FailoverOperation | undefined;
83
+ /**
84
+ * Cancel an in-progress operation
85
+ */
86
+ cancelOperation(operationId: string): Promise<boolean>;
87
+ /**
88
+ * Record an operation to history
89
+ */
90
+ private recordOperation;
91
+ /**
92
+ * Execute switchover operation
93
+ */
94
+ private executeSwitchoverOperation;
95
+ /**
96
+ * Execute failover operation
97
+ */
98
+ private executeFailoverOperation;
99
+ }
100
+ /**
101
+ * Get the Failover executor instance
102
+ */
103
+ export declare function getFailoverExecutor(): FailoverExecutor;
104
+ //# sourceMappingURL=executor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../../../src/core/failover/executor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAiB,YAAY,EAAY,MAAM,sBAAsB,CAAC;AAC9G,OAAO,EAAE,kBAAkB,EAAyB,MAAM,0BAA0B,CAAC;AACrF,OAAO,EAAE,eAAe,EAAsB,MAAM,gCAAgC,CAAC;AACrF,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAOhG;;;GAGG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,YAAY,CAAqB;IACzC,OAAO,CAAC,QAAQ,CAAkB;IAClC,OAAO,CAAC,QAAQ,CAAmB;IACnC,OAAO,CAAC,eAAe,CAAkB;IACzC,OAAO,CAAC,eAAe,CAAkB;IAEzC,OAAO,CAAC,gBAAgB,CAAkC;IAC1D,OAAO,CAAC,gBAAgB,CAA2B;IAEnD,MAAM,CAAC,QAAQ,CAAC,iBAAiB,MAAM;gBAGrC,YAAY,CAAC,EAAE,kBAAkB,EACjC,QAAQ,CAAC,EAAE,eAAe;IAa5B;;OAEG;IACH,uBAAuB,CAAC,IAAI,EAAE,YAAY,GAAG,IAAI;IAIjD;;OAEG;IACH,wBAAwB,CAAC,IAAI,EAAE,YAAY,GAAG,IAAI;IAQlD;;OAEG;IACG,wBAAwB,CAC5B,YAAY,EAAE,YAAY,EAC1B,OAAO,EAAE,YAAY,GACpB,OAAO,CAAC,iBAAiB,CAAC;IAS7B;;;OAGG;IACG,iBAAiB,CACrB,OAAO,EAAE,YAAY,EACrB,eAAe,CAAC,EAAE,MAAM,EACxB,MAAM,GAAE,MAAW,GAClB,OAAO,CAAC,iBAAiB,CAAC;IA+B7B;;OAEG;IACG,qBAAqB,CACzB,OAAO,EAAE,YAAY,EACrB,eAAe,CAAC,EAAE,MAAM,EACxB,MAAM,GAAE,MAAW,GAClB,OAAO,CAAC,iBAAiB,CAAC;IAmC7B;;OAEG;IACH,oBAAoB,IAAI,eAAe,EAAE;IAIzC;;OAEG;IACH,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO;IAI9C;;OAEG;IACG,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAIlE;;OAEG;IACG,kBAAkB,IAAI,OAAO,CAAC,mBAAmB,CAAC;IAIxD;;OAEG;IACH,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO;IAQjD;;OAEG;IACH,mBAAmB,IAAI,iBAAiB,GAAG,IAAI;IAI/C;;OAEG;IACH,mBAAmB,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,KAAK,GAAE,MAAY,GAAG,iBAAiB,EAAE;IAUjF;;OAEG;IACH,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,iBAAiB,GAAG,SAAS;IAIhE;;OAEG;IACG,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAgB5D;;OAEG;IACH,OAAO,CAAC,eAAe;IAKvB;;OAEG;YACW,0BAA0B;IAexC;;OAEG;YACW,wBAAwB;CAgCvC;AAQD;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,gBAAgB,CAKtD"}
@@ -0,0 +1,248 @@
1
+ "use strict";
2
+ /**
3
+ * ClawSQL - Failover Executor
4
+ *
5
+ * Main orchestrator for failover operations.
6
+ * Coordinates switchover, failover, and recovery operations.
7
+ *
8
+ * Terminology:
9
+ * - Switchover: Planned operation when primary is healthy. Promotes a replica and fixes replication.
10
+ * - Failover: Emergency operation when primary is down. Promotes a replica automatically.
11
+ * - Manual Failover: User-initiated when primary is down. User selects which replica to promote.
12
+ */
13
+ Object.defineProperty(exports, "__esModule", { value: true });
14
+ exports.FailoverExecutor = void 0;
15
+ exports.getFailoverExecutor = getFailoverExecutor;
16
+ const index_js_1 = require("../../types/index.js");
17
+ const topology_js_1 = require("../discovery/topology.js");
18
+ const proxysql_manager_js_1 = require("../routing/proxysql-manager.js");
19
+ const operation_builder_js_1 = require("./operation-builder.js");
20
+ const candidate_selector_js_1 = require("./candidate-selector.js");
21
+ const promoter_js_1 = require("./promoter.js");
22
+ const recovery_manager_js_1 = require("./recovery-manager.js");
23
+ const operation_runner_js_1 = require("./operation-runner.js");
24
+ /**
25
+ * Failover Executor
26
+ * Main entry point for all failover operations.
27
+ */
28
+ class FailoverExecutor {
29
+ orchestrator;
30
+ proxysql;
31
+ promoter;
32
+ recoveryManager;
33
+ operationRunner;
34
+ currentOperation = null;
35
+ operationHistory = [];
36
+ static MAX_FAILOVER_TIME = 30; // seconds
37
+ constructor(orchestrator, proxysql) {
38
+ this.orchestrator = orchestrator || (0, topology_js_1.getOrchestratorClient)();
39
+ this.proxysql = proxysql || (0, proxysql_manager_js_1.getProxySQLManager)();
40
+ this.promoter = new promoter_js_1.InstancePromoter(this.orchestrator);
41
+ this.recoveryManager = new recovery_manager_js_1.RecoveryManager(this.orchestrator);
42
+ this.operationRunner = new operation_runner_js_1.OperationRunner(this.promoter, this.proxysql);
43
+ }
44
+ // =========================================================================
45
+ // Hook Registration
46
+ // =========================================================================
47
+ /**
48
+ * Register a pre-failover hook
49
+ */
50
+ registerPreFailoverHook(hook) {
51
+ this.operationRunner.registerPreHook(hook);
52
+ }
53
+ /**
54
+ * Register a post-failover hook
55
+ */
56
+ registerPostFailoverHook(hook) {
57
+ this.operationRunner.registerPostHook(hook);
58
+ }
59
+ // =========================================================================
60
+ // Public Operations
61
+ // =========================================================================
62
+ /**
63
+ * Execute automatic failover
64
+ */
65
+ async executeAutomaticFailover(failureEvent, cluster) {
66
+ const operation = operation_builder_js_1.OperationBuilder.create()
67
+ .forCluster(cluster)
68
+ .asAutomatic(failureEvent.eventId, `Automatic failover due to ${failureEvent.failureType}`)
69
+ .build();
70
+ return this.executeFailoverOperation(operation, cluster);
71
+ }
72
+ /**
73
+ * Execute switchover (planned, primary is healthy)
74
+ * Promotes a replica to primary and starts replication on the old primary.
75
+ */
76
+ async executeSwitchover(cluster, targetPrimaryId, reason = '') {
77
+ // Validate primary is healthy
78
+ if (!cluster.primary || !(0, index_js_1.isOnline)(cluster.primary)) {
79
+ return this.recordOperation((0, operation_builder_js_1.createFailedOperation)(cluster, 'Switchover requires a healthy primary. Use failover for unhealthy primary.', reason || 'Switchover requested'));
80
+ }
81
+ // Validate target if specified
82
+ if (targetPrimaryId) {
83
+ const targetReplica = candidate_selector_js_1.CandidateSelector.findReplica(cluster, targetPrimaryId);
84
+ if (!targetReplica) {
85
+ return this.recordOperation((0, operation_builder_js_1.createFailedOperation)(cluster, `Target '${targetPrimaryId}' not found in cluster replicas. ` +
86
+ `Available: ${cluster.replicas.map(r => `${r.host}:${r.port}`).join(', ')}`, reason || 'Switchover requested'));
87
+ }
88
+ }
89
+ const operation = (0, operation_builder_js_1.createSwitchoverOperation)(cluster, targetPrimaryId, reason);
90
+ return this.executeSwitchoverOperation(operation, cluster);
91
+ }
92
+ /**
93
+ * Execute manual failover (primary is down, user selects replica)
94
+ */
95
+ async executeManualFailover(cluster, targetPrimaryId, reason = '') {
96
+ // Validate primary is NOT healthy
97
+ if (cluster.primary && (0, index_js_1.isOnline)(cluster.primary)) {
98
+ return this.recordOperation((0, operation_builder_js_1.createFailedOperation)(cluster, 'Primary is healthy. Use switchover for planned primary change.', reason || 'Manual failover requested'));
99
+ }
100
+ // Validate target if specified
101
+ if (targetPrimaryId) {
102
+ const targetReplica = candidate_selector_js_1.CandidateSelector.findReplica(cluster, targetPrimaryId);
103
+ if (!targetReplica) {
104
+ return this.recordOperation((0, operation_builder_js_1.createFailedOperation)(cluster, `Target '${targetPrimaryId}' not found in cluster replicas. ` +
105
+ `Available: ${cluster.replicas.map(r => `${r.host}:${r.port}`).join(', ')}`, reason || 'Manual failover requested'));
106
+ }
107
+ }
108
+ const operation = (0, operation_builder_js_1.createFailoverOperation)(cluster, targetPrimaryId, reason);
109
+ return this.executeFailoverOperation(operation, cluster);
110
+ }
111
+ // =========================================================================
112
+ // Recovery Management
113
+ // =========================================================================
114
+ /**
115
+ * Get all pending recoveries
116
+ */
117
+ getPendingRecoveries() {
118
+ return this.recoveryManager.getPending();
119
+ }
120
+ /**
121
+ * Check if an instance is pending recovery
122
+ */
123
+ isPendingRecovery(instanceId) {
124
+ return this.recoveryManager.isPending(instanceId);
125
+ }
126
+ /**
127
+ * Recover an old primary instance
128
+ */
129
+ async recoverInstance(instanceId) {
130
+ return this.recoveryManager.recover(instanceId);
131
+ }
132
+ /**
133
+ * Check all pending recoveries and recover instances that are back online
134
+ */
135
+ async checkAndRecoverAll() {
136
+ return this.recoveryManager.recoverAll();
137
+ }
138
+ /**
139
+ * Clear a pending recovery (manual override)
140
+ */
141
+ clearPendingRecovery(instanceId) {
142
+ return this.recoveryManager.clear(instanceId);
143
+ }
144
+ // =========================================================================
145
+ // Operation History
146
+ // =========================================================================
147
+ /**
148
+ * Get current operation
149
+ */
150
+ getCurrentOperation() {
151
+ return this.currentOperation;
152
+ }
153
+ /**
154
+ * Get operation history
155
+ */
156
+ getOperationHistory(clusterId, limit = 100) {
157
+ let operations = [...this.operationHistory];
158
+ if (clusterId) {
159
+ operations = operations.filter(o => o.clusterId === clusterId);
160
+ }
161
+ return operations
162
+ .sort((a, b) => (a.startedAt?.getTime() || 0) - (b.startedAt?.getTime() || 0))
163
+ .slice(-limit);
164
+ }
165
+ /**
166
+ * Get operation by ID
167
+ */
168
+ getOperation(operationId) {
169
+ return this.operationHistory.find(o => o.operationId === operationId);
170
+ }
171
+ /**
172
+ * Cancel an in-progress operation
173
+ */
174
+ async cancelOperation(operationId) {
175
+ if (this.currentOperation?.operationId === operationId) {
176
+ this.currentOperation.state = index_js_1.FailoverState.FAILED;
177
+ this.currentOperation.error = 'Cancelled by user';
178
+ this.currentOperation.completedAt = new Date();
179
+ this.operationHistory.push(this.currentOperation);
180
+ this.currentOperation = null;
181
+ return true;
182
+ }
183
+ return false;
184
+ }
185
+ // =========================================================================
186
+ // Private Methods
187
+ // =========================================================================
188
+ /**
189
+ * Record an operation to history
190
+ */
191
+ recordOperation(operation) {
192
+ this.operationHistory.push(operation);
193
+ return operation;
194
+ }
195
+ /**
196
+ * Execute switchover operation
197
+ */
198
+ async executeSwitchoverOperation(operation, cluster) {
199
+ this.currentOperation = operation;
200
+ try {
201
+ const result = await this.operationRunner.execute(operation, cluster, true);
202
+ this.operationHistory.push(result);
203
+ return result;
204
+ }
205
+ finally {
206
+ this.currentOperation = null;
207
+ }
208
+ }
209
+ /**
210
+ * Execute failover operation
211
+ */
212
+ async executeFailoverOperation(operation, cluster) {
213
+ this.currentOperation = operation;
214
+ try {
215
+ const result = await this.operationRunner.execute(operation, cluster, false);
216
+ // Queue old primary for recovery on successful failover
217
+ if (result.state === index_js_1.FailoverState.COMPLETED && cluster.primary && result.newPrimaryId) {
218
+ const pendingRecovery = recovery_manager_js_1.RecoveryManager.createPendingRecovery(cluster.clusterId, cluster.primary.host, cluster.primary.port, result.newPrimaryId);
219
+ this.recoveryManager.queueForRecovery(pendingRecovery);
220
+ const addStep = (step) => {
221
+ const timestamp = new Date().toISOString();
222
+ result.steps.push(`[${timestamp}] ${step}`);
223
+ };
224
+ addStep(`Old primary ${pendingRecovery.instanceId} queued for recovery`);
225
+ }
226
+ this.operationHistory.push(result);
227
+ return result;
228
+ }
229
+ finally {
230
+ this.currentOperation = null;
231
+ }
232
+ }
233
+ }
234
+ exports.FailoverExecutor = FailoverExecutor;
235
+ // =============================================================================
236
+ // Singleton
237
+ // =============================================================================
238
+ let failoverExecutor = null;
239
+ /**
240
+ * Get the Failover executor instance
241
+ */
242
+ function getFailoverExecutor() {
243
+ if (!failoverExecutor) {
244
+ failoverExecutor = new FailoverExecutor();
245
+ }
246
+ return failoverExecutor;
247
+ }
248
+ //# sourceMappingURL=executor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"executor.js","sourceRoot":"","sources":["../../../src/core/failover/executor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,71 @@
1
+ /**
2
+ * ClawSQL - Operation Builder
3
+ *
4
+ * Factory for creating failover operations.
5
+ * Uses the Factory Pattern to encapsulate operation creation logic.
6
+ */
7
+ import { FailoverOperation, MySQLCluster, MySQLInstance } from '../../types/index.js';
8
+ /**
9
+ * Operation Builder
10
+ * Provides a fluent interface for constructing failover operations.
11
+ */
12
+ export declare class OperationBuilder {
13
+ private operation;
14
+ /**
15
+ * Start building a new operation
16
+ */
17
+ static create(): OperationBuilder;
18
+ /**
19
+ * Set the operation ID
20
+ */
21
+ withId(id?: string): this;
22
+ /**
23
+ * Set the cluster
24
+ */
25
+ forCluster(cluster: MySQLCluster): this;
26
+ /**
27
+ * Set as manual operation
28
+ */
29
+ asManual(reason: string): this;
30
+ /**
31
+ * Set as automatic operation
32
+ */
33
+ asAutomatic(triggeredBy: string, reason: string): this;
34
+ /**
35
+ * Set target primary
36
+ */
37
+ withTarget(instance: MySQLInstance): this;
38
+ /**
39
+ * Set target by ID
40
+ */
41
+ withTargetId(targetId: string): this;
42
+ /**
43
+ * Mark as failed with error
44
+ */
45
+ asFailed(error: string): this;
46
+ /**
47
+ * Initialize as idle (ready to execute)
48
+ */
49
+ asIdle(): this;
50
+ /**
51
+ * Build the operation
52
+ */
53
+ build(): FailoverOperation;
54
+ }
55
+ /**
56
+ * Create a failed operation immediately
57
+ */
58
+ export declare function createFailedOperation(cluster: MySQLCluster, error: string, reason: string): FailoverOperation;
59
+ /**
60
+ * Create a switchover operation
61
+ */
62
+ export declare function createSwitchoverOperation(cluster: MySQLCluster, targetId: string | undefined, reason: string): FailoverOperation;
63
+ /**
64
+ * Create a failover operation
65
+ */
66
+ export declare function createFailoverOperation(cluster: MySQLCluster, targetId: string | undefined, reason: string): FailoverOperation;
67
+ /**
68
+ * Create an automatic failover operation
69
+ */
70
+ export declare function createAutomaticFailoverOperation(cluster: MySQLCluster, failureType: string, eventId: string): FailoverOperation;
71
+ //# sourceMappingURL=operation-builder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"operation-builder.d.ts","sourceRoot":"","sources":["../../../src/core/failover/operation-builder.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,iBAAiB,EAAiB,YAAY,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAErG;;;GAGG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,SAAS,CAAkC;IAEnD;;OAEG;IACH,MAAM,CAAC,MAAM,IAAI,gBAAgB;IAIjC;;OAEG;IACH,MAAM,CAAC,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI;IAKzB;;OAEG;IACH,UAAU,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI;IAQvC;;OAEG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAM9B;;OAEG;IACH,WAAW,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAOtD;;OAEG;IACH,UAAU,CAAC,QAAQ,EAAE,aAAa,GAAG,IAAI;IAKzC;;OAEG;IACH,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAKpC;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAQ7B;;OAEG;IACH,MAAM,IAAI,IAAI;IAMd;;OAEG;IACH,KAAK,IAAI,iBAAiB;CAY3B;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,YAAY,EACrB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,GACb,iBAAiB,CAMnB;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,YAAY,EACrB,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,MAAM,EAAE,MAAM,GACb,iBAAiB,CAWnB;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,YAAY,EACrB,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,MAAM,EAAE,MAAM,GACb,iBAAiB,CAWnB;AAED;;GAEG;AACH,wBAAgB,gCAAgC,CAC9C,OAAO,EAAE,YAAY,EACrB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,GACd,iBAAiB,CAMnB"}
@@ -0,0 +1,157 @@
1
+ "use strict";
2
+ /**
3
+ * ClawSQL - Operation Builder
4
+ *
5
+ * Factory for creating failover operations.
6
+ * Uses the Factory Pattern to encapsulate operation creation logic.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.OperationBuilder = void 0;
10
+ exports.createFailedOperation = createFailedOperation;
11
+ exports.createSwitchoverOperation = createSwitchoverOperation;
12
+ exports.createFailoverOperation = createFailoverOperation;
13
+ exports.createAutomaticFailoverOperation = createAutomaticFailoverOperation;
14
+ const uuid_1 = require("uuid");
15
+ const index_js_1 = require("../../types/index.js");
16
+ /**
17
+ * Operation Builder
18
+ * Provides a fluent interface for constructing failover operations.
19
+ */
20
+ class OperationBuilder {
21
+ operation = {};
22
+ /**
23
+ * Start building a new operation
24
+ */
25
+ static create() {
26
+ return new OperationBuilder();
27
+ }
28
+ /**
29
+ * Set the operation ID
30
+ */
31
+ withId(id) {
32
+ this.operation.operationId = id || (0, uuid_1.v4)();
33
+ return this;
34
+ }
35
+ /**
36
+ * Set the cluster
37
+ */
38
+ forCluster(cluster) {
39
+ this.operation.clusterId = cluster.clusterId;
40
+ this.operation.oldPrimaryId = cluster.primary
41
+ ? `${cluster.primary.host}:${cluster.primary.port}`
42
+ : '';
43
+ return this;
44
+ }
45
+ /**
46
+ * Set as manual operation
47
+ */
48
+ asManual(reason) {
49
+ this.operation.manual = true;
50
+ this.operation.reason = reason;
51
+ return this;
52
+ }
53
+ /**
54
+ * Set as automatic operation
55
+ */
56
+ asAutomatic(triggeredBy, reason) {
57
+ this.operation.manual = false;
58
+ this.operation.reason = reason;
59
+ this.operation.triggeredBy = triggeredBy;
60
+ return this;
61
+ }
62
+ /**
63
+ * Set target primary
64
+ */
65
+ withTarget(instance) {
66
+ this.operation.newPrimaryId = `${instance.host}:${instance.port}`;
67
+ return this;
68
+ }
69
+ /**
70
+ * Set target by ID
71
+ */
72
+ withTargetId(targetId) {
73
+ this.operation.newPrimaryId = targetId;
74
+ return this;
75
+ }
76
+ /**
77
+ * Mark as failed with error
78
+ */
79
+ asFailed(error) {
80
+ this.operation.state = index_js_1.FailoverState.FAILED;
81
+ this.operation.error = error;
82
+ this.operation.completedAt = new Date();
83
+ this.operation.steps = this.operation.steps || [];
84
+ return this;
85
+ }
86
+ /**
87
+ * Initialize as idle (ready to execute)
88
+ */
89
+ asIdle() {
90
+ this.operation.state = index_js_1.FailoverState.IDLE;
91
+ this.operation.steps = [];
92
+ return this;
93
+ }
94
+ /**
95
+ * Build the operation
96
+ */
97
+ build() {
98
+ if (!this.operation.operationId) {
99
+ this.operation.operationId = (0, uuid_1.v4)();
100
+ }
101
+ if (!this.operation.state) {
102
+ this.operation.state = index_js_1.FailoverState.IDLE;
103
+ }
104
+ if (!this.operation.steps) {
105
+ this.operation.steps = [];
106
+ }
107
+ return this.operation;
108
+ }
109
+ }
110
+ exports.OperationBuilder = OperationBuilder;
111
+ /**
112
+ * Create a failed operation immediately
113
+ */
114
+ function createFailedOperation(cluster, error, reason) {
115
+ return OperationBuilder.create()
116
+ .forCluster(cluster)
117
+ .asManual(reason)
118
+ .asFailed(error)
119
+ .build();
120
+ }
121
+ /**
122
+ * Create a switchover operation
123
+ */
124
+ function createSwitchoverOperation(cluster, targetId, reason) {
125
+ const builder = OperationBuilder.create()
126
+ .forCluster(cluster)
127
+ .asManual(reason)
128
+ .asIdle();
129
+ if (targetId) {
130
+ builder.withTargetId(targetId);
131
+ }
132
+ return builder.build();
133
+ }
134
+ /**
135
+ * Create a failover operation
136
+ */
137
+ function createFailoverOperation(cluster, targetId, reason) {
138
+ const builder = OperationBuilder.create()
139
+ .forCluster(cluster)
140
+ .asManual(reason)
141
+ .asIdle();
142
+ if (targetId) {
143
+ builder.withTargetId(targetId);
144
+ }
145
+ return builder.build();
146
+ }
147
+ /**
148
+ * Create an automatic failover operation
149
+ */
150
+ function createAutomaticFailoverOperation(cluster, failureType, eventId) {
151
+ return OperationBuilder.create()
152
+ .forCluster(cluster)
153
+ .asAutomatic(eventId, `Automatic failover due to ${failureType}`)
154
+ .asIdle()
155
+ .build();
156
+ }
157
+ //# sourceMappingURL=operation-builder.js.map