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.
- package/README.md +20 -11
- package/dist/cjs/cli/build.d.cts +3 -0
- package/dist/cjs/cli/build.d.ts +3 -0
- package/dist/cjs/cli/build.js +195 -0
- package/dist/cjs/cli/build.js.map +1 -0
- package/dist/cjs/cli/index.d.cts +7 -6
- package/dist/cjs/cli/index.d.ts +7 -6
- package/dist/cjs/cli/index.js +12 -6
- package/dist/cjs/cli/index.js.map +1 -1
- package/dist/cjs/cli/init.js +2 -2
- package/dist/cjs/cli/init.js.map +1 -1
- package/dist/cjs/cli/map.js +7 -2
- package/dist/cjs/cli/map.js.map +1 -1
- package/dist/cjs/cli/named.js +63 -21
- package/dist/cjs/cli/named.js.map +1 -1
- package/dist/cjs/cli/path.js +7 -2
- package/dist/cjs/cli/path.js.map +1 -1
- package/dist/cjs/cli/peek.js +7 -2
- package/dist/cjs/cli/peek.js.map +1 -1
- package/dist/cjs/cli/related.js +55 -6
- package/dist/cjs/cli/related.js.map +1 -1
- package/dist/cjs/cli/search.js +54 -15
- package/dist/cjs/cli/search.js.map +1 -1
- package/dist/cjs/cli/shared.d.cts +9 -3
- package/dist/cjs/cli/shared.d.ts +9 -3
- package/dist/cjs/cli/shared.js +109 -74
- package/dist/cjs/cli/shared.js.map +1 -1
- package/dist/cjs/cli/sql.js +8 -3
- package/dist/cjs/cli/sql.js.map +1 -1
- package/dist/cjs/cli/status.js +142 -50
- package/dist/cjs/cli/status.js.map +1 -1
- package/dist/cjs/cli/types.d.cts +4 -2
- package/dist/cjs/cli/types.d.ts +4 -2
- package/dist/cjs/cli.js +10 -4
- package/dist/cjs/cli.js.map +1 -1
- package/dist/cjs/commands/map.js +10 -6
- package/dist/cjs/commands/map.js.map +1 -1
- package/dist/cjs/commands/peek.js +10 -6
- package/dist/cjs/commands/peek.js.map +1 -1
- package/dist/cjs/commands/related.d.cts +1 -0
- package/dist/cjs/commands/related.d.ts +1 -0
- package/dist/cjs/commands/related.js +56 -21
- package/dist/cjs/commands/related.js.map +1 -1
- package/dist/cjs/commands/scope.js +1 -1
- package/dist/cjs/commands/scope.js.map +1 -1
- package/dist/cjs/commands/search.js +102 -84
- package/dist/cjs/commands/search.js.map +1 -1
- package/dist/cjs/config/index.d.cts +1 -1
- package/dist/cjs/config/index.d.ts +1 -1
- package/dist/cjs/config/index.js.map +1 -1
- package/dist/cjs/config/load.d.cts +6 -1
- package/dist/cjs/config/load.d.ts +6 -1
- package/dist/cjs/config/load.js +38 -1
- package/dist/cjs/config/load.js.map +1 -1
- package/dist/cjs/config/types.d.cts +2 -1
- package/dist/cjs/config/types.d.ts +2 -1
- package/dist/cjs/config/types.js +1 -1
- package/dist/cjs/config/types.js.map +1 -1
- package/dist/cjs/config/validate.js +20 -0
- package/dist/cjs/config/validate.js.map +1 -1
- package/dist/cjs/embed/query.d.cts +2 -1
- package/dist/cjs/embed/query.d.ts +2 -1
- package/dist/cjs/embed/query.js +186 -109
- package/dist/cjs/embed/query.js.map +1 -1
- package/dist/cjs/errors.d.cts +1 -1
- package/dist/cjs/errors.d.ts +1 -1
- package/dist/cjs/errors.js.map +1 -1
- package/dist/cjs/features/embed.js.map +1 -1
- package/dist/cjs/graph/traverse.js +11 -6
- package/dist/cjs/graph/traverse.js.map +1 -1
- package/dist/cjs/index.d.cts +3 -3
- package/dist/cjs/index.d.ts +3 -3
- package/dist/cjs/index.js +3 -0
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/lib/atomic-write.js +20 -6
- package/dist/cjs/lib/atomic-write.js.map +1 -1
- package/dist/cjs/lib/serial-query.d.cts +1 -0
- package/dist/cjs/lib/serial-query.d.ts +1 -0
- package/dist/cjs/lib/serial-query.js +22 -0
- package/dist/cjs/lib/serial-query.js.map +1 -0
- package/dist/cjs/scan/index.d.cts +5 -0
- package/dist/cjs/scan/index.d.ts +5 -0
- package/dist/cjs/scan/index.js +12 -4
- package/dist/cjs/scan/index.js.map +1 -1
- package/dist/cjs/scan/pool.d.cts +5 -0
- package/dist/cjs/scan/pool.d.ts +5 -0
- package/dist/cjs/scan/pool.js +167 -55
- package/dist/cjs/scan/pool.js.map +1 -1
- package/dist/cjs/store/builder.d.cts +6 -1
- package/dist/cjs/store/builder.d.ts +6 -1
- package/dist/cjs/store/builder.js +135 -5
- package/dist/cjs/store/builder.js.map +1 -1
- package/dist/cjs/store/duckdb/lexical.d.cts +2 -0
- package/dist/cjs/store/duckdb/lexical.d.ts +2 -0
- package/dist/cjs/store/duckdb/lexical.js +139 -7
- package/dist/cjs/store/duckdb/lexical.js.map +1 -1
- package/dist/cjs/store/duckdb/open.d.cts +3 -3
- package/dist/cjs/store/duckdb/open.d.ts +3 -3
- package/dist/cjs/store/duckdb/open.js +53 -41
- package/dist/cjs/store/duckdb/open.js.map +1 -1
- package/dist/cjs/store/duckdb/reconcile.js +2 -2
- package/dist/cjs/store/duckdb/reconcile.js.map +1 -1
- package/dist/cjs/store/index.d.cts +23 -4
- package/dist/cjs/store/index.d.ts +23 -4
- package/dist/cjs/store/index.js +224 -15
- package/dist/cjs/store/index.js.map +1 -1
- package/dist/cjs/store/open.d.cts +9 -1
- package/dist/cjs/store/open.d.ts +9 -1
- package/dist/cjs/store/open.js +479 -128
- package/dist/cjs/store/open.js.map +1 -1
- package/dist/cjs/store/reconcile.js +93 -63
- package/dist/cjs/store/reconcile.js.map +1 -1
- package/dist/cjs/store/sqlite/open.d.cts +3 -3
- package/dist/cjs/store/sqlite/open.d.ts +3 -3
- package/dist/cjs/store/sqlite/open.js +44 -36
- package/dist/cjs/store/sqlite/open.js.map +1 -1
- package/dist/cjs/store/turso/open.d.cts +3 -3
- package/dist/cjs/store/turso/open.d.ts +3 -3
- package/dist/cjs/store/turso/open.js +83 -66
- package/dist/cjs/store/turso/open.js.map +1 -1
- package/dist/cjs/store/turso/store.d.cts +3 -1
- package/dist/cjs/store/turso/store.d.ts +3 -1
- package/dist/cjs/store/turso/store.js +46 -31
- package/dist/cjs/store/turso/store.js.map +1 -1
- package/dist/cjs/store/types.d.cts +12 -3
- package/dist/cjs/store/types.d.ts +12 -3
- package/dist/cjs/store/types.js.map +1 -1
- package/dist/cjs/watch.js +155 -35
- package/dist/cjs/watch.js.map +1 -1
- package/dist/esm/cli/build.d.ts +3 -0
- package/dist/esm/cli/build.js +18 -0
- package/dist/esm/cli/build.js.map +1 -0
- package/dist/esm/cli/index.d.ts +7 -6
- package/dist/esm/cli/index.js +8 -6
- package/dist/esm/cli/index.js.map +1 -1
- package/dist/esm/cli/init.js +2 -2
- package/dist/esm/cli/init.js.map +1 -1
- package/dist/esm/cli/map.js +8 -2
- package/dist/esm/cli/map.js.map +1 -1
- package/dist/esm/cli/named.js +38 -14
- package/dist/esm/cli/named.js.map +1 -1
- package/dist/esm/cli/path.js +8 -2
- package/dist/esm/cli/path.js.map +1 -1
- package/dist/esm/cli/peek.js +8 -2
- package/dist/esm/cli/peek.js.map +1 -1
- package/dist/esm/cli/related.js +21 -3
- package/dist/esm/cli/related.js.map +1 -1
- package/dist/esm/cli/search.js +28 -7
- package/dist/esm/cli/search.js.map +1 -1
- package/dist/esm/cli/shared.d.ts +9 -3
- package/dist/esm/cli/shared.js +44 -24
- package/dist/esm/cli/shared.js.map +1 -1
- package/dist/esm/cli/sql.js +8 -2
- package/dist/esm/cli/sql.js.map +1 -1
- package/dist/esm/cli/status.js +166 -111
- package/dist/esm/cli/status.js.map +1 -1
- package/dist/esm/cli/types.d.ts +4 -2
- package/dist/esm/cli/types.js.map +1 -1
- package/dist/esm/cli.js +9 -4
- package/dist/esm/cli.js.map +1 -1
- package/dist/esm/commands/map.js +5 -1
- package/dist/esm/commands/map.js.map +1 -1
- package/dist/esm/commands/peek.js +5 -1
- package/dist/esm/commands/peek.js.map +1 -1
- package/dist/esm/commands/related.d.ts +1 -0
- package/dist/esm/commands/related.js +19 -10
- package/dist/esm/commands/related.js.map +1 -1
- package/dist/esm/commands/scope.js +1 -1
- package/dist/esm/commands/scope.js.map +1 -1
- package/dist/esm/commands/search.js +11 -10
- package/dist/esm/commands/search.js.map +1 -1
- package/dist/esm/config/index.d.ts +1 -1
- package/dist/esm/config/index.js.map +1 -1
- package/dist/esm/config/load.d.ts +6 -1
- package/dist/esm/config/load.js +32 -3
- package/dist/esm/config/load.js.map +1 -1
- package/dist/esm/config/types.d.ts +2 -1
- package/dist/esm/config/types.js +1 -1
- package/dist/esm/config/types.js.map +1 -1
- package/dist/esm/config/validate.js +20 -0
- package/dist/esm/config/validate.js.map +1 -1
- package/dist/esm/embed/query.d.ts +2 -1
- package/dist/esm/embed/query.js +40 -34
- package/dist/esm/embed/query.js.map +1 -1
- package/dist/esm/errors.d.ts +1 -1
- package/dist/esm/errors.js.map +1 -1
- package/dist/esm/features/embed.js.map +1 -1
- package/dist/esm/graph/traverse.js +5 -1
- package/dist/esm/graph/traverse.js.map +1 -1
- package/dist/esm/index.d.ts +3 -3
- package/dist/esm/index.js +1 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/lib/atomic-write.js +14 -6
- package/dist/esm/lib/atomic-write.js.map +1 -1
- package/dist/esm/lib/serial-query.d.ts +1 -0
- package/dist/esm/lib/serial-query.js +13 -0
- package/dist/esm/lib/serial-query.js.map +1 -0
- package/dist/esm/scan/index.d.ts +5 -0
- package/dist/esm/scan/index.js +7 -3
- package/dist/esm/scan/index.js.map +1 -1
- package/dist/esm/scan/pool.d.ts +5 -0
- package/dist/esm/scan/pool.js +41 -16
- package/dist/esm/scan/pool.js.map +1 -1
- package/dist/esm/store/builder.d.ts +6 -1
- package/dist/esm/store/builder.js +19 -0
- package/dist/esm/store/builder.js.map +1 -1
- package/dist/esm/store/duckdb/lexical.d.ts +2 -0
- package/dist/esm/store/duckdb/lexical.js +32 -4
- package/dist/esm/store/duckdb/lexical.js.map +1 -1
- package/dist/esm/store/duckdb/open.d.ts +3 -3
- package/dist/esm/store/duckdb/open.js +13 -6
- package/dist/esm/store/duckdb/open.js.map +1 -1
- package/dist/esm/store/duckdb/reconcile.js +2 -2
- package/dist/esm/store/duckdb/reconcile.js.map +1 -1
- package/dist/esm/store/index.d.ts +23 -4
- package/dist/esm/store/index.js +80 -15
- package/dist/esm/store/index.js.map +1 -1
- package/dist/esm/store/open.d.ts +9 -1
- package/dist/esm/store/open.js +175 -84
- package/dist/esm/store/open.js.map +1 -1
- package/dist/esm/store/reconcile.js +12 -0
- package/dist/esm/store/reconcile.js.map +1 -1
- package/dist/esm/store/sqlite/open.d.ts +3 -3
- package/dist/esm/store/sqlite/open.js +9 -6
- package/dist/esm/store/sqlite/open.js.map +1 -1
- package/dist/esm/store/turso/open.d.ts +3 -3
- package/dist/esm/store/turso/open.js +14 -10
- package/dist/esm/store/turso/open.js.map +1 -1
- package/dist/esm/store/turso/store.d.ts +3 -1
- package/dist/esm/store/turso/store.js +5 -1
- package/dist/esm/store/turso/store.js.map +1 -1
- package/dist/esm/store/types.d.ts +12 -3
- package/dist/esm/store/types.js.map +1 -1
- package/dist/esm/watch.js +57 -19
- package/dist/esm/watch.js.map +1 -1
- package/package.json +1 -1
- package/schema.json +7 -2
- package/skills/sense/SKILL.md +3 -3
- package/skills/sense-bases/SKILL.md +1 -2
- package/skills/sense-setup/SKILL.md +1 -1
- package/skills/sense-setup/references/embeddings.md +1 -1
- package/skills/sense-setup/references/store-benchmarks.md +6 -6
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/scan/pool.ts"],"sourcesContent":["import { createRequire } from 'node:module';\n// Type-only: erased at build, but keeps depcheck's usage check satisfied for the tier-2\n// `_require` below (see coding-standards' deferral tiers).\nimport type * as TinypoolNS from 'tinypool';\nimport type { Config } from '../config/index.ts';\nimport type { Feature } from '../features/types.ts';\nimport { resolveWorkerFile } from '../lib/worker-file.ts';\nimport type { ParsedDoc } from '../scan/index.ts';\nimport type { ParseTask, ParseTaskResult, ParseWorkerData } from '../workers/parse.ts';\nimport type { FileStat } from './list.ts';\nimport { reviveError } from './worker-error.ts';\n\n// Tinypool is ESM-only; our floor (>=22.20) has native require(esm), so the tier-2 house deferral reaches it.\nconst _require = typeof require === 'undefined' ? createRequire(import.meta.url) : require;\n\n// parseMs is worker-side only (see workers/parse.ts); absent on the serial path.\nexport type FileResult = { doc: ParsedDoc; warnings: string[]; parseMs?: number };\n\n//
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/scan/pool.ts"],"sourcesContent":["import { createRequire } from 'node:module';\nimport { isDeepStrictEqual } from 'node:util';\n// Type-only: erased at build, but keeps depcheck's usage check satisfied for the tier-2\n// `_require` below (see coding-standards' deferral tiers).\nimport type * as TinypoolNS from 'tinypool';\nimport type { Config } from '../config/index.ts';\nimport type { Feature } from '../features/types.ts';\nimport { resolveWorkerFile } from '../lib/worker-file.ts';\nimport type { ParsedDoc } from '../scan/index.ts';\nimport type { ParseTask, ParseTaskResult, ParseWorkerData } from '../workers/parse.ts';\nimport type { FileStat } from './list.ts';\nimport { reviveError } from './worker-error.ts';\n\n// Tinypool is ESM-only; our floor (>=22.20) has native require(esm), so the tier-2 house deferral reaches it.\nconst _require = typeof require === 'undefined' ? createRequire(import.meta.url) : require;\n\n// parseMs is worker-side only (see workers/parse.ts); absent on the serial path.\nexport type FileResult = { doc: ParsedDoc; warnings: string[]; parseMs?: number };\n\n// Created lazily and reused while dispatch context stays equivalent. A builder owns one instance\n// for its lifetime instead of paying pool startup for unchanged reconciles.\nexport class ParsePool {\n private pool: TinypoolNS.Tinypool | undefined;\n private workerData: ParseWorkerData | undefined;\n private operation: Promise<void> = Promise.resolve();\n // Tinypools this instance has constructed. Repeated equivalent dispatches leave this unchanged;\n // a context change or close followed by run constructs another pool.\n poolsCreated = 0;\n\n private enqueue<T>(operation: () => Promise<T>): Promise<T> {\n const result = this.operation.then(operation);\n this.operation = result.then(\n () => undefined,\n () => undefined\n );\n return result;\n }\n\n private async ensure(workerData: ParseWorkerData, maxWorkers: number): Promise<TinypoolNS.Tinypool> {\n if (this.pool && !isDeepStrictEqual(this.workerData, workerData)) await this.destroy();\n if (!this.pool) {\n const { Tinypool } = _require('tinypool') as typeof TinypoolNS;\n this.pool = new Tinypool({ filename: resolveWorkerFile('parse'), minThreads: maxWorkers, maxThreads: maxWorkers, workerData });\n this.workerData = workerData;\n this.poolsCreated++;\n }\n return this.pool;\n }\n\n // Never the tree: a worker task carries one FileStat and returns only what parseFile returns --\n // extracted text and feature values, never the token tree.\n run(files: FileStat[], features: Feature[], cfg: Config, onParsed: ((done: number) => void) | undefined, maxWorkers: number): Promise<FileResult[]> {\n // Snapshot at invocation so caller mutation cannot change queued work or its reuse baseline.\n const workerData: ParseWorkerData = { cfg: structuredClone(cfg), featureNames: [...new Set(features.map((feature) => feature.name))].sort() };\n return this.enqueue(() => this.dispatch(files, workerData, onParsed, maxWorkers));\n }\n\n private async dispatch(files: FileStat[], workerData: ParseWorkerData, onParsed: ((done: number) => void) | undefined, maxWorkers: number): Promise<FileResult[]> {\n const pool = await this.ensure(workerData, maxWorkers);\n let done = 0;\n const settled = await Promise.allSettled(\n files.map(async (file): Promise<FileResult> => {\n const result = (await pool.run(file as ParseTask)) as ParseTaskResult;\n if (!result.ok) throw reviveError(result.error);\n onParsed?.(++done);\n return { doc: result.doc, warnings: result.warnings, parseMs: result.parseMs };\n })\n );\n const results: FileResult[] = [];\n const failures: unknown[] = [];\n for (const result of settled) {\n if (result.status === 'fulfilled') results.push(result.value);\n else failures.push(result.reason);\n }\n if (failures.length === 1) throw failures[0];\n if (failures.length > 1) throw new AggregateError(failures, `${failures.length} parse tasks failed`);\n // allSettled preserves input order, which downstream first-seen column order depends on.\n return results;\n }\n\n private async destroy(): Promise<void> {\n if (!this.pool) return;\n const pool = this.pool;\n this.pool = undefined;\n this.workerData = undefined;\n await pool.destroy();\n }\n\n // A pool never created costs nothing to destroy. Queuing lets active dispatches drain first.\n close(): Promise<void> {\n return this.enqueue(() => this.destroy());\n }\n}\n"],"names":["ParsePool","_require","require","createRequire","operation","Promise","resolve","poolsCreated","enqueue","result","then","undefined","ensure","workerData","maxWorkers","Tinypool","pool","isDeepStrictEqual","destroy","filename","resolveWorkerFile","minThreads","maxThreads","run","files","features","cfg","onParsed","structuredClone","featureNames","Set","map","feature","name","sort","dispatch","done","settled","results","failures","allSettled","file","ok","reviveError","error","doc","warnings","parseMs","status","push","value","reason","length","AggregateError","close"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type Config } from '../config/index.js';
|
|
2
2
|
import type { EmbedChangeKind } from './embed-scope.js';
|
|
3
3
|
import type { FeatureToggle } from './feature-scope.js';
|
|
4
4
|
import { type ReconcilePaths } from './reconcile.js';
|
|
@@ -10,6 +10,11 @@ export interface Builder {
|
|
|
10
10
|
warnings: string[];
|
|
11
11
|
stages: Stages;
|
|
12
12
|
}>;
|
|
13
|
+
recover(): Promise<{
|
|
14
|
+
parsed: number;
|
|
15
|
+
warnings: string[];
|
|
16
|
+
stages: Stages;
|
|
17
|
+
}>;
|
|
13
18
|
invalidate(kind: EmbedChangeKind): Promise<{
|
|
14
19
|
parsed: number;
|
|
15
20
|
}>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type Config } from '../config/index.js';
|
|
2
2
|
import type { EmbedChangeKind } from './embed-scope.js';
|
|
3
3
|
import type { FeatureToggle } from './feature-scope.js';
|
|
4
4
|
import { type ReconcilePaths } from './reconcile.js';
|
|
@@ -10,6 +10,11 @@ export interface Builder {
|
|
|
10
10
|
warnings: string[];
|
|
11
11
|
stages: Stages;
|
|
12
12
|
}>;
|
|
13
|
+
recover(): Promise<{
|
|
14
|
+
parsed: number;
|
|
15
|
+
warnings: string[];
|
|
16
|
+
stages: Stages;
|
|
17
|
+
}>;
|
|
13
18
|
invalidate(kind: EmbedChangeKind): Promise<{
|
|
14
19
|
parsed: number;
|
|
15
20
|
}>;
|
|
@@ -8,10 +8,11 @@ Object.defineProperty(exports, "createBuilder", {
|
|
|
8
8
|
return createBuilder;
|
|
9
9
|
}
|
|
10
10
|
});
|
|
11
|
+
var _indexts = require("../config/index.js");
|
|
11
12
|
var _embedts = require("../features/embed.js");
|
|
12
|
-
var
|
|
13
|
+
var _indexts1 = require("../features/index.js");
|
|
13
14
|
var _rankts = require("../features/rank.js");
|
|
14
|
-
var
|
|
15
|
+
var _indexts2 = require("../scan/index.js");
|
|
15
16
|
var _poolts = require("../scan/pool.js");
|
|
16
17
|
var _reparsets = require("../scan/reparse.js");
|
|
17
18
|
var _featurescopets = require("./feature-scope.js");
|
|
@@ -196,7 +197,7 @@ function rebuildEmbeddings(conn, cfg, baseDir, dialect, pool) {
|
|
|
196
197
|
]));
|
|
197
198
|
// A file added since the last build has no row yet; leaving it for build() to insert avoids a
|
|
198
199
|
// primary-key collision between this INSERT and build()'s own insert for the same new file.
|
|
199
|
-
files = (0,
|
|
200
|
+
files = (0, _indexts2.listFiles)(cfg, baseDir).filter(function(f) {
|
|
200
201
|
return f.embed && existingPaths.has(f.relPath);
|
|
201
202
|
});
|
|
202
203
|
if (files.length === 0) return [
|
|
@@ -280,7 +281,7 @@ function invalidateFeatureTable(conn, cfg, baseDir, dialect, pool, toggle) {
|
|
|
280
281
|
switch(_state.label){
|
|
281
282
|
case 0:
|
|
282
283
|
table = _featurescopets.NARROW_FEATURE_TABLE[toggle.name];
|
|
283
|
-
feature =
|
|
284
|
+
feature = _indexts1.FEATURES.find(function(f) {
|
|
284
285
|
return f.name === toggle.name;
|
|
285
286
|
});
|
|
286
287
|
if (!feature) throw new Error('invalidateFeatureTable: no registered feature named "'.concat(toggle.name, '"'));
|
|
@@ -303,7 +304,7 @@ function invalidateFeatureTable(conn, cfg, baseDir, dialect, pool, toggle) {
|
|
|
303
304
|
}
|
|
304
305
|
];
|
|
305
306
|
case 2:
|
|
306
|
-
files = (0,
|
|
307
|
+
files = (0, _indexts2.listFiles)(cfg, baseDir);
|
|
307
308
|
return [
|
|
308
309
|
4,
|
|
309
310
|
(0, _reparsets.reparseFiles)(files, [
|
|
@@ -594,12 +595,141 @@ function invalidateFeatureToggles(conn, cfg, baseDir, dialect, pool, toggles) {
|
|
|
594
595
|
});
|
|
595
596
|
})();
|
|
596
597
|
}
|
|
598
|
+
function recoverIncomplete(conn, cfg, paths, dialect, pool) {
|
|
599
|
+
return _async_to_generator(function() {
|
|
600
|
+
var disabled, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, feature, err, toggles, embeddingsTable, forcedPaths;
|
|
601
|
+
return _ts_generator(this, function(_state) {
|
|
602
|
+
switch(_state.label){
|
|
603
|
+
case 0:
|
|
604
|
+
disabled = _indexts1.FEATURES.filter(function(feature) {
|
|
605
|
+
return !(0, _indexts.featureEnabled)(cfg, feature.name);
|
|
606
|
+
});
|
|
607
|
+
_iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
608
|
+
_state.label = 1;
|
|
609
|
+
case 1:
|
|
610
|
+
_state.trys.push([
|
|
611
|
+
1,
|
|
612
|
+
6,
|
|
613
|
+
7,
|
|
614
|
+
8
|
|
615
|
+
]);
|
|
616
|
+
_iterator = disabled[Symbol.iterator]();
|
|
617
|
+
_state.label = 2;
|
|
618
|
+
case 2:
|
|
619
|
+
if (!!(_iteratorNormalCompletion = (_step = _iterator.next()).done)) return [
|
|
620
|
+
3,
|
|
621
|
+
5
|
|
622
|
+
];
|
|
623
|
+
feature = _step.value;
|
|
624
|
+
if (!(feature.name !== 'embed')) return [
|
|
625
|
+
3,
|
|
626
|
+
4
|
|
627
|
+
];
|
|
628
|
+
return [
|
|
629
|
+
4,
|
|
630
|
+
feature.schema(conn)
|
|
631
|
+
];
|
|
632
|
+
case 3:
|
|
633
|
+
_state.sent();
|
|
634
|
+
_state.label = 4;
|
|
635
|
+
case 4:
|
|
636
|
+
_iteratorNormalCompletion = true;
|
|
637
|
+
return [
|
|
638
|
+
3,
|
|
639
|
+
2
|
|
640
|
+
];
|
|
641
|
+
case 5:
|
|
642
|
+
return [
|
|
643
|
+
3,
|
|
644
|
+
8
|
|
645
|
+
];
|
|
646
|
+
case 6:
|
|
647
|
+
err = _state.sent();
|
|
648
|
+
_didIteratorError = true;
|
|
649
|
+
_iteratorError = err;
|
|
650
|
+
return [
|
|
651
|
+
3,
|
|
652
|
+
8
|
|
653
|
+
];
|
|
654
|
+
case 7:
|
|
655
|
+
try {
|
|
656
|
+
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
657
|
+
_iterator.return();
|
|
658
|
+
}
|
|
659
|
+
} finally{
|
|
660
|
+
if (_didIteratorError) {
|
|
661
|
+
throw _iteratorError;
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
return [
|
|
665
|
+
7
|
|
666
|
+
];
|
|
667
|
+
case 8:
|
|
668
|
+
toggles = disabled.filter(function(feature) {
|
|
669
|
+
return feature.name !== 'embed';
|
|
670
|
+
}).map(function(feature) {
|
|
671
|
+
return {
|
|
672
|
+
name: feature.name,
|
|
673
|
+
turnedOn: false
|
|
674
|
+
};
|
|
675
|
+
});
|
|
676
|
+
return [
|
|
677
|
+
4,
|
|
678
|
+
invalidateFeatureToggles(conn, cfg, paths.rootDir, dialect, pool, toggles)
|
|
679
|
+
];
|
|
680
|
+
case 9:
|
|
681
|
+
_state.sent();
|
|
682
|
+
if (!disabled.some(function(feature) {
|
|
683
|
+
return feature.name === 'embed';
|
|
684
|
+
})) return [
|
|
685
|
+
3,
|
|
686
|
+
13
|
|
687
|
+
];
|
|
688
|
+
return [
|
|
689
|
+
4,
|
|
690
|
+
conn.prepare("SELECT name FROM sqlite_master WHERE type = 'table' AND name = 'embeddings'")
|
|
691
|
+
];
|
|
692
|
+
case 10:
|
|
693
|
+
embeddingsTable = _state.sent();
|
|
694
|
+
return [
|
|
695
|
+
4,
|
|
696
|
+
embeddingsTable.all()
|
|
697
|
+
];
|
|
698
|
+
case 11:
|
|
699
|
+
if (!(_state.sent().length > 0)) return [
|
|
700
|
+
3,
|
|
701
|
+
13
|
|
702
|
+
];
|
|
703
|
+
return [
|
|
704
|
+
4,
|
|
705
|
+
(0, _transactionts.withTransaction)(conn, function() {
|
|
706
|
+
return conn.exec('DELETE FROM embeddings');
|
|
707
|
+
}, dialect.beginMode())
|
|
708
|
+
];
|
|
709
|
+
case 12:
|
|
710
|
+
_state.sent();
|
|
711
|
+
_state.label = 13;
|
|
712
|
+
case 13:
|
|
713
|
+
forcedPaths = new Set((0, _indexts2.listFiles)(cfg, paths.rootDir).map(function(file) {
|
|
714
|
+
return file.relPath;
|
|
715
|
+
}));
|
|
716
|
+
return [
|
|
717
|
+
2,
|
|
718
|
+
(0, _reconcilets.reconcile)(conn, cfg, paths, dialect, pool, forcedPaths)
|
|
719
|
+
];
|
|
720
|
+
}
|
|
721
|
+
});
|
|
722
|
+
})();
|
|
723
|
+
}
|
|
597
724
|
function createBuilder(conn, cfg, paths, dialect) {
|
|
598
725
|
var pool = new _poolts.ParsePool();
|
|
599
726
|
return {
|
|
600
727
|
build: function build(forcedPaths) {
|
|
601
728
|
return (0, _reconcilets.reconcile)(conn, cfg, paths, dialect, pool, forcedPaths);
|
|
602
729
|
},
|
|
730
|
+
recover: function recover() {
|
|
731
|
+
return recoverIncomplete(conn, cfg, paths, dialect, pool);
|
|
732
|
+
},
|
|
603
733
|
invalidate: function invalidate(kind) {
|
|
604
734
|
return kind === 'model' ? nullEmbedVectors(conn, dialect) : rebuildEmbeddings(conn, cfg, paths.rootDir, dialect, pool);
|
|
605
735
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/store/builder.ts"],"sourcesContent":["import type { Config } from '../config/index.ts';\nimport { embed } from '../features/embed.ts';\nimport { FEATURES } from '../features/index.ts';\nimport { rank } from '../features/rank.ts';\nimport type { ReconcileDelta } from '../features/types.ts';\nimport { listFiles } from '../scan/index.ts';\nimport { ParsePool } from '../scan/pool.ts';\nimport { reparseFiles } from '../scan/reparse.ts';\nimport type { EmbedChangeKind } from './embed-scope.ts';\nimport type { FeatureToggle } from './feature-scope.ts';\nimport { NARROW_FEATURE_TABLE } from './feature-scope.ts';\nimport { type ReconcilePaths, reconcile } from './reconcile.ts';\nimport { getColumns } from './shared.ts';\nimport type { Stages } from './stages.ts';\nimport { withTransaction } from './transaction.ts';\nimport type { Connection, ReconcileDialect } from './types.ts';\n\n// Owns bringing a store's index current: the write half `Store` (types.ts) deliberately does not\n// carry. A one-shot open calls build() once; a watcher calls it repeatedly on the same instance.\nexport interface Builder {\n // forcedPaths (open.ts's preset-only narrow rebuild) applies to this call alone, not future ones.\n build(forcedPaths?: ReadonlySet<string>): Promise<{ parsed: number; warnings: string[]; stages: Stages }>;\n // Narrow embed invalidation (open.ts, embed-scope.ts's classifyEmbedChange): 'model' nulls every\n // vector/scale in place; 'chunk' rebuilds every embedding row. Neither touches another table.\n invalidate(kind: EmbedChangeKind): Promise<{ parsed: number }>;\n // Narrow feature-toggle invalidation (open.ts, feature-scope.ts's classifyFeatureToggles): a\n // toggle drops (or, turning back on, fully re-derives) that feature's own table; rank instead\n // nulls or recomputes its `_rank` column, since rows written while a feature was off are\n // untrustworthy (reconcile.ts's activeFeatures skips a disabled feature's hooks entirely).\n invalidateFeatures(toggles: FeatureToggle[]): Promise<{ parsed: number }>;\n // Releases the parse worker pool, if this lifetime ever created one; never the connection.\n close(): Promise<void>;\n // Pools this lifetime has constructed, so reuse is observable rather than inferred.\n readonly poolsCreated: number;\n}\n\n// 'model': the provider or model name moved but chunk boundaries did not, so only the vector\n// values are stale. No reparse, and no table but embeddings is touched.\nasync function nullEmbedVectors(conn: Connection, dialect: ReconcileDialect): Promise<{ parsed: number }> {\n await withTransaction(conn, () => conn.exec('UPDATE embeddings SET vector = NULL, scale = NULL'), dialect.beginMode());\n return { parsed: 0 };\n}\n\n// 'chunk': chunkTokens or the chunk version moved, so chunk boundaries genuinely changed. Rebuilds\n// every embedding row through the embed feature's own remove/store, touching no other table.\nasync function rebuildEmbeddings(conn: Connection, cfg: Config, baseDir: string, dialect: ReconcileDialect, pool: ParsePool): Promise<{ parsed: number }> {\n const existingStmt = await conn.prepare('SELECT \"path\" FROM frontmatter');\n const existingPaths = new Set((await existingStmt.all()).map((r) => (r as { path: string }).path));\n // A file added since the last build has no row yet; leaving it for build() to insert avoids a\n // primary-key collision between this INSERT and build()'s own insert for the same new file.\n const files = listFiles(cfg, baseDir).filter((f) => f.embed && existingPaths.has(f.relPath));\n if (files.length === 0) return { parsed: 0 };\n\n const { docs } = await reparseFiles(files, [embed], cfg, new Set(), undefined, { pool });\n const paths = docs.map((d) => d.relPath);\n const delta: ReconcileDelta = { files, reparsed: paths, added: [], vanished: [] };\n await withTransaction(\n conn,\n async () => {\n await embed.remove?.(conn, paths, delta);\n await embed.store?.(\n conn,\n docs.map((d) => ({ path: d.relPath, extracted: d.extracted.embed })),\n delta\n );\n },\n dialect.beginMode()\n );\n return { parsed: docs.length };\n}\n\n// One feature's own table, dropped and (turning on) fully re-derived across every indexed file.\n// Rows left over from before this feature was disabled are untrustworthy by construction (files\n// added, edited, or deleted got no remove/store for it), so this never diffs against them --\n// dropping every row and reparsing the whole tree is the only safe path back to consistent state.\nasync function invalidateFeatureTable(conn: Connection, cfg: Config, baseDir: string, dialect: ReconcileDialect, pool: ParsePool, toggle: FeatureToggle): Promise<{ parsed: number }> {\n const table = NARROW_FEATURE_TABLE[toggle.name];\n const feature = FEATURES.find((f) => f.name === toggle.name);\n if (!feature) throw new Error(`invalidateFeatureTable: no registered feature named \"${toggle.name}\"`);\n\n if (!toggle.turnedOn) {\n await withTransaction(conn, () => conn.exec(`DELETE FROM ${table}`), dialect.beginMode());\n return { parsed: 0 };\n }\n\n const files = listFiles(cfg, baseDir);\n const { docs } = await reparseFiles(files, [feature], cfg, new Set(), undefined, { pool });\n const docsForFeature = docs.map((d) => ({ path: d.relPath, extracted: d.extracted[feature.name] }));\n const paths = docs.map((d) => d.relPath);\n // Every path counts as added, not just touched: nothing stale to diff against. Links resolves\n // dst inside store() itself when added.length equals files.length (a cold build).\n const delta: ReconcileDelta = { files, reparsed: paths, added: paths, vanished: [] };\n await withTransaction(\n conn,\n async () => {\n await conn.exec(`DELETE FROM ${table}`);\n await feature.store?.(conn, docsForFeature, delta);\n await feature.afterReconcile?.(conn, delta);\n },\n dialect.beginMode()\n );\n return { parsed: docs.length };\n}\n\n// rank has no table of its own: frontmatter._rank is the only state it owns. Guarded on column\n// presence, since links can toggle off while rank has never been enabled for this tree.\nasync function nullRank(conn: Connection, dialect: ReconcileDialect): Promise<void> {\n const columns = await getColumns(conn);\n if (!columns.has('_rank')) return;\n await withTransaction(conn, () => conn.exec('UPDATE frontmatter SET \"_rank\" = NULL'), dialect.beginMode());\n}\n\n// Whole-tree and reparse-free: PageRank is computed from the links table, not from files, so\n// turning rank back on needs no reparseFiles pass at all.\nasync function rerunRank(conn: Connection, dialect: ReconcileDialect): Promise<void> {\n const delta: ReconcileDelta = { files: [], reparsed: [], added: [], vanished: [] };\n await withTransaction(\n conn,\n async () => {\n await rank.afterReconcile?.(conn, delta);\n },\n dialect.beginMode()\n );\n}\n\nasync function invalidateFeatureToggles(conn: Connection, cfg: Config, baseDir: string, dialect: ReconcileDialect, pool: ParsePool, toggles: FeatureToggle[]): Promise<{ parsed: number }> {\n const byName = new Map(toggles.map((toggle) => [toggle.name, toggle]));\n let parsed = 0;\n\n // links first, if present: rank's rerun below (whether from its own toggle or the co-change\n // rankToggle carries) must read the links table after it is back in its new state.\n const linksToggle = byName.get('links');\n if (linksToggle) {\n parsed += (await invalidateFeatureTable(conn, cfg, baseDir, dialect, pool, linksToggle)).parsed;\n // Unconditional, per rank's dependency on links: nulling is a no-op (guarded) when rank was\n // never enabled for this tree, so this is safe even when no feature:rank segment changed.\n if (!linksToggle.turnedOn) await nullRank(conn, dialect);\n }\n\n // rank's effective on/off (featureEnabled's links dependency) only appears as a changed\n // `feature:rank` segment when it actually flips -- whether that's rank's own config or a\n // links toggle taking it along -- so honoring it here is complete on its own.\n const rankToggle = byName.get('rank');\n if (rankToggle) {\n if (rankToggle.turnedOn) await rerunRank(conn, dialect);\n else await nullRank(conn, dialect);\n }\n\n for (const toggle of toggles) {\n if (toggle.name === 'links' || toggle.name === 'rank') continue;\n parsed += (await invalidateFeatureTable(conn, cfg, baseDir, dialect, pool, toggle)).parsed;\n }\n return { parsed };\n}\n\n// The pool is created at most once, lazily, on whichever build() or invalidate() call first\n// needs it, and reused by every later call on this instance.\nexport function createBuilder(conn: Connection, cfg: Config, paths: ReconcilePaths, dialect: ReconcileDialect): Builder {\n const pool = new ParsePool();\n return {\n build: (forcedPaths) => reconcile(conn, cfg, paths, dialect, pool, forcedPaths),\n invalidate: (kind) => (kind === 'model' ? nullEmbedVectors(conn, dialect) : rebuildEmbeddings(conn, cfg, paths.rootDir, dialect, pool)),\n invalidateFeatures: (toggles) => invalidateFeatureToggles(conn, cfg, paths.rootDir, dialect, pool, toggles),\n close: () => pool.close(),\n get poolsCreated() {\n return pool.poolsCreated;\n },\n };\n}\n"],"names":["createBuilder","nullEmbedVectors","conn","dialect","withTransaction","exec","beginMode","parsed","rebuildEmbeddings","cfg","baseDir","pool","existingStmt","existingPaths","files","docs","paths","delta","prepare","Set","all","map","r","path","listFiles","filter","f","embed","has","relPath","length","reparseFiles","undefined","d","reparsed","added","vanished","remove","store","extracted","invalidateFeatureTable","toggle","table","feature","docsForFeature","NARROW_FEATURE_TABLE","name","FEATURES","find","Error","turnedOn","afterReconcile","nullRank","columns","getColumns","rerunRank","rank","invalidateFeatureToggles","toggles","byName","linksToggle","rankToggle","Map","get","ParsePool","build","forcedPaths","reconcile","invalidate","kind","rootDir","invalidateFeatures","close","poolsCreated"],"mappings":";;;;+BA6JgBA;;;eAAAA;;;uBA5JM;uBACG;sBACJ;wBAEK;sBACA;yBACG;8BAGQ;2BACU;wBACpB;6BAEK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsBhC,6FAA6F;AAC7F,wEAAwE;AACxE,SAAeC,iBAAiBC,IAAgB,EAAEC,OAAyB;;;;;oBACzE;;wBAAMC,IAAAA,8BAAe,EAACF,MAAM;mCAAMA,KAAKG,IAAI,CAAC;2BAAsDF,QAAQG,SAAS;;;oBAAnH;oBACA;;wBAAO;4BAAEC,QAAQ;wBAAE;;;;IACrB;;AAEA,mGAAmG;AACnG,6FAA6F;AAC7F,SAAeC,kBAAkBN,IAAgB,EAAEO,GAAW,EAAEC,OAAe,EAAEP,OAAyB,EAAEQ,IAAe;;YACnHC,cACAC,kBAGAC,OAGEC,MACFC,OACAC;;;;oBATe;;wBAAMf,KAAKgB,OAAO,CAAC;;;oBAAlCN,eAAe;wBACKO;oBAAK;;wBAAMP,aAAaQ,GAAG;;;oBAA/CP,gBAAgB,IAAA,CAAA,EAAA,MAAIM;;wBAAK,cAA0BE,GAAG,CAAC,SAACC;mCAAM,AAACA,EAAuBC,IAAI;;sBAAC;oBACjG,8FAA8F;oBAC9F,4FAA4F;oBACtFT,QAAQU,IAAAA,mBAAS,EAACf,KAAKC,SAASe,MAAM,CAAC,SAACC;+BAAMA,EAAEC,KAAK,IAAId,cAAce,GAAG,CAACF,EAAEG,OAAO;;oBAC1F,IAAIf,MAAMgB,MAAM,KAAK,GAAG;;wBAAO;4BAAEvB,QAAQ;wBAAE;;oBAE1B;;wBAAMwB,IAAAA,uBAAY,EAACjB;4BAAQa,cAAK;2BAAGlB,KAAK,IAAIU,OAAOa,WAAW;4BAAErB,MAAAA;wBAAK;;;oBAA9EI,OAAS,cAATA;oBACFC,QAAQD,KAAKM,GAAG,CAAC,SAACY;+BAAMA,EAAEJ,OAAO;;oBACjCZ,QAAwB;wBAAEH,OAAAA;wBAAOoB,UAAUlB;wBAAOmB,KAAK;wBAAMC,QAAQ;oBAAK;oBAChF;;wBAAMhC,IAAAA,8BAAe,EACnBF,MACA;;oCACQyB,eACAA;;;;4CADN;;iDAAMA,gBAAAA,cAAK,CAACU,MAAM,cAAZV,oCAAAA,mBAAAA,cAAK,EAAUzB,MAAMc,OAAOC;;;4CAAlC;4CACA;;iDAAMU,eAAAA,cAAK,CAACW,KAAK,cAAXX,mCAAAA,kBAAAA,cAAK,EACTzB,MACAa,KAAKM,GAAG,CAAC,SAACY;2DAAO;wDAAEV,MAAMU,EAAEJ,OAAO;wDAAEU,WAAWN,EAAEM,SAAS,CAACZ,KAAK;oDAAC;oDACjEV;;;4CAHF;;;;;;4BAKF;2BACAd,QAAQG,SAAS;;;oBAVnB;oBAYA;;wBAAO;4BAAEC,QAAQQ,KAAKe,MAAM;wBAAC;;;;IAC/B;;AAEA,gGAAgG;AAChG,gGAAgG;AAChG,6FAA6F;AAC7F,kGAAkG;AAClG,SAAeU,uBAAuBtC,IAAgB,EAAEO,GAAW,EAAEC,OAAe,EAAEP,OAAyB,EAAEQ,IAAe,EAAE8B,MAAqB;;YAC/IC,OACAC,SAQA7B,OACEC,MACF6B,gBACA5B,OAGAC;;;;oBAfAyB,QAAQG,oCAAoB,CAACJ,OAAOK,IAAI,CAAC;oBACzCH,UAAUI,iBAAQ,CAACC,IAAI,CAAC,SAACtB;+BAAMA,EAAEoB,IAAI,KAAKL,OAAOK,IAAI;;oBAC3D,IAAI,CAACH,SAAS,MAAM,IAAIM,MAAM,AAAC,wDAAmE,OAAZR,OAAOK,IAAI,EAAC;yBAE9F,CAACL,OAAOS,QAAQ,EAAhB;;;;oBACF;;wBAAM9C,IAAAA,8BAAe,EAACF,MAAM;mCAAMA,KAAKG,IAAI,CAAC,AAAC,eAAoB,OAANqC;2BAAUvC,QAAQG,SAAS;;;oBAAtF;oBACA;;wBAAO;4BAAEC,QAAQ;wBAAE;;;oBAGfO,QAAQU,IAAAA,mBAAS,EAACf,KAAKC;oBACZ;;wBAAMqB,IAAAA,uBAAY,EAACjB;4BAAQ6B;2BAAUlC,KAAK,IAAIU,OAAOa,WAAW;4BAAErB,MAAAA;wBAAK;;;oBAAhFI,OAAS,cAATA;oBACF6B,iBAAiB7B,KAAKM,GAAG,CAAC,SAACY;+BAAO;4BAAEV,MAAMU,EAAEJ,OAAO;4BAAEU,WAAWN,EAAEM,SAAS,CAACI,QAAQG,IAAI,CAAC;wBAAC;;oBAC1F9B,QAAQD,KAAKM,GAAG,CAAC,SAACY;+BAAMA,EAAEJ,OAAO;;oBACvC,8FAA8F;oBAC9F,kFAAkF;oBAC5EZ,QAAwB;wBAAEH,OAAAA;wBAAOoB,UAAUlB;wBAAOmB,OAAOnB;wBAAOoB,QAAQ;oBAAK;oBACnF;;wBAAMhC,IAAAA,8BAAe,EACnBF,MACA;;oCAEQyC,gBACAA;;;;4CAFN;;gDAAMzC,KAAKG,IAAI,CAAC,AAAC,eAAoB,OAANqC;;;4CAA/B;4CACA;;iDAAMC,iBAAAA,QAAQL,KAAK,cAAbK,qCAAAA,oBAAAA,SAAgBzC,MAAM0C,gBAAgB3B;;;4CAA5C;4CACA;;iDAAM0B,0BAAAA,QAAQQ,cAAc,cAAtBR,8CAAAA,6BAAAA,SAAyBzC,MAAMe;;;4CAArC;;;;;;4BACF;2BACAd,QAAQG,SAAS;;;oBAPnB;oBASA;;wBAAO;4BAAEC,QAAQQ,KAAKe,MAAM;wBAAC;;;;IAC/B;;AAEA,+FAA+F;AAC/F,wFAAwF;AACxF,SAAesB,SAASlD,IAAgB,EAAEC,OAAyB;;YAC3DkD;;;;oBAAU;;wBAAMC,IAAAA,oBAAU,EAACpD;;;oBAA3BmD,UAAU;oBAChB,IAAI,CAACA,QAAQzB,GAAG,CAAC,UAAU;;;oBAC3B;;wBAAMxB,IAAAA,8BAAe,EAACF,MAAM;mCAAMA,KAAKG,IAAI,CAAC;2BAA0CF,QAAQG,SAAS;;;oBAAvG;;;;;;IACF;;AAEA,6FAA6F;AAC7F,0DAA0D;AAC1D,SAAeiD,UAAUrD,IAAgB,EAAEC,OAAyB;;YAC5Dc;;;;oBAAAA,QAAwB;wBAAEH,KAAK;wBAAMoB,QAAQ;wBAAMC,KAAK;wBAAMC,QAAQ;oBAAK;oBACjF;;wBAAMhC,IAAAA,8BAAe,EACnBF,MACA;;oCACQsD;;;;4CAAN;;iDAAMA,uBAAAA,YAAI,CAACL,cAAc,cAAnBK,2CAAAA,0BAAAA,YAAI,EAAkBtD,MAAMe;;;4CAAlC;;;;;;4BACF;2BACAd,QAAQG,SAAS;;;oBALnB;;;;;;IAOF;;AAEA,SAAemD,yBAAyBvD,IAAgB,EAAEO,GAAW,EAAEC,OAAe,EAAEP,OAAyB,EAAEQ,IAAe,EAAE+C,OAAwB;;YACpJC,QACFpD,QAIEqD,aAWAC,YAMD,2BAAA,mBAAA,gBAAA,WAAA,OAAMpB;;;;oBAtBLkB,SAAS,IAAIG,IAAIJ,QAAQrC,GAAG,CAAC,SAACoB;+BAAW;4BAACA,OAAOK,IAAI;4BAAEL;yBAAO;;oBAChElC,SAAS;oBAEb,4FAA4F;oBAC5F,mFAAmF;oBAC7EqD,cAAcD,OAAOI,GAAG,CAAC;yBAC3BH,aAAAA;;;;oBACS;;wBAAMpB,uBAAuBtC,MAAMO,KAAKC,SAASP,SAASQ,MAAMiD;;;oBAA3ErD,SAAAA,SAAU,AAAC,cAA8EA,MAAM;yBAG3F,CAACqD,YAAYV,QAAQ,EAArB;;;;oBAAuB;;wBAAME,SAASlD,MAAMC;;;oBAArB;;;oBAG7B,wFAAwF;oBACxF,yFAAyF;oBACzF,8EAA8E;oBACxE0D,aAAaF,OAAOI,GAAG,CAAC;yBAC1BF,YAAAA;;;;yBACEA,WAAWX,QAAQ,EAAnBW;;;;oBAAqB;;wBAAMN,UAAUrD,MAAMC;;;oBAAtB;;;;;;oBACpB;;wBAAMiD,SAASlD,MAAMC;;;oBAArB;;;oBAGF,kCAAA,2BAAA;;;;;;;;;oBAAA,YAAgBuD;;;2BAAhB,6BAAA,QAAA;;;;oBAAMjB,SAAN;oBACH,IAAIA,OAAOK,IAAI,KAAK,WAAWL,OAAOK,IAAI,KAAK,QAAQ;;;;oBAC5C;;wBAAMN,uBAAuBtC,MAAMO,KAAKC,SAASP,SAASQ,MAAM8B;;;oBAA3ElC,SAAAA,SAAU,AAAC,cAAyEA,MAAM;;;oBAFvF;;;;;;;;;;;;oBAAA;oBAAA;;;;;;;6BAAA,6BAAA;4BAAA;;;4BAAA;kCAAA;;;;;;;oBAIL;;wBAAO;4BAAEA,QAAAA;wBAAO;;;;IAClB;;AAIO,SAASP,cAAcE,IAAgB,EAAEO,GAAW,EAAEO,KAAqB,EAAEb,OAAyB;IAC3G,IAAMQ,OAAO,IAAIqD,iBAAS;IAC1B,OAAO;QACLC,OAAO,SAAPA,MAAQC;mBAAgBC,IAAAA,sBAAS,EAACjE,MAAMO,KAAKO,OAAOb,SAASQ,MAAMuD;;QACnEE,YAAY,SAAZA,WAAaC;mBAAUA,SAAS,UAAUpE,iBAAiBC,MAAMC,WAAWK,kBAAkBN,MAAMO,KAAKO,MAAMsD,OAAO,EAAEnE,SAASQ;;QACjI4D,oBAAoB,SAApBA,mBAAqBb;mBAAYD,yBAAyBvD,MAAMO,KAAKO,MAAMsD,OAAO,EAAEnE,SAASQ,MAAM+C;;QACnGc,OAAO,SAAPA;mBAAa7D,KAAK6D,KAAK;;QACvB,IAAIC;YACF,OAAO9D,KAAK8D,YAAY;QAC1B;IACF;AACF"}
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/store/builder.ts"],"sourcesContent":["import { type Config, featureEnabled } from '../config/index.ts';\nimport { embed } from '../features/embed.ts';\nimport { FEATURES } from '../features/index.ts';\nimport { rank } from '../features/rank.ts';\nimport type { ReconcileDelta } from '../features/types.ts';\nimport { listFiles } from '../scan/index.ts';\nimport { ParsePool } from '../scan/pool.ts';\nimport { reparseFiles } from '../scan/reparse.ts';\nimport type { EmbedChangeKind } from './embed-scope.ts';\nimport type { FeatureToggle } from './feature-scope.ts';\nimport { NARROW_FEATURE_TABLE } from './feature-scope.ts';\nimport { type ReconcilePaths, reconcile } from './reconcile.ts';\nimport { getColumns } from './shared.ts';\nimport type { Stages } from './stages.ts';\nimport { withTransaction } from './transaction.ts';\nimport type { Connection, ReconcileDialect } from './types.ts';\n\n// Owns bringing a store's index current: the write half `Store` (types.ts) deliberately does not\n// carry. A one-shot open calls build() once; a watcher calls it repeatedly on the same instance.\nexport interface Builder {\n // forcedPaths (open.ts's preset-only narrow rebuild) applies to this call alone, not future ones.\n build(forcedPaths?: ReadonlySet<string>): Promise<{ parsed: number; warnings: string[]; stages: Stages }>;\n // Repairs an incomplete generation in place, including state owned by disabled features.\n recover(): Promise<{ parsed: number; warnings: string[]; stages: Stages }>;\n // Narrow embed invalidation (open.ts, embed-scope.ts's classifyEmbedChange): 'model' nulls every\n // vector/scale in place; 'chunk' rebuilds every embedding row. Neither touches another table.\n invalidate(kind: EmbedChangeKind): Promise<{ parsed: number }>;\n // Narrow feature-toggle invalidation (open.ts, feature-scope.ts's classifyFeatureToggles): a\n // toggle drops (or, turning back on, fully re-derives) that feature's own table; rank instead\n // nulls or recomputes its `_rank` column, since rows written while a feature was off are\n // untrustworthy (reconcile.ts's activeFeatures skips a disabled feature's hooks entirely).\n invalidateFeatures(toggles: FeatureToggle[]): Promise<{ parsed: number }>;\n // Releases the parse worker pool, if this lifetime ever created one; never the connection.\n close(): Promise<void>;\n // Pools this lifetime has constructed, so reuse is observable rather than inferred.\n readonly poolsCreated: number;\n}\n\n// 'model': the provider or model name moved but chunk boundaries did not, so only the vector\n// values are stale. No reparse, and no table but embeddings is touched.\nasync function nullEmbedVectors(conn: Connection, dialect: ReconcileDialect): Promise<{ parsed: number }> {\n await withTransaction(conn, () => conn.exec('UPDATE embeddings SET vector = NULL, scale = NULL'), dialect.beginMode());\n return { parsed: 0 };\n}\n\n// 'chunk': chunkTokens or the chunk version moved, so chunk boundaries genuinely changed. Rebuilds\n// every embedding row through the embed feature's own remove/store, touching no other table.\nasync function rebuildEmbeddings(conn: Connection, cfg: Config, baseDir: string, dialect: ReconcileDialect, pool: ParsePool): Promise<{ parsed: number }> {\n const existingStmt = await conn.prepare('SELECT \"path\" FROM frontmatter');\n const existingPaths = new Set((await existingStmt.all()).map((r) => (r as { path: string }).path));\n // A file added since the last build has no row yet; leaving it for build() to insert avoids a\n // primary-key collision between this INSERT and build()'s own insert for the same new file.\n const files = listFiles(cfg, baseDir).filter((f) => f.embed && existingPaths.has(f.relPath));\n if (files.length === 0) return { parsed: 0 };\n\n const { docs } = await reparseFiles(files, [embed], cfg, new Set(), undefined, { pool });\n const paths = docs.map((d) => d.relPath);\n const delta: ReconcileDelta = { files, reparsed: paths, added: [], vanished: [] };\n await withTransaction(\n conn,\n async () => {\n await embed.remove?.(conn, paths, delta);\n await embed.store?.(\n conn,\n docs.map((d) => ({ path: d.relPath, extracted: d.extracted.embed })),\n delta\n );\n },\n dialect.beginMode()\n );\n return { parsed: docs.length };\n}\n\n// One feature's own table, dropped and (turning on) fully re-derived across every indexed file.\n// Rows left over from before this feature was disabled are untrustworthy by construction (files\n// added, edited, or deleted got no remove/store for it), so this never diffs against them --\n// dropping every row and reparsing the whole tree is the only safe path back to consistent state.\nasync function invalidateFeatureTable(conn: Connection, cfg: Config, baseDir: string, dialect: ReconcileDialect, pool: ParsePool, toggle: FeatureToggle): Promise<{ parsed: number }> {\n const table = NARROW_FEATURE_TABLE[toggle.name];\n const feature = FEATURES.find((f) => f.name === toggle.name);\n if (!feature) throw new Error(`invalidateFeatureTable: no registered feature named \"${toggle.name}\"`);\n\n if (!toggle.turnedOn) {\n await withTransaction(conn, () => conn.exec(`DELETE FROM ${table}`), dialect.beginMode());\n return { parsed: 0 };\n }\n\n const files = listFiles(cfg, baseDir);\n const { docs } = await reparseFiles(files, [feature], cfg, new Set(), undefined, { pool });\n const docsForFeature = docs.map((d) => ({ path: d.relPath, extracted: d.extracted[feature.name] }));\n const paths = docs.map((d) => d.relPath);\n // Every path counts as added, not just touched: nothing stale to diff against. Links resolves\n // dst inside store() itself when added.length equals files.length (a cold build).\n const delta: ReconcileDelta = { files, reparsed: paths, added: paths, vanished: [] };\n await withTransaction(\n conn,\n async () => {\n await conn.exec(`DELETE FROM ${table}`);\n await feature.store?.(conn, docsForFeature, delta);\n await feature.afterReconcile?.(conn, delta);\n },\n dialect.beginMode()\n );\n return { parsed: docs.length };\n}\n\n// rank has no table of its own: frontmatter._rank is the only state it owns. Guarded on column\n// presence, since links can toggle off while rank has never been enabled for this tree.\nasync function nullRank(conn: Connection, dialect: ReconcileDialect): Promise<void> {\n const columns = await getColumns(conn);\n if (!columns.has('_rank')) return;\n await withTransaction(conn, () => conn.exec('UPDATE frontmatter SET \"_rank\" = NULL'), dialect.beginMode());\n}\n\n// Whole-tree and reparse-free: PageRank is computed from the links table, not from files, so\n// turning rank back on needs no reparseFiles pass at all.\nasync function rerunRank(conn: Connection, dialect: ReconcileDialect): Promise<void> {\n const delta: ReconcileDelta = { files: [], reparsed: [], added: [], vanished: [] };\n await withTransaction(\n conn,\n async () => {\n await rank.afterReconcile?.(conn, delta);\n },\n dialect.beginMode()\n );\n}\n\nasync function invalidateFeatureToggles(conn: Connection, cfg: Config, baseDir: string, dialect: ReconcileDialect, pool: ParsePool, toggles: FeatureToggle[]): Promise<{ parsed: number }> {\n const byName = new Map(toggles.map((toggle) => [toggle.name, toggle]));\n let parsed = 0;\n\n // links first, if present: rank's rerun below (whether from its own toggle or the co-change\n // rankToggle carries) must read the links table after it is back in its new state.\n const linksToggle = byName.get('links');\n if (linksToggle) {\n parsed += (await invalidateFeatureTable(conn, cfg, baseDir, dialect, pool, linksToggle)).parsed;\n // Unconditional, per rank's dependency on links: nulling is a no-op (guarded) when rank was\n // never enabled for this tree, so this is safe even when no feature:rank segment changed.\n if (!linksToggle.turnedOn) await nullRank(conn, dialect);\n }\n\n // rank's effective on/off (featureEnabled's links dependency) only appears as a changed\n // `feature:rank` segment when it actually flips -- whether that's rank's own config or a\n // links toggle taking it along -- so honoring it here is complete on its own.\n const rankToggle = byName.get('rank');\n if (rankToggle) {\n if (rankToggle.turnedOn) await rerunRank(conn, dialect);\n else await nullRank(conn, dialect);\n }\n\n for (const toggle of toggles) {\n if (toggle.name === 'links' || toggle.name === 'rank') continue;\n parsed += (await invalidateFeatureTable(conn, cfg, baseDir, dialect, pool, toggle)).parsed;\n }\n return { parsed };\n}\n\nasync function recoverIncomplete(conn: Connection, cfg: Config, paths: ReconcilePaths, dialect: ReconcileDialect, pool: ParsePool): Promise<{ parsed: number; warnings: string[]; stages: Stages }> {\n const disabled = FEATURES.filter((feature) => !featureEnabled(cfg, feature.name));\n for (const feature of disabled) {\n if (feature.name !== 'embed') await feature.schema(conn);\n }\n\n const toggles: FeatureToggle[] = disabled.filter((feature) => feature.name !== 'embed').map((feature) => ({ name: feature.name, turnedOn: false }));\n await invalidateFeatureToggles(conn, cfg, paths.rootDir, dialect, pool, toggles);\n if (disabled.some((feature) => feature.name === 'embed')) {\n const embeddingsTable = await conn.prepare(\"SELECT name FROM sqlite_master WHERE type = 'table' AND name = 'embeddings'\");\n if ((await embeddingsTable.all()).length > 0) await withTransaction(conn, () => conn.exec('DELETE FROM embeddings'), dialect.beginMode());\n }\n\n const forcedPaths = new Set(listFiles(cfg, paths.rootDir).map((file) => file.relPath));\n return reconcile(conn, cfg, paths, dialect, pool, forcedPaths);\n}\n\n// The pool is created at most once, lazily, on whichever build() or invalidate() call first\n// needs it, and reused by every later call on this instance.\nexport function createBuilder(conn: Connection, cfg: Config, paths: ReconcilePaths, dialect: ReconcileDialect): Builder {\n const pool = new ParsePool();\n return {\n build: (forcedPaths) => reconcile(conn, cfg, paths, dialect, pool, forcedPaths),\n recover: () => recoverIncomplete(conn, cfg, paths, dialect, pool),\n invalidate: (kind) => (kind === 'model' ? nullEmbedVectors(conn, dialect) : rebuildEmbeddings(conn, cfg, paths.rootDir, dialect, pool)),\n invalidateFeatures: (toggles) => invalidateFeatureToggles(conn, cfg, paths.rootDir, dialect, pool, toggles),\n close: () => pool.close(),\n get poolsCreated() {\n return pool.poolsCreated;\n },\n };\n}\n"],"names":["createBuilder","nullEmbedVectors","conn","dialect","withTransaction","exec","beginMode","parsed","rebuildEmbeddings","cfg","baseDir","pool","existingStmt","existingPaths","files","docs","paths","delta","prepare","Set","all","map","r","path","listFiles","filter","f","embed","has","relPath","length","reparseFiles","undefined","d","reparsed","added","vanished","remove","store","extracted","invalidateFeatureTable","toggle","table","feature","docsForFeature","NARROW_FEATURE_TABLE","name","FEATURES","find","Error","turnedOn","afterReconcile","nullRank","columns","getColumns","rerunRank","rank","invalidateFeatureToggles","toggles","byName","linksToggle","rankToggle","Map","get","recoverIncomplete","disabled","embeddingsTable","forcedPaths","featureEnabled","schema","rootDir","some","file","reconcile","ParsePool","build","recover","invalidate","kind","invalidateFeatures","close","poolsCreated"],"mappings":"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"}
|
|
@@ -4,6 +4,8 @@ interface FtsIndexState {
|
|
|
4
4
|
orderedMacroReady: boolean;
|
|
5
5
|
}
|
|
6
6
|
export declare function markContentStale(conn: Connection): Promise<void>;
|
|
7
|
+
export declare function prepareFts(conn: Connection): Promise<void>;
|
|
8
|
+
export declare function assertFtsReady(conn: Connection): Promise<void>;
|
|
7
9
|
export declare function queryLexical(conn: Connection, terms: string, opts: LexicalQueryOptions, state: FtsIndexState): Promise<LexicalHit[]>;
|
|
8
10
|
export declare function createLexicalIndex(conn: Connection): {
|
|
9
11
|
query: (terms: string, opts: LexicalQueryOptions) => Promise<LexicalHit[]>;
|
|
@@ -4,6 +4,8 @@ interface FtsIndexState {
|
|
|
4
4
|
orderedMacroReady: boolean;
|
|
5
5
|
}
|
|
6
6
|
export declare function markContentStale(conn: Connection): Promise<void>;
|
|
7
|
+
export declare function prepareFts(conn: Connection): Promise<void>;
|
|
8
|
+
export declare function assertFtsReady(conn: Connection): Promise<void>;
|
|
7
9
|
export declare function queryLexical(conn: Connection, terms: string, opts: LexicalQueryOptions, state: FtsIndexState): Promise<LexicalHit[]>;
|
|
8
10
|
export declare function createLexicalIndex(conn: Connection): {
|
|
9
11
|
query: (terms: string, opts: LexicalQueryOptions) => Promise<LexicalHit[]>;
|
|
@@ -11,12 +11,18 @@ function _export(target, all) {
|
|
|
11
11
|
});
|
|
12
12
|
}
|
|
13
13
|
_export(exports, {
|
|
14
|
+
get assertFtsReady () {
|
|
15
|
+
return assertFtsReady;
|
|
16
|
+
},
|
|
14
17
|
get createLexicalIndex () {
|
|
15
18
|
return createLexicalIndex;
|
|
16
19
|
},
|
|
17
20
|
get markContentStale () {
|
|
18
21
|
return markContentStale;
|
|
19
22
|
},
|
|
23
|
+
get prepareFts () {
|
|
24
|
+
return prepareFts;
|
|
25
|
+
},
|
|
20
26
|
get queryLexical () {
|
|
21
27
|
return queryLexical;
|
|
22
28
|
}
|
|
@@ -60,6 +66,12 @@ function _async_to_generator(fn) {
|
|
|
60
66
|
});
|
|
61
67
|
};
|
|
62
68
|
}
|
|
69
|
+
function _instanceof(left, right) {
|
|
70
|
+
"@swc/helpers - instanceof";
|
|
71
|
+
if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) {
|
|
72
|
+
return !!right[Symbol.hasInstance](left);
|
|
73
|
+
} else return left instanceof right;
|
|
74
|
+
}
|
|
63
75
|
function _iterable_to_array(iter) {
|
|
64
76
|
if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) {
|
|
65
77
|
return Array.from(iter);
|
|
@@ -283,6 +295,31 @@ function stateFor(conn) {
|
|
|
283
295
|
});
|
|
284
296
|
})();
|
|
285
297
|
}
|
|
298
|
+
function hasFtsArtifact(conn) {
|
|
299
|
+
return _async_to_generator(function() {
|
|
300
|
+
var stmt;
|
|
301
|
+
return _ts_generator(this, function(_state) {
|
|
302
|
+
switch(_state.label){
|
|
303
|
+
case 0:
|
|
304
|
+
return [
|
|
305
|
+
4,
|
|
306
|
+
conn.prepare("\n SELECT 1 AS ready\n FROM duckdb_functions()\n WHERE schema_name = 'fts_main_content'\n AND function_name = 'match_bm25'\n AND function_type = 'macro'\n LIMIT 1\n ")
|
|
307
|
+
];
|
|
308
|
+
case 1:
|
|
309
|
+
stmt = _state.sent();
|
|
310
|
+
return [
|
|
311
|
+
4,
|
|
312
|
+
stmt.get()
|
|
313
|
+
];
|
|
314
|
+
case 2:
|
|
315
|
+
return [
|
|
316
|
+
2,
|
|
317
|
+
_state.sent() !== undefined
|
|
318
|
+
];
|
|
319
|
+
}
|
|
320
|
+
});
|
|
321
|
+
})();
|
|
322
|
+
}
|
|
286
323
|
function markContentStale(conn) {
|
|
287
324
|
return _async_to_generator(function() {
|
|
288
325
|
return _ts_generator(this, function(_state) {
|
|
@@ -403,21 +440,36 @@ function splitTerms(terms) {
|
|
|
403
440
|
}
|
|
404
441
|
// No incremental update (verified 1.5.5: PRAGMA create_fts_index is rebuild-only), so this pays
|
|
405
442
|
// the full rebuild whenever `state.stale`, which meta.fts_stale keeps true across processes until cleared below.
|
|
406
|
-
function
|
|
443
|
+
function rebuildFts(conn, state) {
|
|
407
444
|
return _async_to_generator(function() {
|
|
445
|
+
var _tmp;
|
|
408
446
|
return _ts_generator(this, function(_state) {
|
|
409
447
|
switch(_state.label){
|
|
410
448
|
case 0:
|
|
411
|
-
if (!state.stale) return [
|
|
412
|
-
2
|
|
413
|
-
];
|
|
414
|
-
state.orderedMacroReady = false;
|
|
415
449
|
return [
|
|
416
450
|
4,
|
|
417
451
|
conn.exec('INSTALL fts; LOAD fts;')
|
|
418
452
|
];
|
|
419
453
|
case 1:
|
|
420
454
|
_state.sent();
|
|
455
|
+
_tmp = !state.stale;
|
|
456
|
+
if (!_tmp) return [
|
|
457
|
+
3,
|
|
458
|
+
3
|
|
459
|
+
];
|
|
460
|
+
return [
|
|
461
|
+
4,
|
|
462
|
+
hasFtsArtifact(conn)
|
|
463
|
+
];
|
|
464
|
+
case 2:
|
|
465
|
+
_tmp = _state.sent();
|
|
466
|
+
_state.label = 3;
|
|
467
|
+
case 3:
|
|
468
|
+
if (_tmp) return [
|
|
469
|
+
2
|
|
470
|
+
];
|
|
471
|
+
state.stale = true;
|
|
472
|
+
state.orderedMacroReady = false;
|
|
421
473
|
return [
|
|
422
474
|
4,
|
|
423
475
|
(0, _transactionts.withTransaction)(conn, function() {
|
|
@@ -449,7 +501,7 @@ function ensureFtsFresh(conn, state) {
|
|
|
449
501
|
})();
|
|
450
502
|
})
|
|
451
503
|
];
|
|
452
|
-
case
|
|
504
|
+
case 4:
|
|
453
505
|
_state.sent();
|
|
454
506
|
state.stale = false;
|
|
455
507
|
return [
|
|
@@ -459,6 +511,86 @@ function ensureFtsFresh(conn, state) {
|
|
|
459
511
|
});
|
|
460
512
|
})();
|
|
461
513
|
}
|
|
514
|
+
function prepareFts(conn) {
|
|
515
|
+
return _async_to_generator(function() {
|
|
516
|
+
var _tmp;
|
|
517
|
+
return _ts_generator(this, function(_state) {
|
|
518
|
+
switch(_state.label){
|
|
519
|
+
case 0:
|
|
520
|
+
_tmp = [
|
|
521
|
+
conn
|
|
522
|
+
];
|
|
523
|
+
return [
|
|
524
|
+
4,
|
|
525
|
+
stateFor(conn)
|
|
526
|
+
];
|
|
527
|
+
case 1:
|
|
528
|
+
return [
|
|
529
|
+
4,
|
|
530
|
+
rebuildFts.apply(void 0, _tmp.concat([
|
|
531
|
+
_state.sent()
|
|
532
|
+
]))
|
|
533
|
+
];
|
|
534
|
+
case 2:
|
|
535
|
+
_state.sent();
|
|
536
|
+
return [
|
|
537
|
+
2
|
|
538
|
+
];
|
|
539
|
+
}
|
|
540
|
+
});
|
|
541
|
+
})();
|
|
542
|
+
}
|
|
543
|
+
function assertFtsReady(conn) {
|
|
544
|
+
return _async_to_generator(function() {
|
|
545
|
+
var state, err;
|
|
546
|
+
return _ts_generator(this, function(_state) {
|
|
547
|
+
switch(_state.label){
|
|
548
|
+
case 0:
|
|
549
|
+
return [
|
|
550
|
+
4,
|
|
551
|
+
stateFor(conn)
|
|
552
|
+
];
|
|
553
|
+
case 1:
|
|
554
|
+
state = _state.sent();
|
|
555
|
+
if (state.stale) throw new _errorsts.SenseError('INDEX_NOT_READY', 'the DuckDB lexical index is missing or stale; run `sense build` (or library build(config)) before lexical querying with build disabled');
|
|
556
|
+
_state.label = 2;
|
|
557
|
+
case 2:
|
|
558
|
+
_state.trys.push([
|
|
559
|
+
2,
|
|
560
|
+
5,
|
|
561
|
+
,
|
|
562
|
+
6
|
|
563
|
+
]);
|
|
564
|
+
return [
|
|
565
|
+
4,
|
|
566
|
+
conn.exec('LOAD fts;')
|
|
567
|
+
];
|
|
568
|
+
case 3:
|
|
569
|
+
_state.sent();
|
|
570
|
+
return [
|
|
571
|
+
4,
|
|
572
|
+
hasFtsArtifact(conn)
|
|
573
|
+
];
|
|
574
|
+
case 4:
|
|
575
|
+
if (!_state.sent()) {
|
|
576
|
+
throw new _errorsts.SenseError('INDEX_NOT_READY', 'the DuckDB lexical index artifact is missing; run `sense build` (or library build(config)) before lexical querying with build disabled');
|
|
577
|
+
}
|
|
578
|
+
return [
|
|
579
|
+
3,
|
|
580
|
+
6
|
|
581
|
+
];
|
|
582
|
+
case 5:
|
|
583
|
+
err = _state.sent();
|
|
584
|
+
if (_instanceof(err, _errorsts.SenseError)) throw err;
|
|
585
|
+
throw new _errorsts.SenseError('INDEX_NOT_READY', "the DuckDB lexical extension is not prepared (".concat(err.message, "); run `sense build` (or library build(config))"));
|
|
586
|
+
case 6:
|
|
587
|
+
return [
|
|
588
|
+
2
|
|
589
|
+
];
|
|
590
|
+
}
|
|
591
|
+
});
|
|
592
|
+
})();
|
|
593
|
+
}
|
|
462
594
|
// Field-weighted fragments (title 10 / summary 5 / text 1), with params emitted in the exact left-to-right order the assembled SQL needs for positional `?` binding.
|
|
463
595
|
// score/gate params stay in separate arrays until joined at the end, since the SQL puts every score part before every gate part; sharing one array would shift binds once a query has both words and substrings (PRINCIPLES: no-silent-modes).
|
|
464
596
|
function buildScoreAndGate(words, bareWords, phraseWords, substrings) {
|
|
@@ -588,7 +720,7 @@ function queryLexical(conn, terms, opts, state) {
|
|
|
588
720
|
];
|
|
589
721
|
return [
|
|
590
722
|
4,
|
|
591
|
-
|
|
723
|
+
assertFtsReady(conn)
|
|
592
724
|
];
|
|
593
725
|
case 1:
|
|
594
726
|
_state.sent();
|