@syke1/mcp-server 1.5.6 → 1.6.1
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/LICENSE +13 -57
- package/README.md +18 -21
- package/dist/ai/analyzer.js +1 -112
- package/dist/ai/context-extractor.js +1 -224
- package/dist/ai/provider.js +1 -186
- package/dist/ai/realtime-analyzer.js +1 -253
- package/dist/config.js +1 -121
- package/dist/git/change-coupling.js +1 -250
- package/dist/graph/incremental.js +1 -319
- package/dist/graph/memo-cache.js +1 -176
- package/dist/graph/scc.js +1 -206
- package/dist/graph.js +1 -137
- package/dist/index.js +1 -852
- package/dist/license/validator.d.ts +3 -0
- package/dist/license/validator.js +1 -328
- package/dist/scoring/pagerank.js +1 -221
- package/dist/scoring/risk-scorer.js +1 -623
- package/dist/tools/analyze-impact.js +1 -378
- package/dist/tools/gate-build.js +1 -409
- package/dist/watcher/file-cache.js +1 -281
- package/dist/web/server.js +1 -925
- package/package.json +53 -68
package/dist/graph/memo-cache.js
CHANGED
|
@@ -1,176 +1 @@
|
|
|
1
|
-
|
|
2
|
-
/**
|
|
3
|
-
* Memoized BFS Result Cache for SYKE.
|
|
4
|
-
*
|
|
5
|
-
* Caches impact analysis results (BFS reverse traversals) so that
|
|
6
|
-
* repeated queries for the same file return instantly.
|
|
7
|
-
*
|
|
8
|
-
* Smart invalidation: when a file changes, only cache entries that
|
|
9
|
-
* could be affected are evicted. A reverse index maps each file to
|
|
10
|
-
* the set of cache keys whose impactSet contains it, making
|
|
11
|
-
* invalidation O(affected) instead of O(cache_size).
|
|
12
|
-
*
|
|
13
|
-
* Uses LRU eviction when the cache exceeds maxSize.
|
|
14
|
-
*/
|
|
15
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
-
exports.createMemoCache = createMemoCache;
|
|
17
|
-
exports.getMemoCache = getMemoCache;
|
|
18
|
-
exports.resetMemoCache = resetMemoCache;
|
|
19
|
-
// ── Implementation ──
|
|
20
|
-
/**
|
|
21
|
-
* Create a new MemoCache with LRU eviction and reverse-index invalidation.
|
|
22
|
-
*
|
|
23
|
-
* @param maxSize Maximum number of cached entries (default 500).
|
|
24
|
-
*/
|
|
25
|
-
function createMemoCache(maxSize = 500) {
|
|
26
|
-
// Main cache: filePath -> MemoEntry
|
|
27
|
-
const cache = new Map();
|
|
28
|
-
// LRU tracking: most recently accessed key moves to the end
|
|
29
|
-
const accessOrder = [];
|
|
30
|
-
// Reverse index: maps each file to the set of cache keys whose
|
|
31
|
-
// impactSet contains that file. Used for O(affected) invalidation.
|
|
32
|
-
const reverseIndex = new Map();
|
|
33
|
-
// Stats
|
|
34
|
-
let hits = 0;
|
|
35
|
-
let misses = 0;
|
|
36
|
-
/**
|
|
37
|
-
* Move a key to the end of the access order (most recently used).
|
|
38
|
-
*/
|
|
39
|
-
function touchKey(key) {
|
|
40
|
-
const idx = accessOrder.indexOf(key);
|
|
41
|
-
if (idx !== -1) {
|
|
42
|
-
accessOrder.splice(idx, 1);
|
|
43
|
-
}
|
|
44
|
-
accessOrder.push(key);
|
|
45
|
-
}
|
|
46
|
-
/**
|
|
47
|
-
* Remove a single entry from the cache and clean up the reverse index.
|
|
48
|
-
*/
|
|
49
|
-
function removeEntry(key) {
|
|
50
|
-
const entry = cache.get(key);
|
|
51
|
-
if (!entry)
|
|
52
|
-
return;
|
|
53
|
-
// Remove from reverse index
|
|
54
|
-
for (const file of entry.impactSet) {
|
|
55
|
-
const keys = reverseIndex.get(file);
|
|
56
|
-
if (keys) {
|
|
57
|
-
keys.delete(key);
|
|
58
|
-
if (keys.size === 0) {
|
|
59
|
-
reverseIndex.delete(file);
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
// Also remove the key itself from the reverse index
|
|
64
|
-
const selfKeys = reverseIndex.get(key);
|
|
65
|
-
if (selfKeys) {
|
|
66
|
-
selfKeys.delete(key);
|
|
67
|
-
if (selfKeys.size === 0) {
|
|
68
|
-
reverseIndex.delete(key);
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
cache.delete(key);
|
|
72
|
-
const orderIdx = accessOrder.indexOf(key);
|
|
73
|
-
if (orderIdx !== -1) {
|
|
74
|
-
accessOrder.splice(orderIdx, 1);
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
/**
|
|
78
|
-
* Evict the least recently used entry when cache exceeds maxSize.
|
|
79
|
-
*/
|
|
80
|
-
function evictLRU() {
|
|
81
|
-
while (cache.size > maxSize && accessOrder.length > 0) {
|
|
82
|
-
const lruKey = accessOrder.shift();
|
|
83
|
-
removeEntry(lruKey);
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
/**
|
|
87
|
-
* Add a file -> cacheKey mapping to the reverse index.
|
|
88
|
-
*/
|
|
89
|
-
function addToReverseIndex(file, cacheKey) {
|
|
90
|
-
let keys = reverseIndex.get(file);
|
|
91
|
-
if (!keys) {
|
|
92
|
-
keys = new Set();
|
|
93
|
-
reverseIndex.set(file, keys);
|
|
94
|
-
}
|
|
95
|
-
keys.add(cacheKey);
|
|
96
|
-
}
|
|
97
|
-
return {
|
|
98
|
-
get(filePath) {
|
|
99
|
-
const entry = cache.get(filePath);
|
|
100
|
-
if (entry) {
|
|
101
|
-
hits++;
|
|
102
|
-
touchKey(filePath);
|
|
103
|
-
return entry;
|
|
104
|
-
}
|
|
105
|
-
misses++;
|
|
106
|
-
return undefined;
|
|
107
|
-
},
|
|
108
|
-
set(filePath, entry) {
|
|
109
|
-
// If already cached, remove old reverse index entries first
|
|
110
|
-
if (cache.has(filePath)) {
|
|
111
|
-
removeEntry(filePath);
|
|
112
|
-
}
|
|
113
|
-
// Store the entry
|
|
114
|
-
cache.set(filePath, entry);
|
|
115
|
-
touchKey(filePath);
|
|
116
|
-
// Build reverse index: map each file in impactSet -> this cache key
|
|
117
|
-
for (const file of entry.impactSet) {
|
|
118
|
-
addToReverseIndex(file, filePath);
|
|
119
|
-
}
|
|
120
|
-
// Also index the key itself (if the queried file changes, its own
|
|
121
|
-
// cached result is stale)
|
|
122
|
-
addToReverseIndex(filePath, filePath);
|
|
123
|
-
// Evict LRU if over capacity
|
|
124
|
-
evictLRU();
|
|
125
|
-
},
|
|
126
|
-
invalidate(affectedFiles) {
|
|
127
|
-
const keysToInvalidate = new Set();
|
|
128
|
-
for (const file of affectedFiles) {
|
|
129
|
-
// Find all cache keys whose impactSet contains this file
|
|
130
|
-
const keys = reverseIndex.get(file);
|
|
131
|
-
if (keys) {
|
|
132
|
-
for (const key of keys) {
|
|
133
|
-
keysToInvalidate.add(key);
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
// Remove all identified entries
|
|
138
|
-
for (const key of keysToInvalidate) {
|
|
139
|
-
removeEntry(key);
|
|
140
|
-
}
|
|
141
|
-
return keysToInvalidate.size;
|
|
142
|
-
},
|
|
143
|
-
invalidateAll() {
|
|
144
|
-
cache.clear();
|
|
145
|
-
accessOrder.length = 0;
|
|
146
|
-
reverseIndex.clear();
|
|
147
|
-
// Do NOT reset hits/misses — they are cumulative diagnostics
|
|
148
|
-
},
|
|
149
|
-
stats() {
|
|
150
|
-
return {
|
|
151
|
-
size: cache.size,
|
|
152
|
-
hits,
|
|
153
|
-
misses,
|
|
154
|
-
};
|
|
155
|
-
},
|
|
156
|
-
};
|
|
157
|
-
}
|
|
158
|
-
// ── Singleton Instance ──
|
|
159
|
-
let globalMemoCache = null;
|
|
160
|
-
/**
|
|
161
|
-
* Get the global memo cache instance (lazy initialization).
|
|
162
|
-
*/
|
|
163
|
-
function getMemoCache() {
|
|
164
|
-
if (!globalMemoCache) {
|
|
165
|
-
globalMemoCache = createMemoCache();
|
|
166
|
-
}
|
|
167
|
-
return globalMemoCache;
|
|
168
|
-
}
|
|
169
|
-
/**
|
|
170
|
-
* Reset the global memo cache (e.g., on full graph rebuild).
|
|
171
|
-
*/
|
|
172
|
-
function resetMemoCache() {
|
|
173
|
-
if (globalMemoCache) {
|
|
174
|
-
globalMemoCache.invalidateAll();
|
|
175
|
-
}
|
|
176
|
-
}
|
|
1
|
+
'use strict';const _0xf98907=_0x3639;(function(_0x248c39,_0x103b9a){const _0x415fc2={_0xac5bce:0x97,_0x578850:0x90,_0x42095b:0x9a,_0x52531b:0x91,_0x271c87:0x9c,_0x455d8a:0x9d,_0x238631:0x9f},_0x5baa26=_0x3639,_0x35345f=_0x248c39();while(!![]){try{const _0x17521f=parseInt(_0x5baa26(0xa7))/0x1+parseInt(_0x5baa26(_0x415fc2._0xac5bce))/0x2+-parseInt(_0x5baa26(_0x415fc2._0x578850))/0x3*(parseInt(_0x5baa26(0x8f))/0x4)+parseInt(_0x5baa26(_0x415fc2._0x42095b))/0x5*(-parseInt(_0x5baa26(_0x415fc2._0x52531b))/0x6)+-parseInt(_0x5baa26(_0x415fc2._0x271c87))/0x7*(-parseInt(_0x5baa26(_0x415fc2._0x455d8a))/0x8)+parseInt(_0x5baa26(0xa6))/0x9*(-parseInt(_0x5baa26(0x94))/0xa)+-parseInt(_0x5baa26(_0x415fc2._0x238631))/0xb;if(_0x17521f===_0x103b9a)break;else _0x35345f['push'](_0x35345f['shift']());}catch(_0x42cfcb){_0x35345f['push'](_0x35345f['shift']());}}}(_0x5299,0x3d758));function _0x5299(){const _0x5d7f32=['zgvSzxrL','y2XLyxi','C2L6zq','ywrK','Aw5KzxHpzG','EhHgr0u','mti2EeTmtKDW','ndK3ntG2zevpAhvJ','Aw1Wywn0u2v0','C2v0','mtjHyKvVBfa','nZyYotnswKfPwxe','nJiWmJy4v3zpDgnK','BwLZC2vZ','DMfSDwu','mti3mZqWEMrfDxfP','ChvZAa','z2v0','nZeWnJa4wxLYzhnI','BgvUz3rO','C3bSAwnL','nuvuCNvgtq','AgfZ','otG4ntG5BLrpCM9j','mJr0DwzWqw4','wgDKvMu','nZmZntC2og1nu1bewG'];_0x5299=function(){return _0x5d7f32;};return _0x5299();}const _0x5c2bc2={};_0x5c2bc2[_0xf98907(0x93)]=!![],Object['defineProperty'](exports,'__esModule',_0x5c2bc2),exports['createMemoCache']=createMemoCache,exports['getMemoCache']=getMemoCache,exports['resetMemoCache']=resetMemoCache;function createMemoCache(_0x850a27=0x1f4){const _0x13cd44={_0x14f745:0x96,_0x508d33:0xa3},_0x1f8abd={_0x544027:0x9b,_0x4b5ea9:0xa5},_0x12afde={_0x394a5e:0xa9},_0x53f59b={_0x24d279:0x9e},_0x2d761b={_0x170a96:0xa8,_0x35c1d6:0xa0,_0x19901f:0xa2,_0x5abdd9:0xa0,_0x150ae7:0xa4},_0x5429f7={'FhwBi':function(_0x5dc54c,_0x50d2e4){return _0x5dc54c===_0x50d2e4;},'XgdVe':function(_0x125ef2,_0x13f76a){return _0x125ef2(_0x13f76a);},'xxFGE':function(_0x21ea27,_0x332a67,_0x4a052e){return _0x21ea27(_0x332a67,_0x4a052e);},'UqwGt':function(_0x5773d1,_0x4a180d){return _0x5773d1(_0x4a180d);}},_0x4233b3=new Map(),_0x5360b8=[],_0x5e109e=new Map();let _0x34134c=0x0,_0x19e3d2=0x0;function _0x215962(_0x7f850c){const _0x2b3da3=_0x3639,_0x44c501=_0x5360b8[_0x2b3da3(0xa4)](_0x7f850c);_0x44c501!==-0x1&&_0x5360b8[_0x2b3da3(0x99)](_0x44c501,0x1),_0x5360b8[_0x2b3da3(0x95)](_0x7f850c);}function _0x37f9b5(_0x30d4a6){const _0x4db4d2=_0x3639,_0x31999a=_0x4233b3['get'](_0x30d4a6);if(!_0x31999a)return;for(const _0xff7dfb of _0x31999a[_0x4db4d2(_0x2d761b._0x170a96)]){const _0x2c075c=_0x5e109e['get'](_0xff7dfb);_0x2c075c&&(_0x2c075c[_0x4db4d2(0xa0)](_0x30d4a6),_0x5429f7['FhwBi'](_0x2c075c[_0x4db4d2(0xa2)],0x0)&&_0x5e109e['delete'](_0xff7dfb));}const _0x12ae3b=_0x5e109e['get'](_0x30d4a6);_0x12ae3b&&(_0x12ae3b[_0x4db4d2(_0x2d761b._0x35c1d6)](_0x30d4a6),_0x12ae3b[_0x4db4d2(_0x2d761b._0x19901f)]===0x0&&_0x5e109e['delete'](_0x30d4a6));_0x4233b3[_0x4db4d2(_0x2d761b._0x5abdd9)](_0x30d4a6);const _0x378958=_0x5360b8[_0x4db4d2(_0x2d761b._0x150ae7)](_0x30d4a6);_0x378958!==-0x1&&_0x5360b8[_0x4db4d2(0x99)](_0x378958,0x1);}function _0x19ed5b(){const _0x313497=_0x3639;while(_0x4233b3[_0x313497(0xa2)]>_0x850a27&&_0x5360b8[_0x313497(0x98)]>0x0){const _0x2a3f66=_0x5360b8['shift']();_0x5429f7[_0x313497(_0x53f59b._0x24d279)](_0x37f9b5,_0x2a3f66);}}function _0x53c2d3(_0x6fba42,_0x33ef7a){const _0x5135ca=_0x3639;let _0x314f31=_0x5e109e['get'](_0x6fba42);!_0x314f31&&(_0x314f31=new Set(),_0x5e109e[_0x5135ca(_0x12afde._0x394a5e)](_0x6fba42,_0x314f31)),_0x314f31['add'](_0x33ef7a);}return{'get'(_0x1984c0){const _0x312b09=_0x3639,_0x4ed2b8=_0x4233b3[_0x312b09(0x96)](_0x1984c0);if(_0x4ed2b8)return _0x34134c++,_0x215962(_0x1984c0),_0x4ed2b8;return _0x19e3d2++,undefined;},'set'(_0x4e9b91,_0x497360){const _0x58832b=_0x3639;_0x4233b3[_0x58832b(_0x1f8abd._0x544027)](_0x4e9b91)&&_0x5429f7['XgdVe'](_0x37f9b5,_0x4e9b91);_0x4233b3['set'](_0x4e9b91,_0x497360),_0x215962(_0x4e9b91);for(const _0x1f528d of _0x497360['impactSet']){_0x53c2d3(_0x1f528d,_0x4e9b91);}_0x5429f7[_0x58832b(_0x1f8abd._0x4b5ea9)](_0x53c2d3,_0x4e9b91,_0x4e9b91),_0x19ed5b();},'invalidate'(_0x4697da){const _0x30890d=_0x3639,_0x20215a=new Set();for(const _0xa9a082 of _0x4697da){const _0x32ee8d=_0x5e109e[_0x30890d(_0x13cd44._0x14f745)](_0xa9a082);if(_0x32ee8d)for(const _0x1f8161 of _0x32ee8d){_0x20215a[_0x30890d(_0x13cd44._0x508d33)](_0x1f8161);}}for(const _0x2cbd40 of _0x20215a){_0x5429f7['UqwGt'](_0x37f9b5,_0x2cbd40);}return _0x20215a['size'];},'invalidateAll'(){const _0x4ad16c=_0x3639;_0x4233b3[_0x4ad16c(0xa1)](),_0x5360b8[_0x4ad16c(0x98)]=0x0,_0x5e109e[_0x4ad16c(0xa1)]();},'stats'(){const _0x3ee88d=_0x3639,_0x36106e={};return _0x36106e[_0x3ee88d(0xa2)]=_0x4233b3['size'],_0x36106e['hits']=_0x34134c,_0x36106e[_0x3ee88d(0x92)]=_0x19e3d2,_0x36106e;}};}function _0x3639(_0x12d590,_0x1c97d2){_0x12d590=_0x12d590-0x8f;const _0x529939=_0x5299();let _0x36394f=_0x529939[_0x12d590];if(_0x3639['lftYvS']===undefined){var _0x1cac9d=function(_0x50dd2c){const _0x20c09a='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x39c7ff='',_0x205ed0='';for(let _0x2574be=0x0,_0x44b467,_0x3052cd,_0x51ccbe=0x0;_0x3052cd=_0x50dd2c['charAt'](_0x51ccbe++);~_0x3052cd&&(_0x44b467=_0x2574be%0x4?_0x44b467*0x40+_0x3052cd:_0x3052cd,_0x2574be++%0x4)?_0x39c7ff+=String['fromCharCode'](0xff&_0x44b467>>(-0x2*_0x2574be&0x6)):0x0){_0x3052cd=_0x20c09a['indexOf'](_0x3052cd);}for(let _0x4f9340=0x0,_0x5b3e24=_0x39c7ff['length'];_0x4f9340<_0x5b3e24;_0x4f9340++){_0x205ed0+='%'+('00'+_0x39c7ff['charCodeAt'](_0x4f9340)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x205ed0);};_0x3639['egoGQv']=_0x1cac9d,_0x3639['UUBlpH']={},_0x3639['lftYvS']=!![];}const _0x5549cf=_0x529939[0x0],_0xcaa0d2=_0x12d590+_0x5549cf,_0x4e39f1=_0x3639['UUBlpH'][_0xcaa0d2];return!_0x4e39f1?(_0x36394f=_0x3639['egoGQv'](_0x36394f),_0x3639['UUBlpH'][_0xcaa0d2]=_0x36394f):_0x36394f=_0x4e39f1,_0x36394f;}let globalMemoCache=null;function getMemoCache(){const _0x52ac2d={'TauwT':function(_0x13fece){return _0x13fece();}};return!globalMemoCache&&(globalMemoCache=_0x52ac2d['TauwT'](createMemoCache)),globalMemoCache;}function resetMemoCache(){globalMemoCache&&globalMemoCache['invalidateAll']();}
|
package/dist/graph/scc.js
CHANGED
|
@@ -1,206 +1 @@
|
|
|
1
|
-
|
|
2
|
-
/**
|
|
3
|
-
* Strongly Connected Components (SCC) via Tarjan's algorithm,
|
|
4
|
-
* graph condensation into a DAG, and topological sort via Kahn's algorithm.
|
|
5
|
-
*
|
|
6
|
-
* Used to detect circular dependencies and provide accurate cascade-level
|
|
7
|
-
* impact analysis on the condensed (acyclic) dependency graph.
|
|
8
|
-
*/
|
|
9
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
-
exports.computeSCC = computeSCC;
|
|
11
|
-
exports.condenseGraph = condenseGraph;
|
|
12
|
-
exports.topologicalSort = topologicalSort;
|
|
13
|
-
// ── Tarjan's SCC Algorithm ──
|
|
14
|
-
/**
|
|
15
|
-
* Compute all Strongly Connected Components of the dependency graph
|
|
16
|
-
* using Tarjan's algorithm. Returns SCCs, a file-to-SCC mapping,
|
|
17
|
-
* and the condensed DAG with topological ordering.
|
|
18
|
-
*/
|
|
19
|
-
function computeSCC(graph) {
|
|
20
|
-
// Handle empty graph
|
|
21
|
-
if (graph.files.size === 0) {
|
|
22
|
-
const emptyDAG = {
|
|
23
|
-
nodes: [],
|
|
24
|
-
forward: new Map(),
|
|
25
|
-
reverse: new Map(),
|
|
26
|
-
topologicalOrder: [],
|
|
27
|
-
};
|
|
28
|
-
return {
|
|
29
|
-
components: [],
|
|
30
|
-
nodeToComponent: new Map(),
|
|
31
|
-
condensed: emptyDAG,
|
|
32
|
-
};
|
|
33
|
-
}
|
|
34
|
-
const components = [];
|
|
35
|
-
// Tarjan state
|
|
36
|
-
let indexCounter = 0;
|
|
37
|
-
const nodeIndex = new Map();
|
|
38
|
-
const nodeLowlink = new Map();
|
|
39
|
-
const onStack = new Set();
|
|
40
|
-
const stack = [];
|
|
41
|
-
function strongConnect(node) {
|
|
42
|
-
nodeIndex.set(node, indexCounter);
|
|
43
|
-
nodeLowlink.set(node, indexCounter);
|
|
44
|
-
indexCounter++;
|
|
45
|
-
stack.push(node);
|
|
46
|
-
onStack.add(node);
|
|
47
|
-
const successors = graph.forward.get(node) || [];
|
|
48
|
-
for (const successor of successors) {
|
|
49
|
-
// Only process nodes that exist in the graph
|
|
50
|
-
if (!graph.files.has(successor))
|
|
51
|
-
continue;
|
|
52
|
-
if (!nodeIndex.has(successor)) {
|
|
53
|
-
// Successor not yet visited — recurse
|
|
54
|
-
strongConnect(successor);
|
|
55
|
-
nodeLowlink.set(node, Math.min(nodeLowlink.get(node), nodeLowlink.get(successor)));
|
|
56
|
-
}
|
|
57
|
-
else if (onStack.has(successor)) {
|
|
58
|
-
// Successor is on the stack — part of current SCC
|
|
59
|
-
nodeLowlink.set(node, Math.min(nodeLowlink.get(node), nodeIndex.get(successor)));
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
// If node is a root of an SCC, pop the stack to form a component
|
|
63
|
-
if (nodeLowlink.get(node) === nodeIndex.get(node)) {
|
|
64
|
-
const component = [];
|
|
65
|
-
let w;
|
|
66
|
-
do {
|
|
67
|
-
w = stack.pop();
|
|
68
|
-
onStack.delete(w);
|
|
69
|
-
component.push(w);
|
|
70
|
-
} while (w !== node);
|
|
71
|
-
components.push(component);
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
// Visit all nodes (handles disconnected components)
|
|
75
|
-
for (const file of graph.files) {
|
|
76
|
-
if (!nodeIndex.has(file)) {
|
|
77
|
-
strongConnect(file);
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
// Build file-to-component mapping
|
|
81
|
-
const nodeToComponent = new Map();
|
|
82
|
-
for (let i = 0; i < components.length; i++) {
|
|
83
|
-
for (const file of components[i]) {
|
|
84
|
-
nodeToComponent.set(file, i);
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
// Build the condensed DAG
|
|
88
|
-
const condensed = condenseGraph(graph, components, nodeToComponent);
|
|
89
|
-
return { components, nodeToComponent, condensed };
|
|
90
|
-
}
|
|
91
|
-
// ── Graph Condensation ──
|
|
92
|
-
/**
|
|
93
|
-
* Build a DAG where each node represents one SCC.
|
|
94
|
-
* Edges between SCCs are derived from the original graph's edges
|
|
95
|
-
* between files belonging to different SCCs.
|
|
96
|
-
*/
|
|
97
|
-
function condenseGraph(graph, components, nodeToComponent) {
|
|
98
|
-
const numComponents = components.length;
|
|
99
|
-
// Build condensed nodes
|
|
100
|
-
const nodes = components.map((files, index) => ({
|
|
101
|
-
index,
|
|
102
|
-
files,
|
|
103
|
-
size: files.length,
|
|
104
|
-
isCyclic: files.length > 1,
|
|
105
|
-
}));
|
|
106
|
-
// Build forward and reverse edges between SCCs (deduplicated)
|
|
107
|
-
const forwardSets = new Map();
|
|
108
|
-
const reverseSets = new Map();
|
|
109
|
-
for (let i = 0; i < numComponents; i++) {
|
|
110
|
-
forwardSets.set(i, new Set());
|
|
111
|
-
reverseSets.set(i, new Set());
|
|
112
|
-
}
|
|
113
|
-
for (const [file, deps] of graph.forward) {
|
|
114
|
-
const srcSCC = nodeToComponent.get(file);
|
|
115
|
-
if (srcSCC === undefined)
|
|
116
|
-
continue;
|
|
117
|
-
for (const dep of deps) {
|
|
118
|
-
const dstSCC = nodeToComponent.get(dep);
|
|
119
|
-
if (dstSCC === undefined)
|
|
120
|
-
continue;
|
|
121
|
-
// Skip self-edges (within the same SCC)
|
|
122
|
-
if (srcSCC === dstSCC)
|
|
123
|
-
continue;
|
|
124
|
-
forwardSets.get(srcSCC).add(dstSCC);
|
|
125
|
-
reverseSets.get(dstSCC).add(srcSCC);
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
// Convert sets to arrays
|
|
129
|
-
const forward = new Map();
|
|
130
|
-
const reverse = new Map();
|
|
131
|
-
for (const [key, set] of forwardSets) {
|
|
132
|
-
forward.set(key, [...set]);
|
|
133
|
-
}
|
|
134
|
-
for (const [key, set] of reverseSets) {
|
|
135
|
-
reverse.set(key, [...set]);
|
|
136
|
-
}
|
|
137
|
-
const dag = {
|
|
138
|
-
nodes,
|
|
139
|
-
forward,
|
|
140
|
-
reverse,
|
|
141
|
-
topologicalOrder: [],
|
|
142
|
-
};
|
|
143
|
-
// Compute topological order
|
|
144
|
-
dag.topologicalOrder = topologicalSort(dag);
|
|
145
|
-
return dag;
|
|
146
|
-
}
|
|
147
|
-
// ── Topological Sort (Kahn's Algorithm) ──
|
|
148
|
-
/**
|
|
149
|
-
* Compute a topological ordering of the condensed DAG using Kahn's algorithm.
|
|
150
|
-
* The condensed graph is guaranteed to be acyclic after SCC condensation.
|
|
151
|
-
*
|
|
152
|
-
* Returns SCC indices in dependency order: dependencies come before dependents.
|
|
153
|
-
* This uses the `forward` edges (file A imports B means A -> B in forward),
|
|
154
|
-
* so we process nodes with no incoming forward edges first (leaf dependencies).
|
|
155
|
-
*/
|
|
156
|
-
function topologicalSort(dag) {
|
|
157
|
-
const numNodes = dag.nodes.length;
|
|
158
|
-
if (numNodes === 0)
|
|
159
|
-
return [];
|
|
160
|
-
// In-degree = number of dependencies (forward edges out of each node).
|
|
161
|
-
// forward[A] = [B] means A imports B, so A depends on B.
|
|
162
|
-
// For "dependencies first" ordering, nodes with zero dependencies come first.
|
|
163
|
-
const inDegree = new Map();
|
|
164
|
-
for (let i = 0; i < numNodes; i++) {
|
|
165
|
-
inDegree.set(i, 0);
|
|
166
|
-
}
|
|
167
|
-
for (const [src, dsts] of dag.forward) {
|
|
168
|
-
inDegree.set(src, (inDegree.get(src) || 0) + dsts.length);
|
|
169
|
-
}
|
|
170
|
-
// Start with nodes that have no dependencies (in-degree 0 in forward)
|
|
171
|
-
const queue = [];
|
|
172
|
-
for (const [node, degree] of inDegree) {
|
|
173
|
-
if (degree === 0) {
|
|
174
|
-
queue.push(node);
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
const order = [];
|
|
178
|
-
while (queue.length > 0) {
|
|
179
|
-
const current = queue.shift();
|
|
180
|
-
order.push(current);
|
|
181
|
-
// current has no remaining dependencies.
|
|
182
|
-
// For all nodes that depend on current (reverse edges: who imports current),
|
|
183
|
-
// decrement their in-degree.
|
|
184
|
-
const dependents = dag.reverse.get(current) || [];
|
|
185
|
-
for (const dependent of dependents) {
|
|
186
|
-
const newDegree = (inDegree.get(dependent) || 0) - 1;
|
|
187
|
-
inDegree.set(dependent, newDegree);
|
|
188
|
-
if (newDegree === 0) {
|
|
189
|
-
queue.push(dependent);
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
// If order doesn't contain all nodes, there's a bug (shouldn't happen after SCC condensation)
|
|
194
|
-
if (order.length !== numNodes) {
|
|
195
|
-
console.error(`[syke:scc] WARNING: Topological sort produced ${order.length}/${numNodes} nodes. ` +
|
|
196
|
-
`This indicates a bug in SCC condensation.`);
|
|
197
|
-
// Add remaining nodes at the end
|
|
198
|
-
const ordered = new Set(order);
|
|
199
|
-
for (let i = 0; i < numNodes; i++) {
|
|
200
|
-
if (!ordered.has(i)) {
|
|
201
|
-
order.push(i);
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
return order;
|
|
206
|
-
}
|
|
1
|
+
'use strict';const _0x1deb33=_0x3b13;(function(_0x26c90e,_0x2667b7){const _0x32f397={_0x3d46e9:0xa3,_0x378689:0x93,_0x8e2e84:0x96,_0x518e38:0x9c,_0x182833:0x92},_0x5eccd3=_0x3b13,_0x20ba7c=_0x26c90e();while(!![]){try{const _0x2955b0=parseInt(_0x5eccd3(0xa6))/0x1+-parseInt(_0x5eccd3(_0x32f397._0x3d46e9))/0x2*(parseInt(_0x5eccd3(_0x32f397._0x378689))/0x3)+-parseInt(_0x5eccd3(_0x32f397._0x8e2e84))/0x4*(-parseInt(_0x5eccd3(0x8c))/0x5)+-parseInt(_0x5eccd3(0xa5))/0x6+parseInt(_0x5eccd3(0x9d))/0x7*(parseInt(_0x5eccd3(0xa1))/0x8)+-parseInt(_0x5eccd3(_0x32f397._0x518e38))/0x9+parseInt(_0x5eccd3(_0x32f397._0x182833))/0xa;if(_0x2955b0===_0x2667b7)break;else _0x20ba7c['push'](_0x20ba7c['shift']());}catch(_0x4b6cde){_0x20ba7c['push'](_0x20ba7c['shift']());}}}(_0x475e,0x9b649));function _0x3b13(_0xc7160e,_0x39f0f4){_0xc7160e=_0xc7160e-0x81;const _0x475e6e=_0x475e();let _0x3b13d8=_0x475e6e[_0xc7160e];if(_0x3b13['thDDnt']===undefined){var _0x5845dd=function(_0x50a9f4){const _0x4ac2b1='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x2fe325='',_0x5e947e='';for(let _0x5ab84c=0x0,_0x56a2d7,_0x28169f,_0x399efd=0x0;_0x28169f=_0x50a9f4['charAt'](_0x399efd++);~_0x28169f&&(_0x56a2d7=_0x5ab84c%0x4?_0x56a2d7*0x40+_0x28169f:_0x28169f,_0x5ab84c++%0x4)?_0x2fe325+=String['fromCharCode'](0xff&_0x56a2d7>>(-0x2*_0x5ab84c&0x6)):0x0){_0x28169f=_0x4ac2b1['indexOf'](_0x28169f);}for(let _0x4ef712=0x0,_0x4af97f=_0x2fe325['length'];_0x4ef712<_0x4af97f;_0x4ef712++){_0x5e947e+='%'+('00'+_0x2fe325['charCodeAt'](_0x4ef712)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x5e947e);};_0x3b13['EVtOcT']=_0x5845dd,_0x3b13['mpvMxX']={},_0x3b13['thDDnt']=!![];}const _0x3cc067=_0x475e6e[0x0],_0x5180bf=_0xc7160e+_0x3cc067,_0x3c6f11=_0x3b13['mpvMxX'][_0x5180bf];return!_0x3c6f11?(_0x3b13d8=_0x3b13['EVtOcT'](_0x3b13d8),_0x3b13['mpvMxX'][_0x5180bf]=_0x3b13d8):_0x3b13d8=_0x3c6f11,_0x3b13d8;}const _0x30f8ac={};function _0x475e(){const _0x19dadb=['zM9YD2fYza','BgvUz3rO','rMryzeq','AgfZ','C2HPzNq','z2v0','Dg9WB2XVz2LJywXtB3j0','x19LC01VzhvSzq','ntGWvwf4CKXp','zMLSzxm','zgvMAw5LuhjVCgvYDhK','ChvZAa','y29TChv0zvndqW','y29TCg9Uzw50CW','mtmWmZm2nZboz3zezvm','mJiYuMXNrNHw','zw5psLi','CgDTzMy','otC1nLnqs1HLDq','BM9KzvrVq29TCg9Uzw50','AKfQr1u','CMv2zxjZzq','y29UzgvUC2vhCMfWAa','C2L6zq','nZm5otC4mLHPrg1VEa','n0XWyu9dwq','y2jHt2C','w3n5A2u6C2nJxsbxqvjosu5hoIbuB3bVBg9NAwnHBcbZB3j0ihbYB2r1y2vKia','BM9Kzxm','nty2ndqWogjewNLzuq','Exf6y28','mJuZntrqzfDyDfO','y29UzgvUC2vK','nJe5odiZnef0D3DrvG','mteZntq4mLDRr0XSqW','ywrK','C2v0','BwfW'];_0x475e=function(){return _0x19dadb;};return _0x475e();}_0x30f8ac['value']=!![],Object[_0x1deb33(0x8e)](exports,_0x1deb33(0x8b),_0x30f8ac),exports[_0x1deb33(0x90)]=computeSCC,exports[_0x1deb33(0x9a)]=condenseGraph,exports[_0x1deb33(0x8a)]=topologicalSort;function computeSCC(_0x59b5c8){const _0x45aeae={_0x32c64a:0x94,_0x2b8e90:0x8d,_0x395e96:0x87,_0x921443:0x95,_0x4b452a:0xa4},_0xd6561e={_0x124092:0x8f,_0x40c8d1:0x89,_0x46e744:0x8f},_0x322b80=_0x1deb33,_0x281596={'VLudy':function(_0x13a0ce,_0x338800){return _0x13a0ce===_0x338800;},'enOJR':function(_0x2b0d10,_0xf07b97){return _0x2b0d10===_0xf07b97;},'pgmff':function(_0x375211,_0x28d5b5){return _0x375211(_0x28d5b5);},'ngwab':function(_0x53cb21,_0x560596){return _0x53cb21<_0x560596;}};if(_0x281596[_0x322b80(_0x45aeae._0x32c64a)](_0x59b5c8[_0x322b80(_0x45aeae._0x2b8e90)][_0x322b80(0x9b)],0x0)){const _0x586934={'nodes':[],'forward':new Map(),'reverse':new Map(),'topologicalOrder':[]};return{'components':[],'nodeToComponent':new Map(),'condensed':_0x586934};}const _0x51ae76=[];let _0x4402a2=0x0;const _0x4dcf1b=new Map(),_0x446d99=new Map(),_0x4d9706=new Set(),_0x5524c5=[];function _0x59e3e9(_0x5d98e6){const _0x314487=_0x322b80;_0x4dcf1b['set'](_0x5d98e6,_0x4402a2),_0x446d99['set'](_0x5d98e6,_0x4402a2),_0x4402a2++,_0x5524c5[_0x314487(_0xd6561e._0x124092)](_0x5d98e6),_0x4d9706['add'](_0x5d98e6);const _0x4cdc63=_0x59b5c8[_0x314487(0x84)]['get'](_0x5d98e6)||[];for(const _0x3647d of _0x4cdc63){if(!_0x59b5c8[_0x314487(0x8d)][_0x314487(0x87)](_0x3647d))continue;if(!_0x4dcf1b['has'](_0x3647d))_0x59e3e9(_0x3647d),_0x446d99['set'](_0x5d98e6,Math['min'](_0x446d99[_0x314487(_0xd6561e._0x40c8d1)](_0x5d98e6),_0x446d99['get'](_0x3647d)));else _0x4d9706['has'](_0x3647d)&&_0x446d99[_0x314487(0x82)](_0x5d98e6,Math['min'](_0x446d99['get'](_0x5d98e6),_0x4dcf1b[_0x314487(0x89)](_0x3647d)));}if(_0x281596['VLudy'](_0x446d99['get'](_0x5d98e6),_0x4dcf1b[_0x314487(_0xd6561e._0x40c8d1)](_0x5d98e6))){const _0xc1dab1=[];let _0x30a364;do{_0x30a364=_0x5524c5['pop'](),_0x4d9706['delete'](_0x30a364),_0xc1dab1['push'](_0x30a364);}while(_0x30a364!==_0x5d98e6);_0x51ae76[_0x314487(_0xd6561e._0x46e744)](_0xc1dab1);}}for(const _0x524daf of _0x59b5c8[_0x322b80(_0x45aeae._0x2b8e90)]){!_0x4dcf1b[_0x322b80(_0x45aeae._0x395e96)](_0x524daf)&&_0x281596[_0x322b80(_0x45aeae._0x921443)](_0x59e3e9,_0x524daf);}const _0x4813b4=new Map();for(let _0x1c5e72=0x0;_0x281596['ngwab'](_0x1c5e72,_0x51ae76['length']);_0x1c5e72++){for(const _0x404c08 of _0x51ae76[_0x1c5e72]){_0x4813b4['set'](_0x404c08,_0x1c5e72);}}const _0x14f920=condenseGraph(_0x59b5c8,_0x51ae76,_0x4813b4),_0x4bc1f0={};return _0x4bc1f0[_0x322b80(0x91)]=_0x51ae76,_0x4bc1f0[_0x322b80(0x97)]=_0x4813b4,_0x4bc1f0[_0x322b80(_0x45aeae._0x4b452a)]=_0x14f920,_0x4bc1f0;}function condenseGraph(_0x2e6953,_0x282528,_0xad73a5){const _0x48c62f={_0x782ae3:0xa2,_0x5f0b42:0x89,_0x30b85b:0x81,_0x1e7758:0xa0},_0x316f1b=_0x1deb33,_0xade0c4={};_0xade0c4['KLhMW']=function(_0x4ab5a6,_0x135a70){return _0x4ab5a6<_0x135a70;},_0xade0c4['yqzco']=function(_0x14ffdf,_0x427770){return _0x14ffdf===_0x427770;};const _0x3f4573=_0xade0c4,_0x3886d4=_0x282528['length'],_0x24078d=_0x282528[_0x316f1b(0x83)]((_0x365523,_0x30704b)=>({'index':_0x30704b,'files':_0x365523,'size':_0x365523['length'],'isCyclic':_0x365523[_0x316f1b(0x85)]>0x1})),_0x150237=new Map(),_0x11a6f3=new Map();for(let _0x1ef477=0x0;_0x3f4573['KLhMW'](_0x1ef477,_0x3886d4);_0x1ef477++){_0x150237['set'](_0x1ef477,new Set()),_0x11a6f3['set'](_0x1ef477,new Set());}for(const [_0x1e1562,_0x19f777]of _0x2e6953['forward']){const _0x129500=_0xad73a5['get'](_0x1e1562);if(_0x3f4573[_0x316f1b(_0x48c62f._0x782ae3)](_0x129500,undefined))continue;for(const _0xd6977 of _0x19f777){const _0x511b60=_0xad73a5['get'](_0xd6977);if(_0x3f4573['yqzco'](_0x511b60,undefined))continue;if(_0x129500===_0x511b60)continue;_0x150237[_0x316f1b(_0x48c62f._0x5f0b42)](_0x129500)[_0x316f1b(0x81)](_0x511b60),_0x11a6f3['get'](_0x511b60)[_0x316f1b(_0x48c62f._0x30b85b)](_0x129500);}}const _0x18090c=new Map(),_0x173547=new Map();for(const [_0x33d0af,_0x26d791]of _0x150237){_0x18090c['set'](_0x33d0af,[..._0x26d791]);}for(const [_0x341df3,_0x2a4830]of _0x11a6f3){_0x173547['set'](_0x341df3,[..._0x2a4830]);}const _0x526b9b={};_0x526b9b[_0x316f1b(_0x48c62f._0x1e7758)]=_0x24078d,_0x526b9b['forward']=_0x18090c,_0x526b9b[_0x316f1b(0x99)]=_0x173547,_0x526b9b['topologicalOrder']=[];const _0x1e7dba=_0x526b9b;return _0x1e7dba['topologicalOrder']=topologicalSort(_0x1e7dba),_0x1e7dba;}function topologicalSort(_0x2009bf){const _0x696dc1={_0x462818:0x86,_0x2254fd:0x85,_0x16e709:0x98,_0x1ca756:0x82,_0x3875d1:0x9e,_0x1b7806:0x88,_0x117676:0x8f,_0x2f36c6:0x9f,_0x93512a:0x8f},_0x2ad0b6=_0x1deb33,_0x125d6a={};_0x125d6a['jAjGU']=function(_0x1a8cf3,_0x249846){return _0x1a8cf3<_0x249846;},_0x125d6a['tcaVL']=function(_0x19c31e,_0x16afcb){return _0x19c31e+_0x16afcb;},_0x125d6a['cbaOg']=function(_0x1aaa85,_0xda676e){return _0x1aaa85>_0xda676e;},_0x125d6a['EcLOu']=function(_0x434b61,_0x56415b){return _0x434b61===_0x56415b;},_0x125d6a['CLyoO']=function(_0x432b39,_0x3964c7){return _0x432b39!==_0x3964c7;},_0x125d6a[_0x2ad0b6(_0x696dc1._0x462818)]=function(_0x4b246f,_0x5b7a47){return _0x4b246f<_0x5b7a47;};const _0x3660cc=_0x125d6a,_0x519379=_0x2009bf['nodes'][_0x2ad0b6(_0x696dc1._0x2254fd)];if(_0x519379===0x0)return[];const _0x4d31c5=new Map();for(let _0xe9e114=0x0;_0x3660cc[_0x2ad0b6(_0x696dc1._0x16e709)](_0xe9e114,_0x519379);_0xe9e114++){_0x4d31c5[_0x2ad0b6(_0x696dc1._0x1ca756)](_0xe9e114,0x0);}for(const [_0x23b7df,_0x2f3edb]of _0x2009bf['forward']){_0x4d31c5[_0x2ad0b6(_0x696dc1._0x1ca756)](_0x23b7df,_0x3660cc['tcaVL'](_0x4d31c5[_0x2ad0b6(0x89)](_0x23b7df)||0x0,_0x2f3edb[_0x2ad0b6(_0x696dc1._0x2254fd)]));}const _0x3d3032=[];for(const [_0x112d37,_0x4eaa90]of _0x4d31c5){_0x4eaa90===0x0&&_0x3d3032[_0x2ad0b6(0x8f)](_0x112d37);}const _0x537dfc=[];while(_0x3660cc[_0x2ad0b6(_0x696dc1._0x3875d1)](_0x3d3032['length'],0x0)){const _0x52b081=_0x3d3032[_0x2ad0b6(_0x696dc1._0x1b7806)]();_0x537dfc['push'](_0x52b081);const _0x371d77=_0x2009bf['reverse']['get'](_0x52b081)||[];for(const _0x2353e1 of _0x371d77){const _0x38cf44=(_0x4d31c5['get'](_0x2353e1)||0x0)-0x1;_0x4d31c5[_0x2ad0b6(0x82)](_0x2353e1,_0x38cf44),_0x3660cc['EcLOu'](_0x38cf44,0x0)&&_0x3d3032[_0x2ad0b6(_0x696dc1._0x117676)](_0x2353e1);}}if(_0x3660cc['CLyoO'](_0x537dfc['length'],_0x519379)){console['error'](_0x3660cc['tcaVL'](_0x2ad0b6(_0x696dc1._0x2f36c6)+_0x537dfc[_0x2ad0b6(0x85)]+'/'+_0x519379+'\x20nodes.\x20','This\x20indicates\x20a\x20bug\x20in\x20SCC\x20condensation.'));const _0x3ca79a=new Set(_0x537dfc);for(let _0x15590d=0x0;_0x3660cc['FdXdD'](_0x15590d,_0x519379);_0x15590d++){!_0x3ca79a['has'](_0x15590d)&&_0x537dfc[_0x2ad0b6(_0x696dc1._0x93512a)](_0x15590d);}}return _0x537dfc;}
|
package/dist/graph.js
CHANGED
|
@@ -1,137 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.buildGraph = buildGraph;
|
|
37
|
-
exports.getGraph = getGraph;
|
|
38
|
-
exports.rebuildGraph = rebuildGraph;
|
|
39
|
-
const path = __importStar(require("path"));
|
|
40
|
-
const plugin_1 = require("./languages/plugin");
|
|
41
|
-
const typescript_1 = require("./languages/typescript");
|
|
42
|
-
const scc_1 = require("./graph/scc");
|
|
43
|
-
const risk_scorer_1 = require("./scoring/risk-scorer");
|
|
44
|
-
const pagerank_1 = require("./scoring/pagerank");
|
|
45
|
-
const memo_cache_1 = require("./graph/memo-cache");
|
|
46
|
-
let cachedGraph = null;
|
|
47
|
-
function buildGraph(projectRoot, packageName, maxFiles) {
|
|
48
|
-
const detectedPlugins = (0, plugin_1.detectLanguages)(projectRoot);
|
|
49
|
-
const languages = detectedPlugins.map(p => p.id);
|
|
50
|
-
const forward = new Map();
|
|
51
|
-
const reverse = new Map();
|
|
52
|
-
const files = new Set();
|
|
53
|
-
const allSourceDirs = [];
|
|
54
|
-
let totalDiscovered = 0;
|
|
55
|
-
let fileLimitHit = false;
|
|
56
|
-
for (const plugin of detectedPlugins) {
|
|
57
|
-
const dirs = plugin.getSourceDirs(projectRoot);
|
|
58
|
-
console.error(`[syke:debug] ${plugin.id} getSourceDirs(${projectRoot}) => ${dirs.length} dirs: ${dirs.join(", ")}`);
|
|
59
|
-
for (const dir of dirs) {
|
|
60
|
-
if (!allSourceDirs.includes(dir))
|
|
61
|
-
allSourceDirs.push(dir);
|
|
62
|
-
const sourceFiles = plugin.discoverFiles(dir);
|
|
63
|
-
console.error(`[syke:debug] ${plugin.id} discoverFiles(${dir}) => ${sourceFiles.length} files`);
|
|
64
|
-
totalDiscovered += sourceFiles.length;
|
|
65
|
-
for (const f of sourceFiles) {
|
|
66
|
-
if (maxFiles && files.size >= maxFiles) {
|
|
67
|
-
fileLimitHit = true;
|
|
68
|
-
break;
|
|
69
|
-
}
|
|
70
|
-
files.add(f);
|
|
71
|
-
if (!forward.has(f))
|
|
72
|
-
forward.set(f, []);
|
|
73
|
-
}
|
|
74
|
-
for (const f of sourceFiles) {
|
|
75
|
-
if (!files.has(f))
|
|
76
|
-
continue;
|
|
77
|
-
const imports = plugin.parseImports(f, projectRoot, dir);
|
|
78
|
-
const validImports = [];
|
|
79
|
-
for (const imp of imports) {
|
|
80
|
-
if (!files.has(imp))
|
|
81
|
-
continue;
|
|
82
|
-
validImports.push(imp);
|
|
83
|
-
const rev = reverse.get(imp) || [];
|
|
84
|
-
rev.push(f);
|
|
85
|
-
reverse.set(imp, rev);
|
|
86
|
-
}
|
|
87
|
-
forward.set(f, validImports);
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
if (fileLimitHit) {
|
|
92
|
-
console.error(`[syke] Free tier: loaded ${files.size}/${totalDiscovered} files (limit: ${maxFiles}). Upgrade to Pro for unlimited.`);
|
|
93
|
-
}
|
|
94
|
-
const sourceDir = allSourceDirs[0] || path.join(projectRoot, "src");
|
|
95
|
-
const graph = {
|
|
96
|
-
forward,
|
|
97
|
-
reverse,
|
|
98
|
-
files,
|
|
99
|
-
projectRoot,
|
|
100
|
-
languages,
|
|
101
|
-
sourceDirs: allSourceDirs,
|
|
102
|
-
sourceDir,
|
|
103
|
-
};
|
|
104
|
-
// Invalidate memo cache (full rebuild means all cached BFS results are stale)
|
|
105
|
-
(0, memo_cache_1.resetMemoCache)();
|
|
106
|
-
// Compute SCC and attach to graph
|
|
107
|
-
const scc = (0, scc_1.computeSCC)(graph);
|
|
108
|
-
graph.scc = scc;
|
|
109
|
-
// Compute PageRank importance scores
|
|
110
|
-
(0, pagerank_1.invalidatePageRank)();
|
|
111
|
-
graph.pageRank = (0, pagerank_1.computePageRank)(graph);
|
|
112
|
-
const cyclicCount = scc.condensed.nodes.filter(n => n.isCyclic).length;
|
|
113
|
-
cachedGraph = graph;
|
|
114
|
-
console.error(`[syke] Graph built (${languages.join("+")}): ${files.size} files, ${countEdges(forward)} edges, ${scc.components.length} SCCs (${cyclicCount} cyclic)`);
|
|
115
|
-
return graph;
|
|
116
|
-
}
|
|
117
|
-
function countEdges(forward) {
|
|
118
|
-
let count = 0;
|
|
119
|
-
for (const deps of forward.values()) {
|
|
120
|
-
count += deps.length;
|
|
121
|
-
}
|
|
122
|
-
return count;
|
|
123
|
-
}
|
|
124
|
-
function getGraph(projectRoot, packageName, maxFiles) {
|
|
125
|
-
if (cachedGraph && cachedGraph.projectRoot === projectRoot) {
|
|
126
|
-
return cachedGraph;
|
|
127
|
-
}
|
|
128
|
-
return buildGraph(projectRoot, packageName, maxFiles);
|
|
129
|
-
}
|
|
130
|
-
function rebuildGraph(projectRoot, packageName, maxFiles) {
|
|
131
|
-
cachedGraph = null;
|
|
132
|
-
(0, typescript_1.clearAliasCache)();
|
|
133
|
-
(0, risk_scorer_1.invalidateProjectMetrics)();
|
|
134
|
-
(0, pagerank_1.invalidatePageRank)();
|
|
135
|
-
(0, memo_cache_1.resetMemoCache)();
|
|
136
|
-
return buildGraph(projectRoot, packageName, maxFiles);
|
|
137
|
-
}
|
|
1
|
+
'use strict';const _0x3b4bd9=_0x188c;(function(_0x2c0528,_0x41092b){const _0x2faf51={_0x694f3:0x98,_0x10b402:0xa8,_0x1dd178:0xd2,_0x3505b8:0x9a,_0x141d55:0xa5,_0x57ab82:0xb9},_0x5c5aae=_0x188c,_0x19cfcd=_0x2c0528();while(!![]){try{const _0x125e2d=parseInt(_0x5c5aae(_0x2faf51._0x694f3))/0x1*(parseInt(_0x5c5aae(0xcc))/0x2)+-parseInt(_0x5c5aae(_0x2faf51._0x10b402))/0x3+parseInt(_0x5c5aae(_0x2faf51._0x1dd178))/0x4*(parseInt(_0x5c5aae(_0x2faf51._0x3505b8))/0x5)+parseInt(_0x5c5aae(0xd0))/0x6*(-parseInt(_0x5c5aae(_0x2faf51._0x141d55))/0x7)+-parseInt(_0x5c5aae(_0x2faf51._0x57ab82))/0x8+-parseInt(_0x5c5aae(0xd6))/0x9*(parseInt(_0x5c5aae(0x9b))/0xa)+parseInt(_0x5c5aae(0xaf))/0xb;if(_0x125e2d===_0x41092b)break;else _0x19cfcd['push'](_0x19cfcd['shift']());}catch(_0x404de9){_0x19cfcd['push'](_0x19cfcd['shift']());}}}(_0x43fb,0x4e7fe));var __createBinding=this&&this[_0x3b4bd9(0xac)]||(Object[_0x3b4bd9(0xc8)]?function(_0xbd017b,_0x396cd1,_0x197628,_0x33d19a){const _0x35637b={_0x341761:0x96,_0xa9d995:0xd9,_0x4a65a6:0xbe},_0x54a12e=_0x3b4bd9,_0x45542a={};_0x45542a['FUHUE']=function(_0x25da74,_0x60eec1){return _0x25da74===_0x60eec1;};const _0x330f84=_0x45542a;if(_0x330f84['FUHUE'](_0x33d19a,undefined))_0x33d19a=_0x197628;var _0xdc8187=Object[_0x54a12e(_0x35637b._0x341761)](_0x396cd1,_0x197628);if(!_0xdc8187||('get'in _0xdc8187?!_0x396cd1['__esModule']:_0xdc8187[_0x54a12e(_0x35637b._0xa9d995)]||_0xdc8187[_0x54a12e(0x9d)])){const _0x243e89={};_0x243e89['enumerable']=!![],_0x243e89[_0x54a12e(0xb0)]=function(){return _0x396cd1[_0x197628];},_0xdc8187=_0x243e89;}Object[_0x54a12e(_0x35637b._0x4a65a6)](_0xbd017b,_0x33d19a,_0xdc8187);}:function(_0x1d5923,_0x567314,_0x55cb21,_0x31fd43){if(_0x31fd43===undefined)_0x31fd43=_0x55cb21;_0x1d5923[_0x31fd43]=_0x567314[_0x55cb21];}),__setModuleDefault=this&&this['__setModuleDefault']||(Object['create']?function(_0x47077f,_0x3848d7){const _0x38447d=_0x3b4bd9,_0x38d209={};_0x38d209[_0x38447d(0xa2)]=!![],_0x38d209[_0x38447d(0xcb)]=_0x3848d7,Object['defineProperty'](_0x47077f,'default',_0x38d209);}:function(_0x2509d1,_0x23d73c){const _0x54041e=_0x3b4bd9,_0x368922={};_0x368922[_0x54041e(0x97)]=_0x54041e(0x9c);const _0x7db487=_0x368922;_0x2509d1[_0x7db487['xUvLY']]=_0x23d73c;}),__importStar=this&&this[_0x3b4bd9(0xc9)]||(function(){const _0x367625={_0x33e383:0xa7,_0x1e647a:0xd1,_0x181f6d:0xb3},_0x57e01d={_0x5419ce:0xbc},_0x29df7f=_0x3b4bd9,_0x5c3247={'vUJFM':_0x29df7f(0xb5),'bZANs':function(_0x334013,_0x122ebe){return _0x334013!=_0x122ebe;},'LqtVk':function(_0x4a9616,_0x1ad3b9){return _0x4a9616(_0x1ad3b9);},'VHWSb':function(_0xe0561,_0x589f26){return _0xe0561<_0x589f26;},'uczbg':function(_0x3ffe33,_0x9c9108){return _0x3ffe33!==_0x9c9108;},'GEftR':function(_0x1aa4f0,_0x4de556,_0x45d0dc,_0x21055b){return _0x1aa4f0(_0x4de556,_0x45d0dc,_0x21055b);},'dxmLQ':function(_0x44bb3f,_0x212cb5,_0x580ea3){return _0x44bb3f(_0x212cb5,_0x580ea3);}};var _0x342378=function(_0x4f5979){const _0x2dc709=_0x29df7f;return _0x342378=Object[_0x2dc709(0x9e)]||function(_0x4136cd){const _0x54dd61=_0x2dc709;var _0x426630=[];for(var _0x13ebd1 in _0x4136cd)if(Object[_0x54dd61(_0x57e01d._0x5419ce)]['hasOwnProperty']['call'](_0x4136cd,_0x13ebd1))_0x426630[_0x426630['length']]=_0x13ebd1;return _0x426630;},_0x342378(_0x4f5979);};return function(_0x35268d){const _0x46f65c=_0x29df7f,_0x72afe4=_0x5c3247[_0x46f65c(0xca)]['split']('|');let _0x4ee77d=0x0;while(!![]){switch(_0x72afe4[_0x4ee77d++]){case'0':if(_0x5c3247[_0x46f65c(_0x367625._0x33e383)](_0x35268d,null)){for(var _0x4f9154=_0x5c3247['LqtVk'](_0x342378,_0x35268d),_0x41394a=0x0;_0x5c3247[_0x46f65c(_0x367625._0x1e647a)](_0x41394a,_0x4f9154['length']);_0x41394a++)if(_0x5c3247[_0x46f65c(_0x367625._0x181f6d)](_0x4f9154[_0x41394a],_0x46f65c(0x9c)))_0x5c3247[_0x46f65c(0xc3)](__createBinding,_0x2c1bca,_0x35268d,_0x4f9154[_0x41394a]);}continue;case'1':var _0x2c1bca={};continue;case'2':return _0x2c1bca;case'3':_0x5c3247['dxmLQ'](__setModuleDefault,_0x2c1bca,_0x35268d);continue;case'4':if(_0x35268d&&_0x35268d['__esModule'])return _0x35268d;continue;}break;}};}());const _0x475210={};_0x475210['value']=!![],Object[_0x3b4bd9(0xbe)](exports,_0x3b4bd9(0xd7),_0x475210),exports['buildGraph']=buildGraph,exports[_0x3b4bd9(0x9f)]=getGraph,exports[_0x3b4bd9(0xcd)]=rebuildGraph;const path=__importStar(require(_0x3b4bd9(0xd5))),plugin_1=require(_0x3b4bd9(0xb6)),typescript_1=require('./languages/typescript'),scc_1=require(_0x3b4bd9(0xae)),risk_scorer_1=require('./scoring/risk-scorer'),pagerank_1=require(_0x3b4bd9(0xbd)),memo_cache_1=require(_0x3b4bd9(0xd3));let cachedGraph=null;function buildGraph(_0x58ff0e,_0x33b409,_0xd70d6){const _0x2ca28d={_0x5f5a7c:0xd4,_0xeb9a4a:0xa4,_0x8aea80:0xb4,_0x264f02:0xce,_0xe0ebf8:0xab,_0x23641d:0xad,_0x5f57ea:0xba,_0x2d9e07:0xb2,_0x55c462:0xdc,_0x2df3ef:0xc0,_0x515e03:0xa9,_0x46ee78:0xc7,_0x26b219:0xb8,_0x49f165:0xcf,_0x20d01a:0xdb,_0xc5b9f6:0xc6,_0xbe74a3:0x99,_0x4f72a1:0xc1,_0x711d66:0xa3},_0x3b03b0=_0x3b4bd9,_0x33fc88=(0x0,plugin_1[_0x3b03b0(0xd8)])(_0x58ff0e),_0x30f5b8=_0x33fc88[_0x3b03b0(0xc4)](_0x1cd9e8=>_0x1cd9e8['id']),_0x553d5a=new Map(),_0x376905=new Map(),_0x2eb1e4=new Set(),_0xfb86e6=[];let _0x28c179=0x0,_0x40533b=![];for(const _0x3127de of _0x33fc88){const _0x2a5eab=_0x3127de['getSourceDirs'](_0x58ff0e);console['error'](_0x3b03b0(_0x2ca28d._0x5f5a7c)+_0x3127de['id']+_0x3b03b0(0xc2)+_0x58ff0e+')\x20=>\x20'+_0x2a5eab[_0x3b03b0(0xad)]+_0x3b03b0(_0x2ca28d._0xeb9a4a)+_0x2a5eab[_0x3b03b0(_0x2ca28d._0x8aea80)](',\x20'));for(const _0x139438 of _0x2a5eab){if(!_0xfb86e6['includes'](_0x139438))_0xfb86e6[_0x3b03b0(_0x2ca28d._0x264f02)](_0x139438);const _0x35935d=_0x3127de['discoverFiles'](_0x139438);console[_0x3b03b0(0xb1)](_0x3b03b0(0xd4)+_0x3127de['id']+_0x3b03b0(_0x2ca28d._0xe0ebf8)+_0x139438+')\x20=>\x20'+_0x35935d[_0x3b03b0(_0x2ca28d._0x23641d)]+_0x3b03b0(_0x2ca28d._0x5f57ea)),_0x28c179+=_0x35935d[_0x3b03b0(0xad)];for(const _0x555a09 of _0x35935d){if(_0xd70d6&&_0x2eb1e4[_0x3b03b0(_0x2ca28d._0x2d9e07)]>=_0xd70d6){_0x40533b=!![];break;}_0x2eb1e4['add'](_0x555a09);if(!_0x553d5a['has'](_0x555a09))_0x553d5a[_0x3b03b0(_0x2ca28d._0x55c462)](_0x555a09,[]);}for(const _0x571587 of _0x35935d){if(!_0x2eb1e4['has'](_0x571587))continue;const _0x11e6b2=_0x3127de['parseImports'](_0x571587,_0x58ff0e,_0x139438),_0x4b0a22=[];for(const _0x5a30b2 of _0x11e6b2){if(!_0x2eb1e4[_0x3b03b0(0xc5)](_0x5a30b2))continue;_0x4b0a22['push'](_0x5a30b2);const _0x4f3915=_0x376905['get'](_0x5a30b2)||[];_0x4f3915['push'](_0x571587),_0x376905['set'](_0x5a30b2,_0x4f3915);}_0x553d5a[_0x3b03b0(_0x2ca28d._0x55c462)](_0x571587,_0x4b0a22);}}}_0x40533b&&console['error'](_0x3b03b0(_0x2ca28d._0x2df3ef)+_0x2eb1e4['size']+'/'+_0x28c179+'\x20files\x20(limit:\x20'+_0xd70d6+').\x20Upgrade\x20to\x20Pro\x20for\x20unlimited.');const _0x5f1e2d=_0xfb86e6[0x0]||path['join'](_0x58ff0e,'src'),_0xee3770={};_0xee3770[_0x3b03b0(_0x2ca28d._0x515e03)]=_0x553d5a,_0xee3770['reverse']=_0x376905,_0xee3770[_0x3b03b0(0xa1)]=_0x2eb1e4,_0xee3770[_0x3b03b0(0xa0)]=_0x58ff0e,_0xee3770[_0x3b03b0(_0x2ca28d._0x46ee78)]=_0x30f5b8,_0xee3770[_0x3b03b0(0xaa)]=_0xfb86e6,_0xee3770[_0x3b03b0(0xbb)]=_0x5f1e2d;const _0x42ce74=_0xee3770;(0x0,memo_cache_1['resetMemoCache'])();const _0x1cca7e=(0x0,scc_1[_0x3b03b0(_0x2ca28d._0x26b219)])(_0x42ce74);_0x42ce74[_0x3b03b0(_0x2ca28d._0x49f165)]=_0x1cca7e,(0x0,pagerank_1['invalidatePageRank'])(),_0x42ce74[_0x3b03b0(_0x2ca28d._0x20d01a)]=(0x0,pagerank_1['computePageRank'])(_0x42ce74);const _0x1c52a9=_0x1cca7e[_0x3b03b0(0xbf)][_0x3b03b0(_0x2ca28d._0xc5b9f6)][_0x3b03b0(_0x2ca28d._0xbe74a3)](_0x2de8c4=>_0x2de8c4['isCyclic'])['length'];return cachedGraph=_0x42ce74,console[_0x3b03b0(0xb1)]('[syke]\x20Graph\x20built\x20('+_0x30f5b8['join']('+')+'):\x20'+_0x2eb1e4['size']+_0x3b03b0(0xda)+countEdges(_0x553d5a)+_0x3b03b0(_0x2ca28d._0x4f72a1)+_0x1cca7e['components']['length']+_0x3b03b0(0xb7)+_0x1c52a9+_0x3b03b0(_0x2ca28d._0x711d66)),_0x42ce74;}function countEdges(_0x1e96df){const _0x330607=_0x3b4bd9;let _0x455619=0x0;for(const _0x55f5b2 of _0x1e96df['values']()){_0x455619+=_0x55f5b2[_0x330607(0xad)];}return _0x455619;}function getGraph(_0x3e3ce3,_0x1c39bd,_0x43b75f){if(cachedGraph&&cachedGraph['projectRoot']===_0x3e3ce3)return cachedGraph;return buildGraph(_0x3e3ce3,_0x1c39bd,_0x43b75f);}function _0x188c(_0x129ae3,_0x31be1b){_0x129ae3=_0x129ae3-0x96;const _0x43fbdd=_0x43fb();let _0x188c84=_0x43fbdd[_0x129ae3];if(_0x188c['FFNybA']===undefined){var _0x540bfc=function(_0x46c724){const _0x1b4d7a='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x5a92bc='',_0x1f6dcc='';for(let _0x444bde=0x0,_0xcced06,_0x3d7a13,_0xb2f484=0x0;_0x3d7a13=_0x46c724['charAt'](_0xb2f484++);~_0x3d7a13&&(_0xcced06=_0x444bde%0x4?_0xcced06*0x40+_0x3d7a13:_0x3d7a13,_0x444bde++%0x4)?_0x5a92bc+=String['fromCharCode'](0xff&_0xcced06>>(-0x2*_0x444bde&0x6)):0x0){_0x3d7a13=_0x1b4d7a['indexOf'](_0x3d7a13);}for(let _0x3a3e1a=0x0,_0x19620b=_0x5a92bc['length'];_0x3a3e1a<_0x19620b;_0x3a3e1a++){_0x1f6dcc+='%'+('00'+_0x5a92bc['charCodeAt'](_0x3a3e1a)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x1f6dcc);};_0x188c['vZFfEH']=_0x540bfc,_0x188c['BxQLpo']={},_0x188c['FFNybA']=!![];}const _0x245119=_0x43fbdd[0x0],_0x5e2e20=_0x129ae3+_0x245119,_0x1dfbee=_0x188c['BxQLpo'][_0x5e2e20];return!_0x1dfbee?(_0x188c84=_0x188c['vZFfEH'](_0x188c84),_0x188c['BxQLpo'][_0x5e2e20]=_0x188c84):_0x188c84=_0x1dfbee,_0x188c84;}function rebuildGraph(_0x4336ab,_0x6f0263,_0x2f7cf3){const _0x457259=_0x3b4bd9;return cachedGraph=null,(0x0,typescript_1['clearAliasCache'])(),(0x0,risk_scorer_1['invalidateProjectMetrics'])(),(0x0,pagerank_1['invalidatePageRank'])(),(0x0,memo_cache_1[_0x457259(0xa6)])(),buildGraph(_0x4336ab,_0x6f0263,_0x2f7cf3);}function _0x43fb(){const _0x3ed616=['zM9YD2fYza','C291CMnLrgLYCW','igrPC2nVDMvYrMLSzxmO','x19JCMvHDgvcAw5KAw5N','BgvUz3rO','lI9NCMfWAc9Zy2m','mta0mdi2mJnHAKzjsLK','z2v0','zxjYB3i','C2L6zq','Dwn6yMC','AM9PBG','nhWXFdb8m3WY','lI9Syw5NDwfNzxmVCgX1z2LU','ifndq3mGka','y29TChv0zvndqW','mZq1nZa0A1zKs1zR','igzPBgvZ','C291CMnLrgLY','ChjVDg90ExbL','lI9Zy29YAw5Nl3bHz2vYyw5R','zgvMAw5LuhjVCgvYDhK','y29UzgvUC2vK','w3n5A2vDiezYzwuGDgLLCJOGBg9HzgvKia','igvKz2vZlca','igDLDfnVDxjJzurPCNmO','r0vMDfi','BwfW','AgfZ','BM9Kzxm','BgfUz3vHz2vZ','y3jLyxrL','x19PBxbVCNrtDgfY','DLvkrK0','DMfSDwu','mtbZDhDkvMu','CMvIDwLSzeDYyxbO','ChvZAa','C2nJ','mZzdq1nADxu','vKHxu2i','ntCXndH2C2zsDLO','lI9NCMfWAc9Tzw1VlwnHy2HL','w3n5A2u6zgvIDwDDia','Cgf0Aa','ntm1mdCWn0LJDNzcta','x19LC01VzhvSzq','zgv0zwn0tgfUz3vHz2vZ','D3jPDgfIBgu','igzPBgvZlca','CgfNzvjHBMS','C2v0','z2v0t3DUuhjVCgvYDhLezxnJCMLWDg9Y','Efv2tfK','otC0mtvVCwf2D3y','zMLSDgvY','mta1BwrtEwrl','mtbPDujAsuq','zgvMyxvSDa','y29UzMLNDxjHyMXL','z2v0t3DUuhjVCgvYDhLoyw1LCW','z2v0r3jHCgG','ChjVAMvJDfjVB3q','zMLSzxm','zw51BwvYywjSzq','ign5y2XPyYK','igrPCNm6ia','mZuXodi3u3ndC3vs','CMvZzxrnzw1Vq2fJAgu','yLPbtNm','mtqXntG3n2zPq3LIqG'];_0x43fb=function(){return _0x3ed616;};return _0x43fb();}
|