@liendev/core 0.19.5

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 (298) hide show
  1. package/README.md +336 -0
  2. package/dist/config/loader.d.ts +12 -0
  3. package/dist/config/loader.d.ts.map +1 -0
  4. package/dist/config/loader.js +46 -0
  5. package/dist/config/loader.js.map +1 -0
  6. package/dist/config/merge.d.ts +20 -0
  7. package/dist/config/merge.d.ts.map +1 -0
  8. package/dist/config/merge.js +71 -0
  9. package/dist/config/merge.js.map +1 -0
  10. package/dist/config/migration-manager.d.ts +46 -0
  11. package/dist/config/migration-manager.d.ts.map +1 -0
  12. package/dist/config/migration-manager.js +119 -0
  13. package/dist/config/migration-manager.js.map +1 -0
  14. package/dist/config/migration.d.ts +20 -0
  15. package/dist/config/migration.d.ts.map +1 -0
  16. package/dist/config/migration.js +155 -0
  17. package/dist/config/migration.js.map +1 -0
  18. package/dist/config/schema.d.ts +101 -0
  19. package/dist/config/schema.d.ts.map +1 -0
  20. package/dist/config/schema.js +58 -0
  21. package/dist/config/schema.js.map +1 -0
  22. package/dist/config/service.d.ts +122 -0
  23. package/dist/config/service.d.ts.map +1 -0
  24. package/dist/config/service.js +477 -0
  25. package/dist/config/service.js.map +1 -0
  26. package/dist/constants.d.ts +20 -0
  27. package/dist/constants.d.ts.map +1 -0
  28. package/dist/constants.js +43 -0
  29. package/dist/constants.js.map +1 -0
  30. package/dist/embeddings/cache.d.ts +45 -0
  31. package/dist/embeddings/cache.d.ts.map +1 -0
  32. package/dist/embeddings/cache.js +109 -0
  33. package/dist/embeddings/cache.js.map +1 -0
  34. package/dist/embeddings/local.d.ts +10 -0
  35. package/dist/embeddings/local.d.ts.map +1 -0
  36. package/dist/embeddings/local.js +63 -0
  37. package/dist/embeddings/local.js.map +1 -0
  38. package/dist/embeddings/types.d.ts +9 -0
  39. package/dist/embeddings/types.d.ts.map +1 -0
  40. package/dist/embeddings/types.js +5 -0
  41. package/dist/embeddings/types.js.map +1 -0
  42. package/dist/errors/codes.d.ts +18 -0
  43. package/dist/errors/codes.d.ts.map +1 -0
  44. package/dist/errors/codes.js +25 -0
  45. package/dist/errors/codes.js.map +1 -0
  46. package/dist/errors/index.d.ts +85 -0
  47. package/dist/errors/index.d.ts.map +1 -0
  48. package/dist/errors/index.js +134 -0
  49. package/dist/errors/index.js.map +1 -0
  50. package/dist/frameworks/detector-service.d.ts +59 -0
  51. package/dist/frameworks/detector-service.d.ts.map +1 -0
  52. package/dist/frameworks/detector-service.js +219 -0
  53. package/dist/frameworks/detector-service.js.map +1 -0
  54. package/dist/frameworks/laravel/config.d.ts +6 -0
  55. package/dist/frameworks/laravel/config.d.ts.map +1 -0
  56. package/dist/frameworks/laravel/config.js +68 -0
  57. package/dist/frameworks/laravel/config.js.map +1 -0
  58. package/dist/frameworks/laravel/detector.d.ts +6 -0
  59. package/dist/frameworks/laravel/detector.d.ts.map +1 -0
  60. package/dist/frameworks/laravel/detector.js +96 -0
  61. package/dist/frameworks/laravel/detector.js.map +1 -0
  62. package/dist/frameworks/nodejs/config.d.ts +6 -0
  63. package/dist/frameworks/nodejs/config.d.ts.map +1 -0
  64. package/dist/frameworks/nodejs/config.js +57 -0
  65. package/dist/frameworks/nodejs/config.js.map +1 -0
  66. package/dist/frameworks/nodejs/detector.d.ts +6 -0
  67. package/dist/frameworks/nodejs/detector.d.ts.map +1 -0
  68. package/dist/frameworks/nodejs/detector.js +77 -0
  69. package/dist/frameworks/nodejs/detector.js.map +1 -0
  70. package/dist/frameworks/php/config.d.ts +6 -0
  71. package/dist/frameworks/php/config.d.ts.map +1 -0
  72. package/dist/frameworks/php/config.js +53 -0
  73. package/dist/frameworks/php/config.js.map +1 -0
  74. package/dist/frameworks/php/detector.d.ts +7 -0
  75. package/dist/frameworks/php/detector.d.ts.map +1 -0
  76. package/dist/frameworks/php/detector.js +101 -0
  77. package/dist/frameworks/php/detector.js.map +1 -0
  78. package/dist/frameworks/registry.d.ts +20 -0
  79. package/dist/frameworks/registry.d.ts.map +1 -0
  80. package/dist/frameworks/registry.js +38 -0
  81. package/dist/frameworks/registry.js.map +1 -0
  82. package/dist/frameworks/shopify/config.d.ts +6 -0
  83. package/dist/frameworks/shopify/config.d.ts.map +1 -0
  84. package/dist/frameworks/shopify/config.js +50 -0
  85. package/dist/frameworks/shopify/config.js.map +1 -0
  86. package/dist/frameworks/shopify/detector.d.ts +6 -0
  87. package/dist/frameworks/shopify/detector.d.ts.map +1 -0
  88. package/dist/frameworks/shopify/detector.js +103 -0
  89. package/dist/frameworks/shopify/detector.js.map +1 -0
  90. package/dist/frameworks/types.d.ts +51 -0
  91. package/dist/frameworks/types.d.ts.map +1 -0
  92. package/dist/frameworks/types.js +21 -0
  93. package/dist/frameworks/types.js.map +1 -0
  94. package/dist/git/tracker.d.ts +56 -0
  95. package/dist/git/tracker.d.ts.map +1 -0
  96. package/dist/git/tracker.js +189 -0
  97. package/dist/git/tracker.js.map +1 -0
  98. package/dist/git/utils.d.ts +60 -0
  99. package/dist/git/utils.d.ts.map +1 -0
  100. package/dist/git/utils.js +152 -0
  101. package/dist/git/utils.js.map +1 -0
  102. package/dist/index.d.ts +77 -0
  103. package/dist/index.d.ts.map +1 -0
  104. package/dist/index.js +95 -0
  105. package/dist/index.js.map +1 -0
  106. package/dist/indexer/ast/chunker.d.ts +28 -0
  107. package/dist/indexer/ast/chunker.d.ts.map +1 -0
  108. package/dist/indexer/ast/chunker.js +268 -0
  109. package/dist/indexer/ast/chunker.js.map +1 -0
  110. package/dist/indexer/ast/complexity/cognitive.d.ts +16 -0
  111. package/dist/indexer/ast/complexity/cognitive.d.ts.map +1 -0
  112. package/dist/indexer/ast/complexity/cognitive.js +106 -0
  113. package/dist/indexer/ast/complexity/cognitive.js.map +1 -0
  114. package/dist/indexer/ast/complexity/cyclomatic.d.ts +12 -0
  115. package/dist/indexer/ast/complexity/cyclomatic.d.ts.map +1 -0
  116. package/dist/indexer/ast/complexity/cyclomatic.js +61 -0
  117. package/dist/indexer/ast/complexity/cyclomatic.js.map +1 -0
  118. package/dist/indexer/ast/complexity/halstead.d.ts +55 -0
  119. package/dist/indexer/ast/complexity/halstead.d.ts.map +1 -0
  120. package/dist/indexer/ast/complexity/halstead.js +290 -0
  121. package/dist/indexer/ast/complexity/halstead.js.map +1 -0
  122. package/dist/indexer/ast/complexity/index.d.ts +13 -0
  123. package/dist/indexer/ast/complexity/index.d.ts.map +1 -0
  124. package/dist/indexer/ast/complexity/index.js +12 -0
  125. package/dist/indexer/ast/complexity/index.js.map +1 -0
  126. package/dist/indexer/ast/parser.d.ts +27 -0
  127. package/dist/indexer/ast/parser.d.ts.map +1 -0
  128. package/dist/indexer/ast/parser.js +103 -0
  129. package/dist/indexer/ast/parser.js.map +1 -0
  130. package/dist/indexer/ast/symbols.d.ts +17 -0
  131. package/dist/indexer/ast/symbols.d.ts.map +1 -0
  132. package/dist/indexer/ast/symbols.js +265 -0
  133. package/dist/indexer/ast/symbols.js.map +1 -0
  134. package/dist/indexer/ast/traversers/index.d.ts +19 -0
  135. package/dist/indexer/ast/traversers/index.d.ts.map +1 -0
  136. package/dist/indexer/ast/traversers/index.js +42 -0
  137. package/dist/indexer/ast/traversers/index.js.map +1 -0
  138. package/dist/indexer/ast/traversers/php.d.ts +21 -0
  139. package/dist/indexer/ast/traversers/php.d.ts.map +1 -0
  140. package/dist/indexer/ast/traversers/php.js +67 -0
  141. package/dist/indexer/ast/traversers/php.js.map +1 -0
  142. package/dist/indexer/ast/traversers/python.d.ts +28 -0
  143. package/dist/indexer/ast/traversers/python.d.ts.map +1 -0
  144. package/dist/indexer/ast/traversers/python.js +67 -0
  145. package/dist/indexer/ast/traversers/python.js.map +1 -0
  146. package/dist/indexer/ast/traversers/types.d.ts +98 -0
  147. package/dist/indexer/ast/traversers/types.d.ts.map +1 -0
  148. package/dist/indexer/ast/traversers/types.js +2 -0
  149. package/dist/indexer/ast/traversers/types.js.map +1 -0
  150. package/dist/indexer/ast/traversers/typescript.d.ts +29 -0
  151. package/dist/indexer/ast/traversers/typescript.d.ts.map +1 -0
  152. package/dist/indexer/ast/traversers/typescript.js +88 -0
  153. package/dist/indexer/ast/traversers/typescript.js.map +1 -0
  154. package/dist/indexer/ast/types.d.ts +59 -0
  155. package/dist/indexer/ast/types.d.ts.map +1 -0
  156. package/dist/indexer/ast/types.js +2 -0
  157. package/dist/indexer/ast/types.js.map +1 -0
  158. package/dist/indexer/change-detector.d.ts +17 -0
  159. package/dist/indexer/change-detector.d.ts.map +1 -0
  160. package/dist/indexer/change-detector.js +207 -0
  161. package/dist/indexer/change-detector.js.map +1 -0
  162. package/dist/indexer/chunk-batch-processor.d.ts +103 -0
  163. package/dist/indexer/chunk-batch-processor.d.ts.map +1 -0
  164. package/dist/indexer/chunk-batch-processor.js +179 -0
  165. package/dist/indexer/chunk-batch-processor.js.map +1 -0
  166. package/dist/indexer/chunker.d.ts +10 -0
  167. package/dist/indexer/chunker.d.ts.map +1 -0
  168. package/dist/indexer/chunker.js +96 -0
  169. package/dist/indexer/chunker.js.map +1 -0
  170. package/dist/indexer/dependency-analyzer.d.ts +60 -0
  171. package/dist/indexer/dependency-analyzer.d.ts.map +1 -0
  172. package/dist/indexer/dependency-analyzer.js +261 -0
  173. package/dist/indexer/dependency-analyzer.js.map +1 -0
  174. package/dist/indexer/incremental.d.ts +47 -0
  175. package/dist/indexer/incremental.d.ts.map +1 -0
  176. package/dist/indexer/incremental.js +284 -0
  177. package/dist/indexer/incremental.js.map +1 -0
  178. package/dist/indexer/index.d.ts +80 -0
  179. package/dist/indexer/index.d.ts.map +1 -0
  180. package/dist/indexer/index.js +364 -0
  181. package/dist/indexer/index.js.map +1 -0
  182. package/dist/indexer/json-template-chunker.d.ts +9 -0
  183. package/dist/indexer/json-template-chunker.d.ts.map +1 -0
  184. package/dist/indexer/json-template-chunker.js +83 -0
  185. package/dist/indexer/json-template-chunker.js.map +1 -0
  186. package/dist/indexer/liquid-chunker.d.ts +13 -0
  187. package/dist/indexer/liquid-chunker.d.ts.map +1 -0
  188. package/dist/indexer/liquid-chunker.js +272 -0
  189. package/dist/indexer/liquid-chunker.js.map +1 -0
  190. package/dist/indexer/manifest.d.ts +122 -0
  191. package/dist/indexer/manifest.d.ts.map +1 -0
  192. package/dist/indexer/manifest.js +262 -0
  193. package/dist/indexer/manifest.js.map +1 -0
  194. package/dist/indexer/progress-tracker.d.ts +35 -0
  195. package/dist/indexer/progress-tracker.d.ts.map +1 -0
  196. package/dist/indexer/progress-tracker.js +33 -0
  197. package/dist/indexer/progress-tracker.js.map +1 -0
  198. package/dist/indexer/scanner.d.ts +16 -0
  199. package/dist/indexer/scanner.d.ts.map +1 -0
  200. package/dist/indexer/scanner.js +159 -0
  201. package/dist/indexer/scanner.js.map +1 -0
  202. package/dist/indexer/symbol-extractor.d.ts +18 -0
  203. package/dist/indexer/symbol-extractor.d.ts.map +1 -0
  204. package/dist/indexer/symbol-extractor.js +351 -0
  205. package/dist/indexer/symbol-extractor.js.map +1 -0
  206. package/dist/indexer/types.d.ts +34 -0
  207. package/dist/indexer/types.d.ts.map +1 -0
  208. package/dist/indexer/types.js +2 -0
  209. package/dist/indexer/types.js.map +1 -0
  210. package/dist/insights/complexity-analyzer.d.ts +82 -0
  211. package/dist/insights/complexity-analyzer.d.ts.map +1 -0
  212. package/dist/insights/complexity-analyzer.js +356 -0
  213. package/dist/insights/complexity-analyzer.js.map +1 -0
  214. package/dist/insights/formatters/index.d.ts +11 -0
  215. package/dist/insights/formatters/index.d.ts.map +1 -0
  216. package/dist/insights/formatters/index.js +20 -0
  217. package/dist/insights/formatters/index.js.map +1 -0
  218. package/dist/insights/formatters/json.d.ts +7 -0
  219. package/dist/insights/formatters/json.d.ts.map +1 -0
  220. package/dist/insights/formatters/json.js +14 -0
  221. package/dist/insights/formatters/json.js.map +1 -0
  222. package/dist/insights/formatters/sarif.d.ts +6 -0
  223. package/dist/insights/formatters/sarif.d.ts.map +1 -0
  224. package/dist/insights/formatters/sarif.js +113 -0
  225. package/dist/insights/formatters/sarif.js.map +1 -0
  226. package/dist/insights/formatters/text.d.ts +6 -0
  227. package/dist/insights/formatters/text.d.ts.map +1 -0
  228. package/dist/insights/formatters/text.js +154 -0
  229. package/dist/insights/formatters/text.js.map +1 -0
  230. package/dist/insights/types.d.ts +73 -0
  231. package/dist/insights/types.d.ts.map +1 -0
  232. package/dist/insights/types.js +9 -0
  233. package/dist/insights/types.js.map +1 -0
  234. package/dist/types/index.d.ts +14 -0
  235. package/dist/types/index.d.ts.map +1 -0
  236. package/dist/types/index.js +8 -0
  237. package/dist/types/index.js.map +1 -0
  238. package/dist/utils/path-matching.d.ts +69 -0
  239. package/dist/utils/path-matching.d.ts.map +1 -0
  240. package/dist/utils/path-matching.js +123 -0
  241. package/dist/utils/path-matching.js.map +1 -0
  242. package/dist/utils/result.d.ts +65 -0
  243. package/dist/utils/result.d.ts.map +1 -0
  244. package/dist/utils/result.js +67 -0
  245. package/dist/utils/result.js.map +1 -0
  246. package/dist/utils/version.d.ts +22 -0
  247. package/dist/utils/version.d.ts.map +1 -0
  248. package/dist/utils/version.js +28 -0
  249. package/dist/utils/version.js.map +1 -0
  250. package/dist/vectordb/batch-insert.d.ts +14 -0
  251. package/dist/vectordb/batch-insert.d.ts.map +1 -0
  252. package/dist/vectordb/batch-insert.js +185 -0
  253. package/dist/vectordb/batch-insert.js.map +1 -0
  254. package/dist/vectordb/boosting/composer.d.ts +51 -0
  255. package/dist/vectordb/boosting/composer.d.ts.map +1 -0
  256. package/dist/vectordb/boosting/composer.js +65 -0
  257. package/dist/vectordb/boosting/composer.js.map +1 -0
  258. package/dist/vectordb/boosting/index.d.ts +22 -0
  259. package/dist/vectordb/boosting/index.d.ts.map +1 -0
  260. package/dist/vectordb/boosting/index.js +22 -0
  261. package/dist/vectordb/boosting/index.js.map +1 -0
  262. package/dist/vectordb/boosting/strategies.d.ts +40 -0
  263. package/dist/vectordb/boosting/strategies.d.ts.map +1 -0
  264. package/dist/vectordb/boosting/strategies.js +174 -0
  265. package/dist/vectordb/boosting/strategies.js.map +1 -0
  266. package/dist/vectordb/boosting/types.d.ts +20 -0
  267. package/dist/vectordb/boosting/types.d.ts.map +1 -0
  268. package/dist/vectordb/boosting/types.js +2 -0
  269. package/dist/vectordb/boosting/types.js.map +1 -0
  270. package/dist/vectordb/intent-classifier.d.ts +99 -0
  271. package/dist/vectordb/intent-classifier.d.ts.map +1 -0
  272. package/dist/vectordb/intent-classifier.js +193 -0
  273. package/dist/vectordb/intent-classifier.js.map +1 -0
  274. package/dist/vectordb/lancedb.d.ts +45 -0
  275. package/dist/vectordb/lancedb.d.ts.map +1 -0
  276. package/dist/vectordb/lancedb.js +203 -0
  277. package/dist/vectordb/lancedb.js.map +1 -0
  278. package/dist/vectordb/maintenance.d.ts +18 -0
  279. package/dist/vectordb/maintenance.d.ts.map +1 -0
  280. package/dist/vectordb/maintenance.js +87 -0
  281. package/dist/vectordb/maintenance.js.map +1 -0
  282. package/dist/vectordb/query.d.ts +34 -0
  283. package/dist/vectordb/query.d.ts.map +1 -0
  284. package/dist/vectordb/query.js +303 -0
  285. package/dist/vectordb/query.js.map +1 -0
  286. package/dist/vectordb/relevance.d.ts +15 -0
  287. package/dist/vectordb/relevance.d.ts.map +1 -0
  288. package/dist/vectordb/relevance.js +19 -0
  289. package/dist/vectordb/relevance.js.map +1 -0
  290. package/dist/vectordb/types.d.ts +29 -0
  291. package/dist/vectordb/types.d.ts.map +1 -0
  292. package/dist/vectordb/types.js +2 -0
  293. package/dist/vectordb/types.js.map +1 -0
  294. package/dist/vectordb/version.d.ts +16 -0
  295. package/dist/vectordb/version.d.ts.map +1 -0
  296. package/dist/vectordb/version.js +40 -0
  297. package/dist/vectordb/version.js.map +1 -0
  298. package/package.json +66 -0
