@blamechris/repo-memory 0.12.0 → 0.13.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.
Files changed (75) hide show
  1. package/dist/cache/generation.d.ts +50 -0
  2. package/dist/cache/generation.d.ts.map +1 -0
  3. package/dist/cache/generation.js +62 -0
  4. package/dist/cache/generation.js.map +1 -0
  5. package/dist/cache/invalidation.d.ts +3 -1
  6. package/dist/cache/invalidation.d.ts.map +1 -1
  7. package/dist/cache/invalidation.js +4 -5
  8. package/dist/cache/invalidation.js.map +1 -1
  9. package/dist/cache/ranking.d.ts +51 -6
  10. package/dist/cache/ranking.d.ts.map +1 -1
  11. package/dist/cache/ranking.js +92 -18
  12. package/dist/cache/ranking.js.map +1 -1
  13. package/dist/cache/store.d.ts +32 -0
  14. package/dist/cache/store.d.ts.map +1 -1
  15. package/dist/cache/store.js +110 -19
  16. package/dist/cache/store.js.map +1 -1
  17. package/dist/graph/dependency-graph.d.ts +14 -0
  18. package/dist/graph/dependency-graph.d.ts.map +1 -1
  19. package/dist/graph/dependency-graph.js +70 -5
  20. package/dist/graph/dependency-graph.js.map +1 -1
  21. package/dist/graph/refresh.d.ts +21 -0
  22. package/dist/graph/refresh.d.ts.map +1 -0
  23. package/dist/graph/refresh.js +101 -0
  24. package/dist/graph/refresh.js.map +1 -0
  25. package/dist/indexer/imports.d.ts.map +1 -1
  26. package/dist/indexer/imports.js +152 -86
  27. package/dist/indexer/imports.js.map +1 -1
  28. package/dist/indexer/project-map.d.ts +0 -2
  29. package/dist/indexer/project-map.d.ts.map +1 -1
  30. package/dist/indexer/project-map.js +0 -3
  31. package/dist/indexer/project-map.js.map +1 -1
  32. package/dist/indexer/source-extensions.d.ts +10 -0
  33. package/dist/indexer/source-extensions.d.ts.map +1 -0
  34. package/dist/indexer/source-extensions.js +28 -0
  35. package/dist/indexer/source-extensions.js.map +1 -0
  36. package/dist/indexer/summarize.d.ts +16 -1
  37. package/dist/indexer/summarize.d.ts.map +1 -1
  38. package/dist/indexer/summarize.js +38 -23
  39. package/dist/indexer/summarize.js.map +1 -1
  40. package/dist/persistence/db.d.ts.map +1 -1
  41. package/dist/persistence/db.js +78 -13
  42. package/dist/persistence/db.js.map +1 -1
  43. package/dist/server.js +18 -11
  44. package/dist/server.js.map +1 -1
  45. package/dist/tools/batch-file-summaries.d.ts +0 -1
  46. package/dist/tools/batch-file-summaries.d.ts.map +1 -1
  47. package/dist/tools/batch-file-summaries.js +1 -1
  48. package/dist/tools/batch-file-summaries.js.map +1 -1
  49. package/dist/tools/force-reread.d.ts.map +1 -1
  50. package/dist/tools/force-reread.js +7 -0
  51. package/dist/tools/force-reread.js.map +1 -1
  52. package/dist/tools/get-changed-files.d.ts.map +1 -1
  53. package/dist/tools/get-changed-files.js +23 -5
  54. package/dist/tools/get-changed-files.js.map +1 -1
  55. package/dist/tools/get-dependency-graph.d.ts +9 -7
  56. package/dist/tools/get-dependency-graph.d.ts.map +1 -1
  57. package/dist/tools/get-dependency-graph.js +51 -74
  58. package/dist/tools/get-dependency-graph.js.map +1 -1
  59. package/dist/tools/get-file-summary.d.ts +2 -3
  60. package/dist/tools/get-file-summary.d.ts.map +1 -1
  61. package/dist/tools/get-file-summary.js +11 -19
  62. package/dist/tools/get-file-summary.js.map +1 -1
  63. package/dist/tools/get-project-map.d.ts.map +1 -1
  64. package/dist/tools/get-project-map.js +9 -1
  65. package/dist/tools/get-project-map.js.map +1 -1
  66. package/dist/tools/get-related-files.d.ts.map +1 -1
  67. package/dist/tools/get-related-files.js +19 -71
  68. package/dist/tools/get-related-files.js.map +1 -1
  69. package/dist/tools/search-by-purpose.d.ts +2 -3
  70. package/dist/tools/search-by-purpose.d.ts.map +1 -1
  71. package/dist/tools/search-by-purpose.js +103 -44
  72. package/dist/tools/search-by-purpose.js.map +1 -1
  73. package/dist/types.d.ts +6 -0
  74. package/dist/types.d.ts.map +1 -1
  75. package/package.json +1 -1
