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
@@ -14,6 +14,9 @@ _export(exports, {
14
14
  },
15
15
  get openWithDialect () {
16
16
  return openWithDialect;
17
+ },
18
+ get prepareDocumentEmbeddings () {
19
+ return prepareDocumentEmbeddings;
17
20
  }
18
21
  });
19
22
  var _nodediagnostics_channel = require("node:diagnostics_channel");
@@ -21,6 +24,7 @@ var _nodefs = require("node:fs");
21
24
  var _nodepath = require("node:path");
22
25
  var _indexts = require("../config/index.js");
23
26
  var _handoffts = require("../embed/handoff.js");
27
+ var _queryts = require("../embed/query.js");
24
28
  var _errorsts = require("../errors.js");
25
29
  var _indexts1 = require("../features/index.js");
26
30
  var _builderts = require("./builder.js");
@@ -31,6 +35,8 @@ var _lockwaitts = require("./lock-wait.js");
31
35
  var _presetscopets = require("./preset-scope.js");
32
36
  var _sharedts = require("./shared.js");
33
37
  var _signaturets = require("./signature.js");
38
+ var _stagests = require("./stages.js");
39
+ var _transactionts = require("./transaction.js");
34
40
  function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
35
41
  try {
36
42
  var info = gen[key](arg);
@@ -156,11 +162,27 @@ function _ts_generator(thisArg, body) {
156
162
  };
157
163
  }
158
164
  }
159
- // duckdb/turso hold the cache file for their connection's whole life, so a second command waits.
160
- // Bounded by this tree's recorded reconcile time (lock-wait.ts), not a fixed guess.
165
+ var CORE_READY_META_KEY = 'core_ready';
161
166
  var LOCK_POLL_MS = 50;
162
167
  var lockWait = (0, _nodediagnostics_channel.channel)('sensemaking.store.lock-wait');
