@optave/codegraph 2.1.0 → 2.1.1-dev.0e15f12

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/src/structure.js CHANGED
@@ -315,30 +315,40 @@ export function hotspotsData(customDbPath, opts = {}) {
315
315
  const metric = opts.metric || 'fan-in';
316
316
  const level = opts.level || 'file';
317
317
  const limit = opts.limit || 10;
318
+ const noTests = opts.noTests || false;
318
319
 
319
320
  const kind = level === 'directory' ? 'directory' : 'file';
320
321
 
322
+ const testFilter =
323
+ noTests && kind === 'file'
324
+ ? `AND n.name NOT LIKE '%.test.%'
325
+ AND n.name NOT LIKE '%.spec.%'
326
+ AND n.name NOT LIKE '%__test__%'
327
+ AND n.name NOT LIKE '%__tests__%'
328
+ AND n.name NOT LIKE '%.stories.%'`
329
+ : '';
330
+
321
331
  const HOTSPOT_QUERIES = {
322
332
  'fan-in': db.prepare(`
323
333
  SELECT n.name, n.kind, nm.line_count, nm.symbol_count, nm.import_count, nm.export_count,
324
334
  nm.fan_in, nm.fan_out, nm.cohesion, nm.file_count
325
335
  FROM nodes n JOIN node_metrics nm ON n.id = nm.node_id
326
- WHERE n.kind = ? ORDER BY nm.fan_in DESC NULLS LAST LIMIT ?`),
336
+ WHERE n.kind = ? ${testFilter} ORDER BY nm.fan_in DESC NULLS LAST LIMIT ?`),
327
337
  'fan-out': db.prepare(`
328
338
  SELECT n.name, n.kind, nm.line_count, nm.symbol_count, nm.import_count, nm.export_count,
329
339
  nm.fan_in, nm.fan_out, nm.cohesion, nm.file_count
330
340
  FROM nodes n JOIN node_metrics nm ON n.id = nm.node_id
331
- WHERE n.kind = ? ORDER BY nm.fan_out DESC NULLS LAST LIMIT ?`),
341
+ WHERE n.kind = ? ${testFilter} ORDER BY nm.fan_out DESC NULLS LAST LIMIT ?`),
332
342
  density: db.prepare(`
333
343
  SELECT n.name, n.kind, nm.line_count, nm.symbol_count, nm.import_count, nm.export_count,
334
344
  nm.fan_in, nm.fan_out, nm.cohesion, nm.file_count
335
345
  FROM nodes n JOIN node_metrics nm ON n.id = nm.node_id
336
- WHERE n.kind = ? ORDER BY nm.symbol_count DESC NULLS LAST LIMIT ?`),
346
+ WHERE n.kind = ? ${testFilter} ORDER BY nm.symbol_count DESC NULLS LAST LIMIT ?`),
337
347
  coupling: db.prepare(`
338
348
  SELECT n.name, n.kind, nm.line_count, nm.symbol_count, nm.import_count, nm.export_count,
339
349
  nm.fan_in, nm.fan_out, nm.cohesion, nm.file_count
340
350
  FROM nodes n JOIN node_metrics nm ON n.id = nm.node_id
341
- WHERE n.kind = ? ORDER BY (COALESCE(nm.fan_in, 0) + COALESCE(nm.fan_out, 0)) DESC NULLS LAST LIMIT ?`),
351
+ WHERE n.kind = ? ${testFilter} ORDER BY (COALESCE(nm.fan_in, 0) + COALESCE(nm.fan_out, 0)) DESC NULLS LAST LIMIT ?`),
342
352
  };
343
353
 
344
354
  const stmt = HOTSPOT_QUERIES[metric] || HOTSPOT_QUERIES['fan-in'];
package/src/watcher.js CHANGED
@@ -2,6 +2,7 @@ import fs from 'node:fs';
2
2
  import path from 'node:path';
3
3
  import { EXTENSIONS, IGNORE_DIRS, normalizePath } from './constants.js';
4
4
  import { initSchema, openDb } from './db.js';
5
+ import { appendJournalEntries } from './journal.js';
5
6
  import { info, warn } from './logger.js';
6
7
  import { createParseTreeCache, getActiveEngine, parseFileIncremental } from './parser.js';
7
8
  import { resolveImportPath } from './resolve.js';
@@ -205,6 +206,19 @@ export async function watchProject(rootDir, opts = {}) {
205
206
  }
206
207
  const updates = results;
207
208
 
209
+ // Append processed files to journal for Tier 0 detection on next build
210
+ if (updates.length > 0) {
211
+ const entries = updates.map((r) => ({
212
+ file: r.file,
213
+ deleted: r.deleted || false,
214
+ }));
215
+ try {
216
+ appendJournalEntries(rootDir, entries);
217
+ } catch {
218
+ /* journal write failure is non-fatal */
219
+ }
220
+ }
221
+
208
222
  for (const r of updates) {
209
223
  const nodeDelta = r.nodesAdded - r.nodesRemoved;
210
224
  const nodeStr = nodeDelta >= 0 ? `+${nodeDelta}` : `${nodeDelta}`;
@@ -234,6 +248,17 @@ export async function watchProject(rootDir, opts = {}) {
234
248
  process.on('SIGINT', () => {
235
249
  console.log('\nStopping watcher...');
236
250
  watcher.close();
251
+ // Flush any pending file paths to journal before exit
252
+ if (pending.size > 0) {
253
+ const entries = [...pending].map((filePath) => ({
254
+ file: normalizePath(path.relative(rootDir, filePath)),
255
+ }));
256
+ try {
257
+ appendJournalEntries(rootDir, entries);
258
+ } catch {
259
+ /* best-effort */
260
+ }
261
+ }
237
262
  if (cache) cache.clear();
238
263
  db.close();
239
264
  process.exit(0);