@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,7 @@
1
1
  import { Context, Effect, Layer } from "effect";
2
2
  import { DeduplicationRepository } from "../repo/deduplication-repo.js";
3
3
  import { hashContent } from "../mappers/deduplication.js";
4
+ import { BatchProcessingError } from "../errors.js";
4
5
  /**
5
6
  * Default batch size for hash checking operations.
6
7
  * Balances between query efficiency and memory usage.
@@ -18,24 +19,19 @@ export const DeduplicationServiceLive = Layer.effect(DeduplicationService, Effec
18
19
  return {
19
20
  processLine: (content, filePath, lineNumber) => Effect.gen(function* () {
20
21
  const hash = hashContent(content);
21
- const exists = yield* repo.hashExists(hash);
22
- if (exists) {
23
- return {
24
- hash,
25
- isNew: false,
26
- lineNumber,
27
- content
28
- };
29
- }
30
- // Record the new hash
31
- yield* repo.insertHash({
22
+ // Use atomic insert-or-ignore to handle race conditions safely.
23
+ // If two concurrent calls try to process the same content:
24
+ // - First one succeeds with inserted=true
25
+ // - Second one gets inserted=false (hash already exists)
26
+ // No race window between check and insert.
27
+ const { inserted } = yield* repo.tryInsertHash({
32
28
  contentHash: hash,
33
29
  sourceFile: filePath,
34
30
  sourceLine: lineNumber
35
31
  });
36
32
  return {
37
33
  hash,
38
- isNew: true,
34
+ isNew: inserted,
39
35
  lineNumber,
40
36
  content
41
37
  };
@@ -66,25 +62,66 @@ export const DeduplicationServiceLive = Layer.effect(DeduplicationService, Effec
66
62
  ...l,
67
63
  hash: hashContent(l.content)
68
64
  }));
69
- // Check existing hashes in batches
65
+ // Check existing hashes in batches with error handling
70
66
  let existingHashes = new Set();
67
+ const totalBatches = Math.ceil(lineHashes.length / batchSize);
71
68
  for (let i = 0; i < lineHashes.length; i += batchSize) {
69
+ const batchIndex = Math.floor(i / batchSize);
72
70
  const batch = lineHashes.slice(i, i + batchSize);
73
71
  const batchHashes = batch.map(l => l.hash);
74
- const batchExisting = yield* repo.hashesExist(batchHashes);
75
- existingHashes = new Set([...existingHashes, ...batchExisting]);
72
+ const batchResult = yield* repo.hashesExist(batchHashes).pipe(Effect.mapError((cause) => {
73
+ // Calculate partial results up to this point
74
+ const checkedLines = lineHashes.slice(0, i);
75
+ const newLinesPartial = checkedLines.filter(l => !existingHashes.has(l.hash));
76
+ const skippedLinesPartial = checkedLines.filter(l => existingHashes.has(l.hash));
77
+ const lastCheckedLine = checkedLines[checkedLines.length - 1];
78
+ return new BatchProcessingError({
79
+ operation: "hashesExist",
80
+ batchIndex,
81
+ totalBatches,
82
+ partialResult: {
83
+ filePath,
84
+ totalLines: lines.length,
85
+ newLines: newLinesPartial.length,
86
+ skippedLines: skippedLinesPartial.length,
87
+ startLine,
88
+ endLine: lastCheckedLine?.lineNumber ?? startLine - 1,
89
+ duration: Date.now() - startTime
90
+ },
91
+ cause
92
+ });
93
+ }));
94
+ existingHashes = new Set([...existingHashes, ...batchResult]);
76
95
  }
77
96
  // Separate new and existing lines
78
97
  const newLines = lineHashes.filter(l => !existingHashes.has(l.hash));
79
98
  const skippedLines = lineHashes.filter(l => existingHashes.has(l.hash));
80
- // Insert new hashes in batches
99
+ // Insert new hashes with error handling
81
100
  if (newLines.length > 0) {
82
101
  const hashInputs = newLines.map(l => ({
83
102
  contentHash: l.hash,
84
103
  sourceFile: filePath,
85
104
  sourceLine: l.lineNumber
86
105
  }));
87
- yield* repo.insertHashes(hashInputs);
106
+ yield* repo.insertHashes(hashInputs).pipe(Effect.mapError((cause) => {
107
+ // All hash checks completed, but insert failed
108
+ // Return partial result with check phase complete but no inserts
109
+ return new BatchProcessingError({
110
+ operation: "insertHashes",
111
+ batchIndex: 0,
112
+ totalBatches: 1,
113
+ partialResult: {
114
+ filePath,
115
+ totalLines: lines.length,
116
+ newLines: 0, // None were inserted
117
+ skippedLines: skippedLines.length,
118
+ startLine,
119
+ endLine: lineHashes[lineHashes.length - 1]?.lineNumber ?? startLine - 1,
120
+ duration: Date.now() - startTime
121
+ },
122
+ cause
123
+ });
124
+ }));
88
125
  }
89
126
  // Calculate end line
90
127
  const lastLine = linesToProcess[linesToProcess.length - 1];
@@ -103,21 +140,38 @@ export const DeduplicationServiceLive = Layer.effect(DeduplicationService, Effec
103
140
  const hash = hashContent(content);
104
141
  return yield* repo.hashExists(hash);
105
142
  }),
106
- filterProcessed: (contents) => Effect.gen(function* () {
143
+ filterProcessed: (contents, options = {}) => Effect.gen(function* () {
107
144
  if (contents.length === 0)
108
145
  return new Set();
109
- // Compute hashes and check
146
+ const batchSize = options.batchSize ?? DEFAULT_BATCH_SIZE;
147
+ // Compute hashes and build content-to-hash mapping
110
148
  const contentHashMap = new Map();
111
149
  for (const content of contents) {
112
150
  contentHashMap.set(hashContent(content), content);
113
151
  }
114
- const existingHashes = yield* repo.hashesExist([...contentHashMap.keys()]);
115
- // Return the original content strings that have been processed
152
+ const allHashes = [...contentHashMap.keys()];
153
+ const totalBatches = Math.ceil(allHashes.length / batchSize);
116
154
  const processedContents = new Set();
117
- for (const hash of existingHashes) {
118
- const content = contentHashMap.get(hash);
119
- if (content)
120
- processedContents.add(content);
155
+ // Check hashes in batches with error handling
156
+ for (let i = 0; i < allHashes.length; i += batchSize) {
157
+ const batchIndex = Math.floor(i / batchSize);
158
+ const batchHashes = allHashes.slice(i, i + batchSize);
159
+ const existingHashes = yield* repo.hashesExist(batchHashes).pipe(Effect.mapError((cause) => {
160
+ // Return partial results collected so far
161
+ return new BatchProcessingError({
162
+ operation: "filterProcessed",
163
+ batchIndex,
164
+ totalBatches,
165
+ partialResult: new Set(processedContents),
166
+ cause
167
+ });
168
+ }));
169
+ // Add found content strings to the result set
170
+ for (const hash of existingHashes) {
171
+ const content = contentHashMap.get(hash);
172
+ if (content)
173
+ processedContents.add(content);
174
+ }
121
175
  }
122
176
  return processedContents;
123
177
  }),
@@ -1 +1 @@
1
- {"version":3,"file":"deduplication-service.js","sourceRoot":"","sources":["../../src/services/deduplication-service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"deduplication-service.js","sourceRoot":"","sources":["../../src/services/deduplication-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAA;AAC/C,OAAO,EAAE,uBAAuB,EAAE,MAAM,+BAA+B,CAAA;AACvE,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAA;AACzD,OAAO,EAAE,oBAAoB,EAAiB,MAAM,cAAc,CAAA;AAQlE;;;GAGG;AACH,MAAM,kBAAkB,GAAG,GAAG,CAAA;AAE9B;;;;GAIG;AACH,MAAM,OAAO,oBAAqB,SAAQ,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,EA6E1E;CAAG;AAEN,MAAM,CAAC,MAAM,wBAAwB,GAAG,KAAK,CAAC,MAAM,CAClD,oBAAoB,EACpB,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAClB,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,uBAAuB,CAAA;IAE3C,OAAO;QACL,WAAW,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,CAC7C,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;YAClB,MAAM,IAAI,GAAG,WAAW,CAAC,OAAO,CAAC,CAAA;YAEjC,gEAAgE;YAChE,2DAA2D;YAC3D,0CAA0C;YAC1C,yDAAyD;YACzD,2CAA2C;YAC3C,MAAM,EAAE,QAAQ,EAAE,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC;gBAC7C,WAAW,EAAE,IAAI;gBACjB,UAAU,EAAE,QAAQ;gBACpB,UAAU,EAAE,UAAU;aACvB,CAAC,CAAA;YAEF,OAAO;gBACL,IAAI;gBACJ,KAAK,EAAE,QAAQ;gBACf,UAAU;gBACV,OAAO;aACR,CAAA;QACH,CAAC,CAAC;QAEJ,YAAY,EAAE,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,GAAG,EAAE,EAAE,EAAE,CAC9C,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;YAClB,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;YAC5B,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,kBAAkB,CAAA;YACzD,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,CAAC,CAAA;YACxC,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAA;YAEjC,oCAAoC;YACpC,IAAI,cAAc,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,IAAI,SAAS,CAAC,CAAA;YACjE,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;gBAC3B,cAAc,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAA;YACpD,CAAC;YAED,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAChC,OAAO;oBACL,QAAQ;oBACR,UAAU,EAAE,KAAK,CAAC,MAAM;oBACxB,QAAQ,EAAE,CAAC;oBACX,YAAY,EAAE,CAAC;oBACf,SAAS;oBACT,OAAO,EAAE,SAAS,GAAG,CAAC;oBACtB,QAAQ,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;iBACjC,CAAA;YACH,CAAC;YAED,+BAA+B;YAC/B,MAAM,UAAU,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;gBAC1C,GAAG,CAAC;gBACJ,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC;aAC7B,CAAC,CAAC,CAAA;YAEH,uDAAuD;YACvD,IAAI,cAAc,GAAG,IAAI,GAAG,EAAU,CAAA;YACtC,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,GAAG,SAAS,CAAC,CAAA;YAE7D,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,IAAI,SAAS,EAAE,CAAC;gBACtD,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,SAAS,CAAC,CAAA;gBAC5C,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,CAAA;gBAChD,MAAM,WAAW,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAA;gBAE1C,MAAM,WAAW,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC,IAAI,CAC3D,MAAM,CAAC,QAAQ,CAAC,CAAC,KAAK,EAAE,EAAE;oBACxB,6CAA6C;oBAC7C,MAAM,YAAY,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;oBAC3C,MAAM,eAAe,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAA;oBAC7E,MAAM,mBAAmB,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAA;oBAChF,MAAM,eAAe,GAAG,YAAY,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;oBAE7D,OAAO,IAAI,oBAAoB,CAAC;wBAC9B,SAAS,EAAE,aAAa;wBACxB,UAAU;wBACV,YAAY;wBACZ,aAAa,EAAE;4BACb,QAAQ;4BACR,UAAU,EAAE,KAAK,CAAC,MAAM;4BACxB,QAAQ,EAAE,eAAe,CAAC,MAAM;4BAChC,YAAY,EAAE,mBAAmB,CAAC,MAAM;4BACxC,SAAS;4BACT,OAAO,EAAE,eAAe,EAAE,UAAU,IAAI,SAAS,GAAG,CAAC;4BACrD,QAAQ,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;yBACjC;wBACD,KAAK;qBACN,CAAC,CAAA;gBACJ,CAAC,CAAC,CACH,CAAA;gBAED,cAAc,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,cAAc,EAAE,GAAG,WAAW,CAAC,CAAC,CAAA;YAC/D,CAAC;YAED,kCAAkC;YAClC,MAAM,QAAQ,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAA;YACpE,MAAM,YAAY,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAA;YAEvE,wCAAwC;YACxC,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACxB,MAAM,UAAU,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;oBACpC,WAAW,EAAE,CAAC,CAAC,IAAI;oBACnB,UAAU,EAAE,QAAQ;oBACpB,UAAU,EAAE,CAAC,CAAC,UAAU;iBACzB,CAAC,CAAC,CAAA;gBAEH,KAAK,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,IAAI,CACvC,MAAM,CAAC,QAAQ,CAAC,CAAC,KAAK,EAAE,EAAE;oBACxB,+CAA+C;oBAC/C,iEAAiE;oBACjE,OAAO,IAAI,oBAAoB,CAAC;wBAC9B,SAAS,EAAE,cAAc;wBACzB,UAAU,EAAE,CAAC;wBACb,YAAY,EAAE,CAAC;wBACf,aAAa,EAAE;4BACb,QAAQ;4BACR,UAAU,EAAE,KAAK,CAAC,MAAM;4BACxB,QAAQ,EAAE,CAAC,EAAE,qBAAqB;4BAClC,YAAY,EAAE,YAAY,CAAC,MAAM;4BACjC,SAAS;4BACT,OAAO,EAAE,UAAU,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,UAAU,IAAI,SAAS,GAAG,CAAC;4BACvE,QAAQ,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;yBACjC;wBACD,KAAK;qBACN,CAAC,CAAA;gBACJ,CAAC,CAAC,CACH,CAAA;YACH,CAAC;YAED,qBAAqB;YACrB,MAAM,QAAQ,GAAG,cAAc,CAAC,cAAc,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;YAC1D,MAAM,OAAO,GAAG,QAAQ,EAAE,UAAU,IAAI,SAAS,GAAG,CAAC,CAAA;YAErD,OAAO;gBACL,QAAQ;gBACR,UAAU,EAAE,KAAK,CAAC,MAAM;gBACxB,QAAQ,EAAE,QAAQ,CAAC,MAAM;gBACzB,YAAY,EAAE,YAAY,CAAC,MAAM;gBACjC,SAAS;gBACT,OAAO;gBACP,QAAQ,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;aACjC,CAAA;QACH,CAAC,CAAC;QAEJ,WAAW,EAAE,CAAC,OAAO,EAAE,EAAE,CACvB,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;YAClB,MAAM,IAAI,GAAG,WAAW,CAAC,OAAO,CAAC,CAAA;YACjC,OAAO,KAAK,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAA;QACrC,CAAC,CAAC;QAEJ,eAAe,EAAE,CAAC,QAAQ,EAAE,OAAO,GAAG,EAAE,EAAE,EAAE,CAC1C,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;YAClB,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;gBAAE,OAAO,IAAI,GAAG,EAAU,CAAA;YAEnD,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,kBAAkB,CAAA;YAEzD,mDAAmD;YACnD,MAAM,cAAc,GAAG,IAAI,GAAG,EAAkB,CAAA;YAChD,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;gBAC/B,cAAc,CAAC,GAAG,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,CAAA;YACnD,CAAC;YAED,MAAM,SAAS,GAAG,CAAC,GAAG,cAAc,CAAC,IAAI,EAAE,CAAC,CAAA;YAC5C,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,GAAG,SAAS,CAAC,CAAA;YAC5D,MAAM,iBAAiB,GAAG,IAAI,GAAG,EAAU,CAAA;YAE3C,8CAA8C;YAC9C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,IAAI,SAAS,EAAE,CAAC;gBACrD,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,SAAS,CAAC,CAAA;gBAC5C,MAAM,WAAW,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,CAAA;gBAErD,MAAM,cAAc,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC,IAAI,CAC9D,MAAM,CAAC,QAAQ,CAAC,CAAC,KAAK,EAAE,EAAE;oBACxB,0CAA0C;oBAC1C,OAAO,IAAI,oBAAoB,CAAC;wBAC9B,SAAS,EAAE,iBAAiB;wBAC5B,UAAU;wBACV,YAAY;wBACZ,aAAa,EAAE,IAAI,GAAG,CAAC,iBAAiB,CAAC;wBACzC,KAAK;qBACN,CAAC,CAAA;gBACJ,CAAC,CAAC,CACH,CAAA;gBAED,8CAA8C;gBAC9C,KAAK,MAAM,IAAI,IAAI,cAAc,EAAE,CAAC;oBAClC,MAAM,OAAO,GAAG,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;oBACxC,IAAI,OAAO;wBAAE,iBAAiB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;gBAC7C,CAAC;YACH,CAAC;YAED,OAAO,iBAAiB,CAAA;QAC1B,CAAC,CAAC;QAEJ,WAAW,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC;QAEzD,cAAc,EAAE,CAAC,QAAQ,EAAE,iBAAiB,EAAE,cAAc,EAAE,QAAQ,EAAE,YAAY,EAAE,EAAE,CACtF,IAAI,CAAC,kBAAkB,CAAC;YACtB,QAAQ;YACR,iBAAiB;YACjB,cAAc;YACd,QAAQ;YACR,YAAY;SACb,CAAC;QAEJ,SAAS,EAAE,CAAC,QAAQ,EAAE,EAAE,CACtB,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;YAClB,MAAM,aAAa,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,QAAQ,CAAC,CAAA;YAC/D,KAAK,CAAC,CAAC,IAAI,CAAC,kBAAkB,CAAC,QAAQ,CAAC,CAAA;YACxC,OAAO,EAAE,aAAa,EAAE,CAAA;QAC1B,CAAC,CAAC;QAEJ,QAAQ,EAAE,GAAG,EAAE,CACb,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;YAClB,MAAM,WAAW,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,CAAA;YAC7C,MAAM,YAAY,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,UAAU,EAAE,CAAA;YAC7C,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,CAAA;QACtC,CAAC,CAAC;QAEJ,WAAW,EAAE,WAAW;KACzB,CAAA;AACH,CAAC,CAAC,CACH,CAAA"}
@@ -1,11 +1,11 @@
1
1
  import { Context, Effect, Layer } from "effect";
2
2
  import { DependencyRepository } from "../repo/dep-repo.js";
3
3
  import { TaskRepository } from "../repo/task-repo.js";
4
- import { ValidationError, CircularDependencyError, TaskNotFoundError, DatabaseError } from "../errors.js";
4
+ import { ValidationError, CircularDependencyError, TaskNotFoundError, DatabaseError, DependencyNotFoundError } from "../errors.js";
5
5
  import type { TaskId } from "@jamesaphoenix/tx-types";
6
6
  declare const DependencyService_base: Context.TagClass<DependencyService, "DependencyService", {
7
7
  readonly addBlocker: (taskId: TaskId, blockerId: TaskId) => Effect.Effect<void, ValidationError | CircularDependencyError | TaskNotFoundError | DatabaseError>;
8
- readonly removeBlocker: (taskId: TaskId, blockerId: TaskId) => Effect.Effect<void, DatabaseError>;
8
+ readonly removeBlocker: (taskId: TaskId, blockerId: TaskId) => Effect.Effect<void, DatabaseError | DependencyNotFoundError>;
9
9
  }>;
10
10
  export declare class DependencyService extends DependencyService_base {
11
11
  }
@@ -1 +1 @@
1
- {"version":3,"file":"dep-service.d.ts","sourceRoot":"","sources":["../../src/services/dep-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAA;AAC/C,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAA;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AACrD,OAAO,EAAE,eAAe,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AACzG,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAA;;yBAK5B,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,eAAe,GAAG,uBAAuB,GAAG,iBAAiB,GAAG,aAAa,CAAC;4BACtI,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,aAAa,CAAC;;AAJrG,qBAAa,iBAAkB,SAAQ,sBAMpC;CAAG;AAEN,eAAO,MAAM,qBAAqB,8EAqCjC,CAAA"}
1
+ {"version":3,"file":"dep-service.d.ts","sourceRoot":"","sources":["../../src/services/dep-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAA;AAC/C,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAA;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AACrD,OAAO,EAAE,eAAe,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,aAAa,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAA;AAClI,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAA;;yBAK5B,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,eAAe,GAAG,uBAAuB,GAAG,iBAAiB,GAAG,aAAa,CAAC;4BACtI,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,aAAa,GAAG,uBAAuB,CAAC;;AAJ/H,qBAAa,iBAAkB,SAAQ,sBAMpC;CAAG;AAEN,eAAO,MAAM,qBAAqB,8EAwCjC,CAAA"}
@@ -20,13 +20,17 @@ export const DependencyServiceLive = Layer.effect(DependencyService, Effect.gen(
20
20
  if (!blocker) {
21
21
  return yield* Effect.fail(new TaskNotFoundError({ id: blockerId }));
22
22
  }
23
- // Cycle detection: check if there's already a path from taskId to blockerId
24
- // (i.e., blockerId is transitively blocked by taskId)
25
- const wouldCycle = yield* depRepo.hasPath(blockerId, taskId);
26
- if (wouldCycle) {
23
+ // Atomically check for cycles and insert dependency in a single transaction.
24
+ // This prevents race conditions where two concurrent addBlocker calls could
25
+ // both pass cycle detection before either inserts (DOCTRINE RULE 4).
26
+ const result = yield* depRepo.insertWithCycleCheck(blockerId, taskId);
27
+ if (result._tag === "wouldCycle") {
27
28
  return yield* Effect.fail(new CircularDependencyError({ taskId, blockerId }));
28
29
  }
29
- yield* depRepo.insert(blockerId, taskId);
30
+ // Idempotent: dependency already exists, nothing to do
31
+ if (result._tag === "alreadyExists") {
32
+ return;
33
+ }
30
34
  }),
31
35
  removeBlocker: (taskId, blockerId) => depRepo.remove(blockerId, taskId)
32
36
  };
@@ -1 +1 @@
1
- {"version":3,"file":"dep-service.js","sourceRoot":"","sources":["../../src/services/dep-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAA;AAC/C,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAA;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AACrD,OAAO,EAAE,eAAe,EAAE,uBAAuB,EAAE,iBAAiB,EAAiB,MAAM,cAAc,CAAA;AAGzG,MAAM,OAAO,iBAAkB,SAAQ,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,EAMpE;CAAG;AAEN,MAAM,CAAC,MAAM,qBAAqB,GAAG,KAAK,CAAC,MAAM,CAC/C,iBAAiB,EACjB,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAClB,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,oBAAoB,CAAA;IAC3C,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,cAAc,CAAA;IAEtC,OAAO;QACL,UAAU,EAAE,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,CAChC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;YAClB,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;gBACzB,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,eAAe,CAAC,EAAE,MAAM,EAAE,4BAA4B,EAAE,CAAC,CAAC,CAAA;YAC1F,CAAC;YAED,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAA;YAC7C,IAAI,CAAC,IAAI,EAAE,CAAC;gBACV,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,iBAAiB,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,CAAA;YAClE,CAAC;YAED,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAA;YACnD,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,iBAAiB,CAAC,EAAE,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC,CAAA;YACrE,CAAC;YAED,4EAA4E;YAC5E,sDAAsD;YACtD,MAAM,UAAU,GAAG,KAAK,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,EAAE,MAAM,CAAC,CAAA;YAC5D,IAAI,UAAU,EAAE,CAAC;gBACf,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,uBAAuB,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC,CAAA;YAC/E,CAAC;YAED,KAAK,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAA;QAC1C,CAAC,CAAC;QAEJ,aAAa,EAAE,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,CACnC,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC;KACpC,CAAA;AACH,CAAC,CAAC,CACH,CAAA"}
1
+ {"version":3,"file":"dep-service.js","sourceRoot":"","sources":["../../src/services/dep-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAA;AAC/C,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAA;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AACrD,OAAO,EAAE,eAAe,EAAE,uBAAuB,EAAE,iBAAiB,EAA0C,MAAM,cAAc,CAAA;AAGlI,MAAM,OAAO,iBAAkB,SAAQ,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,EAMpE;CAAG;AAEN,MAAM,CAAC,MAAM,qBAAqB,GAAG,KAAK,CAAC,MAAM,CAC/C,iBAAiB,EACjB,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAClB,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,oBAAoB,CAAA;IAC3C,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,cAAc,CAAA;IAEtC,OAAO;QACL,UAAU,EAAE,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,CAChC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;YAClB,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;gBACzB,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,eAAe,CAAC,EAAE,MAAM,EAAE,4BAA4B,EAAE,CAAC,CAAC,CAAA;YAC1F,CAAC;YAED,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAA;YAC7C,IAAI,CAAC,IAAI,EAAE,CAAC;gBACV,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,iBAAiB,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,CAAA;YAClE,CAAC;YAED,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAA;YACnD,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,iBAAiB,CAAC,EAAE,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC,CAAA;YACrE,CAAC;YAED,6EAA6E;YAC7E,4EAA4E;YAC5E,qEAAqE;YACrE,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,OAAO,CAAC,oBAAoB,CAAC,SAAS,EAAE,MAAM,CAAC,CAAA;YACrE,IAAI,MAAM,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;gBACjC,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,uBAAuB,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC,CAAA;YAC/E,CAAC;YACD,uDAAuD;YACvD,IAAI,MAAM,CAAC,IAAI,KAAK,eAAe,EAAE,CAAC;gBACpC,OAAM;YACR,CAAC;QACH,CAAC,CAAC;QAEJ,aAAa,EAAE,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,CACnC,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC;KACpC,CAAA;AACH,CAAC,CAAC,CACH,CAAA"}
@@ -1,5 +1,6 @@
1
1
  import { Context, Effect, Layer } from "effect";
2
2
  import type { LearningWithScore } from "@jamesaphoenix/tx-types";
3
+ import { EmbeddingDimensionMismatchError } from "../errors.js";
3
4
  declare const DiversifierService_base: Context.TagClass<DiversifierService, "DiversifierService", {
4
5
  /**
5
6
  * Apply MMR diversification to scored candidates.
@@ -9,7 +10,7 @@ declare const DiversifierService_base: Context.TagClass<DiversifierService, "Div
9
10
  * @param lambda - Balance between relevance (1.0) and diversity (0.0), default 0.7
10
11
  * @returns Diversified list of learnings, maintaining score order within diversity constraints
11
12
  */
