@wrongstack/tools 0.265.1 → 0.268.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.
@@ -2013,6 +2013,7 @@ async function loadGitignoreMatcher(projectRoot) {
2013
2013
 
2014
2014
  // src/codebase-index/indexer.ts
2015
2015
  var YIELD_EVERY_N = 50;
2016
+ var PARALLEL_BATCH = 20;
2016
2017
  function yieldEventLoop() {
2017
2018
  return new Promise((resolve2) => setImmediate(resolve2));
2018
2019
  }
@@ -2146,97 +2147,108 @@ async function runIndexerWithStore(store, opts) {
2146
2147
  if (!force) {
2147
2148
  for (const meta of store.getAllFileMetas()) existingMeta.set(meta.file, meta);
2148
2149
  }
2149
- for (let fi = 0; fi < files.length; fi++) {
2150
- const file = expectDefined(files[fi]);
2151
- opts.onProgress?.(fi + 1, files.length);
2152
- if (fi > 0 && fi % YIELD_EVERY_N === 0) {
2150
+ for (let batchStart = 0; batchStart < files.length; batchStart += PARALLEL_BATCH) {
2151
+ const batchEnd = Math.min(batchStart + PARALLEL_BATCH, files.length);
2152
+ const batchFiles = files.slice(batchStart, batchEnd);
2153
+ opts.onProgress?.(batchEnd, files.length);
2154
+ if (batchStart > 0 && batchStart % YIELD_EVERY_N === 0) {
2153
2155
  await yieldEventLoop();
2154
2156
  throwIfAborted(signal);
2155
2157
  }
2156
- let stat2;
2157
- try {
2158
- const statOpts = signal ? { signal } : {};
2159
- stat2 = await fs3.stat(file, statOpts);
2160
- } catch (e) {
2161
- if (isAbortError(e)) throw e;
2162
- store.deleteFile(file);
2163
- continue;
2164
- }
2165
- if (!stat2.isFile()) continue;
2166
- const lang = detectLang(file);
2167
- if (!lang) continue;
2168
- const meta = existingMeta.get(file);
2169
- if (!force && meta && meta.mtimeMs === Math.floor(stat2.mtimeMs)) {
2170
- langStats[lang] = (langStats[lang] ?? 0) + meta.symbolCount;
2171
- symbolsIndexed += meta.symbolCount;
2172
- filesIndexed++;
2173
- continue;
2174
- }
2175
- store.deleteRefsForFile(file);
2176
- store.deleteSymbolsForFile(file);
2177
- let content;
2178
- try {
2179
- content = await fs3.readFile(file, { encoding: "utf8", signal });
2180
- } catch (e) {
2181
- if (isAbortError(e)) throw e;
2182
- errors.push(`read error: ${file}: ${e instanceof Error ? e.message : String(e)}`);
2183
- continue;
2184
- }
2185
- let parsed;
2186
- try {
2187
- parsed = await parseFile(file, content, lang);
2188
- } catch (e) {
2189
- errors.push(`parse error: ${file}: ${e instanceof Error ? e.message : String(e)}`);
2190
- continue;
2191
- }
2192
- if (parsed.symbols.length === 0) {
2193
- store.upsertFile({
2194
- file,
2195
- lang,
2196
- mtimeMs: Math.floor(stat2.mtimeMs),
2197
- symbolCount: 0,
2198
- lastIndexed: Date.now()
2199
- });
2200
- filesIndexed++;
2201
- continue;
2202
- }
2203
- const nextId = store.getMaxSymbolId() + 1;
2204
- const symbolsWithIds = parsed.symbols.map((s, i) => ({ ...s, id: nextId + i }));
2205
- store.insertSymbols(symbolsWithIds, nextId);
2206
- const count = symbolsWithIds.length;
2207
- symbolsIndexed += count;
2208
- langStats[lang] = (langStats[lang] ?? 0) + count;
2209
- if (parsed.refs && parsed.refs.length > 0) {
2210
- const refsByLine = /* @__PURE__ */ new Map();
2211
- for (const r of parsed.refs) {
2212
- let arr = refsByLine.get(r.line);
2213
- if (!arr) {
2214
- arr = [];
2215
- refsByLine.set(r.line, arr);
2158
+ const statOpts = signal ? { signal } : {};
2159
+ const statReadParse = await Promise.allSettled(
2160
+ batchFiles.map(async (file) => {
2161
+ let stat2;
2162
+ try {
2163
+ stat2 = await fs3.stat(file, statOpts);
2164
+ } catch (e) {
2165
+ if (isAbortError(e)) throw e;
2166
+ return { file, stat: null, lang: "", parsed: null, error: `stat error: ${e instanceof Error ? e.message : String(e)}` };
2167
+ }
2168
+ if (!stat2.isFile()) return { file, stat: stat2, lang: "", parsed: null };
2169
+ const lang = detectLang(file);
2170
+ if (!lang) return { file, stat: stat2, lang: "", parsed: null };
2171
+ let content;
2172
+ try {
2173
+ content = await fs3.readFile(file, { encoding: "utf8", signal });
2174
+ } catch (e) {
2175
+ if (isAbortError(e)) throw e;
2176
+ return { file, stat: stat2, lang, parsed: null, error: `read error: ${e instanceof Error ? e.message : String(e)}` };
2216
2177
  }
2217
- arr.push(r);
2178
+ let parsed;
2179
+ try {
2180
+ parsed = await parseFile(file, content, lang);
2181
+ } catch (e) {
2182
+ return { file, stat: stat2, lang, parsed: null, error: `parse error: ${e instanceof Error ? e.message : String(e)}` };
2183
+ }
2184
+ return { file, stat: stat2, lang, parsed, content };
2185
+ })
2186
+ );
2187
+ for (let fi = 0; fi < statReadParse.length; fi++) {
2188
+ const settled = statReadParse[fi];
2189
+ const file = expectDefined(batchFiles[fi]);
2190
+ if (settled.status === "rejected") {
2191
+ const err = settled.reason;
2192
+ if (err instanceof Error && isAbortError(err)) throw err;
2193
+ errors.push(`batch error: ${file}: ${err instanceof Error ? err.message : String(err)}`);
2194
+ continue;
2218
2195
  }
2219
- const batch = [];
2220
- for (const sym of symbolsWithIds) {
2221
- const symRefs = refsByLine.get(sym.line);
2222
- if (symRefs) {
2223
- for (const r of symRefs) {
2224
- batch.push({ ...r, fromId: sym.id });
2225
- }
2196
+ const result = settled.value;
2197
+ if (result.error) {
2198
+ if (result.stat) store.deleteFile(file);
2199
+ if (result.error.includes("error:")) errors.push(result.error);
2200
+ continue;
2201
+ }
2202
+ const { stat: stat2, lang, parsed } = result;
2203
+ if (!lang || !parsed) {
2204
+ if (lang) {
2205
+ store.upsertFile({ file, lang, mtimeMs: Math.floor(stat2.mtimeMs), symbolCount: 0, lastIndexed: Date.now() });
2206
+ filesIndexed++;
2226
2207
  }
2208
+ continue;
2209
+ }
2210
+ const meta = existingMeta.get(file);
2211
+ if (!force && meta && meta.mtimeMs === Math.floor(stat2.mtimeMs)) {
2212
+ langStats[lang] = (langStats[lang] ?? 0) + meta.symbolCount;
2213
+ symbolsIndexed += meta.symbolCount;
2214
+ filesIndexed++;
2215
+ continue;
2216
+ }
2217
+ store.deleteRefsForFile(file);
2218
+ store.deleteSymbolsForFile(file);
2219
+ if (parsed.symbols.length === 0) {
2220
+ store.upsertFile({ file, lang, mtimeMs: Math.floor(stat2.mtimeMs), symbolCount: 0, lastIndexed: Date.now() });
2221
+ filesIndexed++;
2222
+ continue;
2227
2223
  }
2228
- if (batch.length > 0) {
2229
- store.insertRefsBatch(batch);
2224
+ const nextId = store.getMaxSymbolId() + 1;
2225
+ const symbolsWithIds = parsed.symbols.map((s, i) => ({ ...s, id: nextId + i }));
2226
+ store.insertSymbols(symbolsWithIds, nextId);
2227
+ const count = symbolsWithIds.length;
2228
+ symbolsIndexed += count;
2229
+ langStats[lang] = (langStats[lang] ?? 0) + count;
2230
+ if (parsed.refs && parsed.refs.length > 0) {
2231
+ const refsByLine = /* @__PURE__ */ new Map();
2232
+ for (const r of parsed.refs) {
2233
+ let arr = refsByLine.get(r.line);
2234
+ if (!arr) {
2235
+ arr = [];
2236
+ refsByLine.set(r.line, arr);
2237
+ }
2238
+ arr.push(r);
2239
+ }
2240
+ const batch = [];
2241
+ for (const sym of symbolsWithIds) {
2242
+ const symRefs = refsByLine.get(sym.line);
2243
+ if (symRefs) {
2244
+ for (const r of symRefs) batch.push({ ...r, fromId: sym.id });
2245
+ }
2246
+ }
2247
+ if (batch.length > 0) store.insertRefsBatch(batch);
2230
2248
  }
2249
+ store.upsertFile({ file, lang, mtimeMs: Math.floor(stat2.mtimeMs), symbolCount: count, lastIndexed: Date.now() });
2250
+ filesIndexed++;
2231
2251
  }
2232
- store.upsertFile({
2233
- file,
2234
- lang,
2235
- mtimeMs: Math.floor(stat2.mtimeMs),
2236
- symbolCount: count,
2237
- lastIndexed: Date.now()
2238
- });
2239
- filesIndexed++;
2240
2252
  }
2241
2253
  for (const [file_] of existingMeta) {
2242
2254
  try {