sensemaking 0.20.0 → 0.21.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 +0 -1
- package/dist/cjs/config/access.d.cts +0 -1
- package/dist/cjs/config/access.d.ts +0 -1
- package/dist/cjs/config/access.js +10 -17
- package/dist/cjs/config/access.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 +0 -3
- package/dist/cjs/config/index.js.map +1 -1
- package/dist/cjs/config/types.d.cts +0 -3
- package/dist/cjs/config/types.d.ts +0 -3
- package/dist/cjs/config/types.js.map +1 -1
- package/dist/cjs/config/validate.js +6 -24
- package/dist/cjs/config/validate.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/links.js +4 -5
- package/dist/cjs/features/links.js.map +1 -1
- package/dist/cjs/features/sections.js +4 -1
- package/dist/cjs/features/sections.js.map +1 -1
- package/dist/cjs/store/builder.d.cts +9 -1
- package/dist/cjs/store/builder.d.ts +9 -1
- package/dist/cjs/store/builder.js +593 -2
- package/dist/cjs/store/builder.js.map +1 -1
- package/dist/cjs/store/duckdb/open.js +7 -1
- package/dist/cjs/store/duckdb/open.js.map +1 -1
- package/dist/cjs/store/duckdb/reconcile.js +30 -5
- package/dist/cjs/store/duckdb/reconcile.js.map +1 -1
- package/dist/cjs/store/embed-scope.d.cts +2 -0
- package/dist/cjs/store/embed-scope.d.ts +2 -0
- package/dist/cjs/store/embed-scope.js +85 -0
- package/dist/cjs/store/embed-scope.js.map +1 -0
- package/dist/cjs/store/feature-scope.d.cts +8 -0
- package/dist/cjs/store/feature-scope.d.ts +8 -0
- package/dist/cjs/store/feature-scope.js +107 -0
- package/dist/cjs/store/feature-scope.js.map +1 -0
- package/dist/cjs/store/open.js +193 -101
- package/dist/cjs/store/open.js.map +1 -1
- package/dist/cjs/store/preset-scope.d.cts +3 -0
- package/dist/cjs/store/preset-scope.d.ts +3 -0
- package/dist/cjs/store/preset-scope.js +293 -0
- package/dist/cjs/store/preset-scope.js.map +1 -0
- package/dist/cjs/store/reconcile.d.cts +1 -1
- package/dist/cjs/store/reconcile.d.ts +1 -1
- package/dist/cjs/store/reconcile.js +172 -178
- package/dist/cjs/store/reconcile.js.map +1 -1
- package/dist/cjs/store/signature.js +7 -5
- package/dist/cjs/store/signature.js.map +1 -1
- package/dist/cjs/store/sqlite/lexical.d.cts +1 -1
- package/dist/cjs/store/sqlite/lexical.d.ts +1 -1
- package/dist/cjs/store/sqlite/lexical.js +2 -2
- package/dist/cjs/store/sqlite/lexical.js.map +1 -1
- package/dist/cjs/store/sqlite/open.d.cts +0 -1
- package/dist/cjs/store/sqlite/open.d.ts +0 -1
- package/dist/cjs/store/sqlite/open.js +14 -231
- package/dist/cjs/store/sqlite/open.js.map +1 -1
- package/dist/cjs/store/sqlite/reconcile.d.cts +1 -1
- package/dist/cjs/store/sqlite/reconcile.d.ts +1 -1
- package/dist/cjs/store/sqlite/reconcile.js +78 -16
- package/dist/cjs/store/sqlite/reconcile.js.map +1 -1
- package/dist/cjs/store/sqlite/sql-functions.d.cts +1 -1
- package/dist/cjs/store/sqlite/sql-functions.d.ts +1 -1
- package/dist/cjs/store/sqlite/sql-functions.js +3 -3
- package/dist/cjs/store/sqlite/sql-functions.js.map +1 -1
- package/dist/cjs/store/sqlite/store.d.cts +1 -2
- package/dist/cjs/store/sqlite/store.d.ts +1 -2
- package/dist/cjs/store/sqlite/store.js +2 -3
- package/dist/cjs/store/sqlite/store.js.map +1 -1
- package/dist/cjs/store/turso/open.js +6 -0
- package/dist/cjs/store/turso/open.js.map +1 -1
- package/dist/cjs/store/turso/reconcile.js +72 -3
- package/dist/cjs/store/turso/reconcile.js.map +1 -1
- package/dist/cjs/store/types.d.cts +2 -4
- package/dist/cjs/store/types.d.ts +2 -4
- package/dist/cjs/store/types.js.map +1 -1
- package/dist/esm/config/access.d.ts +0 -1
- package/dist/esm/config/access.js +12 -17
- package/dist/esm/config/access.js.map +1 -1
- package/dist/esm/config/index.d.ts +1 -1
- package/dist/esm/config/index.js +1 -1
- package/dist/esm/config/index.js.map +1 -1
- package/dist/esm/config/types.d.ts +0 -3
- package/dist/esm/config/types.js.map +1 -1
- package/dist/esm/config/validate.js +6 -22
- package/dist/esm/config/validate.js.map +1 -1
- package/dist/esm/errors.d.ts +1 -1
- package/dist/esm/errors.js.map +1 -1
- package/dist/esm/features/links.js +3 -4
- package/dist/esm/features/links.js.map +1 -1
- package/dist/esm/features/sections.js +4 -1
- package/dist/esm/features/sections.js.map +1 -1
- package/dist/esm/store/builder.d.ts +9 -1
- package/dist/esm/store/builder.js +152 -3
- package/dist/esm/store/builder.js.map +1 -1
- package/dist/esm/store/duckdb/open.js +5 -1
- package/dist/esm/store/duckdb/open.js.map +1 -1
- package/dist/esm/store/duckdb/reconcile.js +11 -3
- package/dist/esm/store/duckdb/reconcile.js.map +1 -1
- package/dist/esm/store/embed-scope.d.ts +2 -0
- package/dist/esm/store/embed-scope.js +28 -0
- package/dist/esm/store/embed-scope.js.map +1 -0
- package/dist/esm/store/feature-scope.d.ts +8 -0
- package/dist/esm/store/feature-scope.js +49 -0
- package/dist/esm/store/feature-scope.js.map +1 -0
- package/dist/esm/store/open.js +78 -28
- package/dist/esm/store/open.js.map +1 -1
- package/dist/esm/store/preset-scope.d.ts +3 -0
- package/dist/esm/store/preset-scope.js +77 -0
- package/dist/esm/store/preset-scope.js.map +1 -0
- package/dist/esm/store/reconcile.d.ts +1 -1
- package/dist/esm/store/reconcile.js +30 -5
- package/dist/esm/store/reconcile.js.map +1 -1
- package/dist/esm/store/signature.js +7 -5
- package/dist/esm/store/signature.js.map +1 -1
- package/dist/esm/store/sqlite/lexical.d.ts +1 -1
- package/dist/esm/store/sqlite/lexical.js +4 -4
- package/dist/esm/store/sqlite/lexical.js.map +1 -1
- package/dist/esm/store/sqlite/open.d.ts +0 -1
- package/dist/esm/store/sqlite/open.js +14 -88
- package/dist/esm/store/sqlite/open.js.map +1 -1
- package/dist/esm/store/sqlite/reconcile.d.ts +1 -1
- package/dist/esm/store/sqlite/reconcile.js +14 -14
- package/dist/esm/store/sqlite/reconcile.js.map +1 -1
- package/dist/esm/store/sqlite/sql-functions.d.ts +1 -1
- package/dist/esm/store/sqlite/sql-functions.js +3 -3
- package/dist/esm/store/sqlite/sql-functions.js.map +1 -1
- package/dist/esm/store/sqlite/store.d.ts +1 -2
- package/dist/esm/store/sqlite/store.js +2 -3
- package/dist/esm/store/sqlite/store.js.map +1 -1
- package/dist/esm/store/turso/open.js +4 -0
- package/dist/esm/store/turso/open.js.map +1 -1
- package/dist/esm/store/turso/reconcile.js +6 -2
- package/dist/esm/store/turso/reconcile.js.map +1 -1
- package/dist/esm/store/types.d.ts +2 -4
- package/dist/esm/store/types.js.map +1 -1
- package/package.json +3 -2
- package/schema.json +0 -11
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/features/links.ts"],"sourcesContent":["import posix from 'node:path/posix';\nimport type { FileStat } from '../scan/index.ts';\nimport type { Connection } from '../store/types.ts';\nimport { maskRegions } from './fences.ts';\nimport type { ExtractedDoc, Feature, ReconcileDelta } from './types.ts';\n\n// links(src, target, target_base, dst, embed): target as written, target_base its indexed baseKey, dst the resolved path or NULL (a queryable dead link).\n// embed distinguishes `![[x]]`/`` from `[[x]]`/`[](x.md)` -- Obsidian's grain: a target both linked and embedded in one note is two rows.\n\n// Alias stripped after |; a leading # keeps the anchor as the target (self-link needs a\n// heading name), else the anchor splits off. Null = not a link.\nfunction parseWikilinkInner(inner: string): string | null {\n const beforeAlias = inner.split('|')[0].trim();\n if (beforeAlias.startsWith('#')) return beforeAlias.length > 1 ? beforeAlias : null;\n const target = beforeAlias.split('#')[0].trim();\n return target || null;\n}\n\n// A frontmatter value counts only when it is exactly a wikilink (\"[[X]]\") -- mid-string and\n// ![[...]] forms don't count there, per Obsidian's rule (probe-verified).\nfunction extract(_raw: string, rawBody: string, _search?: { title: string; summary: string }, data?: Record<string, unknown>): Array<{ target: string; embed: boolean }> {\n const body = /\\[\\[|\\]\\(/.test(rawBody) ? maskRegions(rawBody) : rawBody;\n const seen = new Set<string>();\n const results: Array<{ target: string; embed: boolean }> = [];\n const add = (target: string, embed: boolean) => {\n const key = `${target}\\0${embed ? '1' : '0'}`;\n if (seen.has(key)) return;\n seen.add(key);\n results.push({ target, embed });\n };\n // To the first ]], as Obsidian parses it, so a heading or alias holding a lone ] still\n // matches; anchor and alias split off in parseWikilinkInner.\n for (const m of body.matchAll(/\\[\\[(.*?)\\]\\]/g)) {\n const target = parseWikilinkInner(m[1]);\n if (target) add(target, body[(m.index ?? 0) - 1] === '!');\n }\n // Any internal destination, not only .md-suffixed: \\](Zektor) resolves like [[Zektor]] and\n // \\](#anchor) is a self-edge. External URLs and titled links (dest stops at whitespace) skip.\n for (const m of body.matchAll(/(!)?\\[[^\\]]*\\]\\(((?:[^()\\s]|\\([^()\\s]*\\))+)(?:\\s+(?:\"[^)]*\"|'[^)]*'))?\\)/g)) {\n const dest = m[2].trim();\n // External: a URI scheme prefix (mailto:, tel:, data:, https:...), protocol-relative\n // //host, a www. shorthand, or a scheme anywhere (the malformed double-paren case).\n if (!dest || dest.includes('://')) continue;\n if (/^([a-z][a-z0-9+.-]*:|\\/\\/|www\\.)/i.test(dest)) continue;\n const target = dest.startsWith('#') ? dest : dest.split('#')[0];\n if (target) add(target, m[1] === '!');\n }\n for (const value of Object.values(data ?? {})) {\n for (const item of Array.isArray(value) ? value : [value]) {\n if (typeof item !== 'string') continue;\n const m = /^\\[\\[(.*)\\]\\]$/.exec(item.trim());\n if (!m) continue;\n const target = parseWikilinkInner(m[1]);\n if (target) add(target, false);\n }\n }\n return results;\n}\n\nfunction cleanTarget(target: string): string {\n return target.replace(/\\\\/g, '/').replace(/^\\.\\//, '');\n}\n\nfunction baseKey(path: string): string {\n return posix.basename(path).replace(/\\.md$/i, '').toLowerCase();\n}\n\n// Obsidian-style: exact relative path (with/without .md), path relative to the linking note's\n// directory, then basename match (shortest path wins ties, verified against a cold-loaded vault).\nfunction resolveTarget(src: string, target: string, pathSet: Set<string>, byBase: Map<string, string[]>): string | null {\n // [[#Heading]]: a same-note anchor, always the note itself -- never depends on other files.\n if (target.startsWith('#')) return src;\n const clean = cleanTarget(target);\n const fromSrc = posix.normalize(posix.join(posix.dirname(src), clean));\n for (const candidate of [clean, `${clean}.md`, fromSrc, `${fromSrc}.md`]) {\n if (pathSet.has(candidate)) return candidate;\n }\n const candidates = byBase.get(baseKey(clean));\n if (!candidates) return null;\n // The linking note itself wins a basename collision (Obsidian resolves to self before the\n // shortest-path rule -- cold-load verified on the hub corpus).\n return candidates.includes(src) ? src : candidates[0];\n}\n\n// Shortest path wins a basename collision; equal lengths fall back to lexicographic, our own\n// deterministic tiebreak for a case Obsidian itself leaves registration-order-dependent.\nfunction buildByBase(files: FileStat[]): Map<string, string[]> {\n const byBase = new Map<string, string[]>();\n const paths = files.map((f) => f.relPath).sort((a, b) => a.length - b.length || (a < b ? -1 : a > b ? 1 : 0));\n for (const path of paths) {\n const key = baseKey(path);\n const list = byBase.get(key);\n if (list) list.push(path);\n else byBase.set(key, [path]);\n }\n return byBase;\n}\n\ninterface LinkRow {\n src: string;\n target: string;\n dst: string | null;\n embed: number;\n}\n\n// resolveTarget applied to `rows`, returning only the rows whose dst changed, so the caller\n// can write them in one runBatch call.\nfunction resolveRows(rows: LinkRow[], pathSet: Set<string>, byBase: Map<string, string[]>): LinkRow[] {\n const changed: LinkRow[] = [];\n for (const row of rows) {\n const dst = resolveTarget(row.src, row.target, pathSet, byBase);\n if (dst !== row.dst) changed.push({ ...row, dst });\n }\n return changed;\n}\n\nasync function writeResolved(db: Connection, rows: LinkRow[]): Promise<void> {\n if (rows.length === 0) return;\n await db.runBatch(\n 'UPDATE links SET dst = ? WHERE src = ? AND target = ?',\n rows.map((r) => [r.dst, r.src, r.target])\n );\n}\n\n// A new or deleted file can change any note's resolution, so re-resolve the whole table.\n// Fallback for cold builds and large deltas -- see afterReconcile's threshold.\nasync function resolveAll(db: Connection, files: FileStat[]): Promise<boolean> {\n const pathSet = new Set(files.map((f) => f.relPath));\n const byBase = buildByBase(files);\n const stmt = await db.prepare('SELECT src, target, dst, embed FROM links');\n const rows = (await stmt.all()) as unknown as LinkRow[];\n const changed = resolveRows(rows, pathSet, byBase);\n await writeResolved(db, changed);\n return changed.length > 0;\n}\n\n// Chunked so a large-but-under-threshold delta never exceeds SQLite's bound-variable limit\n// (SQLITE_MAX_VARIABLE_NUMBER, 32766); harmless headroom on DuckDB, which has no such cap.\nasync function selectIn(db: Connection, column: string, keys: string[]): Promise<LinkRow[]> {\n const rows: LinkRow[] = [];\n for (let i = 0; i < keys.length; i += 500) {\n const chunk = keys.slice(i, i + 500);\n const stmt = await db.prepare(`SELECT src, target, dst, embed FROM links WHERE ${column} IN (${chunk.map(() => '?').join(', ')})`);\n rows.push(...((await stmt.all(...chunk)) as unknown as LinkRow[]));\n }\n return rows;\n}\n\n// Re-resolves only what this reconcile could have touched: re-stored sources, links whose\n// target basename matches an added/vanished file, and links whose dst vanished -- all indexed.\nasync function resolveIncremental(db: Connection, delta: ReconcileDelta): Promise<boolean> {\n const pathSet = new Set(delta.files.map((f) => f.relPath));\n const byBase = buildByBase(delta.files);\n\n const changedBasenames = new Set<string>();\n for (const p of delta.added) changedBasenames.add(baseKey(p));\n for (const p of delta.vanished) changedBasenames.add(baseKey(p));\n\n // \\0 can't appear in a path or target, so the key never collides; a space can.\n const candidates = new Map<string, LinkRow>();\n const collect = (rows: LinkRow[]) => {\n for (const row of rows) candidates.set(`${row.src}\\0${row.target}\\0${row.embed}`, row);\n };\n collect(await selectIn(db, 'src', delta.reparsed));\n collect(await selectIn(db, 'target_base', [...changedBasenames]));\n collect(await selectIn(db, 'dst', delta.vanished));\n\n const changed = resolveRows([...candidates.values()], pathSet, byBase);\n await writeResolved(db, changed);\n return changed.length > 0;\n}\n\n// One edge per (src, target); an embed row is excluded only when the same pair also exists as\n// a link. Self-edges are dropped so PageRank mass is not self-recycled.\nexport const LINK_EDGES_SQL = `SELECT src, dst FROM links WHERE dst IS NOT NULL AND embed = 0 AND src != dst\n UNION ALL\n SELECT src, dst FROM links l WHERE dst IS NOT NULL AND embed = 1 AND src != dst\n AND NOT EXISTS (SELECT 1 FROM links l0 WHERE l0.src = l.src AND l0.target = l.target AND l0.embed = 0)`;\n\nexport function toEdges(rows: Array<{ src: string; dst: string }>): [string, string][] {\n return rows.map((r) => [r.src, r.dst]);\n}\n\n// Resolved edges, for rank (inside reconcile's afterReconcile pass).\nexport async function linkEdges(db: Connection): Promise<[string, string][]> {\n const stmt = await db.prepare(LINK_EDGES_SQL);\n return toEdges((await stmt.all()) as Array<{ src: string; dst: string }>);\n}\n\n// Records whether remove()/store() deleted any link row, since afterReconcile runs after both\n// and dstChanged alone misses the reparsed-to-zero-links case. Keyed on delta so state dies with it.\nconst removedWithLinks = new WeakMap<ReconcileDelta, boolean>();\n\nexport const links: Feature = {\n name: 'links',\n async schema(db) {\n await db.exec('CREATE TABLE IF NOT EXISTS links (src TEXT, target TEXT, target_base TEXT, dst TEXT, embed INTEGER, PRIMARY KEY (src, target, embed))');\n await db.exec('CREATE INDEX IF NOT EXISTS links_dst ON links(dst)');\n await db.exec('CREATE INDEX IF NOT EXISTS links_target_base ON links(target_base)');\n },\n extract,\n // Reparsed docs are diffed in store() instead of wiped here: delete-and-reinsert resets dst\n // to NULL, making every touch-only reparse look like an edge change and recompute PageRank.\n async remove(db, paths, delta) {\n const vanishedSet = new Set(delta.vanished);\n const vanished = paths.filter((p) => vanishedSet.has(p));\n if (vanished.length === 0) return;\n const existingRows = await selectIn(db, 'src', vanished);\n await db.runBatch(\n 'DELETE FROM links WHERE src = ?',\n vanished.map((p) => [p])\n );\n if (existingRows.length > 0) removedWithLinks.set(delta, true);\n },\n async store(db, docs: ExtractedDoc[], delta) {\n const byPath = new Map(docs.map((d) => [d.path, d.extracted as Array<{ target: string; embed: boolean }>]));\n const addedSet = new Set(delta.added);\n const reparsedExisting = docs.map((d) => d.path).filter((p) => !addedSet.has(p));\n\n // Stale rows (target/embed pairs missing from the new parse) are diffed in JS from one\n // bulk SELECT, so this pass costs one query plus one batched DELETE regardless of file count.\n const existingRows = await selectIn(db, 'src', reparsedExisting);\n const staleRows = existingRows.filter((row) => {\n const targets = byPath.get(row.src) ?? [];\n return !targets.some((t) => t.target === row.target && (t.embed ? 1 : 0) === row.embed);\n });\n if (staleRows.length > 0) {\n await db.runBatch(\n 'DELETE FROM links WHERE src = ? AND target = ? AND embed = ?',\n staleRows.map((r) => [r.src, r.target, r.embed])\n );\n removedWithLinks.set(delta, true);\n }\n\n // Upsert preserves dst on surviving rows; only new rows start at NULL. A same-note anchor\n // gets no target_base, so SQL's `IN` excludes it from resolveIncremental's lookup.\n const upsertRows: unknown[][] = [];\n for (const [path, targets] of byPath) {\n for (const { target, embed } of targets) upsertRows.push([path, target, target.startsWith('#') ? null : baseKey(cleanTarget(target)), embed ? 1 : 0]);\n }\n if (upsertRows.length > 0) {\n await db.runBatch('INSERT INTO links (src, target, target_base, dst, embed) VALUES (?, ?, ?, NULL, ?) ON CONFLICT(src, target, embed) DO UPDATE SET target_base = excluded.target_base', upsertRows);\n }\n },\n async afterReconcile(db, delta) {\n // Any deleted rows mean the edge set shrank -- whether the file vanished or was reparsed\n // down to fewer/no links.\n const removeHadLinks = removedWithLinks.get(delta) ?? false;\n\n const churn = delta.reparsed.length + delta.vanished.length;\n // Past this share of the tree, a full pass is the only one guaranteed to match\n // resolveTarget's ambiguity rules. A cold build clears the threshold on its own.\n const large = delta.files.length === 0 || churn > 0.2 * delta.files.length;\n\n const dstChanged = large ? await resolveAll(db, delta.files) : await resolveIncremental(db, delta);\n delta.linksChanged = dstChanged || removeHadLinks;\n },\n};\n"],"names":["LINK_EDGES_SQL","linkEdges","links","toEdges","parseWikilinkInner","inner","beforeAlias","split","trim","startsWith","length","target","extract","_raw","rawBody","_search","data","body","test","maskRegions","seen","Set","results","add","embed","key","has","push","matchAll","m","index","dest","includes","Object","values","value","Array","isArray","item","exec","cleanTarget","replace","baseKey","path","posix","basename","toLowerCase","resolveTarget","src","pathSet","byBase","clean","fromSrc","normalize","join","dirname","candidate","candidates","get","buildByBase","files","Map","paths","map","f","relPath","sort","a","b","list","set","resolveRows","rows","changed","row","dst","writeResolved","db","runBatch","r","resolveAll","stmt","prepare","all","selectIn","column","keys","i","chunk","slice","resolveIncremental","delta","changedBasenames","p","collect","added","vanished","reparsed","removedWithLinks","WeakMap","name","schema","remove","vanishedSet","existingRows","filter","store","docs","byPath","addedSet","reparsedExisting","staleRows","upsertRows","targets","d","extracted","some","t","afterReconcile","removeHadLinks","churn","large","dstChanged","linksChanged"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/features/links.ts"],"sourcesContent":["import posix from 'node:path/posix';\nimport type { FileStat } from '../scan/index.ts';\nimport type { Connection } from '../store/types.ts';\nimport { maskRegions } from './fences.ts';\nimport type { ExtractedDoc, Feature, ReconcileDelta } from './types.ts';\n\n// links(src, target, target_base, dst, embed): target as written, target_base its indexed baseKey, dst the resolved path or NULL (a queryable dead link).\n// embed distinguishes `![[x]]`/`` from `[[x]]`/`[](x.md)` -- Obsidian's grain: a target both linked and embedded in one note is two rows.\n\n// Alias stripped after |; a leading # keeps the anchor as the target (self-link needs a\n// heading name), else the anchor splits off. Null = not a link.\nfunction parseWikilinkInner(inner: string): string | null {\n const beforeAlias = inner.split('|')[0].trim();\n if (beforeAlias.startsWith('#')) return beforeAlias.length > 1 ? beforeAlias : null;\n const target = beforeAlias.split('#')[0].trim();\n return target || null;\n}\n\n// A frontmatter value counts only when it is exactly a wikilink (\"[[X]]\") -- mid-string and\n// ![[...]] forms don't count there, per Obsidian's rule (probe-verified).\nfunction extract(_raw: string, rawBody: string, _search?: { title: string; summary: string }, data?: Record<string, unknown>): Array<{ target: string; embed: boolean }> {\n const body = /\\[\\[|\\]\\(/.test(rawBody) ? maskRegions(rawBody) : rawBody;\n const seen = new Set<string>();\n const results: Array<{ target: string; embed: boolean }> = [];\n const add = (target: string, embed: boolean) => {\n const key = `${target}\\0${embed ? '1' : '0'}`;\n if (seen.has(key)) return;\n seen.add(key);\n results.push({ target, embed });\n };\n // To the first ]], as Obsidian parses it, so a heading or alias holding a lone ] still\n // matches; anchor and alias split off in parseWikilinkInner.\n for (const m of body.matchAll(/\\[\\[(.*?)\\]\\]/g)) {\n const target = parseWikilinkInner(m[1]);\n if (target) add(target, body[(m.index ?? 0) - 1] === '!');\n }\n // Any internal destination, not only .md-suffixed: \\](Zektor) resolves like [[Zektor]] and\n // \\](#anchor) is a self-edge. External URLs and titled links (dest stops at whitespace) skip.\n for (const m of body.matchAll(/(!)?\\[[^\\]]*\\]\\(((?:[^()\\s]|\\([^()\\s]*\\))+)(?:\\s+(?:\"[^)]*\"|'[^)]*'))?\\)/g)) {\n const dest = m[2].trim();\n // External: a URI scheme prefix (mailto:, tel:, data:, https:...), protocol-relative\n // //host, a www. shorthand, or a scheme anywhere (the malformed double-paren case).\n if (!dest || dest.includes('://')) continue;\n if (/^([a-z][a-z0-9+.-]*:|\\/\\/|www\\.)/i.test(dest)) continue;\n const target = dest.startsWith('#') ? dest : dest.split('#')[0];\n if (target) add(target, m[1] === '!');\n }\n for (const value of Object.values(data ?? {})) {\n for (const item of Array.isArray(value) ? value : [value]) {\n if (typeof item !== 'string') continue;\n const m = /^\\[\\[(.*)\\]\\]$/.exec(item.trim());\n if (!m) continue;\n const target = parseWikilinkInner(m[1]);\n if (target) add(target, false);\n }\n }\n return results;\n}\n\nfunction cleanTarget(target: string): string {\n return target.replace(/\\\\/g, '/').replace(/^\\.\\//, '');\n}\n\nfunction baseKey(path: string): string {\n return posix.basename(path).replace(/\\.md$/i, '').toLowerCase();\n}\n\n// Obsidian-style: exact relative path (with/without .md), path relative to the linking note's\n// directory, then basename match (shortest path wins ties, verified against a cold-loaded vault).\nfunction resolveTarget(src: string, target: string, pathSet: Set<string>, byBase: Map<string, string[]>): string | null {\n // [[#Heading]]: a same-note anchor, always the note itself -- never depends on other files.\n if (target.startsWith('#')) return src;\n const clean = cleanTarget(target);\n const fromSrc = posix.normalize(posix.join(posix.dirname(src), clean));\n for (const candidate of [clean, `${clean}.md`, fromSrc, `${fromSrc}.md`]) {\n if (pathSet.has(candidate)) return candidate;\n }\n const candidates = byBase.get(baseKey(clean));\n if (!candidates) return null;\n // The linking note itself wins a basename collision (Obsidian resolves to self before the\n // shortest-path rule -- cold-load verified on the hub corpus).\n return candidates.includes(src) ? src : candidates[0];\n}\n\n// Shortest path wins a basename collision; equal lengths fall back to lexicographic, our own\n// deterministic tiebreak for a case Obsidian itself leaves registration-order-dependent.\nfunction buildByBase(files: FileStat[]): Map<string, string[]> {\n const byBase = new Map<string, string[]>();\n const paths = files.map((f) => f.relPath).sort((a, b) => a.length - b.length || (a < b ? -1 : a > b ? 1 : 0));\n for (const path of paths) {\n const key = baseKey(path);\n const list = byBase.get(key);\n if (list) list.push(path);\n else byBase.set(key, [path]);\n }\n return byBase;\n}\n\ninterface LinkRow {\n src: string;\n target: string;\n dst: string | null;\n embed: number;\n}\n\n// resolveTarget applied to `rows`, returning only the rows whose dst changed, so the caller\n// can write them in one runBatch call.\nfunction resolveRows(rows: LinkRow[], pathSet: Set<string>, byBase: Map<string, string[]>): LinkRow[] {\n const changed: LinkRow[] = [];\n for (const row of rows) {\n const dst = resolveTarget(row.src, row.target, pathSet, byBase);\n if (dst !== row.dst) changed.push({ ...row, dst });\n }\n return changed;\n}\n\nasync function writeResolved(db: Connection, rows: LinkRow[]): Promise<void> {\n if (rows.length === 0) return;\n await db.runBatch(\n 'UPDATE links SET dst = ? WHERE src = ? AND target = ?',\n rows.map((r) => [r.dst, r.src, r.target])\n );\n}\n\n// A new or deleted file can change any note's resolution, so re-resolve the whole table.\n// Fallback for cold builds and large deltas -- see afterReconcile's threshold.\nasync function resolveAll(db: Connection, files: FileStat[]): Promise<boolean> {\n const pathSet = new Set(files.map((f) => f.relPath));\n const byBase = buildByBase(files);\n const stmt = await db.prepare('SELECT src, target, dst, embed FROM links');\n const rows = (await stmt.all()) as unknown as LinkRow[];\n const changed = resolveRows(rows, pathSet, byBase);\n await writeResolved(db, changed);\n return changed.length > 0;\n}\n\n// Chunked so a large-but-under-threshold delta never exceeds SQLite's bound-variable limit\n// (SQLITE_MAX_VARIABLE_NUMBER, 32766); harmless headroom on DuckDB, which has no such cap.\nasync function selectIn(db: Connection, column: string, keys: string[]): Promise<LinkRow[]> {\n const rows: LinkRow[] = [];\n for (let i = 0; i < keys.length; i += 500) {\n const chunk = keys.slice(i, i + 500);\n const stmt = await db.prepare(`SELECT src, target, dst, embed FROM links WHERE ${column} IN (${chunk.map(() => '?').join(', ')})`);\n rows.push(...((await stmt.all(...chunk)) as unknown as LinkRow[]));\n }\n return rows;\n}\n\n// Re-resolves only what this reconcile could have touched: re-stored sources, links whose\n// target basename matches an added/vanished file, and links whose dst vanished -- all indexed.\nasync function resolveIncremental(db: Connection, delta: ReconcileDelta): Promise<boolean> {\n const pathSet = new Set(delta.files.map((f) => f.relPath));\n const byBase = buildByBase(delta.files);\n\n const changedBasenames = new Set<string>();\n for (const p of delta.added) changedBasenames.add(baseKey(p));\n for (const p of delta.vanished) changedBasenames.add(baseKey(p));\n\n // \\0 can't appear in a path or target, so the key never collides; a space can.\n const candidates = new Map<string, LinkRow>();\n const collect = (rows: LinkRow[]) => {\n for (const row of rows) candidates.set(`${row.src}\\0${row.target}\\0${row.embed}`, row);\n };\n collect(await selectIn(db, 'src', delta.reparsed));\n collect(await selectIn(db, 'target_base', [...changedBasenames]));\n collect(await selectIn(db, 'dst', delta.vanished));\n\n const changed = resolveRows([...candidates.values()], pathSet, byBase);\n await writeResolved(db, changed);\n return changed.length > 0;\n}\n\n// One edge per (src, target); an embed row is excluded only when the same pair also exists as\n// a link. Self-edges are dropped so PageRank mass is not self-recycled.\nexport const LINK_EDGES_SQL = `SELECT src, dst FROM links WHERE dst IS NOT NULL AND embed = 0 AND src != dst\n UNION ALL\n SELECT src, dst FROM links l WHERE dst IS NOT NULL AND embed = 1 AND src != dst\n AND NOT EXISTS (SELECT 1 FROM links l0 WHERE l0.src = l.src AND l0.target = l.target AND l0.embed = 0)`;\n\nexport function toEdges(rows: Array<{ src: string; dst: string }>): [string, string][] {\n return rows.map((r) => [r.src, r.dst]);\n}\n\n// Resolved edges, for rank (inside reconcile's afterReconcile pass).\nexport async function linkEdges(db: Connection): Promise<[string, string][]> {\n const stmt = await db.prepare(LINK_EDGES_SQL);\n return toEdges((await stmt.all()) as Array<{ src: string; dst: string }>);\n}\n\n// Records whether remove()/store() deleted any link row, since afterReconcile runs after both\n// and dstChanged alone misses the reparsed-to-zero-links case. Keyed on delta so state dies with it.\nconst removedWithLinks = new WeakMap<ReconcileDelta, boolean>();\n\nexport const links: Feature = {\n name: 'links',\n async schema(db) {\n await db.exec('CREATE TABLE IF NOT EXISTS links (src TEXT, target TEXT, target_base TEXT, dst TEXT, embed INTEGER, PRIMARY KEY (src, target, embed))');\n await db.exec('CREATE INDEX IF NOT EXISTS links_dst ON links(dst)');\n await db.exec('CREATE INDEX IF NOT EXISTS links_target_base ON links(target_base)');\n },\n extract,\n // Reparsed docs are diffed in store() instead of wiped here: delete-and-reinsert resets dst\n // to NULL, making every touch-only reparse look like an edge change and recompute PageRank.\n async remove(db, paths, delta) {\n const vanishedSet = new Set(delta.vanished);\n const vanished = paths.filter((p) => vanishedSet.has(p));\n if (vanished.length === 0) return;\n const existingRows = await selectIn(db, 'src', vanished);\n await db.runBatch(\n 'DELETE FROM links WHERE src = ?',\n vanished.map((p) => [p])\n );\n if (existingRows.length > 0) removedWithLinks.set(delta, true);\n },\n async store(db, docs: ExtractedDoc[], delta) {\n const byPath = new Map(docs.map((d) => [d.path, d.extracted as Array<{ target: string; embed: boolean }>]));\n const addedSet = new Set(delta.added);\n const reparsedExisting = docs.map((d) => d.path).filter((p) => !addedSet.has(p));\n\n // Stale rows (target/embed pairs missing from the new parse) are diffed in JS from one\n // bulk SELECT, so this pass costs one query plus one batched DELETE regardless of file count.\n const existingRows = await selectIn(db, 'src', reparsedExisting);\n const staleRows = existingRows.filter((row) => {\n const targets = byPath.get(row.src) ?? [];\n return !targets.some((t) => t.target === row.target && (t.embed ? 1 : 0) === row.embed);\n });\n if (staleRows.length > 0) {\n await db.runBatch(\n 'DELETE FROM links WHERE src = ? AND target = ? AND embed = ?',\n staleRows.map((r) => [r.src, r.target, r.embed])\n );\n removedWithLinks.set(delta, true);\n }\n\n // Upsert preserves dst on surviving rows; only new rows start at NULL. A same-note anchor\n // gets no target_base, so SQL's `IN` excludes it from resolveIncremental's lookup.\n const upsertRows: unknown[][] = [];\n for (const [path, targets] of byPath) {\n for (const { target, embed } of targets) upsertRows.push([path, target, target.startsWith('#') ? null : baseKey(cleanTarget(target)), embed ? 1 : 0]);\n }\n if (upsertRows.length > 0) {\n await db.runBatch('INSERT INTO links (src, target, target_base, dst, embed) VALUES (?, ?, ?, NULL, ?) ON CONFLICT(src, target, embed) DO UPDATE SET target_base = excluded.target_base', upsertRows);\n }\n },\n async afterReconcile(db, delta) {\n // Any deleted rows mean the edge set shrank -- whether the file vanished or was reparsed\n // down to fewer/no links.\n const removeHadLinks = removedWithLinks.get(delta) ?? false;\n\n // A cold build is the only case a full pass wins. Measured 2026-09-01 on 6,566 notes, resolve\n // time alone: full is flat near 90ms at any churn, incremental 7ms at 10 files and 30ms at 2,000.\n const large = delta.files.length === 0 || delta.added.length === delta.files.length;\n\n const dstChanged = large ? await resolveAll(db, delta.files) : await resolveIncremental(db, delta);\n delta.linksChanged = dstChanged || removeHadLinks;\n },\n};\n"],"names":["LINK_EDGES_SQL","linkEdges","links","toEdges","parseWikilinkInner","inner","beforeAlias","split","trim","startsWith","length","target","extract","_raw","rawBody","_search","data","body","test","maskRegions","seen","Set","results","add","embed","key","has","push","matchAll","m","index","dest","includes","Object","values","value","Array","isArray","item","exec","cleanTarget","replace","baseKey","path","posix","basename","toLowerCase","resolveTarget","src","pathSet","byBase","clean","fromSrc","normalize","join","dirname","candidate","candidates","get","buildByBase","files","Map","paths","map","f","relPath","sort","a","b","list","set","resolveRows","rows","changed","row","dst","writeResolved","db","runBatch","r","resolveAll","stmt","prepare","all","selectIn","column","keys","i","chunk","slice","resolveIncremental","delta","changedBasenames","p","collect","added","vanished","reparsed","removedWithLinks","WeakMap","name","schema","remove","vanishedSet","existingRows","filter","store","docs","byPath","addedSet","reparsedExisting","staleRows","upsertRows","targets","d","extracted","some","t","afterReconcile","removeHadLinks","large","dstChanged","linksChanged"],"mappings":"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"}
|
|
@@ -248,9 +248,12 @@ var sections = {
|
|
|
248
248
|
if (rows.length === 0) return [
|
|
249
249
|
2
|
|
250
250
|
];
|
|
251
|
+
// DO NOTHING, not a bare INSERT: reconcile's added/touched split is decided before this
|
|
252
|
+
// write's lock, so a path called "added" here can already have this row from a concurrent
|
|
253
|
+
// reconcile that committed first -- same file, same parse, same row.
|
|
251
254
|
return [
|
|
252
255
|
4,
|
|
253
|
-
db.runBatch('INSERT INTO sections ("path", idx, level, heading, start_line, end_line, tokens) VALUES (?, ?, ?, ?, ?, ?, ?)', rows)
|
|
256
|
+
db.runBatch('INSERT INTO sections ("path", idx, level, heading, start_line, end_line, tokens) VALUES (?, ?, ?, ?, ?, ?, ?) ON CONFLICT("path", idx) DO NOTHING', rows)
|
|
254
257
|
];
|
|
255
258
|
case 1:
|
|
256
259
|
_state.sent();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/features/sections.ts"],"sourcesContent":["import type { Block } from '../chunk/index.ts';\nimport { estimateTokens, parse } from '../chunk/index.ts';\nimport { countLines } from '../scan/frontmatter.ts';\nimport type { Feature } from './types.ts';\n\n// sections(path, idx, level, heading, start_line, end_line, tokens): the heading outline,\n// 1-indexed over the raw file so a row is a direct Read range; tokens is estimateTokens (D5), CJK-aware.\n\nexport interface Section {\n level: number;\n heading: string;\n startLine: number;\n endLine: number;\n tokens: number;\n}\n\n// Heading blocks parse() already found (mdast/CommonMark fences), offset back onto the raw file;\n// a section runs to just before the next heading, or EOF.\nfunction sectionsFromBlocks(blocks: Block[], raw: string, body: string): Section[] {\n const rawLines = raw.split('\\n');\n const offset = rawLines.length - countLines(body);\n const found: Section[] = blocks.filter((b) => b.type === 'heading').map((b) => ({ level: b.depth ?? 1, heading: (b.text ?? '').trim(), startLine: b.startLine + offset, endLine: rawLines.length, tokens: 0 }));\n for (let s = 0; s < found.length; s++) {\n if (s + 1 < found.length) found[s].endLine = found[s + 1].startLine - 1;\n const text = rawLines.slice(found[s].startLine - 1, found[s].endLine).join('\\n');\n found[s].tokens = Math.ceil(estimateTokens(text));\n }\n return found;\n}\n\nexport const sections: Feature = {\n name: 'sections',\n async schema(db) {\n await db.exec(`CREATE TABLE IF NOT EXISTS sections (\"path\" TEXT, idx INTEGER, level INTEGER, heading TEXT, start_line INTEGER, end_line INTEGER, tokens INTEGER, PRIMARY KEY (\"path\", idx))`);\n },\n extract(raw, body, _search, _data, _cfg, blocks) {\n return sectionsFromBlocks(blocks ?? parse(body), raw, body);\n },\n async remove(db, paths) {\n if (paths.length === 0) return;\n await db.runBatch(\n 'DELETE FROM sections WHERE \"path\" = ?',\n paths.map((p) => [p])\n );\n },\n async store(db, docs) {\n const rows: unknown[][] = [];\n for (const { path, extracted } of docs) (extracted as Section[]).forEach((s, idx) => rows.push([path, idx, s.level, s.heading, s.startLine, s.endLine, s.tokens]));\n if (rows.length === 0) return;\n await db.runBatch('INSERT INTO sections (\"path\", idx, level, heading, start_line, end_line, tokens) VALUES (?, ?, ?, ?, ?, ?, ?)', rows);\n },\n};\n"],"names":["sections","sectionsFromBlocks","blocks","raw","body","rawLines","split","offset","length","countLines","found","filter","b","type","map","level","depth","heading","text","trim","startLine","endLine","tokens","s","slice","join","Math","ceil","estimateTokens","name","schema","db","exec","extract","_search","_data","_cfg","parse","remove","paths","runBatch","p","store","docs","rows","path","extracted","forEach","idx","push"],"mappings":";;;;+BA8BaA;;;eAAAA;;;uBA7ByB;6BACX;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAc3B,iGAAiG;AACjG,0DAA0D;AAC1D,SAASC,mBAAmBC,MAAe,EAAEC,GAAW,EAAEC,IAAY;IACpE,IAAMC,WAAWF,IAAIG,KAAK,CAAC;IAC3B,IAAMC,SAASF,SAASG,MAAM,GAAGC,IAAAA,yBAAU,EAACL;IAC5C,IAAMM,QAAmBR,OAAOS,MAAM,CAAC,SAACC;eAAMA,EAAEC,IAAI,KAAK;OAAWC,GAAG,CAAC,SAACF;YAAgBA,UAAwBA;eAAjC;YAAEG,KAAK,GAAEH,WAAAA,EAAEI,KAAK,cAAPJ,sBAAAA,WAAW;YAAGK,SAAS,EAACL,UAAAA,EAAEM,IAAI,cAANN,qBAAAA,UAAU,IAAIO,IAAI;YAAIC,WAAWR,EAAEQ,SAAS,GAAGb;YAAQc,SAAShB,SAASG,MAAM;YAAEc,QAAQ;QAAE;;IAC5M,IAAK,IAAIC,IAAI,GAAGA,IAAIb,MAAMF,MAAM,EAAEe,IAAK;QACrC,IAAIA,IAAI,IAAIb,MAAMF,MAAM,EAAEE,KAAK,CAACa,EAAE,CAACF,OAAO,GAAGX,KAAK,CAACa,IAAI,EAAE,CAACH,SAAS,GAAG;QACtE,IAAMF,OAAOb,SAASmB,KAAK,CAACd,KAAK,CAACa,EAAE,CAACH,SAAS,GAAG,GAAGV,KAAK,CAACa,EAAE,CAACF,OAAO,EAAEI,IAAI,CAAC;QAC3Ef,KAAK,CAACa,EAAE,CAACD,MAAM,GAAGI,KAAKC,IAAI,CAACC,IAAAA,uBAAc,EAACV;IAC7C;IACA,OAAOR;AACT;AAEO,IAAMV,WAAoB;IAC/B6B,MAAM;IACAC,QAAN,SAAMA,OAAOC,EAAE;;;;;wBACb;;4BAAMA,GAAGC,IAAI,CAAC;;;wBAAd;;;;;;QACF;;IACAC,SAAAA,SAAAA,QAAQ9B,GAAG,EAAEC,IAAI,EAAE8B,OAAO,EAAEC,KAAK,EAAEC,IAAI,EAAElC,MAAM;QAC7C,OAAOD,mBAAmBC,mBAAAA,oBAAAA,SAAUmC,IAAAA,cAAK,EAACjC,OAAOD,KAAKC;IACxD;IACMkC,QAAN,SAAMA,OAAOP,EAAE,EAAEQ,KAAK;;;;;wBACpB,IAAIA,MAAM/B,MAAM,KAAK,GAAG;;;wBACxB;;4BAAMuB,GAAGS,QAAQ,CACf,yCACAD,MAAMzB,GAAG,CAAC,SAAC2B;uCAAM;oCAACA;iCAAE;;;;wBAFtB;;;;;;QAIF;;IACMC,OAAN,SAAMA,MAAMX,EAAE,EAAEY,IAAI;;gBACZC,MACD,2BAAA,mBAAA,uBAAA,WAAA;;;;wBADCA;wBACD,kCAAA,2BAAA;;;gCAAA,kBAAA,aAAQC,mBAAAA,MAAMC,wBAAAA;gCAAsBA,UAAwBC,OAAO,CAAC,SAACxB,GAAGyB;2CAAQJ,KAAKK,IAAI,CAAC;wCAACJ;wCAAMG;wCAAKzB,EAAER,KAAK;wCAAEQ,EAAEN,OAAO;wCAAEM,EAAEH,SAAS;wCAAEG,EAAEF,OAAO;wCAAEE,EAAED,MAAM;qCAAC;;;4BAAhK,IAAK,YAA6BqB,2BAA7B,6BAAA,QAAA,yBAAA;;4BAAA;4BAAA;;;qCAAA,6BAAA;oCAAA;;;oCAAA;0CAAA;;;;wBACL,IAAIC,KAAKpC,MAAM,KAAK,GAAG;;;wBACvB;;4BAAMuB,GAAGS,QAAQ,CAAC,
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/features/sections.ts"],"sourcesContent":["import type { Block } from '../chunk/index.ts';\nimport { estimateTokens, parse } from '../chunk/index.ts';\nimport { countLines } from '../scan/frontmatter.ts';\nimport type { Feature } from './types.ts';\n\n// sections(path, idx, level, heading, start_line, end_line, tokens): the heading outline,\n// 1-indexed over the raw file so a row is a direct Read range; tokens is estimateTokens (D5), CJK-aware.\n\nexport interface Section {\n level: number;\n heading: string;\n startLine: number;\n endLine: number;\n tokens: number;\n}\n\n// Heading blocks parse() already found (mdast/CommonMark fences), offset back onto the raw file;\n// a section runs to just before the next heading, or EOF.\nfunction sectionsFromBlocks(blocks: Block[], raw: string, body: string): Section[] {\n const rawLines = raw.split('\\n');\n const offset = rawLines.length - countLines(body);\n const found: Section[] = blocks.filter((b) => b.type === 'heading').map((b) => ({ level: b.depth ?? 1, heading: (b.text ?? '').trim(), startLine: b.startLine + offset, endLine: rawLines.length, tokens: 0 }));\n for (let s = 0; s < found.length; s++) {\n if (s + 1 < found.length) found[s].endLine = found[s + 1].startLine - 1;\n const text = rawLines.slice(found[s].startLine - 1, found[s].endLine).join('\\n');\n found[s].tokens = Math.ceil(estimateTokens(text));\n }\n return found;\n}\n\nexport const sections: Feature = {\n name: 'sections',\n async schema(db) {\n await db.exec(`CREATE TABLE IF NOT EXISTS sections (\"path\" TEXT, idx INTEGER, level INTEGER, heading TEXT, start_line INTEGER, end_line INTEGER, tokens INTEGER, PRIMARY KEY (\"path\", idx))`);\n },\n extract(raw, body, _search, _data, _cfg, blocks) {\n return sectionsFromBlocks(blocks ?? parse(body), raw, body);\n },\n async remove(db, paths) {\n if (paths.length === 0) return;\n await db.runBatch(\n 'DELETE FROM sections WHERE \"path\" = ?',\n paths.map((p) => [p])\n );\n },\n async store(db, docs) {\n const rows: unknown[][] = [];\n for (const { path, extracted } of docs) (extracted as Section[]).forEach((s, idx) => rows.push([path, idx, s.level, s.heading, s.startLine, s.endLine, s.tokens]));\n if (rows.length === 0) return;\n // DO NOTHING, not a bare INSERT: reconcile's added/touched split is decided before this\n // write's lock, so a path called \"added\" here can already have this row from a concurrent\n // reconcile that committed first -- same file, same parse, same row.\n await db.runBatch('INSERT INTO sections (\"path\", idx, level, heading, start_line, end_line, tokens) VALUES (?, ?, ?, ?, ?, ?, ?) ON CONFLICT(\"path\", idx) DO NOTHING', rows);\n },\n};\n"],"names":["sections","sectionsFromBlocks","blocks","raw","body","rawLines","split","offset","length","countLines","found","filter","b","type","map","level","depth","heading","text","trim","startLine","endLine","tokens","s","slice","join","Math","ceil","estimateTokens","name","schema","db","exec","extract","_search","_data","_cfg","parse","remove","paths","runBatch","p","store","docs","rows","path","extracted","forEach","idx","push"],"mappings":"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"}
|
|
@@ -1,10 +1,18 @@
|
|
|
1
1
|
import type { Config } from '../config/index.js';
|
|
2
|
+
import type { EmbedChangeKind } from './embed-scope.js';
|
|
3
|
+
import type { FeatureToggle } from './feature-scope.js';
|
|
2
4
|
import type { Connection, ReconcileDialect } from './types.js';
|
|
3
5
|
export interface Builder {
|
|
4
|
-
build(): Promise<{
|
|
6
|
+
build(forcedPaths?: ReadonlySet<string>): Promise<{
|
|
5
7
|
parsed: number;
|
|
6
8
|
warnings: string[];
|
|
7
9
|
}>;
|
|
10
|
+
invalidate(kind: EmbedChangeKind): Promise<{
|
|
11
|
+
parsed: number;
|
|
12
|
+
}>;
|
|
13
|
+
invalidateFeatures(toggles: FeatureToggle[]): Promise<{
|
|
14
|
+
parsed: number;
|
|
15
|
+
}>;
|
|
8
16
|
close(): Promise<void>;
|
|
9
17
|
readonly poolsCreated: number;
|
|
10
18
|
}
|
|
@@ -1,10 +1,18 @@
|
|
|
1
1
|
import type { Config } from '../config/index.js';
|
|
2
|
+
import type { EmbedChangeKind } from './embed-scope.js';
|
|
3
|
+
import type { FeatureToggle } from './feature-scope.js';
|
|
2
4
|
import type { Connection, ReconcileDialect } from './types.js';
|
|
3
5
|
export interface Builder {
|
|
4
|
-
build(): Promise<{
|
|
6
|
+
build(forcedPaths?: ReadonlySet<string>): Promise<{
|
|
5
7
|
parsed: number;
|
|
6
8
|
warnings: string[];
|
|
7
9
|
}>;
|
|
10
|
+
invalidate(kind: EmbedChangeKind): Promise<{
|
|
11
|
+
parsed: number;
|
|
12
|
+
}>;
|
|
13
|
+
invalidateFeatures(toggles: FeatureToggle[]): Promise<{
|
|
14
|
+
parsed: number;
|
|
15
|
+
}>;
|
|
8
16
|
close(): Promise<void>;
|
|
9
17
|
readonly poolsCreated: number;
|
|
10
18
|
}
|