12
- readonly mmrDiversify: (candidates: readonly LearningWithScore[], limit: number, lambda?: number) => Effect.Effect<readonly LearningWithScore[]>;
13
+ readonly mmrDiversify: (candidates: readonly LearningWithScore[], limit: number, lambda?: number) => Effect.Effect<readonly LearningWithScore[], EmbeddingDimensionMismatchError>;
13
14
  }>;
14
15
  /**
15
16
  * DiversifierService provides Maximal Marginal Relevance (MMR) diversification
@@ -1 +1 @@
1
- {"version":3,"file":"diversifier-service.d.ts","sourceRoot":"","sources":["../../src/services/diversifier-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAA;AAC/C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAA;;IAgB5D;;;;;;;OAOG;2BACoB,CACrB,UAAU,EAAE,SAAS,iBAAiB,EAAE,EACxC,KAAK,EAAE,MAAM,EACb,MAAM,CAAC,EAAE,MAAM,KACZ,MAAM,CAAC,MAAM,CAAC,SAAS,iBAAiB,EAAE,CAAC;;AAzBpD;;;;;;;;;GASG;AACH,qBAAa,kBAAmB,SAAQ,uBAiBrC;CAAG;AAmGN;;;GAGG;AACH,eAAO,MAAM,sBAAsB,+CAMlC,CAAA;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,sBAAsB,+CAyElC,CAAA;AA4CD;;GAEG;AACH,eAAO,MAAM,sBAAsB,+CAAyB,CAAA"}
1
+ {"version":3,"file":"diversifier-service.d.ts","sourceRoot":"","sources":["../../src/services/diversifier-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAA;AAC/C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAA;AAEhE,OAAO,EAAE,+BAA+B,EAAE,MAAM,cAAc,CAAA;;IAe1D;;;;;;;OAOG;2BACoB,CACrB,UAAU,EAAE,SAAS,iBAAiB,EAAE,EACxC,KAAK,EAAE,MAAM,EACb,MAAM,CAAC,EAAE,MAAM,KACZ,MAAM,CAAC,MAAM,CAAC,SAAS,iBAAiB,EAAE,EAAE,+BAA+B,CAAC;;AAzBrF;;;;;;;;;GASG;AACH,qBAAa,kBAAmB,SAAQ,uBAiBrC;CAAG;AAkGN;;;GAGG;AACH,eAAO,MAAM,sBAAsB,+CAMlC,CAAA;AAgCD;;;;;;;;GAQG;AACH,eAAO,MAAM,sBAAsB,+CAsDlC,CAAA;AA4CD;;GAEG;AACH,eAAO,MAAM,sBAAsB,+CAAyB,CAAA"}
@@ -31,25 +31,17 @@ const CATEGORY_MAX_PER_TOP_N = 2;
31
31
  const maxSimilarityToSelected = (candidate, selected) => {
32
32
  // No embedding means we can't compute similarity
33
33
  if (!candidate.embedding) {
34
- return 0;
34
+ return Effect.succeed(0);
35
35
  }
36
36
  // No selected items yet
37
37
  if (selected.length === 0) {
38
- return 0;
38
+ return Effect.succeed(0);
39
39
  }
40
- let maxSim = -Infinity;
41
- for (const item of selected) {
42
- // Skip items without embeddings
43
- if (!item.embedding) {
44
- continue;
45
- }
46
- const sim = cosineSimilarity(candidate.embedding, item.embedding);
47
- if (sim > maxSim) {
48
- maxSim = sim;
49
- }
40
+ const itemsWithEmbeddings = selected.filter((item) => item.embedding !== null);
41
+ if (itemsWithEmbeddings.length === 0) {
42
+ return Effect.succeed(0);
50
43
  }
51
- // If no valid comparisons were made, return 0
52
- return maxSim === -Infinity ? 0 : maxSim;
44
+ return Effect.forEach(itemsWithEmbeddings, item => cosineSimilarity(candidate.embedding, item.embedding)).pipe(Effect.map(similarities => Math.max(...similarities)));
53
45
  };
54
46
  /**
55
47
  * Calculate MMR score for a candidate.
@@ -61,8 +53,7 @@ const maxSimilarityToSelected = (candidate, selected) => {
61
53
  */
