sensemaking 0.24.7 → 0.25.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 (242) hide show
  1. package/README.md +20 -11
  2. package/dist/cjs/cli/build.d.cts +3 -0
  3. package/dist/cjs/cli/build.d.ts +3 -0
  4. package/dist/cjs/cli/build.js +195 -0
  5. package/dist/cjs/cli/build.js.map +1 -0
  6. package/dist/cjs/cli/index.d.cts +7 -6
  7. package/dist/cjs/cli/index.d.ts +7 -6
  8. package/dist/cjs/cli/index.js +12 -6
  9. package/dist/cjs/cli/index.js.map +1 -1
  10. package/dist/cjs/cli/init.js +2 -2
  11. package/dist/cjs/cli/init.js.map +1 -1
  12. package/dist/cjs/cli/map.js +7 -2
  13. package/dist/cjs/cli/map.js.map +1 -1
  14. package/dist/cjs/cli/named.js +63 -21
  15. package/dist/cjs/cli/named.js.map +1 -1
  16. package/dist/cjs/cli/path.js +7 -2
  17. package/dist/cjs/cli/path.js.map +1 -1
  18. package/dist/cjs/cli/peek.js +7 -2
  19. package/dist/cjs/cli/peek.js.map +1 -1
  20. package/dist/cjs/cli/related.js +55 -6
  21. package/dist/cjs/cli/related.js.map +1 -1
  22. package/dist/cjs/cli/search.js +54 -15
  23. package/dist/cjs/cli/search.js.map +1 -1
  24. package/dist/cjs/cli/shared.d.cts +9 -3
  25. package/dist/cjs/cli/shared.d.ts +9 -3
  26. package/dist/cjs/cli/shared.js +109 -74
  27. package/dist/cjs/cli/shared.js.map +1 -1
  28. package/dist/cjs/cli/sql.js +8 -3
  29. package/dist/cjs/cli/sql.js.map +1 -1
  30. package/dist/cjs/cli/status.js +142 -50
  31. package/dist/cjs/cli/status.js.map +1 -1
  32. package/dist/cjs/cli/types.d.cts +4 -2
  33. package/dist/cjs/cli/types.d.ts +4 -2
  34. package/dist/cjs/cli.js +10 -4
  35. package/dist/cjs/cli.js.map +1 -1
  36. package/dist/cjs/commands/map.js +10 -6
  37. package/dist/cjs/commands/map.js.map +1 -1
  38. package/dist/cjs/commands/peek.js +10 -6
  39. package/dist/cjs/commands/peek.js.map +1 -1
  40. package/dist/cjs/commands/related.d.cts +1 -0
  41. package/dist/cjs/commands/related.d.ts +1 -0
  42. package/dist/cjs/commands/related.js +56 -21
  43. package/dist/cjs/commands/related.js.map +1 -1
  44. package/dist/cjs/commands/scope.js +1 -1
  45. package/dist/cjs/commands/scope.js.map +1 -1
  46. package/dist/cjs/commands/search.js +102 -84
  47. package/dist/cjs/commands/search.js.map +1 -1
  48. package/dist/cjs/config/index.d.cts +1 -1
  49. package/dist/cjs/config/index.d.ts +1 -1
  50. package/dist/cjs/config/index.js.map +1 -1
  51. package/dist/cjs/config/load.d.cts +6 -1
  52. package/dist/cjs/config/load.d.ts +6 -1
  53. package/dist/cjs/config/load.js +38 -1
  54. package/dist/cjs/config/load.js.map +1 -1
  55. package/dist/cjs/config/types.d.cts +2 -1
  56. package/dist/cjs/config/types.d.ts +2 -1
  57. package/dist/cjs/config/types.js +1 -1
  58. package/dist/cjs/config/types.js.map +1 -1
  59. package/dist/cjs/config/validate.js +20 -0
  60. package/dist/cjs/config/validate.js.map +1 -1
  61. package/dist/cjs/embed/query.d.cts +2 -1
  62. package/dist/cjs/embed/query.d.ts +2 -1
  63. package/dist/cjs/embed/query.js +186 -109
  64. package/dist/cjs/embed/query.js.map +1 -1
  65. package/dist/cjs/errors.d.cts +1 -1
  66. package/dist/cjs/errors.d.ts +1 -1
  67. package/dist/cjs/errors.js.map +1 -1
  68. package/dist/cjs/features/embed.js.map +1 -1
  69. package/dist/cjs/graph/traverse.js +11 -6
  70. package/dist/cjs/graph/traverse.js.map +1 -1
  71. package/dist/cjs/index.d.cts +3 -3
  72. package/dist/cjs/index.d.ts +3 -3
  73. package/dist/cjs/index.js +3 -0
  74. package/dist/cjs/index.js.map +1 -1
  75. package/dist/cjs/lib/atomic-write.js +20 -6
  76. package/dist/cjs/lib/atomic-write.js.map +1 -1
  77. package/dist/cjs/lib/serial-query.d.cts +1 -0
  78. package/dist/cjs/lib/serial-query.d.ts +1 -0
  79. package/dist/cjs/lib/serial-query.js +22 -0
  80. package/dist/cjs/lib/serial-query.js.map +1 -0
  81. package/dist/cjs/scan/index.d.cts +5 -0
  82. package/dist/cjs/scan/index.d.ts +5 -0
  83. package/dist/cjs/scan/index.js +12 -4
  84. package/dist/cjs/scan/index.js.map +1 -1
  85. package/dist/cjs/scan/pool.d.cts +5 -0
  86. package/dist/cjs/scan/pool.d.ts +5 -0
  87. package/dist/cjs/scan/pool.js +167 -55
  88. package/dist/cjs/scan/pool.js.map +1 -1
  89. package/dist/cjs/store/builder.d.cts +6 -1
  90. package/dist/cjs/store/builder.d.ts +6 -1
  91. package/dist/cjs/store/builder.js +135 -5
  92. package/dist/cjs/store/builder.js.map +1 -1
  93. package/dist/cjs/store/duckdb/lexical.d.cts +2 -0
  94. package/dist/cjs/store/duckdb/lexical.d.ts +2 -0
  95. package/dist/cjs/store/duckdb/lexical.js +139 -7
  96. package/dist/cjs/store/duckdb/lexical.js.map +1 -1
  97. package/dist/cjs/store/duckdb/open.d.cts +3 -3
  98. package/dist/cjs/store/duckdb/open.d.ts +3 -3
  99. package/dist/cjs/store/duckdb/open.js +53 -41
  100. package/dist/cjs/store/duckdb/open.js.map +1 -1
  101. package/dist/cjs/store/duckdb/reconcile.js +2 -2
  102. package/dist/cjs/store/duckdb/reconcile.js.map +1 -1
  103. package/dist/cjs/store/index.d.cts +23 -4
  104. package/dist/cjs/store/index.d.ts +23 -4
  105. package/dist/cjs/store/index.js +224 -15
  106. package/dist/cjs/store/index.js.map +1 -1
  107. package/dist/cjs/store/open.d.cts +9 -1
  108. package/dist/cjs/store/open.d.ts +9 -1
  109. package/dist/cjs/store/open.js +479 -128
  110. package/dist/cjs/store/open.js.map +1 -1
  111. package/dist/cjs/store/reconcile.js +93 -63
  112. package/dist/cjs/store/reconcile.js.map +1 -1
  113. package/dist/cjs/store/sqlite/open.d.cts +3 -3
  114. package/dist/cjs/store/sqlite/open.d.ts +3 -3
  115. package/dist/cjs/store/sqlite/open.js +44 -36
  116. package/dist/cjs/store/sqlite/open.js.map +1 -1
  117. package/dist/cjs/store/turso/open.d.cts +3 -3
  118. package/dist/cjs/store/turso/open.d.ts +3 -3
  119. package/dist/cjs/store/turso/open.js +83 -66
  120. package/dist/cjs/store/turso/open.js.map +1 -1
  121. package/dist/cjs/store/turso/store.d.cts +3 -1
  122. package/dist/cjs/store/turso/store.d.ts +3 -1
  123. package/dist/cjs/store/turso/store.js +46 -31
  124. package/dist/cjs/store/turso/store.js.map +1 -1
  125. package/dist/cjs/store/types.d.cts +12 -3
  126. package/dist/cjs/store/types.d.ts +12 -3
  127. package/dist/cjs/store/types.js.map +1 -1
  128. package/dist/cjs/watch.js +155 -35
  129. package/dist/cjs/watch.js.map +1 -1
  130. package/dist/esm/cli/build.d.ts +3 -0
  131. package/dist/esm/cli/build.js +18 -0
  132. package/dist/esm/cli/build.js.map +1 -0
  133. package/dist/esm/cli/index.d.ts +7 -6
  134. package/dist/esm/cli/index.js +8 -6
  135. package/dist/esm/cli/index.js.map +1 -1
  136. package/dist/esm/cli/init.js +2 -2
  137. package/dist/esm/cli/init.js.map +1 -1
  138. package/dist/esm/cli/map.js +8 -2
  139. package/dist/esm/cli/map.js.map +1 -1
  140. package/dist/esm/cli/named.js +38 -14
  141. package/dist/esm/cli/named.js.map +1 -1
  142. package/dist/esm/cli/path.js +8 -2
  143. package/dist/esm/cli/path.js.map +1 -1
  144. package/dist/esm/cli/peek.js +8 -2
  145. package/dist/esm/cli/peek.js.map +1 -1
  146. package/dist/esm/cli/related.js +21 -3
  147. package/dist/esm/cli/related.js.map +1 -1
  148. package/dist/esm/cli/search.js +28 -7
  149. package/dist/esm/cli/search.js.map +1 -1
  150. package/dist/esm/cli/shared.d.ts +9 -3
  151. package/dist/esm/cli/shared.js +44 -24
  152. package/dist/esm/cli/shared.js.map +1 -1
  153. package/dist/esm/cli/sql.js +8 -2
  154. package/dist/esm/cli/sql.js.map +1 -1
  155. package/dist/esm/cli/status.js +166 -111
  156. package/dist/esm/cli/status.js.map +1 -1
  157. package/dist/esm/cli/types.d.ts +4 -2
  158. package/dist/esm/cli/types.js.map +1 -1
  159. package/dist/esm/cli.js +9 -4
  160. package/dist/esm/cli.js.map +1 -1
  161. package/dist/esm/commands/map.js +5 -1
  162. package/dist/esm/commands/map.js.map +1 -1
  163. package/dist/esm/commands/peek.js +5 -1
  164. package/dist/esm/commands/peek.js.map +1 -1
  165. package/dist/esm/commands/related.d.ts +1 -0
  166. package/dist/esm/commands/related.js +19 -10
  167. package/dist/esm/commands/related.js.map +1 -1
  168. package/dist/esm/commands/scope.js +1 -1
  169. package/dist/esm/commands/scope.js.map +1 -1
  170. package/dist/esm/commands/search.js +11 -10
  171. package/dist/esm/commands/search.js.map +1 -1
  172. package/dist/esm/config/index.d.ts +1 -1
  173. package/dist/esm/config/index.js.map +1 -1
  174. package/dist/esm/config/load.d.ts +6 -1
  175. package/dist/esm/config/load.js +32 -3
  176. package/dist/esm/config/load.js.map +1 -1
  177. package/dist/esm/config/types.d.ts +2 -1
  178. package/dist/esm/config/types.js +1 -1
  179. package/dist/esm/config/types.js.map +1 -1
  180. package/dist/esm/config/validate.js +20 -0
  181. package/dist/esm/config/validate.js.map +1 -1
  182. package/dist/esm/embed/query.d.ts +2 -1
  183. package/dist/esm/embed/query.js +40 -34
  184. package/dist/esm/embed/query.js.map +1 -1
  185. package/dist/esm/errors.d.ts +1 -1
  186. package/dist/esm/errors.js.map +1 -1
  187. package/dist/esm/features/embed.js.map +1 -1
  188. package/dist/esm/graph/traverse.js +5 -1
  189. package/dist/esm/graph/traverse.js.map +1 -1
  190. package/dist/esm/index.d.ts +3 -3
  191. package/dist/esm/index.js +1 -1
  192. package/dist/esm/index.js.map +1 -1
  193. package/dist/esm/lib/atomic-write.js +14 -6
  194. package/dist/esm/lib/atomic-write.js.map +1 -1
  195. package/dist/esm/lib/serial-query.d.ts +1 -0
  196. package/dist/esm/lib/serial-query.js +13 -0
  197. package/dist/esm/lib/serial-query.js.map +1 -0
  198. package/dist/esm/scan/index.d.ts +5 -0
  199. package/dist/esm/scan/index.js +7 -3
  200. package/dist/esm/scan/index.js.map +1 -1
  201. package/dist/esm/scan/pool.d.ts +5 -0
  202. package/dist/esm/scan/pool.js +41 -16
  203. package/dist/esm/scan/pool.js.map +1 -1
  204. package/dist/esm/store/builder.d.ts +6 -1
  205. package/dist/esm/store/builder.js +19 -0
  206. package/dist/esm/store/builder.js.map +1 -1
  207. package/dist/esm/store/duckdb/lexical.d.ts +2 -0
  208. package/dist/esm/store/duckdb/lexical.js +32 -4
  209. package/dist/esm/store/duckdb/lexical.js.map +1 -1
  210. package/dist/esm/store/duckdb/open.d.ts +3 -3
  211. package/dist/esm/store/duckdb/open.js +13 -6
  212. package/dist/esm/store/duckdb/open.js.map +1 -1
  213. package/dist/esm/store/duckdb/reconcile.js +2 -2
  214. package/dist/esm/store/duckdb/reconcile.js.map +1 -1
  215. package/dist/esm/store/index.d.ts +23 -4
  216. package/dist/esm/store/index.js +80 -15
  217. package/dist/esm/store/index.js.map +1 -1
  218. package/dist/esm/store/open.d.ts +9 -1
  219. package/dist/esm/store/open.js +175 -84
  220. package/dist/esm/store/open.js.map +1 -1
  221. package/dist/esm/store/reconcile.js +12 -0
  222. package/dist/esm/store/reconcile.js.map +1 -1
  223. package/dist/esm/store/sqlite/open.d.ts +3 -3
  224. package/dist/esm/store/sqlite/open.js +9 -6
  225. package/dist/esm/store/sqlite/open.js.map +1 -1
  226. package/dist/esm/store/turso/open.d.ts +3 -3
  227. package/dist/esm/store/turso/open.js +14 -10
  228. package/dist/esm/store/turso/open.js.map +1 -1
  229. package/dist/esm/store/turso/store.d.ts +3 -1
  230. package/dist/esm/store/turso/store.js +5 -1
  231. package/dist/esm/store/turso/store.js.map +1 -1
  232. package/dist/esm/store/types.d.ts +12 -3
  233. package/dist/esm/store/types.js.map +1 -1
  234. package/dist/esm/watch.js +57 -19
  235. package/dist/esm/watch.js.map +1 -1
  236. package/package.json +1 -1
  237. package/schema.json +7 -2
  238. package/skills/sense/SKILL.md +3 -3
  239. package/skills/sense-bases/SKILL.md +1 -2
  240. package/skills/sense-setup/SKILL.md +1 -1
  241. package/skills/sense-setup/references/embeddings.md +1 -1
  242. package/skills/sense-setup/references/store-benchmarks.md +6 -6
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/store/open.ts"],"sourcesContent":["import { channel } from 'node:diagnostics_channel';\nimport { mkdirSync } from 'node:fs';\nimport { join } from 'node:path';\nimport type { ResolvedConfig } from '../config/index.ts';\nimport { featureSignature, STATE_DIR } from '../config/index.ts';\nimport { rekeyChunkText } from '../embed/handoff.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 type { Connection, OpenDialect, Store } from './types.ts';\n\n// One open algorithm shared by every store, parameterised by a per-engine OpenDialect (types.ts).\n// Ordering is universal, not a dialect concern: connect, meta table, schema-version and\n// feature-signature comparison (rebuild, adopt, or partial rebuild), any extra rebuild trigger,\n// ensureSchema, the derived busy_timeout PRAGMA, reconcile, then the store itself.\n\nexport interface OpenResult {\n store: Store;\n cfg: ResolvedConfig;\n dbPath: string;\n parsed: number;\n warnings: string[];\n // Per-stage wall time for this open's build pass (stages.ts), not for any narrow embed or\n // feature invalidation that ran beside it -- on a cold build there is none, so it is the whole cost.\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}\n\n// duckdb/turso hold the cache file for their connection's whole life, so a second command waits.\n// Bounded by this tree's recorded reconcile time (lock-wait.ts), not a fixed guess.\nconst LOCK_POLL_MS = 50;\nconst lockWait = channel('sensemaking.store.lock-wait');\n\nasync function connectUnlocked<Handle>(dbPath: string, cfg: ResolvedConfig, configDir: string, dialect: OpenDialect<Handle>): 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);\n } catch (err) {\n if (!dialect.isLocked?.(err as Error)) throw err;\n // Observe a real rejected native connection, never merely the start of an async open.\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 connectWithDialect<Handle>(cfg: ResolvedConfig, dialect: OpenDialect<Handle>): 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);\n // A throw below must release this handle, or the leaked WAL makes the cache file undeletable on\n // Windows. `closed` keeps the catch from double-closing a handle a rebuild branch already closed.\n let closed = false;\n // Created here, not inside reconcile(): invalidate()/invalidateFeatures() below share its pool\n // with the build() call that follows them.\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 // Schema-version or feature-set mismatch: reconcile only reparses changed files, so an\n // old cache can't be patched incrementally -- rebuild instead (cheap: nothing expensive lives here).\n const version = await getMeta(conn, 'schema_version');\n const features = await getMeta(conn, 'features');\n const wantFeatures = featureSignature(cfg, FEATURES);\n // Set only by the preset-membership branch below; reconcile treats these paths as touched\n // despite an unchanged stamp, for this one build() call.\n let forcedPaths: Set<string> | undefined;\n // Set only by the embed-narrow branch below; applied via builder.invalidate() after ensureSchema.\n let embedInvalidate: EmbedChangeKind | undefined;\n // Set only by the feature-toggle branch below; applied via builder.invalidateFeatures() after ensureSchema.\n let featureToggles: FeatureToggle[] | undefined;\n if ((version !== null && version !== dialect.schemaVersion) || (features !== null && features !== wantFeatures)) {\n // Indexing derives from presets, so a config edit rebuilding the cache must say so and\n // name what changed -- silent rebuilds make derived indexing look like a hang or a bug.\n if (version !== null && version !== dialect.schemaVersion) {\n console.error('sense: cache format changed (new sensemaking version); rebuilding the index');\n // Close before clearCache deletes the files out from under the still-open handle.\n closed = true;\n await dialect.close(handle);\n clearCache(cfg);\n return connectWithDialect(cfg, dialect);\n }\n const changedKeys = changedSignatureKeys(features ?? '', wantFeatures);\n // Null (rather than the empty set) when changedKeys isn't preset-only, or a changed\n // preset's stored segment can't be parsed back into old include/exclude/vectors -- either\n // way the branch below is skipped and the full rebuild stays the fallback.\n const presetForced = isPresetOnlyChange(changedKeys) ? forcedPresetPaths(cfg, cfg.rootDir ?? cfg.baseDir, features ?? '', changedKeys) : null;\n // Null unless exactly one segment changed and it decomposes into a recognised embed-only\n // case (embed-scope.ts): anything else, including embed toggled on/off, stays null.\n const embedKind = changedKeys.size === 1 && changedKeys.has('embed') ? classifyEmbedChange(features ?? '', wantFeatures) : null;\n // Null (rather than the empty set) when changedKeys isn't feature-toggle-only, or a changed\n // feature's stored segment can't be parsed back into old/new on-off -- either way the branch\n // below is skipped and the full rebuild stays the fallback.\n const toggles = isFeatureOnlyChange(changedKeys) ? classifyFeatureToggles(features ?? '', wantFeatures, changedKeys) : null;\n if (changedKeys.size === 1 && changedKeys.has('embed') && embedIdentityAdopted(features ?? '', wantFeatures)) {\n // First sight of a resolved weight identity: the model itself hasn't changed, so\n // adopt it into meta with no rebuild and no re-embed.\n console.error(\"sense: recorded the embedding model's resolved identity; vectors are unaffected\");\n await setMeta(conn, 'features', wantFeatures);\n } else if (embedKind !== null) {\n // Chunk boundaries are file-derived, not model-derived (embed.ts's chunksOf), so neither\n // case needs any file reparsed for any feature but embed itself.\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 await setMeta(conn, 'features', wantFeatures);\n } else if (presetForced !== null) {\n // Membership only: which files a preset covers moved, not a file's own content, a\n // global feature, or the embed model. reconcile() already knows how to\n // add, update, and remove a file correctly (every cross-feature cascade included); it\n // just needs telling which unchanged files to treat as touched (forcedPaths, above).\n forcedPaths = presetForced;\n const changed = signatureDiff(features ?? '', wantFeatures);\n console.error(`sense: config change (${changed}) reparses only the files it affects`);\n await setMeta(conn, 'features', wantFeatures);\n } else if (toggles !== null) {\n // A feature turned off or on: reconcile.ts's activeFeatures skips a disabled feature's\n // hooks entirely, so its rows rot while off -- invalidateFeatures drops them and, for a\n // feature turning back on, fully re-derives across every indexed file rather than\n // trusting rows written before or during that window.\n featureToggles = toggles;\n const changed = signatureDiff(features ?? '', wantFeatures);\n console.error(`sense: config change (${changed}) reparses only the feature it affects`);\n await setMeta(conn, 'features', wantFeatures);\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 connectWithDialect(cfg, dialect);\n }\n }\n\n await dialect.ensureSchema(handle, conn, cfg);\n\n // 3x the largest reconcile this cache has recorded, floored at 30s and capped at 10min.\n // Installed before build() -- that call is the one that races a watcher's transaction.\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 // Runs before build(): forcedPaths, embedInvalidate and featureToggles never target the same\n // call (each comes from its own mutually exclusive branch above: a preset-only, embed-only, or\n // feature-toggle-only changed-key set).\n const embedParsed = embedInvalidate ? (await builder.invalidate(embedInvalidate)).parsed : 0;\n const featureParsed = featureToggles ? (await builder.invalidateFeatures(featureToggles)).parsed : 0;\n\n const { parsed, warnings, stages } = await builder.build(forcedPaths);\n // Every open reconciles once and is done with it -- a watcher opens fresh per event instead of holding this connection (src/watch.ts).\n await builder.close();\n\n return { handle, conn, cfg, dbPath, parsed: parsed + embedParsed + featureParsed, warnings, stages };\n } catch (err) {\n await builder.close();\n if (!closed) await dialect.close(handle);\n throw err;\n }\n}\n\n// A store's open(): connects (see connectWithDialect above), then wraps the resulting connection\n// in the Store interface. The builder's pool closes right after the initial build.\nexport async function openWithDialect<Handle>(cfg: ResolvedConfig, dialect: OpenDialect<Handle>): Promise<OpenResult> {\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 const { handle, conn, cfg: resolvedCfg, dbPath, parsed, warnings, stages } = await connectWithDialect(cfg, dialect);\n const store = dialect.createStore(handle, conn, resolvedCfg);\n // reconcile ran before this object existed, so its chunk text is keyed by the connection.\n rekeyChunkText(conn, store);\n return { store, cfg: resolvedCfg, dbPath, parsed, warnings, stages };\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","LOCK_POLL_MS","lockWait","channel","connectUnlocked","dbPath","cfg","configDir","dialect","budgetMs","deadline","err","lockWaitBudgetMs","Date","now","connect","isLocked","hasSubscribers","publish","store","SenseError","Math","round","Promise","resolve","setTimeout","connectWithDialect","stateDir","handle","conn","closed","builder","version","features","wantFeatures","forcedPaths","embedInvalidate","featureToggles","changedKeys","presetForced","embedKind","toggles","changed","recordedMaxMs","embedParsed","featureParsed","parsed","warnings","stages","baseDir","join","STATE_DIR","mkdirSync","recursive","filename","createBuilder","rootDir","reconcileDialect","exec","getMeta","featureSignature","FEATURES","schemaVersion","console","error","close","clearCache","changedSignatureKeys","isPresetOnlyChange","forcedPresetPaths","size","has","classifyEmbedChange","isFeatureOnlyChange","classifyFeatureToggles","embedIdentityAdopted","setMeta","signatureDiff","ensureSchema","setDerivedBusyTimeout","Number","min","max","invalidate","invalidateFeatures","build","resolvedCfg","createStore","rekeyChunkText","stmt","prepare","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 { 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":["docCount","openWithDialect","prepareDocumentEmbeddings","CORE_READY_META_KEY","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","version","features","ready","wantFeatures","observational","getMeta","schemaVersion","featureSignature","FEATURES","has","assertLexicalReady","parsed","warnings","stages","stageRecorder","take","close","connectForBuild","stateDir","closed","builder","recoverIncomplete","forcedPaths","embedInvalidate","featureToggles","changedKeys","presetForced","embedKind","toggles","changed","recordedMaxMs","embedParsed","featureParsed","mkdirSync","recursive","createBuilder","reconcileDialect","exec","setMeta","console","error","clearCache","changedSignatureKeys","isPresetOnlyChange","forcedPresetPaths","size","classifyEmbedChange","isFeatureOnlyChange","classifyFeatureToggles","embedIdentityAdopted","signatureDiff","ensureSchema","setDerivedBusyTimeout","Number","min","max","invalidate","invalidateFeatures","recover","build","withTransaction","prepareLexical","allowed","preparedSignature","actualSignature","update","result","embedPending","run","changes","input","buildEnabled","defaultRequirements","connected","Set","anyPresetEmbeds","add","createStore","rekeyChunkText","stmt","get","n"],"mappings":"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"}
@@ -523,6 +523,36 @@ function reconcile(conn, cfg, paths, dialect, pool, forcedPaths) {
523
523
  })
