@jamesaphoenix/tx-core 0.4.2 → 0.4.4

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 (336) hide show
  1. package/README.md +480 -0
  2. package/dist/db.d.ts +28 -14
  3. package/dist/db.d.ts.map +1 -1
  4. package/dist/db.js +108 -14
  5. package/dist/db.js.map +1 -1
  6. package/dist/errors.d.ts +178 -34
  7. package/dist/errors.d.ts.map +1 -1
  8. package/dist/errors.js +119 -26
  9. package/dist/errors.js.map +1 -1
  10. package/dist/id.d.ts +10 -0
  11. package/dist/id.d.ts.map +1 -1
  12. package/dist/id.js +17 -1
  13. package/dist/id.js.map +1 -1
  14. package/dist/index.d.ts +15 -7
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js +62 -8
  17. package/dist/index.js.map +1 -1
  18. package/dist/layer.d.ts +23 -14
  19. package/dist/layer.d.ts.map +1 -1
  20. package/dist/layer.js +75 -76
  21. package/dist/layer.js.map +1 -1
  22. package/dist/mappers/attempt.d.ts +3 -1
  23. package/dist/mappers/attempt.d.ts.map +1 -1
  24. package/dist/mappers/attempt.js +23 -9
  25. package/dist/mappers/attempt.js.map +1 -1
  26. package/dist/mappers/claim.d.ts +1 -1
  27. package/dist/mappers/claim.d.ts.map +1 -1
  28. package/dist/mappers/claim.js +11 -4
  29. package/dist/mappers/claim.js.map +1 -1
  30. package/dist/mappers/deduplication.d.ts +13 -1
  31. package/dist/mappers/deduplication.d.ts.map +1 -1
  32. package/dist/mappers/deduplication.js +22 -3
  33. package/dist/mappers/deduplication.js.map +1 -1
  34. package/dist/mappers/doc.d.ts +24 -0
  35. package/dist/mappers/doc.d.ts.map +1 -0
  36. package/dist/mappers/doc.js +161 -0
  37. package/dist/mappers/doc.js.map +1 -0
  38. package/dist/mappers/file-learning.d.ts.map +1 -1
  39. package/dist/mappers/file-learning.js +2 -1
  40. package/dist/mappers/file-learning.js.map +1 -1
  41. package/dist/mappers/index.d.ts +6 -7
  42. package/dist/mappers/index.d.ts.map +1 -1
  43. package/dist/mappers/index.js +10 -12
  44. package/dist/mappers/index.js.map +1 -1
  45. package/dist/mappers/learning.d.ts +9 -1
  46. package/dist/mappers/learning.d.ts.map +1 -1
  47. package/dist/mappers/learning.js +94 -14
  48. package/dist/mappers/learning.js.map +1 -1
  49. package/dist/mappers/orchestrator-state.d.ts +1 -1
  50. package/dist/mappers/orchestrator-state.d.ts.map +1 -1
  51. package/dist/mappers/orchestrator-state.js +31 -5
  52. package/dist/mappers/orchestrator-state.js.map +1 -1
  53. package/dist/mappers/parse-date.d.ts +11 -0
  54. package/dist/mappers/parse-date.d.ts.map +1 -0
  55. package/dist/mappers/parse-date.js +18 -0
  56. package/dist/mappers/parse-date.js.map +1 -0
  57. package/dist/mappers/run.d.ts +14 -4
  58. package/dist/mappers/run.d.ts.map +1 -1
  59. package/dist/mappers/run.js +49 -18
  60. package/dist/mappers/run.js.map +1 -1
  61. package/dist/mappers/task.d.ts +5 -1
  62. package/dist/mappers/task.d.ts.map +1 -1
  63. package/dist/mappers/task.js +66 -16
  64. package/dist/mappers/task.js.map +1 -1
  65. package/dist/mappers/tracked-project.d.ts +3 -1
  66. package/dist/mappers/tracked-project.d.ts.map +1 -1
  67. package/dist/mappers/tracked-project.js +23 -9
  68. package/dist/mappers/tracked-project.js.map +1 -1
  69. package/dist/mappers/worker.d.ts +1 -1
  70. package/dist/mappers/worker.d.ts.map +1 -1
  71. package/dist/mappers/worker.js +44 -6
  72. package/dist/mappers/worker.js.map +1 -1
  73. package/dist/repo/attempt-repo.d.ts +2 -2
  74. package/dist/repo/attempt-repo.d.ts.map +1 -1
  75. package/dist/repo/attempt-repo.js +16 -6
  76. package/dist/repo/attempt-repo.js.map +1 -1
  77. package/dist/repo/claim-repo.d.ts +46 -2
  78. package/dist/repo/claim-repo.d.ts.map +1 -1
  79. package/dist/repo/claim-repo.js +113 -6
  80. package/dist/repo/claim-repo.js.map +1 -1
  81. package/dist/repo/deduplication-repo.d.ts +9 -1
  82. package/dist/repo/deduplication-repo.d.ts.map +1 -1
  83. package/dist/repo/deduplication-repo.js +46 -9
  84. package/dist/repo/deduplication-repo.js.map +1 -1
  85. package/dist/repo/dep-repo.d.ts +27 -3
  86. package/dist/repo/dep-repo.d.ts.map +1 -1
  87. package/dist/repo/dep-repo.js +166 -39
  88. package/dist/repo/dep-repo.js.map +1 -1
  89. package/dist/repo/doc-repo.d.ts +59 -0
  90. package/dist/repo/doc-repo.d.ts.map +1 -0
  91. package/dist/repo/doc-repo.js +276 -0
  92. package/dist/repo/doc-repo.js.map +1 -0
  93. package/dist/repo/file-learning-repo.d.ts +3 -3
  94. package/dist/repo/file-learning-repo.d.ts.map +1 -1
  95. package/dist/repo/file-learning-repo.js +19 -8
  96. package/dist/repo/file-learning-repo.js.map +1 -1
  97. package/dist/repo/index.d.ts +4 -6
  98. package/dist/repo/index.d.ts.map +1 -1
  99. package/dist/repo/index.js +3 -5
  100. package/dist/repo/index.js.map +1 -1
  101. package/dist/repo/learning-repo.d.ts +10 -3
  102. package/dist/repo/learning-repo.d.ts.map +1 -1
  103. package/dist/repo/learning-repo.js +68 -11
  104. package/dist/repo/learning-repo.js.map +1 -1
  105. package/dist/repo/orchestrator-state-repo.d.ts.map +1 -1
  106. package/dist/repo/orchestrator-state-repo.js +8 -1
  107. package/dist/repo/orchestrator-state-repo.js.map +1 -1
  108. package/dist/repo/run-repo.d.ts +3 -3
  109. package/dist/repo/run-repo.d.ts.map +1 -1
  110. package/dist/repo/run-repo.js +40 -19
  111. package/dist/repo/run-repo.js.map +1 -1
  112. package/dist/repo/task-repo.d.ts +14 -3
  113. package/dist/repo/task-repo.d.ts.map +1 -1
  114. package/dist/repo/task-repo.js +194 -20
  115. package/dist/repo/task-repo.js.map +1 -1
  116. package/dist/repo/tracked-project-repo.d.ts.map +1 -1
  117. package/dist/repo/tracked-project-repo.js +15 -1
  118. package/dist/repo/tracked-project-repo.js.map +1 -1
  119. package/dist/repo/worker-repo.d.ts +3 -2
  120. package/dist/repo/worker-repo.d.ts.map +1 -1
  121. package/dist/repo/worker-repo.js +54 -8
  122. package/dist/repo/worker-repo.js.map +1 -1
  123. package/dist/schemas/sync.js +2 -2
  124. package/dist/schemas/sync.js.map +1 -1
  125. package/dist/schemas/worker.d.ts +1 -0
  126. package/dist/schemas/worker.d.ts.map +1 -1
  127. package/dist/schemas/worker.js +1 -0
  128. package/dist/schemas/worker.js.map +1 -1
  129. package/dist/services/agent-service.d.ts +57 -0
  130. package/dist/services/agent-service.d.ts.map +1 -0
  131. package/dist/services/agent-service.js +81 -0
  132. package/dist/services/agent-service.js.map +1 -0
  133. package/dist/services/attempt-service.d.ts.map +1 -1
  134. package/dist/services/attempt-service.js +1 -4
  135. package/dist/services/attempt-service.js.map +1 -1
  136. package/dist/services/auto-sync-service.d.ts.map +1 -1
  137. package/dist/services/auto-sync-service.js +18 -10
  138. package/dist/services/auto-sync-service.js.map +1 -1
  139. package/dist/services/claim-service.d.ts +8 -2
  140. package/dist/services/claim-service.d.ts.map +1 -1
  141. package/dist/services/claim-service.js +37 -23
  142. package/dist/services/claim-service.js.map +1 -1
  143. package/dist/services/cycle-scan-service.d.ts +32 -0
  144. package/dist/services/cycle-scan-service.d.ts.map +1 -0
  145. package/dist/services/cycle-scan-service.js +546 -0
  146. package/dist/services/cycle-scan-service.js.map +1 -0
  147. package/dist/services/daemon-service.d.ts +40 -2
  148. package/dist/services/daemon-service.d.ts.map +1 -1
  149. package/dist/services/daemon-service.js +199 -52
  150. package/dist/services/daemon-service.js.map +1 -1
  151. package/dist/services/deduplication-service.d.ts +8 -4
  152. package/dist/services/deduplication-service.d.ts.map +1 -1
  153. package/dist/services/deduplication-service.js +79 -25
  154. package/dist/services/deduplication-service.js.map +1 -1
  155. package/dist/services/dep-service.d.ts +2 -2
  156. package/dist/services/dep-service.d.ts.map +1 -1
  157. package/dist/services/dep-service.js +9 -5
  158. package/dist/services/dep-service.js.map +1 -1
  159. package/dist/services/diversifier-service.d.ts +2 -1
  160. package/dist/services/diversifier-service.d.ts.map +1 -1
  161. package/dist/services/diversifier-service.js +37 -43
  162. package/dist/services/diversifier-service.js.map +1 -1
  163. package/dist/services/doc-service.d.ts +49 -0
  164. package/dist/services/doc-service.d.ts.map +1 -0
  165. package/dist/services/doc-service.js +605 -0
  166. package/dist/services/doc-service.js.map +1 -0
  167. package/dist/services/embedding-service.d.ts +66 -2
  168. package/dist/services/embedding-service.d.ts.map +1 -1
  169. package/dist/services/embedding-service.js +138 -24
  170. package/dist/services/embedding-service.js.map +1 -1
  171. package/dist/services/file-learning-service.d.ts.map +1 -1
  172. package/dist/services/file-learning-service.js +8 -7
  173. package/dist/services/file-learning-service.js.map +1 -1
  174. package/dist/services/file-watcher-service.d.ts.map +1 -1
  175. package/dist/services/file-watcher-service.js +58 -11
  176. package/dist/services/file-watcher-service.js.map +1 -1
  177. package/dist/services/hierarchy-service.d.ts +1 -1
  178. package/dist/services/hierarchy-service.d.ts.map +1 -1
  179. package/dist/services/hierarchy-service.js +50 -32
  180. package/dist/services/hierarchy-service.js.map +1 -1
  181. package/dist/services/index.d.ts +13 -15
  182. package/dist/services/index.d.ts.map +1 -1
  183. package/dist/services/index.js +13 -15
  184. package/dist/services/index.js.map +1 -1
  185. package/dist/services/learning-service.d.ts +3 -3
  186. package/dist/services/learning-service.d.ts.map +1 -1
  187. package/dist/services/learning-service.js +75 -42
  188. package/dist/services/learning-service.js.map +1 -1
  189. package/dist/services/llm-service.d.ts +62 -0
  190. package/dist/services/llm-service.d.ts.map +1 -0
  191. package/dist/services/llm-service.js +172 -0
  192. package/dist/services/llm-service.js.map +1 -0
  193. package/dist/services/migration-service.d.ts +1 -1
  194. package/dist/services/migration-service.d.ts.map +1 -1
  195. package/dist/services/migration-service.js +18 -7
  196. package/dist/services/migration-service.js.map +1 -1
  197. package/dist/services/orchestrator-service.d.ts +4 -3
  198. package/dist/services/orchestrator-service.d.ts.map +1 -1
  199. package/dist/services/orchestrator-service.js +66 -27
  200. package/dist/services/orchestrator-service.js.map +1 -1
  201. package/dist/services/query-expansion-service.d.ts +30 -9
  202. package/dist/services/query-expansion-service.d.ts.map +1 -1
  203. package/dist/services/query-expansion-service.js +54 -63
  204. package/dist/services/query-expansion-service.js.map +1 -1
  205. package/dist/services/ready-service.d.ts +21 -1
  206. package/dist/services/ready-service.d.ts.map +1 -1
  207. package/dist/services/ready-service.js +44 -21
  208. package/dist/services/ready-service.js.map +1 -1
  209. package/dist/services/retriever-service.d.ts +10 -10
  210. package/dist/services/retriever-service.d.ts.map +1 -1
  211. package/dist/services/retriever-service.js +53 -161
  212. package/dist/services/retriever-service.js.map +1 -1
  213. package/dist/services/sync-service.d.ts +17 -4
  214. package/dist/services/sync-service.d.ts.map +1 -1
  215. package/dist/services/sync-service.js +381 -116
  216. package/dist/services/sync-service.js.map +1 -1
  217. package/dist/services/task-service.d.ts +6 -4
  218. package/dist/services/task-service.d.ts.map +1 -1
  219. package/dist/services/task-service.js +165 -35
  220. package/dist/services/task-service.js.map +1 -1
  221. package/dist/services/tracing-service.d.ts +55 -0
  222. package/dist/services/tracing-service.d.ts.map +1 -0
  223. package/dist/services/tracing-service.js +99 -0
  224. package/dist/services/tracing-service.js.map +1 -0
  225. package/dist/services/transcript-adapter.d.ts +99 -0
  226. package/dist/services/transcript-adapter.d.ts.map +1 -0
  227. package/dist/services/transcript-adapter.js +283 -0
  228. package/dist/services/transcript-adapter.js.map +1 -0
  229. package/dist/services/validation-service.d.ts +85 -0
  230. package/dist/services/validation-service.d.ts.map +1 -0
  231. package/dist/services/validation-service.js +289 -0
  232. package/dist/services/validation-service.js.map +1 -0
  233. package/dist/services/worker-process.d.ts +23 -4
  234. package/dist/services/worker-process.d.ts.map +1 -1
  235. package/dist/services/worker-process.js +168 -72
  236. package/dist/services/worker-process.js.map +1 -1
  237. package/dist/services/worker-service.d.ts.map +1 -1
  238. package/dist/services/worker-service.js +7 -12
  239. package/dist/services/worker-service.js.map +1 -1
  240. package/dist/sync/claude-task-writer.d.ts +49 -0
  241. package/dist/sync/claude-task-writer.d.ts.map +1 -0
  242. package/dist/sync/claude-task-writer.js +135 -0
  243. package/dist/sync/claude-task-writer.js.map +1 -0
  244. package/dist/utils/doc-hash.d.ts +10 -0
  245. package/dist/utils/doc-hash.d.ts.map +1 -0
  246. package/dist/utils/doc-hash.js +14 -0
  247. package/dist/utils/doc-hash.js.map +1 -0
  248. package/dist/utils/doc-renderer.d.ts +44 -0
  249. package/dist/utils/doc-renderer.d.ts.map +1 -0
  250. package/dist/utils/doc-renderer.js +202 -0
  251. package/dist/utils/doc-renderer.js.map +1 -0
  252. package/dist/utils/math.d.ts +5 -1
  253. package/dist/utils/math.d.ts.map +1 -1
  254. package/dist/utils/math.js +12 -4
  255. package/dist/utils/math.js.map +1 -1
  256. package/dist/utils/sql.d.ts +9 -0
  257. package/dist/utils/sql.d.ts.map +1 -0
  258. package/dist/utils/sql.js +9 -0
  259. package/dist/utils/sql.js.map +1 -0
  260. package/dist/utils/toml-config.d.ts +22 -0
  261. package/dist/utils/toml-config.d.ts.map +1 -0
  262. package/dist/utils/toml-config.js +75 -0
  263. package/dist/utils/toml-config.js.map +1 -0
  264. package/dist/worker/hooks.d.ts +102 -0
  265. package/dist/worker/hooks.d.ts.map +1 -0
  266. package/dist/worker/hooks.js +11 -0
  267. package/dist/worker/hooks.js.map +1 -0
  268. package/dist/worker/index.d.ts +9 -0
  269. package/dist/worker/index.d.ts.map +1 -0
  270. package/dist/worker/index.js +8 -0
  271. package/dist/worker/index.js.map +1 -0
  272. package/dist/worker/run-worker.d.ts +33 -0
  273. package/dist/worker/run-worker.d.ts.map +1 -0
  274. package/dist/worker/run-worker.js +265 -0
  275. package/dist/worker/run-worker.js.map +1 -0
  276. package/package.json +14 -12
  277. package/dist/mappers/anchor.d.ts +0 -14
  278. package/dist/mappers/anchor.d.ts.map +0 -1
  279. package/dist/mappers/anchor.js +0 -38
  280. package/dist/mappers/anchor.js.map +0 -1
  281. package/dist/mappers/candidate.d.ts +0 -23
  282. package/dist/mappers/candidate.d.ts.map +0 -1
  283. package/dist/mappers/candidate.js +0 -53
  284. package/dist/mappers/candidate.js.map +0 -1
  285. package/dist/mappers/edge.d.ts +0 -10
  286. package/dist/mappers/edge.d.ts.map +0 -1
  287. package/dist/mappers/edge.js +0 -19
  288. package/dist/mappers/edge.js.map +0 -1
  289. package/dist/repo/anchor-repo.d.ts +0 -52
  290. package/dist/repo/anchor-repo.d.ts.map +0 -1
  291. package/dist/repo/anchor-repo.js +0 -204
  292. package/dist/repo/anchor-repo.js.map +0 -1
  293. package/dist/repo/candidate-repo.d.ts +0 -16
  294. package/dist/repo/candidate-repo.d.ts.map +0 -1
  295. package/dist/repo/candidate-repo.js +0 -143
  296. package/dist/repo/candidate-repo.js.map +0 -1
  297. package/dist/repo/edge-repo.d.ts +0 -26
  298. package/dist/repo/edge-repo.d.ts.map +0 -1
  299. package/dist/repo/edge-repo.js +0 -227
  300. package/dist/repo/edge-repo.js.map +0 -1
  301. package/dist/services/anchor-service.d.ts +0 -147
  302. package/dist/services/anchor-service.d.ts.map +0 -1
  303. package/dist/services/anchor-service.js +0 -540
  304. package/dist/services/anchor-service.js.map +0 -1
  305. package/dist/services/anchor-verification.d.ts +0 -94
  306. package/dist/services/anchor-verification.d.ts.map +0 -1
  307. package/dist/services/anchor-verification.js +0 -617
  308. package/dist/services/anchor-verification.js.map +0 -1
  309. package/dist/services/ast-grep-service.d.ts +0 -58
  310. package/dist/services/ast-grep-service.d.ts.map +0 -1
  311. package/dist/services/ast-grep-service.js +0 -356
  312. package/dist/services/ast-grep-service.js.map +0 -1
  313. package/dist/services/candidate-extractor-service.d.ts +0 -56
  314. package/dist/services/candidate-extractor-service.d.ts.map +0 -1
  315. package/dist/services/candidate-extractor-service.js +0 -365
  316. package/dist/services/candidate-extractor-service.js.map +0 -1
  317. package/dist/services/edge-service.d.ts +0 -78
  318. package/dist/services/edge-service.d.ts.map +0 -1
  319. package/dist/services/edge-service.js +0 -158
  320. package/dist/services/edge-service.js.map +0 -1
  321. package/dist/services/feedback-tracker.d.ts +0 -64
  322. package/dist/services/feedback-tracker.d.ts.map +0 -1
  323. package/dist/services/feedback-tracker.js +0 -110
  324. package/dist/services/feedback-tracker.js.map +0 -1
  325. package/dist/services/graph-expansion.d.ts +0 -155
  326. package/dist/services/graph-expansion.d.ts.map +0 -1
  327. package/dist/services/graph-expansion.js +0 -466
  328. package/dist/services/graph-expansion.js.map +0 -1
  329. package/dist/services/promotion-service.d.ts +0 -67
  330. package/dist/services/promotion-service.d.ts.map +0 -1
  331. package/dist/services/promotion-service.js +0 -151
  332. package/dist/services/promotion-service.js.map +0 -1
  333. package/dist/services/swarm-verification.d.ts +0 -104
  334. package/dist/services/swarm-verification.d.ts.map +0 -1
  335. package/dist/services/swarm-verification.js +0 -400
  336. package/dist/services/swarm-verification.js.map +0 -1
