sensemaking 0.25.1 → 0.26.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 (316) hide show
  1. package/README.md +13 -9
  2. package/dist/cjs/cli/index.d.cts +1 -1
  3. package/dist/cjs/cli/index.d.ts +1 -1
  4. package/dist/cjs/cli/index.js +1 -1
  5. package/dist/cjs/cli/index.js.map +1 -1
  6. package/dist/cjs/cli/path.js +5 -29
  7. package/dist/cjs/cli/path.js.map +1 -1
  8. package/dist/cjs/cli/related.js +4 -3
  9. package/dist/cjs/cli/related.js.map +1 -1
  10. package/dist/cjs/commands/index.d.cts +6 -3
  11. package/dist/cjs/commands/index.d.ts +6 -3
  12. package/dist/cjs/commands/index.js +4 -0
  13. package/dist/cjs/commands/index.js.map +1 -1
  14. package/dist/cjs/commands/map.d.cts +14 -5
  15. package/dist/cjs/commands/map.d.ts +14 -5
  16. package/dist/cjs/commands/map.js +42 -35
  17. package/dist/cjs/commands/map.js.map +1 -1
  18. package/dist/cjs/commands/path.d.cts +14 -0
  19. package/dist/cjs/commands/path.d.ts +14 -0
  20. package/dist/cjs/commands/path.js +209 -0
  21. package/dist/cjs/commands/path.js.map +1 -0
  22. package/dist/cjs/commands/peek.d.cts +16 -1
  23. package/dist/cjs/commands/peek.d.ts +16 -1
  24. package/dist/cjs/commands/peek.js +71 -33
  25. package/dist/cjs/commands/peek.js.map +1 -1
  26. package/dist/cjs/commands/related.d.cts +16 -3
  27. package/dist/cjs/commands/related.d.ts +16 -3
  28. package/dist/cjs/commands/related.js +131 -98
  29. package/dist/cjs/commands/related.js.map +1 -1
  30. package/dist/cjs/commands/scope.d.cts +1 -0
  31. package/dist/cjs/commands/scope.d.ts +1 -0
  32. package/dist/cjs/commands/scope.js +149 -0
  33. package/dist/cjs/commands/scope.js.map +1 -1
  34. package/dist/cjs/commands/search.d.cts +26 -3
  35. package/dist/cjs/commands/search.d.ts +26 -3
  36. package/dist/cjs/commands/search.js +211 -71
  37. package/dist/cjs/commands/search.js.map +1 -1
  38. package/dist/cjs/commands/signals.d.cts +4 -3
  39. package/dist/cjs/commands/signals.d.ts +4 -3
  40. package/dist/cjs/commands/signals.js +13 -4
  41. package/dist/cjs/commands/signals.js.map +1 -1
  42. package/dist/cjs/commands/snapshot.d.cts +3 -0
  43. package/dist/cjs/commands/snapshot.d.ts +3 -0
  44. package/dist/cjs/commands/snapshot.js +180 -0
  45. package/dist/cjs/commands/snapshot.js.map +1 -0
  46. package/dist/cjs/embed/cohere.js +41 -16
  47. package/dist/cjs/embed/cohere.js.map +1 -1
  48. package/dist/cjs/embed/endpoint.d.cts +2 -0
  49. package/dist/cjs/embed/endpoint.d.ts +2 -0
  50. package/dist/cjs/embed/endpoint.js +30 -0
  51. package/dist/cjs/embed/endpoint.js.map +1 -0
  52. package/dist/cjs/embed/handoff.d.cts +7 -2
  53. package/dist/cjs/embed/handoff.d.ts +7 -2
  54. package/dist/cjs/embed/handoff.js +10 -0
  55. package/dist/cjs/embed/handoff.js.map +1 -1
  56. package/dist/cjs/embed/http.d.cts +18 -1
  57. package/dist/cjs/embed/http.d.ts +18 -1
  58. package/dist/cjs/embed/http.js +239 -40
  59. package/dist/cjs/embed/http.js.map +1 -1
  60. package/dist/cjs/embed/openai.js +39 -17
  61. package/dist/cjs/embed/openai.js.map +1 -1
  62. package/dist/cjs/embed/query.d.cts +9 -3
  63. package/dist/cjs/embed/query.d.ts +9 -3
  64. package/dist/cjs/embed/query.js +257 -90
  65. package/dist/cjs/embed/query.js.map +1 -1
  66. package/dist/cjs/embed/registry.d.cts +2 -2
  67. package/dist/cjs/embed/registry.d.ts +2 -2
  68. package/dist/cjs/embed/registry.js +36 -4
  69. package/dist/cjs/embed/registry.js.map +1 -1
  70. package/dist/cjs/embed/static.js +6 -2
  71. package/dist/cjs/embed/static.js.map +1 -1
  72. package/dist/cjs/embed/store.js +42 -77
  73. package/dist/cjs/embed/store.js.map +1 -1
  74. package/dist/cjs/embed/types.d.cts +5 -2
  75. package/dist/cjs/embed/types.d.ts +5 -2
  76. package/dist/cjs/embed/types.js.map +1 -1
  77. package/dist/cjs/features/embed.js +290 -43
  78. package/dist/cjs/features/embed.js.map +1 -1
  79. package/dist/cjs/graph/traverse.d.cts +2 -2
  80. package/dist/cjs/graph/traverse.d.ts +2 -2
  81. package/dist/cjs/graph/traverse.js +15 -5
  82. package/dist/cjs/graph/traverse.js.map +1 -1
  83. package/dist/cjs/index.d.cts +2 -2
  84. package/dist/cjs/index.d.ts +2 -2
  85. package/dist/cjs/index.js +6 -0
  86. package/dist/cjs/index.js.map +1 -1
  87. package/dist/cjs/output/output.d.cts +4 -36
  88. package/dist/cjs/output/output.d.ts +4 -36
  89. package/dist/cjs/output/output.js +1 -2
  90. package/dist/cjs/output/output.js.map +1 -1
  91. package/dist/cjs/scan/pool.d.cts +2 -1
  92. package/dist/cjs/scan/pool.d.ts +2 -1
  93. package/dist/cjs/scan/pool.js +116 -27
  94. package/dist/cjs/scan/pool.js.map +1 -1
  95. package/dist/cjs/scan/reparse.d.cts +1 -0
  96. package/dist/cjs/scan/reparse.d.ts +1 -0
  97. package/dist/cjs/scan/reparse.js +75 -21
  98. package/dist/cjs/scan/reparse.js.map +1 -1
  99. package/dist/cjs/store/builder.d.cts +11 -21
  100. package/dist/cjs/store/builder.d.ts +11 -21
  101. package/dist/cjs/store/builder.js +1077 -438
  102. package/dist/cjs/store/builder.js.map +1 -1
  103. package/dist/cjs/store/duckdb/connection.js +16 -2
  104. package/dist/cjs/store/duckdb/connection.js.map +1 -1
  105. package/dist/cjs/store/duckdb/open.d.cts +1 -1
  106. package/dist/cjs/store/duckdb/open.d.ts +1 -1
  107. package/dist/cjs/store/duckdb/open.js +73 -65
  108. package/dist/cjs/store/duckdb/open.js.map +1 -1
  109. package/dist/cjs/store/duckdb/reconcile.js +533 -15
  110. package/dist/cjs/store/duckdb/reconcile.js.map +1 -1
  111. package/dist/cjs/store/embed-scope.js +19 -9
  112. package/dist/cjs/store/embed-scope.js.map +1 -1
  113. package/dist/cjs/store/index.d.cts +6 -0
  114. package/dist/cjs/store/index.d.ts +6 -0
  115. package/dist/cjs/store/index.js +8 -4
  116. package/dist/cjs/store/index.js.map +1 -1
  117. package/dist/cjs/store/open.d.cts +6 -1
  118. package/dist/cjs/store/open.d.ts +6 -1
  119. package/dist/cjs/store/open.js +230 -307
  120. package/dist/cjs/store/open.js.map +1 -1
  121. package/dist/cjs/store/readiness.d.cts +5 -0
  122. package/dist/cjs/store/readiness.d.ts +5 -0
  123. package/dist/cjs/store/readiness.js +39 -0
  124. package/dist/cjs/store/readiness.js.map +1 -0
  125. package/dist/cjs/store/reconcile.d.cts +26 -1
  126. package/dist/cjs/store/reconcile.d.ts +26 -1
  127. package/dist/cjs/store/reconcile.js +670 -576
  128. package/dist/cjs/store/reconcile.js.map +1 -1
  129. package/dist/cjs/store/signature.d.cts +1 -0
  130. package/dist/cjs/store/signature.d.ts +1 -0
  131. package/dist/cjs/store/signature.js +9 -0
  132. package/dist/cjs/store/signature.js.map +1 -1
  133. package/dist/cjs/store/sqlite/open.d.cts +1 -1
  134. package/dist/cjs/store/sqlite/open.d.ts +1 -1
  135. package/dist/cjs/store/sqlite/open.js +84 -90
  136. package/dist/cjs/store/sqlite/open.js.map +1 -1
  137. package/dist/cjs/store/sqlite/reconcile.js.map +1 -1
  138. package/dist/cjs/store/sqlite/store.js +63 -60
  139. package/dist/cjs/store/sqlite/store.js.map +1 -1
  140. package/dist/cjs/store/sqlite/vectors.d.cts +2 -2
  141. package/dist/cjs/store/sqlite/vectors.d.ts +2 -2
  142. package/dist/cjs/store/sqlite/vectors.js +8 -4
  143. package/dist/cjs/store/sqlite/vectors.js.map +1 -1
  144. package/dist/cjs/store/stages.js.map +1 -1
  145. package/dist/cjs/store/turso/connection.d.cts +1 -0
  146. package/dist/cjs/store/turso/connection.d.ts +1 -0
  147. package/dist/cjs/store/turso/connection.js +319 -94
  148. package/dist/cjs/store/turso/connection.js.map +1 -1
  149. package/dist/cjs/store/turso/open.d.cts +1 -1
  150. package/dist/cjs/store/turso/open.d.ts +1 -1
  151. package/dist/cjs/store/turso/open.js +70 -74
  152. package/dist/cjs/store/turso/open.js.map +1 -1
  153. package/dist/cjs/store/turso/store.js +25 -23
  154. package/dist/cjs/store/turso/store.js.map +1 -1
  155. package/dist/cjs/store/turso/vectors.d.cts +2 -2
  156. package/dist/cjs/store/turso/vectors.d.ts +2 -2
  157. package/dist/cjs/store/turso/vectors.js +26 -16
  158. package/dist/cjs/store/turso/vectors.js.map +1 -1
  159. package/dist/cjs/store/types.d.cts +4 -1
  160. package/dist/cjs/store/types.d.ts +4 -1
  161. package/dist/cjs/store/types.js.map +1 -1
  162. package/dist/cjs/store/vectors.d.cts +14 -1
  163. package/dist/cjs/store/vectors.d.ts +14 -1
  164. package/dist/cjs/store/vectors.js +61 -0
  165. package/dist/cjs/store/vectors.js.map +1 -1
  166. package/dist/cjs/watch.d.cts +6 -0
  167. package/dist/cjs/watch.d.ts +6 -0
  168. package/dist/cjs/watch.js +42 -10
  169. package/dist/cjs/watch.js.map +1 -1
  170. package/dist/cjs/workers/parse.d.cts +4 -3
  171. package/dist/cjs/workers/parse.d.ts +4 -3
  172. package/dist/cjs/workers/parse.js +19 -17
  173. package/dist/cjs/workers/parse.js.map +1 -1
  174. package/dist/esm/cli/index.d.ts +1 -1
  175. package/dist/esm/cli/index.js +1 -1
  176. package/dist/esm/cli/index.js.map +1 -1
  177. package/dist/esm/cli/path.js +4 -10
  178. package/dist/esm/cli/path.js.map +1 -1
  179. package/dist/esm/cli/related.js +5 -3
  180. package/dist/esm/cli/related.js.map +1 -1
  181. package/dist/esm/commands/index.d.ts +6 -3
  182. package/dist/esm/commands/index.js +1 -0
  183. package/dist/esm/commands/index.js.map +1 -1
  184. package/dist/esm/commands/map.d.ts +14 -5
  185. package/dist/esm/commands/map.js +2 -0
  186. package/dist/esm/commands/map.js.map +1 -1
  187. package/dist/esm/commands/path.d.ts +14 -0
  188. package/dist/esm/commands/path.js +33 -0
  189. package/dist/esm/commands/path.js.map +1 -0
  190. package/dist/esm/commands/peek.d.ts +16 -1
  191. package/dist/esm/commands/peek.js +35 -9
  192. package/dist/esm/commands/peek.js.map +1 -1
  193. package/dist/esm/commands/related.d.ts +16 -3
  194. package/dist/esm/commands/related.js +45 -28
  195. package/dist/esm/commands/related.js.map +1 -1
  196. package/dist/esm/commands/scope.d.ts +1 -0
  197. package/dist/esm/commands/scope.js +58 -0
  198. package/dist/esm/commands/scope.js.map +1 -1
  199. package/dist/esm/commands/search.d.ts +26 -3
  200. package/dist/esm/commands/search.js +85 -18
  201. package/dist/esm/commands/search.js.map +1 -1
  202. package/dist/esm/commands/signals.d.ts +4 -3
  203. package/dist/esm/commands/signals.js +11 -4
  204. package/dist/esm/commands/signals.js.map +1 -1
  205. package/dist/esm/commands/snapshot.d.ts +3 -0
  206. package/dist/esm/commands/snapshot.js +25 -0
  207. package/dist/esm/commands/snapshot.js.map +1 -0
  208. package/dist/esm/embed/cohere.js +35 -10
  209. package/dist/esm/embed/cohere.js.map +1 -1
  210. package/dist/esm/embed/endpoint.d.ts +2 -0
  211. package/dist/esm/embed/endpoint.js +11 -0
  212. package/dist/esm/embed/endpoint.js.map +1 -0
  213. package/dist/esm/embed/handoff.d.ts +7 -2
  214. package/dist/esm/embed/handoff.js +7 -0
  215. package/dist/esm/embed/handoff.js.map +1 -1
  216. package/dist/esm/embed/http.d.ts +18 -1
  217. package/dist/esm/embed/http.js +137 -17
  218. package/dist/esm/embed/http.js.map +1 -1
  219. package/dist/esm/embed/openai.js +34 -12
  220. package/dist/esm/embed/openai.js.map +1 -1
  221. package/dist/esm/embed/query.d.ts +9 -3
  222. package/dist/esm/embed/query.js +98 -26
  223. package/dist/esm/embed/query.js.map +1 -1
  224. package/dist/esm/embed/registry.d.ts +2 -2
  225. package/dist/esm/embed/registry.js +34 -5
  226. package/dist/esm/embed/registry.js.map +1 -1
  227. package/dist/esm/embed/static.js +10 -2
  228. package/dist/esm/embed/static.js.map +1 -1
  229. package/dist/esm/embed/store.js +30 -21
  230. package/dist/esm/embed/store.js.map +1 -1
  231. package/dist/esm/embed/types.d.ts +5 -2
  232. package/dist/esm/embed/types.js.map +1 -1
  233. package/dist/esm/features/embed.js +82 -21
  234. package/dist/esm/features/embed.js.map +1 -1
  235. package/dist/esm/graph/traverse.d.ts +2 -2
  236. package/dist/esm/graph/traverse.js +4 -2
  237. package/dist/esm/graph/traverse.js.map +1 -1
  238. package/dist/esm/index.d.ts +2 -2
  239. package/dist/esm/index.js +1 -1
  240. package/dist/esm/index.js.map +1 -1
  241. package/dist/esm/output/output.d.ts +4 -36
  242. package/dist/esm/output/output.js +1 -2
  243. package/dist/esm/output/output.js.map +1 -1
  244. package/dist/esm/scan/pool.d.ts +2 -1
  245. package/dist/esm/scan/pool.js +80 -23
  246. package/dist/esm/scan/pool.js.map +1 -1
  247. package/dist/esm/scan/reparse.d.ts +1 -0
  248. package/dist/esm/scan/reparse.js +40 -12
  249. package/dist/esm/scan/reparse.js.map +1 -1
  250. package/dist/esm/store/builder.d.ts +11 -21
  251. package/dist/esm/store/builder.js +337 -133
  252. package/dist/esm/store/builder.js.map +1 -1
  253. package/dist/esm/store/duckdb/connection.js +9 -1
  254. package/dist/esm/store/duckdb/connection.js.map +1 -1
  255. package/dist/esm/store/duckdb/open.d.ts +1 -1
  256. package/dist/esm/store/duckdb/open.js +13 -9
  257. package/dist/esm/store/duckdb/open.js.map +1 -1
  258. package/dist/esm/store/duckdb/reconcile.js +145 -10
  259. package/dist/esm/store/duckdb/reconcile.js.map +1 -1
  260. package/dist/esm/store/embed-scope.js +16 -6
  261. package/dist/esm/store/embed-scope.js.map +1 -1
  262. package/dist/esm/store/index.d.ts +6 -0
  263. package/dist/esm/store/index.js +10 -4
  264. package/dist/esm/store/index.js.map +1 -1
  265. package/dist/esm/store/open.d.ts +6 -1
  266. package/dist/esm/store/open.js +77 -87
  267. package/dist/esm/store/open.js.map +1 -1
  268. package/dist/esm/store/readiness.d.ts +5 -0
  269. package/dist/esm/store/readiness.js +11 -0
  270. package/dist/esm/store/readiness.js.map +1 -0
  271. package/dist/esm/store/reconcile.d.ts +26 -1
  272. package/dist/esm/store/reconcile.js +142 -120
  273. package/dist/esm/store/reconcile.js.map +1 -1
  274. package/dist/esm/store/signature.d.ts +1 -0
  275. package/dist/esm/store/signature.js +8 -0
  276. package/dist/esm/store/signature.js.map +1 -1
  277. package/dist/esm/store/sqlite/open.d.ts +1 -1
  278. package/dist/esm/store/sqlite/open.js +12 -12
  279. package/dist/esm/store/sqlite/open.js.map +1 -1
  280. package/dist/esm/store/sqlite/reconcile.js +2 -2
  281. package/dist/esm/store/sqlite/reconcile.js.map +1 -1
  282. package/dist/esm/store/sqlite/store.js +21 -18
  283. package/dist/esm/store/sqlite/store.js.map +1 -1
  284. package/dist/esm/store/sqlite/vectors.d.ts +2 -2
  285. package/dist/esm/store/sqlite/vectors.js +7 -5
  286. package/dist/esm/store/sqlite/vectors.js.map +1 -1
  287. package/dist/esm/store/stages.js.map +1 -1
  288. package/dist/esm/store/turso/connection.d.ts +1 -0
  289. package/dist/esm/store/turso/connection.js +97 -28
  290. package/dist/esm/store/turso/connection.js.map +1 -1
  291. package/dist/esm/store/turso/open.d.ts +1 -1
  292. package/dist/esm/store/turso/open.js +9 -8
  293. package/dist/esm/store/turso/open.js.map +1 -1
  294. package/dist/esm/store/turso/store.js +16 -14
  295. package/dist/esm/store/turso/store.js.map +1 -1
  296. package/dist/esm/store/turso/vectors.d.ts +2 -2
  297. package/dist/esm/store/turso/vectors.js +27 -17
  298. package/dist/esm/store/turso/vectors.js.map +1 -1
  299. package/dist/esm/store/types.d.ts +4 -1
  300. package/dist/esm/store/types.js.map +1 -1
  301. package/dist/esm/store/vectors.d.ts +14 -1
  302. package/dist/esm/store/vectors.js +55 -0
  303. package/dist/esm/store/vectors.js.map +1 -1
  304. package/dist/esm/watch.d.ts +6 -0
  305. package/dist/esm/watch.js +40 -14
  306. package/dist/esm/watch.js.map +1 -1
  307. package/dist/esm/workers/parse.d.ts +4 -3
  308. package/dist/esm/workers/parse.js +19 -17
  309. package/dist/esm/workers/parse.js.map +1 -1
  310. package/package.json +1 -1
  311. package/skills/sense/SKILL.md +4 -2
  312. package/skills/sense/references/stores/duckdb.md +1 -1
  313. package/skills/sense-setup/SKILL.md +2 -2
  314. package/skills/sense-setup/references/embeddings.md +1 -1
  315. package/skills/sense-setup/references/store-benchmarks.md +5 -5
  316. package/skills/sense-setup/references/stores/duckdb.md +1 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/store/index.ts"],"sourcesContent":["// Rows -> a backing store: registry + the public open/build boundary. Parsing lives in scan.ts;\n// everything beyond frontmatter + content lives in src/features/.\n\nimport type { ResolvedConfig, StoreName } from '../config/index.ts';\nimport { anyPresetEmbeds, storeName } from '../config/index.ts';\nimport { SenseError } from '../errors.ts';\nimport { clearCache } from './cache.ts';\nimport { DB_FILENAME as DUCKDB_FILENAME, openDuckdb } from './duckdb/open.ts';\nimport { CAPABILITIES as DUCKDB_CAPABILITIES } from './duckdb/store.ts';\nimport type { BuildRequirement, InternalOpenOptions, OpenOptions, OpenResult } from './open.ts';\nimport { openSqlite, DB_FILENAME as SQLITE_FILENAME } from './sqlite/open.ts';\nimport { CAPABILITIES as SQLITE_CAPABILITIES } from './sqlite/store.ts';\nimport type { Stages } from './stages.ts';\nimport { openTurso, DB_FILENAME as TURSO_FILENAME } from './turso/open.ts';\nimport { CAPABILITIES as TURSO_CAPABILITIES } from './turso/store.ts';\nimport type { Capability } from './types.ts';\n\ninterface StoreEntry {\n capabilities: ReadonlySet<Capability>;\n filename: string;\n open: (cfg: ResolvedConfig, options?: InternalOpenOptions) => Promise<OpenResult>;\n}\n\nconst REGISTRY: Record<StoreName, StoreEntry> = {\n sqlite: { capabilities: SQLITE_CAPABILITIES, filename: SQLITE_FILENAME, open: openSqlite },\n duckdb: { capabilities: DUCKDB_CAPABILITIES, filename: DUCKDB_FILENAME, open: openDuckdb },\n turso: { capabilities: TURSO_CAPABILITIES, filename: TURSO_FILENAME, open: openTurso },\n};\n\nfunction entryFor(name: StoreName): StoreEntry {\n const entry = REGISTRY[name];\n if (!entry) throw new SenseError('STORE_UNKNOWN', `unknown backing store \"${name}\"; available: ${Object.keys(REGISTRY).join(', ')}`);\n return entry;\n}\n\nfunction requirementsFor(cfg: ResolvedConfig): Set<BuildRequirement> {\n const requirements = new Set<BuildRequirement>(['core', 'lexical']);\n if (anyPresetEmbeds(cfg)) requirements.add('vectors');\n return requirements;\n}\n\nfunction validateRequirements(cfg: ResolvedConfig, entry: StoreEntry, requirements: ReadonlySet<BuildRequirement>): void {\n if (requirements.has('vectors') && anyPresetEmbeds(cfg) && !entry.capabilities.has('vectors')) {\n const name = storeName(cfg);\n throw new SenseError('STORE_CAPABILITY_MISSING', `store \"${name}\" does not implement \"vectors\" in this build, but this config's \"embed\" block is in use by at least one preset; remove or narrow it, or set \"store\" to a store that supports vectors (sqlite)`);\n }\n}\n\nexport async function openStoreFor(cfg: ResolvedConfig, options: InternalOpenOptions): Promise<OpenResult> {\n const entry = entryFor(storeName(cfg));\n validateRequirements(cfg, entry, options.requirements ?? new Set<BuildRequirement>(['core']));\n return entry.open(cfg, options);\n}\n\nexport async function openStore(cfg: ResolvedConfig, options: OpenOptions = {}): Promise<OpenResult> {\n const buildEnabled = options.build !== false;\n return openStoreFor(cfg, {\n build: buildEnabled,\n requirements: buildEnabled ? requirementsFor(cfg) : new Set<BuildRequirement>(['core']),\n });\n}\n\nexport async function lexicalReadiness(cfg: ResolvedConfig): Promise<{ ready: boolean; error: string | null }> {\n let opened: OpenResult;\n try {\n opened = await openStoreFor(cfg, { build: false, requirements: new Set<BuildRequirement>(['core', 'lexical']) });\n } catch (err) {\n if (err instanceof SenseError && err.code === 'INDEX_NOT_READY') return { ready: false, error: err.message };\n throw err;\n }\n try {\n return { ready: true, error: null };\n } finally {\n await opened.store.close();\n }\n}\n\nexport interface BuildOptions {\n force?: boolean;\n}\n\nexport interface BuildResult {\n cfg: ResolvedConfig;\n dbPath: string;\n parsed: number;\n warnings: string[];\n stages: Stages;\n}\n\nexport async function buildIndex(cfg: ResolvedConfig, options: BuildOptions = {}): Promise<BuildResult> {\n if (options.force) clearCache(cfg);\n const opened = await openStoreFor(cfg, { build: true, requirements: requirementsFor(cfg) });\n try {\n const { store: _store, ...result } = opened;\n return result;\n } finally {\n await opened.store.close();\n }\n}\n\nexport function storeFilename(cfg: ResolvedConfig): string {\n return entryFor(storeName(cfg)).filename;\n}\n\nexport type { OpenOptions, OpenResult } from './open.ts';\nexport { docCount } from './open.ts';\nexport { getMeta, setMeta } from './shared.ts';\nexport { DB_FILENAME, SCHEMA_VERSION } from './sqlite/open.ts';\nexport type { Stages } from './stages.ts';\nexport type { Capability, Connection, DocumentStore, LexicalHit, LexicalIndex, LexicalQueryOptions, RawStatement, RunResult, SqlSession, Statement, Store, VectorCandidate, VectorSimilar, VectorStore, VectorWriteRow } from './types.ts';\nexport { CAPABILITY_NAMES } from './types.ts';\nexport { clearCache };\n"],"names":["anyPresetEmbeds","storeName","SenseError","clearCache","DB_FILENAME","DUCKDB_FILENAME","openDuckdb","CAPABILITIES","DUCKDB_CAPABILITIES","openSqlite","SQLITE_FILENAME","SQLITE_CAPABILITIES","openTurso","TURSO_FILENAME","TURSO_CAPABILITIES","REGISTRY","sqlite","capabilities","filename","open","duckdb","turso","entryFor","name","entry","Object","keys","join","requirementsFor","cfg","requirements","Set","add","validateRequirements","has","openStoreFor","options","openStore","buildEnabled","build","lexicalReadiness","opened","err","code","ready","error","message","store","close","buildIndex","force","_store","result","storeFilename","docCount","getMeta","setMeta","SCHEMA_VERSION","CAPABILITY_NAMES"],"mappings":"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"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/store/index.ts"],"sourcesContent":["// Rows -> a backing store: registry + the public open/build boundary. Parsing lives in scan.ts;\n// everything beyond frontmatter + content lives in src/features/.\n\nimport type { ResolvedConfig, StoreName } from '../config/index.ts';\nimport { anyPresetEmbeds, storeName } from '../config/index.ts';\nimport { SenseError } from '../errors.ts';\nimport { clearCache } from './cache.ts';\nimport { DB_FILENAME as DUCKDB_FILENAME, openDuckdb } from './duckdb/open.ts';\nimport { CAPABILITIES as DUCKDB_CAPABILITIES } from './duckdb/store.ts';\nimport type { BuildRequirement, InternalOpenOptions, OpenOptions, OpenResult } from './open.ts';\nimport { openSqlite, DB_FILENAME as SQLITE_FILENAME } from './sqlite/open.ts';\nimport { CAPABILITIES as SQLITE_CAPABILITIES } from './sqlite/store.ts';\nimport type { Stages } from './stages.ts';\nimport { openTurso, DB_FILENAME as TURSO_FILENAME } from './turso/open.ts';\nimport { CAPABILITIES as TURSO_CAPABILITIES } from './turso/store.ts';\nimport type { Capability } from './types.ts';\n\ninterface StoreEntry {\n capabilities: ReadonlySet<Capability>;\n filename: string;\n open: (cfg: ResolvedConfig, options?: InternalOpenOptions) => Promise<OpenResult>;\n}\n\nconst REGISTRY: Record<StoreName, StoreEntry> = {\n sqlite: { capabilities: SQLITE_CAPABILITIES, filename: SQLITE_FILENAME, open: openSqlite },\n duckdb: { capabilities: DUCKDB_CAPABILITIES, filename: DUCKDB_FILENAME, open: openDuckdb },\n turso: { capabilities: TURSO_CAPABILITIES, filename: TURSO_FILENAME, open: openTurso },\n};\n\nfunction entryFor(name: StoreName): StoreEntry {\n const entry = REGISTRY[name];\n if (!entry) throw new SenseError('STORE_UNKNOWN', `unknown backing store \"${name}\"; available: ${Object.keys(REGISTRY).join(', ')}`);\n return entry;\n}\n\nfunction requirementsFor(cfg: ResolvedConfig): Set<BuildRequirement> {\n const requirements = new Set<BuildRequirement>(['core', 'lexical']);\n if (anyPresetEmbeds(cfg)) requirements.add('vectors');\n return requirements;\n}\n\nfunction validateRequirements(cfg: ResolvedConfig, entry: StoreEntry, requirements: ReadonlySet<BuildRequirement>): void {\n if (requirements.has('vectors') && anyPresetEmbeds(cfg) && !entry.capabilities.has('vectors')) {\n const name = storeName(cfg);\n throw new SenseError('STORE_CAPABILITY_MISSING', `store \"${name}\" does not implement \"vectors\" in this build, but this config's \"embed\" block is in use by at least one preset; remove or narrow it, or set \"store\" to a store that supports vectors (sqlite)`);\n }\n}\n\nexport async function openStoreFor(cfg: ResolvedConfig, options: InternalOpenOptions): Promise<OpenResult> {\n options.signal?.throwIfAborted();\n const entry = entryFor(storeName(cfg));\n validateRequirements(cfg, entry, options.requirements ?? new Set<BuildRequirement>(['core']));\n return entry.open(cfg, options);\n}\n\n/** Opens a store through the root `open` API, preparing capabilities unless `build` is `false`. */\nexport async function openStore(cfg: ResolvedConfig, options: OpenOptions = {}): Promise<OpenResult> {\n const buildEnabled = options.build !== false;\n return openStoreFor(cfg, {\n build: buildEnabled,\n requirements: buildEnabled ? requirementsFor(cfg) : new Set<BuildRequirement>(['core']),\n signal: options.signal,\n });\n}\n\nexport async function lexicalReadiness(cfg: ResolvedConfig): Promise<{ ready: boolean; error: string | null }> {\n let opened: OpenResult;\n try {\n opened = await openStoreFor(cfg, { build: false, requirements: new Set<BuildRequirement>(['core', 'lexical']) });\n } catch (err) {\n if (err instanceof SenseError && err.code === 'INDEX_NOT_READY') return { ready: false, error: err.message };\n throw err;\n }\n try {\n return { ready: true, error: null };\n } finally {\n await opened.store.close();\n }\n}\n\n/** Options for the root `build(config, options)` API. */\nexport interface BuildOptions {\n /** Recreates the derived cache before building. */\n force?: boolean;\n /** Cancels supported provider I/O and stops between phases after active native work finishes. */\n signal?: AbortSignal;\n}\n\nexport interface BuildResult {\n cfg: ResolvedConfig;\n dbPath: string;\n parsed: number;\n warnings: string[];\n stages: Stages;\n}\n\n/** Builds every configured capability, waiting for active native work and cleanup before settling. */\nexport async function buildIndex(cfg: ResolvedConfig, options: BuildOptions = {}): Promise<BuildResult> {\n options.signal?.throwIfAborted();\n if (options.force) clearCache(cfg);\n const opened = await openStoreFor(cfg, { build: true, requirements: requirementsFor(cfg), signal: options.signal });\n try {\n const { store: _store, ...result } = opened;\n return result;\n } finally {\n await opened.store.close();\n }\n}\n\nexport function storeFilename(cfg: ResolvedConfig): string {\n return entryFor(storeName(cfg)).filename;\n}\n\nexport type { OpenOptions, OpenResult } from './open.ts';\nexport { docCount } from './open.ts';\nexport { getMeta, setMeta } from './shared.ts';\nexport { DB_FILENAME, SCHEMA_VERSION } from './sqlite/open.ts';\nexport type { Stages } from './stages.ts';\nexport type { Capability, Connection, DocumentStore, LexicalHit, LexicalIndex, LexicalQueryOptions, RawStatement, RunResult, SqlSession, Statement, Store, VectorCandidate, VectorSimilar, VectorStore, VectorWriteRow } from './types.ts';\nexport { CAPABILITY_NAMES } from './types.ts';\nexport { clearCache };\n"],"names":["anyPresetEmbeds","storeName","SenseError","clearCache","DB_FILENAME","DUCKDB_FILENAME","openDuckdb","CAPABILITIES","DUCKDB_CAPABILITIES","openSqlite","SQLITE_FILENAME","SQLITE_CAPABILITIES","openTurso","TURSO_FILENAME","TURSO_CAPABILITIES","REGISTRY","sqlite","capabilities","filename","open","duckdb","turso","entryFor","name","entry","Object","keys","join","requirementsFor","cfg","requirements","Set","add","validateRequirements","has","openStoreFor","options","signal","throwIfAborted","openStore","buildEnabled","build","lexicalReadiness","opened","err","code","ready","error","message","store","close","buildIndex","force","_store","result","storeFilename","docCount","getMeta","setMeta","SCHEMA_VERSION","CAPABILITY_NAMES"],"mappings":"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"}
