sensemaking 0.27.0 → 0.28.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (364) hide show
  1. package/bin/cli.js +16 -7
  2. package/dist/cjs/chunk/extract.js.map +1 -1
  3. package/dist/cjs/chunk/group.js.map +1 -1
  4. package/dist/cjs/chunk/index.js.map +1 -1
  5. package/dist/cjs/chunk/parse.js.map +1 -1
  6. package/dist/cjs/chunk/parser.js.map +1 -1
  7. package/dist/cjs/chunk/tokens.js.map +1 -1
  8. package/dist/cjs/chunk/version.js.map +1 -1
  9. package/dist/cjs/cli/build.js.map +1 -1
  10. package/dist/cjs/cli/constants.d.cts +2 -0
  11. package/dist/cjs/cli/constants.d.ts +2 -0
  12. package/dist/cjs/cli/constants.js +21 -0
  13. package/dist/cjs/cli/constants.js.map +1 -0
  14. package/dist/cjs/cli/download.js.map +1 -1
  15. package/dist/cjs/cli/index.js.map +1 -1
  16. package/dist/cjs/cli/init.js.map +1 -1
  17. package/dist/cjs/cli/map.js.map +1 -1
  18. package/dist/cjs/cli/named.js +2 -1
  19. package/dist/cjs/cli/named.js.map +1 -1
  20. package/dist/cjs/cli/path.js.map +1 -1
  21. package/dist/cjs/cli/peek.js.map +1 -1
  22. package/dist/cjs/cli/related.js.map +1 -1
  23. package/dist/cjs/cli/search.js.map +1 -1
  24. package/dist/cjs/cli/shared.js +5 -4
  25. package/dist/cjs/cli/shared.js.map +1 -1
  26. package/dist/cjs/cli/sql.js.map +1 -1
  27. package/dist/cjs/cli/status.js.map +1 -1
  28. package/dist/cjs/cli/watch.js.map +1 -1
  29. package/dist/cjs/cli.js +10 -9
  30. package/dist/cjs/cli.js.map +1 -1
  31. package/dist/cjs/commands/index.js.map +1 -1
  32. package/dist/cjs/commands/map.js.map +1 -1
  33. package/dist/cjs/commands/path.js.map +1 -1
  34. package/dist/cjs/commands/peek.js.map +1 -1
  35. package/dist/cjs/commands/related.js.map +1 -1
  36. package/dist/cjs/commands/scope.js.map +1 -1
  37. package/dist/cjs/commands/search.js.map +1 -1
  38. package/dist/cjs/commands/signals.js.map +1 -1
  39. package/dist/cjs/commands/snapshot.js.map +1 -1
  40. package/dist/cjs/commands/status.js.map +1 -1
  41. package/dist/cjs/config/access.js.map +1 -1
  42. package/dist/cjs/config/index.js.map +1 -1
  43. package/dist/cjs/config/load.js.map +1 -1
  44. package/dist/cjs/config/resolve.js.map +1 -1
  45. package/dist/cjs/config/signals.js.map +1 -1
  46. package/dist/cjs/config/types.js.map +1 -1
  47. package/dist/cjs/config/validate.js.map +1 -1
  48. package/dist/cjs/embed/cohere.js.map +1 -1
  49. package/dist/cjs/embed/distribution.js.map +1 -1
  50. package/dist/cjs/embed/endpoint.js.map +1 -1
  51. package/dist/cjs/embed/handoff.js.map +1 -1
  52. package/dist/cjs/embed/http.js.map +1 -1
  53. package/dist/cjs/embed/identity.js.map +1 -1
  54. package/dist/cjs/embed/langfit.js.map +1 -1
  55. package/dist/cjs/embed/languages.js.map +1 -1
  56. package/dist/cjs/embed/openai.js.map +1 -1
  57. package/dist/cjs/embed/query.js.map +1 -1
  58. package/dist/cjs/embed/registry.js.map +1 -1
  59. package/dist/cjs/embed/static.js.map +1 -1
  60. package/dist/cjs/embed/store.js.map +1 -1
  61. package/dist/cjs/embed/types.js.map +1 -1
  62. package/dist/cjs/errors.js.map +1 -1
  63. package/dist/cjs/features/embed.js.map +1 -1
  64. package/dist/cjs/features/fences.js.map +1 -1
  65. package/dist/cjs/features/index.js.map +1 -1
  66. package/dist/cjs/features/links.js.map +1 -1
  67. package/dist/cjs/features/rank.js.map +1 -1
  68. package/dist/cjs/features/sections.js.map +1 -1
  69. package/dist/cjs/features/tags.js.map +1 -1
  70. package/dist/cjs/graph/graph.js.map +1 -1
  71. package/dist/cjs/graph/traverse.js.map +1 -1
  72. package/dist/cjs/index.js.map +1 -1
  73. package/dist/cjs/lib/atomic-write.js.map +1 -1
  74. package/dist/cjs/lib/guarded-tick.js.map +1 -1
  75. package/dist/cjs/lib/serial-query.js.map +1 -1
  76. package/dist/cjs/lib/watch-notification.js.map +1 -1
  77. package/dist/cjs/lib/worker-file.js.map +1 -1
  78. package/dist/cjs/output/column-hint.js.map +1 -1
  79. package/dist/cjs/output/output.js.map +1 -1
  80. package/dist/cjs/output/progress.js.map +1 -1
  81. package/dist/cjs/output/search-error.js.map +1 -1
  82. package/dist/cjs/scan/frontmatter.js.map +1 -1
  83. package/dist/cjs/scan/index.js.map +1 -1
  84. package/dist/cjs/scan/list.js.map +1 -1
  85. package/dist/cjs/scan/pool.js.map +1 -1
  86. package/dist/cjs/scan/reparse.js.map +1 -1
  87. package/dist/cjs/scan/worker-error.js.map +1 -1
  88. package/dist/cjs/store/batch.js.map +1 -1
  89. package/dist/cjs/store/builder.js.map +1 -1
  90. package/dist/cjs/store/cache.js.map +1 -1
  91. package/dist/cjs/store/duckdb/batch.js.map +1 -1
  92. package/dist/cjs/store/duckdb/connection.js.map +1 -1
  93. package/dist/cjs/store/duckdb/engine.d.cts +11 -0
  94. package/dist/cjs/store/duckdb/engine.d.ts +11 -0
  95. package/dist/cjs/store/duckdb/engine.js +193 -0
  96. package/dist/cjs/store/duckdb/engine.js.map +1 -0
  97. package/dist/cjs/store/duckdb/fieldStats.js.map +1 -1
  98. package/dist/cjs/store/duckdb/lexical.d.cts +1 -6
  99. package/dist/cjs/store/duckdb/lexical.d.ts +1 -6
  100. package/dist/cjs/store/duckdb/lexical.js +48 -45
  101. package/dist/cjs/store/duckdb/lexical.js.map +1 -1
  102. package/dist/cjs/store/duckdb/native.d.cts +5 -3
  103. package/dist/cjs/store/duckdb/native.d.ts +5 -3
  104. package/dist/cjs/store/duckdb/native.js +157 -18
  105. package/dist/cjs/store/duckdb/native.js.map +1 -1
  106. package/dist/cjs/store/duckdb/open.js +151 -3
  107. package/dist/cjs/store/duckdb/open.js.map +1 -1
  108. package/dist/cjs/store/duckdb/ordered-bm25.d.cts +3 -16
  109. package/dist/cjs/store/duckdb/ordered-bm25.d.ts +3 -16
  110. package/dist/cjs/store/duckdb/ordered-bm25.js +24 -80
  111. package/dist/cjs/store/duckdb/ordered-bm25.js.map +1 -1
  112. package/dist/cjs/store/duckdb/reconcile.js.map +1 -1
  113. package/dist/cjs/store/duckdb/sql-functions.js.map +1 -1
  114. package/dist/cjs/store/duckdb/store.js.map +1 -1
  115. package/dist/cjs/store/duckdb/vectors.js.map +1 -1
  116. package/dist/cjs/store/embed-scope.js.map +1 -1
  117. package/dist/cjs/store/engine.d.cts +28 -0
  118. package/dist/cjs/store/engine.d.ts +28 -0
  119. package/dist/cjs/store/engine.js +362 -0
  120. package/dist/cjs/store/engine.js.map +1 -0
  121. package/dist/cjs/store/feature-scope.js.map +1 -1
  122. package/dist/cjs/store/index.js.map +1 -1
  123. package/dist/cjs/store/lock-wait.js.map +1 -1
  124. package/dist/cjs/store/native.d.cts +8 -5
  125. package/dist/cjs/store/native.d.ts +8 -5
  126. package/dist/cjs/store/native.js +78 -73
  127. package/dist/cjs/store/native.js.map +1 -1
  128. package/dist/cjs/store/open.js +100 -40
  129. package/dist/cjs/store/open.js.map +1 -1
  130. package/dist/cjs/store/preset-scope.js.map +1 -1
  131. package/dist/cjs/store/readiness.js.map +1 -1
  132. package/dist/cjs/store/reconcile.js.map +1 -1
  133. package/dist/cjs/store/shared.js.map +1 -1
  134. package/dist/cjs/store/signature.js.map +1 -1
  135. package/dist/cjs/store/sql-functions.js.map +1 -1
  136. package/dist/cjs/store/sqlite/connection.js.map +1 -1
  137. package/dist/cjs/store/sqlite/engine.d.cts +12 -0
  138. package/dist/cjs/store/sqlite/engine.d.ts +12 -0
  139. package/dist/cjs/store/sqlite/engine.js +53 -0
  140. package/dist/cjs/store/sqlite/engine.js.map +1 -0
  141. package/dist/cjs/store/sqlite/fieldStats.js.map +1 -1
  142. package/dist/cjs/store/sqlite/lexical.js +3 -4
  143. package/dist/cjs/store/sqlite/lexical.js.map +1 -1
  144. package/dist/cjs/store/sqlite/open.js +119 -6
  145. package/dist/cjs/store/sqlite/open.js.map +1 -1
  146. package/dist/cjs/store/sqlite/reconcile.js.map +1 -1
  147. package/dist/cjs/store/sqlite/sql-functions.js.map +1 -1
  148. package/dist/cjs/store/sqlite/store.js.map +1 -1
  149. package/dist/cjs/store/sqlite/vectors.js.map +1 -1
  150. package/dist/cjs/store/stages.js.map +1 -1
  151. package/dist/cjs/store/transaction.js.map +1 -1
  152. package/dist/cjs/store/turso/connection.js.map +1 -1
  153. package/dist/cjs/store/turso/engine.d.cts +9 -0
  154. package/dist/cjs/store/turso/engine.d.ts +9 -0
  155. package/dist/cjs/store/turso/engine.js +189 -0
  156. package/dist/cjs/store/turso/engine.js.map +1 -0
  157. package/dist/cjs/store/turso/fieldStats.js.map +1 -1
  158. package/dist/cjs/store/turso/lexical-text.js.map +1 -1
  159. package/dist/cjs/store/turso/lexical.js +16 -11
  160. package/dist/cjs/store/turso/lexical.js.map +1 -1
  161. package/dist/cjs/store/turso/native.d.cts +5 -1
  162. package/dist/cjs/store/turso/native.d.ts +5 -1
  163. package/dist/cjs/store/turso/native.js +157 -8
  164. package/dist/cjs/store/turso/native.js.map +1 -1
  165. package/dist/cjs/store/turso/open.js +172 -27
  166. package/dist/cjs/store/turso/open.js.map +1 -1
  167. package/dist/cjs/store/turso/reconcile.d.cts +0 -1
  168. package/dist/cjs/store/turso/reconcile.d.ts +0 -1
  169. package/dist/cjs/store/turso/reconcile.js +22 -23
  170. package/dist/cjs/store/turso/reconcile.js.map +1 -1
  171. package/dist/cjs/store/turso/sql-functions.js.map +1 -1
  172. package/dist/cjs/store/turso/store.js.map +1 -1
  173. package/dist/cjs/store/turso/vectors.js.map +1 -1
  174. package/dist/cjs/store/types.d.cts +2 -0
  175. package/dist/cjs/store/types.d.ts +2 -0
  176. package/dist/cjs/store/types.js.map +1 -1
  177. package/dist/cjs/store/vectors.js.map +1 -1
  178. package/dist/cjs/text/segment.js.map +1 -1
  179. package/dist/cjs/text/strip.js.map +1 -1
  180. package/dist/cjs/watch-claim.js.map +1 -1
  181. package/dist/cjs/watch.js.map +1 -1
  182. package/dist/cjs/workers/parse.js.map +1 -1
  183. package/dist/cjs/workers/watch-heartbeat.js.map +1 -1
  184. package/dist/esm/chunk/extract.js.map +1 -1
  185. package/dist/esm/chunk/group.js.map +1 -1
  186. package/dist/esm/chunk/index.js.map +1 -1
  187. package/dist/esm/chunk/parse.js.map +1 -1
  188. package/dist/esm/chunk/parser.js.map +1 -1
  189. package/dist/esm/chunk/tokens.js.map +1 -1
  190. package/dist/esm/chunk/types.js.map +1 -1
  191. package/dist/esm/chunk/version.js.map +1 -1
  192. package/dist/esm/cli/build.js.map +1 -1
  193. package/dist/esm/cli/constants.d.ts +2 -0
  194. package/dist/esm/cli/constants.js +2 -0
  195. package/dist/esm/cli/constants.js.map +1 -0
  196. package/dist/esm/cli/download.js.map +1 -1
  197. package/dist/esm/cli/index.js.map +1 -1
  198. package/dist/esm/cli/init.js.map +1 -1
  199. package/dist/esm/cli/map.js.map +1 -1
  200. package/dist/esm/cli/named.js +2 -1
  201. package/dist/esm/cli/named.js.map +1 -1
  202. package/dist/esm/cli/path.js.map +1 -1
  203. package/dist/esm/cli/peek.js.map +1 -1
  204. package/dist/esm/cli/related.js.map +1 -1
  205. package/dist/esm/cli/search.js.map +1 -1
  206. package/dist/esm/cli/shared.js +6 -5
  207. package/dist/esm/cli/shared.js.map +1 -1
  208. package/dist/esm/cli/sql.js.map +1 -1
  209. package/dist/esm/cli/status.js.map +1 -1
  210. package/dist/esm/cli/types.js.map +1 -1
  211. package/dist/esm/cli/watch.js.map +1 -1
  212. package/dist/esm/cli.js +10 -9
  213. package/dist/esm/cli.js.map +1 -1
  214. package/dist/esm/commands/index.js.map +1 -1
  215. package/dist/esm/commands/map.js.map +1 -1
  216. package/dist/esm/commands/path.js.map +1 -1
  217. package/dist/esm/commands/peek.js.map +1 -1
  218. package/dist/esm/commands/related.js.map +1 -1
  219. package/dist/esm/commands/scope.js.map +1 -1
  220. package/dist/esm/commands/search.js.map +1 -1
  221. package/dist/esm/commands/signals.js.map +1 -1
  222. package/dist/esm/commands/snapshot.js.map +1 -1
  223. package/dist/esm/commands/status.js.map +1 -1
  224. package/dist/esm/config/access.js.map +1 -1
  225. package/dist/esm/config/index.js.map +1 -1
  226. package/dist/esm/config/load.js.map +1 -1
  227. package/dist/esm/config/resolve.js.map +1 -1
  228. package/dist/esm/config/signals.js.map +1 -1
  229. package/dist/esm/config/types.js.map +1 -1
  230. package/dist/esm/config/validate.js.map +1 -1
  231. package/dist/esm/embed/cohere.js.map +1 -1
  232. package/dist/esm/embed/distribution.js.map +1 -1
  233. package/dist/esm/embed/endpoint.js.map +1 -1
  234. package/dist/esm/embed/handoff.js.map +1 -1
  235. package/dist/esm/embed/http.js.map +1 -1
  236. package/dist/esm/embed/identity.js.map +1 -1
  237. package/dist/esm/embed/langfit.js.map +1 -1
  238. package/dist/esm/embed/languages.js.map +1 -1
  239. package/dist/esm/embed/openai.js.map +1 -1
  240. package/dist/esm/embed/query.js +1 -1
  241. package/dist/esm/embed/query.js.map +1 -1
  242. package/dist/esm/embed/registry.js.map +1 -1
  243. package/dist/esm/embed/static.js.map +1 -1
  244. package/dist/esm/embed/store.js.map +1 -1
  245. package/dist/esm/embed/types.js.map +1 -1
  246. package/dist/esm/errors.js.map +1 -1
  247. package/dist/esm/features/embed.js.map +1 -1
  248. package/dist/esm/features/fences.js.map +1 -1
  249. package/dist/esm/features/index.js.map +1 -1
  250. package/dist/esm/features/links.js.map +1 -1
  251. package/dist/esm/features/rank.js.map +1 -1
  252. package/dist/esm/features/sections.js.map +1 -1
  253. package/dist/esm/features/tags.js.map +1 -1
  254. package/dist/esm/features/types.js.map +1 -1
  255. package/dist/esm/graph/graph.js.map +1 -1
  256. package/dist/esm/graph/traverse.js.map +1 -1
  257. package/dist/esm/index.js.map +1 -1
  258. package/dist/esm/lib/atomic-write.js.map +1 -1
  259. package/dist/esm/lib/guarded-tick.js.map +1 -1
  260. package/dist/esm/lib/serial-query.js.map +1 -1
  261. package/dist/esm/lib/watch-notification.js.map +1 -1
  262. package/dist/esm/lib/worker-file.js.map +1 -1
  263. package/dist/esm/output/column-hint.js.map +1 -1
  264. package/dist/esm/output/output.js.map +1 -1
  265. package/dist/esm/output/progress.js.map +1 -1
  266. package/dist/esm/output/search-error.js.map +1 -1
  267. package/dist/esm/scan/frontmatter.js.map +1 -1
  268. package/dist/esm/scan/index.js.map +1 -1
  269. package/dist/esm/scan/list.js.map +1 -1
  270. package/dist/esm/scan/pool.js.map +1 -1
  271. package/dist/esm/scan/reparse.js.map +1 -1
  272. package/dist/esm/scan/worker-error.js.map +1 -1
  273. package/dist/esm/store/batch.js.map +1 -1
  274. package/dist/esm/store/builder.js.map +1 -1
  275. package/dist/esm/store/cache.js.map +1 -1
  276. package/dist/esm/store/duckdb/batch.js.map +1 -1
  277. package/dist/esm/store/duckdb/connection.js.map +1 -1
  278. package/dist/esm/store/duckdb/engine.d.ts +11 -0
  279. package/dist/esm/store/duckdb/engine.js +18 -0
  280. package/dist/esm/store/duckdb/engine.js.map +1 -0
  281. package/dist/esm/store/duckdb/fieldStats.js.map +1 -1
  282. package/dist/esm/store/duckdb/lexical.d.ts +1 -6
  283. package/dist/esm/store/duckdb/lexical.js +16 -20
  284. package/dist/esm/store/duckdb/lexical.js.map +1 -1
  285. package/dist/esm/store/duckdb/native.d.ts +5 -3
  286. package/dist/esm/store/duckdb/native.js +16 -14
  287. package/dist/esm/store/duckdb/native.js.map +1 -1
  288. package/dist/esm/store/duckdb/open.js +40 -2
  289. package/dist/esm/store/duckdb/open.js.map +1 -1
  290. package/dist/esm/store/duckdb/ordered-bm25.d.ts +3 -16
  291. package/dist/esm/store/duckdb/ordered-bm25.js +14 -55
  292. package/dist/esm/store/duckdb/ordered-bm25.js.map +1 -1
  293. package/dist/esm/store/duckdb/reconcile.js.map +1 -1
  294. package/dist/esm/store/duckdb/sql-functions.js.map +1 -1
  295. package/dist/esm/store/duckdb/store.js.map +1 -1
  296. package/dist/esm/store/duckdb/vectors.js.map +1 -1
  297. package/dist/esm/store/embed-scope.js.map +1 -1
  298. package/dist/esm/store/engine.d.ts +28 -0
  299. package/dist/esm/store/engine.js +85 -0
  300. package/dist/esm/store/engine.js.map +1 -0
  301. package/dist/esm/store/feature-scope.js.map +1 -1
  302. package/dist/esm/store/index.js.map +1 -1
  303. package/dist/esm/store/lock-wait.js.map +1 -1
  304. package/dist/esm/store/native.d.ts +8 -5
  305. package/dist/esm/store/native.js +59 -57
  306. package/dist/esm/store/native.js.map +1 -1
  307. package/dist/esm/store/open.js +24 -7
  308. package/dist/esm/store/open.js.map +1 -1
  309. package/dist/esm/store/preset-scope.js.map +1 -1
  310. package/dist/esm/store/readiness.js.map +1 -1
  311. package/dist/esm/store/reconcile.js.map +1 -1
  312. package/dist/esm/store/shared.js.map +1 -1
  313. package/dist/esm/store/signature.js.map +1 -1
  314. package/dist/esm/store/sql-functions.js.map +1 -1
  315. package/dist/esm/store/sqlite/connection.js.map +1 -1
  316. package/dist/esm/store/sqlite/engine.d.ts +12 -0
  317. package/dist/esm/store/sqlite/engine.js +16 -0
  318. package/dist/esm/store/sqlite/engine.js.map +1 -0
  319. package/dist/esm/store/sqlite/fieldStats.js.map +1 -1
  320. package/dist/esm/store/sqlite/lexical.js +2 -3
  321. package/dist/esm/store/sqlite/lexical.js.map +1 -1
  322. package/dist/esm/store/sqlite/open.js +38 -7
  323. package/dist/esm/store/sqlite/open.js.map +1 -1
  324. package/dist/esm/store/sqlite/reconcile.js.map +1 -1
  325. package/dist/esm/store/sqlite/sql-functions.js.map +1 -1
  326. package/dist/esm/store/sqlite/store.js.map +1 -1
  327. package/dist/esm/store/sqlite/vectors.js.map +1 -1
  328. package/dist/esm/store/stages.js.map +1 -1
  329. package/dist/esm/store/transaction.js.map +1 -1
  330. package/dist/esm/store/turso/connection.js.map +1 -1
  331. package/dist/esm/store/turso/engine.d.ts +9 -0
  332. package/dist/esm/store/turso/engine.js +14 -0
  333. package/dist/esm/store/turso/engine.js.map +1 -0
  334. package/dist/esm/store/turso/fieldStats.js.map +1 -1
  335. package/dist/esm/store/turso/lexical-text.js.map +1 -1
  336. package/dist/esm/store/turso/lexical.js +9 -9
  337. package/dist/esm/store/turso/lexical.js.map +1 -1
  338. package/dist/esm/store/turso/native.d.ts +5 -1
  339. package/dist/esm/store/turso/native.js +16 -10
  340. package/dist/esm/store/turso/native.js.map +1 -1
  341. package/dist/esm/store/turso/open.js +44 -3
  342. package/dist/esm/store/turso/open.js.map +1 -1
  343. package/dist/esm/store/turso/reconcile.d.ts +0 -1
  344. package/dist/esm/store/turso/reconcile.js +3 -8
  345. package/dist/esm/store/turso/reconcile.js.map +1 -1
  346. package/dist/esm/store/turso/sql-functions.js.map +1 -1
  347. package/dist/esm/store/turso/store.js.map +1 -1
  348. package/dist/esm/store/turso/vectors.js.map +1 -1
  349. package/dist/esm/store/types.d.ts +2 -0
  350. package/dist/esm/store/types.js.map +1 -1
  351. package/dist/esm/store/vectors.js.map +1 -1
  352. package/dist/esm/text/segment.js.map +1 -1
  353. package/dist/esm/text/strip.js.map +1 -1
  354. package/dist/esm/watch-claim.js.map +1 -1
  355. package/dist/esm/watch.js.map +1 -1
  356. package/dist/esm/workers/parse.js.map +1 -1
  357. package/dist/esm/workers/watch-heartbeat.js.map +1 -1
  358. package/package.json +21 -6
  359. package/skills/sense/SKILL.md +1 -1
  360. package/skills/sense/references/stores/duckdb.md +1 -1
  361. package/skills/sense/references/stores/sqlite.md +1 -1
  362. package/skills/sense/references/stores/turso.md +1 -1
  363. package/skills/sense-setup/references/stores/duckdb.md +1 -1
  364. package/skills/sense-setup/references/stores/sqlite.md +1 -1
