@devlusoft/devix 0.4.1-beta.2 → 0.4.1-beta.4

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.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/cli/dev.ts", "../../src/vite/codegen/entry-client.ts", "../../src/vite/codegen/client-routes.ts", "../../src/vite/codegen/render.ts", "../../src/vite/codegen/api.ts", "../../src/utils/patterns.ts", "../../src/server/pages-router.ts", "../../src/server/api-router.ts", "../../src/vite/codegen/context.ts", "../../src/vite/codegen/extract-methods.ts", "../../src/vite/codegen/routes-dts.ts", "../../src/vite/codegen/scan-api.ts", "../../src/vite/codegen/write-routes-dts.ts", "../../src/vite/index.ts", "../../src/utils/duration.ts", "../../src/cli/build.ts", "../../src/cli/generate.ts", "../../src/server/routes.ts", "../../src/utils/env.ts", "../../src/cli/start.ts", "../../src/cli/index.ts"],
4
- "sourcesContent": ["import { spawnSync } from 'node:child_process'\nimport { fileURLToPath } from 'node:url'\nimport { dirname, resolve } from 'node:path'\n\nconst __dirname = dirname(fileURLToPath(import.meta.url))\n\nwhile (true) {\n const result = spawnSync(process.execPath, [resolve(__dirname, 'dev-server.js')], {\n stdio: 'inherit',\n env: process.env,\n })\n if (result.status !== 75) break\n}\n\nexport { }", "interface EntryClientOptions {\n cssUrls: string[]\n}\n\nexport function generateEntryClient({cssUrls}: EntryClientOptions): string {\n const cssImports = cssUrls.map(u => `import '${u}'`).join('\\n')\n\n return `\n${cssImports}\nimport \"@vitejs/plugin-react/preamble\"\nimport React from \"react\"\nimport {hydrateRoot, createRoot} from 'react-dom/client'\nimport {matchClientRoute, loadErrorPage, getDefaultErrorPage} from 'virtual:devix/client-routes'\nimport {RouterProvider} from '@devlusoft/devix'\n\nconst root = document.getElementById('devix-root')\n\nif (!window.__DEVIX__) {\n const ErrorPage = getDefaultErrorPage()\n createRoot(root).render(React.createElement(ErrorPage, {statusCode: 500, message: 'Server error'}))\n} else {\n const {metadata, viewport, clientEntry} = window.__DEVIX__\n const loaderData = window.__LOADER_DATA__\n const layoutsData = window.__LAYOUTS_DATA__ ?? []\n\n const matched = matchClientRoute(window.location.pathname)\n\n if (matched) {\n const [pageMod, ...layoutMods] = await Promise.all([\n matched.load(),\n ...matched.loadLayouts.map(l => l()),\n ])\n hydrateRoot(\n root,\n React.createElement(RouterProvider, {\n clientEntry,\n initialData: loaderData,\n initialParams: matched.params,\n initialPage: pageMod.default,\n initialLayouts: layoutMods.map(m => m.default),\n initialLayoutsData: layoutsData,\n initialMeta: metadata,\n initialViewport: viewport,\n })\n )\n } else {\n const ErrorPage = await loadErrorPage() ?? getDefaultErrorPage()\n createRoot(root).render(\n React.createElement(RouterProvider, {\n clientEntry,\n initialData: null,\n initialParams: {},\n initialPage: () => null,\n initialLayouts: [],\n initialLayoutsData: [],\n initialMeta: null,\n initialError: {statusCode: 404, message: 'Not found'},\n initialErrorPage: ErrorPage,\n })\n )\n }\n}\n`\n}", "interface ClientRoutesOptions {\n pagesDir: string\n matcherPath: string\n}\n\nexport function generateClientRoutes({pagesDir, matcherPath}: ClientRoutesOptions) {\n return `\nimport React from 'react'\nimport { createMatcher } from '${matcherPath}'\nconst pageFiles = import.meta.glob(['/${pagesDir}/**/*.tsx', '!**/error.tsx', '!**/layout.tsx'])\nconst layoutFiles = import.meta.glob('/${pagesDir}/**/layout.tsx')\nconst errorFiles = import.meta.glob('/${pagesDir}/**/error.tsx')\n\nexport const matchClientRoute = createMatcher(pageFiles, layoutFiles)\n\nexport async function loadErrorPage() {\n const key = Object.keys(errorFiles)[0]\n if (!key) return null\n const mod = await errorFiles[key]()\n return mod?.default ?? null\n}\n\nexport function getDefaultErrorPage() {\n return function DefaultError({ statusCode, message }) {\n return React.createElement('main', {\n style: { minHeight: '100dvh', display: 'flex', flexDirection: 'column', \n alignItems: 'center', justifyContent: 'center', gap: '8px',\n fontFamily: 'system-ui, sans-serif' }\n },\n React.createElement('h1', {style: {fontSize: '4rem', fontWeight: 700}}, statusCode),\n React.createElement('p', {style: {color: '#666'}}, message ?? 'An unexpected error occurred'),\n )\n }\n}\n`\n}", "interface RenderOptions {\n pagesDir: string\n renderPath: string\n}\n\nexport function generateRender({pagesDir, renderPath}: RenderOptions): string {\n return `\nimport { render as _render, runLoader as _runLoader, getStaticRoutes as _getStaticRoutes } from '${renderPath}'\n\nconst _pages = import.meta.glob(['/${pagesDir}/**/*.tsx', '!**/error.tsx', '!**/layout.tsx'])\nconst _layouts = import.meta.glob('/${pagesDir}/**/layout.tsx')\n\nconst _glob = {\n pages: _pages,\n layouts: _layouts,\n pagesDir: '/${pagesDir}',\n}\n\nexport function render(url, request, options) {\n return _render(url, request, _glob, options)\n}\n\nexport function runLoader(url, request, options) {\n return _runLoader(url, request, _glob, options)\n}\n\nexport function getStaticRoutes() {\n return _getStaticRoutes(_glob)\n}\n`\n}\n", "interface ApiOptions {\n apiPath: string\n appDir: string\n}\n\nexport function generateApi({apiPath, appDir}: ApiOptions): string {\n return `\nimport { handleApiRequest as _handleApiRequest } from '${apiPath}'\n\nconst _routes = import.meta.glob(['/${appDir}/api/**/*.ts', '!**/middleware.ts'])\nconst _middlewares = import.meta.glob('/${appDir}/api/**/middleware.ts')\n\nconst _glob = {\n routes: _routes,\n middlewares: _middlewares,\n apiDir: '/${appDir}/api',\n}\n\nexport function handleApiRequest(url, request) {\n return _handleApiRequest(url, request, _glob)\n}\n`\n}\n", "export function routePattern(rel: string): string {\n return rel\n .replace(/\\.(tsx|ts|jsx|js)$/, '')\n .replace(/\\(.*?\\)\\//g, '')\n .replace(/^index$|\\/index$/, '')\n .replace(/\\[([^\\]]+)]/g, ':$1')\n || '/'\n}", "import {routePattern} from \"../utils/patterns\";\n\nexport interface Page {\n path: string\n key: string\n params: string[]\n regex: RegExp\n}\n\nexport interface Layout {\n dir: string\n key: string\n}\n\nexport interface PagesResult {\n pages: Page[]\n layouts: Layout[]\n}\n\nfunction keyToRoutePattern(key: string, pagesDir: string): string {\n const rel = key.slice(pagesDir.length + 1).replace(/\\\\/g, '/')\n const pattern = routePattern(rel)\n return pattern === \"/\" ? \"/\" : `/${pattern}`\n}\n\nfunction keyToDir(key: string): string {\n return key.slice(0, key.lastIndexOf('/'))\n}\n\nlet cache: PagesResult | null = null\n\nexport function invalidatePagesCache() {\n cache = null\n}\n\nexport function buildPages(pageKeys: string[], layoutKeys: string[], pagesDir: string): PagesResult {\n if (cache) return cache\n\n const pages: Page[] = []\n const layouts: Layout[] = []\n\n for (const key of layoutKeys) {\n layouts.push({dir: keyToDir(key), key})\n }\n\n for (const key of pageKeys) {\n const pattern = keyToRoutePattern(key, pagesDir)\n const params = [...pattern.matchAll(/:([^/]+)/g)].map(m => m[1])\n const regexStr = pattern\n .replace(/:[^/]+/g, '([^/]+)')\n .replace(/\\//g, '\\\\/')\n pages.push({path: pattern, key, params, regex: new RegExp(`^${regexStr}$`)})\n }\n\n pages.sort((a, b) => {\n const aScore = (a.path.match(/:/g) || []).length\n const bScore = (b.path.match(/:/g) || []).length\n if (aScore !== bScore) return aScore - bScore\n return b.path.length - a.path.length\n })\n\n cache = {pages, layouts}\n return cache\n}\n\nexport function collectLayoutChain(pageKey: string, layouts: Layout[]): Layout[] {\n const pageDir = keyToDir(pageKey)\n\n return layouts\n .filter(layout => pageDir.startsWith(layout.dir))\n .sort((a, b) => a.dir.split('/').length - b.dir.split('/').length)\n}\n\nexport function matchPage(pathname: string, pages: Page[]): {\n page: Page\n params: Record<string, string>\n} | null {\n for (const page of pages) {\n const match = pathname.match(page.regex)\n if (match) {\n const params: Record<string, string> = {}\n page.params.forEach((name, i) => {\n params[name] = decodeURIComponent(match[i + 1])\n })\n return {page, params}\n }\n }\n return null\n}\n", "import {routePattern} from \"../utils/patterns\";\n\nexport interface ApiRoute {\n path: string\n key: string\n params: string[]\n regex: RegExp\n}\n\nexport interface ApiMiddleware {\n dir: string\n key: string\n}\n\nexport interface ApiResult {\n routes: ApiRoute[]\n middlewares: ApiMiddleware[]\n}\n\nexport function keyToRoutePattern(key: string, apiDir: string): string {\n const rel = key.slice(apiDir.length + 1).replace(/\\\\/g, '/')\n const pattern = routePattern(rel)\n return pattern === '/' ? '/api' : `/api/${pattern}`.replace('/api//', '/api/')\n}\n\nfunction keyToDir(key: string): string {\n return key.slice(0, key.lastIndexOf('/'))\n}\n\nlet cache: ApiResult | null = null\n\nexport function invalidateApiCache() {\n cache = null\n}\n\nexport function buildRoutes(routeKeys: string[], middlewareKeys: string[], apiDir: string): ApiResult {\n if (cache) return cache\n\n const routes: ApiRoute[] = []\n const middlewares: ApiMiddleware[] = []\n\n for (const key of middlewareKeys) {\n middlewares.push({dir: keyToDir(key), key})\n }\n\n for (const key of routeKeys) {\n const pattern = keyToRoutePattern(key, apiDir)\n const params = [...pattern.matchAll(/:([^/]+)/g)].map(m => m[1])\n const regexStr = pattern\n .replace(/:[^/]+/g, '([^/]+)')\n .replace(/\\//g, '\\\\/')\n routes.push({path: pattern, key, params, regex: new RegExp(`^${regexStr}$`)})\n }\n routes.sort((a, b) => {\n const aScore = (a.path.match(/:/g) || []).length\n const bScore = (b.path.match(/:/g) || []).length\n if (aScore !== bScore) return aScore - bScore\n return b.path.length - a.path.length\n })\n\n cache = {routes, middlewares}\n return cache\n}\n\nexport function collectMiddlewareChain(routeKey: string, middlewares: ApiMiddleware[]): ApiMiddleware[] {\n const routeDir = keyToDir(routeKey)\n\n return middlewares\n .filter(mw => routeDir.startsWith(mw.dir))\n .sort((a, b) => a.dir.split('/').length - b.dir.split('/').length)\n}\n\nexport function matchRoute(\n pathname: string,\n routes: ApiRoute[]\n): {route: ApiRoute; params: Record<string, string>} | null {\n for (const route of routes) {\n const match = pathname.match(route.regex)\n if (match) {\n const params: Record<string, string> = {}\n route.params.forEach((name, i) => {\n params[name] = decodeURIComponent(match[i + 1])\n })\n return {route, params}\n }\n }\n return null\n}\n", "export function generateContext(): string {\n return `\nexport {RouterContext} from '@devlusoft/devix/runtime/context'\n`\n}", "const HTTP_METHODS = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS'] as const\nexport type HttpMethod = (typeof HTTP_METHODS)[number]\n\nconst METHOD_EXPORT_RE = /export\\s+(?:const|async\\s+function|function)\\s+(GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS)\\b/g\n\nfunction stripComments(content: string): string {\n return content\n .replace(/\\/\\*[\\s\\S]*?\\*\\//g, '')\n .replace(/\\/\\/.*$/gm, '')\n}\n\nexport function extractHttpMethods(content: string): HttpMethod[] {\n const found = new Set<HttpMethod>()\n for (const match of stripComments(content).matchAll(METHOD_EXPORT_RE)) {\n found.add(match[1] as HttpMethod)\n }\n return [...found]\n}\n", "import { keyToRoutePattern } from '../../server/api-router'\nimport type { HttpMethod } from './extract-methods'\n\nexport interface RouteEntry {\n filePath: string\n urlPattern: string\n identifier: string\n methods: HttpMethod[]\n}\n\nexport function filePathToIdentifier(filePath: string, apiDir: string): string {\n return '_api_' + filePath\n .slice(`${apiDir}/`.length)\n .replace(/\\.(ts|tsx)$/, '')\n .replace(/[^a-zA-Z0-9]/g, '_')\n}\n\nexport function buildRouteEntry(filePath: string, apiDir: string, methods: HttpMethod[]): RouteEntry {\n return {\n filePath,\n urlPattern: keyToRoutePattern(filePath, apiDir),\n identifier: filePathToIdentifier(filePath, apiDir),\n methods,\n }\n}\n\nexport function generateRoutesDts(entries: RouteEntry[], apiDir: string): string {\n if (entries.length === 0) {\n return `// auto-generado por devix \u2014 no editar\\ndeclare module '@devlusoft/devix' {\\n interface ApiRoutes {}\\n}\\n`\n }\n\n const imports = entries\n .map(e => {\n const importPath = '../' + e.filePath.replace(/\\.(ts|tsx)$/, '')\n return `import type * as ${e.identifier} from '${importPath}'`\n })\n .join('\\n')\n\n const routeLines = entries.flatMap(e =>\n e.methods.map(m =>\n ` '${m} ${e.urlPattern}': InferRoute<(typeof ${e.identifier})['${m}']>`\n )\n ).join('\\n')\n\n return `// auto-generado por devix \u2014 no editar\n${imports}\n\ntype JsonResponse<T> = Response & { readonly __body: T }\ntype UnwrapJson<T> = T extends JsonResponse<infer U> ? U : never\ntype InferFnReturn<T> = T extends (...args: any[]) => any\n ? UnwrapJson<Awaited<ReturnType<T>>> | Exclude<Awaited<ReturnType<T>>, JsonResponse<any> | null | void | undefined>\n : never\ntype InferRoute<T> =\n T extends { readonly __return?: infer TReturn; readonly __body?: infer TBody }\n ? {\n __body: [TBody] extends [undefined] ? never : Exclude<TBody, undefined>\n __response: InferFnReturn<() => TReturn>\n }\n : InferFnReturn<T>\n\ndeclare module '@devlusoft/devix' {\n interface ApiRoutes {\n${routeLines}\n }\n}\n`\n}\n", "import {readFileSync, readdirSync, statSync} from 'node:fs'\nimport {join, relative} from 'node:path'\nimport {extractHttpMethods} from './extract-methods'\nimport {buildRouteEntry} from './routes-dts'\nimport type {RouteEntry} from './routes-dts'\n\nfunction walkDir(dir: string, root: string): string[] {\n const entries: string[] = []\n for (const name of readdirSync(dir)) {\n const full = join(dir, name)\n if (statSync(full).isDirectory()) {\n entries.push(...walkDir(full, root))\n } else if (/\\.(ts|tsx)$/.test(name)) {\n entries.push(relative(root, full).replace(/\\\\/g, '/'))\n }\n }\n return entries\n}\n\nexport function scanApiFiles(appDir: string, projectRoot: string): RouteEntry[] {\n const apiDir = join(projectRoot, appDir, 'api')\n\n let files: string[]\n try {\n files = walkDir(apiDir, projectRoot)\n } catch {\n return []\n }\n\n return files\n .filter(f => !f.endsWith('middleware.ts') && !f.endsWith('middleware.tsx'))\n .flatMap(filePath => {\n try {\n const content = readFileSync(join(projectRoot, filePath), 'utf-8')\n const methods = extractHttpMethods(content)\n if (methods.length === 0) return []\n return [buildRouteEntry(filePath, `${appDir}/api`, methods)]\n } catch {\n return []\n }\n })\n}\n", "import {mkdirSync, readFileSync, writeFileSync, existsSync} from 'node:fs'\nimport {join} from 'node:path'\n\nexport function writeRoutesDts(content: string, projectRoot: string): boolean {\n const devixDir = join(projectRoot, '.devix')\n const outPath = join(devixDir, 'routes.d.ts')\n\n mkdirSync(devixDir, {recursive: true})\n\n if (existsSync(outPath) && readFileSync(outPath, 'utf-8') === content) {\n return false\n }\n\n writeFileSync(outPath, content, 'utf-8')\n return true\n}\n", "import { UserConfig, Plugin, mergeConfig } from 'vite'\nimport type { DevixConfig } from '../config'\nimport react from '@vitejs/plugin-react'\nimport { fileURLToPath } from 'node:url'\nimport { dirname, resolve } from 'node:path'\nimport { generateEntryClient } from './codegen/entry-client'\nimport { generateClientRoutes } from './codegen/client-routes'\nimport { generateRender } from './codegen/render'\nimport { generateApi } from './codegen/api'\nimport { invalidatePagesCache } from \"../server/pages-router\";\nimport { invalidateApiCache } from \"../server/api-router\";\nimport { generateContext } from \"./codegen/context\";\nimport { scanApiFiles } from \"./codegen/scan-api\";\nimport { generateRoutesDts } from \"./codegen/routes-dts\";\nimport { writeRoutesDts } from \"./codegen/write-routes-dts\";\nimport { parseSync } from 'oxc-parser'\n\nconst __dirname = dirname(fileURLToPath(import.meta.url))\n\nconst VIRTUAL_ENTRY_CLIENT = 'virtual:devix/entry-client'\nconst VIRTUAL_CLIENT_ROUTES = 'virtual:devix/client-routes'\nconst VIRTUAL_RENDER = 'virtual:devix/render'\nconst VIRTUAL_API = 'virtual:devix/api'\nconst VIRTUAL_CONTEXT = 'virtual:devix/context'\n\nconst SERVER_EXPORTS = new Set(['loader', 'guard', 'generateStaticParams', 'headers'])\n\nexport function devix(config: DevixConfig): UserConfig {\n const appDir = config.appDir ?? 'app'\n const pagesDir = `${appDir}/pages`\n const cssUrls = (config.css ?? []).map(u => u.startsWith('/') ? u : `/${u.replace(/^\\.\\//, '')}`)\n\n const renderPath = resolve(__dirname, '../server/render.js').replace(/\\\\/g, '/')\n const apiPath = resolve(__dirname, '../server/api.js').replace(/\\\\/g, '/')\n const matcherPath = resolve(__dirname, '../runtime/client-router.js').replace(/\\\\/g, '/')\n\n const virtualPlugin: Plugin = {\n name: 'devix',\n enforce: 'pre',\n\n resolveId(id) {\n if (id === VIRTUAL_ENTRY_CLIENT) return `\\0${VIRTUAL_ENTRY_CLIENT}`\n if (id === VIRTUAL_CLIENT_ROUTES) return `\\0${VIRTUAL_CLIENT_ROUTES}`\n if (id === VIRTUAL_RENDER) return `\\0${VIRTUAL_RENDER}`\n if (id === VIRTUAL_API) return `\\0${VIRTUAL_API}`\n if (id === VIRTUAL_CONTEXT) return `\\0${VIRTUAL_CONTEXT}`\n },\n\n load(id) {\n if (id === `\\0${VIRTUAL_ENTRY_CLIENT}`)\n return generateEntryClient({ cssUrls })\n if (id === `\\0${VIRTUAL_CLIENT_ROUTES}`)\n return generateClientRoutes({ pagesDir, matcherPath })\n if (id === `\\0${VIRTUAL_RENDER}`)\n return generateRender({ pagesDir, renderPath })\n if (id === `\\0${VIRTUAL_API}`)\n return generateApi({ apiPath, appDir })\n if (id === `\\0${VIRTUAL_CONTEXT}`)\n return generateContext()\n },\n\n\n transform(code, id, options) {\n if (options?.ssr) return\n\n const resolvedPagesDir = resolve(process.cwd(), pagesDir)\n if (!id.startsWith(resolvedPagesDir)) return\n\n const ast = parseSync(id, code, { sourceType: 'module' })\n\n const replacements: { start: number; end: number; name: string }[] = []\n\n for (const node of ast.program.body) {\n if (node.type !== 'ExportNamedDeclaration' || !node.declaration) continue\n\n const decl = node.declaration\n\n if (decl.type === 'FunctionDeclaration' && decl.id && SERVER_EXPORTS.has(decl.id.name)) {\n replacements.push({ start: node.start, end: node.end, name: decl.id.name })\n }\n\n if (decl.type === 'VariableDeclaration') {\n const seen = new Set<number>()\n for (const declarator of decl.declarations) {\n if (declarator.id.type === 'Identifier' && SERVER_EXPORTS.has(declarator.id.name)) {\n if (!seen.has(node.start)) {\n seen.add(node.start)\n replacements.push({ start: node.start, end: node.end, name: declarator.id.name })\n }\n }\n }\n }\n }\n\n if (replacements.length === 0) return\n\n replacements.sort((a, b) => b.start - a.start)\n\n let result = code\n for (const { start, end, name } of replacements) {\n result = result.slice(0, start) + `export const ${name} = undefined` + result.slice(end)\n }\n\n return { code: result, map: null }\n },\n\n buildStart() {\n const root = process.cwd()\n const entries = scanApiFiles(appDir, root)\n writeRoutesDts(generateRoutesDts(entries, `${appDir}/api`), root)\n },\n\n configureServer(server) {\n const root = process.cwd()\n\n const regenerateDts = () => {\n const entries = scanApiFiles(appDir, root)\n writeRoutesDts(generateRoutesDts(entries, `${appDir}/api`), root)\n }\n\n server.watcher.add(resolve(root, 'devix.config.ts'))\n server.watcher.on('change', (file) => {\n if (file === resolve(root, 'devix.config.ts')) {\n console.log('[devix] Config changed, restarting...')\n process.exit(75)\n }\n })\n\n server.watcher.on('add', (file) => {\n if (file.startsWith(resolve(root, pagesDir))) invalidatePagesCache()\n if (file.includes(`${appDir}/api`)) { invalidateApiCache(); regenerateDts() }\n })\n server.watcher.on('unlink', (file) => {\n if (file.startsWith(resolve(root, pagesDir))) invalidatePagesCache()\n if (file.includes(`${appDir}/api`)) { invalidateApiCache(); regenerateDts() }\n })\n server.watcher.on('change', (file) => {\n if (file.includes(`${appDir}/api`) && !file.endsWith('middleware.ts')) {\n regenerateDts()\n }\n })\n },\n }\n\n const base: UserConfig = {\n plugins: [react(), virtualPlugin],\n publicDir: resolve(process.cwd(), config.publicDir ?? 'public'),\n ssr: { noExternal: ['@devlusoft/devix'] },\n ...(config.envPrefix ? { envPrefix: config.envPrefix } : {}),\n }\n\n return mergeConfig(base, config.vite ?? {})\n}", "export function parseDuration(value: number | string): number {\n if (typeof value === 'number') return value\n const match = value.trim().match(/^(\\d+(?:\\.\\d+)?)\\s*(ms|s|m|h)?$/)\n if (!match) throw new Error(`[devix] Invalid duration: \"${value}\". Use a number (ms) or a string like \"5s\", \"2m\", \"500ms\".`)\n const n = parseFloat(match[1])\n switch (match[2]) {\n case 'h': return n * 3_600_000\n case 'm': return n * 60_000\n case 's': return n * 1_000\n case 'ms':\n default: return n\n }\n}\n", "import {writeFileSync} from 'node:fs'\nimport {resolve} from 'node:path'\nimport {build} from 'vite'\nimport type {DevixConfig} from '../config'\nimport {devix} from '../vite'\nimport {parseDuration} from '../utils/duration'\n\nconst config: DevixConfig = (await import(`${process.cwd()}/devix.config.ts`)).default\nconst baseConfig = devix(config)\n\nawait build({\n ...baseConfig,\n configFile: false,\n build: {\n outDir: 'dist/client',\n manifest: true,\n rolldownOptions: {\n input: 'virtual:devix/entry-client',\n },\n },\n})\n\nawait build({\n ...baseConfig,\n configFile: false,\n build: {\n ssr: true,\n outDir: 'dist/server',\n copyPublicDir: false,\n rolldownOptions: {\n input: {\n render: 'virtual:devix/render',\n api: 'virtual:devix/api',\n },\n },\n },\n})\n\nconst runtimeConfig = {\n port: config.port ?? 3000,\n host: config.host ?? false,\n loaderTimeout: parseDuration(config.loaderTimeout ?? 10_000),\n output: config.output ?? 'server',\n}\n\nwriteFileSync(\n resolve(process.cwd(), 'dist/devix.config.json'),\n JSON.stringify(runtimeConfig, null, 2),\n 'utf-8'\n)\n\n\nexport {}", "import {readFileSync, mkdirSync, writeFileSync} from 'node:fs'\nimport {resolve, join} from 'node:path'\nimport type {Manifest} from 'vite'\nimport type {DevixConfig} from '../config'\n\nconst userConfig: DevixConfig = (await import(`${process.cwd()}/devix.config.ts`)).default\nif (userConfig.output !== 'static') {\n console.warn('[devix] Tip: set output: \"static\" in devix.config.ts to skip the SSR server at runtime.')\n}\n\nawait import('./build.js')\n\nconst t = Date.now()\nconst renderModule = await import(resolve(process.cwd(), 'dist/server/render.js') + `?t=${t}`)\n\nconst manifest: Manifest = JSON.parse(\n readFileSync(resolve(process.cwd(), 'dist/client/.vite/manifest.json'), 'utf-8')\n)\n\nconst urls: string[] = await renderModule.getStaticRoutes()\n\nconsole.log(`[devix] Generating ${urls.length} static page${urls.length === 1 ? '' : 's'}...`)\n\nfor (const url of urls) {\n const fullUrl = `http://localhost${url}`\n const {html, statusCode} = await renderModule.render(fullUrl, new Request(fullUrl), {manifest})\n\n if (statusCode !== 200) {\n console.warn(`[devix] Skipping ${url} \u2014 status ${statusCode}`)\n continue\n }\n\n const outPath = url === '/'\n ? join(process.cwd(), 'dist/client/index.html')\n : join(process.cwd(), 'dist/client', url, 'index.html')\n\n mkdirSync(join(outPath, '..'), {recursive: true})\n writeFileSync(outPath, `<!DOCTYPE html>${html}`, 'utf-8')\n console.log(` \u2713 ${url}`)\n}\n\nconsole.log('[devix] Generation complete.')\n\nexport {}\n", "import type {Hono} from 'hono'\nimport type {Manifest} from 'vite'\n\ninterface ServerOptions {\n renderModule: any\n apiModule: any\n manifest?: Manifest\n loaderTimeout?: number\n}\n\nexport function registerApiRoutes(app: Hono, {apiModule, renderModule, loaderTimeout}: ServerOptions) {\n app.all('/api/*', async (c) => {\n try {\n return await apiModule.handleApiRequest(c.req.url, c.req.raw)\n } catch (e) {\n console.error(e)\n return c.json({error: 'internal error'}, 500)\n }\n })\n\n app.get('/_data/*', async (c) => {\n try {\n const {pathname, search} = new URL(c.req.url, 'http://localhost')\n const url = pathname.replace(/^\\/_data/, '') + search\n\n const data = await renderModule.runLoader(url, c.req.raw, {loaderTimeout})\n if (data.error) return c.json({error: 'internal error'}, 500)\n return c.json(data)\n } catch (e) {\n console.error(e)\n return c.json({error: 'internal error'}, 500)\n }\n })\n}\n\nexport function registerSsrRoute(app: Hono, {renderModule, manifest, loaderTimeout}: ServerOptions) {\n app.get('*', async (c) => {\n try {\n const {html, statusCode, headers} = await renderModule.render(c.req.url, c.req.raw, {manifest, loaderTimeout})\n const res = c.html(`<!DOCTYPE html>${html}`, statusCode)\n for (const [key, value] of Object.entries(headers as Record<string, string>)) {\n res.headers.set(key, value)\n }\n return res\n } catch (e) {\n console.error(e)\n return c.text('Internal Server Error', 500)\n }\n })\n}", "import {loadEnv} from 'vite'\n\nexport function loadDotenv(mode: string) {\n const env = loadEnv(mode, process.cwd(), '')\n for (const [key, value] of Object.entries(env)) {\n if (process.env[key] === undefined) {\n process.env[key] = value\n }\n }\n}\n", "import {readFileSync} from 'node:fs'\nimport {serve} from '@hono/node-server'\nimport {serveStatic} from '@hono/node-server/serve-static'\nimport {Hono} from 'hono'\nimport {resolve, join} from 'node:path'\nimport type {Manifest} from 'vite'\nimport {registerApiRoutes, registerSsrRoute} from '../server/routes'\nimport {loadDotenv} from '../utils/env'\n\nloadDotenv('production')\n\nlet renderModule: any\nlet apiModule: any\nlet manifest: Manifest\nlet runtimeConfig: { port: number, host: string | boolean, loaderTimeout: number, output: 'server' | 'static' }\n\ntry {\n runtimeConfig = JSON.parse(readFileSync(resolve(process.cwd(), 'dist/devix.config.json'), 'utf-8'))\n if (runtimeConfig.output !== 'static') {\n renderModule = await import(resolve(process.cwd(), 'dist/server/render.js'))\n apiModule = await import(resolve(process.cwd(), 'dist/server/api.js'))\n }\n manifest = JSON.parse(readFileSync(resolve(process.cwd(), 'dist/client/.vite/manifest.json'), 'utf-8'))\n} catch {\n console.error('[devix] Build not found. Run \"devix build\" first.')\n process.exit(1)\n}\n\nconst port = Number(process.env.PORT) || runtimeConfig!.port || 3000\nconst host = typeof runtimeConfig!.host === 'string'\n ? runtimeConfig!.host\n : runtimeConfig!.host ? '0.0.0.0' : (process.env.HOST || '0.0.0.0')\n\nconst app = new Hono()\n\nconst clientRoot = join(process.cwd(), 'dist/client')\n\napp.use('/*', serveStatic({\n root: clientRoot,\n onFound: (_path, c) => {\n c.header('Cache-Control', _path.includes('/assets/')\n ? 'public, immutable, max-age=31536000'\n : 'no-cache')\n }\n}))\n\nif (runtimeConfig!.output === 'static') {\n console.log('[devix] Static mode \u2014 serving pre-generated files from dist/client')\n} else {\n registerApiRoutes(app, {renderModule, apiModule, manifest})\n registerSsrRoute(app, {renderModule, apiModule, manifest, loaderTimeout: runtimeConfig!.loaderTimeout})\n}\n\nserve({fetch: app.fetch, port, hostname: host}, (info) => console.log(`http://${info.address}:${info.port}`))\n\nexport {}", "#!/usr/bin/env node\ndeclare const __DEVIX_VERSION__: string\n\nconst command = process.argv[2]\n\nswitch (command) {\n case 'dev':\n await import(\"./dev.js\")\n break\n case \"build\":\n await import(\"./build.js\")\n break\n case \"generate\":\n await import(\"./generate.js\")\n break\n case \"start\":\n await import(\"./start.js\")\n break\n case '--version':\n case '-v': {\n console.log(__DEVIX_VERSION__)\n break\n }\n case '--help':\n case '-h':\n console.log(`\ndevix \u2014 a lightweight SSR framework\n\nUsage:\n devix dev Start development server\n devix build Build for production\n devix generate Build and generate static HTML (SSG)\n devix start Start production server\n\nOptions:\n -v, --version Show version\n -h, --help Show this help\n\nOutput modes (set in devix.config.ts):\n output: \"server\" SSR mode \u2014 devix start handles requests dynamically (default)\n output: \"static\" SSG mode \u2014 devix generate pre-renders all pages; devix start serves static files only\n `.trim())\n break\n default:\n console.error(`Unknown command: ${command}`)\n console.error('Usage: devix <dev|build|generate|start>')\n process.exit(1)\n}\n\nexport {}"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { spawnSync } from 'node:child_process'\nimport { fileURLToPath } from 'node:url'\nimport { dirname, resolve } from 'node:path'\n\nconst __dirname = dirname(fileURLToPath(import.meta.url))\n\nwhile (true) {\n const result = spawnSync(process.execPath, [resolve(__dirname, 'dev-server.js')], {\n stdio: 'inherit',\n env: process.env,\n })\n if (result.status !== 75) break\n}\n\nexport { }", "interface EntryClientOptions {\n cssUrls: string[]\n}\n\nexport function generateEntryClient({ cssUrls }: EntryClientOptions): string {\n const cssImports = cssUrls.map(u => `import '${u}'`).join('\\n')\n\n return `\n${cssImports}\nimport \"@vitejs/plugin-react/preamble\"\nimport React from \"react\"\nimport {hydrateRoot, createRoot} from 'react-dom/client'\nimport {matchClientRoute, loadErrorPage, getDefaultErrorPage} from 'virtual:devix/client-routes'\nimport {RouterProvider} from '@devlusoft/devix'\n\nconst root = document.getElementById('devix-root')\n\nif (!window.__DEVIX__) {\n const ErrorPage = getDefaultErrorPage()\n createRoot(root).render(React.createElement(ErrorPage, {statusCode: 500, message: 'Server error'}))\n} else {\n const {metadata, viewport, clientEntry} = window.__DEVIX__\n const loaderData = window.__LOADER_DATA__\n const layoutsData = window.__LAYOUTS_DATA__ ?? []\n\n const matched = matchClientRoute(window.location.pathname)\n\n if (matched) {\n const [pageMod, ...layoutMods] = await Promise.all([\n matched.load(),\n ...matched.loadLayouts.map(l => l()),\n ])\n hydrateRoot(\n root,\n React.createElement(RouterProvider, {\n clientEntry,\n initialData: loaderData,\n initialParams: matched.params,\n initialPage: pageMod.default,\n initialLayouts: layoutMods.map(m => m.default),\n initialLayoutsData: layoutsData,\n initialMeta: metadata,\n initialViewport: viewport,\n })\n )\n\n if (window.location.hash) { \n const id = window.location.hash.slice(1) \n const scrollBehavior = getComputedStyle(document.documentElement).scrollBehavior \n requestAnimationFrame(() => { \n document.getElementById(id)?.scrollIntoView({ behavior: scrollBehavior }) \n }) \n } \n } else {\n const ErrorPage = await loadErrorPage() ?? getDefaultErrorPage()\n createRoot(root).render(\n React.createElement(RouterProvider, {\n clientEntry,\n initialData: null,\n initialParams: {},\n initialPage: () => null,\n initialLayouts: [],\n initialLayoutsData: [],\n initialMeta: null,\n initialError: {statusCode: 404, message: 'Not found'},\n initialErrorPage: ErrorPage,\n })\n )\n }\n}\n`\n}", "interface ClientRoutesOptions {\n pagesDir: string\n matcherPath: string\n}\n\nexport function generateClientRoutes({pagesDir, matcherPath}: ClientRoutesOptions) {\n return `\nimport React from 'react'\nimport { createMatcher } from '${matcherPath}'\nconst pageFiles = import.meta.glob(['/${pagesDir}/**/*.tsx', '!**/error.tsx', '!**/layout.tsx'])\nconst layoutFiles = import.meta.glob('/${pagesDir}/**/layout.tsx')\nconst errorFiles = import.meta.glob('/${pagesDir}/**/error.tsx')\n\nexport const matchClientRoute = createMatcher(pageFiles, layoutFiles)\n\nexport async function loadErrorPage() {\n const key = Object.keys(errorFiles)[0]\n if (!key) return null\n const mod = await errorFiles[key]()\n return mod?.default ?? null\n}\n\nexport function getDefaultErrorPage() {\n return function DefaultError({ statusCode, message }) {\n return React.createElement('main', {\n style: { minHeight: '100dvh', display: 'flex', flexDirection: 'column', \n alignItems: 'center', justifyContent: 'center', gap: '8px',\n fontFamily: 'system-ui, sans-serif' }\n },\n React.createElement('h1', {style: {fontSize: '4rem', fontWeight: 700}}, statusCode),\n React.createElement('p', {style: {color: '#666'}}, message ?? 'An unexpected error occurred'),\n )\n }\n}\n`\n}", "interface RenderOptions {\n pagesDir: string\n renderPath: string\n}\n\nexport function generateRender({pagesDir, renderPath}: RenderOptions): string {\n return `\nimport { render as _render, runLoader as _runLoader, getStaticRoutes as _getStaticRoutes } from '${renderPath}'\n\nconst _pages = import.meta.glob(['/${pagesDir}/**/*.tsx', '!**/error.tsx', '!**/layout.tsx'])\nconst _layouts = import.meta.glob('/${pagesDir}/**/layout.tsx')\n\nconst _glob = {\n pages: _pages,\n layouts: _layouts,\n pagesDir: '/${pagesDir}',\n}\n\nexport function render(url, request, options) {\n return _render(url, request, _glob, options)\n}\n\nexport function runLoader(url, request, options) {\n return _runLoader(url, request, _glob, options)\n}\n\nexport function getStaticRoutes() {\n return _getStaticRoutes(_glob)\n}\n`\n}\n", "interface ApiOptions {\n apiPath: string\n appDir: string\n}\n\nexport function generateApi({apiPath, appDir}: ApiOptions): string {\n return `\nimport { handleApiRequest as _handleApiRequest } from '${apiPath}'\n\nconst _routes = import.meta.glob(['/${appDir}/api/**/*.ts', '!**/middleware.ts'])\nconst _middlewares = import.meta.glob('/${appDir}/api/**/middleware.ts')\n\nconst _glob = {\n routes: _routes,\n middlewares: _middlewares,\n apiDir: '/${appDir}/api',\n}\n\nexport function handleApiRequest(url, request) {\n return _handleApiRequest(url, request, _glob)\n}\n`\n}\n", "export function routePattern(rel: string): string {\n return rel\n .replace(/\\.(tsx|ts|jsx|js)$/, '')\n .replace(/\\(.*?\\)\\//g, '')\n .replace(/^index$|\\/index$/, '')\n .replace(/\\[([^\\]]+)]/g, ':$1')\n || '/'\n}", "import {routePattern} from \"../utils/patterns\";\n\nexport interface Page {\n path: string\n key: string\n params: string[]\n regex: RegExp\n}\n\nexport interface Layout {\n dir: string\n key: string\n}\n\nexport interface PagesResult {\n pages: Page[]\n layouts: Layout[]\n}\n\nfunction keyToRoutePattern(key: string, pagesDir: string): string {\n const rel = key.slice(pagesDir.length + 1).replace(/\\\\/g, '/')\n const pattern = routePattern(rel)\n return pattern === \"/\" ? \"/\" : `/${pattern}`\n}\n\nfunction keyToDir(key: string): string {\n return key.slice(0, key.lastIndexOf('/'))\n}\n\nlet cache: PagesResult | null = null\n\nexport function invalidatePagesCache() {\n cache = null\n}\n\nexport function buildPages(pageKeys: string[], layoutKeys: string[], pagesDir: string): PagesResult {\n if (cache) return cache\n\n const pages: Page[] = []\n const layouts: Layout[] = []\n\n for (const key of layoutKeys) {\n layouts.push({dir: keyToDir(key), key})\n }\n\n for (const key of pageKeys) {\n const pattern = keyToRoutePattern(key, pagesDir)\n const params = [...pattern.matchAll(/:([^/]+)/g)].map(m => m[1])\n const regexStr = pattern\n .replace(/:[^/]+/g, '([^/]+)')\n .replace(/\\//g, '\\\\/')\n pages.push({path: pattern, key, params, regex: new RegExp(`^${regexStr}$`)})\n }\n\n pages.sort((a, b) => {\n const aScore = (a.path.match(/:/g) || []).length\n const bScore = (b.path.match(/:/g) || []).length\n if (aScore !== bScore) return aScore - bScore\n return b.path.length - a.path.length\n })\n\n cache = {pages, layouts}\n return cache\n}\n\nexport function collectLayoutChain(pageKey: string, layouts: Layout[]): Layout[] {\n const pageDir = keyToDir(pageKey)\n\n return layouts\n .filter(layout => pageDir.startsWith(layout.dir))\n .sort((a, b) => a.dir.split('/').length - b.dir.split('/').length)\n}\n\nexport function matchPage(pathname: string, pages: Page[]): {\n page: Page\n params: Record<string, string>\n} | null {\n for (const page of pages) {\n const match = pathname.match(page.regex)\n if (match) {\n const params: Record<string, string> = {}\n page.params.forEach((name, i) => {\n params[name] = decodeURIComponent(match[i + 1])\n })\n return {page, params}\n }\n }\n return null\n}\n", "import {routePattern} from \"../utils/patterns\";\n\nexport interface ApiRoute {\n path: string\n key: string\n params: string[]\n regex: RegExp\n}\n\nexport interface ApiMiddleware {\n dir: string\n key: string\n}\n\nexport interface ApiResult {\n routes: ApiRoute[]\n middlewares: ApiMiddleware[]\n}\n\nexport function keyToRoutePattern(key: string, apiDir: string): string {\n const rel = key.slice(apiDir.length + 1).replace(/\\\\/g, '/')\n const pattern = routePattern(rel)\n return pattern === '/' ? '/api' : `/api/${pattern}`.replace('/api//', '/api/')\n}\n\nfunction keyToDir(key: string): string {\n return key.slice(0, key.lastIndexOf('/'))\n}\n\nlet cache: ApiResult | null = null\n\nexport function invalidateApiCache() {\n cache = null\n}\n\nexport function buildRoutes(routeKeys: string[], middlewareKeys: string[], apiDir: string): ApiResult {\n if (cache) return cache\n\n const routes: ApiRoute[] = []\n const middlewares: ApiMiddleware[] = []\n\n for (const key of middlewareKeys) {\n middlewares.push({dir: keyToDir(key), key})\n }\n\n for (const key of routeKeys) {\n const pattern = keyToRoutePattern(key, apiDir)\n const params = [...pattern.matchAll(/:([^/]+)/g)].map(m => m[1])\n const regexStr = pattern\n .replace(/:[^/]+/g, '([^/]+)')\n .replace(/\\//g, '\\\\/')\n routes.push({path: pattern, key, params, regex: new RegExp(`^${regexStr}$`)})\n }\n routes.sort((a, b) => {\n const aScore = (a.path.match(/:/g) || []).length\n const bScore = (b.path.match(/:/g) || []).length\n if (aScore !== bScore) return aScore - bScore\n return b.path.length - a.path.length\n })\n\n cache = {routes, middlewares}\n return cache\n}\n\nexport function collectMiddlewareChain(routeKey: string, middlewares: ApiMiddleware[]): ApiMiddleware[] {\n const routeDir = keyToDir(routeKey)\n\n return middlewares\n .filter(mw => routeDir.startsWith(mw.dir))\n .sort((a, b) => a.dir.split('/').length - b.dir.split('/').length)\n}\n\nexport function matchRoute(\n pathname: string,\n routes: ApiRoute[]\n): {route: ApiRoute; params: Record<string, string>} | null {\n for (const route of routes) {\n const match = pathname.match(route.regex)\n if (match) {\n const params: Record<string, string> = {}\n route.params.forEach((name, i) => {\n params[name] = decodeURIComponent(match[i + 1])\n })\n return {route, params}\n }\n }\n return null\n}\n", "export function generateContext(): string {\n return `\nexport {RouterContext} from '@devlusoft/devix/runtime/context'\n`\n}", "const HTTP_METHODS = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS'] as const\nexport type HttpMethod = (typeof HTTP_METHODS)[number]\n\nconst METHOD_EXPORT_RE = /export\\s+(?:const|async\\s+function|function)\\s+(GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS)\\b/g\n\nfunction stripComments(content: string): string {\n return content\n .replace(/\\/\\*[\\s\\S]*?\\*\\//g, '')\n .replace(/\\/\\/.*$/gm, '')\n}\n\nexport function extractHttpMethods(content: string): HttpMethod[] {\n const found = new Set<HttpMethod>()\n for (const match of stripComments(content).matchAll(METHOD_EXPORT_RE)) {\n found.add(match[1] as HttpMethod)\n }\n return [...found]\n}\n", "import { keyToRoutePattern } from '../../server/api-router'\nimport type { HttpMethod } from './extract-methods'\n\nexport interface RouteEntry {\n filePath: string\n urlPattern: string\n identifier: string\n methods: HttpMethod[]\n}\n\nexport function filePathToIdentifier(filePath: string, apiDir: string): string {\n return '_api_' + filePath\n .slice(`${apiDir}/`.length)\n .replace(/\\.(ts|tsx)$/, '')\n .replace(/[^a-zA-Z0-9]/g, '_')\n}\n\nexport function buildRouteEntry(filePath: string, apiDir: string, methods: HttpMethod[]): RouteEntry {\n return {\n filePath,\n urlPattern: keyToRoutePattern(filePath, apiDir),\n identifier: filePathToIdentifier(filePath, apiDir),\n methods,\n }\n}\n\nexport function generateRoutesDts(entries: RouteEntry[], apiDir: string): string {\n if (entries.length === 0) {\n return `// auto-generado por devix \u2014 no editar\\ndeclare module '@devlusoft/devix' {\\n interface ApiRoutes {}\\n}\\n`\n }\n\n const imports = entries\n .map(e => {\n const importPath = '../' + e.filePath.replace(/\\.(ts|tsx)$/, '')\n return `import type * as ${e.identifier} from '${importPath}'`\n })\n .join('\\n')\n\n const routeLines = entries.flatMap(e =>\n e.methods.map(m =>\n ` '${m} ${e.urlPattern}': InferRoute<(typeof ${e.identifier})['${m}']>`\n )\n ).join('\\n')\n\n return `// auto-generado por devix \u2014 no editar\n${imports}\n\ntype JsonResponse<T> = Response & { readonly __body: T }\ntype UnwrapJson<T> = T extends JsonResponse<infer U> ? U : never\ntype InferFnReturn<T> = T extends (...args: any[]) => any\n ? UnwrapJson<Awaited<ReturnType<T>>> | Exclude<Awaited<ReturnType<T>>, JsonResponse<any> | null | void | undefined>\n : never\ntype InferRoute<T> =\n T extends { readonly __return?: infer TReturn; readonly __body?: infer TBody }\n ? {\n __body: [TBody] extends [undefined] ? never : Exclude<TBody, undefined>\n __response: InferFnReturn<() => TReturn>\n }\n : InferFnReturn<T>\n\ndeclare module '@devlusoft/devix' {\n interface ApiRoutes {\n${routeLines}\n }\n}\n`\n}\n", "import {readFileSync, readdirSync, statSync} from 'node:fs'\nimport {join, relative} from 'node:path'\nimport {extractHttpMethods} from './extract-methods'\nimport {buildRouteEntry} from './routes-dts'\nimport type {RouteEntry} from './routes-dts'\n\nfunction walkDir(dir: string, root: string): string[] {\n const entries: string[] = []\n for (const name of readdirSync(dir)) {\n const full = join(dir, name)\n if (statSync(full).isDirectory()) {\n entries.push(...walkDir(full, root))\n } else if (/\\.(ts|tsx)$/.test(name)) {\n entries.push(relative(root, full).replace(/\\\\/g, '/'))\n }\n }\n return entries\n}\n\nexport function scanApiFiles(appDir: string, projectRoot: string): RouteEntry[] {\n const apiDir = join(projectRoot, appDir, 'api')\n\n let files: string[]\n try {\n files = walkDir(apiDir, projectRoot)\n } catch {\n return []\n }\n\n return files\n .filter(f => !f.endsWith('middleware.ts') && !f.endsWith('middleware.tsx'))\n .flatMap(filePath => {\n try {\n const content = readFileSync(join(projectRoot, filePath), 'utf-8')\n const methods = extractHttpMethods(content)\n if (methods.length === 0) return []\n return [buildRouteEntry(filePath, `${appDir}/api`, methods)]\n } catch {\n return []\n }\n })\n}\n", "import {mkdirSync, readFileSync, writeFileSync, existsSync} from 'node:fs'\nimport {join} from 'node:path'\n\nexport function writeRoutesDts(content: string, projectRoot: string): boolean {\n const devixDir = join(projectRoot, '.devix')\n const outPath = join(devixDir, 'routes.d.ts')\n\n mkdirSync(devixDir, {recursive: true})\n\n if (existsSync(outPath) && readFileSync(outPath, 'utf-8') === content) {\n return false\n }\n\n writeFileSync(outPath, content, 'utf-8')\n return true\n}\n", "import { UserConfig, Plugin, mergeConfig } from 'vite'\nimport type { DevixConfig } from '../config'\nimport react from '@vitejs/plugin-react'\nimport { fileURLToPath } from 'node:url'\nimport { dirname, resolve } from 'node:path'\nimport { generateEntryClient } from './codegen/entry-client'\nimport { generateClientRoutes } from './codegen/client-routes'\nimport { generateRender } from './codegen/render'\nimport { generateApi } from './codegen/api'\nimport { invalidatePagesCache } from \"../server/pages-router\";\nimport { invalidateApiCache } from \"../server/api-router\";\nimport { generateContext } from \"./codegen/context\";\nimport { scanApiFiles } from \"./codegen/scan-api\";\nimport { generateRoutesDts } from \"./codegen/routes-dts\";\nimport { writeRoutesDts } from \"./codegen/write-routes-dts\";\nimport { parseSync } from 'oxc-parser'\n\nconst __dirname = dirname(fileURLToPath(import.meta.url))\n\nconst VIRTUAL_ENTRY_CLIENT = 'virtual:devix/entry-client'\nconst VIRTUAL_CLIENT_ROUTES = 'virtual:devix/client-routes'\nconst VIRTUAL_RENDER = 'virtual:devix/render'\nconst VIRTUAL_API = 'virtual:devix/api'\nconst VIRTUAL_CONTEXT = 'virtual:devix/context'\n\nconst SERVER_EXPORTS = new Set(['loader', 'guard', 'generateStaticParams', 'headers'])\n\nexport function devix(config: DevixConfig): UserConfig {\n const appDir = config.appDir ?? 'app'\n const pagesDir = `${appDir}/pages`\n const cssUrls = (config.css ?? []).map(u => u.startsWith('/') ? u : `/${u.replace(/^\\.\\//, '')}`)\n\n const renderPath = resolve(__dirname, '../server/render.js').replace(/\\\\/g, '/')\n const apiPath = resolve(__dirname, '../server/api.js').replace(/\\\\/g, '/')\n const matcherPath = resolve(__dirname, '../runtime/client-router.js').replace(/\\\\/g, '/')\n\n const virtualPlugin: Plugin = {\n name: 'devix',\n enforce: 'pre',\n\n resolveId(id) {\n if (id === VIRTUAL_ENTRY_CLIENT) return `\\0${VIRTUAL_ENTRY_CLIENT}`\n if (id === VIRTUAL_CLIENT_ROUTES) return `\\0${VIRTUAL_CLIENT_ROUTES}`\n if (id === VIRTUAL_RENDER) return `\\0${VIRTUAL_RENDER}`\n if (id === VIRTUAL_API) return `\\0${VIRTUAL_API}`\n if (id === VIRTUAL_CONTEXT) return `\\0${VIRTUAL_CONTEXT}`\n },\n\n load(id) {\n if (id === `\\0${VIRTUAL_ENTRY_CLIENT}`)\n return generateEntryClient({ cssUrls })\n if (id === `\\0${VIRTUAL_CLIENT_ROUTES}`)\n return generateClientRoutes({ pagesDir, matcherPath })\n if (id === `\\0${VIRTUAL_RENDER}`)\n return generateRender({ pagesDir, renderPath })\n if (id === `\\0${VIRTUAL_API}`)\n return generateApi({ apiPath, appDir })\n if (id === `\\0${VIRTUAL_CONTEXT}`)\n return generateContext()\n },\n\n\n transform(code, id, options) {\n if (options?.ssr) return\n\n const resolvedPagesDir = resolve(process.cwd(), pagesDir)\n if (!id.startsWith(resolvedPagesDir)) return\n\n const ast = parseSync(id, code, { sourceType: 'module' })\n\n const replacements: { start: number; end: number; name: string }[] = []\n\n for (const node of ast.program.body) {\n if (node.type !== 'ExportNamedDeclaration' || !node.declaration) continue\n\n const decl = node.declaration\n\n if (decl.type === 'FunctionDeclaration' && decl.id && SERVER_EXPORTS.has(decl.id.name)) {\n replacements.push({ start: node.start, end: node.end, name: decl.id.name })\n }\n\n if (decl.type === 'VariableDeclaration') {\n const seen = new Set<number>()\n for (const declarator of decl.declarations) {\n if (declarator.id.type === 'Identifier' && SERVER_EXPORTS.has(declarator.id.name)) {\n if (!seen.has(node.start)) {\n seen.add(node.start)\n replacements.push({ start: node.start, end: node.end, name: declarator.id.name })\n }\n }\n }\n }\n }\n\n if (replacements.length === 0) return\n\n replacements.sort((a, b) => b.start - a.start)\n\n let result = code\n for (const { start, end, name } of replacements) {\n result = result.slice(0, start) + `export const ${name} = undefined` + result.slice(end)\n }\n\n return { code: result, map: null }\n },\n\n buildStart() {\n const root = process.cwd()\n const entries = scanApiFiles(appDir, root)\n writeRoutesDts(generateRoutesDts(entries, `${appDir}/api`), root)\n },\n\n configureServer(server) {\n const root = process.cwd()\n\n const regenerateDts = () => {\n const entries = scanApiFiles(appDir, root)\n writeRoutesDts(generateRoutesDts(entries, `${appDir}/api`), root)\n }\n\n server.watcher.add(resolve(root, 'devix.config.ts'))\n server.watcher.on('change', (file) => {\n if (file === resolve(root, 'devix.config.ts')) {\n console.log('[devix] Config changed, restarting...')\n process.exit(75)\n }\n })\n\n server.watcher.on('add', (file) => {\n if (file.startsWith(resolve(root, pagesDir))) invalidatePagesCache()\n if (file.includes(`${appDir}/api`)) { invalidateApiCache(); regenerateDts() }\n })\n server.watcher.on('unlink', (file) => {\n if (file.startsWith(resolve(root, pagesDir))) invalidatePagesCache()\n if (file.includes(`${appDir}/api`)) { invalidateApiCache(); regenerateDts() }\n })\n server.watcher.on('change', (file) => {\n if (file.includes(`${appDir}/api`) && !file.endsWith('middleware.ts')) {\n regenerateDts()\n }\n })\n },\n }\n\n const base: UserConfig = {\n plugins: [react(), virtualPlugin],\n publicDir: resolve(process.cwd(), config.publicDir ?? 'public'),\n ssr: { noExternal: ['@devlusoft/devix'] },\n ...(config.envPrefix ? { envPrefix: config.envPrefix } : {}),\n }\n\n return mergeConfig(base, config.vite ?? {})\n}", "export function parseDuration(value: number | string): number {\n if (typeof value === 'number') return value\n const match = value.trim().match(/^(\\d+(?:\\.\\d+)?)\\s*(ms|s|m|h)?$/)\n if (!match) throw new Error(`[devix] Invalid duration: \"${value}\". Use a number (ms) or a string like \"5s\", \"2m\", \"500ms\".`)\n const n = parseFloat(match[1])\n switch (match[2]) {\n case 'h': return n * 3_600_000\n case 'm': return n * 60_000\n case 's': return n * 1_000\n case 'ms':\n default: return n\n }\n}\n", "import {writeFileSync} from 'node:fs'\nimport {resolve} from 'node:path'\nimport {build} from 'vite'\nimport type {DevixConfig} from '../config'\nimport {devix} from '../vite'\nimport {parseDuration} from '../utils/duration'\n\nconst config: DevixConfig = (await import(`${process.cwd()}/devix.config.ts`)).default\nconst baseConfig = devix(config)\n\nawait build({\n ...baseConfig,\n configFile: false,\n build: {\n outDir: 'dist/client',\n manifest: true,\n rolldownOptions: {\n input: 'virtual:devix/entry-client',\n },\n },\n})\n\nawait build({\n ...baseConfig,\n configFile: false,\n build: {\n ssr: true,\n outDir: 'dist/server',\n copyPublicDir: false,\n rolldownOptions: {\n input: {\n render: 'virtual:devix/render',\n api: 'virtual:devix/api',\n },\n },\n },\n})\n\nconst runtimeConfig = {\n port: config.port ?? 3000,\n host: config.host ?? false,\n loaderTimeout: parseDuration(config.loaderTimeout ?? 10_000),\n output: config.output ?? 'server',\n}\n\nwriteFileSync(\n resolve(process.cwd(), 'dist/devix.config.json'),\n JSON.stringify(runtimeConfig, null, 2),\n 'utf-8'\n)\n\n\nexport {}", "import {readFileSync, mkdirSync, writeFileSync} from 'node:fs'\nimport {resolve, join} from 'node:path'\nimport type {Manifest} from 'vite'\nimport type {DevixConfig} from '../config'\n\nconst userConfig: DevixConfig = (await import(`${process.cwd()}/devix.config.ts`)).default\nif (userConfig.output !== 'static') {\n console.warn('[devix] Tip: set output: \"static\" in devix.config.ts to skip the SSR server at runtime.')\n}\n\nawait import('./build.js')\n\nconst t = Date.now()\nconst renderModule = await import(resolve(process.cwd(), 'dist/server/render.js') + `?t=${t}`)\n\nconst manifest: Manifest = JSON.parse(\n readFileSync(resolve(process.cwd(), 'dist/client/.vite/manifest.json'), 'utf-8')\n)\n\nconst urls: string[] = await renderModule.getStaticRoutes()\n\nconsole.log(`[devix] Generating ${urls.length} static page${urls.length === 1 ? '' : 's'}...`)\n\nfor (const url of urls) {\n const fullUrl = `http://localhost${url}`\n const {html, statusCode} = await renderModule.render(fullUrl, new Request(fullUrl), {manifest})\n\n if (statusCode !== 200) {\n console.warn(`[devix] Skipping ${url} \u2014 status ${statusCode}`)\n continue\n }\n\n const outPath = url === '/'\n ? join(process.cwd(), 'dist/client/index.html')\n : join(process.cwd(), 'dist/client', url, 'index.html')\n\n mkdirSync(join(outPath, '..'), {recursive: true})\n writeFileSync(outPath, `<!DOCTYPE html>${html}`, 'utf-8')\n console.log(` \u2713 ${url}`)\n}\n\nconsole.log('[devix] Generation complete.')\n\nexport {}\n", "import type {Hono} from 'hono'\nimport type {Manifest} from 'vite'\n\ninterface ServerOptions {\n renderModule: any\n apiModule: any\n manifest?: Manifest\n loaderTimeout?: number\n}\n\nexport function registerApiRoutes(app: Hono, {apiModule, renderModule, loaderTimeout}: ServerOptions) {\n app.all('/api/*', async (c) => {\n try {\n return await apiModule.handleApiRequest(c.req.url, c.req.raw)\n } catch (e) {\n console.error(e)\n return c.json({error: 'internal error'}, 500)\n }\n })\n\n app.get('/_data/*', async (c) => {\n try {\n const {pathname, search} = new URL(c.req.url, 'http://localhost')\n const url = pathname.replace(/^\\/_data/, '') + search\n\n const data = await renderModule.runLoader(url, c.req.raw, {loaderTimeout})\n if (data.error) return c.json({error: 'internal error'}, 500)\n return c.json(data)\n } catch (e) {\n console.error(e)\n return c.json({error: 'internal error'}, 500)\n }\n })\n}\n\nexport function registerSsrRoute(app: Hono, {renderModule, manifest, loaderTimeout}: ServerOptions) {\n app.get('*', async (c) => {\n try {\n const {html, statusCode, headers} = await renderModule.render(c.req.url, c.req.raw, {manifest, loaderTimeout})\n const res = c.html(`<!DOCTYPE html>${html}`, statusCode)\n for (const [key, value] of Object.entries(headers as Record<string, string>)) {\n res.headers.set(key, value)\n }\n return res\n } catch (e) {\n console.error(e)\n return c.text('Internal Server Error', 500)\n }\n })\n}", "import {loadEnv} from 'vite'\n\nexport function loadDotenv(mode: string) {\n const env = loadEnv(mode, process.cwd(), '')\n for (const [key, value] of Object.entries(env)) {\n if (process.env[key] === undefined) {\n process.env[key] = value\n }\n }\n}\n", "import {readFileSync} from 'node:fs'\nimport {serve} from '@hono/node-server'\nimport {serveStatic} from '@hono/node-server/serve-static'\nimport {Hono} from 'hono'\nimport {resolve, join} from 'node:path'\nimport type {Manifest} from 'vite'\nimport {registerApiRoutes, registerSsrRoute} from '../server/routes'\nimport {loadDotenv} from '../utils/env'\n\nloadDotenv('production')\n\nlet renderModule: any\nlet apiModule: any\nlet manifest: Manifest\nlet runtimeConfig: { port: number, host: string | boolean, loaderTimeout: number, output: 'server' | 'static' }\n\ntry {\n runtimeConfig = JSON.parse(readFileSync(resolve(process.cwd(), 'dist/devix.config.json'), 'utf-8'))\n if (runtimeConfig.output !== 'static') {\n renderModule = await import(resolve(process.cwd(), 'dist/server/render.js'))\n apiModule = await import(resolve(process.cwd(), 'dist/server/api.js'))\n }\n manifest = JSON.parse(readFileSync(resolve(process.cwd(), 'dist/client/.vite/manifest.json'), 'utf-8'))\n} catch {\n console.error('[devix] Build not found. Run \"devix build\" first.')\n process.exit(1)\n}\n\nconst port = Number(process.env.PORT) || runtimeConfig!.port || 3000\nconst host = typeof runtimeConfig!.host === 'string'\n ? runtimeConfig!.host\n : runtimeConfig!.host ? '0.0.0.0' : (process.env.HOST || '0.0.0.0')\n\nconst app = new Hono()\n\nconst clientRoot = join(process.cwd(), 'dist/client')\n\napp.use('/*', serveStatic({\n root: clientRoot,\n onFound: (_path, c) => {\n c.header('Cache-Control', _path.includes('/assets/')\n ? 'public, immutable, max-age=31536000'\n : 'no-cache')\n }\n}))\n\nif (runtimeConfig!.output === 'static') {\n console.log('[devix] Static mode \u2014 serving pre-generated files from dist/client')\n} else {\n registerApiRoutes(app, {renderModule, apiModule, manifest})\n registerSsrRoute(app, {renderModule, apiModule, manifest, loaderTimeout: runtimeConfig!.loaderTimeout})\n}\n\nserve({fetch: app.fetch, port, hostname: host}, (info) => console.log(`http://${info.address}:${info.port}`))\n\nexport {}", "#!/usr/bin/env node\ndeclare const __DEVIX_VERSION__: string\n\nconst command = process.argv[2]\n\nswitch (command) {\n case 'dev':\n await import(\"./dev.js\")\n break\n case \"build\":\n await import(\"./build.js\")\n break\n case \"generate\":\n await import(\"./generate.js\")\n break\n case \"start\":\n await import(\"./start.js\")\n break\n case '--version':\n case '-v': {\n console.log(__DEVIX_VERSION__)\n break\n }\n case '--help':\n case '-h':\n console.log(`\ndevix \u2014 a lightweight SSR framework\n\nUsage:\n devix dev Start development server\n devix build Build for production\n devix generate Build and generate static HTML (SSG)\n devix start Start production server\n\nOptions:\n -v, --version Show version\n -h, --help Show this help\n\nOutput modes (set in devix.config.ts):\n output: \"server\" SSR mode \u2014 devix start handles requests dynamically (default)\n output: \"static\" SSG mode \u2014 devix generate pre-renders all pages; devix start serves static files only\n `.trim())\n break\n default:\n console.error(`Unknown command: ${command}`)\n console.error('Usage: devix <dev|build|generate|start>')\n process.exit(1)\n}\n\nexport {}"],
5
+ "mappings": ";mCAAA,IAAAA,GAAA,UAAS,aAAAC,OAAiB,qBAC1B,OAAS,iBAAAC,OAAqB,WAC9B,OAAS,WAAAC,GAAS,WAAAC,OAAe,YAFjC,IAIMC,GAJNC,EAAAC,EAAA,kBAIMF,GAAYF,GAAQD,GAAc,YAAY,GAAG,CAAC,EAExD,KACmBD,GAAU,QAAQ,SAAU,CAACG,GAAQC,GAAW,eAAe,CAAC,EAAG,CAC9E,MAAO,UACP,IAAK,QAAQ,GACjB,CAAC,EACU,SAAW,IAAtB,ICPG,SAASG,EAAoB,CAAE,QAAAC,CAAQ,EAA+B,CAGzE,MAAO;AAAA,EAFYA,EAAQ,IAAIC,GAAK,WAAWA,CAAC,GAAG,EAAE,KAAK;AAAA,CAAI,CAGtD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CA+DZ,CAvEA,IAAAC,EAAAC,EAAA,oBCKO,SAASC,EAAqB,CAAC,SAAAC,EAAU,YAAAC,CAAW,EAAwB,CAC/E,MAAO;AAAA;AAAA,iCAEsBA,CAAW;AAAA,wCACJD,CAAQ;AAAA,yCACPA,CAAQ;AAAA,wCACTA,CAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAwBhD,CAnCA,IAAAE,EAAAC,EAAA,oBCKO,SAASC,EAAe,CAAC,SAAAC,EAAU,WAAAC,CAAU,EAA0B,CAC1E,MAAO;AAAA,mGACwFA,CAAU;AAAA;AAAA,qCAExED,CAAQ;AAAA,sCACPA,CAAQ;AAAA;AAAA;AAAA;AAAA;AAAA,kBAK5BA,CAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAe1B,CA9BA,IAAAE,EAAAC,EAAA,oBCKO,SAASC,GAAY,CAAC,QAAAC,EAAS,OAAAC,CAAM,EAAuB,CAC/D,MAAO;AAAA,yDAC8CD,CAAO;AAAA;AAAA,sCAE1BC,CAAM;AAAA,0CACFA,CAAM;AAAA;AAAA;AAAA;AAAA;AAAA,gBAKhCA,CAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAOtB,CAtBA,IAAAC,GAAAC,EAAA,oBCAO,SAASC,EAAaC,EAAqB,CAC9C,OAAOA,EACE,QAAQ,qBAAsB,EAAE,EAChC,QAAQ,aAAc,EAAE,EACxB,QAAQ,mBAAoB,EAAE,EAC9B,QAAQ,eAAgB,KAAK,GAC/B,GACX,CAPA,IAAAC,EAAAC,EAAA,oBC+BO,SAASC,GAAuB,CACnCC,GAAQ,IACZ,CAjCA,IA6BIA,GA7BJC,GAAAC,EAAA,kBAAAC,IA6BIH,GAA4B,OCVzB,SAASI,GAAkBC,EAAaC,EAAwB,CACnE,IAAMC,EAAMF,EAAI,MAAMC,EAAO,OAAS,CAAC,EAAE,QAAQ,MAAO,GAAG,EACrDE,EAAUC,EAAaF,CAAG,EAChC,OAAOC,IAAY,IAAM,OAAS,QAAQA,CAAO,GAAG,QAAQ,SAAU,OAAO,CACjF,CAQO,SAASE,GAAqB,CACjCC,GAAQ,IACZ,CAjCA,IA6BIA,GA7BJC,EAAAC,EAAA,kBAAAC,IA6BIH,GAA0B,OC7BvB,SAASI,IAA0B,CACtC,MAAO;AAAA;AAAA,CAGX,CAJA,IAAAC,GAAAC,EAAA,oBCKA,SAASC,GAAcC,EAAyB,CAC5C,OAAOA,EACF,QAAQ,oBAAqB,EAAE,EAC/B,QAAQ,YAAa,EAAE,CAChC,CAEO,SAASC,GAAmBD,EAA+B,CAC9D,IAAME,EAAQ,IAAI,IAClB,QAAWC,KAASJ,GAAcC,CAAO,EAAE,SAASI,EAAgB,EAChEF,EAAM,IAAIC,EAAM,CAAC,CAAe,EAEpC,MAAO,CAAC,GAAGD,CAAK,CACpB,CAjBA,IAGME,GAHNC,GAAAC,EAAA,kBAGMF,GAAmB,+FCOlB,SAASG,GAAqBC,EAAkBC,EAAwB,CAC3E,MAAO,QAAUD,EACZ,MAAM,GAAGC,CAAM,IAAI,MAAM,EACzB,QAAQ,cAAe,EAAE,EACzB,QAAQ,gBAAiB,GAAG,CACrC,CAEO,SAASC,GAAgBF,EAAkBC,EAAgBE,EAAmC,CACjG,MAAO,CACH,SAAAH,EACA,WAAYI,GAAkBJ,EAAUC,CAAM,EAC9C,WAAYF,GAAqBC,EAAUC,CAAM,EACjD,QAAAE,CACJ,CACJ,CAEO,SAASE,EAAkBC,EAAuBL,EAAwB,CAC7E,GAAIK,EAAQ,SAAW,EACnB,MAAO;AAAA;AAAA;AAAA;AAAA,EAGX,IAAMC,EAAUD,EACX,IAAIE,GAAK,CACN,IAAMC,EAAa,MAAQD,EAAE,SAAS,QAAQ,cAAe,EAAE,EAC/D,MAAO,oBAAoBA,EAAE,UAAU,UAAUC,CAAU,GAC/D,CAAC,EACA,KAAK;AAAA,CAAI,EAERC,EAAaJ,EAAQ,QAAQE,GAC/BA,EAAE,QAAQ,IAAIG,GACV,QAAQA,CAAC,IAAIH,EAAE,UAAU,yBAAyBA,EAAE,UAAU,MAAMG,CAAC,KACzE,CACJ,EAAE,KAAK;AAAA,CAAI,EAEX,MAAO;AAAA,EACTJ,CAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiBPG,CAAU;AAAA;AAAA;AAAA,CAIZ,CAlEA,IAAAE,EAAAC,EAAA,kBAAAC,MCAA,OAAQ,gBAAAC,GAAc,eAAAC,GAAa,YAAAC,OAAe,UAClD,OAAQ,QAAAC,EAAM,YAAAC,OAAe,YAK7B,SAASC,GAAQC,EAAaC,EAAwB,CAClD,IAAMC,EAAoB,CAAC,EAC3B,QAAWC,KAAQR,GAAYK,CAAG,EAAG,CACjC,IAAMI,EAAOP,EAAKG,EAAKG,CAAI,EACvBP,GAASQ,CAAI,EAAE,YAAY,EAC3BF,EAAQ,KAAK,GAAGH,GAAQK,EAAMH,CAAI,CAAC,EAC5B,cAAc,KAAKE,CAAI,GAC9BD,EAAQ,KAAKJ,GAASG,EAAMG,CAAI,EAAE,QAAQ,MAAO,GAAG,CAAC,CAE7D,CACA,OAAOF,CACX,CAEO,SAASG,EAAaC,EAAgBC,EAAmC,CAC5E,IAAMC,EAASX,EAAKU,EAAaD,EAAQ,KAAK,EAE1CG,EACJ,GAAI,CACAA,EAAQV,GAAQS,EAAQD,CAAW,CACvC,MAAQ,CACJ,MAAO,CAAC,CACZ,CAEA,OAAOE,EACF,OAAOC,GAAK,CAACA,EAAE,SAAS,eAAe,GAAK,CAACA,EAAE,SAAS,gBAAgB,CAAC,EACzE,QAAQC,GAAY,CACjB,GAAI,CACA,IAAMC,EAAUlB,GAAaG,EAAKU,EAAaI,CAAQ,EAAG,OAAO,EAC3DE,EAAUC,GAAmBF,CAAO,EAC1C,OAAIC,EAAQ,SAAW,EAAU,CAAC,EAC3B,CAACE,GAAgBJ,EAAU,GAAGL,CAAM,OAAQO,CAAO,CAAC,CAC/D,MAAQ,CACJ,MAAO,CAAC,CACZ,CACJ,CAAC,CACT,CAzCA,IAAAG,GAAAC,EAAA,kBAEAC,KACAC,MCHA,OAAQ,aAAAC,GAAW,gBAAAC,GAAc,iBAAAC,GAAe,cAAAC,OAAiB,UACjE,OAAQ,QAAAC,OAAW,YAEZ,SAASC,EAAeC,EAAiBC,EAA8B,CAC1E,IAAMC,EAAWJ,GAAKG,EAAa,QAAQ,EACrCE,EAAUL,GAAKI,EAAU,aAAa,EAI5C,OAFAR,GAAUQ,EAAU,CAAC,UAAW,EAAI,CAAC,EAEjCL,GAAWM,CAAO,GAAKR,GAAaQ,EAAS,OAAO,IAAMH,EACnD,IAGXJ,GAAcO,EAASH,EAAS,OAAO,EAChC,GACX,CAfA,IAAAI,GAAAC,EAAA,oBCAA,OAA6B,eAAAC,OAAmB,OAEhD,OAAOC,OAAW,uBAClB,OAAS,iBAAAC,OAAqB,WAC9B,OAAS,WAAAC,GAAS,WAAAC,MAAe,YAWjC,OAAS,aAAAC,OAAiB,aAYnB,SAASC,GAAMC,EAAiC,CACnD,IAAMC,EAASD,EAAO,QAAU,MAC1BE,EAAW,GAAGD,CAAM,SACpBE,GAAWH,EAAO,KAAO,CAAC,GAAG,IAAII,GAAKA,EAAE,WAAW,GAAG,EAAIA,EAAI,IAAIA,EAAE,QAAQ,QAAS,EAAE,CAAC,EAAE,EAE1FC,EAAaR,EAAQS,EAAW,qBAAqB,EAAE,QAAQ,MAAO,GAAG,EACzEC,EAAUV,EAAQS,EAAW,kBAAkB,EAAE,QAAQ,MAAO,GAAG,EACnEE,EAAcX,EAAQS,EAAW,6BAA6B,EAAE,QAAQ,MAAO,GAAG,EAElFG,EAAwB,CAC1B,KAAM,QACN,QAAS,MAET,UAAUC,EAAI,CACV,GAAIA,IAAOC,EAAsB,MAAO,KAAKA,CAAoB,GACjE,GAAID,IAAOE,EAAuB,MAAO,KAAKA,CAAqB,GACnE,GAAIF,IAAOG,EAAgB,MAAO,KAAKA,CAAc,GACrD,GAAIH,IAAOI,EAAa,MAAO,KAAKA,CAAW,GAC/C,GAAIJ,IAAOK,EAAiB,MAAO,KAAKA,CAAe,EAC3D,EAEA,KAAKL,EAAI,CACL,GAAIA,IAAO,KAAKC,CAAoB,GAChC,OAAOK,EAAoB,CAAE,QAAAb,CAAQ,CAAC,EAC1C,GAAIO,IAAO,KAAKE,CAAqB,GACjC,OAAOK,EAAqB,CAAE,SAAAf,EAAU,YAAAM,CAAY,CAAC,EACzD,GAAIE,IAAO,KAAKG,CAAc,GAC1B,OAAOK,EAAe,CAAE,SAAAhB,EAAU,WAAAG,CAAW,CAAC,EAClD,GAAIK,IAAO,KAAKI,CAAW,GACvB,OAAOK,GAAY,CAAE,QAAAZ,EAAS,OAAAN,CAAO,CAAC,EAC1C,GAAIS,IAAO,KAAKK,CAAe,GAC3B,OAAOK,GAAgB,CAC/B,EAGA,UAAUC,EAAMX,EAAIY,EAAS,CACzB,GAAIA,GAAS,IAAK,OAElB,IAAMC,EAAmB1B,EAAQ,QAAQ,IAAI,EAAGK,CAAQ,EACxD,GAAI,CAACQ,EAAG,WAAWa,CAAgB,EAAG,OAEtC,IAAMC,GAAM1B,GAAUY,EAAIW,EAAM,CAAE,WAAY,QAAS,CAAC,EAElDI,EAA+D,CAAC,EAEtE,QAAWC,KAAQF,GAAI,QAAQ,KAAM,CACjC,GAAIE,EAAK,OAAS,0BAA4B,CAACA,EAAK,YAAa,SAEjE,IAAMC,EAAOD,EAAK,YAMlB,GAJIC,EAAK,OAAS,uBAAyBA,EAAK,IAAMC,GAAe,IAAID,EAAK,GAAG,IAAI,GACjFF,EAAa,KAAK,CAAE,MAAOC,EAAK,MAAO,IAAKA,EAAK,IAAK,KAAMC,EAAK,GAAG,IAAK,CAAC,EAG1EA,EAAK,OAAS,sBAAuB,CACrC,IAAME,EAAO,IAAI,IACjB,QAAWC,KAAcH,EAAK,aACtBG,EAAW,GAAG,OAAS,cAAgBF,GAAe,IAAIE,EAAW,GAAG,IAAI,IACvED,EAAK,IAAIH,EAAK,KAAK,IACpBG,EAAK,IAAIH,EAAK,KAAK,EACnBD,EAAa,KAAK,CAAE,MAAOC,EAAK,MAAO,IAAKA,EAAK,IAAK,KAAMI,EAAW,GAAG,IAAK,CAAC,GAIhG,CACJ,CAEA,GAAIL,EAAa,SAAW,EAAG,OAE/BA,EAAa,KAAK,CAACM,EAAGC,IAAMA,EAAE,MAAQD,EAAE,KAAK,EAE7C,IAAIE,EAASZ,EACb,OAAW,CAAE,MAAAa,EAAO,IAAAC,EAAK,KAAAC,CAAK,IAAKX,EAC/BQ,EAASA,EAAO,MAAM,EAAGC,CAAK,EAAI,gBAAgBE,CAAI,eAAiBH,EAAO,MAAME,CAAG,EAG3F,MAAO,CAAE,KAAMF,EAAQ,IAAK,IAAK,CACrC,EAEA,YAAa,CACT,IAAMI,EAAO,QAAQ,IAAI,EACnBC,EAAUC,EAAatC,EAAQoC,CAAI,EACzCG,EAAeC,EAAkBH,EAAS,GAAGrC,CAAM,MAAM,EAAGoC,CAAI,CACpE,EAEA,gBAAgBK,EAAQ,CACpB,IAAML,EAAO,QAAQ,IAAI,EAEnBM,EAAgB,IAAM,CACxB,IAAML,EAAUC,EAAatC,EAAQoC,CAAI,EACzCG,EAAeC,EAAkBH,EAAS,GAAGrC,CAAM,MAAM,EAAGoC,CAAI,CACpE,EAEAK,EAAO,QAAQ,IAAI7C,EAAQwC,EAAM,iBAAiB,CAAC,EACnDK,EAAO,QAAQ,GAAG,SAAWE,GAAS,CAC9BA,IAAS/C,EAAQwC,EAAM,iBAAiB,IACxC,QAAQ,IAAI,uCAAuC,EACnD,QAAQ,KAAK,EAAE,EAEvB,CAAC,EAEDK,EAAO,QAAQ,GAAG,MAAQE,GAAS,CAC3BA,EAAK,WAAW/C,EAAQwC,EAAMnC,CAAQ,CAAC,GAAG2C,EAAqB,EAC/DD,EAAK,SAAS,GAAG3C,CAAM,MAAM,IAAK6C,EAAmB,EAAGH,EAAc,EAC9E,CAAC,EACDD,EAAO,QAAQ,GAAG,SAAWE,GAAS,CAC9BA,EAAK,WAAW/C,EAAQwC,EAAMnC,CAAQ,CAAC,GAAG2C,EAAqB,EAC/DD,EAAK,SAAS,GAAG3C,CAAM,MAAM,IAAK6C,EAAmB,EAAGH,EAAc,EAC9E,CAAC,EACDD,EAAO,QAAQ,GAAG,SAAWE,GAAS,CAC9BA,EAAK,SAAS,GAAG3C,CAAM,MAAM,GAAK,CAAC2C,EAAK,SAAS,eAAe,GAChED,EAAc,CAEtB,CAAC,CACL,CACJ,EAEMI,EAAmB,CACrB,QAAS,CAACrD,GAAM,EAAGe,CAAa,EAChC,UAAWZ,EAAQ,QAAQ,IAAI,EAAGG,EAAO,WAAa,QAAQ,EAC9D,IAAK,CAAE,WAAY,CAAC,kBAAkB,CAAE,EACxC,GAAIA,EAAO,UAAY,CAAE,UAAWA,EAAO,SAAU,EAAI,CAAC,CAC9D,EAEA,OAAOP,GAAYsD,EAAM/C,EAAO,MAAQ,CAAC,CAAC,CAC9C,CAxJA,IAiBMM,EAEAK,EACAC,EACAC,EACAC,EACAC,EAEAa,GAzBNoB,GAAAC,EAAA,kBAKAC,IACAC,IACAC,IACAC,KACAC,KACAC,IACAC,KACAC,KACAC,IACAC,KAGMrD,EAAYV,GAAQD,GAAc,YAAY,GAAG,CAAC,EAElDgB,EAAuB,6BACvBC,EAAwB,8BACxBC,EAAiB,uBACjBC,EAAc,oBACdC,EAAkB,wBAElBa,GAAiB,IAAI,IAAI,CAAC,SAAU,QAAS,uBAAwB,SAAS,CAAC,ICzB9E,SAASgC,GAAcC,EAAgC,CAC1D,GAAI,OAAOA,GAAU,SAAU,OAAOA,EACtC,IAAMC,EAAQD,EAAM,KAAK,EAAE,MAAM,iCAAiC,EAClE,GAAI,CAACC,EAAO,MAAM,IAAI,MAAM,8BAA8BD,CAAK,4DAA4D,EAC3H,IAAME,EAAI,WAAWD,EAAM,CAAC,CAAC,EAC7B,OAAQA,EAAM,CAAC,EAAG,CACd,IAAK,IAAM,OAAOC,EAAI,KACtB,IAAK,IAAM,OAAOA,EAAI,IACtB,IAAK,IAAM,OAAOA,EAAI,IAEtB,QAAW,OAAOA,CACtB,CACJ,CAZA,IAAAC,GAAAC,EAAA,oBCAA,IAAAC,GAAA,UAAQ,iBAAAC,OAAoB,UAC5B,OAAQ,WAAAC,OAAc,YACtB,OAAQ,SAAAC,OAAY,OAFpB,IAOMC,EACAC,GA8BAC,GAtCNC,EAAAC,EAAA,uBAIAC,KACAC,KAEMN,GAAuB,MAAM,OAAO,GAAG,QAAQ,IAAI,CAAC,qBAAqB,QACzEC,GAAaM,GAAMP,CAAM,EAE/B,MAAMD,GAAM,CACR,GAAGE,GACH,WAAY,GACZ,MAAO,CACH,OAAQ,cACR,SAAU,GACV,gBAAiB,CACb,MAAO,4BACX,CACJ,CACJ,CAAC,EAED,MAAMF,GAAM,CACR,GAAGE,GACH,WAAY,GACZ,MAAO,CACH,IAAK,GACL,OAAQ,cACR,cAAe,GACf,gBAAiB,CACb,MAAO,CACH,OAAQ,uBACR,IAAK,mBACT,CACJ,CACJ,CACJ,CAAC,EAEKC,GAAgB,CAClB,KAAMF,EAAO,MAAQ,IACrB,KAAMA,EAAO,MAAQ,GACrB,cAAeQ,GAAcR,EAAO,eAAiB,GAAM,EAC3D,OAAQA,EAAO,QAAU,QAC7B,EAEAH,GACIC,GAAQ,QAAQ,IAAI,EAAG,wBAAwB,EAC/C,KAAK,UAAUI,GAAe,KAAM,CAAC,EACrC,OACJ,ICjDA,IAAAO,GAAA,UAAQ,gBAAAC,GAAc,aAAAC,GAAW,iBAAAC,OAAoB,UACrD,OAAQ,WAAAC,GAAS,QAAAC,MAAW,YAD5B,IAKMC,GAOAC,GACAC,GAEAC,GAIAC,EAnBNC,GAAAC,EAAA,uBAKMN,IAA2B,MAAM,OAAO,GAAG,QAAQ,IAAI,CAAC,qBAAqB,QAC/EA,GAAW,SAAW,UACtB,QAAQ,KAAK,yFAAyF,EAG1G,KAAM,kBAEAC,GAAI,KAAK,IAAI,EACbC,GAAe,MAAM,OAAOJ,GAAQ,QAAQ,IAAI,EAAG,uBAAuB,EAAI,MAAMG,EAAC,IAErFE,GAAqB,KAAK,MAC5BR,GAAaG,GAAQ,QAAQ,IAAI,EAAG,iCAAiC,EAAG,OAAO,CACnF,EAEMM,EAAiB,MAAMF,GAAa,gBAAgB,EAE1D,QAAQ,IAAI,sBAAsBE,EAAK,MAAM,eAAeA,EAAK,SAAW,EAAI,GAAK,GAAG,KAAK,EAE7F,QAAWG,KAAOH,EAAM,CACpB,IAAMI,EAAU,mBAAmBD,CAAG,GAChC,CAAC,KAAAE,EAAM,WAAAC,CAAU,EAAI,MAAMR,GAAa,OAAOM,EAAS,IAAI,QAAQA,CAAO,EAAG,CAAC,SAAAL,EAAQ,CAAC,EAE9F,GAAIO,IAAe,IAAK,CACpB,QAAQ,KAAK,oBAAoBH,CAAG,kBAAaG,CAAU,EAAE,EAC7D,QACJ,CAEA,IAAMC,EAAUJ,IAAQ,IAClBR,EAAK,QAAQ,IAAI,EAAG,wBAAwB,EAC5CA,EAAK,QAAQ,IAAI,EAAG,cAAeQ,EAAK,YAAY,EAE1DX,GAAUG,EAAKY,EAAS,IAAI,EAAG,CAAC,UAAW,EAAI,CAAC,EAChDd,GAAcc,EAAS,kBAAkBF,CAAI,GAAI,OAAO,EACxD,QAAQ,IAAI,YAAOF,CAAG,EAAE,CAC5B,CAEA,QAAQ,IAAI,8BAA8B,IC/BnC,SAASK,GAAkBC,EAAW,CAAC,UAAAC,EAAW,aAAAC,EAAc,cAAAC,CAAa,EAAkB,CAClGH,EAAI,IAAI,SAAU,MAAOI,GAAM,CAC3B,GAAI,CACA,OAAO,MAAMH,EAAU,iBAAiBG,EAAE,IAAI,IAAKA,EAAE,IAAI,GAAG,CAChE,OAASC,EAAG,CACR,eAAQ,MAAMA,CAAC,EACRD,EAAE,KAAK,CAAC,MAAO,gBAAgB,EAAG,GAAG,CAChD,CACJ,CAAC,EAEDJ,EAAI,IAAI,WAAY,MAAOI,GAAM,CAC7B,GAAI,CACA,GAAM,CAAC,SAAAE,EAAU,OAAAC,CAAM,EAAI,IAAI,IAAIH,EAAE,IAAI,IAAK,kBAAkB,EAC1DI,EAAMF,EAAS,QAAQ,WAAY,EAAE,EAAIC,EAEzCE,EAAO,MAAMP,EAAa,UAAUM,EAAKJ,EAAE,IAAI,IAAK,CAAC,cAAAD,CAAa,CAAC,EACzE,OAAIM,EAAK,MAAcL,EAAE,KAAK,CAAC,MAAO,gBAAgB,EAAG,GAAG,EACrDA,EAAE,KAAKK,CAAI,CACtB,OAASJ,EAAG,CACR,eAAQ,MAAMA,CAAC,EACRD,EAAE,KAAK,CAAC,MAAO,gBAAgB,EAAG,GAAG,CAChD,CACJ,CAAC,CACL,CAEO,SAASM,GAAiBV,EAAW,CAAC,aAAAE,EAAc,SAAAS,EAAU,cAAAR,CAAa,EAAkB,CAChGH,EAAI,IAAI,IAAK,MAAOI,GAAM,CACtB,GAAI,CACA,GAAM,CAAC,KAAAQ,EAAM,WAAAC,EAAY,QAAAC,CAAO,EAAI,MAAMZ,EAAa,OAAOE,EAAE,IAAI,IAAKA,EAAE,IAAI,IAAK,CAAC,SAAAO,EAAU,cAAAR,CAAa,CAAC,EACvGY,EAAMX,EAAE,KAAK,kBAAkBQ,CAAI,GAAIC,CAAU,EACvD,OAAW,CAACG,EAAKC,CAAK,IAAK,OAAO,QAAQH,CAAiC,EACvEC,EAAI,QAAQ,IAAIC,EAAKC,CAAK,EAE9B,OAAOF,CACX,OAASV,EAAG,CACR,eAAQ,MAAMA,CAAC,EACRD,EAAE,KAAK,wBAAyB,GAAG,CAC9C,CACJ,CAAC,CACL,CAjDA,IAAAc,GAAAC,EAAA,oBCAA,OAAQ,WAAAC,OAAc,OAEf,SAASC,GAAWC,EAAc,CACrC,IAAMC,EAAMH,GAAQE,EAAM,QAAQ,IAAI,EAAG,EAAE,EAC3C,OAAW,CAACE,EAAKC,CAAK,IAAK,OAAO,QAAQF,CAAG,EACrC,QAAQ,IAAIC,CAAG,IAAM,SACrB,QAAQ,IAAIA,CAAG,EAAIC,EAG/B,CATA,IAAAC,GAAAC,EAAA,oBCAA,IAAAC,GAAA,UAAQ,gBAAAC,OAAmB,UAC3B,OAAQ,SAAAC,OAAY,oBACpB,OAAQ,eAAAC,OAAkB,iCAC1B,OAAQ,QAAAC,OAAW,OACnB,OAAQ,WAAAC,EAAS,QAAAC,OAAW,YAJ5B,IAWIC,EACAC,EACAC,EACAC,EAcEC,GACAC,GAIAC,EAEAC,GAnCNC,GAAAC,EAAA,uBAMAC,KACAC,KAEAC,GAAW,YAAY,EAOvB,GAAI,CACAT,EAAgB,KAAK,MAAMT,GAAaI,EAAQ,QAAQ,IAAI,EAAG,wBAAwB,EAAG,OAAO,CAAC,EAC9FK,EAAc,SAAW,WACzBH,EAAe,MAAM,OAAOF,EAAQ,QAAQ,IAAI,EAAG,uBAAuB,GAC1EG,EAAY,MAAM,OAAOH,EAAQ,QAAQ,IAAI,EAAG,oBAAoB,IAExEI,EAAW,KAAK,MAAMR,GAAaI,EAAQ,QAAQ,IAAI,EAAG,iCAAiC,EAAG,OAAO,CAAC,CAC1G,MAAQ,CACJ,QAAQ,MAAM,mDAAmD,EACjE,QAAQ,KAAK,CAAC,CAClB,CAEMM,GAAO,OAAO,QAAQ,IAAI,IAAI,GAAKD,EAAe,MAAQ,IAC1DE,GAAO,OAAOF,EAAe,MAAS,SACtCA,EAAe,KACfA,EAAe,KAAO,UAAa,QAAQ,IAAI,MAAQ,UAEvDG,EAAM,IAAIT,GAEVU,GAAaR,GAAK,QAAQ,IAAI,EAAG,aAAa,EAEpDO,EAAI,IAAI,KAAMV,GAAY,CACtB,KAAMW,GACN,QAAS,CAACM,EAAOC,IAAM,CACnBA,EAAE,OAAO,gBAAiBD,EAAM,SAAS,UAAU,EAC7C,sCACA,UAAU,CACpB,CACJ,CAAC,CAAC,EAEEV,EAAe,SAAW,SAC1B,QAAQ,IAAI,yEAAoE,GAEhFY,GAAkBT,EAAK,CAAC,aAAAN,EAAc,UAAAC,EAAW,SAAAC,CAAQ,CAAC,EAC1Dc,GAAiBV,EAAK,CAAC,aAAAN,EAAc,UAAAC,EAAW,SAAAC,EAAU,cAAeC,EAAe,aAAa,CAAC,GAG1GR,GAAM,CAAC,MAAOW,EAAI,MAAO,KAAAF,GAAM,SAAUC,EAAI,EAAIY,GAAS,QAAQ,IAAI,UAAUA,EAAK,OAAO,IAAIA,EAAK,IAAI,EAAE,CAAC,IClD5G,IAAMC,GAAU,QAAQ,KAAK,CAAC,EAE9B,OAAQA,GAAS,CACb,IAAK,MACD,KAAM,sCACN,MACJ,IAAK,QACD,KAAM,kBACN,MACJ,IAAK,WACD,KAAM,mBACN,MACJ,IAAK,QACD,KAAM,mBACN,MACJ,IAAK,YACL,IAAK,KAAM,CACP,QAAQ,IAAI,cAAiB,EAC7B,KACJ,CACA,IAAK,SACL,IAAK,KACD,QAAQ,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,UAgBV,KAAK,CAAC,EACR,MACJ,QACI,QAAQ,MAAM,oBAAoBA,EAAO,EAAE,EAC3C,QAAQ,MAAM,yCAAyC,EACvD,QAAQ,KAAK,CAAC,CACtB",
6
6
  "names": ["dev_exports", "spawnSync", "fileURLToPath", "dirname", "resolve", "__dirname", "init_dev", "__esmMin", "generateEntryClient", "cssUrls", "u", "init_entry_client", "__esmMin", "generateClientRoutes", "pagesDir", "matcherPath", "init_client_routes", "__esmMin", "generateRender", "pagesDir", "renderPath", "init_render", "__esmMin", "generateApi", "apiPath", "appDir", "init_api", "__esmMin", "routePattern", "rel", "init_patterns", "__esmMin", "invalidatePagesCache", "cache", "init_pages_router", "__esmMin", "init_patterns", "keyToRoutePattern", "key", "apiDir", "rel", "pattern", "routePattern", "invalidateApiCache", "cache", "init_api_router", "__esmMin", "init_patterns", "generateContext", "init_context", "__esmMin", "stripComments", "content", "extractHttpMethods", "found", "match", "METHOD_EXPORT_RE", "init_extract_methods", "__esmMin", "filePathToIdentifier", "filePath", "apiDir", "buildRouteEntry", "methods", "keyToRoutePattern", "generateRoutesDts", "entries", "imports", "e", "importPath", "routeLines", "m", "init_routes_dts", "__esmMin", "init_api_router", "readFileSync", "readdirSync", "statSync", "join", "relative", "walkDir", "dir", "root", "entries", "name", "full", "scanApiFiles", "appDir", "projectRoot", "apiDir", "files", "f", "filePath", "content", "methods", "extractHttpMethods", "buildRouteEntry", "init_scan_api", "__esmMin", "init_extract_methods", "init_routes_dts", "mkdirSync", "readFileSync", "writeFileSync", "existsSync", "join", "writeRoutesDts", "content", "projectRoot", "devixDir", "outPath", "init_write_routes_dts", "__esmMin", "mergeConfig", "react", "fileURLToPath", "dirname", "resolve", "parseSync", "devix", "config", "appDir", "pagesDir", "cssUrls", "u", "renderPath", "__dirname", "apiPath", "matcherPath", "virtualPlugin", "id", "VIRTUAL_ENTRY_CLIENT", "VIRTUAL_CLIENT_ROUTES", "VIRTUAL_RENDER", "VIRTUAL_API", "VIRTUAL_CONTEXT", "generateEntryClient", "generateClientRoutes", "generateRender", "generateApi", "generateContext", "code", "options", "resolvedPagesDir", "ast", "replacements", "node", "decl", "SERVER_EXPORTS", "seen", "declarator", "a", "b", "result", "start", "end", "name", "root", "entries", "scanApiFiles", "writeRoutesDts", "generateRoutesDts", "server", "regenerateDts", "file", "invalidatePagesCache", "invalidateApiCache", "base", "init_vite", "__esmMin", "init_entry_client", "init_client_routes", "init_render", "init_api", "init_pages_router", "init_api_router", "init_context", "init_scan_api", "init_routes_dts", "init_write_routes_dts", "parseDuration", "value", "match", "n", "init_duration", "__esmMin", "build_exports", "writeFileSync", "resolve", "build", "config", "baseConfig", "runtimeConfig", "init_build", "__esmMin", "init_vite", "init_duration", "devix", "parseDuration", "generate_exports", "readFileSync", "mkdirSync", "writeFileSync", "resolve", "join", "userConfig", "t", "renderModule", "manifest", "urls", "init_generate", "__esmMin", "url", "fullUrl", "html", "statusCode", "outPath", "registerApiRoutes", "app", "apiModule", "renderModule", "loaderTimeout", "c", "e", "pathname", "search", "url", "data", "registerSsrRoute", "manifest", "html", "statusCode", "headers", "res", "key", "value", "init_routes", "__esmMin", "loadEnv", "loadDotenv", "mode", "env", "key", "value", "init_env", "__esmMin", "start_exports", "readFileSync", "serve", "serveStatic", "Hono", "resolve", "join", "renderModule", "apiModule", "manifest", "runtimeConfig", "port", "host", "app", "clientRoot", "init_start", "__esmMin", "init_routes", "init_env", "loadDotenv", "_path", "c", "registerApiRoutes", "registerSsrRoute", "info", "command"]
7
7
  }
@@ -1,2 +1,2 @@
1
- import{useCallback as V,useContext as T,useEffect as Y,useRef as Z,useState as j}from"react";import{RouterContext as b}from"virtual:devix/context";import{getDefaultErrorPage as K,loadErrorPage as U,matchClientRoute as ee}from"virtual:devix/client-routes";import{Fragment as O,jsx as P}from"react/jsx-runtime";function z(e,t){let r=[];e.title&&r.push({tag:"title",children:e.title}),e.description&&r.push({tag:"meta",name:"description",content:e.description}),e.keywords?.length&&r.push({tag:"meta",name:"keywords",content:e.keywords.join(", ")});let n=e.og?.title??e.title;n&&r.push({tag:"meta",property:"og:title",content:n});let a=e.og?.description??e.description;a&&r.push({tag:"meta",property:"og:description",content:a}),e.og?.image&&r.push({tag:"meta",property:"og:image",content:e.og.image}),e.og?.type&&r.push({tag:"meta",property:"og:type",content:e.og.type}),e.og?.url&&r.push({tag:"meta",property:"og:url",content:e.og.url});let s=e.twitter?.title??e.title;s&&r.push({tag:"meta",name:"twitter:title",content:s});let y=e.twitter?.description??e.description;if(y&&r.push({tag:"meta",name:"twitter:description",content:y}),e.twitter?.card&&r.push({tag:"meta",name:"twitter:card",content:e.twitter.card}),e.twitter?.image&&r.push({tag:"meta",name:"twitter:image",content:e.twitter.image}),e.twitter?.creator&&r.push({tag:"meta",name:"twitter:creator",content:e.twitter.creator}),e.canonical&&r.push({tag:"link",rel:"canonical",href:e.canonical}),e.robots&&r.push({tag:"meta",name:"robots",content:e.robots}),e.alternates)for(let[c,u]of Object.entries(e.alternates))r.push({tag:"link",rel:"alternate",href:u,hrefLang:c});if(t){let c=[];t.width!==void 0&&c.push(`width=${t.width}`),t.initialScale!==void 0&&c.push(`initial-scale=${t.initialScale}`),t.maximumScale!==void 0&&c.push(`maximum-scale=${t.maximumScale}`),t.userScalable!==void 0&&c.push(`user-scalable=${t.userScalable?"yes":"no"}`),c.length&&r.push({tag:"meta",name:"viewport",content:c.join(", ")}),t.themeColor&&r.push({tag:"meta",name:"theme-color",content:t.themeColor})}return r}function $({metadata:e,viewport:t}){return typeof window>"u"||!e?null:P(O,{children:Q(e,t)})}function Q(e,t){let r=z(e,t);return P(O,{children:r.map((n,a)=>n.tag==="title"?P("title",{children:n.children},a):n.tag==="link"?P("link",{rel:n.rel,href:n.href,hrefLang:n.hrefLang},a):P("meta",{name:n.name,property:n.property,content:n.content},a))})}import{createContext as H}from"react";var R=globalThis;R.__devix_RouterContext__??=H(null);var _e=R.__devix_RouterContext__;R.__devix_PageMetaContext__??=H(null);R.__devix_RouteDataContext__??=H(null);var F=R.__devix_PageMetaContext__,C=R.__devix_RouteDataContext__;import{Component as X}from"react";import{jsx as I}from"react/jsx-runtime";var M=class extends X{state={error:null};static getDerivedStateFromError(t){return t instanceof N?{error:{statusCode:t.statusCode,message:t.message}}:{error:{statusCode:500,message:t instanceof Error?t.message:"Unknown error"}}}render(){return this.state.error&&this.props.ErrorPage?I(this.props.ErrorPage,{...this.state.error}):this.state.error?I("h1",{children:this.state.error.statusCode}):this.props.children}},N=class extends Error{statusCode;constructor(t,r){super(r),this.statusCode=t}};import{jsx as m,jsxs as le}from"react/jsx-runtime";function te(){return T(b)}var re=()=>Promise.resolve(),ne=()=>Promise.resolve();function oe(){return T(b)?.navigate??re}function ae(){return T(b)?.revalidate??ne}function ie(){let e=T(C);if(!e)throw new Error("useParams must be used within a route or layout");return e.params}function se(){let e=T(C);if(!e)throw new Error("useLoaderData must be used within a route or layout");return e.loaderData}function pe({initialData:e,initialParams:t,initialPage:r,initialLayouts:n=[],initialLayoutsData:a=[],initialMeta:s,initialViewport:y,initialError:c,initialErrorPage:u,clientEntry:h}){let[o,v]=j({pathname:window.location.pathname,params:t,loaderData:e,layoutsData:a,Page:r,layouts:n,metadata:s??null,viewport:y,pendingError:c,ErrorPage:u}),E=Z(null),[W,B]=j(!1),w=V(async(l,p)=>{let d=l.split("?")[0].split("#")[0],i=ee(d);if(!i){let g=await U()??K();v(S=>({...S,pathname:d,pendingError:{statusCode:404,message:"Not found"},ErrorPage:g??void 0}));return}let[x,...L]=await Promise.all([i.load(),...i.loadLayouts.map(g=>g())]);if(p.signal.aborted||!x.default)return;let D=await fetch(`/_data${l}`,{headers:{Accept:"application/json"},signal:p.signal});if(p.signal.aborted)return;if(!D.ok){if(D.status===404){window.location.href=l;return}let g=await U()??K();v(S=>({...S,pathname:d,pendingError:{statusCode:D.status,message:"Server error"},ErrorPage:g??void 0}));return}let f=await D.json();if(f.redirect){f.redirectReplace?window.history.replaceState(null,"",f.redirect):window.history.pushState(null,"",f.redirect),await w(f.redirect,p);return}window.scrollTo(0,0),v({pathname:d,params:f.params??{},loaderData:f.loaderData,layoutsData:(f.layouts??[]).map(g=>g.loaderData),Page:x.default,layouts:L.map(g=>g.default),metadata:f.metadata??null,viewport:f.viewport})},[]),_=V(async(l,p)=>{E.current?.abort();let d=new AbortController;E.current=d,B(!0);let i=async()=>{window.history[p?.replace?"replaceState":"pushState"](null,"",l),await w(l,d)};try{p?.viewTransition&&"startViewTransition"in document?await document.startViewTransition(i).finished:await i()}finally{d.signal.aborted||B(!1)}},[w]),q=V(async()=>{let l=window.location.pathname+window.location.search,p=new AbortController,d=await fetch(`/_data${l}`,{headers:{Accept:"application/json"},signal:p.signal});if(!d.ok)return;let i=await d.json();if(i.redirect){await _(i.redirect,{replace:i.redirectReplace});return}v(x=>({...x,loaderData:i.loaderData,layoutsData:(i.layouts??[]).map(L=>L.loaderData),params:i.params??x.params,metadata:i.metadata??x.metadata,viewport:i.viewport??x.viewport}))},[_]);Y(()=>{let l=()=>{E.current?.abort();let p=new AbortController;E.current=p;let d=window.location.pathname+window.location.search;w(d,p).catch(i=>{i.name!=="AbortError"&&console.error("[router] popstate error:",i)})};return window.addEventListener("popstate",l),()=>window.removeEventListener("popstate",l)},[w]);let A;if(o.pendingError)A=o.ErrorPage?m(o.ErrorPage,{...o.pendingError}):m("h1",{children:o.pendingError.statusCode});else{let l=m(C,{value:{loaderData:o.loaderData,params:o.params},children:m(o.Page,{data:o.loaderData,params:o.params,url:o.pathname})});for(let p=o.layouts.length-1;p>=0;p--){let d=o.layouts[p],i=o.layoutsData[p];l=m(C,{value:{loaderData:i,params:o.params},children:m(d,{data:i,params:o.params,children:l})})}A=m(M,{ErrorPage:o.ErrorPage,children:l},o.pathname)}return le(F,{value:{metadata:o.metadata,viewport:o.viewport,clientEntry:h},children:[m($,{metadata:o.metadata,viewport:o.viewport}),m(b,{value:{...o,isNavigating:W,navigate:_,revalidate:q},children:A})]})}import{useCallback as de,useContext as ue}from"react";import{matchClientRoute as ce}from"virtual:devix/client-routes";import{RouterContext as fe}from"virtual:devix/context";import{jsx as me}from"react/jsx-runtime";function G(e){if(e.startsWith("/")||e.startsWith("http"))return e;let t=window.location.pathname.endsWith("/")?window.location.href:window.location.href+"/",r=new URL(e,t).pathname;return r.length>1?r.replace(/\/$/,""):r}function ge({href:e,prefetch:t=!1,viewTransition:r=!1,children:n,...a}){let s=ue(fe),y=de(()=>{if(!t)return;let u=G(e),h=u.split("?")[0].split("#")[0],o=ce(h);o&&(o.load().catch(()=>{}),fetch(`/_data${u}`,{headers:{Accept:"application/json"}}).catch(()=>{}))},[e,t]);return me("a",{href:e,onClick:u=>{if(s&&!u.ctrlKey&&!u.metaKey&&!u.shiftKey&&u.button===0){u.preventDefault();let h=G(e);r&&typeof document.startViewTransition=="function"?document.startViewTransition(()=>s.navigate(h)):s.navigate(h)}},onMouseEnter:y,...a,children:n})}function ye(e,t){let r=e.headers.get("cookie");if(r)for(let n of r.split(";")){let[a,...s]=n.trim().split("=");if(a.trim()===t)return decodeURIComponent(s.join("="))}}function J(e,t,r,n={}){let a=`${t}=${encodeURIComponent(r)}; Path=${n.path??"/"}`;n.domain&&(a+=`; Domain=${n.domain}`),n.maxAge!==void 0&&(a+=`; Max-Age=${n.maxAge}`),n.expires&&(a+=`; Expires=${n.expires.toUTCString()}`),n.httpOnly&&(a+="; HttpOnly"),n.secure&&(a+="; Secure"),n.sameSite&&(a+=`; SameSite=${n.sameSite}`),e.append("Set-Cookie",a)}function xe(e,t,r={}){J(e,t,"",{...r,maxAge:0,expires:new Date(0)})}var he=(e,t=200)=>new Response(JSON.stringify(e),{status:t,headers:{"Content-Type":"application/json"}}),Re=(e,t=200)=>new Response(e,{status:t,headers:{"Content-Type":"text/plain; charset=utf-8"}}),we=Symbol("devix.redirect");function Pe(e,t){let r=typeof t=="number"?t:t?.status??302,n=typeof t=="object"?t?.replace??!1:!1;return{[we]:!0,url:e,status:r,replace:n}}var k=class extends Error{constructor(r,n,a){super(`HTTP ${r}: ${n}`);this.status=r;this.statusText=n;this.response=a;this.name="FetchError"}};async function Ce(e,t){let r=t?.method??"GET",n=new Headers(t?.headers),a;t?.body!==void 0&&(a=JSON.stringify(t.body),n.has("Content-Type")||n.set("Content-Type","application/json"));let s=await fetch(e,{method:r,headers:n,body:a,signal:t?.signal});if(!s.ok)throw new k(s.status,s.statusText,s);return(s.headers.get("Content-Type")??"").includes("application/json")?s.json():s.text()}var Te="__devix_handler__";function ve(e){return{[Te]:!0,fn:e}}export{Ce as $fetch,k as FetchError,ge as Link,pe as RouterProvider,ve as createHandler,xe as deleteCookie,ye as getCookie,he as json,Pe as redirect,J as setCookie,Re as text,se as useLoaderData,oe as useNavigate,ie as useParams,ae as useRevalidate,te as useRouter};
1
+ import{useCallback as B,useContext as v,useEffect as ee,useRef as te,useState as U}from"react";import{RouterContext as b}from"virtual:devix/context";import{getDefaultErrorPage as G,loadErrorPage as J,matchClientRoute as re}from"virtual:devix/client-routes";import{Fragment as F,jsx as P}from"react/jsx-runtime";function X(e,t){let r=[];e.title&&r.push({tag:"title",children:e.title}),e.description&&r.push({tag:"meta",name:"description",content:e.description}),e.keywords?.length&&r.push({tag:"meta",name:"keywords",content:e.keywords.join(", ")});let o=e.og?.title??e.title;o&&r.push({tag:"meta",property:"og:title",content:o});let a=e.og?.description??e.description;a&&r.push({tag:"meta",property:"og:description",content:a}),e.og?.image&&r.push({tag:"meta",property:"og:image",content:e.og.image}),e.og?.type&&r.push({tag:"meta",property:"og:type",content:e.og.type}),e.og?.url&&r.push({tag:"meta",property:"og:url",content:e.og.url});let s=e.twitter?.title??e.title;s&&r.push({tag:"meta",name:"twitter:title",content:s});let y=e.twitter?.description??e.description;if(y&&r.push({tag:"meta",name:"twitter:description",content:y}),e.twitter?.card&&r.push({tag:"meta",name:"twitter:card",content:e.twitter.card}),e.twitter?.image&&r.push({tag:"meta",name:"twitter:image",content:e.twitter.image}),e.twitter?.creator&&r.push({tag:"meta",name:"twitter:creator",content:e.twitter.creator}),e.canonical&&r.push({tag:"link",rel:"canonical",href:e.canonical}),e.robots&&r.push({tag:"meta",name:"robots",content:e.robots}),e.alternates)for(let[c,u]of Object.entries(e.alternates))r.push({tag:"link",rel:"alternate",href:u,hrefLang:c});if(t){let c=[];t.width!==void 0&&c.push(`width=${t.width}`),t.initialScale!==void 0&&c.push(`initial-scale=${t.initialScale}`),t.maximumScale!==void 0&&c.push(`maximum-scale=${t.maximumScale}`),t.userScalable!==void 0&&c.push(`user-scalable=${t.userScalable?"yes":"no"}`),c.length&&r.push({tag:"meta",name:"viewport",content:c.join(", ")}),t.themeColor&&r.push({tag:"meta",name:"theme-color",content:t.themeColor})}return r}function I({metadata:e,viewport:t}){return typeof window>"u"||!e?null:P(F,{children:Y(e,t)})}function Y(e,t){let r=X(e,t);return P(F,{children:r.map((o,a)=>o.tag==="title"?P("title",{children:o.children},a):o.tag==="link"?P("link",{rel:o.rel,href:o.href,hrefLang:o.hrefLang},a):P("meta",{name:o.name,property:o.property,content:o.content},a))})}import{createContext as H}from"react";var w=globalThis;w.__devix_RouterContext__??=H(null);var Le=w.__devix_RouterContext__;w.__devix_PageMetaContext__??=H(null);w.__devix_RouteDataContext__??=H(null);var j=w.__devix_PageMetaContext__,C=w.__devix_RouteDataContext__;import{Component as Z}from"react";import{jsx as K}from"react/jsx-runtime";var M=class extends Z{state={error:null};static getDerivedStateFromError(t){return t instanceof N?{error:{statusCode:t.statusCode,message:t.message}}:{error:{statusCode:500,message:t instanceof Error?t.message:"Unknown error"}}}render(){return this.state.error&&this.props.ErrorPage?K(this.props.ErrorPage,{...this.state.error}):this.state.error?K("h1",{children:this.state.error.statusCode}):this.props.children}},N=class extends Error{statusCode;constructor(t,r){super(r),this.statusCode=t}};import{jsx as m,jsxs as ue}from"react/jsx-runtime";function oe(){return v(b)}var ne=()=>Promise.resolve(),ae=()=>Promise.resolve();function ie(){return v(b)?.navigate??ne}function se(){return v(b)?.revalidate??ae}function pe(){let e=v(C);if(!e)throw new Error("useParams must be used within a route or layout");return e.params}function le(){let e=v(C);if(!e)throw new Error("useLoaderData must be used within a route or layout");return e.loaderData}function de({initialData:e,initialParams:t,initialPage:r,initialLayouts:o=[],initialLayoutsData:a=[],initialMeta:s,initialViewport:y,initialError:c,initialErrorPage:u,clientEntry:h}){let[n,T]=U({pathname:window.location.pathname,params:t,loaderData:e,layoutsData:a,Page:r,layouts:o,metadata:s??null,viewport:y,pendingError:c,ErrorPage:u}),E=te(null),[z,V]=U(!1),R=B(async(p,l)=>{let d=p.split("?")[0].split("#")[0],i=re(d);if(!i){let g=await J()??G();T(S=>({...S,pathname:d,pendingError:{statusCode:404,message:"Not found"},ErrorPage:g??void 0}));return}let[x,...L]=await Promise.all([i.load(),...i.loadLayouts.map(g=>g())]);if(l.signal.aborted||!x.default)return;let D=await fetch(`/_data${p}`,{headers:{Accept:"application/json"},signal:l.signal});if(l.signal.aborted)return;if(!D.ok){if(D.status===404){window.location.href=p;return}let g=await J()??G();T(S=>({...S,pathname:d,pendingError:{statusCode:D.status,message:"Server error"},ErrorPage:g??void 0}));return}let f=await D.json();if(f.redirect){f.redirectReplace?window.history.replaceState(null,"",f.redirect):window.history.pushState(null,"",f.redirect),await R(f.redirect,l);return}T({pathname:d,params:f.params??{},loaderData:f.loaderData,layoutsData:(f.layouts??[]).map(g=>g.loaderData),Page:x.default,layouts:L.map(g=>g.default),metadata:f.metadata??null,viewport:f.viewport});let $=p.includes("#")?p.split("#")[1]:null,O=getComputedStyle(document.documentElement).scrollBehavior;$?requestAnimationFrame(()=>{document.getElementById($)?.scrollIntoView({behavior:O})}):window.scrollTo({top:0,behavior:O})},[]),_=B(async(p,l)=>{E.current?.abort();let d=new AbortController;E.current=d,V(!0);let i=async()=>{window.history[l?.replace?"replaceState":"pushState"](null,"",p),await R(p,d)};try{l?.viewTransition&&"startViewTransition"in document?await document.startViewTransition(i).finished:await i()}finally{d.signal.aborted||V(!1)}},[R]),Q=B(async()=>{let p=window.location.pathname+window.location.search,l=new AbortController,d=await fetch(`/_data${p}`,{headers:{Accept:"application/json"},signal:l.signal});if(!d.ok)return;let i=await d.json();if(i.redirect){await _(i.redirect,{replace:i.redirectReplace});return}T(x=>({...x,loaderData:i.loaderData,layoutsData:(i.layouts??[]).map(L=>L.loaderData),params:i.params??x.params,metadata:i.metadata??x.metadata,viewport:i.viewport??x.viewport}))},[_]);ee(()=>{let p=()=>{E.current?.abort();let l=new AbortController;E.current=l;let d=window.location.pathname+window.location.search;R(d,l).catch(i=>{i.name!=="AbortError"&&console.error("[router] popstate error:",i)})};return window.addEventListener("popstate",p),()=>window.removeEventListener("popstate",p)},[R]);let A;if(n.pendingError)A=n.ErrorPage?m(n.ErrorPage,{...n.pendingError}):m("h1",{children:n.pendingError.statusCode});else{let p=m(C,{value:{loaderData:n.loaderData,params:n.params},children:m(n.Page,{data:n.loaderData,params:n.params,url:n.pathname})});for(let l=n.layouts.length-1;l>=0;l--){let d=n.layouts[l],i=n.layoutsData[l];p=m(C,{value:{loaderData:i,params:n.params},children:m(d,{data:i,params:n.params,children:p})})}A=m(M,{ErrorPage:n.ErrorPage,children:p},n.pathname)}return ue(j,{value:{metadata:n.metadata,viewport:n.viewport,clientEntry:h},children:[m(I,{metadata:n.metadata,viewport:n.viewport}),m(b,{value:{...n,isNavigating:z,navigate:_,revalidate:Q},children:A})]})}import{useCallback as ce,useContext as fe}from"react";import{matchClientRoute as ge}from"virtual:devix/client-routes";import{RouterContext as me}from"virtual:devix/context";import{jsx as xe}from"react/jsx-runtime";function W(e){if(e.startsWith("/")||e.startsWith("http"))return e;let t=window.location.pathname.endsWith("/")?window.location.href:window.location.href+"/",r=new URL(e,t).pathname;return r.length>1?r.replace(/\/$/,""):r}function ye({href:e,prefetch:t=!1,viewTransition:r=!1,children:o,...a}){let s=fe(me),y=ce(()=>{if(!t)return;let u=W(e),h=u.split("?")[0].split("#")[0],n=ge(h);n&&(n.load().catch(()=>{}),fetch(`/_data${u}`,{headers:{Accept:"application/json"}}).catch(()=>{}))},[e,t]);return xe("a",{href:e,onClick:u=>{if(s&&!u.ctrlKey&&!u.metaKey&&!u.shiftKey&&u.button===0){u.preventDefault();let h=W(e);r&&typeof document.startViewTransition=="function"?document.startViewTransition(()=>s.navigate(h)):s.navigate(h)}},onMouseEnter:y,...a,children:o})}function he(e,t){let r=e.headers.get("cookie");if(r)for(let o of r.split(";")){let[a,...s]=o.trim().split("=");if(a.trim()===t)return decodeURIComponent(s.join("="))}}function q(e,t,r,o={}){let a=`${t}=${encodeURIComponent(r)}; Path=${o.path??"/"}`;o.domain&&(a+=`; Domain=${o.domain}`),o.maxAge!==void 0&&(a+=`; Max-Age=${o.maxAge}`),o.expires&&(a+=`; Expires=${o.expires.toUTCString()}`),o.httpOnly&&(a+="; HttpOnly"),o.secure&&(a+="; Secure"),o.sameSite&&(a+=`; SameSite=${o.sameSite}`),e.append("Set-Cookie",a)}function we(e,t,r={}){q(e,t,"",{...r,maxAge:0,expires:new Date(0)})}var Re=(e,t=200)=>new Response(JSON.stringify(e),{status:t,headers:{"Content-Type":"application/json"}}),Pe=(e,t=200)=>new Response(e,{status:t,headers:{"Content-Type":"text/plain; charset=utf-8"}}),Ce=Symbol("devix.redirect");function ve(e,t){let r=typeof t=="number"?t:t?.status??302,o=typeof t=="object"?t?.replace??!1:!1;return{[Ce]:!0,url:e,status:r,replace:o}}var k=class extends Error{constructor(r,o,a){super(`HTTP ${r}: ${o}`);this.status=r;this.statusText=o;this.response=a;this.name="FetchError"}};async function Te(e,t){let r=t?.method??"GET",o=new Headers(t?.headers),a;t?.body!==void 0&&(a=JSON.stringify(t.body),o.has("Content-Type")||o.set("Content-Type","application/json"));let s=await fetch(e,{method:r,headers:o,body:a,signal:t?.signal});if(!s.ok)throw new k(s.status,s.statusText,s);return(s.headers.get("Content-Type")??"").includes("application/json")?s.json():s.text()}var Ee="__devix_handler__";function De(e){return{[Ee]:!0,fn:e}}export{Te as $fetch,k as FetchError,ye as Link,de as RouterProvider,De as createHandler,we as deleteCookie,he as getCookie,Re as json,ve as redirect,q as setCookie,Pe as text,le as useLoaderData,ie as useNavigate,pe as useParams,se as useRevalidate,oe as useRouter};
2
2
  //# sourceMappingURL=index.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/runtime/router-provider.tsx", "../../src/runtime/head.tsx", "../../src/runtime/context.tsx", "../../src/runtime/error-boundary.tsx", "../../src/runtime/link.tsx", "../../src/utils/cookies.ts", "../../src/utils/response.ts", "../../src/runtime/fetch.ts", "../../src/runtime/create-handler.ts"],
4
- "sourcesContent": ["import {ComponentType, ReactNode, useCallback, useContext, useEffect, useRef, useState} from \"react\";\nimport {RouterContext} from 'virtual:devix/context'\nimport {ErrorProps, LayoutProps, PageProps} from \"../server/types\";\nimport {Metadata, Viewport} from \"../types\";\nimport {getDefaultErrorPage, loadErrorPage, matchClientRoute} from \"virtual:devix/client-routes\";\nimport {HeadSlot} from \"./head\";\nimport {NavigateOptions, PageMetaContext, RouteDataContext} from \"./context\";\nimport {DevixErrorBoundary} from \"./error-boundary\";\nimport type {Redirect} from \"../utils/response\";\n\ninterface RouteState {\n pathname: string\n params: Record<string, string>\n loaderData: unknown\n layoutsData: unknown[]\n Page: ComponentType<PageProps>\n layouts: ComponentType<LayoutProps>[]\n metadata: Metadata | null\n viewport?: Viewport\n pendingError?: ErrorProps\n ErrorPage?: ComponentType<ErrorProps>\n}\n\nexport function useRouter() {\n return useContext(RouterContext)\n}\n\nconst noopNavigate = () => Promise.resolve()\nconst noopRevalidate = () => Promise.resolve()\n\nexport function useNavigate() {\n const ctx = useContext(RouterContext)\n return ctx?.navigate ?? noopNavigate\n}\n\nexport function useRevalidate() {\n const ctx = useContext(RouterContext)\n return ctx?.revalidate ?? noopRevalidate\n}\n\nexport function useParams<T extends Record<string, string>>() {\n const ctx = useContext(RouteDataContext)\n if (!ctx) throw new Error(\"useParams must be used within a route or layout\")\n return ctx.params as T\n}\n\ntype LoaderReturnType<T> = T extends (...args: any[]) => Promise<infer R>\n ? [Exclude<R, Redirect | void | undefined>] extends [never] ? undefined : Exclude<R, Redirect | void | undefined>\n : T extends (...args: any[]) => infer R\n ? [Exclude<R, Redirect | void | undefined>] extends [never] ? undefined : Exclude<R, Redirect | void | undefined>\n : T\n\nexport function useLoaderData<T>() {\n const ctx = useContext(RouteDataContext)\n if (!ctx) throw new Error(\"useLoaderData must be used within a route or layout\")\n return ctx.loaderData as LoaderReturnType<T>\n}\n\n\ninterface RouterProviderProps {\n initialData: unknown\n initialParams: Record<string, string>\n initialPage: ComponentType<PageProps>\n initialLayouts?: ComponentType<LayoutProps>[]\n initialLayoutsData?: unknown[]\n initialMeta?: Metadata | null\n initialViewport?: Viewport\n initialError?: ErrorProps\n initialErrorPage?: ComponentType<ErrorProps>\n clientEntry: string\n}\n\nexport function RouterProvider({\n initialData,\n initialParams,\n initialPage,\n initialLayouts = [],\n initialLayoutsData = [],\n initialMeta,\n initialViewport,\n initialError,\n initialErrorPage,\n clientEntry,\n }: RouterProviderProps) {\n\n const [state, setState] = useState<RouteState>({\n pathname: window.location.pathname,\n params: initialParams,\n loaderData: initialData,\n layoutsData: initialLayoutsData,\n Page: initialPage,\n layouts: initialLayouts,\n metadata: initialMeta ?? null,\n viewport: initialViewport,\n pendingError: initialError,\n ErrorPage: initialErrorPage,\n })\n\n const navigatingRef = useRef<AbortController | null>(null)\n const [isNavigating, setIsNavigating] = useState(false)\n\n const loadRoute = useCallback(async (to: string, controller: AbortController) => {\n const pathname = to.split('?')[0].split('#')[0] \n const matched = matchClientRoute(pathname)\n if (!matched) {\n const ErrorPage = await loadErrorPage() ?? getDefaultErrorPage()\n setState(prev => ({\n ...prev,\n pathname: pathname,\n pendingError: {statusCode: 404, message: 'Not found'},\n ErrorPage: ErrorPage ?? undefined,\n }))\n return\n }\n\n const [pageMod, ...layoutMods] = await Promise.all([\n matched.load(),\n ...matched.loadLayouts.map(l => l()),\n ])\n\n if (controller.signal.aborted) return\n if (!pageMod.default) return\n\n const dataRes = await fetch(`/_data${to}`, {\n headers: {Accept: 'application/json'},\n signal: controller.signal,\n })\n\n if (controller.signal.aborted) return\n\n if (!dataRes.ok) {\n if (dataRes.status === 404) {\n window.location.href = to\n return\n }\n const ErrorPage = await loadErrorPage() ?? getDefaultErrorPage()\n setState(prev => ({\n ...prev,\n pathname,\n pendingError: {statusCode: dataRes.status, message: 'Server error'},\n ErrorPage: ErrorPage ?? undefined,\n }))\n return\n }\n\n const data = await dataRes.json()\n\n if (data.redirect) {\n if (data.redirectReplace) {\n window.history.replaceState(null, '', data.redirect)\n } else {\n window.history.pushState(null, '', data.redirect)\n }\n await loadRoute(data.redirect, controller)\n return\n }\n\n window.scrollTo(0, 0)\n setState({\n pathname,\n params: data.params ?? {},\n loaderData: data.loaderData,\n layoutsData: (data.layouts ?? []).map((l: any) => l.loaderData),\n Page: pageMod.default,\n layouts: layoutMods.map(m => m.default),\n metadata: data.metadata ?? null,\n viewport: data.viewport,\n })\n }, [])\n\n const navigate = useCallback(async (to: string, options?: NavigateOptions) => {\n navigatingRef.current?.abort()\n const controller = new AbortController()\n navigatingRef.current = controller\n\n setIsNavigating(true)\n const run = async () => {\n window.history[options?.replace ? 'replaceState' : 'pushState'](null, '', to)\n await loadRoute(to, controller)\n }\n try {\n if (options?.viewTransition && 'startViewTransition' in document) {\n await (document as any).startViewTransition(run).finished\n } else {\n await run()\n }\n } finally {\n if (!controller.signal.aborted) setIsNavigating(false)\n }\n }, [loadRoute])\n\n const revalidate = useCallback(async () => {\n const to = window.location.pathname + window.location.search\n const controller = new AbortController()\n const dataRes = await fetch(`/_data${to}`, {\n headers: {Accept: 'application/json'},\n signal: controller.signal,\n })\n if (!dataRes.ok) return\n const data = await dataRes.json()\n if (data.redirect) {\n await navigate(data.redirect, {replace: data.redirectReplace})\n return\n }\n setState(prev => ({\n ...prev,\n loaderData: data.loaderData,\n layoutsData: (data.layouts ?? []).map((l: any) => l.loaderData),\n params: data.params ?? prev.params,\n metadata: data.metadata ?? prev.metadata,\n viewport: data.viewport ?? prev.viewport,\n }))\n }, [navigate])\n\n useEffect(() => {\n const handlePop = () => {\n navigatingRef.current?.abort()\n const controller = new AbortController()\n navigatingRef.current = controller\n\n const to = window.location.pathname + window.location.search\n loadRoute(to, controller).catch(err => {\n if (err.name !== 'AbortError') console.error('[router] popstate error:', err)\n })\n }\n window.addEventListener(\"popstate\", handlePop)\n return () => window.removeEventListener(\"popstate\", handlePop)\n }, [loadRoute])\n\n let content: ReactNode\n\n if (state.pendingError) {\n content = state.ErrorPage\n ? <state.ErrorPage {...state.pendingError} />\n : <h1>{state.pendingError.statusCode}</h1>\n } else {\n let tree: ReactNode = (\n <RouteDataContext value={{loaderData: state.loaderData, params: state.params}}>\n <state.Page data={state.loaderData} params={state.params} url={state.pathname}/>\n </RouteDataContext>\n )\n\n for (let i = state.layouts.length - 1; i >= 0; i--) {\n const Layout = state.layouts[i]\n const layoutData = state.layoutsData[i]\n tree = (\n <RouteDataContext value={{loaderData: layoutData, params: state.params}}>\n <Layout data={layoutData} params={state.params}>{tree}</Layout>\n </RouteDataContext>\n )\n }\n\n content = (\n <DevixErrorBoundary key={state.pathname} ErrorPage={state.ErrorPage}>\n {tree}\n </DevixErrorBoundary>\n )\n }\n\n return (\n <PageMetaContext value={{\n metadata: state.metadata,\n viewport: state.viewport,\n clientEntry,\n }}>\n <HeadSlot metadata={state.metadata} viewport={state.viewport}/>\n <RouterContext value={{...state, isNavigating, navigate, revalidate}}>\n {content}\n </RouterContext>\n </PageMetaContext>\n )\n}", "import {Metadata, Viewport} from \"../types\";\nimport {ReactNode} from \"react\";\n\ntype MetaTag =\n | { tag: 'title'; children: string }\n | { tag: 'meta'; name?: string; property?: string; content: string }\n | { tag: 'link'; rel: string; href: string; hrefLang?: string }\n\nfunction collectTags(metadata: Metadata, viewport?: Viewport): MetaTag[] {\n const tags: MetaTag[] = []\n\n if (metadata.title)\n tags.push({tag: 'title', children: metadata.title})\n if (metadata.description)\n tags.push({tag: 'meta', name: 'description', content: metadata.description})\n if (metadata.keywords?.length)\n tags.push({tag: 'meta', name: 'keywords', content: metadata.keywords.join(', ')})\n\n const ogTitle = metadata.og?.title ?? metadata.title\n if (ogTitle) tags.push({tag: 'meta', property: 'og:title', content: ogTitle})\n const ogDesc = metadata.og?.description ?? metadata.description\n if (ogDesc) tags.push({tag: 'meta', property: 'og:description', content: ogDesc})\n if (metadata.og?.image) tags.push({tag: 'meta', property: 'og:image', content: metadata.og.image})\n if (metadata.og?.type) tags.push({tag: 'meta', property: 'og:type', content: metadata.og.type})\n if (metadata.og?.url) tags.push({tag: 'meta', property: 'og:url', content: metadata.og.url})\n\n const twTitle = metadata.twitter?.title ?? metadata.title\n if (twTitle) tags.push({tag: 'meta', name: 'twitter:title', content: twTitle})\n const twDesc = metadata.twitter?.description ?? metadata.description\n if (twDesc) tags.push({tag: 'meta', name: 'twitter:description', content: twDesc})\n if (metadata.twitter?.card) tags.push({\n tag: 'meta', name: 'twitter:card', content:\n metadata.twitter.card\n })\n if (metadata.twitter?.image) tags.push({\n tag: 'meta', name: 'twitter:image', content:\n metadata.twitter.image\n })\n if (metadata.twitter?.creator) tags.push({\n tag: 'meta', name: 'twitter:creator', content:\n metadata.twitter.creator\n })\n\n if (metadata.canonical) tags.push({tag: 'link', rel: 'canonical', href: metadata.canonical})\n if (metadata.robots) tags.push({tag: 'meta', name: 'robots', content: metadata.robots})\n if (metadata.alternates) {\n for (const [lang, href] of Object.entries(metadata.alternates))\n tags.push({tag: 'link', rel: 'alternate', href, hrefLang: lang})\n }\n\n if (viewport) {\n const parts: string[] = []\n if (viewport.width !== undefined) parts.push(`width=${viewport.width}`)\n if (viewport.initialScale !== undefined) parts.push(`initial-scale=${viewport.initialScale}`)\n if (viewport.maximumScale !== undefined) parts.push(`maximum-scale=${viewport.maximumScale}`)\n if (viewport.userScalable !== undefined) parts.push(`user-scalable=${viewport.userScalable ? 'yes' :\n 'no'}`)\n if (parts.length) tags.push({tag: 'meta', name: 'viewport', content: parts.join(', ')})\n if (viewport.themeColor) tags.push({\n tag: 'meta', name: 'theme-color', content: viewport.themeColor\n })\n }\n\n return tags\n}\n\nexport function HeadSlot({metadata, viewport}: {metadata: Metadata | null, viewport?: Viewport}) {\n if (typeof window === 'undefined' || !metadata) return null\n return <>{buildHeadNodes(metadata, viewport)}</>\n}\n\nexport function buildHeadNodes(metadata: Metadata, viewport?: Viewport): ReactNode {\n const tags = collectTags(metadata, viewport)\n\n return <>\n {tags.map((t, i) => {\n if (t.tag === 'title') return <title key={i}>{t.children}</title>\n if (t.tag === 'link') return <link key={i} rel={t.rel} href={t.href} hrefLang={t.hrefLang}/>\n return <meta key={i} name={t.name} property={t.property} content={t.content}/>\n })}\n </>\n}", "import {createContext, Context, ComponentType} from \"react\";\nimport {Metadata, Viewport} from \"../types\";\nimport {LayoutProps, PageProps} from \"../server/types\";\n\nexport interface NavigateOptions {\n replace?: boolean\n viewTransition?: boolean\n}\n\nexport interface RouterContextValue {\n pathname: string\n params: Record<string, string>\n loaderData: unknown\n layoutsData: unknown[]\n Page: ComponentType<PageProps>\n layouts: ComponentType<LayoutProps>[]\n metadata: Metadata | null\n viewport?: Viewport\n navigate: (to: string, options?: NavigateOptions) => Promise<void>\n revalidate: () => Promise<void>\n isNavigating: boolean\n}\n\nexport interface PageMetaContextValue {\n metadata: Metadata | null\n viewport?: Viewport\n clientEntry?: string\n}\n\nexport interface RouteDataContextValue {\n loaderData: unknown\n params: Record<string, string>\n}\n\nconst g = globalThis as any\n\ng.__devix_RouterContext__ ??= createContext<RouterContextValue | null>(null)\nexport const RouterContext: Context<RouterContextValue | null> = g.__devix_RouterContext__\n\ng.__devix_PageMetaContext__ ??= createContext<PageMetaContextValue | null>(null)\ng.__devix_RouteDataContext__ ??= createContext<RouteDataContextValue | null>(null)\n\nexport const PageMetaContext: Context<PageMetaContextValue | null> = g.__devix_PageMetaContext__\nexport const RouteDataContext: Context<RouteDataContextValue | null> = g.__devix_RouteDataContext__\n\n", "import {Component, ComponentType, ReactNode} from \"react\";\nimport {ErrorProps} from \"../server/types\";\n\ninterface Props {\n ErrorPage?: ComponentType<ErrorProps>\n children: ReactNode\n}\n\ninterface State {\n error: ErrorProps | null\n}\n\nexport class DevixErrorBoundary extends Component<Props, State> {\n state: State = { error: null }\n\n static getDerivedStateFromError(err: unknown): State {\n if (err instanceof DevixError) {\n return {\n error: {statusCode: err.statusCode, message: err.message}\n }\n }\n return {\n error: {statusCode: 500, message: err instanceof Error ? err.message : 'Unknown error'}\n }\n }\n\n render() {\n if (this.state.error && this.props.ErrorPage) {\n return <this.props.ErrorPage {...this.state.error} />\n }\n if (this.state.error) {\n return <h1>{this.state.error.statusCode}</h1>\n }\n return this.props.children\n }\n}\n\nexport class DevixError extends Error {\n statusCode: number\n constructor(statusCode: number, message: string) {\n super(message)\n this.statusCode = statusCode\n }\n}\n", "import {AnchorHTMLAttributes, MouseEventHandler, useCallback, useContext} from \"react\";\nimport {matchClientRoute} from \"virtual:devix/client-routes\";\nimport {RouterContext} from 'virtual:devix/context'\n\ninterface LinkProps extends AnchorHTMLAttributes<HTMLAnchorElement> {\n href: string\n prefetch?: boolean\n viewTransition?: boolean\n}\n\nfunction resolveHref(href: string): string {\n if (href.startsWith('/') || href.startsWith('http')) return href\n const base = window.location.pathname.endsWith('/')\n ? window.location.href\n : window.location.href + '/'\n const resolved = new URL(href, base).pathname\n return resolved.length > 1 ? resolved.replace(/\\/$/, '') : resolved\n}\n\nexport function Link({ href, prefetch = false, viewTransition = false, children, ...props }: LinkProps) {\n const router = useContext(RouterContext)\n\n const handleMouseEnter = useCallback(() => {\n if (!prefetch) return\n const resolved = resolveHref(href)\n const pathname = resolved.split('?')[0].split('#')[0]\n const matched = matchClientRoute(pathname)\n if (matched) {\n matched.load().catch(() => {})\n fetch(`/_data${resolved}`, { headers: { Accept: 'application/json' } }).catch(() => {})\n }\n }, [href, prefetch])\n\n const handleClick: MouseEventHandler<HTMLAnchorElement> = (e) => {\n if (!router) return\n if (!e.ctrlKey && !e.metaKey && !e.shiftKey && e.button === 0) {\n e.preventDefault()\n const resolved = resolveHref(href)\n if (viewTransition && typeof document.startViewTransition === 'function') {\n document.startViewTransition(() => router.navigate(resolved))\n } else {\n router.navigate(resolved)\n }\n }\n }\n\n return (\n <a href={href} onClick={handleClick} onMouseEnter={handleMouseEnter} {...props}>\n {children}\n </a>\n )\n}", "export interface CookieOptions {\n httpOnly?: boolean\n secure?: boolean\n sameSite?: 'Strict' | 'Lax' | 'None'\n maxAge?: number\n expires?: Date\n path?: string\n domain?: string\n}\n\nexport function getCookie(req: Request, name: string): string | undefined {\n const header = req.headers.get('cookie')\n if (!header) return undefined\n for (const part of header.split(';')) {\n const [key, ...rest] = part.trim().split('=')\n if (key.trim() === name) return decodeURIComponent(rest.join('='))\n }\n return undefined\n}\n\nexport function setCookie(headers: Headers, name: string, value: string, options: CookieOptions = {}): void {\n let cookie = `${name}=${encodeURIComponent(value)}; Path=${options.path ?? '/'}`\n if (options.domain) cookie += `; Domain=${options.domain}`\n if (options.maxAge !== undefined) cookie += `; Max-Age=${options.maxAge}`\n if (options.expires) cookie += `; Expires=${options.expires.toUTCString()}`\n if (options.httpOnly) cookie += `; HttpOnly`\n if (options.secure) cookie += `; Secure`\n if (options.sameSite) cookie += `; SameSite=${options.sameSite}`\n headers.append('Set-Cookie', cookie)\n}\n\nexport function deleteCookie(headers: Headers, name: string, options: Pick<CookieOptions, 'path' | 'domain'> = {}): void {\n setCookie(headers, name, '', {...options, maxAge: 0, expires: new Date(0)})\n}\n", "export type JsonResponse<T = unknown> = Response & { readonly __body: T }\n\nexport const json = <const T>(data: T, status = 200): JsonResponse<T> =>\n new Response(JSON.stringify(data), {\n status,\n headers: {'Content-Type': 'application/json'},\n }) as JsonResponse<T>\n\nexport const text = (body: string, status = 200): Response =>\n new Response(body, {status, headers: {'Content-Type': 'text/plain; charset=utf-8'}})\n\nconst REDIRECT_BRAND = Symbol('devix.redirect')\n\nexport interface RedirectOptions {\n status?: number\n replace?: boolean\n}\n\nexport interface Redirect {\n readonly [REDIRECT_BRAND]: true\n readonly url: string\n readonly status: number\n readonly replace: boolean\n}\n\nexport function redirect(url: string, statusOrOptions?: number | RedirectOptions): Redirect {\n const status = typeof statusOrOptions === 'number' ? statusOrOptions : (statusOrOptions?.status ?? 302)\n const replace = typeof statusOrOptions === 'object' ? (statusOrOptions?.replace ?? false) : false\n return {[REDIRECT_BRAND]: true, url, status, replace} as Redirect\n}\n\nexport function isRedirect(value: unknown): value is Redirect {\n return typeof value === 'object' && value !== null && REDIRECT_BRAND in value\n}\n", "export interface ApiRoutes { }\n\ntype HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD' | 'OPTIONS'\n\ntype ApiKey<M extends HttpMethod, P extends string> = `${M} ${P}`\n\ntype RouteData<M extends HttpMethod, P extends string> =\n ApiKey<M, P> extends keyof ApiRoutes ? ApiRoutes[ApiKey<M, P>] : unknown\n\ntype AllApiPaths = {\n [K in keyof ApiRoutes]: K extends `${HttpMethod} ${infer P}` ? P : never\n}[keyof ApiRoutes]\n\ntype ApiPath = [AllApiPaths] extends [never] ? string : AllApiPaths | (string & {})\n\ntype ExtractBody<D> = D extends { __body: infer B } ? B : never\ntype UnwrapReturn<R> =\n R extends { __body: infer B } ? B\n : R extends void | undefined ? never\n : R\ntype ExtractResponse<D> =\n D extends { __return: infer R } ? UnwrapReturn<R>\n : D extends { __response: infer R } ? R\n : D\n\ntype InferBody<M extends HttpMethod, P extends string> = ExtractBody<RouteData<M, P>>\ntype InferResult<M extends HttpMethod, P extends string> = ExtractResponse<RouteData<M, P>>\n\ntype BodyOption<M extends HttpMethod, P extends string> =\n [InferBody<M, P>] extends [never] ? unknown : InferBody<M, P>\n\nexport interface FetchOptions<M extends HttpMethod = 'GET', P extends string = string> {\n method?: M\n body?: BodyOption<M, P>\n headers?: HeadersInit\n signal?: AbortSignal\n}\n\nexport class FetchError extends Error {\n constructor(\n public readonly status: number,\n public readonly statusText: string,\n public readonly response: Response,\n ) {\n super(`HTTP ${status}: ${statusText}`)\n this.name = 'FetchError'\n }\n}\n\nexport async function $fetch<\n P extends ApiPath = ApiPath,\n M extends HttpMethod = 'GET',\n>(path: P, options?: FetchOptions<M, P>): Promise<InferResult<M, P>> {\n const method = (options?.method ?? 'GET') as string\n const headers = new Headers(options?.headers)\n\n let body: BodyInit | undefined\n if (options?.body !== undefined) {\n body = JSON.stringify(options.body)\n if (!headers.has('Content-Type')) {\n headers.set('Content-Type', 'application/json')\n }\n }\n\n const response = await fetch(path, { method, headers, body, signal: options?.signal })\n\n if (!response.ok) {\n throw new FetchError(response.status, response.statusText, response)\n }\n\n const contentType = response.headers.get('Content-Type') ?? ''\n if (contentType.includes('application/json')) {\n return response.json() as Promise<InferResult<M, P>>\n }\n\n return response.text() as unknown as Promise<InferResult<M, P>>\n}\n", "export const HANDLER_BRAND = '__devix_handler__' as const\n\nexport interface DevixHandler<TBody = undefined, TReturn = unknown> {\n readonly [HANDLER_BRAND]: true\n readonly fn: (...args: any[]) => any\n readonly __body: TBody\n readonly __return: TReturn\n}\n\ntype ExtractBody<TFn> = TFn extends (body: infer B) => any ? B : undefined\n\nexport function createHandler<TFn extends (...args: any[]) => any>(\n fn: TFn,\n): DevixHandler<ExtractBody<TFn>, Awaited<ReturnType<TFn>>> {\n return {[HANDLER_BRAND]: true, fn} as unknown as DevixHandler<ExtractBody<TFn>, Awaited<ReturnType<TFn>>>\n}\n"],
5
- "mappings": "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",
6
- "names": ["useCallback", "useContext", "useEffect", "useRef", "useState", "RouterContext", "getDefaultErrorPage", "loadErrorPage", "matchClientRoute", "Fragment", "jsx", "collectTags", "metadata", "viewport", "tags", "ogTitle", "ogDesc", "twTitle", "twDesc", "lang", "href", "parts", "HeadSlot", "buildHeadNodes", "t", "i", "createContext", "g", "RouterContext", "PageMetaContext", "RouteDataContext", "Component", "jsx", "DevixErrorBoundary", "err", "DevixError", "statusCode", "message", "jsx", "jsxs", "useRouter", "useContext", "RouterContext", "noopNavigate", "noopRevalidate", "useNavigate", "useRevalidate", "useParams", "ctx", "RouteDataContext", "useLoaderData", "RouterProvider", "initialData", "initialParams", "initialPage", "initialLayouts", "initialLayoutsData", "initialMeta", "initialViewport", "initialError", "initialErrorPage", "clientEntry", "state", "setState", "useState", "navigatingRef", "useRef", "isNavigating", "setIsNavigating", "loadRoute", "useCallback", "to", "controller", "pathname", "matched", "matchClientRoute", "ErrorPage", "loadErrorPage", "getDefaultErrorPage", "prev", "pageMod", "layoutMods", "l", "dataRes", "data", "m", "navigate", "options", "run", "revalidate", "useEffect", "handlePop", "err", "content", "tree", "i", "Layout", "layoutData", "DevixErrorBoundary", "PageMetaContext", "HeadSlot", "useCallback", "useContext", "matchClientRoute", "RouterContext", "jsx", "resolveHref", "href", "base", "resolved", "Link", "prefetch", "viewTransition", "children", "props", "router", "handleMouseEnter", "pathname", "matched", "e", "getCookie", "req", "name", "header", "part", "key", "rest", "setCookie", "headers", "value", "options", "cookie", "deleteCookie", "json", "data", "status", "text", "body", "REDIRECT_BRAND", "redirect", "url", "statusOrOptions", "replace", "FetchError", "status", "statusText", "response", "$fetch", "path", "options", "method", "headers", "body", "HANDLER_BRAND", "createHandler", "fn"]
4
+ "sourcesContent": ["import { ComponentType, ReactNode, useCallback, useContext, useEffect, useRef, useState } from \"react\";\nimport { RouterContext } from 'virtual:devix/context'\nimport { ErrorProps, LayoutProps, PageProps } from \"../server/types\";\nimport { Metadata, Viewport } from \"../types\";\nimport { getDefaultErrorPage, loadErrorPage, matchClientRoute } from \"virtual:devix/client-routes\";\nimport { HeadSlot } from \"./head\";\nimport { NavigateOptions, PageMetaContext, RouteDataContext } from \"./context\";\nimport { DevixErrorBoundary } from \"./error-boundary\";\nimport type { Redirect } from \"../utils/response\";\n\ninterface RouteState {\n pathname: string\n params: Record<string, string>\n loaderData: unknown\n layoutsData: unknown[]\n Page: ComponentType<PageProps>\n layouts: ComponentType<LayoutProps>[]\n metadata: Metadata | null\n viewport?: Viewport\n pendingError?: ErrorProps\n ErrorPage?: ComponentType<ErrorProps>\n}\n\nexport function useRouter() {\n return useContext(RouterContext)\n}\n\nconst noopNavigate = () => Promise.resolve()\nconst noopRevalidate = () => Promise.resolve()\n\nexport function useNavigate() {\n const ctx = useContext(RouterContext)\n return ctx?.navigate ?? noopNavigate\n}\n\nexport function useRevalidate() {\n const ctx = useContext(RouterContext)\n return ctx?.revalidate ?? noopRevalidate\n}\n\nexport function useParams<T extends Record<string, string>>() {\n const ctx = useContext(RouteDataContext)\n if (!ctx) throw new Error(\"useParams must be used within a route or layout\")\n return ctx.params as T\n}\n\ntype LoaderReturnType<T> = T extends (...args: any[]) => Promise<infer R>\n ? [Exclude<R, Redirect | void | undefined>] extends [never] ? undefined : Exclude<R, Redirect | void | undefined>\n : T extends (...args: any[]) => infer R\n ? [Exclude<R, Redirect | void | undefined>] extends [never] ? undefined : Exclude<R, Redirect | void | undefined>\n : T\n\nexport function useLoaderData<T>() {\n const ctx = useContext(RouteDataContext)\n if (!ctx) throw new Error(\"useLoaderData must be used within a route or layout\")\n return ctx.loaderData as LoaderReturnType<T>\n}\n\n\ninterface RouterProviderProps {\n initialData: unknown\n initialParams: Record<string, string>\n initialPage: ComponentType<PageProps>\n initialLayouts?: ComponentType<LayoutProps>[]\n initialLayoutsData?: unknown[]\n initialMeta?: Metadata | null\n initialViewport?: Viewport\n initialError?: ErrorProps\n initialErrorPage?: ComponentType<ErrorProps>\n clientEntry: string\n}\n\nexport function RouterProvider({\n initialData,\n initialParams,\n initialPage,\n initialLayouts = [],\n initialLayoutsData = [],\n initialMeta,\n initialViewport,\n initialError,\n initialErrorPage,\n clientEntry,\n}: RouterProviderProps) {\n\n const [state, setState] = useState<RouteState>({\n pathname: window.location.pathname,\n params: initialParams,\n loaderData: initialData,\n layoutsData: initialLayoutsData,\n Page: initialPage,\n layouts: initialLayouts,\n metadata: initialMeta ?? null,\n viewport: initialViewport,\n pendingError: initialError,\n ErrorPage: initialErrorPage,\n })\n\n const navigatingRef = useRef<AbortController | null>(null)\n const [isNavigating, setIsNavigating] = useState(false)\n\n const loadRoute = useCallback(async (to: string, controller: AbortController) => {\n const pathname = to.split('?')[0].split('#')[0]\n const matched = matchClientRoute(pathname)\n if (!matched) {\n const ErrorPage = await loadErrorPage() ?? getDefaultErrorPage()\n setState(prev => ({\n ...prev,\n pathname: pathname,\n pendingError: { statusCode: 404, message: 'Not found' },\n ErrorPage: ErrorPage ?? undefined,\n }))\n return\n }\n\n const [pageMod, ...layoutMods] = await Promise.all([\n matched.load(),\n ...matched.loadLayouts.map(l => l()),\n ])\n\n if (controller.signal.aborted) return\n if (!pageMod.default) return\n\n const dataRes = await fetch(`/_data${to}`, {\n headers: { Accept: 'application/json' },\n signal: controller.signal,\n })\n\n if (controller.signal.aborted) return\n\n if (!dataRes.ok) {\n if (dataRes.status === 404) {\n window.location.href = to\n return\n }\n const ErrorPage = await loadErrorPage() ?? getDefaultErrorPage()\n setState(prev => ({\n ...prev,\n pathname,\n pendingError: { statusCode: dataRes.status, message: 'Server error' },\n ErrorPage: ErrorPage ?? undefined,\n }))\n return\n }\n\n const data = await dataRes.json()\n\n if (data.redirect) {\n if (data.redirectReplace) {\n window.history.replaceState(null, '', data.redirect)\n } else {\n window.history.pushState(null, '', data.redirect)\n }\n await loadRoute(data.redirect, controller)\n return\n }\n\n setState({\n pathname,\n params: data.params ?? {},\n loaderData: data.loaderData,\n layoutsData: (data.layouts ?? []).map((l: any) => l.loaderData),\n Page: pageMod.default,\n layouts: layoutMods.map(m => m.default),\n metadata: data.metadata ?? null,\n viewport: data.viewport,\n })\n\n const hash = to.includes('#') ? to.split('#')[1] : null\n const scrollBehavior = getComputedStyle(document.documentElement).scrollBehavior as ScrollBehavior\n if (hash) {\n requestAnimationFrame(() => {\n document.getElementById(hash)?.scrollIntoView({ behavior: scrollBehavior })\n })\n } else {\n window.scrollTo({ top: 0, behavior: scrollBehavior })\n }\n }, [])\n\n const navigate = useCallback(async (to: string, options?: NavigateOptions) => {\n navigatingRef.current?.abort()\n const controller = new AbortController()\n navigatingRef.current = controller\n\n setIsNavigating(true)\n const run = async () => {\n window.history[options?.replace ? 'replaceState' : 'pushState'](null, '', to)\n await loadRoute(to, controller)\n }\n try {\n if (options?.viewTransition && 'startViewTransition' in document) {\n await (document as any).startViewTransition(run).finished\n } else {\n await run()\n }\n } finally {\n if (!controller.signal.aborted) setIsNavigating(false)\n }\n }, [loadRoute])\n\n const revalidate = useCallback(async () => {\n const to = window.location.pathname + window.location.search\n const controller = new AbortController()\n const dataRes = await fetch(`/_data${to}`, {\n headers: { Accept: 'application/json' },\n signal: controller.signal,\n })\n if (!dataRes.ok) return\n const data = await dataRes.json()\n if (data.redirect) {\n await navigate(data.redirect, { replace: data.redirectReplace })\n return\n }\n setState(prev => ({\n ...prev,\n loaderData: data.loaderData,\n layoutsData: (data.layouts ?? []).map((l: any) => l.loaderData),\n params: data.params ?? prev.params,\n metadata: data.metadata ?? prev.metadata,\n viewport: data.viewport ?? prev.viewport,\n }))\n }, [navigate])\n\n useEffect(() => {\n const handlePop = () => {\n navigatingRef.current?.abort()\n const controller = new AbortController()\n navigatingRef.current = controller\n\n const to = window.location.pathname + window.location.search\n loadRoute(to, controller).catch(err => {\n if (err.name !== 'AbortError') console.error('[router] popstate error:', err)\n })\n }\n window.addEventListener(\"popstate\", handlePop)\n return () => window.removeEventListener(\"popstate\", handlePop)\n }, [loadRoute])\n\n let content: ReactNode\n\n if (state.pendingError) {\n content = state.ErrorPage\n ? <state.ErrorPage {...state.pendingError} />\n : <h1>{state.pendingError.statusCode}</h1>\n } else {\n let tree: ReactNode = (\n <RouteDataContext value={{ loaderData: state.loaderData, params: state.params }}>\n <state.Page data={state.loaderData} params={state.params} url={state.pathname} />\n </RouteDataContext>\n )\n\n for (let i = state.layouts.length - 1; i >= 0; i--) {\n const Layout = state.layouts[i]\n const layoutData = state.layoutsData[i]\n tree = (\n <RouteDataContext value={{ loaderData: layoutData, params: state.params }}>\n <Layout data={layoutData} params={state.params}>{tree}</Layout>\n </RouteDataContext>\n )\n }\n\n content = (\n <DevixErrorBoundary key={state.pathname} ErrorPage={state.ErrorPage}>\n {tree}\n </DevixErrorBoundary>\n )\n }\n\n return (\n <PageMetaContext value={{\n metadata: state.metadata,\n viewport: state.viewport,\n clientEntry,\n }}>\n <HeadSlot metadata={state.metadata} viewport={state.viewport} />\n <RouterContext value={{ ...state, isNavigating, navigate, revalidate }}>\n {content}\n </RouterContext>\n </PageMetaContext>\n )\n}", "import {Metadata, Viewport} from \"../types\";\nimport {ReactNode} from \"react\";\n\ntype MetaTag =\n | { tag: 'title'; children: string }\n | { tag: 'meta'; name?: string; property?: string; content: string }\n | { tag: 'link'; rel: string; href: string; hrefLang?: string }\n\nfunction collectTags(metadata: Metadata, viewport?: Viewport): MetaTag[] {\n const tags: MetaTag[] = []\n\n if (metadata.title)\n tags.push({tag: 'title', children: metadata.title})\n if (metadata.description)\n tags.push({tag: 'meta', name: 'description', content: metadata.description})\n if (metadata.keywords?.length)\n tags.push({tag: 'meta', name: 'keywords', content: metadata.keywords.join(', ')})\n\n const ogTitle = metadata.og?.title ?? metadata.title\n if (ogTitle) tags.push({tag: 'meta', property: 'og:title', content: ogTitle})\n const ogDesc = metadata.og?.description ?? metadata.description\n if (ogDesc) tags.push({tag: 'meta', property: 'og:description', content: ogDesc})\n if (metadata.og?.image) tags.push({tag: 'meta', property: 'og:image', content: metadata.og.image})\n if (metadata.og?.type) tags.push({tag: 'meta', property: 'og:type', content: metadata.og.type})\n if (metadata.og?.url) tags.push({tag: 'meta', property: 'og:url', content: metadata.og.url})\n\n const twTitle = metadata.twitter?.title ?? metadata.title\n if (twTitle) tags.push({tag: 'meta', name: 'twitter:title', content: twTitle})\n const twDesc = metadata.twitter?.description ?? metadata.description\n if (twDesc) tags.push({tag: 'meta', name: 'twitter:description', content: twDesc})\n if (metadata.twitter?.card) tags.push({\n tag: 'meta', name: 'twitter:card', content:\n metadata.twitter.card\n })\n if (metadata.twitter?.image) tags.push({\n tag: 'meta', name: 'twitter:image', content:\n metadata.twitter.image\n })\n if (metadata.twitter?.creator) tags.push({\n tag: 'meta', name: 'twitter:creator', content:\n metadata.twitter.creator\n })\n\n if (metadata.canonical) tags.push({tag: 'link', rel: 'canonical', href: metadata.canonical})\n if (metadata.robots) tags.push({tag: 'meta', name: 'robots', content: metadata.robots})\n if (metadata.alternates) {\n for (const [lang, href] of Object.entries(metadata.alternates))\n tags.push({tag: 'link', rel: 'alternate', href, hrefLang: lang})\n }\n\n if (viewport) {\n const parts: string[] = []\n if (viewport.width !== undefined) parts.push(`width=${viewport.width}`)\n if (viewport.initialScale !== undefined) parts.push(`initial-scale=${viewport.initialScale}`)\n if (viewport.maximumScale !== undefined) parts.push(`maximum-scale=${viewport.maximumScale}`)\n if (viewport.userScalable !== undefined) parts.push(`user-scalable=${viewport.userScalable ? 'yes' :\n 'no'}`)\n if (parts.length) tags.push({tag: 'meta', name: 'viewport', content: parts.join(', ')})\n if (viewport.themeColor) tags.push({\n tag: 'meta', name: 'theme-color', content: viewport.themeColor\n })\n }\n\n return tags\n}\n\nexport function HeadSlot({metadata, viewport}: {metadata: Metadata | null, viewport?: Viewport}) {\n if (typeof window === 'undefined' || !metadata) return null\n return <>{buildHeadNodes(metadata, viewport)}</>\n}\n\nexport function buildHeadNodes(metadata: Metadata, viewport?: Viewport): ReactNode {\n const tags = collectTags(metadata, viewport)\n\n return <>\n {tags.map((t, i) => {\n if (t.tag === 'title') return <title key={i}>{t.children}</title>\n if (t.tag === 'link') return <link key={i} rel={t.rel} href={t.href} hrefLang={t.hrefLang}/>\n return <meta key={i} name={t.name} property={t.property} content={t.content}/>\n })}\n </>\n}", "import {createContext, Context, ComponentType} from \"react\";\nimport {Metadata, Viewport} from \"../types\";\nimport {LayoutProps, PageProps} from \"../server/types\";\n\nexport interface NavigateOptions {\n replace?: boolean\n viewTransition?: boolean\n}\n\nexport interface RouterContextValue {\n pathname: string\n params: Record<string, string>\n loaderData: unknown\n layoutsData: unknown[]\n Page: ComponentType<PageProps>\n layouts: ComponentType<LayoutProps>[]\n metadata: Metadata | null\n viewport?: Viewport\n navigate: (to: string, options?: NavigateOptions) => Promise<void>\n revalidate: () => Promise<void>\n isNavigating: boolean\n}\n\nexport interface PageMetaContextValue {\n metadata: Metadata | null\n viewport?: Viewport\n clientEntry?: string\n}\n\nexport interface RouteDataContextValue {\n loaderData: unknown\n params: Record<string, string>\n}\n\nconst g = globalThis as any\n\ng.__devix_RouterContext__ ??= createContext<RouterContextValue | null>(null)\nexport const RouterContext: Context<RouterContextValue | null> = g.__devix_RouterContext__\n\ng.__devix_PageMetaContext__ ??= createContext<PageMetaContextValue | null>(null)\ng.__devix_RouteDataContext__ ??= createContext<RouteDataContextValue | null>(null)\n\nexport const PageMetaContext: Context<PageMetaContextValue | null> = g.__devix_PageMetaContext__\nexport const RouteDataContext: Context<RouteDataContextValue | null> = g.__devix_RouteDataContext__\n\n", "import {Component, ComponentType, ReactNode} from \"react\";\nimport {ErrorProps} from \"../server/types\";\n\ninterface Props {\n ErrorPage?: ComponentType<ErrorProps>\n children: ReactNode\n}\n\ninterface State {\n error: ErrorProps | null\n}\n\nexport class DevixErrorBoundary extends Component<Props, State> {\n state: State = { error: null }\n\n static getDerivedStateFromError(err: unknown): State {\n if (err instanceof DevixError) {\n return {\n error: {statusCode: err.statusCode, message: err.message}\n }\n }\n return {\n error: {statusCode: 500, message: err instanceof Error ? err.message : 'Unknown error'}\n }\n }\n\n render() {\n if (this.state.error && this.props.ErrorPage) {\n return <this.props.ErrorPage {...this.state.error} />\n }\n if (this.state.error) {\n return <h1>{this.state.error.statusCode}</h1>\n }\n return this.props.children\n }\n}\n\nexport class DevixError extends Error {\n statusCode: number\n constructor(statusCode: number, message: string) {\n super(message)\n this.statusCode = statusCode\n }\n}\n", "import {AnchorHTMLAttributes, MouseEventHandler, useCallback, useContext} from \"react\";\nimport {matchClientRoute} from \"virtual:devix/client-routes\";\nimport {RouterContext} from 'virtual:devix/context'\n\ninterface LinkProps extends AnchorHTMLAttributes<HTMLAnchorElement> {\n href: string\n prefetch?: boolean\n viewTransition?: boolean\n}\n\nfunction resolveHref(href: string): string {\n if (href.startsWith('/') || href.startsWith('http')) return href\n const base = window.location.pathname.endsWith('/')\n ? window.location.href\n : window.location.href + '/'\n const resolved = new URL(href, base).pathname\n return resolved.length > 1 ? resolved.replace(/\\/$/, '') : resolved\n}\n\nexport function Link({ href, prefetch = false, viewTransition = false, children, ...props }: LinkProps) {\n const router = useContext(RouterContext)\n\n const handleMouseEnter = useCallback(() => {\n if (!prefetch) return\n const resolved = resolveHref(href)\n const pathname = resolved.split('?')[0].split('#')[0]\n const matched = matchClientRoute(pathname)\n if (matched) {\n matched.load().catch(() => {})\n fetch(`/_data${resolved}`, { headers: { Accept: 'application/json' } }).catch(() => {})\n }\n }, [href, prefetch])\n\n const handleClick: MouseEventHandler<HTMLAnchorElement> = (e) => {\n if (!router) return\n if (!e.ctrlKey && !e.metaKey && !e.shiftKey && e.button === 0) {\n e.preventDefault()\n const resolved = resolveHref(href)\n if (viewTransition && typeof document.startViewTransition === 'function') {\n document.startViewTransition(() => router.navigate(resolved))\n } else {\n router.navigate(resolved)\n }\n }\n }\n\n return (\n <a href={href} onClick={handleClick} onMouseEnter={handleMouseEnter} {...props}>\n {children}\n </a>\n )\n}", "export interface CookieOptions {\n httpOnly?: boolean\n secure?: boolean\n sameSite?: 'Strict' | 'Lax' | 'None'\n maxAge?: number\n expires?: Date\n path?: string\n domain?: string\n}\n\nexport function getCookie(req: Request, name: string): string | undefined {\n const header = req.headers.get('cookie')\n if (!header) return undefined\n for (const part of header.split(';')) {\n const [key, ...rest] = part.trim().split('=')\n if (key.trim() === name) return decodeURIComponent(rest.join('='))\n }\n return undefined\n}\n\nexport function setCookie(headers: Headers, name: string, value: string, options: CookieOptions = {}): void {\n let cookie = `${name}=${encodeURIComponent(value)}; Path=${options.path ?? '/'}`\n if (options.domain) cookie += `; Domain=${options.domain}`\n if (options.maxAge !== undefined) cookie += `; Max-Age=${options.maxAge}`\n if (options.expires) cookie += `; Expires=${options.expires.toUTCString()}`\n if (options.httpOnly) cookie += `; HttpOnly`\n if (options.secure) cookie += `; Secure`\n if (options.sameSite) cookie += `; SameSite=${options.sameSite}`\n headers.append('Set-Cookie', cookie)\n}\n\nexport function deleteCookie(headers: Headers, name: string, options: Pick<CookieOptions, 'path' | 'domain'> = {}): void {\n setCookie(headers, name, '', {...options, maxAge: 0, expires: new Date(0)})\n}\n", "export type JsonResponse<T = unknown> = Response & { readonly __body: T }\n\nexport const json = <const T>(data: T, status = 200): JsonResponse<T> =>\n new Response(JSON.stringify(data), {\n status,\n headers: {'Content-Type': 'application/json'},\n }) as JsonResponse<T>\n\nexport const text = (body: string, status = 200): Response =>\n new Response(body, {status, headers: {'Content-Type': 'text/plain; charset=utf-8'}})\n\nconst REDIRECT_BRAND = Symbol('devix.redirect')\n\nexport interface RedirectOptions {\n status?: number\n replace?: boolean\n}\n\nexport interface Redirect {\n readonly [REDIRECT_BRAND]: true\n readonly url: string\n readonly status: number\n readonly replace: boolean\n}\n\nexport function redirect(url: string, statusOrOptions?: number | RedirectOptions): Redirect {\n const status = typeof statusOrOptions === 'number' ? statusOrOptions : (statusOrOptions?.status ?? 302)\n const replace = typeof statusOrOptions === 'object' ? (statusOrOptions?.replace ?? false) : false\n return {[REDIRECT_BRAND]: true, url, status, replace} as Redirect\n}\n\nexport function isRedirect(value: unknown): value is Redirect {\n return typeof value === 'object' && value !== null && REDIRECT_BRAND in value\n}\n", "export interface ApiRoutes { }\n\ntype HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD' | 'OPTIONS'\n\ntype ApiKey<M extends HttpMethod, P extends string> = `${M} ${P}`\n\ntype RouteData<M extends HttpMethod, P extends string> =\n ApiKey<M, P> extends keyof ApiRoutes ? ApiRoutes[ApiKey<M, P>] : unknown\n\ntype AllApiPaths = {\n [K in keyof ApiRoutes]: K extends `${HttpMethod} ${infer P}` ? P : never\n}[keyof ApiRoutes]\n\ntype ApiPath = [AllApiPaths] extends [never] ? string : AllApiPaths | (string & {})\n\ntype ExtractBody<D> = D extends { __body: infer B } ? B : never\ntype UnwrapReturn<R> =\n R extends { __body: infer B } ? B\n : R extends void | undefined ? never\n : R\ntype ExtractResponse<D> =\n D extends { __return: infer R } ? UnwrapReturn<R>\n : D extends { __response: infer R } ? R\n : D\n\ntype InferBody<M extends HttpMethod, P extends string> = ExtractBody<RouteData<M, P>>\ntype InferResult<M extends HttpMethod, P extends string> = ExtractResponse<RouteData<M, P>>\n\ntype BodyOption<M extends HttpMethod, P extends string> =\n [InferBody<M, P>] extends [never] ? unknown : InferBody<M, P>\n\nexport interface FetchOptions<M extends HttpMethod = 'GET', P extends string = string> {\n method?: M\n body?: BodyOption<M, P>\n headers?: HeadersInit\n signal?: AbortSignal\n}\n\nexport class FetchError extends Error {\n constructor(\n public readonly status: number,\n public readonly statusText: string,\n public readonly response: Response,\n ) {\n super(`HTTP ${status}: ${statusText}`)\n this.name = 'FetchError'\n }\n}\n\nexport async function $fetch<\n P extends ApiPath = ApiPath,\n M extends HttpMethod = 'GET',\n>(path: P, options?: FetchOptions<M, P>): Promise<InferResult<M, P>> {\n const method = (options?.method ?? 'GET') as string\n const headers = new Headers(options?.headers)\n\n let body: BodyInit | undefined\n if (options?.body !== undefined) {\n body = JSON.stringify(options.body)\n if (!headers.has('Content-Type')) {\n headers.set('Content-Type', 'application/json')\n }\n }\n\n const response = await fetch(path, { method, headers, body, signal: options?.signal })\n\n if (!response.ok) {\n throw new FetchError(response.status, response.statusText, response)\n }\n\n const contentType = response.headers.get('Content-Type') ?? ''\n if (contentType.includes('application/json')) {\n return response.json() as Promise<InferResult<M, P>>\n }\n\n return response.text() as unknown as Promise<InferResult<M, P>>\n}\n", "export const HANDLER_BRAND = '__devix_handler__' as const\n\nexport interface DevixHandler<TBody = undefined, TReturn = unknown> {\n readonly [HANDLER_BRAND]: true\n readonly fn: (...args: any[]) => any\n readonly __body: TBody\n readonly __return: TReturn\n}\n\ntype ExtractBody<TFn> = TFn extends (body: infer B) => any ? B : undefined\n\nexport function createHandler<TFn extends (...args: any[]) => any>(\n fn: TFn,\n): DevixHandler<ExtractBody<TFn>, Awaited<ReturnType<TFn>>> {\n return {[HANDLER_BRAND]: true, fn} as unknown as DevixHandler<ExtractBody<TFn>, Awaited<ReturnType<TFn>>>\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["useCallback", "useContext", "useEffect", "useRef", "useState", "RouterContext", "getDefaultErrorPage", "loadErrorPage", "matchClientRoute", "Fragment", "jsx", "collectTags", "metadata", "viewport", "tags", "ogTitle", "ogDesc", "twTitle", "twDesc", "lang", "href", "parts", "HeadSlot", "buildHeadNodes", "t", "i", "createContext", "g", "RouterContext", "PageMetaContext", "RouteDataContext", "Component", "jsx", "DevixErrorBoundary", "err", "DevixError", "statusCode", "message", "jsx", "jsxs", "useRouter", "useContext", "RouterContext", "noopNavigate", "noopRevalidate", "useNavigate", "useRevalidate", "useParams", "ctx", "RouteDataContext", "useLoaderData", "RouterProvider", "initialData", "initialParams", "initialPage", "initialLayouts", "initialLayoutsData", "initialMeta", "initialViewport", "initialError", "initialErrorPage", "clientEntry", "state", "setState", "useState", "navigatingRef", "useRef", "isNavigating", "setIsNavigating", "loadRoute", "useCallback", "to", "controller", "pathname", "matched", "matchClientRoute", "ErrorPage", "loadErrorPage", "getDefaultErrorPage", "prev", "pageMod", "layoutMods", "l", "dataRes", "data", "m", "hash", "scrollBehavior", "navigate", "options", "run", "revalidate", "useEffect", "handlePop", "err", "content", "tree", "i", "Layout", "layoutData", "DevixErrorBoundary", "PageMetaContext", "HeadSlot", "useCallback", "useContext", "matchClientRoute", "RouterContext", "jsx", "resolveHref", "href", "base", "resolved", "Link", "prefetch", "viewTransition", "children", "props", "router", "handleMouseEnter", "pathname", "matched", "e", "getCookie", "req", "name", "header", "part", "key", "rest", "setCookie", "headers", "value", "options", "cookie", "deleteCookie", "json", "data", "status", "text", "body", "REDIRECT_BRAND", "redirect", "url", "statusOrOptions", "replace", "FetchError", "status", "statusText", "response", "$fetch", "path", "options", "method", "headers", "body", "HANDLER_BRAND", "createHandler", "fn"]
7
7
  }
@@ -1,2 +1,2 @@
1
- import{useCallback as N,useContext as x,useEffect as Q,useRef as W,useState as B}from"react";import{RouterContext as T}from"virtual:devix/context";import{getDefaultErrorPage as F,loadErrorPage as I,matchClientRoute as X}from"virtual:devix/client-routes";import{Fragment as O,jsx as h}from"react/jsx-runtime";function G(t,e){let r=[];t.title&&r.push({tag:"title",children:t.title}),t.description&&r.push({tag:"meta",name:"description",content:t.description}),t.keywords?.length&&r.push({tag:"meta",name:"keywords",content:t.keywords.join(", ")});let l=t.og?.title??t.title;l&&r.push({tag:"meta",property:"og:title",content:l});let g=t.og?.description??t.description;g&&r.push({tag:"meta",property:"og:description",content:g}),t.og?.image&&r.push({tag:"meta",property:"og:image",content:t.og.image}),t.og?.type&&r.push({tag:"meta",property:"og:type",content:t.og.type}),t.og?.url&&r.push({tag:"meta",property:"og:url",content:t.og.url});let P=t.twitter?.title??t.title;P&&r.push({tag:"meta",name:"twitter:title",content:P});let C=t.twitter?.description??t.description;if(C&&r.push({tag:"meta",name:"twitter:description",content:C}),t.twitter?.card&&r.push({tag:"meta",name:"twitter:card",content:t.twitter.card}),t.twitter?.image&&r.push({tag:"meta",name:"twitter:image",content:t.twitter.image}),t.twitter?.creator&&r.push({tag:"meta",name:"twitter:creator",content:t.twitter.creator}),t.canonical&&r.push({tag:"link",rel:"canonical",href:t.canonical}),t.robots&&r.push({tag:"meta",name:"robots",content:t.robots}),t.alternates)for(let[u,_]of Object.entries(t.alternates))r.push({tag:"link",rel:"alternate",href:_,hrefLang:u});if(e){let u=[];e.width!==void 0&&u.push(`width=${e.width}`),e.initialScale!==void 0&&u.push(`initial-scale=${e.initialScale}`),e.maximumScale!==void 0&&u.push(`maximum-scale=${e.maximumScale}`),e.userScalable!==void 0&&u.push(`user-scalable=${e.userScalable?"yes":"no"}`),u.length&&r.push({tag:"meta",name:"viewport",content:u.join(", ")}),e.themeColor&&r.push({tag:"meta",name:"theme-color",content:e.themeColor})}return r}function $({metadata:t,viewport:e}){return typeof window>"u"||!t?null:h(O,{children:J(t,e)})}function J(t,e){let r=G(t,e);return h(O,{children:r.map((l,g)=>l.tag==="title"?h("title",{children:l.children},g):l.tag==="link"?h("link",{rel:l.rel,href:l.href,hrefLang:l.hrefLang},g):h("meta",{name:l.name,property:l.property,content:l.content},g))})}import{createContext as V}from"react";var f=globalThis;f.__devix_RouterContext__??=V(null);var it=f.__devix_RouterContext__;f.__devix_PageMetaContext__??=V(null);f.__devix_RouteDataContext__??=V(null);var j=f.__devix_PageMetaContext__,y=f.__devix_RouteDataContext__;import{Component as K}from"react";import{jsx as H}from"react/jsx-runtime";var D=class extends K{state={error:null};static getDerivedStateFromError(e){return e instanceof L?{error:{statusCode:e.statusCode,message:e.message}}:{error:{statusCode:500,message:e instanceof Error?e.message:"Unknown error"}}}render(){return this.state.error&&this.props.ErrorPage?H(this.props.ErrorPage,{...this.state.error}):this.state.error?H("h1",{children:this.state.error.statusCode}):this.props.children}},L=class extends Error{statusCode;constructor(e,r){super(r),this.statusCode=e}};import{jsx as d,jsxs as tt}from"react/jsx-runtime";function Rt(){return x(T)}var Y=()=>Promise.resolve(),Z=()=>Promise.resolve();function vt(){return x(T)?.navigate??Y}function Et(){return x(T)?.revalidate??Z}function Dt(){let t=x(y);if(!t)throw new Error("useParams must be used within a route or layout");return t.params}function Tt(){let t=x(y);if(!t)throw new Error("useLoaderData must be used within a route or layout");return t.loaderData}function _t({initialData:t,initialParams:e,initialPage:r,initialLayouts:l=[],initialLayoutsData:g=[],initialMeta:P,initialViewport:C,initialError:u,initialErrorPage:_,clientEntry:U}){let[o,R]=B({pathname:window.location.pathname,params:e,loaderData:t,layoutsData:g,Page:r,layouts:l,metadata:P??null,viewport:C,pendingError:u,ErrorPage:_}),v=W(null),[q,A]=B(!1),w=N(async(i,n)=>{let s=i.split("?")[0].split("#")[0],a=X(s);if(!a){let c=await I()??F();R(S=>({...S,pathname:s,pendingError:{statusCode:404,message:"Not found"},ErrorPage:c??void 0}));return}let[m,...M]=await Promise.all([a.load(),...a.loadLayouts.map(c=>c())]);if(n.signal.aborted||!m.default)return;let E=await fetch(`/_data${i}`,{headers:{Accept:"application/json"},signal:n.signal});if(n.signal.aborted)return;if(!E.ok){if(E.status===404){window.location.href=i;return}let c=await I()??F();R(S=>({...S,pathname:s,pendingError:{statusCode:E.status,message:"Server error"},ErrorPage:c??void 0}));return}let p=await E.json();if(p.redirect){p.redirectReplace?window.history.replaceState(null,"",p.redirect):window.history.pushState(null,"",p.redirect),await w(p.redirect,n);return}window.scrollTo(0,0),R({pathname:s,params:p.params??{},loaderData:p.loaderData,layoutsData:(p.layouts??[]).map(c=>c.loaderData),Page:m.default,layouts:M.map(c=>c.default),metadata:p.metadata??null,viewport:p.viewport})},[]),b=N(async(i,n)=>{v.current?.abort();let s=new AbortController;v.current=s,A(!0);let a=async()=>{window.history[n?.replace?"replaceState":"pushState"](null,"",i),await w(i,s)};try{n?.viewTransition&&"startViewTransition"in document?await document.startViewTransition(a).finished:await a()}finally{s.signal.aborted||A(!1)}},[w]),z=N(async()=>{let i=window.location.pathname+window.location.search,n=new AbortController,s=await fetch(`/_data${i}`,{headers:{Accept:"application/json"},signal:n.signal});if(!s.ok)return;let a=await s.json();if(a.redirect){await b(a.redirect,{replace:a.redirectReplace});return}R(m=>({...m,loaderData:a.loaderData,layoutsData:(a.layouts??[]).map(M=>M.loaderData),params:a.params??m.params,metadata:a.metadata??m.metadata,viewport:a.viewport??m.viewport}))},[b]);Q(()=>{let i=()=>{v.current?.abort();let n=new AbortController;v.current=n;let s=window.location.pathname+window.location.search;w(s,n).catch(a=>{a.name!=="AbortError"&&console.error("[router] popstate error:",a)})};return window.addEventListener("popstate",i),()=>window.removeEventListener("popstate",i)},[w]);let k;if(o.pendingError)k=o.ErrorPage?d(o.ErrorPage,{...o.pendingError}):d("h1",{children:o.pendingError.statusCode});else{let i=d(y,{value:{loaderData:o.loaderData,params:o.params},children:d(o.Page,{data:o.loaderData,params:o.params,url:o.pathname})});for(let n=o.layouts.length-1;n>=0;n--){let s=o.layouts[n],a=o.layoutsData[n];i=d(y,{value:{loaderData:a,params:o.params},children:d(s,{data:a,params:o.params,children:i})})}k=d(D,{ErrorPage:o.ErrorPage,children:i},o.pathname)}return tt(j,{value:{metadata:o.metadata,viewport:o.viewport,clientEntry:U},children:[d($,{metadata:o.metadata,viewport:o.viewport}),d(T,{value:{...o,isNavigating:q,navigate:b,revalidate:z},children:k})]})}export{_t as RouterProvider,Tt as useLoaderData,vt as useNavigate,Dt as useParams,Et as useRevalidate,Rt as useRouter};
1
+ import{useCallback as N,useContext as x,useEffect as X,useRef as Y,useState as F}from"react";import{RouterContext as T}from"virtual:devix/context";import{getDefaultErrorPage as q,loadErrorPage as U,matchClientRoute as Z}from"virtual:devix/client-routes";import{Fragment as j,jsx as h}from"react/jsx-runtime";function K(t,e){let r=[];t.title&&r.push({tag:"title",children:t.title}),t.description&&r.push({tag:"meta",name:"description",content:t.description}),t.keywords?.length&&r.push({tag:"meta",name:"keywords",content:t.keywords.join(", ")});let l=t.og?.title??t.title;l&&r.push({tag:"meta",property:"og:title",content:l});let g=t.og?.description??t.description;g&&r.push({tag:"meta",property:"og:description",content:g}),t.og?.image&&r.push({tag:"meta",property:"og:image",content:t.og.image}),t.og?.type&&r.push({tag:"meta",property:"og:type",content:t.og.type}),t.og?.url&&r.push({tag:"meta",property:"og:url",content:t.og.url});let P=t.twitter?.title??t.title;P&&r.push({tag:"meta",name:"twitter:title",content:P});let C=t.twitter?.description??t.description;if(C&&r.push({tag:"meta",name:"twitter:description",content:C}),t.twitter?.card&&r.push({tag:"meta",name:"twitter:card",content:t.twitter.card}),t.twitter?.image&&r.push({tag:"meta",name:"twitter:image",content:t.twitter.image}),t.twitter?.creator&&r.push({tag:"meta",name:"twitter:creator",content:t.twitter.creator}),t.canonical&&r.push({tag:"link",rel:"canonical",href:t.canonical}),t.robots&&r.push({tag:"meta",name:"robots",content:t.robots}),t.alternates)for(let[u,_]of Object.entries(t.alternates))r.push({tag:"link",rel:"alternate",href:_,hrefLang:u});if(e){let u=[];e.width!==void 0&&u.push(`width=${e.width}`),e.initialScale!==void 0&&u.push(`initial-scale=${e.initialScale}`),e.maximumScale!==void 0&&u.push(`maximum-scale=${e.maximumScale}`),e.userScalable!==void 0&&u.push(`user-scalable=${e.userScalable?"yes":"no"}`),u.length&&r.push({tag:"meta",name:"viewport",content:u.join(", ")}),e.themeColor&&r.push({tag:"meta",name:"theme-color",content:e.themeColor})}return r}function O({metadata:t,viewport:e}){return typeof window>"u"||!t?null:h(j,{children:Q(t,e)})}function Q(t,e){let r=K(t,e);return h(j,{children:r.map((l,g)=>l.tag==="title"?h("title",{children:l.children},g):l.tag==="link"?h("link",{rel:l.rel,href:l.href,hrefLang:l.hrefLang},g):h("meta",{name:l.name,property:l.property,content:l.content},g))})}import{createContext as V}from"react";var f=globalThis;f.__devix_RouterContext__??=V(null);var lt=f.__devix_RouterContext__;f.__devix_PageMetaContext__??=V(null);f.__devix_RouteDataContext__??=V(null);var H=f.__devix_PageMetaContext__,y=f.__devix_RouteDataContext__;import{Component as W}from"react";import{jsx as I}from"react/jsx-runtime";var D=class extends W{state={error:null};static getDerivedStateFromError(e){return e instanceof L?{error:{statusCode:e.statusCode,message:e.message}}:{error:{statusCode:500,message:e instanceof Error?e.message:"Unknown error"}}}render(){return this.state.error&&this.props.ErrorPage?I(this.props.ErrorPage,{...this.state.error}):this.state.error?I("h1",{children:this.state.error.statusCode}):this.props.children}},L=class extends Error{statusCode;constructor(e,r){super(r),this.statusCode=e}};import{jsx as d,jsxs as rt}from"react/jsx-runtime";function Et(){return x(T)}var tt=()=>Promise.resolve(),et=()=>Promise.resolve();function Dt(){return x(T)?.navigate??tt}function Tt(){return x(T)?.revalidate??et}function _t(){let t=x(y);if(!t)throw new Error("useParams must be used within a route or layout");return t.params}function bt(){let t=x(y);if(!t)throw new Error("useLoaderData must be used within a route or layout");return t.loaderData}function kt({initialData:t,initialParams:e,initialPage:r,initialLayouts:l=[],initialLayoutsData:g=[],initialMeta:P,initialViewport:C,initialError:u,initialErrorPage:_,clientEntry:z}){let[o,R]=F({pathname:window.location.pathname,params:e,loaderData:t,layoutsData:g,Page:r,layouts:l,metadata:P??null,viewport:C,pendingError:u,ErrorPage:_}),v=Y(null),[G,A]=F(!1),w=N(async(n,i)=>{let s=n.split("?")[0].split("#")[0],a=Z(s);if(!a){let c=await U()??q();R(S=>({...S,pathname:s,pendingError:{statusCode:404,message:"Not found"},ErrorPage:c??void 0}));return}let[m,...M]=await Promise.all([a.load(),...a.loadLayouts.map(c=>c())]);if(i.signal.aborted||!m.default)return;let E=await fetch(`/_data${n}`,{headers:{Accept:"application/json"},signal:i.signal});if(i.signal.aborted)return;if(!E.ok){if(E.status===404){window.location.href=n;return}let c=await U()??q();R(S=>({...S,pathname:s,pendingError:{statusCode:E.status,message:"Server error"},ErrorPage:c??void 0}));return}let p=await E.json();if(p.redirect){p.redirectReplace?window.history.replaceState(null,"",p.redirect):window.history.pushState(null,"",p.redirect),await w(p.redirect,i);return}R({pathname:s,params:p.params??{},loaderData:p.loaderData,layoutsData:(p.layouts??[]).map(c=>c.loaderData),Page:m.default,layouts:M.map(c=>c.default),metadata:p.metadata??null,viewport:p.viewport});let $=n.includes("#")?n.split("#")[1]:null,B=getComputedStyle(document.documentElement).scrollBehavior;$?requestAnimationFrame(()=>{document.getElementById($)?.scrollIntoView({behavior:B})}):window.scrollTo({top:0,behavior:B})},[]),b=N(async(n,i)=>{v.current?.abort();let s=new AbortController;v.current=s,A(!0);let a=async()=>{window.history[i?.replace?"replaceState":"pushState"](null,"",n),await w(n,s)};try{i?.viewTransition&&"startViewTransition"in document?await document.startViewTransition(a).finished:await a()}finally{s.signal.aborted||A(!1)}},[w]),J=N(async()=>{let n=window.location.pathname+window.location.search,i=new AbortController,s=await fetch(`/_data${n}`,{headers:{Accept:"application/json"},signal:i.signal});if(!s.ok)return;let a=await s.json();if(a.redirect){await b(a.redirect,{replace:a.redirectReplace});return}R(m=>({...m,loaderData:a.loaderData,layoutsData:(a.layouts??[]).map(M=>M.loaderData),params:a.params??m.params,metadata:a.metadata??m.metadata,viewport:a.viewport??m.viewport}))},[b]);X(()=>{let n=()=>{v.current?.abort();let i=new AbortController;v.current=i;let s=window.location.pathname+window.location.search;w(s,i).catch(a=>{a.name!=="AbortError"&&console.error("[router] popstate error:",a)})};return window.addEventListener("popstate",n),()=>window.removeEventListener("popstate",n)},[w]);let k;if(o.pendingError)k=o.ErrorPage?d(o.ErrorPage,{...o.pendingError}):d("h1",{children:o.pendingError.statusCode});else{let n=d(y,{value:{loaderData:o.loaderData,params:o.params},children:d(o.Page,{data:o.loaderData,params:o.params,url:o.pathname})});for(let i=o.layouts.length-1;i>=0;i--){let s=o.layouts[i],a=o.layoutsData[i];n=d(y,{value:{loaderData:a,params:o.params},children:d(s,{data:a,params:o.params,children:n})})}k=d(D,{ErrorPage:o.ErrorPage,children:n},o.pathname)}return rt(H,{value:{metadata:o.metadata,viewport:o.viewport,clientEntry:z},children:[d(O,{metadata:o.metadata,viewport:o.viewport}),d(T,{value:{...o,isNavigating:G,navigate:b,revalidate:J},children:k})]})}export{kt as RouterProvider,bt as useLoaderData,Dt as useNavigate,_t as useParams,Tt as useRevalidate,Et as useRouter};
2
2
  //# sourceMappingURL=router-provider.js.map