@stackmemoryai/stackmemory 0.2.9 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (575) hide show
  1. package/dist/agents/core/agent-task-manager.js +512 -0
  2. package/dist/agents/core/agent-task-manager.js.map +7 -0
  3. package/dist/agents/verifiers/base-verifier.js +129 -0
  4. package/dist/agents/verifiers/base-verifier.js.map +7 -0
  5. package/dist/agents/verifiers/formatter-verifier.js +126 -0
  6. package/dist/agents/verifiers/formatter-verifier.js.map +7 -0
  7. package/dist/agents/verifiers/llm-judge.js +248 -0
  8. package/dist/agents/verifiers/llm-judge.js.map +7 -0
  9. package/dist/cli/__tests__/index.test.js +290 -0
  10. package/dist/cli/__tests__/index.test.js.map +7 -0
  11. package/dist/cli/auto-detect.js +317 -0
  12. package/dist/cli/auto-detect.js.map +7 -0
  13. package/dist/cli/browser-test.js +29 -0
  14. package/dist/cli/browser-test.js.map +7 -0
  15. package/dist/cli/claude-sm.js +369 -0
  16. package/dist/cli/claude-sm.js.map +7 -0
  17. package/dist/cli/codex-sm.js +283 -0
  18. package/dist/cli/codex-sm.js.map +7 -0
  19. package/dist/cli/commands/agent.js +286 -0
  20. package/dist/cli/commands/agent.js.map +7 -0
  21. package/dist/cli/commands/config.js +199 -0
  22. package/dist/cli/commands/config.js.map +7 -0
  23. package/dist/cli/commands/context.js +327 -0
  24. package/dist/cli/commands/context.js.map +7 -0
  25. package/dist/cli/commands/handoff.js +191 -0
  26. package/dist/cli/commands/handoff.js.map +7 -0
  27. package/dist/cli/commands/linear-test.js +115 -0
  28. package/dist/cli/commands/linear-test.js.map +7 -0
  29. package/dist/cli/commands/linear.js +378 -0
  30. package/dist/cli/commands/linear.js.map +7 -0
  31. package/dist/cli/commands/log.js +165 -0
  32. package/dist/cli/commands/log.js.map +7 -0
  33. package/dist/cli/commands/onboard.js +349 -0
  34. package/dist/cli/commands/onboard.js.map +7 -0
  35. package/dist/cli/commands/projects.js +195 -0
  36. package/dist/cli/commands/projects.js.map +7 -0
  37. package/dist/cli/commands/search.js +152 -0
  38. package/dist/cli/commands/search.js.map +7 -0
  39. package/dist/cli/commands/session.js +179 -0
  40. package/dist/cli/commands/session.js.map +7 -0
  41. package/dist/cli/commands/tasks.js +205 -0
  42. package/dist/cli/commands/tasks.js.map +7 -0
  43. package/dist/cli/commands/webhook.js +131 -0
  44. package/dist/cli/commands/webhook.js.map +7 -0
  45. package/dist/cli/commands/worktree.js +276 -0
  46. package/dist/cli/commands/worktree.js.map +7 -0
  47. package/dist/cli/index.js +953 -0
  48. package/dist/cli/index.js.map +7 -0
  49. package/dist/cli/utils/viewer.js +92 -0
  50. package/dist/cli/utils/viewer.js.map +7 -0
  51. package/dist/core/config/__tests__/config-manager.test.js +248 -0
  52. package/dist/core/config/__tests__/config-manager.test.js.map +7 -0
  53. package/dist/core/config/config-manager.js +368 -0
  54. package/dist/core/config/config-manager.js.map +7 -0
  55. package/dist/core/config/types.js +140 -0
  56. package/dist/core/config/types.js.map +7 -0
  57. package/dist/core/context/__tests__/frame-manager.test.js +879 -0
  58. package/dist/core/context/__tests__/frame-manager.test.js.map +7 -0
  59. package/dist/core/context/auto-context.js +72 -0
  60. package/dist/core/context/auto-context.js.map +7 -0
  61. package/dist/core/context/compaction-handler.js +326 -0
  62. package/dist/core/context/compaction-handler.js.map +7 -0
  63. package/dist/core/context/frame-database.js +376 -0
  64. package/dist/core/context/frame-database.js.map +7 -0
  65. package/dist/core/context/frame-digest.js +239 -0
  66. package/dist/core/context/frame-digest.js.map +7 -0
  67. package/dist/core/context/frame-manager.js +682 -0
  68. package/dist/core/context/frame-manager.js.map +7 -0
  69. package/dist/core/context/frame-stack.js +270 -0
  70. package/dist/core/context/frame-stack.js.map +7 -0
  71. package/dist/core/context/frame-types.js +1 -0
  72. package/dist/core/context/frame-types.js.map +7 -0
  73. package/dist/core/context/index.js +33 -0
  74. package/dist/core/context/index.js.map +7 -0
  75. package/dist/core/context/model-aware-compaction.js +619 -0
  76. package/dist/core/context/model-aware-compaction.js.map +7 -0
  77. package/dist/core/context/refactored-frame-manager.js +393 -0
  78. package/dist/core/context/refactored-frame-manager.js.map +7 -0
  79. package/dist/core/database/batch-operations.js +329 -0
  80. package/dist/core/database/batch-operations.js.map +7 -0
  81. package/dist/core/database/connection-pool.js +224 -0
  82. package/dist/core/database/connection-pool.js.map +7 -0
  83. package/dist/core/database/query-cache.js +284 -0
  84. package/dist/core/database/query-cache.js.map +7 -0
  85. package/dist/core/digest/__tests__/enhanced-hybrid-digest.test.js +379 -0
  86. package/dist/core/digest/__tests__/enhanced-hybrid-digest.test.js.map +7 -0
  87. package/dist/core/digest/__tests__/frame-digest-integration.test.js +230 -0
  88. package/dist/core/digest/__tests__/frame-digest-integration.test.js.map +7 -0
  89. package/dist/core/digest/enhanced-hybrid-digest.js +267 -0
  90. package/dist/core/digest/enhanced-hybrid-digest.js.map +7 -0
  91. package/dist/core/digest/frame-digest-integration.js +172 -0
  92. package/dist/core/digest/frame-digest-integration.js.map +7 -0
  93. package/dist/core/digest/hybrid-digest-generator.js +549 -0
  94. package/dist/core/digest/hybrid-digest-generator.js.map +7 -0
  95. package/dist/core/digest/index.js +5 -0
  96. package/dist/core/digest/index.js.map +7 -0
  97. package/dist/core/digest/types.js +21 -0
  98. package/dist/core/digest/types.js.map +7 -0
  99. package/dist/core/errors/__tests__/error-handling.test.js +270 -0
  100. package/dist/core/errors/__tests__/error-handling.test.js.map +7 -0
  101. package/dist/core/errors/index.js +239 -0
  102. package/dist/core/errors/index.js.map +7 -0
  103. package/dist/core/errors/recovery.js +258 -0
  104. package/dist/core/errors/recovery.js.map +7 -0
  105. package/dist/core/merge/__tests__/conflict-scenarios.test.js +414 -0
  106. package/dist/core/merge/__tests__/conflict-scenarios.test.js.map +7 -0
  107. package/dist/core/merge/conflict-detector.js +424 -0
  108. package/dist/core/merge/conflict-detector.js.map +7 -0
  109. package/dist/core/merge/index.js +5 -0
  110. package/dist/core/merge/index.js.map +7 -0
  111. package/dist/core/merge/resolution-engine.js +565 -0
  112. package/dist/core/merge/resolution-engine.js.map +7 -0
  113. package/dist/core/merge/stack-diff.js +528 -0
  114. package/dist/core/merge/stack-diff.js.map +7 -0
  115. package/dist/core/merge/types.js +1 -0
  116. package/dist/core/merge/types.js.map +7 -0
  117. package/dist/core/monitoring/error-handler.js +278 -0
  118. package/dist/core/monitoring/error-handler.js.map +7 -0
  119. package/dist/core/monitoring/logger.js +115 -0
  120. package/dist/core/monitoring/logger.js.map +7 -0
  121. package/dist/core/monitoring/metrics.js +157 -0
  122. package/dist/core/monitoring/metrics.js.map +7 -0
  123. package/dist/core/monitoring/progress-tracker.js +174 -0
  124. package/dist/core/monitoring/progress-tracker.js.map +7 -0
  125. package/dist/core/performance/context-cache.js +269 -0
  126. package/dist/core/performance/context-cache.js.map +7 -0
  127. package/dist/core/performance/index.js +7 -0
  128. package/dist/core/performance/index.js.map +7 -0
  129. package/dist/core/performance/lazy-context-loader.js +319 -0
  130. package/dist/core/performance/lazy-context-loader.js.map +7 -0
  131. package/dist/core/performance/monitor.js +217 -0
  132. package/dist/core/performance/monitor.js.map +7 -0
  133. package/dist/core/performance/optimized-frame-context.js +326 -0
  134. package/dist/core/performance/optimized-frame-context.js.map +7 -0
  135. package/dist/core/performance/performance-benchmark.js +269 -0
  136. package/dist/core/performance/performance-benchmark.js.map +7 -0
  137. package/dist/core/performance/performance-profiler.js +318 -0
  138. package/dist/core/performance/performance-profiler.js.map +7 -0
  139. package/dist/core/performance/streaming-jsonl-parser.js +187 -0
  140. package/dist/core/performance/streaming-jsonl-parser.js.map +7 -0
  141. package/dist/core/persistence/postgres-adapter.js +345 -0
  142. package/dist/core/persistence/postgres-adapter.js.map +7 -0
  143. package/dist/core/projects/project-manager.js +699 -0
  144. package/dist/core/projects/project-manager.js.map +7 -0
  145. package/dist/core/query/__tests__/query-parser.test.js +301 -0
  146. package/dist/core/query/__tests__/query-parser.test.js.map +7 -0
  147. package/dist/core/query/__tests__/query-templates.test.js +210 -0
  148. package/dist/core/query/__tests__/query-templates.test.js.map +7 -0
  149. package/dist/core/query/query-parser.js +366 -0
  150. package/dist/core/query/query-parser.js.map +7 -0
  151. package/dist/core/query/query-templates.js +317 -0
  152. package/dist/core/query/query-templates.js.map +7 -0
  153. package/dist/core/retrieval/index.js +4 -0
  154. package/dist/core/retrieval/index.js.map +7 -0
  155. package/dist/core/retrieval/llm-context-retrieval.js +577 -0
  156. package/dist/core/retrieval/llm-context-retrieval.js.map +7 -0
  157. package/dist/core/retrieval/summary-generator.js +585 -0
  158. package/dist/core/retrieval/summary-generator.js.map +7 -0
  159. package/dist/core/retrieval/types.js +17 -0
  160. package/dist/core/retrieval/types.js.map +7 -0
  161. package/dist/core/session/index.js +11 -0
  162. package/dist/core/session/index.js.map +7 -0
  163. package/dist/core/session/session-manager.js +297 -0
  164. package/dist/core/session/session-manager.js.map +7 -0
  165. package/dist/core/trace/cli-trace-wrapper.js +110 -0
  166. package/dist/core/trace/cli-trace-wrapper.js.map +7 -0
  167. package/dist/core/trace/db-trace-wrapper.js +215 -0
  168. package/dist/core/trace/db-trace-wrapper.js.map +7 -0
  169. package/dist/core/trace/debug-trace.js +385 -0
  170. package/dist/core/trace/debug-trace.js.map +7 -0
  171. package/dist/core/trace/index.js +158 -0
  172. package/dist/core/trace/index.js.map +7 -0
  173. package/dist/core/trace/linear-api-wrapper.js +169 -0
  174. package/dist/core/trace/linear-api-wrapper.js.map +7 -0
  175. package/dist/core/trace/trace-demo.js +135 -0
  176. package/dist/core/trace/trace-demo.js.map +7 -0
  177. package/dist/core/trace/trace-detector.demo.js +138 -0
  178. package/dist/core/trace/trace-detector.demo.js.map +7 -0
  179. package/dist/core/trace/trace-detector.js +386 -0
  180. package/dist/core/trace/trace-detector.js.map +7 -0
  181. package/dist/core/trace/trace-detector.test.js +401 -0
  182. package/dist/core/trace/trace-detector.test.js.map +7 -0
  183. package/dist/core/trace/trace-store.js +341 -0
  184. package/dist/core/trace/trace-store.js.map +7 -0
  185. package/dist/core/trace/types.js +73 -0
  186. package/dist/core/trace/types.js.map +7 -0
  187. package/dist/core/types.js +1 -0
  188. package/dist/core/types.js.map +7 -0
  189. package/dist/core/utils/update-checker.js +214 -0
  190. package/dist/core/utils/update-checker.js.map +7 -0
  191. package/dist/core/worktree/worktree-manager.js +450 -0
  192. package/dist/core/worktree/worktree-manager.js.map +7 -0
  193. package/dist/features/analytics/api/analytics-api.js +283 -0
  194. package/dist/features/analytics/api/analytics-api.js.map +7 -0
  195. package/dist/features/analytics/core/analytics-service.js +267 -0
  196. package/dist/features/analytics/core/analytics-service.js.map +7 -0
  197. package/dist/features/analytics/index.js +14 -0
  198. package/dist/features/analytics/index.js.map +7 -0
  199. package/dist/features/analytics/queries/metrics-queries.js +273 -0
  200. package/dist/features/analytics/queries/metrics-queries.js.map +7 -0
  201. package/dist/features/analytics/types/metrics.js +1 -0
  202. package/dist/features/analytics/types/metrics.js.map +7 -0
  203. package/dist/features/browser/browser-mcp.js +488 -0
  204. package/dist/features/browser/browser-mcp.js.map +7 -0
  205. package/dist/features/tasks/__tests__/pebbles-task-store.test.js +747 -0
  206. package/dist/features/tasks/__tests__/pebbles-task-store.test.js.map +7 -0
  207. package/dist/features/tasks/pebbles-task-store.js +647 -0
  208. package/dist/features/tasks/pebbles-task-store.js.map +7 -0
  209. package/dist/features/tasks/task-aware-context.js +406 -0
  210. package/dist/features/tasks/task-aware-context.js.map +7 -0
  211. package/dist/index.js +21 -0
  212. package/dist/index.js.map +7 -0
  213. package/dist/integrations/linear/__tests__/auth.test.js +558 -0
  214. package/dist/integrations/linear/__tests__/auth.test.js.map +7 -0
  215. package/dist/integrations/linear/__tests__/sync-service.test.js +760 -0
  216. package/dist/integrations/linear/__tests__/sync-service.test.js.map +7 -0
  217. package/dist/integrations/linear/auth.js +308 -0
  218. package/dist/integrations/linear/auth.js.map +7 -0
  219. package/dist/integrations/linear/auto-sync.js +244 -0
  220. package/dist/integrations/linear/auto-sync.js.map +7 -0
  221. package/dist/integrations/linear/client.js +448 -0
  222. package/dist/integrations/linear/client.js.map +7 -0
  223. package/dist/integrations/linear/config.js +115 -0
  224. package/dist/integrations/linear/config.js.map +7 -0
  225. package/dist/integrations/linear/sync-manager.js +233 -0
  226. package/dist/integrations/linear/sync-manager.js.map +7 -0
  227. package/dist/integrations/linear/sync-service.js +214 -0
  228. package/dist/integrations/linear/sync-service.js.map +7 -0
  229. package/dist/integrations/linear/sync.js +565 -0
  230. package/dist/integrations/linear/sync.js.map +7 -0
  231. package/dist/integrations/linear/types.js +1 -0
  232. package/dist/integrations/linear/types.js.map +7 -0
  233. package/dist/integrations/linear/webhook-server.js +204 -0
  234. package/dist/integrations/linear/webhook-server.js.map +7 -0
  235. package/dist/integrations/linear/webhook.js +269 -0
  236. package/dist/integrations/linear/webhook.js.map +7 -0
  237. package/dist/integrations/mcp/__tests__/server.test.js +798 -0
  238. package/dist/integrations/mcp/__tests__/server.test.js.map +7 -0
  239. package/dist/integrations/mcp/handlers/context-handlers.js +253 -0
  240. package/dist/integrations/mcp/handlers/context-handlers.js.map +7 -0
  241. package/dist/integrations/mcp/handlers/index.js +134 -0
  242. package/dist/integrations/mcp/handlers/index.js.map +7 -0
  243. package/dist/integrations/mcp/handlers/linear-handlers.js +243 -0
  244. package/dist/integrations/mcp/handlers/linear-handlers.js.map +7 -0
  245. package/dist/integrations/mcp/handlers/task-handlers.js +235 -0
  246. package/dist/integrations/mcp/handlers/task-handlers.js.map +7 -0
  247. package/dist/integrations/mcp/handlers/trace-handlers.js +304 -0
  248. package/dist/integrations/mcp/handlers/trace-handlers.js.map +7 -0
  249. package/dist/integrations/mcp/index.js +19 -0
  250. package/dist/integrations/mcp/index.js.map +7 -0
  251. package/dist/integrations/mcp/refactored-server.js +331 -0
  252. package/dist/integrations/mcp/refactored-server.js.map +7 -0
  253. package/dist/integrations/mcp/server.js +1621 -0
  254. package/dist/integrations/mcp/server.js.map +7 -0
  255. package/dist/integrations/mcp/tool-definitions.js +562 -0
  256. package/dist/integrations/mcp/tool-definitions.js.map +7 -0
  257. package/dist/integrations/mcp/trace-test.js +44 -0
  258. package/dist/integrations/mcp/trace-test.js.map +7 -0
  259. package/dist/integrations/pg-aiguide/embedding-provider.js +174 -0
  260. package/dist/integrations/pg-aiguide/embedding-provider.js.map +7 -0
  261. package/dist/integrations/pg-aiguide/semantic-search.js +183 -0
  262. package/dist/integrations/pg-aiguide/semantic-search.js.map +7 -0
  263. package/dist/integrations/pg-aiguide/timescale-analytics.js +220 -0
  264. package/dist/integrations/pg-aiguide/timescale-analytics.js.map +7 -0
  265. package/dist/mcp/stackmemory-mcp-server.js +550 -0
  266. package/dist/mcp/stackmemory-mcp-server.js.map +7 -0
  267. package/dist/middleware/exponential-rate-limiter.js +285 -0
  268. package/dist/middleware/exponential-rate-limiter.js.map +7 -0
  269. package/dist/models/user.model.js +351 -0
  270. package/dist/models/user.model.js.map +7 -0
  271. package/dist/scripts/benchmark-performance.d.ts +7 -0
  272. package/dist/scripts/benchmark-performance.d.ts.map +1 -0
  273. package/dist/scripts/benchmark-performance.js +44 -0
  274. package/dist/scripts/benchmark-performance.js.map +1 -0
  275. package/dist/scripts/cleanup-duplicate-tasks.d.ts +12 -0
  276. package/dist/scripts/cleanup-duplicate-tasks.d.ts.map +1 -0
  277. package/dist/scripts/cleanup-duplicate-tasks.js +215 -0
  278. package/dist/scripts/cleanup-duplicate-tasks.js.map +1 -0
  279. package/dist/servers/production/auth-middleware.js +513 -0
  280. package/dist/servers/production/auth-middleware.js.map +7 -0
  281. package/dist/servers/railway/index.js +390 -0
  282. package/dist/servers/railway/index.js.map +7 -0
  283. package/dist/services/config-service.js +62 -0
  284. package/dist/services/config-service.js.map +7 -0
  285. package/dist/services/context-service.js +191 -0
  286. package/dist/services/context-service.js.map +7 -0
  287. package/dist/src/agents/core/agent-task-manager.d.ts +154 -0
  288. package/dist/src/agents/core/agent-task-manager.d.ts.map +1 -0
  289. package/dist/src/agents/core/agent-task-manager.js +504 -0
  290. package/dist/src/agents/core/agent-task-manager.js.map +1 -0
  291. package/dist/src/agents/verifiers/base-verifier.d.ts +112 -0
  292. package/dist/src/agents/verifiers/base-verifier.d.ts.map +1 -0
  293. package/dist/src/agents/verifiers/base-verifier.js +130 -0
  294. package/dist/src/agents/verifiers/base-verifier.js.map +1 -0
  295. package/dist/src/agents/verifiers/formatter-verifier.d.ts +14 -0
  296. package/dist/src/agents/verifiers/formatter-verifier.d.ts.map +1 -0
  297. package/dist/src/agents/verifiers/formatter-verifier.js +107 -0
  298. package/dist/src/agents/verifiers/formatter-verifier.js.map +1 -0
  299. package/dist/src/agents/verifiers/llm-judge.d.ts +46 -0
  300. package/dist/src/agents/verifiers/llm-judge.d.ts.map +1 -0
  301. package/dist/src/agents/verifiers/llm-judge.js +248 -0
  302. package/dist/src/agents/verifiers/llm-judge.js.map +1 -0
  303. package/dist/src/cli/claude-sm.js +55 -0
  304. package/dist/src/cli/claude-sm.js.map +1 -1
  305. package/dist/src/cli/commands/agent.d.ts +9 -0
  306. package/dist/src/cli/commands/agent.d.ts.map +1 -0
  307. package/dist/src/cli/commands/agent.js +303 -0
  308. package/dist/src/cli/commands/agent.js.map +1 -0
  309. package/dist/src/cli/commands/handoff.d.ts +6 -0
  310. package/dist/src/cli/commands/handoff.d.ts.map +1 -0
  311. package/dist/src/cli/commands/handoff.js +212 -0
  312. package/dist/src/cli/commands/handoff.js.map +1 -0
  313. package/dist/src/cli/index.d.ts.map +1 -1
  314. package/dist/src/cli/index.js +4 -0
  315. package/dist/src/cli/index.js.map +1 -1
  316. package/dist/src/core/context/frame-database.d.ts +59 -0
  317. package/dist/src/core/context/frame-database.d.ts.map +1 -0
  318. package/dist/src/core/context/frame-database.js +333 -0
  319. package/dist/src/core/context/frame-database.js.map +1 -0
  320. package/dist/src/core/context/frame-digest.d.ts +59 -0
  321. package/dist/src/core/context/frame-digest.d.ts.map +1 -0
  322. package/dist/src/core/context/frame-digest.js +264 -0
  323. package/dist/src/core/context/frame-digest.js.map +1 -0
  324. package/dist/src/core/context/frame-manager.d.ts +2 -0
  325. package/dist/src/core/context/frame-manager.d.ts.map +1 -1
  326. package/dist/src/core/context/frame-manager.js +7 -0
  327. package/dist/src/core/context/frame-manager.js.map +1 -1
  328. package/dist/src/core/context/frame-stack.d.ts +85 -0
  329. package/dist/src/core/context/frame-stack.d.ts.map +1 -0
  330. package/dist/src/core/context/frame-stack.js +287 -0
  331. package/dist/src/core/context/frame-stack.js.map +1 -0
  332. package/dist/src/core/context/frame-types.d.ts +67 -0
  333. package/dist/src/core/context/frame-types.d.ts.map +1 -0
  334. package/dist/src/core/context/frame-types.js +6 -0
  335. package/dist/src/core/context/frame-types.js.map +1 -0
  336. package/dist/src/core/context/index.d.ts +11 -0
  337. package/dist/src/core/context/index.d.ts.map +1 -0
  338. package/dist/src/core/context/index.js +14 -0
  339. package/dist/src/core/context/index.js.map +1 -0
  340. package/dist/src/core/context/refactored-frame-manager.d.ts +99 -0
  341. package/dist/src/core/context/refactored-frame-manager.d.ts.map +1 -0
  342. package/dist/src/core/context/refactored-frame-manager.js +340 -0
  343. package/dist/src/core/context/refactored-frame-manager.js.map +1 -0
  344. package/dist/src/core/database/batch-operations.d.ts +118 -0
  345. package/dist/src/core/database/batch-operations.d.ts.map +1 -0
  346. package/dist/src/core/database/batch-operations.js +339 -0
  347. package/dist/src/core/database/batch-operations.js.map +1 -0
  348. package/dist/src/core/database/connection-pool.d.ts +79 -0
  349. package/dist/src/core/database/connection-pool.d.ts.map +1 -0
  350. package/dist/src/core/database/connection-pool.js +236 -0
  351. package/dist/src/core/database/connection-pool.js.map +1 -0
  352. package/dist/src/core/database/query-cache.d.ts +135 -0
  353. package/dist/src/core/database/query-cache.d.ts.map +1 -0
  354. package/dist/src/core/database/query-cache.js +294 -0
  355. package/dist/src/core/database/query-cache.js.map +1 -0
  356. package/dist/src/core/digest/enhanced-hybrid-digest.d.ts +125 -0
  357. package/dist/src/core/digest/enhanced-hybrid-digest.d.ts.map +1 -0
  358. package/dist/src/core/digest/enhanced-hybrid-digest.js +282 -0
  359. package/dist/src/core/digest/enhanced-hybrid-digest.js.map +1 -0
  360. package/dist/src/core/digest/frame-digest-integration.d.ts +67 -0
  361. package/dist/src/core/digest/frame-digest-integration.d.ts.map +1 -0
  362. package/dist/src/core/digest/frame-digest-integration.js +198 -0
  363. package/dist/src/core/digest/frame-digest-integration.js.map +1 -0
  364. package/dist/src/core/digest/hybrid-digest-generator.d.ts +3 -3
  365. package/dist/src/core/digest/hybrid-digest-generator.d.ts.map +1 -1
  366. package/dist/src/core/digest/hybrid-digest-generator.js.map +1 -1
  367. package/dist/src/core/digest/index.d.ts +3 -1
  368. package/dist/src/core/digest/index.d.ts.map +1 -1
  369. package/dist/src/core/digest/index.js +3 -1
  370. package/dist/src/core/digest/index.js.map +1 -1
  371. package/dist/src/core/errors/index.d.ts +13 -5
  372. package/dist/src/core/errors/index.d.ts.map +1 -1
  373. package/dist/src/core/errors/index.js +13 -5
  374. package/dist/src/core/errors/index.js.map +1 -1
  375. package/dist/src/core/merge/conflict-detector.d.ts +122 -0
  376. package/dist/src/core/merge/conflict-detector.d.ts.map +1 -0
  377. package/dist/src/core/merge/conflict-detector.js +468 -0
  378. package/dist/src/core/merge/conflict-detector.js.map +1 -0
  379. package/dist/src/core/merge/index.d.ts +9 -0
  380. package/dist/src/core/merge/index.d.ts.map +1 -0
  381. package/dist/src/core/merge/index.js +9 -0
  382. package/dist/src/core/merge/index.js.map +1 -0
  383. package/dist/src/core/merge/resolution-engine.d.ts +120 -0
  384. package/dist/src/core/merge/resolution-engine.d.ts.map +1 -0
  385. package/dist/src/core/merge/resolution-engine.js +573 -0
  386. package/dist/src/core/merge/resolution-engine.js.map +1 -0
  387. package/dist/src/core/merge/stack-diff.d.ts +97 -0
  388. package/dist/src/core/merge/stack-diff.d.ts.map +1 -0
  389. package/dist/src/core/merge/stack-diff.js +516 -0
  390. package/dist/src/core/merge/stack-diff.js.map +1 -0
  391. package/dist/src/core/merge/types.d.ts +110 -0
  392. package/dist/src/core/merge/types.d.ts.map +1 -0
  393. package/dist/src/core/merge/types.js +6 -0
  394. package/dist/src/core/merge/types.js.map +1 -0
  395. package/dist/src/core/performance/context-cache.d.ts +109 -0
  396. package/dist/src/core/performance/context-cache.d.ts.map +1 -0
  397. package/dist/src/core/performance/context-cache.js +280 -0
  398. package/dist/src/core/performance/context-cache.js.map +1 -0
  399. package/dist/src/core/performance/index.d.ts +3 -0
  400. package/dist/src/core/performance/index.d.ts.map +1 -0
  401. package/dist/src/core/performance/index.js +3 -0
  402. package/dist/src/core/performance/index.js.map +1 -0
  403. package/dist/src/core/performance/lazy-context-loader.d.ts +93 -0
  404. package/dist/src/core/performance/lazy-context-loader.d.ts.map +1 -0
  405. package/dist/src/core/performance/lazy-context-loader.js +332 -0
  406. package/dist/src/core/performance/lazy-context-loader.js.map +1 -0
  407. package/dist/src/core/performance/monitor.d.ts +48 -0
  408. package/dist/src/core/performance/monitor.d.ts.map +1 -0
  409. package/dist/src/core/performance/monitor.js +226 -0
  410. package/dist/src/core/performance/monitor.js.map +1 -0
  411. package/dist/src/core/performance/optimized-frame-context.d.ts +74 -0
  412. package/dist/src/core/performance/optimized-frame-context.d.ts.map +1 -0
  413. package/dist/src/core/performance/optimized-frame-context.js +330 -0
  414. package/dist/src/core/performance/optimized-frame-context.js.map +1 -0
  415. package/dist/src/core/performance/performance-benchmark.d.ts +50 -0
  416. package/dist/src/core/performance/performance-benchmark.d.ts.map +1 -0
  417. package/dist/src/core/performance/performance-benchmark.js +290 -0
  418. package/dist/src/core/performance/performance-benchmark.js.map +1 -0
  419. package/dist/src/core/performance/performance-profiler.d.ts +151 -0
  420. package/dist/src/core/performance/performance-profiler.d.ts.map +1 -0
  421. package/dist/src/core/performance/performance-profiler.js +346 -0
  422. package/dist/src/core/performance/performance-profiler.js.map +1 -0
  423. package/dist/src/core/performance/streaming-jsonl-parser.d.ts +41 -0
  424. package/dist/src/core/performance/streaming-jsonl-parser.d.ts.map +1 -0
  425. package/dist/src/core/performance/streaming-jsonl-parser.js +193 -0
  426. package/dist/src/core/performance/streaming-jsonl-parser.js.map +1 -0
  427. package/dist/src/core/persistence/postgres-adapter.d.ts.map +1 -1
  428. package/dist/src/core/persistence/postgres-adapter.js +18 -4
  429. package/dist/src/core/persistence/postgres-adapter.js.map +1 -1
  430. package/dist/src/core/query/query-parser.d.ts +5 -0
  431. package/dist/src/core/query/query-parser.d.ts.map +1 -1
  432. package/dist/src/core/query/query-parser.js +86 -18
  433. package/dist/src/core/query/query-parser.js.map +1 -1
  434. package/dist/src/core/query/query-templates.d.ts +44 -0
  435. package/dist/src/core/query/query-templates.d.ts.map +1 -0
  436. package/dist/src/core/query/query-templates.js +326 -0
  437. package/dist/src/core/query/query-templates.js.map +1 -0
  438. package/dist/src/core/retrieval/llm-context-retrieval.d.ts +5 -3
  439. package/dist/src/core/retrieval/llm-context-retrieval.d.ts.map +1 -1
  440. package/dist/src/core/retrieval/llm-context-retrieval.js +73 -21
  441. package/dist/src/core/retrieval/llm-context-retrieval.js.map +1 -1
  442. package/dist/src/core/trace/cli-trace-wrapper.d.ts +23 -0
  443. package/dist/src/core/trace/cli-trace-wrapper.d.ts.map +1 -0
  444. package/dist/src/core/trace/cli-trace-wrapper.js +141 -0
  445. package/dist/src/core/trace/cli-trace-wrapper.js.map +1 -0
  446. package/dist/src/core/trace/db-trace-wrapper.d.ts +36 -0
  447. package/dist/src/core/trace/db-trace-wrapper.d.ts.map +1 -0
  448. package/dist/src/core/trace/db-trace-wrapper.js +252 -0
  449. package/dist/src/core/trace/db-trace-wrapper.js.map +1 -0
  450. package/dist/src/core/trace/debug-trace.d.ts +84 -0
  451. package/dist/src/core/trace/debug-trace.d.ts.map +1 -0
  452. package/dist/src/core/trace/debug-trace.js +402 -0
  453. package/dist/src/core/trace/debug-trace.js.map +1 -0
  454. package/dist/src/core/trace/error-test.d.ts +6 -0
  455. package/dist/src/core/trace/error-test.d.ts.map +1 -0
  456. package/dist/src/core/trace/error-test.js +128 -0
  457. package/dist/src/core/trace/error-test.js.map +1 -0
  458. package/dist/src/core/trace/index.d.ts +25 -0
  459. package/dist/src/core/trace/index.d.ts.map +1 -0
  460. package/dist/src/core/trace/index.js +121 -0
  461. package/dist/src/core/trace/index.js.map +1 -0
  462. package/dist/src/core/trace/linear-api-wrapper.d.ts +17 -0
  463. package/dist/src/core/trace/linear-api-wrapper.d.ts.map +1 -0
  464. package/dist/src/core/trace/linear-api-wrapper.js +205 -0
  465. package/dist/src/core/trace/linear-api-wrapper.js.map +1 -0
  466. package/dist/src/core/trace/performance-test.d.ts +6 -0
  467. package/dist/src/core/trace/performance-test.d.ts.map +1 -0
  468. package/dist/src/core/trace/performance-test.js +111 -0
  469. package/dist/src/core/trace/performance-test.js.map +1 -0
  470. package/dist/src/core/trace/trace-demo.d.ts +8 -0
  471. package/dist/src/core/trace/trace-demo.d.ts.map +1 -0
  472. package/dist/src/core/trace/trace-demo.js +154 -0
  473. package/dist/src/core/trace/trace-demo.js.map +1 -0
  474. package/dist/src/core/trace/trace-detector.d.ts +2 -2
  475. package/dist/src/core/trace/trace-detector.d.ts.map +1 -1
  476. package/dist/src/core/trace/trace-detector.demo.js +1 -1
  477. package/dist/src/core/trace/trace-detector.demo.js.map +1 -1
  478. package/dist/src/core/trace/trace-detector.js +3 -3
  479. package/dist/src/core/trace/trace-detector.js.map +1 -1
  480. package/dist/src/features/tasks/pebbles-task-store.d.ts +9 -2
  481. package/dist/src/features/tasks/pebbles-task-store.d.ts.map +1 -1
  482. package/dist/src/features/tasks/pebbles-task-store.js +97 -18
  483. package/dist/src/features/tasks/pebbles-task-store.js.map +1 -1
  484. package/dist/src/integrations/linear/auth.d.ts.map +1 -1
  485. package/dist/src/integrations/linear/auth.js.map +1 -1
  486. package/dist/src/integrations/linear/client.d.ts +15 -1
  487. package/dist/src/integrations/linear/client.d.ts.map +1 -1
  488. package/dist/src/integrations/linear/client.js +85 -3
  489. package/dist/src/integrations/linear/client.js.map +1 -1
  490. package/dist/src/integrations/linear/sync-manager.d.ts +2 -0
  491. package/dist/src/integrations/linear/sync-manager.d.ts.map +1 -1
  492. package/dist/src/integrations/linear/sync-manager.js +16 -4
  493. package/dist/src/integrations/linear/sync-manager.js.map +1 -1
  494. package/dist/src/integrations/linear/sync-service.d.ts +23 -2
  495. package/dist/src/integrations/linear/sync-service.d.ts.map +1 -1
  496. package/dist/src/integrations/linear/sync-service.js +44 -25
  497. package/dist/src/integrations/linear/sync-service.js.map +1 -1
  498. package/dist/src/integrations/linear/sync.d.ts +6 -0
  499. package/dist/src/integrations/linear/sync.d.ts.map +1 -1
  500. package/dist/src/integrations/linear/sync.js +27 -2
  501. package/dist/src/integrations/linear/sync.js.map +1 -1
  502. package/dist/src/integrations/linear/types.d.ts +16 -1
  503. package/dist/src/integrations/linear/types.d.ts.map +1 -1
  504. package/dist/src/integrations/linear/webhook-server.d.ts.map +1 -1
  505. package/dist/src/integrations/linear/webhook-server.js +10 -8
  506. package/dist/src/integrations/linear/webhook-server.js.map +1 -1
  507. package/dist/src/integrations/linear/webhook.d.ts +13 -0
  508. package/dist/src/integrations/linear/webhook.d.ts.map +1 -1
  509. package/dist/src/integrations/linear/webhook.js +101 -14
  510. package/dist/src/integrations/linear/webhook.js.map +1 -1
  511. package/dist/src/integrations/mcp/handlers/context-handlers.d.ts +39 -0
  512. package/dist/src/integrations/mcp/handlers/context-handlers.d.ts.map +1 -0
  513. package/dist/src/integrations/mcp/handlers/context-handlers.js +266 -0
  514. package/dist/src/integrations/mcp/handlers/context-handlers.js.map +1 -0
  515. package/dist/src/integrations/mcp/handlers/index.d.ts +37 -0
  516. package/dist/src/integrations/mcp/handlers/index.d.ts.map +1 -0
  517. package/dist/src/integrations/mcp/handlers/index.js +134 -0
  518. package/dist/src/integrations/mcp/handlers/index.js.map +1 -0
  519. package/dist/src/integrations/mcp/handlers/linear-handlers.d.ts +33 -0
  520. package/dist/src/integrations/mcp/handlers/linear-handlers.d.ts.map +1 -0
  521. package/dist/src/integrations/mcp/handlers/linear-handlers.js +251 -0
  522. package/dist/src/integrations/mcp/handlers/linear-handlers.js.map +1 -0
  523. package/dist/src/integrations/mcp/handlers/task-handlers.d.ts +42 -0
  524. package/dist/src/integrations/mcp/handlers/task-handlers.d.ts.map +1 -0
  525. package/dist/src/integrations/mcp/handlers/task-handlers.js +238 -0
  526. package/dist/src/integrations/mcp/handlers/task-handlers.js.map +1 -0
  527. package/dist/src/integrations/mcp/handlers/trace-handlers.d.ts +41 -0
  528. package/dist/src/integrations/mcp/handlers/trace-handlers.d.ts.map +1 -0
  529. package/dist/src/integrations/mcp/handlers/trace-handlers.js +298 -0
  530. package/dist/src/integrations/mcp/handlers/trace-handlers.js.map +1 -0
  531. package/dist/src/integrations/mcp/index.d.ts +13 -0
  532. package/dist/src/integrations/mcp/index.d.ts.map +1 -0
  533. package/dist/src/integrations/mcp/index.js +17 -0
  534. package/dist/src/integrations/mcp/index.js.map +1 -0
  535. package/dist/src/integrations/mcp/refactored-server.d.ts +76 -0
  536. package/dist/src/integrations/mcp/refactored-server.d.ts.map +1 -0
  537. package/dist/src/integrations/mcp/refactored-server.js +351 -0
  538. package/dist/src/integrations/mcp/refactored-server.js.map +1 -0
  539. package/dist/src/integrations/mcp/tool-definitions.d.ts +44 -0
  540. package/dist/src/integrations/mcp/tool-definitions.d.ts.map +1 -0
  541. package/dist/src/integrations/mcp/tool-definitions.js +563 -0
  542. package/dist/src/integrations/mcp/tool-definitions.js.map +1 -0
  543. package/dist/src/integrations/pg-aiguide/semantic-search.d.ts.map +1 -1
  544. package/dist/src/integrations/pg-aiguide/semantic-search.js +43 -21
  545. package/dist/src/integrations/pg-aiguide/semantic-search.js.map +1 -1
  546. package/dist/src/mcp/stackmemory-mcp-server.d.ts +9 -0
  547. package/dist/src/mcp/stackmemory-mcp-server.d.ts.map +1 -0
  548. package/dist/src/mcp/stackmemory-mcp-server.js +519 -0
  549. package/dist/src/mcp/stackmemory-mcp-server.js.map +1 -0
  550. package/dist/src/middleware/exponential-rate-limiter.d.ts +78 -0
  551. package/dist/src/middleware/exponential-rate-limiter.d.ts.map +1 -0
  552. package/dist/src/middleware/exponential-rate-limiter.js +293 -0
  553. package/dist/src/middleware/exponential-rate-limiter.js.map +1 -0
  554. package/dist/src/models/user.model.d.ts +8 -1
  555. package/dist/src/models/user.model.d.ts.map +1 -1
  556. package/dist/src/models/user.model.js +62 -14
  557. package/dist/src/models/user.model.js.map +1 -1
  558. package/dist/src/servers/production/auth-middleware.d.ts +5 -2
  559. package/dist/src/servers/production/auth-middleware.d.ts.map +1 -1
  560. package/dist/src/servers/production/auth-middleware.js +71 -34
  561. package/dist/src/servers/production/auth-middleware.js.map +1 -1
  562. package/dist/src/services/context-service.d.ts.map +1 -1
  563. package/dist/src/services/context-service.js +86 -1
  564. package/dist/src/services/context-service.js.map +1 -1
  565. package/dist/src/validation/schemas.d.ts +633 -0
  566. package/dist/src/validation/schemas.d.ts.map +1 -0
  567. package/dist/src/validation/schemas.js +347 -0
  568. package/dist/src/validation/schemas.js.map +1 -0
  569. package/dist/types/task.js +1 -0
  570. package/dist/types/task.js.map +7 -0
  571. package/dist/utils/logger.js +52 -0
  572. package/dist/utils/logger.js.map +7 -0
  573. package/dist/validation/schemas.js +218 -0
  574. package/dist/validation/schemas.js.map +7 -0
  575. package/package.json +7 -3
