@wrongstack/tools 0.320.1 → 1.0.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/dist/_danger-detect.d.ts +8 -0
- package/dist/_syntax-check.d.ts +1 -2
- package/dist/audit.d.ts +4 -5
- package/dist/audit.js +6 -6
- package/dist/auto-proceed-loop-guard.js +9 -160
- package/dist/bash-kill-guard.d.ts +2 -3
- package/dist/bash.d.ts +2 -3
- package/dist/bash.js +4 -4
- package/dist/batch-tool-use.d.ts +2 -3
- package/dist/batch-tool-use.js +1 -1
- package/dist/browser/index.d.ts +1 -1
- package/dist/browser/index.js +1 -1
- package/dist/browser/tools.d.ts +56 -45
- package/dist/builtin.js +50 -50
- package/dist/{chunk-T77XOX7E.js → chunk-24T5XIJU.js} +1 -1
- package/dist/{chunk-DTQ75VBC.js → chunk-2CTZW6JQ.js} +2 -2
- package/dist/chunk-37QKUQ2Z.js +171 -0
- package/dist/{chunk-KWXIKGE3.js → chunk-3D5DJWOE.js} +3 -3
- package/dist/{chunk-XSSFBS5I.js → chunk-4ERMPDHV.js} +11 -6
- package/dist/{chunk-QSNVDHOZ.js → chunk-4WPBS45A.js} +4 -5
- package/dist/{chunk-4CQWNZ62.js → chunk-5ITQPCLC.js} +2 -2
- package/dist/{chunk-B4HTSV6Z.js → chunk-5KS24LTS.js} +11 -11
- package/dist/{chunk-QPNYDH5B.js → chunk-62OAECEQ.js} +29 -7
- package/dist/{chunk-DFQDJT22.js → chunk-6GOZTS6F.js} +3 -3
- package/dist/{chunk-34VLZ35Z.js → chunk-7HL23T3T.js} +63 -10
- package/dist/{chunk-HFXSNKCV.js → chunk-7JJFC6CT.js} +1 -1
- package/dist/{chunk-NDIT3SBZ.js → chunk-7N5U2RAU.js} +2 -2
- package/dist/{chunk-QBV725YG.js → chunk-7ODZTPCU.js} +2 -2
- package/dist/{chunk-4BABEJC2.js → chunk-AB2CAUOP.js} +64 -53
- package/dist/{chunk-6AAOT4PW.js → chunk-AQ5YBURX.js} +16 -4
- package/dist/{chunk-ZMW6WJFT.js → chunk-ASEXQRA7.js} +3 -3
- package/dist/{chunk-FRN7TIAA.js → chunk-B3MGJBFI.js} +1 -1
- package/dist/{chunk-JLYA4X7K.js → chunk-CGXTR34H.js} +21 -6
- package/dist/{chunk-IU4DV2PA.js → chunk-CHEK3ASV.js} +6 -3
- package/dist/{chunk-GOIZNNOA.js → chunk-DJYLI7EW.js} +1 -1
- package/dist/{chunk-Z6IHMJMC.js → chunk-DK4J2WMH.js} +11 -11
- package/dist/{chunk-OYP27E3I.js → chunk-DRRY6SCM.js} +47 -20
- package/dist/{chunk-BK732J7I.js → chunk-FBUP524S.js} +4 -4
- package/dist/{chunk-NYRLWDT5.js → chunk-FVM3O4JQ.js} +1 -1
- package/dist/chunk-FYDBUVQD.js +244 -0
- package/dist/{chunk-PV6HIZQD.js → chunk-GDDXX27P.js} +50 -50
- package/dist/{chunk-3GIKYHLA.js → chunk-GKSG5CPH.js} +6 -6
- package/dist/{chunk-ESLPBT5A.js → chunk-HDYUBRMF.js} +4 -3
- package/dist/{chunk-ELRRTWNP.js → chunk-IXIS7RSG.js} +2 -2
- package/dist/{chunk-HR67OWEP.js → chunk-IYH4OHBP.js} +5 -5
- package/dist/{chunk-W232EFEM.js → chunk-JDOO4P6Z.js} +7 -4
- package/dist/{chunk-OTPTQBYE.js → chunk-KDEXUQY7.js} +19 -8
- package/dist/{chunk-2OXHS3KZ.js → chunk-KLJZ4WV4.js} +4 -3
- package/dist/{chunk-3M7LLN7W.js → chunk-LQSOU63Z.js} +12 -11
- package/dist/{chunk-JVRLTEO7.js → chunk-M6UV67BH.js} +2 -2
- package/dist/{chunk-C2DQKVLO.js → chunk-MJSJWXBF.js} +1 -1
- package/dist/{chunk-NSPNFOJ7.js → chunk-MK2JK35J.js} +25 -10
- package/dist/{chunk-JSNSMG5R.js → chunk-MSOAX3GC.js} +1 -1
- package/dist/{chunk-J43O3BOX.js → chunk-N3K2SFEI.js} +532 -492
- package/dist/{chunk-J74TMK4M.js → chunk-NJX2RXKJ.js} +50 -7
- package/dist/{chunk-5UFVCIUB.js → chunk-NN2SNP2R.js} +4 -4
- package/dist/{chunk-WAQASTXB.js → chunk-O6BY43ZB.js} +29 -8
- package/dist/{chunk-QGF2C7TF.js → chunk-PVCB7RUZ.js} +2 -2
- package/dist/{chunk-YTKSNTT4.js → chunk-QA6IASYX.js} +8 -8
- package/dist/{chunk-VPALDFYM.js → chunk-RV7BVTDG.js} +1 -1
- package/dist/chunk-S57CDR2H.js +288 -0
- package/dist/{chunk-W2CECGTG.js → chunk-SMARDKAC.js} +1 -1
- package/dist/{chunk-QWKSKFKZ.js → chunk-SOR7OCYP.js} +1 -1
- package/dist/{chunk-I7FBZOEP.js → chunk-T3SMFF5Q.js} +11 -5
- package/dist/{chunk-4BHUSMNL.js → chunk-UI3ZJIG3.js} +1 -1
- package/dist/{chunk-WXJY3BKV.js → chunk-VBF2YXUW.js} +2 -2
- package/dist/{chunk-FQNXYA6W.js → chunk-VU3QBYL4.js} +36 -5
- package/dist/{chunk-VD2LV5WO.js → chunk-VZGPASGD.js} +37 -12
- package/dist/{chunk-UZFY3CKD.js → chunk-WEEVSWQB.js} +17 -6
- package/dist/chunk-XXRMF2BC.js +186 -0
- package/dist/{chunk-LRDIRJJL.js → chunk-YEISRT4S.js} +5 -11
- package/dist/{chunk-Q5JPPCZC.js → chunk-YJTXRH5Y.js} +3 -2
- package/dist/{chunk-23EX5WDO.js → chunk-YULVUTK5.js} +3 -3
- package/dist/{chunk-Z5Q3TXRY.js → chunk-ZTCJCYLN.js} +3 -3
- package/dist/circuit-breaker.d.ts +1 -0
- package/dist/circuit-breaker.js +1 -1
- package/dist/clarify.d.ts +1 -0
- package/dist/codebase-index/codebase-ast-replace-tool.d.ts +2 -3
- package/dist/codebase-index/codebase-impact-analysis-tool.d.ts +5 -4
- package/dist/codebase-index/codebase-incoming-calls-tool.d.ts +4 -3
- package/dist/codebase-index/codebase-index-tool.d.ts +2 -3
- package/dist/codebase-index/codebase-invariant-check-tool.d.ts +2 -3
- package/dist/codebase-index/codebase-outgoing-calls-tool.d.ts +4 -3
- package/dist/codebase-index/codebase-repo-map-tool.d.ts +2 -3
- package/dist/codebase-index/codebase-search-tool.d.ts +2 -3
- package/dist/codebase-index/codebase-skeleton-tool.d.ts +2 -3
- package/dist/codebase-index/codebase-stats-tool.d.ts +9 -3
- package/dist/codebase-index/codebase-targeted-test-tool.d.ts +4 -3
- package/dist/codebase-index/index.d.ts +11 -11
- package/dist/codebase-index/index.js +8 -8
- package/dist/codebase-index/project-server-framing.d.ts +29 -0
- package/dist/codebase-index/project-server-lifecycle.d.ts +20 -0
- package/dist/codebase-index/project-server-operations.d.ts +37 -0
- package/dist/codebase-index/project-server-types.d.ts +30 -0
- package/dist/codebase-index/project-server-watcher.d.ts +25 -0
- package/dist/codebase-index/project-server.js +448 -391
- package/dist/codebase-index/worker.js +2 -2
- package/dist/codebase-index/writer-init.d.ts +13 -0
- package/dist/codebase-index/writer-maintenance.d.ts +14 -0
- package/dist/codebase-index/writer.d.ts +0 -15
- package/dist/design.d.ts +2 -2
- package/dist/design.js +1 -1
- package/dist/diff.d.ts +4 -4
- package/dist/diff.js +1 -1
- package/dist/document.d.ts +3 -4
- package/dist/document.js +1 -1
- package/dist/e2e.d.ts +1 -1
- package/dist/e2e.js +1 -1
- package/dist/edit.d.ts +3 -3
- package/dist/edit.js +6 -6
- package/dist/exec.d.ts +2 -3
- package/dist/exec.js +4 -4
- package/dist/fetch.d.ts +4 -3
- package/dist/fetch.js +1 -1
- package/dist/format.d.ts +17 -45
- package/dist/format.js +12 -8
- package/dist/git.d.ts +3 -3
- package/dist/git.js +1 -1
- package/dist/glob.d.ts +2 -3
- package/dist/glob.js +2 -2
- package/dist/grep.d.ts +7 -5
- package/dist/grep.js +3 -3
- package/dist/index.d.ts +54 -45
- package/dist/index.js +118 -59
- package/dist/install.d.ts +7 -55
- package/dist/install.js +6 -6
- package/dist/json.d.ts +3 -4
- package/dist/json.js +2 -2
- package/dist/kanban-tool-types.d.ts +1 -2
- package/dist/kanban.d.ts +3 -19
- package/dist/kanban.js +1 -1
- package/dist/languages/execute-tool.d.ts +2 -3
- package/dist/languages/index.d.ts +2 -2
- package/dist/languages/index.js +4 -4
- package/dist/languages/tool.d.ts +3 -4
- package/dist/{legacy-bridge-FOV5ODDI.js → legacy-bridge-YXANP5QB.js} +6 -6
- package/dist/lint.d.ts +5 -4
- package/dist/lint.js +6 -6
- package/dist/logs.d.ts +3 -4
- package/dist/logs.js +2 -2
- package/dist/memory.d.ts +7 -8
- package/dist/memory.js +1 -1
- package/dist/mode.d.ts +3 -4
- package/dist/mode.js +1 -1
- package/dist/next-steps-tool.d.ts +2 -3
- package/dist/next-steps.d.ts +4 -0
- package/dist/next-steps.js +9 -175
- package/dist/outdated.d.ts +5 -29
- package/dist/outdated.js +3 -3
- package/dist/pack.js +51 -51
- package/dist/patch.d.ts +2 -3
- package/dist/patch.js +5 -5
- package/dist/plan.d.ts +4 -4
- package/dist/plan.js +3 -3
- package/dist/process-registry.js +2 -2
- package/dist/ps-slash.js +4 -4
- package/dist/pwsh.d.ts +1 -0
- package/dist/read.d.ts +5 -5
- package/dist/read.js +5 -5
- package/dist/replace.d.ts +2 -3
- package/dist/replace.js +6 -6
- package/dist/scaffold.d.ts +7 -3
- package/dist/scaffold.js +3 -1
- package/dist/search.d.ts +17 -3
- package/dist/search.js +5 -1
- package/dist/set-working-dir.d.ts +2 -3
- package/dist/skill.d.ts +4 -5
- package/dist/skill.js +1 -1
- package/dist/task.d.ts +6 -6
- package/dist/task.js +3 -3
- package/dist/test.d.ts +5 -4
- package/dist/test.js +6 -6
- package/dist/todo.d.ts +8 -8
- package/dist/todo.js +2 -2
- package/dist/tool-diff.js +11 -230
- package/dist/tool-help.d.ts +2 -3
- package/dist/tool-help.js +1 -1
- package/dist/tool-search.d.ts +2 -3
- package/dist/tool-search.js +1 -1
- package/dist/tool-summary.js +5 -281
- package/dist/tool-tier.js +52 -52
- package/dist/tool-use.d.ts +2 -3
- package/dist/tool-use.js +1 -1
- package/dist/tree.d.ts +5 -3
- package/dist/tree.js +5 -1
- package/dist/typecheck.d.ts +3 -3
- package/dist/typecheck.js +6 -6
- package/dist/write.d.ts +2 -3
- package/dist/write.js +6 -6
- package/package.json +5 -5
- package/dist/spawn-background.d.ts +0 -80
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
} from "./chunk-YOHO4DVT.js";
|
|
10
10
|
import {
|
|
11
11
|
loadGitignoreMatcher
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-2CTZW6JQ.js";
|
|
13
13
|
|
|
14
14
|
// src/codebase-index/circuit-breaker.ts
|
|
15
15
|
var CircuitOpenError = class extends Error {
|
|
@@ -463,80 +463,6 @@ function runSqliteWithRetry(fn) {
|
|
|
463
463
|
throw lastError;
|
|
464
464
|
}
|
|
465
465
|
|
|
466
|
-
// src/codebase-index/vector-search.ts
|
|
467
|
-
var RRF_K = 60;
|
|
468
|
-
function vectorEmbeddingEnabled() {
|
|
469
|
-
return process.env["WRONGSTACK_INDEX_VECTORS"] === "1";
|
|
470
|
-
}
|
|
471
|
-
var VECTOR_DIMENSIONS = 384;
|
|
472
|
-
var NGRAM_SIZE = 3;
|
|
473
|
-
function embedText(text) {
|
|
474
|
-
const vec = new Float32Array(VECTOR_DIMENSIONS);
|
|
475
|
-
const normalized = text.toLowerCase().trim();
|
|
476
|
-
if (normalized.length === 0) return vec;
|
|
477
|
-
const target = normalized.length < NGRAM_SIZE ? ` ${normalized} `.slice(0, Math.max(NGRAM_SIZE, normalized.length + 2)) : normalized;
|
|
478
|
-
for (let i = 0; i <= target.length - NGRAM_SIZE; i++) {
|
|
479
|
-
const ngram = target.slice(i, i + NGRAM_SIZE);
|
|
480
|
-
const bucket = hashNgram(ngram) % VECTOR_DIMENSIONS;
|
|
481
|
-
vec[bucket] += 1;
|
|
482
|
-
}
|
|
483
|
-
let norm = 0;
|
|
484
|
-
for (let i = 0; i < VECTOR_DIMENSIONS; i++) {
|
|
485
|
-
norm += vec[i] * vec[i];
|
|
486
|
-
}
|
|
487
|
-
norm = Math.sqrt(norm);
|
|
488
|
-
if (norm > 0) {
|
|
489
|
-
for (let i = 0; i < VECTOR_DIMENSIONS; i++) {
|
|
490
|
-
vec[i] /= norm;
|
|
491
|
-
}
|
|
492
|
-
}
|
|
493
|
-
return vec;
|
|
494
|
-
}
|
|
495
|
-
function hashNgram(str) {
|
|
496
|
-
let hash = 2166136261;
|
|
497
|
-
for (let i = 0; i < str.length; i++) {
|
|
498
|
-
hash ^= str.charCodeAt(i);
|
|
499
|
-
hash = Math.imul(hash, 16777619);
|
|
500
|
-
}
|
|
501
|
-
return hash >>> 0;
|
|
502
|
-
}
|
|
503
|
-
function cosineSimilarity(a, b) {
|
|
504
|
-
let dot = 0;
|
|
505
|
-
const len = Math.min(a.length, b.length);
|
|
506
|
-
for (let i = 0; i < len; i++) {
|
|
507
|
-
dot += a[i] * b[i];
|
|
508
|
-
}
|
|
509
|
-
return dot;
|
|
510
|
-
}
|
|
511
|
-
function encodeVector(vec) {
|
|
512
|
-
return Buffer.from(vec.buffer, vec.byteOffset, vec.byteLength);
|
|
513
|
-
}
|
|
514
|
-
function decodeVector(buf) {
|
|
515
|
-
if (buf.byteLength === 0) return new Float32Array(0);
|
|
516
|
-
if (buf.byteLength % 4 !== 0) {
|
|
517
|
-
throw new Error(
|
|
518
|
-
`decodeVector: invalid vector byteLength ${buf.byteLength} (must be a multiple of 4)`
|
|
519
|
-
);
|
|
520
|
-
}
|
|
521
|
-
const copy = new Float32Array(buf.byteLength / 4);
|
|
522
|
-
new Uint8Array(copy.buffer).set(buf);
|
|
523
|
-
return copy;
|
|
524
|
-
}
|
|
525
|
-
function reciprocalRankFusion(bm25Ranks, vectorRanks, k = RRF_K) {
|
|
526
|
-
const allIds = /* @__PURE__ */ new Set([...bm25Ranks.keys(), ...vectorRanks.keys()]);
|
|
527
|
-
const scored = [];
|
|
528
|
-
for (const id of allIds) {
|
|
529
|
-
const bm25Rank = bm25Ranks.get(id);
|
|
530
|
-
const vecRank = vectorRanks.get(id);
|
|
531
|
-
let score = 0;
|
|
532
|
-
if (bm25Rank !== void 0) score += 1 / (k + bm25Rank);
|
|
533
|
-
if (vecRank !== void 0) score += 1 / (k + vecRank);
|
|
534
|
-
scored.push([id, score]);
|
|
535
|
-
}
|
|
536
|
-
scored.sort((a, b) => b[1] - a[1]);
|
|
537
|
-
return scored;
|
|
538
|
-
}
|
|
539
|
-
|
|
540
466
|
// src/codebase-index/writer-admin.ts
|
|
541
467
|
import * as fs from "node:fs";
|
|
542
468
|
import * as path from "node:path";
|
|
@@ -1698,129 +1624,78 @@ function getSymbolGraphWithStatement(stmt, fileFilter) {
|
|
|
1698
1624
|
return { nodes, edges };
|
|
1699
1625
|
}
|
|
1700
1626
|
|
|
1701
|
-
// src/codebase-index/
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1627
|
+
// src/codebase-index/vector-search.ts
|
|
1628
|
+
var RRF_K = 60;
|
|
1629
|
+
function vectorEmbeddingEnabled() {
|
|
1630
|
+
return process.env["WRONGSTACK_INDEX_VECTORS"] === "1";
|
|
1631
|
+
}
|
|
1632
|
+
var VECTOR_DIMENSIONS = 384;
|
|
1633
|
+
var NGRAM_SIZE = 3;
|
|
1634
|
+
function embedText(text) {
|
|
1635
|
+
const vec = new Float32Array(VECTOR_DIMENSIONS);
|
|
1636
|
+
const normalized = text.toLowerCase().trim();
|
|
1637
|
+
if (normalized.length === 0) return vec;
|
|
1638
|
+
const target = normalized.length < NGRAM_SIZE ? ` ${normalized} `.slice(0, Math.max(NGRAM_SIZE, normalized.length + 2)) : normalized;
|
|
1639
|
+
for (let i = 0; i <= target.length - NGRAM_SIZE; i++) {
|
|
1640
|
+
const ngram = target.slice(i, i + NGRAM_SIZE);
|
|
1641
|
+
const bucket = hashNgram(ngram) % VECTOR_DIMENSIONS;
|
|
1642
|
+
vec[bucket] += 1;
|
|
1705
1643
|
}
|
|
1706
|
-
|
|
1707
|
-
for (
|
|
1708
|
-
|
|
1709
|
-
for (const ref of entry.refs) affectedNames.add(ref.toName);
|
|
1644
|
+
let norm = 0;
|
|
1645
|
+
for (let i = 0; i < VECTOR_DIMENSIONS; i++) {
|
|
1646
|
+
norm += vec[i] * vec[i];
|
|
1710
1647
|
}
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
let cursor = 0;
|
|
1716
|
-
for (const take of inListChunks(options.deleteForFiles.length, Math.floor(maxSqlVars / 4))) {
|
|
1717
|
-
const bucket = padToInBucket(options.deleteForFiles.slice(cursor, cursor + take));
|
|
1718
|
-
cursor += take;
|
|
1719
|
-
const ph = placeholders(bucket.length);
|
|
1720
|
-
if (ftsAvailable) {
|
|
1721
|
-
stmtFn(
|
|
1722
|
-
`DELETE FROM symbols_fts WHERE rowid IN (SELECT id FROM symbols WHERE file IN (${ph}))`
|
|
1723
|
-
).run(...bucket);
|
|
1724
|
-
}
|
|
1725
|
-
if (vectorsAvailable) {
|
|
1726
|
-
stmtFn(
|
|
1727
|
-
`DELETE FROM symbol_vectors WHERE symbol_id IN (SELECT id FROM symbols WHERE file IN (${ph}))`
|
|
1728
|
-
).run(...bucket);
|
|
1729
|
-
}
|
|
1730
|
-
stmtFn(
|
|
1731
|
-
`DELETE FROM refs WHERE from_id IN (SELECT id FROM symbols WHERE file IN (${ph}))`
|
|
1732
|
-
).run(...bucket);
|
|
1733
|
-
stmtFn(`DELETE FROM symbols WHERE file IN (${ph})`).run(...bucket);
|
|
1648
|
+
norm = Math.sqrt(norm);
|
|
1649
|
+
if (norm > 0) {
|
|
1650
|
+
for (let i = 0; i < VECTOR_DIMENSIONS; i++) {
|
|
1651
|
+
vec[i] /= norm;
|
|
1734
1652
|
}
|
|
1735
1653
|
}
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
for (const entry of entries) {
|
|
1744
|
-
const insertedForEntry = [];
|
|
1745
|
-
for (const s of entry.symbols) {
|
|
1746
|
-
const id = nextId++;
|
|
1747
|
-
bulkSyms.push({
|
|
1748
|
-
id,
|
|
1749
|
-
lang: s.lang,
|
|
1750
|
-
kind: s.kind,
|
|
1751
|
-
name: s.name,
|
|
1752
|
-
file: s.file,
|
|
1753
|
-
line: s.line,
|
|
1754
|
-
col: s.col,
|
|
1755
|
-
signature: s.signature,
|
|
1756
|
-
docComment: s.docComment,
|
|
1757
|
-
scope: s.scope
|
|
1758
|
-
});
|
|
1759
|
-
if (ftsAvailable) {
|
|
1760
|
-
ftsRows.push({
|
|
1761
|
-
id,
|
|
1762
|
-
text: buildIndexableText(s.name, s.signature, s.docComment)
|
|
1763
|
-
});
|
|
1764
|
-
}
|
|
1765
|
-
if (vectorsAvailable) {
|
|
1766
|
-
vectorRows.push({
|
|
1767
|
-
id,
|
|
1768
|
-
vector: encodeVector(embedText(buildIndexableText(s.name, s.signature, s.docComment)))
|
|
1769
|
-
});
|
|
1770
|
-
}
|
|
1771
|
-
const inserted = { ...s, id };
|
|
1772
|
-
allInserted.push(inserted);
|
|
1773
|
-
insertedForEntry.push(inserted);
|
|
1774
|
-
}
|
|
1775
|
-
refsToInsert.push(...assignRefsToSymbols(entry.refs, insertedForEntry));
|
|
1654
|
+
return vec;
|
|
1655
|
+
}
|
|
1656
|
+
function hashNgram(str) {
|
|
1657
|
+
let hash = 2166136261;
|
|
1658
|
+
for (let i = 0; i < str.length; i++) {
|
|
1659
|
+
hash ^= str.charCodeAt(i);
|
|
1660
|
+
hash = Math.imul(hash, 16777619);
|
|
1776
1661
|
}
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1662
|
+
return hash >>> 0;
|
|
1663
|
+
}
|
|
1664
|
+
function cosineSimilarity(a, b) {
|
|
1665
|
+
let dot = 0;
|
|
1666
|
+
const len = Math.min(a.length, b.length);
|
|
1667
|
+
for (let i = 0; i < len; i++) {
|
|
1668
|
+
dot += a[i] * b[i];
|
|
1781
1669
|
}
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
);
|
|
1793
|
-
const now = Date.now();
|
|
1794
|
-
for (const entry of entries) {
|
|
1795
|
-
upsertStmt.run(
|
|
1796
|
-
entry.file,
|
|
1797
|
-
entry.lang,
|
|
1798
|
-
entry.mtimeMs,
|
|
1799
|
-
entry.contentHash ?? "",
|
|
1800
|
-
entry.symbolCount,
|
|
1801
|
-
now
|
|
1670
|
+
return dot;
|
|
1671
|
+
}
|
|
1672
|
+
function encodeVector(vec) {
|
|
1673
|
+
return Buffer.from(vec.buffer, vec.byteOffset, vec.byteLength);
|
|
1674
|
+
}
|
|
1675
|
+
function decodeVector(buf) {
|
|
1676
|
+
if (buf.byteLength === 0) return new Float32Array(0);
|
|
1677
|
+
if (buf.byteLength % 4 !== 0) {
|
|
1678
|
+
throw new Error(
|
|
1679
|
+
`decodeVector: invalid vector byteLength ${buf.byteLength} (must be a multiple of 4)`
|
|
1802
1680
|
);
|
|
1803
1681
|
}
|
|
1804
|
-
|
|
1805
|
-
|
|
1682
|
+
const copy = new Float32Array(buf.byteLength / 4);
|
|
1683
|
+
new Uint8Array(copy.buffer).set(buf);
|
|
1684
|
+
return copy;
|
|
1806
1685
|
}
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
db.exec(`PRAGMA cache_size = -${cache.cacheSizeKiB}`);
|
|
1818
|
-
db.exec(`PRAGMA mmap_size = ${cache.mmapBytes}`);
|
|
1819
|
-
db.exec("PRAGMA foreign_keys = ON");
|
|
1820
|
-
db.exec("PRAGMA journal_size_limit = 67108864");
|
|
1821
|
-
db.exec("PRAGMA wal_autocheckpoint = 1000");
|
|
1822
|
-
} catch {
|
|
1686
|
+
function reciprocalRankFusion(bm25Ranks, vectorRanks, k = RRF_K) {
|
|
1687
|
+
const allIds = /* @__PURE__ */ new Set([...bm25Ranks.keys(), ...vectorRanks.keys()]);
|
|
1688
|
+
const scored = [];
|
|
1689
|
+
for (const id of allIds) {
|
|
1690
|
+
const bm25Rank = bm25Ranks.get(id);
|
|
1691
|
+
const vecRank = vectorRanks.get(id);
|
|
1692
|
+
let score = 0;
|
|
1693
|
+
if (bm25Rank !== void 0) score += 1 / (k + bm25Rank);
|
|
1694
|
+
if (vecRank !== void 0) score += 1 / (k + vecRank);
|
|
1695
|
+
scored.push([id, score]);
|
|
1823
1696
|
}
|
|
1697
|
+
scored.sort((a, b) => b[1] - a[1]);
|
|
1698
|
+
return scored;
|
|
1824
1699
|
}
|
|
1825
1700
|
|
|
1826
1701
|
// src/codebase-index/writer-schema.ts
|
|
@@ -1914,15 +1789,431 @@ var SYMBOL_VECTORS_TABLE_SQL = `
|
|
|
1914
1789
|
);
|
|
1915
1790
|
`;
|
|
1916
1791
|
|
|
1917
|
-
// src/codebase-index/writer-
|
|
1918
|
-
var
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
OR
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1792
|
+
// src/codebase-index/writer-init.ts
|
|
1793
|
+
var SYMBOLS_TEXT_DROPPED_KEY = "symbols_text_dropped";
|
|
1794
|
+
var NEXT_SYMBOL_ID_KEY = "next_symbol_id";
|
|
1795
|
+
function seedLangFamilies(stmt) {
|
|
1796
|
+
const insert = stmt("INSERT OR REPLACE INTO lang_family(lang, family) VALUES (?, ?)");
|
|
1797
|
+
for (const [lang, family] of LANG_FAMILY_ENTRIES) insert.run(lang, family);
|
|
1798
|
+
insert.run("", LANG_FAMILY_WILDCARD);
|
|
1799
|
+
}
|
|
1800
|
+
function repairMissingColumns(db) {
|
|
1801
|
+
const expected = [
|
|
1802
|
+
{
|
|
1803
|
+
table: "files",
|
|
1804
|
+
columns: [
|
|
1805
|
+
["package", "TEXT NOT NULL DEFAULT ''"],
|
|
1806
|
+
["content_hash", "TEXT NOT NULL DEFAULT ''"]
|
|
1807
|
+
]
|
|
1808
|
+
},
|
|
1809
|
+
{
|
|
1810
|
+
table: "refs",
|
|
1811
|
+
columns: [
|
|
1812
|
+
["lang", "TEXT NOT NULL DEFAULT ''"],
|
|
1813
|
+
["module", "TEXT"],
|
|
1814
|
+
["to_file", "TEXT"]
|
|
1815
|
+
]
|
|
1816
|
+
}
|
|
1817
|
+
];
|
|
1818
|
+
for (const { table, columns } of expected) {
|
|
1819
|
+
const rows = db.prepare(`PRAGMA table_info(${table})`).all();
|
|
1820
|
+
const present = /* @__PURE__ */ new Set();
|
|
1821
|
+
for (const row of rows) {
|
|
1822
|
+
if (typeof row.name === "string") present.add(row.name);
|
|
1823
|
+
}
|
|
1824
|
+
if (present.size === 0) continue;
|
|
1825
|
+
for (const [name, type] of columns) {
|
|
1826
|
+
if (present.has(name)) continue;
|
|
1827
|
+
db.exec(`ALTER TABLE ${table} ADD COLUMN ${name} ${type}`);
|
|
1828
|
+
}
|
|
1829
|
+
}
|
|
1830
|
+
}
|
|
1831
|
+
function dropDeprecatedSymbolsColumns(db, getMetadata, setMetadata) {
|
|
1832
|
+
if (getMetadata(SYMBOLS_TEXT_DROPPED_KEY) !== void 0) return;
|
|
1833
|
+
const present = new Set(
|
|
1834
|
+
db.prepare("PRAGMA table_info(symbols)").all().flatMap(
|
|
1835
|
+
(row) => typeof row.name === "string" ? [row.name] : []
|
|
1836
|
+
)
|
|
1837
|
+
);
|
|
1838
|
+
if (present.size === 0) return;
|
|
1839
|
+
if (!present.has("text")) {
|
|
1840
|
+
setMetadata(SYMBOLS_TEXT_DROPPED_KEY, "1");
|
|
1841
|
+
return;
|
|
1842
|
+
}
|
|
1843
|
+
try {
|
|
1844
|
+
db.exec("ALTER TABLE symbols DROP COLUMN text");
|
|
1845
|
+
setMetadata(SYMBOLS_TEXT_DROPPED_KEY, "1");
|
|
1846
|
+
} catch {
|
|
1847
|
+
}
|
|
1848
|
+
}
|
|
1849
|
+
function initIndexSchema(db, stmt, getMetadata, setMetadata, maxSqlVars, invalidateBm25) {
|
|
1850
|
+
db.exec(METADATA_TABLE_SQL);
|
|
1851
|
+
const storedRows = stmt("SELECT value FROM metadata WHERE key = ?").all("version");
|
|
1852
|
+
const storedVersion = storedRows.length ? Number(storedRows[0]?.value) : null;
|
|
1853
|
+
if (storedVersion !== null && storedVersion !== SCHEMA_VERSION) {
|
|
1854
|
+
db.exec(`
|
|
1855
|
+
DROP TABLE IF EXISTS symbols;
|
|
1856
|
+
DROP TABLE IF EXISTS files;
|
|
1857
|
+
DROP TABLE IF EXISTS refs;
|
|
1858
|
+
DROP TABLE IF EXISTS symbol_vectors;
|
|
1859
|
+
`);
|
|
1860
|
+
db.exec("DROP TABLE IF EXISTS symbols_fts");
|
|
1861
|
+
stmt("UPDATE metadata SET value = ? WHERE key = ?").run(String(SCHEMA_VERSION), "version");
|
|
1862
|
+
} else if (storedVersion === null) {
|
|
1863
|
+
stmt("INSERT INTO metadata(key, value) VALUES (?, ?)").run("version", String(SCHEMA_VERSION));
|
|
1864
|
+
}
|
|
1865
|
+
db.exec(CORE_TABLES_SQL);
|
|
1866
|
+
db.exec(REFS_TABLE_SQL);
|
|
1867
|
+
repairMissingColumns(db);
|
|
1868
|
+
dropDeprecatedSymbolsColumns(db, getMetadata, setMetadata);
|
|
1869
|
+
for (const sql of FILE_INDEX_SQL) db.exec(sql);
|
|
1870
|
+
for (const sql of SYMBOL_INDEX_SQL) db.exec(sql);
|
|
1871
|
+
for (const sql of REFS_INDEX_SQL) db.exec(sql);
|
|
1872
|
+
db.exec(LANG_FAMILY_TABLE_SQL);
|
|
1873
|
+
seedLangFamilies(stmt);
|
|
1874
|
+
let ftsAvailable = false;
|
|
1875
|
+
try {
|
|
1876
|
+
const ftsSchema = stmt(
|
|
1877
|
+
"SELECT sql FROM sqlite_master WHERE type='table' AND name='symbols_fts'"
|
|
1878
|
+
).get();
|
|
1879
|
+
if (ftsSchema?.sql?.includes("unicode61")) {
|
|
1880
|
+
db.exec("DROP TABLE IF EXISTS symbols_fts");
|
|
1881
|
+
}
|
|
1882
|
+
db.exec(SYMBOLS_FTS_SQL);
|
|
1883
|
+
ftsAvailable = true;
|
|
1884
|
+
const symbolCount = Number(
|
|
1885
|
+
stmt("SELECT COUNT(*) AS n FROM symbols").get()?.n ?? 0
|
|
1886
|
+
);
|
|
1887
|
+
const ftsCount = Number(
|
|
1888
|
+
stmt("SELECT COUNT(*) AS n FROM symbols_fts").get()?.n ?? 0
|
|
1889
|
+
);
|
|
1890
|
+
if (symbolCount !== ftsCount) {
|
|
1891
|
+
db.exec("DELETE FROM symbols_fts");
|
|
1892
|
+
if (vectorEmbeddingEnabled() && stmt("SELECT 1 FROM sqlite_master WHERE type='table' AND name='symbol_vectors'").get() !== void 0) {
|
|
1893
|
+
db.exec("DELETE FROM symbol_vectors");
|
|
1894
|
+
}
|
|
1895
|
+
const rows = stmt(
|
|
1896
|
+
"SELECT id, name, signature, doc_comment FROM symbols ORDER BY id"
|
|
1897
|
+
).all();
|
|
1898
|
+
bulkInsertFtsWithStatement(
|
|
1899
|
+
stmt,
|
|
1900
|
+
maxSqlVars,
|
|
1901
|
+
ftsAvailable,
|
|
1902
|
+
rows.map((row) => ({
|
|
1903
|
+
id: row.id,
|
|
1904
|
+
text: buildIndexableText(row.name, row.signature, row.doc_comment)
|
|
1905
|
+
}))
|
|
1906
|
+
);
|
|
1907
|
+
invalidateBm25();
|
|
1908
|
+
}
|
|
1909
|
+
} catch {
|
|
1910
|
+
ftsAvailable = false;
|
|
1911
|
+
}
|
|
1912
|
+
let vectorsAvailable = false;
|
|
1913
|
+
try {
|
|
1914
|
+
if (vectorEmbeddingEnabled()) {
|
|
1915
|
+
db.exec(SYMBOL_VECTORS_TABLE_SQL);
|
|
1916
|
+
vectorsAvailable = true;
|
|
1917
|
+
} else {
|
|
1918
|
+
db.exec("DROP TABLE IF EXISTS symbol_vectors");
|
|
1919
|
+
vectorsAvailable = false;
|
|
1920
|
+
}
|
|
1921
|
+
} catch {
|
|
1922
|
+
vectorsAvailable = false;
|
|
1923
|
+
}
|
|
1924
|
+
ensureNextSymbolIdSeeded(stmt);
|
|
1925
|
+
return { ftsAvailable, vectorsAvailable };
|
|
1926
|
+
}
|
|
1927
|
+
function ensureNextSymbolIdSeeded(stmt) {
|
|
1928
|
+
const existing = stmt("SELECT value FROM metadata WHERE key = ?").get(NEXT_SYMBOL_ID_KEY);
|
|
1929
|
+
if (existing?.value !== void 0) return;
|
|
1930
|
+
const maxRows = stmt("SELECT MAX(id) AS m FROM symbols").all();
|
|
1931
|
+
const next = (maxRows[0]?.m ?? 0) + 1;
|
|
1932
|
+
stmt("INSERT OR REPLACE INTO metadata(key, value) VALUES (?, ?)").run(
|
|
1933
|
+
NEXT_SYMBOL_ID_KEY,
|
|
1934
|
+
String(next)
|
|
1935
|
+
);
|
|
1936
|
+
}
|
|
1937
|
+
function allocateSymbolIds(stmt, count, getMaxSymbolId) {
|
|
1938
|
+
if (count <= 0) return getMaxSymbolId() + 1;
|
|
1939
|
+
ensureNextSymbolIdSeeded(stmt);
|
|
1940
|
+
const row = stmt("SELECT value FROM metadata WHERE key = ?").get(NEXT_SYMBOL_ID_KEY);
|
|
1941
|
+
const start = Math.max(1, Number(row?.value ?? 1) || 1);
|
|
1942
|
+
stmt("INSERT OR REPLACE INTO metadata(key, value) VALUES (?, ?)").run(
|
|
1943
|
+
NEXT_SYMBOL_ID_KEY,
|
|
1944
|
+
String(start + count)
|
|
1945
|
+
);
|
|
1946
|
+
return start;
|
|
1947
|
+
}
|
|
1948
|
+
|
|
1949
|
+
// src/codebase-index/writer-maintenance.ts
|
|
1950
|
+
var FTS_CHURN_KEY = "fts_churn_since_maintain";
|
|
1951
|
+
function optimizeStore(db) {
|
|
1952
|
+
try {
|
|
1953
|
+
db.exec("PRAGMA optimize");
|
|
1954
|
+
} catch {
|
|
1955
|
+
}
|
|
1956
|
+
}
|
|
1957
|
+
function recordFtsChurn(ftsAvailable, getMetadata, setMetadata, rows) {
|
|
1958
|
+
if (rows <= 0 || !ftsAvailable) return;
|
|
1959
|
+
try {
|
|
1960
|
+
const current = Number(getMetadata(FTS_CHURN_KEY) ?? "0") || 0;
|
|
1961
|
+
setMetadata(FTS_CHURN_KEY, String(current + rows));
|
|
1962
|
+
} catch {
|
|
1963
|
+
}
|
|
1964
|
+
}
|
|
1965
|
+
function optimizeFtsIfNeeded(stmt, ftsAvailable, getMetadata, setMetadata, runWithRetry, options = {}) {
|
|
1966
|
+
if (!ftsAvailable) return false;
|
|
1967
|
+
try {
|
|
1968
|
+
const minChurnRatio = options.minChurnRatio ?? 0.1;
|
|
1969
|
+
const minChurnRows = options.minChurnRows ?? 5e3;
|
|
1970
|
+
const churn = Number(getMetadata(FTS_CHURN_KEY) ?? "0") || 0;
|
|
1971
|
+
const liveRows = Number(
|
|
1972
|
+
stmt("SELECT COUNT(*) AS n FROM symbols").get()?.n ?? 0
|
|
1973
|
+
);
|
|
1974
|
+
if (churn < Math.max(minChurnRows, liveRows * minChurnRatio)) return false;
|
|
1975
|
+
runWithRetry(() => {
|
|
1976
|
+
stmt(`INSERT INTO symbols_fts(symbols_fts) VALUES('optimize')`).run();
|
|
1977
|
+
});
|
|
1978
|
+
setMetadata(FTS_CHURN_KEY, "0");
|
|
1979
|
+
return true;
|
|
1980
|
+
} catch {
|
|
1981
|
+
return false;
|
|
1982
|
+
}
|
|
1983
|
+
}
|
|
1984
|
+
function checkpointWal(db) {
|
|
1985
|
+
try {
|
|
1986
|
+
const probe = db.prepare("PRAGMA wal_checkpoint(PASSIVE)").get();
|
|
1987
|
+
if (Number(probe?.busy ?? 1) !== 0) return false;
|
|
1988
|
+
const done = db.prepare("PRAGMA wal_checkpoint(TRUNCATE)").get();
|
|
1989
|
+
return Number(done?.busy ?? 1) === 0;
|
|
1990
|
+
} catch {
|
|
1991
|
+
return false;
|
|
1992
|
+
}
|
|
1993
|
+
}
|
|
1994
|
+
function compactIfNeeded(db, stmt, runWithRetry, options = {}) {
|
|
1995
|
+
const minBytes = options.minBytes ?? 256 * 1024 * 1024;
|
|
1996
|
+
const minFreeRatio = options.minFreeRatio ?? 0.35;
|
|
1997
|
+
try {
|
|
1998
|
+
const pageCount = Number(
|
|
1999
|
+
stmt("PRAGMA page_count").get()?.page_count ?? 0
|
|
2000
|
+
);
|
|
2001
|
+
const pageSize = Number(
|
|
2002
|
+
stmt("PRAGMA page_size").get()?.page_size ?? 0
|
|
2003
|
+
);
|
|
2004
|
+
const freePages = Number(
|
|
2005
|
+
stmt("PRAGMA freelist_count").get()?.freelist_count ?? 0
|
|
2006
|
+
);
|
|
2007
|
+
if (pageCount <= 0 || pageSize <= 0 || pageCount * pageSize < minBytes || freePages / pageCount < minFreeRatio) {
|
|
2008
|
+
return false;
|
|
2009
|
+
}
|
|
2010
|
+
runWithRetry(() => {
|
|
2011
|
+
db.exec("PRAGMA wal_checkpoint(TRUNCATE)");
|
|
2012
|
+
db.exec("VACUUM");
|
|
2013
|
+
db.exec("PRAGMA wal_checkpoint(TRUNCATE)");
|
|
2014
|
+
});
|
|
2015
|
+
return true;
|
|
2016
|
+
} catch {
|
|
2017
|
+
return false;
|
|
2018
|
+
}
|
|
2019
|
+
}
|
|
2020
|
+
|
|
2021
|
+
// src/codebase-index/writer-mutations.ts
|
|
2022
|
+
function commitBatchWithStatement(stmtFn, maxSqlVars, ftsAvailable, vectorsAvailable, allocateSymbolIds2, invalidateIncomingRefsForFiles, resolveRefsForNamesUnsafe2, entries, options = {}) {
|
|
2023
|
+
if (entries.length === 0 && (options.deleteForFiles?.length ?? 0) === 0) {
|
|
2024
|
+
return [];
|
|
2025
|
+
}
|
|
2026
|
+
const affectedNames = /* @__PURE__ */ new Set();
|
|
2027
|
+
for (const entry of entries) {
|
|
2028
|
+
for (const symbol of entry.symbols) affectedNames.add(symbol.name);
|
|
2029
|
+
for (const ref of entry.refs) affectedNames.add(ref.toName);
|
|
2030
|
+
}
|
|
2031
|
+
if (options.deleteForFiles && options.deleteForFiles.length > 0) {
|
|
2032
|
+
for (const name of invalidateIncomingRefsForFiles(options.deleteForFiles)) {
|
|
2033
|
+
affectedNames.add(name);
|
|
2034
|
+
}
|
|
2035
|
+
let cursor = 0;
|
|
2036
|
+
for (const take of inListChunks(options.deleteForFiles.length, Math.floor(maxSqlVars / 4))) {
|
|
2037
|
+
const bucket = padToInBucket(options.deleteForFiles.slice(cursor, cursor + take));
|
|
2038
|
+
cursor += take;
|
|
2039
|
+
const ph = placeholders(bucket.length);
|
|
2040
|
+
if (ftsAvailable) {
|
|
2041
|
+
stmtFn(
|
|
2042
|
+
`DELETE FROM symbols_fts WHERE rowid IN (SELECT id FROM symbols WHERE file IN (${ph}))`
|
|
2043
|
+
).run(...bucket);
|
|
2044
|
+
}
|
|
2045
|
+
if (vectorsAvailable) {
|
|
2046
|
+
stmtFn(
|
|
2047
|
+
`DELETE FROM symbol_vectors WHERE symbol_id IN (SELECT id FROM symbols WHERE file IN (${ph}))`
|
|
2048
|
+
).run(...bucket);
|
|
2049
|
+
}
|
|
2050
|
+
stmtFn(
|
|
2051
|
+
`DELETE FROM refs WHERE from_id IN (SELECT id FROM symbols WHERE file IN (${ph}))`
|
|
2052
|
+
).run(...bucket);
|
|
2053
|
+
stmtFn(`DELETE FROM symbols WHERE file IN (${ph})`).run(...bucket);
|
|
2054
|
+
}
|
|
2055
|
+
}
|
|
2056
|
+
const totalSymbols = entries.reduce((n, e) => n + e.symbols.length, 0);
|
|
2057
|
+
let nextId = allocateSymbolIds2(totalSymbols);
|
|
2058
|
+
const allInserted = [];
|
|
2059
|
+
const refsToInsert = [];
|
|
2060
|
+
const bulkSyms = [];
|
|
2061
|
+
const ftsRows = [];
|
|
2062
|
+
const vectorRows = [];
|
|
2063
|
+
for (const entry of entries) {
|
|
2064
|
+
const insertedForEntry = [];
|
|
2065
|
+
for (const s of entry.symbols) {
|
|
2066
|
+
const id = nextId++;
|
|
2067
|
+
bulkSyms.push({
|
|
2068
|
+
id,
|
|
2069
|
+
lang: s.lang,
|
|
2070
|
+
kind: s.kind,
|
|
2071
|
+
name: s.name,
|
|
2072
|
+
file: s.file,
|
|
2073
|
+
line: s.line,
|
|
2074
|
+
col: s.col,
|
|
2075
|
+
signature: s.signature,
|
|
2076
|
+
docComment: s.docComment,
|
|
2077
|
+
scope: s.scope
|
|
2078
|
+
});
|
|
2079
|
+
if (ftsAvailable) {
|
|
2080
|
+
ftsRows.push({
|
|
2081
|
+
id,
|
|
2082
|
+
text: buildIndexableText(s.name, s.signature, s.docComment)
|
|
2083
|
+
});
|
|
2084
|
+
}
|
|
2085
|
+
if (vectorsAvailable) {
|
|
2086
|
+
vectorRows.push({
|
|
2087
|
+
id,
|
|
2088
|
+
vector: encodeVector(embedText(buildIndexableText(s.name, s.signature, s.docComment)))
|
|
2089
|
+
});
|
|
2090
|
+
}
|
|
2091
|
+
const inserted = { ...s, id };
|
|
2092
|
+
allInserted.push(inserted);
|
|
2093
|
+
insertedForEntry.push(inserted);
|
|
2094
|
+
}
|
|
2095
|
+
refsToInsert.push(...assignRefsToSymbols(entry.refs, insertedForEntry));
|
|
2096
|
+
}
|
|
2097
|
+
bulkInsertSymbolsWithStatement((sql) => stmtFn(sql), maxSqlVars, bulkSyms);
|
|
2098
|
+
bulkInsertFtsWithStatement((sql) => stmtFn(sql), maxSqlVars, ftsAvailable, ftsRows);
|
|
2099
|
+
if (vectorsAvailable) {
|
|
2100
|
+
bulkInsertVectorsWithStatement((sql) => stmtFn(sql), maxSqlVars, vectorRows);
|
|
2101
|
+
}
|
|
2102
|
+
bulkInsertRefsWithStatement((sql) => stmtFn(sql), maxSqlVars, refsToInsert);
|
|
2103
|
+
const upsertStmt = stmtFn(
|
|
2104
|
+
`INSERT INTO files(file, lang, mtime_ms, content_hash, symbol_count, last_indexed)
|
|
2105
|
+
VALUES (?, ?, ?, ?, ?, ?)
|
|
2106
|
+
ON CONFLICT(file) DO UPDATE SET
|
|
2107
|
+
lang = excluded.lang,
|
|
2108
|
+
mtime_ms = excluded.mtime_ms,
|
|
2109
|
+
content_hash = excluded.content_hash,
|
|
2110
|
+
symbol_count = excluded.symbol_count,
|
|
2111
|
+
last_indexed = excluded.last_indexed`
|
|
2112
|
+
);
|
|
2113
|
+
const now = Date.now();
|
|
2114
|
+
for (const entry of entries) {
|
|
2115
|
+
upsertStmt.run(
|
|
2116
|
+
entry.file,
|
|
2117
|
+
entry.lang,
|
|
2118
|
+
entry.mtimeMs,
|
|
2119
|
+
entry.contentHash ?? "",
|
|
2120
|
+
entry.symbolCount,
|
|
2121
|
+
now
|
|
2122
|
+
);
|
|
2123
|
+
}
|
|
2124
|
+
resolveRefsForNamesUnsafe2(affectedNames);
|
|
2125
|
+
return allInserted;
|
|
2126
|
+
}
|
|
2127
|
+
function insertSymbolsWithStatement(stmtFn, maxSqlVars, ftsAvailable, vectorsAvailable, allocateSymbolIds2, symbols) {
|
|
2128
|
+
let nextId = allocateSymbolIds2(symbols.length);
|
|
2129
|
+
const result = [];
|
|
2130
|
+
const bulk = [];
|
|
2131
|
+
const ftsRows = [];
|
|
2132
|
+
const vectorRows = [];
|
|
2133
|
+
for (const s of symbols) {
|
|
2134
|
+
const id = nextId++;
|
|
2135
|
+
bulk.push({
|
|
2136
|
+
id,
|
|
2137
|
+
lang: s.lang,
|
|
2138
|
+
kind: s.kind,
|
|
2139
|
+
name: s.name,
|
|
2140
|
+
file: s.file,
|
|
2141
|
+
line: s.line,
|
|
2142
|
+
col: s.col,
|
|
2143
|
+
signature: s.signature,
|
|
2144
|
+
docComment: s.docComment,
|
|
2145
|
+
scope: s.scope
|
|
2146
|
+
});
|
|
2147
|
+
if (ftsAvailable) {
|
|
2148
|
+
ftsRows.push({ id, text: buildIndexableText(s.name, s.signature, s.docComment) });
|
|
2149
|
+
}
|
|
2150
|
+
if (vectorsAvailable) {
|
|
2151
|
+
vectorRows.push({
|
|
2152
|
+
id,
|
|
2153
|
+
vector: encodeVector(embedText(buildIndexableText(s.name, s.signature, s.docComment)))
|
|
2154
|
+
});
|
|
2155
|
+
}
|
|
2156
|
+
result.push({ ...s, id });
|
|
2157
|
+
}
|
|
2158
|
+
bulkInsertSymbolsWithStatement((sql) => stmtFn(sql), maxSqlVars, bulk);
|
|
2159
|
+
bulkInsertFtsWithStatement((sql) => stmtFn(sql), maxSqlVars, ftsAvailable, ftsRows);
|
|
2160
|
+
if (vectorsAvailable) {
|
|
2161
|
+
bulkInsertVectorsWithStatement((sql) => stmtFn(sql), maxSqlVars, vectorRows);
|
|
2162
|
+
}
|
|
2163
|
+
return result;
|
|
2164
|
+
}
|
|
2165
|
+
function upsertFileWithStatement(stmtFn, meta) {
|
|
2166
|
+
stmtFn(
|
|
2167
|
+
`INSERT INTO files(file, lang, mtime_ms, content_hash, symbol_count, last_indexed)
|
|
2168
|
+
VALUES (?, ?, ?, ?, ?, ?)
|
|
2169
|
+
ON CONFLICT(file) DO UPDATE SET
|
|
2170
|
+
lang = excluded.lang,
|
|
2171
|
+
mtime_ms = excluded.mtime_ms,
|
|
2172
|
+
content_hash = excluded.content_hash,
|
|
2173
|
+
symbol_count = excluded.symbol_count,
|
|
2174
|
+
last_indexed = excluded.last_indexed`
|
|
2175
|
+
).run(
|
|
2176
|
+
meta.file,
|
|
2177
|
+
meta.lang,
|
|
2178
|
+
meta.mtimeMs,
|
|
2179
|
+
meta.contentHash ?? "",
|
|
2180
|
+
meta.symbolCount,
|
|
2181
|
+
meta.lastIndexed
|
|
2182
|
+
);
|
|
2183
|
+
}
|
|
2184
|
+
function setFilePackagesWithStatement(stmtFn, entries) {
|
|
2185
|
+
if (entries.size === 0) return;
|
|
2186
|
+
const update = stmtFn("UPDATE files SET package = ? WHERE file = ?");
|
|
2187
|
+
for (const [file, label] of entries) update.run(label, file);
|
|
2188
|
+
}
|
|
2189
|
+
|
|
2190
|
+
// src/codebase-index/writer-pragmas.ts
|
|
2191
|
+
import { sqliteCachePragmas } from "@wrongstack/core/utils";
|
|
2192
|
+
function applyIndexStorePragmas(db) {
|
|
2193
|
+
try {
|
|
2194
|
+
db.exec("PRAGMA journal_mode = WAL");
|
|
2195
|
+
db.exec("PRAGMA synchronous = NORMAL");
|
|
2196
|
+
db.exec("PRAGMA busy_timeout = 15000");
|
|
2197
|
+
db.exec("PRAGMA temp_store = MEMORY");
|
|
2198
|
+
const cache = sqliteCachePragmas();
|
|
2199
|
+
db.exec(`PRAGMA cache_size = -${cache.cacheSizeKiB}`);
|
|
2200
|
+
db.exec(`PRAGMA mmap_size = ${cache.mmapBytes}`);
|
|
2201
|
+
db.exec("PRAGMA foreign_keys = ON");
|
|
2202
|
+
db.exec("PRAGMA journal_size_limit = 67108864");
|
|
2203
|
+
db.exec("PRAGMA wal_autocheckpoint = 1000");
|
|
2204
|
+
} catch {
|
|
2205
|
+
}
|
|
2206
|
+
}
|
|
2207
|
+
|
|
2208
|
+
// src/codebase-index/writer-refs.ts
|
|
2209
|
+
var FAMILY_MATCH_SQL = `(
|
|
2210
|
+
sym.lang = refs.lang
|
|
2211
|
+
OR refs.lang = ''
|
|
2212
|
+
OR EXISTS (
|
|
2213
|
+
SELECT 1 FROM lang_family lf1
|
|
2214
|
+
JOIN lang_family lf2 ON lf1.family = lf2.family
|
|
2215
|
+
WHERE lf1.lang = sym.lang AND lf2.lang = refs.lang
|
|
2216
|
+
)
|
|
1926
2217
|
OR ? IN (
|
|
1927
2218
|
SELECT family FROM lang_family WHERE lang = refs.lang
|
|
1928
2219
|
)
|
|
@@ -2517,180 +2808,26 @@ var IndexStore = class _IndexStore {
|
|
|
2517
2808
|
this.db.exec("ROLLBACK");
|
|
2518
2809
|
}
|
|
2519
2810
|
}
|
|
2520
|
-
seedLangFamilies() {
|
|
2521
|
-
const insert = this.stmt("INSERT OR REPLACE INTO lang_family(lang, family) VALUES (?, ?)");
|
|
2522
|
-
for (const [lang, family] of LANG_FAMILY_ENTRIES) insert.run(lang, family);
|
|
2523
|
-
insert.run("", LANG_FAMILY_WILDCARD);
|
|
2524
|
-
}
|
|
2525
|
-
repairMissingColumns() {
|
|
2526
|
-
const expected = [
|
|
2527
|
-
{
|
|
2528
|
-
table: "files",
|
|
2529
|
-
columns: [
|
|
2530
|
-
["package", "TEXT NOT NULL DEFAULT ''"],
|
|
2531
|
-
["content_hash", "TEXT NOT NULL DEFAULT ''"]
|
|
2532
|
-
]
|
|
2533
|
-
},
|
|
2534
|
-
{
|
|
2535
|
-
table: "refs",
|
|
2536
|
-
columns: [
|
|
2537
|
-
["lang", "TEXT NOT NULL DEFAULT ''"],
|
|
2538
|
-
["module", "TEXT"],
|
|
2539
|
-
["to_file", "TEXT"]
|
|
2540
|
-
]
|
|
2541
|
-
}
|
|
2542
|
-
];
|
|
2543
|
-
for (const { table, columns } of expected) {
|
|
2544
|
-
const rows = this.db.prepare(`PRAGMA table_info(${table})`).all();
|
|
2545
|
-
const present = /* @__PURE__ */ new Set();
|
|
2546
|
-
for (const row of rows) {
|
|
2547
|
-
if (typeof row.name === "string") present.add(row.name);
|
|
2548
|
-
}
|
|
2549
|
-
if (present.size === 0) continue;
|
|
2550
|
-
for (const [name, type] of columns) {
|
|
2551
|
-
if (present.has(name)) continue;
|
|
2552
|
-
this.db.exec(`ALTER TABLE ${table} ADD COLUMN ${name} ${type}`);
|
|
2553
|
-
}
|
|
2554
|
-
}
|
|
2555
|
-
}
|
|
2556
|
-
/**
|
|
2557
|
-
* P4: `symbols.text` duplicated name + signature + doc_comment (~19 MB on
|
|
2558
|
-
* the live index) and is derived on demand now. In-place DROP COLUMN — no
|
|
2559
|
-
* SCHEMA_VERSION bump, so no wipe-and-reparse. Best-effort: a busy or
|
|
2560
|
-
* SQLite-without-DROP-COLUMN open leaves the column in place, where new
|
|
2561
|
-
* inserts simply default it to '' and the next open retries.
|
|
2562
|
-
*/
|
|
2563
|
-
dropDeprecatedSymbolsColumns() {
|
|
2564
|
-
if (this.getMetadata(_IndexStore.SYMBOLS_TEXT_DROPPED_KEY) !== void 0) return;
|
|
2565
|
-
const present = new Set(
|
|
2566
|
-
this.db.prepare("PRAGMA table_info(symbols)").all().flatMap(
|
|
2567
|
-
(row) => typeof row.name === "string" ? [row.name] : []
|
|
2568
|
-
)
|
|
2569
|
-
);
|
|
2570
|
-
if (present.size === 0) return;
|
|
2571
|
-
if (!present.has("text")) {
|
|
2572
|
-
this.setMetadata(_IndexStore.SYMBOLS_TEXT_DROPPED_KEY, "1");
|
|
2573
|
-
return;
|
|
2574
|
-
}
|
|
2575
|
-
try {
|
|
2576
|
-
this.db.exec("ALTER TABLE symbols DROP COLUMN text");
|
|
2577
|
-
this.setMetadata(_IndexStore.SYMBOLS_TEXT_DROPPED_KEY, "1");
|
|
2578
|
-
} catch {
|
|
2579
|
-
}
|
|
2580
|
-
}
|
|
2581
2811
|
initSchema() {
|
|
2582
|
-
|
|
2583
|
-
|
|
2584
|
-
|
|
2585
|
-
|
|
2586
|
-
this.
|
|
2587
|
-
|
|
2588
|
-
|
|
2589
|
-
DROP TABLE IF EXISTS refs;
|
|
2590
|
-
DROP TABLE IF EXISTS symbol_vectors;
|
|
2591
|
-
`);
|
|
2592
|
-
this.db.exec("DROP TABLE IF EXISTS symbols_fts");
|
|
2593
|
-
this.stmt("UPDATE metadata SET value = ? WHERE key = ?").run(
|
|
2594
|
-
String(SCHEMA_VERSION),
|
|
2595
|
-
"version"
|
|
2596
|
-
);
|
|
2597
|
-
} else if (storedVersion === null) {
|
|
2598
|
-
this.stmt("INSERT INTO metadata(key, value) VALUES (?, ?)").run(
|
|
2599
|
-
"version",
|
|
2600
|
-
String(SCHEMA_VERSION)
|
|
2601
|
-
);
|
|
2602
|
-
}
|
|
2603
|
-
this.db.exec(CORE_TABLES_SQL);
|
|
2604
|
-
this.db.exec(REFS_TABLE_SQL);
|
|
2605
|
-
this.repairMissingColumns();
|
|
2606
|
-
this.dropDeprecatedSymbolsColumns();
|
|
2607
|
-
for (const sql of FILE_INDEX_SQL) this.db.exec(sql);
|
|
2608
|
-
for (const sql of SYMBOL_INDEX_SQL) this.db.exec(sql);
|
|
2609
|
-
for (const sql of REFS_INDEX_SQL) this.db.exec(sql);
|
|
2610
|
-
this.db.exec(LANG_FAMILY_TABLE_SQL);
|
|
2611
|
-
this.seedLangFamilies();
|
|
2612
|
-
try {
|
|
2613
|
-
const ftsSchema = this.stmt(
|
|
2614
|
-
"SELECT sql FROM sqlite_master WHERE type='table' AND name='symbols_fts'"
|
|
2615
|
-
).get();
|
|
2616
|
-
if (ftsSchema?.sql?.includes("unicode61")) {
|
|
2617
|
-
this.db.exec("DROP TABLE IF EXISTS symbols_fts");
|
|
2618
|
-
}
|
|
2619
|
-
this.db.exec(SYMBOLS_FTS_SQL);
|
|
2620
|
-
this.ftsAvailable = true;
|
|
2621
|
-
const symbolCount = Number(
|
|
2622
|
-
this.stmt("SELECT COUNT(*) AS n FROM symbols").get()?.n ?? 0
|
|
2623
|
-
);
|
|
2624
|
-
const ftsCount = Number(
|
|
2625
|
-
this.stmt("SELECT COUNT(*) AS n FROM symbols_fts").get()?.n ?? 0
|
|
2626
|
-
);
|
|
2627
|
-
if (symbolCount !== ftsCount) {
|
|
2628
|
-
this.db.exec("DELETE FROM symbols_fts");
|
|
2629
|
-
if (vectorEmbeddingEnabled() && this.stmt(
|
|
2630
|
-
"SELECT 1 FROM sqlite_master WHERE type='table' AND name='symbol_vectors'"
|
|
2631
|
-
).get() !== void 0) {
|
|
2632
|
-
this.db.exec("DELETE FROM symbol_vectors");
|
|
2633
|
-
}
|
|
2634
|
-
const rows = this.stmt(
|
|
2635
|
-
"SELECT id, name, signature, doc_comment FROM symbols ORDER BY id"
|
|
2636
|
-
).all();
|
|
2637
|
-
bulkInsertFtsWithStatement(
|
|
2638
|
-
(sql) => this.stmt(sql),
|
|
2639
|
-
_IndexStore.MAX_SQL_VARS,
|
|
2640
|
-
this.ftsAvailable,
|
|
2641
|
-
rows.map((row) => ({
|
|
2642
|
-
id: row.id,
|
|
2643
|
-
text: buildIndexableText(row.name, row.signature, row.doc_comment)
|
|
2644
|
-
}))
|
|
2645
|
-
);
|
|
2646
|
-
this.invalidateBm25();
|
|
2647
|
-
}
|
|
2648
|
-
} catch {
|
|
2649
|
-
this.ftsAvailable = false;
|
|
2650
|
-
}
|
|
2651
|
-
try {
|
|
2652
|
-
if (vectorEmbeddingEnabled()) {
|
|
2653
|
-
this.db.exec(SYMBOL_VECTORS_TABLE_SQL);
|
|
2654
|
-
this.vectorsAvailable = true;
|
|
2655
|
-
} else {
|
|
2656
|
-
this.db.exec("DROP TABLE IF EXISTS symbol_vectors");
|
|
2657
|
-
this.vectorsAvailable = false;
|
|
2658
|
-
}
|
|
2659
|
-
} catch {
|
|
2660
|
-
this.vectorsAvailable = false;
|
|
2661
|
-
}
|
|
2662
|
-
this.ensureNextSymbolIdSeeded();
|
|
2663
|
-
}
|
|
2664
|
-
static NEXT_SYMBOL_ID_KEY = "next_symbol_id";
|
|
2665
|
-
static MAX_SQL_VARS = 900;
|
|
2666
|
-
/** P2: persisted FTS-mutation churn counter — see {@link optimizeFtsIfNeeded}. */
|
|
2667
|
-
static FTS_CHURN_KEY = "fts_churn_since_maintain";
|
|
2668
|
-
/** P4: one-shot marker that the deprecated symbols.text column is gone. */
|
|
2669
|
-
static SYMBOLS_TEXT_DROPPED_KEY = "symbols_text_dropped";
|
|
2670
|
-
ensureNextSymbolIdSeeded() {
|
|
2671
|
-
const existing = this.stmt("SELECT value FROM metadata WHERE key = ?").get(
|
|
2672
|
-
_IndexStore.NEXT_SYMBOL_ID_KEY
|
|
2673
|
-
);
|
|
2674
|
-
if (existing?.value !== void 0) return;
|
|
2675
|
-
const maxRows = this.stmt("SELECT MAX(id) AS m FROM symbols").all();
|
|
2676
|
-
const next = (maxRows[0]?.m ?? 0) + 1;
|
|
2677
|
-
this.stmt("INSERT OR REPLACE INTO metadata(key, value) VALUES (?, ?)").run(
|
|
2678
|
-
_IndexStore.NEXT_SYMBOL_ID_KEY,
|
|
2679
|
-
String(next)
|
|
2812
|
+
const { ftsAvailable, vectorsAvailable } = initIndexSchema(
|
|
2813
|
+
this.db,
|
|
2814
|
+
(sql) => this.stmt(sql),
|
|
2815
|
+
(key) => this.getMetadata(key),
|
|
2816
|
+
(key, value) => this.setMetadata(key, value),
|
|
2817
|
+
_IndexStore.MAX_SQL_VARS,
|
|
2818
|
+
() => this.invalidateBm25()
|
|
2680
2819
|
);
|
|
2820
|
+
this.ftsAvailable = ftsAvailable;
|
|
2821
|
+
this.vectorsAvailable = vectorsAvailable;
|
|
2681
2822
|
}
|
|
2823
|
+
static NEXT_SYMBOL_ID_KEY = NEXT_SYMBOL_ID_KEY;
|
|
2824
|
+
static MAX_SQL_VARS = 900;
|
|
2682
2825
|
allocateSymbolIds(count) {
|
|
2683
|
-
|
|
2684
|
-
|
|
2685
|
-
|
|
2686
|
-
|
|
2687
|
-
);
|
|
2688
|
-
const start = Math.max(1, Number(row?.value ?? 1) || 1);
|
|
2689
|
-
this.stmt("INSERT OR REPLACE INTO metadata(key, value) VALUES (?, ?)").run(
|
|
2690
|
-
_IndexStore.NEXT_SYMBOL_ID_KEY,
|
|
2691
|
-
String(start + count)
|
|
2826
|
+
return allocateSymbolIds(
|
|
2827
|
+
(sql) => this.stmt(sql),
|
|
2828
|
+
count,
|
|
2829
|
+
() => this.getMaxSymbolId()
|
|
2692
2830
|
);
|
|
2693
|
-
return start;
|
|
2694
2831
|
}
|
|
2695
2832
|
invalidateIncomingRefsForFiles(files) {
|
|
2696
2833
|
if (files.length === 0) return /* @__PURE__ */ new Set();
|
|
@@ -2720,52 +2857,14 @@ var IndexStore = class _IndexStore {
|
|
|
2720
2857
|
return this.runWithRetry(() => {
|
|
2721
2858
|
const ownsTransaction = this.beginWriteTransaction();
|
|
2722
2859
|
try {
|
|
2723
|
-
|
|
2724
|
-
const result = [];
|
|
2725
|
-
const bulk = [];
|
|
2726
|
-
const ftsRows = [];
|
|
2727
|
-
const vectorRows = [];
|
|
2728
|
-
for (const s of symbols) {
|
|
2729
|
-
const id = nextId++;
|
|
2730
|
-
bulk.push({
|
|
2731
|
-
id,
|
|
2732
|
-
lang: s.lang,
|
|
2733
|
-
kind: s.kind,
|
|
2734
|
-
name: s.name,
|
|
2735
|
-
file: s.file,
|
|
2736
|
-
line: s.line,
|
|
2737
|
-
col: s.col,
|
|
2738
|
-
signature: s.signature,
|
|
2739
|
-
docComment: s.docComment,
|
|
2740
|
-
scope: s.scope
|
|
2741
|
-
});
|
|
2742
|
-
if (this.ftsAvailable) {
|
|
2743
|
-
ftsRows.push({ id, text: buildIndexableText(s.name, s.signature, s.docComment) });
|
|
2744
|
-
}
|
|
2745
|
-
if (this.vectorsAvailable) {
|
|
2746
|
-
vectorRows.push({
|
|
2747
|
-
id,
|
|
2748
|
-
vector: encodeVector(
|
|
2749
|
-
embedText(buildIndexableText(s.name, s.signature, s.docComment))
|
|
2750
|
-
)
|
|
2751
|
-
});
|
|
2752
|
-
}
|
|
2753
|
-
result.push({ ...s, id });
|
|
2754
|
-
}
|
|
2755
|
-
bulkInsertSymbolsWithStatement((sql) => this.stmt(sql), _IndexStore.MAX_SQL_VARS, bulk);
|
|
2756
|
-
bulkInsertFtsWithStatement(
|
|
2860
|
+
const result = insertSymbolsWithStatement(
|
|
2757
2861
|
(sql) => this.stmt(sql),
|
|
2758
2862
|
_IndexStore.MAX_SQL_VARS,
|
|
2759
2863
|
this.ftsAvailable,
|
|
2760
|
-
|
|
2864
|
+
this.vectorsAvailable,
|
|
2865
|
+
this.allocateSymbolIds.bind(this),
|
|
2866
|
+
symbols
|
|
2761
2867
|
);
|
|
2762
|
-
if (this.vectorsAvailable) {
|
|
2763
|
-
bulkInsertVectorsWithStatement(
|
|
2764
|
-
(sql) => this.stmt(sql),
|
|
2765
|
-
_IndexStore.MAX_SQL_VARS,
|
|
2766
|
-
vectorRows
|
|
2767
|
-
);
|
|
2768
|
-
}
|
|
2769
2868
|
this.recordFtsChurn(symbols.length);
|
|
2770
2869
|
this.commitWriteTransaction(ownsTransaction);
|
|
2771
2870
|
return result;
|
|
@@ -2836,25 +2935,7 @@ var IndexStore = class _IndexStore {
|
|
|
2836
2935
|
});
|
|
2837
2936
|
}
|
|
2838
2937
|
upsertFile(meta) {
|
|
2839
|
-
this.runWithRetry(() =>
|
|
2840
|
-
this.stmt(
|
|
2841
|
-
`INSERT INTO files(file, lang, mtime_ms, content_hash, symbol_count, last_indexed)
|
|
2842
|
-
VALUES (?, ?, ?, ?, ?, ?)
|
|
2843
|
-
ON CONFLICT(file) DO UPDATE SET
|
|
2844
|
-
lang = excluded.lang,
|
|
2845
|
-
mtime_ms = excluded.mtime_ms,
|
|
2846
|
-
content_hash = excluded.content_hash,
|
|
2847
|
-
symbol_count = excluded.symbol_count,
|
|
2848
|
-
last_indexed = excluded.last_indexed`
|
|
2849
|
-
).run(
|
|
2850
|
-
meta.file,
|
|
2851
|
-
meta.lang,
|
|
2852
|
-
meta.mtimeMs,
|
|
2853
|
-
meta.contentHash ?? "",
|
|
2854
|
-
meta.symbolCount,
|
|
2855
|
-
meta.lastIndexed
|
|
2856
|
-
);
|
|
2857
|
-
});
|
|
2938
|
+
this.runWithRetry(() => upsertFileWithStatement((sql) => this.stmt(sql), meta));
|
|
2858
2939
|
}
|
|
2859
2940
|
getFileMeta(file) {
|
|
2860
2941
|
return getFileMetaWithStatement((sql) => this.stmt(sql), file);
|
|
@@ -2863,11 +2944,7 @@ var IndexStore = class _IndexStore {
|
|
|
2863
2944
|
return getAllFileMetasWithStatement((sql) => this.stmt(sql));
|
|
2864
2945
|
}
|
|
2865
2946
|
setFilePackages(entries) {
|
|
2866
|
-
|
|
2867
|
-
this.runWithRetry(() => {
|
|
2868
|
-
const update = this.stmt("UPDATE files SET package = ? WHERE file = ?");
|
|
2869
|
-
for (const [file, label] of entries) update.run(label, file);
|
|
2870
|
-
});
|
|
2947
|
+
this.runWithRetry(() => setFilePackagesWithStatement((sql) => this.stmt(sql), entries));
|
|
2871
2948
|
}
|
|
2872
2949
|
getNamespaceDeclarations() {
|
|
2873
2950
|
return getNamespaceDeclarationsWithStatement((sql) => this.stmt(sql));
|
|
@@ -3089,10 +3166,7 @@ var IndexStore = class _IndexStore {
|
|
|
3089
3166
|
});
|
|
3090
3167
|
}
|
|
3091
3168
|
optimize() {
|
|
3092
|
-
|
|
3093
|
-
this.db.exec("PRAGMA optimize");
|
|
3094
|
-
} catch {
|
|
3095
|
-
}
|
|
3169
|
+
optimizeStore(this.db);
|
|
3096
3170
|
}
|
|
3097
3171
|
/**
|
|
3098
3172
|
* P2: churn-gated FTS5 segment maintenance.
|
|
@@ -3110,23 +3184,14 @@ var IndexStore = class _IndexStore {
|
|
|
3110
3184
|
* it ran, safe to call from the daemon's single-threaded idle path.
|
|
3111
3185
|
*/
|
|
3112
3186
|
optimizeFtsIfNeeded(options = {}) {
|
|
3113
|
-
|
|
3114
|
-
|
|
3115
|
-
|
|
3116
|
-
|
|
3117
|
-
|
|
3118
|
-
|
|
3119
|
-
|
|
3120
|
-
|
|
3121
|
-
if (churn < Math.max(minChurnRows, liveRows * minChurnRatio)) return false;
|
|
3122
|
-
this.runWithRetry(() => {
|
|
3123
|
-
this.stmt(`INSERT INTO symbols_fts(symbols_fts) VALUES('optimize')`).run();
|
|
3124
|
-
});
|
|
3125
|
-
this.setMetadata(_IndexStore.FTS_CHURN_KEY, "0");
|
|
3126
|
-
return true;
|
|
3127
|
-
} catch {
|
|
3128
|
-
return false;
|
|
3129
|
-
}
|
|
3187
|
+
return optimizeFtsIfNeeded(
|
|
3188
|
+
(sql) => this.stmt(sql),
|
|
3189
|
+
this.ftsAvailable,
|
|
3190
|
+
(key) => this.getMetadata(key),
|
|
3191
|
+
(key, value) => this.setMetadata(key, value),
|
|
3192
|
+
(fn) => this.runWithRetry(fn),
|
|
3193
|
+
options
|
|
3194
|
+
);
|
|
3130
3195
|
}
|
|
3131
3196
|
/**
|
|
3132
3197
|
* Best-effort churn bookkeeping for {@link optimizeFtsIfNeeded}. Counts the
|
|
@@ -3135,12 +3200,12 @@ var IndexStore = class _IndexStore {
|
|
|
3135
3200
|
* survives store open/close cycles in the daemon pool.
|
|
3136
3201
|
*/
|
|
3137
3202
|
recordFtsChurn(rows) {
|
|
3138
|
-
|
|
3139
|
-
|
|
3140
|
-
|
|
3141
|
-
this.setMetadata(
|
|
3142
|
-
|
|
3143
|
-
|
|
3203
|
+
recordFtsChurn(
|
|
3204
|
+
this.ftsAvailable,
|
|
3205
|
+
(key) => this.getMetadata(key),
|
|
3206
|
+
(key, value) => this.setMetadata(key, value),
|
|
3207
|
+
rows
|
|
3208
|
+
);
|
|
3144
3209
|
}
|
|
3145
3210
|
/**
|
|
3146
3211
|
* P4.14: best-effort WAL checkpoint for idle-time maintenance.
|
|
@@ -3154,40 +3219,15 @@ var IndexStore = class _IndexStore {
|
|
|
3154
3219
|
* never wait on readers here: busy means "retry at the next idle window".
|
|
3155
3220
|
*/
|
|
3156
3221
|
checkpointWal() {
|
|
3157
|
-
|
|
3158
|
-
const probe = this.db.prepare("PRAGMA wal_checkpoint(PASSIVE)").get();
|
|
3159
|
-
if (Number(probe?.busy ?? 1) !== 0) return false;
|
|
3160
|
-
const done = this.db.prepare("PRAGMA wal_checkpoint(TRUNCATE)").get();
|
|
3161
|
-
return Number(done?.busy ?? 1) === 0;
|
|
3162
|
-
} catch {
|
|
3163
|
-
return false;
|
|
3164
|
-
}
|
|
3222
|
+
return checkpointWal(this.db);
|
|
3165
3223
|
}
|
|
3166
3224
|
compactIfNeeded(options = {}) {
|
|
3167
|
-
|
|
3168
|
-
|
|
3169
|
-
|
|
3170
|
-
|
|
3171
|
-
|
|
3172
|
-
|
|
3173
|
-
const pageSize = Number(
|
|
3174
|
-
this.stmt("PRAGMA page_size").get()?.page_size ?? 0
|
|
3175
|
-
);
|
|
3176
|
-
const freePages = Number(
|
|
3177
|
-
this.stmt("PRAGMA freelist_count").get()?.freelist_count ?? 0
|
|
3178
|
-
);
|
|
3179
|
-
if (pageCount <= 0 || pageSize <= 0 || pageCount * pageSize < minBytes || freePages / pageCount < minFreeRatio) {
|
|
3180
|
-
return false;
|
|
3181
|
-
}
|
|
3182
|
-
this.runWithRetry(() => {
|
|
3183
|
-
this.db.exec("PRAGMA wal_checkpoint(TRUNCATE)");
|
|
3184
|
-
this.db.exec("VACUUM");
|
|
3185
|
-
this.db.exec("PRAGMA wal_checkpoint(TRUNCATE)");
|
|
3186
|
-
});
|
|
3187
|
-
return true;
|
|
3188
|
-
} catch {
|
|
3189
|
-
return false;
|
|
3190
|
-
}
|
|
3225
|
+
return compactIfNeeded(
|
|
3226
|
+
this.db,
|
|
3227
|
+
(sql) => this.stmt(sql),
|
|
3228
|
+
(fn) => this.runWithRetry(fn),
|
|
3229
|
+
options
|
|
3230
|
+
);
|
|
3191
3231
|
}
|
|
3192
3232
|
findIncomingCallsByName(symbolName, file, limit = 100) {
|
|
3193
3233
|
return findIncomingCallsByName((sql) => this.stmt(sql), symbolName, file, limit);
|
|
@@ -4608,4 +4648,4 @@ export {
|
|
|
4608
4648
|
incomingCallsService,
|
|
4609
4649
|
outgoingCallsService
|
|
4610
4650
|
};
|
|
4611
|
-
//# sourceMappingURL=chunk-
|
|
4651
|
+
//# sourceMappingURL=chunk-N3K2SFEI.js.map
|