packlyze 1.0.5 β†’ 2.0.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/README.md CHANGED
@@ -4,19 +4,20 @@
4
4
  [![Build Status](https://img.shields.io/github/workflow/status/iamabhshk/Packlyze/CI)](https://github.com/iamabhshk/Packlyze/actions)
5
5
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
6
6
 
7
- # Packlyze
7
+ ## Packlyze
8
8
 
9
- Advanced bundle analyzer with insights, recommendations, and historical tracking.
9
+ Advanced bundle analyzer with insights, recommendations, historical tracking, and a sleek HTML report.
10
10
 
11
11
  ## πŸ“Š Features
12
12
 
13
- - **Package Analysis**: Parse and analyze webpack, rollup, and esbuild stats files
14
- - **Smart Recommendations**: AI-powered suggestions to optimize your bundle
15
- - **Tree-Shaking Detection**: Identify modules preventing tree-shaking
16
- - **Duplicate Detection**: Find and quantify duplicate modules
17
- - **Beautiful Reports**: Generate interactive HTML reports
18
- - **CLI Tool**: Easy-to-use command-line interface
19
- - **TypeScript Ready**: Full TypeScript support with type definitions
13
+ - **Package Analysis**: Parse and analyze webpack, rollup, and esbuild stats files.
14
+ - **Smart Recommendations**: Suggestions to optimize bundle size and structure.
15
+ - **Tree-Shaking Detection**: Identify modules and patterns that block tree-shaking.
16
+ - **Duplicate Detection**: Find and quantify duplicate modules with potential savings.
17
+ - **Beautiful HTML Report**: Sleek, dark-themed, responsive report with high-level metrics and deep insights.
18
+ - **Baseline Comparison**: Compare current vs previous stats to see regressions and improvements.
19
+ - **CLI Tool**: Easy-to-use command-line interface with filters and CI-friendly thresholds.
20
+ - **TypeScript Ready**: Full TypeScript support with type definitions.
20
21
 
21
22
  ## πŸš€ Quick Start
22
23
 
@@ -43,7 +44,7 @@ npx webpack --profile --json stats.json
43
44
  ```
44
45
  - This will create a readable `stats.json` file in your project directory.
45
46
 
46
- **3. Run Packlyze analysis:**
47
+ **3. Run Packlyze analysis (CLI):**
47
48
  ```bash
48
49
  packlyze analyze stats.json
49
50
  # or (if using npx)
@@ -122,10 +123,83 @@ The analyzer provides:
122
123
  - Info: Monitor for growth
123
124
 
124
125
  ### Insights
125
- - Tree-shaking issues
126
- - Duplicate modules
127
- - Large modules (>5% of bundle)
128
- - Module count analysis
126
+ - Tree-shaking issues.
127
+ - Duplicate modules.
128
+ - Large modules (configurable threshold, default >5% of bundle).
129
+ - Module count and chunk analysis.
130
+
131
+ ### HTML Report
132
+
133
+ The generated HTML report is a single, static file with a modern dark UI:
134
+
135
+ - **Header**: Run timestamp, optional baseline timestamp, and quick badges that summarize what you’re seeing.
136
+ - **Metrics Grid**: Cards for total size, gzip size, modules, chunks, average module size, and largest module.
137
+ - When a `--baseline` is provided, each metric shows a colored delta (green for improvement, red for regression).
138
+ - **Recommendations**: Color-coded cards grouped by severity (critical, warning, info) with clear β€œAction” text.
139
+ - **Top Modules Table**: Top 10 modules by size, with size and share of the bundle.
140
+ - **Duplicate Modules Section**: Table with count, total size, potential savings, and example module names.
141
+ - **Tree-Shaking Section**: List of CommonJS / `require`-style modules that may block tree-shaking.
142
+
143
+ You can open the HTML report directly in any modern browser; no network access or JS bundling is required.
144
+
145
+ ---
146
+
147
+ ## βš™οΈ CLI Usage & Options
148
+
149
+ The main CLI entry point is the `analyze` command:
150
+
151
+ ```bash
152
+ packlyze analyze <statsFile> [options]
153
+ ```
154
+
155
+ ### Core options
156
+
157
+ - `-o, --output <path>`: Path to the HTML report (default: `./bundle-report.html`).
158
+ - `-j, --json`: Output raw JSON analysis to stdout instead of human-readable text/HTML.
159
+ - `-v, --verbose`: Reserved for future verbose logging.
160
+
161
+ ### Focus & filter options
162
+
163
+ - `--only-duplicates`: Only print duplicate modules table in the CLI output.
164
+ - `--only-large-modules`: Only print large modules table in the CLI output.
165
+ - `--large-module-threshold <percent>`: Percentage of bundle size at which a module is considered β€œlarge” (default: `5`).
166
+ - `--no-html`: Skip HTML report generation (useful in fast CLI-only workflows).
167
+
168
+ ### Baseline comparison
169
+
170
+ - `--baseline <statsFile>`: Provide a previous stats file to compare against.
171
+
172
+ When a baseline is provided:
173
+
174
+ - CLI summary prints deltas for total size, gzip size, module count, and chunk count.
175
+ - HTML metrics cards show deltas under each metric (green good, red regression).
176
+
177
+ Example:
178
+
179
+ ```bash
180
+ packlyze analyze dist/stats.new.json --baseline dist/stats.old.json
181
+ ```
182
+
183
+ ### CI-friendly thresholds
184
+
185
+ Packlyze can enforce bundle-size budgets and fail your CI when limits are exceeded:
186
+
187
+ - `--max-gzip-size <mb>`: Fail if gzip size exceeds this many megabytes.
188
+ - `--max-initial-size <mb>`: Fail if initial bundle size (initial chunks) exceeds this many megabytes.
189
+
190
+ When thresholds are violated:
191
+
192
+ - The CLI prints a clear error message.
193
+ - `packlyze` exits with a non-zero exit code so your CI job can fail on regressions.
194
+
195
+ Example:
196
+
197
+ ```bash
198
+ packlyze analyze dist/stats.json \
199
+ --max-gzip-size 1.2 \
200
+ --max-initial-size 0.9 \
201
+ --no-html
202
+ ```
129
203
 
130
204
  ## 🎯 Use Cases
131
205
 
package/dist/cli.js CHANGED
@@ -7,9 +7,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
7
7
  const commander_1 = require("commander");
8
8
  const chalk_1 = __importDefault(require("chalk"));
9
9
  const ora_1 = __importDefault(require("ora"));
10
+ const fs_1 = __importDefault(require("fs"));
11
+ const table_1 = require("table");
10
12
  const packlyze_1 = require("./analyzer/packlyze");
11
13
  const reports_1 = require("./visualization/reports");
12
- const fs_1 = __importDefault(require("fs"));
13
14
  const program = new commander_1.Command();
14
15
  program
15
16
  .name('packlyze')
@@ -22,6 +23,13 @@ program
22
23
  .option('-o, --output <path>', 'Output HTML report path', './bundle-report.html')
23
24
  .option('-j, --json', 'Output as JSON')
24
25
  .option('-v, --verbose', 'Verbose output')
26
+ .option('--no-html', 'Do not generate HTML report')
27
+ .option('--only-duplicates', 'Show only duplicate modules information')
28
+ .option('--only-large-modules', 'Show only large modules information')
29
+ .option('--large-module-threshold <percent>', 'Threshold in % of bundle size for a module to be considered large', parseFloat, 5)
30
+ .option('--max-gzip-size <mb>', 'Fail if gzip bundle size exceeds this value (in MB)', parseFloat)
31
+ .option('--max-initial-size <mb>', 'Fail if initial bundle size exceeds this value (in MB)', parseFloat)
32
+ .option('--baseline <statsFile>', 'Baseline stats file to compare against')
25
33
  .action(async (statsFile, options) => {
26
34
  const spinner = (0, ora_1.default)('Analyzing package...').start();
27
35
  try {
@@ -31,48 +39,41 @@ program
31
39
  }
32
40
  const analyzer = new packlyze_1.Packlyze(statsFile);
33
41
  const result = await analyzer.analyze();
42
+ let baselineResult;
43
+ if (options.baseline) {
44
+ const baselinePath = options.baseline;
45
+ if (!fs_1.default.existsSync(baselinePath)) {
46
+ throw new Error(`Baseline file not found: ${baselinePath}`);
47
+ }
48
+ const baselineAnalyzer = new packlyze_1.Packlyze(baselinePath);
49
+ baselineResult = await baselineAnalyzer.analyze();
50
+ }
34
51
  spinner.succeed('Analysis complete!');
35
52
  if (options.json) {
36
53
  console.log(JSON.stringify(result, null, 2));
37
54
  }
38
55
  else {
39
56
  // Display formatted results
40
- console.log(chalk_1.default.bold.cyan('\nπŸ“Š Package Analysis Results\n'));
41
- console.log(chalk_1.default.bold('Metrics:'));
42
- console.log(` Total Size: ${chalk_1.default.red((result.metrics.totalSize / 1024 / 1024).toFixed(2))}MB`);
43
- console.log(` Gzip Size: ${chalk_1.default.yellow((result.metrics.totalGzipSize / 1024 / 1024).toFixed(2))}MB`);
44
- console.log(` Modules: ${chalk_1.default.blue(result.metrics.moduleCount)}`);
45
- console.log(` Chunks: ${chalk_1.default.blue(result.metrics.chunkCount)}`);
46
- console.log(` Avg Module: ${chalk_1.default.green((result.metrics.averageModuleSize / 1024).toFixed(2))}KB\n`);
47
- // Top modules
48
- console.log(chalk_1.default.bold('Top 5 Modules:'));
49
- result.bundleStats.modules.slice(0, 5).forEach((m, i) => {
50
- const bar = 'β–ˆ'.repeat(Math.round(m.percentage / 2));
51
- console.log(` ${i + 1}. ${m.name.slice(-30).padEnd(30)} ${(m.size / 1024).toFixed(2)}KB ${bar}`);
52
- });
53
- // Recommendations
54
- if (result.recommendations.length > 0) {
55
- console.log(chalk_1.default.bold.cyan('\nπŸ’‘ Recommendations\n'));
56
- result.recommendations.forEach(rec => {
57
- const icon = rec.severity === 'critical' ? 'πŸ”΄' : rec.severity === 'warning' ? '🟑' : '🟒';
58
- console.log(`${icon} ${rec.message}`);
59
- console.log(` β†’ ${rec.action}\n`);
60
- });
57
+ printSummary(result, options, baselineResult);
58
+ if (!options.onlyDuplicates && !options.onlyLargeModules) {
59
+ printTopModules(result);
60
+ printRecommendations(result);
61
+ printTreeshakingIssues(result);
61
62
  }
62
- // Tree-shaking issues
63
- if (result.treeshakingIssues.length > 0) {
64
- console.log(chalk_1.default.bold.yellow('\n🌳 Tree-Shaking Issues\n'));
65
- result.treeshakingIssues.slice(0, 3).forEach(issue => {
66
- console.log(` β€’ ${issue}`);
67
- });
68
- if (result.treeshakingIssues.length > 3) {
69
- console.log(` ... and ${result.treeshakingIssues.length - 3} more`);
70
- }
71
- console.log();
63
+ if (options.onlyDuplicates || (!options.onlyLargeModules && !options.onlyDuplicates)) {
64
+ printDuplicates(result);
65
+ }
66
+ if (options.onlyLargeModules || (!options.onlyLargeModules && !options.onlyDuplicates)) {
67
+ printLargeModules(result, options.largeModuleThreshold);
68
+ }
69
+ if (options.html !== false) {
70
+ (0, reports_1.generateHTMLReport)(result, options.output, baselineResult);
71
+ console.log(chalk_1.default.green(`βœ… Report saved to ${options.output}`));
72
+ }
73
+ const exitCode = evaluateThresholds(result, options);
74
+ if (exitCode !== 0) {
75
+ process.exit(exitCode);
72
76
  }
73
- // Generate HTML report
74
- (0, reports_1.generateHTMLReport)(result, options.output);
75
- console.log(chalk_1.default.green(`βœ… Report saved to ${options.output}`));
76
77
  }
77
78
  }
78
79
  catch (error) {
@@ -82,4 +83,137 @@ program
82
83
  }
83
84
  });
84
85
  program.parse();
86
+ function printSummary(result, options, baseline) {
87
+ console.log(chalk_1.default.bold.cyan('\nπŸ“Š Package Analysis Results\n'));
88
+ console.log(chalk_1.default.bold('Metrics:'));
89
+ const totalMb = result.metrics.totalSize / 1024 / 1024;
90
+ const gzipMb = result.metrics.totalGzipSize / 1024 / 1024;
91
+ console.log(` Total Size: ${chalk_1.default.red(totalMb.toFixed(2))}MB${formatDeltaMb(baseline?.metrics.totalSize, result.metrics.totalSize)}`);
92
+ console.log(` Gzip Size: ${chalk_1.default.yellow(gzipMb.toFixed(2))}MB${formatDeltaMb(baseline?.metrics.totalGzipSize, result.metrics.totalGzipSize)}`);
93
+ console.log(` Modules: ${chalk_1.default.blue(result.metrics.moduleCount)}${formatDeltaCount(baseline?.metrics.moduleCount, result.metrics.moduleCount)}`);
94
+ console.log(` Chunks: ${chalk_1.default.blue(result.metrics.chunkCount)}${formatDeltaCount(baseline?.metrics.chunkCount, result.metrics.chunkCount)}`);
95
+ console.log(` Avg Module: ${chalk_1.default.green((result.metrics.averageModuleSize / 1024).toFixed(2))}KB\n`);
96
+ if (options.maxGzipSize) {
97
+ console.log(` Max Gzip Threshold: ${chalk_1.default.yellow(options.maxGzipSize)}MB (${result.metrics.totalGzipSize / 1024 / 1024 > options.maxGzipSize ? chalk_1.default.red('violated') : chalk_1.default.green('ok')})`);
98
+ }
99
+ if (options.maxInitialSize) {
100
+ const initialMb = (result.bundleStats.isInitialBySize / 1024 / 1024).toFixed(2);
101
+ console.log(` Max Initial Threshold: ${chalk_1.default.yellow(options.maxInitialSize)}MB (${Number(initialMb) > options.maxInitialSize ? chalk_1.default.red('violated') : chalk_1.default.green('ok')})`);
102
+ }
103
+ console.log();
104
+ }
105
+ function printTopModules(result) {
106
+ console.log(chalk_1.default.bold('Top 5 Modules:'));
107
+ result.bundleStats.modules.slice(0, 5).forEach((m, i) => {
108
+ const bar = 'β–ˆ'.repeat(Math.round(m.percentage / 2));
109
+ console.log(` ${i + 1}. ${m.name.slice(-30).padEnd(30)} ${(m.size / 1024).toFixed(2)}KB ${bar}`);
110
+ });
111
+ console.log();
112
+ }
113
+ function printRecommendations(result) {
114
+ if (result.recommendations.length === 0)
115
+ return;
116
+ console.log(chalk_1.default.bold.cyan('\nπŸ’‘ Recommendations\n'));
117
+ result.recommendations.forEach((rec) => {
118
+ const icon = rec.severity === 'critical' ? 'πŸ”΄' : rec.severity === 'warning' ? '🟑' : '🟒';
119
+ console.log(`${icon} ${rec.message}`);
120
+ console.log(` β†’ ${rec.action}\n`);
121
+ });
122
+ }
123
+ function printTreeshakingIssues(result) {
124
+ if (result.treeshakingIssues.length === 0)
125
+ return;
126
+ console.log(chalk_1.default.bold.yellow('\n🌳 Tree-Shaking Issues\n'));
127
+ result.treeshakingIssues.slice(0, 3).forEach((issue) => {
128
+ console.log(` β€’ ${issue}`);
129
+ });
130
+ if (result.treeshakingIssues.length > 3) {
131
+ console.log(` ... and ${result.treeshakingIssues.length - 3} more`);
132
+ }
133
+ console.log();
134
+ }
135
+ function printDuplicates(result) {
136
+ if (result.duplicates.length === 0) {
137
+ console.log(chalk_1.default.bold.green('\nβœ… No duplicate modules detected\n'));
138
+ return;
139
+ }
140
+ console.log(chalk_1.default.bold.magenta('\nπŸ” Duplicate Modules\n'));
141
+ const data = [];
142
+ data.push(['#', 'Count', 'Total Size (KB)', 'Potential Savings (KB)', 'Example Names']);
143
+ result.duplicates.forEach((dup, index) => {
144
+ const totalKb = (dup.totalSize / 1024).toFixed(2);
145
+ const savingsKb = (dup.savings / 1024).toFixed(2);
146
+ const sampleNames = dup.names.slice(0, 3).join('\n');
147
+ data.push([String(index + 1), String(dup.names.length), totalKb, savingsKb, sampleNames]);
148
+ });
149
+ console.log((0, table_1.table)(data, {
150
+ columns: {
151
+ 0: { alignment: 'right' },
152
+ 1: { alignment: 'right' },
153
+ 2: { alignment: 'right' },
154
+ 3: { alignment: 'right' },
155
+ 4: { alignment: 'left' },
156
+ },
157
+ }));
158
+ }
159
+ function printLargeModules(result, thresholdPercent) {
160
+ const threshold = Number.isFinite(thresholdPercent) ? thresholdPercent : 5;
161
+ const largeModules = result.bundleStats.modules.filter((m) => m.percentage >= threshold);
162
+ if (largeModules.length === 0) {
163
+ console.log(chalk_1.default.bold.green(`\nβœ… No modules above ${threshold}% of bundle size\n`));
164
+ return;
165
+ }
166
+ console.log(chalk_1.default.bold.red(`\nπŸ“¦ Modules >= ${threshold}% of bundle size\n`));
167
+ const data = [];
168
+ data.push(['#', 'Module', 'Size (KB)', '% of Bundle']);
169
+ largeModules.forEach((m, index) => {
170
+ data.push([String(index + 1), m.name.slice(-60), (m.size / 1024).toFixed(2), m.percentage.toFixed(2)]);
171
+ });
172
+ console.log((0, table_1.table)(data, {
173
+ columns: {
174
+ 0: { alignment: 'right' },
175
+ 1: { alignment: 'left' },
176
+ 2: { alignment: 'right' },
177
+ 3: { alignment: 'right' },
178
+ },
179
+ }));
180
+ }
181
+ function evaluateThresholds(result, options) {
182
+ let exitCode = 0;
183
+ if (typeof options.maxGzipSize === 'number') {
184
+ const gzipMb = result.metrics.totalGzipSize / 1024 / 1024;
185
+ if (gzipMb > options.maxGzipSize) {
186
+ console.error(chalk_1.default.red(`\n❌ Bundle gzip size (${gzipMb.toFixed(2)}MB) exceeds threshold (${options.maxGzipSize}MB).`));
187
+ exitCode = 2;
188
+ }
189
+ }
190
+ if (typeof options.maxInitialSize === 'number') {
191
+ const initialMb = result.bundleStats.isInitialBySize / 1024 / 1024;
192
+ if (initialMb > options.maxInitialSize) {
193
+ console.error(chalk_1.default.red(`\n❌ Initial bundle size (${initialMb.toFixed(2)}MB) exceeds threshold (${options.maxInitialSize}MB).`));
194
+ exitCode = Math.max(exitCode, 3);
195
+ }
196
+ }
197
+ return exitCode;
198
+ }
199
+ function formatDeltaMb(baselineBytes, currentBytes) {
200
+ if (baselineBytes === undefined || currentBytes === undefined)
201
+ return '';
202
+ const diffMb = (currentBytes - baselineBytes) / 1024 / 1024;
203
+ if (Math.abs(diffMb) < 0.01)
204
+ return '';
205
+ const sign = diffMb > 0 ? '+' : '-';
206
+ const color = diffMb > 0 ? chalk_1.default.red : chalk_1.default.green;
207
+ return ` (${color(`${sign}${Math.abs(diffMb).toFixed(2)}MB vs baseline`)})`;
208
+ }
209
+ function formatDeltaCount(baseline, current) {
210
+ if (baseline === undefined || current === undefined)
211
+ return '';
212
+ const diff = current - baseline;
213
+ if (diff === 0)
214
+ return '';
215
+ const sign = diff > 0 ? '+' : '-';
216
+ const color = diff > 0 ? chalk_1.default.red : chalk_1.default.green;
217
+ return ` (${color(`${sign}${Math.abs(diff)} vs baseline`)})`;
218
+ }
85
219
  //# sourceMappingURL=cli.js.map
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,3 @@
1
1
  import { AnalysisResult } from '../types.js';
2
- export declare function generateHTMLReport(result: AnalysisResult, outputPath: string): void;
2
+ export declare function generateHTMLReport(result: AnalysisResult, outputPath: string, baselineResult?: AnalysisResult): void;
3
3
  //# sourceMappingURL=reports.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"reports.d.ts","sourceRoot":"","sources":["../../src/visualization/reports.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE7C,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,CAGnF"}
1
+ {"version":3,"file":"reports.d.ts","sourceRoot":"","sources":["../../src/visualization/reports.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE7C,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,cAAc,GAAG,IAAI,CASpH"}
@@ -5,11 +5,16 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.generateHTMLReport = generateHTMLReport;
7
7
  const fs_1 = __importDefault(require("fs"));
8
- function generateHTMLReport(result, outputPath) {
9
- const html = generateHTML(result);
8
+ const path_1 = __importDefault(require("path"));
9
+ function generateHTMLReport(result, outputPath, baselineResult) {
10
+ const html = generateHTML(result, baselineResult);
11
+ const dir = path_1.default.dirname(outputPath);
12
+ if (dir && dir !== '.' && !fs_1.default.existsSync(dir)) {
13
+ fs_1.default.mkdirSync(dir, { recursive: true });
14
+ }
10
15
  fs_1.default.writeFileSync(outputPath, html);
11
16
  }
12
- function generateHTML(result) {
17
+ function generateHTML(result, baseline) {
13
18
  const recommendations = result.recommendations
14
19
  .map(rec => `
15
20
  <div class="recommendation ${rec.severity}">
@@ -31,6 +36,20 @@ function generateHTML(result) {
31
36
  </tr>
32
37
  `)
33
38
  .join('');
39
+ const duplicates = result.duplicates
40
+ .map(dup => `
41
+ <tr>
42
+ <td>${dup.names.length}</td>
43
+ <td>${(dup.totalSize / 1024).toFixed(2)} KB</td>
44
+ <td>${(dup.savings / 1024).toFixed(2)} KB</td>
45
+ <td>${dup.names.slice(0, 3).map(name => escapeHtml(name)).join('<br/>')}${dup.names.length > 3 ? '…' : ''}</td>
46
+ </tr>
47
+ `)
48
+ .join('');
49
+ const treeshakingIssues = result.treeshakingIssues
50
+ .slice(0, 10)
51
+ .map(issue => `<li>${escapeHtml(issue)}</li>`)
52
+ .join('');
34
53
  return `
35
54
  <!DOCTYPE html>
36
55
  <html lang="en">
@@ -39,97 +58,448 @@ function generateHTML(result) {
39
58
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
40
59
  <title>Package Analysis Report</title>
41
60
  <style>
42
- * { margin: 0; padding: 0; box-sizing: border-box; }
43
- body {
44
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
45
- background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
46
- color: #333;
61
+ * {
62
+ margin: 0;
63
+ padding: 0;
64
+ box-sizing: border-box;
65
+ }
66
+
67
+ :root {
68
+ --bg-body: #050816;
69
+ --bg-panel: #0f172a;
70
+ --bg-panel-soft: #020617;
71
+ --border-subtle: rgba(148, 163, 184, 0.3);
72
+ --accent: #6366f1;
73
+ --accent-soft: rgba(99, 102, 241, 0.18);
74
+ --accent-strong: #4f46e5;
75
+ --text-main: #e5e7eb;
76
+ --text-soft: #9ca3af;
77
+ --text-subtle: #6b7280;
78
+ --critical: #f97373;
79
+ --warning: #fb923c;
80
+ --info: #38bdf8;
81
+ --good: #22c55e;
82
+ --shadow-soft: 0 18px 40px rgba(15, 23, 42, 0.75);
83
+ --radius-lg: 18px;
84
+ --radius-md: 12px;
85
+ --radius-sm: 9px;
86
+ --blur-backdrop: 20px;
87
+ }
88
+
89
+ body {
90
+ font-family: system-ui, -apple-system, BlinkMacSystemFont, 'SF Pro Text', 'Segoe UI', sans-serif;
91
+ background: radial-gradient(circle at top, #1e293b 0, #020617 45%, #000 100%);
92
+ color: var(--text-main);
47
93
  min-height: 100vh;
48
- padding: 20px;
94
+ padding: 32px 20px 40px;
95
+ display: flex;
96
+ justify-content: center;
97
+ }
98
+
99
+ .container {
100
+ width: 100%;
101
+ max-width: 1120px;
49
102
  }
50
- .container { max-width: 1200px; margin: 0 auto; }
103
+
51
104
  header {
52
- background: white;
53
- padding: 30px;
54
- border-radius: 8px;
55
- margin-bottom: 20px;
56
- box-shadow: 0 4px 6px rgba(0,0,0,0.1);
57
- }
58
- h1 { color: #667eea; font-size: 28px; margin-bottom: 10px; }
59
- .timestamp { color: #999; font-size: 12px; }
60
-
105
+ background: linear-gradient(135deg, rgba(15, 23, 42, 0.96), rgba(15, 23, 42, 0.92));
106
+ border-radius: 24px;
107
+ padding: 24px 28px 20px;
108
+ margin-bottom: 24px;
109
+ border: 1px solid rgba(148, 163, 184, 0.35);
110
+ box-shadow: var(--shadow-soft);
111
+ backdrop-filter: blur(var(--blur-backdrop));
112
+ position: relative;
113
+ overflow: hidden;
114
+ }
115
+
116
+ header::before {
117
+ content: '';
118
+ position: absolute;
119
+ inset: -40%;
120
+ background:
121
+ radial-gradient(circle at 0% 0%, rgba(56, 189, 248, 0.09) 0, transparent 55%),
122
+ radial-gradient(circle at 100% 0%, rgba(129, 140, 248, 0.18) 0, transparent 60%);
123
+ opacity: 0.7;
124
+ pointer-events: none;
125
+ }
126
+
127
+ .header-inner {
128
+ position: relative;
129
+ display: flex;
130
+ justify-content: space-between;
131
+ align-items: flex-start;
132
+ gap: 16px;
133
+ }
134
+
135
+ h1 {
136
+ color: #f9fafb;
137
+ font-size: 26px;
138
+ letter-spacing: 0.02em;
139
+ margin-bottom: 6px;
140
+ display: flex;
141
+ align-items: center;
142
+ gap: 10px;
143
+ }
144
+
145
+ h1 span.icon {
146
+ font-size: 26px;
147
+ }
148
+
149
+ .header-subtitle {
150
+ color: var(--text-soft);
151
+ font-size: 13px;
152
+ }
153
+
154
+ .timestamp-group {
155
+ text-align: right;
156
+ font-size: 11px;
157
+ color: var(--text-subtle);
158
+ }
159
+
160
+ .timestamp-label {
161
+ text-transform: uppercase;
162
+ letter-spacing: 0.1em;
163
+ font-size: 10px;
164
+ color: var(--text-subtle);
165
+ }
166
+
167
+ .timestamp-value {
168
+ margin-top: 3px;
169
+ }
170
+
171
+ .badge-row {
172
+ display: flex;
173
+ flex-wrap: wrap;
174
+ gap: 8px;
175
+ margin-top: 14px;
176
+ }
177
+
178
+ .badge {
179
+ border-radius: 999px;
180
+ padding: 4px 9px;
181
+ font-size: 11px;
182
+ border: 1px solid rgba(148, 163, 184, 0.35);
183
+ color: var(--text-soft);
184
+ display: inline-flex;
185
+ align-items: center;
186
+ gap: 6px;
187
+ background: rgba(15, 23, 42, 0.8);
188
+ backdrop-filter: blur(10px);
189
+ }
190
+
191
+ .badge-accent {
192
+ border-color: rgba(99, 102, 241, 0.5);
193
+ color: #e0e7ff;
194
+ background: rgba(79, 70, 229, 0.22);
195
+ }
196
+
197
+ .badge-dot {
198
+ width: 7px;
199
+ height: 7px;
200
+ border-radius: 999px;
201
+ background: var(--good);
202
+ box-shadow: 0 0 0 4px rgba(34, 197, 94, 0.17);
203
+ }
204
+
61
205
  .metrics-grid {
62
206
  display: grid;
63
- grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
64
- gap: 15px;
65
- margin-bottom: 20px;
207
+ grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
208
+ gap: 14px;
209
+ margin-bottom: 22px;
66
210
  }
211
+
67
212
  .metric-card {
68
- background: white;
69
- padding: 20px;
70
- border-radius: 8px;
71
- box-shadow: 0 4px 6px rgba(0,0,0,0.1);
72
- }
73
- .metric-label { color: #999; font-size: 12px; text-transform: uppercase; margin-bottom: 10px; }
74
- .metric-value { font-size: 24px; font-weight: bold; color: #667eea; }
75
-
213
+ background: radial-gradient(circle at 0 0, rgba(148, 163, 184, 0.08) 0, rgba(15, 23, 42, 0.98) 55%);
214
+ padding: 16px 16px 14px;
215
+ border-radius: var(--radius-md);
216
+ border: 1px solid rgba(30, 64, 175, 0.55);
217
+ box-shadow: 0 10px 30px rgba(15, 23, 42, 0.8);
218
+ position: relative;
219
+ overflow: hidden;
220
+ }
221
+
222
+ .metric-card::after {
223
+ content: '';
224
+ position: absolute;
225
+ inset: 0;
226
+ background: linear-gradient(135deg, rgba(148, 163, 184, 0.05), transparent 40%);
227
+ opacity: 0.9;
228
+ pointer-events: none;
229
+ }
230
+
231
+ .metric-label {
232
+ color: var(--text-subtle);
233
+ font-size: 11px;
234
+ text-transform: uppercase;
235
+ letter-spacing: 0.12em;
236
+ margin-bottom: 8px;
237
+ }
238
+
239
+ .metric-value {
240
+ font-size: 22px;
241
+ font-weight: 600;
242
+ color: #e5e7eb;
243
+ position: relative;
244
+ z-index: 1;
245
+ }
246
+
247
+ .metric-delta {
248
+ font-size: 11px;
249
+ margin-top: 4px;
250
+ position: relative;
251
+ z-index: 1;
252
+ }
253
+
254
+ .delta-positive {
255
+ color: #4ade80;
256
+ }
257
+
258
+ .delta-negative {
259
+ color: #fb7185;
260
+ }
261
+
76
262
  .section {
77
- background: white;
78
- padding: 25px;
79
- border-radius: 8px;
80
- margin-bottom: 20px;
81
- box-shadow: 0 4px 6px rgba(0,0,0,0.1);
82
- }
83
- .section h2 { color: #333; margin-bottom: 15px; font-size: 18px; border-bottom: 2px solid #eee; padding-bottom: 10px; }
84
-
263
+ background: radial-gradient(circle at 0 0, rgba(148, 163, 184, 0.07) 0, rgba(15, 23, 42, 0.98) 55%);
264
+ padding: 20px 20px 18px;
265
+ border-radius: var(--radius-lg);
266
+ margin-bottom: 18px;
267
+ border: 1px solid var(--border-subtle);
268
+ box-shadow: var(--shadow-soft);
269
+ position: relative;
270
+ overflow: hidden;
271
+ }
272
+
273
+ .section::before {
274
+ content: '';
275
+ position: absolute;
276
+ inset: -30%;
277
+ background: radial-gradient(circle at 100% 0, rgba(96, 165, 250, 0.11) 0, transparent 55%);
278
+ opacity: 0.75;
279
+ pointer-events: none;
280
+ }
281
+
282
+ .section-inner {
283
+ position: relative;
284
+ }
285
+
286
+ .section h2 {
287
+ color: #e5e7eb;
288
+ margin-bottom: 16px;
289
+ font-size: 16px;
290
+ font-weight: 600;
291
+ display: flex;
292
+ align-items: center;
293
+ justify-content: space-between;
294
+ gap: 10px;
295
+ border-bottom: 1px solid rgba(148, 163, 184, 0.25);
296
+ padding-bottom: 9px;
297
+ }
298
+
299
+ .section-tag {
300
+ font-size: 11px;
301
+ text-transform: uppercase;
302
+ letter-spacing: 0.16em;
303
+ color: var(--text-subtle);
304
+ }
305
+
85
306
  .recommendation {
86
307
  display: flex;
87
- gap: 15px;
88
- padding: 15px;
308
+ gap: 14px;
309
+ padding: 13px 12px;
89
310
  margin-bottom: 10px;
90
- border-radius: 6px;
91
- border-left: 4px solid;
92
- }
93
- .recommendation.critical { background: #fff5f5; border-left-color: #f56565; }
94
- .recommendation.warning { background: #fffaf0; border-left-color: #ed8936; }
95
- .recommendation.info { background: #ebf8ff; border-left-color: #4299e1; }
96
-
97
- .rec-icon { font-size: 24px; }
98
- .rec-content { flex: 1; }
99
- .rec-message { font-weight: 600; margin-bottom: 5px; }
100
- .rec-action { font-size: 13px; color: #666; }
101
-
102
- table { width: 100%; border-collapse: collapse; }
103
- th { background: #f7f7f7; padding: 12px; text-align: left; font-weight: 600; border-bottom: 2px solid #eee; }
104
- td { padding: 12px; border-bottom: 1px solid #eee; }
105
- tr:hover { background: #f9f9f9; }
106
-
107
- footer { text-align: center; color: #999; font-size: 12px; margin-top: 30px; }
311
+ border-radius: var(--radius-md);
312
+ border: 1px solid rgba(148, 163, 184, 0.35);
313
+ background: rgba(15, 23, 42, 0.92);
314
+ }
315
+
316
+ .recommendation.critical {
317
+ border-color: rgba(248, 113, 113, 0.6);
318
+ background: linear-gradient(135deg, rgba(127, 29, 29, 0.9), rgba(15, 23, 42, 0.96));
319
+ }
320
+
321
+ .recommendation.warning {
322
+ border-color: rgba(251, 146, 60, 0.7);
323
+ background: linear-gradient(135deg, rgba(124, 45, 18, 0.9), rgba(15, 23, 42, 0.96));
324
+ }
325
+
326
+ .recommendation.info {
327
+ border-color: rgba(56, 189, 248, 0.65);
328
+ background: linear-gradient(135deg, rgba(12, 74, 110, 0.9), rgba(15, 23, 42, 0.96));
329
+ }
330
+
331
+ .rec-icon {
332
+ font-size: 22px;
333
+ line-height: 1;
334
+ margin-top: 2px;
335
+ }
336
+
337
+ .rec-content {
338
+ flex: 1;
339
+ }
340
+
341
+ .rec-message {
342
+ font-weight: 600;
343
+ margin-bottom: 4px;
344
+ color: #f9fafb;
345
+ font-size: 14px;
346
+ }
347
+
348
+ .rec-action {
349
+ font-size: 12px;
350
+ color: var(--text-soft);
351
+ }
352
+
353
+ table {
354
+ width: 100%;
355
+ border-collapse: collapse;
356
+ font-size: 12px;
357
+ }
358
+
359
+ th,
360
+ td {
361
+ padding: 9px 10px;
362
+ border-bottom: 1px solid rgba(51, 65, 85, 0.9);
363
+ }
364
+
365
+ th {
366
+ background: radial-gradient(circle at 0 0, rgba(148, 163, 184, 0.22) 0, rgba(15, 23, 42, 0.98) 70%);
367
+ text-align: left;
368
+ font-weight: 600;
369
+ color: #e5e7eb;
370
+ position: sticky;
371
+ top: 0;
372
+ z-index: 1;
373
+ }
374
+
375
+ td {
376
+ color: var(--text-main);
377
+ vertical-align: top;
378
+ }
379
+
380
+ tr:nth-child(even) td {
381
+ background: rgba(15, 23, 42, 0.92);
382
+ }
383
+
384
+ tr:nth-child(odd) td {
385
+ background: rgba(15, 23, 42, 0.86);
386
+ }
387
+
388
+ tr:hover td {
389
+ background: rgba(30, 64, 175, 0.6);
390
+ }
391
+
392
+ ul {
393
+ list-style: none;
394
+ padding-left: 0;
395
+ font-size: 13px;
396
+ color: var(--text-main);
397
+ }
398
+
399
+ ul li {
400
+ margin-bottom: 7px;
401
+ padding-left: 14px;
402
+ position: relative;
403
+ }
404
+
405
+ ul li::before {
406
+ content: 'β€’';
407
+ position: absolute;
408
+ left: 0;
409
+ color: var(--accent);
410
+ }
411
+
412
+ footer {
413
+ text-align: center;
414
+ color: var(--text-subtle);
415
+ font-size: 11px;
416
+ margin-top: 28px;
417
+ }
418
+
419
+ footer span {
420
+ color: var(--accent);
421
+ font-weight: 500;
422
+ }
423
+
424
+ @media (max-width: 768px) {
425
+ body {
426
+ padding: 18px 12px 28px;
427
+ }
428
+
429
+ header {
430
+ padding: 18px 16px 16px;
431
+ }
432
+
433
+ .header-inner {
434
+ flex-direction: column;
435
+ align-items: flex-start;
436
+ gap: 10px;
437
+ }
438
+
439
+ .timestamp-group {
440
+ text-align: left;
441
+ }
442
+
443
+ .metrics-grid {
444
+ grid-template-columns: repeat(2, minmax(0, 1fr));
445
+ }
446
+ }
447
+
448
+ @media (max-width: 520px) {
449
+ .metrics-grid {
450
+ grid-template-columns: minmax(0, 1fr);
451
+ }
452
+ }
108
453
  </style>
109
454
  </head>
110
455
  <body>
111
456
  <div class="container">
112
457
  <header>
113
- <h1>πŸ“Š Package Analysis Report</h1>
114
- <div class="timestamp">Generated: ${new Date(result.timestamp).toLocaleString()}</div>
458
+ <div class="header-inner">
459
+ <div>
460
+ <h1><span class="icon">πŸ“Š</span> Package Analysis Report</h1>
461
+ <p class="header-subtitle">High-signal insights into your JavaScript bundle: size, composition, and optimization opportunities.</p>
462
+ <div class="badge-row">
463
+ <span class="badge badge-accent"><span class="badge-dot"></span> Bundle Health Overview</span>
464
+ <span class="badge">Metrics, duplicates, and tree-shaking diagnostics</span>
465
+ ${baseline ? '<span class="badge">Baseline comparison enabled</span>' : ''}
466
+ </div>
467
+ </div>
468
+ <div class="timestamp-group">
469
+ <div>
470
+ <div class="timestamp-label">Current Run</div>
471
+ <div class="timestamp-value">${new Date(result.timestamp).toLocaleString()}</div>
472
+ </div>
473
+ ${baseline
474
+ ? `<div style="margin-top:8px;">
475
+ <div class="timestamp-label">Baseline</div>
476
+ <div class="timestamp-value">${new Date(baseline.timestamp).toLocaleString()}</div>
477
+ </div>`
478
+ : ''}
479
+ </div>
480
+ </div>
115
481
  </header>
116
482
 
117
483
  <div class="metrics-grid">
118
484
  <div class="metric-card">
119
485
  <div class="metric-label">Total Size</div>
120
486
  <div class="metric-value">${(result.metrics.totalSize / 1024 / 1024).toFixed(2)} MB</div>
487
+ ${formatDeltaHtmlMb(baseline?.metrics.totalSize, result.metrics.totalSize)}
121
488
  </div>
122
489
  <div class="metric-card">
123
490
  <div class="metric-label">Gzip Size</div>
124
491
  <div class="metric-value">${(result.metrics.totalGzipSize / 1024 / 1024).toFixed(2)} MB</div>
492
+ ${formatDeltaHtmlMb(baseline?.metrics.totalGzipSize, result.metrics.totalGzipSize)}
125
493
  </div>
126
494
  <div class="metric-card">
127
495
  <div class="metric-label">Modules</div>
128
496
  <div class="metric-value">${result.metrics.moduleCount}</div>
497
+ ${formatDeltaHtmlCount(baseline?.metrics.moduleCount, result.metrics.moduleCount)}
129
498
  </div>
130
499
  <div class="metric-card">
131
500
  <div class="metric-label">Chunks</div>
132
501
  <div class="metric-value">${result.metrics.chunkCount}</div>
502
+ ${formatDeltaHtmlCount(baseline?.metrics.chunkCount, result.metrics.chunkCount)}
133
503
  </div>
134
504
  <div class="metric-card">
135
505
  <div class="metric-label">Avg Module Size</div>
@@ -143,29 +513,81 @@ function generateHTML(result) {
143
513
 
144
514
  ${result.recommendations.length > 0 ? `
145
515
  <div class="section">
146
- <h2>πŸ’‘ Recommendations</h2>
147
- ${recommendations}
516
+ <div class="section-inner">
517
+ <h2>
518
+ <span>πŸ’‘ Recommendations</span>
519
+ <span class="section-tag">Optimization guidance</span>
520
+ </h2>
521
+ ${recommendations}
522
+ </div>
148
523
  </div>
149
524
  ` : ''}
150
525
 
151
526
  <div class="section">
152
- <h2>πŸ“¦ Top 10 Modules by Size</h2>
153
- <table>
154
- <thead>
155
- <tr>
156
- <th>Module Name</th>
157
- <th>Size</th>
158
- <th>Percentage</th>
159
- </tr>
160
- </thead>
161
- <tbody>
162
- ${topModules}
163
- </tbody>
164
- </table>
527
+ <div class="section-inner">
528
+ <h2>
529
+ <span>πŸ“¦ Top 10 Modules by Size</span>
530
+ <span class="section-tag">Heaviest contributors</span>
531
+ </h2>
532
+ <table>
533
+ <thead>
534
+ <tr>
535
+ <th>Module Name</th>
536
+ <th>Size</th>
537
+ <th>Percentage</th>
538
+ </tr>
539
+ </thead>
540
+ <tbody>
541
+ ${topModules}
542
+ </tbody>
543
+ </table>
544
+ </div>
545
+ </div>
546
+
547
+ <div class="section">
548
+ <div class="section-inner">
549
+ <h2>
550
+ <span>πŸ” Duplicate Modules</span>
551
+ <span class="section-tag">De-duplication opportunities</span>
552
+ </h2>
553
+ ${result.duplicates.length === 0
554
+ ? '<p>No duplicate modules detected.</p>'
555
+ : `
556
+ <table>
557
+ <thead>
558
+ <tr>
559
+ <th>Count</th>
560
+ <th>Total Size</th>
561
+ <th>Potential Savings</th>
562
+ <th>Example Names</th>
563
+ </tr>
564
+ </thead>
565
+ <tbody>
566
+ ${duplicates}
567
+ </tbody>
568
+ </table>
569
+ `}
570
+ </div>
571
+ </div>
572
+
573
+ <div class="section">
574
+ <div class="section-inner">
575
+ <h2>
576
+ <span>🌳 Tree-Shaking Issues</span>
577
+ <span class="section-tag">Modern module usage</span>
578
+ </h2>
579
+ ${result.treeshakingIssues.length === 0
580
+ ? '<p>No obvious tree-shaking issues detected.</p>'
581
+ : `
582
+ <ul>
583
+ ${treeshakingIssues}
584
+ </ul>
585
+ `}
586
+ </div>
165
587
  </div>
166
588
 
167
589
  <footer>
168
- <p>Package Analyzer Plus v1.0.0 - Advanced Package Analysis Tool</p>
590
+ <p><span>Packlyze</span> Β· Advanced JavaScript bundle analysis</p>
169
591
  </footer>
170
592
  </div>
171
593
  </body>
@@ -182,4 +604,24 @@ function escapeHtml(text) {
182
604
  };
183
605
  return text.replace(/[&<>"']/g, char => map[char]);
184
606
  }
607
+ function formatDeltaHtmlMb(baselineBytes, currentBytes) {
608
+ if (baselineBytes === undefined || currentBytes === undefined)
609
+ return '';
610
+ const diffMb = (currentBytes - baselineBytes) / 1024 / 1024;
611
+ if (Math.abs(diffMb) < 0.01)
612
+ return '';
613
+ const sign = diffMb > 0 ? '+' : '-';
614
+ const cls = diffMb > 0 ? 'delta-negative' : 'delta-positive';
615
+ return `<div class="metric-delta ${cls}">${sign}${Math.abs(diffMb).toFixed(2)} MB vs baseline</div>`;
616
+ }
617
+ function formatDeltaHtmlCount(baseline, current) {
618
+ if (baseline === undefined || current === undefined)
619
+ return '';
620
+ const diff = current - baseline;
621
+ if (diff === 0)
622
+ return '';
623
+ const sign = diff > 0 ? '+' : '-';
624
+ const cls = diff > 0 ? 'delta-negative' : 'delta-positive';
625
+ return `<div class="metric-delta ${cls}">${sign}${Math.abs(diff)} vs baseline</div>`;
626
+ }
185
627
  //# sourceMappingURL=reports.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"reports.js","sourceRoot":"","sources":["../../src/visualization/reports.ts"],"names":[],"mappings":";;;;;AAGA,gDAGC;AAND,4CAAoB;AAGpB,SAAgB,kBAAkB,CAAC,MAAsB,EAAE,UAAkB;IAC3E,MAAM,IAAI,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;IAClC,YAAE,CAAC,aAAa,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;AACrC,CAAC;AAED,SAAS,YAAY,CAAC,MAAsB;IAC1C,MAAM,eAAe,GAAG,MAAM,CAAC,eAAe;SAC3C,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;mCACmB,GAAG,CAAC,QAAQ;gCACf,GAAG,CAAC,QAAQ,KAAK,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI;;qCAExE,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC;4CAChB,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC;;;KAG7D,CAAC;SACD,IAAI,CAAC,EAAE,CAAC,CAAC;IAEZ,MAAM,UAAU,GAAG,MAAM,CAAC,WAAW,CAAC,OAAO;SAC1C,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC;SACZ,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;;cAEA,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;cAC7B,CAAC,CAAC,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;cAC1B,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC;;KAEhC,CAAC;SACD,IAAI,CAAC,EAAE,CAAC,CAAC;IAEZ,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;0CAgFiC,IAAI,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,cAAc,EAAE;;;;;;oCAMjD,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;;;;oCAInD,CAAC,MAAM,CAAC,OAAO,CAAC,aAAa,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;;;;oCAIvD,MAAM,CAAC,OAAO,CAAC,WAAW;;;;oCAI1B,MAAM,CAAC,OAAO,CAAC,UAAU;;;;oCAIzB,CAAC,MAAM,CAAC,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;;;;oCAIpD,CAAC,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;;;;MAInF,MAAM,CAAC,eAAe,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;;;UAGhC,eAAe;;KAEpB,CAAC,CAAC,CAAC,EAAE;;;;;;;;;;;;;YAaE,UAAU;;;;;;;;;;;GAWnB,CAAC;AACJ,CAAC;AAED,SAAS,UAAU,CAAC,IAAY;IAC9B,MAAM,GAAG,GAA4B;QACnC,GAAG,EAAE,OAAO;QACZ,GAAG,EAAE,MAAM;QACX,GAAG,EAAE,MAAM;QACX,GAAG,EAAE,QAAQ;QACb,GAAG,EAAE,QAAQ;KACd,CAAC;IACF,OAAO,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;AACrD,CAAC"}
1
+ {"version":3,"file":"reports.js","sourceRoot":"","sources":["../../src/visualization/reports.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "packlyze",
3
- "version": "1.0.5",
3
+ "version": "2.0.1",
4
4
  "description": "Advanced bundle analyzer with insights, recommendations, and historical tracking",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",