raggrep 0.10.1 → 0.10.4
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/app/indexer/index.d.ts +30 -0
- package/dist/cli/main.js +169 -39
- package/dist/cli/main.js.map +5 -5
- package/dist/index.js +144 -36
- package/dist/index.js.map +4 -4
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -11395,6 +11395,11 @@ import { watch } from "chokidar";
|
|
|
11395
11395
|
init_config2();
|
|
11396
11396
|
|
|
11397
11397
|
// src/app/indexer/index.ts
|
|
11398
|
+
var FRESHNESS_CACHE_TTL_MS = 5000;
|
|
11399
|
+
var freshnessCache = null;
|
|
11400
|
+
function clearFreshnessCache() {
|
|
11401
|
+
freshnessCache = null;
|
|
11402
|
+
}
|
|
11398
11403
|
function computeContentHash(content) {
|
|
11399
11404
|
return crypto2.createHash("sha256").update(content, "utf-8").digest("hex");
|
|
11400
11405
|
}
|
|
@@ -11436,10 +11441,12 @@ function getOptimalConcurrency() {
|
|
|
11436
11441
|
return optimal;
|
|
11437
11442
|
}
|
|
11438
11443
|
var DEFAULT_CONCURRENCY = getOptimalConcurrency();
|
|
11444
|
+
var STAT_CONCURRENCY = Math.max(32, getOptimalConcurrency() * 4);
|
|
11439
11445
|
async function indexDirectory(rootDir, options = {}) {
|
|
11440
11446
|
const verbose = options.verbose ?? false;
|
|
11441
11447
|
const quiet = options.quiet ?? false;
|
|
11442
11448
|
const concurrency = options.concurrency ?? DEFAULT_CONCURRENCY;
|
|
11449
|
+
clearFreshnessCache();
|
|
11443
11450
|
const logger = options.logger ? options.logger : quiet ? createSilentLogger() : createLogger({ verbose });
|
|
11444
11451
|
rootDir = path21.resolve(rootDir);
|
|
11445
11452
|
const location = getIndexLocation(rootDir);
|
|
@@ -11538,6 +11545,7 @@ async function deleteIndex(rootDir) {
|
|
|
11538
11545
|
}
|
|
11539
11546
|
async function resetIndex(rootDir) {
|
|
11540
11547
|
rootDir = path21.resolve(rootDir);
|
|
11548
|
+
clearFreshnessCache();
|
|
11541
11549
|
const status = await getIndexStatus(rootDir);
|
|
11542
11550
|
if (!status.exists) {
|
|
11543
11551
|
throw new Error(`No index found for ${rootDir}`);
|
|
@@ -11551,10 +11559,20 @@ async function resetIndex(rootDir) {
|
|
|
11551
11559
|
async function ensureIndexFresh(rootDir, options = {}) {
|
|
11552
11560
|
const verbose = options.verbose ?? false;
|
|
11553
11561
|
const quiet = options.quiet ?? false;
|
|
11562
|
+
const showTiming = options.timing ?? false;
|
|
11563
|
+
const startTime = Date.now();
|
|
11564
|
+
let fileDiscoveryMs = 0;
|
|
11565
|
+
let statCheckMs = 0;
|
|
11566
|
+
let indexingMs = 0;
|
|
11567
|
+
let cleanupMs = 0;
|
|
11568
|
+
let filesDiscovered = 0;
|
|
11569
|
+
let filesStatChecked = 0;
|
|
11570
|
+
let filesIndexed = 0;
|
|
11554
11571
|
const logger = options.logger ? options.logger : quiet ? createSilentLogger() : createLogger({ verbose });
|
|
11555
11572
|
rootDir = path21.resolve(rootDir);
|
|
11556
11573
|
const status = await getIndexStatus(rootDir);
|
|
11557
11574
|
if (!status.exists) {
|
|
11575
|
+
clearFreshnessCache();
|
|
11558
11576
|
logger.info(`No index found. Creating index...
|
|
11559
11577
|
`);
|
|
11560
11578
|
const results = await indexDirectory(rootDir, { ...options, logger });
|
|
@@ -11563,6 +11581,7 @@ async function ensureIndexFresh(rootDir, options = {}) {
|
|
|
11563
11581
|
}
|
|
11564
11582
|
const versionCompatible = await isIndexVersionCompatible(rootDir);
|
|
11565
11583
|
if (!versionCompatible) {
|
|
11584
|
+
clearFreshnessCache();
|
|
11566
11585
|
logger.info(`Index version incompatible. Rebuilding...
|
|
11567
11586
|
`);
|
|
11568
11587
|
await deleteIndex(rootDir);
|
|
@@ -11571,14 +11590,44 @@ async function ensureIndexFresh(rootDir, options = {}) {
|
|
|
11571
11590
|
return { indexed: totalIndexed2, removed: 0, unchanged: 0 };
|
|
11572
11591
|
}
|
|
11573
11592
|
const config = await loadConfig(rootDir);
|
|
11593
|
+
const globalManifestPath = getGlobalManifestPath(rootDir, config);
|
|
11594
|
+
let currentManifestMtime = 0;
|
|
11595
|
+
try {
|
|
11596
|
+
const manifestStats = await fs8.stat(globalManifestPath);
|
|
11597
|
+
currentManifestMtime = manifestStats.mtimeMs;
|
|
11598
|
+
} catch {}
|
|
11599
|
+
const now = Date.now();
|
|
11600
|
+
if (freshnessCache && freshnessCache.rootDir === rootDir && now - freshnessCache.timestamp < FRESHNESS_CACHE_TTL_MS && freshnessCache.manifestMtime === currentManifestMtime) {
|
|
11601
|
+
logger.debug("Using cached freshness check result");
|
|
11602
|
+
const cachedResult = { ...freshnessCache.result };
|
|
11603
|
+
if (showTiming) {
|
|
11604
|
+
cachedResult.timing = {
|
|
11605
|
+
totalMs: Date.now() - startTime,
|
|
11606
|
+
fileDiscoveryMs: 0,
|
|
11607
|
+
statCheckMs: 0,
|
|
11608
|
+
indexingMs: 0,
|
|
11609
|
+
cleanupMs: 0,
|
|
11610
|
+
filesDiscovered: 0,
|
|
11611
|
+
filesStatChecked: 0,
|
|
11612
|
+
filesIndexed: 0,
|
|
11613
|
+
fromCache: true
|
|
11614
|
+
};
|
|
11615
|
+
}
|
|
11616
|
+
return cachedResult;
|
|
11617
|
+
}
|
|
11574
11618
|
await registerBuiltInModules();
|
|
11575
11619
|
const enabledModules = registry.getEnabled(config);
|
|
11576
11620
|
if (enabledModules.length === 0) {
|
|
11577
11621
|
return { indexed: 0, removed: 0, unchanged: 0 };
|
|
11578
11622
|
}
|
|
11623
|
+
const fileDiscoveryStart = Date.now();
|
|
11579
11624
|
const introspection = new IntrospectionIndex(rootDir);
|
|
11580
|
-
await
|
|
11581
|
-
|
|
11625
|
+
const [, currentFiles] = await Promise.all([
|
|
11626
|
+
introspection.initialize(),
|
|
11627
|
+
findFiles(rootDir, config)
|
|
11628
|
+
]);
|
|
11629
|
+
fileDiscoveryMs = Date.now() - fileDiscoveryStart;
|
|
11630
|
+
filesDiscovered = currentFiles.length;
|
|
11582
11631
|
const currentFileSet = new Set(currentFiles.map((f) => path21.relative(rootDir, f)));
|
|
11583
11632
|
let totalIndexed = 0;
|
|
11584
11633
|
let totalRemoved = 0;
|
|
@@ -11607,20 +11656,21 @@ async function ensureIndexFresh(rootDir, options = {}) {
|
|
|
11607
11656
|
filesToRemove.push(filepath);
|
|
11608
11657
|
}
|
|
11609
11658
|
}
|
|
11659
|
+
const cleanupStart = Date.now();
|
|
11610
11660
|
const removedFilepaths = [];
|
|
11611
|
-
|
|
11612
|
-
|
|
11613
|
-
|
|
11614
|
-
|
|
11615
|
-
|
|
11616
|
-
|
|
11617
|
-
|
|
11618
|
-
|
|
11619
|
-
|
|
11620
|
-
|
|
11621
|
-
|
|
11622
|
-
|
|
11623
|
-
totalRemoved
|
|
11661
|
+
if (filesToRemove.length > 0) {
|
|
11662
|
+
await Promise.all(filesToRemove.map(async (filepath) => {
|
|
11663
|
+
logger.debug(` Removing stale: ${filepath}`);
|
|
11664
|
+
const indexFilePath = path21.join(indexPath, filepath.replace(/\.[^.]+$/, ".json"));
|
|
11665
|
+
const symbolicFilePath = path21.join(indexPath, "symbolic", filepath.replace(/\.[^.]+$/, ".json"));
|
|
11666
|
+
await Promise.all([
|
|
11667
|
+
fs8.unlink(indexFilePath).catch(() => {}),
|
|
11668
|
+
fs8.unlink(symbolicFilePath).catch(() => {})
|
|
11669
|
+
]);
|
|
11670
|
+
delete manifest.files[filepath];
|
|
11671
|
+
removedFilepaths.push(filepath);
|
|
11672
|
+
}));
|
|
11673
|
+
totalRemoved += removedFilepaths.length;
|
|
11624
11674
|
}
|
|
11625
11675
|
if (removedFilepaths.length > 0) {
|
|
11626
11676
|
try {
|
|
@@ -11634,6 +11684,7 @@ async function ensureIndexFresh(rootDir, options = {}) {
|
|
|
11634
11684
|
await literalIndex.save();
|
|
11635
11685
|
} catch {}
|
|
11636
11686
|
}
|
|
11687
|
+
cleanupMs += Date.now() - cleanupStart;
|
|
11637
11688
|
const ctx = {
|
|
11638
11689
|
rootDir,
|
|
11639
11690
|
config,
|
|
@@ -11648,21 +11699,51 @@ async function ensureIndexFresh(rootDir, options = {}) {
|
|
|
11648
11699
|
},
|
|
11649
11700
|
getIntrospection: (filepath) => introspection.getFile(filepath)
|
|
11650
11701
|
};
|
|
11651
|
-
const
|
|
11652
|
-
let completedCount = 0;
|
|
11653
|
-
const processIncrementalFile = async (filepath) => {
|
|
11702
|
+
const statCheck = async (filepath) => {
|
|
11654
11703
|
const relativePath = path21.relative(rootDir, filepath);
|
|
11655
11704
|
try {
|
|
11656
11705
|
const stats = await fs8.stat(filepath);
|
|
11657
11706
|
const lastModified = stats.mtime.toISOString();
|
|
11658
11707
|
const existingEntry = manifest.files[relativePath];
|
|
11659
|
-
if (existingEntry
|
|
11660
|
-
|
|
11661
|
-
|
|
11708
|
+
if (!existingEntry) {
|
|
11709
|
+
return { filepath, relativePath, lastModified, needsCheck: true, isNew: true };
|
|
11710
|
+
}
|
|
11711
|
+
if (existingEntry.lastModified === lastModified) {
|
|
11712
|
+
return { filepath, relativePath, lastModified, needsCheck: false, isNew: false };
|
|
11662
11713
|
}
|
|
11714
|
+
return { filepath, relativePath, lastModified, needsCheck: true, isNew: false };
|
|
11715
|
+
} catch {
|
|
11716
|
+
return null;
|
|
11717
|
+
}
|
|
11718
|
+
};
|
|
11719
|
+
const statCheckStart = Date.now();
|
|
11720
|
+
const statResults = await parallelMap(currentFiles, statCheck, STAT_CONCURRENCY);
|
|
11721
|
+
statCheckMs += Date.now() - statCheckStart;
|
|
11722
|
+
filesStatChecked += currentFiles.length;
|
|
11723
|
+
const filesToProcess = [];
|
|
11724
|
+
let unchangedCount = 0;
|
|
11725
|
+
for (const result2 of statResults) {
|
|
11726
|
+
if (!result2.success || !result2.value)
|
|
11727
|
+
continue;
|
|
11728
|
+
if (result2.value.needsCheck) {
|
|
11729
|
+
filesToProcess.push(result2.value);
|
|
11730
|
+
} else {
|
|
11731
|
+
unchangedCount++;
|
|
11732
|
+
}
|
|
11733
|
+
}
|
|
11734
|
+
if (filesToProcess.length === 0) {
|
|
11735
|
+
totalUnchanged += unchangedCount;
|
|
11736
|
+
continue;
|
|
11737
|
+
}
|
|
11738
|
+
let completedCount = 0;
|
|
11739
|
+
const totalToProcess = filesToProcess.length;
|
|
11740
|
+
const processChangedFile = async (statResult) => {
|
|
11741
|
+
const { filepath, relativePath, lastModified, isNew } = statResult;
|
|
11742
|
+
try {
|
|
11663
11743
|
const content = await fs8.readFile(filepath, "utf-8");
|
|
11664
11744
|
const contentHash = computeContentHash(content);
|
|
11665
|
-
|
|
11745
|
+
const existingEntry = manifest.files[relativePath];
|
|
11746
|
+
if (!isNew && existingEntry?.contentHash && existingEntry.contentHash === contentHash) {
|
|
11666
11747
|
completedCount++;
|
|
11667
11748
|
return {
|
|
11668
11749
|
relativePath,
|
|
@@ -11672,7 +11753,7 @@ async function ensureIndexFresh(rootDir, options = {}) {
|
|
|
11672
11753
|
};
|
|
11673
11754
|
}
|
|
11674
11755
|
completedCount++;
|
|
11675
|
-
logger.progress(` [${completedCount}/${
|
|
11756
|
+
logger.progress(` [${completedCount}/${totalToProcess}] Indexing: ${relativePath}`);
|
|
11676
11757
|
introspection.addFile(relativePath, content);
|
|
11677
11758
|
const fileIndex = await module2.indexFile(relativePath, content, ctx);
|
|
11678
11759
|
if (!fileIndex) {
|
|
@@ -11691,8 +11772,12 @@ async function ensureIndexFresh(rootDir, options = {}) {
|
|
|
11691
11772
|
return { relativePath, status: "error", error };
|
|
11692
11773
|
}
|
|
11693
11774
|
};
|
|
11775
|
+
const indexingStart = Date.now();
|
|
11694
11776
|
const concurrency = options.concurrency ?? DEFAULT_CONCURRENCY;
|
|
11695
|
-
const results = await parallelMap(
|
|
11777
|
+
const results = await parallelMap(filesToProcess, processChangedFile, concurrency);
|
|
11778
|
+
indexingMs += Date.now() - indexingStart;
|
|
11779
|
+
filesIndexed += filesToProcess.length;
|
|
11780
|
+
totalUnchanged += unchangedCount;
|
|
11696
11781
|
logger.clearProgress();
|
|
11697
11782
|
let mtimeUpdates = 0;
|
|
11698
11783
|
for (const item of results) {
|
|
@@ -11746,12 +11831,38 @@ async function ensureIndexFresh(rootDir, options = {}) {
|
|
|
11746
11831
|
}
|
|
11747
11832
|
if (totalIndexed > 0 || totalRemoved > 0) {
|
|
11748
11833
|
await updateGlobalManifest(rootDir, enabledModules, config);
|
|
11834
|
+
clearFreshnessCache();
|
|
11749
11835
|
}
|
|
11750
|
-
|
|
11836
|
+
const result = {
|
|
11751
11837
|
indexed: totalIndexed,
|
|
11752
11838
|
removed: totalRemoved,
|
|
11753
11839
|
unchanged: totalUnchanged
|
|
11754
11840
|
};
|
|
11841
|
+
if (showTiming) {
|
|
11842
|
+
result.timing = {
|
|
11843
|
+
totalMs: Date.now() - startTime,
|
|
11844
|
+
fileDiscoveryMs,
|
|
11845
|
+
statCheckMs,
|
|
11846
|
+
indexingMs,
|
|
11847
|
+
cleanupMs,
|
|
11848
|
+
filesDiscovered,
|
|
11849
|
+
filesStatChecked,
|
|
11850
|
+
filesIndexed,
|
|
11851
|
+
fromCache: false
|
|
11852
|
+
};
|
|
11853
|
+
}
|
|
11854
|
+
let finalManifestMtime = currentManifestMtime;
|
|
11855
|
+
try {
|
|
11856
|
+
const manifestStats = await fs8.stat(globalManifestPath);
|
|
11857
|
+
finalManifestMtime = manifestStats.mtimeMs;
|
|
11858
|
+
} catch {}
|
|
11859
|
+
freshnessCache = {
|
|
11860
|
+
rootDir,
|
|
11861
|
+
result: { indexed: totalIndexed, removed: totalRemoved, unchanged: totalUnchanged },
|
|
11862
|
+
timestamp: Date.now(),
|
|
11863
|
+
manifestMtime: finalManifestMtime
|
|
11864
|
+
};
|
|
11865
|
+
return result;
|
|
11755
11866
|
}
|
|
11756
11867
|
async function indexWithModule(rootDir, files, module2, config, verbose, introspection, logger, concurrency = DEFAULT_CONCURRENCY) {
|
|
11757
11868
|
const result = {
|
|
@@ -11889,16 +12000,13 @@ async function indexWithModule(rootDir, files, module2, config, verbose, introsp
|
|
|
11889
12000
|
async function findFiles(rootDir, config) {
|
|
11890
12001
|
const patterns = config.extensions.map((ext) => `**/*${ext}`);
|
|
11891
12002
|
const ignorePatterns = config.ignorePaths.map((p) => `**/${p}/**`);
|
|
11892
|
-
const
|
|
11893
|
-
|
|
11894
|
-
|
|
11895
|
-
|
|
11896
|
-
|
|
11897
|
-
|
|
11898
|
-
|
|
11899
|
-
files.push(...matches);
|
|
11900
|
-
}
|
|
11901
|
-
return [...new Set(files)];
|
|
12003
|
+
const results = await Promise.all(patterns.map((pattern) => glob(pattern, {
|
|
12004
|
+
cwd: rootDir,
|
|
12005
|
+
absolute: true,
|
|
12006
|
+
ignore: ignorePatterns
|
|
12007
|
+
})));
|
|
12008
|
+
const allFiles = results.flat();
|
|
12009
|
+
return [...new Set(allFiles)];
|
|
11902
12010
|
}
|
|
11903
12011
|
async function loadModuleManifest(rootDir, moduleId, config) {
|
|
11904
12012
|
const manifestPath = getModuleManifestPath(rootDir, moduleId, config);
|
|
@@ -13476,4 +13584,4 @@ export {
|
|
|
13476
13584
|
ConsoleLogger
|
|
13477
13585
|
};
|
|
13478
13586
|
|
|
13479
|
-
//# debugId=
|
|
13587
|
+
//# debugId=EA9D4B791B6DE73764756E2164756E21
|