@@ -0,0 +1,329 @@
1
+ import { logger } from "../monitoring/logger.js";
2
+ import { trace } from "../trace/index.js";
3
+ class BatchOperationsManager {
4
+ db;
5
+ preparedStatements = /* @__PURE__ */ new Map();
6
+ batchQueue = [];
7
+ isProcessing = false;
8
+ constructor(db) {
9
+ if (db) {
10
+ this.db = db;
11
+ this.initializePreparedStatements();
12
+ } else {
13
+ this.db = void 0;
14
+ }
15
+ }
16
+ /**
17
+ * Add events in bulk with optimized batching
18
+ */
19
+ async bulkInsertEvents(events, options = {}) {
20
+ const {
21
+ batchSize = 100,
22
+ onConflict = "ignore",
23
+ enableTransactions = true
24
+ } = options;
25
+ return this.performBulkInsert("events", events, {
26
+ batchSize,
27
+ onConflict,
28
+ enableTransactions,
29
+ preprocessor: (event) => ({
30
+ ...event,
31
+ event_id: `evt_${event.frame_id}_${event.seq}_${Date.now()}`,
32
+ payload: JSON.stringify(event.payload)
33
+ })
34
+ });
35
+ }
36
+ /**
37
+ * Add anchors in bulk
38
+ */
39
+ async bulkInsertAnchors(anchors, options = {}) {
40
+ return this.performBulkInsert("anchors", anchors, {
41
+ ...options,
42
+ preprocessor: (anchor) => ({
43
+ ...anchor,
44
+ anchor_id: `anc_${anchor.frame_id}_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
45
+ metadata: JSON.stringify(anchor.metadata),
46
+ created_at: Date.now()
47
+ })
48
+ });
49
+ }
50
+ /**
51
+ * Bulk update frame digests
52
+ */
53
+ async bulkUpdateFrameDigests(updates, options = {}) {
54
+ const {
55
+ batchSize = 50,
56
+ enableTransactions = true
57
+ } = options;
58
+ return trace.traceAsync("function", "bulkUpdateFrameDigests", { count: updates.length }, async () => {
59
+ const startTime = performance.now();
60
+ const stats = {
61
+ totalRecords: updates.length,
62
+ batchesProcessed: 0,
63
+ successfulInserts: 0,
64
+ failedInserts: 0,
65
+ totalTimeMs: 0,
66
+ avgBatchTimeMs: 0
67
+ };
68
+ if (updates.length === 0) return stats;
69
+ const stmt = this.db.prepare(`
70
+ UPDATE frames
71
+ SET digest_text = ?,
72
+ digest_json = ?,
73
+ closed_at = COALESCE(?, closed_at),
74
+ state = CASE WHEN ? IS NOT NULL THEN 'closed' ELSE state END
75
+ WHERE frame_id = ?
76
+ `);
77
+ const updateFn = (batch) => {
78
+ for (const update of batch) {
79
+ try {
80
+ const result = stmt.run(
81
+ update.digest_text,
82
+ JSON.stringify(update.digest_json),
83
+ update.closed_at,
84
+ update.closed_at,
85
+ update.frame_id
86
+ );
87
+ stats.successfulInserts += result.changes;
88
+ } catch (error) {
89
+ stats.failedInserts++;
90
+ logger.warn("Failed to update frame digest", {
91
+ frameId: update.frame_id,
92
+ error: error.message
93
+ });
94
+ }
95
+ }
96
+ };
97
+ if (enableTransactions) {
98
+ const transaction = this.db.transaction(updateFn);
99
+ await this.processBatches(updates, batchSize, transaction, stats);
100
+ } else {
101
+ await this.processBatches(updates, batchSize, updateFn, stats);
102
+ }
103
+ stats.totalTimeMs = performance.now() - startTime;
104
+ stats.avgBatchTimeMs = stats.batchesProcessed > 0 ? stats.totalTimeMs / stats.batchesProcessed : 0;
105
+ logger.info("Bulk frame digest update completed", stats);
106
+ return stats;
107
+ });
108
+ }
109
+ /**
110
+ * Generic bulk insert with preprocessing
111
+ */
112
+ async performBulkInsert(table, records, options = {}) {
113
+ const {
114
+ batchSize = 100,
115
+ onConflict = "ignore",
116
+ enableTransactions = true,
117
+ preprocessor
118
+ } = options;
119
+ return trace.traceAsync("function", `bulkInsert${table}`, { count: records.length }, async () => {
120
+ const startTime = performance.now();
121
+ const stats = {
122
+ totalRecords: records.length,
123
+ batchesProcessed: 0,
124
+ successfulInserts: 0,
125
+ failedInserts: 0,
126
+ totalTimeMs: 0,
127
+ avgBatchTimeMs: 0
128
+ };
129
+ if (records.length === 0) return stats;
130
+ const processedRecords = preprocessor ? records.map(preprocessor) : records;
131
+ const firstRecord = processedRecords[0];
132
+ const columns = Object.keys(firstRecord);
133
+ const placeholders = columns.map(() => "?").join(", ");
134
+ const conflictClause = this.getConflictClause(onConflict);
135
+ const insertSql = `INSERT ${conflictClause} INTO ${table} (${columns.join(", ")}) VALUES (${placeholders})`;
136
+ const stmt = this.db.prepare(insertSql);
137
+ const insertFn = (batch) => {
138
+ for (const record of batch) {
139
+ try {
140
+ const values = columns.map((col) => record[col]);
141
+ const result = stmt.run(...values);
142
+ stats.successfulInserts += result.changes;
143
+ } catch (error) {
144
+ stats.failedInserts++;
145
+ logger.warn(`Failed to insert ${table} record`, {
146
+ record,
147
+ error: error.message
148
+ });
149
+ }
150
+ }
151
+ };
152
+ if (enableTransactions) {
153
+ const transaction = this.db.transaction(insertFn);
154
+ await this.processBatches(processedRecords, batchSize, transaction, stats);
155
+ } else {
156
+ await this.processBatches(processedRecords, batchSize, insertFn, stats);
157
+ }
158
+ stats.totalTimeMs = performance.now() - startTime;
159
+ stats.avgBatchTimeMs = stats.batchesProcessed > 0 ? stats.totalTimeMs / stats.batchesProcessed : 0;
160
+ logger.info(`Bulk ${table} insert completed`, stats);
161
+ return stats;
162
+ });
163
+ }
164
+ /**
165
+ * Process records in batches
166
+ */
167
+ async processBatches(records, batchSize, processFn, stats) {
168
+ for (let i = 0; i < records.length; i += batchSize) {
169
+ const batch = records.slice(i, i + batchSize);
170
+ const batchStart = performance.now();
171
+ try {
172
+ processFn(batch);
173
+ stats.batchesProcessed++;
174
+ const batchTime = performance.now() - batchStart;
175
+ logger.debug("Batch processed", {
176
+ batchNumber: stats.batchesProcessed,
177
+ records: batch.length,
178
+ timeMs: batchTime.toFixed(2)
179
+ });
180
+ if (stats.batchesProcessed % 10 === 0) {
181
+ await new Promise((resolve) => setImmediate(resolve));
182
+ }
183
+ } catch (error) {
184
+ stats.failedInserts += batch.length;
185
+ logger.error("Batch processing failed", error, {
186
+ batchNumber: stats.batchesProcessed + 1,
187
+ batchSize: batch.length
188
+ });
189
+ }
190
+ }
191
+ }
192
+ /**
193
+ * Queue batch operation for later processing
194
+ */
195
+ queueBatchOperation(operation) {
196
+ this.batchQueue.push(operation);
197
+ if (this.batchQueue.length >= 10 && !this.isProcessing) {
198
+ setImmediate(() => this.processBatchQueue());
199
+ }
200
+ }
201
+ /**
202
+ * Process queued batch operations
203
+ */
204
+ async processBatchQueue() {
205
+ if (this.isProcessing || this.batchQueue.length === 0) {
206
+ return;
207
+ }
208
+ this.isProcessing = true;
209
+ const operations = [...this.batchQueue];
210
+ this.batchQueue = [];
211
+ try {
212
+ const groupedOps = this.groupOperationsByTable(operations);
213
+ for (const [table, tableOps] of groupedOps) {
214
+ await this.processTableOperations(table, tableOps);
215
+ }
216
+ logger.info("Batch queue processed", {
217
+ operations: operations.length,
218
+ tables: groupedOps.size
219
+ });
220
+ } catch (error) {
221
+ logger.error("Batch queue processing failed", error);
222
+ } finally {
223
+ this.isProcessing = false;
224
+ }
225
+ }
226
+ /**
227
+ * Flush any remaining queued operations
228
+ */
229
+ async flush() {
230
+ if (this.batchQueue.length > 0) {
231
+ await this.processBatchQueue();
232
+ }
233
+ }
234
+ /**
235
+ * Get SQL conflict clause
236
+ */
237
+ getConflictClause(onConflict) {
238
+ switch (onConflict) {
239
+ case "ignore":
240
+ return "OR IGNORE";
241
+ case "replace":
242
+ return "OR REPLACE";
243
+ case "update":
244
+ return "ON CONFLICT DO UPDATE SET";
245
+ default:
246
+ return "";
247
+ }
248
+ }
249
+ /**
250
+ * Group operations by table for efficient processing
251
+ */
252
+ groupOperationsByTable(operations) {
253
+ const grouped = /* @__PURE__ */ new Map();
254
+ for (const op of operations) {
255
+ if (!grouped.has(op.table)) {
256
+ grouped.set(op.table, []);
257
+ }
258
+ grouped.get(op.table).push(op);
259
+ }
260
+ return grouped;
261
+ }
262
+ /**
263
+ * Process all operations for a specific table
264
+ */
265
+ async processTableOperations(table, operations) {
266
+ for (const op of operations) {
267
+ switch (op.operation) {
268
+ case "insert":
269
+ await this.performBulkInsert(table, op.data, {
270
+ onConflict: op.onConflict
271
+ });
272
+ break;
273
+ // Add update and delete operations as needed
274
+ default:
275
+ logger.warn("Unsupported batch operation", { table, operation: op.operation });
276
+ }
277
+ }
278
+ }
279
+ /**
280
+ * Initialize commonly used prepared statements
281
+ */
282
+ initializePreparedStatements() {
283
+ this.preparedStatements.set(
284
+ "insert_event",
285
+ this.db.prepare(`
286
+ INSERT OR IGNORE INTO events
287
+ (event_id, frame_id, run_id, seq, event_type, payload, ts)
288
+ VALUES (?, ?, ?, ?, ?, ?, ?)
289
+ `)
290
+ );
291
+ this.preparedStatements.set(
292
+ "insert_anchor",
293
+ this.db.prepare(`
294
+ INSERT OR IGNORE INTO anchors
295
+ (anchor_id, frame_id, type, text, priority, metadata, created_at)
296
+ VALUES (?, ?, ?, ?, ?, ?, ?)
297
+ `)
298
+ );
299
+ logger.info("Batch operations prepared statements initialized");
300
+ }
301
+ /**
302
+ * Cleanup resources
303
+ */
304
+ cleanup() {
305
+ this.preparedStatements.clear();
306
+ }
307
+ }
308
+ let globalBatchManager = null;
309
+ function getBatchManager(db) {
310
+ if (!globalBatchManager) {
311
+ globalBatchManager = new BatchOperationsManager(db);
312
+ }
313
+ return globalBatchManager;
314
+ }
315
+ async function bulkInsertEvents(events, options) {
316
+ const manager = getBatchManager();
317
+ return manager.bulkInsertEvents(events, options);
318
+ }
319
+ async function bulkInsertAnchors(anchors, options) {
320
+ const manager = getBatchManager();
321
+ return manager.bulkInsertAnchors(anchors, options);
322
+ }
323
+ export {
324
+ BatchOperationsManager,
325
+ bulkInsertAnchors,
326
+ bulkInsertEvents,
327
+ getBatchManager
328
+ };
329
+ //# sourceMappingURL=batch-operations.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/core/database/batch-operations.ts"],
4
+ "sourcesContent": ["/**\n * Batch Database Operations\n * High-performance bulk operations with transaction management\n */\n\nimport Database from 'better-sqlite3';\nimport { getConnectionPool } from './connection-pool.js';\nimport { logger } from '../monitoring/logger.js';\nimport { trace } from '../trace/index.js';\n\nexport interface BatchOperation {\n table: string;\n operation: 'insert' | 'update' | 'delete';\n data: Record<string, any>[];\n onConflict?: 'ignore' | 'replace' | 'update';\n}\n\nexport interface BulkInsertOptions {\n batchSize?: number;\n onConflict?: 'ignore' | 'replace' | 'update';\n enableTransactions?: boolean;\n parallelTables?: boolean;\n}\n\nexport interface BatchStats {\n totalRecords: number;\n batchesProcessed: number;\n successfulInserts: number;\n failedInserts: number;\n totalTimeMs: number;\n avgBatchTimeMs: number;\n}\n\n/**\n * High-performance batch operations manager\n */\nexport class BatchOperationsManager {\n private db: Database.Database;\n private preparedStatements = new Map<string, Database.Statement>();\n private batchQueue: BatchOperation[] = [];\n private isProcessing = false;\n\n constructor(db?: Database.Database) {\n if (db) {\n this.db = db;\n this.initializePreparedStatements();\n } else {\n // Will be initialized when used with getConnectionPool().withConnection()\n this.db = undefined as any;\n }\n }\n\n /**\n * Add events in bulk with optimized batching\n */\n async bulkInsertEvents(\n events: Array<{\n frame_id: string;\n run_id: string;\n seq: number;\n event_type: string;\n payload: any;\n ts: number;\n }>,\n options: BulkInsertOptions = {}\n ): Promise<BatchStats> {\n const {\n batchSize = 100,\n onConflict = 'ignore',\n enableTransactions = true,\n } = options;\n\n return this.performBulkInsert('events', events, {\n batchSize,\n onConflict,\n enableTransactions,\n preprocessor: (event) => ({\n ...event,\n event_id: `evt_${event.frame_id}_${event.seq}_${Date.now()}`,\n payload: JSON.stringify(event.payload),\n }),\n });\n }\n\n /**\n * Add anchors in bulk\n */\n async bulkInsertAnchors(\n anchors: Array<{\n frame_id: string;\n type: string;\n text: string;\n priority: number;\n metadata: any;\n }>,\n options: BulkInsertOptions = {}\n ): Promise<BatchStats> {\n return this.performBulkInsert('anchors', anchors, {\n ...options,\n preprocessor: (anchor) => ({\n ...anchor,\n anchor_id: `anc_${anchor.frame_id}_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,\n metadata: JSON.stringify(anchor.metadata),\n created_at: Date.now(),\n }),\n });\n }\n\n /**\n * Bulk update frame digests\n */\n async bulkUpdateFrameDigests(\n updates: Array<{\n frame_id: string;\n digest_text: string;\n digest_json: any;\n closed_at?: number;\n }>,\n options: BulkInsertOptions = {}\n ): Promise<BatchStats> {\n const {\n batchSize = 50,\n enableTransactions = true,\n } = options;\n\n return trace.traceAsync('function', 'bulkUpdateFrameDigests', { count: updates.length }, async () => {\n const startTime = performance.now();\n const stats: BatchStats = {\n totalRecords: updates.length,\n batchesProcessed: 0,\n successfulInserts: 0,\n failedInserts: 0,\n totalTimeMs: 0,\n avgBatchTimeMs: 0,\n };\n\n if (updates.length === 0) return stats;\n\n const stmt = this.db.prepare(`\n UPDATE frames \n SET digest_text = ?, \n digest_json = ?, \n closed_at = COALESCE(?, closed_at),\n state = CASE WHEN ? IS NOT NULL THEN 'closed' ELSE state END\n WHERE frame_id = ?\n `);\n\n const updateFn = (batch: typeof updates) => {\n for (const update of batch) {\n try {\n const result = stmt.run(\n update.digest_text,\n JSON.stringify(update.digest_json),\n update.closed_at,\n update.closed_at,\n update.frame_id\n );\n stats.successfulInserts += result.changes;\n } catch (error) {\n stats.failedInserts++;\n logger.warn('Failed to update frame digest', {\n frameId: update.frame_id,\n error: (error as Error).message,\n });\n }\n }\n };\n\n if (enableTransactions) {\n const transaction = this.db.transaction(updateFn);\n await this.processBatches(updates, batchSize, transaction, stats);\n } else {\n await this.processBatches(updates, batchSize, updateFn, stats);\n }\n\n stats.totalTimeMs = performance.now() - startTime;\n stats.avgBatchTimeMs = stats.batchesProcessed > 0 \n ? stats.totalTimeMs / stats.batchesProcessed \n : 0;\n\n logger.info('Bulk frame digest update completed', stats as unknown as Record<string, unknown>);\n return stats;\n });\n }\n\n /**\n * Generic bulk insert with preprocessing\n */\n private async performBulkInsert<T extends Record<string, any>>(\n table: string,\n records: T[],\n options: BulkInsertOptions & {\n preprocessor?: (record: T) => Record<string, any>;\n } = {}\n ): Promise<BatchStats> {\n const {\n batchSize = 100,\n onConflict = 'ignore',\n enableTransactions = true,\n preprocessor,\n } = options;\n\n return trace.traceAsync('function', `bulkInsert${table}`, { count: records.length }, async () => {\n const startTime = performance.now();\n const stats: BatchStats = {\n totalRecords: records.length,\n batchesProcessed: 0,\n successfulInserts: 0,\n failedInserts: 0,\n totalTimeMs: 0,\n avgBatchTimeMs: 0,\n };\n\n if (records.length === 0) return stats;\n\n // Preprocess records if needed\n const processedRecords = preprocessor \n ? records.map(preprocessor)\n : records;\n\n // Build dynamic insert statement\n const firstRecord = processedRecords[0];\n const columns = Object.keys(firstRecord);\n const placeholders = columns.map(() => '?').join(', ');\n const conflictClause = this.getConflictClause(onConflict);\n \n const insertSql = `INSERT ${conflictClause} INTO ${table} (${columns.join(', ')}) VALUES (${placeholders})`;\n const stmt = this.db.prepare(insertSql);\n\n const insertFn = (batch: typeof processedRecords) => {\n for (const record of batch) {\n try {\n const values = columns.map(col => record[col]);\n const result = stmt.run(...values);\n stats.successfulInserts += result.changes;\n } catch (error) {\n stats.failedInserts++;\n logger.warn(`Failed to insert ${table} record`, {\n record,\n error: (error as Error).message,\n });\n }\n }\n };\n\n if (enableTransactions) {\n const transaction = this.db.transaction(insertFn);\n await this.processBatches(processedRecords, batchSize, transaction, stats);\n } else {\n await this.processBatches(processedRecords, batchSize, insertFn, stats);\n }\n\n stats.totalTimeMs = performance.now() - startTime;\n stats.avgBatchTimeMs = stats.batchesProcessed > 0 \n ? stats.totalTimeMs / stats.batchesProcessed \n : 0;\n\n logger.info(`Bulk ${table} insert completed`, stats as unknown as Record<string, unknown>);\n return stats;\n });\n }\n\n /**\n * Process records in batches\n */\n private async processBatches<T>(\n records: T[],\n batchSize: number,\n processFn: (batch: T[]) => void,\n stats: BatchStats\n ): Promise<void> {\n for (let i = 0; i < records.length; i += batchSize) {\n const batch = records.slice(i, i + batchSize);\n const batchStart = performance.now();\n \n try {\n processFn(batch);\n stats.batchesProcessed++;\n \n const batchTime = performance.now() - batchStart;\n logger.debug('Batch processed', {\n batchNumber: stats.batchesProcessed,\n records: batch.length,\n timeMs: batchTime.toFixed(2),\n });\n\n // Yield control to prevent blocking\n if (stats.batchesProcessed % 10 === 0) {\n await new Promise(resolve => setImmediate(resolve));\n }\n\n } catch (error) {\n stats.failedInserts += batch.length;\n logger.error('Batch processing failed', error as Error, {\n batchNumber: stats.batchesProcessed + 1,\n batchSize: batch.length,\n });\n }\n }\n }\n\n /**\n * Queue batch operation for later processing\n */\n queueBatchOperation(operation: BatchOperation): void {\n this.batchQueue.push(operation);\n \n if (this.batchQueue.length >= 10 && !this.isProcessing) {\n setImmediate(() => this.processBatchQueue());\n }\n }\n\n /**\n * Process queued batch operations\n */\n async processBatchQueue(): Promise<void> {\n if (this.isProcessing || this.batchQueue.length === 0) {\n return;\n }\n\n this.isProcessing = true;\n const operations = [...this.batchQueue];\n this.batchQueue = [];\n\n try {\n const groupedOps = this.groupOperationsByTable(operations);\n \n for (const [table, tableOps] of groupedOps) {\n await this.processTableOperations(table, tableOps);\n }\n\n logger.info('Batch queue processed', {\n operations: operations.length,\n tables: groupedOps.size,\n });\n\n } catch (error) {\n logger.error('Batch queue processing failed', error as Error);\n } finally {\n this.isProcessing = false;\n }\n }\n\n /**\n * Flush any remaining queued operations\n */\n async flush(): Promise<void> {\n if (this.batchQueue.length > 0) {\n await this.processBatchQueue();\n }\n }\n\n /**\n * Get SQL conflict clause\n */\n private getConflictClause(onConflict: string): string {\n switch (onConflict) {\n case 'ignore':\n return 'OR IGNORE';\n case 'replace':\n return 'OR REPLACE';\n case 'update':\n return 'ON CONFLICT DO UPDATE SET';\n default:\n return '';\n }\n }\n\n /**\n * Group operations by table for efficient processing\n */\n private groupOperationsByTable(operations: BatchOperation[]): Map<string, BatchOperation[]> {\n const grouped = new Map<string, BatchOperation[]>();\n \n for (const op of operations) {\n if (!grouped.has(op.table)) {\n grouped.set(op.table, []);\n }\n grouped.get(op.table)!.push(op);\n }\n \n return grouped;\n }\n\n /**\n * Process all operations for a specific table\n */\n private async processTableOperations(table: string, operations: BatchOperation[]): Promise<void> {\n for (const op of operations) {\n switch (op.operation) {\n case 'insert':\n await this.performBulkInsert(table, op.data, {\n onConflict: op.onConflict,\n });\n break;\n // Add update and delete operations as needed\n default:\n logger.warn('Unsupported batch operation', { table, operation: op.operation });\n }\n }\n }\n\n /**\n * Initialize commonly used prepared statements\n */\n private initializePreparedStatements(): void {\n // Event insertion\n this.preparedStatements.set('insert_event', \n this.db.prepare(`\n INSERT OR IGNORE INTO events \n (event_id, frame_id, run_id, seq, event_type, payload, ts) \n VALUES (?, ?, ?, ?, ?, ?, ?)\n `)\n );\n\n // Anchor insertion\n this.preparedStatements.set('insert_anchor',\n this.db.prepare(`\n INSERT OR IGNORE INTO anchors \n (anchor_id, frame_id, type, text, priority, metadata, created_at) \n VALUES (?, ?, ?, ?, ?, ?, ?)\n `)\n );\n\n logger.info('Batch operations prepared statements initialized');\n }\n\n /**\n * Cleanup resources\n */\n cleanup(): void {\n // Modern better-sqlite3 automatically handles cleanup\n this.preparedStatements.clear();\n }\n}\n\n// Global batch operations manager\nlet globalBatchManager: BatchOperationsManager | null = null;\n\n/**\n * Get or create global batch operations manager\n */\nexport function getBatchManager(db?: Database.Database): BatchOperationsManager {\n if (!globalBatchManager) {\n globalBatchManager = new BatchOperationsManager(db);\n }\n return globalBatchManager;\n}\n\n/**\n * Convenience function for bulk event insertion\n */\nexport async function bulkInsertEvents(\n events: any[],\n options?: BulkInsertOptions\n): Promise<BatchStats> {\n const manager = getBatchManager();\n return manager.bulkInsertEvents(events, options);\n}\n\n/**\n * Convenience function for bulk anchor insertion\n */\nexport async function bulkInsertAnchors(\n anchors: any[],\n options?: BulkInsertOptions\n): Promise<BatchStats> {\n const manager = getBatchManager();\n return manager.bulkInsertAnchors(anchors, options);\n}"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,224 @@
1
+ import { createTracedDatabase } from "../trace/db-trace-wrapper.js";
2
+ import { logger } from "../monitoring/logger.js";
3
+ class SQLiteConnectionPool {
4
+ connections = /* @__PURE__ */ new Map();
5
+ filename;
6
+ options;
7
+ maxConnections;
8
+ acquireTimeoutMs;
9
+ idleTimeoutMs;
10
+ cleanupInterval = null;
11
+ // Statistics
12
+ stats = {
13
+ totalCreated: 0,
14
+ totalAcquired: 0,
15
+ totalReleased: 0,
16
+ currentActive: 0,
17
+ currentIdle: 0
18
+ };
19
+ constructor(filename, options = {}) {
20
+ this.filename = filename;
21
+ this.options = options;
22
+ this.maxConnections = options.maxConnections ?? 5;
23
+ this.acquireTimeoutMs = options.acquireTimeoutMs ?? 5e3;
24
+ this.idleTimeoutMs = options.idleTimeoutMs ?? 3e5;
25
+ if (options.checkInterval !== 0) {
26
+ this.cleanupInterval = setInterval(
27
+ () => this.cleanup(),
28
+ options.checkInterval ?? 6e4
29
+ // 1 minute
30
+ );
31
+ }
32
+ logger.info("SQLite connection pool initialized", {
33
+ filename,
34
+ maxConnections: this.maxConnections,
35
+ acquireTimeoutMs: this.acquireTimeoutMs,
36
+ idleTimeoutMs: this.idleTimeoutMs
37
+ });
38
+ }
39
+ /**
40
+ * Acquire a connection from the pool
41
+ */
42
+ async acquire() {
43
+ const startTime = Date.now();
44
+ while (Date.now() - startTime < this.acquireTimeoutMs) {
45
+ for (const [id, connection] of this.connections) {
46
+ if (!connection.inUse) {
47
+ connection.inUse = true;
48
+ connection.lastUsed = Date.now();
49
+ this.stats.totalAcquired++;
50
+ this.stats.currentActive++;
51
+ this.stats.currentIdle--;
52
+ logger.debug("Reused connection from pool", { connectionId: id });
53
+ return connection;
54
+ }
55
+ }
56
+ if (this.connections.size < this.maxConnections) {
57
+ return this.createConnection();
58
+ }
59
+ await new Promise((resolve) => setTimeout(resolve, 10));
60
+ }
61
+ throw new Error(`Failed to acquire connection within ${this.acquireTimeoutMs}ms timeout`);
62
+ }
63
+ /**
64
+ * Release a connection back to the pool
65
+ */
66
+ release(connection) {
67
+ if (this.connections.has(connection.id)) {
68
+ connection.inUse = false;
69
+ connection.lastUsed = Date.now();
70
+ this.stats.totalReleased++;
71
+ this.stats.currentActive--;
72
+ this.stats.currentIdle++;
73
+ logger.debug("Released connection to pool", { connectionId: connection.id });
74
+ }
75
+ }
76
+ /**
77
+ * Execute a function with a pooled connection
78
+ */
79
+ async withConnection(fn) {
80
+ const connection = await this.acquire();
81
+ try {
82
+ return await fn(connection.db);
83
+ } finally {
84
+ this.release(connection);
85
+ }
86
+ }
87
+ /**
88
+ * Execute a transaction with a pooled connection
89
+ */
90
+ async withTransaction(fn) {
91
+ const connection = await this.acquire();
92
+ try {
93
+ const transaction = connection.db.transaction(() => fn(connection.db));
94
+ return transaction();
95
+ } finally {
96
+ this.release(connection);
97
+ }
98
+ }
99
+ /**
100
+ * Get pool statistics
101
+ */
102
+ getStats() {
103
+ return {
104
+ ...this.stats,
105
+ totalConnections: this.connections.size,
106
+ maxConnections: this.maxConnections
107
+ };
108
+ }
109
+ /**
110
+ * Close all connections and cleanup
111
+ */
112
+ async close() {
113
+ if (this.cleanupInterval) {
114
+ clearInterval(this.cleanupInterval);
115
+ this.cleanupInterval = null;
116
+ }
117
+ for (const [id, connection] of this.connections) {
118
+ try {
119
+ connection.db.close();
120
+ logger.debug("Closed connection", { connectionId: id });
121
+ } catch (error) {
122
+ logger.warn("Error closing connection", {
123
+ connectionId: id,
124
+ error: error.message
125
+ });
126
+ }
127
+ }
128
+ this.connections.clear();
129
+ this.stats.currentActive = 0;
130
+ this.stats.currentIdle = 0;
131
+ logger.info("Connection pool closed", {
132
+ totalCreated: this.stats.totalCreated,
133
+ totalAcquired: this.stats.totalAcquired,
134
+ totalReleased: this.stats.totalReleased
135
+ });
136
+ }
137
+ /**
138
+ * Create a new connection
139
+ */
140
+ createConnection() {
141
+ const id = `conn_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
142
+ const now = Date.now();
143
+ const db = createTracedDatabase(this.filename, this.options);
144
+ db.pragma("journal_mode = WAL");
145
+ db.pragma("synchronous = NORMAL");
146
+ db.pragma("cache_size = 1000");
147
+ db.pragma("temp_store = MEMORY");
148
+ const connection = {
149
+ db,
150
+ id,
151
+ createdAt: now,
152
+ lastUsed: now,
153
+ inUse: true
154
+ };
155
+ this.connections.set(id, connection);
156
+ this.stats.totalCreated++;
157
+ this.stats.totalAcquired++;
158
+ this.stats.currentActive++;
159
+ logger.debug("Created new connection", {
160
+ connectionId: id,
161
+ totalConnections: this.connections.size
162
+ });
163
+ return connection;
164
+ }
165
+ /**
166
+ * Clean up idle connections
167
+ */
168
+ cleanup() {
169
+ const now = Date.now();
170
+ const toRemove = [];
171
+ for (const [id, connection] of this.connections) {
172
+ if (!connection.inUse && now - connection.lastUsed > this.idleTimeoutMs) {
173
+ toRemove.push(id);
174
+ }
175
+ }
176
+ for (const id of toRemove) {
177
+ const connection = this.connections.get(id);
178
+ if (connection) {
179
+ try {
180
+ connection.db.close();
181
+ this.connections.delete(id);
182
+ this.stats.currentIdle--;
183
+ logger.debug("Cleaned up idle connection", {
184
+ connectionId: id,
185
+ idleTime: now - connection.lastUsed
186
+ });
187
+ } catch (error) {
188
+ logger.warn("Error cleaning up connection", {
189
+ connectionId: id,
190
+ error: error.message
191
+ });
192
+ }
193
+ }
194
+ }
195
+ if (toRemove.length > 0) {
196
+ logger.info("Connection cleanup completed", {
197
+ removed: toRemove.length,
198
+ remaining: this.connections.size
199
+ });
200
+ }
201
+ }
202
+ }
203
+ let globalPool = null;
204
+ function getConnectionPool(filename, options) {
205
+ if (!globalPool && filename) {
206
+ globalPool = new SQLiteConnectionPool(filename, options);
207
+ }
208
+ if (!globalPool) {
209
+ throw new Error("Connection pool not initialized. Call with filename first.");
210
+ }
211
+ return globalPool;
212
+ }
213
+ async function closeGlobalPool() {
214
+ if (globalPool) {
215
+ await globalPool.close();
216
+ globalPool = null;
217
+ }
218
+ }
219
+ export {
220
+ SQLiteConnectionPool,
221
+ closeGlobalPool,
222
+ getConnectionPool
223
+ };
224
+ //# sourceMappingURL=connection-pool.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/core/database/connection-pool.ts"],
4
+ "sourcesContent": ["/**\n * SQLite Connection Pool\n * Manages a pool of SQLite database connections for performance optimization\n */\n\nimport Database from 'better-sqlite3';\nimport { createTracedDatabase, TracedDatabaseOptions } from '../trace/db-trace-wrapper.js';\nimport { logger } from '../monitoring/logger.js';\n\nexport interface ConnectionPoolOptions extends TracedDatabaseOptions {\n maxConnections?: number;\n acquireTimeoutMs?: number;\n idleTimeoutMs?: number;\n checkInterval?: number;\n}\n\nexport interface PooledConnection {\n db: Database.Database;\n id: string;\n createdAt: number;\n lastUsed: number;\n inUse: boolean;\n}\n\nexport class SQLiteConnectionPool {\n private connections: Map<string, PooledConnection> = new Map();\n private filename: string;\n private options: ConnectionPoolOptions;\n private maxConnections: number;\n private acquireTimeoutMs: number;\n private idleTimeoutMs: number;\n private cleanupInterval: NodeJS.Timeout | null = null;\n \n // Statistics\n private stats = {\n totalCreated: 0,\n totalAcquired: 0,\n totalReleased: 0,\n currentActive: 0,\n currentIdle: 0,\n };\n\n constructor(filename: string, options: ConnectionPoolOptions = {}) {\n this.filename = filename;\n this.options = options;\n this.maxConnections = options.maxConnections ?? 5;\n this.acquireTimeoutMs = options.acquireTimeoutMs ?? 5000;\n this.idleTimeoutMs = options.idleTimeoutMs ?? 300000; // 5 minutes\n \n // Start cleanup interval\n if (options.checkInterval !== 0) {\n this.cleanupInterval = setInterval(\n () => this.cleanup(),\n options.checkInterval ?? 60000 // 1 minute\n );\n }\n\n logger.info('SQLite connection pool initialized', {\n filename,\n maxConnections: this.maxConnections,\n acquireTimeoutMs: this.acquireTimeoutMs,\n idleTimeoutMs: this.idleTimeoutMs,\n });\n }\n\n /**\n * Acquire a connection from the pool\n */\n async acquire(): Promise<PooledConnection> {\n const startTime = Date.now();\n \n while (Date.now() - startTime < this.acquireTimeoutMs) {\n // Try to find an idle connection\n for (const [id, connection] of this.connections) {\n if (!connection.inUse) {\n connection.inUse = true;\n connection.lastUsed = Date.now();\n this.stats.totalAcquired++;\n this.stats.currentActive++;\n this.stats.currentIdle--;\n \n logger.debug('Reused connection from pool', { connectionId: id });\n return connection;\n }\n }\n\n // Create new connection if under limit\n if (this.connections.size < this.maxConnections) {\n return this.createConnection();\n }\n\n // Wait briefly before retrying\n await new Promise(resolve => setTimeout(resolve, 10));\n }\n\n throw new Error(`Failed to acquire connection within ${this.acquireTimeoutMs}ms timeout`);\n }\n\n /**\n * Release a connection back to the pool\n */\n release(connection: PooledConnection): void {\n if (this.connections.has(connection.id)) {\n connection.inUse = false;\n connection.lastUsed = Date.now();\n this.stats.totalReleased++;\n this.stats.currentActive--;\n this.stats.currentIdle++;\n \n logger.debug('Released connection to pool', { connectionId: connection.id });\n }\n }\n\n /**\n * Execute a function with a pooled connection\n */\n async withConnection<T>(fn: (db: Database.Database) => T | Promise<T>): Promise<T> {\n const connection = await this.acquire();\n try {\n return await fn(connection.db);\n } finally {\n this.release(connection);\n }\n }\n\n /**\n * Execute a transaction with a pooled connection\n */\n async withTransaction<T>(fn: (db: Database.Database) => T): Promise<T> {\n const connection = await this.acquire();\n try {\n const transaction = connection.db.transaction(() => fn(connection.db));\n return transaction();\n } finally {\n this.release(connection);\n }\n }\n\n /**\n * Get pool statistics\n */\n getStats() {\n return {\n ...this.stats,\n totalConnections: this.connections.size,\n maxConnections: this.maxConnections,\n };\n }\n\n /**\n * Close all connections and cleanup\n */\n async close(): Promise<void> {\n if (this.cleanupInterval) {\n clearInterval(this.cleanupInterval);\n this.cleanupInterval = null;\n }\n\n for (const [id, connection] of this.connections) {\n try {\n connection.db.close();\n logger.debug('Closed connection', { connectionId: id });\n } catch (error) {\n logger.warn('Error closing connection', {\n connectionId: id,\n error: (error as Error).message,\n });\n }\n }\n\n this.connections.clear();\n this.stats.currentActive = 0;\n this.stats.currentIdle = 0;\n \n logger.info('Connection pool closed', { \n totalCreated: this.stats.totalCreated,\n totalAcquired: this.stats.totalAcquired,\n totalReleased: this.stats.totalReleased,\n });\n }\n\n /**\n * Create a new connection\n */\n private createConnection(): PooledConnection {\n const id = `conn_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;\n const now = Date.now();\n \n const db = createTracedDatabase(this.filename, this.options);\n \n // Configure for performance\n db.pragma('journal_mode = WAL');\n db.pragma('synchronous = NORMAL');\n db.pragma('cache_size = 1000');\n db.pragma('temp_store = MEMORY');\n \n const connection: PooledConnection = {\n db,\n id,\n createdAt: now,\n lastUsed: now,\n inUse: true,\n };\n\n this.connections.set(id, connection);\n this.stats.totalCreated++;\n this.stats.totalAcquired++;\n this.stats.currentActive++;\n\n logger.debug('Created new connection', { \n connectionId: id,\n totalConnections: this.connections.size,\n });\n\n return connection;\n }\n\n /**\n * Clean up idle connections\n */\n private cleanup(): void {\n const now = Date.now();\n const toRemove: string[] = [];\n\n for (const [id, connection] of this.connections) {\n if (!connection.inUse && now - connection.lastUsed > this.idleTimeoutMs) {\n toRemove.push(id);\n }\n }\n\n for (const id of toRemove) {\n const connection = this.connections.get(id);\n if (connection) {\n try {\n connection.db.close();\n this.connections.delete(id);\n this.stats.currentIdle--;\n \n logger.debug('Cleaned up idle connection', { \n connectionId: id,\n idleTime: now - connection.lastUsed,\n });\n } catch (error) {\n logger.warn('Error cleaning up connection', {\n connectionId: id,\n error: (error as Error).message,\n });\n }\n }\n }\n\n if (toRemove.length > 0) {\n logger.info('Connection cleanup completed', {\n removed: toRemove.length,\n remaining: this.connections.size,\n });\n }\n }\n}\n\n// Global pool instance\nlet globalPool: SQLiteConnectionPool | null = null;\n\n/**\n * Get or create the global connection pool\n */\nexport function getConnectionPool(\n filename?: string, \n options?: ConnectionPoolOptions\n): SQLiteConnectionPool {\n if (!globalPool && filename) {\n globalPool = new SQLiteConnectionPool(filename, options);\n }\n \n if (!globalPool) {\n throw new Error('Connection pool not initialized. Call with filename first.');\n }\n \n return globalPool;\n}\n\n/**\n * Close the global connection pool\n */\nexport async function closeGlobalPool(): Promise<void> {\n if (globalPool) {\n await globalPool.close();\n globalPool = null;\n }\n}"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }