@stacksjs/stx 0.2.0 → 0.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (275) hide show
  1. package/dist/a11y.d.ts +109 -5
  2. package/dist/analytics.d.ts +40 -0
  3. package/dist/animation.d.ts +90 -0
  4. package/dist/app.d.ts +51 -0
  5. package/dist/ast.d.ts +286 -0
  6. package/dist/async-components.d.ts +101 -0
  7. package/dist/auth.d.ts +1 -3
  8. package/dist/browser-composables.d.ts +314 -0
  9. package/dist/build-optimizer.d.ts +126 -0
  10. package/dist/build-views.d.ts +37 -0
  11. package/dist/bundle-analyzer/collector.d.ts +66 -0
  12. package/dist/bundle-analyzer/index.d.ts +60 -0
  13. package/dist/bundle-analyzer/report.d.ts +39 -0
  14. package/dist/bundle-analyzer/treemap.d.ts +19 -0
  15. package/dist/bundle-analyzer.js +499 -0
  16. package/dist/caching.d.ts +7 -0
  17. package/dist/cli.js +10880 -1199
  18. package/dist/client/directive.d.ts +10 -0
  19. package/dist/client/index.d.ts +7 -0
  20. package/dist/client/router.d.ts +36 -0
  21. package/dist/client/stx-router.browser.d.ts +0 -0
  22. package/dist/client-script.d.ts +22 -0
  23. package/dist/component-hmr.d.ts +120 -0
  24. package/dist/components.d.ts +23 -1
  25. package/dist/composables/index.d.ts +277 -0
  26. package/dist/composables/use-battery.d.ts +46 -0
  27. package/dist/composables/use-broadcast-channel.d.ts +58 -0
  28. package/dist/composables/use-clipboard.d.ts +34 -0
  29. package/dist/composables/use-cookie.d.ts +70 -0
  30. package/dist/composables/use-device-orientation.d.ts +109 -0
  31. package/dist/composables/use-event-source.d.ts +77 -0
  32. package/dist/composables/use-eye-dropper.d.ts +107 -0
  33. package/dist/composables/use-fetch.d.ts +84 -0
  34. package/dist/composables/use-fullscreen.d.ts +47 -0
  35. package/dist/composables/use-geolocation.d.ts +62 -0
  36. package/dist/composables/use-idle.d.ts +84 -0
  37. package/dist/composables/use-intersection-observer.d.ts +81 -0
  38. package/dist/composables/use-keyboard.d.ts +100 -0
  39. package/dist/composables/use-media-query.d.ts +56 -0
  40. package/dist/composables/use-mouse.d.ts +64 -0
  41. package/dist/composables/use-mutation-observer.d.ts +101 -0
  42. package/dist/composables/use-network.d.ts +40 -0
  43. package/dist/composables/use-notification.d.ts +89 -0
  44. package/dist/composables/use-permissions.d.ts +109 -0
  45. package/dist/composables/use-resize-observer.d.ts +60 -0
  46. package/dist/composables/use-share.d.ts +70 -0
  47. package/dist/composables/use-speech.d.ts +117 -0
  48. package/dist/composables/use-storage.d.ts +64 -0
  49. package/dist/composables/use-text-selection.d.ts +97 -0
  50. package/dist/composables/use-wake-lock.d.ts +85 -0
  51. package/dist/composables/use-websocket.d.ts +69 -0
  52. package/dist/composables/use-window.d.ts +84 -0
  53. package/dist/composables.d.ts +268 -0
  54. package/dist/composition-api.d.ts +190 -0
  55. package/dist/computed.d.ts +137 -0
  56. package/dist/conditionals.d.ts +14 -2
  57. package/dist/config.d.ts +35 -2
  58. package/dist/craft-bridge.d.ts +319 -0
  59. package/dist/craft-compiler.d.ts +229 -0
  60. package/dist/craft-components.d.ts +411 -0
  61. package/dist/craft-entry.d.ts +5 -0
  62. package/dist/craft-ssr.d.ts +134 -0
  63. package/dist/craft.js +1553 -0
  64. package/dist/csp.d.ts +229 -0
  65. package/dist/database.d.ts +407 -0
  66. package/dist/database.js +5 -0
  67. package/dist/defer.d.ts +4 -0
  68. package/dist/deploy/config-generators.d.ts +75 -0
  69. package/dist/deploy/index.d.ts +84 -0
  70. package/dist/deploy/netlify.d.ts +109 -0
  71. package/dist/dev-server/crosswind.d.ts +54 -0
  72. package/dist/dev-server/index.d.ts +7 -0
  73. package/dist/dev-server/keyboard-shortcuts.d.ts +34 -0
  74. package/dist/dev-server/native-window.d.ts +40 -0
  75. package/dist/dev-server/port-utils.d.ts +27 -0
  76. package/dist/dev-server/terminal-colors.d.ts +60 -0
  77. package/dist/dev-server/theme-selector.d.ts +32 -0
  78. package/dist/dev-server/types.d.ts +92 -0
  79. package/dist/dev-server.d.ts +21 -0
  80. package/dist/devtools.d.ts +142 -0
  81. package/dist/directive-api.d.ts +111 -0
  82. package/dist/dynamic-components.d.ts +14 -0
  83. package/dist/edge-runtime.d.ts +200 -0
  84. package/dist/env.d.ts +9 -0
  85. package/dist/error-boundaries.d.ts +71 -0
  86. package/dist/error-handling.d.ts +1 -101
  87. package/dist/errors/codes.d.ts +99 -0
  88. package/dist/errors/formatter.d.ts +64 -0
  89. package/dist/errors/index.d.ts +56 -0
  90. package/dist/errors/logger.d.ts +74 -0
  91. package/dist/errors/sanitizer.d.ts +43 -0
  92. package/dist/errors/types.d.ts +79 -0
  93. package/dist/events.d.ts +106 -0
  94. package/dist/expressions.d.ts +86 -11
  95. package/dist/forms-validation.d.ts +173 -0
  96. package/dist/forms.d.ts +157 -8
  97. package/dist/head.d.ts +225 -0
  98. package/dist/heatmap.d.ts +125 -0
  99. package/dist/hot-reload.d.ts +87 -0
  100. package/dist/hydration-runtime.d.ts +47 -0
  101. package/dist/hydration.d.ts +161 -0
  102. package/dist/i18n.d.ts +239 -3
  103. package/dist/image-optimization/build-plugin.d.ts +53 -0
  104. package/dist/image-optimization/component.d.ts +46 -0
  105. package/dist/image-optimization/directive.d.ts +30 -0
  106. package/dist/image-optimization/index.d.ts +86 -0
  107. package/dist/image-optimization/processor.d.ts +112 -0
  108. package/dist/includes.d.ts +94 -9
  109. package/dist/index.d.ts +63 -3
  110. package/dist/index.js +11603 -1318
  111. package/dist/init.d.ts +32 -2
  112. package/dist/interactive.d.ts +14 -0
  113. package/dist/internal-markdown.d.ts +22 -0
  114. package/dist/jsx-runtime.d.ts +110 -0
  115. package/dist/keep-alive.d.ts +87 -0
  116. package/dist/lazy-loader.d.ts +122 -0
  117. package/dist/loading-indicator.d.ts +40 -0
  118. package/dist/loops.d.ts +22 -1
  119. package/dist/media/client/blur-up.d.ts +65 -0
  120. package/dist/media/client/index.d.ts +77 -0
  121. package/dist/media/client/lazy-load.d.ts +73 -0
  122. package/dist/media/client/upload-handler.d.ts +79 -0
  123. package/dist/media/image/component.d.ts +46 -0
  124. package/dist/media/image/directive.d.ts +9 -0
  125. package/dist/media/image/editing.d.ts +212 -0
  126. package/dist/media/image/index.d.ts +118 -0
  127. package/dist/media/image/placeholder.d.ts +78 -0
  128. package/dist/media/image/processor/cache.d.ts +32 -0
  129. package/dist/media/image/processor/index.d.ts +12 -0
  130. package/dist/media/image/processor/optimizer.d.ts +13 -0
  131. package/dist/media/image/processor/responsive.d.ts +17 -0
  132. package/dist/media/image/srcset.d.ts +158 -0
  133. package/dist/media/index.d.ts +295 -0
  134. package/dist/media/manager/embed.d.ts +25 -0
  135. package/dist/media/protected/component.d.ts +34 -0
  136. package/dist/media/protected/index.d.ts +34 -0
  137. package/dist/media/protected/signature.d.ts +72 -0
  138. package/dist/media/shared/cache.d.ts +54 -0
  139. package/dist/media/shared/hash.d.ts +24 -0
  140. package/dist/media/shared/index.d.ts +2 -0
  141. package/dist/media/types.d.ts +1051 -0
  142. package/dist/media/upload/component.d.ts +23 -0
  143. package/dist/media/upload/index.d.ts +1 -0
  144. package/dist/media/video/directive.d.ts +9 -0
  145. package/dist/media/video/index.d.ts +47 -0
  146. package/dist/media/video/processor/cache.d.ts +33 -0
  147. package/dist/media/video/processor/index.d.ts +21 -0
  148. package/dist/media/video/processor/streaming.d.ts +19 -0
  149. package/dist/media/video/processor/thumbnail.d.ts +28 -0
  150. package/dist/media/video/processor/transcoder.d.ts +9 -0
  151. package/dist/middleware.d.ts +42 -3
  152. package/dist/native-build.d.ts +74 -0
  153. package/dist/parser/directive-parser.d.ts +79 -0
  154. package/dist/parser/expression-parser.d.ts +59 -0
  155. package/dist/parser/index.d.ts +35 -0
  156. package/dist/parser/tokenizer.d.ts +81 -0
  157. package/dist/partial-hydration.d.ts +88 -0
  158. package/dist/performance-utils.d.ts +146 -3
  159. package/dist/plugin-system.d.ts +128 -0
  160. package/dist/precompiler.d.ts +108 -0
  161. package/dist/production-build.d.ts +199 -0
  162. package/dist/props.d.ts +199 -0
  163. package/dist/pwa/audit.d.ts +42 -0
  164. package/dist/pwa/directives.d.ts +29 -0
  165. package/dist/pwa/icons.d.ts +39 -0
  166. package/dist/pwa/index.d.ts +59 -0
  167. package/dist/pwa/inject.d.ts +22 -0
  168. package/dist/pwa/manifest.d.ts +104 -0
  169. package/dist/pwa/offline.d.ts +8 -0
  170. package/dist/pwa/precache.d.ts +29 -0
  171. package/dist/pwa/service-worker.d.ts +21 -0
  172. package/dist/pwa/workbox-strategies.d.ts +100 -0
  173. package/dist/pwa/workbox.d.ts +52 -0
  174. package/dist/pwa.d.ts +51 -0
  175. package/dist/pwa.js +8124 -0
  176. package/dist/reactive-bindings.d.ts +24 -0
  177. package/dist/reactive.d.ts +100 -0
  178. package/dist/reactivity.d.ts +253 -0
  179. package/dist/route-middleware.d.ts +232 -0
  180. package/dist/router.d.ts +31 -0
  181. package/dist/routes.d.ts +0 -7
  182. package/dist/runtime.d.ts +140 -0
  183. package/dist/safe-evaluator.d.ts +117 -3
  184. package/dist/scaffolding.d.ts +113 -0
  185. package/dist/seo.d.ts +120 -7
  186. package/dist/server-components.d.ts +134 -0
  187. package/dist/signals.d.ts +501 -0
  188. package/dist/slots.d.ts +63 -0
  189. package/dist/source-maps.d.ts +117 -0
  190. package/dist/ssg.d.ts +157 -0
  191. package/dist/ssg.js +6831 -0
  192. package/dist/ssr.d.ts +107 -0
  193. package/dist/state-management.d.ts +324 -0
  194. package/dist/stores-client.d.ts +70 -0
  195. package/dist/story/addons.d.ts +123 -0
  196. package/dist/story/analytics.d.ts +92 -0
  197. package/dist/story/auto-stories.d.ts +38 -0
  198. package/dist/story/bookmarks.d.ts +53 -0
  199. package/dist/story/bun-test.d.ts +44 -0
  200. package/dist/story/cli.d.ts +34 -0
  201. package/dist/story/collect/analyzer.d.ts +33 -0
  202. package/dist/story/collect/index.d.ts +27 -0
  203. package/dist/story/collect/parser.d.ts +17 -0
  204. package/dist/story/collect/scanner.d.ts +13 -0
  205. package/dist/story/collect/tree.d.ts +17 -0
  206. package/dist/story/commands/build.d.ts +14 -0
  207. package/dist/story/commands/dev.d.ts +16 -0
  208. package/dist/story/commands/index.d.ts +6 -0
  209. package/dist/story/commands/preview.d.ts +15 -0
  210. package/dist/story/compiled-output.d.ts +26 -0
  211. package/dist/story/composition.d.ts +47 -0
  212. package/dist/story/config-watcher.d.ts +26 -0
  213. package/dist/story/config.d.ts +26 -0
  214. package/dist/story/context.d.ts +21 -0
  215. package/dist/story/controls/index.d.ts +54 -0
  216. package/dist/story/crosswind.d.ts +29 -0
  217. package/dist/story/desktop-preview.d.ts +34 -0
  218. package/dist/story/docs-generator.d.ts +30 -0
  219. package/dist/story/errors.d.ts +47 -0
  220. package/dist/story/figma-export.d.ts +169 -0
  221. package/dist/story/generator.d.ts +21 -0
  222. package/dist/story/hmr.d.ts +64 -0
  223. package/dist/story/hot-swap.d.ts +35 -0
  224. package/dist/story/index.d.ts +51 -0
  225. package/dist/story/interactions.d.ts +52 -0
  226. package/dist/story/keyboard-shortcuts.d.ts +34 -0
  227. package/dist/story/output.d.ts +85 -0
  228. package/dist/story/performance.d.ts +76 -0
  229. package/dist/story/presets.d.ts +62 -0
  230. package/dist/story/props-validation.d.ts +45 -0
  231. package/dist/story/renderer.d.ts +53 -0
  232. package/dist/story/search-index.d.ts +47 -0
  233. package/dist/story/search.d.ts +45 -0
  234. package/dist/story/server.d.ts +21 -0
  235. package/dist/story/setup.d.ts +47 -0
  236. package/dist/story/snapshots.d.ts +65 -0
  237. package/dist/story/testing.d.ts +58 -0
  238. package/dist/story/theme.d.ts +68 -0
  239. package/dist/story/types.d.ts +249 -0
  240. package/dist/story/ui/code-panel.d.ts +42 -0
  241. package/dist/story/ui/controls-panel.d.ts +25 -0
  242. package/dist/story/ui/index.d.ts +4 -0
  243. package/dist/story/ui/navigation.d.ts +55 -0
  244. package/dist/story/ui/preview.d.ts +46 -0
  245. package/dist/story/visual-testing.d.ts +45 -0
  246. package/dist/streaming.d.ts +82 -2
  247. package/dist/suspense.d.ts +83 -0
  248. package/dist/teleport.d.ts +9 -0
  249. package/dist/testing.d.ts +289 -0
  250. package/dist/transitions.d.ts +87 -0
  251. package/dist/type-checker.d.ts +109 -0
  252. package/dist/types/component-types.d.ts +129 -0
  253. package/dist/types/config-types.d.ts +336 -0
  254. package/dist/types/context-types.d.ts +99 -0
  255. package/dist/types/csp-types.d.ts +79 -0
  256. package/dist/types/directive-types.d.ts +259 -0
  257. package/dist/types/index.d.ts +98 -0
  258. package/dist/types/pwa-types.d.ts +218 -0
  259. package/dist/types.d.ts +1 -315
  260. package/dist/typescript-templates.d.ts +178 -0
  261. package/dist/utils.d.ts +52 -6
  262. package/dist/validator.d.ts +77 -0
  263. package/dist/variable-extractor.d.ts +39 -0
  264. package/dist/view-composers.d.ts +154 -9
  265. package/dist/virtual-scrolling.d.ts +103 -0
  266. package/dist/visual-editor.d.ts +209 -0
  267. package/dist/visual-testing.d.ts +109 -0
  268. package/dist/visual-testing.js +126 -0
  269. package/dist/vue-template.d.ts +16 -0
  270. package/dist/web-components/css-scoping.d.ts +54 -0
  271. package/dist/web-components/index.d.ts +20 -0
  272. package/dist/web-components/reactive-generator.d.ts +72 -0
  273. package/dist/web-components.d.ts +222 -2
  274. package/dist/x-element.d.ts +35 -0
  275. package/package.json +41 -11