62
54
  const mmrScore = (candidate, selected, lambda) => {
63
55
  const relevance = candidate.relevanceScore;
64
- const maxSim = maxSimilarityToSelected(candidate, selected);
65
- return lambda * relevance - (1 - lambda) * maxSim;
56
+ return maxSimilarityToSelected(candidate, selected).pipe(Effect.map(maxSim => lambda * relevance - (1 - lambda) * maxSim));
66
57
  };
67
58
  /**
68
59
  * Check if adding a candidate would violate category limits in top N.
@@ -90,6 +81,26 @@ const wouldViolateCategoryLimit = (candidate, selected, topN = CATEGORY_LIMIT_TO
90
81
  export const DiversifierServiceNoop = Layer.succeed(DiversifierService, {
91
82
  mmrDiversify: (candidates, limit, _lambda) => Effect.succeed(candidates.slice(0, limit))
92
83
  });
84
+ /**
85
+ * Find the best candidate from remaining items using MMR scoring.
86
+ * Returns the candidate with the highest MMR score that doesn't violate category limits.
87
+ */
88
+ const findBestCandidate = (remaining, selected, lambda, checkCategoryLimits) => Effect.gen(function* () {
89
+ let bestCandidate = null;
90
+ let bestScore = -Infinity;
91
+ for (const candidate of remaining) {
92
+ // Skip if would violate category limit (when checking is enabled)
93
+ if (checkCategoryLimits && wouldViolateCategoryLimit(candidate, selected)) {
94
+ continue;
95
+ }
96
+ const score = yield* mmrScore(candidate, selected, lambda);
97
+ if (score > bestScore) {
98
+ bestScore = score;
99
+ bestCandidate = candidate;
100
+ }
101
+ }
102
+ return bestCandidate ? { candidate: bestCandidate, score: bestScore } : null;
103
+ });
93
104
  /**
94
105
  * Live implementation with full MMR algorithm and category limits.
95
106
  *
@@ -100,7 +111,7 @@ export const DiversifierServiceNoop = Layer.succeed(DiversifierService, {
100
111
  * 4. Repeat until limit reached or no candidates remain
101
112
  */