@@ -25,10 +25,14 @@ _export(exports, {
25
25
  var _typests = require("../../embed/types.js");
26
26
  var _errorsts = require("../../errors.js");
27
27
  var _indexts = require("../../features/index.js");
28
+ var _enginets = require("../engine.js");
29
+ var _nativets = require("../native.js");
28
30
  var _opents = require("../open.js");
29
31
  var _sharedts = require("../shared.js");
30
32
  var _connectionts = require("./connection.js");
31
- var _nativets = require("./native.js");
33
+ var _enginets1 = require("./engine.js");
34
+ var _lexicalts = require("./lexical.js");
35
+ var _nativets1 = require("./native.js");
32
36
  var _reconcilets = require("./reconcile.js");
33
37
  var _storets = require("./store.js");
34
38
  function _array_like_to_array(arr, len) {
@@ -271,45 +275,50 @@ function ensureCoreSchema(_handle, conn) {
271
275
  case 4:
272
276
  _state.trys.push([
273
277
  4,
274
- 9,
275
278
  10,
276
- 11
279
+ 11,
280
+ 12
277
281
  ]);
278
- _iterator = _reconcilets.CONTENT_FTS_DDL[Symbol.iterator]();
279
- _state.label = 5;
282
+ return [
283
+ 4,
284
+ (0, _enginets1.tursoFts)()
285
+ ];
280
286
  case 5:
287
+ _iterator = _state.sent().indexDdl()[Symbol.iterator]();
288
+ _state.label = 6;
289
+ case 6:
281
290
  if (!!(_iteratorNormalCompletion = (_step = _iterator.next()).done)) return [
282
291
  3,
283
- 8
292
+ 9
284
293
  ];
285
294
  ddl = _step.value;
286
295
  return [
287
296
  4,
288
297
  conn.exec(ddl)
289
298
  ];
290
- case 6:
291
- _state.sent();
292
- _state.label = 7;
293
299
  case 7:
300
+ _state.sent();
301
+ _state.label = 8;
302
+ case 8:
294
303
  _iteratorNormalCompletion = true;
295
304
  return [
296
305
  3,
297
- 5
306
+ 6
298
307
  ];
299
- case 8:
308
+ case 9:
300
309
  return [
301
310
  3,
302
- 11
311
+ 12
303
312
  ];
304
- case 9:
313
+ case 10:
305
314
  err = _state.sent();
306
315
  _didIteratorError = true;
307
316
  _iteratorError = err;
308
317
  return [
309
318
  3,
310
- 11
319
+ 12
311
320
  ];
312
- case 10:
321
+ case 11:
313
322
  try {
314
323
  if (!_iteratorNormalCompletion && _iterator.return != null) {
315
324
  _iterator.return();
@@ -322,36 +331,36 @@ function ensureCoreSchema(_handle, conn) {
322
331
  return [
323
332
  7
324
333
  ];
325
- case 11:
334
+ case 12:
326
335
  return [
327
336
  4,
328
337
  conn.exec('CREATE TABLE IF NOT EXISTS preset_files ("path" TEXT, preset TEXT, PRIMARY KEY ("path", preset))')
329
338
  ];
330
- case 12:
339
+ case 13:
331
340
  _state.sent();
332
341
  return [
333
342
  4,
334
343
  conn.exec('CREATE INDEX IF NOT EXISTS preset_files_preset ON preset_files(preset)')
335
344
  ];
336
- case 13:
345
+ case 14:
337
346
  _state.sent();
338
347
  return [
339
348
  4,
340
349
  (0, _sharedts.getMeta)(conn, 'schema_version')
341
350
  ];
342
- case 14:
351
+ case 15:
343
352
  if (!(_state.sent() === null)) return [
344
353
  3,
345
- 16
354
+ 17
346
355
  ];
347
356
  return [
348
357
  4,
349
358
  (0, _sharedts.setMeta)(conn, 'schema_version', SCHEMA_VERSION)
350
359
  ];
351
- case 15:
352
- _state.sent();
353
- _state.label = 16;
354
360
  case 16:
361
+ _state.sent();
362
+ _state.label = 17;
363
+ case 17:
355
364
  return [
356
365
  2
357
366
  ];
@@ -509,7 +518,7 @@ function connect(dbPath, _cfg, options) {
509
518
  ]);
510
519
  return [
511
520
  4,
512
- (0, _nativets.tursoApi)()
521
+ (0, _nativets1.tursoApi)()
513
522
  ];
514
523
  case 1:
515
524
  turso = _state.sent();
@@ -520,7 +529,7 @@ function connect(dbPath, _cfg, options) {
520
529
  case 2:
521
530
  err = _state.sent();
522
531
  if (_instanceof(err, _errorsts.SenseError)) throw err;
523
- throw new _errorsts.SenseError('STORE_DEPENDENCY_MISSING', 'store "turso" needs the '.concat(_nativets.TURSO_PACKAGE, " package (").concat(err.message, ")"));
532
+ throw new _errorsts.SenseError('STORE_DEPENDENCY_MISSING', 'store "turso" needs the '.concat(_nativets1.TURSO_PACKAGE, " package (").concat(err.message, ")"));
524
533
  case 3:
525
534
  _state.trys.push([
526
535
  3,
@@ -530,8 +539,8 @@ function connect(dbPath, _cfg, options) {
530
539
  ]);
531
540
  return [
532
541
  4,
533
- turso.connect(dbPath, _object_spread(_object_spread_props(_object_spread({}, _nativets.CONNECT_OPTS), {
534
- experimental: _to_consumable_array(_nativets.CONNECT_OPTS.experimental)
542
+ turso.connect(dbPath, _object_spread(_object_spread_props(_object_spread({}, _nativets1.CONNECT_OPTS), {
543
+ experimental: _to_consumable_array(_nativets1.CONNECT_OPTS.experimental)
535
544
  }), options.existingOnly ? {
536
545
  fileMustExist: true
537
546
  } : {}))
@@ -559,6 +568,140 @@ function connect(dbPath, _cfg, options) {
559
568
  });
560
569
  })();
561
570
  }
571
+ function tursoEngineIdentity() {
572
+ return _async_to_generator(function() {
573
+ var _tmp;
574
+ return _ts_generator(this, function(_state) {
575
+ switch(_state.label){
576
+ case 0:
577
+ _tmp = [
578
+ _nativets1.TURSO_PACKAGE
579
+ ];
580
+ return [
581
+ 4,
582
+ (0, _nativets1.tursoNative)()
583
+ ];
584
+ case 1:
585
+ return [
586
+ 2,
587
+ _enginets.engineIdentity.apply(void 0, _tmp.concat([
588
+ _state.sent().version
589
+ ]))
590
+ ];
591
+ }
592
+ });
593
+ })();
594
+ }
595
+ // The real schema, content write and lexical query over store/engine.ts's fixture, in memory.
596
+ function checkTursoEngine() {
597
+ return _async_to_generator(function() {
598
+ var _ref, api, version, db, conn, docs;
599
+ return _ts_generator(this, function(_state) {
600
+ switch(_state.label){
601
+ case 0:
602
+ return [
603
+ 4,
604
+ (0, _nativets1.tursoNative)()
605
+ ];
606
+ case 1:
607
+ _ref = _state.sent(), api = _ref.api, version = _ref.version;
608
+ return [
609
+ 4,
610
+ api.connect(':memory:', _object_spread_props(_object_spread({}, _nativets1.CONNECT_OPTS), {
611
+ experimental: _to_consumable_array(_nativets1.CONNECT_OPTS.experimental)
612
+ }))
613
+ ];
614
+ case 2:
615
+ db = _state.sent();
616
+ _state.label = 3;
617
+ case 3:
618
+ _state.trys.push([
619
+ 3,
620
+ ,
621
+ 8,
622
+ 10
623
+ ]);
624
+ conn = (0, _connectionts.createConnection)(db);
625
+ return [
626
+ 4,
627
+ conn.exec('CREATE TABLE meta (key TEXT PRIMARY KEY, value TEXT)')
628
+ ];
629
+ case 4:
630
+ _state.sent();
631
+ return [
632
+ 4,
633
+ ensureCoreSchema(db, conn)
634
+ ];
635
+ case 5:
636
+ _state.sent();
637
+ docs = _enginets.ENGINE_CHECK_DOCS.map(function(doc) {
638
+ return {
639
+ relPath: doc.path,
640
+ search: {
641
+ title: doc.title,
642
+ summary: doc.summary,
643
+ text: doc.text
644
+ }
645
+ };
646
+ });
647
+ return [
648
+ 4,
649
+ (0, _reconcilets.reconcileTursoContentWithStrategy)(conn, [], docs, 'incremental')
650
+ ];
651
+ case 6:
652
+ _state.sent();
653
+ return [
654
+ 4,
655
+ (0, _enginets.checkEngine)('turso', (0, _enginets.engineIdentity)(_nativets1.TURSO_PACKAGE, version), (0, _enginets.npmRemedy)(_nativets1.TURSO_PACKAGE, (0, _nativets.peerRange)(_nativets1.TURSO_PACKAGE)), function(terms) {
656
+ return _async_to_generator(function() {
657
+ return _ts_generator(this, function(_state) {
658
+ switch(_state.label){
659
+ case 0:
660
+ return [
661
+ 4,
662
+ (0, _lexicalts.queryLexical)(conn, terms, {
663
+ whereJoin: '',
664
+ whereCond: '',
665
+ scopeCond: '',
666
+ limit: 10
667
+ })
668
+ ];
669
+ case 1:
670
+ return [
671
+ 2,
672
+ _state.sent().map(function(hit) {
673
+ return hit.path;
674
+ })
675
+ ];
676
+ }
677
+ });
678
+ })();
679
+ })
680
+ ];
681
+ case 7:
682
+ _state.sent();
683
+ return [
684
+ 3,
685
+ 10
686
+ ];
687
+ case 8:
688
+ return [
689
+ 4,
690
+ db.close()
691
+ ];
692
+ case 9:
693
+ _state.sent();
694
+ return [
695
+ 7
696
+ ];
697
+ case 10:
698
+ return [
699
+ 2
700
+ ];
701
+ }
702
+ });
703
+ })();
704
+ }
562
705
  var tursoOpenDialect = {
563
706
  filename: DB_FILENAME,
564
707
  schemaVersion: SCHEMA_VERSION,
@@ -571,6 +714,8 @@ var tursoOpenDialect = {
571
714
  isLocked: function isLocked(err) {
572
715
  return /File is locked by another process|locked a portion of the file/.test(err.message);
573
716
  },
717
+ engineIdentity: tursoEngineIdentity,
718
+ checkEngine: checkTursoEngine,
574
719
  ensureCoreSchema: ensureCoreSchema,
575
720
  ensureFeatureSchema: ensureFeatureSchema,
576
721
  setDerivedBusyTimeout: setDerivedBusyTimeout,
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/store/turso/open.ts"],"sourcesContent":["import type { Database } from '@tursodatabase/database';\nimport type { Config, ResolvedConfig } from '../../config/index.ts';\nimport { STORE_DIMS } from '../../embed/types.ts';\nimport { SenseError } from '../../errors.ts';\nimport { activeFeatures } from '../../features/index.ts';\nimport type { InternalOpenOptions, OpenResult } from '../open.ts';\nimport { openWithDialect } from '../open.ts';\nimport { getMeta, setMeta } from '../shared.ts';\nimport type { Connection, OpenDialect } from '../types.ts';\nimport { checkpointWal, createConnection } from './connection.ts';\nimport { CONNECT_OPTS, TURSO_PACKAGE, tursoApi } from './native.ts';\nimport { CONTENT_FTS_DDL, tursoDialect } from './reconcile.ts';\nimport { createStore } from './store.ts';\n\nexport const DB_FILENAME = 'cache.turso.db';\n// Independent of sqlite's and duckdb's SCHEMA_VERSION: each store's cache shape evolves\n// separately. Covers the FTS indexes, the \"_ngram\" sidecar columns, and embeddings.vector's width.\nexport const SCHEMA_VERSION = '10';\n\nexport type { OpenResult };\n\n// This store's Handle (types.ts's OpenDialect<Handle>) is the connected Database itself: no\n// extra native state to thread, unlike duckdb's separate instance/connection pair.\nasync function ensureCoreSchema(_handle: Database, conn: Connection): Promise<void> {\n await conn.exec(`CREATE TABLE IF NOT EXISTS frontmatter (\"path\" TEXT PRIMARY KEY, \"_mtime\" REAL, \"_ctime\" REAL, \"_size\" INTEGER, \"_parse_error\" TEXT)`);\n await conn.exec(`CREATE TABLE IF NOT EXISTS content (\"path\" TEXT PRIMARY KEY, title TEXT, summary TEXT, text TEXT, title_stem TEXT, summary_stem TEXT, text_stem TEXT, title_ngram TEXT, summary_ngram TEXT, text_ngram TEXT)`);\n await conn.exec(`CREATE TABLE IF NOT EXISTS indexed_sources (\"path\" TEXT PRIMARY KEY, text TEXT NOT NULL)`);\n for (const ddl of CONTENT_FTS_DDL) await conn.exec(ddl);\n await conn.exec(`CREATE TABLE IF NOT EXISTS preset_files (\"path\" TEXT, preset TEXT, PRIMARY KEY (\"path\", preset))`);\n await conn.exec('CREATE INDEX IF NOT EXISTS preset_files_preset ON preset_files(preset)');\n if ((await getMeta(conn, 'schema_version')) === null) await setMeta(conn, 'schema_version', SCHEMA_VERSION);\n}\n\nasync function ensureFeatureSchema(_handle: Database, conn: Connection, cfg: Config): Promise<void> {\n for (const feature of activeFeatures(cfg)) {\n // Native F32_BLOB(STORE_DIMS) instead of the embed feature's engine-neutral BLOB DDL. `scale`\n // is kept unused, so the shared reconcile-time INSERT/DELETE names a column both stores have.\n if (feature.name === 'embed') {\n await conn.exec(`CREATE TABLE IF NOT EXISTS embeddings (\"path\" TEXT, chunk INTEGER, start_line INTEGER, end_line INTEGER, content_identity TEXT NOT NULL, scale REAL, vector F32_BLOB(${STORE_DIMS}), PRIMARY KEY (\"path\", chunk))`);\n continue;\n }\n await feature.schema(conn);\n }\n}\n\nasync function close(handle: Database, options: { observational?: boolean } = {}): Promise<void> {\n if (!options.observational) await checkpointWal(handle);\n await handle.close();\n}\n\nasync function setDerivedBusyTimeout(_handle: Database, conn: Connection, ms: number): Promise<void> {\n await conn.exec(`PRAGMA busy_timeout = ${ms}`);\n}\n\nasync function connect(dbPath: string, _cfg: ResolvedConfig, options: { existingOnly: boolean; observational: boolean }): Promise<{ handle: Database; conn: Connection }> {\n // Dynamic, not a top-level import: a sqlite or duckdb tree must never attempt to resolve this\n // optional dependency until a turso tree is actually opened. Installed on first use if missing.\n let turso: Awaited<ReturnType<typeof tursoApi>>;\n try {\n turso = await tursoApi();\n } catch (err) {\n if (err instanceof SenseError) throw err;\n throw new SenseError('STORE_DEPENDENCY_MISSING', `store \"turso\" needs the ${TURSO_PACKAGE} package (${(err as Error).message})`);\n }\n\n let db: Database;\n try {\n // Turso's readonly mode rejects native FTS SELECTs and TEMP query tables. Existing-only opens\n // stay query-capable; shared no-build orchestration and observational close prevent upkeep writes.\n db = await turso.connect(dbPath, { ...CONNECT_OPTS, experimental: [...CONNECT_OPTS.experimental], ...(options.existingOnly ? { fileMustExist: true } : {}) });\n } catch (err) {\n throw new SenseError('STORE_DEPENDENCY_MISSING', `store \"turso\" failed to open ${dbPath}: ${(err as Error).message}`);\n }\n return { handle: db, conn: createConnection(db) };\n}\n\n// This store's dialect (types.ts's OpenDialect) for the shared orchestration in store/open.ts.\nexport const tursoOpenDialect: OpenDialect<Database> = {\n filename: DB_FILENAME,\n schemaVersion: SCHEMA_VERSION,\n reconcileDialect: tursoDialect,\n connect,\n close,\n // \"Locking error: Failed locking file ...\", worded per platform: posix \"File is locked by another\n // process\", Windows \"another process has locked a portion of the file (os error 33)\". Distinct from\n // the write-time \"database is locked\" its connect-time `timeout` covers; that one never reaches here.\n isLocked: (err) => /File is locked by another process|locked a portion of the file/.test(err.message),\n ensureCoreSchema,\n ensureFeatureSchema,\n setDerivedBusyTimeout,\n createStore: (handle, conn, _cfg, options) => createStore(handle, conn, options),\n};\n\nexport async function openTurso(cfg: ResolvedConfig, options?: InternalOpenOptions): Promise<OpenResult> {\n return openWithDialect(cfg, tursoOpenDialect, options);\n}\n"],"names":["DB_FILENAME","SCHEMA_VERSION","openTurso","tursoOpenDialect","ensureCoreSchema","_handle","conn","ddl","exec","CONTENT_FTS_DDL","getMeta","setMeta","ensureFeatureSchema","cfg","feature","activeFeatures","name","STORE_DIMS","schema","close","handle","options","observational","checkpointWal","setDerivedBusyTimeout","ms","connect","dbPath","_cfg","turso","err","db","tursoApi","SenseError","TURSO_PACKAGE","message","CONNECT_OPTS","experimental","existingOnly","fileMustExist","createConnection","filename","schemaVersion","reconcileDialect","tursoDialect","isLocked","test","createStore","openWithDialect"],"mappings":"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"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/open-source/ai/sensemaking/src/store/turso/open.ts"],"sourcesContent":["import type { Database } from '@tursodatabase/database';\nimport type { Config, ResolvedConfig } from '../../config/index.ts';\nimport { STORE_DIMS } from '../../embed/types.ts';\nimport { SenseError } from '../../errors.ts';\nimport { activeFeatures } from '../../features/index.ts';\nimport type { ParsedDoc } from '../../scan/index.ts';\nimport { ENGINE_CHECK_DOCS, engineIdentity, npmRemedy, checkEngine as runEngineCheck } from '../engine.ts';\nimport { peerRange } from '../native.ts';\nimport type { InternalOpenOptions, OpenResult } from '../open.ts';\nimport { openWithDialect } from '../open.ts';\nimport { getMeta, setMeta } from '../shared.ts';\nimport type { Connection, OpenDialect } from '../types.ts';\nimport { checkpointWal, createConnection } from './connection.ts';\nimport { tursoFts } from './engine.ts';\nimport { queryLexical } from './lexical.ts';\nimport { CONNECT_OPTS, TURSO_PACKAGE, tursoApi, tursoNative } from './native.ts';\nimport { reconcileTursoContentWithStrategy, tursoDialect } from './reconcile.ts';\nimport { createStore } from './store.ts';\n\nexport const DB_FILENAME = 'cache.turso.db';\n// Independent of sqlite's and duckdb's SCHEMA_VERSION: each store's cache shape evolves\n// separately. Covers the FTS indexes, the \"_ngram\" sidecar columns, and embeddings.vector's width.\nexport const SCHEMA_VERSION = '10';\n\nexport type { OpenResult };\n\n// This store's Handle (types.ts's OpenDialect<Handle>) is the connected Database itself: no\n// extra native state to thread, unlike duckdb's separate instance/connection pair.\nasync function ensureCoreSchema(_handle: Database, conn: Connection): Promise<void> {\n await conn.exec(`CREATE TABLE IF NOT EXISTS frontmatter (\"path\" TEXT PRIMARY KEY, \"_mtime\" REAL, \"_ctime\" REAL, \"_size\" INTEGER, \"_parse_error\" TEXT)`);\n await conn.exec(`CREATE TABLE IF NOT EXISTS content (\"path\" TEXT PRIMARY KEY, title TEXT, summary TEXT, text TEXT, title_stem TEXT, summary_stem TEXT, text_stem TEXT, title_ngram TEXT, summary_ngram TEXT, text_ngram TEXT)`);\n await conn.exec(`CREATE TABLE IF NOT EXISTS indexed_sources (\"path\" TEXT PRIMARY KEY, text TEXT NOT NULL)`);\n for (const ddl of (await tursoFts()).indexDdl()) await conn.exec(ddl);\n await conn.exec(`CREATE TABLE IF NOT EXISTS preset_files (\"path\" TEXT, preset TEXT, PRIMARY KEY (\"path\", preset))`);\n await conn.exec('CREATE INDEX IF NOT EXISTS preset_files_preset ON preset_files(preset)');\n if ((await getMeta(conn, 'schema_version')) === null) await setMeta(conn, 'schema_version', SCHEMA_VERSION);\n}\n\nasync function ensureFeatureSchema(_handle: Database, conn: Connection, cfg: Config): Promise<void> {\n for (const feature of activeFeatures(cfg)) {\n // Native F32_BLOB(STORE_DIMS) instead of the embed feature's engine-neutral BLOB DDL. `scale`\n // is kept unused, so the shared reconcile-time INSERT/DELETE names a column both stores have.\n if (feature.name === 'embed') {\n await conn.exec(`CREATE TABLE IF NOT EXISTS embeddings (\"path\" TEXT, chunk INTEGER, start_line INTEGER, end_line INTEGER, content_identity TEXT NOT NULL, scale REAL, vector F32_BLOB(${STORE_DIMS}), PRIMARY KEY (\"path\", chunk))`);\n continue;\n }\n await feature.schema(conn);\n }\n}\n\nasync function close(handle: Database, options: { observational?: boolean } = {}): Promise<void> {\n if (!options.observational) await checkpointWal(handle);\n await handle.close();\n}\n\nasync function setDerivedBusyTimeout(_handle: Database, conn: Connection, ms: number): Promise<void> {\n await conn.exec(`PRAGMA busy_timeout = ${ms}`);\n}\n\nasync function connect(dbPath: string, _cfg: ResolvedConfig, options: { existingOnly: boolean; observational: boolean }): Promise<{ handle: Database; conn: Connection }> {\n // Dynamic, not a top-level import: a sqlite or duckdb tree must never attempt to resolve this\n // optional dependency until a turso tree is actually opened. Installed on first use if missing.\n let turso: Awaited<ReturnType<typeof tursoApi>>;\n try {\n turso = await tursoApi();\n } catch (err) {\n if (err instanceof SenseError) throw err;\n throw new SenseError('STORE_DEPENDENCY_MISSING', `store \"turso\" needs the ${TURSO_PACKAGE} package (${(err as Error).message})`);\n }\n\n let db: Database;\n try {\n // Turso's readonly mode rejects native FTS SELECTs and TEMP query tables. Existing-only opens\n // stay query-capable; shared no-build orchestration and observational close prevent upkeep writes.\n db = await turso.connect(dbPath, { ...CONNECT_OPTS, experimental: [...CONNECT_OPTS.experimental], ...(options.existingOnly ? { fileMustExist: true } : {}) });\n } catch (err) {\n throw new SenseError('STORE_DEPENDENCY_MISSING', `store \"turso\" failed to open ${dbPath}: ${(err as Error).message}`);\n }\n return { handle: db, conn: createConnection(db) };\n}\n\nasync function tursoEngineIdentity(): Promise<string> {\n return engineIdentity(TURSO_PACKAGE, (await tursoNative()).version);\n}\n\n// The real schema, content write and lexical query over store/engine.ts's fixture, in memory.\nasync function checkTursoEngine(): Promise<void> {\n const { api, version } = await tursoNative();\n const db = await api.connect(':memory:', { ...CONNECT_OPTS, experimental: [...CONNECT_OPTS.experimental] });\n try {\n const conn = createConnection(db);\n await conn.exec('CREATE TABLE meta (key TEXT PRIMARY KEY, value TEXT)');\n await ensureCoreSchema(db, conn);\n const docs = ENGINE_CHECK_DOCS.map((doc) => ({ relPath: doc.path, search: { title: doc.title, summary: doc.summary, text: doc.text } }) as ParsedDoc);\n await reconcileTursoContentWithStrategy(conn, [], docs, 'incremental');\n await runEngineCheck('turso', engineIdentity(TURSO_PACKAGE, version), npmRemedy(TURSO_PACKAGE, peerRange(TURSO_PACKAGE)), async (terms) => (await queryLexical(conn, terms, { whereJoin: '', whereCond: '', scopeCond: '', limit: 10 })).map((hit) => hit.path));\n } finally {\n await db.close();\n }\n}\n\n// This store's dialect (types.ts's OpenDialect) for the shared orchestration in store/open.ts.\nexport const tursoOpenDialect: OpenDialect<Database> = {\n filename: DB_FILENAME,\n schemaVersion: SCHEMA_VERSION,\n reconcileDialect: tursoDialect,\n connect,\n close,\n // \"Locking error: Failed locking file ...\", worded per platform: posix \"File is locked by another\n // process\", Windows \"another process has locked a portion of the file (os error 33)\". Distinct from\n // the write-time \"database is locked\" its connect-time `timeout` covers; that one never reaches here.\n isLocked: (err) => /File is locked by another process|locked a portion of the file/.test(err.message),\n engineIdentity: tursoEngineIdentity,\n checkEngine: checkTursoEngine,\n ensureCoreSchema,\n ensureFeatureSchema,\n setDerivedBusyTimeout,\n createStore: (handle, conn, _cfg, options) => createStore(handle, conn, options),\n};\n\nexport async function openTurso(cfg: ResolvedConfig, options?: InternalOpenOptions): Promise<OpenResult> {\n return openWithDialect(cfg, tursoOpenDialect, options);\n}\n"],"names":["DB_FILENAME","SCHEMA_VERSION","openTurso","tursoOpenDialect","ensureCoreSchema","_handle","conn","ddl","exec","tursoFts","indexDdl","getMeta","setMeta","ensureFeatureSchema","cfg","feature","activeFeatures","name","STORE_DIMS","schema","close","handle","options","observational","checkpointWal","setDerivedBusyTimeout","ms","connect","dbPath","_cfg","turso","err","db","tursoApi","SenseError","TURSO_PACKAGE","message","CONNECT_OPTS","experimental","existingOnly","fileMustExist","createConnection","tursoEngineIdentity","tursoNative","engineIdentity","version","checkTursoEngine","api","docs","ENGINE_CHECK_DOCS","map","doc","relPath","path","search","title","summary","text","reconcileTursoContentWithStrategy","runEngineCheck","npmRemedy","peerRange","terms","queryLexical","whereJoin","whereCond","scopeCond","limit","hit","filename","schemaVersion","reconcileDialect","tursoDialect","isLocked","test","checkEngine","createStore","openWithDialect"],"mappings":"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"}
@@ -1,7 +1,6 @@
1
1
  import type { ReconcileDelta } from '../../features/types.js';
2
2
  import type { ParsedDoc } from '../../scan/index.js';
3
3
  import type { Connection, ReconcileDialect } from '../types.js';
4
- export declare const CONTENT_FTS_DDL: readonly ["CREATE INDEX IF NOT EXISTS content_fts ON content USING fts (title_stem, summary_stem, text_stem) WITH (weights = 'title_stem=10.0,summary_stem=5.0,text_stem=1.0')", "CREATE INDEX IF NOT EXISTS content_fts_ngram ON content USING fts (title_ngram, summary_ngram, text_ngram) WITH (tokenizer='ngram', weights='title_ngram=10.0,summary_ngram=5.0,text_ngram=1.0')"];
5
4
  export declare const CONTENT_FTS_NAMES: readonly ["content_fts", "content_fts_ngram"];
6
5
  export declare const FTS_REBUILD_THRESHOLD = 250;
7
6
  export type TursoFtsStrategy = 'incremental' | 'rebuild';
@@ -1,7 +1,6 @@
1
1
  import type { ReconcileDelta } from '../../features/types.js';
2
2
  import type { ParsedDoc } from '../../scan/index.js';
3
3
  import type { Connection, ReconcileDialect } from '../types.js';
4
- export declare const CONTENT_FTS_DDL: readonly ["CREATE INDEX IF NOT EXISTS content_fts ON content USING fts (title_stem, summary_stem, text_stem) WITH (weights = 'title_stem=10.0,summary_stem=5.0,text_stem=1.0')", "CREATE INDEX IF NOT EXISTS content_fts_ngram ON content USING fts (title_ngram, summary_ngram, text_ngram) WITH (tokenizer='ngram', weights='title_ngram=10.0,summary_ngram=5.0,text_ngram=1.0')"];
5
4
  export declare const CONTENT_FTS_NAMES: readonly ["content_fts", "content_fts_ngram"];
6
5
  export declare const FTS_REBUILD_THRESHOLD = 250;
7
6
  export type TursoFtsStrategy = 'incremental' | 'rebuild';
@@ -9,9 +9,6 @@ function _export(target, all) {
9
9
  });
10
10
  }
11
11
  _export(exports, {
12
- get CONTENT_FTS_DDL () {
13
- return CONTENT_FTS_DDL;
14
- },
15
12
  get CONTENT_FTS_NAMES () {
16
13
  return CONTENT_FTS_NAMES;
17
14
  },
@@ -32,6 +29,7 @@ var _errorsts = require("../../errors.js");
32
29
  var _segmentts = require("../../text/segment.js");
33
30
  var _sharedts = require("../shared.js");
34
31
  var _transactionts = require("../transaction.js");
32
+ var _enginets = require("./engine.js");
35
33
  var _lexicaltextts = require("./lexical-text.js");
36
34
  function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
37
35
  try {
@@ -158,10 +156,6 @@ function _ts_generator(thisArg, body) {
158
156
  };
159
157
  }
160
158
  }
161
- var CONTENT_FTS_DDL = [
162
- "CREATE INDEX IF NOT EXISTS content_fts ON content USING fts (title_stem, summary_stem, text_stem) WITH (weights = 'title_stem=10.0,summary_stem=5.0,text_stem=1.0')",
163
- "CREATE INDEX IF NOT EXISTS content_fts_ngram ON content USING fts (title_ngram, summary_ngram, text_ngram) WITH (tokenizer='ngram', weights='title_ngram=10.0,summary_ngram=5.0,text_ngram=1.0')"
164
- ];
165
159
  var CONTENT_FTS_NAMES = [
166
160
  'content_fts',
167
161
  'content_fts_ngram'
@@ -298,51 +292,56 @@ function reconcileTursoContentWithStrategy(conn, touched, docs, strategy) {
298
292
  _iteratorNormalCompletion1 = true, _didIteratorError1 = false, _iteratorError1 = undefined;
299
293
  if (!bulk) return [
300
294
  3,
301
- 20
295
+ 21
302
296
  ];
303
297
  _state.label = 13;
304
298
  case 13:
305
299
  _state.trys.push([
306
300
  13,
307
- 18,
308
301
  19,
309
- 20
302
+ 20,
303
+ 21
310
304
  ]);
311
- _iterator1 = CONTENT_FTS_DDL[Symbol.iterator]();
312
- _state.label = 14;
305
+ return [
306
+ 4,
307
+ (0, _enginets.tursoFts)()
308
+ ];
313
309
  case 14:
310
+ _iterator1 = _state.sent().indexDdl()[Symbol.iterator]();
311
+ _state.label = 15;
312
+ case 15:
314
313
  if (!!(_iteratorNormalCompletion1 = (_step1 = _iterator1.next()).done)) return [
315
314
  3,
316
- 17
315
+ 18
317
316
  ];
318
317
  ddl = _step1.value;
319
318
  return [
320
319
  4,
321
320
  conn.exec(ddl)
322
321
  ];
323
- case 15:
324
- _state.sent();
325
- _state.label = 16;
326
322
  case 16:
323
+ _state.sent();
324
+ _state.label = 17;
325
+ case 17:
327
326
  _iteratorNormalCompletion1 = true;
328
327
  return [
329
328
  3,
330
- 14
329
+ 15
331
330
  ];
332
- case 17:
331
+ case 18:
333
332
  return [
334
333
  3,
335
- 20
334
+ 21
336
335
  ];
337
- case 18:
336
+ case 19:
338
337
  err = _state.sent();
339
338
  _didIteratorError1 = true;
340
339
  _iteratorError1 = err;
341
340
  return [
342
341
  3,
343
- 20
342
+ 21
344
343
  ];
345
- case 19:
344
+ case 20:
346
345
  try {
347
346
  if (!_iteratorNormalCompletion1 && _iterator1.return != null) {
348
347
  _iterator1.return();
@@ -355,7 +354,7 @@ function reconcileTursoContentWithStrategy(conn, touched, docs, strategy) {
355
354
  return [
356
355
  7
357
356
  ];
358
- case 20:
357
+ case 21:
359
358
  return [
360
359
  2
361
360
  ];
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/store/turso/reconcile.ts"],"sourcesContent":["import type { Config } from '../../config/index.ts';\nimport { SenseError } from '../../errors.ts';\nimport type { ReconcileDelta } from '../../features/types.ts';\nimport type { ParsedDoc } from '../../scan/index.ts';\nimport { hasUnspacedRun } from '../../text/segment.ts';\nimport { quoteIdent, recordReconcileDuration } from '../shared.ts';\nimport { BEGIN_WRITE } from '../transaction.ts';\nimport type { Connection, ReconcileDialect } from '../types.ts';\nimport { stemFolded } from './lexical-text.ts';\n\n// This store's dialect (types.ts's ReconcileDialect) for the shared orchestration in\n// store/reconcile.ts. content is a plain table with \"_ngram\" sidecars for lexical.ts.\n\n// The ngram index is scoped to disjoint \"_ngram\" sidecar columns: a second index over the same\n// columns makes a bare substring match a whole word, defeating the prefix-query rejection.\n// The two FTS indexes, named here (not open.ts) because reconcile drops and rebuilds them around\n// a bulk load: Tantivy maintains them per inserted row, which is quadratic in what is already indexed.\nexport const CONTENT_FTS_DDL = [\n `CREATE INDEX IF NOT EXISTS content_fts ON content USING fts (title_stem, summary_stem, text_stem) WITH (weights = 'title_stem=10.0,summary_stem=5.0,text_stem=1.0')`,\n `CREATE INDEX IF NOT EXISTS content_fts_ngram ON content USING fts (title_ngram, summary_ngram, text_ngram) WITH (tokenizer='ngram', weights='title_ngram=10.0,summary_ngram=5.0,text_ngram=1.0')`,\n] as const;\nexport const CONTENT_FTS_NAMES = ['content_fts', 'content_fts_ngram'] as const;\n\n// '' when the field has no unspaced-script run (the common case), so the ngram index carries\n// nothing for it -- same \"pay for nothing when absent\" shape as sqlite's segmentField sidecars.\nfunction ngramSidecar(text: string): string {\n return hasUnspacedRun(text) ? text : '';\n}\n\n// Not a compile-time cap on ALTER TABLE ADD COLUMN (spike-measured: turso accepts 10,000 with\n// no error); the real fence is a SELECT projecting more than this many result columns, which fails to prepare.\nconst MAX_FRONTMATTER_COLUMNS = 2000;\n\n// Retained policy boundary from 2026-08-30 corpus-scale measurements; the optimum after later\n// update-path changes remains pending matched corpus-scale crossover evidence.\nexport const FTS_REBUILD_THRESHOLD = 250;\n\nexport type TursoFtsStrategy = 'incremental' | 'rebuild';\n\n// No rowid coupling (unlike sqlite's FTS5 content): `path` is content's own primary key.\nconst INSERT_CONTENT_SQL = `INSERT INTO content (\"path\", title, summary, text, title_stem, summary_stem, text_stem, title_ngram, summary_ngram, text_ngram) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`;\n\nfunction contentRow(doc: ParsedDoc): unknown[] {\n const { title, summary, text } = doc.search;\n return [doc.relPath, title, summary, text, stemFolded(title), stemFolded(summary), stemFolded(text), ngramSidecar(title), ngramSidecar(summary), ngramSidecar(text)];\n}\n\nexport function tursoFtsStrategy(delta: ReconcileDelta): TursoFtsStrategy {\n const churn = delta.reparsed.length + delta.vanished.length;\n return delta.files.length === 0 || churn > FTS_REBUILD_THRESHOLD ? 'rebuild' : 'incremental';\n}\n\n// Kept transaction-free because the shared reconcile owns the one write transaction. The explicit\n// strategy is internal composition for real-engine diagnostics; production selects it from delta.\nexport async function reconcileTursoContentWithStrategy(conn: Connection, touched: string[], docs: ParsedDoc[], strategy: TursoFtsStrategy): Promise<void> {\n // Tantivy indexes per inserted row at a cost that grows with the batch, so a large insert is\n // superlinear and a rebuild wins past the threshold.\n const bulk = strategy === 'rebuild';\n if (bulk) for (const name of CONTENT_FTS_NAMES) await conn.exec(`DROP INDEX IF EXISTS ${name}`);\n\n // content is a plain table keyed by its own path (no rowid subquery, unlike sqlite's FTS5\n // content), so vanished and reparsed docs delete in one pass.\n if (touched.length > 0) {\n const placeholders = touched.map(() => '?').join(', ');\n await conn.runBatch(`DELETE FROM content WHERE \"path\" IN (${placeholders})`, [touched]);\n }\n if (docs.length > 0) await conn.runBatch(INSERT_CONTENT_SQL, docs.map(contentRow));\n if (bulk) for (const ddl of CONTENT_FTS_DDL) await conn.exec(ddl);\n}\n\nasync function reconcileTursoContent(conn: Connection, touched: string[], docs: ParsedDoc[], delta: ReconcileDelta, _cfg: Config): Promise<void> {\n await reconcileTursoContentWithStrategy(conn, touched, docs, tursoFtsStrategy(delta));\n}\n\n// turso's ADD COLUMN is metadata-only, so a loop costs nothing extra over one statement.\nasync function addColumns(conn: Connection, names: string[]): Promise<void> {\n for (const name of names) await conn.exec(`ALTER TABLE frontmatter ADD COLUMN ${quoteIdent(name)}`);\n}\n\nexport const tursoDialect: ReconcileDialect = {\n beginMode: () => BEGIN_WRITE,\n checkColumnLimit(count) {\n if (count > MAX_FRONTMATTER_COLUMNS) {\n throw new SenseError(\n 'COLUMN_LIMIT',\n `frontmatter would need ${count} columns, crossing turso's SELECT result-set column limit (${MAX_FRONTMATTER_COLUMNS}; ALTER TABLE ADD COLUMN itself accepts far more, but a query projecting past this many columns fails to prepare). Narrow the presets' include globs so fewer/other files are indexed, or fix whatever is generating unbounded frontmatter keys.`\n );\n }\n },\n addColumns,\n reconcileContent: reconcileTursoContent,\n recordDuration: recordReconcileDuration,\n};\n"],"names":["CONTENT_FTS_DDL","CONTENT_FTS_NAMES","FTS_REBUILD_THRESHOLD","reconcileTursoContentWithStrategy","tursoDialect","tursoFtsStrategy","ngramSidecar","text","hasUnspacedRun","MAX_FRONTMATTER_COLUMNS","INSERT_CONTENT_SQL","contentRow","doc","search","title","summary","relPath","stemFolded","delta","churn","reparsed","length","vanished","files","conn","touched","docs","strategy","bulk","name","placeholders","ddl","exec","map","join","runBatch","reconcileTursoContent","_cfg","addColumns","names","quoteIdent","beginMode","BEGIN_WRITE","checkColumnLimit","count","SenseError","reconcileContent","recordDuration","recordReconcileDuration"],"mappings":"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"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/open-source/ai/sensemaking/src/store/turso/reconcile.ts"],"sourcesContent":["import type { Config } from '../../config/index.ts';\nimport { SenseError } from '../../errors.ts';\nimport type { ReconcileDelta } from '../../features/types.ts';\nimport type { ParsedDoc } from '../../scan/index.ts';\nimport { hasUnspacedRun } from '../../text/segment.ts';\nimport { quoteIdent, recordReconcileDuration } from '../shared.ts';\nimport { BEGIN_WRITE } from '../transaction.ts';\nimport type { Connection, ReconcileDialect } from '../types.ts';\nimport { tursoFts } from './engine.ts';\nimport { stemFolded } from './lexical-text.ts';\n\n// This store's dialect (types.ts's ReconcileDialect) for the shared orchestration in\n// store/reconcile.ts. content is a plain table with \"_ngram\" sidecars for lexical.ts.\n\n// The two FTS indexes (engine.ts's indexDdl), named here because reconcile drops and rebuilds them around\n// a bulk load: Tantivy maintains them per inserted row, which is quadratic in what is already indexed.\nexport const CONTENT_FTS_NAMES = ['content_fts', 'content_fts_ngram'] as const;\n\n// '' when the field has no unspaced-script run (the common case), so the ngram index carries\n// nothing for it -- same \"pay for nothing when absent\" shape as sqlite's segmentField sidecars.\nfunction ngramSidecar(text: string): string {\n return hasUnspacedRun(text) ? text : '';\n}\n\n// Not a compile-time cap on ALTER TABLE ADD COLUMN (spike-measured: turso accepts 10,000 with\n// no error); the real fence is a SELECT projecting more than this many result columns, which fails to prepare.\nconst MAX_FRONTMATTER_COLUMNS = 2000;\n\n// Retained policy boundary from 2026-08-30 corpus-scale measurements; the optimum after later\n// update-path changes remains pending matched corpus-scale crossover evidence.\nexport const FTS_REBUILD_THRESHOLD = 250;\n\nexport type TursoFtsStrategy = 'incremental' | 'rebuild';\n\n// No rowid coupling (unlike sqlite's FTS5 content): `path` is content's own primary key.\nconst INSERT_CONTENT_SQL = `INSERT INTO content (\"path\", title, summary, text, title_stem, summary_stem, text_stem, title_ngram, summary_ngram, text_ngram) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`;\n\nfunction contentRow(doc: ParsedDoc): unknown[] {\n const { title, summary, text } = doc.search;\n return [doc.relPath, title, summary, text, stemFolded(title), stemFolded(summary), stemFolded(text), ngramSidecar(title), ngramSidecar(summary), ngramSidecar(text)];\n}\n\nexport function tursoFtsStrategy(delta: ReconcileDelta): TursoFtsStrategy {\n const churn = delta.reparsed.length + delta.vanished.length;\n return delta.files.length === 0 || churn > FTS_REBUILD_THRESHOLD ? 'rebuild' : 'incremental';\n}\n\n// Kept transaction-free because the shared reconcile owns the one write transaction. The explicit\n// strategy is internal composition for real-engine diagnostics; production selects it from delta.\nexport async function reconcileTursoContentWithStrategy(conn: Connection, touched: string[], docs: ParsedDoc[], strategy: TursoFtsStrategy): Promise<void> {\n // Tantivy indexes per inserted row at a cost that grows with the batch, so a large insert is\n // superlinear and a rebuild wins past the threshold.\n const bulk = strategy === 'rebuild';\n if (bulk) for (const name of CONTENT_FTS_NAMES) await conn.exec(`DROP INDEX IF EXISTS ${name}`);\n\n // content is a plain table keyed by its own path (no rowid subquery, unlike sqlite's FTS5\n // content), so vanished and reparsed docs delete in one pass.\n if (touched.length > 0) {\n const placeholders = touched.map(() => '?').join(', ');\n await conn.runBatch(`DELETE FROM content WHERE \"path\" IN (${placeholders})`, [touched]);\n }\n if (docs.length > 0) await conn.runBatch(INSERT_CONTENT_SQL, docs.map(contentRow));\n if (bulk) for (const ddl of (await tursoFts()).indexDdl()) await conn.exec(ddl);\n}\n\nasync function reconcileTursoContent(conn: Connection, touched: string[], docs: ParsedDoc[], delta: ReconcileDelta, _cfg: Config): Promise<void> {\n await reconcileTursoContentWithStrategy(conn, touched, docs, tursoFtsStrategy(delta));\n}\n\n// turso's ADD COLUMN is metadata-only, so a loop costs nothing extra over one statement.\nasync function addColumns(conn: Connection, names: string[]): Promise<void> {\n for (const name of names) await conn.exec(`ALTER TABLE frontmatter ADD COLUMN ${quoteIdent(name)}`);\n}\n\nexport const tursoDialect: ReconcileDialect = {\n beginMode: () => BEGIN_WRITE,\n checkColumnLimit(count) {\n if (count > MAX_FRONTMATTER_COLUMNS) {\n throw new SenseError(\n 'COLUMN_LIMIT',\n `frontmatter would need ${count} columns, crossing turso's SELECT result-set column limit (${MAX_FRONTMATTER_COLUMNS}; ALTER TABLE ADD COLUMN itself accepts far more, but a query projecting past this many columns fails to prepare). Narrow the presets' include globs so fewer/other files are indexed, or fix whatever is generating unbounded frontmatter keys.`\n );\n }\n },\n addColumns,\n reconcileContent: reconcileTursoContent,\n recordDuration: recordReconcileDuration,\n};\n"],"names":["CONTENT_FTS_NAMES","FTS_REBUILD_THRESHOLD","reconcileTursoContentWithStrategy","tursoDialect","tursoFtsStrategy","ngramSidecar","text","hasUnspacedRun","MAX_FRONTMATTER_COLUMNS","INSERT_CONTENT_SQL","contentRow","doc","search","title","summary","relPath","stemFolded","delta","churn","reparsed","length","vanished","files","conn","touched","docs","strategy","bulk","name","placeholders","ddl","exec","map","join","runBatch","tursoFts","indexDdl","reconcileTursoContent","_cfg","addColumns","names","quoteIdent","beginMode","BEGIN_WRITE","checkColumnLimit","count","SenseError","reconcileContent","recordDuration","recordReconcileDuration"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/store/turso/sql-functions.ts"],"sourcesContent":["import { SenseError } from '../../errors.ts';\n\n// Turso can't register UDFs: has()/basename() are rewritten into portable SQL below; segment()\n// (Intl.Segmenter grapheme clustering, types.ts's 'segment' capability) has none, so it's rejected like an unsupported FTS5 operator.\n\n// Non-global: recursion (readArgs' contents rewritten via rewriteFunctions) reenters this module's\n// regexes before the outer scan resumes, and a global regex's lastIndex does not nest across that.\nconst CALL_ANYWHERE = /\\b(has|basename|segment)\\s*\\(/i;\nconst CALL_AT_START = /^(has|basename|segment)\\s*\\(/i;\n\nfunction isWordChar(ch: string | undefined): boolean {\n return ch !== undefined && /[A-Za-z0-9_]/.test(ch);\n}\n\n// The index just past the quoted literal or SQL comment starting at i, or null if i starts\n// neither. Shared by the scan and readArgs so both leave quoted/comment text opaque to a call match.\nfunction skipOpaque(sql: string, i: number): number | null {\n const ch = sql[i];\n if (ch === \"'\" || ch === '\"') {\n let j = i + 1;\n while (j < sql.length) {\n if (sql[j] === ch) {\n if (sql[j + 1] === ch) {\n j += 2;\n continue;\n }\n return j + 1;\n }\n j++;\n }\n return j; // unterminated literal: consume to end rather than loop forever\n }\n if (ch === '-' && sql[i + 1] === '-') {\n const nl = sql.indexOf('\\n', i);\n return nl === -1 ? sql.length : nl + 1;\n }\n if (ch === '/' && sql[i + 1] === '*') {\n const close = sql.indexOf('*/', i + 2);\n return close === -1 ? sql.length : close + 2;\n }\n return null;\n}\n\n// `?N`/named placeholders bind by number/name, so repeating one is safe; an anonymous `?` takes\n// the next slot per occurrence, so it's numbered here first -- sqlHas/sqlBasename duplicate their arguments.\nfunction numberPlaceholders(sql: string): string {\n let out = '';\n let i = 0;\n let n = 0;\n while (i < sql.length) {\n const skip = skipOpaque(sql, i);\n if (skip !== null) {\n out += sql.slice(i, skip);\n i = skip;\n continue;\n }\n if (sql[i] === '?' && !/[0-9]/.test(sql[i + 1] ?? '')) {\n n++;\n out += `?${n}`;\n i++;\n continue;\n }\n out += sql[i];\n i++;\n }\n return out;\n}\n\n// The un-rewritten argument texts of the call whose '(' sits at parenStart, and the index just\n// past its matching ')'. Paren depth is tracked so a nested call's commas/parens aren't mistaken for ours.\nfunction readArgs(sql: string, parenStart: number): { args: string[]; end: number } {\n const args: string[] = [];\n let depth = 1;\n let cur = '';\n let i = parenStart + 1;\n while (i < sql.length) {\n const skip = skipOpaque(sql, i);\n if (skip !== null) {\n cur += sql.slice(i, skip);\n i = skip;\n continue;\n }\n const ch = sql[i];\n if (ch === '(') {\n depth++;\n cur += ch;\n i++;\n continue;\n }\n if (ch === ')') {\n depth--;\n i++;\n if (depth === 0) break;\n cur += ch;\n continue;\n }\n if (ch === ',' && depth === 1) {\n args.push(cur.trim());\n cur = '';\n i++;\n continue;\n }\n cur += ch;\n i++;\n }\n if (depth !== 0) throw new Error(`turso: unterminated argument list starting at \"${sql.slice(parenStart, parenStart + 30)}...\"`);\n if (cur.trim() !== '') args.push(cur.trim());\n return { args, end: i };\n}\n\n// field.startsWith('[') && JSON.parse(field) is an array, matched by membership; every other\n// field, stringified, matched by substring (sql-functions.ts's hasImpl, mirrored branch for branch).\nfunction sqlHas(fieldExpr: string, valueExpr: string): string {\n const isArray = `substr(${fieldExpr},1,1) = '[' AND json_valid(${fieldExpr})`;\n // json_each's argument is re-guarded by its own CASE (falling back to '[]'): turso evaluates a\n // CASE branch's table function even when untaken, and a non-array argument there raises rather than yielding 0 rows (spike-verified).\n return `(CASE\n WHEN ${fieldExpr} IS NULL THEN 0\n WHEN ${isArray} THEN\n (SELECT COUNT(*) FROM json_each(CASE WHEN ${isArray} THEN ${fieldExpr} ELSE '[]' END) je WHERE CAST(je.value AS TEXT) = CAST(${valueExpr} AS TEXT)) > 0\n ELSE instr(CAST(${fieldExpr} AS TEXT), CAST(${valueExpr} AS TEXT)) > 0\n END)`;\n}\n\n// posix.basename(String(path)), suffix stripped Unix-style (sql-functions.ts's basenameImpl). No\n// last-'/' primitive exists, so reverse() finds the first '/' from the end, then reverse() restores order.\nfunction sqlBasename(pathExpr: string, suffixExpr: string): string {\n const trimmed = `rtrim(CAST(${pathExpr} AS TEXT), '/')`;\n const name = `CASE\n WHEN ${trimmed} = '' THEN ''\n WHEN instr(${trimmed}, '/') = 0 THEN ${trimmed}\n ELSE reverse(substr(reverse(${trimmed}), 1, instr(reverse(${trimmed}), '/') - 1))\n END`;\n return `(CASE WHEN ${pathExpr} IS NULL THEN NULL ELSE\n (CASE WHEN ${suffixExpr} IS NOT NULL AND CAST(${suffixExpr} AS TEXT) != '' AND CAST(${suffixExpr} AS TEXT) != (${name})\n AND substr((${name}), -length(CAST(${suffixExpr} AS TEXT))) = CAST(${suffixExpr} AS TEXT)\n THEN substr((${name}), 1, length((${name})) - length(CAST(${suffixExpr} AS TEXT)))\n ELSE (${name}) END)\n END)`;\n}\n\n// Rewrites every has()/basename() call into the portable SQL above, recursing into each call's own\n// arguments first so a nested `instr(basename(f.path), 'x')` resolves inside out; segment() instead raises STORE_CAPABILITY_MISSING, named, like an unsupported FTS5 operator.\nexport function rewriteFunctions(sql: string): string {\n if (!CALL_ANYWHERE.test(sql)) return sql;\n // Numbered once, over the whole statement, before any argument is duplicated below -- rewrite()\n // recurses over already-numbered substrings, never renumbering them a second time.\n return rewrite(numberPlaceholders(sql));\n}\n\nfunction rewrite(sql: string): string {\n let out = '';\n let i = 0;\n while (i < sql.length) {\n const skip = skipOpaque(sql, i);\n if (skip !== null) {\n out += sql.slice(i, skip);\n i = skip;\n continue;\n }\n const m = !isWordChar(sql[i - 1]) ? CALL_AT_START.exec(sql.slice(i)) : null;\n if (m) {\n const name = m[1].toLowerCase();\n const parenStart = i + m[0].length - 1;\n if (name === 'segment') {\n throw new SenseError('STORE_CAPABILITY_MISSING', `store \"turso\" does not implement segment() as a SQL function in this build (its client cannot register UDFs); rephrase the query without it, or set \"store\" to \"sqlite\" in this tree's config to run it as written`);\n }\n const { args, end } = readArgs(sql, parenStart);\n const rewrittenArgs = args.map(rewrite);\n if (name === 'has') {\n if (rewrittenArgs.length !== 2) throw new Error(`turso: has() takes exactly 2 arguments (field, value), got ${rewrittenArgs.length}`);\n out += sqlHas(rewrittenArgs[0], rewrittenArgs[1]);\n } else {\n if (rewrittenArgs.length < 1 || rewrittenArgs.length > 2) throw new Error(`turso: basename() takes 1 or 2 arguments (path, suffix?), got ${rewrittenArgs.length}`);\n out += sqlBasename(rewrittenArgs[0], rewrittenArgs[1] ?? 'NULL');\n }\n i = end;\n continue;\n }\n out += sql[i];\n i++;\n }\n return out;\n}\n"],"names":["rewriteFunctions","CALL_ANYWHERE","CALL_AT_START","isWordChar","ch","undefined","test","skipOpaque","sql","i","j","length","nl","indexOf","close","numberPlaceholders","out","n","skip","slice","readArgs","parenStart","args","depth","cur","push","trim","Error","end","sqlHas","fieldExpr","valueExpr","isArray","sqlBasename","pathExpr","suffixExpr","trimmed","name","rewrite","m","exec","toLowerCase","SenseError","rewrittenArgs","map"],"mappings":"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"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/open-source/ai/sensemaking/src/store/turso/sql-functions.ts"],"sourcesContent":["import { SenseError } from '../../errors.ts';\n\n// Turso can't register UDFs: has()/basename() are rewritten into portable SQL below; segment()\n// (Intl.Segmenter grapheme clustering, types.ts's 'segment' capability) has none, so it's rejected like an unsupported FTS5 operator.\n\n// Non-global: recursion (readArgs' contents rewritten via rewriteFunctions) reenters this module's\n// regexes before the outer scan resumes, and a global regex's lastIndex does not nest across that.\nconst CALL_ANYWHERE = /\\b(has|basename|segment)\\s*\\(/i;\nconst CALL_AT_START = /^(has|basename|segment)\\s*\\(/i;\n\nfunction isWordChar(ch: string | undefined): boolean {\n return ch !== undefined && /[A-Za-z0-9_]/.test(ch);\n}\n\n// The index just past the quoted literal or SQL comment starting at i, or null if i starts\n// neither. Shared by the scan and readArgs so both leave quoted/comment text opaque to a call match.\nfunction skipOpaque(sql: string, i: number): number | null {\n const ch = sql[i];\n if (ch === \"'\" || ch === '\"') {\n let j = i + 1;\n while (j < sql.length) {\n if (sql[j] === ch) {\n if (sql[j + 1] === ch) {\n j += 2;\n continue;\n }\n return j + 1;\n }\n j++;\n }\n return j; // unterminated literal: consume to end rather than loop forever\n }\n if (ch === '-' && sql[i + 1] === '-') {\n const nl = sql.indexOf('\\n', i);\n return nl === -1 ? sql.length : nl + 1;\n }\n if (ch === '/' && sql[i + 1] === '*') {\n const close = sql.indexOf('*/', i + 2);\n return close === -1 ? sql.length : close + 2;\n }\n return null;\n}\n\n// `?N`/named placeholders bind by number/name, so repeating one is safe; an anonymous `?` takes\n// the next slot per occurrence, so it's numbered here first -- sqlHas/sqlBasename duplicate their arguments.\nfunction numberPlaceholders(sql: string): string {\n let out = '';\n let i = 0;\n let n = 0;\n while (i < sql.length) {\n const skip = skipOpaque(sql, i);\n if (skip !== null) {\n out += sql.slice(i, skip);\n i = skip;\n continue;\n }\n if (sql[i] === '?' && !/[0-9]/.test(sql[i + 1] ?? '')) {\n n++;\n out += `?${n}`;\n i++;\n continue;\n }\n out += sql[i];\n i++;\n }\n return out;\n}\n\n// The un-rewritten argument texts of the call whose '(' sits at parenStart, and the index just\n// past its matching ')'. Paren depth is tracked so a nested call's commas/parens aren't mistaken for ours.\nfunction readArgs(sql: string, parenStart: number): { args: string[]; end: number } {\n const args: string[] = [];\n let depth = 1;\n let cur = '';\n let i = parenStart + 1;\n while (i < sql.length) {\n const skip = skipOpaque(sql, i);\n if (skip !== null) {\n cur += sql.slice(i, skip);\n i = skip;\n continue;\n }\n const ch = sql[i];\n if (ch === '(') {\n depth++;\n cur += ch;\n i++;\n continue;\n }\n if (ch === ')') {\n depth--;\n i++;\n if (depth === 0) break;\n cur += ch;\n continue;\n }\n if (ch === ',' && depth === 1) {\n args.push(cur.trim());\n cur = '';\n i++;\n continue;\n }\n cur += ch;\n i++;\n }\n if (depth !== 0) throw new Error(`turso: unterminated argument list starting at \"${sql.slice(parenStart, parenStart + 30)}...\"`);\n if (cur.trim() !== '') args.push(cur.trim());\n return { args, end: i };\n}\n\n// field.startsWith('[') && JSON.parse(field) is an array, matched by membership; every other\n// field, stringified, matched by substring (sql-functions.ts's hasImpl, mirrored branch for branch).\nfunction sqlHas(fieldExpr: string, valueExpr: string): string {\n const isArray = `substr(${fieldExpr},1,1) = '[' AND json_valid(${fieldExpr})`;\n // json_each's argument is re-guarded by its own CASE (falling back to '[]'): turso evaluates a\n // CASE branch's table function even when untaken, and a non-array argument there raises rather than yielding 0 rows (spike-verified).\n return `(CASE\n WHEN ${fieldExpr} IS NULL THEN 0\n WHEN ${isArray} THEN\n (SELECT COUNT(*) FROM json_each(CASE WHEN ${isArray} THEN ${fieldExpr} ELSE '[]' END) je WHERE CAST(je.value AS TEXT) = CAST(${valueExpr} AS TEXT)) > 0\n ELSE instr(CAST(${fieldExpr} AS TEXT), CAST(${valueExpr} AS TEXT)) > 0\n END)`;\n}\n\n// posix.basename(String(path)), suffix stripped Unix-style (sql-functions.ts's basenameImpl). No\n// last-'/' primitive exists, so reverse() finds the first '/' from the end, then reverse() restores order.\nfunction sqlBasename(pathExpr: string, suffixExpr: string): string {\n const trimmed = `rtrim(CAST(${pathExpr} AS TEXT), '/')`;\n const name = `CASE\n WHEN ${trimmed} = '' THEN ''\n WHEN instr(${trimmed}, '/') = 0 THEN ${trimmed}\n ELSE reverse(substr(reverse(${trimmed}), 1, instr(reverse(${trimmed}), '/') - 1))\n END`;\n return `(CASE WHEN ${pathExpr} IS NULL THEN NULL ELSE\n (CASE WHEN ${suffixExpr} IS NOT NULL AND CAST(${suffixExpr} AS TEXT) != '' AND CAST(${suffixExpr} AS TEXT) != (${name})\n AND substr((${name}), -length(CAST(${suffixExpr} AS TEXT))) = CAST(${suffixExpr} AS TEXT)\n THEN substr((${name}), 1, length((${name})) - length(CAST(${suffixExpr} AS TEXT)))\n ELSE (${name}) END)\n END)`;\n}\n\n// Rewrites every has()/basename() call into the portable SQL above, recursing into each call's own\n// arguments first so a nested `instr(basename(f.path), 'x')` resolves inside out; segment() instead raises STORE_CAPABILITY_MISSING, named, like an unsupported FTS5 operator.\nexport function rewriteFunctions(sql: string): string {\n if (!CALL_ANYWHERE.test(sql)) return sql;\n // Numbered once, over the whole statement, before any argument is duplicated below -- rewrite()\n // recurses over already-numbered substrings, never renumbering them a second time.\n return rewrite(numberPlaceholders(sql));\n}\n\nfunction rewrite(sql: string): string {\n let out = '';\n let i = 0;\n while (i < sql.length) {\n const skip = skipOpaque(sql, i);\n if (skip !== null) {\n out += sql.slice(i, skip);\n i = skip;\n continue;\n }\n const m = !isWordChar(sql[i - 1]) ? CALL_AT_START.exec(sql.slice(i)) : null;\n if (m) {\n const name = m[1].toLowerCase();\n const parenStart = i + m[0].length - 1;\n if (name === 'segment') {\n throw new SenseError('STORE_CAPABILITY_MISSING', `store \"turso\" does not implement segment() as a SQL function in this build (its client cannot register UDFs); rephrase the query without it, or set \"store\" to \"sqlite\" in this tree's config to run it as written`);\n }\n const { args, end } = readArgs(sql, parenStart);\n const rewrittenArgs = args.map(rewrite);\n if (name === 'has') {\n if (rewrittenArgs.length !== 2) throw new Error(`turso: has() takes exactly 2 arguments (field, value), got ${rewrittenArgs.length}`);\n out += sqlHas(rewrittenArgs[0], rewrittenArgs[1]);\n } else {\n if (rewrittenArgs.length < 1 || rewrittenArgs.length > 2) throw new Error(`turso: basename() takes 1 or 2 arguments (path, suffix?), got ${rewrittenArgs.length}`);\n out += sqlBasename(rewrittenArgs[0], rewrittenArgs[1] ?? 'NULL');\n }\n i = end;\n continue;\n }\n out += sql[i];\n i++;\n }\n return out;\n}\n"],"names":["rewriteFunctions","CALL_ANYWHERE","CALL_AT_START","isWordChar","ch","undefined","test","skipOpaque","sql","i","j","length","nl","indexOf","close","numberPlaceholders","out","n","skip","slice","readArgs","parenStart","args","depth","cur","push","trim","Error","end","sqlHas","fieldExpr","valueExpr","isArray","sqlBasename","pathExpr","suffixExpr","trimmed","name","rewrite","m","exec","toLowerCase","SenseError","rewrittenArgs","map"],"mappings":"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"}