163
- function connectUnlocked(dbPath, cfg, configDir, dialect) {
168
+ function notReady(reason) {
169
+ return new _errorsts.SenseError('INDEX_NOT_READY', "".concat(reason, '; run "sense build" or call build(config) before opening with { build: false }'));
170
+ }
171
+ function normaliseConfig(cfg) {
172
+ // `baseDir` was the original public open() input. Keep direct API callers working while
173
+ // making the two ownership paths explicit for every internal operation.
174
+ if (!cfg.rootDir) {
175
+ if (!cfg.baseDir) throw new _errorsts.SenseError('CONFIG_INVALID', 'open requires rootDir (or legacy baseDir)');
176
+ cfg.rootDir = cfg.baseDir;
177
+ }
178
+ if (!cfg.configDir) cfg.configDir = cfg.rootDir;
179
+ return cfg;
180
+ }
181
+ function cachePath(cfg, dialect) {
182
+ var _cfg_configDir;
183
+ return (0, _nodepath.join)((_cfg_configDir = cfg.configDir) !== null && _cfg_configDir !== void 0 ? _cfg_configDir : cfg.baseDir, _indexts.STATE_DIR, dialect.filename);
184
+ }
185
+ function connectUnlocked(dbPath, cfg, configDir, dialect, options) {
164
186
  return _async_to_generator(function() {
165
187
  var budgetMs, deadline, err, _dialect_isLocked;
166
188
  return _ts_generator(this, function(_state) {
@@ -178,7 +200,7 @@ function connectUnlocked(dbPath, cfg, configDir, dialect) {
178
200
  ]);
179
201
  return [
180
202
  4,
181
- dialect.connect(dbPath, cfg)
203
+ dialect.connect(dbPath, cfg, options)
182
204
  ];
183
205
  case 2:
184
206
  return [
@@ -187,8 +209,10 @@ function connectUnlocked(dbPath, cfg, configDir, dialect) {
187
209
  ];
188
210
  case 3:
189
211
  err = _state.sent();
212
+ if (options.existingOnly && !(0, _nodefs.existsSync)(dbPath)) {
213
+ throw notReady("the derived index does not exist at ".concat(dbPath));
214
+ }
190
215
  if (!((_dialect_isLocked = dialect.isLocked) === null || _dialect_isLocked === void 0 ? void 0 : _dialect_isLocked.call(dialect, err))) throw err;
191
- // Observe a real rejected native connection, never merely the start of an async open.
192
216
  if (lockWait.hasSubscribers) lockWait.publish({
193
217
  store: cfg.store,
194
218
  dbPath: dbPath
@@ -221,9 +245,176 @@ function connectUnlocked(dbPath, cfg, configDir, dialect) {
221
245
  });
222
246
  })();
223
247
  }
224
- function connectWithDialect(cfg, dialect) {
248
+ function assertCoreSchema(conn) {
249
+ return _async_to_generator(function() {
250
+ var _i, _iter, table;
251
+ return _ts_generator(this, function(_state) {
252
+ switch(_state.label){
253
+ case 0:
254
+ _i = 0, _iter = [
255
+ 'frontmatter',
256
+ 'content',
257
+ 'preset_files',
258
+ 'indexed_sources'
259
+ ];
260
+ _state.label = 1;
261
+ case 1:
262
+ if (!(_i < _iter.length)) return [
263
+ 3,
264
+ 5
265
+ ];
266
+ table = _iter[_i];
267
+ return [
268
+ 4,
269
+ conn.prepare("SELECT 1 FROM ".concat(table, " LIMIT 0"))
270
+ ];
271
+ case 2:
272
+ return [
273
+ 4,
274
+ _state.sent().all()
275
+ ];
276
+ case 3:
277
+ _state.sent();
278
+ _state.label = 4;
279
+ case 4:
280
+ _i++;
281
+ return [
282
+ 3,
283
+ 1
284
+ ];
285
+ case 5:
286
+ return [
287
+ 2
288
+ ];
289
+ }
290
+ });
291
+ })();
292
+ }
293
+ function connectExisting(cfg, dialect, requirements) {
294
+ return _async_to_generator(function() {
295
+ var _cfg_configDir, configDir, dbPath, _ref, handle, conn, version, features, ready, unused, wantFeatures, _dialect_assertLexicalReady, err;
296
+ return _ts_generator(this, function(_state) {
297
+ switch(_state.label){
298
+ case 0:
299
+ configDir = (_cfg_configDir = cfg.configDir) !== null && _cfg_configDir !== void 0 ? _cfg_configDir : cfg.baseDir;
300
+ dbPath = cachePath(cfg, dialect);
301
+ if (!(0, _nodefs.existsSync)(dbPath)) throw notReady("the derived index does not exist at ".concat(dbPath));
302
+ return [
303
+ 4,
304
+ connectUnlocked(dbPath, cfg, configDir, dialect, {
305
+ existingOnly: true,
306
+ observational: true
307
+ })
308
+ ];
309
+ case 1:
310
+ _ref = _state.sent(), handle = _ref.handle, conn = _ref.conn;
311
+ _state.label = 2;
312
+ case 2:
313
+ _state.trys.push([
314
+ 2,
315
+ 12,
316
+ ,
317
+ 14
318
+ ]);
319
+ _state.label = 3;
320
+ case 3:
321
+ _state.trys.push([
322
+ 3,
323
+ 8,
324
+ ,
325
+ 9
326
+ ]);
327
+ return [
328
+ 4,
329
+ (0, _sharedts.getMeta)(conn, 'schema_version')
330
+ ];
331
+ case 4:
332
+ version = _state.sent();
333
+ return [
334
+ 4,
335
+ (0, _sharedts.getMeta)(conn, 'features')
336
+ ];
337
+ case 5:
338
+ features = _state.sent();
339
+ return [
340
+ 4,
341
+ (0, _sharedts.getMeta)(conn, CORE_READY_META_KEY)
342
+ ];
343
+ case 6:
344
+ ready = _state.sent();
345
+ return [
346
+ 4,
347
+ assertCoreSchema(conn)
348
+ ];
349
+ case 7:
350
+ _state.sent();
351
+ return [
352
+ 3,
353
+ 9
354
+ ];
355
+ case 8:
356
+ unused = _state.sent();
357
+ if (!(0, _nodefs.existsSync)(dbPath)) throw notReady("the derived index was deleted while opening ".concat(dbPath));
358
+ throw notReady("the derived index at ".concat(dbPath, " has no compatible schema"));
359
+ case 9:
360
+ if (version !== dialect.schemaVersion) {
361
+ throw notReady("the derived index at ".concat(dbPath, " uses schema ").concat(version !== null && version !== void 0 ? version : 'unknown', ", but this sense version requires ").concat(dialect.schemaVersion));
362
+ }
363
+ wantFeatures = (0, _indexts.featureSignature)(cfg, _indexts1.FEATURES);
364
+ if (features !== wantFeatures) {
365
+ throw notReady("the derived index at ".concat(dbPath, " was built for different configuration features"));
366
+ }
367
+ if (ready !== '1') {
368
+ throw notReady("the derived index at ".concat(dbPath, " has an incomplete core build"));
369
+ }
370
+ if (!requirements.has('lexical')) return [
371
+ 3,
372
+ 11
373
+ ];
374
+ return [
375
+ 4,
376
+ (_dialect_assertLexicalReady = dialect.assertLexicalReady) === null || _dialect_assertLexicalReady === void 0 ? void 0 : _dialect_assertLexicalReady.call(dialect, conn)
377
+ ];
378
+ case 10:
379
+ _state.sent();
380
+ _state.label = 11;
381
+ case 11:
382
+ if (!(0, _nodefs.existsSync)(dbPath)) throw notReady("the derived index was deleted while opening ".concat(dbPath));
383
+ return [
384
+ 2,
385
+ {
386
+ handle: handle,
387
+ conn: conn,
388
+ cfg: cfg,
389
+ dbPath: dbPath,
390
+ parsed: 0,
391
+ warnings: [],
392
+ stages: (0, _stagests.stageRecorder)().take(0, 0),
393
+ observational: true
394
+ }
395
+ ];
396
+ case 12:
397
+ err = _state.sent();
398
+ return [
399
+ 4,
400
+ dialect.close(handle, {
401
+ observational: true
402
+ })
403
+ ];
404
+ case 13:
405
+ _state.sent();
406
+ throw err;
407
+ case 14:
408
+ return [
409
+ 2
410
+ ];
411
+ }
412
+ });
413
+ })();
414
+ }
415
+ function connectForBuild(cfg, dialect, requirements) {
225
416
  return _async_to_generator(function() {
226
- var _cfg_configDir, _cfg_rootDir, configDir, stateDir, dbPath, _ref, handle, conn, closed, builder, version, features, wantFeatures, forcedPaths, embedInvalidate, featureToggles, _cfg_rootDir1, changedKeys, presetForced, embedKind, toggles, changed, changed1, changed2, _ref1, recordedMaxMs, embedParsed, _tmp, featureParsed, _tmp1, _ref2, parsed, warnings, stages, err;
417
+ var _cfg_configDir, _cfg_rootDir, configDir, stateDir, dbPath, _ref, handle, conn, closed, builder, version, features, ready, wantFeatures, recoverIncomplete, forcedPaths, embedInvalidate, featureToggles, _cfg_rootDir1, changedKeys, presetForced, embedKind, toggles, changed, changed1, changed2, _ref1, recordedMaxMs, embedParsed, _tmp, featureParsed, _tmp1, _ref2, parsed, warnings, stages, _tmp2, _dialect_prepareLexical, err;
227
418
  return _ts_generator(this, function(_state) {
228
419
  switch(_state.label){
229
420
  case 0:
@@ -235,15 +426,14 @@ function connectWithDialect(cfg, dialect) {
235
426
  dbPath = (0, _nodepath.join)(stateDir, dialect.filename);
236
427
  return [
237
428
  4,
238
- connectUnlocked(dbPath, cfg, configDir, dialect)
429
+ connectUnlocked(dbPath, cfg, configDir, dialect, {
430
+ existingOnly: false,
431
+ observational: false
432
+ })
239
433
  ];
240
434
  case 1:
241
435
  _ref = _state.sent(), handle = _ref.handle, conn = _ref.conn;
242
- // A throw below must release this handle, or the leaked WAL makes the cache file undeletable on
243
- // Windows. `closed` keeps the catch from double-closing a handle a rebuild branch already closed.
244
436
  closed = false;
245
- // Created here, not inside reconcile(): invalidate()/invalidateFeatures() below share its pool
246
- // with the build() call that follows them.
247
437
  builder = (0, _builderts.createBuilder)(conn, cfg, {
248
438
  rootDir: (_cfg_rootDir = cfg.rootDir) !== null && _cfg_rootDir !== void 0 ? _cfg_rootDir : cfg.baseDir,
249
439
  configDir: configDir
@@ -252,9 +442,9 @@ function connectWithDialect(cfg, dialect) {
252
442
  case 2:
253
443
  _state.trys.push([
254
444
  2,
255
- 30,
445
+ 35,
256
446
  ,
257
- 34
447
+ 39
258
448
  ]);
259
449
  return [
260
450
  4,
@@ -274,123 +464,103 @@ function connectWithDialect(cfg, dialect) {
274
464
  ];
275
465
  case 5:
276
466
  features = _state.sent();
467
+ return [
468
+ 4,
469
+ (0, _sharedts.getMeta)(conn, CORE_READY_META_KEY)
470
+ ];
471
+ case 6:
472
+ ready = _state.sent();
277
473
  wantFeatures = (0, _indexts.featureSignature)(cfg, _indexts1.FEATURES);
278
- if (!(version !== null && version !== dialect.schemaVersion || features !== null && features !== wantFeatures)) return [
279
- 3,
280
- 17
474
+ // `ready=0` may belong to another SQLite builder, so recovery stays in place and lets the
475
+ // engine serialize it. It never unlinks the cache.
476
+ return [
477
+ 4,
478
+ (0, _sharedts.setMeta)(conn, CORE_READY_META_KEY, '0')
281
479
  ];
480
+ case 7:
481
+ _state.sent();
482
+ recoverIncomplete = ready === '0' && (version === null || version === dialect.schemaVersion);
282
483
  if (!(version !== null && version !== dialect.schemaVersion)) return [
283
484
  3,
284
- 7
485
+ 9
285
486
  ];
286
487
  console.error('sense: cache format changed (new sensemaking version); rebuilding the index');
287
- // Close before clearCache deletes the files out from under the still-open handle.
288
488
  closed = true;
289
489
  return [
290
490
  4,
291
491
  dialect.close(handle)
292
492
  ];
293
- case 6:
493
+ case 8:
294
494
  _state.sent();
295
495
  (0, _cachets.clearCache)(cfg);
296
496
  return [
297
497
  2,
298
- connectWithDialect(cfg, dialect)
498
+ connectForBuild(cfg, dialect, requirements)
499
+ ];
500
+ case 9:
501
+ if (!recoverIncomplete) return [
502
+ 3,
503
+ 10
504
+ ];
505
+ console.error('sense: recovering an incomplete index generation in place');
506
+ return [
507
+ 3,
508
+ 16
509
+ ];
510
+ case 10:
511
+ if (!(features !== null && features !== wantFeatures)) return [
512
+ 3,
513
+ 16
299
514
  ];
300
- case 7:
301
515
  changedKeys = (0, _signaturets.changedSignatureKeys)(features !== null && features !== void 0 ? features : '', wantFeatures);
302
- // Null (rather than the empty set) when changedKeys isn't preset-only, or a changed
303
- // preset's stored segment can't be parsed back into old include/exclude/vectors -- either
304
- // way the branch below is skipped and the full rebuild stays the fallback.
305
516
  presetForced = (0, _presetscopets.isPresetOnlyChange)(changedKeys) ? (0, _presetscopets.forcedPresetPaths)(cfg, (_cfg_rootDir1 = cfg.rootDir) !== null && _cfg_rootDir1 !== void 0 ? _cfg_rootDir1 : cfg.baseDir, features !== null && features !== void 0 ? features : '', changedKeys) : null;
306
- // Null unless exactly one segment changed and it decomposes into a recognised embed-only
307
- // case (embed-scope.ts): anything else, including embed toggled on/off, stays null.
308
517
  embedKind = changedKeys.size === 1 && changedKeys.has('embed') ? (0, _embedscopets.classifyEmbedChange)(features !== null && features !== void 0 ? features : '', wantFeatures) : null;
309
- // Null (rather than the empty set) when changedKeys isn't feature-toggle-only, or a changed
310
- // feature's stored segment can't be parsed back into old/new on-off -- either way the branch
311
- // below is skipped and the full rebuild stays the fallback.
312
518
  toggles = (0, _featurescopets.isFeatureOnlyChange)(changedKeys) ? (0, _featurescopets.classifyFeatureToggles)(features !== null && features !== void 0 ? features : '', wantFeatures, changedKeys) : null;
313
519
  if (!(changedKeys.size === 1 && changedKeys.has('embed') && (0, _signaturets.embedIdentityAdopted)(features !== null && features !== void 0 ? features : '', wantFeatures))) return [
314
520
  3,
315
- 9
521
+ 11
316
522
  ];
317
- // First sight of a resolved weight identity: the model itself hasn't changed, so
318
- // adopt it into meta with no rebuild and no re-embed.
319
523
  console.error("sense: recorded the embedding model's resolved identity; vectors are unaffected");
320
- return [
321
- 4,
322
- (0, _sharedts.setMeta)(conn, 'features', wantFeatures)
323
- ];
324
- case 8:
325
- _state.sent();
326
524
  return [
327
525
  3,
328
- 17
526
+ 16
329
527
  ];
330
- case 9:
528
+ case 11:
331
529
  if (!(embedKind !== null)) return [
332
530
  3,
333
- 11
531
+ 12
334
532
  ];
335
- // Chunk boundaries are file-derived, not model-derived (embed.ts's chunksOf), so neither
336
- // case needs any file reparsed for any feature but embed itself.
337
533
  embedInvalidate = embedKind;
338
534
  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');
339
- return [
340
- 4,
341
- (0, _sharedts.setMeta)(conn, 'features', wantFeatures)
342
- ];
343
- case 10:
344
- _state.sent();
345
535
  return [
346
536
  3,
347
- 17
537
+ 16
348
538
  ];
349
- case 11:
539
+ case 12:
350
540
  if (!(presetForced !== null)) return [
351
541
  3,
352
542
  13
353
543
  ];
354
- // Membership only: which files a preset covers moved, not a file's own content, a
355
- // global feature, or the embed model. reconcile() already knows how to
356
- // add, update, and remove a file correctly (every cross-feature cascade included); it
357
- // just needs telling which unchanged files to treat as touched (forcedPaths, above).
358
544
  forcedPaths = presetForced;
359
545
  changed = (0, _signaturets.signatureDiff)(features !== null && features !== void 0 ? features : '', wantFeatures);
360
546
  console.error("sense: config change (".concat(changed, ") reparses only the files it affects"));
361
- return [
362
- 4,
363
- (0, _sharedts.setMeta)(conn, 'features', wantFeatures)
364
- ];
365
- case 12:
366
- _state.sent();
367
547
  return [
368
548
  3,
369
- 17
549
+ 16
370
550
  ];
371
551
  case 13:
372
552
  if (!(toggles !== null)) return [
373
553
  3,
374
- 15
554
+ 14
375
555
  ];
376
- // A feature turned off or on: reconcile.ts's activeFeatures skips a disabled feature's
377
- // hooks entirely, so its rows rot while off -- invalidateFeatures drops them and, for a
378
- // feature turning back on, fully re-derives across every indexed file rather than
379
- // trusting rows written before or during that window.
380
556
  featureToggles = toggles;
381
557
  changed1 = (0, _signaturets.signatureDiff)(features !== null && features !== void 0 ? features : '', wantFeatures);
382
558
  console.error("sense: config change (".concat(changed1, ") reparses only the feature it affects"));
383
- return [
384
- 4,
385
- (0, _sharedts.setMeta)(conn, 'features', wantFeatures)
386
- ];
387
- case 14:
388
- _state.sent();
389
559
  return [
390
560
  3,
391
- 17
561
+ 16
392
562
  ];
393
- case 15:
563
+ case 14:
394
564
  changed2 = (0, _signaturets.signatureDiff)(features !== null && features !== void 0 ? features : '', wantFeatures);
395
565
  console.error("sense: config change (".concat(changed2, ") rebuilds the index"));
396
566
  closed = true;
@@ -398,29 +568,29 @@ function connectWithDialect(cfg, dialect) {
398
568
  4,
399
569
  dialect.close(handle)
400
570
  ];
401
- case 16:
571
+ case 15:
402
572
  _state.sent();
403
573
  (0, _cachets.clearCache)(cfg);
404
574
  return [
405
575
  2,
406
- connectWithDialect(cfg, dialect)
576
+ connectForBuild(cfg, dialect, requirements)
407
577
  ];
408
- case 17:
578
+ case 16:
409
579
  return [
410
580
  4,
411
581
  dialect.ensureSchema(handle, conn, cfg)
412
582
  ];
413
- case 18:
583
+ case 17:
414
584
  _state.sent();
415
585
  if (!dialect.setDerivedBusyTimeout) return [
416
586
  3,
417
- 21
587
+ 20
418
588
  ];
419
589
  return [
420
590
  4,
421
591
  (0, _sharedts.getMeta)(conn, 'reconcile_max_ms')
422
592
  ];
423
- case 19:
593
+ case 18:
424
594
  recordedMaxMs = Number.apply(void 0, [
425
595
  (_ref1 = _state.sent()) !== null && _ref1 !== void 0 ? _ref1 : '0'
426
596
  ]);
@@ -428,60 +598,118 @@ function connectWithDialect(cfg, dialect) {
428
598
  4,
429
599
  dialect.setDerivedBusyTimeout(handle, conn, Math.min(Math.max(30000, 3 * recordedMaxMs), 600000))
430
600
  ];
431
- case 20:
601
+ case 19:
432
602
  _state.sent();
433
- _state.label = 21;
434
- case 21:
603
+ _state.label = 20;
604
+ case 20:
435
605
  if (!embedInvalidate) return [
436
606
  3,
437
- 23
607
+ 22
438
608
  ];
439
609
  return [
440
610
  4,
441
611
  builder.invalidate(embedInvalidate)
442
612
  ];
443
- case 22:
613
+ case 21:
444
614
  _tmp = _state.sent().parsed;
445
615
  return [
446
616
  3,
447
- 24
617
+ 23
448
618
  ];
449
- case 23:
619
+ case 22:
450
620
  _tmp = 0;
451
- _state.label = 24;
452
- case 24:
621
+ _state.label = 23;
622
+ case 23:
453
623
  embedParsed = _tmp;
454
624
  if (!featureToggles) return [
455
625
  3,
456
- 26
626
+ 25
457
627
  ];
458
628
  return [
459
629
  4,
460
630
  builder.invalidateFeatures(featureToggles)
461
631
  ];
462
- case 25:
632
+ case 24:
463
633
  _tmp1 = _state.sent().parsed;
464
634
  return [
465
635
  3,
466
- 27
636
+ 26
467
637
  ];
468
- case 26:
638
+ case 25:
469
639
  _tmp1 = 0;
470
- _state.label = 27;
471
- case 27:
640
+ _state.label = 26;
641
+ case 26:
472
642
  featureParsed = _tmp1;
643
+ if (!recoverIncomplete) return [
644
+ 3,
645
+ 28
646
+ ];
473
647
  return [
474
648
  4,
475
- builder.build(forcedPaths)
649
+ builder.recover()
650
+ ];
651
+ case 27:
652
+ _tmp2 = _state.sent();
653
+ return [
654
+ 3,
655
+ 30
476
656
  ];
477
657
  case 28:
478
- _ref2 = _state.sent(), parsed = _ref2.parsed, warnings = _ref2.warnings, stages = _ref2.stages;
479
- // Every open reconciles once and is done with it -- a watcher opens fresh per event instead of holding this connection (src/watch.ts).
480
658
  return [
481
659
  4,
482
- builder.close()
660
+ builder.build(forcedPaths)
483
661
  ];
484
662
  case 29:
663
+ _tmp2 = _state.sent();
664
+ _state.label = 30;
665
+ case 30:
666
+ _ref2 = _tmp2, parsed = _ref2.parsed, warnings = _ref2.warnings, stages = _ref2.stages;
667
+ return [
668
+ 4,
669
+ (0, _transactionts.withTransaction)(conn, function() {
670
+ return _async_to_generator(function() {
671
+ return _ts_generator(this, function(_state) {
672
+ switch(_state.label){
673
+ case 0:
674
+ return [
675
+ 4,
676
+ (0, _sharedts.setMeta)(conn, 'features', wantFeatures)
677
+ ];
678
+ case 1:
679
+ _state.sent();
680
+ return [
681
+ 4,
682
+ (0, _sharedts.setMeta)(conn, CORE_READY_META_KEY, '1')
683
+ ];
684
+ case 2:
685
+ _state.sent();
686
+ return [
687
+ 2
688
+ ];
689
+ }
690
+ });
691
+ })();
692
+ })
693
+ ];
694
+ case 31:
695
+ _state.sent();
696
+ if (!requirements.has('lexical')) return [
697
+ 3,
698
+ 33
699
+ ];
700
+ return [
701
+ 4,
702
+ (_dialect_prepareLexical = dialect.prepareLexical) === null || _dialect_prepareLexical === void 0 ? void 0 : _dialect_prepareLexical.call(dialect, conn)
703
+ ];
704
+ case 32:
705
+ _state.sent();
706
+ _state.label = 33;
707
+ case 33:
708
+ return [
709
+ 4,
710
+ builder.close()
711
+ ];
712
+ case 34:
485
713
  _state.sent();
486
714
  return [
487
715
  2,
@@ -492,31 +720,32 @@ function connectWithDialect(cfg, dialect) {
492
720
  dbPath: dbPath,
493
721
  parsed: parsed + embedParsed + featureParsed,
494
722
  warnings: warnings,
495
- stages: stages
723
+ stages: stages,
724
+ observational: false
496
725
  }
497
726
  ];
498
- case 30:
727
+ case 35:
499
728
  err = _state.sent();
500
729
  return [
501
730
  4,
502
731
  builder.close()
503
732
  ];
504
- case 31:
733
+ case 36:
505
734
  _state.sent();
506
735
  if (!!closed) return [
507
736
  3,
508
- 33
737
+ 38
509
738
  ];
510
739
  return [
511
740
  4,
512
741
  dialect.close(handle)
513
742
  ];
514
- case 32:
743
+ case 37:
515
744
  _state.sent();
516
- _state.label = 33;
517
- case 33:
745
+ _state.label = 38;
746
+ case 38:
518
747
  throw err;
519
- case 34:
748
+ case 39:
520
749
  return [
521
750
  2
522
751
  ];
@@ -524,42 +753,164 @@ function connectWithDialect(cfg, dialect) {
524
753
  });
525
754
  })();
526
755
  }
527
- function openWithDialect(cfg, dialect) {
756
+ function prepareDocumentEmbeddings(store, cfg, allowed) {
528
757
  return _async_to_generator(function() {
529
- var _ref, handle, conn, resolvedCfg, dbPath, parsed, warnings, stages, store;
758
+ var preparedSignature, actualSignature, changedKeys, update, result;
530
759
  return _ts_generator(this, function(_state) {
531
760
  switch(_state.label){
532
761
  case 0:
533
- // `baseDir` was the original public open() input. Keep direct API callers working while
534
- // making the two ownership paths explicit for every internal operation.
535
- if (!cfg.rootDir) {
536
- if (!cfg.baseDir) throw new _errorsts.SenseError('CONFIG_INVALID', 'open requires rootDir (or legacy baseDir)');
537
- cfg.rootDir = cfg.baseDir;
762
+ return [
763
+ 4,
764
+ (0, _sharedts.getMeta)(store, 'features')
765
+ ];
766
+ case 1:
767
+ preparedSignature = _state.sent();
768
+ return [
769
+ 4,
770
+ (0, _queryts.embedPending)(store, cfg, allowed)
771
+ ];
772
+ case 2:
773
+ _state.sent();
774
+ actualSignature = (0, _indexts.featureSignature)(cfg, _indexts1.FEATURES);
775
+ if (preparedSignature === actualSignature) return [
776
+ 2
777
+ ];
778
+ changedKeys = (0, _signaturets.changedSignatureKeys)(preparedSignature !== null && preparedSignature !== void 0 ? preparedSignature : '', actualSignature);
779
+ if (preparedSignature === null || changedKeys.size !== 1 || !changedKeys.has('embed') || !(0, _signaturets.embedIdentityAdopted)(preparedSignature, actualSignature)) {
780
+ throw notReady('the index configuration changed while vectors were being prepared');
538
781
  }
539
- if (!cfg.configDir) cfg.configDir = cfg.rootDir;
540
782
  return [
541
783
  4,
542
- connectWithDialect(cfg, dialect)
784
+ store.prepare('UPDATE meta SET value = ? WHERE key = ? AND value = ?')
785
+ ];
786
+ case 3:
787
+ update = _state.sent();
788
+ return [
789
+ 4,
790
+ update.run(actualSignature, 'features', preparedSignature)
791
+ ];
792
+ case 4:
793
+ result = _state.sent();
794
+ if (Number(result.changes) !== 1) throw notReady('another build changed the index configuration while vectors were being prepared');
795
+ return [
796
+ 2
797
+ ];
798
+ }
799
+ });
800
+ })();
801
+ }
802
+ function openWithDialect(_0, _1) {
803
+ return _async_to_generator(function(input, dialect) {
804
+ var options, _options_requirements, cfg, buildEnabled, defaultRequirements, requirements, connected, _tmp, store, err;
805
+ var _arguments = arguments;
806
+ return _ts_generator(this, function(_state) {
807
+ switch(_state.label){
808
+ case 0:
809
+ options = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
810
+ cfg = normaliseConfig(input);
811
+ buildEnabled = options.build !== false;
812
+ defaultRequirements = new Set(buildEnabled ? [
813
+ 'core',
814
+ 'lexical'
815
+ ] : [
816
+ 'core'
817
+ ]);
818
+ if (buildEnabled && (0, _indexts.anyPresetEmbeds)(cfg)) defaultRequirements.add('vectors');
819
+ requirements = (_options_requirements = options.requirements) !== null && _options_requirements !== void 0 ? _options_requirements : defaultRequirements;
820
+ if (!buildEnabled) return [
821
+ 3,
822
+ 2
823
+ ];
824
+ return [
825
+ 4,
826
+ connectForBuild(cfg, dialect, requirements)
543
827
  ];
544
828
  case 1:
545
- _ref = _state.sent(), handle = _ref.handle, conn = _ref.conn, resolvedCfg = _ref.cfg, dbPath = _ref.dbPath, parsed = _ref.parsed, warnings = _ref.warnings, stages = _ref.stages;
546
- store = dialect.createStore(handle, conn, resolvedCfg);
547
- // reconcile ran before this object existed, so its chunk text is keyed by the connection.
548
- (0, _handoffts.rekeyChunkText)(conn, store);
829
+ _tmp = _state.sent();
830
+ return [
831
+ 3,
832
+ 4
833
+ ];
834
+ case 2:
835
+ return [
836
+ 4,
837
+ connectExisting(cfg, dialect, requirements)
838
+ ];
839
+ case 3:
840
+ _tmp = _state.sent();
841
+ _state.label = 4;
842
+ case 4:
843
+ connected = _tmp;
844
+ _state.label = 5;
845
+ case 5:
846
+ _state.trys.push([
847
+ 5,
848
+ 8,
849
+ ,
850
+ 13
851
+ ]);
852
+ store = dialect.createStore(connected.handle, connected.conn, connected.cfg, {
853
+ observational: connected.observational
854
+ });
855
+ (0, _handoffts.rekeyChunkText)(connected.conn, store);
856
+ if (!(requirements.has('vectors') && buildEnabled)) return [
857
+ 3,
858
+ 7
859
+ ];
860
+ return [
861
+ 4,
862
+ prepareDocumentEmbeddings(store, connected.cfg)
863
+ ];
864
+ case 6:
865
+ _state.sent();
866
+ _state.label = 7;
867
+ case 7:
549
868
  return [
550
869
  2,
551
870
  {
552
871
  store: store,
553
- cfg: resolvedCfg,
554
- dbPath: dbPath,
555
- parsed: parsed,
556
- warnings: warnings,
557
- stages: stages
872
+ cfg: connected.cfg,
873
+ dbPath: connected.dbPath,
874
+ parsed: connected.parsed,
875
+ warnings: connected.warnings,
876
+ stages: connected.stages
558
877
  }
559
878
  ];
879
+ case 8:
880
+ err = _state.sent();
881
+ if (!store) return [
882
+ 3,
883
+ 10
884
+ ];
885
+ return [
886
+ 4,
887
+ store.close()
888
+ ];
889
+ case 9:
890
+ _state.sent();
891
+ return [
892
+ 3,
893
+ 12
894
+ ];
895
+ case 10:
896
+ return [
897
+ 4,
898
+ dialect.close(connected.handle, {
899
+ observational: connected.observational
900
+ })
901
+ ];
902
+ case 11:
903
+ _state.sent();
904
+ _state.label = 12;
905
+ case 12:
906
+ throw err;
907
+ case 13:
908
+ return [
909
+ 2
910
+ ];
560
911
  }
561
912
  });
562
- })();
913
+ }).apply(this, arguments);
563
914
  }
564
915
  function docCount(store) {
565
916
  return _async_to_generator(function() {