102
113
  export const DiversifierServiceLive = Layer.succeed(DiversifierService, {
103
- mmrDiversify: (candidates, limit, lambda = DEFAULT_LAMBDA) => Effect.sync(() => {
114
+ mmrDiversify: (candidates, limit, lambda = DEFAULT_LAMBDA) => Effect.gen(function* () {
104
115
  // Edge case: empty candidates
105
116
  if (candidates.length === 0) {
106
117
  return [];
@@ -109,8 +120,8 @@ export const DiversifierServiceLive = Layer.succeed(DiversifierService, {
109
120
  if (limit <= 0) {
110
121
  return [];
111
122
  }
112
- // Edge case: only one candidate or limit is 1
113
- if (candidates.length === 1 || limit === 1) {
123
+ // Edge case: only one candidate
124
+ if (candidates.length === 1) {
114
125
  return candidates.slice(0, 1);
115
126
  }
116
127
  // Check if any candidates have embeddings
@@ -123,36 +134,19 @@ export const DiversifierServiceLive = Layer.succeed(DiversifierService, {
123
134
  const selected = [];
124
135
  const remaining = new Set(candidates);
125
136
  while (selected.length < limit && remaining.size > 0) {
126
- let bestCandidate = null;
127
- let bestScore = -Infinity;
128
- for (const candidate of remaining) {
129
- // Skip if would violate category limit
130
- if (wouldViolateCategoryLimit(candidate, selected)) {
131
- continue;
132
- }
133
- const score = mmrScore(candidate, selected, lambda);
134
- if (score > bestScore) {
135
- bestScore = score;
136
- bestCandidate = candidate;
137
- }
138
- }
137
+ // Try to find best candidate respecting category limits
138
+ let result = yield* findBestCandidate(remaining, selected, lambda, true);
139
139
  // If no valid candidate found (all remaining violate category limits),
140
140
  // try to find any candidate without category limit check
141
- if (!bestCandidate) {
142
- for (const candidate of remaining) {
143
- const score = mmrScore(candidate, selected, lambda);
144
- if (score > bestScore) {
145
- bestScore = score;
146
- bestCandidate = candidate;
147
- }
148
- }
141
+ if (!result) {
142
+ result = yield* findBestCandidate(remaining, selected, lambda, false);
149
143
  }
150
144
  // Still no candidate? We're done
151
- if (!bestCandidate) {
145
+ if (!result) {
152
146
  break;
153
147
  }
154
- selected.push(bestCandidate);
155
- remaining.delete(bestCandidate);
148
+ selected.push(result.candidate);
149
+ remaining.delete(result.candidate);
156
150
  }
157
151
  return selected;
158
152
  })
@@ -1 +1 @@
1
- {"version":3,"file":"diversifier-service.js","sourceRoot":"","sources":["../../src/services/diversifier-service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"diversifier-service.js","sourceRoot":"","sources":["../../src/services/diversifier-service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * DocService — business logic for docs-as-primitives (DD-023).
3
+ *
4
+ * Manages doc lifecycle (create/update/lock/version), rendering (YAML→MD),
5
+ * linking (doc-doc, task-doc), invariant sync, drift detection, and graph data.
6
+ *
7
+ * YAML content lives on disk (.tx/docs/); DB stores metadata + links only.
8
+ */
9
+ import { Context, Effect, Layer } from "effect";
10
+ import { DocRepository } from "../repo/doc-repo.js";
11
+ import { DatabaseError, ValidationError, DocNotFoundError, DocLockedError, InvalidDocYamlError, InvariantNotFoundError } from "../errors.js";
12
+ import type { Doc, DocKind, DocStatus, DocLink, DocLinkType, Invariant, InvariantCheck, DocGraph } from "@jamesaphoenix/tx-types";
13
+ declare const DocService_base: Context.TagClass<DocService, "DocService", {
14
+ readonly create: (input: {
15
+ kind: DocKind;
16
+ name: string;
17
+ title: string;
18
+ yamlContent: string;
19
+ metadata?: Record<string, unknown>;
20
+ }) => Effect.Effect<Doc, ValidationError | InvalidDocYamlError | DatabaseError>;
21
+ readonly get: (name: string, version?: number) => Effect.Effect<Doc, DocNotFoundError | DatabaseError>;
22
+ readonly update: (name: string, yamlContent: string) => Effect.Effect<Doc, DocNotFoundError | DocLockedError | InvalidDocYamlError | DatabaseError>;
23
+ readonly lock: (name: string) => Effect.Effect<Doc, DocNotFoundError | DatabaseError>;
24
+ readonly list: (filter?: {
25
+ kind?: DocKind;
26
+ status?: DocStatus;
27
+ }) => Effect.Effect<readonly Doc[], DatabaseError>;
28
+ readonly remove: (name: string) => Effect.Effect<void, DocNotFoundError | DocLockedError | DatabaseError>;
29
+ readonly render: (name?: string) => Effect.Effect<readonly string[], DocNotFoundError | InvalidDocYamlError | DatabaseError>;
30
+ readonly createVersion: (name: string) => Effect.Effect<Doc, DocNotFoundError | ValidationError | DatabaseError>;
31
+ readonly linkDocs: (fromName: string, toName: string, linkType?: DocLinkType) => Effect.Effect<DocLink, DocNotFoundError | ValidationError | DatabaseError>;
32
+ readonly attachTask: (taskId: string, docName: string, linkType?: "implements" | "references") => Effect.Effect<void, DocNotFoundError | DatabaseError>;
33
+ readonly createPatch: (designName: string, patchName: string, patchTitle: string) => Effect.Effect<Doc, DocNotFoundError | ValidationError | InvalidDocYamlError | DatabaseError>;
34
+ readonly validate: () => Effect.Effect<readonly string[], DatabaseError>;
35
+ readonly detectDrift: (name: string) => Effect.Effect<readonly string[], DocNotFoundError | DatabaseError>;
36
+ readonly generateIndex: () => Effect.Effect<void, DatabaseError>;
37
+ readonly syncInvariants: (docName?: string) => Effect.Effect<readonly Invariant[], DocNotFoundError | InvalidDocYamlError | DatabaseError>;
38
+ readonly listInvariants: (filter?: {
39
+ subsystem?: string;
40
+ enforcement?: string;
41
+ }) => Effect.Effect<readonly Invariant[], DatabaseError>;
42
+ readonly recordInvariantCheck: (id: string, passed: boolean, details?: string, durationMs?: number) => Effect.Effect<InvariantCheck, InvariantNotFoundError | DatabaseError>;
43
+ readonly getDocGraph: () => Effect.Effect<DocGraph, DatabaseError>;
44
+ }>;
45
+ export declare class DocService extends DocService_base {
46
+ }
47
+ export declare const DocServiceLive: Layer.Layer<DocService, never, DocRepository>;
48
+ export {};
49
+ //# sourceMappingURL=doc-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doc-service.d.ts","sourceRoot":"","sources":["../../src/services/doc-service.ts"],"names":[],"mappings":"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"}