@sigx/ssg 0.2.1 → 0.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/build.ts", "../src/config.ts", "../src/routing/scanner.ts", "../src/mdx/frontmatter.ts", "../src/routing/virtual.ts", "../src/routing/navigation.ts", "../src/routing/virtual-navigation.ts", "../src/layouts/resolver.ts", "../src/layouts/virtual.ts", "../src/sitemap.ts", "../src/vite/virtual-entries.ts", "../src/dev.ts", "../src/vite/plugin.ts", "../src/mdx/shiki.ts", "../src/mdx/rehype-headings.ts", "../src/mdx/plugin.ts", "../src/cli.ts"],
4
- "sourcesContent": ["/**\r\n * SSG Build CLI\r\n *\r\n * Static site generation build process:\r\n * 1. Load configuration\r\n * 2. Scan routes and expand dynamic paths\r\n * 3. Build with Vite for production\r\n * 4. Render each route to static HTML\r\n * 5. Write output files\r\n * 6. Generate sitemap and robots.txt\r\n */\r\n\r\nimport path from 'node:path';\r\nimport fs from 'node:fs/promises';\r\nimport fsSync from 'node:fs';\r\nimport { createRequire } from 'node:module';\r\nimport { pathToFileURL } from 'node:url';\r\nimport type { SSGConfig, BuildOptions, BuildResult, PageBuildResult, SSGRoute, PageModule } from './types';\r\nimport { loadConfig, resolveConfigPaths } from './config';\r\nimport { scanPages, isDynamicRoute, extractParams, expandDynamicRoute } from './routing/index';\r\nimport { discoverLayouts } from './layouts/index';\r\nimport { writeSitemap } from './sitemap';\r\nimport {\r\n detectCustomEntries,\r\n generateClientEntry,\r\n generateServerEntry,\r\n generateProductionHtmlTemplate,\r\n VIRTUAL_CLIENT_ID,\r\n VIRTUAL_SERVER_ID,\r\n} from './vite/virtual-entries';\r\n\r\n/**\r\n * Build static site\r\n */\r\nexport async function build(options: BuildOptions = {}): Promise<BuildResult> {\r\n const startTime = Date.now();\r\n const root = process.cwd();\r\n const warnings: string[] = [];\r\n const pages: PageBuildResult[] = [];\r\n\r\n console.log('\\n\uD83D\uDE80 @sigx/ssg - Building static site...\\n');\r\n\r\n // Step 1: Load configuration\r\n console.log('\uD83D\uDCE6 Loading configuration...');\r\n const config = await loadConfig(options.configPath);\r\n const resolvedConfig = resolveConfigPaths(config, root);\r\n\r\n // Step 2: Scan routes\r\n console.log('\uD83D\uDD0D Scanning pages...');\r\n const routes = await scanPages(resolvedConfig, root);\r\n console.log(` Found ${routes.length} page(s)`);\r\n\r\n // Step 3: Discover layouts\r\n console.log('\uD83D\uDCD0 Discovering layouts...');\r\n const layouts = await discoverLayouts(resolvedConfig, root);\r\n console.log(` Found ${layouts.length} layout(s)`);\r\n\r\n // Step 4: Detect entry points\r\n const entryDetection = detectCustomEntries(root, resolvedConfig);\r\n if (entryDetection.useVirtualClient || entryDetection.useVirtualServer) {\r\n console.log('\uD83D\uDCE6 Using zero-config mode');\r\n if (entryDetection.useVirtualClient) console.log(' \u2192 Virtual client entry');\r\n if (entryDetection.useVirtualServer) console.log(' \u2192 Virtual server entry');\r\n if (entryDetection.useVirtualHtml) console.log(' \u2192 Virtual HTML template');\r\n }\r\n\r\n // Get entry points (may create temp files for virtual entries)\r\n const clientEntry = await getClientEntryPoint(resolvedConfig, root);\r\n const ssrEntry = await getSSREntryPoint(resolvedConfig, root);\r\n\r\n // Always write HTML template for the build (either generated or updated from custom)\r\n // This ensures Vite processes it and outputs index.html\r\n const htmlTemplatePath = path.join(root, 'index.html');\r\n let cleanupHtml = false;\r\n let originalHtmlContent: string | null = null;\r\n \r\n // Save original HTML content if we're modifying a custom one\r\n if (!entryDetection.useVirtualHtml && fsSync.existsSync(htmlTemplatePath)) {\r\n originalHtmlContent = fsSync.readFileSync(htmlTemplatePath, 'utf-8');\r\n }\r\n \r\n const htmlContent = await getHtmlTemplate(resolvedConfig, root, clientEntry);\r\n fsSync.writeFileSync(htmlTemplatePath, htmlContent, 'utf-8');\r\n cleanupHtml = entryDetection.useVirtualHtml; // Only cleanup (delete) if we generated it\r\n\r\n // Step 5: Build with Vite\r\n console.log('\uD83D\uDD28 Building with Vite...');\r\n const vite = await import('vite');\r\n\r\n try {\r\n // Build client bundle\r\n // Note: We don't empty the outDir since vite build may have already run\r\n // Always use HTML as input so Vite outputs index.html properly\r\n const clientInput = htmlTemplatePath;\r\n \r\n await vite.build({\r\n root,\r\n mode: 'production',\r\n build: {\r\n outDir: resolvedConfig.outDir,\r\n emptyOutDir: false,\r\n ssrManifest: true,\r\n rollupOptions: {\r\n input: clientInput,\r\n },\r\n },\r\n logLevel: options.verbose ? 'info' : 'warn',\r\n });\r\n\r\n // Build SSR bundle\r\n const ssrOutDir = path.join(resolvedConfig.outDir!, '.ssg');\r\n await vite.build({\r\n root,\r\n mode: 'production',\r\n build: {\r\n outDir: ssrOutDir,\r\n ssr: true,\r\n rollupOptions: {\r\n input: ssrEntry,\r\n },\r\n },\r\n logLevel: options.verbose ? 'info' : 'warn',\r\n });\r\n\r\n // Step 6: Collect all paths to render\r\n console.log('\uD83D\uDCDD Collecting paths to render...');\r\n const pathsToRender = await collectPaths(routes, root, warnings);\r\n console.log(` ${pathsToRender.length} path(s) to render`);\r\n\r\n // Pre-create all output directories to avoid mkdir contention during parallel rendering\r\n const outputDirs = new Set<string>();\r\n for (const pathInfo of pathsToRender) {\r\n const outputPath = getOutputPath(pathInfo.path, resolvedConfig.outDir!);\r\n outputDirs.add(path.dirname(outputPath));\r\n }\r\n await Promise.all(\r\n Array.from(outputDirs).map(dir => fs.mkdir(dir, { recursive: true }))\r\n );\r\n\r\n // Step 7: Render each path to HTML\r\n console.log('\uD83C\uDFA8 Rendering pages...');\r\n\r\n // Determine the SSR entry output name (based on input file name)\r\n const ssrEntryBasename = path.basename(ssrEntry, path.extname(ssrEntry));\r\n const ssrEntryName = ssrEntryBasename + '.js';\r\n\r\n // Pre-load the SSR module once for all pages\r\n const entryPath = path.join(ssrOutDir, ssrEntryName);\r\n const entryModule = await import(pathToFileURL(entryPath).href);\r\n\r\n // Load HTML template once\r\n const templatePath = path.join(resolvedConfig.outDir!, 'index.html');\r\n const template = await fs.readFile(templatePath, 'utf-8');\r\n\r\n // Parallel rendering configuration - higher concurrency since rendering is CPU-bound\r\n const CONCURRENCY = options.concurrency ?? 20; // Number of pages to render in parallel\r\n const verbose = options.verbose ?? false;\r\n\r\n interface RenderResult {\r\n pathInfo: PathToRender;\r\n html: string;\r\n outputPath: string;\r\n renderTime: number;\r\n }\r\n\r\n // Render a single page (CPU-bound, no I/O)\r\n async function renderPage(pathInfo: PathToRender): Promise<RenderResult | null> {\r\n const renderStart = Date.now();\r\n\r\n try {\r\n // Render the app\r\n const appHtml = await entryModule.render(pathInfo.path, {\r\n params: pathInfo.params,\r\n props: pathInfo.props,\r\n });\r\n\r\n // Inject into template\r\n let html = template.replace('<!--app-html-->', appHtml);\r\n const headTags = generateHeadTags(pathInfo, resolvedConfig);\r\n html = html.replace('<!--head-tags-->', headTags);\r\n\r\n const outputPath = getOutputPath(pathInfo.path, resolvedConfig.outDir!);\r\n const renderTime = Date.now() - renderStart;\r\n\r\n return { pathInfo, html, outputPath, renderTime };\r\n } catch (err) {\r\n const errorMessage = err instanceof Error ? err.message : String(err);\r\n console.error(` \u274C ${pathInfo.path}: ${errorMessage}`);\r\n warnings.push(`Failed to render ${pathInfo.path}: ${errorMessage}`);\r\n return null;\r\n }\r\n }\r\n\r\n // Render all pages in parallel batches (CPU-bound, no I/O)\r\n console.log(' Phase 1: Rendering...');\r\n const renderPhaseStart = Date.now();\r\n const renderResults: RenderResult[] = [];\r\n \r\n for (let i = 0; i < pathsToRender.length; i += CONCURRENCY) {\r\n const batch = pathsToRender.slice(i, i + CONCURRENCY);\r\n const results = await Promise.all(batch.map(renderPage));\r\n \r\n for (const result of results) {\r\n if (result) {\r\n renderResults.push(result);\r\n }\r\n }\r\n }\r\n const renderPhaseDuration = Date.now() - renderPhaseStart;\r\n console.log(` Phase 1 complete: ${renderResults.length} pages in ${renderPhaseDuration}ms (${Math.round(renderPhaseDuration / renderResults.length)}ms avg)`);\r\n\r\n // Write all files in parallel with limited concurrency\r\n console.log(' Phase 2: Writing files...');\r\n const writePhaseStart = Date.now();\r\n const WRITE_CONCURRENCY = 10; // Limit parallel writes to reduce I/O contention\r\n \r\n for (let i = 0; i < renderResults.length; i += WRITE_CONCURRENCY) {\r\n const batch = renderResults.slice(i, i + WRITE_CONCURRENCY);\r\n await Promise.all(batch.map(async (result) => {\r\n await fs.writeFile(result.outputPath, result.html, 'utf-8');\r\n const size = Buffer.byteLength(result.html, 'utf-8');\r\n\r\n pages.push({\r\n path: result.pathInfo.path,\r\n file: result.outputPath,\r\n time: result.renderTime,\r\n size,\r\n });\r\n \r\n if (verbose) {\r\n console.log(` \u2713 ${result.pathInfo.path} (${result.renderTime}ms, ${formatBytes(size)})`);\r\n }\r\n }));\r\n }\r\n const writePhaseDuration = Date.now() - writePhaseStart;\r\n console.log(` Phase 2 complete: ${renderResults.length} files in ${writePhaseDuration}ms`);\r\n \r\n // Summary (non-verbose)\r\n if (!verbose) {\r\n console.log(` \u2713 Rendered ${renderResults.length} pages`);\r\n }\r\n\r\n // Step 8: Clean up SSR build\r\n await fs.rm(ssrOutDir, { recursive: true, force: true });\r\n\r\n // Step 9: Generate sitemap and robots.txt\r\n if (pages.length > 0) {\r\n console.log('\uD83D\uDDFA\uFE0F Generating sitemap...');\r\n await writeSitemap(pages, resolvedConfig, resolvedConfig.outDir!);\r\n console.log(' \u2713 sitemap.xml');\r\n console.log(' \u2713 robots.txt');\r\n }\r\n\r\n } finally {\r\n // Clean up temporary entry files\r\n await cleanupTempEntries(root);\r\n \r\n // Clean up or restore HTML template\r\n if (cleanupHtml) {\r\n // We generated a virtual HTML, remove it\r\n try {\r\n await fs.unlink(htmlTemplatePath);\r\n } catch {\r\n // Ignore\r\n }\r\n } else if (originalHtmlContent !== null) {\r\n // We modified a custom HTML, restore the original\r\n try {\r\n await fs.writeFile(htmlTemplatePath, originalHtmlContent, 'utf-8');\r\n } catch {\r\n // Ignore\r\n }\r\n }\r\n }\r\n\r\n // Done\r\n const totalTime = Date.now() - startTime;\r\n\r\n console.log(`\\n\u2705 Built ${pages.length} page(s) in ${totalTime}ms`);\r\n\r\n if (warnings.length > 0) {\r\n console.log(`\\n\u26A0\uFE0F ${warnings.length} warning(s):`);\r\n for (const warning of warnings) {\r\n console.log(` - ${warning}`);\r\n }\r\n }\r\n\r\n console.log(`\\n\uD83D\uDCC1 Output: ${resolvedConfig.outDir}\\n`);\r\n\r\n return {\r\n pages,\r\n totalTime,\r\n warnings,\r\n };\r\n}\r\n\r\n/**\r\n * Path information for rendering\r\n */\r\ninterface PathToRender {\r\n path: string;\r\n route: SSGRoute;\r\n params: Record<string, string>;\r\n props?: Record<string, unknown>;\r\n}\r\n\r\n/**\r\n * Collect all paths to render, expanding dynamic routes\r\n */\r\nasync function collectPaths(\r\n routes: SSGRoute[],\r\n root: string,\r\n warnings: string[]\r\n): Promise<PathToRender[]> {\r\n const paths: PathToRender[] = [];\r\n\r\n for (const route of routes) {\r\n if (isDynamicRoute(route)) {\r\n // Load module and call getStaticPaths\r\n try {\r\n const moduleUrl = pathToFileURL(route.file).href;\r\n const pageModule = (await import(moduleUrl)) as PageModule;\r\n\r\n if (!pageModule.getStaticPaths) {\r\n const params = extractParams(route.path).join(', ');\r\n console.warn(\r\n `\\n\u26A0\uFE0F SSG102: Dynamic route missing getStaticPaths()\\n` +\r\n ` \uD83D\uDCC1 ${route.file}\\n` +\r\n ` Route: ${route.path} (params: ${params})\\n` +\r\n ` \uD83D\uDCA1 Export getStaticPaths() to generate static pages:\\n\\n` +\r\n ` export async function getStaticPaths() {\\n` +\r\n ` return [{ params: { ${params.split(', ')[0]}: 'value' } }];\\n` +\r\n ` }\\n`\r\n );\r\n warnings.push(\r\n `Route ${route.path} has dynamic segments [${params}] but no getStaticPaths() export. Skipping.`\r\n );\r\n continue;\r\n }\r\n\r\n const staticPaths = await pageModule.getStaticPaths();\r\n\r\n for (const staticPath of staticPaths) {\r\n const expandedPaths = expandDynamicRoute(route, [staticPath]);\r\n for (const expandedPath of expandedPaths) {\r\n paths.push({\r\n path: expandedPath,\r\n route,\r\n params: staticPath.params,\r\n props: staticPath.props,\r\n });\r\n }\r\n }\r\n } catch (err) {\r\n warnings.push(`Failed to load ${route.file}: ${err}`);\r\n }\r\n } else {\r\n paths.push({\r\n path: route.path,\r\n route,\r\n params: {},\r\n });\r\n }\r\n }\r\n\r\n return paths;\r\n}\r\n\r\n/**\r\n * Render a page to HTML\r\n */\r\nasync function renderPage(\r\n pathInfo: PathToRender,\r\n config: SSGConfig,\r\n ssrOutDir: string,\r\n ssrEntryName: string\r\n): Promise<string> {\r\n // Load the SSR entry module\r\n // This should export a render function that returns HTML string\r\n const entryPath = path.join(ssrOutDir, ssrEntryName);\r\n const entryModule = await import(pathToFileURL(entryPath).href);\r\n\r\n // Render the app - the entry module's render function handles SSR\r\n const appHtml = await entryModule.render(pathInfo.path, {\r\n params: pathInfo.params,\r\n props: pathInfo.props,\r\n });\r\n\r\n // Load HTML template\r\n const templatePath = path.join(config.outDir!, 'index.html');\r\n let template = await fs.readFile(templatePath, 'utf-8');\r\n\r\n // Inject app HTML\r\n template = template.replace('<!--app-html-->', appHtml);\r\n\r\n // Inject head tags if any\r\n const headTags = generateHeadTags(pathInfo, config);\r\n template = template.replace('<!--head-tags-->', headTags);\r\n\r\n return template;\r\n}\r\n\r\n/**\r\n * Generate head tags for a page\r\n */\r\nfunction generateHeadTags(pathInfo: PathToRender, config: SSGConfig): string {\r\n const tags: string[] = [];\r\n const meta = pathInfo.route.meta || {};\r\n\r\n // Title\r\n const title = meta.title || config.site?.title;\r\n if (title) {\r\n tags.push(`<title>${escapeHtml(title)}</title>`);\r\n }\r\n\r\n // Description\r\n const description = meta.description || config.site?.description;\r\n if (description) {\r\n tags.push(`<meta name=\"description\" content=\"${escapeHtml(description)}\">`);\r\n }\r\n\r\n // Canonical URL\r\n if (config.site?.url) {\r\n const canonical = new URL(pathInfo.path, config.site.url).href;\r\n tags.push(`<link rel=\"canonical\" href=\"${canonical}\">`);\r\n }\r\n\r\n return tags.join('\\n ');\r\n}\r\n\r\n/**\r\n * Get output file path for a URL path\r\n */\r\nfunction getOutputPath(urlPath: string, outDir: string): string {\r\n // Normalize path\r\n let normalized = urlPath.replace(/^\\//, '').replace(/\\/$/, '');\r\n\r\n if (!normalized) {\r\n normalized = 'index';\r\n }\r\n\r\n // Add .html extension or /index.html for directories\r\n if (!normalized.endsWith('.html')) {\r\n normalized = path.join(normalized, 'index.html');\r\n }\r\n\r\n return path.join(outDir, normalized);\r\n}\r\n\r\n/**\r\n * Get SSR entry point\r\n * Returns virtual module ID if no custom entry exists\r\n */\r\nasync function getSSREntryPoint(config: SSGConfig, root: string): Promise<string> {\r\n // Check for custom entry points\r\n const detection = detectCustomEntries(root, config);\r\n \r\n if (!detection.useVirtualServer && detection.customServerPath) {\r\n return detection.customServerPath;\r\n }\r\n\r\n // Use virtual server entry - we need to write a temp file for the build\r\n // because Rollup input must be a real file path\r\n const virtualServerCode = generateServerEntry(config);\r\n const tempServerPath = path.join(root, '.ssg-temp-entry-server.tsx');\r\n fsSync.writeFileSync(tempServerPath, virtualServerCode, 'utf-8');\r\n \r\n return tempServerPath;\r\n}\r\n\r\n/**\r\n * Get client entry point\r\n * Returns virtual module ID if no custom entry exists\r\n */\r\nasync function getClientEntryPoint(config: SSGConfig, root: string): Promise<string> {\r\n const detection = detectCustomEntries(root, config);\r\n \r\n if (!detection.useVirtualClient && detection.customClientPath) {\r\n return detection.customClientPath;\r\n }\r\n\r\n // Use virtual client entry - write a temp file\r\n const virtualClientCode = generateClientEntry(config, detection);\r\n const tempClientPath = path.join(root, '.ssg-temp-entry-client.tsx');\r\n fsSync.writeFileSync(tempClientPath, virtualClientCode, 'utf-8');\r\n \r\n return tempClientPath;\r\n}\r\n\r\n/**\r\n * Clean up temporary entry files\r\n */\r\nasync function cleanupTempEntries(root: string): Promise<void> {\r\n const tempFiles = [\r\n path.join(root, '.ssg-temp-entry-server.tsx'),\r\n path.join(root, '.ssg-temp-entry-client.tsx'),\r\n ];\r\n \r\n for (const file of tempFiles) {\r\n try {\r\n await fs.unlink(file);\r\n } catch {\r\n // Ignore if file doesn't exist\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Get or generate HTML template\r\n */\r\nasync function getHtmlTemplate(config: SSGConfig, root: string, clientEntryPath: string): Promise<string> {\r\n const detection = detectCustomEntries(root, config);\r\n \r\n if (!detection.useVirtualHtml && detection.customHtmlPath) {\r\n // Read custom HTML and update the script src to point to the temp entry file\r\n let html = await fs.readFile(detection.customHtmlPath, 'utf-8');\r\n // Replace any virtual SSG client paths with the actual temp entry path\r\n // Use relative path from root for the script src\r\n const relativePath = './' + path.relative(root, clientEntryPath).replace(/\\\\/g, '/');\r\n html = html.replace(\r\n /<script([^>]*)\\s+src=[\"']?\\/@ssg\\/client\\.tsx[\"']?/g,\r\n `<script$1 src=\"${relativePath}\"`\r\n );\r\n return html;\r\n }\r\n\r\n // Generate virtual HTML template\r\n return generateProductionHtmlTemplate(config, clientEntryPath);\r\n}\r\n\r\n/**\r\n * Format bytes to human-readable string\r\n */\r\nfunction formatBytes(bytes: number): string {\r\n if (bytes < 1024) return `${bytes}B`;\r\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)}KB`;\r\n return `${(bytes / (1024 * 1024)).toFixed(1)}MB`;\r\n}\r\n\r\n/**\r\n * Escape HTML special characters\r\n */\r\nfunction escapeHtml(str: string): string {\r\n return str\r\n .replace(/&/g, '&amp;')\r\n .replace(/</g, '&lt;')\r\n .replace(/>/g, '&gt;')\r\n .replace(/\"/g, '&quot;')\r\n .replace(/'/g, '&#39;');\r\n}\r\n", "/**\r\n * SSG Configuration helper\r\n */\r\n\r\nimport path from 'node:path';\r\nimport type { SSGConfig } from './types';\r\n\r\n/**\r\n * Define SSG configuration with type safety\r\n *\r\n * @example\r\n * ```ts\r\n * // ssg.config.ts\r\n * import { defineSSGConfig } from '@sigx/ssg';\r\n *\r\n * export default defineSSGConfig({\r\n * pages: 'src/pages',\r\n * layouts: 'src/layouts',\r\n * theme: '@sigx/ssg-theme-daisyui',\r\n * site: {\r\n * title: 'My Site',\r\n * description: 'A SignalX-powered static site'\r\n * }\r\n * });\r\n * ```\r\n */\r\nexport function defineSSGConfig(config: SSGConfig): SSGConfig {\r\n return {\r\n // Defaults\r\n pages: 'src/pages',\r\n layouts: 'src/layouts',\r\n content: 'src/content',\r\n defaultLayout: 'default',\r\n outDir: 'dist',\r\n base: '/',\r\n // Zero-config defaults\r\n autoEntries: true,\r\n prefetch: true,\r\n // User overrides\r\n ...config,\r\n // Merge nested objects\r\n site: {\r\n lang: 'en',\r\n ...config.site,\r\n },\r\n markdown: {\r\n shiki: true,\r\n ...config.markdown,\r\n },\r\n toc: {\r\n minLevel: 2,\r\n maxLevel: 3,\r\n ...config.toc,\r\n },\r\n };\r\n}\r\n\r\n/**\r\n * Load SSG config from file\r\n */\r\nexport async function loadConfig(configPath?: string): Promise<SSGConfig> {\r\n const fsPath = await import('node:path');\r\n const fs = await import('node:fs');\r\n const { pathToFileURL } = await import('node:url');\r\n const os = await import('node:os');\r\n\r\n // Find config file\r\n const cwd = process.cwd();\r\n const possiblePaths = configPath\r\n ? [fsPath.resolve(cwd, configPath)]\r\n : [\r\n fsPath.resolve(cwd, 'ssg.config.ts'),\r\n fsPath.resolve(cwd, 'ssg.config.js'),\r\n fsPath.resolve(cwd, 'ssg.config.mjs'),\r\n ];\r\n\r\n let foundPath: string | null = null;\r\n for (const p of possiblePaths) {\r\n if (fs.existsSync(p)) {\r\n foundPath = p;\r\n break;\r\n }\r\n }\r\n\r\n if (!foundPath) {\r\n console.warn('No ssg.config found, using defaults');\r\n return defineSSGConfig({});\r\n }\r\n\r\n try {\r\n // For TypeScript files, use esbuild to compile them first\r\n if (foundPath.endsWith('.ts')) {\r\n const esbuild = await import('esbuild');\r\n const tempDir = os.tmpdir();\r\n const tempFile = fsPath.join(tempDir, `ssg-config-${Date.now()}.mjs`);\r\n \r\n // Read and transform the TypeScript file\r\n const source = fs.readFileSync(foundPath, 'utf-8');\r\n \r\n // Transform: remove the import and defineSSGConfig wrapper\r\n // The config file typically does: export default defineSSGConfig({ ... })\r\n // We just need the config object, so we can transform it\r\n const result = await esbuild.transform(source, {\r\n loader: 'ts',\r\n format: 'esm',\r\n });\r\n \r\n // Write the transformed code to a temp file in the same directory as the config\r\n // This ensures relative imports and package resolution work correctly\r\n const configDir = fsPath.dirname(foundPath);\r\n const localTempFile = fsPath.join(configDir, `.ssg-config-temp-${Date.now()}.mjs`);\r\n \r\n fs.writeFileSync(localTempFile, result.code);\r\n \r\n try {\r\n const configModule = await import(pathToFileURL(localTempFile).href);\r\n return defineSSGConfig(configModule.default || configModule);\r\n } finally {\r\n // Clean up temp file\r\n try {\r\n fs.unlinkSync(localTempFile);\r\n } catch {\r\n // Ignore cleanup errors\r\n }\r\n }\r\n }\r\n \r\n // For JS files, import directly\r\n const configModule = await import(pathToFileURL(foundPath).href);\r\n return defineSSGConfig(configModule.default || configModule);\r\n } catch (err) {\r\n console.error(`Failed to load config from ${foundPath}:`, err);\r\n return defineSSGConfig({});\r\n }\r\n}\r\n\r\n/**\r\n * Resolve paths in config to absolute paths\r\n */\r\nexport function resolveConfigPaths(config: SSGConfig, root: string): SSGConfig {\r\n return {\r\n ...config,\r\n pages: path.resolve(root, config.pages || 'src/pages'),\r\n layouts: path.resolve(root, config.layouts || 'src/layouts'),\r\n content: path.resolve(root, config.content || 'src/content'),\r\n outDir: path.resolve(root, config.outDir || 'dist'),\r\n };\r\n}\r\n", "/**\r\n * File-based route scanner\r\n *\r\n * Scans a pages directory and generates route definitions from file paths.\r\n * Supports dynamic routes with [param] and catch-all with [...slug] patterns.\r\n */\r\n\r\nimport fg from 'fast-glob';\r\nimport path from 'node:path';\r\nimport fs from 'node:fs';\r\nimport type { SSGRoute, SSGConfig, PageMeta } from '../types';\r\nimport { parseFrontmatter } from '../mdx/frontmatter';\r\n\r\n/**\r\n * File extensions to treat as pages\r\n */\r\nconst PAGE_EXTENSIONS = ['.tsx', '.jsx', '.mdx', '.md'];\r\n\r\n/**\r\n * Files/directories to exclude from routing\r\n * \r\n * Only exclude common non-page folders at the ROOT of pages directory.\r\n * Nested folders like /docs/components/ are valid routes.\r\n */\r\nconst EXCLUDED_PATTERNS = [\r\n 'components/**', // Root-level components folder only\r\n 'hooks/**', // Root-level hooks folder only\r\n 'utils/**', // Root-level utils folder only\r\n 'lib/**', // Root-level lib folder only\r\n '**/_*', // Files/folders starting with underscore (at any level)\r\n '**/*.test.*',\r\n '**/*.spec.*',\r\n];\r\n\r\n/**\r\n * Scan pages directory and generate routes\r\n */\r\nexport async function scanPages(config: SSGConfig, root: string): Promise<SSGRoute[]> {\r\n const pagesDir = path.resolve(root, config.pages || 'src/pages');\r\n\r\n // Find all page files\r\n const patterns = PAGE_EXTENSIONS.map(ext => `**/*${ext}`);\r\n const files = await fg(patterns, {\r\n cwd: pagesDir,\r\n ignore: EXCLUDED_PATTERNS,\r\n onlyFiles: true,\r\n absolute: false,\r\n });\r\n\r\n // Convert files to routes (with frontmatter extraction)\r\n const routes: SSGRoute[] = [];\r\n\r\n for (const file of files) {\r\n const route = await fileToRouteWithMeta(file, pagesDir);\r\n if (route) {\r\n routes.push(route);\r\n }\r\n }\r\n\r\n // Sort routes by specificity (static > dynamic > catch-all)\r\n return sortRoutes(routes);\r\n}\r\n\r\n/**\r\n * Convert a file path to a route definition with frontmatter metadata\r\n */\r\nasync function fileToRouteWithMeta(filePath: string, pagesDir: string): Promise<SSGRoute | null> {\r\n const route = fileToRoute(filePath, pagesDir);\r\n if (!route) return null;\r\n\r\n // Extract frontmatter from MDX/MD files\r\n const ext = path.extname(filePath).toLowerCase();\r\n if (ext === '.mdx' || ext === '.md') {\r\n try {\r\n const content = fs.readFileSync(route.file, 'utf-8');\r\n const { data } = parseFrontmatter(content);\r\n route.meta = data;\r\n } catch (err) {\r\n // Ignore read errors - frontmatter just won't be available\r\n }\r\n }\r\n\r\n return route;\r\n}\r\n\r\n/**\r\n * Convert a file path to a route definition\r\n */\r\nexport function fileToRoute(filePath: string, pagesDir: string): SSGRoute | null {\r\n // Remove extension\r\n const ext = path.extname(filePath);\r\n let routePath = filePath.slice(0, -ext.length);\r\n\r\n // Handle index files\r\n if (routePath.endsWith('/index') || routePath === 'index') {\r\n routePath = routePath.replace(/\\/?index$/, '') || '/';\r\n }\r\n\r\n // Convert file path to URL path\r\n routePath = filePathToRoutePath(routePath);\r\n\r\n // Generate route name from path\r\n const name = pathToRouteName(routePath);\r\n\r\n return {\r\n path: routePath.startsWith('/') ? routePath : `/${routePath}`,\r\n file: path.join(pagesDir, filePath),\r\n name,\r\n };\r\n}\r\n\r\n/**\r\n * Convert file path patterns to route path patterns\r\n *\r\n * Examples:\r\n * blog/[slug] -> /blog/:slug\r\n * docs/[...path] -> /docs/*path\r\n * users/[id]/posts -> /users/:id/posts\r\n */\r\nexport function filePathToRoutePath(filePath: string): string {\r\n return filePath\r\n .split('/')\r\n .map(segment => {\r\n // Catch-all: [...slug] -> *slug\r\n if (segment.startsWith('[...') && segment.endsWith(']')) {\r\n const param = segment.slice(4, -1);\r\n return `*${param}`;\r\n }\r\n\r\n // Optional catch-all: [[...slug]] -> *slug (same behavior)\r\n if (segment.startsWith('[[...') && segment.endsWith(']]')) {\r\n const param = segment.slice(5, -2);\r\n return `*${param}`;\r\n }\r\n\r\n // Dynamic segment: [id] -> :id\r\n if (segment.startsWith('[') && segment.endsWith(']')) {\r\n const param = segment.slice(1, -1);\r\n return `:${param}`;\r\n }\r\n\r\n // Optional segment: [[id]] -> :id?\r\n if (segment.startsWith('[[') && segment.endsWith(']]')) {\r\n const param = segment.slice(2, -2);\r\n return `:${param}?`;\r\n }\r\n\r\n return segment;\r\n })\r\n .join('/');\r\n}\r\n\r\n/**\r\n * Convert route path to a route name\r\n *\r\n * Examples:\r\n * / -> index\r\n * /about -> about\r\n * /blog/:slug -> blog-slug\r\n * /docs/*path -> docs-path\r\n */\r\nexport function pathToRouteName(routePath: string): string {\r\n if (routePath === '/' || routePath === '') {\r\n return 'index';\r\n }\r\n\r\n return routePath\r\n .replace(/^\\//, '') // Remove leading slash\r\n .replace(/\\//g, '-') // Replace slashes with dashes\r\n .replace(/:/g, '') // Remove param colons\r\n .replace(/\\*/g, '') // Remove wildcards\r\n .replace(/\\?/g, '') // Remove optional markers\r\n .replace(/-+/g, '-') // Collapse multiple dashes\r\n .replace(/-$/, ''); // Remove trailing dash\r\n}\r\n\r\n/**\r\n * Sort routes by specificity\r\n *\r\n * Order:\r\n * 1. Static routes (most specific)\r\n * 2. Dynamic param routes\r\n * 3. Catch-all routes (least specific)\r\n *\r\n * Within each category, longer paths come first\r\n */\r\nexport function sortRoutes(routes: SSGRoute[]): SSGRoute[] {\r\n return routes.sort((a, b) => {\r\n const scoreA = getRouteScore(a.path);\r\n const scoreB = getRouteScore(b.path);\r\n\r\n // Higher score = more specific = should come first\r\n if (scoreA !== scoreB) {\r\n return scoreB - scoreA;\r\n }\r\n\r\n // Same score: longer paths first\r\n return b.path.length - a.path.length;\r\n });\r\n}\r\n\r\n/**\r\n * Calculate specificity score for a route\r\n */\r\nfunction getRouteScore(routePath: string): number {\r\n const segments = routePath.split('/').filter(Boolean);\r\n let score = 0;\r\n\r\n for (const segment of segments) {\r\n if (segment.startsWith('*')) {\r\n // Catch-all: lowest priority\r\n score += 1;\r\n } else if (segment.startsWith(':')) {\r\n // Dynamic param: medium priority\r\n score += 10;\r\n } else {\r\n // Static segment: highest priority\r\n score += 100;\r\n }\r\n }\r\n\r\n return score;\r\n}\r\n\r\n/**\r\n * Check if a route has dynamic segments\r\n */\r\nexport function isDynamicRoute(route: SSGRoute): boolean {\r\n return route.path.includes(':') || route.path.includes('*');\r\n}\r\n\r\n/**\r\n * Extract parameter names from a route path\r\n */\r\nexport function extractParams(routePath: string): string[] {\r\n const params: string[] = [];\r\n const segments = routePath.split('/');\r\n\r\n for (const segment of segments) {\r\n if (segment.startsWith(':')) {\r\n params.push(segment.slice(1).replace('?', ''));\r\n } else if (segment.startsWith('*')) {\r\n params.push(segment.slice(1));\r\n }\r\n }\r\n\r\n return params;\r\n}\r\n\r\n/**\r\n * Generate all static paths for a route using getStaticPaths\r\n */\r\nexport function expandDynamicRoute(\r\n route: SSGRoute,\r\n staticPaths: Array<{ params: Record<string, string> }>\r\n): string[] {\r\n const paths: string[] = [];\r\n\r\n for (const { params } of staticPaths) {\r\n let expandedPath = route.path;\r\n\r\n for (const [key, value] of Object.entries(params)) {\r\n // Replace :param with value\r\n expandedPath = expandedPath.replace(`:${key}`, value);\r\n // Replace *param with value\r\n expandedPath = expandedPath.replace(`*${key}`, value);\r\n }\r\n\r\n paths.push(expandedPath);\r\n }\r\n\r\n return paths;\r\n}\r\n", "/**\r\n * Frontmatter parser\r\n *\r\n * Extracts and parses YAML frontmatter from Markdown/MDX files.\r\n */\r\n\r\nimport matter from 'gray-matter';\r\nimport type { PageMeta } from '../types';\r\n\r\n/**\r\n * Result of parsing frontmatter\r\n */\r\nexport interface FrontmatterResult {\r\n /**\r\n * Parsed frontmatter data\r\n */\r\n data: PageMeta;\r\n\r\n /**\r\n * Content body without frontmatter\r\n */\r\n content: string;\r\n\r\n /**\r\n * Raw frontmatter string\r\n */\r\n raw: string;\r\n\r\n /**\r\n * Whether frontmatter was present\r\n */\r\n hasFrontmatter: boolean;\r\n}\r\n\r\n/**\r\n * Parse frontmatter from content\r\n */\r\nexport function parseFrontmatter(source: string): FrontmatterResult {\r\n const { data, content, matter: raw } = matter(source);\r\n\r\n return {\r\n data: normalizeFrontmatter(data),\r\n content,\r\n raw: raw || '',\r\n hasFrontmatter: !!raw,\r\n };\r\n}\r\n\r\n/**\r\n * Normalize frontmatter data to PageMeta\r\n */\r\nfunction normalizeFrontmatter(data: Record<string, unknown>): PageMeta {\r\n const meta: PageMeta = {};\r\n\r\n // Standard fields\r\n if (typeof data.title === 'string') meta.title = data.title;\r\n if (typeof data.description === 'string') meta.description = data.description;\r\n if (typeof data.layout === 'string') meta.layout = data.layout;\r\n if (typeof data.draft === 'boolean') meta.draft = data.draft;\r\n\r\n // Date handling\r\n if (data.date) {\r\n if (data.date instanceof Date) {\r\n meta.date = data.date;\r\n } else if (typeof data.date === 'string') {\r\n meta.date = new Date(data.date);\r\n }\r\n }\r\n\r\n // Tags\r\n if (Array.isArray(data.tags)) {\r\n meta.tags = data.tags.filter((t) => typeof t === 'string');\r\n }\r\n\r\n // SSR flag\r\n if (typeof data.ssr === 'boolean') meta.ssr = data.ssr;\r\n\r\n // Copy all other fields\r\n for (const [key, value] of Object.entries(data)) {\r\n if (!(key in meta)) {\r\n meta[key] = value;\r\n }\r\n }\r\n\r\n return meta;\r\n}\r\n\r\n/**\r\n * Extract title from markdown content if not in frontmatter\r\n *\r\n * Looks for the first H1 heading\r\n */\r\nexport function extractTitleFromContent(content: string): string | null {\r\n const h1Match = content.match(/^#\\s+(.+)$/m);\r\n return h1Match ? h1Match[1].trim() : null;\r\n}\r\n\r\n/**\r\n * Serialize frontmatter back to YAML string\r\n */\r\nexport function serializeFrontmatter(data: PageMeta): string {\r\n const lines: string[] = ['---'];\r\n\r\n for (const [key, value] of Object.entries(data)) {\r\n if (value === undefined) continue;\r\n\r\n if (value instanceof Date) {\r\n lines.push(`${key}: ${value.toISOString().split('T')[0]}`);\r\n } else if (Array.isArray(value)) {\r\n lines.push(`${key}:`);\r\n for (const item of value) {\r\n lines.push(` - ${JSON.stringify(item)}`);\r\n }\r\n } else if (typeof value === 'object' && value !== null) {\r\n lines.push(`${key}: ${JSON.stringify(value)}`);\r\n } else {\r\n lines.push(`${key}: ${JSON.stringify(value)}`);\r\n }\r\n }\r\n\r\n lines.push('---');\r\n return lines.join('\\n');\r\n}\r\n", "/**\r\n * Virtual module generator for routes\r\n *\r\n * Generates the virtual:ssg-routes module that exports all routes\r\n * for use by the router.\r\n */\r\n\r\nimport type { SSGRoute, SSGConfig } from '../types';\r\nimport { scanPages } from './scanner';\r\n\r\n/**\r\n * Virtual module ID for SSG routes\r\n */\r\nexport const VIRTUAL_ROUTES_ID = 'virtual:ssg-routes';\r\nexport const RESOLVED_VIRTUAL_ROUTES_ID = '\\0' + VIRTUAL_ROUTES_ID;\r\n\r\n/**\r\n * Normalize file path to use forward slashes (for ES module imports)\r\n */\r\nfunction normalizePath(filePath: string): string {\r\n return filePath.replace(/\\\\/g, '/');\r\n}\r\n\r\n/**\r\n * Generate the virtual routes module code\r\n */\r\nexport function generateRoutesModule(routes: SSGRoute[], config: SSGConfig): string {\r\n const imports: string[] = [];\r\n const routeDefinitions: string[] = [];\r\n\r\n for (let i = 0; i < routes.length; i++) {\r\n const route = routes[i];\r\n const componentName = `Page${i}`;\r\n const metaName = `meta${i}`;\r\n const normalizedFile = normalizePath(route.file);\r\n\r\n // Import the full module to access both default export and named exports\r\n imports.push(`import * as ${componentName}Module from '${normalizedFile}';`);\r\n\r\n // Build meta from module exports with safe access (avoid Rollup warnings)\r\n // For TSX pages, meta is a named export\r\n // For MDX pages, frontmatter might be attached to the default export\r\n // Also include headings for table of contents (exported by MDX plugin)\r\n imports.push(\r\n `const ${metaName} = { ...('meta' in ${componentName}Module ? ${componentName}Module.meta : ${componentName}Module.default?.frontmatter || ${JSON.stringify(route.meta || {})}), headings: 'headings' in ${componentName}Module ? ${componentName}Module.headings : [] };`\r\n );\r\n imports.push(\r\n `const ${componentName} = ${componentName}Module.default || ${componentName}Module;`\r\n );\r\n\r\n routeDefinitions.push(`\r\n {\r\n path: '${route.path}',\r\n name: '${route.name}',\r\n file: '${normalizedFile}',\r\n component: ${componentName},\r\n meta: ${metaName},\r\n layout: ${metaName}.layout || '${config.defaultLayout || 'default'}',\r\n }`);\r\n }\r\n\r\n return `\r\n${imports.join('\\n')}\r\n\r\nconst routes = [${routeDefinitions.join(',')}\r\n];\r\n\r\nexport default routes;\r\n`;\r\n}\r\n\r\n/**\r\n * Generate lazy-loading routes module (for development with HMR)\r\n */\r\nexport function generateLazyRoutesModule(routes: SSGRoute[], config: SSGConfig): string {\r\n const imports: string[] = [];\r\n const routeDefinitions: string[] = [];\r\n\r\n for (let i = 0; i < routes.length; i++) {\r\n const route = routes[i];\r\n const componentName = `Page${i}`;\r\n const metaName = `meta${i}`;\r\n const normalizedFile = normalizePath(route.file);\r\n\r\n // Import the module to read meta/frontmatter for layout resolution\r\n imports.push(`import * as ${componentName}Module from '${normalizedFile}';`);\r\n // Build meta with safe access to avoid Rollup warnings about missing exports\r\n imports.push(\r\n `const ${metaName} = { ...('meta' in ${componentName}Module ? ${componentName}Module.meta : ${componentName}Module.default?.frontmatter || ${JSON.stringify(route.meta || {})}), headings: 'headings' in ${componentName}Module ? ${componentName}Module.headings : [] };`\r\n );\r\n\r\n routeDefinitions.push(`\r\n {\r\n path: '${route.path}',\r\n name: '${route.name}',\r\n file: '${normalizedFile}',\r\n component: () => import('${normalizedFile}'),\r\n meta: ${metaName},\r\n layout: ${metaName}.layout || '${config.defaultLayout || 'default'}',\r\n }`);\r\n }\r\n\r\n return `\r\n${imports.join('\\n')}\r\n\r\nconst routes = [${routeDefinitions.join(',')}\r\n];\r\n\r\nexport default routes;\r\n`;\r\n}\r\n\r\n/**\r\n * Create a module loader for routes\r\n */\r\nexport async function loadRoutesModule(\r\n config: SSGConfig,\r\n root: string\r\n): Promise<{ routes: SSGRoute[]; code: string }> {\r\n const routes = await scanPages(config, root);\r\n const code = generateRoutesModule(routes, config);\r\n\r\n return { routes, code };\r\n}\r\n", "/**\r\n * Navigation generator for SSG\r\n *\r\n * Generates navigation structure from scanned routes based on\r\n * page frontmatter (category, order) or explicit configuration.\r\n */\r\n\r\nimport type { SSGRoute, SSGConfig, NavSection, NavItem, PageMeta, CollectionConfig } from '../types';\r\n\r\n/**\r\n * Collection navigation result\r\n */\r\nexport interface CollectionNavigation {\r\n sidebar: NavSection[];\r\n}\r\n\r\n/**\r\n * Internal type for building navigation tree\r\n */\r\ninterface NavBuildContext {\r\n categories: Map<string, NavBuildCategory>;\r\n uncategorized: NavBuildItem[];\r\n}\r\n\r\ninterface NavBuildCategory {\r\n title: string;\r\n order: number | undefined;\r\n items: NavBuildItem[];\r\n children: Map<string, NavBuildCategory>;\r\n}\r\n\r\ninterface NavBuildItem {\r\n title: string;\r\n href: string;\r\n order: number;\r\n}\r\n\r\n/**\r\n * Generate navigation structure from routes for a specific collection path\r\n *\r\n * @param routes - Scanned SSG routes\r\n * @param collectionPath - Path prefix for the collection (e.g., '/docs')\r\n * @param showDrafts - Whether to show draft pages\r\n * @param isDev - Whether running in development mode\r\n */\r\nexport function generateNavigation(\r\n routes: SSGRoute[],\r\n collectionPath: string,\r\n showDrafts: 'dev' | 'never',\r\n isDev: boolean\r\n): CollectionNavigation {\r\n // Filter routes for navigation\r\n const navRoutes = routes.filter((route) => {\r\n // Must be under collection path\r\n if (!route.path.startsWith(collectionPath)) {\r\n return false;\r\n }\r\n\r\n const meta = route.meta || {};\r\n\r\n // Check sidebar flag (default true)\r\n if (meta.sidebar === false) {\r\n return false;\r\n }\r\n\r\n // Handle draft pages\r\n if (meta.draft) {\r\n if (showDrafts === 'never') {\r\n return false;\r\n }\r\n if (showDrafts === 'dev' && !isDev) {\r\n return false;\r\n }\r\n }\r\n\r\n return true;\r\n });\r\n\r\n // Build navigation structure\r\n const context: NavBuildContext = {\r\n categories: new Map(),\r\n uncategorized: [],\r\n };\r\n\r\n for (const route of navRoutes) {\r\n const meta = route.meta || {};\r\n const title = meta.title || routeToTitle(route.path);\r\n const order = typeof meta.order === 'number' ? meta.order : 999;\r\n const category = meta.category;\r\n\r\n const item: NavBuildItem = {\r\n title,\r\n href: route.path,\r\n order,\r\n };\r\n\r\n if (!category) {\r\n // No category - add to uncategorized\r\n context.uncategorized.push(item);\r\n } else if (typeof category === 'string') {\r\n // Single category\r\n addToCategory(context.categories, [category], item);\r\n } else if (Array.isArray(category)) {\r\n // Nested categories\r\n addToCategory(context.categories, category, item);\r\n }\r\n }\r\n\r\n // Convert to NavSection array\r\n const sidebar = buildSections(context);\r\n\r\n return { sidebar };\r\n}\r\n\r\n/**\r\n * Add an item to a nested category structure\r\n */\r\nfunction addToCategory(\r\n categories: Map<string, NavBuildCategory>,\r\n path: string[],\r\n item: NavBuildItem\r\n): void {\r\n if (path.length === 0) {\r\n return;\r\n }\r\n\r\n const [first, ...rest] = path;\r\n\r\n let category = categories.get(first);\r\n if (!category) {\r\n category = {\r\n title: first,\r\n order: undefined,\r\n items: [],\r\n children: new Map(),\r\n };\r\n categories.set(first, category);\r\n }\r\n\r\n if (rest.length === 0) {\r\n // This is the target category\r\n category.items.push(item);\r\n } else {\r\n // Recurse into children\r\n addToCategory(category.children, rest, item);\r\n }\r\n}\r\n\r\n/**\r\n * Common section ordering for navigation\r\n * Used for both top-level sections and nested categories\r\n */\r\nconst SECTION_ORDER: Record<string, number> = {\r\n 'Getting Started': 10,\r\n 'Core Concepts': 20,\r\n 'Core': 20,\r\n 'Built-in Components': 30,\r\n 'Components': 30,\r\n 'Guides': 40,\r\n 'Advanced': 50,\r\n 'Ecosystem': 60,\r\n 'API Reference': 70,\r\n 'API': 70,\r\n 'Reference': 80,\r\n // DaisyUI component categories (matching DaisyUI website)\r\n 'Actions': 100,\r\n 'Data Display': 110,\r\n 'Navigation': 120,\r\n 'Feedback': 130,\r\n 'Data Input': 140,\r\n 'Layout': 150,\r\n 'Mockup': 160,\r\n 'Other': 999,\r\n};\r\n\r\n/**\r\n * Get sort order for a section/category title\r\n */\r\nfunction getSectionOrder(title: string, explicitOrder?: number): number {\r\n if (explicitOrder !== undefined) {\r\n return explicitOrder;\r\n }\r\n return SECTION_ORDER[title] ?? 50;\r\n}\r\n\r\n/**\r\n * Build NavSection array from context\r\n */\r\nfunction buildSections(context: NavBuildContext): NavSection[] {\r\n const sections: NavSection[] = [];\r\n\r\n // Add categorized items\r\n for (const [, category] of context.categories) {\r\n sections.push(buildSection(category));\r\n }\r\n\r\n // Add uncategorized items as a section if any exist\r\n if (context.uncategorized.length > 0) {\r\n sections.push({\r\n title: 'Other',\r\n items: context.uncategorized\r\n .sort((a, b) => a.order - b.order || a.title.localeCompare(b.title))\r\n .map((item) => ({\r\n title: item.title,\r\n href: item.href,\r\n order: item.order,\r\n })),\r\n order: 999,\r\n });\r\n }\r\n\r\n sections.sort((a, b) => {\r\n const orderA = getSectionOrder(a.title, a.order);\r\n const orderB = getSectionOrder(b.title, b.order);\r\n return orderA - orderB;\r\n });\r\n\r\n return sections;\r\n}\r\n\r\n/**\r\n * Build a NavSection from a category\r\n */\r\nfunction buildSection(category: NavBuildCategory): NavSection {\r\n // Sort items\r\n const sortedItems = category.items\r\n .sort((a, b) => a.order - b.order || a.title.localeCompare(b.title))\r\n .map((item) => ({\r\n title: item.title,\r\n href: item.href,\r\n order: item.order,\r\n }));\r\n\r\n // Build nested children\r\n const childSections: NavItem[] = [];\r\n for (const [, child] of category.children) {\r\n childSections.push(buildNestedSection(child));\r\n }\r\n\r\n // Merge items and child sections\r\n const items: NavItem[] = [...sortedItems];\r\n\r\n // Add nested sections as groups, sorted by section order\r\n for (const nested of childSections.sort((a, b) => {\r\n const orderA = getSectionOrder(a.title, a.order);\r\n const orderB = getSectionOrder(b.title, b.order);\r\n return orderA - orderB;\r\n })) {\r\n items.push(nested);\r\n }\r\n\r\n return {\r\n title: category.title,\r\n items,\r\n order: category.order,\r\n };\r\n}\r\n\r\n/**\r\n * Build a nested NavItem from a child category\r\n */\r\nfunction buildNestedSection(category: NavBuildCategory): NavItem {\r\n const sortedItems = category.items\r\n .sort((a, b) => a.order - b.order || a.title.localeCompare(b.title))\r\n .map((item) => ({\r\n title: item.title,\r\n href: item.href,\r\n order: item.order,\r\n }));\r\n\r\n // Recursively build children\r\n const childItems: NavItem[] = [];\r\n for (const [, child] of category.children) {\r\n childItems.push(buildNestedSection(child));\r\n }\r\n\r\n return {\r\n title: category.title,\r\n items: [...sortedItems, ...childItems.sort((a, b) => (a.order ?? 0) - (b.order ?? 0))],\r\n order: category.order,\r\n };\r\n}\r\n\r\n/**\r\n * Convert route path to a display title\r\n *\r\n * @example '/docs/getting-started' -> 'Getting Started'\r\n * @example '/docs/api/router' -> 'Router'\r\n */\r\nfunction routeToTitle(routePath: string): string {\r\n const segments = routePath.split('/').filter(Boolean);\r\n const lastSegment = segments[segments.length - 1] || 'Home';\r\n\r\n return lastSegment\r\n .replace(/-/g, ' ')\r\n .replace(/\\b\\w/g, (c) => c.toUpperCase());\r\n}\r\n\r\n/**\r\n * Merge explicit sidebar config with auto-generated navigation\r\n */\r\nexport function mergeNavigation(\r\n autoGenerated: NavSection[],\r\n explicit: NavSection[]\r\n): NavSection[] {\r\n const merged = new Map<string, NavSection>();\r\n\r\n // Add auto-generated first\r\n for (const section of autoGenerated) {\r\n merged.set(section.title, section);\r\n }\r\n\r\n // Override/add explicit sections\r\n for (const section of explicit) {\r\n if (merged.has(section.title)) {\r\n // Merge items\r\n const existing = merged.get(section.title)!;\r\n merged.set(section.title, {\r\n ...existing,\r\n ...section,\r\n items: [...existing.items, ...section.items],\r\n });\r\n } else {\r\n merged.set(section.title, section);\r\n }\r\n }\r\n\r\n return Array.from(merged.values());\r\n}\r\n\r\n/**\r\n * Generate navigation for all collections\r\n *\r\n * @param routes - Scanned SSG routes\r\n * @param config - SSG configuration\r\n * @param isDev - Whether running in development mode\r\n * @returns Record mapping collection names to their navigation\r\n */\r\nexport function generateAllCollections(\r\n routes: SSGRoute[],\r\n config: SSGConfig,\r\n isDev: boolean\r\n): Record<string, CollectionNavigation> {\r\n const collections = config.collections || {};\r\n const result: Record<string, CollectionNavigation> = {};\r\n\r\n for (const [name, collectionConfig] of Object.entries(collections)) {\r\n const showDrafts = collectionConfig.showDrafts ?? config.navigation?.showDrafts ?? 'dev';\r\n result[name] = generateNavigation(routes, collectionConfig.path, showDrafts, isDev);\r\n }\r\n\r\n return result;\r\n}\r\n\r\n/**\r\n * Detect which collection a route path belongs to\r\n *\r\n * @param path - Current route path\r\n * @param collections - Collections configuration\r\n * @returns The collection name if found, undefined otherwise\r\n */\r\nexport function detectCollection(\r\n path: string,\r\n collections: Record<string, CollectionConfig>\r\n): string | undefined {\r\n // Sort by path length descending to match most specific path first\r\n const sorted = Object.entries(collections).sort(\r\n ([, a], [, b]) => b.path.length - a.path.length\r\n );\r\n\r\n for (const [name, config] of sorted) {\r\n if (path.startsWith(config.path)) {\r\n return name;\r\n }\r\n }\r\n\r\n return undefined;\r\n}\r\n", "/**\r\n * Virtual module generator for navigation\r\n *\r\n * Generates the virtual:ssg-navigation module that exports\r\n * the navigation structure for all collections.\r\n */\r\n\r\nimport type { SSGConfig, NavSection, NavItem, CollectionConfig } from '../types';\r\nimport type { SSGRoute } from '../types';\r\nimport { generateAllCollections, detectCollection as detectCollectionImpl, CollectionNavigation } from './navigation';\r\n\r\n/**\r\n * Virtual module ID for SSG navigation\r\n */\r\nexport const VIRTUAL_NAVIGATION_ID = 'virtual:ssg-navigation';\r\nexport const RESOLVED_VIRTUAL_NAVIGATION_ID = '\\0' + VIRTUAL_NAVIGATION_ID;\r\n\r\n/**\r\n * Navigation module result type\r\n */\r\nexport interface NavigationModule {\r\n /** Navigation keyed by collection name */\r\n navigation: Record<string, CollectionNavigation>;\r\n /** Collections configuration for path detection */\r\n collections: Record<string, CollectionConfig>;\r\n}\r\n\r\n/**\r\n * Generate the virtual navigation module code\r\n *\r\n * @param routes - Scanned SSG routes with metadata\r\n * @param config - SSG configuration\r\n * @param isDev - Whether running in development mode\r\n */\r\nexport function generateNavigationModule(\r\n routes: SSGRoute[],\r\n config: SSGConfig,\r\n isDev: boolean\r\n): string {\r\n const navigation = generateAllCollections(routes, config, isDev);\r\n const collections = config.collections || {};\r\n\r\n // Serialize navigation and collections to JSON\r\n const navJson = JSON.stringify(navigation, null, 2);\r\n const collectionsJson = JSON.stringify(collections, null, 2);\r\n\r\n return `\r\n/**\r\n * Auto-generated navigation module\r\n * \r\n * @generated by @sigx/ssg\r\n */\r\n\r\n/**\r\n * Navigation for all collections, keyed by collection name\r\n */\r\nexport const navigation = ${navJson};\r\n\r\n/**\r\n * Collections configuration\r\n */\r\nconst collections = ${collectionsJson};\r\n\r\n/**\r\n * Get navigation for a specific collection\r\n * @param name - Collection name (e.g., 'docs', 'examples')\r\n * @returns The collection's navigation or undefined if not found\r\n */\r\nexport function getCollectionNav(name) {\r\n return navigation[name];\r\n}\r\n\r\n/**\r\n * Detect which collection a route path belongs to\r\n * @param path - Current route path\r\n * @returns The collection name if found, undefined otherwise\r\n */\r\nexport function detectCollection(path) {\r\n // Sort by path length descending to match most specific path first\r\n const sorted = Object.entries(collections).sort(\r\n ([, a], [, b]) => b.path.length - a.path.length\r\n );\r\n\r\n for (const [name, config] of sorted) {\r\n if (path.startsWith(config.path)) {\r\n return name;\r\n }\r\n }\r\n\r\n return undefined;\r\n}\r\n\r\n/**\r\n * Get sidebar for a specific collection\r\n * @param name - Collection name\r\n * @returns The sidebar array or empty array if not found\r\n */\r\nexport function getSidebar(name) {\r\n return navigation[name]?.sidebar || [];\r\n}\r\n\r\nexport default { navigation, collections, getCollectionNav, detectCollection, getSidebar };\r\n`;\r\n}\r\n\r\n/**\r\n * Create a loader for the navigation module\r\n */\r\nexport async function loadNavigationModule(\r\n routes: SSGRoute[],\r\n config: SSGConfig,\r\n isDev: boolean\r\n): Promise<{ navigation: Record<string, CollectionNavigation>; code: string }> {\r\n const navigation = generateAllCollections(routes, config, isDev);\r\n const code = generateNavigationModule(routes, config, isDev);\r\n return { navigation, code };\r\n}\r\n", "/**\r\n * Layout resolver\r\n *\r\n * Resolves layouts from local layouts directory or theme packages.\r\n * Layouts wrap page content and provide consistent structure.\r\n */\r\n\r\nimport fg from 'fast-glob';\r\nimport path from 'node:path';\r\nimport fs from 'node:fs';\r\nimport type { SSGConfig, LayoutModule, ThemeModule } from '../types';\r\n\r\n/**\r\n * Discovered layout information\r\n */\r\nexport interface LayoutInfo {\r\n /**\r\n * Layout name (e.g., 'default', 'docs', 'blog')\r\n */\r\n name: string;\r\n\r\n /**\r\n * Absolute file path to the layout component\r\n */\r\n file: string;\r\n\r\n /**\r\n * Source: 'local' or theme package name\r\n */\r\n source: string;\r\n}\r\n\r\n/**\r\n * Layout extensions to search for\r\n */\r\nconst LAYOUT_EXTENSIONS = ['.tsx', '.jsx'];\r\n\r\n/**\r\n * Scan local layouts directory\r\n */\r\nexport async function scanLocalLayouts(config: SSGConfig, root: string): Promise<LayoutInfo[]> {\r\n const layoutsDir = path.resolve(root, config.layouts || 'src/layouts');\r\n\r\n if (!fs.existsSync(layoutsDir)) {\r\n return [];\r\n }\r\n\r\n const patterns = LAYOUT_EXTENSIONS.map((ext) => `*${ext}`);\r\n const files = await fg(patterns, {\r\n cwd: layoutsDir,\r\n onlyFiles: true,\r\n absolute: false,\r\n });\r\n\r\n return files.map((file) => {\r\n const ext = path.extname(file);\r\n const name = file.slice(0, -ext.length);\r\n\r\n return {\r\n name,\r\n file: path.join(layoutsDir, file),\r\n source: 'local',\r\n };\r\n });\r\n}\r\n\r\n/**\r\n * Load layouts from a theme package\r\n */\r\nexport async function loadThemeLayouts(themeName: string, root: string): Promise<LayoutInfo[]> {\r\n try {\r\n // Import theme package from the project's context\r\n // Use createRequire to resolve from the project root\r\n const { createRequire } = await import('node:module');\r\n const { pathToFileURL } = await import('node:url');\r\n const require = createRequire(path.join(root, 'package.json'));\r\n \r\n // Resolve the theme package directory from the project\r\n // Use require.resolve with the package.json to get the package directory\r\n const themePackageJson = require.resolve(`${themeName}/package.json`);\r\n const themeDir = path.dirname(themePackageJson);\r\n \r\n // Read the package.json to find the main export\r\n const packageJson = JSON.parse(fs.readFileSync(themePackageJson, 'utf-8'));\r\n const mainFile = packageJson.exports?.['.']?.import || packageJson.main || './dist/index.js';\r\n const themePath = path.resolve(themeDir, mainFile);\r\n \r\n const themeModule = (await import(pathToFileURL(themePath).href)) as ThemeModule;\r\n\r\n if (!themeModule.layouts) {\r\n return [];\r\n }\r\n\r\n // Theme layouts are already loaded as components\r\n // We need to create virtual files for them\r\n return Object.keys(themeModule.layouts).map((name) => ({\r\n name,\r\n file: `${themeName}/layouts/${name}`,\r\n source: themeName,\r\n }));\r\n } catch (err) {\r\n console.warn(`Failed to load theme ${themeName}:`, err);\r\n return [];\r\n }\r\n}\r\n\r\n/**\r\n * Discover all available layouts\r\n *\r\n * Priority order:\r\n * 1. Local layouts (can override theme)\r\n * 2. Theme layouts\r\n */\r\nexport async function discoverLayouts(config: SSGConfig, root: string): Promise<LayoutInfo[]> {\r\n const layouts: Map<string, LayoutInfo> = new Map();\r\n\r\n // Load theme layouts first (can be overridden)\r\n if (config.theme) {\r\n const themeLayouts = await loadThemeLayouts(config.theme, root);\r\n for (const layout of themeLayouts) {\r\n layouts.set(layout.name, layout);\r\n }\r\n }\r\n\r\n // Load local layouts (override theme)\r\n const localLayouts = await scanLocalLayouts(config, root);\r\n for (const layout of localLayouts) {\r\n layouts.set(layout.name, layout);\r\n }\r\n\r\n return Array.from(layouts.values());\r\n}\r\n\r\n/**\r\n * Get the default layout\r\n */\r\nexport function getDefaultLayout(layouts: LayoutInfo[], config: SSGConfig): LayoutInfo | null {\r\n const defaultName = config.defaultLayout || 'default';\r\n return layouts.find((l) => l.name === defaultName) || layouts[0] || null;\r\n}\r\n\r\n/**\r\n * Find a layout by name\r\n */\r\nexport function findLayout(layouts: LayoutInfo[], name: string): LayoutInfo | null {\r\n return layouts.find((l) => l.name === name) || null;\r\n}\r\n", "/**\r\n * Virtual module generator for layouts\r\n *\r\n * Generates the virtual:generated-layouts module that provides\r\n * layout components and the setupLayouts function.\r\n * \r\n * IMPORTANT: Layouts are designed to persist across navigation.\r\n * Instead of wrapping each route with a layout component (which causes\r\n * full re-renders on navigation), we use a shared LayoutRouter component\r\n * that maintains the layout and only updates the page content reactively.\r\n */\r\n\r\nimport type { SSGConfig, SSGRoute } from '../types';\r\nimport type { LayoutInfo } from './resolver';\r\nimport { discoverLayouts } from './resolver';\r\n\r\n// Note: The generated virtual module imports component from sigx\r\n\r\n/**\r\n * Virtual module ID for generated layouts\r\n */\r\nexport const VIRTUAL_LAYOUTS_ID = 'virtual:generated-layouts';\r\nexport const RESOLVED_VIRTUAL_LAYOUTS_ID = '\\0virtual:generated-layouts';\r\n\r\n/**\r\n * Normalize file path to use forward slashes (for ES module imports)\r\n */\r\nfunction normalizePath(filePath: string): string {\r\n return filePath.replace(/\\\\/g, '/');\r\n}\r\n\r\n/**\r\n * Generate the virtual layouts module code\r\n */\r\nexport function generateLayoutsModule(layouts: LayoutInfo[], config: SSGConfig): string {\r\n const imports: string[] = [];\r\n const layoutEntries: string[] = [];\r\n\r\n for (let i = 0; i < layouts.length; i++) {\r\n const layout = layouts[i];\r\n const importName = `Layout${i}`;\r\n\r\n // Handle theme vs local layouts differently\r\n if (layout.source === 'local') {\r\n const normalizedFile = normalizePath(layout.file);\r\n imports.push(`import ${importName} from '${normalizedFile}';`);\r\n } else {\r\n // Theme layout - import from theme package\r\n imports.push(`import { layouts as themeLayouts${i} } from '${layout.source}';`);\r\n imports.push(`const ${importName} = themeLayouts${i}['${layout.name}'];`);\r\n }\r\n\r\n layoutEntries.push(` '${layout.name}': ${importName}.default || ${importName}`);\r\n }\r\n\r\n return `\r\nimport { component, signal, jsx } from 'sigx';\r\nimport { useRoute } from '@sigx/router';\r\n${imports.join('\\n')}\r\n\r\n/**\r\n * All available layouts\r\n */\r\nexport const layouts = {\r\n${layoutEntries.join(',\\n')}\r\n};\r\n\r\n/**\r\n * Default layout name\r\n */\r\nexport const defaultLayout = '${config.defaultLayout || 'default'}';\r\n\r\n/**\r\n * Check if a component is marked as lazy (created by lazy())\r\n */\r\nfunction isMarkedLazy(component) {\r\n return component && component.__lazy === true;\r\n}\r\n\r\n/**\r\n * Check if a value is a Promise/thenable\r\n */\r\nfunction isPromise(value) {\r\n return value && typeof value.then === 'function';\r\n}\r\n\r\n/**\r\n * Track hydration state - we're hydrating if the app container has SSR content\r\n */\r\nlet isHydrating = typeof window !== 'undefined' && \r\n document.getElementById('app')?.innerHTML?.trim().length > 0;\r\n\r\n// After first render, we're no longer hydrating\r\nif (typeof window !== 'undefined') {\r\n const markHydrationComplete = () => { isHydrating = false; };\r\n if ('requestIdleCallback' in window) {\r\n window.requestIdleCallback(markHydrationComplete);\r\n } else {\r\n setTimeout(markHydrationComplete, 0);\r\n }\r\n}\r\n\r\n/**\r\n * Placeholder component that preserves existing DOM during hydration.\r\n */\r\nconst HydrationPlaceholder = component(() => {\r\n return () => null;\r\n}, { name: 'HydrationPlaceholder' });\r\n\r\n/**\r\n * Layout router component that preserves layouts across navigation.\r\n * \r\n * This component renders the current route's layout and page content reactively.\r\n * When navigating between routes with the same layout, only the page content\r\n * updates - the layout (Navbar, Sidebar, Footer) persists without re-rendering.\r\n */\r\nexport const LayoutRouter = component((ctx) => {\r\n const route = useRoute();\r\n \r\n // Track loaded lazy components to avoid reloading\r\n const loadedComponents = {};\r\n \r\n // Track if this is the initial hydration render\r\n let initialRender = true;\r\n \r\n // HMR support: Listen for MDX updates and clear the component cache\r\n if (typeof window !== 'undefined' && import.meta.hot) {\r\n // Listen for sigx:mdx-hmr events dispatched by MDX files after they accept HMR\r\n const handleMdxHmr = (event) => {\r\n const { moduleId, newModule } = event.detail || {};\r\n \r\n // Clear all cached components to force reload with new module\r\n for (const key in loadedComponents) {\r\n delete loadedComponents[key];\r\n }\r\n \r\n // If we have the new module directly from HMR, cache it for the matching route\r\n if (newModule?.default) {\r\n const currentPath = route.path;\r\n loadedComponents[currentPath] = newModule.default;\r\n }\r\n \r\n // Force re-render\r\n ctx.update();\r\n };\r\n \r\n window.addEventListener('sigx:mdx-hmr', handleMdxHmr);\r\n \r\n ctx.onUnmounted(() => {\r\n window.removeEventListener('sigx:mdx-hmr', handleMdxHmr);\r\n });\r\n }\r\n \r\n return () => {\r\n const matched = route.matched;\r\n if (!matched || matched.length === 0) return null;\r\n \r\n const match = matched[0];\r\n if (!match) return null;\r\n \r\n // Get layout name from route meta or use default\r\n const layoutName = match.layout || match.meta?.layout || defaultLayout;\r\n const Layout = layouts[layoutName];\r\n \r\n if (!Layout) {\r\n console.warn(\\`Layout \"\\${layoutName}\" not found for route \\${route.path}\\`);\r\n return null;\r\n }\r\n \r\n // Get the original (unwrapped) component\r\n const rawComponent = match.originalComponent || match.component;\r\n const routePath = route.path;\r\n \r\n // Handle lazy/dynamic import components\r\n if (isMarkedLazy(rawComponent) || (typeof rawComponent === 'function' && !rawComponent.__setup)) {\r\n // Check if already loaded\r\n if (loadedComponents[routePath]) {\r\n const PageComponent = loadedComponents[routePath];\r\n initialRender = false;\r\n return jsx(Layout, { \r\n meta: match.meta, \r\n path: routePath, \r\n key: layoutName, // Key by layout to preserve layout across pages\r\n children: PageComponent({}) \r\n });\r\n }\r\n \r\n // Load the component\r\n const loadState = signal({ value: null, loading: true, error: null });\r\n \r\n try {\r\n const result = rawComponent();\r\n if (isPromise(result)) {\r\n result.then(module => {\r\n const Component = module.default || module;\r\n loadedComponents[routePath] = Component;\r\n loadState.value = Component;\r\n loadState.loading = false;\r\n }).catch(err => {\r\n console.error('Failed to load component for route:', routePath, err);\r\n loadState.error = err;\r\n loadState.loading = false;\r\n });\r\n } else {\r\n // Not a promise, use directly\r\n loadedComponents[routePath] = rawComponent;\r\n loadState.value = rawComponent;\r\n loadState.loading = false;\r\n }\r\n } catch (err) {\r\n loadState.error = err;\r\n loadState.loading = false;\r\n }\r\n \r\n // During hydration, preserve existing SSR content instead of showing loading state\r\n if (loadState.loading) {\r\n if (isHydrating && initialRender) {\r\n return jsx(Layout, { \r\n meta: match.meta, \r\n path: routePath, \r\n key: layoutName,\r\n children: jsx(HydrationPlaceholder, {})\r\n });\r\n }\r\n return jsx(Layout, { \r\n meta: match.meta, \r\n path: routePath, \r\n key: layoutName,\r\n children: null \r\n });\r\n }\r\n \r\n if (loadState.error || !loadState.value) {\r\n return jsx(Layout, { \r\n meta: match.meta, \r\n path: routePath, \r\n key: layoutName,\r\n children: null \r\n });\r\n }\r\n \r\n const PageComponent = loadState.value;\r\n initialRender = false;\r\n return jsx(Layout, { \r\n meta: match.meta, \r\n path: routePath, \r\n key: layoutName,\r\n children: PageComponent({}) \r\n });\r\n }\r\n \r\n // Eager component (has __setup)\r\n // Check cache first for HMR-updated components\r\n if (loadedComponents[routePath]) {\r\n const PageComponent = loadedComponents[routePath];\r\n initialRender = false;\r\n return jsx(Layout, { \r\n meta: match.meta, \r\n path: routePath, \r\n key: layoutName,\r\n children: PageComponent({}) \r\n });\r\n }\r\n \r\n initialRender = false;\r\n return jsx(Layout, { \r\n meta: match.meta, \r\n path: routePath, \r\n key: layoutName,\r\n children: rawComponent({}) \r\n });\r\n };\r\n}, { name: 'LayoutRouter' });\r\n\r\n/**\r\n * Setup layouts for routes\r\n *\r\n * This function now simply annotates routes with their layout information.\r\n * The actual layout wrapping is handled by LayoutRouter, which preserves\r\n * layouts across navigation.\r\n */\r\nexport function setupLayouts(routes) {\r\n const availableLayoutNames = Object.keys(layouts);\r\n \r\n return routes.map(route => {\r\n const layoutName = route.layout || route.meta?.layout || defaultLayout;\r\n const Layout = layouts[layoutName];\r\n\r\n if (!Layout) {\r\n console.error(\r\n \\`\u274C SSG103: Layout \"\\${layoutName}\" not found for route \\${route.path}\\\\n\\` +\r\n \\` \uD83D\uDCC1 \\${route.file || 'unknown'}\\\\n\\` +\r\n \\` \uD83D\uDCA1 Available layouts: \\${availableLayoutNames.join(', ') || 'none'}\\\\n\\` +\r\n \\` Create src/layouts/\\${layoutName}.tsx or set a valid layout in frontmatter.\\`\r\n );\r\n return route;\r\n }\r\n\r\n // Store layout info on the route, but don't wrap the component\r\n // LayoutRouter will handle layout rendering\r\n return {\r\n ...route,\r\n layout: layoutName,\r\n originalComponent: route.component,\r\n meta: {\r\n ...route.meta,\r\n layout: layoutName,\r\n },\r\n };\r\n });\r\n}\r\n\r\nexport default layouts;\r\n`;\r\n}\r\n\r\n/**\r\n * Generate a simpler layouts module for theme-only setups\r\n */\r\nexport function generateThemeLayoutsModule(themeName: string, config: SSGConfig): string {\r\n return `\r\nimport { component, signal, jsx } from 'sigx';\r\nimport { useRoute } from '@sigx/router';\r\nimport { layouts as themeLayouts, config as themeConfig } from '${themeName}';\r\n\r\nexport const layouts = themeLayouts || {};\r\nexport const defaultLayout = '${config.defaultLayout}' || themeConfig?.defaultLayout || 'default';\r\n\r\n/**\r\n * Check if a component is marked as lazy (created by lazy())\r\n */\r\nfunction isMarkedLazy(component) {\r\n return component && component.__lazy === true;\r\n}\r\n\r\n/**\r\n * Check if a value is a Promise/thenable\r\n */\r\nfunction isPromise(value) {\r\n return value && typeof value.then === 'function';\r\n}\r\n\r\n/**\r\n * Layout router component that preserves layouts across navigation.\r\n */\r\nexport const LayoutRouter = component((ctx) => {\r\n const route = useRoute();\r\n const loadedComponents = {};\r\n \r\n // HMR support: Listen for MDX updates and clear the component cache\r\n if (typeof window !== 'undefined' && import.meta.hot) {\r\n const handleMdxHmr = (event) => {\r\n for (const key in loadedComponents) {\r\n delete loadedComponents[key];\r\n }\r\n ctx.update();\r\n };\r\n \r\n window.addEventListener('sigx:mdx-hmr', handleMdxHmr);\r\n \r\n import.meta.hot.on('vite:beforeUpdate', (payload) => {\r\n const hasMdxUpdate = payload.updates?.some(update => \r\n update.path?.endsWith('.mdx') || update.path?.endsWith('.md')\r\n );\r\n if (hasMdxUpdate) {\r\n for (const key in loadedComponents) {\r\n delete loadedComponents[key];\r\n }\r\n }\r\n });\r\n \r\n ctx.onUnmounted(() => {\r\n window.removeEventListener('sigx:mdx-hmr', handleMdxHmr);\r\n });\r\n }\r\n \r\n return () => {\r\n const matched = route.matched;\r\n if (!matched || matched.length === 0) return null;\r\n \r\n const match = matched[0];\r\n if (!match) return null;\r\n \r\n const layoutName = match.layout || match.meta?.layout || defaultLayout;\r\n const Layout = layouts[layoutName];\r\n \r\n if (!Layout) {\r\n console.warn(\\`Layout \"\\${layoutName}\" not found for route \\${route.path}\\`);\r\n return null;\r\n }\r\n \r\n const rawComponent = match.originalComponent || match.component;\r\n const routePath = route.path;\r\n \r\n // Handle lazy/dynamic import components\r\n if (isMarkedLazy(rawComponent) || (typeof rawComponent === 'function' && !rawComponent.__setup)) {\r\n if (loadedComponents[routePath]) {\r\n const PageComponent = loadedComponents[routePath];\r\n return jsx(Layout, { \r\n meta: match.meta, \r\n path: routePath, \r\n key: layoutName,\r\n children: PageComponent({}) \r\n });\r\n }\r\n \r\n const loadState = signal({ value: null, loading: true, error: null });\r\n \r\n try {\r\n const result = rawComponent();\r\n if (isPromise(result)) {\r\n result.then(module => {\r\n const Component = module.default || module;\r\n loadedComponents[routePath] = Component;\r\n loadState.value = Component;\r\n loadState.loading = false;\r\n }).catch(err => {\r\n console.error('Failed to load component:', routePath, err);\r\n loadState.error = err;\r\n loadState.loading = false;\r\n });\r\n } else {\r\n loadedComponents[routePath] = rawComponent;\r\n loadState.value = rawComponent;\r\n loadState.loading = false;\r\n }\r\n } catch (err) {\r\n loadState.error = err;\r\n loadState.loading = false;\r\n }\r\n \r\n if (loadState.loading) {\r\n return jsx(Layout, { meta: match.meta, path: routePath, key: layoutName, children: null });\r\n }\r\n if (loadState.error || !loadState.value) {\r\n return jsx(Layout, { meta: match.meta, path: routePath, key: layoutName, children: null });\r\n }\r\n \r\n return jsx(Layout, { \r\n meta: match.meta, \r\n path: routePath, \r\n key: layoutName,\r\n children: loadState.value({}) \r\n });\r\n }\r\n \r\n return jsx(Layout, { \r\n meta: match.meta, \r\n path: routePath, \r\n key: layoutName,\r\n children: rawComponent({}) \r\n });\r\n };\r\n}, { name: 'LayoutRouter' });\r\n\r\nexport function setupLayouts(routes) {\r\n return routes.map(route => {\r\n const layoutName = route.layout || route.meta?.layout || defaultLayout;\r\n const Layout = layouts[layoutName];\r\n\r\n if (!Layout) {\r\n console.warn(\\`Layout \"\\${layoutName}\" not found for route \\${route.path}\\`);\r\n return route;\r\n }\r\n\r\n return {\r\n ...route,\r\n layout: layoutName,\r\n originalComponent: route.component,\r\n meta: {\r\n ...route.meta,\r\n layout: layoutName,\r\n },\r\n };\r\n });\r\n}\r\n\r\nexport default layouts;\r\n`;\r\n}\r\n\r\n/**\r\n * Load and generate the layouts module\r\n */\r\nexport async function loadLayoutsModule(\r\n config: SSGConfig,\r\n root: string\r\n): Promise<{ layouts: LayoutInfo[]; code: string }> {\r\n const layouts = await discoverLayouts(config, root);\r\n const code = generateLayoutsModule(layouts, config);\r\n\r\n return { layouts, code };\r\n}\r\n", "/**\r\n * Sitemap Generation\r\n *\r\n * Generates XML sitemaps for SSG sites following the sitemap protocol.\r\n * https://www.sitemaps.org/protocol.html\r\n */\r\n\r\nimport fs from 'node:fs/promises';\r\nimport path from 'node:path';\r\nimport type { SSGConfig, PageBuildResult } from './types';\r\n\r\n/**\r\n * Sitemap entry with optional metadata\r\n */\r\nexport interface SitemapEntry {\r\n /** URL path (relative to site base) */\r\n path: string;\r\n /** Last modification date */\r\n lastmod?: Date | string;\r\n /** Change frequency hint */\r\n changefreq?: 'always' | 'hourly' | 'daily' | 'weekly' | 'monthly' | 'yearly' | 'never';\r\n /** Priority relative to other pages (0.0 to 1.0) */\r\n priority?: number;\r\n}\r\n\r\n/**\r\n * Sitemap generation options\r\n */\r\nexport interface SitemapOptions {\r\n /** Include all built pages automatically */\r\n includePages?: boolean;\r\n /** Additional URLs to include */\r\n additionalUrls?: SitemapEntry[];\r\n /** URLs to exclude (glob patterns or exact matches) */\r\n exclude?: string[];\r\n /** Default change frequency */\r\n defaultChangefreq?: SitemapEntry['changefreq'];\r\n /** Default priority */\r\n defaultPriority?: number;\r\n}\r\n\r\n/**\r\n * Generate sitemap XML content\r\n */\r\nexport function generateSitemap(\r\n entries: SitemapEntry[],\r\n config: SSGConfig\r\n): string {\r\n const siteUrl = config.site?.url?.replace(/\\/$/, '') || '';\r\n const base = config.base?.replace(/\\/$/, '') || '';\r\n\r\n const urlEntries = entries.map((entry) => {\r\n const loc = `${siteUrl}${base}${entry.path}`;\r\n const lastmod = entry.lastmod\r\n ? typeof entry.lastmod === 'string'\r\n ? entry.lastmod\r\n : entry.lastmod.toISOString().split('T')[0]\r\n : undefined;\r\n\r\n return ` <url>\r\n <loc>${escapeXml(loc)}</loc>${lastmod ? `\r\n <lastmod>${lastmod}</lastmod>` : ''}${entry.changefreq ? `\r\n <changefreq>${entry.changefreq}</changefreq>` : ''}${entry.priority !== undefined ? `\r\n <priority>${entry.priority.toFixed(1)}</priority>` : ''}\r\n </url>`;\r\n });\r\n\r\n return `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">\r\n${urlEntries.join('\\n')}\r\n</urlset>`;\r\n}\r\n\r\n/**\r\n * Generate robots.txt content\r\n */\r\nexport function generateRobotsTxt(config: SSGConfig, sitemapPath = '/sitemap.xml'): string {\r\n const siteUrl = config.site?.url?.replace(/\\/$/, '') || '';\r\n const base = config.base?.replace(/\\/$/, '') || '';\r\n\r\n return `User-agent: *\r\nAllow: /\r\n\r\nSitemap: ${siteUrl}${base}${sitemapPath}\r\n`;\r\n}\r\n\r\n/**\r\n * Convert page build results to sitemap entries\r\n */\r\nexport function pagesToSitemapEntries(\r\n pages: PageBuildResult[],\r\n options: SitemapOptions = {}\r\n): SitemapEntry[] {\r\n const {\r\n exclude = [],\r\n defaultChangefreq = 'weekly',\r\n defaultPriority = 0.5,\r\n } = options;\r\n\r\n return pages\r\n .filter((page) => {\r\n // Filter out excluded paths\r\n for (const pattern of exclude) {\r\n if (pattern.includes('*')) {\r\n // Simple glob matching\r\n const regex = new RegExp(\r\n '^' + pattern.replace(/\\*/g, '.*').replace(/\\?/g, '.') + '$'\r\n );\r\n if (regex.test(page.path)) return false;\r\n } else if (page.path === pattern) {\r\n return false;\r\n }\r\n }\r\n return true;\r\n })\r\n .map((page) => {\r\n // Determine priority based on path depth\r\n const depth = page.path.split('/').filter(Boolean).length;\r\n let priority = defaultPriority;\r\n \r\n if (page.path === '/') {\r\n priority = 1.0; // Homepage highest priority\r\n } else if (depth === 1) {\r\n priority = 0.8; // Top-level pages\r\n } else if (depth === 2) {\r\n priority = 0.6; // Second-level pages\r\n }\r\n\r\n return {\r\n path: page.path,\r\n changefreq: defaultChangefreq,\r\n priority,\r\n };\r\n });\r\n}\r\n\r\n/**\r\n * Write sitemap and robots.txt to output directory\r\n */\r\nexport async function writeSitemap(\r\n pages: PageBuildResult[],\r\n config: SSGConfig,\r\n outDir: string,\r\n options: SitemapOptions = {}\r\n): Promise<{ sitemapPath: string; robotsPath: string }> {\r\n // Generate entries from pages\r\n const entries = pagesToSitemapEntries(pages, options);\r\n\r\n // Add additional URLs if provided\r\n if (options.additionalUrls) {\r\n entries.push(...options.additionalUrls);\r\n }\r\n\r\n // Generate sitemap XML\r\n const sitemapContent = generateSitemap(entries, config);\r\n const sitemapPath = path.join(outDir, 'sitemap.xml');\r\n await fs.writeFile(sitemapPath, sitemapContent, 'utf-8');\r\n\r\n // Generate robots.txt\r\n const robotsContent = generateRobotsTxt(config);\r\n const robotsPath = path.join(outDir, 'robots.txt');\r\n await fs.writeFile(robotsPath, robotsContent, 'utf-8');\r\n\r\n return { sitemapPath, robotsPath };\r\n}\r\n\r\n/**\r\n * Escape special XML characters\r\n */\r\nfunction escapeXml(str: string): string {\r\n return str\r\n .replace(/&/g, '&amp;')\r\n .replace(/</g, '&lt;')\r\n .replace(/>/g, '&gt;')\r\n .replace(/\"/g, '&quot;')\r\n .replace(/'/g, '&apos;');\r\n}\r\n", "/**\r\n * Virtual Entry Point Generation\r\n * \r\n * Generates auto-configured client and server entry points for zero-config mode.\r\n * Users can override by providing their own entry files.\r\n */\r\n\r\nimport fs from 'node:fs';\r\nimport path from 'node:path';\r\nimport type { SSGConfig } from '../types';\r\n\r\n/**\r\n * Virtual module IDs\r\n * Note: We use a special path format that Vite can resolve from HTML\r\n */\r\nexport const VIRTUAL_CLIENT_ID = 'virtual:ssg-client';\r\nexport const RESOLVED_VIRTUAL_CLIENT_ID = '\\0' + VIRTUAL_CLIENT_ID + '.tsx';\r\n\r\n// Special entry path that can be used in HTML and resolved by the plugin\r\nexport const SSG_CLIENT_ENTRY_PATH = '/@ssg/client.tsx';\r\n\r\nexport const VIRTUAL_SERVER_ID = 'virtual:ssg-server';\r\nexport const RESOLVED_VIRTUAL_SERVER_ID = '\\0' + VIRTUAL_SERVER_ID + '.tsx';\r\n\r\nexport const VIRTUAL_HTML_ID = 'virtual:ssg-html';\r\nexport const RESOLVED_VIRTUAL_HTML_ID = '\\0' + VIRTUAL_HTML_ID;\r\n\r\n/**\r\n * Detection result for custom entry points\r\n */\r\nexport interface EntryDetectionResult {\r\n /** Whether to use virtual client entry */\r\n useVirtualClient: boolean;\r\n /** Whether to use virtual server entry */\r\n useVirtualServer: boolean;\r\n /** Whether to use virtual HTML template */\r\n useVirtualHtml: boolean;\r\n /** Path to custom client entry if found */\r\n customClientPath?: string;\r\n /** Path to custom server entry if found */\r\n customServerPath?: string;\r\n /** Path to custom HTML template if found */\r\n customHtmlPath?: string;\r\n /** Path to global CSS if found */\r\n globalCssPath?: string;\r\n}\r\n\r\n/**\r\n * Detect if user has custom entry points\r\n */\r\nexport function detectCustomEntries(root: string, config: SSGConfig): EntryDetectionResult {\r\n // Custom client entry paths (if found, user has custom setup)\r\n const clientPaths = [\r\n 'src/main.tsx',\r\n 'src/main.ts',\r\n 'src/entry-client.tsx',\r\n 'src/entry-client.ts',\r\n 'src/entry.tsx',\r\n 'src/entry.ts',\r\n ];\r\n\r\n const serverPaths = [\r\n 'src/entry-server.tsx',\r\n 'src/entry-server.ts',\r\n ];\r\n\r\n const htmlPaths = [\r\n 'index.html',\r\n ];\r\n\r\n // Global CSS to auto-import (checked in order of preference)\r\n const cssPaths = [\r\n 'src/styles/global.css',\r\n 'src/styles/main.css',\r\n 'src/styles/index.css',\r\n 'src/style.css',\r\n 'src/global.css',\r\n 'src/index.css',\r\n ];\r\n\r\n let customClientPath: string | undefined;\r\n let customServerPath: string | undefined;\r\n let customHtmlPath: string | undefined;\r\n let globalCssPath: string | undefined;\r\n\r\n // Check for custom client entry\r\n for (const p of clientPaths) {\r\n const fullPath = path.join(root, p);\r\n if (fs.existsSync(fullPath)) {\r\n customClientPath = fullPath;\r\n break;\r\n }\r\n }\r\n\r\n // Check for custom server entry\r\n for (const p of serverPaths) {\r\n const fullPath = path.join(root, p);\r\n if (fs.existsSync(fullPath)) {\r\n customServerPath = fullPath;\r\n break;\r\n }\r\n }\r\n\r\n // Check for custom HTML template\r\n for (const p of htmlPaths) {\r\n const fullPath = path.join(root, p);\r\n if (fs.existsSync(fullPath)) {\r\n customHtmlPath = fullPath;\r\n break;\r\n }\r\n }\r\n\r\n // Check for global CSS\r\n for (const p of cssPaths) {\r\n const fullPath = path.join(root, p);\r\n if (fs.existsSync(fullPath)) {\r\n globalCssPath = '/' + p.replace(/\\\\/g, '/');\r\n break;\r\n }\r\n }\r\n\r\n return {\r\n useVirtualClient: !customClientPath,\r\n useVirtualServer: !customServerPath,\r\n useVirtualHtml: !customHtmlPath,\r\n customClientPath,\r\n customServerPath,\r\n customHtmlPath,\r\n globalCssPath,\r\n };\r\n}\r\n\r\n/**\r\n * Generate virtual client entry code\r\n */\r\nexport function generateClientEntry(config: SSGConfig, detection: EntryDetectionResult): string {\r\n const cssImport = detection.globalCssPath\r\n ? `import '${detection.globalCssPath}';\\n`\r\n : '';\r\n\r\n // Additional client imports from config\r\n const additionalImports = (config.clientImports ?? [])\r\n .map(imp => `import '${imp}';`)\r\n .join('\\n');\r\n const additionalImportsBlock = additionalImports ? `\\n${additionalImports}\\n` : '';\r\n\r\n const prefetchDelay = typeof config.prefetch === 'object'\r\n ? config.prefetch.delay ?? 100\r\n : 100;\r\n\r\n const prefetchEnabled = config.prefetch !== false;\r\n\r\n return `/**\r\n * Auto-generated client entry point\r\n * This file is generated by @sigx/ssg when no custom entry is detected.\r\n * To customize, create src/main.tsx or src/entry-client.tsx\r\n */\r\n${cssImport}${additionalImportsBlock}\r\nimport { defineApp, component } from 'sigx';\r\nimport { createRouter, createWebHistory } from '@sigx/router';\r\nimport { ssrClientPlugin } from '@sigx/ssg/client';\r\nimport routes from 'virtual:ssg-routes';\r\nimport { setupLayouts, LayoutRouter } from 'virtual:generated-layouts';\r\n${prefetchEnabled ? `import { setupPrefetch } from '@sigx/ssg/client';` : ''}\r\n\r\n// Apply layouts to routes (annotates routes with layout info)\r\nconst layoutRoutes = setupLayouts(routes);\r\n\r\n// Create router with browser history\r\nconst router = createRouter({\r\n history: createWebHistory('${config.base || '/'}'),\r\n routes: layoutRoutes,\r\n});\r\n\r\n// Root app component - uses LayoutRouter which preserves layouts across navigation\r\nconst App = component(() => {\r\n return () => <LayoutRouter />;\r\n});\r\n\r\n// Hydrate the server-rendered HTML\r\ndefineApp(<App />)\r\n .use(router)\r\n .use(ssrClientPlugin)\r\n .hydrate('#app');\r\n\r\n${prefetchEnabled ? `// Enable link prefetching for faster navigation\r\nsetupPrefetch({ delay: ${prefetchDelay} });` : ''}\r\n`;\r\n}\r\n\r\n/**\r\n * Generate virtual server entry code\r\n */\r\nexport function generateServerEntry(config: SSGConfig): string {\r\n return `/**\r\n * Auto-generated server entry point\r\n * This file is generated by @sigx/ssg when no custom entry is detected.\r\n * To customize, create src/entry-server.tsx\r\n */\r\nimport { renderToString } from '@sigx/server-renderer/server';\r\nimport { defineApp } from 'sigx';\r\nimport { createRouter, createMemoryHistory } from '@sigx/router';\r\nimport routes from 'virtual:ssg-routes';\r\nimport { setupLayouts, LayoutRouter } from 'virtual:generated-layouts';\r\n\r\n// Pre-process routes with layouts once at module load time (not per-render)\r\nconst routesWithLayouts = setupLayouts(routes);\r\n\r\n/**\r\n * Render the app to HTML string for a given URL\r\n */\r\nexport async function render(url, context) {\r\n // Create router with memory history for SSR\r\n // Note: We must create a new router per render because history is URL-specific\r\n const router = createRouter({\r\n routes: routesWithLayouts,\r\n history: createMemoryHistory({ initialLocation: url || '/' }),\r\n });\r\n\r\n // Create app with router - router's install() sets up DI via app.defineProvide()\r\n const app = defineApp(<LayoutRouter />).use(router);\r\n \r\n const html = await renderToString(app);\r\n return html;\r\n}\r\n`;\r\n}\r\n\r\n/**\r\n * Generate virtual HTML template\r\n */\r\nexport function generateHtmlTemplate(config: SSGConfig): string {\r\n const site = config.site || {};\r\n const lang = site.lang || 'en';\r\n const title = site.title || 'SignalX App';\r\n const description = site.description || '';\r\n const favicon = site.favicon || '/favicon.ico';\r\n const themeColor = site.themeColor || '#000000';\r\n const ogImage = site.ogImage || '';\r\n const url = site.url || '';\r\n const twitter = site.twitter || '';\r\n const fonts = site.fonts || [];\r\n\r\n // Build font preconnect and stylesheet links\r\n let fontLinks = '';\r\n if (fonts.length > 0) {\r\n fontLinks = `\r\n <link rel=\"preconnect\" href=\"https://fonts.googleapis.com\" />\r\n <link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin />\r\n <link href=\"https://fonts.googleapis.com/css2?family=${fonts.join('&family=')}&display=swap\" rel=\"stylesheet\" />`;\r\n }\r\n\r\n // Build OG meta tags\r\n let ogTags = '';\r\n if (url || ogImage) {\r\n ogTags = `\r\n <!-- Open Graph -->\r\n <meta property=\"og:type\" content=\"website\" />\r\n <meta property=\"og:title\" content=\"${title}\" />\r\n <meta property=\"og:description\" content=\"${description}\" />${url ? `\r\n <meta property=\"og:url\" content=\"${url}\" />` : ''}${ogImage ? `\r\n <meta property=\"og:image\" content=\"${ogImage}\" />` : ''}`;\r\n }\r\n\r\n // Build Twitter card tags\r\n let twitterTags = '';\r\n if (twitter || ogImage) {\r\n twitterTags = `\r\n <!-- Twitter Card -->\r\n <meta name=\"twitter:card\" content=\"${ogImage ? 'summary_large_image' : 'summary'}\" />${twitter ? `\r\n <meta name=\"twitter:site\" content=\"@${twitter}\" />` : ''}\r\n <meta name=\"twitter:title\" content=\"${title}\" />\r\n <meta name=\"twitter:description\" content=\"${description}\" />${ogImage ? `\r\n <meta name=\"twitter:image\" content=\"${ogImage}\" />` : ''}`;\r\n }\r\n\r\n return `<!DOCTYPE html>\r\n<html lang=\"${lang}\">\r\n<head>\r\n <meta charset=\"UTF-8\" />\r\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\r\n <meta name=\"description\" content=\"${description}\" />\r\n <meta name=\"theme-color\" content=\"${themeColor}\" />\r\n <link rel=\"icon\" type=\"image/x-icon\" href=\"${favicon}\" />${fontLinks}${ogTags}${twitterTags}\r\n <title>${title}</title>\r\n <!--head-tags-->\r\n</head>\r\n<body>\r\n <div id=\"app\"><!--app-html--></div>\r\n <script type=\"module\" src=\"/@ssg/client.tsx\"></script>\r\n</body>\r\n</html>\r\n`;\r\n}\r\n\r\n/**\r\n * Generate HTML template for production build\r\n * Uses the actual client entry path instead of virtual module\r\n */\r\nexport function generateProductionHtmlTemplate(config: SSGConfig, clientEntryPath: string): string {\r\n const site = config.site || {};\r\n const lang = site.lang || 'en';\r\n const title = site.title || 'SignalX App';\r\n const description = site.description || '';\r\n const favicon = site.favicon || '/favicon.ico';\r\n const themeColor = site.themeColor || '#000000';\r\n const ogImage = site.ogImage || '';\r\n const url = site.url || '';\r\n const twitter = site.twitter || '';\r\n const fonts = site.fonts || [];\r\n\r\n // Build font preconnect and stylesheet links\r\n let fontLinks = '';\r\n if (fonts.length > 0) {\r\n fontLinks = `\r\n <link rel=\"preconnect\" href=\"https://fonts.googleapis.com\" />\r\n <link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin />\r\n <link href=\"https://fonts.googleapis.com/css2?family=${fonts.join('&family=')}&display=swap\" rel=\"stylesheet\" />`;\r\n }\r\n\r\n // Build OG meta tags\r\n let ogTags = '';\r\n if (url || ogImage) {\r\n ogTags = `\r\n <!-- Open Graph -->\r\n <meta property=\"og:type\" content=\"website\" />\r\n <meta property=\"og:title\" content=\"${title}\" />\r\n <meta property=\"og:description\" content=\"${description}\" />${url ? `\r\n <meta property=\"og:url\" content=\"${url}\" />` : ''}${ogImage ? `\r\n <meta property=\"og:image\" content=\"${ogImage}\" />` : ''}`;\r\n }\r\n\r\n // Build Twitter card tags\r\n let twitterTags = '';\r\n if (twitter || ogImage) {\r\n twitterTags = `\r\n <!-- Twitter Card -->\r\n <meta name=\"twitter:card\" content=\"${ogImage ? 'summary_large_image' : 'summary'}\" />${twitter ? `\r\n <meta name=\"twitter:site\" content=\"@${twitter}\" />` : ''}\r\n <meta name=\"twitter:title\" content=\"${title}\" />\r\n <meta name=\"twitter:description\" content=\"${description}\" />${ogImage ? `\r\n <meta name=\"twitter:image\" content=\"${ogImage}\" />` : ''}`;\r\n }\r\n\r\n return `<!DOCTYPE html>\r\n<html lang=\"${lang}\">\r\n<head>\r\n <meta charset=\"UTF-8\" />\r\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\r\n <meta name=\"description\" content=\"${description}\" />\r\n <meta name=\"theme-color\" content=\"${themeColor}\" />\r\n <link rel=\"icon\" type=\"image/x-icon\" href=\"${favicon}\" />${fontLinks}${ogTags}${twitterTags}\r\n <title>${title}</title>\r\n <!--head-tags-->\r\n</head>\r\n<body>\r\n <div id=\"app\"><!--app-html--></div>\r\n <script type=\"module\" src=\"${clientEntryPath}\"></script>\r\n</body>\r\n</html>\r\n`;\r\n}\r\n", "/**\r\n * SSG Dev Server\r\n *\r\n * Starts a Vite development server with SSG plugins pre-configured.\r\n * Provides a unified `ssg dev` command for zero-config development.\r\n */\r\n\r\nimport path from 'node:path';\r\nimport fs from 'node:fs';\r\nimport type { SSGConfig } from './types';\r\nimport { loadConfig } from './config';\r\nimport { ssgPlugin } from './vite/plugin';\r\n\r\n/**\r\n * Dev server options\r\n */\r\nexport interface DevOptions {\r\n /**\r\n * Path to ssg.config.ts\r\n */\r\n configPath?: string;\r\n\r\n /**\r\n * Port to run dev server on\r\n * @default 5173\r\n */\r\n port?: number;\r\n\r\n /**\r\n * Host to bind to\r\n * @default 'localhost'\r\n */\r\n host?: string | boolean;\r\n\r\n /**\r\n * Open browser automatically\r\n * @default false\r\n */\r\n open?: boolean;\r\n\r\n /**\r\n * Enable verbose logging\r\n */\r\n verbose?: boolean;\r\n}\r\n\r\n/**\r\n * Start the SSG development server\r\n */\r\nexport async function dev(options: DevOptions = {}): Promise<void> {\r\n const root = process.cwd();\r\n\r\n console.log('\\n\uD83D\uDE80 @sigx/ssg - Starting development server...\\n');\r\n\r\n // Load SSG config\r\n const ssgConfig = await loadConfig(options.configPath);\r\n\r\n // Check if user has a vite.config.ts\r\n const hasViteConfig = fs.existsSync(path.join(root, 'vite.config.ts')) ||\r\n fs.existsSync(path.join(root, 'vite.config.js')) ||\r\n fs.existsSync(path.join(root, 'vite.config.mjs'));\r\n\r\n // Import Vite\r\n const vite = await import('vite');\r\n\r\n if (hasViteConfig) {\r\n // User has their own vite.config - use it directly\r\n // They should have ssgPlugin() configured already\r\n console.log('\uD83D\uDCE6 Using existing vite.config\\n');\r\n\r\n const server = await vite.createServer({\r\n root,\r\n server: {\r\n port: options.port,\r\n host: options.host,\r\n open: options.open,\r\n },\r\n });\r\n\r\n await server.listen();\r\n server.printUrls();\r\n } else {\r\n // Zero-config mode - configure everything automatically\r\n console.log('\uD83D\uDCE6 Zero-config mode enabled\\n');\r\n\r\n // Try to import @sigx/vite plugin\r\n let sigxPlugin: ((...args: any[]) => any) | undefined;\r\n try {\r\n const sigxVite = await import('@sigx/vite');\r\n sigxPlugin = sigxVite.sigxPlugin;\r\n } catch {\r\n console.warn('\u26A0\uFE0F @sigx/vite not found, JSX transform may not work');\r\n console.warn(' Install with: npm install @sigx/vite\\n');\r\n }\r\n\r\n // Build plugins array\r\n const plugins: any[] = [];\r\n\r\n // Add Tailwind CSS if available\r\n try {\r\n // @ts-expect-error - Optional dependency\r\n const tailwind = await import('@tailwindcss/vite');\r\n plugins.push(tailwind.default());\r\n } catch {\r\n // Tailwind not installed, skip\r\n }\r\n\r\n // Add SignalX plugin if available\r\n if (sigxPlugin) {\r\n plugins.push(sigxPlugin());\r\n }\r\n\r\n // Add SSG plugin\r\n plugins.push(...ssgPlugin({ configPath: options.configPath }));\r\n\r\n const server = await vite.createServer({\r\n root,\r\n plugins,\r\n // Vite 8 uses oxc instead of esbuild for JSX transforms\r\n oxc: {\r\n jsx: {\r\n runtime: 'automatic',\r\n importSource: 'sigx',\r\n }\r\n },\r\n server: {\r\n port: options.port ?? 5173,\r\n host: options.host,\r\n open: options.open,\r\n },\r\n });\r\n\r\n await server.listen();\r\n server.printUrls();\r\n }\r\n}\r\n\r\n/**\r\n * Preview the production build\r\n */\r\nexport async function preview(options: DevOptions = {}): Promise<void> {\r\n const root = process.cwd();\r\n\r\n console.log('\\n\uD83D\uDC40 @sigx/ssg - Preview server...\\n');\r\n\r\n const vite = await import('vite');\r\n\r\n const server = await vite.preview({\r\n root,\r\n preview: {\r\n port: options.port ?? 4173,\r\n host: options.host,\r\n open: options.open,\r\n },\r\n });\r\n\r\n server.printUrls();\r\n console.log('\\n');\r\n}\r\n", "/**\r\n * SSG Vite Plugin\r\n *\r\n * Main Vite plugin for @sigx/ssg that integrates:\r\n * - File-based routing with virtual modules\r\n * - Layout system\r\n * - MDX processing\r\n * - HMR for development\r\n * - Zero-config entry point generation\r\n */\r\n\r\nimport type { Plugin, ResolvedConfig, ViteDevServer } from 'vite';\r\nimport path from 'node:path';\r\nimport fs from 'node:fs';\r\nimport type { SSGConfig } from '../types';\r\nimport { defineSSGConfig, loadConfig } from '../config';\r\nimport { scanPages } from '../routing/scanner';\r\nimport { generateRoutesModule, generateLazyRoutesModule, VIRTUAL_ROUTES_ID, RESOLVED_VIRTUAL_ROUTES_ID } from '../routing/virtual';\r\nimport { generateNavigationModule, VIRTUAL_NAVIGATION_ID, RESOLVED_VIRTUAL_NAVIGATION_ID } from '../routing/virtual-navigation';\r\nimport { discoverLayouts } from '../layouts/resolver';\r\nimport { generateLayoutsModule, VIRTUAL_LAYOUTS_ID, RESOLVED_VIRTUAL_LAYOUTS_ID } from '../layouts/virtual';\r\nimport { mdxPlugin } from '../mdx/plugin';\r\nimport { parseFrontmatter } from '../mdx/frontmatter';\r\nimport {\r\n detectCustomEntries,\r\n generateClientEntry,\r\n generateServerEntry,\r\n generateHtmlTemplate,\r\n VIRTUAL_CLIENT_ID,\r\n RESOLVED_VIRTUAL_CLIENT_ID,\r\n VIRTUAL_SERVER_ID,\r\n RESOLVED_VIRTUAL_SERVER_ID,\r\n SSG_CLIENT_ENTRY_PATH,\r\n type EntryDetectionResult,\r\n} from './virtual-entries';\r\n\r\n/**\r\n * SSG Plugin options\r\n */\r\nexport interface SSGPluginOptions extends Partial<SSGConfig> {\r\n /**\r\n * Path to ssg.config.ts\r\n */\r\n configPath?: string;\r\n \r\n /**\r\n * Enable built-in MDX processing. Set to false if using external MDX plugin.\r\n * @default true\r\n */\r\n enableMdx?: boolean;\r\n}\r\n\r\n/**\r\n * Virtual module for SSG config\r\n */\r\nconst VIRTUAL_CONFIG_ID = 'virtual:ssg-config';\r\nconst RESOLVED_VIRTUAL_CONFIG_ID = '\\0' + VIRTUAL_CONFIG_ID;\r\n\r\n/**\r\n * Create the SSG Vite plugin\r\n */\r\nexport function ssgPlugin(options: SSGPluginOptions = {}): Plugin[] {\r\n let config: ResolvedConfig;\r\n let ssgConfig: SSGConfig;\r\n let root: string;\r\n let server: ViteDevServer | undefined;\r\n let entryDetection: EntryDetectionResult;\r\n\r\n // Cache for virtual modules\r\n let routesCache: { routes: any[]; code: string } | null = null;\r\n let layoutsCache: { layouts: any[]; code: string } | null = null;\r\n let navigationCache: { code: string } | null = null;\r\n \r\n // Cache for frontmatter hashes to detect changes\r\n const frontmatterHashCache = new Map<string, string>();\r\n\r\n const mainPlugin: Plugin = {\r\n name: 'sigx-ssg',\r\n enforce: 'pre',\r\n\r\n async configResolved(resolvedConfig) {\r\n config = resolvedConfig;\r\n root = resolvedConfig.root;\r\n\r\n // Load SSG config - always try to load from file first\r\n const fileConfig = await loadConfig(options.configPath);\r\n \r\n // Merge file config with plugin options (plugin options take precedence)\r\n ssgConfig = defineSSGConfig({\r\n ...fileConfig,\r\n ...options,\r\n });\r\n\r\n // Detect custom entry points\r\n entryDetection = detectCustomEntries(root, ssgConfig);\r\n\r\n // Log zero-config mode status\r\n if (entryDetection.useVirtualClient || entryDetection.useVirtualServer) {\r\n console.log('\uD83D\uDCE6 @sigx/ssg: Using zero-config mode');\r\n if (entryDetection.useVirtualClient) {\r\n console.log(' \u2192 Virtual client entry');\r\n }\r\n if (entryDetection.useVirtualServer) {\r\n console.log(' \u2192 Virtual server entry');\r\n }\r\n if (entryDetection.globalCssPath) {\r\n console.log(` \u2192 Auto-importing ${entryDetection.globalCssPath}`);\r\n }\r\n }\r\n },\r\n\r\n configureServer(devServer) {\r\n server = devServer;\r\n\r\n // Watch pages and layouts directories for changes\r\n const pagesDir = path.resolve(root, ssgConfig.pages || 'src/pages');\r\n const layoutsDir = path.resolve(root, ssgConfig.layouts || 'src/layouts');\r\n const contentDir = path.resolve(root, ssgConfig.content || 'src/content');\r\n\r\n // Clear caches and trigger HMR on file changes\r\n devServer.watcher.on('add', (file) => {\r\n if (file.startsWith(pagesDir)) {\r\n routesCache = null;\r\n navigationCache = null;\r\n invalidateModule(RESOLVED_VIRTUAL_ROUTES_ID);\r\n invalidateModule(RESOLVED_VIRTUAL_NAVIGATION_ID);\r\n } else if (file.startsWith(layoutsDir)) {\r\n layoutsCache = null;\r\n invalidateModule(RESOLVED_VIRTUAL_LAYOUTS_ID);\r\n }\r\n });\r\n\r\n devServer.watcher.on('unlink', (file) => {\r\n if (file.startsWith(pagesDir)) {\r\n routesCache = null;\r\n navigationCache = null;\r\n // Clean up frontmatter hash cache\r\n frontmatterHashCache.delete(file);\r\n invalidateModule(RESOLVED_VIRTUAL_ROUTES_ID);\r\n invalidateModule(RESOLVED_VIRTUAL_NAVIGATION_ID);\r\n } else if (file.startsWith(layoutsDir)) {\r\n layoutsCache = null;\r\n invalidateModule(RESOLVED_VIRTUAL_LAYOUTS_ID);\r\n }\r\n });\r\n\r\n // Handle MDX/MD file content changes for frontmatter updates\r\n devServer.watcher.on('change', async (file) => {\r\n if (!file.startsWith(pagesDir)) return;\r\n if (!/\\.mdx?$/.test(file)) return;\r\n \r\n try {\r\n const content = await fs.promises.readFile(file, 'utf-8');\r\n const { data: newFrontmatter } = parseFrontmatter(content);\r\n const newHash = JSON.stringify(newFrontmatter);\r\n const oldHash = frontmatterHashCache.get(file);\r\n \r\n // Update the cache\r\n frontmatterHashCache.set(file, newHash);\r\n \r\n // If frontmatter changed, invalidate navigation (titles, categories may have changed)\r\n if (oldHash !== undefined && oldHash !== newHash) {\r\n navigationCache = null;\r\n routesCache = null;\r\n \r\n const navMod = devServer.moduleGraph.getModuleById(RESOLVED_VIRTUAL_NAVIGATION_ID);\r\n if (navMod) {\r\n devServer.moduleGraph.invalidateModule(navMod);\r\n }\r\n \r\n const routesMod = devServer.moduleGraph.getModuleById(RESOLVED_VIRTUAL_ROUTES_ID);\r\n if (routesMod) {\r\n devServer.moduleGraph.invalidateModule(routesMod);\r\n }\r\n \r\n // Send HMR update for navigation changes\r\n devServer.ws.send({ type: 'full-reload' });\r\n }\r\n } catch (err) {\r\n // File read error, ignore\r\n }\r\n });\r\n\r\n function invalidateModule(id: string) {\r\n const mod = devServer.moduleGraph.getModuleById(id);\r\n if (mod) {\r\n devServer.moduleGraph.invalidateModule(mod);\r\n devServer.ws.send({ type: 'full-reload' });\r\n }\r\n }\r\n\r\n // Serve virtual HTML template if no index.html exists\r\n if (entryDetection.useVirtualHtml) {\r\n devServer.middlewares.use((req, res, next) => {\r\n // Skip virtual modules and special Vite paths\r\n if (req.url?.startsWith('/@') || \r\n req.url?.startsWith('/__') || \r\n req.url?.includes('virtual:') ||\r\n req.url?.includes('node_modules') ||\r\n req.url?.startsWith('/@vite') ||\r\n req.url?.startsWith('/@fs')) {\r\n return next();\r\n }\r\n \r\n // Only handle requests for HTML pages (not assets with extensions)\r\n if (req.url && (req.url === '/' || !req.url.includes('.'))) {\r\n const html = generateHtmlTemplate(ssgConfig);\r\n // Transform HTML through Vite for HMR injection\r\n devServer.transformIndexHtml(req.url, html).then((transformedHtml) => {\r\n res.setHeader('Content-Type', 'text/html');\r\n res.end(transformedHtml);\r\n }).catch(next);\r\n return;\r\n }\r\n next();\r\n });\r\n }\r\n },\r\n\r\n resolveId(id) {\r\n // Handle virtual modules\r\n if (id === VIRTUAL_ROUTES_ID) {\r\n return RESOLVED_VIRTUAL_ROUTES_ID;\r\n }\r\n if (id === VIRTUAL_LAYOUTS_ID) {\r\n return RESOLVED_VIRTUAL_LAYOUTS_ID;\r\n }\r\n if (id === VIRTUAL_CONFIG_ID) {\r\n return RESOLVED_VIRTUAL_CONFIG_ID;\r\n }\r\n if (id === VIRTUAL_NAVIGATION_ID) {\r\n return RESOLVED_VIRTUAL_NAVIGATION_ID;\r\n }\r\n // Handle virtual entry points (both formats)\r\n if (id === VIRTUAL_CLIENT_ID || id === SSG_CLIENT_ENTRY_PATH) {\r\n return RESOLVED_VIRTUAL_CLIENT_ID;\r\n }\r\n if (id === VIRTUAL_SERVER_ID) {\r\n return RESOLVED_VIRTUAL_SERVER_ID;\r\n }\r\n return null;\r\n },\r\n\r\n async load(id) {\r\n // Generate virtual routes module\r\n if (id === RESOLVED_VIRTUAL_ROUTES_ID) {\r\n if (!routesCache) {\r\n const routes = await scanPages(ssgConfig, root);\r\n // Use lazy loading in dev mode for proper HMR and MDX processing\r\n const code = config.command === 'serve'\r\n ? generateLazyRoutesModule(routes, ssgConfig)\r\n : generateRoutesModule(routes, ssgConfig);\r\n routesCache = { routes, code };\r\n }\r\n return routesCache.code;\r\n }\r\n\r\n // Generate virtual layouts module\r\n if (id === RESOLVED_VIRTUAL_LAYOUTS_ID) {\r\n if (!layoutsCache) {\r\n const layouts = await discoverLayouts(ssgConfig, root);\r\n const code = generateLayoutsModule(layouts, ssgConfig);\r\n layoutsCache = { layouts, code };\r\n }\r\n return layoutsCache.code;\r\n }\r\n\r\n // Generate virtual navigation module\r\n if (id === RESOLVED_VIRTUAL_NAVIGATION_ID) {\r\n if (!navigationCache) {\r\n // Ensure routes are loaded (reuse cache if available)\r\n if (!routesCache) {\r\n const routes = await scanPages(ssgConfig, root);\r\n const routesCode = config.command === 'serve'\r\n ? generateLazyRoutesModule(routes, ssgConfig)\r\n : generateRoutesModule(routes, ssgConfig);\r\n routesCache = { routes, code: routesCode };\r\n }\r\n const isDev = config.command === 'serve';\r\n const code = generateNavigationModule(routesCache.routes, ssgConfig, isDev);\r\n navigationCache = { code };\r\n }\r\n return navigationCache.code;\r\n }\r\n\r\n // Generate virtual config module\r\n if (id === RESOLVED_VIRTUAL_CONFIG_ID) {\r\n return `export default ${JSON.stringify(ssgConfig)};`;\r\n }\r\n\r\n // Generate virtual client entry (needs JSX transform)\r\n if (id === RESOLVED_VIRTUAL_CLIENT_ID) {\r\n const code = generateClientEntry(ssgConfig, entryDetection);\r\n const esbuild = await import('esbuild');\r\n const result = await esbuild.transform(code, {\r\n loader: 'tsx',\r\n jsx: 'automatic',\r\n jsxImportSource: 'sigx',\r\n });\r\n return result.code;\r\n }\r\n\r\n // Generate virtual server entry (needs JSX transform)\r\n if (id === RESOLVED_VIRTUAL_SERVER_ID) {\r\n const code = generateServerEntry(ssgConfig);\r\n const esbuild = await import('esbuild');\r\n const result = await esbuild.transform(code, {\r\n loader: 'tsx',\r\n jsx: 'automatic',\r\n jsxImportSource: 'sigx',\r\n });\r\n return result.code;\r\n }\r\n\r\n return null;\r\n },\r\n\r\n // Handle HMR for layouts and pages\r\n async handleHotUpdate({ file, server }) {\r\n const layoutsDir = path.resolve(root, ssgConfig.layouts || 'src/layouts');\r\n const pagesDir = path.resolve(root, ssgConfig.pages || 'src/pages');\r\n\r\n if (file.startsWith(layoutsDir)) {\r\n // Clear layout cache\r\n layoutsCache = null;\r\n\r\n // Invalidate the virtual layouts module\r\n const mod = server.moduleGraph.getModuleById(RESOLVED_VIRTUAL_LAYOUTS_ID);\r\n if (mod) {\r\n server.moduleGraph.invalidateModule(mod);\r\n }\r\n\r\n // Also reload pages that use this layout\r\n return [];\r\n }\r\n\r\n // Handle MDX/MD file changes in pages directory\r\n if (file.startsWith(pagesDir) && /\\.mdx?$/.test(file)) {\r\n // The MDX plugin handles the transform and HMR code injection.\r\n // We just need to ensure the module is properly invalidated.\r\n // Vite will handle the rest via the injected import.meta.hot.accept()\r\n \r\n // Return undefined to let Vite handle the standard HMR flow\r\n // The MDX file already has import.meta.hot.accept() injected\r\n return undefined;\r\n }\r\n\r\n return undefined;\r\n },\r\n };\r\n\r\n // Combine with MDX plugin if enabled (default: true)\r\n const enableMdx = options.enableMdx !== false;\r\n \r\n if (enableMdx) {\r\n const mdx = mdxPlugin({\r\n markdown: options.markdown,\r\n ssgConfig: undefined as any, // Will be set by configResolved\r\n });\r\n return [mainPlugin, mdx];\r\n }\r\n \r\n return [mainPlugin];\r\n}\r\n\r\n/**\r\n * Export the plugin as default\r\n */\r\nexport default ssgPlugin;\r\n", "/**\r\n * Shiki syntax highlighting integration\r\n *\r\n * Provides code block highlighting for Markdown/MDX content.\r\n */\r\n\r\nimport { createHighlighter, type Highlighter, type BundledLanguage, type BundledTheme } from 'shiki';\r\nimport type { ShikiConfig } from '../types';\r\n\r\n/**\r\n * Cached highlighter instance\r\n */\r\nlet highlighterPromise: Promise<Highlighter> | null = null;\r\n\r\n/**\r\n * Default Shiki configuration\r\n */\r\nconst DEFAULT_CONFIG: Required<ShikiConfig> = {\r\n light: 'github-light',\r\n dark: 'github-dark',\r\n langs: ['javascript', 'typescript', 'jsx', 'tsx', 'json', 'css', 'html', 'markdown', 'bash', 'shell'],\r\n};\r\n\r\n/**\r\n * Initialize or get the Shiki highlighter\r\n */\r\nexport async function getHighlighter(config?: ShikiConfig): Promise<Highlighter> {\r\n if (!highlighterPromise) {\r\n const mergedConfig = { ...DEFAULT_CONFIG, ...config };\r\n\r\n highlighterPromise = createHighlighter({\r\n themes: [mergedConfig.light as BundledTheme, mergedConfig.dark as BundledTheme],\r\n langs: mergedConfig.langs as BundledLanguage[],\r\n });\r\n }\r\n\r\n return highlighterPromise;\r\n}\r\n\r\n/**\r\n * Tab types for preview blocks\r\n */\r\nexport type TabType = 'preview' | 'code' | 'console';\r\n\r\n/**\r\n * Highlight code with Shiki\r\n */\r\nexport async function highlightCode(\r\n code: string,\r\n lang: string,\r\n config?: ShikiConfig,\r\n meta?: { filename?: string; live?: boolean; tabs?: TabType[] }\r\n): Promise<string> {\r\n const highlighter = await getHighlighter(config);\r\n const mergedConfig = { ...DEFAULT_CONFIG, ...config };\r\n\r\n // Check if language is loaded\r\n const loadedLangs = highlighter.getLoadedLanguages();\r\n const effectiveLang = loadedLangs.includes(lang as BundledLanguage) ? lang : 'text';\r\n\r\n // Generate HTML with both themes for CSS-based switching\r\n const codeHtml = highlighter.codeToHtml(code, {\r\n lang: effectiveLang as BundledLanguage,\r\n themes: {\r\n light: mergedConfig.light as BundledTheme,\r\n dark: mergedConfig.dark as BundledTheme,\r\n },\r\n });\r\n\r\n // Wrap in code-window structure\r\n const filename = meta?.filename ?? '';\r\n const isLive = meta?.live ?? false;\r\n const tabs = meta?.tabs; // undefined means no tabbed view, just code\r\n const hasTabs = tabs && tabs.length > 0;\r\n \r\n const filenameHtml = filename \r\n ? `<span class=\"code-window-filename\">${escapeHtml(filename)}</span>`\r\n : `<span class=\"code-window-lang\">${getLanguageLabel(effectiveLang)}</span>`;\r\n\r\n // For preview blocks (has tabs), render a LivePreview island component\r\n if (hasTabs) {\r\n const base64Code = encodeBase64(code);\r\n \r\n // Generate tab buttons HTML based on tabs array\r\n const firstTab = tabs[0];\r\n const tabButtonsHtml = tabs.map((tab, i) => {\r\n const label = tab.charAt(0).toUpperCase() + tab.slice(1);\r\n const isActive = i === 0;\r\n return `<button class=\"code-window-tab${isActive ? ' code-window-tab-active' : ''}\">${label}</button>`;\r\n }).join('\\n ');\r\n \r\n // Return an island marker that will be hydrated on the client\r\n // Use code-window styling for consistency with the nice terminal look\r\n const html = `<div \r\n class=\"live-preview-island\" \r\n data-island=\"LivePreview\" \r\n data-island-strategy=\"visible\"\r\n data-island-props=\"${escapeHtml(JSON.stringify({\r\n code: base64Code,\r\n highlightedCode: codeHtml,\r\n language: effectiveLang,\r\n filename: filename,\r\n tabs: tabs,\r\n live: isLive\r\n }))}\"\r\n>\r\n <div class=\"code-window code-window-live code-window-preview\">\r\n <div class=\"code-window-header\">\r\n <div class=\"code-window-header-left\">\r\n <div class=\"code-window-dots\">\r\n <span class=\"code-window-dot dot-red\"></span>\r\n <span class=\"code-window-dot dot-yellow\"></span>\r\n <span class=\"code-window-dot dot-green\"></span>\r\n </div>\r\n ${filenameHtml}\r\n </div>\r\n <div class=\"code-window-tabs\">\r\n ${tabButtonsHtml}\r\n </div>\r\n <button class=\"code-window-try-live\" disabled>\u26A1 Try Live</button>\r\n </div>\r\n <div class=\"code-window-preview-pane\"${firstTab !== 'preview' ? ' style=\"display:none;\"' : ''}>\r\n <div class=\"code-window-preview-loading\">\r\n <span class=\"code-window-spinner\"></span>\r\n Loading preview...\r\n </div>\r\n </div>\r\n <div class=\"code-window-console-pane\"${firstTab !== 'console' ? ' style=\"display:none;\"' : ''}>\r\n <div class=\"code-window-console-empty\">No console output</div>\r\n </div>\r\n <div class=\"code-window-content\"${firstTab !== 'code' ? ' style=\"display:none;\"' : ''}>\r\n ${codeHtml}\r\n </div>\r\n </div>\r\n</div>`;\r\n return html;\r\n }\r\n\r\n // Add \"Try Live\" button for live code blocks\r\n const tryLiveButton = isLive \r\n ? `<button class=\"code-window-try-live\" data-live-code=\"${escapeHtml(encodeBase64(code))}\" data-lang=\"${effectiveLang}\" data-filename=\"${escapeHtml(filename)}\" title=\"Open in Live Playground\">\u26A1 Try Live</button>`\r\n : '';\r\n\r\n const html = `<div class=\"code-window${isLive ? ' code-window-live' : ''}\">\r\n <div class=\"code-window-header\">\r\n <div class=\"code-window-header-left\">\r\n <div class=\"code-window-dots\">\r\n <span class=\"code-window-dot dot-red\"></span>\r\n <span class=\"code-window-dot dot-yellow\"></span>\r\n <span class=\"code-window-dot dot-green\"></span>\r\n </div>\r\n ${filenameHtml}\r\n </div>\r\n ${tryLiveButton}\r\n </div>\r\n <div class=\"code-window-content\">\r\n ${codeHtml}\r\n </div>\r\n </div>`;\r\n\r\n return html;\r\n}\r\n\r\n/**\r\n * Encode string to base64 (works in both Node.js and browser)\r\n */\r\nfunction encodeBase64(str: string): string {\r\n // Use Buffer in Node.js\r\n if (typeof Buffer !== 'undefined') {\r\n return Buffer.from(str, 'utf-8').toString('base64');\r\n }\r\n // Fallback for browser (shouldn't be needed during SSG build)\r\n return btoa(unescape(encodeURIComponent(str)));\r\n}\r\n\r\n/**\r\n * Get a display label for a language\r\n */\r\nfunction getLanguageLabel(lang: string): string {\r\n const labels: Record<string, string> = {\r\n 'tsx': 'TSX',\r\n 'jsx': 'JSX',\r\n 'ts': 'TypeScript',\r\n 'typescript': 'TypeScript',\r\n 'js': 'JavaScript',\r\n 'javascript': 'JavaScript',\r\n 'css': 'CSS',\r\n 'html': 'HTML',\r\n 'json': 'JSON',\r\n 'bash': 'Terminal',\r\n 'shell': 'Terminal',\r\n 'sh': 'Terminal',\r\n 'md': 'Markdown',\r\n 'markdown': 'Markdown',\r\n 'python': 'Python',\r\n 'py': 'Python',\r\n 'rust': 'Rust',\r\n 'go': 'Go',\r\n 'text': '',\r\n };\r\n return labels[lang.toLowerCase()] ?? lang.toUpperCase();\r\n}\r\n\r\n/**\r\n * Escape HTML special characters\r\n */\r\nfunction escapeHtml(str: string): string {\r\n return str\r\n .replace(/&/g, '&amp;')\r\n .replace(/</g, '&lt;')\r\n .replace(/>/g, '&gt;')\r\n .replace(/\"/g, '&quot;')\r\n .replace(/'/g, '&#39;');\r\n}\r\n\r\n/**\r\n * Create a rehype plugin for Shiki\r\n */\r\nexport function rehypeShiki(config?: ShikiConfig) {\r\n return async (tree: any) => {\r\n const { visit } = await import('unist-util-visit');\r\n const { fromHtml } = await import('hast-util-from-html');\r\n\r\n const nodesToProcess: Array<{ node: any; parent: any; index: number }> = [];\r\n\r\n visit(tree, 'element', (node: any, index: number | undefined, parent: any) => {\r\n // Look for <pre><code> elements\r\n if (\r\n node.tagName === 'pre' &&\r\n node.children?.[0]?.tagName === 'code'\r\n ) {\r\n nodesToProcess.push({ node, parent, index: index ?? 0 });\r\n }\r\n });\r\n\r\n // Process nodes in parallel\r\n await Promise.all(\r\n nodesToProcess.map(async ({ node, parent, index }) => {\r\n const codeNode = node.children[0];\r\n\r\n // Extract language from class (e.g., \"language-typescript\")\r\n const className = codeNode.properties?.className?.[0] || '';\r\n const lang = className.replace(/^language-/, '') || 'text';\r\n\r\n // Extract filename from meta string if present\r\n // Supports: ```tsx filename=\"Counter.tsx\" or ```tsx title=\"Counter.tsx\"\r\n const metaString = codeNode.data?.meta || codeNode.properties?.metastring || '';\r\n const filename = extractMeta(metaString, 'filename') || extractMeta(metaString, 'title') || '';\r\n \r\n // Check for \"live\" flag in meta string (e.g., ```tsx live)\r\n const isLive = /\\blive\\b/i.test(metaString);\r\n \r\n // Parse tabs from meta string - order determines tab order\r\n // Supported keywords: preview, code, console\r\n // Example: ```tsx code preview console live -> tabs: [code, preview, console], with live button\r\n const tabKeywords = ['preview', 'code', 'console'] as const;\r\n const tabs: TabType[] = [];\r\n \r\n // Find all tab keywords and their positions\r\n const tabPositions: Array<{ tab: TabType; index: number }> = [];\r\n for (const keyword of tabKeywords) {\r\n const regex = new RegExp(`\\\\b${keyword}\\\\b`, 'i');\r\n const match = metaString.match(regex);\r\n if (match && match.index !== undefined) {\r\n tabPositions.push({ tab: keyword, index: match.index });\r\n }\r\n }\r\n \r\n // Sort by position (order of appearance in meta string)\r\n tabPositions.sort((a, b) => a.index - b.index);\r\n \r\n // Extract just the tab names in order\r\n for (const { tab } of tabPositions) {\r\n tabs.push(tab);\r\n }\r\n\r\n // Get raw code content\r\n const code = getTextContent(codeNode);\r\n\r\n // Highlight with Shiki (with meta info)\r\n // Only pass tabs if at least one tab keyword was found\r\n const html = await highlightCode(code.trim(), lang, config, { \r\n filename, \r\n live: isLive, \r\n tabs: tabs.length > 0 ? tabs : undefined \r\n });\r\n\r\n // Parse the HTML string into HAST nodes\r\n const fragment = fromHtml(html, { fragment: true });\r\n \r\n // Replace node with the parsed HAST fragment's children\r\n if (parent && typeof index === 'number' && fragment.children.length > 0) {\r\n // Use the first element from the fragment (should be the code-window div)\r\n parent.children[index] = fragment.children[0];\r\n }\r\n })\r\n );\r\n };\r\n}\r\n\r\n/**\r\n * Extract a meta value from a meta string\r\n * Supports: filename=\"value\" or filename='value' or filename=value\r\n */\r\nfunction extractMeta(metaString: string, key: string): string | null {\r\n if (!metaString) return null;\r\n \r\n // Match: key=\"value\" or key='value' or key=value\r\n const regex = new RegExp(`${key}=[\"']?([^\"'\\\\s]+)[\"']?`, 'i');\r\n const match = metaString.match(regex);\r\n return match ? match[1] : null;\r\n}\r\n\r\n/**\r\n * Extract text content from an AST node\r\n */\r\nfunction getTextContent(node: any): string {\r\n if (node.type === 'text') {\r\n return node.value;\r\n }\r\n\r\n if (node.children) {\r\n return node.children.map(getTextContent).join('');\r\n }\r\n\r\n return '';\r\n}\r\n\r\n/**\r\n * Load additional language on demand\r\n */\r\nexport async function loadLanguage(lang: string): Promise<void> {\r\n const highlighter = await getHighlighter();\r\n const loadedLangs = highlighter.getLoadedLanguages();\r\n\r\n if (!loadedLangs.includes(lang as BundledLanguage)) {\r\n try {\r\n await highlighter.loadLanguage(lang as BundledLanguage);\r\n } catch {\r\n console.warn(`Shiki: Language \"${lang}\" not available, using plain text`);\r\n }\r\n }\r\n}\r\n", "/**\r\n * Rehype plugin to extract headings from MDX/MD content\r\n *\r\n * Extracts headings (h2-h6 by default) with their IDs and text content\r\n * for use in table of contents generation.\r\n */\r\n\r\nimport { visit } from 'unist-util-visit';\r\nimport { toString } from 'hast-util-to-string';\r\nimport type { TocHeading } from '../types';\r\n\r\n/**\r\n * Options for the rehype headings plugin\r\n */\r\nexport interface RehypeHeadingsOptions {\r\n /**\r\n * Minimum heading level to include (1-6)\r\n * @default 2\r\n */\r\n minLevel?: number;\r\n\r\n /**\r\n * Maximum heading level to include (1-6)\r\n * @default 3\r\n */\r\n maxLevel?: number;\r\n}\r\n\r\n/**\r\n * Rehype plugin to extract headings from the document\r\n *\r\n * Stores extracted headings in `file.data.headings` for later use.\r\n *\r\n * @example\r\n * ```ts\r\n * import { rehypeExtractHeadings } from './rehype-headings';\r\n *\r\n * // Use with unified\r\n * unified()\r\n * .use(rehypeSlug) // First add IDs to headings\r\n * .use(rehypeExtractHeadings, { minLevel: 2, maxLevel: 3 })\r\n * ```\r\n */\r\nexport function rehypeExtractHeadings(options: RehypeHeadingsOptions = {}) {\r\n const { minLevel = 2, maxLevel = 3 } = options;\r\n\r\n return (tree: any, file: any) => {\r\n const headings: TocHeading[] = [];\r\n\r\n visit(tree, 'element', (node: any) => {\r\n // Check if this is a heading element (h1-h6)\r\n const match = /^h([1-6])$/.exec(node.tagName);\r\n if (!match) return;\r\n\r\n const level = parseInt(match[1], 10);\r\n\r\n // Skip headings outside configured range\r\n if (level < minLevel || level > maxLevel) return;\r\n\r\n // Get the heading ID (should be set by rehype-slug)\r\n const id = node.properties?.id;\r\n if (!id) return;\r\n\r\n // Extract text content from the heading\r\n const text = toString(node).trim();\r\n if (!text) return;\r\n\r\n headings.push({ id, text, level });\r\n });\r\n\r\n // Store headings in file data for later access\r\n file.data = file.data || {};\r\n file.data.headings = headings;\r\n };\r\n}\r\n\r\nexport default rehypeExtractHeadings;\r\n", "/**\r\n * MDX Vite plugin\r\n *\r\n * Transforms MDX files into SignalX components with:\r\n * - Frontmatter extraction\r\n * - Shiki syntax highlighting\r\n * - SignalX JSX runtime integration\r\n */\r\n\r\nimport type { Plugin, ResolvedConfig } from 'vite';\r\nimport type { SSGConfig, MarkdownConfig, PageMeta, TocHeading } from '../types';\r\nimport { parseFrontmatter, extractTitleFromContent } from './frontmatter';\r\nimport { rehypeShiki } from './shiki';\r\nimport { rehypeExtractHeadings } from './rehype-headings';\r\n\r\n/**\r\n * MDX plugin options\r\n */\r\nexport interface MDXPluginOptions {\r\n /**\r\n * Markdown configuration\r\n */\r\n markdown?: MarkdownConfig;\r\n\r\n /**\r\n * SSG configuration (for layout resolution)\r\n */\r\n ssgConfig?: SSGConfig;\r\n}\r\n\r\n/**\r\n * Create the MDX Vite plugin\r\n */\r\nexport function mdxPlugin(options: MDXPluginOptions = {}): Plugin {\r\n const { markdown = {} } = options;\r\n\r\n let mdxRollup: any;\r\n let viteConfig: ResolvedConfig;\r\n\r\n return {\r\n name: 'sigx-ssg-mdx',\r\n enforce: 'pre',\r\n\r\n async configResolved(config) {\r\n viteConfig = config;\r\n // Dynamically import @mdx-js/rollup\r\n const mdxModule = await import('@mdx-js/rollup');\r\n const remarkFrontmatter = (await import('remark-frontmatter')).default;\r\n const remarkMdxFrontmatter = (await import('remark-mdx-frontmatter')).default;\r\n const remarkGfm = (await import('remark-gfm')).default;\r\n const rehypeSlug = (await import('rehype-slug')).default;\r\n const rehypeAutolinkHeadings = (await import('rehype-autolink-headings')).default;\r\n\r\n // Get TOC config from SSG config\r\n const tocConfig = options.ssgConfig?.toc || { minLevel: 2, maxLevel: 3 };\r\n\r\n // Build rehype plugins array\r\n const rehypePlugins: any[] = [];\r\n\r\n // Add rehype-slug first to generate heading IDs\r\n rehypePlugins.push(rehypeSlug);\r\n\r\n // Add autolink headings (clickable anchor links)\r\n rehypePlugins.push([rehypeAutolinkHeadings, {\r\n behavior: 'append',\r\n properties: {\r\n class: 'heading-anchor',\r\n ariaHidden: true,\r\n tabIndex: -1,\r\n },\r\n content: {\r\n type: 'element',\r\n tagName: 'span',\r\n properties: { class: 'heading-anchor-icon' },\r\n children: [{ type: 'text', value: '#' }],\r\n },\r\n }]);\r\n\r\n // Add heading extraction for TOC\r\n rehypePlugins.push([rehypeExtractHeadings, tocConfig]);\r\n\r\n // Add Shiki if enabled\r\n if (markdown.shiki !== false) {\r\n const shikiConfig = typeof markdown.shiki === 'object' ? markdown.shiki : undefined;\r\n rehypePlugins.push([rehypeShiki, shikiConfig]);\r\n }\r\n\r\n // Add custom rehype plugins\r\n if (markdown.rehypePlugins) {\r\n rehypePlugins.push(...markdown.rehypePlugins);\r\n }\r\n\r\n // Build remark plugins array\r\n const remarkPlugins: any[] = [\r\n remarkFrontmatter,\r\n [remarkMdxFrontmatter, { name: 'frontmatter' }],\r\n remarkGfm,\r\n ];\r\n\r\n // Add custom remark plugins\r\n if (markdown.remarkPlugins) {\r\n remarkPlugins.push(...markdown.remarkPlugins);\r\n }\r\n\r\n // Create MDX plugin\r\n // Use jsx: false to output function calls instead of JSX syntax\r\n // This avoids needing esbuild to process .mdx files as JSX\r\n mdxRollup = mdxModule.default({\r\n jsx: false,\r\n jsxImportSource: 'sigx',\r\n remarkPlugins,\r\n rehypePlugins,\r\n providerImportSource: undefined,\r\n });\r\n },\r\n\r\n async transform(code, id) {\r\n // Only process MDX and MD files\r\n if (!/\\.mdx?$/.test(id)) {\r\n return null;\r\n }\r\n\r\n // Parse frontmatter first\r\n const { data: frontmatter, content } = parseFrontmatter(code);\r\n\r\n // Extract title from content if not in frontmatter\r\n if (!frontmatter.title) {\r\n const extractedTitle = extractTitleFromContent(content);\r\n if (extractedTitle) {\r\n frontmatter.title = extractedTitle;\r\n }\r\n }\r\n\r\n // Transform MDX content\r\n if (!mdxRollup?.transform) {\r\n throw new Error('MDX plugin not initialized');\r\n }\r\n\r\n const result = await mdxRollup.transform(code, id);\r\n\r\n if (!result) {\r\n return null;\r\n }\r\n\r\n // Extract headings from the file data (set by rehype-extract-headings)\r\n // Note: We need to process the content to get headings\r\n const headings = await extractHeadingsFromContent(content, options);\r\n\r\n // Create module ID for HMR tracking (normalize path separators)\r\n const moduleId = id.replace(/\\\\/g, '/');\r\n\r\n // Inject frontmatter export and wrap in SignalX component\r\n const transformedCode = wrapMDXComponent(\r\n result.code,\r\n frontmatter,\r\n headings,\r\n moduleId,\r\n viteConfig.command === 'serve'\r\n );\r\n\r\n return {\r\n code: transformedCode,\r\n map: result.map,\r\n };\r\n },\r\n };\r\n}\r\n\r\n/**\r\n * Wrap MDX output in a SignalX component\r\n * \r\n * Note: remark-mdx-frontmatter already exports `frontmatter`, so we only add the layout export\r\n * \r\n * In dev mode, we:\r\n * 1. Wrap MDXContent in a sigx component() for proper HMR tracking\r\n * 2. Inject HMR registration code so the component updates live\r\n */\r\nfunction wrapMDXComponent(\r\n code: string,\r\n frontmatter: PageMeta,\r\n headings: TocHeading[],\r\n moduleId: string,\r\n isDev: boolean\r\n): string {\r\n // The MDX output already includes frontmatter export from remark-mdx-frontmatter\r\n // We need to add the layout export for the SSG routing system\r\n \r\n // In dev mode, wrap in sigx component for HMR support\r\n if (isDev) {\r\n // Generate a component name from the file path for debugging\r\n const fileName = moduleId.split('/').pop()?.replace(/\\.mdx?$/, '') || 'MDXPage';\r\n const componentName = fileName.charAt(0).toUpperCase() + fileName.slice(1).replace(/[^a-zA-Z0-9]/g, '') + 'Page';\r\n \r\n // The MDX output has \"export default function MDXContent(...)\" \r\n // We need to:\r\n // 1. Remove the \"export default\" from MDXContent to avoid duplicate exports\r\n // 2. Wrap it in a sigx component for HMR\r\n // 3. Export the wrapped component as default\r\n const modifiedCode = code\r\n .replace(/export\\s+default\\s+function\\s+MDXContent/g, 'function _MDXContent')\r\n .replace(/export\\s+{\\s*MDXContent\\s+as\\s+default\\s*}/g, '');\r\n \r\n return `\r\nimport { registerHMRModule } from '@sigx/vite/hmr';\r\nimport { component as __component } from 'sigx';\r\nregisterHMRModule('${moduleId}');\r\n\r\n${modifiedCode}\r\n\r\n// Export layout from frontmatter for SSG routing\r\nexport const layout = ${frontmatter.layout ? JSON.stringify(frontmatter.layout) : 'undefined'};\r\n\r\n// Export headings for table of contents\r\nexport const headings = ${JSON.stringify(headings)};\r\n\r\n// Wrap MDXContent in a sigx component for HMR support\r\nconst MDXPage = __component(() => {\r\n return () => _MDXContent({});\r\n}, { name: '${componentName}' });\r\n\r\nexport default MDXPage;\r\n\r\nif (import.meta.hot) {\r\n // Accept HMR updates with a callback to trigger re-render after module is updated\r\n import.meta.hot.accept((newModule) => {\r\n if (newModule) {\r\n // Notify LayoutRouter to clear its cache and re-render with new module\r\n window.dispatchEvent(new CustomEvent('sigx:mdx-hmr', { \r\n detail: { moduleId: '${moduleId}', newModule } \r\n }));\r\n }\r\n });\r\n}\r\n`;\r\n }\r\n \r\n // Production: just add exports without HMR wrapper\r\n return `\r\n${code}\r\n\r\n// Export layout from frontmatter for SSG routing\r\nexport const layout = ${frontmatter.layout ? JSON.stringify(frontmatter.layout) : 'undefined'};\r\n\r\n// Export headings for table of contents\r\nexport const headings = ${JSON.stringify(headings)};\r\n`;\r\n}\r\n\r\n/**\r\n * Extract headings from markdown/MDX content\r\n */\r\nasync function extractHeadingsFromContent(\r\n content: string,\r\n options: MDXPluginOptions\r\n): Promise<TocHeading[]> {\r\n const { unified } = await import('unified');\r\n const remarkParse = (await import('remark-parse')).default;\r\n const remarkRehype = (await import('remark-rehype')).default;\r\n const rehypeSlug = (await import('rehype-slug')).default;\r\n const rehypeStringify = (await import('rehype-stringify')).default;\r\n\r\n // Get TOC config\r\n const tocConfig = options.ssgConfig?.toc || { minLevel: 2, maxLevel: 3 };\r\n\r\n // Process markdown to extract headings\r\n // Note: rehype-stringify is required for unified to have a compiler\r\n const processor = unified()\r\n .use(remarkParse)\r\n .use(remarkRehype)\r\n .use(rehypeSlug)\r\n .use(rehypeExtractHeadings, tocConfig)\r\n .use(rehypeStringify);\r\n\r\n const file = await processor.process(content);\r\n return (file.data as any).headings || [];\r\n}\r\n\r\n/**\r\n * Create a simple markdown-only plugin (no MDX features)\r\n */\r\nexport function markdownPlugin(options: MDXPluginOptions = {}): Plugin {\r\n return {\r\n name: 'sigx-ssg-markdown',\r\n enforce: 'pre',\r\n\r\n async transform(code, id) {\r\n // Only process .md files (not .mdx)\r\n if (!/\\.md$/.test(id) || /\\.mdx$/.test(id)) {\r\n return null;\r\n }\r\n\r\n // Parse frontmatter\r\n const { data: frontmatter, content } = parseFrontmatter(code);\r\n\r\n // Extract title if not in frontmatter\r\n if (!frontmatter.title) {\r\n const extractedTitle = extractTitleFromContent(content);\r\n if (extractedTitle) {\r\n frontmatter.title = extractedTitle;\r\n }\r\n }\r\n\r\n // Convert markdown to simple HTML using a lightweight parser\r\n // For full MD support, the MDX plugin should be used\r\n const html = await simpleMarkdownToHtml(content, options);\r\n \r\n // Extract headings for TOC\r\n const headings = await extractHeadingsFromContent(content, options);\r\n \r\n const frontmatterJSON = JSON.stringify(frontmatter);\r\n const headingsJSON = JSON.stringify(headings);\r\n\r\n return {\r\n code: `\r\nimport { jsx as _jsx } from 'sigx/jsx-runtime';\r\n\r\nexport const frontmatter = ${frontmatterJSON};\r\nexport const layout = ${frontmatter.layout ? JSON.stringify(frontmatter.layout) : 'undefined'};\r\nexport const headings = ${headingsJSON};\r\n\r\nexport default function MDContent(props) {\r\n return _jsx('div', {\r\n class: 'markdown-content',\r\n dangerouslySetInnerHTML: { __html: ${JSON.stringify(html)} }\r\n });\r\n}\r\n`,\r\n map: null,\r\n };\r\n },\r\n };\r\n}\r\n\r\n/**\r\n * Simple markdown to HTML conversion\r\n * For basic markdown without custom components\r\n */\r\nasync function simpleMarkdownToHtml(markdown: string, options: MDXPluginOptions = {}): Promise<string> {\r\n // Use unified for basic markdown processing\r\n const { unified } = await import('unified');\r\n const remarkParse = (await import('remark-parse')).default;\r\n const remarkRehype = (await import('remark-rehype')).default;\r\n const rehypeSlug = (await import('rehype-slug')).default;\r\n const rehypeStringify = (await import('rehype-stringify')).default;\r\n\r\n const result = await unified()\r\n .use(remarkParse)\r\n .use(remarkRehype)\r\n .use(rehypeSlug) // Add IDs to headings\r\n .use(rehypeStringify)\r\n .process(markdown);\r\n\r\n return String(result);\r\n}\r\n", "import { build } from './build';\r\nimport { dev, preview } from './dev';\r\n\r\n// Dummy export to prevent tree-shaking in library mode\r\nexport const __cli__ = true;\r\n\r\nconst args = process.argv.slice(2);\r\nconst command = args[0];\r\n\r\n// Parse common options\r\nconst configPath = args.find((a: string) => a.startsWith('--config='))?.split('=')[1];\r\nconst port = parseInt(args.find((a: string) => a.startsWith('--port='))?.split('=')[1] || '');\r\nconst host = args.includes('--host') ? true : args.find((a: string) => a.startsWith('--host='))?.split('=')[1];\r\nconst open = args.includes('--open');\r\nconst verbose = args.includes('--verbose') || args.includes('-v');\r\n\r\nif (command === 'dev') {\r\n dev({ \r\n configPath, \r\n port: isNaN(port) ? undefined : port, \r\n host, \r\n open,\r\n verbose,\r\n }).catch((err: unknown) => {\r\n console.error('Dev server failed:', err);\r\n process.exit(1);\r\n });\r\n} else if (command === 'build') {\r\n build({ configPath, verbose }).catch((err: unknown) => {\r\n console.error('Build failed:', err);\r\n process.exit(1);\r\n });\r\n} else if (command === 'preview') {\r\n preview({ \r\n configPath, \r\n port: isNaN(port) ? undefined : port, \r\n host, \r\n open,\r\n }).catch((err: unknown) => {\r\n console.error('Preview server failed:', err);\r\n process.exit(1);\r\n });\r\n} else {\r\n console.log(`\r\n@sigx/ssg - Static Site Generator for SignalX\r\n\r\nUsage:\r\n ssg dev [options] Start development server\r\n ssg build [options] Build static site for production\r\n ssg preview [options] Preview production build locally\r\n\r\nOptions:\r\n --config=path Path to ssg.config.ts (default: ./ssg.config.ts)\r\n --port=number Port for dev/preview server (default: 5173/4173)\r\n --host Expose to network (or --host=0.0.0.0)\r\n --open Open browser automatically\r\n --verbose, -v Enable verbose logging\r\n\r\nExamples:\r\n ssg dev Start dev server on localhost:5173\r\n ssg dev --port=3000 --open Start on port 3000 and open browser\r\n ssg build Build static site to ./dist\r\n ssg preview Preview built site on localhost:4173\r\n`);\r\n}\r\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\r\n * SSG Build CLI\r\n *\r\n * Static site generation build process:\r\n * 1. Load configuration\r\n * 2. Scan routes and expand dynamic paths\r\n * 3. Build with Vite for production\r\n * 4. Render each route to static HTML\r\n * 5. Write output files\r\n * 6. Generate sitemap and robots.txt\r\n */\r\n\r\nimport path from 'node:path';\r\nimport fs from 'node:fs/promises';\r\nimport fsSync from 'node:fs';\r\nimport { createRequire } from 'node:module';\r\nimport { pathToFileURL } from 'node:url';\r\nimport type { SSGConfig, BuildOptions, BuildResult, PageBuildResult, SSGRoute, PageModule } from './types';\r\nimport { loadConfig, resolveConfigPaths } from './config';\r\nimport { scanPages, isDynamicRoute, extractParams, expandDynamicRoute } from './routing/index';\r\nimport { discoverLayouts } from './layouts/index';\r\nimport { writeSitemap } from './sitemap';\r\nimport {\r\n detectCustomEntries,\r\n generateClientEntry,\r\n generateServerEntry,\r\n generateProductionHtmlTemplate,\r\n VIRTUAL_CLIENT_ID,\r\n VIRTUAL_SERVER_ID,\r\n} from './vite/virtual-entries';\r\n\r\n/**\r\n * Build static site\r\n */\r\nexport async function build(options: BuildOptions = {}): Promise<BuildResult> {\r\n const startTime = Date.now();\r\n const root = process.cwd();\r\n const warnings: string[] = [];\r\n const pages: PageBuildResult[] = [];\r\n\r\n console.log('\\n\uD83D\uDE80 @sigx/ssg - Building static site...\\n');\r\n\r\n // Step 1: Load configuration\r\n console.log('\uD83D\uDCE6 Loading configuration...');\r\n const config = await loadConfig(options.configPath);\r\n const resolvedConfig = resolveConfigPaths(config, root);\r\n\r\n // Step 2: Scan routes\r\n console.log('\uD83D\uDD0D Scanning pages...');\r\n const routes = await scanPages(resolvedConfig, root);\r\n console.log(` Found ${routes.length} page(s)`);\r\n\r\n // Step 3: Discover layouts\r\n console.log('\uD83D\uDCD0 Discovering layouts...');\r\n const layouts = await discoverLayouts(resolvedConfig, root);\r\n console.log(` Found ${layouts.length} layout(s)`);\r\n\r\n // Step 4: Detect entry points\r\n const entryDetection = detectCustomEntries(root, resolvedConfig);\r\n if (entryDetection.useVirtualClient || entryDetection.useVirtualServer) {\r\n console.log('\uD83D\uDCE6 Using zero-config mode');\r\n if (entryDetection.useVirtualClient) console.log(' \u2192 Virtual client entry');\r\n if (entryDetection.useVirtualServer) console.log(' \u2192 Virtual server entry');\r\n if (entryDetection.useVirtualHtml) console.log(' \u2192 Virtual HTML template');\r\n }\r\n\r\n // Get entry points (may create temp files for virtual entries)\r\n const clientEntry = await getClientEntryPoint(resolvedConfig, root);\r\n const ssrEntry = await getSSREntryPoint(resolvedConfig, root);\r\n\r\n // Always write HTML template for the build (either generated or updated from custom)\r\n // This ensures Vite processes it and outputs index.html\r\n const htmlTemplatePath = path.join(root, 'index.html');\r\n let cleanupHtml = false;\r\n let originalHtmlContent: string | null = null;\r\n \r\n // Save original HTML content if we're modifying a custom one\r\n if (!entryDetection.useVirtualHtml && fsSync.existsSync(htmlTemplatePath)) {\r\n originalHtmlContent = fsSync.readFileSync(htmlTemplatePath, 'utf-8');\r\n }\r\n \r\n const htmlContent = await getHtmlTemplate(resolvedConfig, root, clientEntry);\r\n fsSync.writeFileSync(htmlTemplatePath, htmlContent, 'utf-8');\r\n cleanupHtml = entryDetection.useVirtualHtml; // Only cleanup (delete) if we generated it\r\n\r\n // Step 5: Build with Vite\r\n console.log('\uD83D\uDD28 Building with Vite...');\r\n const vite = await import('vite');\r\n\r\n try {\r\n // Build client bundle\r\n // Note: We don't empty the outDir since vite build may have already run\r\n // Always use HTML as input so Vite outputs index.html properly\r\n const clientInput = htmlTemplatePath;\r\n \r\n await vite.build({\r\n root,\r\n mode: 'production',\r\n build: {\r\n outDir: resolvedConfig.outDir,\r\n emptyOutDir: false,\r\n ssrManifest: true,\r\n rollupOptions: {\r\n input: clientInput,\r\n },\r\n },\r\n logLevel: options.verbose ? 'info' : 'warn',\r\n });\r\n\r\n // Build SSR bundle\r\n const ssrOutDir = path.join(resolvedConfig.outDir!, '.ssg');\r\n await vite.build({\r\n root,\r\n mode: 'production',\r\n build: {\r\n outDir: ssrOutDir,\r\n ssr: true,\r\n rollupOptions: {\r\n input: ssrEntry,\r\n },\r\n },\r\n logLevel: options.verbose ? 'info' : 'warn',\r\n });\r\n\r\n // Step 6: Collect all paths to render\r\n console.log('\uD83D\uDCDD Collecting paths to render...');\r\n const pathsToRender = await collectPaths(routes, root, warnings);\r\n console.log(` ${pathsToRender.length} path(s) to render`);\r\n\r\n // Pre-create all output directories to avoid mkdir contention during parallel rendering\r\n const outputDirs = new Set<string>();\r\n for (const pathInfo of pathsToRender) {\r\n const outputPath = getOutputPath(pathInfo.path, resolvedConfig.outDir!);\r\n outputDirs.add(path.dirname(outputPath));\r\n }\r\n await Promise.all(\r\n Array.from(outputDirs).map(dir => fs.mkdir(dir, { recursive: true }))\r\n );\r\n\r\n // Step 7: Render each path to HTML\r\n console.log('\uD83C\uDFA8 Rendering pages...');\r\n\r\n // Determine the SSR entry output name (based on input file name)\r\n const ssrEntryBasename = path.basename(ssrEntry, path.extname(ssrEntry));\r\n const ssrEntryName = ssrEntryBasename + '.js';\r\n\r\n // Pre-load the SSR module once for all pages\r\n const entryPath = path.join(ssrOutDir, ssrEntryName);\r\n const entryModule = await import(pathToFileURL(entryPath).href);\r\n\r\n // Load HTML template once\r\n const templatePath = path.join(resolvedConfig.outDir!, 'index.html');\r\n const template = await fs.readFile(templatePath, 'utf-8');\r\n\r\n // Parallel rendering configuration - higher concurrency since rendering is CPU-bound\r\n const CONCURRENCY = options.concurrency ?? 20; // Number of pages to render in parallel\r\n const verbose = options.verbose ?? false;\r\n\r\n interface RenderResult {\r\n pathInfo: PathToRender;\r\n html: string;\r\n outputPath: string;\r\n renderTime: number;\r\n }\r\n\r\n // Render a single page (CPU-bound, no I/O)\r\n async function renderPage(pathInfo: PathToRender): Promise<RenderResult | null> {\r\n const renderStart = Date.now();\r\n\r\n try {\r\n // Render the app\r\n const appHtml = await entryModule.render(pathInfo.path, {\r\n params: pathInfo.params,\r\n props: pathInfo.props,\r\n });\r\n\r\n // Inject into template\r\n let html = template.replace('<!--app-html-->', appHtml);\r\n const headTags = generateHeadTags(pathInfo, resolvedConfig);\r\n html = html.replace('<!--head-tags-->', headTags);\r\n\r\n const outputPath = getOutputPath(pathInfo.path, resolvedConfig.outDir!);\r\n const renderTime = Date.now() - renderStart;\r\n\r\n return { pathInfo, html, outputPath, renderTime };\r\n } catch (err) {\r\n const errorMessage = err instanceof Error ? err.message : String(err);\r\n console.error(` \u274C ${pathInfo.path}: ${errorMessage}`);\r\n warnings.push(`Failed to render ${pathInfo.path}: ${errorMessage}`);\r\n return null;\r\n }\r\n }\r\n\r\n // Render all pages in parallel batches (CPU-bound, no I/O)\r\n console.log(' Phase 1: Rendering...');\r\n const renderPhaseStart = Date.now();\r\n const renderResults: RenderResult[] = [];\r\n \r\n for (let i = 0; i < pathsToRender.length; i += CONCURRENCY) {\r\n const batch = pathsToRender.slice(i, i + CONCURRENCY);\r\n const results = await Promise.all(batch.map(renderPage));\r\n \r\n for (const result of results) {\r\n if (result) {\r\n renderResults.push(result);\r\n }\r\n }\r\n }\r\n const renderPhaseDuration = Date.now() - renderPhaseStart;\r\n console.log(` Phase 1 complete: ${renderResults.length} pages in ${renderPhaseDuration}ms (${Math.round(renderPhaseDuration / renderResults.length)}ms avg)`);\r\n\r\n // Write all files in parallel with limited concurrency\r\n console.log(' Phase 2: Writing files...');\r\n const writePhaseStart = Date.now();\r\n const WRITE_CONCURRENCY = 10; // Limit parallel writes to reduce I/O contention\r\n \r\n for (let i = 0; i < renderResults.length; i += WRITE_CONCURRENCY) {\r\n const batch = renderResults.slice(i, i + WRITE_CONCURRENCY);\r\n await Promise.all(batch.map(async (result) => {\r\n await fs.writeFile(result.outputPath, result.html, 'utf-8');\r\n const size = Buffer.byteLength(result.html, 'utf-8');\r\n\r\n pages.push({\r\n path: result.pathInfo.path,\r\n file: result.outputPath,\r\n time: result.renderTime,\r\n size,\r\n });\r\n \r\n if (verbose) {\r\n console.log(` \u2713 ${result.pathInfo.path} (${result.renderTime}ms, ${formatBytes(size)})`);\r\n }\r\n }));\r\n }\r\n const writePhaseDuration = Date.now() - writePhaseStart;\r\n console.log(` Phase 2 complete: ${renderResults.length} files in ${writePhaseDuration}ms`);\r\n \r\n // Summary (non-verbose)\r\n if (!verbose) {\r\n console.log(` \u2713 Rendered ${renderResults.length} pages`);\r\n }\r\n\r\n // Step 8: Clean up SSR build\r\n await fs.rm(ssrOutDir, { recursive: true, force: true });\r\n\r\n // Step 9: Generate sitemap and robots.txt\r\n if (pages.length > 0) {\r\n console.log('\uD83D\uDDFA\uFE0F Generating sitemap...');\r\n await writeSitemap(pages, resolvedConfig, resolvedConfig.outDir!);\r\n console.log(' \u2713 sitemap.xml');\r\n console.log(' \u2713 robots.txt');\r\n }\r\n\r\n } finally {\r\n // Clean up temporary entry files\r\n await cleanupTempEntries(root);\r\n \r\n // Clean up or restore HTML template\r\n if (cleanupHtml) {\r\n // We generated a virtual HTML, remove it\r\n try {\r\n await fs.unlink(htmlTemplatePath);\r\n } catch {\r\n // Ignore\r\n }\r\n } else if (originalHtmlContent !== null) {\r\n // We modified a custom HTML, restore the original\r\n try {\r\n await fs.writeFile(htmlTemplatePath, originalHtmlContent, 'utf-8');\r\n } catch {\r\n // Ignore\r\n }\r\n }\r\n }\r\n\r\n // Done\r\n const totalTime = Date.now() - startTime;\r\n\r\n console.log(`\\n\u2705 Built ${pages.length} page(s) in ${totalTime}ms`);\r\n\r\n if (warnings.length > 0) {\r\n console.log(`\\n\u26A0\uFE0F ${warnings.length} warning(s):`);\r\n for (const warning of warnings) {\r\n console.log(` - ${warning}`);\r\n }\r\n }\r\n\r\n console.log(`\\n\uD83D\uDCC1 Output: ${resolvedConfig.outDir}\\n`);\r\n\r\n return {\r\n pages,\r\n totalTime,\r\n warnings,\r\n };\r\n}\r\n\r\n/**\r\n * Path information for rendering\r\n */\r\ninterface PathToRender {\r\n path: string;\r\n route: SSGRoute;\r\n params: Record<string, string>;\r\n props?: Record<string, unknown>;\r\n}\r\n\r\n/**\r\n * Collect all paths to render, expanding dynamic routes\r\n */\r\nasync function collectPaths(\r\n routes: SSGRoute[],\r\n root: string,\r\n warnings: string[]\r\n): Promise<PathToRender[]> {\r\n const paths: PathToRender[] = [];\r\n\r\n for (const route of routes) {\r\n if (isDynamicRoute(route)) {\r\n // Load module and call getStaticPaths\r\n try {\r\n const moduleUrl = pathToFileURL(route.file).href;\r\n const pageModule = (await import(moduleUrl)) as PageModule;\r\n\r\n if (!pageModule.getStaticPaths) {\r\n const params = extractParams(route.path).join(', ');\r\n console.warn(\r\n `\\n\u26A0\uFE0F SSG102: Dynamic route missing getStaticPaths()\\n` +\r\n ` \uD83D\uDCC1 ${route.file}\\n` +\r\n ` Route: ${route.path} (params: ${params})\\n` +\r\n ` \uD83D\uDCA1 Export getStaticPaths() to generate static pages:\\n\\n` +\r\n ` export async function getStaticPaths() {\\n` +\r\n ` return [{ params: { ${params.split(', ')[0]}: 'value' } }];\\n` +\r\n ` }\\n`\r\n );\r\n warnings.push(\r\n `Route ${route.path} has dynamic segments [${params}] but no getStaticPaths() export. Skipping.`\r\n );\r\n continue;\r\n }\r\n\r\n const staticPaths = await pageModule.getStaticPaths();\r\n\r\n for (const staticPath of staticPaths) {\r\n const expandedPaths = expandDynamicRoute(route, [staticPath]);\r\n for (const expandedPath of expandedPaths) {\r\n paths.push({\r\n path: expandedPath,\r\n route,\r\n params: staticPath.params,\r\n props: staticPath.props,\r\n });\r\n }\r\n }\r\n } catch (err) {\r\n warnings.push(`Failed to load ${route.file}: ${err}`);\r\n }\r\n } else {\r\n paths.push({\r\n path: route.path,\r\n route,\r\n params: {},\r\n });\r\n }\r\n }\r\n\r\n return paths;\r\n}\r\n\r\n/**\r\n * Render a page to HTML\r\n */\r\nasync function renderPage(\r\n pathInfo: PathToRender,\r\n config: SSGConfig,\r\n ssrOutDir: string,\r\n ssrEntryName: string\r\n): Promise<string> {\r\n // Load the SSR entry module\r\n // This should export a render function that returns HTML string\r\n const entryPath = path.join(ssrOutDir, ssrEntryName);\r\n const entryModule = await import(pathToFileURL(entryPath).href);\r\n\r\n // Render the app - the entry module's render function handles SSR\r\n const appHtml = await entryModule.render(pathInfo.path, {\r\n params: pathInfo.params,\r\n props: pathInfo.props,\r\n });\r\n\r\n // Load HTML template\r\n const templatePath = path.join(config.outDir!, 'index.html');\r\n let template = await fs.readFile(templatePath, 'utf-8');\r\n\r\n // Inject app HTML\r\n template = template.replace('<!--app-html-->', appHtml);\r\n\r\n // Inject head tags if any\r\n const headTags = generateHeadTags(pathInfo, config);\r\n template = template.replace('<!--head-tags-->', headTags);\r\n\r\n return template;\r\n}\r\n\r\n/**\r\n * Generate head tags for a page\r\n */\r\nfunction generateHeadTags(pathInfo: PathToRender, config: SSGConfig): string {\r\n const tags: string[] = [];\r\n const meta = pathInfo.route.meta || {};\r\n\r\n // Title\r\n const title = meta.title || config.site?.title;\r\n if (title) {\r\n tags.push(`<title>${escapeHtml(title)}</title>`);\r\n }\r\n\r\n // Description\r\n const description = meta.description || config.site?.description;\r\n if (description) {\r\n tags.push(`<meta name=\"description\" content=\"${escapeHtml(description)}\">`);\r\n }\r\n\r\n // Canonical URL\r\n if (config.site?.url) {\r\n const canonical = new URL(pathInfo.path, config.site.url).href;\r\n tags.push(`<link rel=\"canonical\" href=\"${canonical}\">`);\r\n }\r\n\r\n return tags.join('\\n ');\r\n}\r\n\r\n/**\r\n * Get output file path for a URL path\r\n */\r\nfunction getOutputPath(urlPath: string, outDir: string): string {\r\n // Normalize path\r\n let normalized = urlPath.replace(/^\\//, '').replace(/\\/$/, '');\r\n\r\n if (!normalized) {\r\n normalized = 'index';\r\n }\r\n\r\n // Add .html extension or /index.html for directories\r\n if (!normalized.endsWith('.html')) {\r\n normalized = path.join(normalized, 'index.html');\r\n }\r\n\r\n return path.join(outDir, normalized);\r\n}\r\n\r\n/**\r\n * Get SSR entry point\r\n * Returns virtual module ID if no custom entry exists\r\n */\r\nasync function getSSREntryPoint(config: SSGConfig, root: string): Promise<string> {\r\n // Check for custom entry points\r\n const detection = detectCustomEntries(root, config);\r\n \r\n if (!detection.useVirtualServer && detection.customServerPath) {\r\n return detection.customServerPath;\r\n }\r\n\r\n // Use virtual server entry - we need to write a temp file for the build\r\n // because Rollup input must be a real file path\r\n const virtualServerCode = generateServerEntry(config);\r\n const tempServerPath = path.join(root, '.ssg-temp-entry-server.tsx');\r\n fsSync.writeFileSync(tempServerPath, virtualServerCode, 'utf-8');\r\n \r\n return tempServerPath;\r\n}\r\n\r\n/**\r\n * Get client entry point\r\n * Returns virtual module ID if no custom entry exists\r\n */\r\nasync function getClientEntryPoint(config: SSGConfig, root: string): Promise<string> {\r\n const detection = detectCustomEntries(root, config);\r\n \r\n if (!detection.useVirtualClient && detection.customClientPath) {\r\n return detection.customClientPath;\r\n }\r\n\r\n // Use virtual client entry - write a temp file\r\n const virtualClientCode = generateClientEntry(config, detection);\r\n const tempClientPath = path.join(root, '.ssg-temp-entry-client.tsx');\r\n fsSync.writeFileSync(tempClientPath, virtualClientCode, 'utf-8');\r\n \r\n return tempClientPath;\r\n}\r\n\r\n/**\r\n * Clean up temporary entry files\r\n */\r\nasync function cleanupTempEntries(root: string): Promise<void> {\r\n const tempFiles = [\r\n path.join(root, '.ssg-temp-entry-server.tsx'),\r\n path.join(root, '.ssg-temp-entry-client.tsx'),\r\n ];\r\n \r\n for (const file of tempFiles) {\r\n try {\r\n await fs.unlink(file);\r\n } catch {\r\n // Ignore if file doesn't exist\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Get or generate HTML template\r\n */\r\nasync function getHtmlTemplate(config: SSGConfig, root: string, clientEntryPath: string): Promise<string> {\r\n const detection = detectCustomEntries(root, config);\r\n \r\n if (!detection.useVirtualHtml && detection.customHtmlPath) {\r\n // Read custom HTML and update the script src to point to the temp entry file\r\n let html = await fs.readFile(detection.customHtmlPath, 'utf-8');\r\n // Replace any virtual SSG client paths with the actual temp entry path\r\n // Use relative path from root for the script src\r\n const relativePath = './' + path.relative(root, clientEntryPath).replace(/\\\\/g, '/');\r\n html = html.replace(\r\n /<script([^>]*)\\s+src=[\"']?\\/@ssg\\/client\\.tsx[\"']?/g,\r\n `<script$1 src=\"${relativePath}\"`\r\n );\r\n return html;\r\n }\r\n\r\n // Generate virtual HTML template\r\n return generateProductionHtmlTemplate(config, clientEntryPath);\r\n}\r\n\r\n/**\r\n * Format bytes to human-readable string\r\n */\r\nfunction formatBytes(bytes: number): string {\r\n if (bytes < 1024) return `${bytes}B`;\r\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)}KB`;\r\n return `${(bytes / (1024 * 1024)).toFixed(1)}MB`;\r\n}\r\n\r\n/**\r\n * Escape HTML special characters\r\n */\r\nfunction escapeHtml(str: string): string {\r\n return str\r\n .replace(/&/g, '&amp;')\r\n .replace(/</g, '&lt;')\r\n .replace(/>/g, '&gt;')\r\n .replace(/\"/g, '&quot;')\r\n .replace(/'/g, '&#39;');\r\n}\r\n", "/**\r\n * SSG Configuration helper\r\n */\r\n\r\nimport path from 'node:path';\r\nimport type { SSGConfig } from './types';\r\n\r\n/**\r\n * Define SSG configuration with type safety\r\n *\r\n * @example\r\n * ```ts\r\n * // ssg.config.ts\r\n * import { defineSSGConfig } from '@sigx/ssg';\r\n *\r\n * export default defineSSGConfig({\r\n * pages: 'src/pages',\r\n * layouts: 'src/layouts',\r\n * theme: '@sigx/ssg-theme-daisyui',\r\n * site: {\r\n * title: 'My Site',\r\n * description: 'A SignalX-powered static site'\r\n * }\r\n * });\r\n * ```\r\n */\r\nexport function defineSSGConfig(config: SSGConfig): SSGConfig {\r\n return {\r\n // Defaults\r\n pages: 'src/pages',\r\n layouts: 'src/layouts',\r\n content: 'src/content',\r\n defaultLayout: 'default',\r\n outDir: 'dist',\r\n base: '/',\r\n // Zero-config defaults\r\n autoEntries: true,\r\n prefetch: true,\r\n // User overrides\r\n ...config,\r\n // Merge nested objects\r\n site: {\r\n lang: 'en',\r\n ...config.site,\r\n },\r\n markdown: {\r\n shiki: true,\r\n ...config.markdown,\r\n },\r\n toc: {\r\n minLevel: 2,\r\n maxLevel: 3,\r\n ...config.toc,\r\n },\r\n };\r\n}\r\n\r\n/**\r\n * Load SSG config from file\r\n */\r\nexport async function loadConfig(configPath?: string): Promise<SSGConfig> {\r\n const fsPath = await import('node:path');\r\n const fs = await import('node:fs');\r\n const { pathToFileURL } = await import('node:url');\r\n const os = await import('node:os');\r\n\r\n // Find config file\r\n const cwd = process.cwd();\r\n const possiblePaths = configPath\r\n ? [fsPath.resolve(cwd, configPath)]\r\n : [\r\n fsPath.resolve(cwd, 'ssg.config.ts'),\r\n fsPath.resolve(cwd, 'ssg.config.js'),\r\n fsPath.resolve(cwd, 'ssg.config.mjs'),\r\n ];\r\n\r\n let foundPath: string | null = null;\r\n for (const p of possiblePaths) {\r\n if (fs.existsSync(p)) {\r\n foundPath = p;\r\n break;\r\n }\r\n }\r\n\r\n if (!foundPath) {\r\n console.warn('No ssg.config found, using defaults');\r\n return defineSSGConfig({});\r\n }\r\n\r\n try {\r\n // For TypeScript files, use esbuild to compile them first\r\n if (foundPath.endsWith('.ts')) {\r\n const esbuild = await import('esbuild');\r\n const tempDir = os.tmpdir();\r\n const tempFile = fsPath.join(tempDir, `ssg-config-${Date.now()}.mjs`);\r\n \r\n // Read and transform the TypeScript file\r\n const source = fs.readFileSync(foundPath, 'utf-8');\r\n \r\n // Transform: remove the import and defineSSGConfig wrapper\r\n // The config file typically does: export default defineSSGConfig({ ... })\r\n // We just need the config object, so we can transform it\r\n const result = await esbuild.transform(source, {\r\n loader: 'ts',\r\n format: 'esm',\r\n });\r\n \r\n // Write the transformed code to a temp file in the same directory as the config\r\n // This ensures relative imports and package resolution work correctly\r\n const configDir = fsPath.dirname(foundPath);\r\n const localTempFile = fsPath.join(configDir, `.ssg-config-temp-${Date.now()}.mjs`);\r\n \r\n fs.writeFileSync(localTempFile, result.code);\r\n \r\n try {\r\n const configModule = await import(pathToFileURL(localTempFile).href);\r\n return defineSSGConfig(configModule.default || configModule);\r\n } finally {\r\n // Clean up temp file\r\n try {\r\n fs.unlinkSync(localTempFile);\r\n } catch {\r\n // Ignore cleanup errors\r\n }\r\n }\r\n }\r\n \r\n // For JS files, import directly\r\n const configModule = await import(pathToFileURL(foundPath).href);\r\n return defineSSGConfig(configModule.default || configModule);\r\n } catch (err) {\r\n console.error(`Failed to load config from ${foundPath}:`, err);\r\n return defineSSGConfig({});\r\n }\r\n}\r\n\r\n/**\r\n * Resolve paths in config to absolute paths\r\n */\r\nexport function resolveConfigPaths(config: SSGConfig, root: string): SSGConfig {\r\n return {\r\n ...config,\r\n pages: path.resolve(root, config.pages || 'src/pages'),\r\n layouts: path.resolve(root, config.layouts || 'src/layouts'),\r\n content: path.resolve(root, config.content || 'src/content'),\r\n outDir: path.resolve(root, config.outDir || 'dist'),\r\n };\r\n}\r\n", "/**\r\n * File-based route scanner\r\n *\r\n * Scans a pages directory and generates route definitions from file paths.\r\n * Supports dynamic routes with [param] and catch-all with [...slug] patterns.\r\n */\r\n\r\nimport fg from 'fast-glob';\r\nimport path from 'node:path';\r\nimport fs from 'node:fs';\r\nimport type { SSGRoute, SSGConfig, PageMeta } from '../types';\r\nimport { parseFrontmatter } from '../mdx/frontmatter';\r\n\r\n/**\r\n * File extensions to treat as pages\r\n */\r\nconst PAGE_EXTENSIONS = ['.tsx', '.jsx', '.mdx', '.md'];\r\n\r\n/**\r\n * Files/directories to exclude from routing\r\n * \r\n * Only exclude common non-page folders at the ROOT of pages directory.\r\n * Nested folders like /docs/components/ are valid routes.\r\n */\r\nconst EXCLUDED_PATTERNS = [\r\n 'components/**', // Root-level components folder only\r\n 'hooks/**', // Root-level hooks folder only\r\n 'utils/**', // Root-level utils folder only\r\n 'lib/**', // Root-level lib folder only\r\n '**/_*', // Files/folders starting with underscore (at any level)\r\n '**/*.test.*',\r\n '**/*.spec.*',\r\n];\r\n\r\n/**\r\n * Scan pages directory and generate routes\r\n */\r\nexport async function scanPages(config: SSGConfig, root: string): Promise<SSGRoute[]> {\r\n const pagesDir = path.resolve(root, config.pages || 'src/pages');\r\n\r\n // Find all page files\r\n const patterns = PAGE_EXTENSIONS.map(ext => `**/*${ext}`);\r\n const files = await fg(patterns, {\r\n cwd: pagesDir,\r\n ignore: EXCLUDED_PATTERNS,\r\n onlyFiles: true,\r\n absolute: false,\r\n });\r\n\r\n // Convert files to routes (with frontmatter extraction)\r\n const routes: SSGRoute[] = [];\r\n\r\n for (const file of files) {\r\n const route = await fileToRouteWithMeta(file, pagesDir);\r\n if (route) {\r\n routes.push(route);\r\n }\r\n }\r\n\r\n // Sort routes by specificity (static > dynamic > catch-all)\r\n return sortRoutes(routes);\r\n}\r\n\r\n/**\r\n * Convert a file path to a route definition with frontmatter metadata\r\n */\r\nasync function fileToRouteWithMeta(filePath: string, pagesDir: string): Promise<SSGRoute | null> {\r\n const route = fileToRoute(filePath, pagesDir);\r\n if (!route) return null;\r\n\r\n // Extract frontmatter from MDX/MD files\r\n const ext = path.extname(filePath).toLowerCase();\r\n if (ext === '.mdx' || ext === '.md') {\r\n try {\r\n const content = fs.readFileSync(route.file, 'utf-8');\r\n const { data } = parseFrontmatter(content);\r\n route.meta = data;\r\n } catch (err) {\r\n // Ignore read errors - frontmatter just won't be available\r\n }\r\n }\r\n\r\n return route;\r\n}\r\n\r\n/**\r\n * Convert a file path to a route definition\r\n */\r\nexport function fileToRoute(filePath: string, pagesDir: string): SSGRoute | null {\r\n // Remove extension\r\n const ext = path.extname(filePath);\r\n let routePath = filePath.slice(0, -ext.length);\r\n\r\n // Handle index files\r\n if (routePath.endsWith('/index') || routePath === 'index') {\r\n routePath = routePath.replace(/\\/?index$/, '') || '/';\r\n }\r\n\r\n // Convert file path to URL path\r\n routePath = filePathToRoutePath(routePath);\r\n\r\n // Generate route name from path\r\n const name = pathToRouteName(routePath);\r\n\r\n return {\r\n path: routePath.startsWith('/') ? routePath : `/${routePath}`,\r\n file: path.join(pagesDir, filePath),\r\n name,\r\n };\r\n}\r\n\r\n/**\r\n * Convert file path patterns to route path patterns\r\n *\r\n * Examples:\r\n * blog/[slug] -> /blog/:slug\r\n * docs/[...path] -> /docs/*path\r\n * users/[id]/posts -> /users/:id/posts\r\n */\r\nexport function filePathToRoutePath(filePath: string): string {\r\n return filePath\r\n .split('/')\r\n .map(segment => {\r\n // Catch-all: [...slug] -> *slug\r\n if (segment.startsWith('[...') && segment.endsWith(']')) {\r\n const param = segment.slice(4, -1);\r\n return `*${param}`;\r\n }\r\n\r\n // Optional catch-all: [[...slug]] -> *slug (same behavior)\r\n if (segment.startsWith('[[...') && segment.endsWith(']]')) {\r\n const param = segment.slice(5, -2);\r\n return `*${param}`;\r\n }\r\n\r\n // Dynamic segment: [id] -> :id\r\n if (segment.startsWith('[') && segment.endsWith(']')) {\r\n const param = segment.slice(1, -1);\r\n return `:${param}`;\r\n }\r\n\r\n // Optional segment: [[id]] -> :id?\r\n if (segment.startsWith('[[') && segment.endsWith(']]')) {\r\n const param = segment.slice(2, -2);\r\n return `:${param}?`;\r\n }\r\n\r\n return segment;\r\n })\r\n .join('/');\r\n}\r\n\r\n/**\r\n * Convert route path to a route name\r\n *\r\n * Examples:\r\n * / -> index\r\n * /about -> about\r\n * /blog/:slug -> blog-slug\r\n * /docs/*path -> docs-path\r\n */\r\nexport function pathToRouteName(routePath: string): string {\r\n if (routePath === '/' || routePath === '') {\r\n return 'index';\r\n }\r\n\r\n return routePath\r\n .replace(/^\\//, '') // Remove leading slash\r\n .replace(/\\//g, '-') // Replace slashes with dashes\r\n .replace(/:/g, '') // Remove param colons\r\n .replace(/\\*/g, '') // Remove wildcards\r\n .replace(/\\?/g, '') // Remove optional markers\r\n .replace(/-+/g, '-') // Collapse multiple dashes\r\n .replace(/-$/, ''); // Remove trailing dash\r\n}\r\n\r\n/**\r\n * Sort routes by specificity\r\n *\r\n * Order:\r\n * 1. Static routes (most specific)\r\n * 2. Dynamic param routes\r\n * 3. Catch-all routes (least specific)\r\n *\r\n * Within each category, longer paths come first\r\n */\r\nexport function sortRoutes(routes: SSGRoute[]): SSGRoute[] {\r\n return routes.sort((a, b) => {\r\n const scoreA = getRouteScore(a.path);\r\n const scoreB = getRouteScore(b.path);\r\n\r\n // Higher score = more specific = should come first\r\n if (scoreA !== scoreB) {\r\n return scoreB - scoreA;\r\n }\r\n\r\n // Same score: longer paths first\r\n return b.path.length - a.path.length;\r\n });\r\n}\r\n\r\n/**\r\n * Calculate specificity score for a route\r\n */\r\nfunction getRouteScore(routePath: string): number {\r\n const segments = routePath.split('/').filter(Boolean);\r\n let score = 0;\r\n\r\n for (const segment of segments) {\r\n if (segment.startsWith('*')) {\r\n // Catch-all: lowest priority\r\n score += 1;\r\n } else if (segment.startsWith(':')) {\r\n // Dynamic param: medium priority\r\n score += 10;\r\n } else {\r\n // Static segment: highest priority\r\n score += 100;\r\n }\r\n }\r\n\r\n return score;\r\n}\r\n\r\n/**\r\n * Check if a route has dynamic segments\r\n */\r\nexport function isDynamicRoute(route: SSGRoute): boolean {\r\n return route.path.includes(':') || route.path.includes('*');\r\n}\r\n\r\n/**\r\n * Extract parameter names from a route path\r\n */\r\nexport function extractParams(routePath: string): string[] {\r\n const params: string[] = [];\r\n const segments = routePath.split('/');\r\n\r\n for (const segment of segments) {\r\n if (segment.startsWith(':')) {\r\n params.push(segment.slice(1).replace('?', ''));\r\n } else if (segment.startsWith('*')) {\r\n params.push(segment.slice(1));\r\n }\r\n }\r\n\r\n return params;\r\n}\r\n\r\n/**\r\n * Generate all static paths for a route using getStaticPaths\r\n */\r\nexport function expandDynamicRoute(\r\n route: SSGRoute,\r\n staticPaths: Array<{ params: Record<string, string> }>\r\n): string[] {\r\n const paths: string[] = [];\r\n\r\n for (const { params } of staticPaths) {\r\n let expandedPath = route.path;\r\n\r\n for (const [key, value] of Object.entries(params)) {\r\n // Replace :param with value\r\n expandedPath = expandedPath.replace(`:${key}`, value);\r\n // Replace *param with value\r\n expandedPath = expandedPath.replace(`*${key}`, value);\r\n }\r\n\r\n paths.push(expandedPath);\r\n }\r\n\r\n return paths;\r\n}\r\n", "/**\r\n * Frontmatter parser\r\n *\r\n * Extracts and parses YAML frontmatter from Markdown/MDX files.\r\n */\r\n\r\nimport matter from 'gray-matter';\r\nimport type { PageMeta } from '../types';\r\n\r\n/**\r\n * Result of parsing frontmatter\r\n */\r\nexport interface FrontmatterResult {\r\n /**\r\n * Parsed frontmatter data\r\n */\r\n data: PageMeta;\r\n\r\n /**\r\n * Content body without frontmatter\r\n */\r\n content: string;\r\n\r\n /**\r\n * Raw frontmatter string\r\n */\r\n raw: string;\r\n\r\n /**\r\n * Whether frontmatter was present\r\n */\r\n hasFrontmatter: boolean;\r\n}\r\n\r\n/**\r\n * Parse frontmatter from content\r\n */\r\nexport function parseFrontmatter(source: string): FrontmatterResult {\r\n const { data, content, matter: raw } = matter(source);\r\n\r\n return {\r\n data: normalizeFrontmatter(data),\r\n content,\r\n raw: raw || '',\r\n hasFrontmatter: !!raw,\r\n };\r\n}\r\n\r\n/**\r\n * Normalize frontmatter data to PageMeta\r\n */\r\nfunction normalizeFrontmatter(data: Record<string, unknown>): PageMeta {\r\n const meta: PageMeta = {};\r\n\r\n // Standard fields\r\n if (typeof data.title === 'string') meta.title = data.title;\r\n if (typeof data.description === 'string') meta.description = data.description;\r\n if (typeof data.layout === 'string') meta.layout = data.layout;\r\n if (typeof data.draft === 'boolean') meta.draft = data.draft;\r\n\r\n // Date handling\r\n if (data.date) {\r\n if (data.date instanceof Date) {\r\n meta.date = data.date;\r\n } else if (typeof data.date === 'string') {\r\n meta.date = new Date(data.date);\r\n }\r\n }\r\n\r\n // Tags\r\n if (Array.isArray(data.tags)) {\r\n meta.tags = data.tags.filter((t) => typeof t === 'string');\r\n }\r\n\r\n // SSR flag\r\n if (typeof data.ssr === 'boolean') meta.ssr = data.ssr;\r\n\r\n // Copy all other fields\r\n for (const [key, value] of Object.entries(data)) {\r\n if (!(key in meta)) {\r\n meta[key] = value;\r\n }\r\n }\r\n\r\n return meta;\r\n}\r\n\r\n/**\r\n * Extract title from markdown content if not in frontmatter\r\n *\r\n * Looks for the first H1 heading\r\n */\r\nexport function extractTitleFromContent(content: string): string | null {\r\n const h1Match = content.match(/^#\\s+(.+)$/m);\r\n return h1Match ? h1Match[1].trim() : null;\r\n}\r\n\r\n/**\r\n * Serialize frontmatter back to YAML string\r\n */\r\nexport function serializeFrontmatter(data: PageMeta): string {\r\n const lines: string[] = ['---'];\r\n\r\n for (const [key, value] of Object.entries(data)) {\r\n if (value === undefined) continue;\r\n\r\n if (value instanceof Date) {\r\n lines.push(`${key}: ${value.toISOString().split('T')[0]}`);\r\n } else if (Array.isArray(value)) {\r\n lines.push(`${key}:`);\r\n for (const item of value) {\r\n lines.push(` - ${JSON.stringify(item)}`);\r\n }\r\n } else if (typeof value === 'object' && value !== null) {\r\n lines.push(`${key}: ${JSON.stringify(value)}`);\r\n } else {\r\n lines.push(`${key}: ${JSON.stringify(value)}`);\r\n }\r\n }\r\n\r\n lines.push('---');\r\n return lines.join('\\n');\r\n}\r\n", "/**\r\n * Virtual module generator for routes\r\n *\r\n * Generates the virtual:ssg-routes module that exports all routes\r\n * for use by the router.\r\n */\r\n\r\nimport type { SSGRoute, SSGConfig } from '../types';\r\nimport { scanPages } from './scanner';\r\n\r\n/**\r\n * Virtual module ID for SSG routes\r\n */\r\nexport const VIRTUAL_ROUTES_ID = 'virtual:ssg-routes';\r\nexport const RESOLVED_VIRTUAL_ROUTES_ID = '\\0' + VIRTUAL_ROUTES_ID;\r\n\r\n/**\r\n * Normalize file path to use forward slashes (for ES module imports)\r\n */\r\nfunction normalizePath(filePath: string): string {\r\n return filePath.replace(/\\\\/g, '/');\r\n}\r\n\r\n/**\r\n * Generate the virtual routes module code\r\n */\r\nexport function generateRoutesModule(routes: SSGRoute[], config: SSGConfig): string {\r\n const imports: string[] = [];\r\n const routeDefinitions: string[] = [];\r\n\r\n for (let i = 0; i < routes.length; i++) {\r\n const route = routes[i];\r\n const componentName = `Page${i}`;\r\n const metaName = `meta${i}`;\r\n const normalizedFile = normalizePath(route.file);\r\n\r\n // Import the full module to access both default export and named exports\r\n imports.push(`import * as ${componentName}Module from '${normalizedFile}';`);\r\n\r\n // Build meta from module exports with safe access (avoid Rollup warnings)\r\n // For TSX pages, meta is a named export\r\n // For MDX pages, frontmatter might be attached to the default export\r\n // Also include headings for table of contents (exported by MDX plugin)\r\n imports.push(\r\n `const ${metaName} = { ...('meta' in ${componentName}Module ? ${componentName}Module.meta : ${componentName}Module.default?.frontmatter || ${JSON.stringify(route.meta || {})}), headings: 'headings' in ${componentName}Module ? ${componentName}Module.headings : [] };`\r\n );\r\n imports.push(\r\n `const ${componentName} = ${componentName}Module.default || ${componentName}Module;`\r\n );\r\n\r\n routeDefinitions.push(`\r\n {\r\n path: '${route.path}',\r\n name: '${route.name}',\r\n file: '${normalizedFile}',\r\n component: ${componentName},\r\n meta: ${metaName},\r\n layout: ${metaName}.layout || '${config.defaultLayout || 'default'}',\r\n }`);\r\n }\r\n\r\n return `\r\n${imports.join('\\n')}\r\n\r\nconst routes = [${routeDefinitions.join(',')}\r\n];\r\n\r\nexport default routes;\r\n`;\r\n}\r\n\r\n/**\r\n * Generate lazy-loading routes module (for development with HMR)\r\n */\r\nexport function generateLazyRoutesModule(routes: SSGRoute[], config: SSGConfig): string {\r\n const imports: string[] = [];\r\n const routeDefinitions: string[] = [];\r\n\r\n for (let i = 0; i < routes.length; i++) {\r\n const route = routes[i];\r\n const componentName = `Page${i}`;\r\n const metaName = `meta${i}`;\r\n const normalizedFile = normalizePath(route.file);\r\n\r\n // Import the module to read meta/frontmatter for layout resolution\r\n imports.push(`import * as ${componentName}Module from '${normalizedFile}';`);\r\n // Build meta with safe access to avoid Rollup warnings about missing exports\r\n imports.push(\r\n `const ${metaName} = { ...('meta' in ${componentName}Module ? ${componentName}Module.meta : ${componentName}Module.default?.frontmatter || ${JSON.stringify(route.meta || {})}), headings: 'headings' in ${componentName}Module ? ${componentName}Module.headings : [] };`\r\n );\r\n\r\n routeDefinitions.push(`\r\n {\r\n path: '${route.path}',\r\n name: '${route.name}',\r\n file: '${normalizedFile}',\r\n component: () => import('${normalizedFile}'),\r\n meta: ${metaName},\r\n layout: ${metaName}.layout || '${config.defaultLayout || 'default'}',\r\n }`);\r\n }\r\n\r\n return `\r\n${imports.join('\\n')}\r\n\r\nconst routes = [${routeDefinitions.join(',')}\r\n];\r\n\r\nexport default routes;\r\n`;\r\n}\r\n\r\n/**\r\n * Create a module loader for routes\r\n */\r\nexport async function loadRoutesModule(\r\n config: SSGConfig,\r\n root: string\r\n): Promise<{ routes: SSGRoute[]; code: string }> {\r\n const routes = await scanPages(config, root);\r\n const code = generateRoutesModule(routes, config);\r\n\r\n return { routes, code };\r\n}\r\n", "/**\r\n * Navigation generator for SSG\r\n *\r\n * Generates navigation structure from scanned routes based on\r\n * page frontmatter (category, order) or explicit configuration.\r\n */\r\n\r\nimport type { SSGRoute, SSGConfig, NavSection, NavItem, PageMeta, CollectionConfig } from '../types';\r\n\r\n/**\r\n * Collection navigation result\r\n */\r\nexport interface CollectionNavigation {\r\n sidebar: NavSection[];\r\n}\r\n\r\n/**\r\n * Internal type for building navigation tree\r\n */\r\ninterface NavBuildContext {\r\n categories: Map<string, NavBuildCategory>;\r\n uncategorized: NavBuildItem[];\r\n}\r\n\r\ninterface NavBuildCategory {\r\n title: string;\r\n order: number | undefined;\r\n items: NavBuildItem[];\r\n children: Map<string, NavBuildCategory>;\r\n}\r\n\r\ninterface NavBuildItem {\r\n title: string;\r\n href: string;\r\n order: number;\r\n}\r\n\r\n/**\r\n * Generate navigation structure from routes for a specific collection path\r\n *\r\n * @param routes - Scanned SSG routes\r\n * @param collectionPath - Path prefix for the collection (e.g., '/docs')\r\n * @param showDrafts - Whether to show draft pages\r\n * @param isDev - Whether running in development mode\r\n */\r\nexport function generateNavigation(\r\n routes: SSGRoute[],\r\n collectionPath: string,\r\n showDrafts: 'dev' | 'never',\r\n isDev: boolean\r\n): CollectionNavigation {\r\n // Filter routes for navigation\r\n const navRoutes = routes.filter((route) => {\r\n // Must be under collection path\r\n if (!route.path.startsWith(collectionPath)) {\r\n return false;\r\n }\r\n\r\n const meta = route.meta || {};\r\n\r\n // Check sidebar flag (default true)\r\n if (meta.sidebar === false) {\r\n return false;\r\n }\r\n\r\n // Handle draft pages\r\n if (meta.draft) {\r\n if (showDrafts === 'never') {\r\n return false;\r\n }\r\n if (showDrafts === 'dev' && !isDev) {\r\n return false;\r\n }\r\n }\r\n\r\n return true;\r\n });\r\n\r\n // Build navigation structure\r\n const context: NavBuildContext = {\r\n categories: new Map(),\r\n uncategorized: [],\r\n };\r\n\r\n for (const route of navRoutes) {\r\n const meta = route.meta || {};\r\n const title = meta.title || routeToTitle(route.path);\r\n const order = typeof meta.order === 'number' ? meta.order : 999;\r\n const category = meta.category;\r\n\r\n const item: NavBuildItem = {\r\n title,\r\n href: route.path,\r\n order,\r\n };\r\n\r\n if (!category) {\r\n // No category - add to uncategorized\r\n context.uncategorized.push(item);\r\n } else if (typeof category === 'string') {\r\n // Single category\r\n addToCategory(context.categories, [category], item);\r\n } else if (Array.isArray(category)) {\r\n // Nested categories\r\n addToCategory(context.categories, category, item);\r\n }\r\n }\r\n\r\n // Convert to NavSection array\r\n const sidebar = buildSections(context);\r\n\r\n return { sidebar };\r\n}\r\n\r\n/**\r\n * Add an item to a nested category structure\r\n */\r\nfunction addToCategory(\r\n categories: Map<string, NavBuildCategory>,\r\n path: string[],\r\n item: NavBuildItem\r\n): void {\r\n if (path.length === 0) {\r\n return;\r\n }\r\n\r\n const [first, ...rest] = path;\r\n\r\n let category = categories.get(first);\r\n if (!category) {\r\n category = {\r\n title: first,\r\n order: undefined,\r\n items: [],\r\n children: new Map(),\r\n };\r\n categories.set(first, category);\r\n }\r\n\r\n if (rest.length === 0) {\r\n // This is the target category\r\n category.items.push(item);\r\n } else {\r\n // Recurse into children\r\n addToCategory(category.children, rest, item);\r\n }\r\n}\r\n\r\n/**\r\n * Common section ordering for navigation\r\n * Used for both top-level sections and nested categories\r\n */\r\nconst SECTION_ORDER: Record<string, number> = {\r\n 'Getting Started': 10,\r\n 'Core Concepts': 20,\r\n 'Core': 20,\r\n 'Built-in Components': 30,\r\n 'Components': 30,\r\n 'Guides': 40,\r\n 'Advanced': 50,\r\n 'Ecosystem': 60,\r\n 'API Reference': 70,\r\n 'API': 70,\r\n 'Reference': 80,\r\n // DaisyUI component categories (matching DaisyUI website)\r\n 'Actions': 100,\r\n 'Data Display': 110,\r\n 'Navigation': 120,\r\n 'Feedback': 130,\r\n 'Data Input': 140,\r\n 'Layout': 150,\r\n 'Mockup': 160,\r\n 'Other': 999,\r\n};\r\n\r\n/**\r\n * Get sort order for a section/category title\r\n */\r\nfunction getSectionOrder(title: string, explicitOrder?: number): number {\r\n if (explicitOrder !== undefined) {\r\n return explicitOrder;\r\n }\r\n return SECTION_ORDER[title] ?? 50;\r\n}\r\n\r\n/**\r\n * Build NavSection array from context\r\n */\r\nfunction buildSections(context: NavBuildContext): NavSection[] {\r\n const sections: NavSection[] = [];\r\n\r\n // Add categorized items\r\n for (const [, category] of context.categories) {\r\n sections.push(buildSection(category));\r\n }\r\n\r\n // Add uncategorized items as a section if any exist\r\n if (context.uncategorized.length > 0) {\r\n sections.push({\r\n title: 'Other',\r\n items: context.uncategorized\r\n .sort((a, b) => a.order - b.order || a.title.localeCompare(b.title))\r\n .map((item) => ({\r\n title: item.title,\r\n href: item.href,\r\n order: item.order,\r\n })),\r\n order: 999,\r\n });\r\n }\r\n\r\n sections.sort((a, b) => {\r\n const orderA = getSectionOrder(a.title, a.order);\r\n const orderB = getSectionOrder(b.title, b.order);\r\n return orderA - orderB;\r\n });\r\n\r\n return sections;\r\n}\r\n\r\n/**\r\n * Build a NavSection from a category\r\n */\r\nfunction buildSection(category: NavBuildCategory): NavSection {\r\n // Sort items\r\n const sortedItems = category.items\r\n .sort((a, b) => a.order - b.order || a.title.localeCompare(b.title))\r\n .map((item) => ({\r\n title: item.title,\r\n href: item.href,\r\n order: item.order,\r\n }));\r\n\r\n // Build nested children\r\n const childSections: NavItem[] = [];\r\n for (const [, child] of category.children) {\r\n childSections.push(buildNestedSection(child));\r\n }\r\n\r\n // Merge items and child sections\r\n const items: NavItem[] = [...sortedItems];\r\n\r\n // Add nested sections as groups, sorted by section order\r\n for (const nested of childSections.sort((a, b) => {\r\n const orderA = getSectionOrder(a.title, a.order);\r\n const orderB = getSectionOrder(b.title, b.order);\r\n return orderA - orderB;\r\n })) {\r\n items.push(nested);\r\n }\r\n\r\n return {\r\n title: category.title,\r\n items,\r\n order: category.order,\r\n };\r\n}\r\n\r\n/**\r\n * Build a nested NavItem from a child category\r\n */\r\nfunction buildNestedSection(category: NavBuildCategory): NavItem {\r\n const sortedItems = category.items\r\n .sort((a, b) => a.order - b.order || a.title.localeCompare(b.title))\r\n .map((item) => ({\r\n title: item.title,\r\n href: item.href,\r\n order: item.order,\r\n }));\r\n\r\n // Recursively build children\r\n const childItems: NavItem[] = [];\r\n for (const [, child] of category.children) {\r\n childItems.push(buildNestedSection(child));\r\n }\r\n\r\n return {\r\n title: category.title,\r\n items: [...sortedItems, ...childItems.sort((a, b) => (a.order ?? 0) - (b.order ?? 0))],\r\n order: category.order,\r\n };\r\n}\r\n\r\n/**\r\n * Convert route path to a display title\r\n *\r\n * @example '/docs/getting-started' -> 'Getting Started'\r\n * @example '/docs/api/router' -> 'Router'\r\n */\r\nfunction routeToTitle(routePath: string): string {\r\n const segments = routePath.split('/').filter(Boolean);\r\n const lastSegment = segments[segments.length - 1] || 'Home';\r\n\r\n return lastSegment\r\n .replace(/-/g, ' ')\r\n .replace(/\\b\\w/g, (c) => c.toUpperCase());\r\n}\r\n\r\n/**\r\n * Merge explicit sidebar config with auto-generated navigation\r\n */\r\nexport function mergeNavigation(\r\n autoGenerated: NavSection[],\r\n explicit: NavSection[]\r\n): NavSection[] {\r\n const merged = new Map<string, NavSection>();\r\n\r\n // Add auto-generated first\r\n for (const section of autoGenerated) {\r\n merged.set(section.title, section);\r\n }\r\n\r\n // Override/add explicit sections\r\n for (const section of explicit) {\r\n if (merged.has(section.title)) {\r\n // Merge items\r\n const existing = merged.get(section.title)!;\r\n merged.set(section.title, {\r\n ...existing,\r\n ...section,\r\n items: [...existing.items, ...section.items],\r\n });\r\n } else {\r\n merged.set(section.title, section);\r\n }\r\n }\r\n\r\n return Array.from(merged.values());\r\n}\r\n\r\n/**\r\n * Generate navigation for all collections\r\n *\r\n * @param routes - Scanned SSG routes\r\n * @param config - SSG configuration\r\n * @param isDev - Whether running in development mode\r\n * @returns Record mapping collection names to their navigation\r\n */\r\nexport function generateAllCollections(\r\n routes: SSGRoute[],\r\n config: SSGConfig,\r\n isDev: boolean\r\n): Record<string, CollectionNavigation> {\r\n const collections = config.collections || {};\r\n const result: Record<string, CollectionNavigation> = {};\r\n\r\n for (const [name, collectionConfig] of Object.entries(collections)) {\r\n const showDrafts = collectionConfig.showDrafts ?? config.navigation?.showDrafts ?? 'dev';\r\n result[name] = generateNavigation(routes, collectionConfig.path, showDrafts, isDev);\r\n }\r\n\r\n return result;\r\n}\r\n\r\n/**\r\n * Detect which collection a route path belongs to\r\n *\r\n * @param path - Current route path\r\n * @param collections - Collections configuration\r\n * @returns The collection name if found, undefined otherwise\r\n */\r\nexport function detectCollection(\r\n path: string,\r\n collections: Record<string, CollectionConfig>\r\n): string | undefined {\r\n // Sort by path length descending to match most specific path first\r\n const sorted = Object.entries(collections).sort(\r\n ([, a], [, b]) => b.path.length - a.path.length\r\n );\r\n\r\n for (const [name, config] of sorted) {\r\n if (path.startsWith(config.path)) {\r\n return name;\r\n }\r\n }\r\n\r\n return undefined;\r\n}\r\n", "/**\r\n * Virtual module generator for navigation\r\n *\r\n * Generates the virtual:ssg-navigation module that exports\r\n * the navigation structure for all collections.\r\n */\r\n\r\nimport type { SSGConfig, NavSection, NavItem, CollectionConfig } from '../types';\r\nimport type { SSGRoute } from '../types';\r\nimport { generateAllCollections, detectCollection as detectCollectionImpl, CollectionNavigation } from './navigation';\r\n\r\n/**\r\n * Virtual module ID for SSG navigation\r\n */\r\nexport const VIRTUAL_NAVIGATION_ID = 'virtual:ssg-navigation';\r\nexport const RESOLVED_VIRTUAL_NAVIGATION_ID = '\\0' + VIRTUAL_NAVIGATION_ID;\r\n\r\n/**\r\n * Navigation module result type\r\n */\r\nexport interface NavigationModule {\r\n /** Navigation keyed by collection name */\r\n navigation: Record<string, CollectionNavigation>;\r\n /** Collections configuration for path detection */\r\n collections: Record<string, CollectionConfig>;\r\n}\r\n\r\n/**\r\n * Generate the virtual navigation module code\r\n *\r\n * @param routes - Scanned SSG routes with metadata\r\n * @param config - SSG configuration\r\n * @param isDev - Whether running in development mode\r\n */\r\nexport function generateNavigationModule(\r\n routes: SSGRoute[],\r\n config: SSGConfig,\r\n isDev: boolean\r\n): string {\r\n const navigation = generateAllCollections(routes, config, isDev);\r\n const collections = config.collections || {};\r\n\r\n // Serialize navigation and collections to JSON\r\n const navJson = JSON.stringify(navigation, null, 2);\r\n const collectionsJson = JSON.stringify(collections, null, 2);\r\n\r\n return `\r\n/**\r\n * Auto-generated navigation module\r\n * \r\n * @generated by @sigx/ssg\r\n */\r\n\r\n/**\r\n * Navigation for all collections, keyed by collection name\r\n */\r\nexport const navigation = ${navJson};\r\n\r\n/**\r\n * Collections configuration\r\n */\r\nconst collections = ${collectionsJson};\r\n\r\n/**\r\n * Get navigation for a specific collection\r\n * @param name - Collection name (e.g., 'docs', 'examples')\r\n * @returns The collection's navigation or undefined if not found\r\n */\r\nexport function getCollectionNav(name) {\r\n return navigation[name];\r\n}\r\n\r\n/**\r\n * Detect which collection a route path belongs to\r\n * @param path - Current route path\r\n * @returns The collection name if found, undefined otherwise\r\n */\r\nexport function detectCollection(path) {\r\n // Sort by path length descending to match most specific path first\r\n const sorted = Object.entries(collections).sort(\r\n ([, a], [, b]) => b.path.length - a.path.length\r\n );\r\n\r\n for (const [name, config] of sorted) {\r\n if (path.startsWith(config.path)) {\r\n return name;\r\n }\r\n }\r\n\r\n return undefined;\r\n}\r\n\r\n/**\r\n * Get sidebar for a specific collection\r\n * @param name - Collection name\r\n * @returns The sidebar array or empty array if not found\r\n */\r\nexport function getSidebar(name) {\r\n return navigation[name]?.sidebar || [];\r\n}\r\n\r\nexport default { navigation, collections, getCollectionNav, detectCollection, getSidebar };\r\n`;\r\n}\r\n\r\n/**\r\n * Create a loader for the navigation module\r\n */\r\nexport async function loadNavigationModule(\r\n routes: SSGRoute[],\r\n config: SSGConfig,\r\n isDev: boolean\r\n): Promise<{ navigation: Record<string, CollectionNavigation>; code: string }> {\r\n const navigation = generateAllCollections(routes, config, isDev);\r\n const code = generateNavigationModule(routes, config, isDev);\r\n return { navigation, code };\r\n}\r\n", "/**\r\n * Layout resolver\r\n *\r\n * Resolves layouts from local layouts directory or theme packages.\r\n * Layouts wrap page content and provide consistent structure.\r\n */\r\n\r\nimport fg from 'fast-glob';\r\nimport path from 'node:path';\r\nimport fs from 'node:fs';\r\nimport type { SSGConfig, LayoutModule, ThemeModule } from '../types';\r\n\r\n/**\r\n * Discovered layout information\r\n */\r\nexport interface LayoutInfo {\r\n /**\r\n * Layout name (e.g., 'default', 'docs', 'blog')\r\n */\r\n name: string;\r\n\r\n /**\r\n * Absolute file path to the layout component\r\n */\r\n file: string;\r\n\r\n /**\r\n * Source: 'local' or theme package name\r\n */\r\n source: string;\r\n}\r\n\r\n/**\r\n * Layout extensions to search for\r\n */\r\nconst LAYOUT_EXTENSIONS = ['.tsx', '.jsx'];\r\n\r\n/**\r\n * Scan local layouts directory\r\n */\r\nexport async function scanLocalLayouts(config: SSGConfig, root: string): Promise<LayoutInfo[]> {\r\n const layoutsDir = path.resolve(root, config.layouts || 'src/layouts');\r\n\r\n if (!fs.existsSync(layoutsDir)) {\r\n return [];\r\n }\r\n\r\n const patterns = LAYOUT_EXTENSIONS.map((ext) => `*${ext}`);\r\n const files = await fg(patterns, {\r\n cwd: layoutsDir,\r\n onlyFiles: true,\r\n absolute: false,\r\n });\r\n\r\n return files.map((file) => {\r\n const ext = path.extname(file);\r\n const name = file.slice(0, -ext.length);\r\n\r\n return {\r\n name,\r\n file: path.join(layoutsDir, file),\r\n source: 'local',\r\n };\r\n });\r\n}\r\n\r\n/**\r\n * Load layouts from a theme package\r\n */\r\nexport async function loadThemeLayouts(themeName: string, root: string): Promise<LayoutInfo[]> {\r\n try {\r\n // Import theme package from the project's context\r\n // Use createRequire to resolve from the project root\r\n const { createRequire } = await import('node:module');\r\n const { pathToFileURL } = await import('node:url');\r\n const require = createRequire(path.join(root, 'package.json'));\r\n \r\n // Resolve the theme package directory from the project\r\n // Use require.resolve with the package.json to get the package directory\r\n const themePackageJson = require.resolve(`${themeName}/package.json`);\r\n const themeDir = path.dirname(themePackageJson);\r\n \r\n // Read the package.json to find the main export\r\n const packageJson = JSON.parse(fs.readFileSync(themePackageJson, 'utf-8'));\r\n const mainFile = packageJson.exports?.['.']?.import || packageJson.main || './dist/index.js';\r\n const themePath = path.resolve(themeDir, mainFile);\r\n \r\n const themeModule = (await import(pathToFileURL(themePath).href)) as ThemeModule;\r\n\r\n if (!themeModule.layouts) {\r\n return [];\r\n }\r\n\r\n // Theme layouts are already loaded as components\r\n // We need to create virtual files for them\r\n return Object.keys(themeModule.layouts).map((name) => ({\r\n name,\r\n file: `${themeName}/layouts/${name}`,\r\n source: themeName,\r\n }));\r\n } catch (err) {\r\n console.warn(`Failed to load theme ${themeName}:`, err);\r\n return [];\r\n }\r\n}\r\n\r\n/**\r\n * Discover all available layouts\r\n *\r\n * Priority order:\r\n * 1. Local layouts (can override theme)\r\n * 2. Theme layouts\r\n */\r\nexport async function discoverLayouts(config: SSGConfig, root: string): Promise<LayoutInfo[]> {\r\n const layouts: Map<string, LayoutInfo> = new Map();\r\n\r\n // Load theme layouts first (can be overridden)\r\n if (config.theme) {\r\n const themeLayouts = await loadThemeLayouts(config.theme, root);\r\n for (const layout of themeLayouts) {\r\n layouts.set(layout.name, layout);\r\n }\r\n }\r\n\r\n // Load local layouts (override theme)\r\n const localLayouts = await scanLocalLayouts(config, root);\r\n for (const layout of localLayouts) {\r\n layouts.set(layout.name, layout);\r\n }\r\n\r\n return Array.from(layouts.values());\r\n}\r\n\r\n/**\r\n * Get the default layout\r\n */\r\nexport function getDefaultLayout(layouts: LayoutInfo[], config: SSGConfig): LayoutInfo | null {\r\n const defaultName = config.defaultLayout || 'default';\r\n return layouts.find((l) => l.name === defaultName) || layouts[0] || null;\r\n}\r\n\r\n/**\r\n * Find a layout by name\r\n */\r\nexport function findLayout(layouts: LayoutInfo[], name: string): LayoutInfo | null {\r\n return layouts.find((l) => l.name === name) || null;\r\n}\r\n", "/**\r\n * Virtual module generator for layouts\r\n *\r\n * Generates the virtual:generated-layouts module that provides\r\n * layout components and the setupLayouts function.\r\n * \r\n * IMPORTANT: Layouts are designed to persist across navigation.\r\n * Instead of wrapping each route with a layout component (which causes\r\n * full re-renders on navigation), we use a shared LayoutRouter component\r\n * that maintains the layout and only updates the page content reactively.\r\n */\r\n\r\nimport type { SSGConfig, SSGRoute } from '../types';\r\nimport type { LayoutInfo } from './resolver';\r\nimport { discoverLayouts } from './resolver';\r\n\r\n// Note: The generated virtual module imports component from sigx\r\n\r\n/**\r\n * Virtual module ID for generated layouts\r\n */\r\nexport const VIRTUAL_LAYOUTS_ID = 'virtual:generated-layouts';\r\nexport const RESOLVED_VIRTUAL_LAYOUTS_ID = '\\0virtual:generated-layouts';\r\n\r\n/**\r\n * Normalize file path to use forward slashes (for ES module imports)\r\n */\r\nfunction normalizePath(filePath: string): string {\r\n return filePath.replace(/\\\\/g, '/');\r\n}\r\n\r\n/**\r\n * Generate the virtual layouts module code\r\n */\r\nexport function generateLayoutsModule(layouts: LayoutInfo[], config: SSGConfig): string {\r\n const imports: string[] = [];\r\n const layoutEntries: string[] = [];\r\n\r\n for (let i = 0; i < layouts.length; i++) {\r\n const layout = layouts[i];\r\n const importName = `Layout${i}`;\r\n\r\n // Handle theme vs local layouts differently\r\n if (layout.source === 'local') {\r\n const normalizedFile = normalizePath(layout.file);\r\n imports.push(`import ${importName} from '${normalizedFile}';`);\r\n } else {\r\n // Theme layout - import from theme package\r\n imports.push(`import { layouts as themeLayouts${i} } from '${layout.source}';`);\r\n imports.push(`const ${importName} = themeLayouts${i}['${layout.name}'];`);\r\n }\r\n\r\n layoutEntries.push(` '${layout.name}': ${importName}.default || ${importName}`);\r\n }\r\n\r\n return `\r\nimport { component, signal, jsx } from 'sigx';\r\nimport { useRoute } from '@sigx/router';\r\n${imports.join('\\n')}\r\n\r\n/**\r\n * All available layouts\r\n */\r\nexport const layouts = {\r\n${layoutEntries.join(',\\n')}\r\n};\r\n\r\n/**\r\n * Default layout name\r\n */\r\nexport const defaultLayout = '${config.defaultLayout || 'default'}';\r\n\r\n/**\r\n * Check if a component is marked as lazy (created by lazy())\r\n */\r\nfunction isMarkedLazy(component) {\r\n return component && component.__lazy === true;\r\n}\r\n\r\n/**\r\n * Check if a value is a Promise/thenable\r\n */\r\nfunction isPromise(value) {\r\n return value && typeof value.then === 'function';\r\n}\r\n\r\n/**\r\n * Track hydration state - we're hydrating if the app container has SSR content\r\n */\r\nlet isHydrating = typeof window !== 'undefined' && \r\n document.getElementById('app')?.innerHTML?.trim().length > 0;\r\n\r\n// After first render, we're no longer hydrating\r\nif (typeof window !== 'undefined') {\r\n const markHydrationComplete = () => { isHydrating = false; };\r\n if ('requestIdleCallback' in window) {\r\n window.requestIdleCallback(markHydrationComplete);\r\n } else {\r\n setTimeout(markHydrationComplete, 0);\r\n }\r\n}\r\n\r\n/**\r\n * Placeholder component that preserves existing DOM during hydration.\r\n */\r\nconst HydrationPlaceholder = component(() => {\r\n return () => null;\r\n}, { name: 'HydrationPlaceholder' });\r\n\r\n/**\r\n * Layout router component that preserves layouts across navigation.\r\n * \r\n * This component renders the current route's layout and page content reactively.\r\n * When navigating between routes with the same layout, only the page content\r\n * updates - the layout (Navbar, Sidebar, Footer) persists without re-rendering.\r\n */\r\nexport const LayoutRouter = component((ctx) => {\r\n const route = useRoute();\r\n \r\n // Track loaded lazy components to avoid reloading\r\n const loadedComponents = {};\r\n \r\n // Track if this is the initial hydration render\r\n let initialRender = true;\r\n \r\n // HMR support: Listen for MDX updates and clear the component cache\r\n if (typeof window !== 'undefined' && import.meta.hot) {\r\n // Listen for sigx:mdx-hmr events dispatched by MDX files after they accept HMR\r\n const handleMdxHmr = (event) => {\r\n const { moduleId, newModule } = event.detail || {};\r\n \r\n // Clear all cached components to force reload with new module\r\n for (const key in loadedComponents) {\r\n delete loadedComponents[key];\r\n }\r\n \r\n // If we have the new module directly from HMR, cache it for the matching route\r\n if (newModule?.default) {\r\n const currentPath = route.path;\r\n loadedComponents[currentPath] = newModule.default;\r\n }\r\n \r\n // Force re-render\r\n ctx.update();\r\n };\r\n \r\n window.addEventListener('sigx:mdx-hmr', handleMdxHmr);\r\n \r\n ctx.onUnmounted(() => {\r\n window.removeEventListener('sigx:mdx-hmr', handleMdxHmr);\r\n });\r\n }\r\n \r\n return () => {\r\n const matched = route.matched;\r\n if (!matched || matched.length === 0) return null;\r\n \r\n const match = matched[0];\r\n if (!match) return null;\r\n \r\n // Get layout name from route meta or use default\r\n const layoutName = match.layout || match.meta?.layout || defaultLayout;\r\n const Layout = layouts[layoutName];\r\n \r\n if (!Layout) {\r\n console.warn(\\`Layout \"\\${layoutName}\" not found for route \\${route.path}\\`);\r\n return null;\r\n }\r\n \r\n // Get the original (unwrapped) component\r\n const rawComponent = match.originalComponent || match.component;\r\n const routePath = route.path;\r\n \r\n // Handle lazy/dynamic import components\r\n if (isMarkedLazy(rawComponent) || (typeof rawComponent === 'function' && !rawComponent.__setup)) {\r\n // Check if already loaded\r\n if (loadedComponents[routePath]) {\r\n const PageComponent = loadedComponents[routePath];\r\n initialRender = false;\r\n return jsx(Layout, { \r\n meta: match.meta, \r\n path: routePath, \r\n key: layoutName, // Key by layout to preserve layout across pages\r\n children: PageComponent({}) \r\n });\r\n }\r\n \r\n // Load the component\r\n const loadState = signal({ value: null, loading: true, error: null });\r\n \r\n try {\r\n const result = rawComponent();\r\n if (isPromise(result)) {\r\n result.then(module => {\r\n const Component = module.default || module;\r\n loadedComponents[routePath] = Component;\r\n loadState.value = Component;\r\n loadState.loading = false;\r\n }).catch(err => {\r\n console.error('Failed to load component for route:', routePath, err);\r\n loadState.error = err;\r\n loadState.loading = false;\r\n });\r\n } else {\r\n // Not a promise, use directly\r\n loadedComponents[routePath] = rawComponent;\r\n loadState.value = rawComponent;\r\n loadState.loading = false;\r\n }\r\n } catch (err) {\r\n loadState.error = err;\r\n loadState.loading = false;\r\n }\r\n \r\n // During hydration, preserve existing SSR content instead of showing loading state\r\n if (loadState.loading) {\r\n if (isHydrating && initialRender) {\r\n return jsx(Layout, { \r\n meta: match.meta, \r\n path: routePath, \r\n key: layoutName,\r\n children: jsx(HydrationPlaceholder, {})\r\n });\r\n }\r\n return jsx(Layout, { \r\n meta: match.meta, \r\n path: routePath, \r\n key: layoutName,\r\n children: null \r\n });\r\n }\r\n \r\n if (loadState.error || !loadState.value) {\r\n return jsx(Layout, { \r\n meta: match.meta, \r\n path: routePath, \r\n key: layoutName,\r\n children: null \r\n });\r\n }\r\n \r\n const PageComponent = loadState.value;\r\n initialRender = false;\r\n return jsx(Layout, { \r\n meta: match.meta, \r\n path: routePath, \r\n key: layoutName,\r\n children: PageComponent({}) \r\n });\r\n }\r\n \r\n // Eager component (has __setup)\r\n // Check cache first for HMR-updated components\r\n if (loadedComponents[routePath]) {\r\n const PageComponent = loadedComponents[routePath];\r\n initialRender = false;\r\n return jsx(Layout, { \r\n meta: match.meta, \r\n path: routePath, \r\n key: layoutName,\r\n children: PageComponent({}) \r\n });\r\n }\r\n \r\n initialRender = false;\r\n return jsx(Layout, { \r\n meta: match.meta, \r\n path: routePath, \r\n key: layoutName,\r\n children: rawComponent({}) \r\n });\r\n };\r\n}, { name: 'LayoutRouter' });\r\n\r\n/**\r\n * Setup layouts for routes\r\n *\r\n * This function now simply annotates routes with their layout information.\r\n * The actual layout wrapping is handled by LayoutRouter, which preserves\r\n * layouts across navigation.\r\n */\r\nexport function setupLayouts(routes) {\r\n const availableLayoutNames = Object.keys(layouts);\r\n \r\n return routes.map(route => {\r\n const layoutName = route.layout || route.meta?.layout || defaultLayout;\r\n const Layout = layouts[layoutName];\r\n\r\n if (!Layout) {\r\n console.error(\r\n \\`\u274C SSG103: Layout \"\\${layoutName}\" not found for route \\${route.path}\\\\n\\` +\r\n \\` \uD83D\uDCC1 \\${route.file || 'unknown'}\\\\n\\` +\r\n \\` \uD83D\uDCA1 Available layouts: \\${availableLayoutNames.join(', ') || 'none'}\\\\n\\` +\r\n \\` Create src/layouts/\\${layoutName}.tsx or set a valid layout in frontmatter.\\`\r\n );\r\n return route;\r\n }\r\n\r\n // Store layout info on the route, but don't wrap the component\r\n // LayoutRouter will handle layout rendering\r\n return {\r\n ...route,\r\n layout: layoutName,\r\n originalComponent: route.component,\r\n meta: {\r\n ...route.meta,\r\n layout: layoutName,\r\n },\r\n };\r\n });\r\n}\r\n\r\nexport default layouts;\r\n`;\r\n}\r\n\r\n/**\r\n * Generate a simpler layouts module for theme-only setups\r\n */\r\nexport function generateThemeLayoutsModule(themeName: string, config: SSGConfig): string {\r\n return `\r\nimport { component, signal, jsx } from 'sigx';\r\nimport { useRoute } from '@sigx/router';\r\nimport { layouts as themeLayouts, config as themeConfig } from '${themeName}';\r\n\r\nexport const layouts = themeLayouts || {};\r\nexport const defaultLayout = '${config.defaultLayout}' || themeConfig?.defaultLayout || 'default';\r\n\r\n/**\r\n * Check if a component is marked as lazy (created by lazy())\r\n */\r\nfunction isMarkedLazy(component) {\r\n return component && component.__lazy === true;\r\n}\r\n\r\n/**\r\n * Check if a value is a Promise/thenable\r\n */\r\nfunction isPromise(value) {\r\n return value && typeof value.then === 'function';\r\n}\r\n\r\n/**\r\n * Layout router component that preserves layouts across navigation.\r\n */\r\nexport const LayoutRouter = component((ctx) => {\r\n const route = useRoute();\r\n const loadedComponents = {};\r\n \r\n // HMR support: Listen for MDX updates and clear the component cache\r\n if (typeof window !== 'undefined' && import.meta.hot) {\r\n const handleMdxHmr = (event) => {\r\n for (const key in loadedComponents) {\r\n delete loadedComponents[key];\r\n }\r\n ctx.update();\r\n };\r\n \r\n window.addEventListener('sigx:mdx-hmr', handleMdxHmr);\r\n \r\n import.meta.hot.on('vite:beforeUpdate', (payload) => {\r\n const hasMdxUpdate = payload.updates?.some(update => \r\n update.path?.endsWith('.mdx') || update.path?.endsWith('.md')\r\n );\r\n if (hasMdxUpdate) {\r\n for (const key in loadedComponents) {\r\n delete loadedComponents[key];\r\n }\r\n }\r\n });\r\n \r\n ctx.onUnmounted(() => {\r\n window.removeEventListener('sigx:mdx-hmr', handleMdxHmr);\r\n });\r\n }\r\n \r\n return () => {\r\n const matched = route.matched;\r\n if (!matched || matched.length === 0) return null;\r\n \r\n const match = matched[0];\r\n if (!match) return null;\r\n \r\n const layoutName = match.layout || match.meta?.layout || defaultLayout;\r\n const Layout = layouts[layoutName];\r\n \r\n if (!Layout) {\r\n console.warn(\\`Layout \"\\${layoutName}\" not found for route \\${route.path}\\`);\r\n return null;\r\n }\r\n \r\n const rawComponent = match.originalComponent || match.component;\r\n const routePath = route.path;\r\n \r\n // Handle lazy/dynamic import components\r\n if (isMarkedLazy(rawComponent) || (typeof rawComponent === 'function' && !rawComponent.__setup)) {\r\n if (loadedComponents[routePath]) {\r\n const PageComponent = loadedComponents[routePath];\r\n return jsx(Layout, { \r\n meta: match.meta, \r\n path: routePath, \r\n key: layoutName,\r\n children: PageComponent({}) \r\n });\r\n }\r\n \r\n const loadState = signal({ value: null, loading: true, error: null });\r\n \r\n try {\r\n const result = rawComponent();\r\n if (isPromise(result)) {\r\n result.then(module => {\r\n const Component = module.default || module;\r\n loadedComponents[routePath] = Component;\r\n loadState.value = Component;\r\n loadState.loading = false;\r\n }).catch(err => {\r\n console.error('Failed to load component:', routePath, err);\r\n loadState.error = err;\r\n loadState.loading = false;\r\n });\r\n } else {\r\n loadedComponents[routePath] = rawComponent;\r\n loadState.value = rawComponent;\r\n loadState.loading = false;\r\n }\r\n } catch (err) {\r\n loadState.error = err;\r\n loadState.loading = false;\r\n }\r\n \r\n if (loadState.loading) {\r\n return jsx(Layout, { meta: match.meta, path: routePath, key: layoutName, children: null });\r\n }\r\n if (loadState.error || !loadState.value) {\r\n return jsx(Layout, { meta: match.meta, path: routePath, key: layoutName, children: null });\r\n }\r\n \r\n return jsx(Layout, { \r\n meta: match.meta, \r\n path: routePath, \r\n key: layoutName,\r\n children: loadState.value({}) \r\n });\r\n }\r\n \r\n return jsx(Layout, { \r\n meta: match.meta, \r\n path: routePath, \r\n key: layoutName,\r\n children: rawComponent({}) \r\n });\r\n };\r\n}, { name: 'LayoutRouter' });\r\n\r\nexport function setupLayouts(routes) {\r\n return routes.map(route => {\r\n const layoutName = route.layout || route.meta?.layout || defaultLayout;\r\n const Layout = layouts[layoutName];\r\n\r\n if (!Layout) {\r\n console.warn(\\`Layout \"\\${layoutName}\" not found for route \\${route.path}\\`);\r\n return route;\r\n }\r\n\r\n return {\r\n ...route,\r\n layout: layoutName,\r\n originalComponent: route.component,\r\n meta: {\r\n ...route.meta,\r\n layout: layoutName,\r\n },\r\n };\r\n });\r\n}\r\n\r\nexport default layouts;\r\n`;\r\n}\r\n\r\n/**\r\n * Load and generate the layouts module\r\n */\r\nexport async function loadLayoutsModule(\r\n config: SSGConfig,\r\n root: string\r\n): Promise<{ layouts: LayoutInfo[]; code: string }> {\r\n const layouts = await discoverLayouts(config, root);\r\n const code = generateLayoutsModule(layouts, config);\r\n\r\n return { layouts, code };\r\n}\r\n", "/**\r\n * Sitemap Generation\r\n *\r\n * Generates XML sitemaps for SSG sites following the sitemap protocol.\r\n * https://www.sitemaps.org/protocol.html\r\n */\r\n\r\nimport fs from 'node:fs/promises';\r\nimport path from 'node:path';\r\nimport type { SSGConfig, PageBuildResult } from './types';\r\n\r\n/**\r\n * Sitemap entry with optional metadata\r\n */\r\nexport interface SitemapEntry {\r\n /** URL path (relative to site base) */\r\n path: string;\r\n /** Last modification date */\r\n lastmod?: Date | string;\r\n /** Change frequency hint */\r\n changefreq?: 'always' | 'hourly' | 'daily' | 'weekly' | 'monthly' | 'yearly' | 'never';\r\n /** Priority relative to other pages (0.0 to 1.0) */\r\n priority?: number;\r\n}\r\n\r\n/**\r\n * Sitemap generation options\r\n */\r\nexport interface SitemapOptions {\r\n /** Include all built pages automatically */\r\n includePages?: boolean;\r\n /** Additional URLs to include */\r\n additionalUrls?: SitemapEntry[];\r\n /** URLs to exclude (glob patterns or exact matches) */\r\n exclude?: string[];\r\n /** Default change frequency */\r\n defaultChangefreq?: SitemapEntry['changefreq'];\r\n /** Default priority */\r\n defaultPriority?: number;\r\n}\r\n\r\n/**\r\n * Generate sitemap XML content\r\n */\r\nexport function generateSitemap(\r\n entries: SitemapEntry[],\r\n config: SSGConfig\r\n): string {\r\n const siteUrl = config.site?.url?.replace(/\\/$/, '') || '';\r\n const base = config.base?.replace(/\\/$/, '') || '';\r\n\r\n const urlEntries = entries.map((entry) => {\r\n const loc = `${siteUrl}${base}${entry.path}`;\r\n const lastmod = entry.lastmod\r\n ? typeof entry.lastmod === 'string'\r\n ? entry.lastmod\r\n : entry.lastmod.toISOString().split('T')[0]\r\n : undefined;\r\n\r\n return ` <url>\r\n <loc>${escapeXml(loc)}</loc>${lastmod ? `\r\n <lastmod>${lastmod}</lastmod>` : ''}${entry.changefreq ? `\r\n <changefreq>${entry.changefreq}</changefreq>` : ''}${entry.priority !== undefined ? `\r\n <priority>${entry.priority.toFixed(1)}</priority>` : ''}\r\n </url>`;\r\n });\r\n\r\n return `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">\r\n${urlEntries.join('\\n')}\r\n</urlset>`;\r\n}\r\n\r\n/**\r\n * Generate robots.txt content\r\n */\r\nexport function generateRobotsTxt(config: SSGConfig, sitemapPath = '/sitemap.xml'): string {\r\n const siteUrl = config.site?.url?.replace(/\\/$/, '') || '';\r\n const base = config.base?.replace(/\\/$/, '') || '';\r\n\r\n return `User-agent: *\r\nAllow: /\r\n\r\nSitemap: ${siteUrl}${base}${sitemapPath}\r\n`;\r\n}\r\n\r\n/**\r\n * Convert page build results to sitemap entries\r\n */\r\nexport function pagesToSitemapEntries(\r\n pages: PageBuildResult[],\r\n options: SitemapOptions = {}\r\n): SitemapEntry[] {\r\n const {\r\n exclude = [],\r\n defaultChangefreq = 'weekly',\r\n defaultPriority = 0.5,\r\n } = options;\r\n\r\n return pages\r\n .filter((page) => {\r\n // Filter out excluded paths\r\n for (const pattern of exclude) {\r\n if (pattern.includes('*')) {\r\n // Simple glob matching\r\n const regex = new RegExp(\r\n '^' + pattern.replace(/\\*/g, '.*').replace(/\\?/g, '.') + '$'\r\n );\r\n if (regex.test(page.path)) return false;\r\n } else if (page.path === pattern) {\r\n return false;\r\n }\r\n }\r\n return true;\r\n })\r\n .map((page) => {\r\n // Determine priority based on path depth\r\n const depth = page.path.split('/').filter(Boolean).length;\r\n let priority = defaultPriority;\r\n \r\n if (page.path === '/') {\r\n priority = 1.0; // Homepage highest priority\r\n } else if (depth === 1) {\r\n priority = 0.8; // Top-level pages\r\n } else if (depth === 2) {\r\n priority = 0.6; // Second-level pages\r\n }\r\n\r\n return {\r\n path: page.path,\r\n changefreq: defaultChangefreq,\r\n priority,\r\n };\r\n });\r\n}\r\n\r\n/**\r\n * Write sitemap and robots.txt to output directory\r\n */\r\nexport async function writeSitemap(\r\n pages: PageBuildResult[],\r\n config: SSGConfig,\r\n outDir: string,\r\n options: SitemapOptions = {}\r\n): Promise<{ sitemapPath: string; robotsPath: string }> {\r\n // Generate entries from pages\r\n const entries = pagesToSitemapEntries(pages, options);\r\n\r\n // Add additional URLs if provided\r\n if (options.additionalUrls) {\r\n entries.push(...options.additionalUrls);\r\n }\r\n\r\n // Generate sitemap XML\r\n const sitemapContent = generateSitemap(entries, config);\r\n const sitemapPath = path.join(outDir, 'sitemap.xml');\r\n await fs.writeFile(sitemapPath, sitemapContent, 'utf-8');\r\n\r\n // Generate robots.txt\r\n const robotsContent = generateRobotsTxt(config);\r\n const robotsPath = path.join(outDir, 'robots.txt');\r\n await fs.writeFile(robotsPath, robotsContent, 'utf-8');\r\n\r\n return { sitemapPath, robotsPath };\r\n}\r\n\r\n/**\r\n * Escape special XML characters\r\n */\r\nfunction escapeXml(str: string): string {\r\n return str\r\n .replace(/&/g, '&amp;')\r\n .replace(/</g, '&lt;')\r\n .replace(/>/g, '&gt;')\r\n .replace(/\"/g, '&quot;')\r\n .replace(/'/g, '&apos;');\r\n}\r\n", "/**\r\n * Virtual Entry Point Generation\r\n * \r\n * Generates auto-configured client and server entry points for zero-config mode.\r\n * Users can override by providing their own entry files.\r\n */\r\n\r\nimport fs from 'node:fs';\r\nimport path from 'node:path';\r\nimport type { SSGConfig } from '../types';\r\n\r\n/**\r\n * Virtual module IDs\r\n * Note: We use a special path format that Vite can resolve from HTML\r\n */\r\nexport const VIRTUAL_CLIENT_ID = 'virtual:ssg-client';\r\nexport const RESOLVED_VIRTUAL_CLIENT_ID = '\\0' + VIRTUAL_CLIENT_ID + '.tsx';\r\n\r\n// Special entry path that can be used in HTML and resolved by the plugin\r\nexport const SSG_CLIENT_ENTRY_PATH = '/@ssg/client.tsx';\r\n\r\nexport const VIRTUAL_SERVER_ID = 'virtual:ssg-server';\r\nexport const RESOLVED_VIRTUAL_SERVER_ID = '\\0' + VIRTUAL_SERVER_ID + '.tsx';\r\n\r\nexport const VIRTUAL_HTML_ID = 'virtual:ssg-html';\r\nexport const RESOLVED_VIRTUAL_HTML_ID = '\\0' + VIRTUAL_HTML_ID;\r\n\r\n/**\r\n * Detection result for custom entry points\r\n */\r\nexport interface EntryDetectionResult {\r\n /** Whether to use virtual client entry */\r\n useVirtualClient: boolean;\r\n /** Whether to use virtual server entry */\r\n useVirtualServer: boolean;\r\n /** Whether to use virtual HTML template */\r\n useVirtualHtml: boolean;\r\n /** Path to custom client entry if found */\r\n customClientPath?: string;\r\n /** Path to custom server entry if found */\r\n customServerPath?: string;\r\n /** Path to custom HTML template if found */\r\n customHtmlPath?: string;\r\n /** Path to global CSS if found */\r\n globalCssPath?: string;\r\n}\r\n\r\n/**\r\n * Detect if user has custom entry points\r\n */\r\nexport function detectCustomEntries(root: string, config: SSGConfig): EntryDetectionResult {\r\n // Custom client entry paths (if found, user has custom setup)\r\n const clientPaths = [\r\n 'src/main.tsx',\r\n 'src/main.ts',\r\n 'src/entry-client.tsx',\r\n 'src/entry-client.ts',\r\n 'src/entry.tsx',\r\n 'src/entry.ts',\r\n ];\r\n\r\n const serverPaths = [\r\n 'src/entry-server.tsx',\r\n 'src/entry-server.ts',\r\n ];\r\n\r\n const htmlPaths = [\r\n 'index.html',\r\n ];\r\n\r\n // Global CSS to auto-import (checked in order of preference)\r\n const cssPaths = [\r\n 'src/styles/global.css',\r\n 'src/styles/main.css',\r\n 'src/styles/index.css',\r\n 'src/style.css',\r\n 'src/global.css',\r\n 'src/index.css',\r\n ];\r\n\r\n let customClientPath: string | undefined;\r\n let customServerPath: string | undefined;\r\n let customHtmlPath: string | undefined;\r\n let globalCssPath: string | undefined;\r\n\r\n // Check for custom client entry\r\n for (const p of clientPaths) {\r\n const fullPath = path.join(root, p);\r\n if (fs.existsSync(fullPath)) {\r\n customClientPath = fullPath;\r\n break;\r\n }\r\n }\r\n\r\n // Check for custom server entry\r\n for (const p of serverPaths) {\r\n const fullPath = path.join(root, p);\r\n if (fs.existsSync(fullPath)) {\r\n customServerPath = fullPath;\r\n break;\r\n }\r\n }\r\n\r\n // Check for custom HTML template\r\n for (const p of htmlPaths) {\r\n const fullPath = path.join(root, p);\r\n if (fs.existsSync(fullPath)) {\r\n customHtmlPath = fullPath;\r\n break;\r\n }\r\n }\r\n\r\n // Check for global CSS\r\n for (const p of cssPaths) {\r\n const fullPath = path.join(root, p);\r\n if (fs.existsSync(fullPath)) {\r\n globalCssPath = '/' + p.replace(/\\\\/g, '/');\r\n break;\r\n }\r\n }\r\n\r\n return {\r\n useVirtualClient: !customClientPath,\r\n useVirtualServer: !customServerPath,\r\n useVirtualHtml: !customHtmlPath,\r\n customClientPath,\r\n customServerPath,\r\n customHtmlPath,\r\n globalCssPath,\r\n };\r\n}\r\n\r\n/**\r\n * Generate virtual client entry code\r\n */\r\nexport function generateClientEntry(config: SSGConfig, detection: EntryDetectionResult): string {\r\n const cssImport = detection.globalCssPath\r\n ? `import '${detection.globalCssPath}';\\n`\r\n : '';\r\n\r\n // Additional client imports from config\r\n const additionalImports = (config.clientImports ?? [])\r\n .map(imp => `import '${imp}';`)\r\n .join('\\n');\r\n const additionalImportsBlock = additionalImports ? `\\n${additionalImports}\\n` : '';\r\n\r\n const prefetchDelay = typeof config.prefetch === 'object'\r\n ? config.prefetch.delay ?? 100\r\n : 100;\r\n\r\n const prefetchEnabled = config.prefetch !== false;\r\n\r\n return `/**\r\n * Auto-generated client entry point\r\n * This file is generated by @sigx/ssg when no custom entry is detected.\r\n * To customize, create src/main.tsx or src/entry-client.tsx\r\n */\r\n${cssImport}${additionalImportsBlock}\r\nimport { defineApp, component } from 'sigx';\r\nimport { createRouter, createWebHistory } from '@sigx/router';\r\nimport { ssrClientPlugin } from '@sigx/ssg/client';\r\nimport routes from 'virtual:ssg-routes';\r\nimport { setupLayouts, LayoutRouter } from 'virtual:generated-layouts';\r\n${prefetchEnabled ? `import { setupPrefetch } from '@sigx/ssg/client';` : ''}\r\n\r\n// Apply layouts to routes (annotates routes with layout info)\r\nconst layoutRoutes = setupLayouts(routes);\r\n\r\n// Create router with browser history\r\nconst router = createRouter({\r\n history: createWebHistory('${config.base || '/'}'),\r\n routes: layoutRoutes,\r\n scrollBehavior(to, from, savedPosition) {\r\n if (savedPosition) return savedPosition;\r\n if (to.hash) return { el: to.hash };\r\n return { top: 0 };\r\n },\r\n});\r\n\r\n// Root app component - uses LayoutRouter which preserves layouts across navigation\r\nconst App = component(() => {\r\n return () => <LayoutRouter />;\r\n});\r\n\r\n// Hydrate the server-rendered HTML\r\ndefineApp(<App />)\r\n .use(router)\r\n .use(ssrClientPlugin)\r\n .hydrate('#app');\r\n\r\n${prefetchEnabled ? `// Enable link prefetching for faster navigation\r\nsetupPrefetch({ delay: ${prefetchDelay} });` : ''}\r\n`;\r\n}\r\n\r\n/**\r\n * Generate virtual server entry code\r\n */\r\nexport function generateServerEntry(config: SSGConfig): string {\r\n return `/**\r\n * Auto-generated server entry point\r\n * This file is generated by @sigx/ssg when no custom entry is detected.\r\n * To customize, create src/entry-server.tsx\r\n */\r\nimport { renderToString } from '@sigx/server-renderer/server';\r\nimport { defineApp } from 'sigx';\r\nimport { createRouter, createMemoryHistory } from '@sigx/router';\r\nimport routes from 'virtual:ssg-routes';\r\nimport { setupLayouts, LayoutRouter } from 'virtual:generated-layouts';\r\n\r\n// Pre-process routes with layouts once at module load time (not per-render)\r\nconst routesWithLayouts = setupLayouts(routes);\r\n\r\n/**\r\n * Render the app to HTML string for a given URL\r\n */\r\nexport async function render(url, context) {\r\n // Create router with memory history for SSR\r\n // Note: We must create a new router per render because history is URL-specific\r\n const router = createRouter({\r\n routes: routesWithLayouts,\r\n history: createMemoryHistory({ initialLocation: url || '/' }),\r\n });\r\n\r\n // Create app with router - router's install() sets up DI via app.defineProvide()\r\n const app = defineApp(<LayoutRouter />).use(router);\r\n \r\n const html = await renderToString(app);\r\n return html;\r\n}\r\n`;\r\n}\r\n\r\n/**\r\n * Generate virtual HTML template\r\n */\r\nexport function generateHtmlTemplate(config: SSGConfig): string {\r\n const site = config.site || {};\r\n const lang = site.lang || 'en';\r\n const title = site.title || 'SignalX App';\r\n const description = site.description || '';\r\n const favicon = site.favicon || '/favicon.ico';\r\n const themeColor = site.themeColor || '#000000';\r\n const ogImage = site.ogImage || '';\r\n const url = site.url || '';\r\n const twitter = site.twitter || '';\r\n const fonts = site.fonts || [];\r\n\r\n // Build font preconnect and stylesheet links\r\n let fontLinks = '';\r\n if (fonts.length > 0) {\r\n fontLinks = `\r\n <link rel=\"preconnect\" href=\"https://fonts.googleapis.com\" />\r\n <link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin />\r\n <link href=\"https://fonts.googleapis.com/css2?family=${fonts.join('&family=')}&display=swap\" rel=\"stylesheet\" />`;\r\n }\r\n\r\n // Build OG meta tags\r\n let ogTags = '';\r\n if (url || ogImage) {\r\n ogTags = `\r\n <!-- Open Graph -->\r\n <meta property=\"og:type\" content=\"website\" />\r\n <meta property=\"og:title\" content=\"${title}\" />\r\n <meta property=\"og:description\" content=\"${description}\" />${url ? `\r\n <meta property=\"og:url\" content=\"${url}\" />` : ''}${ogImage ? `\r\n <meta property=\"og:image\" content=\"${ogImage}\" />` : ''}`;\r\n }\r\n\r\n // Build Twitter card tags\r\n let twitterTags = '';\r\n if (twitter || ogImage) {\r\n twitterTags = `\r\n <!-- Twitter Card -->\r\n <meta name=\"twitter:card\" content=\"${ogImage ? 'summary_large_image' : 'summary'}\" />${twitter ? `\r\n <meta name=\"twitter:site\" content=\"@${twitter}\" />` : ''}\r\n <meta name=\"twitter:title\" content=\"${title}\" />\r\n <meta name=\"twitter:description\" content=\"${description}\" />${ogImage ? `\r\n <meta name=\"twitter:image\" content=\"${ogImage}\" />` : ''}`;\r\n }\r\n\r\n return `<!DOCTYPE html>\r\n<html lang=\"${lang}\">\r\n<head>\r\n <meta charset=\"UTF-8\" />\r\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\r\n <meta name=\"description\" content=\"${description}\" />\r\n <meta name=\"theme-color\" content=\"${themeColor}\" />\r\n <link rel=\"icon\" type=\"image/x-icon\" href=\"${favicon}\" />${fontLinks}${ogTags}${twitterTags}\r\n <title>${title}</title>\r\n <!--head-tags-->\r\n</head>\r\n<body>\r\n <div id=\"app\"><!--app-html--></div>\r\n <script type=\"module\" src=\"/@ssg/client.tsx\"></script>\r\n</body>\r\n</html>\r\n`;\r\n}\r\n\r\n/**\r\n * Generate HTML template for production build\r\n * Uses the actual client entry path instead of virtual module\r\n */\r\nexport function generateProductionHtmlTemplate(config: SSGConfig, clientEntryPath: string): string {\r\n const site = config.site || {};\r\n const lang = site.lang || 'en';\r\n const title = site.title || 'SignalX App';\r\n const description = site.description || '';\r\n const favicon = site.favicon || '/favicon.ico';\r\n const themeColor = site.themeColor || '#000000';\r\n const ogImage = site.ogImage || '';\r\n const url = site.url || '';\r\n const twitter = site.twitter || '';\r\n const fonts = site.fonts || [];\r\n\r\n // Build font preconnect and stylesheet links\r\n let fontLinks = '';\r\n if (fonts.length > 0) {\r\n fontLinks = `\r\n <link rel=\"preconnect\" href=\"https://fonts.googleapis.com\" />\r\n <link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin />\r\n <link href=\"https://fonts.googleapis.com/css2?family=${fonts.join('&family=')}&display=swap\" rel=\"stylesheet\" />`;\r\n }\r\n\r\n // Build OG meta tags\r\n let ogTags = '';\r\n if (url || ogImage) {\r\n ogTags = `\r\n <!-- Open Graph -->\r\n <meta property=\"og:type\" content=\"website\" />\r\n <meta property=\"og:title\" content=\"${title}\" />\r\n <meta property=\"og:description\" content=\"${description}\" />${url ? `\r\n <meta property=\"og:url\" content=\"${url}\" />` : ''}${ogImage ? `\r\n <meta property=\"og:image\" content=\"${ogImage}\" />` : ''}`;\r\n }\r\n\r\n // Build Twitter card tags\r\n let twitterTags = '';\r\n if (twitter || ogImage) {\r\n twitterTags = `\r\n <!-- Twitter Card -->\r\n <meta name=\"twitter:card\" content=\"${ogImage ? 'summary_large_image' : 'summary'}\" />${twitter ? `\r\n <meta name=\"twitter:site\" content=\"@${twitter}\" />` : ''}\r\n <meta name=\"twitter:title\" content=\"${title}\" />\r\n <meta name=\"twitter:description\" content=\"${description}\" />${ogImage ? `\r\n <meta name=\"twitter:image\" content=\"${ogImage}\" />` : ''}`;\r\n }\r\n\r\n return `<!DOCTYPE html>\r\n<html lang=\"${lang}\">\r\n<head>\r\n <meta charset=\"UTF-8\" />\r\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\r\n <meta name=\"description\" content=\"${description}\" />\r\n <meta name=\"theme-color\" content=\"${themeColor}\" />\r\n <link rel=\"icon\" type=\"image/x-icon\" href=\"${favicon}\" />${fontLinks}${ogTags}${twitterTags}\r\n <title>${title}</title>\r\n <!--head-tags-->\r\n</head>\r\n<body>\r\n <div id=\"app\"><!--app-html--></div>\r\n <script type=\"module\" src=\"${clientEntryPath}\"></script>\r\n</body>\r\n</html>\r\n`;\r\n}\r\n", "/**\r\n * SSG Dev Server\r\n *\r\n * Starts a Vite development server with SSG plugins pre-configured.\r\n * Provides a unified `ssg dev` command for zero-config development.\r\n */\r\n\r\nimport path from 'node:path';\r\nimport fs from 'node:fs';\r\nimport type { SSGConfig } from './types';\r\nimport { loadConfig } from './config';\r\nimport { ssgPlugin } from './vite/plugin';\r\n\r\n/**\r\n * Dev server options\r\n */\r\nexport interface DevOptions {\r\n /**\r\n * Path to ssg.config.ts\r\n */\r\n configPath?: string;\r\n\r\n /**\r\n * Port to run dev server on\r\n * @default 5173\r\n */\r\n port?: number;\r\n\r\n /**\r\n * Host to bind to\r\n * @default 'localhost'\r\n */\r\n host?: string | boolean;\r\n\r\n /**\r\n * Open browser automatically\r\n * @default false\r\n */\r\n open?: boolean;\r\n\r\n /**\r\n * Enable verbose logging\r\n */\r\n verbose?: boolean;\r\n}\r\n\r\n/**\r\n * Start the SSG development server\r\n */\r\nexport async function dev(options: DevOptions = {}): Promise<void> {\r\n const root = process.cwd();\r\n\r\n console.log('\\n\uD83D\uDE80 @sigx/ssg - Starting development server...\\n');\r\n\r\n // Load SSG config\r\n const ssgConfig = await loadConfig(options.configPath);\r\n\r\n // Check if user has a vite.config.ts\r\n const hasViteConfig = fs.existsSync(path.join(root, 'vite.config.ts')) ||\r\n fs.existsSync(path.join(root, 'vite.config.js')) ||\r\n fs.existsSync(path.join(root, 'vite.config.mjs'));\r\n\r\n // Import Vite\r\n const vite = await import('vite');\r\n\r\n if (hasViteConfig) {\r\n // User has their own vite.config - use it directly\r\n // They should have ssgPlugin() configured already\r\n console.log('\uD83D\uDCE6 Using existing vite.config\\n');\r\n\r\n const server = await vite.createServer({\r\n root,\r\n server: {\r\n port: options.port,\r\n host: options.host,\r\n open: options.open,\r\n },\r\n });\r\n\r\n await server.listen();\r\n server.printUrls();\r\n } else {\r\n // Zero-config mode - configure everything automatically\r\n console.log('\uD83D\uDCE6 Zero-config mode enabled\\n');\r\n\r\n // Try to import @sigx/vite plugin\r\n let sigxPlugin: ((...args: any[]) => any) | undefined;\r\n try {\r\n const sigxVite = await import('@sigx/vite');\r\n sigxPlugin = sigxVite.sigxPlugin;\r\n } catch {\r\n console.warn('\u26A0\uFE0F @sigx/vite not found, JSX transform may not work');\r\n console.warn(' Install with: npm install @sigx/vite\\n');\r\n }\r\n\r\n // Build plugins array\r\n const plugins: any[] = [];\r\n\r\n // Add Tailwind CSS if available\r\n try {\r\n // @ts-expect-error - Optional dependency\r\n const tailwind = await import('@tailwindcss/vite');\r\n plugins.push(tailwind.default());\r\n } catch {\r\n // Tailwind not installed, skip\r\n }\r\n\r\n // Add SignalX plugin if available\r\n if (sigxPlugin) {\r\n plugins.push(sigxPlugin());\r\n }\r\n\r\n // Add SSG plugin\r\n plugins.push(...ssgPlugin({ configPath: options.configPath }));\r\n\r\n const server = await vite.createServer({\r\n root,\r\n plugins,\r\n // Vite 8 uses oxc instead of esbuild for JSX transforms\r\n oxc: {\r\n jsx: {\r\n runtime: 'automatic',\r\n importSource: 'sigx',\r\n }\r\n },\r\n server: {\r\n port: options.port ?? 5173,\r\n host: options.host,\r\n open: options.open,\r\n },\r\n });\r\n\r\n await server.listen();\r\n server.printUrls();\r\n }\r\n}\r\n\r\n/**\r\n * Preview the production build\r\n */\r\nexport async function preview(options: DevOptions = {}): Promise<void> {\r\n const root = process.cwd();\r\n\r\n console.log('\\n\uD83D\uDC40 @sigx/ssg - Preview server...\\n');\r\n\r\n const vite = await import('vite');\r\n\r\n const server = await vite.preview({\r\n root,\r\n preview: {\r\n port: options.port ?? 4173,\r\n host: options.host,\r\n open: options.open,\r\n },\r\n });\r\n\r\n server.printUrls();\r\n console.log('\\n');\r\n}\r\n", "/**\r\n * SSG Vite Plugin\r\n *\r\n * Main Vite plugin for @sigx/ssg that integrates:\r\n * - File-based routing with virtual modules\r\n * - Layout system\r\n * - MDX processing\r\n * - HMR for development\r\n * - Zero-config entry point generation\r\n */\r\n\r\nimport type { Plugin, ResolvedConfig, ViteDevServer } from 'vite';\r\nimport path from 'node:path';\r\nimport fs from 'node:fs';\r\nimport type { SSGConfig } from '../types';\r\nimport { defineSSGConfig, loadConfig } from '../config';\r\nimport { scanPages } from '../routing/scanner';\r\nimport { generateRoutesModule, generateLazyRoutesModule, VIRTUAL_ROUTES_ID, RESOLVED_VIRTUAL_ROUTES_ID } from '../routing/virtual';\r\nimport { generateNavigationModule, VIRTUAL_NAVIGATION_ID, RESOLVED_VIRTUAL_NAVIGATION_ID } from '../routing/virtual-navigation';\r\nimport { discoverLayouts } from '../layouts/resolver';\r\nimport { generateLayoutsModule, VIRTUAL_LAYOUTS_ID, RESOLVED_VIRTUAL_LAYOUTS_ID } from '../layouts/virtual';\r\nimport { mdxPlugin } from '../mdx/plugin';\r\nimport { parseFrontmatter } from '../mdx/frontmatter';\r\nimport {\r\n detectCustomEntries,\r\n generateClientEntry,\r\n generateServerEntry,\r\n generateHtmlTemplate,\r\n VIRTUAL_CLIENT_ID,\r\n RESOLVED_VIRTUAL_CLIENT_ID,\r\n VIRTUAL_SERVER_ID,\r\n RESOLVED_VIRTUAL_SERVER_ID,\r\n SSG_CLIENT_ENTRY_PATH,\r\n type EntryDetectionResult,\r\n} from './virtual-entries';\r\n\r\n/**\r\n * SSG Plugin options\r\n */\r\nexport interface SSGPluginOptions extends Partial<SSGConfig> {\r\n /**\r\n * Path to ssg.config.ts\r\n */\r\n configPath?: string;\r\n \r\n /**\r\n * Enable built-in MDX processing. Set to false if using external MDX plugin.\r\n * @default true\r\n */\r\n enableMdx?: boolean;\r\n}\r\n\r\n/**\r\n * Virtual module for SSG config\r\n */\r\nconst VIRTUAL_CONFIG_ID = 'virtual:ssg-config';\r\nconst RESOLVED_VIRTUAL_CONFIG_ID = '\\0' + VIRTUAL_CONFIG_ID;\r\n\r\n/**\r\n * Create the SSG Vite plugin\r\n */\r\nexport function ssgPlugin(options: SSGPluginOptions = {}): Plugin[] {\r\n let config: ResolvedConfig;\r\n let ssgConfig: SSGConfig;\r\n let root: string;\r\n let server: ViteDevServer | undefined;\r\n let entryDetection: EntryDetectionResult;\r\n\r\n // Cache for virtual modules\r\n let routesCache: { routes: any[]; code: string } | null = null;\r\n let layoutsCache: { layouts: any[]; code: string } | null = null;\r\n let navigationCache: { code: string } | null = null;\r\n \r\n // Cache for frontmatter hashes to detect changes\r\n const frontmatterHashCache = new Map<string, string>();\r\n\r\n const mainPlugin: Plugin = {\r\n name: 'sigx-ssg',\r\n enforce: 'pre',\r\n\r\n async configResolved(resolvedConfig) {\r\n config = resolvedConfig;\r\n root = resolvedConfig.root;\r\n\r\n // Load SSG config - always try to load from file first\r\n const fileConfig = await loadConfig(options.configPath);\r\n \r\n // Merge file config with plugin options (plugin options take precedence)\r\n ssgConfig = defineSSGConfig({\r\n ...fileConfig,\r\n ...options,\r\n });\r\n\r\n // Detect custom entry points\r\n entryDetection = detectCustomEntries(root, ssgConfig);\r\n\r\n // Log zero-config mode status\r\n if (entryDetection.useVirtualClient || entryDetection.useVirtualServer) {\r\n console.log('\uD83D\uDCE6 @sigx/ssg: Using zero-config mode');\r\n if (entryDetection.useVirtualClient) {\r\n console.log(' \u2192 Virtual client entry');\r\n }\r\n if (entryDetection.useVirtualServer) {\r\n console.log(' \u2192 Virtual server entry');\r\n }\r\n if (entryDetection.globalCssPath) {\r\n console.log(` \u2192 Auto-importing ${entryDetection.globalCssPath}`);\r\n }\r\n }\r\n },\r\n\r\n configureServer(devServer) {\r\n server = devServer;\r\n\r\n // Watch pages and layouts directories for changes\r\n const pagesDir = path.resolve(root, ssgConfig.pages || 'src/pages');\r\n const layoutsDir = path.resolve(root, ssgConfig.layouts || 'src/layouts');\r\n const contentDir = path.resolve(root, ssgConfig.content || 'src/content');\r\n\r\n // Clear caches and trigger HMR on file changes\r\n devServer.watcher.on('add', (file) => {\r\n if (file.startsWith(pagesDir)) {\r\n routesCache = null;\r\n navigationCache = null;\r\n invalidateModule(RESOLVED_VIRTUAL_ROUTES_ID);\r\n invalidateModule(RESOLVED_VIRTUAL_NAVIGATION_ID);\r\n } else if (file.startsWith(layoutsDir)) {\r\n layoutsCache = null;\r\n invalidateModule(RESOLVED_VIRTUAL_LAYOUTS_ID);\r\n }\r\n });\r\n\r\n devServer.watcher.on('unlink', (file) => {\r\n if (file.startsWith(pagesDir)) {\r\n routesCache = null;\r\n navigationCache = null;\r\n // Clean up frontmatter hash cache\r\n frontmatterHashCache.delete(file);\r\n invalidateModule(RESOLVED_VIRTUAL_ROUTES_ID);\r\n invalidateModule(RESOLVED_VIRTUAL_NAVIGATION_ID);\r\n } else if (file.startsWith(layoutsDir)) {\r\n layoutsCache = null;\r\n invalidateModule(RESOLVED_VIRTUAL_LAYOUTS_ID);\r\n }\r\n });\r\n\r\n // Handle MDX/MD file content changes for frontmatter updates\r\n devServer.watcher.on('change', async (file) => {\r\n if (!file.startsWith(pagesDir)) return;\r\n if (!/\\.mdx?$/.test(file)) return;\r\n \r\n try {\r\n const content = await fs.promises.readFile(file, 'utf-8');\r\n const { data: newFrontmatter } = parseFrontmatter(content);\r\n const newHash = JSON.stringify(newFrontmatter);\r\n const oldHash = frontmatterHashCache.get(file);\r\n \r\n // Update the cache\r\n frontmatterHashCache.set(file, newHash);\r\n \r\n // If frontmatter changed, invalidate navigation (titles, categories may have changed)\r\n if (oldHash !== undefined && oldHash !== newHash) {\r\n navigationCache = null;\r\n routesCache = null;\r\n \r\n const navMod = devServer.moduleGraph.getModuleById(RESOLVED_VIRTUAL_NAVIGATION_ID);\r\n if (navMod) {\r\n devServer.moduleGraph.invalidateModule(navMod);\r\n }\r\n \r\n const routesMod = devServer.moduleGraph.getModuleById(RESOLVED_VIRTUAL_ROUTES_ID);\r\n if (routesMod) {\r\n devServer.moduleGraph.invalidateModule(routesMod);\r\n }\r\n \r\n // Send HMR update for navigation changes\r\n devServer.ws.send({ type: 'full-reload' });\r\n }\r\n } catch (err) {\r\n // File read error, ignore\r\n }\r\n });\r\n\r\n function invalidateModule(id: string) {\r\n const mod = devServer.moduleGraph.getModuleById(id);\r\n if (mod) {\r\n devServer.moduleGraph.invalidateModule(mod);\r\n devServer.ws.send({ type: 'full-reload' });\r\n }\r\n }\r\n\r\n // Serve virtual HTML template if no index.html exists\r\n if (entryDetection.useVirtualHtml) {\r\n devServer.middlewares.use((req, res, next) => {\r\n // Skip virtual modules and special Vite paths\r\n if (req.url?.startsWith('/@') || \r\n req.url?.startsWith('/__') || \r\n req.url?.includes('virtual:') ||\r\n req.url?.includes('node_modules') ||\r\n req.url?.startsWith('/@vite') ||\r\n req.url?.startsWith('/@fs')) {\r\n return next();\r\n }\r\n \r\n // Only handle requests for HTML pages (not assets with extensions)\r\n if (req.url && (req.url === '/' || !req.url.includes('.'))) {\r\n const html = generateHtmlTemplate(ssgConfig);\r\n // Transform HTML through Vite for HMR injection\r\n devServer.transformIndexHtml(req.url, html).then((transformedHtml) => {\r\n res.setHeader('Content-Type', 'text/html');\r\n res.end(transformedHtml);\r\n }).catch(next);\r\n return;\r\n }\r\n next();\r\n });\r\n }\r\n },\r\n\r\n resolveId(id) {\r\n // Handle virtual modules\r\n if (id === VIRTUAL_ROUTES_ID) {\r\n return RESOLVED_VIRTUAL_ROUTES_ID;\r\n }\r\n if (id === VIRTUAL_LAYOUTS_ID) {\r\n return RESOLVED_VIRTUAL_LAYOUTS_ID;\r\n }\r\n if (id === VIRTUAL_CONFIG_ID) {\r\n return RESOLVED_VIRTUAL_CONFIG_ID;\r\n }\r\n if (id === VIRTUAL_NAVIGATION_ID) {\r\n return RESOLVED_VIRTUAL_NAVIGATION_ID;\r\n }\r\n // Handle virtual entry points (both formats)\r\n if (id === VIRTUAL_CLIENT_ID || id === SSG_CLIENT_ENTRY_PATH) {\r\n return RESOLVED_VIRTUAL_CLIENT_ID;\r\n }\r\n if (id === VIRTUAL_SERVER_ID) {\r\n return RESOLVED_VIRTUAL_SERVER_ID;\r\n }\r\n return null;\r\n },\r\n\r\n async load(id) {\r\n // Generate virtual routes module\r\n if (id === RESOLVED_VIRTUAL_ROUTES_ID) {\r\n if (!routesCache) {\r\n const routes = await scanPages(ssgConfig, root);\r\n // Use lazy loading in dev mode for proper HMR and MDX processing\r\n const code = config.command === 'serve'\r\n ? generateLazyRoutesModule(routes, ssgConfig)\r\n : generateRoutesModule(routes, ssgConfig);\r\n routesCache = { routes, code };\r\n }\r\n return routesCache.code;\r\n }\r\n\r\n // Generate virtual layouts module\r\n if (id === RESOLVED_VIRTUAL_LAYOUTS_ID) {\r\n if (!layoutsCache) {\r\n const layouts = await discoverLayouts(ssgConfig, root);\r\n const code = generateLayoutsModule(layouts, ssgConfig);\r\n layoutsCache = { layouts, code };\r\n }\r\n return layoutsCache.code;\r\n }\r\n\r\n // Generate virtual navigation module\r\n if (id === RESOLVED_VIRTUAL_NAVIGATION_ID) {\r\n if (!navigationCache) {\r\n // Ensure routes are loaded (reuse cache if available)\r\n if (!routesCache) {\r\n const routes = await scanPages(ssgConfig, root);\r\n const routesCode = config.command === 'serve'\r\n ? generateLazyRoutesModule(routes, ssgConfig)\r\n : generateRoutesModule(routes, ssgConfig);\r\n routesCache = { routes, code: routesCode };\r\n }\r\n const isDev = config.command === 'serve';\r\n const code = generateNavigationModule(routesCache.routes, ssgConfig, isDev);\r\n navigationCache = { code };\r\n }\r\n return navigationCache.code;\r\n }\r\n\r\n // Generate virtual config module\r\n if (id === RESOLVED_VIRTUAL_CONFIG_ID) {\r\n return `export default ${JSON.stringify(ssgConfig)};`;\r\n }\r\n\r\n // Generate virtual client entry (needs JSX transform)\r\n if (id === RESOLVED_VIRTUAL_CLIENT_ID) {\r\n const code = generateClientEntry(ssgConfig, entryDetection);\r\n const esbuild = await import('esbuild');\r\n const result = await esbuild.transform(code, {\r\n loader: 'tsx',\r\n jsx: 'automatic',\r\n jsxImportSource: 'sigx',\r\n });\r\n return result.code;\r\n }\r\n\r\n // Generate virtual server entry (needs JSX transform)\r\n if (id === RESOLVED_VIRTUAL_SERVER_ID) {\r\n const code = generateServerEntry(ssgConfig);\r\n const esbuild = await import('esbuild');\r\n const result = await esbuild.transform(code, {\r\n loader: 'tsx',\r\n jsx: 'automatic',\r\n jsxImportSource: 'sigx',\r\n });\r\n return result.code;\r\n }\r\n\r\n return null;\r\n },\r\n\r\n // Handle HMR for layouts and pages\r\n async handleHotUpdate({ file, server }) {\r\n const layoutsDir = path.resolve(root, ssgConfig.layouts || 'src/layouts');\r\n const pagesDir = path.resolve(root, ssgConfig.pages || 'src/pages');\r\n\r\n if (file.startsWith(layoutsDir)) {\r\n // Clear layout cache\r\n layoutsCache = null;\r\n\r\n // Invalidate the virtual layouts module\r\n const mod = server.moduleGraph.getModuleById(RESOLVED_VIRTUAL_LAYOUTS_ID);\r\n if (mod) {\r\n server.moduleGraph.invalidateModule(mod);\r\n }\r\n\r\n // Also reload pages that use this layout\r\n return [];\r\n }\r\n\r\n // Handle MDX/MD file changes in pages directory\r\n if (file.startsWith(pagesDir) && /\\.mdx?$/.test(file)) {\r\n // The MDX plugin handles the transform and HMR code injection.\r\n // We just need to ensure the module is properly invalidated.\r\n // Vite will handle the rest via the injected import.meta.hot.accept()\r\n \r\n // Return undefined to let Vite handle the standard HMR flow\r\n // The MDX file already has import.meta.hot.accept() injected\r\n return undefined;\r\n }\r\n\r\n return undefined;\r\n },\r\n };\r\n\r\n // Combine with MDX plugin if enabled (default: true)\r\n const enableMdx = options.enableMdx !== false;\r\n \r\n if (enableMdx) {\r\n const mdx = mdxPlugin({\r\n markdown: options.markdown,\r\n ssgConfig: undefined as any, // Will be set by configResolved\r\n });\r\n return [mainPlugin, mdx];\r\n }\r\n \r\n return [mainPlugin];\r\n}\r\n\r\n/**\r\n * Export the plugin as default\r\n */\r\nexport default ssgPlugin;\r\n", "/**\r\n * Shiki syntax highlighting integration\r\n *\r\n * Provides code block highlighting for Markdown/MDX content.\r\n */\r\n\r\nimport { createHighlighter, type Highlighter, type BundledLanguage, type BundledTheme } from 'shiki';\r\nimport type { ShikiConfig } from '../types';\r\n\r\n/**\r\n * Cached highlighter instance\r\n */\r\nlet highlighterPromise: Promise<Highlighter> | null = null;\r\n\r\n/**\r\n * Default Shiki configuration\r\n */\r\nconst DEFAULT_CONFIG: Required<ShikiConfig> = {\r\n light: 'github-light',\r\n dark: 'github-dark',\r\n langs: ['javascript', 'typescript', 'jsx', 'tsx', 'json', 'css', 'html', 'markdown', 'bash', 'shell'],\r\n};\r\n\r\n/**\r\n * Initialize or get the Shiki highlighter\r\n */\r\nexport async function getHighlighter(config?: ShikiConfig): Promise<Highlighter> {\r\n if (!highlighterPromise) {\r\n const mergedConfig = { ...DEFAULT_CONFIG, ...config };\r\n\r\n highlighterPromise = createHighlighter({\r\n themes: [mergedConfig.light as BundledTheme, mergedConfig.dark as BundledTheme],\r\n langs: mergedConfig.langs as BundledLanguage[],\r\n });\r\n }\r\n\r\n return highlighterPromise;\r\n}\r\n\r\n/**\r\n * Tab types for preview blocks\r\n */\r\nexport type TabType = 'preview' | 'code' | 'console';\r\n\r\n/**\r\n * Highlight code with Shiki\r\n */\r\nexport async function highlightCode(\r\n code: string,\r\n lang: string,\r\n config?: ShikiConfig,\r\n meta?: { filename?: string; live?: boolean; tabs?: TabType[] }\r\n): Promise<string> {\r\n const highlighter = await getHighlighter(config);\r\n const mergedConfig = { ...DEFAULT_CONFIG, ...config };\r\n\r\n // Check if language is loaded\r\n const loadedLangs = highlighter.getLoadedLanguages();\r\n const effectiveLang = loadedLangs.includes(lang as BundledLanguage) ? lang : 'text';\r\n\r\n // Generate HTML with both themes for CSS-based switching\r\n const codeHtml = highlighter.codeToHtml(code, {\r\n lang: effectiveLang as BundledLanguage,\r\n themes: {\r\n light: mergedConfig.light as BundledTheme,\r\n dark: mergedConfig.dark as BundledTheme,\r\n },\r\n });\r\n\r\n // Wrap in code-window structure\r\n const filename = meta?.filename ?? '';\r\n const isLive = meta?.live ?? false;\r\n const tabs = meta?.tabs; // undefined means no tabbed view, just code\r\n const hasTabs = tabs && tabs.length > 0;\r\n \r\n const filenameHtml = filename \r\n ? `<span class=\"code-window-filename\">${escapeHtml(filename)}</span>`\r\n : `<span class=\"code-window-lang\">${getLanguageLabel(effectiveLang)}</span>`;\r\n\r\n // For preview blocks (has tabs), render a LivePreview island component\r\n if (hasTabs) {\r\n const base64Code = encodeBase64(code);\r\n \r\n // Generate tab buttons HTML based on tabs array\r\n const firstTab = tabs[0];\r\n const tabButtonsHtml = tabs.map((tab, i) => {\r\n const label = tab.charAt(0).toUpperCase() + tab.slice(1);\r\n const isActive = i === 0;\r\n return `<button class=\"code-window-tab${isActive ? ' code-window-tab-active' : ''}\">${label}</button>`;\r\n }).join('\\n ');\r\n \r\n // Return an island marker that will be hydrated on the client\r\n // Use code-window styling for consistency with the nice terminal look\r\n const html = `<div \r\n class=\"live-preview-island\" \r\n data-island=\"LivePreview\" \r\n data-island-strategy=\"visible\"\r\n data-island-props=\"${escapeHtml(JSON.stringify({\r\n code: base64Code,\r\n highlightedCode: codeHtml,\r\n language: effectiveLang,\r\n filename: filename,\r\n tabs: tabs,\r\n live: isLive\r\n }))}\"\r\n>\r\n <div class=\"code-window code-window-live code-window-preview\">\r\n <div class=\"code-window-header\">\r\n <div class=\"code-window-header-left\">\r\n <div class=\"code-window-dots\">\r\n <span class=\"code-window-dot dot-red\"></span>\r\n <span class=\"code-window-dot dot-yellow\"></span>\r\n <span class=\"code-window-dot dot-green\"></span>\r\n </div>\r\n ${filenameHtml}\r\n </div>\r\n <div class=\"code-window-tabs\">\r\n ${tabButtonsHtml}\r\n </div>\r\n <button class=\"code-window-try-live\" disabled>\u26A1 Try Live</button>\r\n </div>\r\n <div class=\"code-window-preview-pane\"${firstTab !== 'preview' ? ' style=\"display:none;\"' : ''}>\r\n <div class=\"code-window-preview-loading\">\r\n <span class=\"code-window-spinner\"></span>\r\n Loading preview...\r\n </div>\r\n </div>\r\n <div class=\"code-window-console-pane\"${firstTab !== 'console' ? ' style=\"display:none;\"' : ''}>\r\n <div class=\"code-window-console-empty\">No console output</div>\r\n </div>\r\n <div class=\"code-window-content\"${firstTab !== 'code' ? ' style=\"display:none;\"' : ''}>\r\n ${codeHtml}\r\n </div>\r\n </div>\r\n</div>`;\r\n return html;\r\n }\r\n\r\n // Add \"Try Live\" button for live code blocks\r\n const tryLiveButton = isLive \r\n ? `<button class=\"code-window-try-live\" data-live-code=\"${escapeHtml(encodeBase64(code))}\" data-lang=\"${effectiveLang}\" data-filename=\"${escapeHtml(filename)}\" title=\"Open in Live Playground\">\u26A1 Try Live</button>`\r\n : '';\r\n\r\n const html = `<div class=\"code-window${isLive ? ' code-window-live' : ''}\">\r\n <div class=\"code-window-header\">\r\n <div class=\"code-window-header-left\">\r\n <div class=\"code-window-dots\">\r\n <span class=\"code-window-dot dot-red\"></span>\r\n <span class=\"code-window-dot dot-yellow\"></span>\r\n <span class=\"code-window-dot dot-green\"></span>\r\n </div>\r\n ${filenameHtml}\r\n </div>\r\n ${tryLiveButton}\r\n </div>\r\n <div class=\"code-window-content\">\r\n ${codeHtml}\r\n </div>\r\n </div>`;\r\n\r\n return html;\r\n}\r\n\r\n/**\r\n * Encode string to base64 (works in both Node.js and browser)\r\n */\r\nfunction encodeBase64(str: string): string {\r\n // Use Buffer in Node.js\r\n if (typeof Buffer !== 'undefined') {\r\n return Buffer.from(str, 'utf-8').toString('base64');\r\n }\r\n // Fallback for browser (shouldn't be needed during SSG build)\r\n return btoa(unescape(encodeURIComponent(str)));\r\n}\r\n\r\n/**\r\n * Get a display label for a language\r\n */\r\nfunction getLanguageLabel(lang: string): string {\r\n const labels: Record<string, string> = {\r\n 'tsx': 'TSX',\r\n 'jsx': 'JSX',\r\n 'ts': 'TypeScript',\r\n 'typescript': 'TypeScript',\r\n 'js': 'JavaScript',\r\n 'javascript': 'JavaScript',\r\n 'css': 'CSS',\r\n 'html': 'HTML',\r\n 'json': 'JSON',\r\n 'bash': 'Terminal',\r\n 'shell': 'Terminal',\r\n 'sh': 'Terminal',\r\n 'md': 'Markdown',\r\n 'markdown': 'Markdown',\r\n 'python': 'Python',\r\n 'py': 'Python',\r\n 'rust': 'Rust',\r\n 'go': 'Go',\r\n 'text': '',\r\n };\r\n return labels[lang.toLowerCase()] ?? lang.toUpperCase();\r\n}\r\n\r\n/**\r\n * Escape HTML special characters\r\n */\r\nfunction escapeHtml(str: string): string {\r\n return str\r\n .replace(/&/g, '&amp;')\r\n .replace(/</g, '&lt;')\r\n .replace(/>/g, '&gt;')\r\n .replace(/\"/g, '&quot;')\r\n .replace(/'/g, '&#39;');\r\n}\r\n\r\n/**\r\n * Create a rehype plugin for Shiki\r\n */\r\nexport function rehypeShiki(config?: ShikiConfig) {\r\n return async (tree: any) => {\r\n const { visit } = await import('unist-util-visit');\r\n const { fromHtml } = await import('hast-util-from-html');\r\n\r\n const nodesToProcess: Array<{ node: any; parent: any; index: number }> = [];\r\n\r\n visit(tree, 'element', (node: any, index: number | undefined, parent: any) => {\r\n // Look for <pre><code> elements\r\n if (\r\n node.tagName === 'pre' &&\r\n node.children?.[0]?.tagName === 'code'\r\n ) {\r\n nodesToProcess.push({ node, parent, index: index ?? 0 });\r\n }\r\n });\r\n\r\n // Process nodes in parallel\r\n await Promise.all(\r\n nodesToProcess.map(async ({ node, parent, index }) => {\r\n const codeNode = node.children[0];\r\n\r\n // Extract language from class (e.g., \"language-typescript\")\r\n const className = codeNode.properties?.className?.[0] || '';\r\n const lang = className.replace(/^language-/, '') || 'text';\r\n\r\n // Extract filename from meta string if present\r\n // Supports: ```tsx filename=\"Counter.tsx\" or ```tsx title=\"Counter.tsx\"\r\n const metaString = codeNode.data?.meta || codeNode.properties?.metastring || '';\r\n const filename = extractMeta(metaString, 'filename') || extractMeta(metaString, 'title') || '';\r\n \r\n // Check for \"live\" flag in meta string (e.g., ```tsx live)\r\n const isLive = /\\blive\\b/i.test(metaString);\r\n \r\n // Parse tabs from meta string - order determines tab order\r\n // Supported keywords: preview, code, console\r\n // Example: ```tsx code preview console live -> tabs: [code, preview, console], with live button\r\n const tabKeywords = ['preview', 'code', 'console'] as const;\r\n const tabs: TabType[] = [];\r\n \r\n // Find all tab keywords and their positions\r\n const tabPositions: Array<{ tab: TabType; index: number }> = [];\r\n for (const keyword of tabKeywords) {\r\n const regex = new RegExp(`\\\\b${keyword}\\\\b`, 'i');\r\n const match = metaString.match(regex);\r\n if (match && match.index !== undefined) {\r\n tabPositions.push({ tab: keyword, index: match.index });\r\n }\r\n }\r\n \r\n // Sort by position (order of appearance in meta string)\r\n tabPositions.sort((a, b) => a.index - b.index);\r\n \r\n // Extract just the tab names in order\r\n for (const { tab } of tabPositions) {\r\n tabs.push(tab);\r\n }\r\n\r\n // Get raw code content\r\n const code = getTextContent(codeNode);\r\n\r\n // Highlight with Shiki (with meta info)\r\n // Only pass tabs if at least one tab keyword was found\r\n const html = await highlightCode(code.trim(), lang, config, { \r\n filename, \r\n live: isLive, \r\n tabs: tabs.length > 0 ? tabs : undefined \r\n });\r\n\r\n // Parse the HTML string into HAST nodes\r\n const fragment = fromHtml(html, { fragment: true });\r\n \r\n // Replace node with the parsed HAST fragment's children\r\n if (parent && typeof index === 'number' && fragment.children.length > 0) {\r\n // Use the first element from the fragment (should be the code-window div)\r\n parent.children[index] = fragment.children[0];\r\n }\r\n })\r\n );\r\n };\r\n}\r\n\r\n/**\r\n * Extract a meta value from a meta string\r\n * Supports: filename=\"value\" or filename='value' or filename=value\r\n */\r\nfunction extractMeta(metaString: string, key: string): string | null {\r\n if (!metaString) return null;\r\n \r\n // Match: key=\"value\" or key='value' or key=value\r\n const regex = new RegExp(`${key}=[\"']?([^\"'\\\\s]+)[\"']?`, 'i');\r\n const match = metaString.match(regex);\r\n return match ? match[1] : null;\r\n}\r\n\r\n/**\r\n * Extract text content from an AST node\r\n */\r\nfunction getTextContent(node: any): string {\r\n if (node.type === 'text') {\r\n return node.value;\r\n }\r\n\r\n if (node.children) {\r\n return node.children.map(getTextContent).join('');\r\n }\r\n\r\n return '';\r\n}\r\n\r\n/**\r\n * Load additional language on demand\r\n */\r\nexport async function loadLanguage(lang: string): Promise<void> {\r\n const highlighter = await getHighlighter();\r\n const loadedLangs = highlighter.getLoadedLanguages();\r\n\r\n if (!loadedLangs.includes(lang as BundledLanguage)) {\r\n try {\r\n await highlighter.loadLanguage(lang as BundledLanguage);\r\n } catch {\r\n console.warn(`Shiki: Language \"${lang}\" not available, using plain text`);\r\n }\r\n }\r\n}\r\n", "/**\r\n * Rehype plugin to extract headings from MDX/MD content\r\n *\r\n * Extracts headings (h2-h6 by default) with their IDs and text content\r\n * for use in table of contents generation.\r\n */\r\n\r\nimport { visit } from 'unist-util-visit';\r\nimport { toString } from 'hast-util-to-string';\r\nimport type { TocHeading } from '../types';\r\n\r\n/**\r\n * Options for the rehype headings plugin\r\n */\r\nexport interface RehypeHeadingsOptions {\r\n /**\r\n * Minimum heading level to include (1-6)\r\n * @default 2\r\n */\r\n minLevel?: number;\r\n\r\n /**\r\n * Maximum heading level to include (1-6)\r\n * @default 3\r\n */\r\n maxLevel?: number;\r\n}\r\n\r\n/**\r\n * Rehype plugin to extract headings from the document\r\n *\r\n * Stores extracted headings in `file.data.headings` for later use.\r\n *\r\n * @example\r\n * ```ts\r\n * import { rehypeExtractHeadings } from './rehype-headings';\r\n *\r\n * // Use with unified\r\n * unified()\r\n * .use(rehypeSlug) // First add IDs to headings\r\n * .use(rehypeExtractHeadings, { minLevel: 2, maxLevel: 3 })\r\n * ```\r\n */\r\nexport function rehypeExtractHeadings(options: RehypeHeadingsOptions = {}) {\r\n const { minLevel = 2, maxLevel = 3 } = options;\r\n\r\n return (tree: any, file: any) => {\r\n const headings: TocHeading[] = [];\r\n\r\n visit(tree, 'element', (node: any) => {\r\n // Check if this is a heading element (h1-h6)\r\n const match = /^h([1-6])$/.exec(node.tagName);\r\n if (!match) return;\r\n\r\n const level = parseInt(match[1], 10);\r\n\r\n // Skip headings outside configured range\r\n if (level < minLevel || level > maxLevel) return;\r\n\r\n // Get the heading ID (should be set by rehype-slug)\r\n const id = node.properties?.id;\r\n if (!id) return;\r\n\r\n // Extract text content from the heading\r\n const text = toString(node).trim();\r\n if (!text) return;\r\n\r\n headings.push({ id, text, level });\r\n });\r\n\r\n // Store headings in file data for later access\r\n file.data = file.data || {};\r\n file.data.headings = headings;\r\n };\r\n}\r\n\r\nexport default rehypeExtractHeadings;\r\n", "/**\r\n * MDX Vite plugin\r\n *\r\n * Transforms MDX files into SignalX components with:\r\n * - Frontmatter extraction\r\n * - Shiki syntax highlighting\r\n * - SignalX JSX runtime integration\r\n */\r\n\r\nimport type { Plugin, ResolvedConfig } from 'vite';\r\nimport type { SSGConfig, MarkdownConfig, PageMeta, TocHeading } from '../types';\r\nimport { parseFrontmatter, extractTitleFromContent } from './frontmatter';\r\nimport { rehypeShiki } from './shiki';\r\nimport { rehypeExtractHeadings } from './rehype-headings';\r\n\r\n/**\r\n * MDX plugin options\r\n */\r\nexport interface MDXPluginOptions {\r\n /**\r\n * Markdown configuration\r\n */\r\n markdown?: MarkdownConfig;\r\n\r\n /**\r\n * SSG configuration (for layout resolution)\r\n */\r\n ssgConfig?: SSGConfig;\r\n}\r\n\r\n/**\r\n * Create the MDX Vite plugin\r\n */\r\nexport function mdxPlugin(options: MDXPluginOptions = {}): Plugin {\r\n const { markdown = {} } = options;\r\n\r\n let mdxRollup: any;\r\n let viteConfig: ResolvedConfig;\r\n\r\n return {\r\n name: 'sigx-ssg-mdx',\r\n enforce: 'pre',\r\n\r\n async configResolved(config) {\r\n viteConfig = config;\r\n // Dynamically import @mdx-js/rollup\r\n const mdxModule = await import('@mdx-js/rollup');\r\n const remarkFrontmatter = (await import('remark-frontmatter')).default;\r\n const remarkMdxFrontmatter = (await import('remark-mdx-frontmatter')).default;\r\n const remarkGfm = (await import('remark-gfm')).default;\r\n const rehypeSlug = (await import('rehype-slug')).default;\r\n const rehypeAutolinkHeadings = (await import('rehype-autolink-headings')).default;\r\n\r\n // Get TOC config from SSG config\r\n const tocConfig = options.ssgConfig?.toc || { minLevel: 2, maxLevel: 3 };\r\n\r\n // Build rehype plugins array\r\n const rehypePlugins: any[] = [];\r\n\r\n // Add rehype-slug first to generate heading IDs\r\n rehypePlugins.push(rehypeSlug);\r\n\r\n // Add autolink headings (clickable anchor links)\r\n rehypePlugins.push([rehypeAutolinkHeadings, {\r\n behavior: 'append',\r\n properties: {\r\n class: 'heading-anchor',\r\n ariaHidden: true,\r\n tabIndex: -1,\r\n },\r\n content: {\r\n type: 'element',\r\n tagName: 'span',\r\n properties: { class: 'heading-anchor-icon' },\r\n children: [{ type: 'text', value: '#' }],\r\n },\r\n }]);\r\n\r\n // Add heading extraction for TOC\r\n rehypePlugins.push([rehypeExtractHeadings, tocConfig]);\r\n\r\n // Add Shiki if enabled\r\n if (markdown.shiki !== false) {\r\n const shikiConfig = typeof markdown.shiki === 'object' ? markdown.shiki : undefined;\r\n rehypePlugins.push([rehypeShiki, shikiConfig]);\r\n }\r\n\r\n // Add custom rehype plugins\r\n if (markdown.rehypePlugins) {\r\n rehypePlugins.push(...markdown.rehypePlugins);\r\n }\r\n\r\n // Build remark plugins array\r\n const remarkPlugins: any[] = [\r\n remarkFrontmatter,\r\n [remarkMdxFrontmatter, { name: 'frontmatter' }],\r\n remarkGfm,\r\n ];\r\n\r\n // Add custom remark plugins\r\n if (markdown.remarkPlugins) {\r\n remarkPlugins.push(...markdown.remarkPlugins);\r\n }\r\n\r\n // Create MDX plugin\r\n // Use jsx: false to output function calls instead of JSX syntax\r\n // This avoids needing esbuild to process .mdx files as JSX\r\n mdxRollup = mdxModule.default({\r\n jsx: false,\r\n jsxImportSource: 'sigx',\r\n remarkPlugins,\r\n rehypePlugins,\r\n providerImportSource: undefined,\r\n });\r\n },\r\n\r\n async transform(code, id) {\r\n // Only process MDX and MD files\r\n if (!/\\.mdx?$/.test(id)) {\r\n return null;\r\n }\r\n\r\n // Parse frontmatter first\r\n const { data: frontmatter, content } = parseFrontmatter(code);\r\n\r\n // Extract title from content if not in frontmatter\r\n if (!frontmatter.title) {\r\n const extractedTitle = extractTitleFromContent(content);\r\n if (extractedTitle) {\r\n frontmatter.title = extractedTitle;\r\n }\r\n }\r\n\r\n // Transform MDX content\r\n if (!mdxRollup?.transform) {\r\n throw new Error('MDX plugin not initialized');\r\n }\r\n\r\n const result = await mdxRollup.transform(code, id);\r\n\r\n if (!result) {\r\n return null;\r\n }\r\n\r\n // Extract headings from the file data (set by rehype-extract-headings)\r\n // Note: We need to process the content to get headings\r\n const headings = await extractHeadingsFromContent(content, options);\r\n\r\n // Create module ID for HMR tracking (normalize path separators)\r\n const moduleId = id.replace(/\\\\/g, '/');\r\n\r\n // Inject frontmatter export and wrap in SignalX component\r\n const transformedCode = wrapMDXComponent(\r\n result.code,\r\n frontmatter,\r\n headings,\r\n moduleId,\r\n viteConfig.command === 'serve'\r\n );\r\n\r\n return {\r\n code: transformedCode,\r\n map: result.map,\r\n };\r\n },\r\n };\r\n}\r\n\r\n/**\r\n * Wrap MDX output in a SignalX component\r\n * \r\n * Note: remark-mdx-frontmatter already exports `frontmatter`, so we only add the layout export\r\n * \r\n * In dev mode, we:\r\n * 1. Wrap MDXContent in a sigx component() for proper HMR tracking\r\n * 2. Inject HMR registration code so the component updates live\r\n */\r\nfunction wrapMDXComponent(\r\n code: string,\r\n frontmatter: PageMeta,\r\n headings: TocHeading[],\r\n moduleId: string,\r\n isDev: boolean\r\n): string {\r\n // The MDX output already includes frontmatter export from remark-mdx-frontmatter\r\n // We need to add the layout export for the SSG routing system\r\n \r\n // In dev mode, wrap in sigx component for HMR support\r\n if (isDev) {\r\n // Generate a component name from the file path for debugging\r\n const fileName = moduleId.split('/').pop()?.replace(/\\.mdx?$/, '') || 'MDXPage';\r\n const componentName = fileName.charAt(0).toUpperCase() + fileName.slice(1).replace(/[^a-zA-Z0-9]/g, '') + 'Page';\r\n \r\n // The MDX output has \"export default function MDXContent(...)\" \r\n // We need to:\r\n // 1. Remove the \"export default\" from MDXContent to avoid duplicate exports\r\n // 2. Wrap it in a sigx component for HMR\r\n // 3. Export the wrapped component as default\r\n const modifiedCode = code\r\n .replace(/export\\s+default\\s+function\\s+MDXContent/g, 'function _MDXContent')\r\n .replace(/export\\s+{\\s*MDXContent\\s+as\\s+default\\s*}/g, '');\r\n \r\n return `\r\nimport { registerHMRModule } from '@sigx/vite/hmr';\r\nimport { component as __component } from 'sigx';\r\nregisterHMRModule('${moduleId}');\r\n\r\n${modifiedCode}\r\n\r\n// Export layout from frontmatter for SSG routing\r\nexport const layout = ${frontmatter.layout ? JSON.stringify(frontmatter.layout) : 'undefined'};\r\n\r\n// Export headings for table of contents\r\nexport const headings = ${JSON.stringify(headings)};\r\n\r\n// Wrap MDXContent in a sigx component for HMR support\r\nconst MDXPage = __component(() => {\r\n return () => _MDXContent({});\r\n}, { name: '${componentName}' });\r\n\r\nexport default MDXPage;\r\n\r\nif (import.meta.hot) {\r\n // Accept HMR updates with a callback to trigger re-render after module is updated\r\n import.meta.hot.accept((newModule) => {\r\n if (newModule) {\r\n // Notify LayoutRouter to clear its cache and re-render with new module\r\n window.dispatchEvent(new CustomEvent('sigx:mdx-hmr', { \r\n detail: { moduleId: '${moduleId}', newModule } \r\n }));\r\n }\r\n });\r\n}\r\n`;\r\n }\r\n \r\n // Production: just add exports without HMR wrapper\r\n return `\r\n${code}\r\n\r\n// Export layout from frontmatter for SSG routing\r\nexport const layout = ${frontmatter.layout ? JSON.stringify(frontmatter.layout) : 'undefined'};\r\n\r\n// Export headings for table of contents\r\nexport const headings = ${JSON.stringify(headings)};\r\n`;\r\n}\r\n\r\n/**\r\n * Extract headings from markdown/MDX content\r\n */\r\nasync function extractHeadingsFromContent(\r\n content: string,\r\n options: MDXPluginOptions\r\n): Promise<TocHeading[]> {\r\n const { unified } = await import('unified');\r\n const remarkParse = (await import('remark-parse')).default;\r\n const remarkRehype = (await import('remark-rehype')).default;\r\n const rehypeSlug = (await import('rehype-slug')).default;\r\n const rehypeStringify = (await import('rehype-stringify')).default;\r\n\r\n // Get TOC config\r\n const tocConfig = options.ssgConfig?.toc || { minLevel: 2, maxLevel: 3 };\r\n\r\n // Process markdown to extract headings\r\n // Note: rehype-stringify is required for unified to have a compiler\r\n const processor = unified()\r\n .use(remarkParse)\r\n .use(remarkRehype)\r\n .use(rehypeSlug)\r\n .use(rehypeExtractHeadings, tocConfig)\r\n .use(rehypeStringify);\r\n\r\n const file = await processor.process(content);\r\n return (file.data as any).headings || [];\r\n}\r\n\r\n/**\r\n * Create a simple markdown-only plugin (no MDX features)\r\n */\r\nexport function markdownPlugin(options: MDXPluginOptions = {}): Plugin {\r\n return {\r\n name: 'sigx-ssg-markdown',\r\n enforce: 'pre',\r\n\r\n async transform(code, id) {\r\n // Only process .md files (not .mdx)\r\n if (!/\\.md$/.test(id) || /\\.mdx$/.test(id)) {\r\n return null;\r\n }\r\n\r\n // Parse frontmatter\r\n const { data: frontmatter, content } = parseFrontmatter(code);\r\n\r\n // Extract title if not in frontmatter\r\n if (!frontmatter.title) {\r\n const extractedTitle = extractTitleFromContent(content);\r\n if (extractedTitle) {\r\n frontmatter.title = extractedTitle;\r\n }\r\n }\r\n\r\n // Convert markdown to simple HTML using a lightweight parser\r\n // For full MD support, the MDX plugin should be used\r\n const html = await simpleMarkdownToHtml(content, options);\r\n \r\n // Extract headings for TOC\r\n const headings = await extractHeadingsFromContent(content, options);\r\n \r\n const frontmatterJSON = JSON.stringify(frontmatter);\r\n const headingsJSON = JSON.stringify(headings);\r\n\r\n return {\r\n code: `\r\nimport { jsx as _jsx } from 'sigx/jsx-runtime';\r\n\r\nexport const frontmatter = ${frontmatterJSON};\r\nexport const layout = ${frontmatter.layout ? JSON.stringify(frontmatter.layout) : 'undefined'};\r\nexport const headings = ${headingsJSON};\r\n\r\nexport default function MDContent(props) {\r\n return _jsx('div', {\r\n class: 'markdown-content',\r\n dangerouslySetInnerHTML: { __html: ${JSON.stringify(html)} }\r\n });\r\n}\r\n`,\r\n map: null,\r\n };\r\n },\r\n };\r\n}\r\n\r\n/**\r\n * Simple markdown to HTML conversion\r\n * For basic markdown without custom components\r\n */\r\nasync function simpleMarkdownToHtml(markdown: string, options: MDXPluginOptions = {}): Promise<string> {\r\n // Use unified for basic markdown processing\r\n const { unified } = await import('unified');\r\n const remarkParse = (await import('remark-parse')).default;\r\n const remarkRehype = (await import('remark-rehype')).default;\r\n const rehypeSlug = (await import('rehype-slug')).default;\r\n const rehypeStringify = (await import('rehype-stringify')).default;\r\n\r\n const result = await unified()\r\n .use(remarkParse)\r\n .use(remarkRehype)\r\n .use(rehypeSlug) // Add IDs to headings\r\n .use(rehypeStringify)\r\n .process(markdown);\r\n\r\n return String(result);\r\n}\r\n", "import { build } from './build';\r\nimport { dev, preview } from './dev';\r\n\r\n// Dummy export to prevent tree-shaking in library mode\r\nexport const __cli__ = true;\r\n\r\nconst args = process.argv.slice(2);\r\nconst command = args[0];\r\n\r\n// Parse common options\r\nconst configPath = args.find((a: string) => a.startsWith('--config='))?.split('=')[1];\r\nconst port = parseInt(args.find((a: string) => a.startsWith('--port='))?.split('=')[1] || '');\r\nconst host = args.includes('--host') ? true : args.find((a: string) => a.startsWith('--host='))?.split('=')[1];\r\nconst open = args.includes('--open');\r\nconst verbose = args.includes('--verbose') || args.includes('-v');\r\n\r\nif (command === 'dev') {\r\n dev({ \r\n configPath, \r\n port: isNaN(port) ? undefined : port, \r\n host, \r\n open,\r\n verbose,\r\n }).catch((err: unknown) => {\r\n console.error('Dev server failed:', err);\r\n process.exit(1);\r\n });\r\n} else if (command === 'build') {\r\n build({ configPath, verbose }).catch((err: unknown) => {\r\n console.error('Build failed:', err);\r\n process.exit(1);\r\n });\r\n} else if (command === 'preview') {\r\n preview({ \r\n configPath, \r\n port: isNaN(port) ? undefined : port, \r\n host, \r\n open,\r\n }).catch((err: unknown) => {\r\n console.error('Preview server failed:', err);\r\n process.exit(1);\r\n });\r\n} else {\r\n console.log(`\r\n@sigx/ssg - Static Site Generator for SignalX\r\n\r\nUsage:\r\n ssg dev [options] Start development server\r\n ssg build [options] Build static site for production\r\n ssg preview [options] Preview production build locally\r\n\r\nOptions:\r\n --config=path Path to ssg.config.ts (default: ./ssg.config.ts)\r\n --port=number Port for dev/preview server (default: 5173/4173)\r\n --host Expose to network (or --host=0.0.0.0)\r\n --open Open browser automatically\r\n --verbose, -v Enable verbose logging\r\n\r\nExamples:\r\n ssg dev Start dev server on localhost:5173\r\n ssg dev --port=3000 --open Start on port 3000 and open browser\r\n ssg build Build static site to ./dist\r\n ssg preview Preview built site on localhost:4173\r\n`);\r\n}\r\n"],
5
+ "mappings": "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",
6
6
  "names": ["path", "fs", "configPath", "fs", "pathToFileURL", "configModule", "path", "path", "path", "fg", "path", "fs", "pathToFileURL", "require", "normalizePath", "fs", "path", "fs", "path", "path", "fs", "verbose", "path", "fs", "path", "fs", "path", "fs", "escapeHtml", "html", "visit", "path", "fs", "server", "fs", "path"]
7
7
  }