@@ -1,4 +1,24 @@
1
1
  import { getDatabase } from '../persistence/db.js';
2
+ import { GENERATION_META_KEY, isStoredGenerationNewer } from './generation.js';
3
+ const UPSERT_ENTRY = `INSERT INTO files (path, hash, last_checked, summary_json)
4
+ VALUES (?, ?, ?, ?)
5
+ ON CONFLICT(path) DO UPDATE SET
6
+ hash = excluded.hash,
7
+ last_checked = excluded.last_checked,
8
+ summary_json = excluded.summary_json`;
9
+ /**
10
+ * Upsert used when a lower-generation process tried to write a summary
11
+ * (read-through mode): the hash and timestamp are persisted so change
12
+ * detection stays correct, but the summary is not — and a newer-generation
13
+ * summary already stored for the *same hash* is preserved rather than nulled.
14
+ * (`files.hash` in the CASE refers to the pre-update row value.)
15
+ */
16
+ const UPSERT_ENTRY_WITHOUT_SUMMARY = `INSERT INTO files (path, hash, last_checked, summary_json)
17
+ VALUES (?, ?, ?, NULL)
18
+ ON CONFLICT(path) DO UPDATE SET
19
+ summary_json = CASE WHEN files.hash = excluded.hash THEN files.summary_json ELSE NULL END,
20
+ hash = excluded.hash,
21
+ last_checked = excluded.last_checked`;
2
22
  function rowToEntry(row) {
3
23
  return {
4
24
  path: row.path,
@@ -21,14 +41,27 @@ export class CacheStore {
21
41
  }
22
42
  setEntry(path, hash, summary) {
23
43
  const db = getDatabase(this.projectRoot);
24
- const summaryJson = summary ? JSON.stringify(summary) : null;
25
44
  const now = Date.now();
26
- db.prepare(`INSERT INTO files (path, hash, last_checked, summary_json)
27
- VALUES (?, ?, ?, ?)
28
- ON CONFLICT(path) DO UPDATE SET
29
- hash = excluded.hash,
30
- last_checked = excluded.last_checked,
31
- summary_json = excluded.summary_json`).run(path, hash, now, summaryJson);
45
+ if (summary === null) {
46
+ // A single statement is already atomic, and a null summary is safe to
47
+ // write at any generation — no guard needed.
48
+ db.prepare(UPSERT_ENTRY).run(path, hash, now, null);
49
+ return;
50
+ }
51
+ // Summary writes re-check the stored generation tag every time (cheap
52
+ // single-row read) instead of trusting the per-process memoization in
53
+ // ensureSummaryGeneration: an external writer (e.g. a newer package
54
+ // version run by a post-merge hook) may have bumped the generation since
55
+ // this process last looked. BEGIN IMMEDIATE holds the write lock across
56
+ // the check and the write so the tag cannot change in between.
57
+ db.transaction(() => {
58
+ if (this.summaryWritesBlocked(db)) {
59
+ db.prepare(UPSERT_ENTRY_WITHOUT_SUMMARY).run(path, hash, now);
60
+ }
61
+ else {
62
+ db.prepare(UPSERT_ENTRY).run(path, hash, now, JSON.stringify(summary));
63
+ }
64
+ }).immediate();
32
65
  }
33
66
  getAllEntries() {
34
67
  const db = getDatabase(this.projectRoot);
@@ -37,26 +70,55 @@ export class CacheStore {
37
70
  .all();
38
71
  return rows.map(rowToEntry);
39
72
  }
73
+ /**
74
+ * Remove a cache entry and the dependency-graph edges extracted from it, in
75
+ * one transaction. Edges derive from the file's contents, so they share the
76
+ * entry's lifetime — leaving them behind would serve stale graph data until
77
+ * the next GC pass. (Incoming edges from other files are left alone: those
78
+ * files' contents still declare the import.)
79
+ */
40
80
  deleteEntry(path) {
41
81
  const db = getDatabase(this.projectRoot);
42
- db.prepare('DELETE FROM files WHERE path = ?').run(path);
82
+ const remove = db.transaction((p) => {
83
+ db.prepare('DELETE FROM imports WHERE source = ?').run(p);
84
+ db.prepare('DELETE FROM files WHERE path = ?').run(p);
85
+ });
86
+ remove(path);
87
+ }
88
+ /** Refresh last_checked for an entry without altering its hash or summary. */
89
+ touchEntry(path) {
90
+ const db = getDatabase(this.projectRoot);
91
+ db.prepare('UPDATE files SET last_checked = ? WHERE path = ?').run(Date.now(), path);
43
92
  }
44
93
  setEntries(entries) {
45
94
  const db = getDatabase(this.projectRoot);
46
95
  const now = Date.now();
47
- const stmt = db.prepare(`INSERT INTO files (path, hash, last_checked, summary_json)
48
- VALUES (?, ?, ?, ?)
49
- ON CONFLICT(path) DO UPDATE SET
50
- hash = excluded.hash,
51
- last_checked = excluded.last_checked,
52
- summary_json = excluded.summary_json`);
53
- const runBatch = db.transaction(() => {
96
+ const upsert = db.prepare(UPSERT_ENTRY);
97
+ const upsertWithoutSummary = db.prepare(UPSERT_ENTRY_WITHOUT_SUMMARY);
98
+ // IMMEDIATE so the generation check and the batch write happen under one
99
+ // uninterrupted write lock (see setEntry).
100
+ db.transaction(() => {
101
+ const blocked = this.summaryWritesBlocked(db);
54
102
  for (const entry of entries) {
55
- const summaryJson = entry.summary ? JSON.stringify(entry.summary) : null;
56
- stmt.run(entry.path, entry.hash, now, summaryJson);
103
+ if (entry.summary && blocked) {
104
+ upsertWithoutSummary.run(entry.path, entry.hash, now);
105
+ }
106
+ else {
107
+ const summaryJson = entry.summary ? JSON.stringify(entry.summary) : null;
108
+ upsert.run(entry.path, entry.hash, now, summaryJson);
109
+ }
57
110
  }
58
- });
59
- runBatch();
111
+ }).immediate();
112
+ }
113
+ /**
114
+ * Whether the stored generation tag belongs to a strictly newer package
115
+ * generation than this process, in which case summary writes from this
116
+ * process must not be persisted (Guardian I3). Must be called while the
117
+ * write lock is held so the answer cannot change before the write lands.
118
+ */
119
+ summaryWritesBlocked(db) {
120
+ const row = db.prepare('SELECT value FROM meta WHERE key = ?').get(GENERATION_META_KEY);
121
+ return isStoredGenerationNewer(row?.value ?? null);
60
122
  }
61
123
  /** Read a value from the meta key/value table. */
62
124
  getMeta(key) {
@@ -79,6 +141,35 @@ export class CacheStore {
79
141
  const db = getDatabase(this.projectRoot);
80
142
  db.prepare('UPDATE files SET summary_json = NULL').run();
81
143
  }
144
+ /**
145
+ * Atomically drop all summaries and write a meta value in one IMMEDIATE
146
+ * transaction (Guardian I4). Used for generation bumps: no other process
147
+ * can insert an old-generation summary between the clear and the tag write,
148
+ * and a crash between the two is unobservable.
149
+ */
150
+ clearAllSummariesAndSetMeta(key, value) {
151
+ const db = getDatabase(this.projectRoot);
152
+ db.transaction(() => {
153
+ db.prepare('UPDATE files SET summary_json = NULL').run();
154
+ db.prepare(`INSERT INTO meta (key, value) VALUES (?, ?)
155
+ ON CONFLICT(key) DO UPDATE SET value = excluded.value`).run(key, value);
156
+ }).immediate();
157
+ }
158
+ /**
159
+ * Run `fn` while holding the database write lock (BEGIN IMMEDIATE). Use for
160
+ * read-decide-write sequences that must not interleave with writes from
161
+ * other processes. Nested store calls that open their own transactions
162
+ * collapse into savepoints inside this one.
163
+ */
164
+ withWriteLock(fn) {
165
+ const db = getDatabase(this.projectRoot);
166
+ return db.transaction(fn).immediate();
167
+ }
168
+ /** Delete every cache entry in a single atomic statement. */
169
+ deleteAllEntries() {
170
+ const db = getDatabase(this.projectRoot);
171
+ db.prepare('DELETE FROM files').run();
172
+ }
82
173
  getStaleEntries(maxAge) {
83
174
  const db = getDatabase(this.projectRoot);
84
175
  const cutoff = Date.now() - maxAge;
@@ -1 +1 @@
1
- {"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/cache/store.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/cache/store.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAU/E,MAAM,YAAY,GAAG;;;;;0CAKqB,CAAC;AAE3C;;;;;;GAMG;AACH,MAAM,4BAA4B,GAAG;;;;;0CAKK,CAAC;AAE3C,SAAS,UAAU,CAAC,GAAY;IAC9B,OAAO;QACL,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,WAAW,EAAE,GAAG,CAAC,YAAY;QAC7B,OAAO,EAAE,GAAG,CAAC,YAAY,CAAC,CAAC,CAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,YAAY,CAAiB,CAAC,CAAC,CAAC,IAAI;KACjF,CAAC;AACJ,CAAC;AAED,MAAM,OAAO,UAAU;IACJ,WAAW,CAAS;IAErC,YAAY,WAAmB;QAC7B,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;IACjC,CAAC;IAED,QAAQ,CAAC,IAAY;QACnB,MAAM,EAAE,GAAG,WAAW,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACzC,MAAM,GAAG,GAAG,EAAE;aACX,OAAO,CAAC,yEAAyE,CAAC;aAClF,GAAG,CAAC,IAAI,CAAwB,CAAC;QAEpC,OAAO,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACtC,CAAC;IAED,QAAQ,CAAC,IAAY,EAAE,IAAY,EAAE,OAA2B;QAC9D,MAAM,EAAE,GAAG,WAAW,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACzC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAEvB,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;YACrB,sEAAsE;YACtE,6CAA6C;YAC7C,EAAE,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;YACpD,OAAO;QACT,CAAC;QAED,sEAAsE;QACtE,sEAAsE;QACtE,oEAAoE;QACpE,yEAAyE;QACzE,wEAAwE;QACxE,+DAA+D;QAC/D,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE;YAClB,IAAI,IAAI,CAAC,oBAAoB,CAAC,EAAE,CAAC,EAAE,CAAC;gBAClC,EAAE,CAAC,OAAO,CAAC,4BAA4B,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC;YAChE,CAAC;iBAAM,CAAC;gBACN,EAAE,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC;YACzE,CAAC;QACH,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC;IACjB,CAAC;IAED,aAAa;QACX,MAAM,EAAE,GAAG,WAAW,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACzC,MAAM,IAAI,GAAG,EAAE;aACZ,OAAO,CAAC,0DAA0D,CAAC;aACnE,GAAG,EAAe,CAAC;QAEtB,OAAO,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IAC9B,CAAC;IAED;;;;;;OAMG;IACH,WAAW,CAAC,IAAY;QACtB,MAAM,EAAE,GAAG,WAAW,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACzC,MAAM,MAAM,GAAG,EAAE,CAAC,WAAW,CAAC,CAAC,CAAS,EAAE,EAAE;YAC1C,EAAE,CAAC,OAAO,CAAC,sCAAsC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YAC1D,EAAE,CAAC,OAAO,CAAC,kCAAkC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACxD,CAAC,CAAC,CAAC;QACH,MAAM,CAAC,IAAI,CAAC,CAAC;IACf,CAAC;IAED,8EAA8E;IAC9E,UAAU,CAAC,IAAY;QACrB,MAAM,EAAE,GAAG,WAAW,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACzC,EAAE,CAAC,OAAO,CAAC,kDAAkD,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,IAAI,CAAC,CAAC;IACvF,CAAC;IAED,UAAU,CAAC,OAA4E;QACrF,MAAM,EAAE,GAAG,WAAW,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACzC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,MAAM,MAAM,GAAG,EAAE,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;QACxC,MAAM,oBAAoB,GAAG,EAAE,CAAC,OAAO,CAAC,4BAA4B,CAAC,CAAC;QAEtE,yEAAyE;QACzE,2CAA2C;QAC3C,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE;YAClB,MAAM,OAAO,GAAG,IAAI,CAAC,oBAAoB,CAAC,EAAE,CAAC,CAAC;YAC9C,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;gBAC5B,IAAI,KAAK,CAAC,OAAO,IAAI,OAAO,EAAE,CAAC;oBAC7B,oBAAoB,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;gBACxD,CAAC;qBAAM,CAAC;oBACN,MAAM,WAAW,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;oBACzE,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,GAAG,EAAE,WAAW,CAAC,CAAC;gBACvD,CAAC;YACH,CAAC;QACH,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC;IACjB,CAAC;IAED;;;;;OAKG;IACK,oBAAoB,CAAC,EAAY;QACvC,MAAM,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,sCAAsC,CAAC,CAAC,GAAG,CAAC,mBAAmB,CAEzE,CAAC;QACd,OAAO,uBAAuB,CAAC,GAAG,EAAE,KAAK,IAAI,IAAI,CAAC,CAAC;IACrD,CAAC;IAED,kDAAkD;IAClD,OAAO,CAAC,GAAW;QACjB,MAAM,EAAE,GAAG,WAAW,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACzC,MAAM,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,sCAAsC,CAAC,CAAC,GAAG,CAAC,GAAG,CAEzD,CAAC;QACd,OAAO,GAAG,EAAE,KAAK,IAAI,IAAI,CAAC;IAC5B,CAAC;IAED,iDAAiD;IACjD,OAAO,CAAC,GAAW,EAAE,KAAa;QAChC,MAAM,EAAE,GAAG,WAAW,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACzC,EAAE,CAAC,OAAO,CACR;6DACuD,CACxD,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IACpB,CAAC;IAED;;;;OAIG;IACH,iBAAiB;QACf,MAAM,EAAE,GAAG,WAAW,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACzC,EAAE,CAAC,OAAO,CAAC,sCAAsC,CAAC,CAAC,GAAG,EAAE,CAAC;IAC3D,CAAC;IAED;;;;;OAKG;IACH,2BAA2B,CAAC,GAAW,EAAE,KAAa;QACpD,MAAM,EAAE,GAAG,WAAW,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACzC,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE;YAClB,EAAE,CAAC,OAAO,CAAC,sCAAsC,CAAC,CAAC,GAAG,EAAE,CAAC;YACzD,EAAE,CAAC,OAAO,CACR;+DACuD,CACxD,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QACpB,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC;IACjB,CAAC;IAED;;;;;OAKG;IACH,aAAa,CAAI,EAAW;QAC1B,MAAM,EAAE,GAAG,WAAW,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACzC,OAAO,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC;IACxC,CAAC;IAED,6DAA6D;IAC7D,gBAAgB;QACd,MAAM,EAAE,GAAG,WAAW,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACzC,EAAE,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAC,GAAG,EAAE,CAAC;IACxC,CAAC;IAED,eAAe,CAAC,MAAc;QAC5B,MAAM,EAAE,GAAG,WAAW,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACzC,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC;QACnC,MAAM,IAAI,GAAG,EAAE;aACZ,OAAO,CACN,iFAAiF,CAClF;aACA,GAAG,CAAC,MAAM,CAAc,CAAC;QAE5B,OAAO,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IAC9B,CAAC;CACF"}
@@ -7,6 +7,18 @@ export declare class DependencyGraph {
7
7
  load(): void;
8
8
  /** Update edges for a single file (incremental). */
9
9
  updateFile(filePath: string, contents: string): void;
10
+ /**
11
+ * Remove a file from the graph entirely: every persisted edge where it is
12
+ * the source or the target, plus the in-memory adjacency for both
13
+ * directions. Used when a file no longer exists on disk.
14
+ */
15
+ removeFile(filePath: string): void;
16
+ /**
17
+ * Remove every graph node (and its edges, in both directions) that is not
18
+ * in the given set of existing files. Call after load() so the in-memory
19
+ * maps reflect the persisted state.
20
+ */
21
+ prune(existingFiles: ReadonlySet<string>): void;
10
22
  /** Get direct dependencies of a file. */
11
23
  getDependencies(path: string): string[];
12
24
  /** Get direct dependents of a file. */
@@ -26,6 +38,8 @@ export declare class DependencyGraph {
26
38
  path: string;
27
39
  connections: number;
28
40
  }>;
41
+ /** Drop a node from the in-memory adjacency maps, in both directions. */
42
+ private removeNode;
29
43
  private addEdge;
30
44
  private bfs;
31
45
  }
@@ -1 +1 @@
1
- {"version":3,"file":"dependency-graph.d.ts","sourceRoot":"","sources":["../../src/graph/dependency-graph.ts"],"names":[],"mappings":"AAGA,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAA2B;IAC3C,OAAO,CAAC,QAAQ,CAA2B;gBAE/B,WAAW,EAAE,MAAM;IAM/B,wDAAwD;IACxD,IAAI,IAAI,IAAI;IAcZ,oDAAoD;IACpD,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;IAuCpD,yCAAyC;IACzC,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE;IAKvC,uCAAuC;IACvC,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE;IAKrC,2DAA2D;IAC3D,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IAwBtH,uEAAuE;IACvE,yBAAyB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE;IAIpE,qEAAqE;IACrE,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE;IAIlE,sEAAsE;IACtE,gBAAgB,CAAC,KAAK,GAAE,MAAW,GAAG,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC;IAgBlF,OAAO,CAAC,OAAO;IAgBf,OAAO,CAAC,GAAG;CAkCZ"}
1
+ {"version":3,"file":"dependency-graph.d.ts","sourceRoot":"","sources":["../../src/graph/dependency-graph.ts"],"names":[],"mappings":"AAGA,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAA2B;IAC3C,OAAO,CAAC,QAAQ,CAA2B;gBAE/B,WAAW,EAAE,MAAM;IAM/B,wDAAwD;IACxD,IAAI,IAAI,IAAI;IAcZ,oDAAoD;IACpD,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;IA0CpD;;;;OAIG;IACH,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAUlC;;;;OAIG;IACH,KAAK,CAAC,aAAa,EAAE,WAAW,CAAC,MAAM,CAAC,GAAG,IAAI;IAa/C,yCAAyC;IACzC,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE;IAKvC,uCAAuC;IACvC,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE;IAKrC,2DAA2D;IAC3D,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IAwBtH,uEAAuE;IACvE,yBAAyB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE;IAIpE,qEAAqE;IACrE,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE;IAIlE,sEAAsE;IACtE,gBAAgB,CAAC,KAAK,GAAE,MAAW,GAAG,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC;IAgBlF,yEAAyE;IACzE,OAAO,CAAC,UAAU;IA0BlB,OAAO,CAAC,OAAO;IAgBf,OAAO,CAAC,GAAG;CAkCZ"}
@@ -38,19 +38,57 @@ export class DependencyGraph {
38
38
  }
39
39
  this.outgoing.delete(filePath);
40
40
  }
41
- // Delete old rows from DB
42
- db.prepare('DELETE FROM imports WHERE source = ?').run(filePath);
43
41
  // Extract new imports
44
42
  const imports = extractImports(filePath, contents, this.projectRoot);
45
- // Insert new rows and update in-memory maps
46
43
  const insert = db.prepare('INSERT OR REPLACE INTO imports (source, target, specifiers, import_type) VALUES (?, ?, ?, ?)');
47
- const insertAll = db.transaction(() => {
44
+ // Delete + insert in ONE transaction so concurrent readers never observe a
45
+ // torn state where the file's old edges are gone but the new ones are not
46
+ // yet written (audit invariant I2).
47
+ const replaceAll = db.transaction(() => {
48
+ db.prepare('DELETE FROM imports WHERE source = ?').run(filePath);
48
49
  for (const ref of imports) {
50
+ // External targets (bare modules, builtins, unresolvable paths) are not
51
+ // repo files — persisting them would pollute traversal and mostConnected.
52
+ if (ref.external)
53
+ continue;
49
54
  insert.run(ref.source, ref.target, JSON.stringify(ref.specifiers), ref.type);
50
55
  this.addEdge(ref.source, ref.target);
51
56
  }
52
57
  });
53
- insertAll();
58
+ replaceAll();
59
+ }
60
+ /**
61
+ * Remove a file from the graph entirely: every persisted edge where it is
62
+ * the source or the target, plus the in-memory adjacency for both
63
+ * directions. Used when a file no longer exists on disk.
64
+ */
65
+ removeFile(filePath) {
66
+ const db = getDatabase(this.projectRoot);
67
+ const remove = db.transaction(() => {
68
+ db.prepare('DELETE FROM imports WHERE source = ?').run(filePath);
69
+ db.prepare('DELETE FROM imports WHERE target = ?').run(filePath);
70
+ });
71
+ remove();
72
+ this.removeNode(filePath);
73
+ }
74
+ /**
75
+ * Remove every graph node (and its edges, in both directions) that is not
76
+ * in the given set of existing files. Call after load() so the in-memory
77
+ * maps reflect the persisted state.
78
+ */
79
+ prune(existingFiles) {
80
+ const missing = new Set();
81
+ for (const node of this.outgoing.keys()) {
82
+ if (!existingFiles.has(node))
83
+ missing.add(node);
84
+ }
85
+ for (const node of this.incoming.keys()) {
86
+ if (!existingFiles.has(node))
87
+ missing.add(node);
88
+ }
89
+ for (const node of missing) {
90
+ this.removeFile(node);
91
+ }
54
92
  }
55
93
  /** Get direct dependencies of a file. */
56
94
  getDependencies(path) {
@@ -109,6 +147,33 @@ export class DependencyGraph {
109
147
  result.sort((a, b) => b.connections - a.connections);
110
148
  return result.slice(0, limit);
111
149
  }
150
+ /** Drop a node from the in-memory adjacency maps, in both directions. */
151
+ removeNode(node) {
152
+ const targets = this.outgoing.get(node);
153
+ if (targets) {
154
+ for (const target of targets) {
155
+ const sources = this.incoming.get(target);
156
+ if (sources) {
157
+ sources.delete(node);
158
+ if (sources.size === 0)
159
+ this.incoming.delete(target);
160
+ }
161
+ }
162
+ this.outgoing.delete(node);
163
+ }
164
+ const sources = this.incoming.get(node);
165
+ if (sources) {
166
+ for (const source of sources) {
167
+ const targets = this.outgoing.get(source);
168
+ if (targets) {
169
+ targets.delete(node);
170
+ if (targets.size === 0)
171
+ this.outgoing.delete(source);
172
+ }
173
+ }
174
+ this.incoming.delete(node);
175
+ }
176
+ }
112
177
  addEdge(source, target) {
113
178
  let targets = this.outgoing.get(source);
114
179
  if (!targets) {
@@ -1 +1 @@
1
- {"version":3,"file":"dependency-graph.js","sourceRoot":"","sources":["../../src/graph/dependency-graph.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"dependency-graph.js","sourceRoot":"","sources":["../../src/graph/dependency-graph.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import { DependencyGraph } from './dependency-graph.js';
2
+ /**
3
+ * Load the persisted dependency graph and bring it up to date without
4
+ * re-reading unchanged files.
5
+ *
6
+ * Freshness strategy:
7
+ * 1. `load()` the persisted edges, then prune nodes whose files are gone from
8
+ * the project file list.
9
+ * 2. For each graph-indexable file, `stat` it (cheap, no content read). If a
10
+ * `files` row exists and the mtime predates the row's `last_checked`, the
11
+ * content cannot have changed since the stored hash was computed — skip.
12
+ * 3. Otherwise read the file once, hash it, and compare with the stored hash:
13
+ * only a real change (or a missing row) re-extracts edges. Edge writes and
14
+ * summary-cache rows share the same hash bookkeeping, so edges have the
15
+ * same freshness semantics as summaries (never-stale invariant).
16
+ *
17
+ * @param scannedFiles Optional pre-scanned project file list (avoids a second
18
+ * scan when the caller already has one).
19
+ */
20
+ export declare function loadFreshGraph(projectRoot: string, scannedFiles?: string[]): Promise<DependencyGraph>;
21
+ //# sourceMappingURL=refresh.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"refresh.d.ts","sourceRoot":"","sources":["../../src/graph/refresh.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAoBxD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,cAAc,CAClC,WAAW,EAAE,MAAM,EACnB,YAAY,CAAC,EAAE,MAAM,EAAE,GACtB,OAAO,CAAC,eAAe,CAAC,CA8D1B"}
@@ -0,0 +1,101 @@
1
+ import { readFile, stat } from 'node:fs/promises';
2
+ import { join } from 'node:path';
3
+ import { hashContents } from '../cache/hash.js';
4
+ import { CacheStore } from '../cache/store.js';
5
+ import { scanProject } from '../indexer/scanner.js';
6
+ import { isGraphIndexable } from '../indexer/source-extensions.js';
7
+ import { DependencyGraph } from './dependency-graph.js';
8
+ /**
9
+ * Meta key recording that the persisted graph has been fully built at least
10
+ * once by this implementation. Caches created before the graph was wired into
11
+ * the write path have file rows but no edges — without this marker those
12
+ * files would look "fresh" forever and never get indexed. Bump the value to
13
+ * force a one-time full re-extraction after a change to the edge format.
14
+ */
15
+ const GRAPH_GENERATION_KEY = 'graph_generation';
16
+ const GRAPH_GENERATION = '1';
17
+ /**
18
+ * Filesystem mtimes can be coarser than Date.now() (whole-second granularity
19
+ * on some filesystems), so an edit made just after a check can carry an mtime
20
+ * that is *truncated below* the stored last_checked. Files whose mtime falls
21
+ * within this window of last_checked stay suspect and get hash-checked.
22
+ */
23
+ const MTIME_SAFETY_WINDOW_MS = 2000;
24
+ /**
25
+ * Load the persisted dependency graph and bring it up to date without
26
+ * re-reading unchanged files.
27
+ *
28
+ * Freshness strategy:
29
+ * 1. `load()` the persisted edges, then prune nodes whose files are gone from
30
+ * the project file list.
31
+ * 2. For each graph-indexable file, `stat` it (cheap, no content read). If a
32
+ * `files` row exists and the mtime predates the row's `last_checked`, the
33
+ * content cannot have changed since the stored hash was computed — skip.
34
+ * 3. Otherwise read the file once, hash it, and compare with the stored hash:
35
+ * only a real change (or a missing row) re-extracts edges. Edge writes and
36
+ * summary-cache rows share the same hash bookkeeping, so edges have the
37
+ * same freshness semantics as summaries (never-stale invariant).
38
+ *
39
+ * @param scannedFiles Optional pre-scanned project file list (avoids a second
40
+ * scan when the caller already has one).
41
+ */
42
+ export async function loadFreshGraph(projectRoot, scannedFiles) {
43
+ const files = scannedFiles ?? (await scanProject(projectRoot));
44
+ const store = new CacheStore(projectRoot);
45
+ const graph = new DependencyGraph(projectRoot);
46
+ graph.load();
47
+ // Legacy caches (or a bumped edge format) need one full re-extraction pass.
48
+ const fullRebuild = store.getMeta(GRAPH_GENERATION_KEY) !== GRAPH_GENERATION;
49
+ // Files that left the project take their edges with them. (Files still in
50
+ // the git index but deleted from disk are caught by the stat pass below.)
51
+ graph.prune(new Set(files));
52
+ for (const file of files) {
53
+ if (!isGraphIndexable(file))
54
+ continue;
55
+ const absolutePath = join(projectRoot, file);
56
+ let mtimeMs;
57
+ try {
58
+ mtimeMs = (await stat(absolutePath)).mtimeMs;
59
+ }
60
+ catch {
61
+ // Tracked in git but missing on disk (or deleted mid-pass): the file
62
+ // does not exist anymore, so its edges must not be served.
63
+ graph.removeFile(file);
64
+ continue;
65
+ }
66
+ const entry = store.getEntry(file);
67
+ if (!fullRebuild && entry && mtimeMs < entry.lastChecked - MTIME_SAFETY_WINDOW_MS) {
68
+ // Unmodified since the stored hash was computed — do not re-read.
69
+ continue;
70
+ }
71
+ let contents;
72
+ try {
73
+ contents = await readFile(absolutePath, 'utf-8');
74
+ }
75
+ catch {
76
+ graph.removeFile(file);
77
+ continue;
78
+ }
79
+ const currentHash = hashContents(contents);
80
+ if (entry && entry.hash === currentHash) {
81
+ // Content unchanged; edges for this hash are already persisted (unless
82
+ // this is the one-time full rebuild). Bump last_checked so the next
83
+ // pass can skip on mtime alone once the file ages past the safety window.
84
+ if (fullRebuild)
85
+ graph.updateFile(file, contents);
86
+ store.touchEntry(file);
87
+ }
88
+ else {
89
+ graph.updateFile(file, contents);
90
+ // Record the hash the edges were extracted from. A pre-existing summary
91
+ // was computed from different content, so it must not survive the hash
92
+ // update (same rule as the summary cache itself).
93
+ store.setEntry(file, currentHash, null);
94
+ }
95
+ }
96
+ if (fullRebuild) {
97
+ store.setMeta(GRAPH_GENERATION_KEY, GRAPH_GENERATION);
98
+ }
99
+ return graph;
100
+ }
101
+ //# sourceMappingURL=refresh.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"refresh.js","sourceRoot":"","sources":["../../src/graph/refresh.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"imports.d.ts","sourceRoot":"","sources":["../../src/indexer/imports.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAqL7C,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,GAClB,SAAS,EAAE,CA0Eb;AA6BD,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,GACnB,SAAS,EAAE,CA8Cb;AAgDD,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,GAClB,SAAS,EAAE,CAuDb;AA0BD,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,GACnB,SAAS,EAAE,CAkBb;AAED,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,GACnB,SAAS,EAAE,CA8Bb;AAQD,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,GAClB,SAAS,EAAE,CAsBb"}
1
+ {"version":3,"file":"imports.d.ts","sourceRoot":"","sources":["../../src/indexer/imports.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AA0R7C,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,GAClB,SAAS,EAAE,CA6Db;AA6BD,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,GACnB,SAAS,EAAE,CAiDb;AAgDD,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,GAClB,SAAS,EAAE,CAoDb;AA0BD,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,GACnB,SAAS,EAAE,CAoBb;AAED,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,GACnB,SAAS,EAAE,CAgCb;AAQD,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,GAClB,SAAS,EAAE,CAsBb"}