sensemaking 0.27.0 → 0.28.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 (364) hide show
  1. package/bin/cli.js +16 -7
  2. package/dist/cjs/chunk/extract.js.map +1 -1
  3. package/dist/cjs/chunk/group.js.map +1 -1
  4. package/dist/cjs/chunk/index.js.map +1 -1
  5. package/dist/cjs/chunk/parse.js.map +1 -1
  6. package/dist/cjs/chunk/parser.js.map +1 -1
  7. package/dist/cjs/chunk/tokens.js.map +1 -1
  8. package/dist/cjs/chunk/version.js.map +1 -1
  9. package/dist/cjs/cli/build.js.map +1 -1
  10. package/dist/cjs/cli/constants.d.cts +2 -0
  11. package/dist/cjs/cli/constants.d.ts +2 -0
  12. package/dist/cjs/cli/constants.js +21 -0
  13. package/dist/cjs/cli/constants.js.map +1 -0
  14. package/dist/cjs/cli/download.js.map +1 -1
  15. package/dist/cjs/cli/index.js.map +1 -1
  16. package/dist/cjs/cli/init.js.map +1 -1
  17. package/dist/cjs/cli/map.js.map +1 -1
  18. package/dist/cjs/cli/named.js +2 -1
  19. package/dist/cjs/cli/named.js.map +1 -1
  20. package/dist/cjs/cli/path.js.map +1 -1
  21. package/dist/cjs/cli/peek.js.map +1 -1
  22. package/dist/cjs/cli/related.js.map +1 -1
  23. package/dist/cjs/cli/search.js.map +1 -1
  24. package/dist/cjs/cli/shared.js +5 -4
  25. package/dist/cjs/cli/shared.js.map +1 -1
  26. package/dist/cjs/cli/sql.js.map +1 -1
  27. package/dist/cjs/cli/status.js.map +1 -1
  28. package/dist/cjs/cli/watch.js.map +1 -1
  29. package/dist/cjs/cli.js +10 -9
  30. package/dist/cjs/cli.js.map +1 -1
  31. package/dist/cjs/commands/index.js.map +1 -1
  32. package/dist/cjs/commands/map.js.map +1 -1
  33. package/dist/cjs/commands/path.js.map +1 -1
  34. package/dist/cjs/commands/peek.js.map +1 -1
  35. package/dist/cjs/commands/related.js.map +1 -1
  36. package/dist/cjs/commands/scope.js.map +1 -1
  37. package/dist/cjs/commands/search.js.map +1 -1
  38. package/dist/cjs/commands/signals.js.map +1 -1
  39. package/dist/cjs/commands/snapshot.js.map +1 -1
  40. package/dist/cjs/commands/status.js.map +1 -1
  41. package/dist/cjs/config/access.js.map +1 -1
  42. package/dist/cjs/config/index.js.map +1 -1
  43. package/dist/cjs/config/load.js.map +1 -1
  44. package/dist/cjs/config/resolve.js.map +1 -1
  45. package/dist/cjs/config/signals.js.map +1 -1
  46. package/dist/cjs/config/types.js.map +1 -1
  47. package/dist/cjs/config/validate.js.map +1 -1
  48. package/dist/cjs/embed/cohere.js.map +1 -1
  49. package/dist/cjs/embed/distribution.js.map +1 -1
  50. package/dist/cjs/embed/endpoint.js.map +1 -1
  51. package/dist/cjs/embed/handoff.js.map +1 -1
  52. package/dist/cjs/embed/http.js.map +1 -1
  53. package/dist/cjs/embed/identity.js.map +1 -1
  54. package/dist/cjs/embed/langfit.js.map +1 -1
  55. package/dist/cjs/embed/languages.js.map +1 -1
  56. package/dist/cjs/embed/openai.js.map +1 -1
  57. package/dist/cjs/embed/query.js.map +1 -1
  58. package/dist/cjs/embed/registry.js.map +1 -1
  59. package/dist/cjs/embed/static.js.map +1 -1
  60. package/dist/cjs/embed/store.js.map +1 -1
  61. package/dist/cjs/embed/types.js.map +1 -1
  62. package/dist/cjs/errors.js.map +1 -1
  63. package/dist/cjs/features/embed.js.map +1 -1
  64. package/dist/cjs/features/fences.js.map +1 -1
  65. package/dist/cjs/features/index.js.map +1 -1
  66. package/dist/cjs/features/links.js.map +1 -1
  67. package/dist/cjs/features/rank.js.map +1 -1
  68. package/dist/cjs/features/sections.js.map +1 -1
  69. package/dist/cjs/features/tags.js.map +1 -1
  70. package/dist/cjs/graph/graph.js.map +1 -1
  71. package/dist/cjs/graph/traverse.js.map +1 -1
  72. package/dist/cjs/index.js.map +1 -1
  73. package/dist/cjs/lib/atomic-write.js.map +1 -1
  74. package/dist/cjs/lib/guarded-tick.js.map +1 -1
  75. package/dist/cjs/lib/serial-query.js.map +1 -1
  76. package/dist/cjs/lib/watch-notification.js.map +1 -1
  77. package/dist/cjs/lib/worker-file.js.map +1 -1
  78. package/dist/cjs/output/column-hint.js.map +1 -1
  79. package/dist/cjs/output/output.js.map +1 -1
  80. package/dist/cjs/output/progress.js.map +1 -1
  81. package/dist/cjs/output/search-error.js.map +1 -1
  82. package/dist/cjs/scan/frontmatter.js.map +1 -1
  83. package/dist/cjs/scan/index.js.map +1 -1
  84. package/dist/cjs/scan/list.js.map +1 -1
  85. package/dist/cjs/scan/pool.js.map +1 -1
  86. package/dist/cjs/scan/reparse.js.map +1 -1
  87. package/dist/cjs/scan/worker-error.js.map +1 -1
  88. package/dist/cjs/store/batch.js.map +1 -1
  89. package/dist/cjs/store/builder.js.map +1 -1
  90. package/dist/cjs/store/cache.js.map +1 -1
  91. package/dist/cjs/store/duckdb/batch.js.map +1 -1
  92. package/dist/cjs/store/duckdb/connection.js.map +1 -1
  93. package/dist/cjs/store/duckdb/engine.d.cts +11 -0
  94. package/dist/cjs/store/duckdb/engine.d.ts +11 -0
  95. package/dist/cjs/store/duckdb/engine.js +193 -0
  96. package/dist/cjs/store/duckdb/engine.js.map +1 -0
  97. package/dist/cjs/store/duckdb/fieldStats.js.map +1 -1
  98. package/dist/cjs/store/duckdb/lexical.d.cts +1 -6
  99. package/dist/cjs/store/duckdb/lexical.d.ts +1 -6
  100. package/dist/cjs/store/duckdb/lexical.js +48 -45
  101. package/dist/cjs/store/duckdb/lexical.js.map +1 -1
  102. package/dist/cjs/store/duckdb/native.d.cts +5 -3
  103. package/dist/cjs/store/duckdb/native.d.ts +5 -3
  104. package/dist/cjs/store/duckdb/native.js +157 -18
  105. package/dist/cjs/store/duckdb/native.js.map +1 -1
  106. package/dist/cjs/store/duckdb/open.js +151 -3
  107. package/dist/cjs/store/duckdb/open.js.map +1 -1
  108. package/dist/cjs/store/duckdb/ordered-bm25.d.cts +3 -16
  109. package/dist/cjs/store/duckdb/ordered-bm25.d.ts +3 -16
  110. package/dist/cjs/store/duckdb/ordered-bm25.js +24 -80
  111. package/dist/cjs/store/duckdb/ordered-bm25.js.map +1 -1
  112. package/dist/cjs/store/duckdb/reconcile.js.map +1 -1
  113. package/dist/cjs/store/duckdb/sql-functions.js.map +1 -1
  114. package/dist/cjs/store/duckdb/store.js.map +1 -1
  115. package/dist/cjs/store/duckdb/vectors.js.map +1 -1
  116. package/dist/cjs/store/embed-scope.js.map +1 -1
  117. package/dist/cjs/store/engine.d.cts +28 -0
  118. package/dist/cjs/store/engine.d.ts +28 -0
  119. package/dist/cjs/store/engine.js +362 -0
  120. package/dist/cjs/store/engine.js.map +1 -0
  121. package/dist/cjs/store/feature-scope.js.map +1 -1
  122. package/dist/cjs/store/index.js.map +1 -1
  123. package/dist/cjs/store/lock-wait.js.map +1 -1
  124. package/dist/cjs/store/native.d.cts +8 -5
  125. package/dist/cjs/store/native.d.ts +8 -5
  126. package/dist/cjs/store/native.js +78 -73
  127. package/dist/cjs/store/native.js.map +1 -1
  128. package/dist/cjs/store/open.js +100 -40
  129. package/dist/cjs/store/open.js.map +1 -1
  130. package/dist/cjs/store/preset-scope.js.map +1 -1
  131. package/dist/cjs/store/readiness.js.map +1 -1
  132. package/dist/cjs/store/reconcile.js.map +1 -1
  133. package/dist/cjs/store/shared.js.map +1 -1
  134. package/dist/cjs/store/signature.js.map +1 -1
  135. package/dist/cjs/store/sql-functions.js.map +1 -1
  136. package/dist/cjs/store/sqlite/connection.js.map +1 -1
  137. package/dist/cjs/store/sqlite/engine.d.cts +12 -0
  138. package/dist/cjs/store/sqlite/engine.d.ts +12 -0
  139. package/dist/cjs/store/sqlite/engine.js +53 -0
  140. package/dist/cjs/store/sqlite/engine.js.map +1 -0
  141. package/dist/cjs/store/sqlite/fieldStats.js.map +1 -1
  142. package/dist/cjs/store/sqlite/lexical.js +3 -4
  143. package/dist/cjs/store/sqlite/lexical.js.map +1 -1
  144. package/dist/cjs/store/sqlite/open.js +119 -6
  145. package/dist/cjs/store/sqlite/open.js.map +1 -1
  146. package/dist/cjs/store/sqlite/reconcile.js.map +1 -1
  147. package/dist/cjs/store/sqlite/sql-functions.js.map +1 -1
  148. package/dist/cjs/store/sqlite/store.js.map +1 -1
  149. package/dist/cjs/store/sqlite/vectors.js.map +1 -1
  150. package/dist/cjs/store/stages.js.map +1 -1
  151. package/dist/cjs/store/transaction.js.map +1 -1
  152. package/dist/cjs/store/turso/connection.js.map +1 -1
  153. package/dist/cjs/store/turso/engine.d.cts +9 -0
  154. package/dist/cjs/store/turso/engine.d.ts +9 -0
  155. package/dist/cjs/store/turso/engine.js +189 -0
  156. package/dist/cjs/store/turso/engine.js.map +1 -0
  157. package/dist/cjs/store/turso/fieldStats.js.map +1 -1
  158. package/dist/cjs/store/turso/lexical-text.js.map +1 -1
  159. package/dist/cjs/store/turso/lexical.js +16 -11
  160. package/dist/cjs/store/turso/lexical.js.map +1 -1
  161. package/dist/cjs/store/turso/native.d.cts +5 -1
  162. package/dist/cjs/store/turso/native.d.ts +5 -1
  163. package/dist/cjs/store/turso/native.js +157 -8
  164. package/dist/cjs/store/turso/native.js.map +1 -1
  165. package/dist/cjs/store/turso/open.js +172 -27
  166. package/dist/cjs/store/turso/open.js.map +1 -1
  167. package/dist/cjs/store/turso/reconcile.d.cts +0 -1
  168. package/dist/cjs/store/turso/reconcile.d.ts +0 -1
  169. package/dist/cjs/store/turso/reconcile.js +22 -23
  170. package/dist/cjs/store/turso/reconcile.js.map +1 -1
  171. package/dist/cjs/store/turso/sql-functions.js.map +1 -1
  172. package/dist/cjs/store/turso/store.js.map +1 -1
  173. package/dist/cjs/store/turso/vectors.js.map +1 -1
  174. package/dist/cjs/store/types.d.cts +2 -0
  175. package/dist/cjs/store/types.d.ts +2 -0
  176. package/dist/cjs/store/types.js.map +1 -1
  177. package/dist/cjs/store/vectors.js.map +1 -1
  178. package/dist/cjs/text/segment.js.map +1 -1
  179. package/dist/cjs/text/strip.js.map +1 -1
  180. package/dist/cjs/watch-claim.js.map +1 -1
  181. package/dist/cjs/watch.js.map +1 -1
  182. package/dist/cjs/workers/parse.js.map +1 -1
  183. package/dist/cjs/workers/watch-heartbeat.js.map +1 -1
  184. package/dist/esm/chunk/extract.js.map +1 -1
  185. package/dist/esm/chunk/group.js.map +1 -1
  186. package/dist/esm/chunk/index.js.map +1 -1
  187. package/dist/esm/chunk/parse.js.map +1 -1
  188. package/dist/esm/chunk/parser.js.map +1 -1
  189. package/dist/esm/chunk/tokens.js.map +1 -1
  190. package/dist/esm/chunk/types.js.map +1 -1
  191. package/dist/esm/chunk/version.js.map +1 -1
  192. package/dist/esm/cli/build.js.map +1 -1
  193. package/dist/esm/cli/constants.d.ts +2 -0
  194. package/dist/esm/cli/constants.js +2 -0
  195. package/dist/esm/cli/constants.js.map +1 -0
  196. package/dist/esm/cli/download.js.map +1 -1
  197. package/dist/esm/cli/index.js.map +1 -1
  198. package/dist/esm/cli/init.js.map +1 -1
  199. package/dist/esm/cli/map.js.map +1 -1
  200. package/dist/esm/cli/named.js +2 -1
  201. package/dist/esm/cli/named.js.map +1 -1
  202. package/dist/esm/cli/path.js.map +1 -1
  203. package/dist/esm/cli/peek.js.map +1 -1
  204. package/dist/esm/cli/related.js.map +1 -1
  205. package/dist/esm/cli/search.js.map +1 -1
  206. package/dist/esm/cli/shared.js +6 -5
  207. package/dist/esm/cli/shared.js.map +1 -1
  208. package/dist/esm/cli/sql.js.map +1 -1
  209. package/dist/esm/cli/status.js.map +1 -1
  210. package/dist/esm/cli/types.js.map +1 -1
  211. package/dist/esm/cli/watch.js.map +1 -1
  212. package/dist/esm/cli.js +10 -9
  213. package/dist/esm/cli.js.map +1 -1
  214. package/dist/esm/commands/index.js.map +1 -1
  215. package/dist/esm/commands/map.js.map +1 -1
  216. package/dist/esm/commands/path.js.map +1 -1
  217. package/dist/esm/commands/peek.js.map +1 -1
  218. package/dist/esm/commands/related.js.map +1 -1
  219. package/dist/esm/commands/scope.js.map +1 -1
  220. package/dist/esm/commands/search.js.map +1 -1
  221. package/dist/esm/commands/signals.js.map +1 -1
  222. package/dist/esm/commands/snapshot.js.map +1 -1
  223. package/dist/esm/commands/status.js.map +1 -1
  224. package/dist/esm/config/access.js.map +1 -1
  225. package/dist/esm/config/index.js.map +1 -1
  226. package/dist/esm/config/load.js.map +1 -1
  227. package/dist/esm/config/resolve.js.map +1 -1
  228. package/dist/esm/config/signals.js.map +1 -1
  229. package/dist/esm/config/types.js.map +1 -1
  230. package/dist/esm/config/validate.js.map +1 -1
  231. package/dist/esm/embed/cohere.js.map +1 -1
  232. package/dist/esm/embed/distribution.js.map +1 -1
  233. package/dist/esm/embed/endpoint.js.map +1 -1
  234. package/dist/esm/embed/handoff.js.map +1 -1
  235. package/dist/esm/embed/http.js.map +1 -1
  236. package/dist/esm/embed/identity.js.map +1 -1
  237. package/dist/esm/embed/langfit.js.map +1 -1
  238. package/dist/esm/embed/languages.js.map +1 -1
  239. package/dist/esm/embed/openai.js.map +1 -1
  240. package/dist/esm/embed/query.js +1 -1
  241. package/dist/esm/embed/query.js.map +1 -1
  242. package/dist/esm/embed/registry.js.map +1 -1
  243. package/dist/esm/embed/static.js.map +1 -1
  244. package/dist/esm/embed/store.js.map +1 -1
  245. package/dist/esm/embed/types.js.map +1 -1
  246. package/dist/esm/errors.js.map +1 -1
  247. package/dist/esm/features/embed.js.map +1 -1
  248. package/dist/esm/features/fences.js.map +1 -1
  249. package/dist/esm/features/index.js.map +1 -1
  250. package/dist/esm/features/links.js.map +1 -1
  251. package/dist/esm/features/rank.js.map +1 -1
  252. package/dist/esm/features/sections.js.map +1 -1
  253. package/dist/esm/features/tags.js.map +1 -1
  254. package/dist/esm/features/types.js.map +1 -1
  255. package/dist/esm/graph/graph.js.map +1 -1
  256. package/dist/esm/graph/traverse.js.map +1 -1
  257. package/dist/esm/index.js.map +1 -1
  258. package/dist/esm/lib/atomic-write.js.map +1 -1
  259. package/dist/esm/lib/guarded-tick.js.map +1 -1
  260. package/dist/esm/lib/serial-query.js.map +1 -1
  261. package/dist/esm/lib/watch-notification.js.map +1 -1
  262. package/dist/esm/lib/worker-file.js.map +1 -1
  263. package/dist/esm/output/column-hint.js.map +1 -1
  264. package/dist/esm/output/output.js.map +1 -1
  265. package/dist/esm/output/progress.js.map +1 -1
  266. package/dist/esm/output/search-error.js.map +1 -1
  267. package/dist/esm/scan/frontmatter.js.map +1 -1
  268. package/dist/esm/scan/index.js.map +1 -1
  269. package/dist/esm/scan/list.js.map +1 -1
  270. package/dist/esm/scan/pool.js.map +1 -1
  271. package/dist/esm/scan/reparse.js.map +1 -1
  272. package/dist/esm/scan/worker-error.js.map +1 -1
  273. package/dist/esm/store/batch.js.map +1 -1
  274. package/dist/esm/store/builder.js.map +1 -1
  275. package/dist/esm/store/cache.js.map +1 -1
  276. package/dist/esm/store/duckdb/batch.js.map +1 -1
  277. package/dist/esm/store/duckdb/connection.js.map +1 -1
  278. package/dist/esm/store/duckdb/engine.d.ts +11 -0
  279. package/dist/esm/store/duckdb/engine.js +18 -0
  280. package/dist/esm/store/duckdb/engine.js.map +1 -0
  281. package/dist/esm/store/duckdb/fieldStats.js.map +1 -1
  282. package/dist/esm/store/duckdb/lexical.d.ts +1 -6
  283. package/dist/esm/store/duckdb/lexical.js +16 -20
  284. package/dist/esm/store/duckdb/lexical.js.map +1 -1
  285. package/dist/esm/store/duckdb/native.d.ts +5 -3
  286. package/dist/esm/store/duckdb/native.js +16 -14
  287. package/dist/esm/store/duckdb/native.js.map +1 -1
  288. package/dist/esm/store/duckdb/open.js +40 -2
  289. package/dist/esm/store/duckdb/open.js.map +1 -1
  290. package/dist/esm/store/duckdb/ordered-bm25.d.ts +3 -16
  291. package/dist/esm/store/duckdb/ordered-bm25.js +14 -55
  292. package/dist/esm/store/duckdb/ordered-bm25.js.map +1 -1
  293. package/dist/esm/store/duckdb/reconcile.js.map +1 -1
  294. package/dist/esm/store/duckdb/sql-functions.js.map +1 -1
  295. package/dist/esm/store/duckdb/store.js.map +1 -1
  296. package/dist/esm/store/duckdb/vectors.js.map +1 -1
  297. package/dist/esm/store/embed-scope.js.map +1 -1
  298. package/dist/esm/store/engine.d.ts +28 -0
  299. package/dist/esm/store/engine.js +85 -0
  300. package/dist/esm/store/engine.js.map +1 -0
  301. package/dist/esm/store/feature-scope.js.map +1 -1
  302. package/dist/esm/store/index.js.map +1 -1
  303. package/dist/esm/store/lock-wait.js.map +1 -1
  304. package/dist/esm/store/native.d.ts +8 -5
  305. package/dist/esm/store/native.js +59 -57
  306. package/dist/esm/store/native.js.map +1 -1
  307. package/dist/esm/store/open.js +24 -7
  308. package/dist/esm/store/open.js.map +1 -1
  309. package/dist/esm/store/preset-scope.js.map +1 -1
  310. package/dist/esm/store/readiness.js.map +1 -1
  311. package/dist/esm/store/reconcile.js.map +1 -1
  312. package/dist/esm/store/shared.js.map +1 -1
  313. package/dist/esm/store/signature.js.map +1 -1
  314. package/dist/esm/store/sql-functions.js.map +1 -1
  315. package/dist/esm/store/sqlite/connection.js.map +1 -1
  316. package/dist/esm/store/sqlite/engine.d.ts +12 -0
  317. package/dist/esm/store/sqlite/engine.js +16 -0
  318. package/dist/esm/store/sqlite/engine.js.map +1 -0
  319. package/dist/esm/store/sqlite/fieldStats.js.map +1 -1
  320. package/dist/esm/store/sqlite/lexical.js +2 -3
  321. package/dist/esm/store/sqlite/lexical.js.map +1 -1
  322. package/dist/esm/store/sqlite/open.js +38 -7
  323. package/dist/esm/store/sqlite/open.js.map +1 -1
  324. package/dist/esm/store/sqlite/reconcile.js.map +1 -1
  325. package/dist/esm/store/sqlite/sql-functions.js.map +1 -1
  326. package/dist/esm/store/sqlite/store.js.map +1 -1
  327. package/dist/esm/store/sqlite/vectors.js.map +1 -1
  328. package/dist/esm/store/stages.js.map +1 -1
  329. package/dist/esm/store/transaction.js.map +1 -1
  330. package/dist/esm/store/turso/connection.js.map +1 -1
  331. package/dist/esm/store/turso/engine.d.ts +9 -0
  332. package/dist/esm/store/turso/engine.js +14 -0
  333. package/dist/esm/store/turso/engine.js.map +1 -0
  334. package/dist/esm/store/turso/fieldStats.js.map +1 -1
  335. package/dist/esm/store/turso/lexical-text.js.map +1 -1
  336. package/dist/esm/store/turso/lexical.js +9 -9
  337. package/dist/esm/store/turso/lexical.js.map +1 -1
  338. package/dist/esm/store/turso/native.d.ts +5 -1
  339. package/dist/esm/store/turso/native.js +16 -10
  340. package/dist/esm/store/turso/native.js.map +1 -1
  341. package/dist/esm/store/turso/open.js +44 -3
  342. package/dist/esm/store/turso/open.js.map +1 -1
  343. package/dist/esm/store/turso/reconcile.d.ts +0 -1
  344. package/dist/esm/store/turso/reconcile.js +3 -8
  345. package/dist/esm/store/turso/reconcile.js.map +1 -1
  346. package/dist/esm/store/turso/sql-functions.js.map +1 -1
  347. package/dist/esm/store/turso/store.js.map +1 -1
  348. package/dist/esm/store/turso/vectors.js.map +1 -1
  349. package/dist/esm/store/types.d.ts +2 -0
  350. package/dist/esm/store/types.js.map +1 -1
  351. package/dist/esm/store/vectors.js.map +1 -1
  352. package/dist/esm/text/segment.js.map +1 -1
  353. package/dist/esm/text/strip.js.map +1 -1
  354. package/dist/esm/watch-claim.js.map +1 -1
  355. package/dist/esm/watch.js.map +1 -1
  356. package/dist/esm/workers/parse.js.map +1 -1
  357. package/dist/esm/workers/watch-heartbeat.js.map +1 -1
  358. package/package.json +21 -6
  359. package/skills/sense/SKILL.md +1 -1
  360. package/skills/sense/references/stores/duckdb.md +1 -1
  361. package/skills/sense/references/stores/sqlite.md +1 -1
  362. package/skills/sense/references/stores/turso.md +1 -1
  363. package/skills/sense-setup/references/stores/duckdb.md +1 -1
  364. package/skills/sense-setup/references/stores/sqlite.md +1 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/store/open.ts"],"sourcesContent":["import { channel } from 'node:diagnostics_channel';\nimport { existsSync, mkdirSync } from 'node:fs';\nimport { join } from 'node:path';\nimport type { ResolvedConfig } from '../config/index.ts';\nimport { anyPresetEmbeds, featureSignature, STATE_DIR } from '../config/index.ts';\nimport { rekeyChunkText } from '../embed/handoff.ts';\nimport { embedPending } from '../embed/query.ts';\nimport type { EmbedCallOptions } from '../embed/types.ts';\nimport { SenseError } from '../errors.ts';\nimport { FEATURES } from '../features/index.ts';\nimport { createBuilder } from './builder.ts';\nimport { clearCache } from './cache.ts';\nimport { lockWaitBudgetMs } from './lock-wait.ts';\nimport { CORE_READY_META_KEY, FEATURE_SIGNATURE_META_KEY, isCoreReady, isPublishedFeatureSignature } from './readiness.ts';\nimport { getMeta } from './shared.ts';\nimport { changedSignatureKeys, embedIdentityAdopted } from './signature.ts';\nimport type { Stages } from './stages.ts';\nimport { stageRecorder } from './stages.ts';\nimport { withTransaction } from './transaction.ts';\nimport type { Connection, OpenDialect, Store } from './types.ts';\n\nexport type BuildRequirement = 'core' | 'lexical' | 'vectors';\n\n/** Options for the root `open(config, options)` API. */\nexport interface OpenOptions {\n /** Prepares configured capabilities by default; `false` opens compatible published state without repair. */\n build?: boolean;\n /** Cancels supported provider I/O and stops between phases after active native work finishes. */\n signal?: AbortSignal;\n}\n\nexport interface InternalOpenOptions extends OpenOptions {\n requirements?: ReadonlySet<BuildRequirement>;\n}\n\nexport interface OpenResult {\n store: Store;\n cfg: ResolvedConfig;\n dbPath: string;\n parsed: number;\n warnings: string[];\n stages: Stages;\n}\n\ninterface ConnectResult<Handle> {\n handle: Handle;\n conn: Connection;\n cfg: ResolvedConfig;\n dbPath: string;\n parsed: number;\n warnings: string[];\n stages: Stages;\n observational: boolean;\n}\n\nconst LOCK_POLL_MS = 50;\nconst lockWait = channel('sensemaking.store.lock-wait');\n\nfunction notReady(reason: string): SenseError {\n return new SenseError('INDEX_NOT_READY', `${reason}; run \"sense build\" or call build(config) before opening with { build: false }`);\n}\n\nfunction normaliseConfig(cfg: ResolvedConfig): ResolvedConfig {\n // `baseDir` was the original public open() input. Keep direct API callers working while\n // making the two ownership paths explicit for every internal operation.\n if (!cfg.rootDir) {\n if (!cfg.baseDir) throw new SenseError('CONFIG_INVALID', 'open requires rootDir (or legacy baseDir)');\n cfg.rootDir = cfg.baseDir;\n }\n if (!cfg.configDir) cfg.configDir = cfg.rootDir;\n return cfg;\n}\n\nfunction cachePath<Handle>(cfg: ResolvedConfig, dialect: OpenDialect<Handle>): string {\n return join(cfg.configDir ?? cfg.baseDir, STATE_DIR, dialect.filename);\n}\n\nasync function connectUnlocked<Handle>(dbPath: string, cfg: ResolvedConfig, configDir: string, dialect: OpenDialect<Handle>, options: { existingOnly: boolean; observational: boolean }): Promise<{ handle: Handle; conn: Connection }> {\n const budgetMs = lockWaitBudgetMs(configDir);\n const deadline = Date.now() + budgetMs;\n for (;;) {\n try {\n return await dialect.connect(dbPath, cfg, options);\n } catch (err) {\n if (options.existingOnly && !existsSync(dbPath)) {\n throw notReady(`the derived index does not exist at ${dbPath}`);\n }\n if (!dialect.isLocked?.(err as Error)) throw err;\n if (lockWait.hasSubscribers) lockWait.publish({ store: cfg.store, dbPath });\n if (Date.now() >= deadline) {\n throw new SenseError('STORE_BUSY', `another sense process is using this tree's ${cfg.store} cache (${dbPath}) and did not release it within ${Math.round(budgetMs / 1000)}s; wait for that command to finish, or set \"store\" to \"sqlite\" in sense.config.json, which serves concurrent commands`);\n }\n await new Promise((resolve) => setTimeout(resolve, LOCK_POLL_MS));\n }\n }\n}\n\nasync function assertCoreSchema(conn: Connection): Promise<void> {\n for (const table of ['frontmatter', 'content', 'preset_files', 'indexed_sources']) {\n await (await conn.prepare(`SELECT 1 FROM ${table} LIMIT 0`)).all();\n }\n}\n\nasync function connectExisting<Handle>(cfg: ResolvedConfig, dialect: OpenDialect<Handle>, requirements: ReadonlySet<BuildRequirement>): Promise<ConnectResult<Handle>> {\n const configDir = cfg.configDir ?? cfg.baseDir;\n const dbPath = cachePath(cfg, dialect);\n if (!existsSync(dbPath)) throw notReady(`the derived index does not exist at ${dbPath}`);\n\n const { handle, conn } = await connectUnlocked(dbPath, cfg, configDir, dialect, { existingOnly: true, observational: true });\n try {\n let state: { version: string | null; features: string | null; ready: string | null };\n try {\n state = await withTransaction(conn, async () => {\n const version = await getMeta(conn, 'schema_version');\n const features = await getMeta(conn, FEATURE_SIGNATURE_META_KEY);\n const ready = await getMeta(conn, CORE_READY_META_KEY);\n await assertCoreSchema(conn);\n return { version, features, ready };\n });\n } catch {\n if (!existsSync(dbPath)) throw notReady(`the derived index was deleted while opening ${dbPath}`);\n throw notReady(`the derived index at ${dbPath} has no compatible schema`);\n }\n\n if (state.version !== dialect.schemaVersion) {\n throw notReady(`the derived index at ${dbPath} uses schema ${state.version ?? 'unknown'}, but this sense version requires ${dialect.schemaVersion}`);\n }\n const wantFeatures = featureSignature(cfg, FEATURES);\n if (!isPublishedFeatureSignature(state.features, wantFeatures)) {\n throw notReady(`the derived index at ${dbPath} was built for different configuration features`);\n }\n if (!isCoreReady(state.ready)) {\n throw notReady(`the derived index at ${dbPath} has an incomplete core build`);\n }\n if (requirements.has('lexical')) {\n await dialect.assertLexicalReady?.(conn);\n }\n if (!existsSync(dbPath)) throw notReady(`the derived index was deleted while opening ${dbPath}`);\n\n return {\n handle,\n conn,\n cfg,\n dbPath,\n parsed: 0,\n warnings: [],\n stages: stageRecorder().take(0, 0),\n observational: true,\n };\n } catch (err) {\n await dialect.close(handle, { observational: true });\n throw err;\n }\n}\n\nasync function connectForBuild<Handle>(cfg: ResolvedConfig, dialect: OpenDialect<Handle>, requirements: ReadonlySet<BuildRequirement>, cacheReplaced = false): Promise<ConnectResult<Handle>> {\n const configDir = cfg.configDir ?? cfg.baseDir;\n const stateDir = join(configDir, STATE_DIR);\n mkdirSync(stateDir, { recursive: true });\n const dbPath = join(stateDir, dialect.filename);\n\n const { handle, conn } = await connectUnlocked(dbPath, cfg, configDir, dialect, { existingOnly: false, observational: false });\n let closed = false;\n let builder: ReturnType<typeof createBuilder> | undefined;\n try {\n await conn.exec('CREATE TABLE IF NOT EXISTS meta (key TEXT PRIMARY KEY, value TEXT)');\n\n const version = await getMeta(conn, 'schema_version');\n if (version !== null && version !== dialect.schemaVersion) {\n console.error('sense: cache format changed (new sensemaking version); rebuilding the index');\n await dialect.close(handle);\n closed = true;\n if (cacheReplaced) throw notReady(`the derived index at ${dbPath} still reports incompatible schema ${version} after cache replacement`);\n clearCache(cfg);\n return connectForBuild(cfg, dialect, requirements, true);\n }\n\n if (version === null) await dialect.ensureCoreSchema(handle, conn);\n await dialect.prepareConnection?.(handle, conn, cfg);\n\n if (dialect.setDerivedBusyTimeout) {\n const recordedMaxMs = Number((await getMeta(conn, 'reconcile_max_ms')) ?? '0');\n await dialect.setDerivedBusyTimeout(handle, conn, Math.min(Math.max(30000, 3 * recordedMaxMs), 600_000));\n }\n\n builder = createBuilder(conn, cfg, dialect.reconcileDialect, (snapshotCfg) => dialect.ensureFeatureSchema(handle, conn, snapshotCfg));\n const { parsed, warnings, stages, messages } = await builder.build();\n for (const message of messages) console.error(message);\n\n // Lexical preparation is a separate capability stage. A failure leaves core usable and the\n // dialect's own lexical marker stale, so unrelated map/peek/path/sql commands stay available.\n if (requirements.has('lexical')) {\n await dialect.prepareLexical?.(conn);\n }\n\n await builder.close();\n return { handle, conn, cfg, dbPath, parsed, warnings, stages, observational: false };\n } catch (err) {\n const cleanupTasks: Array<Promise<void>> = [];\n if (builder) {\n const builderToClose = builder;\n cleanupTasks.push(Promise.resolve().then(() => builderToClose.close()));\n }\n if (!closed) cleanupTasks.push(Promise.resolve().then(() => dialect.close(handle)));\n const cleanup = await Promise.allSettled(cleanupTasks);\n const cleanupErrors = cleanup.filter((result): result is PromiseRejectedResult => result.status === 'rejected').map((result) => result.reason);\n if (cleanupErrors.length > 0) throw new AggregateError([err, ...cleanupErrors], 'opening the derived index failed and cleanup also failed');\n throw err;\n }\n}\n\n// A static provider can resolve its identity while embedding. Publish it only after vectors\n// succeed and only when the durable signature still matches the prepared generation.\nexport async function prepareDocumentEmbeddings(store: Store, cfg: ResolvedConfig, allowed?: ReadonlySet<string>, options: EmbedCallOptions = {}): Promise<void> {\n options.signal?.throwIfAborted();\n const preparedSignature = await getMeta(store, FEATURE_SIGNATURE_META_KEY);\n options.signal?.throwIfAborted();\n await embedPending(store, cfg, allowed, preparedSignature, options);\n options.signal?.throwIfAborted();\n const actualSignature = featureSignature(cfg, FEATURES);\n if (preparedSignature === actualSignature) return;\n\n const changedKeys = changedSignatureKeys(preparedSignature ?? '', actualSignature);\n if (preparedSignature === null || changedKeys.size !== 1 || !changedKeys.has('embed') || !embedIdentityAdopted(preparedSignature, actualSignature)) {\n throw notReady('the index configuration changed while vectors were being prepared');\n }\n\n await store.transaction(async () => {\n options.signal?.throwIfAborted();\n const update = await store.prepare('UPDATE meta SET value = ? WHERE key = ? AND value = ?');\n options.signal?.throwIfAborted();\n const result = await update.run(actualSignature, FEATURE_SIGNATURE_META_KEY, preparedSignature);\n options.signal?.throwIfAborted();\n if (Number(result.changes) !== 1) throw notReady('another build changed the index configuration while vectors were being prepared');\n });\n}\n\nexport async function openWithDialect<Handle>(input: ResolvedConfig, dialect: OpenDialect<Handle>, options: InternalOpenOptions = {}): Promise<OpenResult> {\n options.signal?.throwIfAborted();\n const cfg = normaliseConfig(input);\n const buildEnabled = options.build !== false;\n const defaultRequirements = new Set<BuildRequirement>(buildEnabled ? ['core', 'lexical'] : ['core']);\n if (buildEnabled && anyPresetEmbeds(cfg)) defaultRequirements.add('vectors');\n const requirements = options.requirements ?? defaultRequirements;\n const connected = buildEnabled ? await connectForBuild(cfg, dialect, requirements) : await connectExisting(cfg, dialect, requirements);\n let store: Store | undefined;\n try {\n store = dialect.createStore(connected.handle, connected.conn, connected.cfg, { observational: connected.observational });\n rekeyChunkText(connected.conn, store);\n if (requirements.has('vectors') && buildEnabled) await prepareDocumentEmbeddings(store, connected.cfg, undefined, { signal: options.signal });\n options.signal?.throwIfAborted();\n return {\n store,\n cfg: connected.cfg,\n dbPath: connected.dbPath,\n parsed: connected.parsed,\n warnings: connected.warnings,\n stages: connected.stages,\n };\n } catch (err) {\n const cleanup = await Promise.allSettled([Promise.resolve().then(() => (store ? store.close() : dialect.close(connected.handle, { observational: connected.observational })))]);\n if (cleanup[0].status === 'rejected') throw new AggregateError([err, cleanup[0].reason], 'opening the derived index failed and cleanup also failed');\n throw err;\n }\n}\n\nexport async function docCount(store: Store): Promise<number> {\n const stmt = await store.prepare('SELECT COUNT(*) AS n FROM frontmatter');\n return ((await stmt.get()) as { n: number }).n;\n}\n"],"names":["docCount","openWithDialect","prepareDocumentEmbeddings","LOCK_POLL_MS","lockWait","channel","notReady","reason","SenseError","normaliseConfig","cfg","rootDir","baseDir","configDir","cachePath","dialect","join","STATE_DIR","filename","connectUnlocked","dbPath","options","budgetMs","deadline","err","lockWaitBudgetMs","Date","now","connect","existingOnly","existsSync","isLocked","hasSubscribers","publish","store","Math","round","Promise","resolve","setTimeout","assertCoreSchema","conn","table","prepare","all","connectExisting","requirements","handle","state","wantFeatures","observational","withTransaction","version","features","ready","getMeta","FEATURE_SIGNATURE_META_KEY","CORE_READY_META_KEY","schemaVersion","featureSignature","FEATURES","isPublishedFeatureSignature","isCoreReady","has","assertLexicalReady","parsed","warnings","stages","stageRecorder","take","close","connectForBuild","cacheReplaced","stateDir","closed","builder","recordedMaxMs","messages","message","cleanupTasks","builderToClose","cleanup","cleanupErrors","mkdirSync","recursive","exec","console","error","clearCache","ensureCoreSchema","prepareConnection","setDerivedBusyTimeout","Number","min","max","createBuilder","reconcileDialect","snapshotCfg","ensureFeatureSchema","build","prepareLexical","push","then","allSettled","filter","result","status","map","length","AggregateError","allowed","preparedSignature","actualSignature","changedKeys","signal","throwIfAborted","embedPending","changedSignatureKeys","size","embedIdentityAdopted","transaction","update","run","changes","input","buildEnabled","defaultRequirements","connected","Set","anyPresetEmbeds","add","createStore","rekeyChunkText","undefined","stmt","get","n"],"mappings":";;;;;;;;;;;QA0QsBA;eAAAA;;QA7BAC;eAAAA;;QAxBAC;eAAAA;;;uCArNE;sBACc;wBACjB;uBAEwC;yBAC9B;uBACF;wBAEF;wBACF;yBACK;uBACH;0BACM;2BACyE;wBAClF;2BACmC;wBAE7B;6BACE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqChC,IAAMC,eAAe;AACrB,IAAMC,WAAWC,IAAAA,gCAAO,EAAC;AAEzB,SAASC,SAASC,MAAc;IAC9B,OAAO,IAAIC,oBAAU,CAAC,mBAAmB,AAAC,GAAS,OAAPD,QAAO;AACrD;AAEA,SAASE,gBAAgBC,GAAmB;IAC1C,wFAAwF;IACxF,wEAAwE;IACxE,IAAI,CAACA,IAAIC,OAAO,EAAE;QAChB,IAAI,CAACD,IAAIE,OAAO,EAAE,MAAM,IAAIJ,oBAAU,CAAC,kBAAkB;QACzDE,IAAIC,OAAO,GAAGD,IAAIE,OAAO;IAC3B;IACA,IAAI,CAACF,IAAIG,SAAS,EAAEH,IAAIG,SAAS,GAAGH,IAAIC,OAAO;IAC/C,OAAOD;AACT;AAEA,SAASI,UAAkBJ,GAAmB,EAAEK,OAA4B;QAC9DL;IAAZ,OAAOM,IAAAA,cAAI,GAACN,iBAAAA,IAAIG,SAAS,cAAbH,4BAAAA,iBAAiBA,IAAIE,OAAO,EAAEK,kBAAS,EAAEF,QAAQG,QAAQ;AACvE;AAEA,SAAeC,gBAAwBC,MAAc,EAAEV,GAAmB,EAAEG,SAAiB,EAAEE,OAA4B,EAAEM,OAA0D;;YAC/KC,UACAC,UAIKC,KAIFT;;;;oBATHO,WAAWG,IAAAA,4BAAgB,EAACZ;oBAC5BU,WAAWG,KAAKC,GAAG,KAAKL;;;;;;;;;oBAGnB;;wBAAMP,QAAQa,OAAO,CAACR,QAAQV,KAAKW;;;oBAA1C;;wBAAO;;;oBACAG;oBACP,IAAIH,QAAQQ,YAAY,IAAI,CAACC,IAAAA,kBAAU,EAACV,SAAS;wBAC/C,MAAMd,SAAS,AAAC,uCAA6C,OAAPc;oBACxD;oBACA,IAAI,GAACL,oBAAAA,QAAQgB,QAAQ,cAAhBhB,wCAAAA,uBAAAA,SAAmBS,OAAe,MAAMA;oBAC7C,IAAIpB,SAAS4B,cAAc,EAAE5B,SAAS6B,OAAO,CAAC;wBAAEC,OAAOxB,IAAIwB,KAAK;wBAAEd,QAAAA;oBAAO;oBACzE,IAAIM,KAAKC,GAAG,MAAMJ,UAAU;wBAC1B,MAAM,IAAIf,oBAAU,CAAC,cAAc,AAAC,8CAAiEY,OAApBV,IAAIwB,KAAK,EAAC,YAAmDC,OAAzCf,QAAO,oCAA8D,OAA5Be,KAAKC,KAAK,CAACd,WAAW,OAAM;oBAC5K;oBACA;;wBAAM,IAAIe,QAAQ,SAACC;mCAAYC,WAAWD,SAASnC;;;;oBAAnD;;;;;;;;;;;;;;;;IAGN;;AAEA,SAAeqC,iBAAiBC,IAAgB;;gBAC1B,OAATC;;;;4BAAS;wBAAC;wBAAe;wBAAW;wBAAgB;;;;+BAA3C;;;;oBAATA,QAAS;oBACX;;wBAAMD,KAAKE,OAAO,CAAC,AAAC,iBAAsB,OAAND,OAAM;;;oBAAjD;;wBAAO,cAAsDE,GAAG;;;oBAAhE;;;;;;;;;;;;;;IAEJ;;AAEA,SAAeC,gBAAwBnC,GAAmB,EAAEK,OAA4B,EAAE+B,YAA2C;;YACjHpC,gBAAZG,WACAO,QAGmB,MAAjB2B,QAAQN,MAEVO,eAe2DA,gBAEzDC,cAQElC,6BAcDS;;;;oBA7CHX,aAAYH,iBAAAA,IAAIG,SAAS,cAAbH,4BAAAA,iBAAiBA,IAAIE,OAAO;oBACxCQ,SAASN,UAAUJ,KAAKK;oBAC9B,IAAI,CAACe,IAAAA,kBAAU,EAACV,SAAS,MAAMd,SAAS,AAAC,uCAA6C,OAAPc;oBAEtD;;wBAAMD,gBAAgBC,QAAQV,KAAKG,WAAWE,SAAS;4BAAEc,cAAc;4BAAMqB,eAAe;wBAAK;;;oBAAjG,OAAA,eAAjBH,SAAiB,KAAjBA,QAAQN,OAAS,KAATA;;;;;;;;;;;;;;;;;oBAIJ;;wBAAMU,IAAAA,8BAAe,EAACV,MAAM;;oCAC5BW,SACAC,UACAC;;;;4CAFU;;gDAAMC,IAAAA,iBAAO,EAACd,MAAM;;;4CAA9BW,UAAU;4CACC;;gDAAMG,IAAAA,iBAAO,EAACd,MAAMe,uCAA0B;;;4CAAzDH,WAAW;4CACH;;gDAAME,IAAAA,iBAAO,EAACd,MAAMgB,gCAAmB;;;4CAA/CH,QAAQ;4CACd;;gDAAMd,iBAAiBC;;;4CAAvB;4CACA;;gDAAO;oDAAEW,SAAAA;oDAASC,UAAAA;oDAAUC,OAAAA;gDAAM;;;;4BACpC;;;;oBANAN,QAAQ;;;;;;;oBAQR,IAAI,CAAClB,IAAAA,kBAAU,EAACV,SAAS,MAAMd,SAAS,AAAC,+CAAqD,OAAPc;oBACvF,MAAMd,SAAS,AAAC,wBAA8B,OAAPc,QAAO;;oBAGhD,IAAI4B,MAAMI,OAAO,KAAKrC,QAAQ2C,aAAa,EAAE;;wBAC3C,MAAMpD,SAAS,AA7HrB,AA6HsB,+BAAuBc,QAAO,iBAA8EL,QAA/DiC,iBAAAA,MAAMI,OAAO,cAAbJ,4BAAAA,iBAAiB,WAAU,sCAA0D,OAAtBjC,QAAQ2C,aAAa;oBACnJ;oBACMT,eAAeU,IAAAA,yBAAgB,EAACjD,KAAKkD,kBAAQ;oBACnD,IAAI,CAACC,IAAAA,wCAA2B,EAACb,MAAMK,QAAQ,EAAEJ,eAAe;wBAC9D,MAAM3C,SAAS,AAAC,wBAA8B,OAAPc,QAAO;oBAChD;oBACA,IAAI,CAAC0C,IAAAA,wBAAW,EAACd,MAAMM,KAAK,GAAG;wBAC7B,MAAMhD,SAAS,AAAC,wBAA8B,OAAPc,QAAO;oBAChD;yBACI0B,aAAaiB,GAAG,CAAC,YAAjBjB;;;;oBACF;;yBAAM/B,8BAAAA,QAAQiD,kBAAkB,cAA1BjD,kDAAAA,iCAAAA,SAA6B0B;;;oBAAnC;;;oBAEF,IAAI,CAACX,IAAAA,kBAAU,EAACV,SAAS,MAAMd,SAAS,AAAC,+CAAqD,OAAPc;oBAEvF;;wBAAO;4BACL2B,QAAAA;4BACAN,MAAAA;4BACA/B,KAAAA;4BACAU,QAAAA;4BACA6C,QAAQ;4BACRC,QAAQ;4BACRC,QAAQC,IAAAA,uBAAa,IAAGC,IAAI,CAAC,GAAG;4BAChCnB,eAAe;wBACjB;;;oBACO1B;oBACP;;wBAAMT,QAAQuD,KAAK,CAACvB,QAAQ;4BAAEG,eAAe;wBAAK;;;oBAAlD;oBACA,MAAM1B;;;;;;;IAEV;;AAEA,SAAe+C,gBAAwB7D,GAAmB,EAAEK,OAA4B,EAAE+B,YAA2C;QAAE0B,gBAAAA,iEAAgB;;YACnI9D,gBAAZG,WACA4D,UAEArD,QAEmB,MAAjB2B,QAAQN,MACZiC,QACAC,SAeI5D,4BAXAqC,SAc0B,OAAxBwB,eAKuC,OAAvCX,QAAQC,UAAUC,QAAQU,UAC7B,2BAAA,mBAAA,gBAAA,WAAA,OAAMC,SAKH/D,yBAKDS,KACDuD,cAEEC,gBAIFC,SACAC;;;;oBAjDFrE,aAAYH,iBAAAA,IAAIG,SAAS,cAAbH,4BAAAA,iBAAiBA,IAAIE,OAAO;oBACxC6D,WAAWzD,IAAAA,cAAI,EAACH,WAAWI,kBAAS;oBAC1CkE,IAAAA,iBAAS,EAACV,UAAU;wBAAEW,WAAW;oBAAK;oBAChChE,SAASJ,IAAAA,cAAI,EAACyD,UAAU1D,QAAQG,QAAQ;oBAErB;;wBAAMC,gBAAgBC,QAAQV,KAAKG,WAAWE,SAAS;4BAAEc,cAAc;4BAAOqB,eAAe;wBAAM;;;oBAAnG,OAAA,eAAjBH,SAAiB,KAAjBA,QAAQN,OAAS,KAATA;oBACZiC,SAAS;;;;;;;;;oBAGX;;wBAAMjC,KAAK4C,IAAI,CAAC;;;oBAAhB;oBAEgB;;wBAAM9B,IAAAA,iBAAO,EAACd,MAAM;;;oBAA9BW,UAAU;yBACZA,CAAAA,YAAY,QAAQA,YAAYrC,QAAQ2C,aAAa,AAAD,GAApDN;;;;oBACFkC,QAAQC,KAAK,CAAC;oBACd;;wBAAMxE,QAAQuD,KAAK,CAACvB;;;oBAApB;oBACA2B,SAAS;oBACT,IAAIF,eAAe,MAAMlE,SAAS,AAAC,wBAAmE8C,OAA5ChC,QAAO,uCAA6C,OAARgC,SAAQ;oBAC9GoC,IAAAA,mBAAU,EAAC9E;oBACX;;wBAAO6D,gBAAgB7D,KAAKK,SAAS+B,cAAc;;;yBAGjDM,CAAAA,YAAY,IAAG,GAAfA;;;;oBAAkB;;wBAAMrC,QAAQ0E,gBAAgB,CAAC1C,QAAQN;;;oBAAvC;;;oBACtB;;yBAAM1B,6BAAAA,QAAQ2E,iBAAiB,cAAzB3E,iDAAAA,gCAAAA,SAA4BgC,QAAQN,MAAM/B;;;oBAAhD;yBAEIK,QAAQ4E,qBAAqB,EAA7B5E;;;;oBAC4B;;wBAAMwC,IAAAA,iBAAO,EAACd,MAAM;;;oBAA5CmC,gBAAgBgB;yBAAQ,QAAA,2BAAA,mBAAA,QAA4C;;oBAC1E;;wBAAM7E,QAAQ4E,qBAAqB,CAAC5C,QAAQN,MAAMN,KAAK0D,GAAG,CAAC1D,KAAK2D,GAAG,CAAC,OAAO,IAAIlB,gBAAgB;;;oBAA/F;;;oBAGFD,UAAUoB,IAAAA,wBAAa,EAACtD,MAAM/B,KAAKK,QAAQiF,gBAAgB,EAAE,SAACC;+BAAgBlF,QAAQmF,mBAAmB,CAACnD,QAAQN,MAAMwD;;oBACzE;;wBAAMtB,QAAQwB,KAAK;;;oBAAnB,QAAA,eAAvClC,SAAuC,MAAvCA,QAAQC,WAA+B,MAA/BA,UAAUC,SAAqB,MAArBA,QAAQU,WAAa,MAAbA;oBAC7B,kCAAA,2BAAA;;wBAAL,IAAK,YAAiBA,+BAAjB,6BAAA,QAAA,yBAAA;4BAAMC,UAAN;4BAA2BQ,QAAQC,KAAK,CAACT;;;wBAAzC;wBAAA;;;iCAAA,6BAAA;gCAAA;;;gCAAA;sCAAA;;;;yBAIDhC,aAAaiB,GAAG,CAAC,YAAjBjB;;;;oBACF;;yBAAM/B,0BAAAA,QAAQqF,cAAc,cAAtBrF,8CAAAA,6BAAAA,SAAyB0B;;;oBAA/B;;;oBAGF;;wBAAMkC,QAAQL,KAAK;;;oBAAnB;oBACA;;wBAAO;4BAAEvB,QAAAA;4BAAQN,MAAAA;4BAAM/B,KAAAA;4BAAKU,QAAAA;4BAAQ6C,QAAAA;4BAAQC,UAAAA;4BAAUC,QAAAA;4BAAQjB,eAAe;wBAAM;;;oBAC5E1B;oBACDuD;oBACN,IAAIJ,SAAS;wBACLK,iBAAiBL;wBACvBI,aAAasB,IAAI,CAAChE,QAAQC,OAAO,GAAGgE,IAAI,CAAC;mCAAMtB,eAAeV,KAAK;;oBACrE;oBACA,IAAI,CAACI,QAAQK,aAAasB,IAAI,CAAChE,QAAQC,OAAO,GAAGgE,IAAI,CAAC;+BAAMvF,QAAQuD,KAAK,CAACvB;;oBAC1D;;wBAAMV,QAAQkE,UAAU,CAACxB;;;oBAAnCE,UAAU;oBACVC,gBAAgBD,QAAQuB,MAAM,CAAC,SAACC;+BAA4CA,OAAOC,MAAM,KAAK;uBAAYC,GAAG,CAAC,SAACF;+BAAWA,OAAOlG,MAAM;;oBAC7I,IAAI2E,cAAc0B,MAAM,GAAG,GAAG,MAAM,IAAIC,eAAe;wBAACrF;sBAAD,OAAM,qBAAG0D,iBAAgB;oBAChF,MAAM1D;;;;;;;IAEV;;AAIO,SAAetB;wCAA0BgC,KAAY,EAAExB,GAAmB,EAAEoG,OAA6B;YAAEzF,SAChHA,iBAEAA,kBAEAA,kBAHM0F,mBAIAC,iBAGAC;;;;;oBAT0G5F,UAAAA,oEAA4B,CAAC;qBAC7IA,kBAAAA,QAAQ6F,MAAM,cAAd7F,sCAAAA,gBAAgB8F,cAAc;oBACJ;;wBAAM5D,IAAAA,iBAAO,EAACrB,OAAOsB,uCAA0B;;;oBAAnEuD,oBAAoB;qBAC1B1F,mBAAAA,QAAQ6F,MAAM,cAAd7F,uCAAAA,iBAAgB8F,cAAc;oBAC9B;;wBAAMC,IAAAA,qBAAY,EAAClF,OAAOxB,KAAKoG,SAASC,mBAAmB1F;;;oBAA3D;qBACAA,mBAAAA,QAAQ6F,MAAM,cAAd7F,uCAAAA,iBAAgB8F,cAAc;oBACxBH,kBAAkBrD,IAAAA,yBAAgB,EAACjD,KAAKkD,kBAAQ;oBACtD,IAAImD,sBAAsBC,iBAAiB;;;oBAErCC,cAAcI,IAAAA,iCAAoB,EAACN,8BAAAA,+BAAAA,oBAAqB,IAAIC;oBAClE,IAAID,sBAAsB,QAAQE,YAAYK,IAAI,KAAK,KAAK,CAACL,YAAYlD,GAAG,CAAC,YAAY,CAACwD,IAAAA,iCAAoB,EAACR,mBAAmBC,kBAAkB;wBAClJ,MAAM1G,SAAS;oBACjB;oBAEA;;wBAAM4B,MAAMsF,WAAW,CAAC;;oCACtBnG,iBAEAA,kBAEAA,kBAHMoG,QAEAhB;;;;6CAHNpF,kBAAAA,QAAQ6F,MAAM,cAAd7F,sCAAAA,gBAAgB8F,cAAc;4CACf;;gDAAMjF,MAAMS,OAAO,CAAC;;;4CAA7B8E,SAAS;6CACfpG,mBAAAA,QAAQ6F,MAAM,cAAd7F,uCAAAA,iBAAgB8F,cAAc;4CACf;;gDAAMM,OAAOC,GAAG,CAACV,iBAAiBxD,uCAA0B,EAAEuD;;;4CAAvEN,SAAS;6CACfpF,mBAAAA,QAAQ6F,MAAM,cAAd7F,uCAAAA,iBAAgB8F,cAAc;4CAC9B,IAAIvB,OAAOa,OAAOkB,OAAO,MAAM,GAAG,MAAMrH,SAAS;;;;;;4BACnD;;;;oBAPA;;;;;;IAQF;;AAEO,SAAeL;wCAAwB2H,KAAqB,EAAE7G,OAA4B;YAAEM,SAM5EA,uBALrBA,iBACMX,KACAmH,cACAC,qBAEAhF,cACAiF,iBACF7F,OAKFb,kBASOG,KACDyD;;;;;oBAvByF5D,UAAAA,oEAA+B,CAAC;qBACjIA,kBAAAA,QAAQ6F,MAAM,cAAd7F,sCAAAA,gBAAgB8F,cAAc;oBACxBzG,MAAMD,gBAAgBmH;oBACtBC,eAAexG,QAAQ8E,KAAK,KAAK;oBACjC2B,sBAAsB,IAAIE,IAAsBH;wBAAgB;wBAAQ;;wBAAc;;oBAC5F,IAAIA,gBAAgBI,IAAAA,wBAAe,EAACvH,MAAMoH,oBAAoBI,GAAG,CAAC;oBAC5DpF,gBAAezB,wBAAAA,QAAQyB,YAAY,cAApBzB,mCAAAA,wBAAwByG;yBAC3BD,cAAAA;;;;oBAAe;;wBAAMtD,gBAAgB7D,KAAKK,SAAS+B;;;2BAApC;;;;;;oBAAoD;;wBAAMD,gBAAgBnC,KAAKK,SAAS+B;;;2BAApC;;;oBAA/EiF;;;;;;;;;oBAGJ7F,QAAQnB,QAAQoH,WAAW,CAACJ,UAAUhF,MAAM,EAAEgF,UAAUtF,IAAI,EAAEsF,UAAUrH,GAAG,EAAE;wBAAEwC,eAAe6E,UAAU7E,aAAa;oBAAC;oBACtHkF,IAAAA,yBAAc,EAACL,UAAUtF,IAAI,EAAEP;yBAC3BY,CAAAA,aAAaiB,GAAG,CAAC,cAAc8D,YAAW,GAA1C/E;;;;oBAA6C;;wBAAM5C,0BAA0BgC,OAAO6F,UAAUrH,GAAG,EAAE2H,WAAW;4BAAEnB,QAAQ7F,QAAQ6F,MAAM;wBAAC;;;oBAA1F;;;qBACjD7F,mBAAAA,QAAQ6F,MAAM,cAAd7F,uCAAAA,iBAAgB8F,cAAc;oBAC9B;;wBAAO;4BACLjF,OAAAA;4BACAxB,KAAKqH,UAAUrH,GAAG;4BAClBU,QAAQ2G,UAAU3G,MAAM;4BACxB6C,QAAQ8D,UAAU9D,MAAM;4BACxBC,UAAU6D,UAAU7D,QAAQ;4BAC5BC,QAAQ4D,UAAU5D,MAAM;wBAC1B;;;oBACO3C;oBACS;;wBAAMa,QAAQkE,UAAU;4BAAElE,QAAQC,OAAO,GAAGgE,IAAI,CAAC;uCAAOpE,QAAQA,MAAMoC,KAAK,KAAKvD,QAAQuD,KAAK,CAACyD,UAAUhF,MAAM,EAAE;oCAAEG,eAAe6E,UAAU7E,aAAa;gCAAC;;;;;oBAAnK+B,UAAU;oBAChB,IAAIA,OAAO,CAAC,EAAE,CAACyB,MAAM,KAAK,YAAY,MAAM,IAAIG;wBAAgBrF;wBAAKyD,OAAO,CAAC,EAAE,CAAC1E,MAAM;uBAAG;oBACzF,MAAMiB;;;;;;;IAEV;;AAEO,SAAexB,SAASkC,KAAY;;YACnCoG;;;;oBAAO;;wBAAMpG,MAAMS,OAAO,CAAC;;;oBAA3B2F,OAAO;oBACJ;;wBAAMA,KAAKC,GAAG;;;oBAAvB;;wBAAS,cAAoCC,CAAC;;;;IAChD"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/open-source/ai/sensemaking/src/store/open.ts"],"sourcesContent":["import { channel } from 'node:diagnostics_channel';\nimport { existsSync, mkdirSync } from 'node:fs';\nimport { join } from 'node:path';\nimport type { ResolvedConfig } from '../config/index.ts';\nimport { anyPresetEmbeds, featureSignature, STATE_DIR } from '../config/index.ts';\nimport { rekeyChunkText } from '../embed/handoff.ts';\nimport { embedPending } from '../embed/query.ts';\nimport type { EmbedCallOptions } from '../embed/types.ts';\nimport { SenseError } from '../errors.ts';\nimport { FEATURES } from '../features/index.ts';\nimport { createBuilder } from './builder.ts';\nimport { clearCache } from './cache.ts';\nimport { ENGINE_IDENTITY_META_KEY } from './engine.ts';\nimport { lockWaitBudgetMs } from './lock-wait.ts';\nimport { CORE_READY_META_KEY, FEATURE_SIGNATURE_META_KEY, isCoreReady, isPublishedFeatureSignature } from './readiness.ts';\nimport { getMeta, setMeta } from './shared.ts';\nimport { changedSignatureKeys, embedIdentityAdopted } from './signature.ts';\nimport type { Stages } from './stages.ts';\nimport { stageRecorder } from './stages.ts';\nimport { withTransaction } from './transaction.ts';\nimport type { Connection, OpenDialect, Store } from './types.ts';\n\nexport type BuildRequirement = 'core' | 'lexical' | 'vectors';\n\n/** Options for the root `open(config, options)` API. */\nexport interface OpenOptions {\n /** Prepares configured capabilities by default; `false` opens compatible published state without repair. */\n build?: boolean;\n /** Cancels supported provider I/O and stops between phases after active native work finishes. */\n signal?: AbortSignal;\n}\n\nexport interface InternalOpenOptions extends OpenOptions {\n requirements?: ReadonlySet<BuildRequirement>;\n}\n\nexport interface OpenResult {\n store: Store;\n cfg: ResolvedConfig;\n dbPath: string;\n parsed: number;\n warnings: string[];\n stages: Stages;\n}\n\ninterface ConnectResult<Handle> {\n handle: Handle;\n conn: Connection;\n cfg: ResolvedConfig;\n dbPath: string;\n parsed: number;\n warnings: string[];\n stages: Stages;\n observational: boolean;\n}\n\nconst LOCK_POLL_MS = 50;\nconst lockWait = channel('sensemaking.store.lock-wait');\n\nfunction notReady(reason: string): SenseError {\n return new SenseError('INDEX_NOT_READY', `${reason}; run \"sense build\" or call build(config) before opening with { build: false }`);\n}\n\nfunction normaliseConfig(cfg: ResolvedConfig): ResolvedConfig {\n // `baseDir` was the original public open() input. Keep direct API callers working while\n // making the two ownership paths explicit for every internal operation.\n if (!cfg.rootDir) {\n if (!cfg.baseDir) throw new SenseError('CONFIG_INVALID', 'open requires rootDir (or legacy baseDir)');\n cfg.rootDir = cfg.baseDir;\n }\n if (!cfg.configDir) cfg.configDir = cfg.rootDir;\n return cfg;\n}\n\nfunction cachePath<Handle>(cfg: ResolvedConfig, dialect: OpenDialect<Handle>): string {\n return join(cfg.configDir ?? cfg.baseDir, STATE_DIR, dialect.filename);\n}\n\nasync function connectUnlocked<Handle>(dbPath: string, cfg: ResolvedConfig, configDir: string, dialect: OpenDialect<Handle>, options: { existingOnly: boolean; observational: boolean }): Promise<{ handle: Handle; conn: Connection }> {\n const budgetMs = lockWaitBudgetMs(configDir);\n const deadline = Date.now() + budgetMs;\n for (;;) {\n try {\n return await dialect.connect(dbPath, cfg, options);\n } catch (err) {\n if (options.existingOnly && !existsSync(dbPath)) {\n throw notReady(`the derived index does not exist at ${dbPath}`);\n }\n if (!dialect.isLocked?.(err as Error)) throw err;\n if (lockWait.hasSubscribers) lockWait.publish({ store: cfg.store, dbPath });\n if (Date.now() >= deadline) {\n throw new SenseError('STORE_BUSY', `another sense process is using this tree's ${cfg.store} cache (${dbPath}) and did not release it within ${Math.round(budgetMs / 1000)}s; wait for that command to finish, or set \"store\" to \"sqlite\" in sense.config.json, which serves concurrent commands`);\n }\n await new Promise((resolve) => setTimeout(resolve, LOCK_POLL_MS));\n }\n }\n}\n\nasync function assertCoreSchema(conn: Connection): Promise<void> {\n for (const table of ['frontmatter', 'content', 'preset_files', 'indexed_sources']) {\n await (await conn.prepare(`SELECT 1 FROM ${table} LIMIT 0`)).all();\n }\n}\n\nasync function connectExisting<Handle>(cfg: ResolvedConfig, dialect: OpenDialect<Handle>, requirements: ReadonlySet<BuildRequirement>): Promise<ConnectResult<Handle>> {\n const configDir = cfg.configDir ?? cfg.baseDir;\n const dbPath = cachePath(cfg, dialect);\n if (!existsSync(dbPath)) throw notReady(`the derived index does not exist at ${dbPath}`);\n\n const { handle, conn } = await connectUnlocked(dbPath, cfg, configDir, dialect, { existingOnly: true, observational: true });\n try {\n let state: { version: string | null; features: string | null; ready: string | null; engine: string | null };\n try {\n state = await withTransaction(conn, async () => {\n const version = await getMeta(conn, 'schema_version');\n const features = await getMeta(conn, FEATURE_SIGNATURE_META_KEY);\n const ready = await getMeta(conn, CORE_READY_META_KEY);\n const engine = await getMeta(conn, ENGINE_IDENTITY_META_KEY);\n await assertCoreSchema(conn);\n return { version, features, ready, engine };\n });\n } catch {\n if (!existsSync(dbPath)) throw notReady(`the derived index was deleted while opening ${dbPath}`);\n throw notReady(`the derived index at ${dbPath} has no compatible schema`);\n }\n\n if (state.version !== dialect.schemaVersion) {\n throw notReady(`the derived index at ${dbPath} uses schema ${state.version ?? 'unknown'}, but this sense version requires ${dialect.schemaVersion}`);\n }\n const engine = await dialect.engineIdentity?.();\n if (engine !== undefined && state.engine !== engine) {\n throw notReady(`the derived index at ${dbPath} was built with ${state.engine ?? 'an unrecorded engine'}, but this process loads ${engine}`);\n }\n const wantFeatures = featureSignature(cfg, FEATURES);\n if (!isPublishedFeatureSignature(state.features, wantFeatures)) {\n throw notReady(`the derived index at ${dbPath} was built for different configuration features`);\n }\n if (!isCoreReady(state.ready)) {\n throw notReady(`the derived index at ${dbPath} has an incomplete core build`);\n }\n if (requirements.has('lexical')) {\n await dialect.assertLexicalReady?.(conn);\n }\n if (!existsSync(dbPath)) throw notReady(`the derived index was deleted while opening ${dbPath}`);\n\n return {\n handle,\n conn,\n cfg,\n dbPath,\n parsed: 0,\n warnings: [],\n stages: stageRecorder().take(0, 0),\n observational: true,\n };\n } catch (err) {\n await dialect.close(handle, { observational: true });\n throw err;\n }\n}\n\nasync function connectForBuild<Handle>(cfg: ResolvedConfig, dialect: OpenDialect<Handle>, requirements: ReadonlySet<BuildRequirement>, cacheReplaced = false): Promise<ConnectResult<Handle>> {\n const configDir = cfg.configDir ?? cfg.baseDir;\n const stateDir = join(configDir, STATE_DIR);\n mkdirSync(stateDir, { recursive: true });\n const dbPath = join(stateDir, dialect.filename);\n\n const { handle, conn } = await connectUnlocked(dbPath, cfg, configDir, dialect, { existingOnly: false, observational: false });\n let closed = false;\n let builder: ReturnType<typeof createBuilder> | undefined;\n try {\n await conn.exec('CREATE TABLE IF NOT EXISTS meta (key TEXT PRIMARY KEY, value TEXT)');\n\n const version = await getMeta(conn, 'schema_version');\n const engine = await dialect.engineIdentity?.();\n const builtWith = version === null ? null : await getMeta(conn, ENGINE_IDENTITY_META_KEY);\n const engineChanged = version !== null && engine !== undefined && builtWith !== engine;\n if (version !== null && (version !== dialect.schemaVersion || engineChanged)) {\n console.error(version !== dialect.schemaVersion ? 'sense: cache format changed (new sensemaking version); rebuilding the index' : `sense: index was built with ${builtWith ?? 'an unrecorded engine'}; rebuilding it with ${engine}`);\n await dialect.close(handle);\n closed = true;\n if (cacheReplaced) throw notReady(`the derived index at ${dbPath} still reports incompatible schema ${version} or engine ${builtWith ?? 'unrecorded'} after cache replacement`);\n clearCache(cfg);\n return connectForBuild(cfg, dialect, requirements, true);\n }\n\n if (version === null) {\n await dialect.checkEngine?.();\n await dialect.ensureCoreSchema(handle, conn);\n if (engine !== undefined) await setMeta(conn, ENGINE_IDENTITY_META_KEY, engine);\n }\n await dialect.prepareConnection?.(handle, conn, cfg);\n\n if (dialect.setDerivedBusyTimeout) {\n const recordedMaxMs = Number((await getMeta(conn, 'reconcile_max_ms')) ?? '0');\n await dialect.setDerivedBusyTimeout(handle, conn, Math.min(Math.max(30000, 3 * recordedMaxMs), 600_000));\n }\n\n builder = createBuilder(conn, cfg, dialect.reconcileDialect, (snapshotCfg) => dialect.ensureFeatureSchema(handle, conn, snapshotCfg));\n const { parsed, warnings, stages, messages } = await builder.build();\n for (const message of messages) console.error(message);\n\n // Lexical preparation is a separate capability stage. A failure leaves core usable and the\n // dialect's own lexical marker stale, so unrelated map/peek/path/sql commands stay available.\n if (requirements.has('lexical')) {\n await dialect.prepareLexical?.(conn);\n }\n\n await builder.close();\n return { handle, conn, cfg, dbPath, parsed, warnings, stages, observational: false };\n } catch (err) {\n const cleanupTasks: Array<Promise<void>> = [];\n if (builder) {\n const builderToClose = builder;\n cleanupTasks.push(Promise.resolve().then(() => builderToClose.close()));\n }\n if (!closed) cleanupTasks.push(Promise.resolve().then(() => dialect.close(handle)));\n const cleanup = await Promise.allSettled(cleanupTasks);\n const cleanupErrors = cleanup.filter((result): result is PromiseRejectedResult => result.status === 'rejected').map((result) => result.reason);\n if (cleanupErrors.length > 0) throw new AggregateError([err, ...cleanupErrors], 'opening the derived index failed and cleanup also failed');\n throw err;\n }\n}\n\n// A static provider can resolve its identity while embedding. Publish it only after vectors\n// succeed and only when the durable signature still matches the prepared generation.\nexport async function prepareDocumentEmbeddings(store: Store, cfg: ResolvedConfig, allowed?: ReadonlySet<string>, options: EmbedCallOptions = {}): Promise<void> {\n options.signal?.throwIfAborted();\n const preparedSignature = await getMeta(store, FEATURE_SIGNATURE_META_KEY);\n options.signal?.throwIfAborted();\n await embedPending(store, cfg, allowed, preparedSignature, options);\n options.signal?.throwIfAborted();\n const actualSignature = featureSignature(cfg, FEATURES);\n if (preparedSignature === actualSignature) return;\n\n const changedKeys = changedSignatureKeys(preparedSignature ?? '', actualSignature);\n if (preparedSignature === null || changedKeys.size !== 1 || !changedKeys.has('embed') || !embedIdentityAdopted(preparedSignature, actualSignature)) {\n throw notReady('the index configuration changed while vectors were being prepared');\n }\n\n await store.transaction(async () => {\n options.signal?.throwIfAborted();\n const update = await store.prepare('UPDATE meta SET value = ? WHERE key = ? AND value = ?');\n options.signal?.throwIfAborted();\n const result = await update.run(actualSignature, FEATURE_SIGNATURE_META_KEY, preparedSignature);\n options.signal?.throwIfAborted();\n if (Number(result.changes) !== 1) throw notReady('another build changed the index configuration while vectors were being prepared');\n });\n}\n\nexport async function openWithDialect<Handle>(input: ResolvedConfig, dialect: OpenDialect<Handle>, options: InternalOpenOptions = {}): Promise<OpenResult> {\n options.signal?.throwIfAborted();\n const cfg = normaliseConfig(input);\n const buildEnabled = options.build !== false;\n const defaultRequirements = new Set<BuildRequirement>(buildEnabled ? ['core', 'lexical'] : ['core']);\n if (buildEnabled && anyPresetEmbeds(cfg)) defaultRequirements.add('vectors');\n const requirements = options.requirements ?? defaultRequirements;\n const connected = buildEnabled ? await connectForBuild(cfg, dialect, requirements) : await connectExisting(cfg, dialect, requirements);\n let store: Store | undefined;\n try {\n store = dialect.createStore(connected.handle, connected.conn, connected.cfg, { observational: connected.observational });\n rekeyChunkText(connected.conn, store);\n if (requirements.has('vectors') && buildEnabled) await prepareDocumentEmbeddings(store, connected.cfg, undefined, { signal: options.signal });\n options.signal?.throwIfAborted();\n return {\n store,\n cfg: connected.cfg,\n dbPath: connected.dbPath,\n parsed: connected.parsed,\n warnings: connected.warnings,\n stages: connected.stages,\n };\n } catch (err) {\n const cleanup = await Promise.allSettled([Promise.resolve().then(() => (store ? store.close() : dialect.close(connected.handle, { observational: connected.observational })))]);\n if (cleanup[0].status === 'rejected') throw new AggregateError([err, cleanup[0].reason], 'opening the derived index failed and cleanup also failed');\n throw err;\n }\n}\n\nexport async function docCount(store: Store): Promise<number> {\n const stmt = await store.prepare('SELECT COUNT(*) AS n FROM frontmatter');\n return ((await stmt.get()) as { n: number }).n;\n}\n"],"names":["docCount","openWithDialect","prepareDocumentEmbeddings","LOCK_POLL_MS","lockWait","channel","notReady","reason","SenseError","normaliseConfig","cfg","rootDir","baseDir","configDir","cachePath","dialect","join","STATE_DIR","filename","connectUnlocked","dbPath","options","budgetMs","deadline","err","lockWaitBudgetMs","Date","now","connect","existingOnly","existsSync","isLocked","hasSubscribers","publish","store","Math","round","Promise","resolve","setTimeout","assertCoreSchema","conn","table","prepare","all","connectExisting","requirements","handle","state","engine","wantFeatures","observational","withTransaction","version","features","ready","getMeta","FEATURE_SIGNATURE_META_KEY","CORE_READY_META_KEY","ENGINE_IDENTITY_META_KEY","schemaVersion","engineIdentity","undefined","featureSignature","FEATURES","isPublishedFeatureSignature","isCoreReady","has","assertLexicalReady","parsed","warnings","stages","stageRecorder","take","close","connectForBuild","cacheReplaced","stateDir","closed","builder","builtWith","engineChanged","recordedMaxMs","messages","message","cleanupTasks","builderToClose","cleanup","cleanupErrors","mkdirSync","recursive","exec","console","error","clearCache","checkEngine","ensureCoreSchema","setMeta","prepareConnection","setDerivedBusyTimeout","Number","min","max","createBuilder","reconcileDialect","snapshotCfg","ensureFeatureSchema","build","prepareLexical","push","then","allSettled","filter","result","status","map","length","AggregateError","allowed","preparedSignature","actualSignature","changedKeys","signal","throwIfAborted","embedPending","changedSignatureKeys","size","embedIdentityAdopted","transaction","update","run","changes","input","buildEnabled","defaultRequirements","connected","Set","anyPresetEmbeds","add","createStore","rekeyChunkText","stmt","get","n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/store/preset-scope.ts"],"sourcesContent":["import type { Config } from '../config/index.ts';\nimport { presetHasSignal } from '../config/index.ts';\nimport { listFiles } from '../scan/index.ts';\n\n// A signature change open() can route to a narrow reparse instead of a full clear: every changed\n// segment is a preset's own (glob or vector on/off), never a global feature or embed change.\nexport function isPresetOnlyChange(changedKeys: ReadonlySet<string>): boolean {\n return changedKeys.size > 0 && [...changedKeys].every((key) => key.startsWith('preset:'));\n}\n\ninterface PresetDef {\n include: string[];\n exclude: string[];\n vectors: boolean;\n}\n\n// One preset's old include/exclude/vectors-on-off, read back out of a stored `preset:<name>:...`\n// segment (config/access.ts's featureSignature format). Absent (a brand-new preset) is the empty\n// preset, not a parse failure; a segment present but not in that exact shape returns null so the\n// caller falls back to a full rebuild instead of guessing.\nfunction parseOldPreset(before: string, name: string): PresetDef | null {\n const part = before.split('|').find((p) => p.startsWith(`preset:${name}:`));\n if (part === undefined) return { include: [], exclude: [], vectors: false };\n const fields = part.split(':');\n if (fields.length !== 5) return null;\n const [, , includeStr, excludeStr, onOff] = fields;\n if (onOff !== 'on' && onOff !== 'off') return null;\n return { include: includeStr === '' ? [] : includeStr.split('+'), exclude: excludeStr === '' ? [] : excludeStr.split('+'), vectors: onOff === 'on' };\n}\n\n// Paths one preset definition covers, via the real listFiles so stat filtering (directories,\n// dangling symlinks) matches production coverage exactly.\nfunction matchPreset(cfg: Config, baseDir: string, name: string, def: PresetDef): Set<string> {\n const scoped: Config = { ...cfg, presets: { [name]: { include: def.include, exclude: def.exclude } } };\n return new Set(listFiles(scoped, baseDir).map((f) => f.relPath));\n}\n\n// Every path whose coverage by a changed preset genuinely moved: gained or lost it (a glob edit),\n// or kept it under a flipped vectors on/off (that preset's whole match set, since its contribution\n// to the file's union embed flag may have changed even though membership itself did not). Returns\n// null when a changed preset's stored segment can't be parsed, so the caller takes the full rebuild.\nexport function forcedPresetPaths(cfg: Config, baseDir: string, before: string, changedKeys: ReadonlySet<string>): Set<string> | null {\n const forced = new Set<string>();\n for (const key of changedKeys) {\n const name = key.slice('preset:'.length);\n const oldDef = parseOldPreset(before, name);\n if (oldDef === null) return null;\n const stillDeclared = Object.hasOwn(cfg.presets, name);\n const newDef: PresetDef = stillDeclared ? { include: cfg.presets[name].include, exclude: cfg.presets[name].exclude ?? [], vectors: presetHasSignal(cfg, name, 'vectors') } : { include: [], exclude: [], vectors: false };\n\n const oldMatch = matchPreset(cfg, baseDir, name, oldDef);\n const newMatch = stillDeclared ? matchPreset(cfg, baseDir, name, newDef) : new Set<string>();\n\n if (oldDef.vectors !== newDef.vectors) {\n for (const p of oldMatch) forced.add(p);\n for (const p of newMatch) forced.add(p);\n } else {\n for (const p of oldMatch) if (!newMatch.has(p)) forced.add(p);\n for (const p of newMatch) if (!oldMatch.has(p)) forced.add(p);\n }\n }\n return forced;\n}\n"],"names":["forcedPresetPaths","isPresetOnlyChange","changedKeys","size","every","key","startsWith","parseOldPreset","before","name","part","split","find","p","undefined","include","exclude","vectors","fields","length","includeStr","excludeStr","onOff","matchPreset","cfg","baseDir","def","scoped","presets","Set","listFiles","map","f","relPath","forced","slice","oldDef","stillDeclared","Object","hasOwn","newDef","presetHasSignal","oldMatch","newMatch","add","has"],"mappings":"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"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/open-source/ai/sensemaking/src/store/preset-scope.ts"],"sourcesContent":["import type { Config } from '../config/index.ts';\nimport { presetHasSignal } from '../config/index.ts';\nimport { listFiles } from '../scan/index.ts';\n\n// A signature change open() can route to a narrow reparse instead of a full clear: every changed\n// segment is a preset's own (glob or vector on/off), never a global feature or embed change.\nexport function isPresetOnlyChange(changedKeys: ReadonlySet<string>): boolean {\n return changedKeys.size > 0 && [...changedKeys].every((key) => key.startsWith('preset:'));\n}\n\ninterface PresetDef {\n include: string[];\n exclude: string[];\n vectors: boolean;\n}\n\n// One preset's old include/exclude/vectors-on-off, read back out of a stored `preset:<name>:...`\n// segment (config/access.ts's featureSignature format). Absent (a brand-new preset) is the empty\n// preset, not a parse failure; a segment present but not in that exact shape returns null so the\n// caller falls back to a full rebuild instead of guessing.\nfunction parseOldPreset(before: string, name: string): PresetDef | null {\n const part = before.split('|').find((p) => p.startsWith(`preset:${name}:`));\n if (part === undefined) return { include: [], exclude: [], vectors: false };\n const fields = part.split(':');\n if (fields.length !== 5) return null;\n const [, , includeStr, excludeStr, onOff] = fields;\n if (onOff !== 'on' && onOff !== 'off') return null;\n return { include: includeStr === '' ? [] : includeStr.split('+'), exclude: excludeStr === '' ? [] : excludeStr.split('+'), vectors: onOff === 'on' };\n}\n\n// Paths one preset definition covers, via the real listFiles so stat filtering (directories,\n// dangling symlinks) matches production coverage exactly.\nfunction matchPreset(cfg: Config, baseDir: string, name: string, def: PresetDef): Set<string> {\n const scoped: Config = { ...cfg, presets: { [name]: { include: def.include, exclude: def.exclude } } };\n return new Set(listFiles(scoped, baseDir).map((f) => f.relPath));\n}\n\n// Every path whose coverage by a changed preset genuinely moved: gained or lost it (a glob edit),\n// or kept it under a flipped vectors on/off (that preset's whole match set, since its contribution\n// to the file's union embed flag may have changed even though membership itself did not). Returns\n// null when a changed preset's stored segment can't be parsed, so the caller takes the full rebuild.\nexport function forcedPresetPaths(cfg: Config, baseDir: string, before: string, changedKeys: ReadonlySet<string>): Set<string> | null {\n const forced = new Set<string>();\n for (const key of changedKeys) {\n const name = key.slice('preset:'.length);\n const oldDef = parseOldPreset(before, name);\n if (oldDef === null) return null;\n const stillDeclared = Object.hasOwn(cfg.presets, name);\n const newDef: PresetDef = stillDeclared ? { include: cfg.presets[name].include, exclude: cfg.presets[name].exclude ?? [], vectors: presetHasSignal(cfg, name, 'vectors') } : { include: [], exclude: [], vectors: false };\n\n const oldMatch = matchPreset(cfg, baseDir, name, oldDef);\n const newMatch = stillDeclared ? matchPreset(cfg, baseDir, name, newDef) : new Set<string>();\n\n if (oldDef.vectors !== newDef.vectors) {\n for (const p of oldMatch) forced.add(p);\n for (const p of newMatch) forced.add(p);\n } else {\n for (const p of oldMatch) if (!newMatch.has(p)) forced.add(p);\n for (const p of newMatch) if (!oldMatch.has(p)) forced.add(p);\n }\n }\n return forced;\n}\n"],"names":["forcedPresetPaths","isPresetOnlyChange","changedKeys","size","every","key","startsWith","parseOldPreset","before","name","part","split","find","p","undefined","include","exclude","vectors","fields","length","includeStr","excludeStr","onOff","matchPreset","cfg","baseDir","def","scoped","presets","Set","listFiles","map","f","relPath","forced","slice","oldDef","stillDeclared","Object","hasOwn","newDef","presetHasSignal","oldMatch","newMatch","add","has"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/store/readiness.ts"],"sourcesContent":["// Published core state has one exact durable signature. Static model identity adoption is a\n// preparation transition, not permission for a read snapshot to accept a different signature.\nexport const CORE_READY_META_KEY = 'core_ready';\nexport const CORE_GENERATION_META_KEY = 'core_generation';\nexport const FEATURE_SIGNATURE_META_KEY = 'features';\n\nexport function isCoreReady(value: string | null): boolean {\n return value === '1';\n}\n\nexport function isPublishedFeatureSignature(actual: string | null, expected: string): boolean {\n return actual === expected;\n}\n"],"names":["CORE_GENERATION_META_KEY","CORE_READY_META_KEY","FEATURE_SIGNATURE_META_KEY","isCoreReady","isPublishedFeatureSignature","value","actual","expected"],"mappings":"AAAA,4FAA4F;AAC5F,8FAA8F;;;;;;;;;;;;QAEjFA;eAAAA;;QADAC;eAAAA;;QAEAC;eAAAA;;QAEGC;eAAAA;;QAIAC;eAAAA;;;AART,IAAMH,sBAAsB;AAC5B,IAAMD,2BAA2B;AACjC,IAAME,6BAA6B;AAEnC,SAASC,YAAYE,KAAoB;IAC9C,OAAOA,UAAU;AACnB;AAEO,SAASD,4BAA4BE,MAAqB,EAAEC,QAAgB;IACjF,OAAOD,WAAWC;AACpB"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/open-source/ai/sensemaking/src/store/readiness.ts"],"sourcesContent":["// Published core state has one exact durable signature. Static model identity adoption is a\n// preparation transition, not permission for a read snapshot to accept a different signature.\nexport const CORE_READY_META_KEY = 'core_ready';\nexport const CORE_GENERATION_META_KEY = 'core_generation';\nexport const FEATURE_SIGNATURE_META_KEY = 'features';\n\nexport function isCoreReady(value: string | null): boolean {\n return value === '1';\n}\n\nexport function isPublishedFeatureSignature(actual: string | null, expected: string): boolean {\n return actual === expected;\n}\n"],"names":["CORE_GENERATION_META_KEY","CORE_READY_META_KEY","FEATURE_SIGNATURE_META_KEY","isCoreReady","isPublishedFeatureSignature","value","actual","expected"],"mappings":"AAAA,4FAA4F;AAC5F,8FAA8F;;;;;;;;;;;;QAEjFA;eAAAA;;QADAC;eAAAA;;QAEAC;eAAAA;;QAEGC;eAAAA;;QAIAC;eAAAA;;;AART,IAAMH,sBAAsB;AAC5B,IAAMD,2BAA2B;AACjC,IAAME,6BAA6B;AAEnC,SAASC,YAAYE,KAAoB;IAC9C,OAAOA,UAAU;AACnB;AAEO,SAASD,4BAA4BE,MAAqB,EAAEC,QAAgB;IACjF,OAAOD,WAAWC;AACpB"}
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/store/reconcile.ts"],"sourcesContent":["import type { Config } from '../config/index.ts';\nimport { activeFeatures } from '../features/index.ts';\nimport type { ExtractedDoc, ReconcileDelta } from '../features/types.ts';\nimport { progress } from '../output/progress.ts';\nimport { listFiles, RESERVED_COLUMNS } from '../scan/index.ts';\nimport type { ParsePool } from '../scan/pool.ts';\nimport { reparseFiles } from '../scan/reparse.ts';\nimport { recordLockWaitMs } from './lock-wait.ts';\nimport { appendRows, getColumns, quoteIdent } from './shared.ts';\nimport { featureStage, type StageRecorder, type Stages, stageRecorder } from './stages.ts';\nimport { withTransaction } from './transaction.ts';\nimport type { Connection, ReconcileDialect } from './types.ts';\n\n// One reconcile algorithm shared by every store, parameterised by a per-engine ReconcileDialect\n// (types.ts). Ordering is universal, not a dialect concern: ALTER, then the frontmatter upsert,\n// then reconcileContent, then preset_files, then the vanished-frontmatter delete, then feature hooks\n// -- a vanished path's content delete (inside reconcileContent) must precede its frontmatter\n// delete, since sqlite's delete SQL resolves the row via its frontmatter rowid.\n\n// Feature-owned columns (`_rank`) must stay out of the upsert: a reparse would null the last\n// computed value on every touch, not just the reconciles that recompute it.\nexport const CORE_FRONTMATTER_COLUMNS = new Set(['path', '_mtime', '_ctime', '_size', '_parse_error']);\n\nexport interface ReconcilePaths {\n rootDir: string;\n configDir: string;\n}\n\nexport interface ReconcileSnapshot {\n existingRows: Array<{ path: string; _mtime: number; _size: number }>;\n seenColumns: Set<string>;\n}\n\nexport interface ReconcilePlan {\n mutated: boolean;\n parsed: number;\n warnings: string[];\n apply(conn: Connection): Promise<void>;\n finish(txMs: number): Stages;\n record(conn: Connection, txMs: number): Promise<void>;\n}\n\nexport interface ReconcileTiming {\n stages: StageRecorder;\n elapsed(): number;\n workerParseMs: number;\n txMs: number;\n}\n\nexport function createReconcileTiming(cfg: Config): ReconcileTiming {\n const start = process.hrtime.bigint();\n return {\n stages: stageRecorder(activeFeatures(cfg).map((feature) => feature.name)),\n elapsed: () => Number(process.hrtime.bigint() - start) / 1e6,\n workerParseMs: 0,\n txMs: 0,\n };\n}\n\n// Called inside the builder's short planning snapshot, alongside its metadata baseline. Parsing\n// happens only after that transaction closes; publication later rejects this state if generation\n// or configuration moved in the meantime.\nexport async function readReconcileSnapshot(conn: Connection, timing: ReconcileTiming): Promise<ReconcileSnapshot> {\n const existingRows = await timing.stages.time('existing', async () => {\n const existingStmt = await conn.prepare('SELECT \"path\", \"_mtime\", \"_size\" FROM frontmatter');\n return (await existingStmt.all()) as ReconcileSnapshot['existingRows'];\n });\n return { existingRows, seenColumns: await getColumns(conn) };\n}\n\nexport async function prepareReconcile(snapshot: ReconcileSnapshot, cfg: Config, paths: ReconcilePaths, dialect: ReconcileDialect, timing: ReconcileTiming, pool?: ParsePool, forcedPaths?: ReadonlySet<string>): Promise<ReconcilePlan> {\n const { rootDir, configDir } = paths;\n const features = activeFeatures(cfg);\n const { stages, elapsed } = timing;\n const files = await stages.time('list', () => listFiles(cfg, rootDir));\n const currentSet = new Set(files.map((f) => f.relPath));\n const existingRows = snapshot.existingRows;\n const existing = new Map(existingRows.map((r) => [r.path, r]));\n // A path whose coverage moved between presets (forcedPaths) but is no longer covered at all is\n // already caught below by !currentSet.has, since it can only be forced by having existed under\n // an old preset's match, which means it was reconciled into `existing` already.\n const vanished = existingRows.filter((r) => !currentSet.has(r.path)).map((r) => r.path);\n\n // forcedPaths treats an unchanged file as touched because its preset coverage moved, not its\n // stamp -- reconcile still owns add/update/remove and every cross-feature cascade for it.\n const toReparse = files.filter((f) => {\n const row = existing.get(f.relPath);\n return !row || row._mtime !== f.mtimeMs || row._size !== f.size || (forcedPaths?.has(f.relPath) ?? false);\n });\n\n if (vanished.length === 0 && toReparse.length === 0) {\n return {\n mutated: false,\n parsed: 0,\n warnings: [],\n apply: async () => {},\n finish: (txMs) => stages.take(elapsed(), txMs, timing.workerParseMs),\n record: async () => {},\n };\n }\n\n const seenColumns = new Set(snapshot.seenColumns);\n\n // Bulk reparses (a sync, a cold build) are the long silences a query can hit; short\n // reconciles stay silent (progress() has a threshold).\n const report = progress('reparsing files', toReparse.length);\n // Pool wall time, dispatch to drain, so this stage shares a clock with every other one.\n const { docs: parsedDocs, warnings, newColumns, workerParseMs } = await stages.time('parse', () => reparseFiles(toReparse, features, cfg, seenColumns, report.tick, { pool }));\n timing.workerParseMs += workerParseMs;\n report.finish();\n for (const col of newColumns) seenColumns.add(col);\n\n const allColumns = [...seenColumns];\n // Fence before ALTERing: a store's own failure past this point is a raw, engine-specific\n // error with no indication of the boundary or the levers -- dialect.checkColumnLimit names both.\n dialect.checkColumnLimit(allColumns.length);\n // Columns the frontmatter upsert actually writes: core + parsed frontmatter keys, never a\n // feature-owned reserved column (see CORE_FRONTMATTER_COLUMNS above).\n const writableColumns = allColumns.filter((c) => CORE_FRONTMATTER_COLUMNS.has(c) || !RESERVED_COLUMNS.has(c));\n // ON CONFLICT DO UPDATE (not OR REPLACE) keeps the row's rowid stable across reparses --\n // sqlite's content rows are coupled to that rowid.\n const insertSql = `INSERT INTO frontmatter (${writableColumns.map(quoteIdent).join(', ')}) VALUES (${writableColumns.map(() => '?').join(', ')}) ON CONFLICT(\"path\") DO UPDATE SET ${writableColumns\n .filter((c) => c !== 'path')\n .map((c) => `${quoteIdent(c)} = excluded.${quoteIdent(c)}`)\n .join(', ')}`;\n\n const added = toReparse.filter((f) => !existing.has(f.relPath)).map((f) => f.relPath);\n const delta: ReconcileDelta = { files, reparsed: parsedDocs.map((d) => d.relPath), added, vanished };\n const addedSet = new Set(added);\n const reparsedExisting = parsedDocs.map((d) => d.relPath).filter((p) => !addedSet.has(p));\n // Paths whose content (and, per feature, other rows) need clearing: gone entirely, or about to\n // be reinserted fresh. Disjoint from `added`, which has nothing to clear.\n const touched = [...vanished, ...reparsedExisting];\n\n return {\n mutated: true,\n parsed: parsedDocs.length,\n warnings,\n async apply(conn) {\n // The generation fence already proved the planning snapshot current under this write lock.\n // Re-read columns only because schema setup is not itself a core generation publication.\n const present = await getColumns(conn);\n const missingColumns = newColumns.filter((col) => !present.has(col));\n if (missingColumns.length > 0) await stages.time('alter', () => dialect.addColumns(conn, missingColumns));\n\n if (parsedDocs.length > 0) {\n const toRow = (doc: (typeof parsedDocs)[number]) =>\n writableColumns.map((col) => {\n if (col === 'path') return doc.relPath;\n if (col === '_mtime') return doc.mtimeMs;\n if (col === '_ctime') return doc.ctimeMs;\n if (col === '_size') return doc.size;\n if (col === '_parse_error') return doc.parseError;\n return doc.data[col] ?? null;\n });\n await stages.time('fm-upsert', async () => {\n const newDocs = parsedDocs.filter((d) => addedSet.has(d.relPath));\n const updateDocs = parsedDocs.filter((d) => !addedSet.has(d.relPath));\n await appendRows(conn, 'frontmatter', writableColumns, insertSql, newDocs.map(toRow));\n if (updateDocs.length > 0) {\n const rows = updateDocs.map(toRow);\n if (dialect.updateFrontmatter) await dialect.updateFrontmatter(conn, writableColumns, rows);\n else await conn.runBatch(insertSql, rows);\n }\n });\n }\n\n await stages.time('text-index', () => dialect.reconcileContent(conn, touched, parsedDocs, delta, cfg));\n if (touched.length > 0)\n await conn.runBatch(\n 'DELETE FROM indexed_sources WHERE \"path\" = ?',\n touched.map((p) => [p])\n );\n await appendRows(\n conn,\n 'indexed_sources',\n ['path', 'text'],\n 'INSERT INTO indexed_sources (\"path\", text) VALUES (?, ?) ON CONFLICT(\"path\") DO UPDATE SET text = excluded.text',\n parsedDocs.map((doc) => [doc.relPath, doc.source])\n );\n\n await stages.time('presets', async () => {\n if (touched.length > 0)\n await conn.runBatch(\n 'DELETE FROM preset_files WHERE \"path\" = ?',\n touched.map((p) => [p])\n );\n const presetRows: unknown[][] = [];\n for (const doc of parsedDocs) for (const presetName of doc.presets) presetRows.push([doc.relPath, presetName]);\n await appendRows(conn, 'preset_files', ['path', 'preset'], 'INSERT INTO preset_files (\"path\", preset) VALUES (?, ?) ON CONFLICT(\"path\", preset) DO NOTHING', presetRows);\n });\n\n if (vanished.length > 0)\n await stages.time('vanished', () =>\n conn.runBatch(\n 'DELETE FROM frontmatter WHERE \"path\" = ?',\n vanished.map((p) => [p])\n )\n );\n\n if (touched.length > 0) for (const feature of features) await stages.time(featureStage(feature.name, 'remove'), () => feature.remove?.(conn, touched, delta));\n for (const feature of features) {\n const docsForFeature: ExtractedDoc[] = parsedDocs.map((doc) => ({ path: doc.relPath, extracted: doc.extracted[feature.name] }));\n await stages.time(featureStage(feature.name, 'store'), () => feature.store?.(conn, docsForFeature, delta));\n }\n for (const feature of features) await stages.time(featureStage(feature.name, 'after'), () => feature.afterReconcile?.(conn, delta));\n },\n finish: (txMs) => stages.take(elapsed(), txMs, timing.workerParseMs),\n async record(conn, txMs) {\n recordLockWaitMs(configDir, txMs);\n if (dialect.recordDuration) await stages.time('meta', () => dialect.recordDuration?.(conn, txMs));\n },\n };\n}\n\n// Lower-level entrypoint retained only for focused reconcile tests. It has no generation fence;\n// production publication must go through builder.ts, and any new caller must provide exclusivity.\nexport async function reconcile(conn: Connection, cfg: Config, paths: ReconcilePaths, dialect: ReconcileDialect, pool?: ParsePool, forcedPaths?: ReadonlySet<string>): Promise<{ parsed: number; warnings: string[]; stages: Stages }> {\n const timing = createReconcileTiming(cfg);\n const snapshot = await withTransaction(conn, () => readReconcileSnapshot(conn, timing));\n const plan = await prepareReconcile(snapshot, cfg, paths, dialect, timing, pool, forcedPaths);\n if (!plan.mutated) return { parsed: plan.parsed, warnings: plan.warnings, stages: plan.finish(0) };\n const txStart = Date.now();\n let txMs: number;\n try {\n await withTransaction(conn, () => plan.apply(conn), dialect.beginMode());\n } finally {\n txMs = Date.now() - txStart;\n timing.txMs += txMs;\n }\n await plan.record(conn, txMs);\n return { parsed: plan.parsed, warnings: plan.warnings, stages: plan.finish(timing.txMs) };\n}\n"],"names":["CORE_FRONTMATTER_COLUMNS","createReconcileTiming","prepareReconcile","readReconcileSnapshot","reconcile","Set","cfg","start","process","hrtime","bigint","stages","stageRecorder","activeFeatures","map","feature","name","elapsed","Number","workerParseMs","txMs","conn","timing","existingRows","time","existingStmt","prepare","all","getColumns","seenColumns","snapshot","paths","dialect","pool","forcedPaths","rootDir","configDir","features","files","currentSet","existing","vanished","toReparse","report","parsedDocs","warnings","newColumns","col","allColumns","writableColumns","insertSql","added","delta","addedSet","reparsedExisting","touched","listFiles","f","relPath","Map","r","path","filter","has","row","get","_mtime","mtimeMs","_size","size","length","mutated","parsed","apply","finish","take","record","progress","reparseFiles","tick","docs","add","checkColumnLimit","c","RESERVED_COLUMNS","quoteIdent","join","reparsed","d","p","present","missingColumns","toRow","addColumns","doc","ctimeMs","parseError","data","newDocs","updateDocs","rows","appendRows","updateFrontmatter","runBatch","reconcileContent","source","presetRows","presetName","presets","push","featureStage","remove","docsForFeature","extracted","store","afterReconcile","recordLockWaitMs","recordDuration","plan","txStart","withTransaction","Date","now","beginMode"],"mappings":"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"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/open-source/ai/sensemaking/src/store/reconcile.ts"],"sourcesContent":["import type { Config } from '../config/index.ts';\nimport { activeFeatures } from '../features/index.ts';\nimport type { ExtractedDoc, ReconcileDelta } from '../features/types.ts';\nimport { progress } from '../output/progress.ts';\nimport { listFiles, RESERVED_COLUMNS } from '../scan/index.ts';\nimport type { ParsePool } from '../scan/pool.ts';\nimport { reparseFiles } from '../scan/reparse.ts';\nimport { recordLockWaitMs } from './lock-wait.ts';\nimport { appendRows, getColumns, quoteIdent } from './shared.ts';\nimport { featureStage, type StageRecorder, type Stages, stageRecorder } from './stages.ts';\nimport { withTransaction } from './transaction.ts';\nimport type { Connection, ReconcileDialect } from './types.ts';\n\n// One reconcile algorithm shared by every store, parameterised by a per-engine ReconcileDialect\n// (types.ts). Ordering is universal, not a dialect concern: ALTER, then the frontmatter upsert,\n// then reconcileContent, then preset_files, then the vanished-frontmatter delete, then feature hooks\n// -- a vanished path's content delete (inside reconcileContent) must precede its frontmatter\n// delete, since sqlite's delete SQL resolves the row via its frontmatter rowid.\n\n// Feature-owned columns (`_rank`) must stay out of the upsert: a reparse would null the last\n// computed value on every touch, not just the reconciles that recompute it.\nexport const CORE_FRONTMATTER_COLUMNS = new Set(['path', '_mtime', '_ctime', '_size', '_parse_error']);\n\nexport interface ReconcilePaths {\n rootDir: string;\n configDir: string;\n}\n\nexport interface ReconcileSnapshot {\n existingRows: Array<{ path: string; _mtime: number; _size: number }>;\n seenColumns: Set<string>;\n}\n\nexport interface ReconcilePlan {\n mutated: boolean;\n parsed: number;\n warnings: string[];\n apply(conn: Connection): Promise<void>;\n finish(txMs: number): Stages;\n record(conn: Connection, txMs: number): Promise<void>;\n}\n\nexport interface ReconcileTiming {\n stages: StageRecorder;\n elapsed(): number;\n workerParseMs: number;\n txMs: number;\n}\n\nexport function createReconcileTiming(cfg: Config): ReconcileTiming {\n const start = process.hrtime.bigint();\n return {\n stages: stageRecorder(activeFeatures(cfg).map((feature) => feature.name)),\n elapsed: () => Number(process.hrtime.bigint() - start) / 1e6,\n workerParseMs: 0,\n txMs: 0,\n };\n}\n\n// Called inside the builder's short planning snapshot, alongside its metadata baseline. Parsing\n// happens only after that transaction closes; publication later rejects this state if generation\n// or configuration moved in the meantime.\nexport async function readReconcileSnapshot(conn: Connection, timing: ReconcileTiming): Promise<ReconcileSnapshot> {\n const existingRows = await timing.stages.time('existing', async () => {\n const existingStmt = await conn.prepare('SELECT \"path\", \"_mtime\", \"_size\" FROM frontmatter');\n return (await existingStmt.all()) as ReconcileSnapshot['existingRows'];\n });\n return { existingRows, seenColumns: await getColumns(conn) };\n}\n\nexport async function prepareReconcile(snapshot: ReconcileSnapshot, cfg: Config, paths: ReconcilePaths, dialect: ReconcileDialect, timing: ReconcileTiming, pool?: ParsePool, forcedPaths?: ReadonlySet<string>): Promise<ReconcilePlan> {\n const { rootDir, configDir } = paths;\n const features = activeFeatures(cfg);\n const { stages, elapsed } = timing;\n const files = await stages.time('list', () => listFiles(cfg, rootDir));\n const currentSet = new Set(files.map((f) => f.relPath));\n const existingRows = snapshot.existingRows;\n const existing = new Map(existingRows.map((r) => [r.path, r]));\n // A path whose coverage moved between presets (forcedPaths) but is no longer covered at all is\n // already caught below by !currentSet.has, since it can only be forced by having existed under\n // an old preset's match, which means it was reconciled into `existing` already.\n const vanished = existingRows.filter((r) => !currentSet.has(r.path)).map((r) => r.path);\n\n // forcedPaths treats an unchanged file as touched because its preset coverage moved, not its\n // stamp -- reconcile still owns add/update/remove and every cross-feature cascade for it.\n const toReparse = files.filter((f) => {\n const row = existing.get(f.relPath);\n return !row || row._mtime !== f.mtimeMs || row._size !== f.size || (forcedPaths?.has(f.relPath) ?? false);\n });\n\n if (vanished.length === 0 && toReparse.length === 0) {\n return {\n mutated: false,\n parsed: 0,\n warnings: [],\n apply: async () => {},\n finish: (txMs) => stages.take(elapsed(), txMs, timing.workerParseMs),\n record: async () => {},\n };\n }\n\n const seenColumns = new Set(snapshot.seenColumns);\n\n // Bulk reparses (a sync, a cold build) are the long silences a query can hit; short\n // reconciles stay silent (progress() has a threshold).\n const report = progress('reparsing files', toReparse.length);\n // Pool wall time, dispatch to drain, so this stage shares a clock with every other one.\n const { docs: parsedDocs, warnings, newColumns, workerParseMs } = await stages.time('parse', () => reparseFiles(toReparse, features, cfg, seenColumns, report.tick, { pool }));\n timing.workerParseMs += workerParseMs;\n report.finish();\n for (const col of newColumns) seenColumns.add(col);\n\n const allColumns = [...seenColumns];\n // Fence before ALTERing: a store's own failure past this point is a raw, engine-specific\n // error with no indication of the boundary or the levers -- dialect.checkColumnLimit names both.\n dialect.checkColumnLimit(allColumns.length);\n // Columns the frontmatter upsert actually writes: core + parsed frontmatter keys, never a\n // feature-owned reserved column (see CORE_FRONTMATTER_COLUMNS above).\n const writableColumns = allColumns.filter((c) => CORE_FRONTMATTER_COLUMNS.has(c) || !RESERVED_COLUMNS.has(c));\n // ON CONFLICT DO UPDATE (not OR REPLACE) keeps the row's rowid stable across reparses --\n // sqlite's content rows are coupled to that rowid.\n const insertSql = `INSERT INTO frontmatter (${writableColumns.map(quoteIdent).join(', ')}) VALUES (${writableColumns.map(() => '?').join(', ')}) ON CONFLICT(\"path\") DO UPDATE SET ${writableColumns\n .filter((c) => c !== 'path')\n .map((c) => `${quoteIdent(c)} = excluded.${quoteIdent(c)}`)\n .join(', ')}`;\n\n const added = toReparse.filter((f) => !existing.has(f.relPath)).map((f) => f.relPath);\n const delta: ReconcileDelta = { files, reparsed: parsedDocs.map((d) => d.relPath), added, vanished };\n const addedSet = new Set(added);\n const reparsedExisting = parsedDocs.map((d) => d.relPath).filter((p) => !addedSet.has(p));\n // Paths whose content (and, per feature, other rows) need clearing: gone entirely, or about to\n // be reinserted fresh. Disjoint from `added`, which has nothing to clear.\n const touched = [...vanished, ...reparsedExisting];\n\n return {\n mutated: true,\n parsed: parsedDocs.length,\n warnings,\n async apply(conn) {\n // The generation fence already proved the planning snapshot current under this write lock.\n // Re-read columns only because schema setup is not itself a core generation publication.\n const present = await getColumns(conn);\n const missingColumns = newColumns.filter((col) => !present.has(col));\n if (missingColumns.length > 0) await stages.time('alter', () => dialect.addColumns(conn, missingColumns));\n\n if (parsedDocs.length > 0) {\n const toRow = (doc: (typeof parsedDocs)[number]) =>\n writableColumns.map((col) => {\n if (col === 'path') return doc.relPath;\n if (col === '_mtime') return doc.mtimeMs;\n if (col === '_ctime') return doc.ctimeMs;\n if (col === '_size') return doc.size;\n if (col === '_parse_error') return doc.parseError;\n return doc.data[col] ?? null;\n });\n await stages.time('fm-upsert', async () => {\n const newDocs = parsedDocs.filter((d) => addedSet.has(d.relPath));\n const updateDocs = parsedDocs.filter((d) => !addedSet.has(d.relPath));\n await appendRows(conn, 'frontmatter', writableColumns, insertSql, newDocs.map(toRow));\n if (updateDocs.length > 0) {\n const rows = updateDocs.map(toRow);\n if (dialect.updateFrontmatter) await dialect.updateFrontmatter(conn, writableColumns, rows);\n else await conn.runBatch(insertSql, rows);\n }\n });\n }\n\n await stages.time('text-index', () => dialect.reconcileContent(conn, touched, parsedDocs, delta, cfg));\n if (touched.length > 0)\n await conn.runBatch(\n 'DELETE FROM indexed_sources WHERE \"path\" = ?',\n touched.map((p) => [p])\n );\n await appendRows(\n conn,\n 'indexed_sources',\n ['path', 'text'],\n 'INSERT INTO indexed_sources (\"path\", text) VALUES (?, ?) ON CONFLICT(\"path\") DO UPDATE SET text = excluded.text',\n parsedDocs.map((doc) => [doc.relPath, doc.source])\n );\n\n await stages.time('presets', async () => {\n if (touched.length > 0)\n await conn.runBatch(\n 'DELETE FROM preset_files WHERE \"path\" = ?',\n touched.map((p) => [p])\n );\n const presetRows: unknown[][] = [];\n for (const doc of parsedDocs) for (const presetName of doc.presets) presetRows.push([doc.relPath, presetName]);\n await appendRows(conn, 'preset_files', ['path', 'preset'], 'INSERT INTO preset_files (\"path\", preset) VALUES (?, ?) ON CONFLICT(\"path\", preset) DO NOTHING', presetRows);\n });\n\n if (vanished.length > 0)\n await stages.time('vanished', () =>\n conn.runBatch(\n 'DELETE FROM frontmatter WHERE \"path\" = ?',\n vanished.map((p) => [p])\n )\n );\n\n if (touched.length > 0) for (const feature of features) await stages.time(featureStage(feature.name, 'remove'), () => feature.remove?.(conn, touched, delta));\n for (const feature of features) {\n const docsForFeature: ExtractedDoc[] = parsedDocs.map((doc) => ({ path: doc.relPath, extracted: doc.extracted[feature.name] }));\n await stages.time(featureStage(feature.name, 'store'), () => feature.store?.(conn, docsForFeature, delta));\n }\n for (const feature of features) await stages.time(featureStage(feature.name, 'after'), () => feature.afterReconcile?.(conn, delta));\n },\n finish: (txMs) => stages.take(elapsed(), txMs, timing.workerParseMs),\n async record(conn, txMs) {\n recordLockWaitMs(configDir, txMs);\n if (dialect.recordDuration) await stages.time('meta', () => dialect.recordDuration?.(conn, txMs));\n },\n };\n}\n\n// Lower-level entrypoint retained only for focused reconcile tests. It has no generation fence;\n// production publication must go through builder.ts, and any new caller must provide exclusivity.\nexport async function reconcile(conn: Connection, cfg: Config, paths: ReconcilePaths, dialect: ReconcileDialect, pool?: ParsePool, forcedPaths?: ReadonlySet<string>): Promise<{ parsed: number; warnings: string[]; stages: Stages }> {\n const timing = createReconcileTiming(cfg);\n const snapshot = await withTransaction(conn, () => readReconcileSnapshot(conn, timing));\n const plan = await prepareReconcile(snapshot, cfg, paths, dialect, timing, pool, forcedPaths);\n if (!plan.mutated) return { parsed: plan.parsed, warnings: plan.warnings, stages: plan.finish(0) };\n const txStart = Date.now();\n let txMs: number;\n try {\n await withTransaction(conn, () => plan.apply(conn), dialect.beginMode());\n } finally {\n txMs = Date.now() - txStart;\n timing.txMs += txMs;\n }\n await plan.record(conn, txMs);\n return { parsed: plan.parsed, warnings: plan.warnings, stages: plan.finish(timing.txMs) };\n}\n"],"names":["CORE_FRONTMATTER_COLUMNS","createReconcileTiming","prepareReconcile","readReconcileSnapshot","reconcile","Set","cfg","start","process","hrtime","bigint","stages","stageRecorder","activeFeatures","map","feature","name","elapsed","Number","workerParseMs","txMs","conn","timing","existingRows","time","existingStmt","prepare","all","getColumns","seenColumns","snapshot","paths","dialect","pool","forcedPaths","rootDir","configDir","features","files","currentSet","existing","vanished","toReparse","report","parsedDocs","warnings","newColumns","col","allColumns","writableColumns","insertSql","added","delta","addedSet","reparsedExisting","touched","listFiles","f","relPath","Map","r","path","filter","has","row","get","_mtime","mtimeMs","_size","size","length","mutated","parsed","apply","finish","take","record","progress","reparseFiles","tick","docs","add","checkColumnLimit","c","RESERVED_COLUMNS","quoteIdent","join","reparsed","d","p","present","missingColumns","toRow","addColumns","doc","ctimeMs","parseError","data","newDocs","updateDocs","rows","appendRows","updateFrontmatter","runBatch","reconcileContent","source","presetRows","presetName","presets","push","featureStage","remove","docsForFeature","extracted","store","afterReconcile","recordLockWaitMs","recordDuration","plan","txStart","withTransaction","Date","now","beginMode"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/store/shared.ts"],"sourcesContent":["import type { Connection } from './types.ts';\n\n// SQL and meta-table primitives both stores' open()/reconcile() need. Engine-neutral: both\n// stores' Connection satisfies the same async exec/prepare/runBatch shape (types.ts).\n\n// Rows that cannot conflict, at whatever speed this connection offers: the append path where the\n// store has one, else the caller's own guarded `conflictSql` statement bound the ordinary way.\nexport async function appendRows(conn: Connection, table: string, columns: string[], conflictSql: string, rows: unknown[][]): Promise<void> {\n if (rows.length === 0) return;\n if (conn.appendRows) await conn.appendRows(table, columns, rows);\n else await conn.runBatch(conflictSql, rows);\n}\n\nexport function quoteIdent(name: string): string {\n return `\"${name.split('\"').join('\"\"')}\"`;\n}\n\nexport async function getColumns(conn: Connection): Promise<Set<string>> {\n const stmt = await conn.prepare('PRAGMA table_info(frontmatter)');\n const rows = (await stmt.all()) as Array<{ name: string }>;\n return new Set(rows.map((r) => r.name));\n}\n\nexport async function getMeta(conn: Connection, key: string): Promise<string | null> {\n const stmt = await conn.prepare('SELECT value FROM meta WHERE key = ?');\n const row = (await stmt.get(key)) as { value: string } | undefined;\n return row ? row.value : null;\n}\n\nexport async function setMeta(conn: Connection, key: string, value: string | null): Promise<void> {\n if (value === null) {\n const stmt = await conn.prepare('DELETE FROM meta WHERE key = ?');\n await stmt.run(key);\n return;\n }\n const stmt = await conn.prepare('INSERT INTO meta (key, value) VALUES (?, ?) ON CONFLICT(key) DO UPDATE SET value = excluded.value');\n await stmt.run(key, value);\n}\n\n// Reconcile's own write-transaction duration, for open()'s derived busy_timeout: keep the\n// observed max so a big watcher reconcile's lock hold is what the next open bounds its wait against.\nexport async function recordReconcileDuration(conn: Connection, ms: number): Promise<void> {\n const prevRaw = await getMeta(conn, 'reconcile_max_ms');\n // -1, not 0, so a genuinely 0ms first reconcile (sub-millisecond, common on a tiny tree)\n // still gets recorded instead of losing to the \"nothing recorded yet\" default.\n const prevMax = prevRaw === null ? -1 : Number(prevRaw);\n if (ms > prevMax) await setMeta(conn, 'reconcile_max_ms', String(ms));\n}\n"],"names":["appendRows","getColumns","getMeta","quoteIdent","recordReconcileDuration","setMeta","conn","table","columns","conflictSql","rows","length","runBatch","name","split","join","stmt","prepare","all","Set","map","r","key","row","get","value","run","ms","prevRaw","prevMax","Number","String"],"mappings":";;;;;;;;;;;QAOsBA;eAAAA;;QAUAC;eAAAA;;QAMAC;eAAAA;;QAVNC;eAAAA;;QA4BMC;eAAAA;;QAZAC;eAAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAtBf,SAAeL,WAAWM,IAAgB,EAAEC,KAAa,EAAEC,OAAiB,EAAEC,WAAmB,EAAEC,IAAiB;;;;;oBACzH,IAAIA,KAAKC,MAAM,KAAK,GAAG;;;yBACnBL,KAAKN,UAAU,EAAfM;;;;oBAAiB;;wBAAMA,KAAKN,UAAU,CAACO,OAAOC,SAASE;;;oBAAtC;;;;;;oBAChB;;wBAAMJ,KAAKM,QAAQ,CAACH,aAAaC;;;oBAAjC;;;;;;;;IACP;;AAEO,SAASP,WAAWU,IAAY;IACrC,OAAO,AAAC,IAA8B,OAA3BA,KAAKC,KAAK,CAAC,KAAKC,IAAI,CAAC,OAAM;AACxC;AAEO,SAAed,WAAWK,IAAgB;;YACzCU,MACAN;;;;oBADO;;wBAAMJ,KAAKW,OAAO,CAAC;;;oBAA1BD,OAAO;oBACC;;wBAAMA,KAAKE,GAAG;;;oBAAtBR,OAAQ;oBACd;;wBAAO,IAAIS,IAAIT,KAAKU,GAAG,CAAC,SAACC;mCAAMA,EAAER,IAAI;;;;;IACvC;;AAEO,SAAeX,QAAQI,IAAgB,EAAEgB,GAAW;;YACnDN,MACAO;;;;oBADO;;wBAAMjB,KAAKW,OAAO,CAAC;;;oBAA1BD,OAAO;oBACA;;wBAAMA,KAAKQ,GAAG,CAACF;;;oBAAtBC,MAAO;oBACb;;wBAAOA,MAAMA,IAAIE,KAAK,GAAG;;;;IAC3B;;AAEO,SAAepB,QAAQC,IAAgB,EAAEgB,GAAW,EAAEG,KAAoB;;YAEvET,MAIFA;;;;yBALFS,CAAAA,UAAU,IAAG,GAAbA;;;;oBACW;;wBAAMnB,KAAKW,OAAO,CAAC;;;oBAA1BD,OAAO;oBACb;;wBAAMA,KAAKU,GAAG,CAACJ;;;oBAAf;oBACA;;;;oBAEW;;wBAAMhB,KAAKW,OAAO,CAAC;;;oBAA1BD,QAAO;oBACb;;wBAAMA,MAAKU,GAAG,CAACJ,KAAKG;;;oBAApB;;;;;;IACF;;AAIO,SAAerB,wBAAwBE,IAAgB,EAAEqB,EAAU;;YAClEC,SAGAC;;;;oBAHU;;wBAAM3B,QAAQI,MAAM;;;oBAA9BsB,UAAU;oBAChB,yFAAyF;oBACzF,+EAA+E;oBACzEC,UAAUD,YAAY,OAAO,CAAC,IAAIE,OAAOF;yBAC3CD,CAAAA,KAAKE,OAAM,GAAXF;;;;oBAAc;;wBAAMtB,QAAQC,MAAM,oBAAoByB,OAAOJ;;;oBAA/C;;;;;;;;IACpB"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/open-source/ai/sensemaking/src/store/shared.ts"],"sourcesContent":["import type { Connection } from './types.ts';\n\n// SQL and meta-table primitives both stores' open()/reconcile() need. Engine-neutral: both\n// stores' Connection satisfies the same async exec/prepare/runBatch shape (types.ts).\n\n// Rows that cannot conflict, at whatever speed this connection offers: the append path where the\n// store has one, else the caller's own guarded `conflictSql` statement bound the ordinary way.\nexport async function appendRows(conn: Connection, table: string, columns: string[], conflictSql: string, rows: unknown[][]): Promise<void> {\n if (rows.length === 0) return;\n if (conn.appendRows) await conn.appendRows(table, columns, rows);\n else await conn.runBatch(conflictSql, rows);\n}\n\nexport function quoteIdent(name: string): string {\n return `\"${name.split('\"').join('\"\"')}\"`;\n}\n\nexport async function getColumns(conn: Connection): Promise<Set<string>> {\n const stmt = await conn.prepare('PRAGMA table_info(frontmatter)');\n const rows = (await stmt.all()) as Array<{ name: string }>;\n return new Set(rows.map((r) => r.name));\n}\n\nexport async function getMeta(conn: Connection, key: string): Promise<string | null> {\n const stmt = await conn.prepare('SELECT value FROM meta WHERE key = ?');\n const row = (await stmt.get(key)) as { value: string } | undefined;\n return row ? row.value : null;\n}\n\nexport async function setMeta(conn: Connection, key: string, value: string | null): Promise<void> {\n if (value === null) {\n const stmt = await conn.prepare('DELETE FROM meta WHERE key = ?');\n await stmt.run(key);\n return;\n }\n const stmt = await conn.prepare('INSERT INTO meta (key, value) VALUES (?, ?) ON CONFLICT(key) DO UPDATE SET value = excluded.value');\n await stmt.run(key, value);\n}\n\n// Reconcile's own write-transaction duration, for open()'s derived busy_timeout: keep the\n// observed max so a big watcher reconcile's lock hold is what the next open bounds its wait against.\nexport async function recordReconcileDuration(conn: Connection, ms: number): Promise<void> {\n const prevRaw = await getMeta(conn, 'reconcile_max_ms');\n // -1, not 0, so a genuinely 0ms first reconcile (sub-millisecond, common on a tiny tree)\n // still gets recorded instead of losing to the \"nothing recorded yet\" default.\n const prevMax = prevRaw === null ? -1 : Number(prevRaw);\n if (ms > prevMax) await setMeta(conn, 'reconcile_max_ms', String(ms));\n}\n"],"names":["appendRows","getColumns","getMeta","quoteIdent","recordReconcileDuration","setMeta","conn","table","columns","conflictSql","rows","length","runBatch","name","split","join","stmt","prepare","all","Set","map","r","key","row","get","value","run","ms","prevRaw","prevMax","Number","String"],"mappings":";;;;;;;;;;;QAOsBA;eAAAA;;QAUAC;eAAAA;;QAMAC;eAAAA;;QAVNC;eAAAA;;QA4BMC;eAAAA;;QAZAC;eAAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAtBf,SAAeL,WAAWM,IAAgB,EAAEC,KAAa,EAAEC,OAAiB,EAAEC,WAAmB,EAAEC,IAAiB;;;;;oBACzH,IAAIA,KAAKC,MAAM,KAAK,GAAG;;;yBACnBL,KAAKN,UAAU,EAAfM;;;;oBAAiB;;wBAAMA,KAAKN,UAAU,CAACO,OAAOC,SAASE;;;oBAAtC;;;;;;oBAChB;;wBAAMJ,KAAKM,QAAQ,CAACH,aAAaC;;;oBAAjC;;;;;;;;IACP;;AAEO,SAASP,WAAWU,IAAY;IACrC,OAAO,AAAC,IAA8B,OAA3BA,KAAKC,KAAK,CAAC,KAAKC,IAAI,CAAC,OAAM;AACxC;AAEO,SAAed,WAAWK,IAAgB;;YACzCU,MACAN;;;;oBADO;;wBAAMJ,KAAKW,OAAO,CAAC;;;oBAA1BD,OAAO;oBACC;;wBAAMA,KAAKE,GAAG;;;oBAAtBR,OAAQ;oBACd;;wBAAO,IAAIS,IAAIT,KAAKU,GAAG,CAAC,SAACC;mCAAMA,EAAER,IAAI;;;;;IACvC;;AAEO,SAAeX,QAAQI,IAAgB,EAAEgB,GAAW;;YACnDN,MACAO;;;;oBADO;;wBAAMjB,KAAKW,OAAO,CAAC;;;oBAA1BD,OAAO;oBACA;;wBAAMA,KAAKQ,GAAG,CAACF;;;oBAAtBC,MAAO;oBACb;;wBAAOA,MAAMA,IAAIE,KAAK,GAAG;;;;IAC3B;;AAEO,SAAepB,QAAQC,IAAgB,EAAEgB,GAAW,EAAEG,KAAoB;;YAEvET,MAIFA;;;;yBALFS,CAAAA,UAAU,IAAG,GAAbA;;;;oBACW;;wBAAMnB,KAAKW,OAAO,CAAC;;;oBAA1BD,OAAO;oBACb;;wBAAMA,KAAKU,GAAG,CAACJ;;;oBAAf;oBACA;;;;oBAEW;;wBAAMhB,KAAKW,OAAO,CAAC;;;oBAA1BD,QAAO;oBACb;;wBAAMA,MAAKU,GAAG,CAACJ,KAAKG;;;oBAApB;;;;;;IACF;;AAIO,SAAerB,wBAAwBE,IAAgB,EAAEqB,EAAU;;YAClEC,SAGAC;;;;oBAHU;;wBAAM3B,QAAQI,MAAM;;;oBAA9BsB,UAAU;oBAChB,yFAAyF;oBACzF,+EAA+E;oBACzEC,UAAUD,YAAY,OAAO,CAAC,IAAIE,OAAOF;yBAC3CD,CAAAA,KAAKE,OAAM,GAAXF;;;;oBAAc;;wBAAMtB,QAAQC,MAAM,oBAAoByB,OAAOJ;;;oBAA/C;;;;;;;;IACpB"}
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/store/signature.ts"],"sourcesContent":["// Feature-signature comparison for open()'s rebuild-vs-adopt decision (config.featureSignature's\n// format: one `feature:<name>:on|off` segment per feature, embed provider, then one segment per\n// preset). Pure string comparison, no SQL, shared by every store's open dialect.\n\n// Segment keys that moved between two feature signatures. `preset:` and `feature:` segments key\n// on their first two colon-separated parts (e.g. `preset:default`, `feature:tags`) so a change to\n// one preset or one feature is independently detectable; every other segment keys on its prefix alone.\nexport function changedSignatureKeys(before: string, after: string): Set<string> {\n const keyOf = (part: string) => (part.startsWith('preset:') || part.startsWith('feature:') ? part.split(':').slice(0, 2).join(':') : part.split(':')[0]);\n const parse = (sig: string) => new Map(sig.split('|').map((part) => [keyOf(part), part]));\n const a = parse(before);\n const b = parse(after);\n const changed = new Set<string>();\n for (const [key, val] of b) if (a.get(key) !== val) changed.add(key);\n for (const key of a.keys()) if (!b.has(key)) changed.add(key);\n return changed;\n}\n\n// Whether the embed segment only gained its resolved weight identity: same provider and\n// model, no identity recorded before, one now -- adopted into meta without a rebuild.\nexport function embedIdentityAdopted(before: string, after: string): boolean {\n const embedPart = (sig: string) => sig.split('|').find((p) => p.startsWith('embed:'));\n const b = embedPart(before);\n const a = embedPart(after);\n if (b === undefined || a === undefined) return false;\n const at = a.indexOf('@');\n return b.indexOf('@') === -1 && at !== -1 && a.slice(0, at) === b;\n}\n\n// Embedding work captured against an unresolved static-model signature may finish under the\n// same model after its weight identity is known. Every published read still requires exactness.\nexport function embeddingSignatureCompatible(expected: string | null, actual: string): boolean {\n if (expected === actual) return true;\n if (expected === null) return false;\n const changed = changedSignatureKeys(expected, actual);\n return changed.size === 1 && changed.has('embed') && embedIdentityAdopted(expected, actual);\n}\n\n// Names what moved, for the rebuild notice.\nexport function signatureDiff(before: string, after: string): string {\n const changed = changedSignatureKeys(before, after);\n const label = (key: string) => (key === 'embed' ? 'embed settings' : key.startsWith('preset:') ? `preset \"${key.slice(7)}\"` : key.startsWith('feature:') ? `feature \"${key.slice(8)}\"` : 'features');\n return changed.size === 0 ? 'features' : [...changed].map(label).join(', ');\n}\n"],"names":["changedSignatureKeys","embedIdentityAdopted","embeddingSignatureCompatible","signatureDiff","before","after","keyOf","part","startsWith","split","slice","join","parse","sig","Map","map","a","b","changed","Set","key","val","get","add","keys","has","embedPart","find","p","undefined","at","indexOf","expected","actual","size","label"],"mappings":"AAAA,iGAAiG;AACjG,gGAAgG;AAChG,iFAAiF;AAEjF,gGAAgG;AAChG,kGAAkG;AAClG,uGAAuG;;;;;;;;;;;;QACvFA;eAAAA;;QAaAC;eAAAA;;QAWAC;eAAAA;;QAQAC;eAAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAhCT,SAASH,qBAAqBI,MAAc,EAAEC,KAAa;IAChE,IAAMC,QAAQ,eAACC;eAAkBA,KAAKC,UAAU,CAAC,cAAcD,KAAKC,UAAU,CAAC,cAAcD,KAAKE,KAAK,CAAC,KAAKC,KAAK,CAAC,GAAG,GAAGC,IAAI,CAAC,OAAOJ,KAAKE,KAAK,CAAC,IAAI,CAAC,EAAE;;IACvJ,IAAMG,QAAQ,eAACC;eAAgB,IAAIC,IAAID,IAAIJ,KAAK,CAAC,KAAKM,GAAG,CAAC,SAACR;mBAAS;gBAACD,MAAMC;gBAAOA;aAAK;;;IACvF,IAAMS,IAAIJ,MAAMR;IAChB,IAAMa,IAAIL,MAAMP;IAChB,IAAMa,UAAU,IAAIC;QACf,kCAAA,2BAAA;;QAAL,QAAK,YAAoBF,sBAApB,SAAA,6BAAA,QAAA,yBAAA;YAAA,mCAAA,iBAAOG,sBAAKC;YAAW,IAAIL,EAAEM,GAAG,CAACF,SAASC,KAAKH,QAAQK,GAAG,CAACH;;;QAA3D;QAAA;;;iBAAA,6BAAA;gBAAA;;;gBAAA;sBAAA;;;;QACA,mCAAA,4BAAA;;QAAL,QAAK,aAAaJ,EAAEQ,IAAI,uBAAnB,UAAA,8BAAA,SAAA,0BAAA;YAAA,IAAMJ,OAAN;YAAuB,IAAI,CAACH,EAAEQ,GAAG,CAACL,OAAMF,QAAQK,GAAG,CAACH;;;QAApD;QAAA;;;iBAAA,8BAAA;gBAAA;;;gBAAA;sBAAA;;;;IACL,OAAOF;AACT;AAIO,SAASjB,qBAAqBG,MAAc,EAAEC,KAAa;IAChE,IAAMqB,YAAY,mBAACb;eAAgBA,IAAIJ,KAAK,CAAC,KAAKkB,IAAI,CAAC,SAACC;mBAAMA,EAAEpB,UAAU,CAAC;;;IAC3E,IAAMS,IAAIS,UAAUtB;IACpB,IAAMY,IAAIU,UAAUrB;IACpB,IAAIY,MAAMY,aAAab,MAAMa,WAAW,OAAO;IAC/C,IAAMC,KAAKd,EAAEe,OAAO,CAAC;IACrB,OAAOd,EAAEc,OAAO,CAAC,SAAS,CAAC,KAAKD,OAAO,CAAC,KAAKd,EAAEN,KAAK,CAAC,GAAGoB,QAAQb;AAClE;AAIO,SAASf,6BAA6B8B,QAAuB,EAAEC,MAAc;IAClF,IAAID,aAAaC,QAAQ,OAAO;IAChC,IAAID,aAAa,MAAM,OAAO;IAC9B,IAAMd,UAAUlB,qBAAqBgC,UAAUC;IAC/C,OAAOf,QAAQgB,IAAI,KAAK,KAAKhB,QAAQO,GAAG,CAAC,YAAYxB,qBAAqB+B,UAAUC;AACtF;AAGO,SAAS9B,cAAcC,MAAc,EAAEC,KAAa;IACzD,IAAMa,UAAUlB,qBAAqBI,QAAQC;IAC7C,IAAM8B,QAAQ,eAACf;eAAiBA,QAAQ,UAAU,mBAAmBA,IAAIZ,UAAU,CAAC,aAAa,AAAC,WAAuB,OAAbY,IAAIV,KAAK,CAAC,IAAG,OAAKU,IAAIZ,UAAU,CAAC,cAAc,AAAC,YAAwB,OAAbY,IAAIV,KAAK,CAAC,IAAG,OAAK;;IACzL,OAAOQ,QAAQgB,IAAI,KAAK,IAAI,aAAa,AAAC,qBAAGhB,SAASH,GAAG,CAACoB,OAAOxB,IAAI,CAAC;AACxE"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/open-source/ai/sensemaking/src/store/signature.ts"],"sourcesContent":["// Feature-signature comparison for open()'s rebuild-vs-adopt decision (config.featureSignature's\n// format: one `feature:<name>:on|off` segment per feature, embed provider, then one segment per\n// preset). Pure string comparison, no SQL, shared by every store's open dialect.\n\n// Segment keys that moved between two feature signatures. `preset:` and `feature:` segments key\n// on their first two colon-separated parts (e.g. `preset:default`, `feature:tags`) so a change to\n// one preset or one feature is independently detectable; every other segment keys on its prefix alone.\nexport function changedSignatureKeys(before: string, after: string): Set<string> {\n const keyOf = (part: string) => (part.startsWith('preset:') || part.startsWith('feature:') ? part.split(':').slice(0, 2).join(':') : part.split(':')[0]);\n const parse = (sig: string) => new Map(sig.split('|').map((part) => [keyOf(part), part]));\n const a = parse(before);\n const b = parse(after);\n const changed = new Set<string>();\n for (const [key, val] of b) if (a.get(key) !== val) changed.add(key);\n for (const key of a.keys()) if (!b.has(key)) changed.add(key);\n return changed;\n}\n\n// Whether the embed segment only gained its resolved weight identity: same provider and\n// model, no identity recorded before, one now -- adopted into meta without a rebuild.\nexport function embedIdentityAdopted(before: string, after: string): boolean {\n const embedPart = (sig: string) => sig.split('|').find((p) => p.startsWith('embed:'));\n const b = embedPart(before);\n const a = embedPart(after);\n if (b === undefined || a === undefined) return false;\n const at = a.indexOf('@');\n return b.indexOf('@') === -1 && at !== -1 && a.slice(0, at) === b;\n}\n\n// Embedding work captured against an unresolved static-model signature may finish under the\n// same model after its weight identity is known. Every published read still requires exactness.\nexport function embeddingSignatureCompatible(expected: string | null, actual: string): boolean {\n if (expected === actual) return true;\n if (expected === null) return false;\n const changed = changedSignatureKeys(expected, actual);\n return changed.size === 1 && changed.has('embed') && embedIdentityAdopted(expected, actual);\n}\n\n// Names what moved, for the rebuild notice.\nexport function signatureDiff(before: string, after: string): string {\n const changed = changedSignatureKeys(before, after);\n const label = (key: string) => (key === 'embed' ? 'embed settings' : key.startsWith('preset:') ? `preset \"${key.slice(7)}\"` : key.startsWith('feature:') ? `feature \"${key.slice(8)}\"` : 'features');\n return changed.size === 0 ? 'features' : [...changed].map(label).join(', ');\n}\n"],"names":["changedSignatureKeys","embedIdentityAdopted","embeddingSignatureCompatible","signatureDiff","before","after","keyOf","part","startsWith","split","slice","join","parse","sig","Map","map","a","b","changed","Set","key","val","get","add","keys","has","embedPart","find","p","undefined","at","indexOf","expected","actual","size","label"],"mappings":"AAAA,iGAAiG;AACjG,gGAAgG;AAChG,iFAAiF;AAEjF,gGAAgG;AAChG,kGAAkG;AAClG,uGAAuG;;;;;;;;;;;;QACvFA;eAAAA;;QAaAC;eAAAA;;QAWAC;eAAAA;;QAQAC;eAAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAhCT,SAASH,qBAAqBI,MAAc,EAAEC,KAAa;IAChE,IAAMC,QAAQ,eAACC;eAAkBA,KAAKC,UAAU,CAAC,cAAcD,KAAKC,UAAU,CAAC,cAAcD,KAAKE,KAAK,CAAC,KAAKC,KAAK,CAAC,GAAG,GAAGC,IAAI,CAAC,OAAOJ,KAAKE,KAAK,CAAC,IAAI,CAAC,EAAE;;IACvJ,IAAMG,QAAQ,eAACC;eAAgB,IAAIC,IAAID,IAAIJ,KAAK,CAAC,KAAKM,GAAG,CAAC,SAACR;mBAAS;gBAACD,MAAMC;gBAAOA;aAAK;;;IACvF,IAAMS,IAAIJ,MAAMR;IAChB,IAAMa,IAAIL,MAAMP;IAChB,IAAMa,UAAU,IAAIC;QACf,kCAAA,2BAAA;;QAAL,QAAK,YAAoBF,sBAApB,SAAA,6BAAA,QAAA,yBAAA;YAAA,mCAAA,iBAAOG,sBAAKC;YAAW,IAAIL,EAAEM,GAAG,CAACF,SAASC,KAAKH,QAAQK,GAAG,CAACH;;;QAA3D;QAAA;;;iBAAA,6BAAA;gBAAA;;;gBAAA;sBAAA;;;;QACA,mCAAA,4BAAA;;QAAL,QAAK,aAAaJ,EAAEQ,IAAI,uBAAnB,UAAA,8BAAA,SAAA,0BAAA;YAAA,IAAMJ,OAAN;YAAuB,IAAI,CAACH,EAAEQ,GAAG,CAACL,OAAMF,QAAQK,GAAG,CAACH;;;QAApD;QAAA;;;iBAAA,8BAAA;gBAAA;;;gBAAA;sBAAA;;;;IACL,OAAOF;AACT;AAIO,SAASjB,qBAAqBG,MAAc,EAAEC,KAAa;IAChE,IAAMqB,YAAY,mBAACb;eAAgBA,IAAIJ,KAAK,CAAC,KAAKkB,IAAI,CAAC,SAACC;mBAAMA,EAAEpB,UAAU,CAAC;;;IAC3E,IAAMS,IAAIS,UAAUtB;IACpB,IAAMY,IAAIU,UAAUrB;IACpB,IAAIY,MAAMY,aAAab,MAAMa,WAAW,OAAO;IAC/C,IAAMC,KAAKd,EAAEe,OAAO,CAAC;IACrB,OAAOd,EAAEc,OAAO,CAAC,SAAS,CAAC,KAAKD,OAAO,CAAC,KAAKd,EAAEN,KAAK,CAAC,GAAGoB,QAAQb;AAClE;AAIO,SAASf,6BAA6B8B,QAAuB,EAAEC,MAAc;IAClF,IAAID,aAAaC,QAAQ,OAAO;IAChC,IAAID,aAAa,MAAM,OAAO;IAC9B,IAAMd,UAAUlB,qBAAqBgC,UAAUC;IAC/C,OAAOf,QAAQgB,IAAI,KAAK,KAAKhB,QAAQO,GAAG,CAAC,YAAYxB,qBAAqB+B,UAAUC;AACtF;AAGO,SAAS9B,cAAcC,MAAc,EAAEC,KAAa;IACzD,IAAMa,UAAUlB,qBAAqBI,QAAQC;IAC7C,IAAM8B,QAAQ,eAACf;eAAiBA,QAAQ,UAAU,mBAAmBA,IAAIZ,UAAU,CAAC,aAAa,AAAC,WAAuB,OAAbY,IAAIV,KAAK,CAAC,IAAG,OAAKU,IAAIZ,UAAU,CAAC,cAAc,AAAC,YAAwB,OAAbY,IAAIV,KAAK,CAAC,IAAG,OAAK;;IACzL,OAAOQ,QAAQgB,IAAI,KAAK,IAAI,aAAa,AAAC,qBAAGhB,SAASH,GAAG,CAACoB,OAAOxB,IAAI,CAAC;AACxE"}
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/store/sql-functions.ts"],"sourcesContent":["import posix from 'node:path/posix';\n\n// has(field, value) / basename(path, suffix): the two sense-supplied SQL functions with no\n// engine-specific pieces, registered identically by each store instead of a hand-copied one.\n\n// JSON-array field -> membership, string field -> substring, NULL -> false.\nexport function hasImpl(field: unknown, value: unknown): number {\n if (field === null || field === undefined) return 0;\n const needle = String(value);\n if (typeof field === 'string') {\n if (field.startsWith('[')) {\n try {\n const parsed = JSON.parse(field);\n if (Array.isArray(parsed)) return parsed.some((item) => String(item) === needle) ? 1 : 0;\n } catch {}\n }\n return field.includes(needle) ? 1 : 0;\n }\n return String(field).includes(needle) ? 1 : 0;\n}\n\n// Unix basename(path, suffix?): the filename, minus suffix when it ends with one. Neither engine\n// has a filename function of its own, and LIKE tricks that fake one also match folder names.\nexport function basenameImpl(path: unknown, suffix?: unknown): string | null {\n if (path === null || path === undefined) return null;\n const name = posix.basename(String(path));\n const tail = suffix === null || suffix === undefined ? '' : String(suffix);\n // POSIX: a suffix identical to the whole name is not removed (node's own basename strips it).\n return tail !== '' && tail !== name && name.endsWith(tail) ? name.slice(0, -tail.length) : name;\n}\n"],"names":["basenameImpl","hasImpl","field","value","undefined","needle","String","startsWith","parsed","JSON","parse","Array","isArray","some","item","includes","path","suffix","name","posix","basename","tail","endsWith","slice","length"],"mappings":";;;;;;;;;;;QAuBgBA;eAAAA;;QAjBAC;eAAAA;;;4DANE;;;;;;AAMX,SAASA,QAAQC,KAAc,EAAEC,KAAc;IACpD,IAAID,UAAU,QAAQA,UAAUE,WAAW,OAAO;IAClD,IAAMC,SAASC,OAAOH;IACtB,IAAI,OAAOD,UAAU,UAAU;QAC7B,IAAIA,MAAMK,UAAU,CAAC,MAAM;YACzB,IAAI;gBACF,IAAMC,SAASC,KAAKC,KAAK,CAACR;gBAC1B,IAAIS,MAAMC,OAAO,CAACJ,SAAS,OAAOA,OAAOK,IAAI,CAAC,SAACC;2BAASR,OAAOQ,UAAUT;qBAAU,IAAI;YACzF,EAAE,eAAM,CAAC;QACX;QACA,OAAOH,MAAMa,QAAQ,CAACV,UAAU,IAAI;IACtC;IACA,OAAOC,OAAOJ,OAAOa,QAAQ,CAACV,UAAU,IAAI;AAC9C;AAIO,SAASL,aAAagB,IAAa,EAAEC,MAAgB;IAC1D,IAAID,SAAS,QAAQA,SAASZ,WAAW,OAAO;IAChD,IAAMc,OAAOC,cAAK,CAACC,QAAQ,CAACd,OAAOU;IACnC,IAAMK,OAAOJ,WAAW,QAAQA,WAAWb,YAAY,KAAKE,OAAOW;IACnE,8FAA8F;IAC9F,OAAOI,SAAS,MAAMA,SAASH,QAAQA,KAAKI,QAAQ,CAACD,QAAQH,KAAKK,KAAK,CAAC,GAAG,CAACF,KAAKG,MAAM,IAAIN;AAC7F"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/open-source/ai/sensemaking/src/store/sql-functions.ts"],"sourcesContent":["import posix from 'node:path/posix';\n\n// has(field, value) / basename(path, suffix): the two sense-supplied SQL functions with no\n// engine-specific pieces, registered identically by each store instead of a hand-copied one.\n\n// JSON-array field -> membership, string field -> substring, NULL -> false.\nexport function hasImpl(field: unknown, value: unknown): number {\n if (field === null || field === undefined) return 0;\n const needle = String(value);\n if (typeof field === 'string') {\n if (field.startsWith('[')) {\n try {\n const parsed = JSON.parse(field);\n if (Array.isArray(parsed)) return parsed.some((item) => String(item) === needle) ? 1 : 0;\n } catch {}\n }\n return field.includes(needle) ? 1 : 0;\n }\n return String(field).includes(needle) ? 1 : 0;\n}\n\n// Unix basename(path, suffix?): the filename, minus suffix when it ends with one. Neither engine\n// has a filename function of its own, and LIKE tricks that fake one also match folder names.\nexport function basenameImpl(path: unknown, suffix?: unknown): string | null {\n if (path === null || path === undefined) return null;\n const name = posix.basename(String(path));\n const tail = suffix === null || suffix === undefined ? '' : String(suffix);\n // POSIX: a suffix identical to the whole name is not removed (node's own basename strips it).\n return tail !== '' && tail !== name && name.endsWith(tail) ? name.slice(0, -tail.length) : name;\n}\n"],"names":["basenameImpl","hasImpl","field","value","undefined","needle","String","startsWith","parsed","JSON","parse","Array","isArray","some","item","includes","path","suffix","name","posix","basename","tail","endsWith","slice","length"],"mappings":";;;;;;;;;;;QAuBgBA;eAAAA;;QAjBAC;eAAAA;;;4DANE;;;;;;AAMX,SAASA,QAAQC,KAAc,EAAEC,KAAc;IACpD,IAAID,UAAU,QAAQA,UAAUE,WAAW,OAAO;IAClD,IAAMC,SAASC,OAAOH;IACtB,IAAI,OAAOD,UAAU,UAAU;QAC7B,IAAIA,MAAMK,UAAU,CAAC,MAAM;YACzB,IAAI;gBACF,IAAMC,SAASC,KAAKC,KAAK,CAACR;gBAC1B,IAAIS,MAAMC,OAAO,CAACJ,SAAS,OAAOA,OAAOK,IAAI,CAAC,SAACC;2BAASR,OAAOQ,UAAUT;qBAAU,IAAI;YACzF,EAAE,eAAM,CAAC;QACX;QACA,OAAOH,MAAMa,QAAQ,CAACV,UAAU,IAAI;IACtC;IACA,OAAOC,OAAOJ,OAAOa,QAAQ,CAACV,UAAU,IAAI;AAC9C;AAIO,SAASL,aAAagB,IAAa,EAAEC,MAAgB;IAC1D,IAAID,SAAS,QAAQA,SAASZ,WAAW,OAAO;IAChD,IAAMc,OAAOC,cAAK,CAACC,QAAQ,CAACd,OAAOU;IACnC,IAAMK,OAAOJ,WAAW,QAAQA,WAAWb,YAAY,KAAKE,OAAOW;IACnE,8FAA8F;IAC9F,OAAOI,SAAS,MAAMA,SAASH,QAAQA,KAAKI,QAAQ,CAACD,QAAQH,KAAKK,KAAK,CAAC,GAAG,CAACF,KAAKG,MAAM,IAAIN;AAC7F"}
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/store/sqlite/connection.ts"],"sourcesContent":["import type { DatabaseSync, StatementSync } from 'node:sqlite';\nimport { BEGIN_WRITE, withTransaction } from '../transaction.ts';\nimport type { Connection, RunResult, Statement } from '../types.ts';\n\n// Wraps node:sqlite's synchronous DatabaseSync in the async Connection/Statement shape every store presents. Every method does its real\n// work synchronously and returns an already-resolved promise, so reconcile's loop, the feature hooks, and runBatch never cross an async boundary internally.\nclass SqliteStatement implements Statement {\n private stmt: StatementSync;\n\n constructor(stmt: StatementSync) {\n this.stmt = stmt;\n }\n\n async run(...params: unknown[]): Promise<RunResult> {\n return this.stmt.run(...(params as Parameters<StatementSync['run']>));\n }\n\n async get(...params: unknown[]): Promise<unknown> {\n return this.stmt.get(...(params as Parameters<StatementSync['get']>));\n }\n\n async all(...params: unknown[]): Promise<unknown[]> {\n return this.stmt.all(...(params as Parameters<StatementSync['all']>));\n }\n\n async *iterate(...params: unknown[]): AsyncIterable<unknown> {\n yield* this.stmt.iterate(...(params as Parameters<StatementSync['iterate']>));\n }\n\n columns(): Array<{ name: string }> {\n return this.stmt.columns();\n }\n\n setReadBigInts(enabled: boolean): void {\n this.stmt.setReadBigInts(enabled);\n }\n}\n\nexport function createConnection(db: DatabaseSync): Connection {\n const conn: Connection = {\n async exec(sql: string): Promise<void> {\n db.exec(sql);\n },\n async prepare(sql: string): Promise<Statement> {\n return new SqliteStatement(db.prepare(sql));\n },\n // Prepares once and loops synchronously, wrapped as one async call so features share one\n // Connection contract with DuckDB. Joins the caller's transaction when there is one (reconcile); otherwise opens its own, so a standalone batch stays atomic and commits once, not per row.\n async runBatch(sql: string, paramRows: unknown[][]): Promise<void> {\n if (paramRows.length === 0) return;\n await withTransaction(\n conn,\n async () => {\n const stmt = db.prepare(sql);\n for (const row of paramRows) stmt.run(...(row as Parameters<StatementSync['run']>));\n },\n BEGIN_WRITE\n );\n },\n };\n return conn;\n}\n"],"names":["createConnection","SqliteStatement","stmt","run","params","get","all","iterate","columns","setReadBigInts","enabled","db","conn","exec","sql","prepare","runBatch","paramRows","length","withTransaction","row","BEGIN_WRITE"],"mappings":"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"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/open-source/ai/sensemaking/src/store/sqlite/connection.ts"],"sourcesContent":["import type { DatabaseSync, StatementSync } from 'node:sqlite';\nimport { BEGIN_WRITE, withTransaction } from '../transaction.ts';\nimport type { Connection, RunResult, Statement } from '../types.ts';\n\n// Wraps node:sqlite's synchronous DatabaseSync in the async Connection/Statement shape every store presents. Every method does its real\n// work synchronously and returns an already-resolved promise, so reconcile's loop, the feature hooks, and runBatch never cross an async boundary internally.\nclass SqliteStatement implements Statement {\n private stmt: StatementSync;\n\n constructor(stmt: StatementSync) {\n this.stmt = stmt;\n }\n\n async run(...params: unknown[]): Promise<RunResult> {\n return this.stmt.run(...(params as Parameters<StatementSync['run']>));\n }\n\n async get(...params: unknown[]): Promise<unknown> {\n return this.stmt.get(...(params as Parameters<StatementSync['get']>));\n }\n\n async all(...params: unknown[]): Promise<unknown[]> {\n return this.stmt.all(...(params as Parameters<StatementSync['all']>));\n }\n\n async *iterate(...params: unknown[]): AsyncIterable<unknown> {\n yield* this.stmt.iterate(...(params as Parameters<StatementSync['iterate']>));\n }\n\n columns(): Array<{ name: string }> {\n return this.stmt.columns();\n }\n\n setReadBigInts(enabled: boolean): void {\n this.stmt.setReadBigInts(enabled);\n }\n}\n\nexport function createConnection(db: DatabaseSync): Connection {\n const conn: Connection = {\n async exec(sql: string): Promise<void> {\n db.exec(sql);\n },\n async prepare(sql: string): Promise<Statement> {\n return new SqliteStatement(db.prepare(sql));\n },\n // Prepares once and loops synchronously, wrapped as one async call so features share one\n // Connection contract with DuckDB. Joins the caller's transaction when there is one (reconcile); otherwise opens its own, so a standalone batch stays atomic and commits once, not per row.\n async runBatch(sql: string, paramRows: unknown[][]): Promise<void> {\n if (paramRows.length === 0) return;\n await withTransaction(\n conn,\n async () => {\n const stmt = db.prepare(sql);\n for (const row of paramRows) stmt.run(...(row as Parameters<StatementSync['run']>));\n },\n BEGIN_WRITE\n );\n },\n };\n return conn;\n}\n"],"names":["createConnection","SqliteStatement","stmt","run","params","get","all","iterate","columns","setReadBigInts","enabled","db","conn","exec","sql","prepare","runBatch","paramRows","length","withTransaction","row","BEGIN_WRITE"],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import { type EnginePatch } from '../engine.js';
2
+ export declare const SQLITE_ENGINE = "node:sqlite";
3
+ export declare const SQLITE_VERSION: string | undefined;
4
+ export declare const TOKENIZE = "porter unicode61";
5
+ export interface SqliteFtsBuilders {
6
+ createContent(): string;
7
+ rankedMatch(whereJoin: string, whereCond: string, scopeCond: string, limit: number): string;
8
+ }
9
+ export declare const SQLITE_FTS_BUILDERS: SqliteFtsBuilders;
10
+ export declare const SQLITE_PATCHES: readonly EnginePatch<SqliteFtsBuilders>[];
11
+ export declare const sqliteIdentity: () => string;
12
+ export declare function sqliteFts(): SqliteFtsBuilders;
@@ -0,0 +1,12 @@
1
+ import { type EnginePatch } from '../engine.js';
2
+ export declare const SQLITE_ENGINE = "node:sqlite";
3
+ export declare const SQLITE_VERSION: string | undefined;
4
+ export declare const TOKENIZE = "porter unicode61";
5
+ export interface SqliteFtsBuilders {
6
+ createContent(): string;
7
+ rankedMatch(whereJoin: string, whereCond: string, scopeCond: string, limit: number): string;
8
+ }
9
+ export declare const SQLITE_FTS_BUILDERS: SqliteFtsBuilders;
10
+ export declare const SQLITE_PATCHES: readonly EnginePatch<SqliteFtsBuilders>[];
11
+ export declare const sqliteIdentity: () => string;
12
+ export declare function sqliteFts(): SqliteFtsBuilders;
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ function _export(target, all) {
6
+ for(var name in all)Object.defineProperty(target, name, {
7
+ enumerable: true,
8
+ get: Object.getOwnPropertyDescriptor(all, name).get
9
+ });
10
+ }
11
+ _export(exports, {
12
+ get SQLITE_ENGINE () {
13
+ return SQLITE_ENGINE;
14
+ },
15
+ get SQLITE_FTS_BUILDERS () {
16
+ return SQLITE_FTS_BUILDERS;
17
+ },
18
+ get SQLITE_PATCHES () {
19
+ return SQLITE_PATCHES;
20
+ },
21
+ get SQLITE_VERSION () {
22
+ return SQLITE_VERSION;
23
+ },
24
+ get TOKENIZE () {
25
+ return TOKENIZE;
26
+ },
27
+ get sqliteFts () {
28
+ return sqliteFts;
29
+ },
30
+ get sqliteIdentity () {
31
+ return sqliteIdentity;
32
+ }
33
+ });
34
+ var _enginets = require("../engine.js");
35
+ var SQLITE_ENGINE = 'node:sqlite';
36
+ var SQLITE_VERSION = process.versions.sqlite;
37
+ var TOKENIZE = 'porter unicode61';
38
+ var SQLITE_FTS_BUILDERS = {
39
+ createContent: function createContent() {
40
+ return "CREATE VIRTUAL TABLE IF NOT EXISTS content USING fts5(title, summary, text, path UNINDEXED, title_seg, summary_seg, text_seg, tokenize = '".concat(TOKENIZE, "')");
41
+ },
42
+ rankedMatch: function rankedMatch(whereJoin, whereCond, scopeCond, limit) {
43
+ return "SELECT content.path AS path FROM content ".concat(whereJoin, " WHERE content MATCH ? ").concat(whereCond, " ").concat(scopeCond, " ORDER BY bm25(content, 10.0, 5.0, 1.0, 0, 10.0, 5.0, 1.0) LIMIT ").concat(limit);
44
+ }
45
+ };
46
+ var SQLITE_PATCHES = [];
47
+ var sqliteIdentity = function sqliteIdentity() {
48
+ return (0, _enginets.engineIdentity)(SQLITE_ENGINE, SQLITE_VERSION);
49
+ };
50
+ function sqliteFts() {
51
+ return (0, _enginets.selectBuilders)(SQLITE_FTS_BUILDERS, SQLITE_PATCHES, SQLITE_VERSION);
52
+ }
53
+ /* CJS INTEROP */ if (exports.__esModule && exports.default) { try { Object.defineProperty(exports.default, '__esModule', { value: true }); for (var key in exports) { exports.default[key] = exports[key]; } } catch (_) {}; module.exports = exports.default; }
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/Users/kevin/Dev/open-source/ai/sensemaking/src/store/sqlite/engine.ts"],"sourcesContent":["import { type EnginePatch, engineIdentity, selectBuilders } from '../engine.ts';\n\n// node:sqlite is Node's bundled SQLite, so its version changes with Node rather than with an npm install.\nexport const SQLITE_ENGINE = 'node:sqlite';\nexport const SQLITE_VERSION: string | undefined = process.versions.sqlite;\n\n// unicode61 splits on spaces, so a language written without them indexes a whole run as one\n// token and word search finds nothing; the `_seg` sidecars (always populated) cover that case.\nexport const TOKENIZE = 'porter unicode61';\n\n// Every FTS5 statement this store depends on; a SQLite version that behaves differently gets a SQLITE_PATCHES entry.\nexport interface SqliteFtsBuilders {\n // The `_seg` sidecars are appended after path, never inserted: bm25() and snippet(content, 2)\n // are documented against the first three columns. Each holds its field's exploded unspaced runs.\n createContent(): string;\n // One bound parameter, the FTS5 MATCH expression; ranked by field-weighted bm25.\n rankedMatch(whereJoin: string, whereCond: string, scopeCond: string, limit: number): string;\n}\n\nexport const SQLITE_FTS_BUILDERS: SqliteFtsBuilders = {\n createContent: () => `CREATE VIRTUAL TABLE IF NOT EXISTS content USING fts5(title, summary, text, path UNINDEXED, title_seg, summary_seg, text_seg, tokenize = '${TOKENIZE}')`,\n rankedMatch: (whereJoin, whereCond, scopeCond, limit) => `SELECT content.path AS path FROM content ${whereJoin} WHERE content MATCH ? ${whereCond} ${scopeCond} ORDER BY bm25(content, 10.0, 5.0, 1.0, 0, 10.0, 5.0, 1.0) LIMIT ${limit}`,\n};\n\nexport const SQLITE_PATCHES: readonly EnginePatch<SqliteFtsBuilders>[] = [];\n\nexport const sqliteIdentity = (): string => engineIdentity(SQLITE_ENGINE, SQLITE_VERSION);\n\nexport function sqliteFts(): SqliteFtsBuilders {\n return selectBuilders(SQLITE_FTS_BUILDERS, SQLITE_PATCHES, SQLITE_VERSION);\n}\n"],"names":["SQLITE_ENGINE","SQLITE_FTS_BUILDERS","SQLITE_PATCHES","SQLITE_VERSION","TOKENIZE","sqliteFts","sqliteIdentity","process","versions","sqlite","createContent","rankedMatch","whereJoin","whereCond","scopeCond","limit","engineIdentity","selectBuilders"],"mappings":";;;;;;;;;;;QAGaA;eAAAA;;QAgBAC;eAAAA;;QAKAC;eAAAA;;QApBAC;eAAAA;;QAIAC;eAAAA;;QAoBGC;eAAAA;;QAFHC;eAAAA;;;wBA1BoD;AAG1D,IAAMN,gBAAgB;AACtB,IAAMG,iBAAqCI,QAAQC,QAAQ,CAACC,MAAM;AAIlE,IAAML,WAAW;AAWjB,IAAMH,sBAAyC;IACpDS,eAAe,SAAfA;eAAqB,AAAC,6IAAqJ,OAATN,UAAS;;IAC3KO,aAAa,SAAbA,YAAcC,WAAWC,WAAWC,WAAWC;eAAU,AAAC,4CAA8EF,OAAnCD,WAAU,2BAAsCE,OAAbD,WAAU,KAAgFE,OAA7ED,WAAU,qEAAyE,OAANC;;AACpO;AAEO,IAAMb,iBAA4D,EAAE;AAEpE,IAAMI,iBAAiB;WAAcU,IAAAA,wBAAc,EAAChB,eAAeG;;AAEnE,SAASE;IACd,OAAOY,IAAAA,wBAAc,EAAChB,qBAAqBC,gBAAgBC;AAC7D"}
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/store/sqlite/fieldStats.ts"],"sourcesContent":["import { quoteIdent } from '../shared.ts';\nimport type { Connection, FieldStat } from '../types.ts';\n\n// One aggregate query per column (COUNT + GROUP_CONCAT(DISTINCT typeof())), O(columns) not O(rows x columns);\n// typeof()'s output is already the shared vocabulary, and GROUP_CONCAT's order is unsorted, so JS sorts the type set.\nexport async function fieldStats(conn: Connection, columns: string[], scopeWhere: string): Promise<FieldStat[]> {\n const exprs = columns.map((name, i) => {\n const quoted = quoteIdent(name);\n return `COUNT(${quoted}) AS n${i}, GROUP_CONCAT(DISTINCT typeof(${quoted})) FILTER (WHERE ${quoted} IS NOT NULL) AS t${i}`;\n });\n const stmt = await conn.prepare(`SELECT ${exprs.join(', ')} FROM frontmatter ${scopeWhere}`);\n const row = (await stmt.get()) as Record<string, number | string | null>;\n return columns.map((name, i) => ({\n field: name,\n coverage: Number(row[`n${i}`] ?? 0),\n type: [...new Set(((row[`t${i}`] as string) ?? '').split(',').filter(Boolean))].sort().join(','),\n }));\n}\n"],"names":["fieldStats","conn","columns","scopeWhere","exprs","stmt","row","map","name","i","quoted","quoteIdent","prepare","join","get","field","coverage","Number","type","Set","split","filter","Boolean","sort"],"mappings":";;;;+BAKsBA;;;eAAAA;;;wBALK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAKpB,SAAeA,WAAWC,IAAgB,EAAEC,OAAiB,EAAEC,UAAkB;;YAChFC,OAIAC,MACAC;;;;oBALAF,QAAQF,QAAQK,GAAG,CAAC,SAACC,MAAMC;wBAC/B,IAAMC,SAASC,IAAAA,oBAAU,EAACH;wBAC1B,OAAO,AAAC,SAAuBC,OAAfC,QAAO,UAA2CA,OAAnCD,GAAE,mCAA2DC,OAA1BA,QAAO,qBAA8CD,OAA3BC,QAAO,sBAAsB,OAAFD;oBACzH;oBACa;;wBAAMR,KAAKW,OAAO,CAAC,AAAC,UAA8CT,OAArCC,MAAMS,IAAI,CAAC,OAAM,sBAA+B,OAAXV;;;oBAAzEE,OAAO;oBACA;;wBAAMA,KAAKS,GAAG;;;oBAArBR,MAAO;oBACb;;wBAAOJ,QAAQK,GAAG,CAAC,SAACC,MAAMC;gCAEPH,OACGA;mCAHW;gCAC/BS,OAAOP;gCACPQ,UAAUC,QAAOX,QAAAA,GAAG,CAAC,AAAC,IAAK,OAAFG,GAAI,cAAZH,mBAAAA,QAAgB;gCACjCY,MAAM,AAAC,qBAAG,IAAIC,IAAI,EAAEb,SAAAA,GAAG,CAAC,AAAC,IAAK,OAAFG,GAAI,cAAZH,oBAAAA,SAA2B,IAAIc,KAAK,CAAC,KAAKC,MAAM,CAACC,WAAWC,IAAI,GAAGV,IAAI,CAAC;4BAC9F;;;;;IACF"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/open-source/ai/sensemaking/src/store/sqlite/fieldStats.ts"],"sourcesContent":["import { quoteIdent } from '../shared.ts';\nimport type { Connection, FieldStat } from '../types.ts';\n\n// One aggregate query per column (COUNT + GROUP_CONCAT(DISTINCT typeof())), O(columns) not O(rows x columns);\n// typeof()'s output is already the shared vocabulary, and GROUP_CONCAT's order is unsorted, so JS sorts the type set.\nexport async function fieldStats(conn: Connection, columns: string[], scopeWhere: string): Promise<FieldStat[]> {\n const exprs = columns.map((name, i) => {\n const quoted = quoteIdent(name);\n return `COUNT(${quoted}) AS n${i}, GROUP_CONCAT(DISTINCT typeof(${quoted})) FILTER (WHERE ${quoted} IS NOT NULL) AS t${i}`;\n });\n const stmt = await conn.prepare(`SELECT ${exprs.join(', ')} FROM frontmatter ${scopeWhere}`);\n const row = (await stmt.get()) as Record<string, number | string | null>;\n return columns.map((name, i) => ({\n field: name,\n coverage: Number(row[`n${i}`] ?? 0),\n type: [...new Set(((row[`t${i}`] as string) ?? '').split(',').filter(Boolean))].sort().join(','),\n }));\n}\n"],"names":["fieldStats","conn","columns","scopeWhere","exprs","stmt","row","map","name","i","quoted","quoteIdent","prepare","join","get","field","coverage","Number","type","Set","split","filter","Boolean","sort"],"mappings":";;;;+BAKsBA;;;eAAAA;;;wBALK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAKpB,SAAeA,WAAWC,IAAgB,EAAEC,OAAiB,EAAEC,UAAkB;;YAChFC,OAIAC,MACAC;;;;oBALAF,QAAQF,QAAQK,GAAG,CAAC,SAACC,MAAMC;wBAC/B,IAAMC,SAASC,IAAAA,oBAAU,EAACH;wBAC1B,OAAO,AAAC,SAAuBC,OAAfC,QAAO,UAA2CA,OAAnCD,GAAE,mCAA2DC,OAA1BA,QAAO,qBAA8CD,OAA3BC,QAAO,sBAAsB,OAAFD;oBACzH;oBACa;;wBAAMR,KAAKW,OAAO,CAAC,AAAC,UAA8CT,OAArCC,MAAMS,IAAI,CAAC,OAAM,sBAA+B,OAAXV;;;oBAAzEE,OAAO;oBACA;;wBAAMA,KAAKS,GAAG;;;oBAArBR,MAAO;oBACb;;wBAAOJ,QAAQK,GAAG,CAAC,SAACC,MAAMC;gCAEPH,OACGA;mCAHW;gCAC/BS,OAAOP;gCACPQ,UAAUC,QAAOX,QAAAA,GAAG,CAAC,AAAC,IAAK,OAAFG,GAAI,cAAZH,mBAAAA,QAAgB;gCACjCY,MAAM,AAAC,qBAAG,IAAIC,IAAI,EAAEb,SAAAA,GAAG,CAAC,AAAC,IAAK,OAAFG,GAAI,cAAZH,oBAAAA,SAA2B,IAAIc,KAAK,CAAC,KAAKC,MAAM,CAACC,WAAWC,IAAI,GAAGV,IAAI,CAAC;4BAC9F;;;;;IACF"}
@@ -9,6 +9,7 @@ Object.defineProperty(exports, "queryLexical", {
9
9
  }
10
10
  });
