@ui-entropy/scanner-core 0.1.2 → 0.2.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.
- package/README.md +8 -10
- package/dist/analyzers/css-waste.d.ts +36 -0
- package/dist/analyzers/css-waste.d.ts.map +1 -0
- package/dist/analyzers/css-waste.js +116 -0
- package/dist/analyzers/duplication.d.ts +29 -0
- package/dist/analyzers/duplication.d.ts.map +1 -0
- package/dist/analyzers/duplication.js +44 -0
- package/dist/analyzers/entropy-engine.d.ts +19 -0
- package/dist/analyzers/entropy-engine.d.ts.map +1 -0
- package/dist/analyzers/entropy-engine.js +48 -0
- package/dist/analyzers/index.d.ts +17 -0
- package/dist/analyzers/index.d.ts.map +1 -0
- package/dist/analyzers/index.js +24 -0
- package/dist/analyzers/types.d.ts +62 -0
- package/dist/analyzers/types.d.ts.map +1 -0
- package/dist/analyzers/types.js +11 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -1
- package/dist/scan.d.ts +8 -0
- package/dist/scan.d.ts.map +1 -1
- package/dist/scan.js +11 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -28,7 +28,13 @@ npm install @ui-entropy/scanner-core
|
|
|
28
28
|
|
|
29
29
|
**For CLI usage**, install the main package instead:
|
|
30
30
|
```bash
|
|
31
|
-
npm install -g ui-entropy
|
|
31
|
+
npm install -g @ui-entropy/cli
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
The CLI includes smart project initialization:
|
|
35
|
+
```bash
|
|
36
|
+
npx @ui-entropy/cli init # Auto-detects your framework
|
|
37
|
+
npx @ui-entropy/cli scan # Scan with generated config
|
|
32
38
|
```
|
|
33
39
|
|
|
34
40
|
## 🔧 Quick Start
|
|
@@ -97,15 +103,7 @@ Find all class/ID usage across source files.
|
|
|
97
103
|
|
|
98
104
|
Calculate waste metrics and identify unused selectors.
|
|
99
105
|
|
|
100
|
-
##
|
|
101
|
-
|
|
102
|
-
| Project | CSS Size | Waste % | Unused Selectors |
|
|
103
|
-
|---------|----------|---------|------------------|
|
|
104
|
-
| build-and-bloom | 45 KB | 72% | 129 selectors |
|
|
105
|
-
| Portfolio Site | 180 KB | 91% | 1,024 selectors |
|
|
106
|
-
| React Dashboard | 89 KB | 38% | 412 selectors |
|
|
107
|
-
|
|
108
|
-
## 🔗 Related Packages
|
|
106
|
+
## Related Packages
|
|
109
107
|
|
|
110
108
|
- **[ui-entropy](https://npmjs.com/package/ui-entropy)** - CLI tool for terminal usage
|
|
111
109
|
- **UI Entropy Dashboard** _(coming soon)_ - Team analytics and historical tracking
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CSS Waste Analyzer
|
|
3
|
+
*
|
|
4
|
+
* Analyzes unused CSS selectors and calculates waste percentage.
|
|
5
|
+
* This is the primary analyzer for v0.1-v0.2 of UI Entropy.
|
|
6
|
+
*/
|
|
7
|
+
import type { Analyzer, AnalyzerContext, AnalyzerResult } from './types.js';
|
|
8
|
+
export interface CSSWasteMetrics {
|
|
9
|
+
totalClasses: number;
|
|
10
|
+
totalIds: number;
|
|
11
|
+
usedClasses: number;
|
|
12
|
+
usedIds: number;
|
|
13
|
+
unusedClasses: string[];
|
|
14
|
+
unusedIds: string[];
|
|
15
|
+
wastePercentage: number;
|
|
16
|
+
totalCssBytes: number;
|
|
17
|
+
wastedBytes: number;
|
|
18
|
+
totalRules: number;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* CSS Waste Analyzer
|
|
22
|
+
*
|
|
23
|
+
* Calculates entropy based on unused CSS selectors.
|
|
24
|
+
* Score = wastePercentage (0-100)
|
|
25
|
+
*/
|
|
26
|
+
export declare class CSSWasteAnalyzer implements Analyzer {
|
|
27
|
+
name: string;
|
|
28
|
+
weight: number;
|
|
29
|
+
analyze(context: AnalyzerContext): AnalyzerResult;
|
|
30
|
+
private generateRecommendations;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Factory function for creating CSS Waste analyzer
|
|
34
|
+
*/
|
|
35
|
+
export declare function cssWasteAnalyzer(): CSSWasteAnalyzer;
|
|
36
|
+
//# sourceMappingURL=css-waste.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"css-waste.d.ts","sourceRoot":"","sources":["../../src/analyzers/css-waste.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE5E,MAAM,WAAW,eAAe;IAC9B,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;;GAKG;AACH,qBAAa,gBAAiB,YAAW,QAAQ;IAC/C,IAAI,SAAe;IACnB,MAAM,SAAO;IAEb,OAAO,CAAC,OAAO,EAAE,eAAe,GAAG,cAAc;IAiEjD,OAAO,CAAC,uBAAuB;CAgChC;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,gBAAgB,CAEnD"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CSS Waste Analyzer
|
|
3
|
+
*
|
|
4
|
+
* Analyzes unused CSS selectors and calculates waste percentage.
|
|
5
|
+
* This is the primary analyzer for v0.1-v0.2 of UI Entropy.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* CSS Waste Analyzer
|
|
9
|
+
*
|
|
10
|
+
* Calculates entropy based on unused CSS selectors.
|
|
11
|
+
* Score = wastePercentage (0-100)
|
|
12
|
+
*/
|
|
13
|
+
export class CSSWasteAnalyzer {
|
|
14
|
+
name = 'CSS Waste';
|
|
15
|
+
weight = 0.6; // 60% of overall entropy score
|
|
16
|
+
analyze(context) {
|
|
17
|
+
const { selectors, usage } = context;
|
|
18
|
+
// Find unused selectors
|
|
19
|
+
const unusedClasses = [];
|
|
20
|
+
const unusedIds = [];
|
|
21
|
+
let usedClassCount = 0;
|
|
22
|
+
let usedIdCount = 0;
|
|
23
|
+
// Check which classes are unused
|
|
24
|
+
for (const className of selectors.classes) {
|
|
25
|
+
if (usage.classes.has(className)) {
|
|
26
|
+
usedClassCount++;
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
unusedClasses.push(className);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
// Check which IDs are unused
|
|
33
|
+
for (const idName of selectors.ids) {
|
|
34
|
+
if (usage.ids.has(idName)) {
|
|
35
|
+
usedIdCount++;
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
unusedIds.push(idName);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
// Calculate waste percentage
|
|
42
|
+
const totalSelectors = selectors.classes.size + selectors.ids.size;
|
|
43
|
+
const usedSelectors = usedClassCount + usedIdCount;
|
|
44
|
+
const unusedSelectors = totalSelectors - usedSelectors;
|
|
45
|
+
const wastePercentage = totalSelectors > 0
|
|
46
|
+
? Math.round((unusedSelectors / totalSelectors) * 100)
|
|
47
|
+
: 0;
|
|
48
|
+
// Estimate wasted bytes (proportional to unused selectors)
|
|
49
|
+
const wastedBytes = Math.round((selectors.totalBytes * wastePercentage) / 100);
|
|
50
|
+
// Build metrics
|
|
51
|
+
const metrics = {
|
|
52
|
+
totalClasses: selectors.classes.size,
|
|
53
|
+
totalIds: selectors.ids.size,
|
|
54
|
+
usedClasses: usedClassCount,
|
|
55
|
+
usedIds: usedIdCount,
|
|
56
|
+
unusedClasses,
|
|
57
|
+
unusedIds,
|
|
58
|
+
wastePercentage,
|
|
59
|
+
totalCssBytes: selectors.totalBytes,
|
|
60
|
+
wastedBytes,
|
|
61
|
+
totalRules: selectors.totalRules,
|
|
62
|
+
};
|
|
63
|
+
// Generate recommendations
|
|
64
|
+
const recommendations = this.generateRecommendations(wastePercentage);
|
|
65
|
+
return {
|
|
66
|
+
name: this.name,
|
|
67
|
+
score: wastePercentage, // Waste % maps directly to entropy score
|
|
68
|
+
weight: this.weight,
|
|
69
|
+
metrics,
|
|
70
|
+
recommendations,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
generateRecommendations(wastePercentage) {
|
|
74
|
+
if (wastePercentage < 10) {
|
|
75
|
+
return [
|
|
76
|
+
'Excellent! Your CSS is highly optimized.',
|
|
77
|
+
'Continue monitoring to maintain low waste.',
|
|
78
|
+
];
|
|
79
|
+
}
|
|
80
|
+
else if (wastePercentage < 30) {
|
|
81
|
+
return [
|
|
82
|
+
'Good CSS hygiene. Minor cleanup opportunities exist.',
|
|
83
|
+
'Review unused classes for removal.',
|
|
84
|
+
];
|
|
85
|
+
}
|
|
86
|
+
else if (wastePercentage < 50) {
|
|
87
|
+
return [
|
|
88
|
+
'Moderate waste detected.',
|
|
89
|
+
'Consider removing unused framework imports.',
|
|
90
|
+
'Review component-specific stylesheets.',
|
|
91
|
+
];
|
|
92
|
+
}
|
|
93
|
+
else if (wastePercentage < 75) {
|
|
94
|
+
return [
|
|
95
|
+
'High waste detected.',
|
|
96
|
+
'Use PurgeCSS or Tailwind JIT to eliminate unused styles.',
|
|
97
|
+
'Avoid importing full CSS frameworks.',
|
|
98
|
+
];
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
return [
|
|
102
|
+
'Critical waste: Significant cleanup needed.',
|
|
103
|
+
'Enable Tailwind JIT or PurgeCSS immediately.',
|
|
104
|
+
'Remove unused CSS framework files.',
|
|
105
|
+
'Consider switching to a utility-first approach.',
|
|
106
|
+
];
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Factory function for creating CSS Waste analyzer
|
|
112
|
+
*/
|
|
113
|
+
export function cssWasteAnalyzer() {
|
|
114
|
+
return new CSSWasteAnalyzer();
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=css-waste.js.map
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Duplication Analyzer (Placeholder for v0.3+)
|
|
3
|
+
*
|
|
4
|
+
* Analyzes CSS selector duplication and similar styles.
|
|
5
|
+
* Currently returns score of 0 (no duplication detected).
|
|
6
|
+
*/
|
|
7
|
+
import type { Analyzer, AnalyzerContext, AnalyzerResult } from './types.js';
|
|
8
|
+
export interface DuplicationMetrics {
|
|
9
|
+
duplicateSelectors: number;
|
|
10
|
+
similarRules: number;
|
|
11
|
+
duplicationPercentage: number;
|
|
12
|
+
potentialSavings: number;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Duplication Analyzer (v0.3+ feature)
|
|
16
|
+
*
|
|
17
|
+
* Detects duplicate selectors and similar CSS rules.
|
|
18
|
+
* Currently a placeholder that returns 0.
|
|
19
|
+
*/
|
|
20
|
+
export declare class DuplicationAnalyzer implements Analyzer {
|
|
21
|
+
name: string;
|
|
22
|
+
weight: number;
|
|
23
|
+
analyze(_context: AnalyzerContext): AnalyzerResult;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Factory function for creating Duplication analyzer
|
|
27
|
+
*/
|
|
28
|
+
export declare function duplicationAnalyzer(): DuplicationAnalyzer;
|
|
29
|
+
//# sourceMappingURL=duplication.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"duplication.d.ts","sourceRoot":"","sources":["../../src/analyzers/duplication.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE5E,MAAM,WAAW,kBAAkB;IACjC,kBAAkB,EAAE,MAAM,CAAC;IAC3B,YAAY,EAAE,MAAM,CAAC;IACrB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED;;;;;GAKG;AACH,qBAAa,mBAAoB,YAAW,QAAQ;IAClD,IAAI,SAAiB;IACrB,MAAM,SAAO;IAEb,OAAO,CAAC,QAAQ,EAAE,eAAe,GAAG,cAAc;CAuBnD;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,mBAAmB,CAEzD"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Duplication Analyzer (Placeholder for v0.3+)
|
|
3
|
+
*
|
|
4
|
+
* Analyzes CSS selector duplication and similar styles.
|
|
5
|
+
* Currently returns score of 0 (no duplication detected).
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Duplication Analyzer (v0.3+ feature)
|
|
9
|
+
*
|
|
10
|
+
* Detects duplicate selectors and similar CSS rules.
|
|
11
|
+
* Currently a placeholder that returns 0.
|
|
12
|
+
*/
|
|
13
|
+
export class DuplicationAnalyzer {
|
|
14
|
+
name = 'Duplication';
|
|
15
|
+
weight = 0.4; // 40% of overall entropy score
|
|
16
|
+
analyze(_context) {
|
|
17
|
+
// TODO: Implement duplication detection in v0.3+
|
|
18
|
+
// - Find duplicate selectors
|
|
19
|
+
// - Detect similar CSS rules (same properties, different selectors)
|
|
20
|
+
// - Calculate consolidation opportunities
|
|
21
|
+
const metrics = {
|
|
22
|
+
duplicateSelectors: 0,
|
|
23
|
+
similarRules: 0,
|
|
24
|
+
duplicationPercentage: 0,
|
|
25
|
+
potentialSavings: 0,
|
|
26
|
+
};
|
|
27
|
+
return {
|
|
28
|
+
name: this.name,
|
|
29
|
+
score: 0, // Placeholder: no duplication detected
|
|
30
|
+
weight: this.weight,
|
|
31
|
+
metrics,
|
|
32
|
+
recommendations: [
|
|
33
|
+
'Duplication analysis coming in v0.3',
|
|
34
|
+
],
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Factory function for creating Duplication analyzer
|
|
40
|
+
*/
|
|
41
|
+
export function duplicationAnalyzer() {
|
|
42
|
+
return new DuplicationAnalyzer();
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=duplication.js.map
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Entropy Score Engine
|
|
3
|
+
*
|
|
4
|
+
* Combines multiple analyzers to calculate overall UI Entropy score.
|
|
5
|
+
*/
|
|
6
|
+
import type { Analyzer, AnalyzerContext, EntropyScore } from './types.js';
|
|
7
|
+
/**
|
|
8
|
+
* Calculate overall entropy score from multiple analyzers
|
|
9
|
+
*
|
|
10
|
+
* Formula:
|
|
11
|
+
* UI Entropy Score = Σ(analyzer.score × analyzer.weight)
|
|
12
|
+
*
|
|
13
|
+
* Example (v0.1):
|
|
14
|
+
* = (CSS Waste Score × 0.6) + (Duplication Score × 0.4)
|
|
15
|
+
* = (75 × 0.6) + (0 × 0.4)
|
|
16
|
+
* = 45
|
|
17
|
+
*/
|
|
18
|
+
export declare function calculateEntropyScore(context: AnalyzerContext, analyzers: Analyzer[]): EntropyScore;
|
|
19
|
+
//# sourceMappingURL=entropy-engine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entropy-engine.d.ts","sourceRoot":"","sources":["../../src/analyzers/entropy-engine.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,eAAe,EAAkB,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1F;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,eAAe,EACxB,SAAS,EAAE,QAAQ,EAAE,GACpB,YAAY,CA2Bd"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Entropy Score Engine
|
|
3
|
+
*
|
|
4
|
+
* Combines multiple analyzers to calculate overall UI Entropy score.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Calculate overall entropy score from multiple analyzers
|
|
8
|
+
*
|
|
9
|
+
* Formula:
|
|
10
|
+
* UI Entropy Score = Σ(analyzer.score × analyzer.weight)
|
|
11
|
+
*
|
|
12
|
+
* Example (v0.1):
|
|
13
|
+
* = (CSS Waste Score × 0.6) + (Duplication Score × 0.4)
|
|
14
|
+
* = (75 × 0.6) + (0 × 0.4)
|
|
15
|
+
* = 45
|
|
16
|
+
*/
|
|
17
|
+
export function calculateEntropyScore(context, analyzers) {
|
|
18
|
+
// Run all analyzers
|
|
19
|
+
const results = analyzers.map(analyzer => analyzer.analyze(context));
|
|
20
|
+
// Normalize weights to sum to 1.0
|
|
21
|
+
const totalWeight = results.reduce((sum, r) => sum + r.weight, 0);
|
|
22
|
+
const normalizedResults = results.map(r => ({
|
|
23
|
+
...r,
|
|
24
|
+
weight: r.weight / totalWeight,
|
|
25
|
+
}));
|
|
26
|
+
// Calculate weighted average
|
|
27
|
+
const overallScore = normalizedResults.reduce((sum, result) => sum + (result.score * result.weight), 0);
|
|
28
|
+
// Determine severity
|
|
29
|
+
const severity = getSeverityLevel(overallScore);
|
|
30
|
+
return {
|
|
31
|
+
overallScore: Math.round(overallScore),
|
|
32
|
+
analyzers: normalizedResults,
|
|
33
|
+
severity,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Map entropy score to severity level
|
|
38
|
+
*/
|
|
39
|
+
function getSeverityLevel(score) {
|
|
40
|
+
if (score < 20)
|
|
41
|
+
return 'low';
|
|
42
|
+
if (score < 50)
|
|
43
|
+
return 'medium';
|
|
44
|
+
if (score < 75)
|
|
45
|
+
return 'high';
|
|
46
|
+
return 'critical';
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=entropy-engine.js.map
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Analyzer System Exports
|
|
3
|
+
*/
|
|
4
|
+
export * from './types.js';
|
|
5
|
+
export * from './css-waste.js';
|
|
6
|
+
export * from './duplication.js';
|
|
7
|
+
export * from './entropy-engine.js';
|
|
8
|
+
import type { Analyzer } from './types.js';
|
|
9
|
+
/**
|
|
10
|
+
* Default analyzer configuration for v0.1
|
|
11
|
+
*
|
|
12
|
+
* Weights:
|
|
13
|
+
* - CSS Waste: 60%
|
|
14
|
+
* - Duplication: 40% (placeholder, returns 0)
|
|
15
|
+
*/
|
|
16
|
+
export declare function getDefaultAnalyzers(): Analyzer[];
|
|
17
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/analyzers/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AAKpC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C;;;;;;GAMG;AACH,wBAAgB,mBAAmB,IAAI,QAAQ,EAAE,CAKhD"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Analyzer System Exports
|
|
3
|
+
*/
|
|
4
|
+
export * from './types.js';
|
|
5
|
+
export * from './css-waste.js';
|
|
6
|
+
export * from './duplication.js';
|
|
7
|
+
export * from './entropy-engine.js';
|
|
8
|
+
// Default analyzer set for v0.1
|
|
9
|
+
import { cssWasteAnalyzer } from './css-waste.js';
|
|
10
|
+
import { duplicationAnalyzer } from './duplication.js';
|
|
11
|
+
/**
|
|
12
|
+
* Default analyzer configuration for v0.1
|
|
13
|
+
*
|
|
14
|
+
* Weights:
|
|
15
|
+
* - CSS Waste: 60%
|
|
16
|
+
* - Duplication: 40% (placeholder, returns 0)
|
|
17
|
+
*/
|
|
18
|
+
export function getDefaultAnalyzers() {
|
|
19
|
+
return [
|
|
20
|
+
cssWasteAnalyzer(),
|
|
21
|
+
duplicationAnalyzer(),
|
|
22
|
+
];
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Analyzer Plugin System
|
|
3
|
+
*
|
|
4
|
+
* Supports pluggable analyzers for different entropy metrics:
|
|
5
|
+
* - CSS Waste Analyzer (current)
|
|
6
|
+
* - Duplication Analyzer (future)
|
|
7
|
+
* - Framework Analyzer (future)
|
|
8
|
+
* - Accessibility Analyzer (future)
|
|
9
|
+
*/
|
|
10
|
+
import type { ExtractedSelectors } from '../parse-css.js';
|
|
11
|
+
import type { UsageExtractionResult } from '../extract-usage.js';
|
|
12
|
+
import type { CrawlResult } from '../crawl.js';
|
|
13
|
+
/**
|
|
14
|
+
* Input data available to all analyzers
|
|
15
|
+
*/
|
|
16
|
+
export interface AnalyzerContext {
|
|
17
|
+
/** Extracted CSS selectors */
|
|
18
|
+
selectors: ExtractedSelectors;
|
|
19
|
+
/** Usage data from source files */
|
|
20
|
+
usage: UsageExtractionResult;
|
|
21
|
+
/** File crawl results */
|
|
22
|
+
crawl: CrawlResult;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Base analyzer result - all analyzers return a score 0-100
|
|
26
|
+
* where 0 = perfect, 100 = maximum entropy/waste
|
|
27
|
+
*/
|
|
28
|
+
export interface AnalyzerResult {
|
|
29
|
+
/** Analyzer name */
|
|
30
|
+
name: string;
|
|
31
|
+
/** Entropy score (0-100): 0 = perfect, 100 = maximum entropy */
|
|
32
|
+
score: number;
|
|
33
|
+
/** Weight in overall entropy calculation (0-1) */
|
|
34
|
+
weight: number;
|
|
35
|
+
/** Human-readable metrics */
|
|
36
|
+
metrics: Record<string, any>;
|
|
37
|
+
/** Recommendations based on score */
|
|
38
|
+
recommendations: string[];
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Analyzer plugin interface
|
|
42
|
+
*/
|
|
43
|
+
export interface Analyzer {
|
|
44
|
+
/** Analyzer name */
|
|
45
|
+
name: string;
|
|
46
|
+
/** Weight in overall entropy score (0-1) */
|
|
47
|
+
weight: number;
|
|
48
|
+
/** Run the analyzer */
|
|
49
|
+
analyze(context: AnalyzerContext): AnalyzerResult;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Combined entropy score result
|
|
53
|
+
*/
|
|
54
|
+
export interface EntropyScore {
|
|
55
|
+
/** Overall UI Entropy score (0-100) */
|
|
56
|
+
overallScore: number;
|
|
57
|
+
/** Individual analyzer results */
|
|
58
|
+
analyzers: AnalyzerResult[];
|
|
59
|
+
/** Severity level */
|
|
60
|
+
severity: 'low' | 'medium' | 'high' | 'critical';
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/analyzers/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAC1D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AACjE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,8BAA8B;IAC9B,SAAS,EAAE,kBAAkB,CAAC;IAC9B,mCAAmC;IACnC,KAAK,EAAE,qBAAqB,CAAC;IAC7B,yBAAyB;IACzB,KAAK,EAAE,WAAW,CAAC;CACpB;AAED;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,oBAAoB;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,gEAAgE;IAChE,KAAK,EAAE,MAAM,CAAC;IACd,kDAAkD;IAClD,MAAM,EAAE,MAAM,CAAC;IACf,6BAA6B;IAC7B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC7B,qCAAqC;IACrC,eAAe,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,oBAAoB;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,4CAA4C;IAC5C,MAAM,EAAE,MAAM,CAAC;IACf,uBAAuB;IACvB,OAAO,CAAC,OAAO,EAAE,eAAe,GAAG,cAAc,CAAC;CACnD;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,uCAAuC;IACvC,YAAY,EAAE,MAAM,CAAC;IACrB,kCAAkC;IAClC,SAAS,EAAE,cAAc,EAAE,CAAC;IAC5B,qBAAqB;IACrB,QAAQ,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,UAAU,CAAC;CAClD"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Analyzer Plugin System
|
|
3
|
+
*
|
|
4
|
+
* Supports pluggable analyzers for different entropy metrics:
|
|
5
|
+
* - CSS Waste Analyzer (current)
|
|
6
|
+
* - Duplication Analyzer (future)
|
|
7
|
+
* - Framework Analyzer (future)
|
|
8
|
+
* - Accessibility Analyzer (future)
|
|
9
|
+
*/
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=types.js.map
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { extractSelectors, extractSelectorsFromMultiple, type ExtractedSelectors, type ParseWarning, } from './parse-css.js';
|
|
2
2
|
export { extractUsage, extractUsedClasses, extractUsedIds, extractUsageFromMultiple, type UsageExtractionResult, } from './extract-usage.js';
|
|
3
|
+
export { type Analyzer, type AnalyzerContext, type AnalyzerResult, type EntropyScore, cssWasteAnalyzer, duplicationAnalyzer, CSSWasteAnalyzer, DuplicationAnalyzer, calculateEntropyScore, getDefaultAnalyzers, } from './analyzers/index.js';
|
|
3
4
|
export { analyzeWaste, estimateWastedBytes, type AnalysisResult, } from './analyze.js';
|
|
4
5
|
export { generateReport, generateJsonReport, generateTextReport, generateSummaryReport, type ReportFormat, type JsonReport, } from './report.js';
|
|
5
6
|
export { crawl, crawlSync, type CrawlOptions, type CrawlResult, } from './crawl.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,gBAAgB,EAChB,4BAA4B,EAC5B,KAAK,kBAAkB,EACvB,KAAK,YAAY,GAClB,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,cAAc,EACd,wBAAwB,EACxB,KAAK,qBAAqB,GAC3B,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EACL,YAAY,EACZ,mBAAmB,EACnB,KAAK,cAAc,GACpB,MAAM,cAAc,CAAC;AAGtB,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,kBAAkB,EAClB,qBAAqB,EACrB,KAAK,YAAY,EACjB,KAAK,UAAU,GAChB,MAAM,aAAa,CAAC;AAGrB,OAAO,EACL,KAAK,EACL,SAAS,EACT,KAAK,YAAY,EACjB,KAAK,WAAW,GACjB,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,UAAU,EACV,WAAW,EACX,SAAS,EACT,cAAc,EACd,KAAK,MAAM,GACZ,MAAM,aAAa,CAAC;AAGrB,OAAO,EACL,IAAI,EACJ,SAAS,EACT,KAAK,WAAW,EAChB,KAAK,UAAU,GAChB,MAAM,WAAW,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,gBAAgB,EAChB,4BAA4B,EAC5B,KAAK,kBAAkB,EACvB,KAAK,YAAY,GAClB,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,cAAc,EACd,wBAAwB,EACxB,KAAK,qBAAqB,GAC3B,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EAEL,KAAK,QAAQ,EACb,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,KAAK,YAAY,EAGjB,gBAAgB,EAChB,mBAAmB,EACnB,gBAAgB,EAChB,mBAAmB,EAGnB,qBAAqB,EACrB,mBAAmB,GACpB,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EACL,YAAY,EACZ,mBAAmB,EACnB,KAAK,cAAc,GACpB,MAAM,cAAc,CAAC;AAGtB,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,kBAAkB,EAClB,qBAAqB,EACrB,KAAK,YAAY,EACjB,KAAK,UAAU,GAChB,MAAM,aAAa,CAAC;AAGrB,OAAO,EACL,KAAK,EACL,SAAS,EACT,KAAK,YAAY,EACjB,KAAK,WAAW,GACjB,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,UAAU,EACV,WAAW,EACX,SAAS,EACT,cAAc,EACd,KAAK,MAAM,GACZ,MAAM,aAAa,CAAC;AAGrB,OAAO,EACL,IAAI,EACJ,SAAS,EACT,KAAK,WAAW,EAChB,KAAK,UAAU,GAChB,MAAM,WAAW,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -2,7 +2,13 @@
|
|
|
2
2
|
export { extractSelectors, extractSelectorsFromMultiple, } from './parse-css.js';
|
|
3
3
|
// Usage Extraction
|
|
4
4
|
export { extractUsage, extractUsedClasses, extractUsedIds, extractUsageFromMultiple, } from './extract-usage.js';
|
|
5
|
-
//
|
|
5
|
+
// Analyzer System (NEW v0.3+)
|
|
6
|
+
export {
|
|
7
|
+
// Built-in analyzers
|
|
8
|
+
cssWasteAnalyzer, duplicationAnalyzer, CSSWasteAnalyzer, DuplicationAnalyzer,
|
|
9
|
+
// Entropy engine
|
|
10
|
+
calculateEntropyScore, getDefaultAnalyzers, } from './analyzers/index.js';
|
|
11
|
+
// Analysis (Legacy)
|
|
6
12
|
export { analyzeWaste, estimateWastedBytes, } from './analyze.js';
|
|
7
13
|
// Reporting
|
|
8
14
|
export { generateReport, generateJsonReport, generateTextReport, generateSummaryReport, } from './report.js';
|
package/dist/scan.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type ParseWarning } from './parse-css.js';
|
|
2
2
|
import { type AnalysisResult } from './analyze.js';
|
|
3
3
|
import { type ReportFormat } from './report.js';
|
|
4
|
+
import { type Analyzer, type EntropyScore } from './analyzers/index.js';
|
|
4
5
|
export interface ScanOptions {
|
|
5
6
|
/**
|
|
6
7
|
* Directory to scan
|
|
@@ -18,9 +19,16 @@ export interface ScanOptions {
|
|
|
18
19
|
cssPatterns?: string[];
|
|
19
20
|
sourcePatterns?: string[];
|
|
20
21
|
ignorePatterns?: string[];
|
|
22
|
+
/**
|
|
23
|
+
* Custom analyzers (v0.3+)
|
|
24
|
+
* @default getDefaultAnalyzers()
|
|
25
|
+
*/
|
|
26
|
+
analyzers?: Analyzer[];
|
|
21
27
|
}
|
|
22
28
|
export interface ScanResult {
|
|
23
29
|
analysis: AnalysisResult;
|
|
30
|
+
/** NEW: Entropy score from analyzer system */
|
|
31
|
+
entropyScore: EntropyScore;
|
|
24
32
|
report: string;
|
|
25
33
|
files: {
|
|
26
34
|
cssFiles: number;
|
package/dist/scan.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scan.d.ts","sourceRoot":"","sources":["../src/scan.ts"],"names":[],"mappings":"AAEA,OAAO,EAAgC,KAAK,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEjF,OAAO,EAAgB,KAAK,cAAc,EAAE,MAAM,cAAc,CAAC;AACjE,OAAO,EAAkB,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"scan.d.ts","sourceRoot":"","sources":["../src/scan.ts"],"names":[],"mappings":"AAEA,OAAO,EAAgC,KAAK,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEjF,OAAO,EAAgB,KAAK,cAAc,EAAE,MAAM,cAAc,CAAC;AACjE,OAAO,EAAkB,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AAChE,OAAO,EAGL,KAAK,QAAQ,EACb,KAAK,YAAY,EAClB,MAAM,sBAAsB,CAAC;AAE9B,MAAM,WAAW,WAAW;IAC1B;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;;OAGG;IACH,MAAM,CAAC,EAAE,YAAY,CAAC;IAEtB;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAE1B;;;OAGG;IACH,SAAS,CAAC,EAAE,QAAQ,EAAE,CAAC;CACxB;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,cAAc,CAAC;IACzB,8CAA8C;IAC9C,YAAY,EAAE,YAAY,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE;QACL,QAAQ,EAAE,MAAM,CAAC;QACjB,WAAW,EAAE,MAAM,CAAC;QACpB,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;IACF,QAAQ,EAAE,YAAY,EAAE,CAAC;CAC1B;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,IAAI,CAAC,OAAO,GAAE,WAAgB,GAAG,UAAU,CA2E1D;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,OAAO,GAAE,MAAsB,GAAG,MAAM,CAGjE"}
|
package/dist/scan.js
CHANGED
|
@@ -4,6 +4,7 @@ import { extractSelectorsFromMultiple } from './parse-css.js';
|
|
|
4
4
|
import { extractUsageFromMultiple } from './extract-usage.js';
|
|
5
5
|
import { analyzeWaste } from './analyze.js';
|
|
6
6
|
import { generateReport } from './report.js';
|
|
7
|
+
import { getDefaultAnalyzers, calculateEntropyScore, } from './analyzers/index.js';
|
|
7
8
|
/**
|
|
8
9
|
* Scan a project directory for CSS waste
|
|
9
10
|
*
|
|
@@ -16,7 +17,8 @@ import { generateReport } from './report.js';
|
|
|
16
17
|
* 6. Generate report
|
|
17
18
|
*/
|
|
18
19
|
export function scan(options = {}) {
|
|
19
|
-
const { baseDir = process.cwd(), format = 'text', cssPatterns, sourcePatterns, ignorePatterns,
|
|
20
|
+
const { baseDir = process.cwd(), format = 'text', cssPatterns, sourcePatterns, ignorePatterns, analyzers = getDefaultAnalyzers(), // NEW: Default analyzer set
|
|
21
|
+
} = options;
|
|
20
22
|
// 1. Load configuration
|
|
21
23
|
const config = getConfig(baseDir);
|
|
22
24
|
// Override with CLI options if provided
|
|
@@ -46,13 +48,20 @@ export function scan(options = {}) {
|
|
|
46
48
|
// 4. Extract usage from source files
|
|
47
49
|
const sourceContents = crawlResult.sourceFiles.map(f => f.content);
|
|
48
50
|
const usage = extractUsageFromMultiple(sourceContents);
|
|
49
|
-
// 5. Analyze waste
|
|
51
|
+
// 5. Analyze waste (legacy)
|
|
50
52
|
const analysis = analyzeWaste(selectors, usage);
|
|
53
|
+
// 5b. NEW: Run analyzer system and calculate entropy score
|
|
54
|
+
const entropyScore = calculateEntropyScore({
|
|
55
|
+
selectors,
|
|
56
|
+
usage,
|
|
57
|
+
crawl: crawlResult,
|
|
58
|
+
}, analyzers);
|
|
51
59
|
// 6. Generate report
|
|
52
60
|
const reportFormat = config.output?.format ?? format;
|
|
53
61
|
const report = generateReport(analysis, reportFormat, selectors.warnings);
|
|
54
62
|
return {
|
|
55
63
|
analysis,
|
|
64
|
+
entropyScore, // NEW: Entropy score included
|
|
56
65
|
report,
|
|
57
66
|
files: {
|
|
58
67
|
cssFiles: crawlResult.stats.totalCssFiles,
|