524
524
  ];
525
525
  case 8:
526
+ _state.sent();
527
+ if (!(contentTouched.length > 0)) return [
528
+ 3,
529
+ 10
530
+ ];
531
+ return [
532
+ 4,
533
+ conn.runBatch('DELETE FROM indexed_sources WHERE "path" = ?', contentTouched.map(function(p) {
534
+ return [
535
+ p
536
+ ];
537
+ }))
538
+ ];
539
+ case 9:
540
+ _state.sent();
541
+ _state.label = 10;
542
+ case 10:
543
+ return [
544
+ 4,
545
+ (0, _sharedts.appendRows)(conn, 'indexed_sources', [
546
+ 'path',
547
+ 'text'
548
+ ], 'INSERT INTO indexed_sources ("path", text) VALUES (?, ?) ON CONFLICT("path") DO UPDATE SET text = excluded.text', parsedDocs.map(function(doc) {
549
+ return [
550
+ doc.relPath,
551
+ doc.source
552
+ ];
553
+ }))
554
+ ];
555
+ case 11:
526
556
  _state.sent();
527
557
  // A preset edit forces a full rebuild, so an unchanged doc's coverage is already correct;
528
558
  // new docs have nothing to clear, which keeps cold builds linear.
@@ -612,11 +642,11 @@ function reconcile(conn, cfg, paths, dialect, pool, forcedPaths) {
612
642
  })();