11
11
  var _segmentts = require("../../text/segment.js");
12
+ var _enginets = require("./engine.js");
12
13
  function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
13
14
  try {
14
15
  var info = gen[key](arg);
@@ -134,10 +135,9 @@ function _ts_generator(thisArg, body) {
134
135
  };
135
136
  }
136
137
  }
137
- var WEIGHTED_BM25 = 'bm25(content, 10.0, 5.0, 1.0, 0, 10.0, 5.0, 1.0)';
138
138
  function queryLexical(conn, terms, opts) {
139
139
  return _async_to_generator(function() {
140
- var whereJoin, whereCond, scopeCond, limit, query, sql, stmt;
140
+ var whereJoin, whereCond, scopeCond, limit, query, stmt;
141
141
  return _ts_generator(this, function(_state) {
142
142
  switch(_state.label){
143
143
  case 0:
@@ -149,10 +149,9 @@ function queryLexical(conn, terms, opts) {
149
149
  2,
150
150
  []
151
151
  ];
152
- sql = "SELECT content.path AS path FROM content ".concat(whereJoin, " WHERE content MATCH ? ").concat(whereCond, " ").concat(scopeCond, " ORDER BY ").concat(WEIGHTED_BM25, " LIMIT ").concat(limit);
153
152
  return [
154
153
  4,
155
- conn.prepare(sql)
154
+ conn.prepare((0, _enginets.sqliteFts)().rankedMatch(whereJoin, whereCond, scopeCond, limit))
156
155
  ];
157
156
  case 1:
158
157
  stmt = _state.sent();
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/store/sqlite/lexical.ts"],"sourcesContent":["import { segmentMatch } from '../../text/segment.ts';\nimport type { Connection, LexicalHit, LexicalQueryOptions } from '../types.ts';\n\nconst WEIGHTED_BM25 = 'bm25(content, 10.0, 5.0, 1.0, 0, 10.0, 5.0, 1.0)';\n\n// Ranked BM25 word-match query, scoped by the caller-built SQL fragments. An\n// unspaced-script run in `terms` becomes a quoted grapheme phrase against the `_seg` sidecars.\nexport async function queryLexical(conn: Connection, terms: string, opts: LexicalQueryOptions): Promise<LexicalHit[]> {\n const { whereJoin, whereCond, scopeCond, limit } = opts;\n const query = segmentMatch(terms);\n // A run of pure unspaced-script punctuation segments to nothing searchable: an empty MATCH\n // string is an FTS5 syntax error, not zero rows, so return zero rows directly rather than issuing it.\n if (query.trim() === '') return [];\n const sql = `SELECT content.path AS path FROM content ${whereJoin} WHERE content MATCH ? ${whereCond} ${scopeCond} ORDER BY ${WEIGHTED_BM25} LIMIT ${limit}`;\n const stmt = await conn.prepare(sql);\n return (await stmt.all(query)) as unknown as LexicalHit[];\n}\n"],"names":["queryLexical","WEIGHTED_BM25","conn","terms","opts","whereJoin","whereCond","scopeCond","limit","query","sql","stmt","segmentMatch","trim","prepare","all"],"mappings":";;;;+BAOsBA;;;eAAAA;;;yBAPO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAG7B,IAAMC,gBAAgB;AAIf,SAAeD,aAAaE,IAAgB,EAAEC,KAAa,EAAEC,IAAyB;;YACnFC,WAAWC,WAAWC,WAAWC,OACnCC,OAIAC,KACAC;;;;oBANEN,YAA2CD,KAA3CC,WAAWC,YAAgCF,KAAhCE,WAAWC,YAAqBH,KAArBG,WAAWC,QAAUJ,KAAVI;oBACnCC,QAAQG,IAAAA,uBAAY,EAACT;oBAC3B,2FAA2F;oBAC3F,sGAAsG;oBACtG,IAAIM,MAAMI,IAAI,OAAO,IAAI;;;;oBACnBH,MAAM,AAAC,4CAA8EJ,OAAnCD,WAAU,2BAAsCE,OAAbD,WAAU,KAAyBL,OAAtBM,WAAU,cAAmCC,OAAvBP,eAAc,WAAe,OAANO;oBACxI;;wBAAMN,KAAKY,OAAO,CAACJ;;;oBAA1BC,OAAO;oBACL;;wBAAMA,KAAKI,GAAG,CAACN;;;oBAAvB;;wBAAQ;;;;IACV"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/open-source/ai/sensemaking/src/store/sqlite/lexical.ts"],"sourcesContent":["import { segmentMatch } from '../../text/segment.ts';\nimport type { Connection, LexicalHit, LexicalQueryOptions } from '../types.ts';\nimport { sqliteFts } from './engine.ts';\n\n// Ranked BM25 word-match query, scoped by the caller-built SQL fragments. An\n// unspaced-script run in `terms` becomes a quoted grapheme phrase against the `_seg` sidecars.\nexport async function queryLexical(conn: Connection, terms: string, opts: LexicalQueryOptions): Promise<LexicalHit[]> {\n const { whereJoin, whereCond, scopeCond, limit } = opts;\n const query = segmentMatch(terms);\n // A run of pure unspaced-script punctuation segments to nothing searchable: an empty MATCH\n // string is an FTS5 syntax error, not zero rows, so return zero rows directly rather than issuing it.\n if (query.trim() === '') return [];\n const stmt = await conn.prepare(sqliteFts().rankedMatch(whereJoin, whereCond, scopeCond, limit));\n return (await stmt.all(query)) as unknown as LexicalHit[];\n}\n"],"names":["queryLexical","conn","terms","opts","whereJoin","whereCond","scopeCond","limit","query","stmt","segmentMatch","trim","prepare","sqliteFts","rankedMatch","all"],"mappings":";;;;+BAMsBA;;;eAAAA;;;yBANO;wBAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAInB,SAAeA,aAAaC,IAAgB,EAAEC,KAAa,EAAEC,IAAyB;;YACnFC,WAAWC,WAAWC,WAAWC,OACnCC,OAIAC;;;;oBALEL,YAA2CD,KAA3CC,WAAWC,YAAgCF,KAAhCE,WAAWC,YAAqBH,KAArBG,WAAWC,QAAUJ,KAAVI;oBACnCC,QAAQE,IAAAA,uBAAY,EAACR;oBAC3B,2FAA2F;oBAC3F,sGAAsG;oBACtG,IAAIM,MAAMG,IAAI,OAAO,IAAI;;;;oBACZ;;wBAAMV,KAAKW,OAAO,CAACC,IAAAA,mBAAS,IAAGC,WAAW,CAACV,WAAWC,WAAWC,WAAWC;;;oBAAnFE,OAAO;oBACL;;wBAAMA,KAAKM,GAAG,CAACP;;;oBAAvB;;wBAAQ;;;;IACV"}