@@ -1,6 +1,6 @@
1
1
  import { Context, Effect, Layer } from "effect";
2
2
  import { SqliteClient } from "../db.js";
3
- import { DatabaseError } from "../errors.js";
3
+ import { AttemptNotFoundError, DatabaseError, EntityFetchError } from "../errors.js";
4
4
  import { rowToAttempt } from "../mappers/attempt.js";
5
5
  export class AttemptRepository extends Context.Tag("AttemptRepository")() {
6
6
  }
@@ -14,6 +14,13 @@ export const AttemptRepositoryLive = Layer.effect(AttemptRepository, Effect.gen(
14
14
  VALUES (?, ?, ?, ?, ?)`).run(input.taskId, input.approach, input.outcome, input.reason ?? null, now);
15
15
  // Fetch the inserted row
16
16
  const row = db.prepare("SELECT * FROM attempts WHERE id = ?").get(result.lastInsertRowid);
17
+ if (!row) {
18
+ throw new EntityFetchError({
19
+ entity: "attempt",
20
+ id: result.lastInsertRowid,
21
+ operation: "insert"
22
+ });
23
+ }
17
24
  return rowToAttempt(row);
18
25
  },
19
26
  catch: (cause) => new DatabaseError({ cause })
@@ -50,11 +57,14 @@ export const AttemptRepositoryLive = Layer.effect(AttemptRepository, Effect.gen(
50
57
  },
51
58
  catch: (cause) => new DatabaseError({ cause })
52
59
  }),
53
- remove: (id) => Effect.try({
54
- try: () => {
55
- db.prepare("DELETE FROM attempts WHERE id = ?").run(id);
56
- },
57
- catch: (cause) => new DatabaseError({ cause })
60
+ remove: (id) => Effect.gen(function* () {
61
+ const result = yield* Effect.try({
62
+ try: () => db.prepare("DELETE FROM attempts WHERE id = ?").run(id),
63
+ catch: (cause) => new DatabaseError({ cause })
64
+ });
65
+ if (result.changes === 0) {
66
+ yield* Effect.fail(new AttemptNotFoundError({ id }));
67
+ }
58
68
  }),
59
69
  getFailedCountsForTasks: (taskIds) => Effect.try({
60
70
  try: () => {
@@ -1 +1 @@
1
- {"version":3,"file":"attempt-repo.js","sourceRoot":"","sources":["../../src/repo/attempt-repo.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"attempt-repo.js","sourceRoot":"","sources":["../../src/repo/attempt-repo.ts"],"names":[],"mappings":"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"}
@@ -1,14 +1,58 @@
1
1
  import { Context, Effect, Layer } from "effect";
2
2
  import { SqliteClient } from "../db.js";
3
- import { DatabaseError } from "../errors.js";
3
+ import { ClaimIdNotFoundError, DatabaseError } from "../errors.js";
4
4
  import type { TaskClaim } from "../schemas/worker.js";
5
+ /**
6
+ * Result of an atomic claim insert attempt.
7
+ */
8
+ export interface AtomicInsertResult {
9
+ /** Whether the insert succeeded (no existing active claim) */
10
+ success: boolean;
11
+ /** The claim if insert succeeded, null otherwise */
12
+ claim: TaskClaim | null;
13
+ /** If insert failed, the existing claim that blocked it */
14
+ existingClaim: TaskClaim | null;
15
+ }
16
+ /**
17
+ * Result of an atomic lease renewal attempt.
18
+ */
19
+ export interface AtomicRenewResult {
20
+ /** Whether the renewal succeeded */
21
+ success: boolean;
22
+ /** The renewed claim if successful, null otherwise */
23
+ claim: TaskClaim | null;
24
+ /** Reason for failure if not successful */
25
+ failureReason: "not_found" | "expired" | null;
26
+ }
5
27
  declare const ClaimRepository_base: Context.TagClass<ClaimRepository, "ClaimRepository", {
6
28
  readonly insert: (claim: Omit<TaskClaim, "id">) => Effect.Effect<TaskClaim, DatabaseError>;
7
- readonly update: (claim: TaskClaim) => Effect.Effect<void, DatabaseError>;
29
+ /**
30
+ * Atomically insert a claim only if no active claim exists for the task.
31
+ * Uses a single SQL operation to prevent race conditions.
32
+ */
33
+ readonly tryInsertAtomic: (claim: Omit<TaskClaim, "id">) => Effect.Effect<AtomicInsertResult, DatabaseError>;
34
+ readonly update: (claim: TaskClaim) => Effect.Effect<void, DatabaseError | ClaimIdNotFoundError>;
35
+ /**
36
+ * Atomically renew a lease only if it hasn't expired yet.
37
+ * Uses a single SQL operation to prevent race conditions between
38
+ * checking expiration and performing the renewal.
39
+ *
40
+ * @param claimId - The ID of the claim to renew
41
+ * @param workerId - The worker ID that must own the claim
42
+ * @param newLeaseExpiresAt - The new expiration time
43
+ * @returns AtomicRenewResult indicating success/failure and reason
44
+ */
45
+ readonly tryRenewAtomic: (claimId: number, workerId: string, newLeaseExpiresAt: Date) => Effect.Effect<AtomicRenewResult, DatabaseError>;
8
46
  readonly findById: (id: number) => Effect.Effect<TaskClaim | null, DatabaseError>;
9
47
  readonly findActiveByTaskId: (taskId: string) => Effect.Effect<TaskClaim | null, DatabaseError>;
10
48
  readonly findExpired: (now: Date) => Effect.Effect<readonly TaskClaim[], DatabaseError>;
11
49
  readonly releaseAllByWorkerId: (workerId: string) => Effect.Effect<number, DatabaseError>;
50
+ /**
51
+ * Find active claims where the associated task status is not 'active'.
52
+ * This detects orphaned claims left behind when claim release fails
53
+ * after task completion.
54
+ */
55
+ readonly findOrphanedClaims: () => Effect.Effect<readonly TaskClaim[], DatabaseError>;
12
56
  }>;
13
57
  export declare class ClaimRepository extends ClaimRepository_base {
14
58
  }
@@ -1 +1 @@
1
- {"version":3,"file":"claim-repo.d.ts","sourceRoot":"","sources":["../../src/repo/claim-repo.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAA;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAE5C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAA;;qBAKhC,CAAC,KAAK,EAAE,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,KAAK,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,aAAa,CAAC;qBACzE,CAAC,KAAK,EAAE,SAAS,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,aAAa,CAAC;uBACtD,CAAC,EAAE,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,SAAS,GAAG,IAAI,EAAE,aAAa,CAAC;iCACpD,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,SAAS,GAAG,IAAI,EAAE,aAAa,CAAC;0BACzE,CAAC,GAAG,EAAE,IAAI,KAAK,MAAM,CAAC,MAAM,CAAC,SAAS,SAAS,EAAE,EAAE,aAAa,CAAC;mCACxD,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC;;AAR7F,qBAAa,eAAgB,SAAQ,oBAUlC;CAAG;AAEN,eAAO,MAAM,mBAAmB,mDAkG/B,CAAA"}
1
+ {"version":3,"file":"claim-repo.d.ts","sourceRoot":"","sources":["../../src/repo/claim-repo.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAA;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AACvC,OAAO,EAAE,oBAAoB,EAAE,aAAa,EAAoB,MAAM,cAAc,CAAA;AAEpF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAA;AAErD;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,8DAA8D;IAC9D,OAAO,EAAE,OAAO,CAAA;IAChB,oDAAoD;IACpD,KAAK,EAAE,SAAS,GAAG,IAAI,CAAA;IACvB,2DAA2D;IAC3D,aAAa,EAAE,SAAS,GAAG,IAAI,CAAA;CAChC;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,oCAAoC;IACpC,OAAO,EAAE,OAAO,CAAA;IAChB,sDAAsD;IACtD,KAAK,EAAE,SAAS,GAAG,IAAI,CAAA;IACvB,2CAA2C;IAC3C,aAAa,EAAE,WAAW,GAAG,SAAS,GAAG,IAAI,CAAA;CAC9C;;qBAKoB,CAAC,KAAK,EAAE,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,KAAK,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,aAAa,CAAC;IAC1F;;;OAGG;8BACuB,CAAC,KAAK,EAAE,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,KAAK,MAAM,CAAC,MAAM,CAAC,kBAAkB,EAAE,aAAa,CAAC;qBAC3F,CAAC,KAAK,EAAE,SAAS,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,aAAa,GAAG,oBAAoB,CAAC;IAChG;;;;;;;;;OASG;6BACsB,CACvB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,iBAAiB,EAAE,IAAI,KACpB,MAAM,CAAC,MAAM,CAAC,iBAAiB,EAAE,aAAa,CAAC;uBACjC,CAAC,EAAE,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,SAAS,GAAG,IAAI,EAAE,aAAa,CAAC;iCACpD,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,SAAS,GAAG,IAAI,EAAE,aAAa,CAAC;0BACzE,CAAC,GAAG,EAAE,IAAI,KAAK,MAAM,CAAC,MAAM,CAAC,SAAS,SAAS,EAAE,EAAE,aAAa,CAAC;mCACxD,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC;IACzF;;;;OAIG;iCAC0B,MAAM,MAAM,CAAC,MAAM,CAAC,SAAS,SAAS,EAAE,EAAE,aAAa,CAAC;;AAlCzF,qBAAa,eAAgB,SAAQ,oBAoClC;CAAG;AAEN,eAAO,MAAM,mBAAmB,mDAgP/B,CAAA"}
@@ -1,6 +1,6 @@
1
1
  import { Context, Effect, Layer } from "effect";
2
2
  import { SqliteClient } from "../db.js";
3
- import { DatabaseError } from "../errors.js";
3
+ import { ClaimIdNotFoundError, DatabaseError, EntityFetchError } from "../errors.js";
4
4
  import { rowToClaim } from "../mappers/claim.js";
5
5
  export class ClaimRepository extends Context.Tag("ClaimRepository")() {
6
6
  }
@@ -13,16 +13,110 @@ export const ClaimRepositoryLive = Layer.effect(ClaimRepository, Effect.gen(func
13
13
  (task_id, worker_id, claimed_at, lease_expires_at, renewed_count, status)
14
14
  VALUES (?, ?, ?, ?, ?, ?)`).run(claim.taskId, claim.workerId, claim.claimedAt.toISOString(), claim.leaseExpiresAt.toISOString(), claim.renewedCount, claim.status);
15
15
  const row = db.prepare("SELECT * FROM task_claims WHERE id = ?").get(result.lastInsertRowid);
16
+ if (!row) {
17
+ throw new EntityFetchError({
18
+ entity: "claim",
19
+ id: result.lastInsertRowid,
20
+ operation: "insert"
21
+ });
22
+ }
16
23
  return rowToClaim(row);
17
24
  },