613
643
  })
614
644
  ];
615
- case 9:
645
+ case 12:
616
646
  _state.sent();
617
647
  if (!(vanished.length > 0)) return [
618
648
  3,
619
- 11
649
+ 14
620
650
  ];
621
651
  return [
622
652
  4,
@@ -628,22 +658,22 @@ function reconcile(conn, cfg, paths, dialect, pool, forcedPaths) {
628
658
  }));
629
659
  })
630
660
  ];
631
- case 10:
661
+ case 13:
632
662
  _state.sent();
633
- _state.label = 11;
634
- case 11:
663
+ _state.label = 14;
664
+ case 14:
635
665
  _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
636
666
  if (!(touched.length > 0)) return [
637
667
  3,
638
- 19
668
+ 22
639
669
  ];
640
- _state.label = 12;
641
- case 12:
670
+ _state.label = 15;
671
+ case 15:
642
672
  _state.trys.push([
643
- 12,
644
- 17,
645
- 18,
646
- 19
673
+ 15,
674
+ 20,
675
+ 21,
676
+ 22
647
677
  ]);
648
678
  _loop = function() {
649
679
  var feature;
@@ -667,39 +697,39 @@ function reconcile(conn, cfg, paths, dialect, pool, forcedPaths) {
667
697
  });
