vite-plugin-astro-prerender 0.2.0 → 0.3.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 +1 -0
- package/dist/client.js +1 -1
- package/dist/client.js.map +1 -1
- package/dist/index.js +4 -4
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -263,6 +263,7 @@ import type {
|
|
|
263
263
|
|
|
264
264
|
While powerful, this plugin has some limitations to keep in mind:
|
|
265
265
|
|
|
266
|
+
- **JavaScript Expressions (Parser Renderer)**: The `parser` renderer does not evaluate JavaScript expressions like `{items.map(...)}` or `{variable}` (except simple frontmatter string variables). If you use dynamic expressions, they will render as `[object Object]`. Use static HTML in your lazy components, or ensure the `container` renderer is working properly.
|
|
266
267
|
- **Client Interaction**: Components are prerendered as static HTML. While you can include scripts, complex Astro client-side state (like `base` or shared Nanostores) might require careful manual setup in the target page.
|
|
267
268
|
- **Component Imports**: The default `parser` renderer cannot resolve component imports (e.g., `<Button />`). Use the `container` renderer for components with nested dependencies.
|
|
268
269
|
- **Vite Dependency**: The `container` renderer requires a running Vite dev server to perform SSR module loading.
|
package/dist/client.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var m=class{constructor(e={}){this.htmlCache=new Map;this.cssCache=new Set;this.observers=new Map;this.manifest=null;this.manifestLoaded=!1;this.baseCssLoaded=!1;this.legacyCssLoaded=!1;this.stats={totalLoads:0,cacheHits:0,cacheMisses:0,errors:0,totalLoadTime:0,totalBytes:0};this.detailedStats=new Map;var
|
|
1
|
+
var m=class{constructor(e={}){this.htmlCache=new Map;this.cssCache=new Set;this.observers=new Map;this.manifest=null;this.manifestLoaded=!1;this.baseCssLoaded=!1;this.legacyCssLoaded=!1;this.stats={totalLoads:0,cacheHits:0,cacheMisses:0,errors:0,totalLoadTime:0,totalBytes:0};this.detailedStats=new Map;var o,s,r,c,i,a,f,u,n,d,l,h,y,C;let t=(o=e.baseUrl)!=null?o:"/prerendered";this.config={baseUrl:t,cssModules:(s=e.cssModules)!=null?s:!1,manifestUrl:(r=e.manifestUrl)!=null?r:`${t}/manifest.json`,baseCssUrl:(c=e.baseCssUrl)!=null?c:`${t}/base.css`,legacyCssUrl:(i=e.legacyCssUrl)!=null?i:`${t}/lazy-components.css`,preloadCSS:(a=e.preloadCSS)!=null?a:!1,cacheHTML:(f=e.cacheHTML)!=null?f:!0,enableRetry:(u=e.enableRetry)!=null?u:!0,maxRetries:(n=e.maxRetries)!=null?n:3,retryDelay:(d=e.retryDelay)!=null?d:1e3,debug:(l=e.debug)!=null?l:!1,onLoad:(h=e.onLoad)!=null?h:(()=>{}),onError:(y=e.onError)!=null?y:(()=>{}),onCSSLoad:(C=e.onCSSLoad)!=null?C:(()=>{})},this.log("LazyHTMLLoader initialized",this.config)}log(e,...t){this.config.debug&&console.log(`[LazyHTMLLoader] ${e}`,...t)}async fetchWithRetry(e,t=this.config.maxRetries){for(let o=1;o<=t;o++){try{this.log(`Fetching ${e} (attempt ${o}/${t})`);let s=await fetch(e);if(s.ok)return s;if(o===t)throw new Error(`HTTP ${s.status}: ${s.statusText}`);if(s.status===404)throw new Error(`Not found: ${e}`);this.log(`Fetch failed with status ${s.status}, retrying...`)}catch(s){if(o===t)throw s;this.log(`Fetch error: ${s}, retrying...`)}o<t&&await new Promise(s=>setTimeout(s,this.config.retryDelay*o))}throw new Error(`Failed to fetch ${e} after ${t} attempts`)}async loadManifest(){if(this.manifestLoaded)return;let e=performance.now();try{let t=await(this.config.enableRetry?this.fetchWithRetry(this.config.manifestUrl):fetch(this.config.manifestUrl));if(!t.ok)throw new Error(`Failed to load manifest: ${t.statusText}`);this.manifest=await t.json(),this.manifestLoaded=!0;let o=performance.now()-e;this.log(`Manifest loaded in ${o.toFixed(2)}ms`,this.manifest),this.config.onCSSLoad(this.config.manifestUrl,o)}catch(t){console.error("Failed to load CSS manifest:",t),this.config.cssModules=!1,this.manifestLoaded=!0}}async loadBaseCSS(){if(this.baseCssLoaded||(await this.loadManifest(),!this.manifest))return;let e=performance.now();return new Promise((t,o)=>{let s=document.createElement("link");if(s.rel="stylesheet",s.href=this.config.baseCssUrl,s.onload=()=>{this.baseCssLoaded=!0;let r=performance.now()-e;this.log(`Base CSS loaded in ${r.toFixed(2)}ms`),this.config.onCSSLoad(this.config.baseCssUrl,r),t()},s.onerror=()=>{console.error("Failed to load base CSS"),o(new Error("Failed to load base CSS"))},this.config.preloadCSS){let r=document.createElement("link");r.rel="preload",r.as="style",r.href=this.config.baseCssUrl,document.head.appendChild(r)}document.head.appendChild(s)})}async loadComponentCSS(e){if(!this.config.cssModules||!this.manifest)return;let t=this.manifest.components[e];if(!t){this.log(`No CSS file for component: ${e}`);return}if(this.cssCache.has(t)){this.log(`CSS already loaded: ${t}`);return}let o=performance.now(),s=`${this.config.baseUrl}/${t}`;return new Promise((r,c)=>{let i=document.createElement("link");if(i.rel="stylesheet",i.href=s,i.onload=()=>{this.cssCache.add(t);let a=performance.now()-o;this.log(`Component CSS loaded in ${a.toFixed(2)}ms: ${t}`),this.config.onCSSLoad(t,a),r()},i.onerror=()=>{console.error(`Failed to load component CSS: ${t}`),c(new Error(`Failed to load CSS: ${t}`))},this.config.preloadCSS){let a=document.createElement("link");a.rel="preload",a.as="style",a.href=s,document.head.appendChild(a)}document.head.appendChild(i)})}async loadLegacyCSS(){if(this.legacyCssLoaded)return;let e=performance.now();return new Promise((t,o)=>{let s=document.createElement("link");if(s.rel="stylesheet",s.href=this.config.legacyCssUrl,s.onload=()=>{this.legacyCssLoaded=!0;let r=performance.now()-e;this.log(`Legacy CSS loaded in ${r.toFixed(2)}ms`),this.config.onCSSLoad(this.config.legacyCssUrl,r),t()},s.onerror=()=>{console.error("Failed to load legacy CSS"),o(new Error("Failed to load lazy components CSS"))},this.config.preloadCSS){let r=document.createElement("link");r.rel="preload",r.as="style",r.href=this.config.legacyCssUrl,document.head.appendChild(r)}document.head.appendChild(s)})}async load(e){let t=performance.now();try{if(this.config.cacheHTML&&this.htmlCache.has(e)){this.stats.cacheHits++,this.log(`Cache hit: ${e}`);let n=this.htmlCache.get(e),d=new Blob([n]).size,l=performance.now()-t;this.stats.totalLoads++,this.stats.totalLoadTime+=l;let h={duration:l,bytes:d,fromCache:!0,timestamp:Date.now()};return this.detailedStats.set(e,h),this.config.onLoad(e,{duration:l,bytes:d,fromCache:!0}),n}this.stats.cacheMisses++,this.config.cssModules?(await this.loadBaseCSS().catch(n=>{console.warn("Failed to load base CSS:",n)}),await this.loadComponentCSS(e).catch(n=>{console.warn(`Failed to load CSS for ${e}:`,n)})):await this.loadLegacyCSS().catch(n=>{console.warn("Failed to load legacy CSS:",n)});let o=`${this.config.baseUrl}/${e}.html`,s=await(this.config.enableRetry?this.fetchWithRetry(o):fetch(o));if(!s.ok)throw new Error(`HTTP ${s.status}: ${s.statusText}`);let r=await s.text(),c=new Blob([r]).size;this.config.cacheHTML&&this.htmlCache.set(e,r);let i=performance.now()-t;this.stats.totalLoads++,this.stats.totalLoadTime+=i,this.stats.totalBytes+=c,this.log(`Loaded ${e} in ${i.toFixed(2)}ms (${c} bytes)`);let a=[],f=new PerformanceObserver(n=>{n.getEntries().forEach(d=>{let l=d;if(l.startTime>=t-50){let h=l.transferSize||l.decodedBodySize||l.encodedBodySize||0;a.push({url:l.name,bytes:h,duration:l.duration,type:l.initiatorType}),this.stats.totalBytes+=h}})});try{f.observe({entryTypes:["resource"],buffered:!0}),setTimeout(()=>f.disconnect(),6e3)}catch(n){this.log("PerformanceObserver failed");try{f.observe({entryTypes:["resource"]})}catch(d){}}let u={duration:i,bytes:c,fromCache:!1,timestamp:Date.now(),secondaryAssets:a};return this.detailedStats.set(e,u),this.config.onLoad(e,{duration:i,bytes:c,fromCache:!1,secondaryAssets:a}),r}catch(o){this.stats.errors++;let s=o instanceof Error?o:new Error(String(o));throw this.log(`Error loading ${e}:`,s),this.config.onError(e,s),s}}async inject(e,t){let o=await this.load(e),s=document.querySelector(t);if(s)s.innerHTML=o,this.log(`Injected ${e} into ${t}`);else{let r=new Error(`Target element not found: ${t}`);throw this.config.onError(e,r),r}}observeAndLoad(e,t,o){let s=document.querySelector(t);if(!s){console.warn(`Target element not found: ${t}`);return}let r=new IntersectionObserver(c=>{c.forEach(i=>{i.isIntersecting&&(this.log(`Component ${e} entered viewport`),this.inject(e,t).catch(a=>{console.error(`Failed to inject ${e}:`,a)}),r.disconnect(),this.observers.delete(e))})},o||{rootMargin:"100px"});r.observe(s),this.observers.set(e,r),this.log(`Observing ${e} at ${t}`)}async preload(e){await this.load(e)}async preloadBatch(e){this.log(`Preloading ${e.length} components:`,e),await Promise.all(e.map(t=>this.preload(t)))}getStats(){return{totalLoads:this.stats.totalLoads,cacheHits:this.stats.cacheHits,cacheMisses:this.stats.cacheMisses,errors:this.stats.errors,averageLoadTime:this.stats.totalLoads>0?this.stats.totalLoadTime/this.stats.totalLoads:0,totalBytes:this.stats.totalBytes}}getDetailedHistory(){return Array.from(this.detailedStats.entries()).map(([e,t])=>({componentName:e,...t})).sort((e,t)=>t.timestamp-e.timestamp)}clearCache(){this.htmlCache.clear(),this.log("HTML cache cleared")}clearCSSCache(){this.cssCache.clear(),this.baseCssLoaded=!1,this.legacyCssLoaded=!1,this.manifestLoaded=!1,this.manifest=null,this.log("CSS cache cleared")}disconnectAll(){this.observers.forEach(e=>e.disconnect()),this.observers.clear(),this.log("All observers disconnected")}reset(){this.clearCache(),this.clearCSSCache(),this.disconnectAll(),this.stats={totalLoads:0,cacheHits:0,cacheMisses:0,errors:0,totalLoadTime:0,totalBytes:0},this.detailedStats.clear(),this.log("LazyHTMLLoader reset")}};function S(g){return new m(g)}var b=new m;export{m as LazyHTMLLoader,S as createLazyLoader,b as lazyLoader};
|
|
2
2
|
//# sourceMappingURL=client.js.map
|
package/dist/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils/LazyLoader.ts"],"sourcesContent":["// src/utils/LazyLoader.ts\n// Client-side utility for lazy loading prerendered HTML components\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Configuration options for the LazyHTMLLoader\n */\nexport interface LazyLoaderConfig {\n /** Base URL for prerendered files (default: '/prerendered') */\n baseUrl?: string;\n /** Enable CSS modules mode with per-component CSS (default: false) */\n cssModules?: boolean;\n /** URL to CSS modules manifest (default: '/prerendered/manifest.json') */\n manifestUrl?: string;\n /** URL to base CSS file in CSS modules mode (default: '/prerendered/base.css') */\n baseCssUrl?: string;\n /** URL to legacy single CSS file (default: '/prerendered/lazy-components.css') */\n legacyCssUrl?: string;\n /** Preload CSS files before they're needed (default: false) */\n preloadCSS?: boolean;\n /** Cache loaded HTML in memory (default: true) */\n cacheHTML?: boolean;\n /** Enable retry logic for failed fetches (default: true) */\n enableRetry?: boolean;\n /** Maximum number of retry attempts (default: 3) */\n maxRetries?: number;\n /** Delay between retries in milliseconds (default: 1000) */\n retryDelay?: number;\n /** Enable debug logging (default: false) */\n debug?: boolean;\n /** Callback when a component is loaded */\n onLoad?: (componentName: string, stats: {\n duration: number;\n bytes: number;\n fromCache: boolean;\n secondaryAssets?: Array<{ url: string; bytes: number; duration: number; type: string }>\n }) => void;\n /** Callback when an error occurs */\n onError?: (componentName: string, error: Error) => void;\n /** Callback when CSS is loaded */\n onCSSLoad?: (cssFile: string, duration: number) => void;\n}\n\n/**\n * CSS module manifest structure\n */\nexport interface CSSModuleManifest {\n /** Map of component names to their CSS file paths */\n components: Record<string, string>;\n}\n\n/**\n * Load statistics\n */\nexport interface LoadStats {\n /** Total number of successful loads */\n totalLoads: number;\n /** Number of cache hits */\n cacheHits: number;\n /** Number of cache misses */\n cacheMisses: number;\n /** Number of errors encountered */\n errors: number;\n /** Average load time in milliseconds */\n averageLoadTime: number;\n /** Total bytes transferred across all loads */\n totalBytes: number;\n}\n\n// ============================================================================\n// LazyHTMLLoader Class\n// ============================================================================\n\n/**\n * Client-side utility for lazy loading prerendered HTML components\n * \n * @example\n * ```ts\n * import { createLazyLoader } from 'vite-plugin-astro-prerender';\n * \n * const loader = createLazyLoader({ debug: true });\n * \n * // Load and inject when in viewport\n * loader.observeAndLoad('LazyFooter', '#footer-container');\n * \n * // Or load manually\n * const html = await loader.load('LazyHeader');\n * document.getElementById('header')!.innerHTML = html;\n * ```\n */\nexport class LazyHTMLLoader {\n private config: Required<LazyLoaderConfig>;\n private htmlCache = new Map<string, string>();\n private cssCache = new Set<string>();\n private observers = new Map<string, IntersectionObserver>();\n private manifest: CSSModuleManifest | null = null;\n private manifestLoaded = false;\n private baseCssLoaded = false;\n private legacyCssLoaded = false;\n private stats = {\n totalLoads: 0,\n cacheHits: 0,\n cacheMisses: 0,\n errors: 0,\n totalLoadTime: 0,\n totalBytes: 0,\n };\n private detailedStats = new Map<string, {\n duration: number;\n bytes: number;\n fromCache: boolean;\n timestamp: number;\n secondaryAssets?: Array<{ url: string; bytes: number; duration: number; type: string }>\n }>();\n\n constructor(config: LazyLoaderConfig = {}) {\n this.config = {\n baseUrl: config.baseUrl ?? '/prerendered',\n cssModules: config.cssModules ?? false,\n manifestUrl: config.manifestUrl ?? '/prerendered/manifest.json',\n baseCssUrl: config.baseCssUrl ?? '/prerendered/base.css',\n legacyCssUrl: config.legacyCssUrl ?? '/prerendered/lazy-components.css',\n preloadCSS: config.preloadCSS ?? false,\n cacheHTML: config.cacheHTML ?? true,\n enableRetry: config.enableRetry ?? true,\n maxRetries: config.maxRetries ?? 3,\n retryDelay: config.retryDelay ?? 1000,\n debug: config.debug ?? false,\n onLoad: config.onLoad ?? (() => { }),\n onError: config.onError ?? (() => { }),\n onCSSLoad: config.onCSSLoad ?? (() => { }),\n };\n\n this.log('LazyHTMLLoader initialized', this.config);\n }\n\n /**\n * Internal logging method\n */\n private log(message: string, ...args: unknown[]): void {\n if (this.config.debug) {\n console.log(`[LazyHTMLLoader] ${message}`, ...args);\n }\n }\n\n /**\n * Fetch with retry logic\n */\n private async fetchWithRetry(\n url: string,\n retries = this.config.maxRetries,\n ): Promise<Response> {\n for (let attempt = 1; attempt <= retries; attempt++) {\n try {\n this.log(`Fetching ${url} (attempt ${attempt}/${retries})`);\n const response = await fetch(url);\n\n if (response.ok) {\n return response;\n }\n\n if (attempt === retries) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n }\n\n // Don't retry on 404\n if (response.status === 404) {\n throw new Error(`Not found: ${url}`);\n }\n\n this.log(`Fetch failed with status ${response.status}, retrying...`);\n } catch (error) {\n if (attempt === retries) {\n throw error;\n }\n this.log(`Fetch error: ${error}, retrying...`);\n }\n\n // Wait before retrying\n if (attempt < retries) {\n await new Promise((resolve) =>\n setTimeout(resolve, this.config.retryDelay * attempt),\n );\n }\n }\n\n throw new Error(`Failed to fetch ${url} after ${retries} attempts`);\n }\n\n /**\n * Load CSS manifest for CSS modules mode\n */\n private async loadManifest(): Promise<void> {\n if (this.manifestLoaded) {\n return;\n }\n\n const startTime = performance.now();\n\n try {\n const response = await (this.config.enableRetry\n ? this.fetchWithRetry(this.config.manifestUrl)\n : fetch(this.config.manifestUrl));\n\n if (!response.ok) {\n throw new Error(`Failed to load manifest: ${response.statusText}`);\n }\n\n this.manifest = await response.json();\n this.manifestLoaded = true;\n\n const duration = performance.now() - startTime;\n this.log(`Manifest loaded in ${duration.toFixed(2)}ms`, this.manifest);\n this.config.onCSSLoad(this.config.manifestUrl, duration);\n } catch (error) {\n console.error('Failed to load CSS manifest:', error);\n // Fallback to legacy mode\n this.config.cssModules = false;\n this.manifestLoaded = true;\n }\n }\n\n /**\n * Load base CSS file (CSS modules mode)\n */\n private async loadBaseCSS(): Promise<void> {\n if (this.baseCssLoaded) {\n return;\n }\n\n await this.loadManifest();\n\n if (!this.manifest) {\n return;\n }\n\n const startTime = performance.now();\n\n return new Promise((resolve, reject) => {\n const link = document.createElement('link');\n link.rel = 'stylesheet';\n link.href = this.config.baseCssUrl;\n\n link.onload = () => {\n this.baseCssLoaded = true;\n const duration = performance.now() - startTime;\n this.log(`Base CSS loaded in ${duration.toFixed(2)}ms`);\n this.config.onCSSLoad(this.config.baseCssUrl, duration);\n resolve();\n };\n\n link.onerror = () => {\n console.error('Failed to load base CSS');\n reject(new Error('Failed to load base CSS'));\n };\n\n if (this.config.preloadCSS) {\n const preload = document.createElement('link');\n preload.rel = 'preload';\n preload.as = 'style';\n preload.href = this.config.baseCssUrl;\n document.head.appendChild(preload);\n }\n\n document.head.appendChild(link);\n });\n }\n\n /**\n * Load component-specific CSS file (CSS modules mode)\n */\n private async loadComponentCSS(componentName: string): Promise<void> {\n if (!this.config.cssModules || !this.manifest) {\n return;\n }\n\n const cssFile = this.manifest.components[componentName];\n if (!cssFile) {\n this.log(`No CSS file for component: ${componentName}`);\n return;\n }\n\n if (this.cssCache.has(cssFile)) {\n this.log(`CSS already loaded: ${cssFile}`);\n return;\n }\n\n const startTime = performance.now();\n const cssUrl = `${this.config.baseUrl}/${cssFile}`;\n\n return new Promise((resolve, reject) => {\n const link = document.createElement('link');\n link.rel = 'stylesheet';\n link.href = cssUrl;\n\n link.onload = () => {\n this.cssCache.add(cssFile);\n const duration = performance.now() - startTime;\n this.log(\n `Component CSS loaded in ${duration.toFixed(2)}ms: ${cssFile}`,\n );\n this.config.onCSSLoad(cssFile, duration);\n resolve();\n };\n\n link.onerror = () => {\n console.error(`Failed to load component CSS: ${cssFile}`);\n reject(new Error(`Failed to load CSS: ${cssFile}`));\n };\n\n if (this.config.preloadCSS) {\n const preload = document.createElement('link');\n preload.rel = 'preload';\n preload.as = 'style';\n preload.href = cssUrl;\n document.head.appendChild(preload);\n }\n\n document.head.appendChild(link);\n });\n }\n\n /**\n * Load legacy single CSS file\n */\n private async loadLegacyCSS(): Promise<void> {\n if (this.legacyCssLoaded) {\n return;\n }\n\n const startTime = performance.now();\n\n return new Promise((resolve, reject) => {\n const link = document.createElement('link');\n link.rel = 'stylesheet';\n link.href = this.config.legacyCssUrl;\n\n link.onload = () => {\n this.legacyCssLoaded = true;\n const duration = performance.now() - startTime;\n this.log(`Legacy CSS loaded in ${duration.toFixed(2)}ms`);\n this.config.onCSSLoad(this.config.legacyCssUrl, duration);\n resolve();\n };\n\n link.onerror = () => {\n console.error('Failed to load legacy CSS');\n reject(new Error('Failed to load lazy components CSS'));\n };\n\n if (this.config.preloadCSS) {\n const preload = document.createElement('link');\n preload.rel = 'preload';\n preload.as = 'style';\n preload.href = this.config.legacyCssUrl;\n document.head.appendChild(preload);\n }\n\n document.head.appendChild(link);\n });\n }\n\n /**\n * Load HTML fragment from server\n */\n async load(componentName: string): Promise<string> {\n const startTime = performance.now();\n\n try {\n // Check cache\n if (this.config.cacheHTML && this.htmlCache.has(componentName)) {\n this.stats.cacheHits++;\n this.log(`Cache hit: ${componentName}`);\n const html = this.htmlCache.get(componentName)!;\n const bytes = new Blob([html]).size;\n const duration = performance.now() - startTime;\n\n this.stats.totalLoads++;\n this.stats.totalLoadTime += duration;\n\n const loadInfo = { duration, bytes, fromCache: true, timestamp: Date.now() };\n this.detailedStats.set(componentName, loadInfo);\n this.config.onLoad(componentName, { duration, bytes, fromCache: true });\n\n return html;\n }\n\n this.stats.cacheMisses++;\n\n // Load CSS\n if (this.config.cssModules) {\n await this.loadBaseCSS().catch((err) => {\n console.warn('Failed to load base CSS:', err);\n });\n await this.loadComponentCSS(componentName).catch((err) => {\n console.warn(`Failed to load CSS for ${componentName}:`, err);\n });\n } else {\n await this.loadLegacyCSS().catch((err) => {\n console.warn('Failed to load legacy CSS:', err);\n });\n }\n\n // Fetch HTML\n const url = `${this.config.baseUrl}/${componentName}.html`;\n const response = await (this.config.enableRetry\n ? this.fetchWithRetry(url)\n : fetch(url));\n\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n }\n\n const html = await response.text();\n const bytes = new Blob([html]).size;\n\n // Cache HTML\n if (this.config.cacheHTML) {\n this.htmlCache.set(componentName, html);\n }\n\n // Update stats\n const duration = performance.now() - startTime;\n this.stats.totalLoads++;\n this.stats.totalLoadTime += duration;\n this.stats.totalBytes += bytes;\n\n this.log(`Loaded ${componentName} in ${duration.toFixed(2)}ms (${bytes} bytes)`);\n\n // Start tracking secondary assets (images, etc.) that might be triggered by this injection\n const secondaryAssets: Array<{ url: string; bytes: number; duration: number; type: string }> = [];\n\n const resourceObserver = new PerformanceObserver((list) => {\n list.getEntries().forEach((entry) => {\n const res = entry as PerformanceResourceTiming;\n // Filter for assets likely triggered by this component\n if (res.startTime >= (startTime - 50)) {\n const assetBytes = res.transferSize || res.decodedBodySize || res.encodedBodySize || 0;\n\n secondaryAssets.push({\n url: res.name,\n bytes: assetBytes,\n duration: res.duration,\n type: res.initiatorType\n });\n\n // Update total bytes and global stats with secondary assets\n this.stats.totalBytes += assetBytes;\n }\n });\n });\n\n try {\n // Use buffered: true to catch resources that might have started \n // between performance.now() and observe() call\n resourceObserver.observe({ entryTypes: ['resource'], buffered: true });\n\n // Stop observing after a reasonable time (longer for assets)\n setTimeout(() => resourceObserver.disconnect(), 6000);\n } catch (e) {\n this.log('PerformanceObserver failed');\n // Fallback attempt without buffering if that was the cause\n try { resourceObserver.observe({ entryTypes: ['resource'] }); } catch (err) { }\n }\n\n const loadInfo = {\n duration,\n bytes,\n fromCache: false,\n timestamp: Date.now(),\n secondaryAssets\n };\n this.detailedStats.set(componentName, loadInfo);\n this.config.onLoad(componentName, { duration, bytes, fromCache: false, secondaryAssets });\n\n return html;\n } catch (error) {\n this.stats.errors++;\n const err = error instanceof Error ? error : new Error(String(error));\n this.log(`Error loading ${componentName}:`, err);\n this.config.onError(componentName, err);\n throw err;\n }\n }\n\n /**\n * Inject HTML fragment into target element\n */\n async inject(componentName: string, targetSelector: string): Promise<void> {\n const html = await this.load(componentName);\n const target = document.querySelector(targetSelector);\n\n if (target) {\n target.innerHTML = html;\n this.log(`Injected ${componentName} into ${targetSelector}`);\n } else {\n const error = new Error(`Target element not found: ${targetSelector}`);\n this.config.onError(componentName, error);\n throw error;\n }\n }\n\n /**\n * Load HTML fragment when target element enters viewport\n */\n observeAndLoad(\n componentName: string,\n targetSelector: string,\n options?: IntersectionObserverInit,\n ): void {\n const target = document.querySelector(targetSelector);\n if (!target) {\n console.warn(`Target element not found: ${targetSelector}`);\n return;\n }\n\n const observer = new IntersectionObserver(\n (entries) => {\n entries.forEach((entry) => {\n if (entry.isIntersecting) {\n this.log(`Component ${componentName} entered viewport`);\n this.inject(componentName, targetSelector).catch((err) => {\n console.error(`Failed to inject ${componentName}:`, err);\n });\n observer.disconnect();\n this.observers.delete(componentName);\n }\n });\n },\n options || { rootMargin: '100px' },\n );\n\n observer.observe(target);\n this.observers.set(componentName, observer);\n this.log(`Observing ${componentName} at ${targetSelector}`);\n }\n\n /**\n * Preload HTML fragment without injecting\n */\n async preload(componentName: string): Promise<void> {\n await this.load(componentName);\n }\n\n /**\n * Batch preload multiple components\n */\n async preloadBatch(componentNames: string[]): Promise<void> {\n this.log(`Preloading ${componentNames.length} components:`, componentNames);\n await Promise.all(componentNames.map((name) => this.preload(name)));\n }\n\n /**\n * Get load statistics\n */\n getStats(): LoadStats {\n return {\n totalLoads: this.stats.totalLoads,\n cacheHits: this.stats.cacheHits,\n cacheMisses: this.stats.cacheMisses,\n errors: this.stats.errors,\n averageLoadTime:\n this.stats.totalLoads > 0\n ? this.stats.totalLoadTime / this.stats.totalLoads\n : 0,\n totalBytes: this.stats.totalBytes,\n };\n }\n\n /**\n * Get detailed history of all loads in this session\n */\n getDetailedHistory(): Array<{ componentName: string; duration: number; bytes: number; fromCache: boolean; timestamp: number }> {\n return Array.from(this.detailedStats.entries()).map(([name, info]) => ({\n componentName: name,\n ...info,\n })).sort((a, b) => b.timestamp - a.timestamp);\n }\n\n /**\n * Clear HTML cache\n */\n clearCache(): void {\n this.htmlCache.clear();\n this.log('HTML cache cleared');\n }\n\n /**\n * Clear CSS cache (forces reload of CSS files)\n */\n clearCSSCache(): void {\n this.cssCache.clear();\n this.baseCssLoaded = false;\n this.legacyCssLoaded = false;\n this.manifestLoaded = false;\n this.manifest = null;\n this.log('CSS cache cleared');\n }\n\n /**\n * Disconnect all observers\n */\n disconnectAll(): void {\n this.observers.forEach((observer) => observer.disconnect());\n this.observers.clear();\n this.log('All observers disconnected');\n }\n\n /**\n * Reset all state (cache, observers, stats)\n */\n reset(): void {\n this.clearCache();\n this.clearCSSCache();\n this.disconnectAll();\n this.stats = {\n totalLoads: 0,\n cacheHits: 0,\n cacheMisses: 0,\n errors: 0,\n totalLoadTime: 0,\n totalBytes: 0,\n };\n this.detailedStats.clear();\n this.log('LazyHTMLLoader reset');\n }\n}\n\n/**\n * Factory function to create a lazy loader instance\n */\nexport function createLazyLoader(config?: LazyLoaderConfig): LazyHTMLLoader {\n return new LazyHTMLLoader(config);\n}\n\n/**\n * Default lazy loader instance with default configuration\n */\nexport const lazyLoader = new LazyHTMLLoader();"],"mappings":"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","names":["LazyHTMLLoader","config","_a","_b","_c","_d","_e","_f","_g","_h","_i","_j","_k","_l","_m","_n","message","args","url","retries","attempt","response","error","resolve","startTime","duration","reject","link","preload","componentName","cssFile","cssUrl","html","bytes","loadInfo","err","secondaryAssets","resourceObserver","list","entry","res","assetBytes","e","targetSelector","target","options","observer","entries","componentNames","name","info","a","b","createLazyLoader","lazyLoader"]}
|
|
1
|
+
{"version":3,"sources":["../src/utils/LazyLoader.ts"],"sourcesContent":["// src/utils/LazyLoader.ts\n// Client-side utility for lazy loading prerendered HTML components\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Configuration options for the LazyHTMLLoader\n */\nexport interface LazyLoaderConfig {\n /** Base URL for prerendered files (default: '/prerendered') */\n baseUrl?: string;\n /** Enable CSS modules mode with per-component CSS (default: false) */\n cssModules?: boolean;\n /** URL to CSS modules manifest (default: '/prerendered/manifest.json') */\n manifestUrl?: string;\n /** URL to base CSS file in CSS modules mode (default: '/prerendered/base.css') */\n baseCssUrl?: string;\n /** URL to legacy single CSS file (default: '/prerendered/lazy-components.css') */\n legacyCssUrl?: string;\n /** Preload CSS files before they're needed (default: false) */\n preloadCSS?: boolean;\n /** Cache loaded HTML in memory (default: true) */\n cacheHTML?: boolean;\n /** Enable retry logic for failed fetches (default: true) */\n enableRetry?: boolean;\n /** Maximum number of retry attempts (default: 3) */\n maxRetries?: number;\n /** Delay between retries in milliseconds (default: 1000) */\n retryDelay?: number;\n /** Enable debug logging (default: false) */\n debug?: boolean;\n /** Callback when a component is loaded */\n onLoad?: (componentName: string, stats: {\n duration: number;\n bytes: number;\n fromCache: boolean;\n secondaryAssets?: Array<{ url: string; bytes: number; duration: number; type: string }>\n }) => void;\n /** Callback when an error occurs */\n onError?: (componentName: string, error: Error) => void;\n /** Callback when CSS is loaded */\n onCSSLoad?: (cssFile: string, duration: number) => void;\n}\n\n/**\n * CSS module manifest structure\n */\nexport interface CSSModuleManifest {\n /** Map of component names to their CSS file paths */\n components: Record<string, string>;\n}\n\n/**\n * Load statistics\n */\nexport interface LoadStats {\n /** Total number of successful loads */\n totalLoads: number;\n /** Number of cache hits */\n cacheHits: number;\n /** Number of cache misses */\n cacheMisses: number;\n /** Number of errors encountered */\n errors: number;\n /** Average load time in milliseconds */\n averageLoadTime: number;\n /** Total bytes transferred across all loads */\n totalBytes: number;\n}\n\n// ============================================================================\n// LazyHTMLLoader Class\n// ============================================================================\n\n/**\n * Client-side utility for lazy loading prerendered HTML components\n * \n * @example\n * ```ts\n * import { createLazyLoader } from 'vite-plugin-astro-prerender';\n * \n * const loader = createLazyLoader({ debug: true });\n * \n * // Load and inject when in viewport\n * loader.observeAndLoad('LazyFooter', '#footer-container');\n * \n * // Or load manually\n * const html = await loader.load('LazyHeader');\n * document.getElementById('header')!.innerHTML = html;\n * ```\n */\nexport class LazyHTMLLoader {\n private config: Required<LazyLoaderConfig>;\n private htmlCache = new Map<string, string>();\n private cssCache = new Set<string>();\n private observers = new Map<string, IntersectionObserver>();\n private manifest: CSSModuleManifest | null = null;\n private manifestLoaded = false;\n private baseCssLoaded = false;\n private legacyCssLoaded = false;\n private stats = {\n totalLoads: 0,\n cacheHits: 0,\n cacheMisses: 0,\n errors: 0,\n totalLoadTime: 0,\n totalBytes: 0,\n };\n private detailedStats = new Map<string, {\n duration: number;\n bytes: number;\n fromCache: boolean;\n timestamp: number;\n secondaryAssets?: Array<{ url: string; bytes: number; duration: number; type: string }>\n }>();\n\n constructor(config: LazyLoaderConfig = {}) {\n const baseUrl = config.baseUrl ?? '/prerendered';\n this.config = {\n baseUrl,\n cssModules: config.cssModules ?? false,\n manifestUrl: config.manifestUrl ?? `${baseUrl}/manifest.json`,\n baseCssUrl: config.baseCssUrl ?? `${baseUrl}/base.css`,\n legacyCssUrl: config.legacyCssUrl ?? `${baseUrl}/lazy-components.css`,\n preloadCSS: config.preloadCSS ?? false,\n cacheHTML: config.cacheHTML ?? true,\n enableRetry: config.enableRetry ?? true,\n maxRetries: config.maxRetries ?? 3,\n retryDelay: config.retryDelay ?? 1000,\n debug: config.debug ?? false,\n onLoad: config.onLoad ?? (() => { }),\n onError: config.onError ?? (() => { }),\n onCSSLoad: config.onCSSLoad ?? (() => { }),\n };\n\n this.log('LazyHTMLLoader initialized', this.config);\n }\n\n /**\n * Internal logging method\n */\n private log(message: string, ...args: unknown[]): void {\n if (this.config.debug) {\n console.log(`[LazyHTMLLoader] ${message}`, ...args);\n }\n }\n\n /**\n * Fetch with retry logic\n */\n private async fetchWithRetry(\n url: string,\n retries = this.config.maxRetries,\n ): Promise<Response> {\n for (let attempt = 1; attempt <= retries; attempt++) {\n try {\n this.log(`Fetching ${url} (attempt ${attempt}/${retries})`);\n const response = await fetch(url);\n\n if (response.ok) {\n return response;\n }\n\n if (attempt === retries) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n }\n\n // Don't retry on 404\n if (response.status === 404) {\n throw new Error(`Not found: ${url}`);\n }\n\n this.log(`Fetch failed with status ${response.status}, retrying...`);\n } catch (error) {\n if (attempt === retries) {\n throw error;\n }\n this.log(`Fetch error: ${error}, retrying...`);\n }\n\n // Wait before retrying\n if (attempt < retries) {\n await new Promise((resolve) =>\n setTimeout(resolve, this.config.retryDelay * attempt),\n );\n }\n }\n\n throw new Error(`Failed to fetch ${url} after ${retries} attempts`);\n }\n\n /**\n * Load CSS manifest for CSS modules mode\n */\n private async loadManifest(): Promise<void> {\n if (this.manifestLoaded) {\n return;\n }\n\n const startTime = performance.now();\n\n try {\n const response = await (this.config.enableRetry\n ? this.fetchWithRetry(this.config.manifestUrl)\n : fetch(this.config.manifestUrl));\n\n if (!response.ok) {\n throw new Error(`Failed to load manifest: ${response.statusText}`);\n }\n\n this.manifest = await response.json();\n this.manifestLoaded = true;\n\n const duration = performance.now() - startTime;\n this.log(`Manifest loaded in ${duration.toFixed(2)}ms`, this.manifest);\n this.config.onCSSLoad(this.config.manifestUrl, duration);\n } catch (error) {\n console.error('Failed to load CSS manifest:', error);\n // Fallback to legacy mode\n this.config.cssModules = false;\n this.manifestLoaded = true;\n }\n }\n\n /**\n * Load base CSS file (CSS modules mode)\n */\n private async loadBaseCSS(): Promise<void> {\n if (this.baseCssLoaded) {\n return;\n }\n\n await this.loadManifest();\n\n if (!this.manifest) {\n return;\n }\n\n const startTime = performance.now();\n\n return new Promise((resolve, reject) => {\n const link = document.createElement('link');\n link.rel = 'stylesheet';\n link.href = this.config.baseCssUrl;\n\n link.onload = () => {\n this.baseCssLoaded = true;\n const duration = performance.now() - startTime;\n this.log(`Base CSS loaded in ${duration.toFixed(2)}ms`);\n this.config.onCSSLoad(this.config.baseCssUrl, duration);\n resolve();\n };\n\n link.onerror = () => {\n console.error('Failed to load base CSS');\n reject(new Error('Failed to load base CSS'));\n };\n\n if (this.config.preloadCSS) {\n const preload = document.createElement('link');\n preload.rel = 'preload';\n preload.as = 'style';\n preload.href = this.config.baseCssUrl;\n document.head.appendChild(preload);\n }\n\n document.head.appendChild(link);\n });\n }\n\n /**\n * Load component-specific CSS file (CSS modules mode)\n */\n private async loadComponentCSS(componentName: string): Promise<void> {\n if (!this.config.cssModules || !this.manifest) {\n return;\n }\n\n const cssFile = this.manifest.components[componentName];\n if (!cssFile) {\n this.log(`No CSS file for component: ${componentName}`);\n return;\n }\n\n if (this.cssCache.has(cssFile)) {\n this.log(`CSS already loaded: ${cssFile}`);\n return;\n }\n\n const startTime = performance.now();\n const cssUrl = `${this.config.baseUrl}/${cssFile}`;\n\n return new Promise((resolve, reject) => {\n const link = document.createElement('link');\n link.rel = 'stylesheet';\n link.href = cssUrl;\n\n link.onload = () => {\n this.cssCache.add(cssFile);\n const duration = performance.now() - startTime;\n this.log(\n `Component CSS loaded in ${duration.toFixed(2)}ms: ${cssFile}`,\n );\n this.config.onCSSLoad(cssFile, duration);\n resolve();\n };\n\n link.onerror = () => {\n console.error(`Failed to load component CSS: ${cssFile}`);\n reject(new Error(`Failed to load CSS: ${cssFile}`));\n };\n\n if (this.config.preloadCSS) {\n const preload = document.createElement('link');\n preload.rel = 'preload';\n preload.as = 'style';\n preload.href = cssUrl;\n document.head.appendChild(preload);\n }\n\n document.head.appendChild(link);\n });\n }\n\n /**\n * Load legacy single CSS file\n */\n private async loadLegacyCSS(): Promise<void> {\n if (this.legacyCssLoaded) {\n return;\n }\n\n const startTime = performance.now();\n\n return new Promise((resolve, reject) => {\n const link = document.createElement('link');\n link.rel = 'stylesheet';\n link.href = this.config.legacyCssUrl;\n\n link.onload = () => {\n this.legacyCssLoaded = true;\n const duration = performance.now() - startTime;\n this.log(`Legacy CSS loaded in ${duration.toFixed(2)}ms`);\n this.config.onCSSLoad(this.config.legacyCssUrl, duration);\n resolve();\n };\n\n link.onerror = () => {\n console.error('Failed to load legacy CSS');\n reject(new Error('Failed to load lazy components CSS'));\n };\n\n if (this.config.preloadCSS) {\n const preload = document.createElement('link');\n preload.rel = 'preload';\n preload.as = 'style';\n preload.href = this.config.legacyCssUrl;\n document.head.appendChild(preload);\n }\n\n document.head.appendChild(link);\n });\n }\n\n /**\n * Load HTML fragment from server\n */\n async load(componentName: string): Promise<string> {\n const startTime = performance.now();\n\n try {\n // Check cache\n if (this.config.cacheHTML && this.htmlCache.has(componentName)) {\n this.stats.cacheHits++;\n this.log(`Cache hit: ${componentName}`);\n const html = this.htmlCache.get(componentName)!;\n const bytes = new Blob([html]).size;\n const duration = performance.now() - startTime;\n\n this.stats.totalLoads++;\n this.stats.totalLoadTime += duration;\n\n const loadInfo = { duration, bytes, fromCache: true, timestamp: Date.now() };\n this.detailedStats.set(componentName, loadInfo);\n this.config.onLoad(componentName, { duration, bytes, fromCache: true });\n\n return html;\n }\n\n this.stats.cacheMisses++;\n\n // Load CSS\n if (this.config.cssModules) {\n await this.loadBaseCSS().catch((err) => {\n console.warn('Failed to load base CSS:', err);\n });\n await this.loadComponentCSS(componentName).catch((err) => {\n console.warn(`Failed to load CSS for ${componentName}:`, err);\n });\n } else {\n await this.loadLegacyCSS().catch((err) => {\n console.warn('Failed to load legacy CSS:', err);\n });\n }\n\n // Fetch HTML\n const url = `${this.config.baseUrl}/${componentName}.html`;\n const response = await (this.config.enableRetry\n ? this.fetchWithRetry(url)\n : fetch(url));\n\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n }\n\n const html = await response.text();\n const bytes = new Blob([html]).size;\n\n // Cache HTML\n if (this.config.cacheHTML) {\n this.htmlCache.set(componentName, html);\n }\n\n // Update stats\n const duration = performance.now() - startTime;\n this.stats.totalLoads++;\n this.stats.totalLoadTime += duration;\n this.stats.totalBytes += bytes;\n\n this.log(`Loaded ${componentName} in ${duration.toFixed(2)}ms (${bytes} bytes)`);\n\n // Start tracking secondary assets (images, etc.) that might be triggered by this injection\n const secondaryAssets: Array<{ url: string; bytes: number; duration: number; type: string }> = [];\n\n const resourceObserver = new PerformanceObserver((list) => {\n list.getEntries().forEach((entry) => {\n const res = entry as PerformanceResourceTiming;\n // Filter for assets likely triggered by this component\n if (res.startTime >= (startTime - 50)) {\n const assetBytes = res.transferSize || res.decodedBodySize || res.encodedBodySize || 0;\n\n secondaryAssets.push({\n url: res.name,\n bytes: assetBytes,\n duration: res.duration,\n type: res.initiatorType\n });\n\n // Update total bytes and global stats with secondary assets\n this.stats.totalBytes += assetBytes;\n }\n });\n });\n\n try {\n // Use buffered: true to catch resources that might have started \n // between performance.now() and observe() call\n resourceObserver.observe({ entryTypes: ['resource'], buffered: true });\n\n // Stop observing after a reasonable time (longer for assets)\n setTimeout(() => resourceObserver.disconnect(), 6000);\n } catch (e) {\n this.log('PerformanceObserver failed');\n // Fallback attempt without buffering if that was the cause\n try { resourceObserver.observe({ entryTypes: ['resource'] }); } catch (err) { }\n }\n\n const loadInfo = {\n duration,\n bytes,\n fromCache: false,\n timestamp: Date.now(),\n secondaryAssets\n };\n this.detailedStats.set(componentName, loadInfo);\n this.config.onLoad(componentName, { duration, bytes, fromCache: false, secondaryAssets });\n\n return html;\n } catch (error) {\n this.stats.errors++;\n const err = error instanceof Error ? error : new Error(String(error));\n this.log(`Error loading ${componentName}:`, err);\n this.config.onError(componentName, err);\n throw err;\n }\n }\n\n /**\n * Inject HTML fragment into target element\n */\n async inject(componentName: string, targetSelector: string): Promise<void> {\n const html = await this.load(componentName);\n const target = document.querySelector(targetSelector);\n\n if (target) {\n target.innerHTML = html;\n this.log(`Injected ${componentName} into ${targetSelector}`);\n } else {\n const error = new Error(`Target element not found: ${targetSelector}`);\n this.config.onError(componentName, error);\n throw error;\n }\n }\n\n /**\n * Load HTML fragment when target element enters viewport\n */\n observeAndLoad(\n componentName: string,\n targetSelector: string,\n options?: IntersectionObserverInit,\n ): void {\n const target = document.querySelector(targetSelector);\n if (!target) {\n console.warn(`Target element not found: ${targetSelector}`);\n return;\n }\n\n const observer = new IntersectionObserver(\n (entries) => {\n entries.forEach((entry) => {\n if (entry.isIntersecting) {\n this.log(`Component ${componentName} entered viewport`);\n this.inject(componentName, targetSelector).catch((err) => {\n console.error(`Failed to inject ${componentName}:`, err);\n });\n observer.disconnect();\n this.observers.delete(componentName);\n }\n });\n },\n options || { rootMargin: '100px' },\n );\n\n observer.observe(target);\n this.observers.set(componentName, observer);\n this.log(`Observing ${componentName} at ${targetSelector}`);\n }\n\n /**\n * Preload HTML fragment without injecting\n */\n async preload(componentName: string): Promise<void> {\n await this.load(componentName);\n }\n\n /**\n * Batch preload multiple components\n */\n async preloadBatch(componentNames: string[]): Promise<void> {\n this.log(`Preloading ${componentNames.length} components:`, componentNames);\n await Promise.all(componentNames.map((name) => this.preload(name)));\n }\n\n /**\n * Get load statistics\n */\n getStats(): LoadStats {\n return {\n totalLoads: this.stats.totalLoads,\n cacheHits: this.stats.cacheHits,\n cacheMisses: this.stats.cacheMisses,\n errors: this.stats.errors,\n averageLoadTime:\n this.stats.totalLoads > 0\n ? this.stats.totalLoadTime / this.stats.totalLoads\n : 0,\n totalBytes: this.stats.totalBytes,\n };\n }\n\n /**\n * Get detailed history of all loads in this session\n */\n getDetailedHistory(): Array<{ componentName: string; duration: number; bytes: number; fromCache: boolean; timestamp: number }> {\n return Array.from(this.detailedStats.entries()).map(([name, info]) => ({\n componentName: name,\n ...info,\n })).sort((a, b) => b.timestamp - a.timestamp);\n }\n\n /**\n * Clear HTML cache\n */\n clearCache(): void {\n this.htmlCache.clear();\n this.log('HTML cache cleared');\n }\n\n /**\n * Clear CSS cache (forces reload of CSS files)\n */\n clearCSSCache(): void {\n this.cssCache.clear();\n this.baseCssLoaded = false;\n this.legacyCssLoaded = false;\n this.manifestLoaded = false;\n this.manifest = null;\n this.log('CSS cache cleared');\n }\n\n /**\n * Disconnect all observers\n */\n disconnectAll(): void {\n this.observers.forEach((observer) => observer.disconnect());\n this.observers.clear();\n this.log('All observers disconnected');\n }\n\n /**\n * Reset all state (cache, observers, stats)\n */\n reset(): void {\n this.clearCache();\n this.clearCSSCache();\n this.disconnectAll();\n this.stats = {\n totalLoads: 0,\n cacheHits: 0,\n cacheMisses: 0,\n errors: 0,\n totalLoadTime: 0,\n totalBytes: 0,\n };\n this.detailedStats.clear();\n this.log('LazyHTMLLoader reset');\n }\n}\n\n/**\n * Factory function to create a lazy loader instance\n */\nexport function createLazyLoader(config?: LazyLoaderConfig): LazyHTMLLoader {\n return new LazyHTMLLoader(config);\n}\n\n/**\n * Default lazy loader instance with default configuration\n */\nexport const lazyLoader = new LazyHTMLLoader();"],"mappings":"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","names":["LazyHTMLLoader","config","_a","_b","_c","_d","_e","_f","_g","_h","_i","_j","_k","_l","_m","_n","baseUrl","message","args","url","retries","attempt","response","error","resolve","startTime","duration","reject","link","preload","componentName","cssFile","cssUrl","html","bytes","loadInfo","err","secondaryAssets","resourceObserver","list","entry","res","assetBytes","e","targetSelector","target","options","observer","entries","componentNames","name","info","a","b","createLazyLoader","lazyLoader"]}
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{watch as ne}from"chokidar";import{join as w,relative as
|
|
1
|
+
import{watch as ne}from"chokidar";import{join as w,relative as M,basename as ie}from"path";import{createHash as _}from"crypto";import{readFile as G}from"fs/promises";import J from"fast-glob";import{outputFile as K,ensureDir as fe}from"fs-extra";import*as E from"cheerio";import{consola as q}from"consola";function A(c){return q.withTag(c)}async function H(c){let e=await G(c,"utf-8");return _("md5").update(e).digest("hex")}async function B(c){try{return await J("**/*.astro",{cwd:c,absolute:!0,ignore:["**/node_modules/**"]})}catch(e){return[]}}function O(c){let e=E.load(c),t=new Set;return e("[class]").each((r,s)=>{var l;(((l=e(s).attr("class"))==null?void 0:l.split(/\s+/))||[]).forEach(i=>{i&&t.add(i)})}),Array.from(t)}function I(c){let e=E.load(c),t=[];return e("style").each((r,s)=>{let o=e(s).html();o!=null&&o.trim()&&t.push(o)}),t}function V(c){let e=E.load(c);e("script").remove(),e("style").remove(),e("*").each((r,s)=>{let o=e(s),l=s.attribs||{};Object.keys(l).forEach(i=>{(i.startsWith("data-astro-source-")||i.startsWith("data-astro-cid-"))&&o.removeAttr(i)})});let t=e("body").html();return(t==null?void 0:t.trim())||e.html().trim()}async function D(c){try{let{minify:e}=await import("html-minifier-terser");return await e(c,{collapseWhitespace:!0,removeComments:!0,removeRedundantAttributes:!0,removeEmptyAttributes:!0,minifyCSS:!0,minifyJS:!0,conservativeCollapse:!0,preserveLineBreaks:!1})}catch(e){return console.warn("html-minifier-terser not available, skipping minification"),c}}async function L(c,e){await K(c,e,"utf-8")}import{FlatCache as Q}from"flat-cache";var P=class{constructor(e){this.loaded=!1;this.cache=new Q({cacheDir:e,cacheId:"prerender-cache"})}async load(){this.loaded||(this.cache.load(),this.loaded=!0)}async save(){this.cache.save()}isCached(e,t){return this.cache.getKey(e)===t}set(e,t){this.cache.setKey(e,t)}delete(e){this.cache.delete(e)}clear(){this.cache.clear()}};import{pathToFileURL as X}from"url";var F=class{constructor(e,t,r=!0){this.tailwindConfigPath=e,this.logger=t,this.classes=new Set,this.componentStyles=[],this.generateTailwind=r}addClasses(e){e.forEach(t=>this.classes.add(t))}addStyles(e){this.componentStyles.push(...e)}clear(){this.classes.clear(),this.componentStyles=[]}async generate(e){let t=Array.from(this.classes);if(this.logger.info(`CSS Generator state: ${t.length} classes, ${this.componentStyles.length} component styles`),t.length===0&&this.componentStyles.length===0){this.logger.warn("No classes or styles to generate CSS for");return}this.logger.info(`Generating CSS for ${t.length} classes and ${this.componentStyles.length} component styles...`);try{if(!this.generateTailwind&&this.componentStyles.length>0){let S=`/* Component Styles */
|
|
2
2
|
`+this.componentStyles.join(`
|
|
3
3
|
|
|
4
4
|
`);await L(e,S),this.logger.success(`CSS generated (component styles only): ${e}`);return}if(!this.generateTailwind&&t.length>0){if(this.logger.warn(`Found ${t.length} Tailwind classes but generateTailwindCSS is disabled. Enable it to include Tailwind styles.`),this.componentStyles.length>0){let S=`/* Component Styles */
|
|
@@ -13,10 +13,10 @@ import{watch as ne}from"chokidar";import{join as w,relative as x,basename as ie}
|
|
|
13
13
|
/* Component Styles */
|
|
14
14
|
`,f+=this.componentStyles.join(`
|
|
15
15
|
|
|
16
|
-
`));let y=await l([i(u),n]).process(f,{from:void 0});await L(e,y.css),this.logger.success(`CSS generated: ${e}`)}catch(r){throw this.logger.error(`Failed to generate CSS: ${r}`),r}}};import{readFile as Y}from"fs/promises";import"url";import{experimental_AstroContainer as Z}from"astro/container";var
|
|
16
|
+
`));let y=await l([i(u),n]).process(f,{from:void 0});await L(e,y.css),this.logger.success(`CSS generated: ${e}`)}catch(r){throw this.logger.error(`Failed to generate CSS: ${r}`),r}}};import{readFile as Y}from"fs/promises";import"url";import{experimental_AstroContainer as Z}from"astro/container";var T=class{constructor(e){this.logger=e,this.container=null,this.viteServer=null}setViteServer(e){this.viteServer=e}async init(){this.container||(this.container=await Z.create())}async render(e){await this.init();try{let r=(await Y(e,"utf-8")).match(/^---\s*\n([\s\S]*?)\n---/),s={};if(r){let a=r[1].matchAll(/(?:const|let|var)\s+(\w+)\s*=\s*["']([^"']+)["']/g);for(let g of a)s[g[1]]=g[2]}let o;if(!this.viteServer)return this.logger.warn("Container renderer requires Vite dev server - use Parser renderer for builds"),null;try{if(typeof this.viteServer.ssrLoadModule!="function")return this.logger.warn("Vite server does not support SSR module loading"),null;o=await this.viteServer.ssrLoadModule(e)}catch(n){let a=n;return this.logger.warn(`Failed to load via Vite SSR: ${a.message}`),null}let i=await this.container.renderToString(o.default,{props:s});for(let[n,a]of Object.entries(s)){let g=new RegExp(`\\{${n}\\}`,"g");i=i.replace(g,a)}return i}catch(t){let r=t;throw this.logger.error(`Failed to render ${e}: ${r.message}`),t}}};import{parse as ee}from"@astrojs/compiler";import{readFile as te}from"fs/promises";import{consola as re}from"consola";var x=class{constructor(){this.logger=re.withTag("ParserRenderer")}extractFrontmatter(e){let t=e.frontmatter;if(!t||typeof t.value!="string")return{};let r={},o=t.value.matchAll(/(?:const|let|var)\s+(\w+)\s*=\s*["']([^"']+)["']/g);for(let l of o)l[1]&&l[2]&&(r[l[1]]=l[2]);return r}nodeToHTML(e,t=""){if(e.type==="text")return e.value;if(e.type==="element"){let r=e,s=r.attributes.map(i=>i.kind==="quoted"&&i.name&&i.value?`${i.name}="${i.value}"`:i.kind==="empty"&&i.name?i.name:"").filter(Boolean).join(" "),o=s?`<${r.name} ${s}>`:`<${r.name}>`;if(!r.children||r.children.length===0)return["img","br","hr","input","meta","link"].includes(r.name)?`${o.replace(">"," />")}`:`${o}</${r.name}>`;let l=r.children.map(i=>this.nodeToHTML(i,t+" ")).join(`
|
|
17
17
|
`);return`${o}${l}</${r.name}>`}else if(e.type==="component"){let r=e;return this.logger.warn(`Component <${r.name} /> found but won't be resolved (use container renderer for imports)`),`<!-- Component: ${r.name} -->`}else{if(e.type==="expression")return`{${String(e)}}`;if(e.type==="frontmatter")return"";if(e.type==="style"){let r=e,s=(r.attributes||[]).map(n=>n.kind==="quoted"&&n.name&&n.value?`${n.name}="${n.value}"`:n.kind==="empty"&&n.name?n.name:"").filter(Boolean).join(" "),o=s?`<style ${s}>`:"<style>",l=(r.children||[]).map(n=>n.type==="text"?n.value:"").join(""),i=e.content||"";return`${o}${l||i}</style>`}}return""}replaceFrontmatterVars(e,t){let r=e;for(let[s,o]of Object.entries(t)){let l=s.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),i=new RegExp(`\\{${l}\\}`,"g");r=r.replace(i,o)}return r}async render(e){this.logger.info(`Rendering component: ${e}`);try{let t=await te(e,"utf-8"),s=(await ee(t)).ast,o=this.extractFrontmatter(s);this.logger.debug(`Extracted ${Object.keys(o).length} frontmatter variables`);let l="";return s.children&&(l=s.children.map(i=>this.nodeToHTML(i)).join(`
|
|
18
|
-
`)),l=this.replaceFrontmatterVars(l,o),this.logger.success(`Rendered ${e} (${l.length} chars)`),l}catch(t){let r=t;throw this.logger.error(`Failed to render ${e}: ${r.message}`),t}}};var F=class{constructor(e={}){this.htmlCache=new Map;this.cssCache=new Set;this.observers=new Map;this.manifest=null;this.manifestLoaded=!1;this.baseCssLoaded=!1;this.legacyCssLoaded=!1;this.stats={totalLoads:0,cacheHits:0,cacheMisses:0,errors:0,totalLoadTime:0,totalBytes:0};this.detailedStats=new Map;var t,r,s,o,l,i,n,a,g,d,u,f,y,S;this.config={baseUrl:(t=e.baseUrl)!=null?t:"/prerendered",cssModules:(r=e.cssModules)!=null?r:!1,manifestUrl:(s=e.manifestUrl)!=null?s:"/prerendered/manifest.json",baseCssUrl:(o=e.baseCssUrl)!=null?o:"/prerendered/base.css",legacyCssUrl:(l=e.legacyCssUrl)!=null?l:"/prerendered/lazy-components.css",preloadCSS:(i=e.preloadCSS)!=null?i:!1,cacheHTML:(n=e.cacheHTML)!=null?n:!0,enableRetry:(a=e.enableRetry)!=null?a:!0,maxRetries:(g=e.maxRetries)!=null?g:3,retryDelay:(d=e.retryDelay)!=null?d:1e3,debug:(u=e.debug)!=null?u:!1,onLoad:(f=e.onLoad)!=null?f:(()=>{}),onError:(y=e.onError)!=null?y:(()=>{}),onCSSLoad:(S=e.onCSSLoad)!=null?S:(()=>{})},this.log("LazyHTMLLoader initialized",this.config)}log(e,...t){this.config.debug&&console.log(`[LazyHTMLLoader] ${e}`,...t)}async fetchWithRetry(e,t=this.config.maxRetries){for(let r=1;r<=t;r++){try{this.log(`Fetching ${e} (attempt ${r}/${t})`);let s=await fetch(e);if(s.ok)return s;if(r===t)throw new Error(`HTTP ${s.status}: ${s.statusText}`);if(s.status===404)throw new Error(`Not found: ${e}`);this.log(`Fetch failed with status ${s.status}, retrying...`)}catch(s){if(r===t)throw s;this.log(`Fetch error: ${s}, retrying...`)}r<t&&await new Promise(s=>setTimeout(s,this.config.retryDelay*r))}throw new Error(`Failed to fetch ${e} after ${t} attempts`)}async loadManifest(){if(this.manifestLoaded)return;let e=performance.now();try{let t=await(this.config.enableRetry?this.fetchWithRetry(this.config.manifestUrl):fetch(this.config.manifestUrl));if(!t.ok)throw new Error(`Failed to load manifest: ${t.statusText}`);this.manifest=await t.json(),this.manifestLoaded=!0;let r=performance.now()-e;this.log(`Manifest loaded in ${r.toFixed(2)}ms`,this.manifest),this.config.onCSSLoad(this.config.manifestUrl,r)}catch(t){console.error("Failed to load CSS manifest:",t),this.config.cssModules=!1,this.manifestLoaded=!0}}async loadBaseCSS(){if(this.baseCssLoaded||(await this.loadManifest(),!this.manifest))return;let e=performance.now();return new Promise((t,r)=>{let s=document.createElement("link");if(s.rel="stylesheet",s.href=this.config.baseCssUrl,s.onload=()=>{this.baseCssLoaded=!0;let o=performance.now()-e;this.log(`Base CSS loaded in ${o.toFixed(2)}ms`),this.config.onCSSLoad(this.config.baseCssUrl,o),t()},s.onerror=()=>{console.error("Failed to load base CSS"),r(new Error("Failed to load base CSS"))},this.config.preloadCSS){let o=document.createElement("link");o.rel="preload",o.as="style",o.href=this.config.baseCssUrl,document.head.appendChild(o)}document.head.appendChild(s)})}async loadComponentCSS(e){if(!this.config.cssModules||!this.manifest)return;let t=this.manifest.components[e];if(!t){this.log(`No CSS file for component: ${e}`);return}if(this.cssCache.has(t)){this.log(`CSS already loaded: ${t}`);return}let r=performance.now(),s=`${this.config.baseUrl}/${t}`;return new Promise((o,l)=>{let i=document.createElement("link");if(i.rel="stylesheet",i.href=s,i.onload=()=>{this.cssCache.add(t);let n=performance.now()-r;this.log(`Component CSS loaded in ${n.toFixed(2)}ms: ${t}`),this.config.onCSSLoad(t,n),o()},i.onerror=()=>{console.error(`Failed to load component CSS: ${t}`),l(new Error(`Failed to load CSS: ${t}`))},this.config.preloadCSS){let n=document.createElement("link");n.rel="preload",n.as="style",n.href=s,document.head.appendChild(n)}document.head.appendChild(i)})}async loadLegacyCSS(){if(this.legacyCssLoaded)return;let e=performance.now();return new Promise((t,r)=>{let s=document.createElement("link");if(s.rel="stylesheet",s.href=this.config.legacyCssUrl,s.onload=()=>{this.legacyCssLoaded=!0;let o=performance.now()-e;this.log(`Legacy CSS loaded in ${o.toFixed(2)}ms`),this.config.onCSSLoad(this.config.legacyCssUrl,o),t()},s.onerror=()=>{console.error("Failed to load legacy CSS"),r(new Error("Failed to load lazy components CSS"))},this.config.preloadCSS){let o=document.createElement("link");o.rel="preload",o.as="style",o.href=this.config.legacyCssUrl,document.head.appendChild(o)}document.head.appendChild(s)})}async load(e){let t=performance.now();try{if(this.config.cacheHTML&&this.htmlCache.has(e)){this.stats.cacheHits++,this.log(`Cache hit: ${e}`);let d=this.htmlCache.get(e),u=new Blob([d]).size,f=performance.now()-t;this.stats.totalLoads++,this.stats.totalLoadTime+=f;let y={duration:f,bytes:u,fromCache:!0,timestamp:Date.now()};return this.detailedStats.set(e,y),this.config.onLoad(e,{duration:f,bytes:u,fromCache:!0}),d}this.stats.cacheMisses++,this.config.cssModules?(await this.loadBaseCSS().catch(d=>{console.warn("Failed to load base CSS:",d)}),await this.loadComponentCSS(e).catch(d=>{console.warn(`Failed to load CSS for ${e}:`,d)})):await this.loadLegacyCSS().catch(d=>{console.warn("Failed to load legacy CSS:",d)});let r=`${this.config.baseUrl}/${e}.html`,s=await(this.config.enableRetry?this.fetchWithRetry(r):fetch(r));if(!s.ok)throw new Error(`HTTP ${s.status}: ${s.statusText}`);let o=await s.text(),l=new Blob([o]).size;this.config.cacheHTML&&this.htmlCache.set(e,o);let i=performance.now()-t;this.stats.totalLoads++,this.stats.totalLoadTime+=i,this.stats.totalBytes+=l,this.log(`Loaded ${e} in ${i.toFixed(2)}ms (${l} bytes)`);let n=[],a=new PerformanceObserver(d=>{d.getEntries().forEach(u=>{let f=u;if(f.startTime>=t-50){let y=f.transferSize||f.decodedBodySize||f.encodedBodySize||0;n.push({url:f.name,bytes:y,duration:f.duration,type:f.initiatorType}),this.stats.totalBytes+=y}})});try{a.observe({entryTypes:["resource"],buffered:!0}),setTimeout(()=>a.disconnect(),6e3)}catch(d){this.log("PerformanceObserver failed");try{a.observe({entryTypes:["resource"]})}catch(u){}}let g={duration:i,bytes:l,fromCache:!1,timestamp:Date.now(),secondaryAssets:n};return this.detailedStats.set(e,g),this.config.onLoad(e,{duration:i,bytes:l,fromCache:!1,secondaryAssets:n}),o}catch(r){this.stats.errors++;let s=r instanceof Error?r:new Error(String(r));throw this.log(`Error loading ${e}:`,s),this.config.onError(e,s),s}}async inject(e,t){let r=await this.load(e),s=document.querySelector(t);if(s)s.innerHTML=r,this.log(`Injected ${e} into ${t}`);else{let o=new Error(`Target element not found: ${t}`);throw this.config.onError(e,o),o}}observeAndLoad(e,t,r){let s=document.querySelector(t);if(!s){console.warn(`Target element not found: ${t}`);return}let o=new IntersectionObserver(l=>{l.forEach(i=>{i.isIntersecting&&(this.log(`Component ${e} entered viewport`),this.inject(e,t).catch(n=>{console.error(`Failed to inject ${e}:`,n)}),o.disconnect(),this.observers.delete(e))})},r||{rootMargin:"100px"});o.observe(s),this.observers.set(e,o),this.log(`Observing ${e} at ${t}`)}async preload(e){await this.load(e)}async preloadBatch(e){this.log(`Preloading ${e.length} components:`,e),await Promise.all(e.map(t=>this.preload(t)))}getStats(){return{totalLoads:this.stats.totalLoads,cacheHits:this.stats.cacheHits,cacheMisses:this.stats.cacheMisses,errors:this.stats.errors,averageLoadTime:this.stats.totalLoads>0?this.stats.totalLoadTime/this.stats.totalLoads:0,totalBytes:this.stats.totalBytes}}getDetailedHistory(){return Array.from(this.detailedStats.entries()).map(([e,t])=>({componentName:e,...t})).sort((e,t)=>t.timestamp-e.timestamp)}clearCache(){this.htmlCache.clear(),this.log("HTML cache cleared")}clearCSSCache(){this.cssCache.clear(),this.baseCssLoaded=!1,this.legacyCssLoaded=!1,this.manifestLoaded=!1,this.manifest=null,this.log("CSS cache cleared")}disconnectAll(){this.observers.forEach(e=>e.disconnect()),this.observers.clear(),this.log("All observers disconnected")}reset(){this.clearCache(),this.clearCSSCache(),this.disconnectAll(),this.stats={totalLoads:0,cacheHits:0,cacheMisses:0,errors:0,totalLoadTime:0,totalBytes:0},this.detailedStats.clear(),this.log("LazyHTMLLoader reset")}};function se(c){return new F(c)}var oe=new F;function ae({componentsDir:c="src/components/Lazy",outputDir:e="public/prerendered",generateTailwindCSS:t=!0,tailwindConfigPath:r="tailwind.config.mjs",renderer:s="parser",minify:o=!0,base:l=""}={}){let i=l?(l.startsWith("/")?l:"/"+l).replace(/\/$/,""):"",n=A("astro-prerender"),a=null,g=null,d=null,u=null,f=null;async function y(){if(!(a!=null&&a.root))return;let h=a.root,p=w(h,c),C=w(h,e);n.info(`Processing components from ${c}...`),g&&await g.load(),d&&d.clear();let m=await B(p);if(m.length===0){n.warn(`No .astro files found in ${c}`);return}for(let R of m)await S(R);await E(),g&&await g.save(),n.success(`Processed ${m.length} component(s)`)}async function S(h){if(!(a!=null&&a.root))return;let p=a.root,C=w(p,e);try{if(g){let m=await H(h);if(g.isCached(h,m)){n.info(`Skipping cached: ${x(p,h)}`);return}}if(u){let m=await u.render(h);if(!m&&f&&(n.info(`Falling back to parser for: ${x(p,h)}`),m=await f.render(h)),m){let R=I(m);d&&R.length>0&&d.addStyles(R);let v=V(m);if(d){let b=O(v);d.addClasses(b)}if(o){let b=v.length;v=await D(v);let j=v.length,N=Math.round((1-j/b)*100);n.info(`Minified: ${b} \u2192 ${j} bytes (${N}% smaller)`)}let z=ie(h,".astro"),W=w(C,`${z}.html`);if(await L(W,v),g){let b=await H(h);g.set(h,b)}n.success(`${z}.html (${v.length} chars)`)}}}catch(m){n.error(`Failed to process ${x(p,h)}: ${m instanceof Error?m.message:"Unknown error"}`)}}async function E(){if(!d||!(a!=null&&a.root))return;let h=a.root,p=w(h,e),C=w(p,"lazy-components.css");await d.generate(C)}let U=e.replace(/^public\/?/,"");return{name:"astro-prerender-plugin",resolveId(h){return h==="virtual:astro-prerender-config"?h:null},load(h){if(h==="virtual:astro-prerender-config"){let p={base:i,prerenderedPath:`${i}/${U}`,cssPath:`${i}/${U}/lazy-components.css`};return`export const base = ${JSON.stringify(i)};
|
|
18
|
+
`)),l=this.replaceFrontmatterVars(l,o),this.logger.success(`Rendered ${e} (${l.length} chars)`),l}catch(t){let r=t;throw this.logger.error(`Failed to render ${e}: ${r.message}`),t}}};var R=class{constructor(e={}){this.htmlCache=new Map;this.cssCache=new Set;this.observers=new Map;this.manifest=null;this.manifestLoaded=!1;this.baseCssLoaded=!1;this.legacyCssLoaded=!1;this.stats={totalLoads:0,cacheHits:0,cacheMisses:0,errors:0,totalLoadTime:0,totalBytes:0};this.detailedStats=new Map;var r,s,o,l,i,n,a,g,d,u,f,y,S,b;let t=(r=e.baseUrl)!=null?r:"/prerendered";this.config={baseUrl:t,cssModules:(s=e.cssModules)!=null?s:!1,manifestUrl:(o=e.manifestUrl)!=null?o:`${t}/manifest.json`,baseCssUrl:(l=e.baseCssUrl)!=null?l:`${t}/base.css`,legacyCssUrl:(i=e.legacyCssUrl)!=null?i:`${t}/lazy-components.css`,preloadCSS:(n=e.preloadCSS)!=null?n:!1,cacheHTML:(a=e.cacheHTML)!=null?a:!0,enableRetry:(g=e.enableRetry)!=null?g:!0,maxRetries:(d=e.maxRetries)!=null?d:3,retryDelay:(u=e.retryDelay)!=null?u:1e3,debug:(f=e.debug)!=null?f:!1,onLoad:(y=e.onLoad)!=null?y:(()=>{}),onError:(S=e.onError)!=null?S:(()=>{}),onCSSLoad:(b=e.onCSSLoad)!=null?b:(()=>{})},this.log("LazyHTMLLoader initialized",this.config)}log(e,...t){this.config.debug&&console.log(`[LazyHTMLLoader] ${e}`,...t)}async fetchWithRetry(e,t=this.config.maxRetries){for(let r=1;r<=t;r++){try{this.log(`Fetching ${e} (attempt ${r}/${t})`);let s=await fetch(e);if(s.ok)return s;if(r===t)throw new Error(`HTTP ${s.status}: ${s.statusText}`);if(s.status===404)throw new Error(`Not found: ${e}`);this.log(`Fetch failed with status ${s.status}, retrying...`)}catch(s){if(r===t)throw s;this.log(`Fetch error: ${s}, retrying...`)}r<t&&await new Promise(s=>setTimeout(s,this.config.retryDelay*r))}throw new Error(`Failed to fetch ${e} after ${t} attempts`)}async loadManifest(){if(this.manifestLoaded)return;let e=performance.now();try{let t=await(this.config.enableRetry?this.fetchWithRetry(this.config.manifestUrl):fetch(this.config.manifestUrl));if(!t.ok)throw new Error(`Failed to load manifest: ${t.statusText}`);this.manifest=await t.json(),this.manifestLoaded=!0;let r=performance.now()-e;this.log(`Manifest loaded in ${r.toFixed(2)}ms`,this.manifest),this.config.onCSSLoad(this.config.manifestUrl,r)}catch(t){console.error("Failed to load CSS manifest:",t),this.config.cssModules=!1,this.manifestLoaded=!0}}async loadBaseCSS(){if(this.baseCssLoaded||(await this.loadManifest(),!this.manifest))return;let e=performance.now();return new Promise((t,r)=>{let s=document.createElement("link");if(s.rel="stylesheet",s.href=this.config.baseCssUrl,s.onload=()=>{this.baseCssLoaded=!0;let o=performance.now()-e;this.log(`Base CSS loaded in ${o.toFixed(2)}ms`),this.config.onCSSLoad(this.config.baseCssUrl,o),t()},s.onerror=()=>{console.error("Failed to load base CSS"),r(new Error("Failed to load base CSS"))},this.config.preloadCSS){let o=document.createElement("link");o.rel="preload",o.as="style",o.href=this.config.baseCssUrl,document.head.appendChild(o)}document.head.appendChild(s)})}async loadComponentCSS(e){if(!this.config.cssModules||!this.manifest)return;let t=this.manifest.components[e];if(!t){this.log(`No CSS file for component: ${e}`);return}if(this.cssCache.has(t)){this.log(`CSS already loaded: ${t}`);return}let r=performance.now(),s=`${this.config.baseUrl}/${t}`;return new Promise((o,l)=>{let i=document.createElement("link");if(i.rel="stylesheet",i.href=s,i.onload=()=>{this.cssCache.add(t);let n=performance.now()-r;this.log(`Component CSS loaded in ${n.toFixed(2)}ms: ${t}`),this.config.onCSSLoad(t,n),o()},i.onerror=()=>{console.error(`Failed to load component CSS: ${t}`),l(new Error(`Failed to load CSS: ${t}`))},this.config.preloadCSS){let n=document.createElement("link");n.rel="preload",n.as="style",n.href=s,document.head.appendChild(n)}document.head.appendChild(i)})}async loadLegacyCSS(){if(this.legacyCssLoaded)return;let e=performance.now();return new Promise((t,r)=>{let s=document.createElement("link");if(s.rel="stylesheet",s.href=this.config.legacyCssUrl,s.onload=()=>{this.legacyCssLoaded=!0;let o=performance.now()-e;this.log(`Legacy CSS loaded in ${o.toFixed(2)}ms`),this.config.onCSSLoad(this.config.legacyCssUrl,o),t()},s.onerror=()=>{console.error("Failed to load legacy CSS"),r(new Error("Failed to load lazy components CSS"))},this.config.preloadCSS){let o=document.createElement("link");o.rel="preload",o.as="style",o.href=this.config.legacyCssUrl,document.head.appendChild(o)}document.head.appendChild(s)})}async load(e){let t=performance.now();try{if(this.config.cacheHTML&&this.htmlCache.has(e)){this.stats.cacheHits++,this.log(`Cache hit: ${e}`);let d=this.htmlCache.get(e),u=new Blob([d]).size,f=performance.now()-t;this.stats.totalLoads++,this.stats.totalLoadTime+=f;let y={duration:f,bytes:u,fromCache:!0,timestamp:Date.now()};return this.detailedStats.set(e,y),this.config.onLoad(e,{duration:f,bytes:u,fromCache:!0}),d}this.stats.cacheMisses++,this.config.cssModules?(await this.loadBaseCSS().catch(d=>{console.warn("Failed to load base CSS:",d)}),await this.loadComponentCSS(e).catch(d=>{console.warn(`Failed to load CSS for ${e}:`,d)})):await this.loadLegacyCSS().catch(d=>{console.warn("Failed to load legacy CSS:",d)});let r=`${this.config.baseUrl}/${e}.html`,s=await(this.config.enableRetry?this.fetchWithRetry(r):fetch(r));if(!s.ok)throw new Error(`HTTP ${s.status}: ${s.statusText}`);let o=await s.text(),l=new Blob([o]).size;this.config.cacheHTML&&this.htmlCache.set(e,o);let i=performance.now()-t;this.stats.totalLoads++,this.stats.totalLoadTime+=i,this.stats.totalBytes+=l,this.log(`Loaded ${e} in ${i.toFixed(2)}ms (${l} bytes)`);let n=[],a=new PerformanceObserver(d=>{d.getEntries().forEach(u=>{let f=u;if(f.startTime>=t-50){let y=f.transferSize||f.decodedBodySize||f.encodedBodySize||0;n.push({url:f.name,bytes:y,duration:f.duration,type:f.initiatorType}),this.stats.totalBytes+=y}})});try{a.observe({entryTypes:["resource"],buffered:!0}),setTimeout(()=>a.disconnect(),6e3)}catch(d){this.log("PerformanceObserver failed");try{a.observe({entryTypes:["resource"]})}catch(u){}}let g={duration:i,bytes:l,fromCache:!1,timestamp:Date.now(),secondaryAssets:n};return this.detailedStats.set(e,g),this.config.onLoad(e,{duration:i,bytes:l,fromCache:!1,secondaryAssets:n}),o}catch(r){this.stats.errors++;let s=r instanceof Error?r:new Error(String(r));throw this.log(`Error loading ${e}:`,s),this.config.onError(e,s),s}}async inject(e,t){let r=await this.load(e),s=document.querySelector(t);if(s)s.innerHTML=r,this.log(`Injected ${e} into ${t}`);else{let o=new Error(`Target element not found: ${t}`);throw this.config.onError(e,o),o}}observeAndLoad(e,t,r){let s=document.querySelector(t);if(!s){console.warn(`Target element not found: ${t}`);return}let o=new IntersectionObserver(l=>{l.forEach(i=>{i.isIntersecting&&(this.log(`Component ${e} entered viewport`),this.inject(e,t).catch(n=>{console.error(`Failed to inject ${e}:`,n)}),o.disconnect(),this.observers.delete(e))})},r||{rootMargin:"100px"});o.observe(s),this.observers.set(e,o),this.log(`Observing ${e} at ${t}`)}async preload(e){await this.load(e)}async preloadBatch(e){this.log(`Preloading ${e.length} components:`,e),await Promise.all(e.map(t=>this.preload(t)))}getStats(){return{totalLoads:this.stats.totalLoads,cacheHits:this.stats.cacheHits,cacheMisses:this.stats.cacheMisses,errors:this.stats.errors,averageLoadTime:this.stats.totalLoads>0?this.stats.totalLoadTime/this.stats.totalLoads:0,totalBytes:this.stats.totalBytes}}getDetailedHistory(){return Array.from(this.detailedStats.entries()).map(([e,t])=>({componentName:e,...t})).sort((e,t)=>t.timestamp-e.timestamp)}clearCache(){this.htmlCache.clear(),this.log("HTML cache cleared")}clearCSSCache(){this.cssCache.clear(),this.baseCssLoaded=!1,this.legacyCssLoaded=!1,this.manifestLoaded=!1,this.manifest=null,this.log("CSS cache cleared")}disconnectAll(){this.observers.forEach(e=>e.disconnect()),this.observers.clear(),this.log("All observers disconnected")}reset(){this.clearCache(),this.clearCSSCache(),this.disconnectAll(),this.stats={totalLoads:0,cacheHits:0,cacheMisses:0,errors:0,totalLoadTime:0,totalBytes:0},this.detailedStats.clear(),this.log("LazyHTMLLoader reset")}};function se(c){return new R(c)}var oe=new R;function ae({componentsDir:c="src/components/Lazy",outputDir:e="public/prerendered",generateTailwindCSS:t=!0,tailwindConfigPath:r="tailwind.config.mjs",renderer:s="parser",minify:o=!0,base:l=""}={}){let i=l?(l.startsWith("/")?l:"/"+l).replace(/\/$/,""):"",n=A("astro-prerender"),a=null,g=null,d=null,u=null,f=null;async function y(){if(!(a!=null&&a.root))return;let h=a.root,p=w(h,c),C=w(h,e);n.info(`Processing components from ${c}...`),g&&await g.load(),d&&d.clear();let m=await B(p);if(m.length===0){n.warn(`No .astro files found in ${c}`);return}for(let k of m)await S(k);await b(),g&&await g.save(),n.success(`Processed ${m.length} component(s)`)}async function S(h){if(!(a!=null&&a.root))return;let p=a.root,C=w(p,e);try{if(g){let m=await H(h);if(g.isCached(h,m)){n.info(`Skipping cached: ${M(p,h)}`);return}}if(u){let m=await u.render(h);if(!m&&f&&(n.info(`Falling back to parser for: ${M(p,h)}`),m=await f.render(h)),m){let k=I(m);d&&k.length>0&&d.addStyles(k);let v=V(m);if(d){let $=O(v);d.addClasses($)}if(o){let $=v.length;v=await D(v);let j=v.length,N=Math.round((1-j/$)*100);n.info(`Minified: ${$} \u2192 ${j} bytes (${N}% smaller)`)}let z=ie(h,".astro"),W=w(C,`${z}.html`);if(await L(W,v),g){let $=await H(h);g.set(h,$)}n.success(`${z}.html (${v.length} chars)`)}}}catch(m){n.error(`Failed to process ${M(p,h)}: ${m instanceof Error?m.message:"Unknown error"}`)}}async function b(){if(!d||!(a!=null&&a.root))return;let h=a.root,p=w(h,e),C=w(p,"lazy-components.css");await d.generate(C)}let U=e.replace(/^public\/?/,"");return{name:"astro-prerender-plugin",resolveId(h){return h==="virtual:astro-prerender-config"?h:null},load(h){if(h==="virtual:astro-prerender-config"){let p={base:i,prerenderedPath:`${i}/${U}`,cssPath:`${i}/${U}/lazy-components.css`};return`export const base = ${JSON.stringify(i)};
|
|
19
19
|
export const prerenderedPath = ${JSON.stringify(p.prerenderedPath)};
|
|
20
20
|
export const cssPath = ${JSON.stringify(p.cssPath)};
|
|
21
|
-
export default ${JSON.stringify(p)};`}return null},configResolved(h){a=h;let p=a.root;g=new
|
|
21
|
+
export default ${JSON.stringify(p)};`}return null},configResolved(h){a=h;let p=a.root;g=new P(w(p,e)),d=new F(w(p,r),n,t),s==="container"?(u=new T(n),f=new x,n.info("Using Container API renderer (supports imports)")):(u=new x,n.info("Using Parser renderer (simpler, no imports)"))},async buildStart(){(a==null?void 0:a.command)==="build"&&await y()},async configureServer(h){u instanceof T&&u.setViteServer(h),await y();let p=w((a==null?void 0:a.root)||"",c),C=ne(p,{ignored:/node_modules/,persistent:!0});C.on("change",async m=>{a!=null&&a.root&&(n.info(`Component changed: ${M(a.root,m)}`),await S(m),await b())}),C.on("add",async m=>{a!=null&&a.root&&(n.info(`Component added: ${M(a.root,m)}`),await S(m),await b())}),C.on("unlink",m=>{a!=null&&a.root&&(n.info(`Component removed: ${M(a.root,m)}`),g==null||g.delete(m))})}}}function Oe(c={}){return{name:"astro-prerender-integration",hooks:{"astro:config:setup":({config:e,updateConfig:t})=>{var s,o;let r=(o=(s=c.base)!=null?s:e.base)!=null?o:"";t({vite:{plugins:[ae({...c,base:r})]}})}}}}export{F as CSSGenerator,P as CacheManager,T as ContainerRenderer,R as LazyHTMLLoader,x as ParserRenderer,Oe as astroPrerenderIntegration,ae as astroPrerenderPlugin,se as createLazyLoader,oe as lazyLoader};
|
|
22
22
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/utils/index.ts","../src/utils/logger.ts","../src/utils/cache.ts","../src/utils/css-generator.ts","../src/utils/container-renderer.ts","../src/utils/parser-renderer.ts","../src/utils/LazyLoader.ts"],"sourcesContent":["// src/index.ts\nimport { watch } from 'chokidar';\nimport { join, relative, basename } from 'node:path';\nimport {\n createLogger,\n findComponents,\n extractClasses,\n extractStyles,\n cleanHTML,\n minifyHTML,\n getFileHash,\n writeFileWithDir,\n} from './utils';\nimport { CacheManager } from './utils/cache';\nimport { CSSGenerator } from './utils/css-generator';\nimport { ContainerRenderer } from './utils/container-renderer';\nimport { ParserRenderer } from './utils/parser-renderer';\nimport type { AstroIntegration } from 'astro';\nimport type { Plugin as VitePlugin, ResolvedConfig, ViteDevServer } from 'vite';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Plugin configuration options\n */\nexport interface PluginOptions {\n /** Directory containing components to prerender (default: 'src/components/Lazy') */\n componentsDir?: string;\n /** Output directory for prerendered files (default: 'public/prerendered') */\n outputDir?: string;\n /** Generate Tailwind CSS file with tree-shaking (default: true) */\n generateTailwindCSS?: boolean;\n /** Path to Tailwind config file (default: 'tailwind.config.mjs') */\n tailwindConfigPath?: string;\n /** Rendering strategy: 'parser' (simple) or 'container' (full features) */\n renderer?: 'parser' | 'container';\n /** Minify HTML output to reduce file size (default: true) */\n minify?: boolean;\n /** Base URL path for the site (e.g., '/my-subdir'). Read from Astro config if not specified. */\n base?: string;\n}\n\n// ============================================================================\n// Vite Plugin\n// ============================================================================\n\n/**\n * Astro Prerender Vite Plugin\n * Prerenders Astro components to static HTML and generates optimized CSS\n */\nexport function astroPrerenderPlugin({\n componentsDir = 'src/components/Lazy',\n outputDir = 'public/prerendered',\n generateTailwindCSS = true,\n tailwindConfigPath = 'tailwind.config.mjs',\n renderer = 'parser',\n minify = true,\n base = '',\n}: PluginOptions = {}): VitePlugin {\n // Normalize base path: ensure it starts with / and doesn't end with /\n const normalizedBase = base ? (base.startsWith('/') ? base : '/' + base).replace(/\\/$/, '') : '';\n const logger = createLogger('astro-prerender');\n let config: ResolvedConfig | null = null;\n let cacheManager: CacheManager | null = null;\n let cssGenerator: CSSGenerator | null = null;\n let componentRenderer: ContainerRenderer | ParserRenderer | null = null;\n let parserFallback: ParserRenderer | null = null;\n\n /**\n * Process all components\n */\n async function processAll(): Promise<void> {\n if (!config?.root) return;\n\n const root = config.root;\n const componentsPath = join(root, componentsDir);\n const outputPath = join(root, outputDir);\n\n logger.info(`Processing components from ${componentsDir}...`);\n\n // Load cache\n if (cacheManager) {\n await cacheManager.load();\n }\n\n // Clear CSS generator\n if (cssGenerator) {\n cssGenerator.clear();\n }\n\n // Find all components\n const componentFiles = await findComponents(componentsPath);\n\n if (componentFiles.length === 0) {\n logger.warn(`No .astro files found in ${componentsDir}`);\n return;\n }\n\n // Process each component\n for (const componentPath of componentFiles) {\n await processComponent(componentPath);\n }\n\n // Generate CSS\n await generateCSS();\n\n // Save cache\n if (cacheManager) {\n await cacheManager.save();\n }\n\n logger.success(`Processed ${componentFiles.length} component(s)`);\n }\n\n /**\n * Process a single component\n */\n async function processComponent(componentPath: string): Promise<void> {\n if (!config?.root) return;\n\n const root = config.root;\n const outputPath = join(root, outputDir);\n\n try {\n // Check cache\n if (cacheManager) {\n const hash = await getFileHash(componentPath);\n if (cacheManager.isCached(componentPath, hash)) {\n logger.info(`Skipping cached: ${relative(root, componentPath)}`);\n return;\n }\n }\n\n // Render component\n if (componentRenderer) {\n let html = await componentRenderer.render(componentPath);\n\n // If container renderer returned null, fall back to parser\n if (!html && parserFallback) {\n logger.info(`Falling back to parser for: ${relative(root, componentPath)}`);\n html = await parserFallback.render(componentPath);\n }\n\n if (html) {\n // Extract styles before cleaning HTML\n const styles = extractStyles(html);\n\n if (cssGenerator && styles.length > 0) {\n cssGenerator.addStyles(styles);\n }\n\n // Clean HTML\n let cleanedHTML = cleanHTML(html);\n\n // Extract Tailwind classes\n if (cssGenerator) {\n const classes = extractClasses(cleanedHTML);\n cssGenerator.addClasses(classes);\n }\n\n // Minify HTML if enabled\n if (minify) {\n const originalSize = cleanedHTML.length;\n cleanedHTML = await minifyHTML(cleanedHTML);\n const minifiedSize = cleanedHTML.length;\n const savings = Math.round((1 - minifiedSize / originalSize) * 100);\n logger.info(`Minified: ${originalSize} → ${minifiedSize} bytes (${savings}% smaller)`);\n }\n\n // Write HTML file\n const componentName = basename(componentPath, '.astro');\n const htmlOutputPath = join(outputPath, `${componentName}.html`);\n\n await writeFileWithDir(htmlOutputPath, cleanedHTML);\n\n // Update cache\n if (cacheManager) {\n const hash = await getFileHash(componentPath);\n cacheManager.set(componentPath, hash);\n }\n\n logger.success(`${componentName}.html (${cleanedHTML.length} chars)`);\n }\n }\n } catch (error) {\n logger.error(\n `Failed to process ${relative(root, componentPath)}: ${error instanceof Error ? error.message : 'Unknown error'\n }`\n );\n }\n }\n\n /**\n * Generate CSS file\n */\n async function generateCSS(): Promise<void> {\n if (!cssGenerator || !config?.root) return;\n\n const root = config.root;\n const outputPath = join(root, outputDir);\n const cssOutputPath = join(outputPath, 'lazy-components.css');\n\n await cssGenerator.generate(cssOutputPath);\n }\n\n // Compute the prerendered path relative to public (e.g., 'prerendered' from 'public/prerendered')\n const prerenderedPath = outputDir.replace(/^public\\/?/, '');\n\n return {\n name: 'astro-prerender-plugin',\n\n resolveId(id: string) {\n if (id === 'virtual:astro-prerender-config') {\n return id; // Return the id as-is, no prefix needed\n }\n return null;\n },\n\n load(id: string) {\n if (id === 'virtual:astro-prerender-config') {\n // Export config for client-side usage\n const clientConfig = {\n base: normalizedBase,\n prerenderedPath: `${normalizedBase}/${prerenderedPath}`,\n cssPath: `${normalizedBase}/${prerenderedPath}/lazy-components.css`,\n };\n return `export const base = ${JSON.stringify(normalizedBase)};\nexport const prerenderedPath = ${JSON.stringify(clientConfig.prerenderedPath)};\nexport const cssPath = ${JSON.stringify(clientConfig.cssPath)};\nexport default ${JSON.stringify(clientConfig)};`;\n }\n return null;\n },\n\n configResolved(resolvedConfig: ResolvedConfig) {\n config = resolvedConfig;\n const root = config.root;\n\n // Initialize cache manager\n cacheManager = new CacheManager(join(root, outputDir));\n\n // Always initialize CSS generator (it will handle component styles even without Tailwind)\n cssGenerator = new CSSGenerator(\n join(root, tailwindConfigPath),\n logger,\n generateTailwindCSS\n );\n\n // Initialize renderer based on config\n if (renderer === 'container') {\n componentRenderer = new ContainerRenderer(logger);\n parserFallback = new ParserRenderer(); // Fallback for when container fails\n logger.info('Using Container API renderer (supports imports)');\n } else {\n componentRenderer = new ParserRenderer();\n logger.info('Using Parser renderer (simpler, no imports)');\n }\n },\n\n async buildStart() {\n if (config?.command === 'build') {\n await processAll();\n }\n },\n\n async configureServer(server: ViteDevServer) {\n // Set Vite server for Container renderer\n if (componentRenderer instanceof ContainerRenderer) {\n componentRenderer.setViteServer(server);\n }\n\n // Initial processing\n await processAll();\n\n // Watch for changes in components directory\n const componentsPath = join(config?.root || '', componentsDir);\n const watcher = watch(componentsPath, {\n ignored: /node_modules/,\n persistent: true,\n });\n\n watcher.on('change', async (filePath: string) => {\n if (!config?.root) return;\n\n logger.info(`Component changed: ${relative(config.root, filePath)}`);\n await processComponent(filePath);\n await generateCSS();\n });\n\n watcher.on('add', async (filePath: string) => {\n if (!config?.root) return;\n\n logger.info(`Component added: ${relative(config.root, filePath)}`);\n await processComponent(filePath);\n await generateCSS();\n });\n\n watcher.on('unlink', (filePath: string) => {\n if (!config?.root) return;\n\n logger.info(`Component removed: ${relative(config.root, filePath)}`);\n cacheManager?.delete(filePath);\n });\n },\n };\n}\n\n// ============================================================================\n// Astro Integration\n// ============================================================================\n\n/**\n * Astro Integration wrapper for the prerender plugin\n * Use this in your astro.config.mjs integrations array\n * \n * @example\n * ```js\n * import { astroPrerenderIntegration } from 'astro-prerender-plugin';\n * \n * export default defineConfig({\n * integrations: [\n * astroPrerenderIntegration({\n * componentsDir: 'src/components/Lazy',\n * }),\n * ],\n * });\n * ```\n */\nexport function astroPrerenderIntegration(options: PluginOptions = {}): AstroIntegration {\n return {\n name: 'astro-prerender-integration',\n hooks: {\n 'astro:config:setup': ({ config, updateConfig }) => {\n // Read base from Astro config if not explicitly provided\n const baseFromConfig = options.base ?? config.base ?? '';\n\n updateConfig({\n vite: {\n plugins: [astroPrerenderPlugin({ ...options, base: baseFromConfig })],\n },\n });\n },\n },\n };\n}\n\n// ============================================================================\n// Re-exports\n// ============================================================================\n\n// Core utilities\nexport { CacheManager } from './utils/cache';\nexport { CSSGenerator } from './utils/css-generator';\nexport { ContainerRenderer } from './utils/container-renderer';\nexport { ParserRenderer } from './utils/parser-renderer';\nexport type { Logger } from './utils/logger';\n\n// Lazy loader (client-side utility)\nexport {\n LazyHTMLLoader,\n createLazyLoader,\n lazyLoader,\n type LazyLoaderConfig,\n type CSSModuleManifest,\n type LoadStats,\n} from './utils/LazyLoader';","// src/utils/index.ts\nimport { createHash } from 'node:crypto';\nimport { readFile } from 'node:fs/promises';\nimport fg from 'fast-glob';\nimport { outputFile, ensureDir as fsEnsureDir } from 'fs-extra';\nimport * as cheerio from 'cheerio';\n\n// Re-export logger\nexport { createLogger, type Logger } from './logger';\n\n/**\n * Get MD5 hash of file content\n */\nexport async function getFileHash(filePath: string): Promise<string> {\n const content = await readFile(filePath, 'utf-8');\n return createHash('md5').update(content).digest('hex');\n}\n\n/**\n * Find all .astro files recursively in a directory using fast-glob\n */\nexport async function findComponents(dir: string): Promise<string[]> {\n try {\n return await fg('**/*.astro', {\n cwd: dir,\n absolute: true,\n ignore: ['**/node_modules/**'],\n });\n } catch {\n // Directory doesn't exist or is not accessible\n return [];\n }\n}\n\n/**\n * Extract Tailwind classes from HTML using Cheerio\n */\nexport function extractClasses(html: string): string[] {\n const $ = cheerio.load(html);\n const classes = new Set<string>();\n\n $('[class]').each((_, el) => {\n const classList = $(el).attr('class')?.split(/\\s+/) || [];\n classList.forEach((cls) => {\n if (cls) classes.add(cls);\n });\n });\n\n return Array.from(classes);\n}\n\n/**\n * Extract style tags from HTML using Cheerio\n */\nexport function extractStyles(html: string): string[] {\n const $ = cheerio.load(html);\n const styles: string[] = [];\n\n $('style').each((_, el) => {\n const content = $(el).html();\n if (content?.trim()) {\n styles.push(content);\n }\n });\n\n return styles;\n}\n\n/**\n * Clean HTML output by removing unnecessary elements using Cheerio\n */\nexport function cleanHTML(html: string): string {\n const $ = cheerio.load(html);\n\n // Remove script tags\n $('script').remove();\n\n // Remove style tags (they're externalized)\n $('style').remove();\n\n // Remove data-astro-* attributes\n $('*').each((_, el) => {\n const $el = $(el);\n const attrs = (el as unknown as { attribs?: Record<string, string> }).attribs || {};\n\n Object.keys(attrs).forEach((attr) => {\n if (attr.startsWith('data-astro-source-') || attr.startsWith('data-astro-cid-')) {\n $el.removeAttr(attr);\n }\n });\n });\n\n // Get the body content (Cheerio wraps in html/head/body)\n const body = $('body').html();\n return body?.trim() || $.html().trim();\n}\n\n/**\n * Minify HTML using html-minifier-terser\n */\nexport async function minifyHTML(html: string): Promise<string> {\n try {\n const { minify } = await import('html-minifier-terser');\n\n return await minify(html, {\n collapseWhitespace: true,\n removeComments: true,\n removeRedundantAttributes: true,\n removeEmptyAttributes: true,\n minifyCSS: true,\n minifyJS: true,\n conservativeCollapse: true,\n preserveLineBreaks: false,\n });\n } catch (error) {\n console.warn('html-minifier-terser not available, skipping minification');\n return html;\n }\n}\n\n/**\n * Ensure directory exists (using fs-extra)\n */\nexport { fsEnsureDir as ensureDir };\n\n/**\n * Write file with directory creation (using fs-extra)\n */\nexport async function writeFileWithDir(filePath: string, content: string): Promise<void> {\n await outputFile(filePath, content, 'utf-8');\n}","// src/utils/logger.ts\nimport { consola, type ConsolaInstance } from 'consola';\n\n/**\n * Create a logger instance with a specific tag\n * Uses Consola for beautiful, structured logging\n */\nexport function createLogger(tag: string): ConsolaInstance {\n return consola.withTag(tag);\n}\n\nexport type Logger = ConsolaInstance;\n","// src/utils/cache.ts\nimport { FlatCache } from 'flat-cache';\n\n/**\n * Manages cache for rendered components using flat-cache\n * Uses file hashes to skip unchanged components\n */\nexport class CacheManager {\n private cache: FlatCache;\n private loaded: boolean = false;\n\n constructor(cacheDir: string) {\n this.cache = new FlatCache({\n cacheDir,\n cacheId: 'prerender-cache',\n });\n }\n\n /**\n * Load cache from disk\n */\n async load(): Promise<void> {\n if (!this.loaded) {\n this.cache.load();\n this.loaded = true;\n }\n }\n\n /**\n * Save cache to disk\n */\n async save(): Promise<void> {\n this.cache.save();\n }\n\n /**\n * Check if component is cached with same hash\n */\n isCached(componentPath: string, hash: string): boolean {\n return this.cache.getKey(componentPath) === hash;\n }\n\n /**\n * Set component hash in cache\n */\n set(componentPath: string, hash: string): void {\n this.cache.setKey(componentPath, hash);\n }\n\n /**\n * Delete component from cache\n */\n delete(componentPath: string): void {\n this.cache.delete(componentPath);\n }\n\n /**\n * Clear all cache\n */\n clear(): void {\n this.cache.clear();\n }\n}","// src/utils/css-generator.ts\nimport { pathToFileURL } from 'node:url';\nimport { writeFileWithDir } from './index';\nimport type { Logger } from './logger';\nimport type { AcceptedPlugin } from 'postcss';\n\n/**\n * Generates CSS from Tailwind classes and component styles\n * Tree-shakes Tailwind to only include used classes\n */\nexport class CSSGenerator {\n private tailwindConfigPath: string;\n private logger: Logger;\n private classes: Set<string>;\n private componentStyles: string[];\n private generateTailwind: boolean;\n\n constructor(tailwindConfigPath: string, logger: Logger, generateTailwind: boolean = true) {\n this.tailwindConfigPath = tailwindConfigPath;\n this.logger = logger;\n this.classes = new Set();\n this.componentStyles = [];\n this.generateTailwind = generateTailwind;\n }\n\n /**\n * Add Tailwind classes to generate CSS for\n */\n addClasses(classes: string[]): void {\n classes.forEach((cls) => this.classes.add(cls));\n }\n\n /**\n * Add component styles to include in CSS\n */\n addStyles(styles: string[]): void {\n this.componentStyles.push(...styles);\n }\n\n /**\n * Clear all classes and styles\n */\n clear(): void {\n this.classes.clear();\n this.componentStyles = [];\n }\n\n /**\n * Generate CSS file with Tailwind and component styles\n */\n async generate(outputPath: string): Promise<void> {\n const classArray = Array.from(this.classes);\n\n this.logger.info(\n `CSS Generator state: ${classArray.length} classes, ${this.componentStyles.length} component styles`,\n );\n\n if (classArray.length === 0 && this.componentStyles.length === 0) {\n this.logger.warn('No classes or styles to generate CSS for');\n return;\n }\n\n this.logger.info(\n `Generating CSS for ${classArray.length} classes and ${this.componentStyles.length} component styles...`,\n );\n\n try {\n // If Tailwind is disabled and we only have component styles, just write them directly\n if (!this.generateTailwind && this.componentStyles.length > 0) {\n const cssContent = '/* Component Styles */\\n' + this.componentStyles.join('\\n\\n');\n await writeFileWithDir(outputPath, cssContent);\n this.logger.success(`CSS generated (component styles only): ${outputPath}`);\n return;\n }\n\n // If Tailwind is disabled but we have classes, warn the user\n if (!this.generateTailwind && classArray.length > 0) {\n this.logger.warn(\n `Found ${classArray.length} Tailwind classes but generateTailwindCSS is disabled. Enable it to include Tailwind styles.`,\n );\n // Still output component styles if we have them\n if (this.componentStyles.length > 0) {\n const cssContent = '/* Component Styles */\\n' + this.componentStyles.join('\\n\\n');\n await writeFileWithDir(outputPath, cssContent);\n this.logger.success(`CSS generated (component styles only): ${outputPath}`);\n }\n return;\n }\n\n // Full Tailwind + component styles processing\n // Dynamically import dependencies (they're optional peer deps)\n const [postcssModule, tailwindModule, autoprefixerModule] = await Promise.all([\n import('postcss'),\n import('tailwindcss'),\n import('autoprefixer'),\n ]);\n\n const postcss = postcssModule.default;\n const tailwindcss = tailwindModule.default;\n const autoprefixer = autoprefixerModule.default;\n\n // Load the Tailwind config\n const configUrl = pathToFileURL(this.tailwindConfigPath).href;\n const configModule = await import(configUrl);\n const tailwindConfig = configModule.default;\n\n // Override the content to only process the extracted classes\n const modifiedConfig = {\n ...tailwindConfig,\n content: [\n {\n raw: classArray\n .map((cls) => `<div class=\"${cls}\"></div>`)\n .join('\\n'),\n },\n ],\n safelist: classArray,\n };\n\n // Create CSS content with Tailwind directives\n let cssContent = `\n@tailwind base;\n@tailwind components;\n@tailwind utilities;\n`;\n\n // Add component styles if any\n if (this.componentStyles.length > 0) {\n cssContent += '\\n/* Component Styles */\\n';\n cssContent += this.componentStyles.join('\\n\\n');\n }\n\n // Process with PostCSS\n const result = await postcss([\n tailwindcss(modifiedConfig) as AcceptedPlugin,\n autoprefixer as AcceptedPlugin,\n ]).process(cssContent, {\n from: undefined,\n });\n\n // Write the generated CSS\n await writeFileWithDir(outputPath, result.css);\n\n this.logger.success(`CSS generated: ${outputPath}`);\n } catch (error) {\n this.logger.error(`Failed to generate CSS: ${error}`);\n throw error;\n }\n }\n}","// src/utils/container-renderer.ts\nimport { readFile } from 'node:fs/promises';\nimport { pathToFileURL } from 'node:url';\nimport { experimental_AstroContainer as AstroContainer } from 'astro/container';\nimport type { Logger } from './logger';\n\ninterface ViteDevServer {\n ssrLoadModule(url: string): Promise<Record<string, unknown>>;\n}\n\n/**\n * Renders components using Astro Container API\n * Supports component imports and full Astro features\n */\nexport class ContainerRenderer {\n private logger: Logger;\n private container: Awaited<ReturnType<typeof AstroContainer.create>> | null;\n private viteServer: ViteDevServer | null;\n\n constructor(logger: Logger) {\n this.logger = logger;\n this.container = null;\n this.viteServer = null;\n }\n\n /**\n * Set Vite server instance (required for dev mode)\n */\n setViteServer(server: ViteDevServer): void {\n this.viteServer = server;\n }\n\n /**\n * Initialize the container\n */\n private async init(): Promise<void> {\n if (!this.container) {\n this.container = await AstroContainer.create();\n }\n }\n\n /**\n * Render a component to HTML\n */\n async render(componentPath: string): Promise<string> {\n await this.init();\n\n try {\n const fileContent = await readFile(componentPath, 'utf-8');\n\n // Extract frontmatter to get variable values\n const frontmatterMatch = fileContent.match(/^---\\s*\\n([\\s\\S]*?)\\n---/);\n const frontmatterVars: Record<string, string> = {};\n\n if (frontmatterMatch) {\n const frontmatterCode = frontmatterMatch[1];\n // Simple extraction of const/let/var declarations\n const varMatches = frontmatterCode.matchAll(\n /(?:const|let|var)\\s+(\\w+)\\s*=\\s*[\"']([^\"']+)[\"']/g,\n );\n for (const match of varMatches) {\n frontmatterVars[match[1]] = match[2];\n }\n }\n\n let ComponentModule: Record<string, unknown>;\n\n // Container renderer requires Vite SSR to work with .astro files\n if (!this.viteServer) {\n this.logger.warn('Container renderer requires Vite dev server - use Parser renderer for builds');\n return null as unknown as string;\n }\n\n try {\n // Ensure the server has the ssrLoadModule method\n if (typeof this.viteServer.ssrLoadModule !== 'function') {\n this.logger.warn('Vite server does not support SSR module loading');\n return null as unknown as string;\n }\n\n ComponentModule = await this.viteServer.ssrLoadModule(componentPath);\n } catch (error: unknown) {\n const err = error as Error;\n this.logger.warn(`Failed to load via Vite SSR: ${err.message}`);\n // Return null to signal fallback to parser renderer\n return null as unknown as string;\n }\n\n // Render the component with props from frontmatter\n const result = await this.container!.renderToString(\n ComponentModule.default as Awaited<ReturnType<typeof AstroContainer.create>> extends { renderToString: (c: infer T, ...args: unknown[]) => unknown } ? T : never,\n {\n props: frontmatterVars,\n },\n );\n\n // Replace {varName} expressions with actual values\n let html = result;\n for (const [key, value] of Object.entries(frontmatterVars)) {\n const regex = new RegExp(`\\\\{${key}\\\\}`, 'g');\n html = html.replace(regex, value);\n }\n\n return html;\n } catch (error: unknown) {\n const err = error as Error;\n this.logger.error(`Failed to render ${componentPath}: ${err.message}`);\n throw error;\n }\n }\n}","// src/utils/parser-renderer.ts\nimport { parse } from '@astrojs/compiler';\nimport { readFile } from 'node:fs/promises';\nimport { consola } from 'consola';\nimport type { RootNode, Node, ElementNode, AttributeNode } from '@astrojs/compiler/types';\n\n/**\n * Renders components using Astro's AST parser\n * Simpler approach but doesn't resolve component imports\n */\nexport class ParserRenderer {\n private logger = consola.withTag('ParserRenderer');\n\n /**\n * Extract frontmatter variables from AST\n */\n private extractFrontmatter(ast: RootNode): Record<string, string> {\n const frontmatter = (ast as unknown as { frontmatter?: { value?: string } }).frontmatter;\n if (!frontmatter || typeof frontmatter.value !== 'string') return {};\n\n const vars: Record<string, string> = {};\n const code = frontmatter.value;\n\n // Safe regex with limits\n const varMatches = code.matchAll(\n /(?:const|let|var)\\s+(\\w+)\\s*=\\s*[\"']([^\"']+)[\"']/g\n );\n\n for (const match of varMatches) {\n if (match[1] && match[2]) {\n vars[match[1]] = match[2];\n }\n }\n\n return vars;\n }\n\n /**\n * Convert AST node to HTML string\n */\n private nodeToHTML(node: Node, indent = ''): string {\n if (node.type === 'text') {\n return (node as { type: 'text'; value: string }).value;\n } else if (node.type === 'element') {\n const elementNode = node as ElementNode;\n const attrs = elementNode.attributes\n .map((attr: AttributeNode) => {\n if (attr.kind === 'quoted' && attr.name && attr.value) {\n return `${attr.name}=\"${attr.value}\"`;\n } else if (attr.kind === 'empty' && attr.name) {\n return attr.name;\n }\n return '';\n })\n .filter(Boolean)\n .join(' ');\n\n const openTag = attrs ? `<${elementNode.name} ${attrs}>` : `<${elementNode.name}>`;\n\n if (!elementNode.children || elementNode.children.length === 0) {\n // Self-closing tags\n if (['img', 'br', 'hr', 'input', 'meta', 'link'].includes(elementNode.name)) {\n return `${openTag.replace('>', ' />')}`;\n }\n return `${openTag}</${elementNode.name}>`;\n }\n\n const children = elementNode.children\n .map((child: Node) => this.nodeToHTML(child, indent + ' '))\n .join('\\n');\n\n return `${openTag}${children}</${elementNode.name}>`;\n } else if (node.type === 'component') {\n const componentNode = node as { type: 'component'; name: string };\n // Warning for unmatched components\n this.logger.warn(\n `Component <${componentNode.name} /> found but won't be resolved (use container renderer for imports)`,\n );\n\n return `<!-- Component: ${componentNode.name} -->`;\n } else if (node.type === 'expression') {\n return `{${String(node)}}`;\n } else if (node.type === 'frontmatter') {\n // Skip frontmatter nodes\n return '';\n } else if ((node as { type: string }).type === 'style') {\n // Handle style nodes - include them so they get extracted\n const styleNode = node as unknown as { type: 'style'; attributes: AttributeNode[]; children: Node[] };\n const attrs = (styleNode.attributes || [])\n .map((attr: AttributeNode) => {\n if (attr.kind === 'quoted' && attr.name && attr.value) {\n return `${attr.name}=\"${attr.value}\"`;\n } else if (attr.kind === 'empty' && attr.name) {\n return attr.name;\n }\n return '';\n })\n .filter(Boolean)\n .join(' ');\n\n const openTag = attrs ? `<style ${attrs}>` : '<style>';\n\n // Try to get content from children\n const content = (styleNode.children || [])\n .map((child: Node) => {\n if (child.type === 'text') {\n return (child as { type: 'text'; value: string }).value;\n }\n return '';\n })\n .join('');\n\n // If no children, try to get content directly\n const directContent = (node as { content?: string }).content || '';\n\n return `${openTag}${content || directContent}</style>`;\n }\n\n return '';\n }\n\n /**\n * Replace frontmatter variable expressions in HTML\n */\n private replaceFrontmatterVars(html: string, vars: Record<string, string>): string {\n let result = html;\n for (const [key, value] of Object.entries(vars)) {\n // Safe regex replacement\n const escapedKey = key.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n const regex = new RegExp(`\\\\{${escapedKey}\\\\}`, 'g');\n result = result.replace(regex, value);\n }\n return result;\n }\n\n /**\n * Render a component to HTML\n */\n async render(filePath: string): Promise<string> {\n this.logger.info(`Rendering component: ${filePath}`);\n\n try {\n // Read and parse component\n const fileContent = await readFile(filePath, 'utf-8');\n\n // Parse Astro file\n const result = await parse(fileContent);\n const ast = result.ast;\n\n // Extract and log frontmatter variables\n const vars = this.extractFrontmatter(ast);\n this.logger.debug(`Extracted ${Object.keys(vars).length} frontmatter variables`);\n\n // Convert AST to HTML\n let html = '';\n if (ast.children) {\n html = ast.children.map((child: Node) => this.nodeToHTML(child)).join('\\n');\n }\n\n // Replace variables\n html = this.replaceFrontmatterVars(html, vars);\n\n // Success logging\n this.logger.success(`Rendered ${filePath} (${html.length} chars)`);\n\n return html;\n } catch (error: unknown) {\n const err = error as Error;\n this.logger.error(`Failed to render ${filePath}: ${err.message}`);\n throw error;\n }\n }\n}","// src/utils/LazyLoader.ts\n// Client-side utility for lazy loading prerendered HTML components\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Configuration options for the LazyHTMLLoader\n */\nexport interface LazyLoaderConfig {\n /** Base URL for prerendered files (default: '/prerendered') */\n baseUrl?: string;\n /** Enable CSS modules mode with per-component CSS (default: false) */\n cssModules?: boolean;\n /** URL to CSS modules manifest (default: '/prerendered/manifest.json') */\n manifestUrl?: string;\n /** URL to base CSS file in CSS modules mode (default: '/prerendered/base.css') */\n baseCssUrl?: string;\n /** URL to legacy single CSS file (default: '/prerendered/lazy-components.css') */\n legacyCssUrl?: string;\n /** Preload CSS files before they're needed (default: false) */\n preloadCSS?: boolean;\n /** Cache loaded HTML in memory (default: true) */\n cacheHTML?: boolean;\n /** Enable retry logic for failed fetches (default: true) */\n enableRetry?: boolean;\n /** Maximum number of retry attempts (default: 3) */\n maxRetries?: number;\n /** Delay between retries in milliseconds (default: 1000) */\n retryDelay?: number;\n /** Enable debug logging (default: false) */\n debug?: boolean;\n /** Callback when a component is loaded */\n onLoad?: (componentName: string, stats: {\n duration: number;\n bytes: number;\n fromCache: boolean;\n secondaryAssets?: Array<{ url: string; bytes: number; duration: number; type: string }>\n }) => void;\n /** Callback when an error occurs */\n onError?: (componentName: string, error: Error) => void;\n /** Callback when CSS is loaded */\n onCSSLoad?: (cssFile: string, duration: number) => void;\n}\n\n/**\n * CSS module manifest structure\n */\nexport interface CSSModuleManifest {\n /** Map of component names to their CSS file paths */\n components: Record<string, string>;\n}\n\n/**\n * Load statistics\n */\nexport interface LoadStats {\n /** Total number of successful loads */\n totalLoads: number;\n /** Number of cache hits */\n cacheHits: number;\n /** Number of cache misses */\n cacheMisses: number;\n /** Number of errors encountered */\n errors: number;\n /** Average load time in milliseconds */\n averageLoadTime: number;\n /** Total bytes transferred across all loads */\n totalBytes: number;\n}\n\n// ============================================================================\n// LazyHTMLLoader Class\n// ============================================================================\n\n/**\n * Client-side utility for lazy loading prerendered HTML components\n * \n * @example\n * ```ts\n * import { createLazyLoader } from 'vite-plugin-astro-prerender';\n * \n * const loader = createLazyLoader({ debug: true });\n * \n * // Load and inject when in viewport\n * loader.observeAndLoad('LazyFooter', '#footer-container');\n * \n * // Or load manually\n * const html = await loader.load('LazyHeader');\n * document.getElementById('header')!.innerHTML = html;\n * ```\n */\nexport class LazyHTMLLoader {\n private config: Required<LazyLoaderConfig>;\n private htmlCache = new Map<string, string>();\n private cssCache = new Set<string>();\n private observers = new Map<string, IntersectionObserver>();\n private manifest: CSSModuleManifest | null = null;\n private manifestLoaded = false;\n private baseCssLoaded = false;\n private legacyCssLoaded = false;\n private stats = {\n totalLoads: 0,\n cacheHits: 0,\n cacheMisses: 0,\n errors: 0,\n totalLoadTime: 0,\n totalBytes: 0,\n };\n private detailedStats = new Map<string, {\n duration: number;\n bytes: number;\n fromCache: boolean;\n timestamp: number;\n secondaryAssets?: Array<{ url: string; bytes: number; duration: number; type: string }>\n }>();\n\n constructor(config: LazyLoaderConfig = {}) {\n this.config = {\n baseUrl: config.baseUrl ?? '/prerendered',\n cssModules: config.cssModules ?? false,\n manifestUrl: config.manifestUrl ?? '/prerendered/manifest.json',\n baseCssUrl: config.baseCssUrl ?? '/prerendered/base.css',\n legacyCssUrl: config.legacyCssUrl ?? '/prerendered/lazy-components.css',\n preloadCSS: config.preloadCSS ?? false,\n cacheHTML: config.cacheHTML ?? true,\n enableRetry: config.enableRetry ?? true,\n maxRetries: config.maxRetries ?? 3,\n retryDelay: config.retryDelay ?? 1000,\n debug: config.debug ?? false,\n onLoad: config.onLoad ?? (() => { }),\n onError: config.onError ?? (() => { }),\n onCSSLoad: config.onCSSLoad ?? (() => { }),\n };\n\n this.log('LazyHTMLLoader initialized', this.config);\n }\n\n /**\n * Internal logging method\n */\n private log(message: string, ...args: unknown[]): void {\n if (this.config.debug) {\n console.log(`[LazyHTMLLoader] ${message}`, ...args);\n }\n }\n\n /**\n * Fetch with retry logic\n */\n private async fetchWithRetry(\n url: string,\n retries = this.config.maxRetries,\n ): Promise<Response> {\n for (let attempt = 1; attempt <= retries; attempt++) {\n try {\n this.log(`Fetching ${url} (attempt ${attempt}/${retries})`);\n const response = await fetch(url);\n\n if (response.ok) {\n return response;\n }\n\n if (attempt === retries) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n }\n\n // Don't retry on 404\n if (response.status === 404) {\n throw new Error(`Not found: ${url}`);\n }\n\n this.log(`Fetch failed with status ${response.status}, retrying...`);\n } catch (error) {\n if (attempt === retries) {\n throw error;\n }\n this.log(`Fetch error: ${error}, retrying...`);\n }\n\n // Wait before retrying\n if (attempt < retries) {\n await new Promise((resolve) =>\n setTimeout(resolve, this.config.retryDelay * attempt),\n );\n }\n }\n\n throw new Error(`Failed to fetch ${url} after ${retries} attempts`);\n }\n\n /**\n * Load CSS manifest for CSS modules mode\n */\n private async loadManifest(): Promise<void> {\n if (this.manifestLoaded) {\n return;\n }\n\n const startTime = performance.now();\n\n try {\n const response = await (this.config.enableRetry\n ? this.fetchWithRetry(this.config.manifestUrl)\n : fetch(this.config.manifestUrl));\n\n if (!response.ok) {\n throw new Error(`Failed to load manifest: ${response.statusText}`);\n }\n\n this.manifest = await response.json();\n this.manifestLoaded = true;\n\n const duration = performance.now() - startTime;\n this.log(`Manifest loaded in ${duration.toFixed(2)}ms`, this.manifest);\n this.config.onCSSLoad(this.config.manifestUrl, duration);\n } catch (error) {\n console.error('Failed to load CSS manifest:', error);\n // Fallback to legacy mode\n this.config.cssModules = false;\n this.manifestLoaded = true;\n }\n }\n\n /**\n * Load base CSS file (CSS modules mode)\n */\n private async loadBaseCSS(): Promise<void> {\n if (this.baseCssLoaded) {\n return;\n }\n\n await this.loadManifest();\n\n if (!this.manifest) {\n return;\n }\n\n const startTime = performance.now();\n\n return new Promise((resolve, reject) => {\n const link = document.createElement('link');\n link.rel = 'stylesheet';\n link.href = this.config.baseCssUrl;\n\n link.onload = () => {\n this.baseCssLoaded = true;\n const duration = performance.now() - startTime;\n this.log(`Base CSS loaded in ${duration.toFixed(2)}ms`);\n this.config.onCSSLoad(this.config.baseCssUrl, duration);\n resolve();\n };\n\n link.onerror = () => {\n console.error('Failed to load base CSS');\n reject(new Error('Failed to load base CSS'));\n };\n\n if (this.config.preloadCSS) {\n const preload = document.createElement('link');\n preload.rel = 'preload';\n preload.as = 'style';\n preload.href = this.config.baseCssUrl;\n document.head.appendChild(preload);\n }\n\n document.head.appendChild(link);\n });\n }\n\n /**\n * Load component-specific CSS file (CSS modules mode)\n */\n private async loadComponentCSS(componentName: string): Promise<void> {\n if (!this.config.cssModules || !this.manifest) {\n return;\n }\n\n const cssFile = this.manifest.components[componentName];\n if (!cssFile) {\n this.log(`No CSS file for component: ${componentName}`);\n return;\n }\n\n if (this.cssCache.has(cssFile)) {\n this.log(`CSS already loaded: ${cssFile}`);\n return;\n }\n\n const startTime = performance.now();\n const cssUrl = `${this.config.baseUrl}/${cssFile}`;\n\n return new Promise((resolve, reject) => {\n const link = document.createElement('link');\n link.rel = 'stylesheet';\n link.href = cssUrl;\n\n link.onload = () => {\n this.cssCache.add(cssFile);\n const duration = performance.now() - startTime;\n this.log(\n `Component CSS loaded in ${duration.toFixed(2)}ms: ${cssFile}`,\n );\n this.config.onCSSLoad(cssFile, duration);\n resolve();\n };\n\n link.onerror = () => {\n console.error(`Failed to load component CSS: ${cssFile}`);\n reject(new Error(`Failed to load CSS: ${cssFile}`));\n };\n\n if (this.config.preloadCSS) {\n const preload = document.createElement('link');\n preload.rel = 'preload';\n preload.as = 'style';\n preload.href = cssUrl;\n document.head.appendChild(preload);\n }\n\n document.head.appendChild(link);\n });\n }\n\n /**\n * Load legacy single CSS file\n */\n private async loadLegacyCSS(): Promise<void> {\n if (this.legacyCssLoaded) {\n return;\n }\n\n const startTime = performance.now();\n\n return new Promise((resolve, reject) => {\n const link = document.createElement('link');\n link.rel = 'stylesheet';\n link.href = this.config.legacyCssUrl;\n\n link.onload = () => {\n this.legacyCssLoaded = true;\n const duration = performance.now() - startTime;\n this.log(`Legacy CSS loaded in ${duration.toFixed(2)}ms`);\n this.config.onCSSLoad(this.config.legacyCssUrl, duration);\n resolve();\n };\n\n link.onerror = () => {\n console.error('Failed to load legacy CSS');\n reject(new Error('Failed to load lazy components CSS'));\n };\n\n if (this.config.preloadCSS) {\n const preload = document.createElement('link');\n preload.rel = 'preload';\n preload.as = 'style';\n preload.href = this.config.legacyCssUrl;\n document.head.appendChild(preload);\n }\n\n document.head.appendChild(link);\n });\n }\n\n /**\n * Load HTML fragment from server\n */\n async load(componentName: string): Promise<string> {\n const startTime = performance.now();\n\n try {\n // Check cache\n if (this.config.cacheHTML && this.htmlCache.has(componentName)) {\n this.stats.cacheHits++;\n this.log(`Cache hit: ${componentName}`);\n const html = this.htmlCache.get(componentName)!;\n const bytes = new Blob([html]).size;\n const duration = performance.now() - startTime;\n\n this.stats.totalLoads++;\n this.stats.totalLoadTime += duration;\n\n const loadInfo = { duration, bytes, fromCache: true, timestamp: Date.now() };\n this.detailedStats.set(componentName, loadInfo);\n this.config.onLoad(componentName, { duration, bytes, fromCache: true });\n\n return html;\n }\n\n this.stats.cacheMisses++;\n\n // Load CSS\n if (this.config.cssModules) {\n await this.loadBaseCSS().catch((err) => {\n console.warn('Failed to load base CSS:', err);\n });\n await this.loadComponentCSS(componentName).catch((err) => {\n console.warn(`Failed to load CSS for ${componentName}:`, err);\n });\n } else {\n await this.loadLegacyCSS().catch((err) => {\n console.warn('Failed to load legacy CSS:', err);\n });\n }\n\n // Fetch HTML\n const url = `${this.config.baseUrl}/${componentName}.html`;\n const response = await (this.config.enableRetry\n ? this.fetchWithRetry(url)\n : fetch(url));\n\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n }\n\n const html = await response.text();\n const bytes = new Blob([html]).size;\n\n // Cache HTML\n if (this.config.cacheHTML) {\n this.htmlCache.set(componentName, html);\n }\n\n // Update stats\n const duration = performance.now() - startTime;\n this.stats.totalLoads++;\n this.stats.totalLoadTime += duration;\n this.stats.totalBytes += bytes;\n\n this.log(`Loaded ${componentName} in ${duration.toFixed(2)}ms (${bytes} bytes)`);\n\n // Start tracking secondary assets (images, etc.) that might be triggered by this injection\n const secondaryAssets: Array<{ url: string; bytes: number; duration: number; type: string }> = [];\n\n const resourceObserver = new PerformanceObserver((list) => {\n list.getEntries().forEach((entry) => {\n const res = entry as PerformanceResourceTiming;\n // Filter for assets likely triggered by this component\n if (res.startTime >= (startTime - 50)) {\n const assetBytes = res.transferSize || res.decodedBodySize || res.encodedBodySize || 0;\n\n secondaryAssets.push({\n url: res.name,\n bytes: assetBytes,\n duration: res.duration,\n type: res.initiatorType\n });\n\n // Update total bytes and global stats with secondary assets\n this.stats.totalBytes += assetBytes;\n }\n });\n });\n\n try {\n // Use buffered: true to catch resources that might have started \n // between performance.now() and observe() call\n resourceObserver.observe({ entryTypes: ['resource'], buffered: true });\n\n // Stop observing after a reasonable time (longer for assets)\n setTimeout(() => resourceObserver.disconnect(), 6000);\n } catch (e) {\n this.log('PerformanceObserver failed');\n // Fallback attempt without buffering if that was the cause\n try { resourceObserver.observe({ entryTypes: ['resource'] }); } catch (err) { }\n }\n\n const loadInfo = {\n duration,\n bytes,\n fromCache: false,\n timestamp: Date.now(),\n secondaryAssets\n };\n this.detailedStats.set(componentName, loadInfo);\n this.config.onLoad(componentName, { duration, bytes, fromCache: false, secondaryAssets });\n\n return html;\n } catch (error) {\n this.stats.errors++;\n const err = error instanceof Error ? error : new Error(String(error));\n this.log(`Error loading ${componentName}:`, err);\n this.config.onError(componentName, err);\n throw err;\n }\n }\n\n /**\n * Inject HTML fragment into target element\n */\n async inject(componentName: string, targetSelector: string): Promise<void> {\n const html = await this.load(componentName);\n const target = document.querySelector(targetSelector);\n\n if (target) {\n target.innerHTML = html;\n this.log(`Injected ${componentName} into ${targetSelector}`);\n } else {\n const error = new Error(`Target element not found: ${targetSelector}`);\n this.config.onError(componentName, error);\n throw error;\n }\n }\n\n /**\n * Load HTML fragment when target element enters viewport\n */\n observeAndLoad(\n componentName: string,\n targetSelector: string,\n options?: IntersectionObserverInit,\n ): void {\n const target = document.querySelector(targetSelector);\n if (!target) {\n console.warn(`Target element not found: ${targetSelector}`);\n return;\n }\n\n const observer = new IntersectionObserver(\n (entries) => {\n entries.forEach((entry) => {\n if (entry.isIntersecting) {\n this.log(`Component ${componentName} entered viewport`);\n this.inject(componentName, targetSelector).catch((err) => {\n console.error(`Failed to inject ${componentName}:`, err);\n });\n observer.disconnect();\n this.observers.delete(componentName);\n }\n });\n },\n options || { rootMargin: '100px' },\n );\n\n observer.observe(target);\n this.observers.set(componentName, observer);\n this.log(`Observing ${componentName} at ${targetSelector}`);\n }\n\n /**\n * Preload HTML fragment without injecting\n */\n async preload(componentName: string): Promise<void> {\n await this.load(componentName);\n }\n\n /**\n * Batch preload multiple components\n */\n async preloadBatch(componentNames: string[]): Promise<void> {\n this.log(`Preloading ${componentNames.length} components:`, componentNames);\n await Promise.all(componentNames.map((name) => this.preload(name)));\n }\n\n /**\n * Get load statistics\n */\n getStats(): LoadStats {\n return {\n totalLoads: this.stats.totalLoads,\n cacheHits: this.stats.cacheHits,\n cacheMisses: this.stats.cacheMisses,\n errors: this.stats.errors,\n averageLoadTime:\n this.stats.totalLoads > 0\n ? this.stats.totalLoadTime / this.stats.totalLoads\n : 0,\n totalBytes: this.stats.totalBytes,\n };\n }\n\n /**\n * Get detailed history of all loads in this session\n */\n getDetailedHistory(): Array<{ componentName: string; duration: number; bytes: number; fromCache: boolean; timestamp: number }> {\n return Array.from(this.detailedStats.entries()).map(([name, info]) => ({\n componentName: name,\n ...info,\n })).sort((a, b) => b.timestamp - a.timestamp);\n }\n\n /**\n * Clear HTML cache\n */\n clearCache(): void {\n this.htmlCache.clear();\n this.log('HTML cache cleared');\n }\n\n /**\n * Clear CSS cache (forces reload of CSS files)\n */\n clearCSSCache(): void {\n this.cssCache.clear();\n this.baseCssLoaded = false;\n this.legacyCssLoaded = false;\n this.manifestLoaded = false;\n this.manifest = null;\n this.log('CSS cache cleared');\n }\n\n /**\n * Disconnect all observers\n */\n disconnectAll(): void {\n this.observers.forEach((observer) => observer.disconnect());\n this.observers.clear();\n this.log('All observers disconnected');\n }\n\n /**\n * Reset all state (cache, observers, stats)\n */\n reset(): void {\n this.clearCache();\n this.clearCSSCache();\n this.disconnectAll();\n this.stats = {\n totalLoads: 0,\n cacheHits: 0,\n cacheMisses: 0,\n errors: 0,\n totalLoadTime: 0,\n totalBytes: 0,\n };\n this.detailedStats.clear();\n this.log('LazyHTMLLoader reset');\n }\n}\n\n/**\n * Factory function to create a lazy loader instance\n */\nexport function createLazyLoader(config?: LazyLoaderConfig): LazyHTMLLoader {\n return new LazyHTMLLoader(config);\n}\n\n/**\n * Default lazy loader instance with default configuration\n */\nexport const lazyLoader = new LazyHTMLLoader();"],"mappings":"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","names":["watch","join","relative","basename","createHash","readFile","fg","outputFile","fsEnsureDir","cheerio","consola","createLogger","tag","getFileHash","filePath","content","readFile","createHash","findComponents","dir","fg","extractClasses","html","$","classes","_","el","_a","cls","extractStyles","styles","cleanHTML","$el","attrs","attr","body","minifyHTML","minify","error","writeFileWithDir","filePath","content","outputFile","FlatCache","CacheManager","cacheDir","componentPath","hash","pathToFileURL","CSSGenerator","tailwindConfigPath","logger","generateTailwind","classes","cls","styles","outputPath","classArray","cssContent","writeFileWithDir","postcssModule","tailwindModule","autoprefixerModule","postcss","tailwindcss","autoprefixer","modifiedConfig","pathToFileURL","result","error","readFile","AstroContainer","ContainerRenderer","logger","server","componentPath","frontmatterMatch","frontmatterVars","varMatches","match","ComponentModule","error","err","html","key","value","regex","parse","readFile","consola","ParserRenderer","ast","frontmatter","vars","varMatches","match","node","indent","elementNode","attrs","attr","openTag","children","child","componentNode","styleNode","content","directContent","html","result","key","value","escapedKey","regex","filePath","fileContent","error","err","LazyHTMLLoader","config","_a","_b","_c","_d","_e","_f","_g","_h","_i","_j","_k","_l","_m","_n","message","args","url","retries","attempt","response","error","resolve","startTime","duration","reject","link","preload","componentName","cssFile","cssUrl","html","bytes","loadInfo","err","secondaryAssets","resourceObserver","list","entry","res","assetBytes","e","targetSelector","target","options","observer","entries","componentNames","name","info","a","b","createLazyLoader","lazyLoader","astroPrerenderPlugin","componentsDir","outputDir","generateTailwindCSS","tailwindConfigPath","renderer","minify","base","normalizedBase","logger","createLogger","config","cacheManager","cssGenerator","componentRenderer","parserFallback","processAll","root","componentsPath","join","outputPath","componentFiles","findComponents","componentPath","processComponent","generateCSS","hash","getFileHash","relative","html","styles","extractStyles","cleanedHTML","cleanHTML","classes","extractClasses","originalSize","minifyHTML","minifiedSize","savings","componentName","basename","htmlOutputPath","writeFileWithDir","error","cssOutputPath","prerenderedPath","id","clientConfig","resolvedConfig","CacheManager","CSSGenerator","ContainerRenderer","ParserRenderer","server","watcher","watch","filePath","astroPrerenderIntegration","options","updateConfig","_a","_b","baseFromConfig"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/utils/index.ts","../src/utils/logger.ts","../src/utils/cache.ts","../src/utils/css-generator.ts","../src/utils/container-renderer.ts","../src/utils/parser-renderer.ts","../src/utils/LazyLoader.ts"],"sourcesContent":["// src/index.ts\nimport { watch } from 'chokidar';\nimport { join, relative, basename } from 'node:path';\nimport {\n createLogger,\n findComponents,\n extractClasses,\n extractStyles,\n cleanHTML,\n minifyHTML,\n getFileHash,\n writeFileWithDir,\n} from './utils';\nimport { CacheManager } from './utils/cache';\nimport { CSSGenerator } from './utils/css-generator';\nimport { ContainerRenderer } from './utils/container-renderer';\nimport { ParserRenderer } from './utils/parser-renderer';\nimport type { AstroIntegration } from 'astro';\nimport type { Plugin as VitePlugin, ResolvedConfig, ViteDevServer } from 'vite';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Plugin configuration options\n */\nexport interface PluginOptions {\n /** Directory containing components to prerender (default: 'src/components/Lazy') */\n componentsDir?: string;\n /** Output directory for prerendered files (default: 'public/prerendered') */\n outputDir?: string;\n /** Generate Tailwind CSS file with tree-shaking (default: true) */\n generateTailwindCSS?: boolean;\n /** Path to Tailwind config file (default: 'tailwind.config.mjs') */\n tailwindConfigPath?: string;\n /** Rendering strategy: 'parser' (simple) or 'container' (full features) */\n renderer?: 'parser' | 'container';\n /** Minify HTML output to reduce file size (default: true) */\n minify?: boolean;\n /** Base URL path for the site (e.g., '/my-subdir'). Read from Astro config if not specified. */\n base?: string;\n}\n\n// ============================================================================\n// Vite Plugin\n// ============================================================================\n\n/**\n * Astro Prerender Vite Plugin\n * Prerenders Astro components to static HTML and generates optimized CSS\n */\nexport function astroPrerenderPlugin({\n componentsDir = 'src/components/Lazy',\n outputDir = 'public/prerendered',\n generateTailwindCSS = true,\n tailwindConfigPath = 'tailwind.config.mjs',\n renderer = 'parser',\n minify = true,\n base = '',\n}: PluginOptions = {}): VitePlugin {\n // Normalize base path: ensure it starts with / and doesn't end with /\n const normalizedBase = base ? (base.startsWith('/') ? base : '/' + base).replace(/\\/$/, '') : '';\n const logger = createLogger('astro-prerender');\n let config: ResolvedConfig | null = null;\n let cacheManager: CacheManager | null = null;\n let cssGenerator: CSSGenerator | null = null;\n let componentRenderer: ContainerRenderer | ParserRenderer | null = null;\n let parserFallback: ParserRenderer | null = null;\n\n /**\n * Process all components\n */\n async function processAll(): Promise<void> {\n if (!config?.root) return;\n\n const root = config.root;\n const componentsPath = join(root, componentsDir);\n const outputPath = join(root, outputDir);\n\n logger.info(`Processing components from ${componentsDir}...`);\n\n // Load cache\n if (cacheManager) {\n await cacheManager.load();\n }\n\n // Clear CSS generator\n if (cssGenerator) {\n cssGenerator.clear();\n }\n\n // Find all components\n const componentFiles = await findComponents(componentsPath);\n\n if (componentFiles.length === 0) {\n logger.warn(`No .astro files found in ${componentsDir}`);\n return;\n }\n\n // Process each component\n for (const componentPath of componentFiles) {\n await processComponent(componentPath);\n }\n\n // Generate CSS\n await generateCSS();\n\n // Save cache\n if (cacheManager) {\n await cacheManager.save();\n }\n\n logger.success(`Processed ${componentFiles.length} component(s)`);\n }\n\n /**\n * Process a single component\n */\n async function processComponent(componentPath: string): Promise<void> {\n if (!config?.root) return;\n\n const root = config.root;\n const outputPath = join(root, outputDir);\n\n try {\n // Check cache\n if (cacheManager) {\n const hash = await getFileHash(componentPath);\n if (cacheManager.isCached(componentPath, hash)) {\n logger.info(`Skipping cached: ${relative(root, componentPath)}`);\n return;\n }\n }\n\n // Render component\n if (componentRenderer) {\n let html = await componentRenderer.render(componentPath);\n\n // If container renderer returned null, fall back to parser\n if (!html && parserFallback) {\n logger.info(`Falling back to parser for: ${relative(root, componentPath)}`);\n html = await parserFallback.render(componentPath);\n }\n\n if (html) {\n // Extract styles before cleaning HTML\n const styles = extractStyles(html);\n\n if (cssGenerator && styles.length > 0) {\n cssGenerator.addStyles(styles);\n }\n\n // Clean HTML\n let cleanedHTML = cleanHTML(html);\n\n // Extract Tailwind classes\n if (cssGenerator) {\n const classes = extractClasses(cleanedHTML);\n cssGenerator.addClasses(classes);\n }\n\n // Minify HTML if enabled\n if (minify) {\n const originalSize = cleanedHTML.length;\n cleanedHTML = await minifyHTML(cleanedHTML);\n const minifiedSize = cleanedHTML.length;\n const savings = Math.round((1 - minifiedSize / originalSize) * 100);\n logger.info(`Minified: ${originalSize} → ${minifiedSize} bytes (${savings}% smaller)`);\n }\n\n // Write HTML file\n const componentName = basename(componentPath, '.astro');\n const htmlOutputPath = join(outputPath, `${componentName}.html`);\n\n await writeFileWithDir(htmlOutputPath, cleanedHTML);\n\n // Update cache\n if (cacheManager) {\n const hash = await getFileHash(componentPath);\n cacheManager.set(componentPath, hash);\n }\n\n logger.success(`${componentName}.html (${cleanedHTML.length} chars)`);\n }\n }\n } catch (error) {\n logger.error(\n `Failed to process ${relative(root, componentPath)}: ${error instanceof Error ? error.message : 'Unknown error'\n }`\n );\n }\n }\n\n /**\n * Generate CSS file\n */\n async function generateCSS(): Promise<void> {\n if (!cssGenerator || !config?.root) return;\n\n const root = config.root;\n const outputPath = join(root, outputDir);\n const cssOutputPath = join(outputPath, 'lazy-components.css');\n\n await cssGenerator.generate(cssOutputPath);\n }\n\n // Compute the prerendered path relative to public (e.g., 'prerendered' from 'public/prerendered')\n const prerenderedPath = outputDir.replace(/^public\\/?/, '');\n\n return {\n name: 'astro-prerender-plugin',\n\n resolveId(id: string) {\n if (id === 'virtual:astro-prerender-config') {\n return id; // Return the id as-is, no prefix needed\n }\n return null;\n },\n\n load(id: string) {\n if (id === 'virtual:astro-prerender-config') {\n // Export config for client-side usage\n const clientConfig = {\n base: normalizedBase,\n prerenderedPath: `${normalizedBase}/${prerenderedPath}`,\n cssPath: `${normalizedBase}/${prerenderedPath}/lazy-components.css`,\n };\n return `export const base = ${JSON.stringify(normalizedBase)};\nexport const prerenderedPath = ${JSON.stringify(clientConfig.prerenderedPath)};\nexport const cssPath = ${JSON.stringify(clientConfig.cssPath)};\nexport default ${JSON.stringify(clientConfig)};`;\n }\n return null;\n },\n\n configResolved(resolvedConfig: ResolvedConfig) {\n config = resolvedConfig;\n const root = config.root;\n\n // Initialize cache manager\n cacheManager = new CacheManager(join(root, outputDir));\n\n // Always initialize CSS generator (it will handle component styles even without Tailwind)\n cssGenerator = new CSSGenerator(\n join(root, tailwindConfigPath),\n logger,\n generateTailwindCSS\n );\n\n // Initialize renderer based on config\n if (renderer === 'container') {\n componentRenderer = new ContainerRenderer(logger);\n parserFallback = new ParserRenderer(); // Fallback for when container fails\n logger.info('Using Container API renderer (supports imports)');\n } else {\n componentRenderer = new ParserRenderer();\n logger.info('Using Parser renderer (simpler, no imports)');\n }\n },\n\n async buildStart() {\n if (config?.command === 'build') {\n await processAll();\n }\n },\n\n async configureServer(server: ViteDevServer) {\n // Set Vite server for Container renderer\n if (componentRenderer instanceof ContainerRenderer) {\n componentRenderer.setViteServer(server);\n }\n\n // Initial processing\n await processAll();\n\n // Watch for changes in components directory\n const componentsPath = join(config?.root || '', componentsDir);\n const watcher = watch(componentsPath, {\n ignored: /node_modules/,\n persistent: true,\n });\n\n watcher.on('change', async (filePath: string) => {\n if (!config?.root) return;\n\n logger.info(`Component changed: ${relative(config.root, filePath)}`);\n await processComponent(filePath);\n await generateCSS();\n });\n\n watcher.on('add', async (filePath: string) => {\n if (!config?.root) return;\n\n logger.info(`Component added: ${relative(config.root, filePath)}`);\n await processComponent(filePath);\n await generateCSS();\n });\n\n watcher.on('unlink', (filePath: string) => {\n if (!config?.root) return;\n\n logger.info(`Component removed: ${relative(config.root, filePath)}`);\n cacheManager?.delete(filePath);\n });\n },\n };\n}\n\n// ============================================================================\n// Astro Integration\n// ============================================================================\n\n/**\n * Astro Integration wrapper for the prerender plugin\n * Use this in your astro.config.mjs integrations array\n * \n * @example\n * ```js\n * import { astroPrerenderIntegration } from 'astro-prerender-plugin';\n * \n * export default defineConfig({\n * integrations: [\n * astroPrerenderIntegration({\n * componentsDir: 'src/components/Lazy',\n * }),\n * ],\n * });\n * ```\n */\nexport function astroPrerenderIntegration(options: PluginOptions = {}): AstroIntegration {\n return {\n name: 'astro-prerender-integration',\n hooks: {\n 'astro:config:setup': ({ config, updateConfig }) => {\n // Read base from Astro config if not explicitly provided\n const baseFromConfig = options.base ?? config.base ?? '';\n\n updateConfig({\n vite: {\n plugins: [astroPrerenderPlugin({ ...options, base: baseFromConfig })],\n },\n });\n },\n },\n };\n}\n\n// ============================================================================\n// Re-exports\n// ============================================================================\n\n// Core utilities\nexport { CacheManager } from './utils/cache';\nexport { CSSGenerator } from './utils/css-generator';\nexport { ContainerRenderer } from './utils/container-renderer';\nexport { ParserRenderer } from './utils/parser-renderer';\nexport type { Logger } from './utils/logger';\n\n// Lazy loader (client-side utility)\nexport {\n LazyHTMLLoader,\n createLazyLoader,\n lazyLoader,\n type LazyLoaderConfig,\n type CSSModuleManifest,\n type LoadStats,\n} from './utils/LazyLoader';","// src/utils/index.ts\nimport { createHash } from 'node:crypto';\nimport { readFile } from 'node:fs/promises';\nimport fg from 'fast-glob';\nimport { outputFile, ensureDir as fsEnsureDir } from 'fs-extra';\nimport * as cheerio from 'cheerio';\n\n// Re-export logger\nexport { createLogger, type Logger } from './logger';\n\n/**\n * Get MD5 hash of file content\n */\nexport async function getFileHash(filePath: string): Promise<string> {\n const content = await readFile(filePath, 'utf-8');\n return createHash('md5').update(content).digest('hex');\n}\n\n/**\n * Find all .astro files recursively in a directory using fast-glob\n */\nexport async function findComponents(dir: string): Promise<string[]> {\n try {\n return await fg('**/*.astro', {\n cwd: dir,\n absolute: true,\n ignore: ['**/node_modules/**'],\n });\n } catch {\n // Directory doesn't exist or is not accessible\n return [];\n }\n}\n\n/**\n * Extract Tailwind classes from HTML using Cheerio\n */\nexport function extractClasses(html: string): string[] {\n const $ = cheerio.load(html);\n const classes = new Set<string>();\n\n $('[class]').each((_, el) => {\n const classList = $(el).attr('class')?.split(/\\s+/) || [];\n classList.forEach((cls) => {\n if (cls) classes.add(cls);\n });\n });\n\n return Array.from(classes);\n}\n\n/**\n * Extract style tags from HTML using Cheerio\n */\nexport function extractStyles(html: string): string[] {\n const $ = cheerio.load(html);\n const styles: string[] = [];\n\n $('style').each((_, el) => {\n const content = $(el).html();\n if (content?.trim()) {\n styles.push(content);\n }\n });\n\n return styles;\n}\n\n/**\n * Clean HTML output by removing unnecessary elements using Cheerio\n */\nexport function cleanHTML(html: string): string {\n const $ = cheerio.load(html);\n\n // Remove script tags\n $('script').remove();\n\n // Remove style tags (they're externalized)\n $('style').remove();\n\n // Remove data-astro-* attributes\n $('*').each((_, el) => {\n const $el = $(el);\n const attrs = (el as unknown as { attribs?: Record<string, string> }).attribs || {};\n\n Object.keys(attrs).forEach((attr) => {\n if (attr.startsWith('data-astro-source-') || attr.startsWith('data-astro-cid-')) {\n $el.removeAttr(attr);\n }\n });\n });\n\n // Get the body content (Cheerio wraps in html/head/body)\n const body = $('body').html();\n return body?.trim() || $.html().trim();\n}\n\n/**\n * Minify HTML using html-minifier-terser\n */\nexport async function minifyHTML(html: string): Promise<string> {\n try {\n const { minify } = await import('html-minifier-terser');\n\n return await minify(html, {\n collapseWhitespace: true,\n removeComments: true,\n removeRedundantAttributes: true,\n removeEmptyAttributes: true,\n minifyCSS: true,\n minifyJS: true,\n conservativeCollapse: true,\n preserveLineBreaks: false,\n });\n } catch (error) {\n console.warn('html-minifier-terser not available, skipping minification');\n return html;\n }\n}\n\n/**\n * Ensure directory exists (using fs-extra)\n */\nexport { fsEnsureDir as ensureDir };\n\n/**\n * Write file with directory creation (using fs-extra)\n */\nexport async function writeFileWithDir(filePath: string, content: string): Promise<void> {\n await outputFile(filePath, content, 'utf-8');\n}","// src/utils/logger.ts\nimport { consola, type ConsolaInstance } from 'consola';\n\n/**\n * Create a logger instance with a specific tag\n * Uses Consola for beautiful, structured logging\n */\nexport function createLogger(tag: string): ConsolaInstance {\n return consola.withTag(tag);\n}\n\nexport type Logger = ConsolaInstance;\n","// src/utils/cache.ts\nimport { FlatCache } from 'flat-cache';\n\n/**\n * Manages cache for rendered components using flat-cache\n * Uses file hashes to skip unchanged components\n */\nexport class CacheManager {\n private cache: FlatCache;\n private loaded: boolean = false;\n\n constructor(cacheDir: string) {\n this.cache = new FlatCache({\n cacheDir,\n cacheId: 'prerender-cache',\n });\n }\n\n /**\n * Load cache from disk\n */\n async load(): Promise<void> {\n if (!this.loaded) {\n this.cache.load();\n this.loaded = true;\n }\n }\n\n /**\n * Save cache to disk\n */\n async save(): Promise<void> {\n this.cache.save();\n }\n\n /**\n * Check if component is cached with same hash\n */\n isCached(componentPath: string, hash: string): boolean {\n return this.cache.getKey(componentPath) === hash;\n }\n\n /**\n * Set component hash in cache\n */\n set(componentPath: string, hash: string): void {\n this.cache.setKey(componentPath, hash);\n }\n\n /**\n * Delete component from cache\n */\n delete(componentPath: string): void {\n this.cache.delete(componentPath);\n }\n\n /**\n * Clear all cache\n */\n clear(): void {\n this.cache.clear();\n }\n}","// src/utils/css-generator.ts\nimport { pathToFileURL } from 'node:url';\nimport { writeFileWithDir } from './index';\nimport type { Logger } from './logger';\nimport type { AcceptedPlugin } from 'postcss';\n\n/**\n * Generates CSS from Tailwind classes and component styles\n * Tree-shakes Tailwind to only include used classes\n */\nexport class CSSGenerator {\n private tailwindConfigPath: string;\n private logger: Logger;\n private classes: Set<string>;\n private componentStyles: string[];\n private generateTailwind: boolean;\n\n constructor(tailwindConfigPath: string, logger: Logger, generateTailwind: boolean = true) {\n this.tailwindConfigPath = tailwindConfigPath;\n this.logger = logger;\n this.classes = new Set();\n this.componentStyles = [];\n this.generateTailwind = generateTailwind;\n }\n\n /**\n * Add Tailwind classes to generate CSS for\n */\n addClasses(classes: string[]): void {\n classes.forEach((cls) => this.classes.add(cls));\n }\n\n /**\n * Add component styles to include in CSS\n */\n addStyles(styles: string[]): void {\n this.componentStyles.push(...styles);\n }\n\n /**\n * Clear all classes and styles\n */\n clear(): void {\n this.classes.clear();\n this.componentStyles = [];\n }\n\n /**\n * Generate CSS file with Tailwind and component styles\n */\n async generate(outputPath: string): Promise<void> {\n const classArray = Array.from(this.classes);\n\n this.logger.info(\n `CSS Generator state: ${classArray.length} classes, ${this.componentStyles.length} component styles`,\n );\n\n if (classArray.length === 0 && this.componentStyles.length === 0) {\n this.logger.warn('No classes or styles to generate CSS for');\n return;\n }\n\n this.logger.info(\n `Generating CSS for ${classArray.length} classes and ${this.componentStyles.length} component styles...`,\n );\n\n try {\n // If Tailwind is disabled and we only have component styles, just write them directly\n if (!this.generateTailwind && this.componentStyles.length > 0) {\n const cssContent = '/* Component Styles */\\n' + this.componentStyles.join('\\n\\n');\n await writeFileWithDir(outputPath, cssContent);\n this.logger.success(`CSS generated (component styles only): ${outputPath}`);\n return;\n }\n\n // If Tailwind is disabled but we have classes, warn the user\n if (!this.generateTailwind && classArray.length > 0) {\n this.logger.warn(\n `Found ${classArray.length} Tailwind classes but generateTailwindCSS is disabled. Enable it to include Tailwind styles.`,\n );\n // Still output component styles if we have them\n if (this.componentStyles.length > 0) {\n const cssContent = '/* Component Styles */\\n' + this.componentStyles.join('\\n\\n');\n await writeFileWithDir(outputPath, cssContent);\n this.logger.success(`CSS generated (component styles only): ${outputPath}`);\n }\n return;\n }\n\n // Full Tailwind + component styles processing\n // Dynamically import dependencies (they're optional peer deps)\n const [postcssModule, tailwindModule, autoprefixerModule] = await Promise.all([\n import('postcss'),\n import('tailwindcss'),\n import('autoprefixer'),\n ]);\n\n const postcss = postcssModule.default;\n const tailwindcss = tailwindModule.default;\n const autoprefixer = autoprefixerModule.default;\n\n // Load the Tailwind config\n const configUrl = pathToFileURL(this.tailwindConfigPath).href;\n const configModule = await import(configUrl);\n const tailwindConfig = configModule.default;\n\n // Override the content to only process the extracted classes\n const modifiedConfig = {\n ...tailwindConfig,\n content: [\n {\n raw: classArray\n .map((cls) => `<div class=\"${cls}\"></div>`)\n .join('\\n'),\n },\n ],\n safelist: classArray,\n };\n\n // Create CSS content with Tailwind directives\n let cssContent = `\n@tailwind base;\n@tailwind components;\n@tailwind utilities;\n`;\n\n // Add component styles if any\n if (this.componentStyles.length > 0) {\n cssContent += '\\n/* Component Styles */\\n';\n cssContent += this.componentStyles.join('\\n\\n');\n }\n\n // Process with PostCSS\n const result = await postcss([\n tailwindcss(modifiedConfig) as AcceptedPlugin,\n autoprefixer as AcceptedPlugin,\n ]).process(cssContent, {\n from: undefined,\n });\n\n // Write the generated CSS\n await writeFileWithDir(outputPath, result.css);\n\n this.logger.success(`CSS generated: ${outputPath}`);\n } catch (error) {\n this.logger.error(`Failed to generate CSS: ${error}`);\n throw error;\n }\n }\n}","// src/utils/container-renderer.ts\nimport { readFile } from 'node:fs/promises';\nimport { pathToFileURL } from 'node:url';\nimport { experimental_AstroContainer as AstroContainer } from 'astro/container';\nimport type { Logger } from './logger';\n\ninterface ViteDevServer {\n ssrLoadModule(url: string): Promise<Record<string, unknown>>;\n}\n\n/**\n * Renders components using Astro Container API\n * Supports component imports and full Astro features\n */\nexport class ContainerRenderer {\n private logger: Logger;\n private container: Awaited<ReturnType<typeof AstroContainer.create>> | null;\n private viteServer: ViteDevServer | null;\n\n constructor(logger: Logger) {\n this.logger = logger;\n this.container = null;\n this.viteServer = null;\n }\n\n /**\n * Set Vite server instance (required for dev mode)\n */\n setViteServer(server: ViteDevServer): void {\n this.viteServer = server;\n }\n\n /**\n * Initialize the container\n */\n private async init(): Promise<void> {\n if (!this.container) {\n this.container = await AstroContainer.create();\n }\n }\n\n /**\n * Render a component to HTML\n */\n async render(componentPath: string): Promise<string> {\n await this.init();\n\n try {\n const fileContent = await readFile(componentPath, 'utf-8');\n\n // Extract frontmatter to get variable values\n const frontmatterMatch = fileContent.match(/^---\\s*\\n([\\s\\S]*?)\\n---/);\n const frontmatterVars: Record<string, string> = {};\n\n if (frontmatterMatch) {\n const frontmatterCode = frontmatterMatch[1];\n // Simple extraction of const/let/var declarations\n const varMatches = frontmatterCode.matchAll(\n /(?:const|let|var)\\s+(\\w+)\\s*=\\s*[\"']([^\"']+)[\"']/g,\n );\n for (const match of varMatches) {\n frontmatterVars[match[1]] = match[2];\n }\n }\n\n let ComponentModule: Record<string, unknown>;\n\n // Container renderer requires Vite SSR to work with .astro files\n if (!this.viteServer) {\n this.logger.warn('Container renderer requires Vite dev server - use Parser renderer for builds');\n return null as unknown as string;\n }\n\n try {\n // Ensure the server has the ssrLoadModule method\n if (typeof this.viteServer.ssrLoadModule !== 'function') {\n this.logger.warn('Vite server does not support SSR module loading');\n return null as unknown as string;\n }\n\n ComponentModule = await this.viteServer.ssrLoadModule(componentPath);\n } catch (error: unknown) {\n const err = error as Error;\n this.logger.warn(`Failed to load via Vite SSR: ${err.message}`);\n // Return null to signal fallback to parser renderer\n return null as unknown as string;\n }\n\n // Render the component with props from frontmatter\n const result = await this.container!.renderToString(\n ComponentModule.default as Awaited<ReturnType<typeof AstroContainer.create>> extends { renderToString: (c: infer T, ...args: unknown[]) => unknown } ? T : never,\n {\n props: frontmatterVars,\n },\n );\n\n // Replace {varName} expressions with actual values\n let html = result;\n for (const [key, value] of Object.entries(frontmatterVars)) {\n const regex = new RegExp(`\\\\{${key}\\\\}`, 'g');\n html = html.replace(regex, value);\n }\n\n return html;\n } catch (error: unknown) {\n const err = error as Error;\n this.logger.error(`Failed to render ${componentPath}: ${err.message}`);\n throw error;\n }\n }\n}","// src/utils/parser-renderer.ts\nimport { parse } from '@astrojs/compiler';\nimport { readFile } from 'node:fs/promises';\nimport { consola } from 'consola';\nimport type { RootNode, Node, ElementNode, AttributeNode } from '@astrojs/compiler/types';\n\n/**\n * Renders components using Astro's AST parser\n * Simpler approach but doesn't resolve component imports\n */\nexport class ParserRenderer {\n private logger = consola.withTag('ParserRenderer');\n\n /**\n * Extract frontmatter variables from AST\n */\n private extractFrontmatter(ast: RootNode): Record<string, string> {\n const frontmatter = (ast as unknown as { frontmatter?: { value?: string } }).frontmatter;\n if (!frontmatter || typeof frontmatter.value !== 'string') return {};\n\n const vars: Record<string, string> = {};\n const code = frontmatter.value;\n\n // Safe regex with limits\n const varMatches = code.matchAll(\n /(?:const|let|var)\\s+(\\w+)\\s*=\\s*[\"']([^\"']+)[\"']/g\n );\n\n for (const match of varMatches) {\n if (match[1] && match[2]) {\n vars[match[1]] = match[2];\n }\n }\n\n return vars;\n }\n\n /**\n * Convert AST node to HTML string\n */\n private nodeToHTML(node: Node, indent = ''): string {\n if (node.type === 'text') {\n return (node as { type: 'text'; value: string }).value;\n } else if (node.type === 'element') {\n const elementNode = node as ElementNode;\n const attrs = elementNode.attributes\n .map((attr: AttributeNode) => {\n if (attr.kind === 'quoted' && attr.name && attr.value) {\n return `${attr.name}=\"${attr.value}\"`;\n } else if (attr.kind === 'empty' && attr.name) {\n return attr.name;\n }\n return '';\n })\n .filter(Boolean)\n .join(' ');\n\n const openTag = attrs ? `<${elementNode.name} ${attrs}>` : `<${elementNode.name}>`;\n\n if (!elementNode.children || elementNode.children.length === 0) {\n // Self-closing tags\n if (['img', 'br', 'hr', 'input', 'meta', 'link'].includes(elementNode.name)) {\n return `${openTag.replace('>', ' />')}`;\n }\n return `${openTag}</${elementNode.name}>`;\n }\n\n const children = elementNode.children\n .map((child: Node) => this.nodeToHTML(child, indent + ' '))\n .join('\\n');\n\n return `${openTag}${children}</${elementNode.name}>`;\n } else if (node.type === 'component') {\n const componentNode = node as { type: 'component'; name: string };\n // Warning for unmatched components\n this.logger.warn(\n `Component <${componentNode.name} /> found but won't be resolved (use container renderer for imports)`,\n );\n\n return `<!-- Component: ${componentNode.name} -->`;\n } else if (node.type === 'expression') {\n return `{${String(node)}}`;\n } else if (node.type === 'frontmatter') {\n // Skip frontmatter nodes\n return '';\n } else if ((node as { type: string }).type === 'style') {\n // Handle style nodes - include them so they get extracted\n const styleNode = node as unknown as { type: 'style'; attributes: AttributeNode[]; children: Node[] };\n const attrs = (styleNode.attributes || [])\n .map((attr: AttributeNode) => {\n if (attr.kind === 'quoted' && attr.name && attr.value) {\n return `${attr.name}=\"${attr.value}\"`;\n } else if (attr.kind === 'empty' && attr.name) {\n return attr.name;\n }\n return '';\n })\n .filter(Boolean)\n .join(' ');\n\n const openTag = attrs ? `<style ${attrs}>` : '<style>';\n\n // Try to get content from children\n const content = (styleNode.children || [])\n .map((child: Node) => {\n if (child.type === 'text') {\n return (child as { type: 'text'; value: string }).value;\n }\n return '';\n })\n .join('');\n\n // If no children, try to get content directly\n const directContent = (node as { content?: string }).content || '';\n\n return `${openTag}${content || directContent}</style>`;\n }\n\n return '';\n }\n\n /**\n * Replace frontmatter variable expressions in HTML\n */\n private replaceFrontmatterVars(html: string, vars: Record<string, string>): string {\n let result = html;\n for (const [key, value] of Object.entries(vars)) {\n // Safe regex replacement\n const escapedKey = key.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n const regex = new RegExp(`\\\\{${escapedKey}\\\\}`, 'g');\n result = result.replace(regex, value);\n }\n return result;\n }\n\n /**\n * Render a component to HTML\n */\n async render(filePath: string): Promise<string> {\n this.logger.info(`Rendering component: ${filePath}`);\n\n try {\n // Read and parse component\n const fileContent = await readFile(filePath, 'utf-8');\n\n // Parse Astro file\n const result = await parse(fileContent);\n const ast = result.ast;\n\n // Extract and log frontmatter variables\n const vars = this.extractFrontmatter(ast);\n this.logger.debug(`Extracted ${Object.keys(vars).length} frontmatter variables`);\n\n // Convert AST to HTML\n let html = '';\n if (ast.children) {\n html = ast.children.map((child: Node) => this.nodeToHTML(child)).join('\\n');\n }\n\n // Replace variables\n html = this.replaceFrontmatterVars(html, vars);\n\n // Success logging\n this.logger.success(`Rendered ${filePath} (${html.length} chars)`);\n\n return html;\n } catch (error: unknown) {\n const err = error as Error;\n this.logger.error(`Failed to render ${filePath}: ${err.message}`);\n throw error;\n }\n }\n}","// src/utils/LazyLoader.ts\n// Client-side utility for lazy loading prerendered HTML components\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Configuration options for the LazyHTMLLoader\n */\nexport interface LazyLoaderConfig {\n /** Base URL for prerendered files (default: '/prerendered') */\n baseUrl?: string;\n /** Enable CSS modules mode with per-component CSS (default: false) */\n cssModules?: boolean;\n /** URL to CSS modules manifest (default: '/prerendered/manifest.json') */\n manifestUrl?: string;\n /** URL to base CSS file in CSS modules mode (default: '/prerendered/base.css') */\n baseCssUrl?: string;\n /** URL to legacy single CSS file (default: '/prerendered/lazy-components.css') */\n legacyCssUrl?: string;\n /** Preload CSS files before they're needed (default: false) */\n preloadCSS?: boolean;\n /** Cache loaded HTML in memory (default: true) */\n cacheHTML?: boolean;\n /** Enable retry logic for failed fetches (default: true) */\n enableRetry?: boolean;\n /** Maximum number of retry attempts (default: 3) */\n maxRetries?: number;\n /** Delay between retries in milliseconds (default: 1000) */\n retryDelay?: number;\n /** Enable debug logging (default: false) */\n debug?: boolean;\n /** Callback when a component is loaded */\n onLoad?: (componentName: string, stats: {\n duration: number;\n bytes: number;\n fromCache: boolean;\n secondaryAssets?: Array<{ url: string; bytes: number; duration: number; type: string }>\n }) => void;\n /** Callback when an error occurs */\n onError?: (componentName: string, error: Error) => void;\n /** Callback when CSS is loaded */\n onCSSLoad?: (cssFile: string, duration: number) => void;\n}\n\n/**\n * CSS module manifest structure\n */\nexport interface CSSModuleManifest {\n /** Map of component names to their CSS file paths */\n components: Record<string, string>;\n}\n\n/**\n * Load statistics\n */\nexport interface LoadStats {\n /** Total number of successful loads */\n totalLoads: number;\n /** Number of cache hits */\n cacheHits: number;\n /** Number of cache misses */\n cacheMisses: number;\n /** Number of errors encountered */\n errors: number;\n /** Average load time in milliseconds */\n averageLoadTime: number;\n /** Total bytes transferred across all loads */\n totalBytes: number;\n}\n\n// ============================================================================\n// LazyHTMLLoader Class\n// ============================================================================\n\n/**\n * Client-side utility for lazy loading prerendered HTML components\n * \n * @example\n * ```ts\n * import { createLazyLoader } from 'vite-plugin-astro-prerender';\n * \n * const loader = createLazyLoader({ debug: true });\n * \n * // Load and inject when in viewport\n * loader.observeAndLoad('LazyFooter', '#footer-container');\n * \n * // Or load manually\n * const html = await loader.load('LazyHeader');\n * document.getElementById('header')!.innerHTML = html;\n * ```\n */\nexport class LazyHTMLLoader {\n private config: Required<LazyLoaderConfig>;\n private htmlCache = new Map<string, string>();\n private cssCache = new Set<string>();\n private observers = new Map<string, IntersectionObserver>();\n private manifest: CSSModuleManifest | null = null;\n private manifestLoaded = false;\n private baseCssLoaded = false;\n private legacyCssLoaded = false;\n private stats = {\n totalLoads: 0,\n cacheHits: 0,\n cacheMisses: 0,\n errors: 0,\n totalLoadTime: 0,\n totalBytes: 0,\n };\n private detailedStats = new Map<string, {\n duration: number;\n bytes: number;\n fromCache: boolean;\n timestamp: number;\n secondaryAssets?: Array<{ url: string; bytes: number; duration: number; type: string }>\n }>();\n\n constructor(config: LazyLoaderConfig = {}) {\n const baseUrl = config.baseUrl ?? '/prerendered';\n this.config = {\n baseUrl,\n cssModules: config.cssModules ?? false,\n manifestUrl: config.manifestUrl ?? `${baseUrl}/manifest.json`,\n baseCssUrl: config.baseCssUrl ?? `${baseUrl}/base.css`,\n legacyCssUrl: config.legacyCssUrl ?? `${baseUrl}/lazy-components.css`,\n preloadCSS: config.preloadCSS ?? false,\n cacheHTML: config.cacheHTML ?? true,\n enableRetry: config.enableRetry ?? true,\n maxRetries: config.maxRetries ?? 3,\n retryDelay: config.retryDelay ?? 1000,\n debug: config.debug ?? false,\n onLoad: config.onLoad ?? (() => { }),\n onError: config.onError ?? (() => { }),\n onCSSLoad: config.onCSSLoad ?? (() => { }),\n };\n\n this.log('LazyHTMLLoader initialized', this.config);\n }\n\n /**\n * Internal logging method\n */\n private log(message: string, ...args: unknown[]): void {\n if (this.config.debug) {\n console.log(`[LazyHTMLLoader] ${message}`, ...args);\n }\n }\n\n /**\n * Fetch with retry logic\n */\n private async fetchWithRetry(\n url: string,\n retries = this.config.maxRetries,\n ): Promise<Response> {\n for (let attempt = 1; attempt <= retries; attempt++) {\n try {\n this.log(`Fetching ${url} (attempt ${attempt}/${retries})`);\n const response = await fetch(url);\n\n if (response.ok) {\n return response;\n }\n\n if (attempt === retries) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n }\n\n // Don't retry on 404\n if (response.status === 404) {\n throw new Error(`Not found: ${url}`);\n }\n\n this.log(`Fetch failed with status ${response.status}, retrying...`);\n } catch (error) {\n if (attempt === retries) {\n throw error;\n }\n this.log(`Fetch error: ${error}, retrying...`);\n }\n\n // Wait before retrying\n if (attempt < retries) {\n await new Promise((resolve) =>\n setTimeout(resolve, this.config.retryDelay * attempt),\n );\n }\n }\n\n throw new Error(`Failed to fetch ${url} after ${retries} attempts`);\n }\n\n /**\n * Load CSS manifest for CSS modules mode\n */\n private async loadManifest(): Promise<void> {\n if (this.manifestLoaded) {\n return;\n }\n\n const startTime = performance.now();\n\n try {\n const response = await (this.config.enableRetry\n ? this.fetchWithRetry(this.config.manifestUrl)\n : fetch(this.config.manifestUrl));\n\n if (!response.ok) {\n throw new Error(`Failed to load manifest: ${response.statusText}`);\n }\n\n this.manifest = await response.json();\n this.manifestLoaded = true;\n\n const duration = performance.now() - startTime;\n this.log(`Manifest loaded in ${duration.toFixed(2)}ms`, this.manifest);\n this.config.onCSSLoad(this.config.manifestUrl, duration);\n } catch (error) {\n console.error('Failed to load CSS manifest:', error);\n // Fallback to legacy mode\n this.config.cssModules = false;\n this.manifestLoaded = true;\n }\n }\n\n /**\n * Load base CSS file (CSS modules mode)\n */\n private async loadBaseCSS(): Promise<void> {\n if (this.baseCssLoaded) {\n return;\n }\n\n await this.loadManifest();\n\n if (!this.manifest) {\n return;\n }\n\n const startTime = performance.now();\n\n return new Promise((resolve, reject) => {\n const link = document.createElement('link');\n link.rel = 'stylesheet';\n link.href = this.config.baseCssUrl;\n\n link.onload = () => {\n this.baseCssLoaded = true;\n const duration = performance.now() - startTime;\n this.log(`Base CSS loaded in ${duration.toFixed(2)}ms`);\n this.config.onCSSLoad(this.config.baseCssUrl, duration);\n resolve();\n };\n\n link.onerror = () => {\n console.error('Failed to load base CSS');\n reject(new Error('Failed to load base CSS'));\n };\n\n if (this.config.preloadCSS) {\n const preload = document.createElement('link');\n preload.rel = 'preload';\n preload.as = 'style';\n preload.href = this.config.baseCssUrl;\n document.head.appendChild(preload);\n }\n\n document.head.appendChild(link);\n });\n }\n\n /**\n * Load component-specific CSS file (CSS modules mode)\n */\n private async loadComponentCSS(componentName: string): Promise<void> {\n if (!this.config.cssModules || !this.manifest) {\n return;\n }\n\n const cssFile = this.manifest.components[componentName];\n if (!cssFile) {\n this.log(`No CSS file for component: ${componentName}`);\n return;\n }\n\n if (this.cssCache.has(cssFile)) {\n this.log(`CSS already loaded: ${cssFile}`);\n return;\n }\n\n const startTime = performance.now();\n const cssUrl = `${this.config.baseUrl}/${cssFile}`;\n\n return new Promise((resolve, reject) => {\n const link = document.createElement('link');\n link.rel = 'stylesheet';\n link.href = cssUrl;\n\n link.onload = () => {\n this.cssCache.add(cssFile);\n const duration = performance.now() - startTime;\n this.log(\n `Component CSS loaded in ${duration.toFixed(2)}ms: ${cssFile}`,\n );\n this.config.onCSSLoad(cssFile, duration);\n resolve();\n };\n\n link.onerror = () => {\n console.error(`Failed to load component CSS: ${cssFile}`);\n reject(new Error(`Failed to load CSS: ${cssFile}`));\n };\n\n if (this.config.preloadCSS) {\n const preload = document.createElement('link');\n preload.rel = 'preload';\n preload.as = 'style';\n preload.href = cssUrl;\n document.head.appendChild(preload);\n }\n\n document.head.appendChild(link);\n });\n }\n\n /**\n * Load legacy single CSS file\n */\n private async loadLegacyCSS(): Promise<void> {\n if (this.legacyCssLoaded) {\n return;\n }\n\n const startTime = performance.now();\n\n return new Promise((resolve, reject) => {\n const link = document.createElement('link');\n link.rel = 'stylesheet';\n link.href = this.config.legacyCssUrl;\n\n link.onload = () => {\n this.legacyCssLoaded = true;\n const duration = performance.now() - startTime;\n this.log(`Legacy CSS loaded in ${duration.toFixed(2)}ms`);\n this.config.onCSSLoad(this.config.legacyCssUrl, duration);\n resolve();\n };\n\n link.onerror = () => {\n console.error('Failed to load legacy CSS');\n reject(new Error('Failed to load lazy components CSS'));\n };\n\n if (this.config.preloadCSS) {\n const preload = document.createElement('link');\n preload.rel = 'preload';\n preload.as = 'style';\n preload.href = this.config.legacyCssUrl;\n document.head.appendChild(preload);\n }\n\n document.head.appendChild(link);\n });\n }\n\n /**\n * Load HTML fragment from server\n */\n async load(componentName: string): Promise<string> {\n const startTime = performance.now();\n\n try {\n // Check cache\n if (this.config.cacheHTML && this.htmlCache.has(componentName)) {\n this.stats.cacheHits++;\n this.log(`Cache hit: ${componentName}`);\n const html = this.htmlCache.get(componentName)!;\n const bytes = new Blob([html]).size;\n const duration = performance.now() - startTime;\n\n this.stats.totalLoads++;\n this.stats.totalLoadTime += duration;\n\n const loadInfo = { duration, bytes, fromCache: true, timestamp: Date.now() };\n this.detailedStats.set(componentName, loadInfo);\n this.config.onLoad(componentName, { duration, bytes, fromCache: true });\n\n return html;\n }\n\n this.stats.cacheMisses++;\n\n // Load CSS\n if (this.config.cssModules) {\n await this.loadBaseCSS().catch((err) => {\n console.warn('Failed to load base CSS:', err);\n });\n await this.loadComponentCSS(componentName).catch((err) => {\n console.warn(`Failed to load CSS for ${componentName}:`, err);\n });\n } else {\n await this.loadLegacyCSS().catch((err) => {\n console.warn('Failed to load legacy CSS:', err);\n });\n }\n\n // Fetch HTML\n const url = `${this.config.baseUrl}/${componentName}.html`;\n const response = await (this.config.enableRetry\n ? this.fetchWithRetry(url)\n : fetch(url));\n\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n }\n\n const html = await response.text();\n const bytes = new Blob([html]).size;\n\n // Cache HTML\n if (this.config.cacheHTML) {\n this.htmlCache.set(componentName, html);\n }\n\n // Update stats\n const duration = performance.now() - startTime;\n this.stats.totalLoads++;\n this.stats.totalLoadTime += duration;\n this.stats.totalBytes += bytes;\n\n this.log(`Loaded ${componentName} in ${duration.toFixed(2)}ms (${bytes} bytes)`);\n\n // Start tracking secondary assets (images, etc.) that might be triggered by this injection\n const secondaryAssets: Array<{ url: string; bytes: number; duration: number; type: string }> = [];\n\n const resourceObserver = new PerformanceObserver((list) => {\n list.getEntries().forEach((entry) => {\n const res = entry as PerformanceResourceTiming;\n // Filter for assets likely triggered by this component\n if (res.startTime >= (startTime - 50)) {\n const assetBytes = res.transferSize || res.decodedBodySize || res.encodedBodySize || 0;\n\n secondaryAssets.push({\n url: res.name,\n bytes: assetBytes,\n duration: res.duration,\n type: res.initiatorType\n });\n\n // Update total bytes and global stats with secondary assets\n this.stats.totalBytes += assetBytes;\n }\n });\n });\n\n try {\n // Use buffered: true to catch resources that might have started \n // between performance.now() and observe() call\n resourceObserver.observe({ entryTypes: ['resource'], buffered: true });\n\n // Stop observing after a reasonable time (longer for assets)\n setTimeout(() => resourceObserver.disconnect(), 6000);\n } catch (e) {\n this.log('PerformanceObserver failed');\n // Fallback attempt without buffering if that was the cause\n try { resourceObserver.observe({ entryTypes: ['resource'] }); } catch (err) { }\n }\n\n const loadInfo = {\n duration,\n bytes,\n fromCache: false,\n timestamp: Date.now(),\n secondaryAssets\n };\n this.detailedStats.set(componentName, loadInfo);\n this.config.onLoad(componentName, { duration, bytes, fromCache: false, secondaryAssets });\n\n return html;\n } catch (error) {\n this.stats.errors++;\n const err = error instanceof Error ? error : new Error(String(error));\n this.log(`Error loading ${componentName}:`, err);\n this.config.onError(componentName, err);\n throw err;\n }\n }\n\n /**\n * Inject HTML fragment into target element\n */\n async inject(componentName: string, targetSelector: string): Promise<void> {\n const html = await this.load(componentName);\n const target = document.querySelector(targetSelector);\n\n if (target) {\n target.innerHTML = html;\n this.log(`Injected ${componentName} into ${targetSelector}`);\n } else {\n const error = new Error(`Target element not found: ${targetSelector}`);\n this.config.onError(componentName, error);\n throw error;\n }\n }\n\n /**\n * Load HTML fragment when target element enters viewport\n */\n observeAndLoad(\n componentName: string,\n targetSelector: string,\n options?: IntersectionObserverInit,\n ): void {\n const target = document.querySelector(targetSelector);\n if (!target) {\n console.warn(`Target element not found: ${targetSelector}`);\n return;\n }\n\n const observer = new IntersectionObserver(\n (entries) => {\n entries.forEach((entry) => {\n if (entry.isIntersecting) {\n this.log(`Component ${componentName} entered viewport`);\n this.inject(componentName, targetSelector).catch((err) => {\n console.error(`Failed to inject ${componentName}:`, err);\n });\n observer.disconnect();\n this.observers.delete(componentName);\n }\n });\n },\n options || { rootMargin: '100px' },\n );\n\n observer.observe(target);\n this.observers.set(componentName, observer);\n this.log(`Observing ${componentName} at ${targetSelector}`);\n }\n\n /**\n * Preload HTML fragment without injecting\n */\n async preload(componentName: string): Promise<void> {\n await this.load(componentName);\n }\n\n /**\n * Batch preload multiple components\n */\n async preloadBatch(componentNames: string[]): Promise<void> {\n this.log(`Preloading ${componentNames.length} components:`, componentNames);\n await Promise.all(componentNames.map((name) => this.preload(name)));\n }\n\n /**\n * Get load statistics\n */\n getStats(): LoadStats {\n return {\n totalLoads: this.stats.totalLoads,\n cacheHits: this.stats.cacheHits,\n cacheMisses: this.stats.cacheMisses,\n errors: this.stats.errors,\n averageLoadTime:\n this.stats.totalLoads > 0\n ? this.stats.totalLoadTime / this.stats.totalLoads\n : 0,\n totalBytes: this.stats.totalBytes,\n };\n }\n\n /**\n * Get detailed history of all loads in this session\n */\n getDetailedHistory(): Array<{ componentName: string; duration: number; bytes: number; fromCache: boolean; timestamp: number }> {\n return Array.from(this.detailedStats.entries()).map(([name, info]) => ({\n componentName: name,\n ...info,\n })).sort((a, b) => b.timestamp - a.timestamp);\n }\n\n /**\n * Clear HTML cache\n */\n clearCache(): void {\n this.htmlCache.clear();\n this.log('HTML cache cleared');\n }\n\n /**\n * Clear CSS cache (forces reload of CSS files)\n */\n clearCSSCache(): void {\n this.cssCache.clear();\n this.baseCssLoaded = false;\n this.legacyCssLoaded = false;\n this.manifestLoaded = false;\n this.manifest = null;\n this.log('CSS cache cleared');\n }\n\n /**\n * Disconnect all observers\n */\n disconnectAll(): void {\n this.observers.forEach((observer) => observer.disconnect());\n this.observers.clear();\n this.log('All observers disconnected');\n }\n\n /**\n * Reset all state (cache, observers, stats)\n */\n reset(): void {\n this.clearCache();\n this.clearCSSCache();\n this.disconnectAll();\n this.stats = {\n totalLoads: 0,\n cacheHits: 0,\n cacheMisses: 0,\n errors: 0,\n totalLoadTime: 0,\n totalBytes: 0,\n };\n this.detailedStats.clear();\n this.log('LazyHTMLLoader reset');\n }\n}\n\n/**\n * Factory function to create a lazy loader instance\n */\nexport function createLazyLoader(config?: LazyLoaderConfig): LazyHTMLLoader {\n return new LazyHTMLLoader(config);\n}\n\n/**\n * Default lazy loader instance with default configuration\n */\nexport const lazyLoader = new LazyHTMLLoader();"],"mappings":"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","names":["watch","join","relative","basename","createHash","readFile","fg","outputFile","fsEnsureDir","cheerio","consola","createLogger","tag","getFileHash","filePath","content","readFile","createHash","findComponents","dir","fg","extractClasses","html","$","classes","_","el","_a","cls","extractStyles","styles","cleanHTML","$el","attrs","attr","body","minifyHTML","minify","error","writeFileWithDir","filePath","content","outputFile","FlatCache","CacheManager","cacheDir","componentPath","hash","pathToFileURL","CSSGenerator","tailwindConfigPath","logger","generateTailwind","classes","cls","styles","outputPath","classArray","cssContent","writeFileWithDir","postcssModule","tailwindModule","autoprefixerModule","postcss","tailwindcss","autoprefixer","modifiedConfig","pathToFileURL","result","error","readFile","AstroContainer","ContainerRenderer","logger","server","componentPath","frontmatterMatch","frontmatterVars","varMatches","match","ComponentModule","error","err","html","key","value","regex","parse","readFile","consola","ParserRenderer","ast","frontmatter","vars","varMatches","match","node","indent","elementNode","attrs","attr","openTag","children","child","componentNode","styleNode","content","directContent","html","result","key","value","escapedKey","regex","filePath","fileContent","error","err","LazyHTMLLoader","config","_a","_b","_c","_d","_e","_f","_g","_h","_i","_j","_k","_l","_m","_n","baseUrl","message","args","url","retries","attempt","response","error","resolve","startTime","duration","reject","link","preload","componentName","cssFile","cssUrl","html","bytes","loadInfo","err","secondaryAssets","resourceObserver","list","entry","res","assetBytes","e","targetSelector","target","options","observer","entries","componentNames","name","info","a","b","createLazyLoader","lazyLoader","astroPrerenderPlugin","componentsDir","outputDir","generateTailwindCSS","tailwindConfigPath","renderer","minify","base","normalizedBase","logger","createLogger","config","cacheManager","cssGenerator","componentRenderer","parserFallback","processAll","root","componentsPath","join","outputPath","componentFiles","findComponents","componentPath","processComponent","generateCSS","hash","getFileHash","relative","html","styles","extractStyles","cleanedHTML","cleanHTML","classes","extractClasses","originalSize","minifyHTML","minifiedSize","savings","componentName","basename","htmlOutputPath","writeFileWithDir","error","cssOutputPath","prerenderedPath","id","clientConfig","resolvedConfig","CacheManager","CSSGenerator","ContainerRenderer","ParserRenderer","server","watcher","watch","filePath","astroPrerenderIntegration","options","updateConfig","_a","_b","baseFromConfig"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vite-plugin-astro-prerender",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "A Vite plugin for Astro that prerenders components to static HTML and generates optimized CSS with Tailwind tree-shaking for lazy-loading below-the-fold content",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Ishan Parlikar"
|