18
25
  catch: (cause) => new DatabaseError({ cause })
19
26
  }),
20
- update: (claim) => Effect.try({
27
+ tryInsertAtomic: (claim) => Effect.try({
21
28
  try: () => {
22
- db.prepare(`UPDATE task_claims SET
23
- task_id = ?, worker_id = ?, claimed_at = ?,
24
- lease_expires_at = ?, renewed_count = ?, status = ?
25
- WHERE id = ?`).run(claim.taskId, claim.workerId, claim.claimedAt.toISOString(), claim.leaseExpiresAt.toISOString(), claim.renewedCount, claim.status, claim.id);
29
+ // Use INSERT ... WHERE NOT EXISTS to atomically check and insert
30
+ // This prevents the check-then-act race condition
31
+ const result = db.prepare(`INSERT INTO task_claims
32
+ (task_id, worker_id, claimed_at, lease_expires_at, renewed_count, status)
33
+ SELECT ?, ?, ?, ?, ?, ?
34
+ WHERE NOT EXISTS (
35
+ SELECT 1 FROM task_claims
36
+ WHERE task_id = ? AND status = 'active'
37
+ )`).run(claim.taskId, claim.workerId, claim.claimedAt.toISOString(), claim.leaseExpiresAt.toISOString(), claim.renewedCount, claim.status, claim.taskId // For the WHERE NOT EXISTS subquery
38
+ );
39
+ if (result.changes > 0) {
40
+ // Insert succeeded - fetch the newly created claim
41
+ const row = db.prepare("SELECT * FROM task_claims WHERE id = ?").get(result.lastInsertRowid);
42
+ if (!row) {
43
+ throw new EntityFetchError({
44
+ entity: "claim",
45
+ id: result.lastInsertRowid,
46
+ operation: "insert"
47
+ });
48
+ }
49
+ return {
50
+ success: true,
51
+ claim: rowToClaim(row),
52
+ existingClaim: null
53
+ };
54
+ }
55
+ else {
56
+ // Insert was blocked by existing active claim - fetch it
57
+ const existingRow = db.prepare("SELECT * FROM task_claims WHERE task_id = ? AND status = 'active' LIMIT 1").get(claim.taskId);
58
+ return {
59
+ success: false,
60
+ claim: null,
61
+ existingClaim: existingRow ? rowToClaim(existingRow) : null
62
+ };
63
+ }
64
+ },
65
+ catch: (cause) => new DatabaseError({ cause })
66
+ }),
67
+ update: (claim) => Effect.gen(function* () {
68
+ const result = yield* Effect.try({
69
+ try: () => db.prepare(`UPDATE task_claims SET
70
+ task_id = ?, worker_id = ?, claimed_at = ?,
71
+ lease_expires_at = ?, renewed_count = ?, status = ?
72
+ WHERE id = ?`).run(claim.taskId, claim.workerId, claim.claimedAt.toISOString(), claim.leaseExpiresAt.toISOString(), claim.renewedCount, claim.status, claim.id),
73
+ catch: (cause) => new DatabaseError({ cause })
74
+ });
75
+ if (result.changes === 0) {
76
+ yield* Effect.fail(new ClaimIdNotFoundError({ claimId: claim.id }));
77
+ }
78
+ }),
79
+ tryRenewAtomic: (claimId, workerId, newLeaseExpiresAt) => Effect.try({
80
+ try: () => {
81
+ const now = new Date().toISOString();
82
+ // Atomic update: only succeeds if claim is active, owned by worker, and not expired
83
+ const result = db.prepare(`UPDATE task_claims
84
+ SET lease_expires_at = ?, renewed_count = renewed_count + 1
85
+ WHERE id = ? AND worker_id = ? AND status = 'active' AND lease_expires_at >= ?`).run(newLeaseExpiresAt.toISOString(), claimId, workerId, now);
86
+ if (result.changes > 0) {
87
+ // Renewal succeeded - fetch the updated claim
88
+ const row = db.prepare("SELECT * FROM task_claims WHERE id = ?").get(claimId);
89
+ if (!row) {
90
+ throw new EntityFetchError({
91
+ entity: "claim",
92
+ id: claimId,
93
+ operation: "update"
94
+ });
95
+ }
96
+ return {
97
+ success: true,
98
+ claim: rowToClaim(row),
99
+ failureReason: null
100
+ };
101
+ }
102
+ else {
103
+ // Renewal failed - determine why
104
+ // Check if claim exists and is owned by this worker
105
+ const existingRow = db.prepare("SELECT * FROM task_claims WHERE id = ? AND worker_id = ? AND status = 'active'").get(claimId, workerId);
106
+ if (!existingRow) {
107
+ return {
108
+ success: false,
109
+ claim: null,
110
+ failureReason: "not_found"
111
+ };
112
+ }
113
+ // Claim exists but lease has expired
114
+ return {
115
+ success: false,
116
+ claim: null,
117
+ failureReason: "expired"
118
+ };
119
+ }
26
120
  },
27
121
  catch: (cause) => new DatabaseError({ cause })
28
122
  }),
@@ -56,6 +150,19 @@ export const ClaimRepositoryLive = Layer.effect(ClaimRepository, Effect.gen(func
56
150
  return result.changes;
57
151
  },
58
152
  catch: (cause) => new DatabaseError({ cause })
153
+ }),
154
+ findOrphanedClaims: () => Effect.try({
155
+ try: () => {
156
+ // Find active claims where the task status is NOT 'active'
157
+ // This catches claims that weren't released after task completion
158
+ const rows = db.prepare(`SELECT c.* FROM task_claims c
159
+ JOIN tasks t ON c.task_id = t.id
160
+ WHERE c.status = 'active'
161
+ AND t.status != 'active'
162
+ ORDER BY c.claimed_at ASC`).all();
163
+ return rows.map(rowToClaim);
164
+ },
165
+ catch: (cause) => new DatabaseError({ cause })
59
166
  })
60
167
  };