@@ -0,0 +1,179 @@
1
+ /**
2
+ * ChunkBatchProcessor - Handles concurrent chunk accumulation and batch processing.
3
+ *
4
+ * Extracted from performFullIndex to:
5
+ * 1. Encapsulate mutex/lock management complexity
6
+ * 2. Make the batch processing logic testable
7
+ * 3. Separate concerns (accumulation vs processing vs coordination)
8
+ *
9
+ * Key responsibilities:
10
+ * - Accumulate chunks from concurrent file processing
11
+ * - Batch chunks for embedding generation
12
+ * - Manage concurrent access with mutex pattern
13
+ * - Process batches through embedding → vectordb pipeline
14
+ */
15
+ import { EMBEDDING_MICRO_BATCH_SIZE } from '../constants.js';
16
+ /**
17
+ * Process embeddings in micro-batches to prevent event loop blocking.
18
+ * Yields to the event loop between batches for UI responsiveness.
19
+ */
20
+ export async function processEmbeddingMicroBatches(texts, embeddings) {
21
+ const results = [];
22
+ for (let j = 0; j < texts.length; j += EMBEDDING_MICRO_BATCH_SIZE) {
23
+ const microBatch = texts.slice(j, Math.min(j + EMBEDDING_MICRO_BATCH_SIZE, texts.length));
24
+ const microResults = await embeddings.embedBatch(microBatch);
25
+ results.push(...microResults);
26
+ // Yield to event loop for UI responsiveness
27
+ await new Promise(resolve => setImmediate(resolve));
28
+ }
29
+ return results;
30
+ }
31
+ /**
32
+ * ChunkBatchProcessor handles the complex concurrent chunk accumulation
33
+ * and batch processing logic for indexing.
34
+ *
35
+ * Usage:
36
+ * ```typescript
37
+ * const processor = new ChunkBatchProcessor(vectorDB, embeddings, config, tracker);
38
+ *
39
+ * // From concurrent file processing tasks:
40
+ * await processor.addChunks(chunks, filepath, mtime);
41
+ *
42
+ * // After all files processed:
43
+ * await processor.flush();
44
+ *
45
+ * // Get results:
46
+ * const { processedChunks, indexedFiles } = processor.getResults();
47
+ * ```
48
+ */
49
+ export class ChunkBatchProcessor {
50
+ vectorDB;
51
+ embeddings;
52
+ config;
53
+ progressTracker;
54
+ accumulator = [];
55
+ indexedFiles = [];
56
+ processedChunkCount = 0;
57
+ // Mutex state for concurrent access protection
58
+ addChunksLock = null;
59
+ processingQueue = null;
60
+ constructor(vectorDB, embeddings, config, progressTracker) {
61
+ this.vectorDB = vectorDB;
62
+ this.embeddings = embeddings;
63
+ this.config = config;
64
+ this.progressTracker = progressTracker;
65
+ }
66
+ /**
67
+ * Add chunks from a processed file.
68
+ * Thread-safe: uses mutex to prevent race conditions with concurrent calls.
69
+ *
70
+ * @param chunks - Code chunks to add
71
+ * @param filepath - Source file path (for manifest)
72
+ * @param mtime - File modification time in ms (for change detection)
73
+ */
74
+ async addChunks(chunks, filepath, mtime) {
75
+ if (chunks.length === 0) {
76
+ return;
77
+ }
78
+ // Wait for any in-progress add operation (mutex acquire)
79
+ if (this.addChunksLock) {
80
+ await this.addChunksLock;
81
+ }
82
+ // Create new lock promise
83
+ let releaseLock;
84
+ this.addChunksLock = new Promise(resolve => {
85
+ releaseLock = resolve;
86
+ });
87
+ try {
88
+ // Critical section: modify shared state
89
+ for (const chunk of chunks) {
90
+ this.accumulator.push({
91
+ chunk,
92
+ content: chunk.content,
93
+ });
94
+ }
95
+ // Track file for manifest
96
+ this.indexedFiles.push({
97
+ filepath,
98
+ chunkCount: chunks.length,
99
+ mtime,
100
+ });
101
+ // Process if batch threshold reached
102
+ if (this.accumulator.length >= this.config.batchThreshold) {
103
+ await this.triggerProcessing();
104
+ }
105
+ }
106
+ finally {
107
+ // Release mutex
108
+ releaseLock();
109
+ this.addChunksLock = null;
110
+ }
111
+ }
112
+ /**
113
+ * Flush any remaining accumulated chunks.
114
+ * Call this after all files have been processed.
115
+ */
116
+ async flush() {
117
+ this.progressTracker.setMessage?.('Processing final chunks...');
118
+ await this.triggerProcessing();
119
+ }
120
+ /**
121
+ * Get processing results.
122
+ */
123
+ getResults() {
124
+ return {
125
+ processedChunks: this.processedChunkCount,
126
+ indexedFiles: [...this.indexedFiles],
127
+ };
128
+ }
129
+ /**
130
+ * Trigger batch processing. Uses queue-based synchronization
131
+ * to prevent TOCTOU race conditions.
132
+ */
133
+ async triggerProcessing() {
134
+ // Chain onto existing processing promise to create a queue
135
+ if (this.processingQueue) {
136
+ this.processingQueue = this.processingQueue.then(() => this.doProcess());
137
+ }
138
+ else {
139
+ this.processingQueue = this.doProcess();
140
+ }
141
+ return this.processingQueue;
142
+ }
143
+ /**
144
+ * The actual batch processing logic.
145
+ * Processes accumulated chunks through embedding → vectordb pipeline.
146
+ */
147
+ async doProcess() {
148
+ if (this.accumulator.length === 0) {
149
+ return;
150
+ }
151
+ const currentPromise = this.processingQueue;
152
+ try {
153
+ // Drain accumulator atomically
154
+ const toProcess = this.accumulator.splice(0, this.accumulator.length);
155
+ // Process in batches for memory/API limits
156
+ for (let i = 0; i < toProcess.length; i += this.config.embeddingBatchSize) {
157
+ const batch = toProcess.slice(i, Math.min(i + this.config.embeddingBatchSize, toProcess.length));
158
+ const texts = batch.map(item => item.content);
159
+ // Generate embeddings
160
+ this.progressTracker.setMessage?.('Generating embeddings...');
161
+ const embeddingVectors = await processEmbeddingMicroBatches(texts, this.embeddings);
162
+ this.processedChunkCount += batch.length;
163
+ // Insert into vector database
164
+ this.progressTracker.setMessage?.(`Inserting ${batch.length} chunks...`);
165
+ await this.vectorDB.insertBatch(embeddingVectors, batch.map(item => item.chunk.metadata), texts);
166
+ // Yield to event loop
167
+ await new Promise(resolve => setImmediate(resolve));
168
+ }
169
+ this.progressTracker.setMessage?.('Processing files...');
170
+ }
171
+ finally {
172
+ // Clear queue reference if we're the current operation
173
+ if (this.processingQueue === currentPromise) {
174
+ this.processingQueue = null;
175
+ }
176
+ }
177
+ }
178
+ }
179
+ //# sourceMappingURL=chunk-batch-processor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunk-batch-processor.js","sourceRoot":"","sources":["../../src/indexer/chunk-batch-processor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import { CodeChunk } from './types.js';
2
+ export interface ChunkOptions {
3
+ chunkSize?: number;
4
+ chunkOverlap?: number;
5
+ useAST?: boolean;
6
+ astFallback?: 'line-based' | 'error';
7
+ }
8
+ export declare function chunkFile(filepath: string, content: string, options?: ChunkOptions): CodeChunk[];
9
+ export declare function chunkText(text: string, options?: ChunkOptions): string[];
10
+ //# sourceMappingURL=chunker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunker.d.ts","sourceRoot":"","sources":["../../src/indexer/chunker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAOvC,MAAM,WAAW,YAAY;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,WAAW,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC;CACtC;AAED,wBAAgB,SAAS,CACvB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,YAAiB,GACzB,SAAS,EAAE,CAmCb;AAuDD,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,YAAiB,GAAG,MAAM,EAAE,CAqB5E"}
@@ -0,0 +1,96 @@
1
+ import { detectLanguage } from './scanner.js';
2
+ import { extractSymbols } from './symbol-extractor.js';
3
+ import { shouldUseAST, chunkByAST } from './ast/chunker.js';
4
+ import { chunkLiquidFile } from './liquid-chunker.js';
5
+ import { chunkJSONTemplate } from './json-template-chunker.js';
6
+ export function chunkFile(filepath, content, options = {}) {
7
+ const { chunkSize = 75, chunkOverlap = 10, useAST = true, astFallback = 'line-based' } = options;
8
+ // Special handling for Liquid files
9
+ if (filepath.endsWith('.liquid')) {
10
+ return chunkLiquidFile(filepath, content, chunkSize, chunkOverlap);
11
+ }
12
+ // Special handling for Shopify JSON template files (templates/**/*.json)
13
+ // Use regex to ensure 'templates/' is a path segment, not part of another name
14
+ // Matches: templates/product.json OR some-path/templates/customers/account.json
15
+ // Rejects: my-templates/config.json OR node_modules/pkg/templates/file.json (filtered by scanner)
16
+ if (filepath.endsWith('.json') && /(?:^|\/)templates\//.test(filepath)) {
17
+ return chunkJSONTemplate(filepath, content);
18
+ }
19
+ // Try AST-based chunking for supported languages
20
+ if (useAST && shouldUseAST(filepath)) {
21
+ try {
22
+ return chunkByAST(filepath, content, {
23
+ minChunkSize: Math.floor(chunkSize / 10),
24
+ });
25
+ }
26
+ catch (error) {
27
+ // Handle AST errors based on configuration
28
+ if (astFallback === 'error') {
29
+ // Throw error if user wants strict AST-only behavior
30
+ throw new Error(`AST chunking failed for ${filepath}: ${error instanceof Error ? error.message : String(error)}`);
31
+ }
32
+ // Otherwise fallback to line-based chunking
33
+ console.warn(`AST chunking failed for ${filepath}, falling back to line-based:`, error);
34
+ }
35
+ }
36
+ // Line-based chunking (original implementation)
37
+ return chunkByLines(filepath, content, chunkSize, chunkOverlap);
38
+ }
39
+ /**
40
+ * Original line-based chunking implementation
41
+ */
42
+ function chunkByLines(filepath, content, chunkSize, chunkOverlap) {
43
+ const lines = content.split('\n');
44
+ const chunks = [];
45
+ const language = detectLanguage(filepath);
46
+ // Handle empty files
47
+ if (lines.length === 0 || (lines.length === 1 && lines[0].trim() === '')) {
48
+ return chunks;
49
+ }
50
+ // Chunk by lines with overlap
51
+ for (let i = 0; i < lines.length; i += chunkSize - chunkOverlap) {
52
+ const endLine = Math.min(i + chunkSize, lines.length);
53
+ const chunkLines = lines.slice(i, endLine);
54
+ const chunkContent = chunkLines.join('\n');
55
+ // Skip empty chunks
56
+ if (chunkContent.trim().length === 0) {
57
+ continue;
58
+ }
59
+ // Extract symbols from the chunk
60
+ const symbols = extractSymbols(chunkContent, language);
61
+ chunks.push({
62
+ content: chunkContent,
63
+ metadata: {
64
+ file: filepath,
65
+ startLine: i + 1,
66
+ endLine: endLine,
67
+ type: 'block', // MVP: all chunks are 'block' type
68
+ language,
69
+ symbols,
70
+ },
71
+ });
72
+ // If we've reached the end, break
73
+ if (endLine >= lines.length) {
74
+ break;
75
+ }
76
+ }
77
+ return chunks;
78
+ }
79
+ export function chunkText(text, options = {}) {
80
+ const { chunkSize = 75, chunkOverlap = 10 } = options;
81
+ const lines = text.split('\n');
82
+ const chunks = [];
83
+ for (let i = 0; i < lines.length; i += chunkSize - chunkOverlap) {
84
+ const endLine = Math.min(i + chunkSize, lines.length);
85
+ const chunkLines = lines.slice(i, endLine);
86
+ const chunkContent = chunkLines.join('\n');
87
+ if (chunkContent.trim().length > 0) {
88
+ chunks.push(chunkContent);
89
+ }
90
+ if (endLine >= lines.length) {
91
+ break;
92
+ }
93
+ }
94
+ return chunks;
95
+ }
96
+ //# sourceMappingURL=chunker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunker.js","sourceRoot":"","sources":["../../src/indexer/chunker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,60 @@
1
+ import { SearchResult } from '../vectordb/types.js';
2
+ import { RiskLevel } from '../insights/types.js';
3
+ /**
4
+ * Risk level thresholds for dependent count.
5
+ * Based on impact analysis: more dependents = higher risk of breaking changes.
6
+ */
7
+ export declare const DEPENDENT_COUNT_THRESHOLDS: {
8
+ readonly LOW: 5;
9
+ readonly MEDIUM: 15;
10
+ readonly HIGH: 30;
11
+ };
12
+ /**
13
+ * Complexity thresholds for risk assessment.
14
+ * Based on cyclomatic complexity: higher complexity = harder to change safely.
15
+ */
16
+ export declare const COMPLEXITY_THRESHOLDS: {
17
+ readonly HIGH_COMPLEXITY_DEPENDENT: 10;
18
+ readonly CRITICAL_AVG: 15;
19
+ readonly CRITICAL_MAX: 25;
20
+ readonly HIGH_AVG: 10;
21
+ readonly HIGH_MAX: 20;
22
+ readonly MEDIUM_AVG: 6;
23
+ readonly MEDIUM_MAX: 15;
24
+ };
25
+ export interface FileComplexityInfo {
26
+ filepath: string;
27
+ avgComplexity: number;
28
+ maxComplexity: number;
29
+ complexityScore: number;
30
+ chunksWithComplexity: number;
31
+ }
32
+ export interface DependencyAnalysisResult {
33
+ dependents: Array<{
34
+ filepath: string;
35
+ isTestFile: boolean;
36
+ }>;
37
+ dependentCount: number;
38
+ riskLevel: RiskLevel;
39
+ complexityMetrics?: {
40
+ averageComplexity: number;
41
+ maxComplexity: number;
42
+ filesWithComplexityData: number;
43
+ highComplexityDependents: Array<{
44
+ filepath: string;
45
+ maxComplexity: number;
46
+ avgComplexity: number;
47
+ }>;
48
+ complexityRiskBoost: RiskLevel;
49
+ };
50
+ }
51
+ /**
52
+ * Analyzes dependencies for a given file by finding all chunks that import it.
53
+ *
54
+ * @param targetFilepath - The file to analyze dependencies for
55
+ * @param allChunks - All chunks from the vector database
56
+ * @param workspaceRoot - The workspace root directory
57
+ * @returns Dependency analysis including dependents, count, and risk level
58
+ */
59
+ export declare function analyzeDependencies(targetFilepath: string, allChunks: SearchResult[], workspaceRoot: string): DependencyAnalysisResult;
60
+ //# sourceMappingURL=dependency-analyzer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dependency-analyzer.d.ts","sourceRoot":"","sources":["../../src/indexer/dependency-analyzer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEpD,OAAO,EAAc,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAE7D;;;GAGG;AACH,eAAO,MAAM,0BAA0B;;;;CAI7B,CAAC;AAEX;;;GAGG;AACH,eAAO,MAAM,qBAAqB;;;;;;;;CAQxB,CAAC;AAEX,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,oBAAoB,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,wBAAwB;IACvC,UAAU,EAAE,KAAK,CAAC;QAChB,QAAQ,EAAE,MAAM,CAAC;QACjB,UAAU,EAAE,OAAO,CAAC;KACrB,CAAC,CAAC;IACH,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,SAAS,CAAC;IACrB,iBAAiB,CAAC,EAAE;QAClB,iBAAiB,EAAE,MAAM,CAAC;QAC1B,aAAa,EAAE,MAAM,CAAC;QACtB,uBAAuB,EAAE,MAAM,CAAC;QAChC,wBAAwB,EAAE,KAAK,CAAC;YAC9B,QAAQ,EAAE,MAAM,CAAC;YACjB,aAAa,EAAE,MAAM,CAAC;YACtB,aAAa,EAAE,MAAM,CAAC;SACvB,CAAC,CAAC;QACH,mBAAmB,EAAE,SAAS,CAAC;KAChC,CAAC;CACH;AAyOD;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CACjC,cAAc,EAAE,MAAM,EACtB,SAAS,EAAE,YAAY,EAAE,EACzB,aAAa,EAAE,MAAM,GACpB,wBAAwB,CAwC1B"}
@@ -0,0 +1,261 @@
1
+ import { normalizePath, getCanonicalPath, matchesFile, isTestFile } from '../utils/path-matching.js';
2
+ import { RISK_ORDER } from '../insights/types.js';
3
+ /**
4
+ * Risk level thresholds for dependent count.
5
+ * Based on impact analysis: more dependents = higher risk of breaking changes.
6
+ */
7
+ export const DEPENDENT_COUNT_THRESHOLDS = {
8
+ LOW: 5, // Few dependents, safe to change
9
+ MEDIUM: 15, // Moderate impact, review dependents
10
+ HIGH: 30, // High impact, careful planning needed
11
+ };
12
+ /**
13
+ * Complexity thresholds for risk assessment.
14
+ * Based on cyclomatic complexity: higher complexity = harder to change safely.
15
+ */
16
+ export const COMPLEXITY_THRESHOLDS = {
17
+ HIGH_COMPLEXITY_DEPENDENT: 10, // Individual file is complex
18
+ CRITICAL_AVG: 15, // Average complexity indicates systemic complexity
19
+ CRITICAL_MAX: 25, // Peak complexity indicates hotspot
20
+ HIGH_AVG: 10, // Moderately complex on average
21
+ HIGH_MAX: 20, // Some complex functions exist
22
+ MEDIUM_AVG: 6, // Slightly above simple code
23
+ MEDIUM_MAX: 15, // Occasional branching
24
+ };
25
+ /**
26
+ * Creates a cached path normalizer to avoid repeated string operations.
27
+ *
28
+ * @param workspaceRoot - The workspace root directory for path normalization
29
+ * @returns A function that normalizes and caches file paths
30
+ */
31
+ function createPathNormalizer(workspaceRoot) {
32
+ const cache = new Map();
33
+ return (path) => {
34
+ const cached = cache.get(path);
35
+ if (cached !== undefined)
36
+ return cached;
37
+ const normalized = normalizePath(path, workspaceRoot);
38
+ cache.set(path, normalized);
39
+ return normalized;
40
+ };
41
+ }
42
+ /**
43
+ * Builds an index mapping normalized import paths to chunks that import them.
44
+ * Enables O(1) lookup instead of O(n*m) iteration.
45
+ *
46
+ * @param chunks - All chunks from the vector database
47
+ * @param normalizePathCached - Cached path normalization function
48
+ * @returns Map of normalized import paths to chunks that import them
49
+ */
50
+ function buildImportIndex(chunks, normalizePathCached) {
51
+ const importIndex = new Map();
52
+ for (const chunk of chunks) {
53
+ const imports = chunk.metadata.imports || [];
54
+ for (const imp of imports) {
55
+ const normalizedImport = normalizePathCached(imp);
56
+ let chunkList = importIndex.get(normalizedImport);
57
+ if (!chunkList) {
58
+ chunkList = [];
59
+ importIndex.set(normalizedImport, chunkList);
60
+ }
61
+ chunkList.push(chunk);
62
+ }
63
+ }
64
+ return importIndex;
65
+ }
66
+ /**
67
+ * Finds all chunks that import the target file using index + fuzzy matching.
68
+ *
69
+ * @param normalizedTarget - The normalized path of the target file
70
+ * @param importIndex - Index mapping import paths to chunks
71
+ * @returns Array of chunks that import the target file (deduplicated)
72
+ */
73
+ function findDependentChunks(normalizedTarget, importIndex) {
74
+ const dependentChunks = [];
75
+ const seenChunkIds = new Set();
76
+ const addChunk = (chunk) => {
77
+ const chunkId = `${chunk.metadata.file}:${chunk.metadata.startLine}-${chunk.metadata.endLine}`;
78
+ if (!seenChunkIds.has(chunkId)) {
79
+ dependentChunks.push(chunk);
80
+ seenChunkIds.add(chunkId);
81
+ }
82
+ };
83
+ // Direct index lookup (fastest path)
84
+ const directMatches = importIndex.get(normalizedTarget);
85
+ if (directMatches) {
86
+ for (const chunk of directMatches) {
87
+ addChunk(chunk);
88
+ }
89
+ }
90
+ // Fuzzy match for relative imports and path variations
91
+ // Note: This is O(M) where M = unique import paths. For large codebases with many
92
+ // violations, consider caching fuzzy match results at a higher level.
93
+ for (const [normalizedImport, chunks] of importIndex.entries()) {
94
+ if (normalizedImport !== normalizedTarget && matchesFile(normalizedImport, normalizedTarget)) {
95
+ for (const chunk of chunks) {
96
+ addChunk(chunk);
97
+ }
98
+ }
99
+ }
100
+ return dependentChunks;
101
+ }
102
+ /**
103
+ * Groups chunks by their canonical file path.
104
+ *
105
+ * @param chunks - Array of chunks to group
106
+ * @param workspaceRoot - The workspace root directory
107
+ * @returns Map of canonical file paths to their chunks
108
+ */
109
+ function groupChunksByFile(chunks, workspaceRoot) {
110
+ const chunksByFile = new Map();
111
+ for (const chunk of chunks) {
112
+ const canonical = getCanonicalPath(chunk.metadata.file, workspaceRoot);
113
+ let existing = chunksByFile.get(canonical);
114
+ if (!existing) {
115
+ existing = [];
116
+ chunksByFile.set(canonical, existing);
117
+ }
118
+ existing.push(chunk);
119
+ }
120
+ return chunksByFile;
121
+ }
122
+ /**
123
+ * Calculates complexity metrics for each file based on its chunks.
124
+ *
125
+ * @param chunksByFile - Map of file paths to their chunks
126
+ * @returns Array of complexity info for files with complexity data
127
+ */
128
+ function calculateFileComplexities(chunksByFile) {
129
+ const fileComplexities = [];
130
+ for (const [filepath, chunks] of chunksByFile.entries()) {
131
+ const complexities = chunks
132
+ .map(c => c.metadata.complexity)
133
+ .filter((c) => typeof c === 'number' && c > 0);
134
+ if (complexities.length > 0) {
135
+ const sum = complexities.reduce((a, b) => a + b, 0);
136
+ const avg = sum / complexities.length;
137
+ const max = Math.max(...complexities);
138
+ fileComplexities.push({
139
+ filepath,
140
+ avgComplexity: Math.round(avg * 10) / 10,
141
+ maxComplexity: max,
142
+ complexityScore: sum,
143
+ chunksWithComplexity: complexities.length,
144
+ });
145
+ }
146
+ }
147
+ return fileComplexities;
148
+ }
149
+ /**
150
+ * Calculates overall complexity metrics from per-file data.
151
+ *
152
+ * @param fileComplexities - Array of per-file complexity info
153
+ * @returns Aggregated complexity metrics, or undefined if no data
154
+ */
155
+ function calculateOverallComplexityMetrics(fileComplexities) {
156
+ if (fileComplexities.length === 0) {
157
+ return undefined;
158
+ }
159
+ const allAvgs = fileComplexities.map(f => f.avgComplexity);
160
+ const allMaxes = fileComplexities.map(f => f.maxComplexity);
161
+ const totalAvg = allAvgs.reduce((a, b) => a + b, 0) / allAvgs.length;
162
+ const globalMax = Math.max(...allMaxes);
163
+ // Identify high-complexity dependents (top 5)
164
+ const highComplexityDependents = fileComplexities
165
+ .filter(f => f.maxComplexity > COMPLEXITY_THRESHOLDS.HIGH_COMPLEXITY_DEPENDENT)
166
+ .sort((a, b) => b.maxComplexity - a.maxComplexity)
167
+ .slice(0, 5)
168
+ .map(f => ({
169
+ filepath: f.filepath,
170
+ maxComplexity: f.maxComplexity,
171
+ avgComplexity: f.avgComplexity,
172
+ }));
173
+ // Calculate complexity-based risk boost
174
+ const complexityRiskBoost = calculateComplexityRiskBoost(totalAvg, globalMax);
175
+ return {
176
+ averageComplexity: Math.round(totalAvg * 10) / 10,
177
+ maxComplexity: globalMax,
178
+ filesWithComplexityData: fileComplexities.length,
179
+ highComplexityDependents,
180
+ complexityRiskBoost,
181
+ };
182
+ }
183
+ /**
184
+ * Determines risk level based on complexity thresholds.
185
+ *
186
+ * @param avgComplexity - Average complexity across all files
187
+ * @param maxComplexity - Maximum complexity found in any file
188
+ * @returns Risk level based on complexity thresholds
189
+ */
190
+ function calculateComplexityRiskBoost(avgComplexity, maxComplexity) {
191
+ if (avgComplexity > COMPLEXITY_THRESHOLDS.CRITICAL_AVG || maxComplexity > COMPLEXITY_THRESHOLDS.CRITICAL_MAX) {
192
+ return 'critical';
193
+ }
194
+ if (avgComplexity > COMPLEXITY_THRESHOLDS.HIGH_AVG || maxComplexity > COMPLEXITY_THRESHOLDS.HIGH_MAX) {
195
+ return 'high';
196
+ }
197
+ if (avgComplexity > COMPLEXITY_THRESHOLDS.MEDIUM_AVG || maxComplexity > COMPLEXITY_THRESHOLDS.MEDIUM_MAX) {
198
+ return 'medium';
199
+ }
200
+ return 'low';
201
+ }
202
+ /**
203
+ * Calculates risk level based on dependent count.
204
+ *
205
+ * @param count - Number of dependent files
206
+ * @returns Risk level based on dependent count thresholds
207
+ */
208
+ function calculateRiskLevelFromCount(count) {
209
+ if (count <= DEPENDENT_COUNT_THRESHOLDS.LOW) {
210
+ return 'low';
211
+ }
212
+ if (count <= DEPENDENT_COUNT_THRESHOLDS.MEDIUM) {
213
+ return 'medium';
214
+ }
215
+ if (count <= DEPENDENT_COUNT_THRESHOLDS.HIGH) {
216
+ return 'high';
217
+ }
218
+ return 'critical';
219
+ }
220
+ /**
221
+ * Analyzes dependencies for a given file by finding all chunks that import it.
222
+ *
223
+ * @param targetFilepath - The file to analyze dependencies for
224
+ * @param allChunks - All chunks from the vector database
225
+ * @param workspaceRoot - The workspace root directory
226
+ * @returns Dependency analysis including dependents, count, and risk level
227
+ */
228
+ export function analyzeDependencies(targetFilepath, allChunks, workspaceRoot) {
229
+ // Create cached path normalizer
230
+ const normalizePathCached = createPathNormalizer(workspaceRoot);
231
+ // Build import index for efficient lookup
232
+ const importIndex = buildImportIndex(allChunks, normalizePathCached);
233
+ // Find all dependent chunks
234
+ const normalizedTarget = normalizePathCached(targetFilepath);
235
+ const dependentChunks = findDependentChunks(normalizedTarget, importIndex);
236
+ // Group by file for analysis
237
+ const chunksByFile = groupChunksByFile(dependentChunks, workspaceRoot);
238
+ // Calculate complexity metrics
239
+ const fileComplexities = calculateFileComplexities(chunksByFile);
240
+ const complexityMetrics = calculateOverallComplexityMetrics(fileComplexities);
241
+ // Build dependents list
242
+ const dependents = Array.from(chunksByFile.keys()).map(filepath => ({
243
+ filepath,
244
+ isTestFile: isTestFile(filepath),
245
+ }));
246
+ // Calculate risk level
247
+ let riskLevel = calculateRiskLevelFromCount(dependents.length);
248
+ // Boost risk level if complexity warrants it
249
+ if (complexityMetrics?.complexityRiskBoost) {
250
+ if (RISK_ORDER[complexityMetrics.complexityRiskBoost] > RISK_ORDER[riskLevel]) {
251
+ riskLevel = complexityMetrics.complexityRiskBoost;
252
+ }
253
+ }
254
+ return {
255
+ dependents,
256
+ dependentCount: dependents.length,
257
+ riskLevel,
258
+ complexityMetrics,
259
+ };
260
+ }
261
+ //# sourceMappingURL=dependency-analyzer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dependency-analyzer.js","sourceRoot":"","sources":["../../src/indexer/dependency-analyzer.ts"],"names":[],"mappings":"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"}