668
698
  };
669
699
  _iterator = features[Symbol.iterator]();
670
- _state.label = 13;
671
- case 13:
700
+ _state.label = 16;
701
+ case 16:
672
702
  if (!!(_iteratorNormalCompletion = (_step = _iterator.next()).done)) return [
673
703
  3,
674
- 16
704
+ 19
675
705
  ];
676
706
  return [
677
707
  5,
678
708
  _ts_values(_loop())
679
709
  ];
680
- case 14:
710
+ case 17:
681
711
  _state.sent();
682
- _state.label = 15;
683
- case 15:
712
+ _state.label = 18;
713
+ case 18:
684
714
  _iteratorNormalCompletion = true;
685
715
  return [
686
716
  3,
687
- 13
717
+ 16
688
718
  ];
689
- case 16:
719
+ case 19:
690
720
  return [
691
721
  3,
692
- 19
722
+ 22
693
723
  ];
694
- case 17:
724
+ case 20:
695
725
  err = _state.sent();
696
726
  _didIteratorError = true;
697
727
  _iteratorError = err;
698
728
  return [
699
729
  3,
700
- 19
730
+ 22
701
731
  ];
702
- case 18:
732
+ case 21:
703
733
  try {
704
734
  if (!_iteratorNormalCompletion && _iterator.return != null) {
705
735
  _iterator.return();
@@ -712,15 +742,15 @@ function reconcile(conn, cfg, paths, dialect, pool, forcedPaths) {
712
742
  return [
713
743
  7
714
744
  ];
715
- case 19:
745
+ case 22:
716
746
  _iteratorNormalCompletion1 = true, _didIteratorError1 = false, _iteratorError1 = undefined;
717
- _state.label = 20;
718
- case 20:
747
+ _state.label = 23;
748
+ case 23:
719
749
  _state.trys.push([
720
- 20,
721
- 25,
722
- 26,
723
- 27
750
+ 23,
751
+ 28,
752
+ 29,
753
+ 30
724
754
  ]);
725
755
  _loop1 = function() {
726
756
  var feature, docsForFeature;
@@ -750,39 +780,39 @@ function reconcile(conn, cfg, paths, dialect, pool, forcedPaths) {
750
780
  });
751
781
  };
752
782
  _iterator1 = features[Symbol.iterator]();
753
- _state.label = 21;
754
- case 21:
783
+ _state.label = 24;
784
+ case 24:
755
785
  if (!!(_iteratorNormalCompletion1 = (_step1 = _iterator1.next()).done)) return [
756
786
  3,
757
- 24
787
+ 27
758
788
  ];
759
789
  return [
760
790
  5,
761
791
  _ts_values(_loop1())
762
792
  ];
763
- case 22:
793
+ case 25:
764
794
  _state.sent();
765
- _state.label = 23;
766
- case 23:
795
+ _state.label = 26;
796
+ case 26:
767
797
  _iteratorNormalCompletion1 = true;
768
798
  return [
769
799
  3,
770
- 21
800
+ 24
771
801
  ];
772
- case 24:
802
+ case 27:
773
803
  return [
774
804
  3,
775
- 27
805
+ 30
776
806
  ];
777
- case 25:
807
+ case 28:
778
808
  err = _state.sent();
779
809
  _didIteratorError1 = true;
780
810
  _iteratorError1 = err;
781
811
  return [
782
812
  3,
783
- 27
813
+ 30
784
814
  ];
785
- case 26:
815
+ case 29:
786
816
  try {
787
817
  if (!_iteratorNormalCompletion1 && _iterator1.return != null) {
788
818
  _iterator1.return();
@@ -795,15 +825,15 @@ function reconcile(conn, cfg, paths, dialect, pool, forcedPaths) {
795
825
  return [
796
826
  7
797
827
  ];
798
- case 27:
828
+ case 30:
799
829
  _iteratorNormalCompletion2 = true, _didIteratorError2 = false, _iteratorError2 = undefined;
800
- _state.label = 28;
801
- case 28:
830
+ _state.label = 31;
831
+ case 31:
802
832
  _state.trys.push([
803
- 28,
804
- 33,
805
- 34,
806
- 35
833
+ 31,
834
+ 36,
835
+ 37,
836
+ 38
807
837
  ]);
808
838
  _loop2 = function() {
809
839
  var feature;
@@ -827,39 +857,39 @@ function reconcile(conn, cfg, paths, dialect, pool, forcedPaths) {
827
857
  });
828
858
  };
829
859
  _iterator2 = features[Symbol.iterator]();
830
- _state.label = 29;
831
- case 29:
860
+ _state.label = 32;
861
+ case 32:
832
862
  if (!!(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done)) return [
833
863
  3,
834
- 32
864
+ 35
835
865
  ];
836
866
  return [
837
867
  5,
838
868
  _ts_values(_loop2())
839
869
  ];
840
- case 30:
870
+ case 33:
841
871
  _state.sent();
842
- _state.label = 31;
843
- case 31:
872
+ _state.label = 34;
873
+ case 34:
844
874
  _iteratorNormalCompletion2 = true;
845
875
  return [
846
876
  3,
847
- 29
877
+ 32
848
878
  ];
849
- case 32:
879
+ case 35:
850
880
  return [
851
881
  3,
852
- 35
882
+ 38
853
883
  ];
854
- case 33:
884
+ case 36:
855
885
  err = _state.sent();
856
886
  _didIteratorError2 = true;
857
887
  _iteratorError2 = err;
858
888
  return [
859
889
  3,
860
- 35
890
+ 38
861
891
  ];
862
- case 34:
892
+ case 37:
863
893
  try {
864
894
  if (!_iteratorNormalCompletion2 && _iterator2.return != null) {
865
895
  _iterator2.return();
@@ -872,7 +902,7 @@ function reconcile(conn, cfg, paths, dialect, pool, forcedPaths) {
872
902
  return [
873
903
  7
874
904
  ];
875
- case 35:
905
+ case 38:
876
906
  return [
877
907
  2
878
908
  ];
@@ -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 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 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 { rootDir, configDir } = paths;\n const start = process.hrtime.bigint();\n const features = activeFeatures(cfg);\n const stages = stageRecorder(features.map((f) => f.name));\n const elapsed = () => Number(process.hrtime.bigint() - start) / 1e6;\n const files = await stages.time('list', () => listFiles(cfg, rootDir));\n const currentSet = new Set(files.map((f) => f.relPath));\n\n const existingRows = await stages.time('existing', async () => {\n const existingStmt = await conn.prepare('SELECT \"path\", \"_mtime\", \"_size\" FROM frontmatter');\n return (await existingStmt.all()) as Array<{ path: string; _mtime: number; _size: number }>;\n });\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) return { parsed: 0, warnings: [], stages: stages.take(elapsed(), 0) };\n\n const seenColumns = await getColumns(conn);\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 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 const txStart = Date.now();\n await withTransaction(\n conn,\n async () => {\n // Re-read inside the write transaction: newColumns came from a read taken before it opened, so a\n // concurrent reconcile may have added some of them since. ALTER has no IF NOT EXISTS.\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 // Revalidated once the lock is held, before this process's own frontmatter upsert below:\n // `added` came from a path read taken before this transaction's lock, so a path still\n // called \"added\" here may already have a content row from a concurrent reconcile that\n // committed while this one waited. One SELECT, not a DELETE per added file -- with no\n // contention it returns the same set `existing` already ruled out, so nothing extra clears.\n let contentTouched = touched;\n if (added.length > 0)\n contentTouched = await stages.time('added-recheck', async () => {\n const currentPathsStmt = await conn.prepare('SELECT \"path\" FROM frontmatter');\n const currentPaths = new Set(((await currentPathsStmt.all()) as Array<{ path: string }>).map((r) => r.path));\n const staleAdded = added.filter((p) => currentPaths.has(p));\n return staleAdded.length > 0 ? [...touched, ...staleAdded] : touched;\n });\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 // Written per parse, unlike _rank, which a feature pass owns and the upsert skips.\n if (col === '_parse_error') return doc.parseError;\n return doc.data[col] ?? null;\n });\n // A path in `added` has no existing frontmatter row, so it can never conflict; the rest\n // genuinely can, and keep the upsert.\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) await conn.runBatch(insertSql, updateDocs.map(toRow));\n });\n }\n\n // After the upsert, so every doc already has the frontmatter row sqlite's content rowid\n // couples to. ON CONFLICT DO UPDATE preserves that rowid, so a reparse keeps its identity.\n await stages.time('text-index', () => dialect.reconcileContent(conn, contentTouched, parsedDocs, delta, cfg));\n\n // A preset edit forces a full rebuild, so an unchanged doc's coverage is already correct;\n // new docs have nothing to clear, which keeps cold builds linear.\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 // DO NOTHING, not a bare INSERT: the added/touched split above comes from a read taken\n // before this transaction's lock, so a path this process calls \"added\" can already have\n // its (path, preset) row committed by a concurrent reconcile -- the row would be identical either way.\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 // Before the feature hooks, never after: rank's afterReconcile reads frontmatter as PageRank's\n // node set, so a lingering vanished row would dilute rank mass across every surviving note.\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 // Timed per feature per hook, so link resolution and PageRank are named stages without\n // links.ts or rank.ts knowing anything about this, and a new feature is visible for free.\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 dialect.beginMode()\n );\n\n const durationMs = Date.now() - txStart;\n // Every store, not just the ones with a PRAGMA to derive: connectUnlocked's lock-wait budget needs it too.\n recordLockWaitMs(configDir, durationMs);\n if (dialect.recordDuration) await stages.time('meta', () => dialect.recordDuration?.(conn, durationMs));\n\n return { parsed: parsedDocs.length, warnings, stages: stages.take(elapsed(), durationMs, workerParseMs) };\n}\n"],"names":["CORE_FRONTMATTER_COLUMNS","reconcile","Set","conn","cfg","paths","dialect","pool","forcedPaths","rootDir","configDir","start","features","stages","elapsed","files","currentSet","existingRows","existing","vanished","toReparse","seenColumns","report","parsedDocs","warnings","newColumns","workerParseMs","col","allColumns","writableColumns","insertSql","added","delta","addedSet","reparsedExisting","touched","txStart","durationMs","process","hrtime","bigint","activeFeatures","stageRecorder","map","f","name","Number","time","listFiles","relPath","existingStmt","prepare","all","Map","r","path","filter","has","row","get","_mtime","mtimeMs","_size","size","length","parsed","take","getColumns","progress","reparseFiles","tick","docs","finish","add","checkColumnLimit","c","RESERVED_COLUMNS","quoteIdent","join","reparsed","d","p","Date","now","withTransaction","present","missingColumns","contentTouched","toRow","addColumns","currentPathsStmt","currentPaths","staleAdded","doc","ctimeMs","parseError","data","newDocs","updateDocs","appendRows","runBatch","reconcileContent","presetRows","presetName","presets","push","feature","featureStage","remove","docsForFeature","extracted","store","afterReconcile","beginMode","recordLockWaitMs","recordDuration"],"mappings":";;;;;;;;;;;QAqBaA;eAAAA;;QAOSC;eAAAA;;;uBA3BS;0BAEN;wBACmB;yBAEf;0BACI;wBACkB;wBACM;6BACzB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAWzB,IAAMD,2BAA2B,IAAIE,IAAI;IAAC;IAAQ;IAAU;IAAU;IAAS;CAAe;AAO9F,SAAeD,UAAUE,IAAgB,EAAEC,GAAW,EAAEC,KAAqB,EAAEC,OAAyB,EAAEC,IAAgB,EAAEC,WAAiC;;YAC1JC,SAASC,WACXC,OACAC,UACAC,QACAC,SACAC,OACAC,YAEAC,cAIAC,UAIAC,UAIAC,WAOAC,aAIAC,QAE4D,MAApDC,YAAYC,UAAUC,YAAYC,eAE3C,2BAAA,mBAAA,gBAAA,WAAA,OAAMC,KAELC,YAMAC,iBAGAC,WAKAC,OACAC,OACAC,UACAC,kBAGAC,SAEAC,SAuFAC;;;;oBAlJE5B,UAAuBJ,MAAvBI,SAASC,YAAcL,MAAdK;oBACXC,QAAQ2B,QAAQC,MAAM,CAACC,MAAM;oBAC7B5B,WAAW6B,IAAAA,uBAAc,EAACrC;oBAC1BS,SAAS6B,IAAAA,uBAAa,EAAC9B,SAAS+B,GAAG,CAAC,SAACC;+BAAMA,EAAEC,IAAI;;oBACjD/B,UAAU;+BAAMgC,OAAOR,QAAQC,MAAM,CAACC,MAAM,KAAK7B,SAAS;;oBAClD;;wBAAME,OAAOkC,IAAI,CAAC,QAAQ;mCAAMC,IAAAA,mBAAS,EAAC5C,KAAKK;;;;oBAAvDM,QAAQ;oBACRC,aAAa,IAAId,IAAIa,MAAM4B,GAAG,CAAC,SAACC;+BAAMA,EAAEK,OAAO;;oBAEhC;;wBAAMpC,OAAOkC,IAAI,CAAC,YAAY;;oCAC3CG;;;;4CAAe;;gDAAM/C,KAAKgD,OAAO,CAAC;;;4CAAlCD,eAAe;4CACb;;gDAAMA,aAAaE,GAAG;;;4CAA9B;;gDAAQ;;;;4BACV;;;;oBAHMnC,eAAe;oBAIfC,WAAW,IAAImC,IAAIpC,aAAa0B,GAAG,CAAC,SAACW;+BAAM;4BAACA,EAAEC,IAAI;4BAAED;yBAAE;;oBAC5D,+FAA+F;oBAC/F,+FAA+F;oBAC/F,gFAAgF;oBAC1EnC,WAAWF,aAAauC,MAAM,CAAC,SAACF;+BAAM,CAACtC,WAAWyC,GAAG,CAACH,EAAEC,IAAI;uBAAGZ,GAAG,CAAC,SAACW;+BAAMA,EAAEC,IAAI;;oBAEtF,6FAA6F;oBAC7F,0FAA0F;oBACpFnC,YAAYL,MAAMyC,MAAM,CAAC,SAACZ;;wBAC9B,IAAMc,MAAMxC,SAASyC,GAAG,CAACf,EAAEK,OAAO;wBAClC,OAAO,CAACS,OAAOA,IAAIE,MAAM,KAAKhB,EAAEiB,OAAO,IAAIH,IAAII,KAAK,KAAKlB,EAAEmB,IAAI,aAAKvD,wBAAAA,kCAAAA,YAAaiD,GAAG,CAACb,EAAEK,OAAO,wCAAK;oBACrG;oBAEA,IAAI9B,SAAS6C,MAAM,KAAK,KAAK5C,UAAU4C,MAAM,KAAK,GAAG;;wBAAO;4BAAEC,QAAQ;4BAAGzC,QAAQ;4BAAMX,QAAQA,OAAOqD,IAAI,CAACpD,WAAW;wBAAG;;oBAErG;;wBAAMqD,IAAAA,oBAAU,EAAChE;;;oBAA/BkB,cAAc;oBAEpB,oFAAoF;oBACpF,uDAAuD;oBACjDC,SAAS8C,IAAAA,oBAAQ,EAAC,mBAAmBhD,UAAU4C,MAAM;oBAEO;;wBAAMnD,OAAOkC,IAAI,CAAC,SAAS;mCAAMsB,IAAAA,uBAAY,EAACjD,WAAWR,UAAUR,KAAKiB,aAAaC,OAAOgD,IAAI,EAAE;gCAAE/D,MAAAA;4BAAK;;;;oBAAzG,OAAA,eAApDgB,aAAoD,KAA1DgD,MAAkB/C,WAAwC,KAAxCA,UAAUC,aAA8B,KAA9BA,YAAYC,gBAAkB,KAAlBA;oBAChDJ,OAAOkD,MAAM;oBACR,kCAAA,2BAAA;;wBAAL,IAAK,YAAa/C,iCAAb,6BAAA,QAAA,yBAAA;4BAAME,MAAN;4BAAyBN,YAAYoD,GAAG,CAAC9C;;;wBAAzC;wBAAA;;;iCAAA,6BAAA;gCAAA;;;gCAAA;sCAAA;;;;oBAECC,aAAc,qBAAGP;oBACvB,yFAAyF;oBACzF,iGAAiG;oBACjGf,QAAQoE,gBAAgB,CAAC9C,WAAWoC,MAAM;oBAC1C,0FAA0F;oBAC1F,sEAAsE;oBAChEnC,kBAAkBD,WAAW4B,MAAM,CAAC,SAACmB;+BAAM3E,yBAAyByD,GAAG,CAACkB,MAAM,CAACC,0BAAgB,CAACnB,GAAG,CAACkB;;oBAC1G,yFAAyF;oBACzF,mDAAmD;oBAC7C7C,YAAY,AAAC,4BAAkFD,OAAvDA,gBAAgBc,GAAG,CAACkC,oBAAU,EAAEC,IAAI,CAAC,OAAM,cAA4FjD,OAAhFA,gBAAgBc,GAAG,CAAC;+BAAM;uBAAKmC,IAAI,CAAC,OAAM,wCAGjI,OAHuKjD,gBAClL2B,MAAM,CAAC,SAACmB;+BAAMA,MAAM;uBACpBhC,GAAG,CAAC,SAACgC;+BAAM,AAAC,GAA8BE,OAA5BA,IAAAA,oBAAU,EAACF,IAAG,gBAA4B,OAAdE,IAAAA,oBAAU,EAACF;uBACrDG,IAAI,CAAC;oBAEF/C,QAAQX,UAAUoC,MAAM,CAAC,SAACZ;+BAAM,CAAC1B,SAASuC,GAAG,CAACb,EAAEK,OAAO;uBAAGN,GAAG,CAAC,SAACC;+BAAMA,EAAEK,OAAO;;oBAC9EjB,QAAwB;wBAAEjB,OAAAA;wBAAOgE,UAAUxD,WAAWoB,GAAG,CAAC,SAACqC;mCAAMA,EAAE/B,OAAO;;wBAAGlB,OAAAA;wBAAOZ,UAAAA;oBAAS;oBAC7Fc,WAAW,IAAI/B,IAAI6B;oBACnBG,mBAAmBX,WAAWoB,GAAG,CAAC,SAACqC;+BAAMA,EAAE/B,OAAO;uBAAEO,MAAM,CAAC,SAACyB;+BAAM,CAAChD,SAASwB,GAAG,CAACwB;;oBACtF,+FAA+F;oBAC/F,0EAA0E;oBACpE9C,UAAU,AAAC,qBAAGhB,iBAAU,qBAAGe;oBAE3BE,UAAU8C,KAAKC,GAAG;oBACxB;;wBAAMC,IAAAA,8BAAe,EACnBjF,MACA;;oCAGQkF,SACAC,gBAQFC,gBAUIC,OAoDqB,2BAAA,mBAAA,uBAAA,WAAA,YACxB,4BAAA,oBAAA,yBAAA,YAAA,aAIA,4BAAA,oBAAA,yBAAA,YAAA;;;;4CA5EW;;gDAAMrB,IAAAA,oBAAU,EAAChE;;;4CAA3BkF,UAAU;4CACVC,iBAAiB7D,WAAW+B,MAAM,CAAC,SAAC7B;uDAAQ,CAAC0D,QAAQ5B,GAAG,CAAC9B;;iDAC3D2D,CAAAA,eAAetB,MAAM,GAAG,CAAA,GAAxBsB;;;;4CAA2B;;gDAAMzE,OAAOkC,IAAI,CAAC,SAAS;2DAAMzC,QAAQmF,UAAU,CAACtF,MAAMmF;;;;4CAA1D;;;4CAE/B,yFAAyF;4CACzF,sFAAsF;4CACtF,sFAAsF;4CACtF,sFAAsF;4CACtF,4FAA4F;4CACxFC,iBAAiBpD;iDACjBJ,CAAAA,MAAMiC,MAAM,GAAG,CAAA,GAAfjC;;;;4CACe;;gDAAMlB,OAAOkC,IAAI,CAAC,iBAAiB;;4DAC5C2C,kBACAC,iBACAC;;;;oEAFmB;;wEAAMzF,KAAKgD,OAAO,CAAC;;;oEAAtCuC,mBAAmB;wEACAxF;oEAAM;;wEAAMwF,iBAAiBtC,GAAG;;;oEAAnDuC,eAAe,IAAA,CAAA,EAAA,MAAIzF;;wEAAM,cAA0DyC,GAAG,CAAC,SAACW;mFAAMA,EAAEC,IAAI;;sEAAC;oEACrGqC,aAAa7D,MAAMyB,MAAM,CAAC,SAACyB;+EAAMU,aAAalC,GAAG,CAACwB;;oEACxD;;wEAAOW,WAAW5B,MAAM,GAAG,IAAI,AAAC,qBAAG7B,gBAAS,qBAAGyD,eAAczD;;;;oDAC/D;;;;4CALAoD,iBAAiB;;;iDAOfhE,CAAAA,WAAWyC,MAAM,GAAG,CAAA,GAApBzC;;;;4CACIiE,QAAQ,eAACK;uDACbhE,gBAAgBc,GAAG,CAAC,SAAChB;wDAOZkE;oDANP,IAAIlE,QAAQ,QAAQ,OAAOkE,IAAI5C,OAAO;oDACtC,IAAItB,QAAQ,UAAU,OAAOkE,IAAIhC,OAAO;oDACxC,IAAIlC,QAAQ,UAAU,OAAOkE,IAAIC,OAAO;oDACxC,IAAInE,QAAQ,SAAS,OAAOkE,IAAI9B,IAAI;oDACpC,mFAAmF;oDACnF,IAAIpC,QAAQ,gBAAgB,OAAOkE,IAAIE,UAAU;oDACjD,QAAOF,gBAAAA,IAAIG,IAAI,CAACrE,IAAI,cAAbkE,2BAAAA,gBAAiB;gDAC1B;;4CACF,wFAAwF;4CACxF,sCAAsC;4CACtC;;gDAAMhF,OAAOkC,IAAI,CAAC,aAAa;;4DACvBkD,SACAC;;;;oEADAD,UAAU1E,WAAWiC,MAAM,CAAC,SAACwB;+EAAM/C,SAASwB,GAAG,CAACuB,EAAE/B,OAAO;;oEACzDiD,aAAa3E,WAAWiC,MAAM,CAAC,SAACwB;+EAAM,CAAC/C,SAASwB,GAAG,CAACuB,EAAE/B,OAAO;;oEACnE;;wEAAMkD,IAAAA,oBAAU,EAAChG,MAAM,eAAe0B,iBAAiBC,WAAWmE,QAAQtD,GAAG,CAAC6C;;;oEAA9E;yEACIU,CAAAA,WAAWlC,MAAM,GAAG,CAAA,GAApBkC;;;;oEAAuB;;wEAAM/F,KAAKiG,QAAQ,CAACtE,WAAWoE,WAAWvD,GAAG,CAAC6C;;;oEAA9C;;;;;;;;oDAC7B;;;;4CALA;;;4CAQF,wFAAwF;4CACxF,2FAA2F;4CAC3F;;gDAAM3E,OAAOkC,IAAI,CAAC,cAAc;2DAAMzC,QAAQ+F,gBAAgB,CAAClG,MAAMoF,gBAAgBhE,YAAYS,OAAO5B;;;;4CAAxG;4CAEA,0FAA0F;4CAC1F,kEAAkE;4CAClE;;gDAAMS,OAAOkC,IAAI,CAAC,WAAW;;4DAMrBuD,YAC6B,2BAAA,mBAAA,gBAA9B,4BAAA,oBAAA,iBAAA,WAAA,OAAMT,KAAwB,YAAA,QAAMU;;;;yEANrCpE,CAAAA,QAAQ6B,MAAM,GAAG,CAAA,GAAjB7B;;;;oEACF;;wEAAMhC,KAAKiG,QAAQ,CACjB,6CACAjE,QAAQQ,GAAG,CAAC,SAACsC;mFAAM;gFAACA;6EAAE;;;;oEAFxB;;;oEAIIqB;oEAC6B,kCAAA,2BAAA,4BAA9B,mCAAA,4BAAA;;wEAAL,IAAK,YAAa/E,iCAAb,8BAAA,QAAA,yBAAA;4EAAMsE,MAAN;;gFAAyB,IAAK,aAAoBA,IAAIW,OAAO,uBAA/B,6BAAA,SAAA,0BAAA;oFAAMD,aAAN;oFAAiCD,WAAWG,IAAI;wFAAEZ,IAAI5C,OAAO;wFAAEsD;;;;gFAA/D;gFAAA;;;yFAAA,6BAAA;wFAAA;;;wFAAA;8FAAA;;;;;;wEAA9B;wEAAA;;;iFAAA,8BAAA;gFAAA;;;gFAAA;sFAAA;;;;oEACL,uFAAuF;oEACvF,wFAAwF;oEACxF,uGAAuG;oEACvG;;wEAAMJ,IAAAA,oBAAU,EAAChG,MAAM;4EAAiB;4EAAQ;2EAAW,kGAAkGmG;;;oEAA7J;;;;;;oDACF;;;;4CAZA;iDAgBInF,CAAAA,SAAS6C,MAAM,GAAG,CAAA,GAAlB7C;;;;4CACF;;gDAAMN,OAAOkC,IAAI,CAAC,YAAY;2DAC5B5C,KAAKiG,QAAQ,CACX,4CACAjF,SAASwB,GAAG,CAAC,SAACsC;+DAAM;4DAACA;yDAAE;;;;;4CAH3B;;;4CAS2B,kCAAA,2BAAA;iDAAzB9C,CAAAA,QAAQ6B,MAAM,GAAG,CAAA,GAAjB7B;;;;;;;;;;;;;oDAA+BuE;;;;4DAAAA,UAAN;4DAA2B;;gEAAM7F,OAAOkC,IAAI,CAAC4D,IAAAA,sBAAY,EAACD,QAAQ7D,IAAI,EAAE,WAAW;wEAAM6D;4EAAAA,kBAAAA,QAAQE,MAAM,cAAdF,sCAAAA,qBAAAA,SAAiBvG,MAAMgC,SAASH;;;;4DAA9F;;;;;;;4CAA3B,YAAiBpB;;;mDAAjB,6BAAA,QAAA;;;;;;;;;;;;4CAAA;;;;;;;;;;;;4CAAA;4CAAA;;;;;;;qDAAA,6BAAA;oDAAA;;;oDAAA;0DAAA;;;;;;;4CACxB,mCAAA,4BAAA;;;;;;;;;;oDAAM8F,SACHG;;;;4DADGH,UAAN;4DACGG,iBAAiCtF,WAAWoB,GAAG,CAAC,SAACkD;uEAAS;oEAAEtC,MAAMsC,IAAI5C,OAAO;oEAAE6D,WAAWjB,IAAIiB,SAAS,CAACJ,QAAQ7D,IAAI,CAAC;gEAAC;;4DAC5H;;gEAAMhC,OAAOkC,IAAI,CAAC4D,IAAAA,sBAAY,EAACD,QAAQ7D,IAAI,EAAE,UAAU;wEAAM6D;4EAAAA,iBAAAA,QAAQK,KAAK,cAAbL,qCAAAA,oBAAAA,SAAgBvG,MAAM0G,gBAAgB7E;;;;4DAAnG;;;;;;4CACF;4CAHK,aAAiBpB;;;mDAAjB,8BAAA,SAAA;;;;;;;;;;;;4CAAA;;;;;;;;;;;;4CAAA;4CAAA;;;;;;;qDAAA,8BAAA;oDAAA;;;oDAAA;0DAAA;;;;;;;4CAIA,mCAAA,4BAAA;;;;;;;;;;oDAAM8F;;;;4DAAAA,UAAN;4DAA2B;;gEAAM7F,OAAOkC,IAAI,CAAC4D,IAAAA,sBAAY,EAACD,QAAQ7D,IAAI,EAAE,UAAU;wEAAM6D;4EAAAA,0BAAAA,QAAQM,cAAc,cAAtBN,8CAAAA,6BAAAA,SAAyBvG,MAAM6B;;;;4DAA5F;;;;;;;4CAA3B,aAAiBpB;;;mDAAjB,8BAAA,SAAA;;;;;;;;;;;;4CAAA;;;;;;;;;;;;4CAAA;4CAAA;;;;;;;qDAAA,8BAAA;oDAAA;;;oDAAA;0DAAA;;;;;;;;;;;;4BACP;2BACAN,QAAQ2G,SAAS;;;oBAnFnB;oBAsFM5E,aAAa6C,KAAKC,GAAG,KAAK/C;oBAChC,2GAA2G;oBAC3G8E,IAAAA,4BAAgB,EAACxG,WAAW2B;yBACxB/B,QAAQ6G,cAAc,EAAtB7G;;;;oBAAwB;;wBAAMO,OAAOkC,IAAI,CAAC,QAAQ;gCAAMzC;oCAAAA,0BAAAA,QAAQ6G,cAAc,cAAtB7G,8CAAAA,6BAAAA,SAAyBH,MAAMkC;;;;oBAA/D;;;oBAE5B;;wBAAO;4BAAE4B,QAAQ1C,WAAWyC,MAAM;4BAAExC,UAAAA;4BAAUX,QAAQA,OAAOqD,IAAI,CAACpD,WAAWuB,YAAYX;wBAAe;;;;IAC1G"}
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 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 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 { rootDir, configDir } = paths;\n const start = process.hrtime.bigint();\n const features = activeFeatures(cfg);\n const stages = stageRecorder(features.map((f) => f.name));\n const elapsed = () => Number(process.hrtime.bigint() - start) / 1e6;\n const files = await stages.time('list', () => listFiles(cfg, rootDir));\n const currentSet = new Set(files.map((f) => f.relPath));\n\n const existingRows = await stages.time('existing', async () => {\n const existingStmt = await conn.prepare('SELECT \"path\", \"_mtime\", \"_size\" FROM frontmatter');\n return (await existingStmt.all()) as Array<{ path: string; _mtime: number; _size: number }>;\n });\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) return { parsed: 0, warnings: [], stages: stages.take(elapsed(), 0) };\n\n const seenColumns = await getColumns(conn);\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 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 const txStart = Date.now();\n await withTransaction(\n conn,\n async () => {\n // Re-read inside the write transaction: newColumns came from a read taken before it opened, so a\n // concurrent reconcile may have added some of them since. ALTER has no IF NOT EXISTS.\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 // Revalidated once the lock is held, before this process's own frontmatter upsert below:\n // `added` came from a path read taken before this transaction's lock, so a path still\n // called \"added\" here may already have a content row from a concurrent reconcile that\n // committed while this one waited. One SELECT, not a DELETE per added file -- with no\n // contention it returns the same set `existing` already ruled out, so nothing extra clears.\n let contentTouched = touched;\n if (added.length > 0)\n contentTouched = await stages.time('added-recheck', async () => {\n const currentPathsStmt = await conn.prepare('SELECT \"path\" FROM frontmatter');\n const currentPaths = new Set(((await currentPathsStmt.all()) as Array<{ path: string }>).map((r) => r.path));\n const staleAdded = added.filter((p) => currentPaths.has(p));\n return staleAdded.length > 0 ? [...touched, ...staleAdded] : touched;\n });\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 // Written per parse, unlike _rank, which a feature pass owns and the upsert skips.\n if (col === '_parse_error') return doc.parseError;\n return doc.data[col] ?? null;\n });\n // A path in `added` has no existing frontmatter row, so it can never conflict; the rest\n // genuinely can, and keep the upsert.\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) await conn.runBatch(insertSql, updateDocs.map(toRow));\n });\n }\n\n // After the upsert, so every doc already has the frontmatter row sqlite's content rowid\n // couples to. ON CONFLICT DO UPDATE preserves that rowid, so a reparse keeps its identity.\n await stages.time('text-index', () => dialect.reconcileContent(conn, contentTouched, parsedDocs, delta, cfg));\n\n // Exact source text belongs to the same indexed generation as content and section ranges.\n // The upsert also covers an added path another writer committed while this build waited.\n if (contentTouched.length > 0)\n await conn.runBatch(\n 'DELETE FROM indexed_sources WHERE \"path\" = ?',\n contentTouched.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 // A preset edit forces a full rebuild, so an unchanged doc's coverage is already correct;\n // new docs have nothing to clear, which keeps cold builds linear.\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 // DO NOTHING, not a bare INSERT: the added/touched split above comes from a read taken\n // before this transaction's lock, so a path this process calls \"added\" can already have\n // its (path, preset) row committed by a concurrent reconcile -- the row would be identical either way.\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 // Before the feature hooks, never after: rank's afterReconcile reads frontmatter as PageRank's\n // node set, so a lingering vanished row would dilute rank mass across every surviving note.\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 // Timed per feature per hook, so link resolution and PageRank are named stages without\n // links.ts or rank.ts knowing anything about this, and a new feature is visible for free.\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 dialect.beginMode()\n );\n\n const durationMs = Date.now() - txStart;\n // Every store, not just the ones with a PRAGMA to derive: connectUnlocked's lock-wait budget needs it too.\n recordLockWaitMs(configDir, durationMs);\n if (dialect.recordDuration) await stages.time('meta', () => dialect.recordDuration?.(conn, durationMs));\n\n return { parsed: parsedDocs.length, warnings, stages: stages.take(elapsed(), durationMs, workerParseMs) };\n}\n"],"names":["CORE_FRONTMATTER_COLUMNS","reconcile","Set","conn","cfg","paths","dialect","pool","forcedPaths","rootDir","configDir","start","features","stages","elapsed","files","currentSet","existingRows","existing","vanished","toReparse","seenColumns","report","parsedDocs","warnings","newColumns","workerParseMs","col","allColumns","writableColumns","insertSql","added","delta","addedSet","reparsedExisting","touched","txStart","durationMs","process","hrtime","bigint","activeFeatures","stageRecorder","map","f","name","Number","time","listFiles","relPath","existingStmt","prepare","all","Map","r","path","filter","has","row","get","_mtime","mtimeMs","_size","size","length","parsed","take","getColumns","progress","reparseFiles","tick","docs","finish","add","checkColumnLimit","c","RESERVED_COLUMNS","quoteIdent","join","reparsed","d","p","Date","now","withTransaction","present","missingColumns","contentTouched","toRow","addColumns","currentPathsStmt","currentPaths","staleAdded","doc","ctimeMs","parseError","data","newDocs","updateDocs","appendRows","runBatch","reconcileContent","source","presetRows","presetName","presets","push","feature","featureStage","remove","docsForFeature","extracted","store","afterReconcile","beginMode","recordLockWaitMs","recordDuration"],"mappings":"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"}
@@ -1,12 +1,12 @@
1
1
  import { DatabaseSync } from 'node:sqlite';
2
2
  import type { ResolvedConfig } from '../../config/index.js';
3
- import type { OpenResult } from '../open.js';
3
+ import type { InternalOpenOptions, OpenResult } from '../open.js';
4
4
  import type { OpenDialect } from '../types.js';
5
5
  export declare const DB_FILENAME = "cache.db";
6
- export declare const SCHEMA_VERSION = "20";
6
+ export declare const SCHEMA_VERSION = "21";
7
7
  export type { OpenResult };
8
8
  interface SqliteHandle {
9
9
  db: DatabaseSync;
10
10
  }
11
11
  export declare const sqliteOpenDialect: OpenDialect<SqliteHandle>;
12
- export declare function openSqlite(cfg: ResolvedConfig): Promise<OpenResult>;
12
+ export declare function openSqlite(cfg: ResolvedConfig, options?: InternalOpenOptions): Promise<OpenResult>;
@@ -1,12 +1,12 @@
1
1
  import { DatabaseSync } from 'node:sqlite';
2
2
  import type { ResolvedConfig } from '../../config/index.js';
3
- import type { OpenResult } from '../open.js';
3
+ import type { InternalOpenOptions, OpenResult } from '../open.js';
4
4
  import type { OpenDialect } from '../types.js';
5
5
  export declare const DB_FILENAME = "cache.db";
6
- export declare const SCHEMA_VERSION = "20";
6
+ export declare const SCHEMA_VERSION = "21";
7
7
  export type { OpenResult };
8
8
  interface SqliteHandle {
9
9
  db: DatabaseSync;
10
10
  }
11
11
  export declare const sqliteOpenDialect: OpenDialect<SqliteHandle>;
12
- export declare function openSqlite(cfg: ResolvedConfig): Promise<OpenResult>;
12
+ export declare function openSqlite(cfg: ResolvedConfig, options?: InternalOpenOptions): Promise<OpenResult>;