61
168
  }));
@@ -1 +1 @@
1
- {"version":3,"file":"claim-repo.js","sourceRoot":"","sources":["../../src/repo/claim-repo.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAA;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAC5C,OAAO,EAAE,UAAU,EAAiB,MAAM,qBAAqB,CAAA;AAG/D,MAAM,OAAO,eAAgB,SAAQ,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,EAUhE;CAAG;AAEN,MAAM,CAAC,MAAM,mBAAmB,GAAG,KAAK,CAAC,MAAM,CAC7C,eAAe,EACf,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAClB,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,YAAY,CAAA;IAE9B,OAAO;QACL,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE,CAChB,MAAM,CAAC,GAAG,CAAC;YACT,GAAG,EAAE,GAAG,EAAE;gBACR,MAAM,MAAM,GAAG,EAAE,CAAC,OAAO,CACvB;;yCAE2B,CAC5B,CAAC,GAAG,CACH,KAAK,CAAC,MAAM,EACZ,KAAK,CAAC,QAAQ,EACd,KAAK,CAAC,SAAS,CAAC,WAAW,EAAE,EAC7B,KAAK,CAAC,cAAc,CAAC,WAAW,EAAE,EAClC,KAAK,CAAC,YAAY,EAClB,KAAK,CAAC,MAAM,CACb,CAAA;gBACD,MAAM,GAAG,GAAG,EAAE,CAAC,OAAO,CACpB,wCAAwC,CACzC,CAAC,GAAG,CAAC,MAAM,CAAC,eAAe,CAAa,CAAA;gBACzC,OAAO,UAAU,CAAC,GAAG,CAAC,CAAA;YACxB,CAAC;YACD,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,aAAa,CAAC,EAAE,KAAK,EAAE,CAAC;SAC/C,CAAC;QAEJ,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE,CAChB,MAAM,CAAC,GAAG,CAAC;YACT,GAAG,EAAE,GAAG,EAAE;gBACR,EAAE,CAAC,OAAO,CACR;;;4BAGc,CACf,CAAC,GAAG,CACH,KAAK,CAAC,MAAM,EACZ,KAAK,CAAC,QAAQ,EACd,KAAK,CAAC,SAAS,CAAC,WAAW,EAAE,EAC7B,KAAK,CAAC,cAAc,CAAC,WAAW,EAAE,EAClC,KAAK,CAAC,YAAY,EAClB,KAAK,CAAC,MAAM,EACZ,KAAK,CAAC,EAAE,CACT,CAAA;YACH,CAAC;YACD,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,aAAa,CAAC,EAAE,KAAK,EAAE,CAAC;SAC/C,CAAC;QAEJ,QAAQ,EAAE,CAAC,EAAE,EAAE,EAAE,CACf,MAAM,CAAC,GAAG,CAAC;YACT,GAAG,EAAE,GAAG,EAAE;gBACR,MAAM,GAAG,GAAG,EAAE,CAAC,OAAO,CACpB,wCAAwC,CACzC,CAAC,GAAG,CAAC,EAAE,CAAyB,CAAA;gBACjC,OAAO,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;YACrC,CAAC;YACD,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,aAAa,CAAC,EAAE,KAAK,EAAE,CAAC;SAC/C,CAAC;QAEJ,kBAAkB,EAAE,CAAC,MAAM,EAAE,EAAE,CAC7B,MAAM,CAAC,GAAG,CAAC;YACT,GAAG,EAAE,GAAG,EAAE;gBACR,MAAM,GAAG,GAAG,EAAE,CAAC,OAAO,CACpB,2EAA2E,CAC5E,CAAC,GAAG,CAAC,MAAM,CAAyB,CAAA;gBACrC,OAAO,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;YACrC,CAAC;YACD,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,aAAa,CAAC,EAAE,KAAK,EAAE,CAAC;SAC/C,CAAC;QAEJ,WAAW,EAAE,CAAC,GAAG,EAAE,EAAE,CACnB,MAAM,CAAC,GAAG,CAAC;YACT,GAAG,EAAE,GAAG,EAAE;gBACR,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,CACrB;;6CAE+B,CAChC,CAAC,GAAG,CAAC,GAAG,CAAC,WAAW,EAAE,CAAe,CAAA;gBACtC,OAAO,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,CAAA;YAC7B,CAAC;YACD,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,aAAa,CAAC,EAAE,KAAK,EAAE,CAAC;SAC/C,CAAC;QAEJ,oBAAoB,EAAE,CAAC,QAAQ,EAAE,EAAE,CACjC,MAAM,CAAC,GAAG,CAAC;YACT,GAAG,EAAE,GAAG,EAAE;gBACR,MAAM,MAAM,GAAG,EAAE,CAAC,OAAO,CACvB;yDAC2C,CAC5C,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;gBACf,OAAO,MAAM,CAAC,OAAO,CAAA;YACvB,CAAC;YACD,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,aAAa,CAAC,EAAE,KAAK,EAAE,CAAC;SAC/C,CAAC;KACL,CAAA;AACH,CAAC,CAAC,CACH,CAAA"}
1
+ {"version":3,"file":"claim-repo.js","sourceRoot":"","sources":["../../src/repo/claim-repo.ts"],"names":[],"mappings":"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"}
@@ -9,6 +9,14 @@ declare const DeduplicationRepository_base: Context.TagClass<DeduplicationReposi
9
9
  readonly hashesExist: (contentHashes: readonly string[]) => Effect.Effect<Set<string>, DatabaseError>;
10
10
  /** Record a processed hash */
11
11
  readonly insertHash: (input: CreateProcessedHashInput) => Effect.Effect<ProcessedHash, DatabaseError>;
12
+ /**
13
+ * Atomically try to insert a hash, returning whether it was actually inserted.
14
+ * Uses INSERT OR IGNORE to handle race conditions safely.
15
+ * Returns { inserted: true } if this was a new hash, { inserted: false } if it already existed.
16
+ */
17
+ readonly tryInsertHash: (input: CreateProcessedHashInput) => Effect.Effect<{
18
+ inserted: boolean;
19
+ }, DatabaseError>;
12
20
  /** Record multiple hashes at once (batch operation) */
13
21
  readonly insertHashes: (inputs: readonly CreateProcessedHashInput[]) => Effect.Effect<number, DatabaseError>;
14
22
  /** Find a hash record by content hash */
@@ -24,7 +32,7 @@ declare const DeduplicationRepository_base: Context.TagClass<DeduplicationReposi
24
32
  /** Update or create progress for a file */
25
33
  readonly upsertFileProgress: (input: UpsertFileProgressInput) => Effect.Effect<FileProgress, DatabaseError>;
26
34
  /** Delete progress for a file */
27
- readonly deleteFileProgress: (filePath: string) => Effect.Effect<void, DatabaseError>;
35
+ readonly deleteFileProgress: (filePath: string) => Effect.Effect<number, DatabaseError>;
28
36
  /** Get all tracked files */
29
37
  readonly getAllFileProgress: () => Effect.Effect<readonly FileProgress[], DatabaseError>;
30
38
  /** Count tracked files */
@@ -1 +1 @@
1
- {"version":3,"file":"deduplication-repo.d.ts","sourceRoot":"","sources":["../../src/repo/deduplication-repo.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAA;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAE5C,OAAO,KAAK,EACV,aAAa,EAEb,wBAAwB,EACxB,YAAY,EAEZ,uBAAuB,EACxB,MAAM,yBAAyB,CAAA;;IAO5B,6CAA6C;yBACxB,CAAC,WAAW,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,aAAa,CAAC;IAEnF,sDAAsD;0BAChC,CAAC,aAAa,EAAE,SAAS,MAAM,EAAE,KAAK,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,aAAa,CAAC;IAErG,8BAA8B;yBACT,CAAC,KAAK,EAAE,wBAAwB,KAAK,MAAM,CAAC,MAAM,CAAC,aAAa,EAAE,aAAa,CAAC;IAErG,uDAAuD;2BAChC,CAAC,MAAM,EAAE,SAAS,wBAAwB,EAAE,KAAK,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC;IAE5G,yCAAyC;yBACpB,CAAC,WAAW,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,aAAa,GAAG,IAAI,EAAE,aAAa,CAAC;IAEhG,0CAA0C;0BACpB,MAAM,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC;IAEhE,qCAAqC;+BACV,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,SAAS,aAAa,EAAE,EAAE,aAAa,CAAC;IAEvG,sDAAsD;kCACxB,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC;IAIxF,8BAA8B;8BACJ,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,YAAY,GAAG,IAAI,EAAE,aAAa,CAAC;IAEjG,2CAA2C;iCACd,CAAC,KAAK,EAAE,uBAAuB,KAAK,MAAM,CAAC,MAAM,CAAC,YAAY,EAAE,aAAa,CAAC;IAE3G,iCAAiC;iCACJ,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,aAAa,CAAC;IAErF,4BAA4B;iCACC,MAAM,MAAM,CAAC,MAAM,CAAC,SAAS,YAAY,EAAE,EAAE,aAAa,CAAC;IAExF,0BAA0B;yBACL,MAAM,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC;;AA5CnE,qBAAa,uBAAwB,SAAQ,4BA8C1C;CAAG;AAEN,eAAO,MAAM,2BAA2B,2DA+LvC,CAAA"}
1
+ {"version":3,"file":"deduplication-repo.d.ts","sourceRoot":"","sources":["../../src/repo/deduplication-repo.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAA;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AACvC,OAAO,EAAE,aAAa,EAAoB,MAAM,cAAc,CAAA;AAE9D,OAAO,KAAK,EACV,aAAa,EAEb,wBAAwB,EACxB,YAAY,EAEZ,uBAAuB,EACxB,MAAM,yBAAyB,CAAA;;IAO5B,6CAA6C;yBACxB,CAAC,WAAW,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,aAAa,CAAC;IAEnF,sDAAsD;0BAChC,CAAC,aAAa,EAAE,SAAS,MAAM,EAAE,KAAK,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,aAAa,CAAC;IAErG,8BAA8B;yBACT,CAAC,KAAK,EAAE,wBAAwB,KAAK,MAAM,CAAC,MAAM,CAAC,aAAa,EAAE,aAAa,CAAC;IAErG;;;;OAIG;4BACqB,CAAC,KAAK,EAAE,wBAAwB,KAAK,MAAM,CAAC,MAAM,CAAC;QAAE,QAAQ,EAAE,OAAO,CAAA;KAAE,EAAE,aAAa,CAAC;IAEhH,uDAAuD;2BAChC,CAAC,MAAM,EAAE,SAAS,wBAAwB,EAAE,KAAK,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC;IAE5G,yCAAyC;yBACpB,CAAC,WAAW,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,aAAa,GAAG,IAAI,EAAE,aAAa,CAAC;IAEhG,0CAA0C;0BACpB,MAAM,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC;IAEhE,qCAAqC;+BACV,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,SAAS,aAAa,EAAE,EAAE,aAAa,CAAC;IAEvG,sDAAsD;kCACxB,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC;IAIxF,8BAA8B;8BACJ,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,YAAY,GAAG,IAAI,EAAE,aAAa,CAAC;IAEjG,2CAA2C;iCACd,CAAC,KAAK,EAAE,uBAAuB,KAAK,MAAM,CAAC,MAAM,CAAC,YAAY,EAAE,aAAa,CAAC;IAE3G,iCAAiC;iCACJ,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC;IAEvF,4BAA4B;iCACC,MAAM,MAAM,CAAC,MAAM,CAAC,SAAS,YAAY,EAAE,EAAE,aAAa,CAAC;IAExF,0BAA0B;yBACL,MAAM,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC;;AAnDnE,qBAAa,uBAAwB,SAAQ,4BAqD1C;CAAG;AAEN,eAAO,MAAM,2BAA2B,2DAsOvC,CAAA"}
@@ -1,6 +1,6 @@
1
1
  import { Context, Effect, Layer } from "effect";
2
2
  import { SqliteClient } from "../db.js";
3
- import { DatabaseError } from "../errors.js";
3
+ import { DatabaseError, EntityFetchError } from "../errors.js";
4
4
  import { rowToProcessedHash, rowToFileProgress } from "../mappers/deduplication.js";
5
5
  export class DeduplicationRepository extends Context.Tag("DeduplicationRepository")() {
6
6
  }
@@ -11,7 +11,7 @@ export const DeduplicationRepositoryLive = Layer.effect(DeduplicationRepository,
11
11
  hashExists: (contentHash) => Effect.try({
12
12
  try: () => {
13
13
  const row = db.prepare("SELECT 1 FROM processed_hashes WHERE content_hash = ? LIMIT 1").get(contentHash);
14
- return row !== undefined;
14
+ return row != null;
15
15
  },
16
16
  catch: (cause) => new DatabaseError({ cause })
17
17
  }),
@@ -33,10 +33,30 @@ export const DeduplicationRepositoryLive = Layer.effect(DeduplicationRepository,
33
33
  VALUES (?, ?, ?)
34
34
  `).run(input.contentHash, input.sourceFile, input.sourceLine);
35
35
  const row = db.prepare("SELECT * FROM processed_hashes WHERE content_hash = ?").get(input.contentHash);
36
+ if (!row) {
37
+ throw new EntityFetchError({
38
+ entity: "processed_hash",
39
+ id: input.contentHash,
40
+ operation: "insert"
41
+ });
42
+ }
36
43
  return rowToProcessedHash(row);
37
44
  },
38
45
  catch: (cause) => new DatabaseError({ cause })
39
46
  }),
47
+ tryInsertHash: (input) => Effect.try({
48
+ try: () => {
49
+ // Use INSERT OR IGNORE to atomically handle duplicates
50
+ // This is race-condition safe: if two processes try to insert
51
+ // the same hash concurrently, one succeeds and the other gets changes=0
52
+ const result = db.prepare(`
53
+ INSERT OR IGNORE INTO processed_hashes (content_hash, source_file, source_line)
54
+ VALUES (?, ?, ?)
55
+ `).run(input.contentHash, input.sourceFile, input.sourceLine);
56
+ return { inserted: result.changes > 0 };
57
+ },
58
+ catch: (cause) => new DatabaseError({ cause })
59
+ }),
40
60
  insertHashes: (inputs) => Effect.try({
41
61
  try: () => {
42
62
  if (inputs.length === 0)
@@ -45,13 +65,22 @@ export const DeduplicationRepositoryLive = Layer.effect(DeduplicationRepository,
45
65
  INSERT OR IGNORE INTO processed_hashes (content_hash, source_file, source_line)
46
66
  VALUES (?, ?, ?)
47
67
  `);
48
- let inserted = 0;
49
- for (const input of inputs) {
50
- const result = stmt.run(input.contentHash, input.sourceFile, input.sourceLine);
51
- if (result.changes > 0)
52
- inserted++;
68
+ // Use a transaction for atomicity and performance
69
+ db.exec("BEGIN IMMEDIATE");
70
+ try {
71
+ let inserted = 0;
72
+ for (const input of inputs) {
73
+ const result = stmt.run(input.contentHash, input.sourceFile, input.sourceLine);
74
+ if (result.changes > 0)
75
+ inserted++;
76
+ }
77
+ db.exec("COMMIT");
78
+ return inserted;
79
+ }
80
+ catch (e) {
81
+ db.exec("ROLLBACK");
82
+ throw e;
53
83
  }
54
- return inserted;
55
84
  },
56
85
  catch: (cause) => new DatabaseError({ cause })
57
86
  }),
@@ -104,13 +133,21 @@ export const DeduplicationRepositoryLive = Layer.effect(DeduplicationRepository,
104
133
  last_processed_at = datetime('now')
105
134
  `).run(input.filePath, input.lastLineProcessed, input.lastByteOffset, input.fileSize ?? null, input.fileChecksum ?? null);
106
135
  const row = db.prepare("SELECT * FROM file_progress WHERE file_path = ?").get(input.filePath);
136
+ if (!row) {
137
+ throw new EntityFetchError({
138
+ entity: "file_progress",
139
+ id: input.filePath,
140
+ operation: "insert"
141
+ });
142
+ }
107
143
  return rowToFileProgress(row);
108
144
  },
109
145
  catch: (cause) => new DatabaseError({ cause })
110
146
  }),
111
147
  deleteFileProgress: (filePath) => Effect.try({
112
148
  try: () => {
113
- db.prepare("DELETE FROM file_progress WHERE file_path = ?").run(filePath);
149
+ const result = db.prepare("DELETE FROM file_progress WHERE file_path = ?").run(filePath);
150
+ return result.changes;
114
151
  },
115
152
  catch: (cause) => new DatabaseError({ cause })
116
153
  }),
@@ -1 +1 @@
1
- {"version":3,"file":"deduplication-repo.js","sourceRoot":"","sources":["../../src/repo/deduplication-repo.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"deduplication-repo.js","sourceRoot":"","sources":["../../src/repo/deduplication-repo.ts"],"names":[],"mappings":"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"}
@@ -1,16 +1,40 @@
1
1
  import { Context, Effect, Layer } from "effect";
2
2
  import { SqliteClient } from "../db.js";
3
- import { DatabaseError } from "../errors.js";
3
+ import { DatabaseError, DependencyNotFoundError } from "../errors.js";
4
4
  import type { TaskId, TaskDependency } from "@jamesaphoenix/tx-types";
5
+ /**
6
+ * Result of atomic cycle-check-and-insert operation.
7
+ */
8
+ export type InsertWithCycleCheckResult = {
9
+ readonly _tag: "inserted";
10
+ } | {
11
+ readonly _tag: "wouldCycle";
12
+ } | {
13
+ readonly _tag: "alreadyExists";
14
+ };
5
15
  declare const DependencyRepository_base: Context.TagClass<DependencyRepository, "DependencyRepository", {
6
16
  readonly insert: (blockerId: string, blockedId: string) => Effect.Effect<void, DatabaseError>;
7
- readonly remove: (blockerId: string, blockedId: string) => Effect.Effect<void, DatabaseError>;
17
+ readonly remove: (blockerId: string, blockedId: string) => Effect.Effect<void, DatabaseError | DependencyNotFoundError>;
8
18
  readonly getBlockerIds: (blockedId: string) => Effect.Effect<readonly TaskId[], DatabaseError>;
9
19
  readonly getBlockingIds: (blockerId: string) => Effect.Effect<readonly TaskId[], DatabaseError>;
10
20
  readonly getBlockerIdsForMany: (blockedIds: readonly string[]) => Effect.Effect<Map<string, readonly TaskId[]>, DatabaseError>;
11
21
  readonly getBlockingIdsForMany: (blockerIds: readonly string[]) => Effect.Effect<Map<string, readonly TaskId[]>, DatabaseError>;
12
22
  readonly hasPath: (fromId: string, toId: string) => Effect.Effect<boolean, DatabaseError>;
13
- readonly getAll: () => Effect.Effect<readonly TaskDependency[], DatabaseError>;
23
+ readonly getAll: (limit?: number) => Effect.Effect<readonly TaskDependency[], DatabaseError>;
24
+ /**
25
+ * Remove all dependency edges where any of the given task IDs appear
26
+ * as either blocker_id or blocked_id. Used during cascade delete to
27
+ * explicitly clean up edges rather than relying solely on FK CASCADE.
28
+ */
29
+ readonly removeByTaskIds: (taskIds: readonly string[]) => Effect.Effect<void, DatabaseError>;
30
+ /**
31
+ * Atomically check for cycles and insert dependency in a single transaction.
32
+ * This prevents race conditions where two concurrent addBlocker calls could
33
+ * both pass cycle detection before either inserts.
34
+ *
35
+ * Uses BEGIN IMMEDIATE to acquire write lock before cycle check.
36
+ */
37
+ readonly insertWithCycleCheck: (blockerId: string, blockedId: string) => Effect.Effect<InsertWithCycleCheckResult, DatabaseError>;
14
38
  }>;
15
39
  export declare class DependencyRepository extends DependencyRepository_base {
16
40
  }
@@ -1 +1 @@
1
- {"version":3,"file":"dep-repo.d.ts","sourceRoot":"","sources":["../../src/repo/dep-repo.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAA;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAE5C,OAAO,KAAK,EAAE,MAAM,EAAE,cAAc,EAAiB,MAAM,yBAAyB,CAAA;;qBAK/D,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,aAAa,CAAC;qBAC5E,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,aAAa,CAAC;4BACrE,CAAC,SAAS,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,SAAS,MAAM,EAAE,EAAE,aAAa,CAAC;6BACrE,CAAC,SAAS,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,SAAS,MAAM,EAAE,EAAE,aAAa,CAAC;mCAChE,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,KAAK,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,EAAE,aAAa,CAAC;oCAC9F,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,KAAK,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,EAAE,aAAa,CAAC;sBAC7G,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,aAAa,CAAC;qBACxE,MAAM,MAAM,CAAC,MAAM,CAAC,SAAS,cAAc,EAAE,EAAE,aAAa,CAAC;;AAVlF,qBAAa,oBAAqB,SAAQ,yBAYvC;CAAG;AAEN,eAAO,MAAM,wBAAwB,wDA0IpC,CAAA"}
1
+ {"version":3,"file":"dep-repo.d.ts","sourceRoot":"","sources":["../../src/repo/dep-repo.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAA;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AACvC,OAAO,EAAE,aAAa,EAAE,uBAAuB,EAA2B,MAAM,cAAc,CAAA;AAG9F,OAAO,KAAK,EAAE,MAAM,EAAE,cAAc,EAAiB,MAAM,yBAAyB,CAAA;AAYpF;;GAEG;AACH,MAAM,MAAM,0BAA0B,GAClC;IAAE,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAA;CAAE,GAC7B;IAAE,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAA;CAAE,GAC/B;IAAE,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAA;CAAE,CAAA;;qBAKjB,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,aAAa,CAAC;qBAC5E,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,aAAa,GAAG,uBAAuB,CAAC;4BAC/F,CAAC,SAAS,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,SAAS,MAAM,EAAE,EAAE,aAAa,CAAC;6BACrE,CAAC,SAAS,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,SAAS,MAAM,EAAE,EAAE,aAAa,CAAC;mCAChE,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,KAAK,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,EAAE,aAAa,CAAC;oCAC9F,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,KAAK,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,EAAE,aAAa,CAAC;sBAC7G,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,aAAa,CAAC;qBACxE,CAAC,KAAK,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,SAAS,cAAc,EAAE,EAAE,aAAa,CAAC;IAC5F;;;;OAIG;8BACuB,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,aAAa,CAAC;IAC5F;;;;;;OAMG;mCAC4B,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,0BAA0B,EAAE,aAAa,CAAC;;AAxBrI,qBAAa,oBAAqB,SAAQ,yBA0BvC;CAAG;AAEN,eAAO,MAAM,wBAAwB,wDAqRpC,CAAA"}