@@ -0,0 +1,60 @@
1
+ import { collectBundleStats, formatBytes, parseSize } from './collector';
2
+ import { generateReport, analyzeBundle } from './report';
3
+ import { generateTreemap, openInBrowser } from './treemap';
4
+ /**
5
+ * Analyze a bundle directory and generate a report
6
+ */
7
+ export declare function analyze(options?: AnalyzeOptions): Promise<{
8
+ stats: ReturnType<typeof collectBundleStats> extends Promise<infer T> ? T : never
9
+ report: string
10
+ outputPath?: string
11
+ exceedsThreshold: boolean
12
+ }>;
13
+ /**
14
+ * Quick summary of bundle size
15
+ */
16
+ export declare function getBundleSummary(directory: string): Promise<{
17
+ totalSize: number
18
+ totalSizeFormatted: string
19
+ gzipSize: number
20
+ gzipSizeFormatted: string
21
+ moduleCount: number
22
+ chunkCount: number
23
+ }>;
24
+ export declare interface AnalyzeOptions {
25
+ directory?: string
26
+ output?: string
27
+ format?: 'html' | 'json' | 'text' | 'markdown'
28
+ open?: boolean
29
+ gzip?: boolean
30
+ threshold?: string | number
31
+ recommendations?: boolean
32
+ topModules?: number
33
+ parseImports?: boolean
34
+ }
35
+ export {
36
+ collectBundleStats,
37
+ formatBytes,
38
+ parseSize,
39
+ percentage,
40
+ type ModuleInfo,
41
+ type ModuleType,
42
+ type ChunkInfo,
43
+ type DuplicateModule,
44
+ type BundleStats,
45
+ type CollectorOptions,
46
+ } from './collector';
47
+ export {
48
+ generateReport,
49
+ analyzeBundle,
50
+ getModuleRecommendation,
51
+ type ReportOptions,
52
+ type AnalysisResult,
53
+ type AnalysisIssue,
54
+ type Recommendation,
55
+ } from './report';
56
+ export {
57
+ generateTreemap,
58
+ openInBrowser,
59
+ type TreemapOptions,
60
+ } from './treemap';
@@ -0,0 +1,39 @@
1
+ import type { BundleStats } from './collector';
2
+ /**
3
+ * Generate a report from bundle statistics
4
+ */
5
+ export declare function generateReport(stats: BundleStats, options: ReportOptions): string;
6
+ /**
7
+ * Analyze bundle for issues and recommendations
8
+ */
9
+ export declare function analyzeBundle(stats: BundleStats, options: ReportOptions): AnalysisResult;
10
+ /**
11
+ * Get recommendations for a specific module
12
+ */
13
+ export declare function getModuleRecommendation(modulePath: string): Recommendation | null;
14
+ // ============================================================================
15
+ // Types
16
+ // ============================================================================
17
+ export declare interface ReportOptions {
18
+ format: 'text' | 'json' | 'markdown'
19
+ threshold?: number
20
+ recommendations?: boolean
21
+ topModules?: number
22
+ showGzip?: boolean
23
+ }
24
+ export declare interface AnalysisResult {
25
+ score: number
26
+ issues: AnalysisIssue[]
27
+ recommendations: Recommendation[]
28
+ }
29
+ export declare interface AnalysisIssue {
30
+ severity: 'error' | 'warning' | 'info'
31
+ message: string
32
+ details?: string
33
+ }
34
+ export declare interface Recommendation {
35
+ title: string
36
+ description: string
37
+ impact: 'high' | 'medium' | 'low'
38
+ effort: 'low' | 'medium' | 'high'
39
+ }
@@ -0,0 +1,19 @@
1
+ import type { BundleStats } from './collector';
2
+ /**
3
+ * Generate interactive HTML treemap
4
+ */
5
+ export declare function generateTreemap(stats: BundleStats, options?: TreemapOptions): string;
6
+ /**
7
+ * Open URL in default browser
8
+ */
9
+ export declare function openInBrowser(filePath: string): void;
10
+ // ============================================================================
11
+ // Types
12
+ // ============================================================================
13
+ export declare interface TreemapOptions {
14
+ output?: string
15
+ open?: boolean
16
+ title?: string
17
+ gzip?: boolean
18
+ colorScheme?: 'default' | 'pastel' | 'monochrome'
19
+ }
@@ -0,0 +1,499 @@
1
+ // @bun
2
+ import v from"fs";import H from"path";import{gzipSync as z}from"zlib";import{createHash as g}from"crypto";var D={".js":"js",".mjs":"js",".cjs":"js",".ts":"js",".jsx":"js",".tsx":"js",".css":"css",".scss":"css",".sass":"css",".less":"css",".html":"html",".htm":"html",".png":"image",".jpg":"image",".jpeg":"image",".gif":"image",".svg":"image",".webp":"image",".avif":"image",".ico":"image",".woff":"font",".woff2":"font",".ttf":"font",".eot":"font",".otf":"font"},b=[/node_modules/,/vendor/,/bower_components/,/\.min\./],B=[/index\.(js|ts|html)$/,/main\.(js|ts)$/,/app\.(js|ts)$/,/entry\.(js|ts)$/];async function L(Z,$={}){let{includeSourceMaps:X=!1,parseImports:j=!0,detectDuplicates:U=!0,topModulesCount:Q=20}=$;if(!v.existsSync(Z))throw Error(`Build directory not found: ${Z}`);if(!v.statSync(Z).isDirectory())throw Error(`Not a directory: ${Z}`);let K=await k(Z,X),J=[],F=[];for(let A of K)try{let O=await f(A,Z,j);J.push(O)}catch(O){F.push(`Failed to process ${A}: ${O}`)}let Y=c(J,Z),V=J.reduce((A,O)=>A+O.size,0),_=J.reduce((A,O)=>A+O.gzipSize,0),w=m(J),G=U?p(J):[],C=[...J].sort((A,O)=>O.size-A.size).slice(0,Q);return{timestamp:Date.now(),buildDir:H.resolve(Z),chunks:Y,totalSize:V,totalGzipSize:_,moduleCount:J.length,duplicates:G,byType:w,largestModules:C,warnings:F}}async function k(Z,$){let X=[];async function j(U){let Q=await v.promises.readdir(U,{withFileTypes:!0});for(let q of Q){let K=H.join(U,q.name);if(q.isDirectory()){if(!q.name.startsWith(".")&&q.name!=="node_modules")await j(K)}else if(q.isFile()){if(!$&&q.name.endsWith(".map"))continue;X.push(K)}}}return await j(Z),X}async function f(Z,$,X){let j=await v.promises.readFile(Z),U=H.relative($,Z),Q=H.extname(Z).toLowerCase(),q=j.length,K=y(j),J=h(j,Q),F=g("md5").update(j).digest("hex").slice(0,8),Y=D[Q]||"other",V=[];if(X&&Y==="js")V.push(...d(j.toString("utf-8")));return{id:U,path:U,size:q,gzipSize:K,parsedSize:J,extension:Q,type:Y,imports:V,importedBy:[],hash:F}}function y(Z){try{let $=z(Z,{level:9}).length;return Math.min($,Z.length)}catch{return Z.length}}function h(Z,$){if($.includes(".min.")||Z.length<1000)return Z.length;let j=D[$];if(j==="js")return Math.round(Z.length*0.6);if(j==="css")return Math.round(Z.length*0.7);return Z.length}function d(Z){let $=[],X=/import\s+(?:[\w*{}\s,]+\s+from\s+)?['"]([^'"]+)['"]/g,j;while((j=X.exec(Z))!==null)$.push(j[1]);let U=/import\s*\(\s*['"]([^'"]+)['"]\s*\)/g;while((j=U.exec(Z))!==null)$.push(j[1]);let Q=/require\s*\(\s*['"]([^'"]+)['"]\s*\)/g;while((j=Q.exec(Z))!==null)$.push(j[1]);return[...new Set($)]}function c(Z,$){let X=new Map;for(let U of Z){let Q=U.path.split(H.sep),q;if(Q.length===1)q=H.basename(U.path,U.extension);else q=Q[0];let K=X.get(q)||[];K.push(U),X.set(q,K)}let j=[];for(let[U,Q]of X){let q=Q.reduce((Y,V)=>Y+V.size,0),K=Q.reduce((Y,V)=>Y+V.gzipSize,0),J=Q.some((Y)=>B.some((V)=>V.test(Y.path))),F=Q.some((Y)=>b.some((V)=>V.test(Y.path)));j.push({name:U,files:Q.map((Y)=>Y.path),modules:Q,size:q,gzipSize:K,isEntry:J,isVendor:F})}return j.sort((U,Q)=>Q.size-U.size)}function m(Z){let $={js:{count:0,size:0,gzipSize:0},css:{count:0,size:0,gzipSize:0},html:{count:0,size:0,gzipSize:0},image:{count:0,size:0,gzipSize:0},font:{count:0,size:0,gzipSize:0},other:{count:0,size:0,gzipSize:0}};for(let X of Z)$[X.type].count++,$[X.type].size+=X.size,$[X.type].gzipSize+=X.gzipSize;return $}function p(Z){let $=new Map;for(let j of Z){let U=$.get(j.hash)||[];U.push(j),$.set(j.hash,U)}let X=[];for(let[,j]of $)if(j.length>1){let U=j[0];X.push({path:U.path,count:j.length,wastedBytes:U.size*(j.length-1),locations:j.map((Q)=>Q.path)})}return X.sort((j,U)=>U.wastedBytes-j.wastedBytes)}function W(Z){if(Z<1024)return`${Z} B`;if(Z<1048576)return`${(Z/1024).toFixed(2)} KB`;return`${(Z/1048576).toFixed(2)} MB`}function I(Z){let $=Z.match(/^([\d.]+)\s*(B|KB|MB|GB)?$/i);if(!$)return 0;let X=Number.parseFloat($[1]);switch(($[2]||"B").toUpperCase()){case"KB":return X*1024;case"MB":return X*1024*1024;case"GB":return X*1024*1024*1024;default:return X}}function E(Z,$){if($===0)return"0%";return`${(Z/$*100).toFixed(1)}%`}function x(Z,$){switch($.format){case"json":return u(Z,$);case"markdown":return l(Z,$);case"text":default:return r(Z,$)}}function u(Z,$){let X=N(Z,$);return JSON.stringify({timestamp:Z.timestamp,buildDir:Z.buildDir,summary:{totalSize:Z.totalSize,totalSizeFormatted:W(Z.totalSize),totalGzipSize:Z.totalGzipSize,totalGzipSizeFormatted:W(Z.totalGzipSize),moduleCount:Z.moduleCount,chunkCount:Z.chunks.length,duplicateCount:Z.duplicates.length},byType:Object.fromEntries(Object.entries(Z.byType).map(([j,U])=>[j,{...U,sizeFormatted:W(U.size),gzipSizeFormatted:W(U.gzipSize)}])),chunks:Z.chunks.map((j)=>({name:j.name,size:j.size,sizeFormatted:W(j.size),gzipSize:j.gzipSize,gzipSizeFormatted:W(j.gzipSize),moduleCount:j.modules.length,isEntry:j.isEntry,isVendor:j.isVendor})),largestModules:Z.largestModules.slice(0,$.topModules||10).map((j)=>({path:j.path,size:j.size,sizeFormatted:W(j.size),gzipSize:j.gzipSize,gzipSizeFormatted:W(j.gzipSize),type:j.type})),duplicates:Z.duplicates,analysis:X,warnings:Z.warnings},null,2)}function r(Z,$){let X=[],j=$.showGzip!==!1;if(X.push(""),X.push("Bundle Analysis Report"),X.push("\u2550".repeat(50)),X.push(""),X.push("Summary"),X.push("\u2500".repeat(50)),j)X.push(`Total Size: ${W(Z.totalSize)} (${W(Z.totalGzipSize)} gzip)`);else X.push(`Total Size: ${W(Z.totalSize)}`);if(X.push(`Modules: ${Z.moduleCount}`),X.push(`Chunks: ${Z.chunks.length}`),Z.duplicates.length>0)X.push(`Duplicates: ${Z.duplicates.length}`);if(X.push(""),$.threshold&&Z.totalSize>$.threshold)X.push(`\u26A0\uFE0F Bundle exceeds threshold of ${W($.threshold)}!`),X.push("");X.push("Size by Type"),X.push("\u2500".repeat(50));let U=["js","css","html","image","font","other"];for(let q of U){let K=Z.byType[q];if(K.count>0){let J=E(K.size,Z.totalSize),F=j?` (${W(K.gzipSize)} gzip)`:"";X.push(` ${q.padEnd(8)} ${W(K.size).padStart(12)}${F} ${J.padStart(6)} (${K.count} files)`)}}X.push(""),X.push("Chunks"),X.push("\u2500".repeat(50));for(let q of Z.chunks.slice(0,10)){let K=[];if(q.isEntry)K.push("entry");if(q.isVendor)K.push("vendor");let J=K.length>0?` [${K.join(", ")}]`:"",F=j?` (${W(q.gzipSize)} gzip)`:"";X.push(` ${q.name.padEnd(20)} ${W(q.size).padStart(12)}${F}${J}`)}if(Z.chunks.length>10)X.push(` ... and ${Z.chunks.length-10} more chunks`);X.push("");let Q=$.topModules||10;X.push(`Largest Modules (Top ${Q})`),X.push("\u2500".repeat(50));for(let q=0;q<Math.min(Q,Z.largestModules.length);q++){let K=Z.largestModules[q],J=j?` (${W(K.gzipSize)} gzip)`:"";X.push(` ${(q+1).toString().padStart(2)}. ${K.path}`),X.push(` ${W(K.size)}${J}`)}if(X.push(""),Z.duplicates.length>0){X.push("Duplicate Modules"),X.push("\u2500".repeat(50));for(let q of Z.duplicates.slice(0,5))X.push(` ${q.path}`),X.push(` ${q.count} copies, wasting ${W(q.wastedBytes)}`);if(Z.duplicates.length>5)X.push(` ... and ${Z.duplicates.length-5} more duplicates`);X.push("")}if($.recommendations!==!1){let q=N(Z,$);if(q.recommendations.length>0){X.push("Recommendations"),X.push("\u2500".repeat(50));for(let K of q.recommendations.slice(0,5)){let J=K.impact==="high"?"\u26A1":K.impact==="medium"?"\uD83D\uDCCA":"\uD83D\uDCA1";X.push(` ${J} ${K.title}`),X.push(` ${K.description}`)}X.push("")}}if(Z.warnings.length>0){X.push("Warnings"),X.push("\u2500".repeat(50));for(let q of Z.warnings)X.push(` \u26A0\uFE0F ${q}`);X.push("")}return X.join(`
3
+ `)}function l(Z,$){let X=[],j=$.showGzip!==!1;if(X.push("# Bundle Analysis Report"),X.push(""),X.push(`Generated: ${new Date(Z.timestamp).toISOString()}`),X.push(""),X.push("## Summary"),X.push(""),X.push("| Metric | Value |"),X.push("|--------|-------|"),X.push(`| Total Size | ${W(Z.totalSize)} |`),j)X.push(`| Gzip Size | ${W(Z.totalGzipSize)} |`);X.push(`| Modules | ${Z.moduleCount} |`),X.push(`| Chunks | ${Z.chunks.length} |`),X.push(`| Duplicates | ${Z.duplicates.length} |`),X.push(""),X.push("## Size by Type"),X.push(""),X.push("| Type | Size | Gzip | % | Files |"),X.push("|------|------|------|---|-------|");let U=["js","css","html","image","font","other"];for(let q of U){let K=Z.byType[q];if(K.count>0)X.push(`| ${q} | ${W(K.size)} | ${W(K.gzipSize)} | ${E(K.size,Z.totalSize)} | ${K.count} |`)}X.push(""),X.push("## Chunks"),X.push(""),X.push("| Name | Size | Gzip | Modules | Type |"),X.push("|------|------|------|---------|------|");for(let q of Z.chunks.slice(0,15)){let K=q.isEntry?"Entry":q.isVendor?"Vendor":"-";X.push(`| ${q.name} | ${W(q.size)} | ${W(q.gzipSize)} | ${q.modules.length} | ${K} |`)}X.push("");let Q=$.topModules||10;X.push(`## Largest Modules (Top ${Q})`),X.push(""),X.push("| # | Path | Size | Gzip |"),X.push("|---|------|------|------|");for(let q=0;q<Math.min(Q,Z.largestModules.length);q++){let K=Z.largestModules[q];X.push(`| ${q+1} | \`${K.path}\` | ${W(K.size)} | ${W(K.gzipSize)} |`)}if(X.push(""),Z.duplicates.length>0){X.push("## Duplicates"),X.push(""),X.push("| Path | Copies | Wasted |"),X.push("|------|--------|--------|");for(let q of Z.duplicates.slice(0,10))X.push(`| \`${q.path}\` | ${q.count} | ${W(q.wastedBytes)} |`);X.push("")}if($.recommendations!==!1){let q=N(Z,$);if(q.recommendations.length>0){X.push("## Recommendations"),X.push("");for(let K of q.recommendations)X.push(`### ${K.title}`),X.push(""),X.push(K.description),X.push(""),X.push(`- **Impact:** ${K.impact}`),X.push(`- **Effort:** ${K.effort}`),X.push("")}}return X.join(`
4
+ `)}function N(Z,$){let X=[],j=[];if($.threshold&&Z.totalSize>$.threshold)X.push({severity:"error",message:`Bundle size (${W(Z.totalSize)}) exceeds threshold (${W($.threshold)})`});if(Z.totalSize>1048576)X.push({severity:"warning",message:`Bundle is over 1MB (${W(Z.totalSize)})`,details:"Large bundles can significantly impact load time"});if(Z.duplicates.length>0){let K=Z.duplicates.reduce((J,F)=>J+F.wastedBytes,0);X.push({severity:"warning",message:`${Z.duplicates.length} duplicate modules found, wasting ${W(K)}`}),j.push({title:"Remove Duplicate Modules",description:"Consider using import aliases or ensuring consistent package versions to eliminate duplicates.",impact:"medium",effort:"low"})}if(Z.byType.js.size/Z.totalSize>0.8&&Z.totalSize>512000)j.push({title:"Code Splitting",description:"Over 80% of your bundle is JavaScript. Consider splitting code by route or feature.",impact:"high",effort:"medium"});let Q=Z.largestModules.filter((K)=>K.size>102400);if(Q.length>0){X.push({severity:"info",message:`${Q.length} modules are over 100KB`});for(let K of Q){if(K.path.includes("lodash")&&!K.path.includes("lodash-es"))j.push({title:"Use lodash-es instead of lodash",description:"lodash-es supports tree-shaking and can significantly reduce bundle size.",impact:"high",effort:"low"});if(K.path.includes("moment"))j.push({title:"Replace moment.js",description:"Consider using date-fns or dayjs for smaller date handling libraries.",impact:"high",effort:"medium"})}}if(Z.byType.image.size>512000)j.push({title:"Optimize Images",description:`Images account for ${W(Z.byType.image.size)}. Consider using WebP/AVIF formats and responsive images.`,impact:"high",effort:"low"});let q=100;if(Z.totalSize>1048576)q-=20;else if(Z.totalSize>512000)q-=10;if(q-=Math.min(20,Z.duplicates.length*2),q-=Math.min(15,Q.length*3),$.threshold&&Z.totalSize>$.threshold)q-=25;return{score:Math.max(0,q),issues:X,recommendations:j}}var i={lodash:{alternative:"lodash-es or individual imports",savings:"~70%"},moment:{alternative:"date-fns or dayjs",savings:"~90%"},"chart.js":{alternative:"chart.js with tree-shaking",savings:"~50%"},"highlight.js":{alternative:"Selective language imports",savings:"~80%"},fontawesome:{alternative:"Individual icon imports",savings:"~90%"},"material-ui":{alternative:"Named imports from @mui/*",savings:"~60%"}};function n(Z){for(let[$,X]of Object.entries(i))if(Z.includes($))return{title:`Optimize ${$}`,description:`Consider using ${X.alternative}. Potential savings: ${X.savings}`,impact:"high",effort:"low"};return null}var o={default:{js:"#f7df1e",css:"#264de4",html:"#e34c26",image:"#4caf50",font:"#9c27b0",other:"#607d8b",vendor:"#ff5722"},pastel:{js:"#fff3b0",css:"#b0d4ff",html:"#ffb0b0",image:"#b0ffb0",font:"#e0b0ff",other:"#d0d0d0",vendor:"#ffcfb0"},monochrome:{js:"#333333",css:"#555555",html:"#777777",image:"#999999",font:"#bbbbbb",other:"#dddddd",vendor:"#444444"}};function R(Z,$={}){let{title:X="Bundle Analysis",gzip:j=!0,colorScheme:U="default"}=$,Q=o[U],q=a(Z),K=JSON.stringify(q);return`<!DOCTYPE html>
5
+ <html lang="en">
6
+ <head>
7
+ <meta charset="UTF-8">
8
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
9
+ <title>${M(X)}</title>
10
+ <style>
11
+ * {
12
+ box-sizing: border-box;
13
+ margin: 0;
14
+ padding: 0;
15
+ }
16
+
17
+ body {
18
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;
19
+ background: #1a1a2e;
20
+ color: #eee;
21
+ min-height: 100vh;
22
+ }
23
+
24
+ .header {
25
+ background: #16213e;
26
+ padding: 1rem 2rem;
27
+ display: flex;
28
+ justify-content: space-between;
29
+ align-items: center;
30
+ border-bottom: 1px solid #0f3460;
31
+ }
32
+
33
+ .header h1 {
34
+ font-size: 1.5rem;
35
+ font-weight: 500;
36
+ }
37
+
38
+ .stats {
39
+ display: flex;
40
+ gap: 2rem;
41
+ }
42
+
43
+ .stat {
44
+ text-align: center;
45
+ }
46
+
47
+ .stat-value {
48
+ font-size: 1.25rem;
49
+ font-weight: bold;
50
+ color: #e94560;
51
+ }
52
+
53
+ .stat-label {
54
+ font-size: 0.75rem;
55
+ color: #888;
56
+ text-transform: uppercase;
57
+ }
58
+
59
+ .controls {
60
+ background: #16213e;
61
+ padding: 0.75rem 2rem;
62
+ display: flex;
63
+ gap: 1rem;
64
+ align-items: center;
65
+ border-bottom: 1px solid #0f3460;
66
+ }
67
+
68
+ .controls label {
69
+ display: flex;
70
+ align-items: center;
71
+ gap: 0.5rem;
72
+ cursor: pointer;
73
+ }
74
+
75
+ .controls input[type="checkbox"] {
76
+ width: 1rem;
77
+ height: 1rem;
78
+ }
79
+
80
+ .search-box {
81
+ flex: 1;
82
+ max-width: 300px;
83
+ }
84
+
85
+ .search-box input {
86
+ width: 100%;
87
+ padding: 0.5rem 1rem;
88
+ border: 1px solid #0f3460;
89
+ border-radius: 4px;
90
+ background: #1a1a2e;
91
+ color: #eee;
92
+ font-size: 0.875rem;
93
+ }
94
+
95
+ .search-box input:focus {
96
+ outline: none;
97
+ border-color: #e94560;
98
+ }
99
+
100
+ .breadcrumb {
101
+ background: #16213e;
102
+ padding: 0.5rem 2rem;
103
+ display: flex;
104
+ gap: 0.5rem;
105
+ align-items: center;
106
+ font-size: 0.875rem;
107
+ border-bottom: 1px solid #0f3460;
108
+ }
109
+
110
+ .breadcrumb-item {
111
+ color: #888;
112
+ cursor: pointer;
113
+ }
114
+
115
+ .breadcrumb-item:hover {
116
+ color: #e94560;
117
+ }
118
+
119
+ .breadcrumb-item.active {
120
+ color: #eee;
121
+ cursor: default;
122
+ }
123
+
124
+ .breadcrumb-sep {
125
+ color: #444;
126
+ }
127
+
128
+ #treemap {
129
+ width: 100%;
130
+ height: calc(100vh - 180px);
131
+ min-height: 400px;
132
+ }
133
+
134
+ .tooltip {
135
+ position: fixed;
136
+ background: #16213e;
137
+ border: 1px solid #0f3460;
138
+ border-radius: 4px;
139
+ padding: 0.75rem 1rem;
140
+ pointer-events: none;
141
+ z-index: 1000;
142
+ max-width: 400px;
143
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
144
+ }
145
+
146
+ .tooltip-title {
147
+ font-weight: bold;
148
+ margin-bottom: 0.5rem;
149
+ word-break: break-all;
150
+ }
151
+
152
+ .tooltip-row {
153
+ display: flex;
154
+ justify-content: space-between;
155
+ gap: 2rem;
156
+ font-size: 0.875rem;
157
+ color: #888;
158
+ }
159
+
160
+ .tooltip-row span:last-child {
161
+ color: #eee;
162
+ font-weight: 500;
163
+ }
164
+
165
+ .legend {
166
+ position: fixed;
167
+ bottom: 1rem;
168
+ right: 1rem;
169
+ background: #16213e;
170
+ border: 1px solid #0f3460;
171
+ border-radius: 4px;
172
+ padding: 0.75rem 1rem;
173
+ }
174
+
175
+ .legend-title {
176
+ font-size: 0.75rem;
177
+ color: #888;
178
+ margin-bottom: 0.5rem;
179
+ text-transform: uppercase;
180
+ }
181
+
182
+ .legend-item {
183
+ display: flex;
184
+ align-items: center;
185
+ gap: 0.5rem;
186
+ font-size: 0.75rem;
187
+ margin-bottom: 0.25rem;
188
+ }
189
+
190
+ .legend-color {
191
+ width: 12px;
192
+ height: 12px;
193
+ border-radius: 2px;
194
+ }
195
+
196
+ .node {
197
+ cursor: pointer;
198
+ transition: opacity 0.2s;
199
+ }
200
+
201
+ .node:hover {
202
+ opacity: 0.8;
203
+ }
204
+
205
+ .node-label {
206
+ font-size: 11px;
207
+ fill: #000;
208
+ pointer-events: none;
209
+ text-anchor: middle;
210
+ }
211
+ </style>
212
+ </head>
213
+ <body>
214
+ <div class="header">
215
+ <h1>${M(X)}</h1>
216
+ <div class="stats">
217
+ <div class="stat">
218
+ <div class="stat-value" id="total-size">${W(Z.totalSize)}</div>
219
+ <div class="stat-label">Total Size</div>
220
+ </div>
221
+ <div class="stat">
222
+ <div class="stat-value" id="gzip-size">${W(Z.totalGzipSize)}</div>
223
+ <div class="stat-label">Gzip Size</div>
224
+ </div>
225
+ <div class="stat">
226
+ <div class="stat-value">${Z.moduleCount}</div>
227
+ <div class="stat-label">Modules</div>
228
+ </div>
229
+ <div class="stat">
230
+ <div class="stat-value">${Z.chunks.length}</div>
231
+ <div class="stat-label">Chunks</div>
232
+ </div>
233
+ </div>
234
+ </div>
235
+
236
+ <div class="controls">
237
+ <div class="search-box">
238
+ <input type="text" id="search" placeholder="Search modules...">
239
+ </div>
240
+ <label>
241
+ <input type="checkbox" id="show-gzip" ${j?"checked":""}>
242
+ Show Gzip Size
243
+ </label>
244
+ </div>
245
+
246
+ <div class="breadcrumb" id="breadcrumb">
247
+ <span class="breadcrumb-item active">root</span>
248
+ </div>
249
+
250
+ <div id="treemap"></div>
251
+
252
+ <div class="tooltip" id="tooltip" style="display: none;"></div>
253
+
254
+ <div class="legend">
255
+ <div class="legend-title">File Types</div>
256
+ <div class="legend-item">
257
+ <div class="legend-color" style="background: ${Q.js}"></div>
258
+ <span>JavaScript</span>
259
+ </div>
260
+ <div class="legend-item">
261
+ <div class="legend-color" style="background: ${Q.css}"></div>
262
+ <span>CSS</span>
263
+ </div>
264
+ <div class="legend-item">
265
+ <div class="legend-color" style="background: ${Q.html}"></div>
266
+ <span>HTML</span>
267
+ </div>
268
+ <div class="legend-item">
269
+ <div class="legend-color" style="background: ${Q.image}"></div>
270
+ <span>Images</span>
271
+ </div>
272
+ <div class="legend-item">
273
+ <div class="legend-color" style="background: ${Q.font}"></div>
274
+ <span>Fonts</span>
275
+ </div>
276
+ <div class="legend-item">
277
+ <div class="legend-color" style="background: ${Q.other}"></div>
278
+ <span>Other</span>
279
+ </div>
280
+ </div>
281
+
282
+ <script src="https://d3js.org/d3.v7.min.js"></script>
283
+ <script>
284
+ const data = ${K};
285
+ const colors = ${JSON.stringify(Q)};
286
+
287
+ let showGzip = ${j};
288
+ let currentRoot = data;
289
+ let searchTerm = '';
290
+
291
+ const container = document.getElementById('treemap');
292
+ const tooltip = document.getElementById('tooltip');
293
+ const breadcrumb = document.getElementById('breadcrumb');
294
+ const searchInput = document.getElementById('search');
295
+ const showGzipCheckbox = document.getElementById('show-gzip');
296
+
297
+ function formatSize(bytes) {
298
+ if (bytes < 1024) return bytes + ' B';
299
+ if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(2) + ' KB';
300
+ return (bytes / (1024 * 1024)).toFixed(2) + ' MB';
301
+ }
302
+
303
+ function getColor(d) {
304
+ if (d.data.type) {
305
+ return colors[d.data.type] || colors.other;
306
+ }
307
+ if (d.data.name.includes('node_modules') || d.data.name.includes('vendor')) {
308
+ return colors.vendor;
309
+ }
310
+ return colors.other;
311
+ }
312
+
313
+ function getSizeValue(d) {
314
+ return showGzip ? d.data.gzipSize : d.data.size;
315
+ }
316
+
317
+ function render() {
318
+ container.innerHTML = '';
319
+
320
+ const width = container.clientWidth;
321
+ const height = container.clientHeight;
322
+
323
+ const hierarchy = d3.hierarchy(currentRoot)
324
+ .sum(d => {
325
+ if (searchTerm && d.name && !d.name.toLowerCase().includes(searchTerm.toLowerCase())) {
326
+ return 0;
327
+ }
328
+ return d.children ? 0 : getSizeValue({ data: d });
329
+ })
330
+ .sort((a, b) => getSizeValue(b) - getSizeValue(a));
331
+
332
+ const treemap = d3.treemap()
333
+ .size([width, height])
334
+ .paddingOuter(3)
335
+ .paddingTop(19)
336
+ .paddingInner(1)
337
+ .round(true);
338
+
339
+ const root = treemap(hierarchy);
340
+
341
+ const svg = d3.select(container)
342
+ .append('svg')
343
+ .attr('width', width)
344
+ .attr('height', height);
345
+
346
+ const node = svg.selectAll('g')
347
+ .data(root.descendants().filter(d => d.depth > 0))
348
+ .join('g')
349
+ .attr('transform', d => \`translate(\${d.x0},\${d.y0})\`);
350
+
351
+ node.append('rect')
352
+ .attr('class', 'node')
353
+ .attr('width', d => Math.max(0, d.x1 - d.x0))
354
+ .attr('height', d => Math.max(0, d.y1 - d.y0))
355
+ .attr('fill', d => getColor(d))
356
+ .attr('stroke', '#1a1a2e')
357
+ .attr('stroke-width', 1)
358
+ .on('click', (event, d) => {
359
+ if (d.children) {
360
+ zoomIn(d.data);
361
+ }
362
+ })
363
+ .on('mouseover', (event, d) => showTooltip(event, d))
364
+ .on('mousemove', (event) => moveTooltip(event))
365
+ .on('mouseout', hideTooltip);
366
+
367
+ node.append('text')
368
+ .attr('class', 'node-label')
369
+ .attr('x', d => (d.x1 - d.x0) / 2)
370
+ .attr('y', d => (d.y1 - d.y0) / 2 + 4)
371
+ .text(d => {
372
+ const width = d.x1 - d.x0;
373
+ const height = d.y1 - d.y0;
374
+ if (width < 40 || height < 20) return '';
375
+ const name = d.data.name;
376
+ const maxLen = Math.floor(width / 7);
377
+ return name.length > maxLen ? name.slice(0, maxLen - 2) + '..' : name;
378
+ });
379
+
380
+ // Group headers
381
+ node.filter(d => d.children)
382
+ .append('text')
383
+ .attr('x', 4)
384
+ .attr('y', 14)
385
+ .attr('fill', '#000')
386
+ .attr('font-size', '12px')
387
+ .attr('font-weight', 'bold')
388
+ .text(d => {
389
+ const width = d.x1 - d.x0;
390
+ const name = d.data.name;
391
+ const maxLen = Math.floor(width / 7);
392
+ return name.length > maxLen ? name.slice(0, maxLen - 2) + '..' : name;
393
+ });
394
+ }
395
+
396
+ function showTooltip(event, d) {
397
+ const size = d.data.size || d.value;
398
+ const gzipSize = d.data.gzipSize || Math.round(size * 0.3);
399
+ const path = d.data.path || d.data.name;
400
+
401
+ tooltip.innerHTML = \`
402
+ <div class="tooltip-title">\${path}</div>
403
+ <div class="tooltip-row">
404
+ <span>Size</span>
405
+ <span>\${formatSize(size)}</span>
406
+ </div>
407
+ <div class="tooltip-row">
408
+ <span>Gzip</span>
409
+ <span>\${formatSize(gzipSize)}</span>
410
+ </div>
411
+ \${d.data.type ? \`<div class="tooltip-row"><span>Type</span><span>\${d.data.type}</span></div>\` : ''}
412
+ \${d.children ? \`<div class="tooltip-row"><span>Children</span><span>\${d.children.length}</span></div>\` : ''}
413
+ \`;
414
+ tooltip.style.display = 'block';
415
+ moveTooltip(event);
416
+ }
417
+
418
+ function moveTooltip(event) {
419
+ const x = event.clientX + 10;
420
+ const y = event.clientY + 10;
421
+ tooltip.style.left = x + 'px';
422
+ tooltip.style.top = y + 'px';
423
+ }
424
+
425
+ function hideTooltip() {
426
+ tooltip.style.display = 'none';
427
+ }
428
+
429
+ function zoomIn(node) {
430
+ currentRoot = node;
431
+ updateBreadcrumb();
432
+ render();
433
+ }
434
+
435
+ function zoomOut(index) {
436
+ let node = data;
437
+ const parts = getBreadcrumbParts();
438
+ for (let i = 1; i <= index; i++) {
439
+ const child = node.children?.find(c => c.name === parts[i]);
440
+ if (child) node = child;
441
+ }
442
+ currentRoot = node;
443
+ updateBreadcrumb();
444
+ render();
445
+ }
446
+
447
+ function getBreadcrumbParts() {
448
+ const parts = ['root'];
449
+ let node = currentRoot;
450
+ const path = [];
451
+
452
+ function findPath(current, target, currentPath) {
453
+ if (current === target) {
454
+ path.push(...currentPath);
455
+ return true;
456
+ }
457
+ if (current.children) {
458
+ for (const child of current.children) {
459
+ if (findPath(child, target, [...currentPath, child.name])) {
460
+ return true;
461
+ }
462
+ }
463
+ }
464
+ return false;
465
+ }
466
+
467
+ if (currentRoot !== data) {
468
+ findPath(data, currentRoot, []);
469
+ parts.push(...path);
470
+ }
471
+
472
+ return parts;
473
+ }
474
+
475
+ function updateBreadcrumb() {
476
+ const parts = getBreadcrumbParts();
477
+ breadcrumb.innerHTML = parts.map((part, i) => {
478
+ const isLast = i === parts.length - 1;
479
+ const sep = i > 0 ? '<span class="breadcrumb-sep">/</span>' : '';
480
+ return \`\${sep}<span class="breadcrumb-item \${isLast ? 'active' : ''}" onclick="zoomOut(\${i})">\${part}</span>\`;
481
+ }).join('');
482
+ }
483
+
484
+ searchInput.addEventListener('input', (e) => {
485
+ searchTerm = e.target.value;
486
+ render();
487
+ });
488
+
489
+ showGzipCheckbox.addEventListener('change', (e) => {
490
+ showGzip = e.target.checked;
491
+ render();
492
+ });
493
+
494
+ window.addEventListener('resize', render);
495
+
496
+ render();
497
+ </script>
498
+ </body>
499
+ </html>`}function a(Z){let $={name:"root",size:Z.totalSize,gzipSize:Z.totalGzipSize,children:[]};for(let X of Z.chunks){let j={name:X.name,size:X.size,gzipSize:X.gzipSize,children:[]};for(let U of X.modules)e(j,U);$.children.push(j)}return $}function e(Z,$){let X=$.path.split("/"),j=Z;for(let Q=0;Q<X.length-1;Q++){let q=X[Q],K=j.children?.find((J)=>J.name===q);if(!K){if(K={name:q,size:0,gzipSize:0,children:[]},!j.children)j.children=[];j.children.push(K)}j=K}let U=X[X.length-1];if(!j.children)j.children=[];j.children.push({name:U,path:$.path,size:$.size,gzipSize:$.gzipSize,type:$.type}),s(Z,$.size,$.gzipSize)}function s(Z,$,X){}function M(Z){return Z.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#039;")}function T(Z){let $=process.platform,X=$==="darwin"?"open":$==="win32"?"start":"xdg-open";Bun.spawn([X,Z],{stdio:["ignore","ignore","ignore"]})}import P from"fs";import S from"path";async function CX(Z={}){let{directory:$="dist",output:X,format:j="html",open:U=!0,gzip:Q=!0,threshold:q,recommendations:K=!0,topModules:J=20,parseImports:F=!0}=Z,V=await L($,{parseImports:F,detectDuplicates:!0,topModulesCount:J}),_=q?typeof q==="string"?I(q):q:void 0,w=_?V.totalSize>_:!1,G,C;if(j==="html"){let A={title:`Bundle Analysis - ${S.basename(S.resolve($))}`,gzip:Q};if(G=R(V,A),C=X||S.join($,"bundle-report.html"),await P.promises.writeFile(C,G),U)T(C)}else if(G=x(V,{format:j,threshold:_,recommendations:K,topModules:J,showGzip:Q}),X)C=X,await P.promises.writeFile(C,G);return{stats:V,report:G,outputPath:C,exceedsThreshold:w}}async function GX(Z){let $=await L(Z,{parseImports:!1,detectDuplicates:!1,topModulesCount:0});return{totalSize:$.totalSize,totalSizeFormatted:W($.totalSize),gzipSize:$.totalGzipSize,gzipSizeFormatted:W($.totalGzipSize),moduleCount:$.moduleCount,chunkCount:$.chunks.length}}export{E as percentage,I as parseSize,T as openInBrowser,n as getModuleRecommendation,GX as getBundleSummary,R as generateTreemap,x as generateReport,W as formatBytes,L as collectBundleStats,N as analyzeBundle,CX as analyze};
package/dist/caching.d.ts CHANGED
@@ -9,6 +9,13 @@ export declare function checkCache(filePath: string, options: StxOptions): Promi
9
9
  export declare function cacheTemplate(filePath: string, output: string, dependencies: Set<string>, options: StxOptions): Promise<void>;
10
10
  /**
11
11
  * Create a hash of the file path for cache filenames
12
+ *
13
+ * Uses SHA-1 (fast, collision-resistant enough for cache keys) truncated to
14
+ * CACHE_HASH_LENGTH characters. The truncated hash still provides strong
15
+ * uniqueness guarantees for cache file identification.
16
+ *
17
+ * @param filePath - Absolute path to the template file
18
+ * @returns A 16-character hex string suitable for use as a filename
12
19
  */
13
20
  export declare function hashFilePath(filePath: string): string;
14
21
  // Memory cache for compiled templates