@@ -1,9 +1,14 @@
1
1
  import type { ResolvedConfig } from '../config/index.js';
2
+ import type { EmbedCallOptions } from '../embed/types.js';
2
3
  import type { Stages } from './stages.js';
3
4
  import type { OpenDialect, Store } from './types.js';
4
5
  export type BuildRequirement = 'core' | 'lexical' | 'vectors';
6
+ /** Options for the root `open(config, options)` API. */
5
7
  export interface OpenOptions {
8
+ /** Prepares configured capabilities by default; `false` opens compatible published state without repair. */
6
9
  build?: boolean;
10
+ /** Cancels supported provider I/O and stops between phases after active native work finishes. */
11
+ signal?: AbortSignal;
7
12
  }
8
13
  export interface InternalOpenOptions extends OpenOptions {
9
14
  requirements?: ReadonlySet<BuildRequirement>;
@@ -16,6 +21,6 @@ export interface OpenResult {
16
21
  warnings: string[];
17
22
  stages: Stages;
18
23
  }
19
- export declare function prepareDocumentEmbeddings(store: Store, cfg: ResolvedConfig, allowed?: ReadonlySet<string>): Promise<void>;
24
+ export declare function prepareDocumentEmbeddings(store: Store, cfg: ResolvedConfig, allowed?: ReadonlySet<string>, options?: EmbedCallOptions): Promise<void>;
20
25
  export declare function openWithDialect<Handle>(input: ResolvedConfig, dialect: OpenDialect<Handle>, options?: InternalOpenOptions): Promise<OpenResult>;
21
26
  export declare function docCount(store: Store): Promise<number>;
@@ -8,15 +8,12 @@ import { SenseError } from '../errors.js';
8
8
  import { FEATURES } from '../features/index.js';
9
9
  import { createBuilder } from './builder.js';
10
10
  import { clearCache } from './cache.js';
11
- import { classifyEmbedChange } from './embed-scope.js';
12
- import { classifyFeatureToggles, isFeatureOnlyChange } from './feature-scope.js';
13
11
  import { lockWaitBudgetMs } from './lock-wait.js';
14
- import { forcedPresetPaths, isPresetOnlyChange } from './preset-scope.js';
15
- import { getMeta, setMeta } from './shared.js';
16
- import { changedSignatureKeys, embedIdentityAdopted, signatureDiff } from './signature.js';
12
+ import { CORE_READY_META_KEY, FEATURE_SIGNATURE_META_KEY, isCoreReady, isPublishedFeatureSignature } from './readiness.js';
13
+ import { getMeta } from './shared.js';
14
+ import { changedSignatureKeys, embedIdentityAdopted } from './signature.js';
17
15
  import { stageRecorder } from './stages.js';
18
16
  import { withTransaction } from './transaction.js';
19
- const CORE_READY_META_KEY = 'core_ready';
20
17
  const LOCK_POLL_MS = 50;
21
18
  const lockWait = channel('sensemaking.store.lock-wait');
22
19
  function notReady(reason) {
@@ -79,26 +76,32 @@ async function connectExisting(cfg, dialect, requirements) {
79
76
  observational: true
80
77
  });
81
78
  try {
82
- let version;
83
- let features;
84
- let ready;
79
+ let state;
85
80
  try {
86
- version = await getMeta(conn, 'schema_version');
87
- features = await getMeta(conn, 'features');
88
- ready = await getMeta(conn, CORE_READY_META_KEY);
89
- await assertCoreSchema(conn);
81
+ state = await withTransaction(conn, async ()=>{
82
+ const version = await getMeta(conn, 'schema_version');
83
+ const features = await getMeta(conn, FEATURE_SIGNATURE_META_KEY);
84
+ const ready = await getMeta(conn, CORE_READY_META_KEY);
85
+ await assertCoreSchema(conn);
86
+ return {
87
+ version,
88
+ features,
89
+ ready
90
+ };
91
+ });
90
92
  } catch {
91
93
  if (!existsSync(dbPath)) throw notReady(`the derived index was deleted while opening ${dbPath}`);
92
94
  throw notReady(`the derived index at ${dbPath} has no compatible schema`);
93
95
  }
94
- if (version !== dialect.schemaVersion) {
95
- throw notReady(`the derived index at ${dbPath} uses schema ${version !== null && version !== void 0 ? version : 'unknown'}, but this sense version requires ${dialect.schemaVersion}`);
96
+ if (state.version !== dialect.schemaVersion) {
97
+ var _state_version;
98
+ throw notReady(`the derived index at ${dbPath} uses schema ${(_state_version = state.version) !== null && _state_version !== void 0 ? _state_version : 'unknown'}, but this sense version requires ${dialect.schemaVersion}`);
96
99
  }
97
100
  const wantFeatures = featureSignature(cfg, FEATURES);
98
- if (features !== wantFeatures) {
101
+ if (!isPublishedFeatureSignature(state.features, wantFeatures)) {
99
102
  throw notReady(`the derived index at ${dbPath} was built for different configuration features`);
100
103
  }
101
- if (ready !== '1') {
104
+ if (!isCoreReady(state.ready)) {
102
105
  throw notReady(`the derived index at ${dbPath} has an incomplete core build`);
103
106
  }
104
107
  if (requirements.has('lexical')) {
@@ -123,8 +126,8 @@ async function connectExisting(cfg, dialect, requirements) {
123
126
  throw err;
124
127
  }
125
128
  }
126
- async function connectForBuild(cfg, dialect, requirements) {
127
- var _cfg_configDir, _cfg_rootDir;
129
+ async function connectForBuild(cfg, dialect, requirements, cacheReplaced = false) {
130
+ var _cfg_configDir;
128
131
  const configDir = (_cfg_configDir = cfg.configDir) !== null && _cfg_configDir !== void 0 ? _cfg_configDir : cfg.baseDir;
129
132
  const stateDir = join(configDir, STATE_DIR);
130
133
  mkdirSync(stateDir, {
@@ -136,73 +139,29 @@ async function connectForBuild(cfg, dialect, requirements) {
136
139
  observational: false
137
140
  });
138
141
  let closed = false;
139
- const builder = createBuilder(conn, cfg, {
140
- rootDir: (_cfg_rootDir = cfg.rootDir) !== null && _cfg_rootDir !== void 0 ? _cfg_rootDir : cfg.baseDir,
141
- configDir
142
- }, dialect.reconcileDialect);
142
+ let builder;
143
143
  try {
144
+ var _dialect_prepareConnection;
144
145
  await conn.exec('CREATE TABLE IF NOT EXISTS meta (key TEXT PRIMARY KEY, value TEXT)');
145
146
  const version = await getMeta(conn, 'schema_version');
146
- const features = await getMeta(conn, 'features');
147
- const ready = await getMeta(conn, CORE_READY_META_KEY);
148
- const wantFeatures = featureSignature(cfg, FEATURES);
149
- // `ready=0` may belong to another SQLite builder, so recovery stays in place and lets the
150
- // engine serialize it. It never unlinks the cache.
151
- await setMeta(conn, CORE_READY_META_KEY, '0');
152
- const recoverIncomplete = ready === '0' && (version === null || version === dialect.schemaVersion);
153
- let forcedPaths;
154
- let embedInvalidate;
155
- let featureToggles;
156
147
  if (version !== null && version !== dialect.schemaVersion) {
157
148
  console.error('sense: cache format changed (new sensemaking version); rebuilding the index');
158
- closed = true;
159
149
  await dialect.close(handle);
150
+ closed = true;
151
+ if (cacheReplaced) throw notReady(`the derived index at ${dbPath} still reports incompatible schema ${version} after cache replacement`);
160
152
  clearCache(cfg);
161
- return connectForBuild(cfg, dialect, requirements);
162
- }
163
- if (recoverIncomplete) {
164
- console.error('sense: recovering an incomplete index generation in place');
165
- } else if (features !== null && features !== wantFeatures) {
166
- var _cfg_rootDir1;
167
- const changedKeys = changedSignatureKeys(features !== null && features !== void 0 ? features : '', wantFeatures);
168
- const presetForced = isPresetOnlyChange(changedKeys) ? forcedPresetPaths(cfg, (_cfg_rootDir1 = cfg.rootDir) !== null && _cfg_rootDir1 !== void 0 ? _cfg_rootDir1 : cfg.baseDir, features !== null && features !== void 0 ? features : '', changedKeys) : null;
169
- const embedKind = changedKeys.size === 1 && changedKeys.has('embed') ? classifyEmbedChange(features !== null && features !== void 0 ? features : '', wantFeatures) : null;
170
- const toggles = isFeatureOnlyChange(changedKeys) ? classifyFeatureToggles(features !== null && features !== void 0 ? features : '', wantFeatures, changedKeys) : null;
171
- if (changedKeys.size === 1 && changedKeys.has('embed') && embedIdentityAdopted(features !== null && features !== void 0 ? features : '', wantFeatures)) {
172
- console.error("sense: recorded the embedding model's resolved identity; vectors are unaffected");
173
- } else if (embedKind !== null) {
174
- embedInvalidate = embedKind;
175
- console.error(embedKind === 'model' ? 'sense: config change (embed settings) invalidates only the stale vectors' : 'sense: config change (embed settings) rebuilds only the embeddings it affects');
176
- } else if (presetForced !== null) {
177
- forcedPaths = presetForced;
178
- const changed = signatureDiff(features !== null && features !== void 0 ? features : '', wantFeatures);
179
- console.error(`sense: config change (${changed}) reparses only the files it affects`);
180
- } else if (toggles !== null) {
181
- featureToggles = toggles;
182
- const changed = signatureDiff(features !== null && features !== void 0 ? features : '', wantFeatures);
183
- console.error(`sense: config change (${changed}) reparses only the feature it affects`);
184
- } else {
185
- const changed = signatureDiff(features !== null && features !== void 0 ? features : '', wantFeatures);
186
- console.error(`sense: config change (${changed}) rebuilds the index`);
187
- closed = true;
188
- await dialect.close(handle);
189
- clearCache(cfg);
190
- return connectForBuild(cfg, dialect, requirements);
191
- }
153
+ return connectForBuild(cfg, dialect, requirements, true);
192
154
  }
193
- await dialect.ensureSchema(handle, conn, cfg);
155
+ if (version === null) await dialect.ensureCoreSchema(handle, conn);
156
+ await ((_dialect_prepareConnection = dialect.prepareConnection) === null || _dialect_prepareConnection === void 0 ? void 0 : _dialect_prepareConnection.call(dialect, handle, conn, cfg));
194
157
  if (dialect.setDerivedBusyTimeout) {
195
158
  var _ref;
196
159
  const recordedMaxMs = Number((_ref = await getMeta(conn, 'reconcile_max_ms')) !== null && _ref !== void 0 ? _ref : '0');
197
160
  await dialect.setDerivedBusyTimeout(handle, conn, Math.min(Math.max(30000, 3 * recordedMaxMs), 600000));
198
161
  }
199
- const embedParsed = embedInvalidate ? (await builder.invalidate(embedInvalidate)).parsed : 0;
200
- const featureParsed = featureToggles ? (await builder.invalidateFeatures(featureToggles)).parsed : 0;
201
- const { parsed, warnings, stages } = recoverIncomplete ? await builder.recover() : await builder.build(forcedPaths);
202
- await withTransaction(conn, async ()=>{
203
- await setMeta(conn, 'features', wantFeatures);
204
- await setMeta(conn, CORE_READY_META_KEY, '1');
205
- });
162
+ builder = createBuilder(conn, cfg, dialect.reconcileDialect, (snapshotCfg)=>dialect.ensureFeatureSchema(handle, conn, snapshotCfg));
163
+ const { parsed, warnings, stages, messages } = await builder.build();
164
+ for (const message of messages)console.error(message);
206
165
  // Lexical preparation is a separate capability stage. A failure leaves core usable and the
207
166
  // dialect's own lexical marker stale, so unrelated map/peek/path/sql commands stay available.
208
167
  if (requirements.has('lexical')) {
@@ -215,34 +174,56 @@ async function connectForBuild(cfg, dialect, requirements) {
215
174
  conn,
216
175
  cfg,
217
176
  dbPath,
218
- parsed: parsed + embedParsed + featureParsed,
177
+ parsed,
219
178
  warnings,
220
179
  stages,
221
180
  observational: false
222
181
  };
223
182
  } catch (err) {
224
- await builder.close();
225
- if (!closed) await dialect.close(handle);
183
+ const cleanupTasks = [];
184
+ if (builder) {
185
+ const builderToClose = builder;
186
+ cleanupTasks.push(Promise.resolve().then(()=>builderToClose.close()));
187
+ }
188
+ if (!closed) cleanupTasks.push(Promise.resolve().then(()=>dialect.close(handle)));
189
+ const cleanup = await Promise.allSettled(cleanupTasks);
190
+ const cleanupErrors = cleanup.filter((result)=>result.status === 'rejected').map((result)=>result.reason);
191
+ if (cleanupErrors.length > 0) throw new AggregateError([
192
+ err,
193
+ ...cleanupErrors
194
+ ], 'opening the derived index failed and cleanup also failed');
226
195
  throw err;
227
196
  }
228
197
  }
229
198
  // A static provider can resolve its identity while embedding. Publish it only after vectors
230
199
  // succeed and only when the durable signature still matches the prepared generation.
231
- export async function prepareDocumentEmbeddings(store, cfg, allowed) {
232
- const preparedSignature = await getMeta(store, 'features');
233
- await embedPending(store, cfg, allowed);
200
+ export async function prepareDocumentEmbeddings(store, cfg, allowed, options = {}) {
201
+ var _options_signal, _options_signal1, _options_signal2;
202
+ (_options_signal = options.signal) === null || _options_signal === void 0 ? void 0 : _options_signal.throwIfAborted();
203
+ const preparedSignature = await getMeta(store, FEATURE_SIGNATURE_META_KEY);
204
+ (_options_signal1 = options.signal) === null || _options_signal1 === void 0 ? void 0 : _options_signal1.throwIfAborted();
205
+ await embedPending(store, cfg, allowed, preparedSignature, options);
206
+ (_options_signal2 = options.signal) === null || _options_signal2 === void 0 ? void 0 : _options_signal2.throwIfAborted();
234
207
  const actualSignature = featureSignature(cfg, FEATURES);
235
208
  if (preparedSignature === actualSignature) return;
236
209
  const changedKeys = changedSignatureKeys(preparedSignature !== null && preparedSignature !== void 0 ? preparedSignature : '', actualSignature);
237
210
  if (preparedSignature === null || changedKeys.size !== 1 || !changedKeys.has('embed') || !embedIdentityAdopted(preparedSignature, actualSignature)) {
238
211
  throw notReady('the index configuration changed while vectors were being prepared');
239
212
  }
240
- const update = await store.prepare('UPDATE meta SET value = ? WHERE key = ? AND value = ?');
241
- const result = await update.run(actualSignature, 'features', preparedSignature);
242
- if (Number(result.changes) !== 1) throw notReady('another build changed the index configuration while vectors were being prepared');
213
+ await store.transaction(async ()=>{
214
+ var _options_signal, _options_signal1, _options_signal2;
215
+ (_options_signal = options.signal) === null || _options_signal === void 0 ? void 0 : _options_signal.throwIfAborted();
216
+ const update = await store.prepare('UPDATE meta SET value = ? WHERE key = ? AND value = ?');
217
+ (_options_signal1 = options.signal) === null || _options_signal1 === void 0 ? void 0 : _options_signal1.throwIfAborted();
218
+ const result = await update.run(actualSignature, FEATURE_SIGNATURE_META_KEY, preparedSignature);
219
+ (_options_signal2 = options.signal) === null || _options_signal2 === void 0 ? void 0 : _options_signal2.throwIfAborted();
220
+ if (Number(result.changes) !== 1) throw notReady('another build changed the index configuration while vectors were being prepared');
221
+ });
243
222
  }
244
223
  export async function openWithDialect(input, dialect, options = {}) {
245
224
  var _options_requirements;
225
+ var _options_signal;
226
+ (_options_signal = options.signal) === null || _options_signal === void 0 ? void 0 : _options_signal.throwIfAborted();
246
227
  const cfg = normaliseConfig(input);
247
228
  const buildEnabled = options.build !== false;
248
229
  const defaultRequirements = new Set(buildEnabled ? [
@@ -256,11 +237,15 @@ export async function openWithDialect(input, dialect, options = {}) {
256
237
  const connected = buildEnabled ? await connectForBuild(cfg, dialect, requirements) : await connectExisting(cfg, dialect, requirements);
257
238
  let store;
258
239
  try {
240
+ var _options_signal1;
259
241
  store = dialect.createStore(connected.handle, connected.conn, connected.cfg, {
260
242
  observational: connected.observational
261
243
  });
262
244
  rekeyChunkText(connected.conn, store);
263
- if (requirements.has('vectors') && buildEnabled) await prepareDocumentEmbeddings(store, connected.cfg);
245
+ if (requirements.has('vectors') && buildEnabled) await prepareDocumentEmbeddings(store, connected.cfg, undefined, {
246
+ signal: options.signal
247
+ });
248
+ (_options_signal1 = options.signal) === null || _options_signal1 === void 0 ? void 0 : _options_signal1.throwIfAborted();
264
249
  return {
265
250
  store,
266
251
  cfg: connected.cfg,
@@ -270,10 +255,15 @@ export async function openWithDialect(input, dialect, options = {}) {
270
255
  stages: connected.stages
271
256
  };
272
257
  } catch (err) {
273
- if (store) await store.close();
274
- else await dialect.close(connected.handle, {
275
- observational: connected.observational
276
- });
258
+ const cleanup = await Promise.allSettled([
259
+ Promise.resolve().then(()=>store ? store.close() : dialect.close(connected.handle, {
260
+ observational: connected.observational
261
+ }))
262
+ ]);
263
+ if (cleanup[0].status === 'rejected') throw new AggregateError([
264
+ err,
265
+ cleanup[0].reason
266
+ ], 'opening the derived index failed and cleanup also failed');
277
267
  throw err;
278
268
  }
279
269
  }
@@ -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 { SenseError } from '../errors.ts';\nimport { FEATURES } from '../features/index.ts';\nimport { createBuilder } from './builder.ts';\nimport { clearCache } from './cache.ts';\nimport type { EmbedChangeKind } from './embed-scope.ts';\nimport { classifyEmbedChange } from './embed-scope.ts';\nimport type { FeatureToggle } from './feature-scope.ts';\nimport { classifyFeatureToggles, isFeatureOnlyChange } from './feature-scope.ts';\nimport { lockWaitBudgetMs } from './lock-wait.ts';\nimport { forcedPresetPaths, isPresetOnlyChange } from './preset-scope.ts';\nimport { getMeta, setMeta } from './shared.ts';\nimport { changedSignatureKeys, embedIdentityAdopted, signatureDiff } 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\nexport interface OpenOptions {\n build?: boolean;\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 CORE_READY_META_KEY = 'core_ready';\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 version: string | null;\n let features: string | null;\n let ready: string | null;\n try {\n version = await getMeta(conn, 'schema_version');\n features = await getMeta(conn, 'features');\n ready = await getMeta(conn, CORE_READY_META_KEY);\n await assertCoreSchema(conn);\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 (version !== dialect.schemaVersion) {\n throw notReady(`the derived index at ${dbPath} uses schema ${version ?? 'unknown'}, but this sense version requires ${dialect.schemaVersion}`);\n }\n const wantFeatures = featureSignature(cfg, FEATURES);\n if (features !== wantFeatures) {\n throw notReady(`the derived index at ${dbPath} was built for different configuration features`);\n }\n if (ready !== '1') {\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>): 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 const builder = createBuilder(conn, cfg, { rootDir: cfg.rootDir ?? cfg.baseDir, configDir }, dialect.reconcileDialect);\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 features = await getMeta(conn, 'features');\n const ready = await getMeta(conn, CORE_READY_META_KEY);\n const wantFeatures = featureSignature(cfg, FEATURES);\n // `ready=0` may belong to another SQLite builder, so recovery stays in place and lets the\n // engine serialize it. It never unlinks the cache.\n await setMeta(conn, CORE_READY_META_KEY, '0');\n const recoverIncomplete = ready === '0' && (version === null || version === dialect.schemaVersion);\n let forcedPaths: Set<string> | undefined;\n let embedInvalidate: EmbedChangeKind | undefined;\n let featureToggles: FeatureToggle[] | undefined;\n if (version !== null && version !== dialect.schemaVersion) {\n console.error('sense: cache format changed (new sensemaking version); rebuilding the index');\n closed = true;\n await dialect.close(handle);\n clearCache(cfg);\n return connectForBuild(cfg, dialect, requirements);\n }\n if (recoverIncomplete) {\n console.error('sense: recovering an incomplete index generation in place');\n } else if (features !== null && features !== wantFeatures) {\n const changedKeys = changedSignatureKeys(features ?? '', wantFeatures);\n const presetForced = isPresetOnlyChange(changedKeys) ? forcedPresetPaths(cfg, cfg.rootDir ?? cfg.baseDir, features ?? '', changedKeys) : null;\n const embedKind = changedKeys.size === 1 && changedKeys.has('embed') ? classifyEmbedChange(features ?? '', wantFeatures) : null;\n const toggles = isFeatureOnlyChange(changedKeys) ? classifyFeatureToggles(features ?? '', wantFeatures, changedKeys) : null;\n if (changedKeys.size === 1 && changedKeys.has('embed') && embedIdentityAdopted(features ?? '', wantFeatures)) {\n console.error(\"sense: recorded the embedding model's resolved identity; vectors are unaffected\");\n } else if (embedKind !== null) {\n embedInvalidate = embedKind;\n console.error(embedKind === 'model' ? 'sense: config change (embed settings) invalidates only the stale vectors' : 'sense: config change (embed settings) rebuilds only the embeddings it affects');\n } else if (presetForced !== null) {\n forcedPaths = presetForced;\n const changed = signatureDiff(features ?? '', wantFeatures);\n console.error(`sense: config change (${changed}) reparses only the files it affects`);\n } else if (toggles !== null) {\n featureToggles = toggles;\n const changed = signatureDiff(features ?? '', wantFeatures);\n console.error(`sense: config change (${changed}) reparses only the feature it affects`);\n } else {\n const changed = signatureDiff(features ?? '', wantFeatures);\n console.error(`sense: config change (${changed}) rebuilds the index`);\n closed = true;\n await dialect.close(handle);\n clearCache(cfg);\n return connectForBuild(cfg, dialect, requirements);\n }\n }\n\n await dialect.ensureSchema(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 const embedParsed = embedInvalidate ? (await builder.invalidate(embedInvalidate)).parsed : 0;\n const featureParsed = featureToggles ? (await builder.invalidateFeatures(featureToggles)).parsed : 0;\n const { parsed, warnings, stages } = recoverIncomplete ? await builder.recover() : await builder.build(forcedPaths);\n await withTransaction(conn, async () => {\n await setMeta(conn, 'features', wantFeatures);\n await setMeta(conn, CORE_READY_META_KEY, '1');\n });\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: parsed + embedParsed + featureParsed, warnings, stages, observational: false };\n } catch (err) {\n await builder.close();\n if (!closed) await dialect.close(handle);\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>): Promise<void> {\n const preparedSignature = await getMeta(store, 'features');\n await embedPending(store, cfg, allowed);\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 const update = await store.prepare('UPDATE meta SET value = ? WHERE key = ? AND value = ?');\n const result = await update.run(actualSignature, 'features', preparedSignature);\n if (Number(result.changes) !== 1) throw notReady('another build changed the index configuration while vectors were being prepared');\n}\n\nexport async function openWithDialect<Handle>(input: ResolvedConfig, dialect: OpenDialect<Handle>, options: InternalOpenOptions = {}): Promise<OpenResult> {\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);\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 if (store) await store.close();\n else await dialect.close(connected.handle, { observational: connected.observational });\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":["channel","existsSync","mkdirSync","join","anyPresetEmbeds","featureSignature","STATE_DIR","rekeyChunkText","embedPending","SenseError","FEATURES","createBuilder","clearCache","classifyEmbedChange","classifyFeatureToggles","isFeatureOnlyChange","lockWaitBudgetMs","forcedPresetPaths","isPresetOnlyChange","getMeta","setMeta","changedSignatureKeys","embedIdentityAdopted","signatureDiff","stageRecorder","withTransaction","CORE_READY_META_KEY","LOCK_POLL_MS","lockWait","notReady","reason","normaliseConfig","cfg","rootDir","baseDir","configDir","cachePath","dialect","filename","connectUnlocked","dbPath","options","budgetMs","deadline","Date","now","connect","err","existingOnly","isLocked","hasSubscribers","publish","store","Math","round","Promise","resolve","setTimeout","assertCoreSchema","conn","table","prepare","all","connectExisting","requirements","handle","observational","version","features","ready","schemaVersion","wantFeatures","has","assertLexicalReady","parsed","warnings","stages","take","close","connectForBuild","stateDir","recursive","closed","builder","reconcileDialect","exec","recoverIncomplete","forcedPaths","embedInvalidate","featureToggles","console","error","changedKeys","presetForced","embedKind","size","toggles","changed","ensureSchema","setDerivedBusyTimeout","recordedMaxMs","Number","min","max","embedParsed","invalidate","featureParsed","invalidateFeatures","recover","build","prepareLexical","prepareDocumentEmbeddings","allowed","preparedSignature","actualSignature","update","result","run","changes","openWithDialect","input","buildEnabled","defaultRequirements","Set","add","connected","createStore","docCount","stmt","get","n"],"mappings":"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"}
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":["channel","existsSync","mkdirSync","join","anyPresetEmbeds","featureSignature","STATE_DIR","rekeyChunkText","embedPending","SenseError","FEATURES","createBuilder","clearCache","lockWaitBudgetMs","CORE_READY_META_KEY","FEATURE_SIGNATURE_META_KEY","isCoreReady","isPublishedFeatureSignature","getMeta","changedSignatureKeys","embedIdentityAdopted","stageRecorder","withTransaction","LOCK_POLL_MS","lockWait","notReady","reason","normaliseConfig","cfg","rootDir","baseDir","configDir","cachePath","dialect","filename","connectUnlocked","dbPath","options","budgetMs","deadline","Date","now","connect","err","existingOnly","isLocked","hasSubscribers","publish","store","Math","round","Promise","resolve","setTimeout","assertCoreSchema","conn","table","prepare","all","connectExisting","requirements","handle","observational","state","version","features","ready","schemaVersion","wantFeatures","has","assertLexicalReady","parsed","warnings","stages","take","close","connectForBuild","cacheReplaced","stateDir","recursive","closed","builder","exec","console","error","ensureCoreSchema","prepareConnection","setDerivedBusyTimeout","recordedMaxMs","Number","min","max","reconcileDialect","snapshotCfg","ensureFeatureSchema","messages","build","message","prepareLexical","cleanupTasks","builderToClose","push","then","cleanup","allSettled","cleanupErrors","filter","result","status","map","length","AggregateError","prepareDocumentEmbeddings","allowed","signal","throwIfAborted","preparedSignature","actualSignature","changedKeys","size","transaction","update","run","changes","openWithDialect","input","buildEnabled","defaultRequirements","Set","add","connected","createStore","undefined","docCount","stmt","get","n"],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export declare const CORE_READY_META_KEY = "core_ready";
2
+ export declare const CORE_GENERATION_META_KEY = "core_generation";
3
+ export declare const FEATURE_SIGNATURE_META_KEY = "features";
4
+ export declare function isCoreReady(value: string | null): boolean;
5
+ export declare function isPublishedFeatureSignature(actual: string | null, expected: string): boolean;
@@ -0,0 +1,11 @@
1
+ // Published core state has one exact durable signature. Static model identity adoption is a
2
+ // preparation transition, not permission for a read snapshot to accept a different signature.
3
+ export const CORE_READY_META_KEY = 'core_ready';
4
+ export const CORE_GENERATION_META_KEY = 'core_generation';
5
+ export const FEATURE_SIGNATURE_META_KEY = 'features';
6
+ export function isCoreReady(value) {
7
+ return value === '1';
8
+ }
9
+ export function isPublishedFeatureSignature(actual, expected) {
10
+ return actual === expected;
11
+ }
@@ -0,0 +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_READY_META_KEY","CORE_GENERATION_META_KEY","FEATURE_SIGNATURE_META_KEY","isCoreReady","value","isPublishedFeatureSignature","actual","expected"],"mappings":"AAAA,4FAA4F;AAC5F,8FAA8F;AAC9F,OAAO,MAAMA,sBAAsB,aAAa;AAChD,OAAO,MAAMC,2BAA2B,kBAAkB;AAC1D,OAAO,MAAMC,6BAA6B,WAAW;AAErD,OAAO,SAASC,YAAYC,KAAoB;IAC9C,OAAOA,UAAU;AACnB;AAEA,OAAO,SAASC,4BAA4BC,MAAqB,EAAEC,QAAgB;IACjF,OAAOD,WAAWC;AACpB"}
@@ -1,12 +1,37 @@
1
1
  import type { Config } from '../config/index.js';
2
2
  import type { ParsePool } from '../scan/pool.js';
3
- import { type Stages } from './stages.js';
3
+ import { type StageRecorder, type Stages } from './stages.js';
4
4
  import type { Connection, ReconcileDialect } from './types.js';
5
5
  export declare const CORE_FRONTMATTER_COLUMNS: Set<string>;
6
6
  export interface ReconcilePaths {
7
7
  rootDir: string;
8
8
  configDir: string;
9
9
  }
10
+ export interface ReconcileSnapshot {
11
+ existingRows: Array<{
12
+ path: string;
13
+ _mtime: number;
14
+ _size: number;
15
+ }>;
16
+ seenColumns: Set<string>;
17
+ }
18
+ export interface ReconcilePlan {
19
+ mutated: boolean;
20
+ parsed: number;
21
+ warnings: string[];
22
+ apply(conn: Connection): Promise<void>;
23
+ finish(txMs: number): Stages;
24
+ record(conn: Connection, txMs: number): Promise<void>;
25
+ }
26
+ export interface ReconcileTiming {
27
+ stages: StageRecorder;
28
+ elapsed(): number;
29
+ workerParseMs: number;
30
+ txMs: number;
31
+ }
32
+ export declare function createReconcileTiming(cfg: Config): ReconcileTiming;
33
+ export declare function readReconcileSnapshot(conn: Connection, timing: ReconcileTiming): Promise<ReconcileSnapshot>;
34
+ export declare function prepareReconcile(snapshot: ReconcileSnapshot, cfg: Config, paths: ReconcilePaths, dialect: ReconcileDialect, timing: ReconcileTiming, pool?: ParsePool, forcedPaths?: ReadonlySet<string>): Promise<ReconcilePlan>;
10
35
  export declare function reconcile(conn: Connection, cfg: Config, paths: ReconcilePaths, dialect: ReconcileDialect, pool?: ParsePool, forcedPaths?: ReadonlySet<string>): Promise<{
11
36
  parsed: number;
12
37
  warnings: string[];