olova 2.0.59 → 2.0.60
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/entry-worker.cjs.map +1 -1
- package/dist/entry-worker.js.map +1 -1
- package/dist/main.cjs +5 -30
- package/dist/main.cjs.map +1 -1
- package/dist/main.js +4 -29
- package/dist/main.js.map +1 -1
- package/dist/olova.cjs +18 -22
- package/dist/olova.cjs.map +1 -1
- package/dist/olova.js +17 -21
- package/dist/olova.js.map +1 -1
- package/main.tsx +76 -0
- package/olova.ts +619 -0
- package/package.json +18 -34
- package/src/entry-server.tsx +165 -0
- package/src/entry-worker.tsx +201 -0
- package/src/generator/index.ts +409 -0
- package/src/hydration/flight.ts +320 -0
- package/src/hydration/index.ts +12 -0
- package/src/hydration/types.ts +225 -0
- package/src/logger.ts +182 -0
- package/src/main.tsx +24 -0
- package/src/performance.ts +488 -0
- package/src/plugin/index.ts +204 -0
- package/src/router/ErrorBoundary.tsx +145 -0
- package/src/router/Link.tsx +117 -0
- package/src/router/OlovaRouter.tsx +354 -0
- package/src/router/Outlet.tsx +8 -0
- package/src/router/context.ts +117 -0
- package/src/router/index.ts +29 -0
- package/src/router/matching.ts +63 -0
- package/src/router/router.tsx +23 -0
- package/src/router/search-params.ts +29 -0
- package/src/scanner/index.ts +114 -0
- package/src/types/index.ts +190 -0
- package/src/utils/export.ts +85 -0
- package/src/utils/index.ts +4 -0
- package/src/utils/naming.ts +54 -0
- package/src/utils/path.ts +45 -0
- package/tsup.config.ts +35 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/entry-worker.tsx"],"names":["routes","layouts","jsx","Outlet","QueryClient","dehydrate","renderToString","StrictMode","QueryClientProvider","HydrationBoundary","Suspense","OlovaRouter","notFoundPages"],"mappings":"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","file":"entry-worker.cjs","sourcesContent":["/**\r\n * Olova Cloudflare Workers Entry\r\n * Auto-generated by plugin - handles SSR for routes with loaders only\r\n */\r\n\r\nimport { renderToString } from 'react-dom/server';\r\nimport { StrictMode, Suspense } from 'react';\r\nimport { QueryClient, QueryClientProvider, dehydrate, HydrationBoundary } from '@tanstack/react-query';\r\n// @ts-expect-error - Virtual module resolved by vite-plugin-olova\r\nimport { layouts, notFoundPages, OlovaRouter, Outlet, routes } from 'virtual:olova-app';\r\n\r\n// =============================================================================\r\n// TYPES\r\n// =============================================================================\r\n\r\ninterface RouteMatch {\r\n route: any;\r\n params: Record<string, string>;\r\n}\r\n\r\n// =============================================================================\r\n// ROUTE MATCHING\r\n// =============================================================================\r\n\r\nfunction matchRoute(pathname: string): RouteMatch | null {\r\n for (const route of routes) {\r\n // Exact match\r\n if (route.path === pathname) {\r\n return { route, params: {} };\r\n }\r\n\r\n // Dynamic segments\r\n if (route.path.includes(':') || route.path.includes('*')) {\r\n const pattern = route.path\r\n .replace(/\\*/g, '(.*)')\r\n .replace(/:[^/]+/g, '([^/]+)');\r\n const regex = new RegExp(`^${pattern}$`);\r\n const match = pathname.match(regex);\r\n\r\n if (match) {\r\n const params: Record<string, string> = {};\r\n const paramNames = route.path.match(/:[^/]+|\\*/g) || [];\r\n\r\n paramNames.forEach((name: string, i: number) => {\r\n const key = name === '*' ? '*' : name.slice(1);\r\n params[key] = match[i + 1];\r\n });\r\n\r\n return { route, params };\r\n }\r\n }\r\n }\r\n\r\n return null;\r\n}\r\n\r\n// =============================================================================\r\n// SSR RENDERING\r\n// =============================================================================\r\n\r\n// Wrapper to support \"children\" prop style layouts\r\nconst wrappedLayouts = layouts.map((item: any) => ({\r\n ...item,\r\n layout: (props: any) => (\r\n <item.layout {...props}>\r\n <Outlet />\r\n </item.layout>\r\n )\r\n}));\r\n\r\nasync function render(\r\n pathname: string,\r\n loaderData?: Record<string, unknown>\r\n): Promise<{ html: string; queryState: unknown }> {\r\n // Mock browser globals\r\n const g = globalThis as any;\r\n g.window = {\r\n location: { pathname, search: '', hash: '' },\r\n addEventListener: () => {},\r\n removeEventListener: () => {},\r\n history: { pushState: () => {}, replaceState: () => {} },\r\n __LOADER_DATA__: loaderData\r\n };\r\n g.__LOADER_DATA__ = loaderData;\r\n\r\n // Create QueryClient with pre-loaded data\r\n const queryClient = new QueryClient({\r\n defaultOptions: {\r\n queries: {\r\n staleTime: Infinity,\r\n gcTime: Infinity,\r\n },\r\n },\r\n });\r\n\r\n // Pre-populate query client with loader data\r\n if (loaderData) {\r\n Object.entries(loaderData).forEach(([key, value]) => {\r\n queryClient.setQueryData([key], value);\r\n });\r\n }\r\n\r\n // Get dehydrated state for client hydration\r\n const queryState = dehydrate(queryClient);\r\n\r\n const html = renderToString(\r\n <StrictMode>\r\n <QueryClientProvider client={queryClient}>\r\n <HydrationBoundary state={queryState}>\r\n <Suspense fallback={null}>\r\n <OlovaRouter\r\n routes={routes}\r\n layouts={wrappedLayouts}\r\n notFoundPages={notFoundPages}\r\n />\r\n </Suspense>\r\n </HydrationBoundary>\r\n </QueryClientProvider>\r\n </StrictMode>\r\n );\r\n\r\n return { html, queryState };\r\n}\r\n\r\n// =============================================================================\r\n// WORKER EXPORT\r\n// =============================================================================\r\n\r\nexport interface WorkerEnv {\r\n ASSETS: { fetch: (request: Request | URL) => Promise<Response> };\r\n}\r\n\r\nexport default {\r\n async fetch(request: Request, env: WorkerEnv): Promise<Response> {\r\n const url = new URL(request.url);\r\n const pathname = url.pathname;\r\n\r\n // 1. Non-HTML requests → serve static assets directly\r\n if (!request.headers.get('accept')?.includes('text/html')) {\r\n return env.ASSETS.fetch(request);\r\n }\r\n\r\n // 2. Check if route has loader (needs SSR)\r\n const match = matchRoute(pathname);\r\n const needsSSR = match?.route?.loader;\r\n\r\n // 3. No SSR needed → serve pre-built static HTML\r\n if (!needsSSR) {\r\n const staticPath = pathname === '/' ? '/index.html' : `${pathname}/index.html`;\r\n try {\r\n const staticResponse = await env.ASSETS.fetch(new URL(staticPath, url));\r\n if (staticResponse.ok) {\r\n return new Response(staticResponse.body, {\r\n status: 200,\r\n headers: { 'Content-Type': 'text/html; charset=utf-8' }\r\n });\r\n }\r\n } catch {}\r\n \r\n // Fallback to 404.html\r\n try {\r\n const notFoundResponse = await env.ASSETS.fetch(new URL('/404.html', url));\r\n return new Response(notFoundResponse.body, { \r\n status: 404, \r\n headers: { 'Content-Type': 'text/html; charset=utf-8' } \r\n });\r\n } catch {}\r\n \r\n return new Response('Not Found', { status: 404 });\r\n }\r\n\r\n // 4. Route has loader → run SSR\r\n let loaderData: Record<string, unknown> | undefined;\r\n\r\n try {\r\n const result = await match.route.loader({\r\n request,\r\n params: match.params\r\n });\r\n\r\n if (!(result instanceof Response)) {\r\n loaderData = result;\r\n }\r\n } catch (error) {\r\n console.error('[Olova] Loader error:', error);\r\n }\r\n\r\n // 5. Render with loader data\r\n const { html: appHtml, queryState } = await render(pathname, loaderData);\r\n\r\n // Build full HTML document\r\n const html = `<!DOCTYPE html>${appHtml}<script>window.__QUERY_STATE__=${JSON.stringify(queryState)}</script><script type=\"module\" src=\"/assets/_olova/main.js\"></script>`;\r\n\r\n return new Response(html, {\r\n headers: { 'Content-Type': 'text/html; charset=utf-8' }\r\n });\r\n }\r\n};\r\n\r\n// Export for SSG builds\r\nexport { render, matchRoute };\r\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/entry-worker.tsx"],"names":["routes","layouts","jsx","Outlet","QueryClient","dehydrate","renderToString","StrictMode","QueryClientProvider","HydrationBoundary","Suspense","OlovaRouter","notFoundPages"],"mappings":"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","file":"entry-worker.cjs","sourcesContent":["/**\n * Olova Cloudflare Workers Entry\n * Auto-generated by plugin - handles SSR for routes with loaders only\n */\n\nimport { renderToString } from 'react-dom/server';\nimport { StrictMode, Suspense } from 'react';\nimport { QueryClient, QueryClientProvider, dehydrate, HydrationBoundary } from '@tanstack/react-query';\n// @ts-expect-error - Virtual module resolved by vite-plugin-olova\nimport { layouts, notFoundPages, OlovaRouter, Outlet, routes } from 'virtual:olova-app';\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\ninterface RouteMatch {\n route: any;\n params: Record<string, string>;\n}\n\n// =============================================================================\n// ROUTE MATCHING\n// =============================================================================\n\nfunction matchRoute(pathname: string): RouteMatch | null {\n for (const route of routes) {\n // Exact match\n if (route.path === pathname) {\n return { route, params: {} };\n }\n\n // Dynamic segments\n if (route.path.includes(':') || route.path.includes('*')) {\n const pattern = route.path\n .replace(/\\*/g, '(.*)')\n .replace(/:[^/]+/g, '([^/]+)');\n const regex = new RegExp(`^${pattern}$`);\n const match = pathname.match(regex);\n\n if (match) {\n const params: Record<string, string> = {};\n const paramNames = route.path.match(/:[^/]+|\\*/g) || [];\n\n paramNames.forEach((name: string, i: number) => {\n const key = name === '*' ? '*' : name.slice(1);\n params[key] = match[i + 1];\n });\n\n return { route, params };\n }\n }\n }\n\n return null;\n}\n\n// =============================================================================\n// SSR RENDERING\n// =============================================================================\n\n// Wrapper to support \"children\" prop style layouts\nconst wrappedLayouts = layouts.map((item: any) => ({\n ...item,\n layout: (props: any) => (\n <item.layout {...props}>\n <Outlet />\n </item.layout>\n )\n}));\n\nasync function render(\n pathname: string,\n loaderData?: Record<string, unknown>\n): Promise<{ html: string; queryState: unknown }> {\n // Mock browser globals\n const g = globalThis as any;\n g.window = {\n location: { pathname, search: '', hash: '' },\n addEventListener: () => {},\n removeEventListener: () => {},\n history: { pushState: () => {}, replaceState: () => {} },\n __LOADER_DATA__: loaderData\n };\n g.__LOADER_DATA__ = loaderData;\n\n // Create QueryClient with pre-loaded data\n const queryClient = new QueryClient({\n defaultOptions: {\n queries: {\n staleTime: Infinity,\n gcTime: Infinity,\n },\n },\n });\n\n // Pre-populate query client with loader data\n if (loaderData) {\n Object.entries(loaderData).forEach(([key, value]) => {\n queryClient.setQueryData([key], value);\n });\n }\n\n // Get dehydrated state for client hydration\n const queryState = dehydrate(queryClient);\n\n const html = renderToString(\n <StrictMode>\n <QueryClientProvider client={queryClient}>\n <HydrationBoundary state={queryState}>\n <Suspense fallback={null}>\n <OlovaRouter\n routes={routes}\n layouts={wrappedLayouts}\n notFoundPages={notFoundPages}\n />\n </Suspense>\n </HydrationBoundary>\n </QueryClientProvider>\n </StrictMode>\n );\n\n return { html, queryState };\n}\n\n// =============================================================================\n// WORKER EXPORT\n// =============================================================================\n\nexport interface WorkerEnv {\n ASSETS: { fetch: (request: Request | URL) => Promise<Response> };\n}\n\nexport default {\n async fetch(request: Request, env: WorkerEnv): Promise<Response> {\n const url = new URL(request.url);\n const pathname = url.pathname;\n\n // 1. Non-HTML requests → serve static assets directly\n if (!request.headers.get('accept')?.includes('text/html')) {\n return env.ASSETS.fetch(request);\n }\n\n // 2. Check if route has loader (needs SSR)\n const match = matchRoute(pathname);\n const needsSSR = match?.route?.loader;\n\n // 3. No SSR needed → serve pre-built static HTML\n if (!needsSSR) {\n const staticPath = pathname === '/' ? '/index.html' : `${pathname}/index.html`;\n try {\n const staticResponse = await env.ASSETS.fetch(new URL(staticPath, url));\n if (staticResponse.ok) {\n return new Response(staticResponse.body, {\n status: 200,\n headers: { 'Content-Type': 'text/html; charset=utf-8' }\n });\n }\n } catch {}\n \n // Fallback to 404.html\n try {\n const notFoundResponse = await env.ASSETS.fetch(new URL('/404.html', url));\n return new Response(notFoundResponse.body, { \n status: 404, \n headers: { 'Content-Type': 'text/html; charset=utf-8' } \n });\n } catch {}\n \n return new Response('Not Found', { status: 404 });\n }\n\n // 4. Route has loader → run SSR\n let loaderData: Record<string, unknown> | undefined;\n\n try {\n const result = await match.route.loader({\n request,\n params: match.params\n });\n\n if (!(result instanceof Response)) {\n loaderData = result;\n }\n } catch (error) {\n console.error('[Olova] Loader error:', error);\n }\n\n // 5. Render with loader data\n const { html: appHtml, queryState } = await render(pathname, loaderData);\n\n // Build full HTML document\n const html = `<!DOCTYPE html>${appHtml}<script>window.__QUERY_STATE__=${JSON.stringify(queryState)}</script><script type=\"module\" src=\"/assets/_olova/main.js\"></script>`;\n\n return new Response(html, {\n headers: { 'Content-Type': 'text/html; charset=utf-8' }\n });\n }\n};\n\n// Export for SSG builds\nexport { render, matchRoute };\n"]}
|
package/dist/entry-worker.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/entry-worker.tsx"],"names":[],"mappings":"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","file":"entry-worker.js","sourcesContent":["/**\r\n * Olova Cloudflare Workers Entry\r\n * Auto-generated by plugin - handles SSR for routes with loaders only\r\n */\r\n\r\nimport { renderToString } from 'react-dom/server';\r\nimport { StrictMode, Suspense } from 'react';\r\nimport { QueryClient, QueryClientProvider, dehydrate, HydrationBoundary } from '@tanstack/react-query';\r\n// @ts-expect-error - Virtual module resolved by vite-plugin-olova\r\nimport { layouts, notFoundPages, OlovaRouter, Outlet, routes } from 'virtual:olova-app';\r\n\r\n// =============================================================================\r\n// TYPES\r\n// =============================================================================\r\n\r\ninterface RouteMatch {\r\n route: any;\r\n params: Record<string, string>;\r\n}\r\n\r\n// =============================================================================\r\n// ROUTE MATCHING\r\n// =============================================================================\r\n\r\nfunction matchRoute(pathname: string): RouteMatch | null {\r\n for (const route of routes) {\r\n // Exact match\r\n if (route.path === pathname) {\r\n return { route, params: {} };\r\n }\r\n\r\n // Dynamic segments\r\n if (route.path.includes(':') || route.path.includes('*')) {\r\n const pattern = route.path\r\n .replace(/\\*/g, '(.*)')\r\n .replace(/:[^/]+/g, '([^/]+)');\r\n const regex = new RegExp(`^${pattern}$`);\r\n const match = pathname.match(regex);\r\n\r\n if (match) {\r\n const params: Record<string, string> = {};\r\n const paramNames = route.path.match(/:[^/]+|\\*/g) || [];\r\n\r\n paramNames.forEach((name: string, i: number) => {\r\n const key = name === '*' ? '*' : name.slice(1);\r\n params[key] = match[i + 1];\r\n });\r\n\r\n return { route, params };\r\n }\r\n }\r\n }\r\n\r\n return null;\r\n}\r\n\r\n// =============================================================================\r\n// SSR RENDERING\r\n// =============================================================================\r\n\r\n// Wrapper to support \"children\" prop style layouts\r\nconst wrappedLayouts = layouts.map((item: any) => ({\r\n ...item,\r\n layout: (props: any) => (\r\n <item.layout {...props}>\r\n <Outlet />\r\n </item.layout>\r\n )\r\n}));\r\n\r\nasync function render(\r\n pathname: string,\r\n loaderData?: Record<string, unknown>\r\n): Promise<{ html: string; queryState: unknown }> {\r\n // Mock browser globals\r\n const g = globalThis as any;\r\n g.window = {\r\n location: { pathname, search: '', hash: '' },\r\n addEventListener: () => {},\r\n removeEventListener: () => {},\r\n history: { pushState: () => {}, replaceState: () => {} },\r\n __LOADER_DATA__: loaderData\r\n };\r\n g.__LOADER_DATA__ = loaderData;\r\n\r\n // Create QueryClient with pre-loaded data\r\n const queryClient = new QueryClient({\r\n defaultOptions: {\r\n queries: {\r\n staleTime: Infinity,\r\n gcTime: Infinity,\r\n },\r\n },\r\n });\r\n\r\n // Pre-populate query client with loader data\r\n if (loaderData) {\r\n Object.entries(loaderData).forEach(([key, value]) => {\r\n queryClient.setQueryData([key], value);\r\n });\r\n }\r\n\r\n // Get dehydrated state for client hydration\r\n const queryState = dehydrate(queryClient);\r\n\r\n const html = renderToString(\r\n <StrictMode>\r\n <QueryClientProvider client={queryClient}>\r\n <HydrationBoundary state={queryState}>\r\n <Suspense fallback={null}>\r\n <OlovaRouter\r\n routes={routes}\r\n layouts={wrappedLayouts}\r\n notFoundPages={notFoundPages}\r\n />\r\n </Suspense>\r\n </HydrationBoundary>\r\n </QueryClientProvider>\r\n </StrictMode>\r\n );\r\n\r\n return { html, queryState };\r\n}\r\n\r\n// =============================================================================\r\n// WORKER EXPORT\r\n// =============================================================================\r\n\r\nexport interface WorkerEnv {\r\n ASSETS: { fetch: (request: Request | URL) => Promise<Response> };\r\n}\r\n\r\nexport default {\r\n async fetch(request: Request, env: WorkerEnv): Promise<Response> {\r\n const url = new URL(request.url);\r\n const pathname = url.pathname;\r\n\r\n // 1. Non-HTML requests → serve static assets directly\r\n if (!request.headers.get('accept')?.includes('text/html')) {\r\n return env.ASSETS.fetch(request);\r\n }\r\n\r\n // 2. Check if route has loader (needs SSR)\r\n const match = matchRoute(pathname);\r\n const needsSSR = match?.route?.loader;\r\n\r\n // 3. No SSR needed → serve pre-built static HTML\r\n if (!needsSSR) {\r\n const staticPath = pathname === '/' ? '/index.html' : `${pathname}/index.html`;\r\n try {\r\n const staticResponse = await env.ASSETS.fetch(new URL(staticPath, url));\r\n if (staticResponse.ok) {\r\n return new Response(staticResponse.body, {\r\n status: 200,\r\n headers: { 'Content-Type': 'text/html; charset=utf-8' }\r\n });\r\n }\r\n } catch {}\r\n \r\n // Fallback to 404.html\r\n try {\r\n const notFoundResponse = await env.ASSETS.fetch(new URL('/404.html', url));\r\n return new Response(notFoundResponse.body, { \r\n status: 404, \r\n headers: { 'Content-Type': 'text/html; charset=utf-8' } \r\n });\r\n } catch {}\r\n \r\n return new Response('Not Found', { status: 404 });\r\n }\r\n\r\n // 4. Route has loader → run SSR\r\n let loaderData: Record<string, unknown> | undefined;\r\n\r\n try {\r\n const result = await match.route.loader({\r\n request,\r\n params: match.params\r\n });\r\n\r\n if (!(result instanceof Response)) {\r\n loaderData = result;\r\n }\r\n } catch (error) {\r\n console.error('[Olova] Loader error:', error);\r\n }\r\n\r\n // 5. Render with loader data\r\n const { html: appHtml, queryState } = await render(pathname, loaderData);\r\n\r\n // Build full HTML document\r\n const html = `<!DOCTYPE html>${appHtml}<script>window.__QUERY_STATE__=${JSON.stringify(queryState)}</script><script type=\"module\" src=\"/assets/_olova/main.js\"></script>`;\r\n\r\n return new Response(html, {\r\n headers: { 'Content-Type': 'text/html; charset=utf-8' }\r\n });\r\n }\r\n};\r\n\r\n// Export for SSG builds\r\nexport { render, matchRoute };\r\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/entry-worker.tsx"],"names":[],"mappings":"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","file":"entry-worker.js","sourcesContent":["/**\n * Olova Cloudflare Workers Entry\n * Auto-generated by plugin - handles SSR for routes with loaders only\n */\n\nimport { renderToString } from 'react-dom/server';\nimport { StrictMode, Suspense } from 'react';\nimport { QueryClient, QueryClientProvider, dehydrate, HydrationBoundary } from '@tanstack/react-query';\n// @ts-expect-error - Virtual module resolved by vite-plugin-olova\nimport { layouts, notFoundPages, OlovaRouter, Outlet, routes } from 'virtual:olova-app';\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\ninterface RouteMatch {\n route: any;\n params: Record<string, string>;\n}\n\n// =============================================================================\n// ROUTE MATCHING\n// =============================================================================\n\nfunction matchRoute(pathname: string): RouteMatch | null {\n for (const route of routes) {\n // Exact match\n if (route.path === pathname) {\n return { route, params: {} };\n }\n\n // Dynamic segments\n if (route.path.includes(':') || route.path.includes('*')) {\n const pattern = route.path\n .replace(/\\*/g, '(.*)')\n .replace(/:[^/]+/g, '([^/]+)');\n const regex = new RegExp(`^${pattern}$`);\n const match = pathname.match(regex);\n\n if (match) {\n const params: Record<string, string> = {};\n const paramNames = route.path.match(/:[^/]+|\\*/g) || [];\n\n paramNames.forEach((name: string, i: number) => {\n const key = name === '*' ? '*' : name.slice(1);\n params[key] = match[i + 1];\n });\n\n return { route, params };\n }\n }\n }\n\n return null;\n}\n\n// =============================================================================\n// SSR RENDERING\n// =============================================================================\n\n// Wrapper to support \"children\" prop style layouts\nconst wrappedLayouts = layouts.map((item: any) => ({\n ...item,\n layout: (props: any) => (\n <item.layout {...props}>\n <Outlet />\n </item.layout>\n )\n}));\n\nasync function render(\n pathname: string,\n loaderData?: Record<string, unknown>\n): Promise<{ html: string; queryState: unknown }> {\n // Mock browser globals\n const g = globalThis as any;\n g.window = {\n location: { pathname, search: '', hash: '' },\n addEventListener: () => {},\n removeEventListener: () => {},\n history: { pushState: () => {}, replaceState: () => {} },\n __LOADER_DATA__: loaderData\n };\n g.__LOADER_DATA__ = loaderData;\n\n // Create QueryClient with pre-loaded data\n const queryClient = new QueryClient({\n defaultOptions: {\n queries: {\n staleTime: Infinity,\n gcTime: Infinity,\n },\n },\n });\n\n // Pre-populate query client with loader data\n if (loaderData) {\n Object.entries(loaderData).forEach(([key, value]) => {\n queryClient.setQueryData([key], value);\n });\n }\n\n // Get dehydrated state for client hydration\n const queryState = dehydrate(queryClient);\n\n const html = renderToString(\n <StrictMode>\n <QueryClientProvider client={queryClient}>\n <HydrationBoundary state={queryState}>\n <Suspense fallback={null}>\n <OlovaRouter\n routes={routes}\n layouts={wrappedLayouts}\n notFoundPages={notFoundPages}\n />\n </Suspense>\n </HydrationBoundary>\n </QueryClientProvider>\n </StrictMode>\n );\n\n return { html, queryState };\n}\n\n// =============================================================================\n// WORKER EXPORT\n// =============================================================================\n\nexport interface WorkerEnv {\n ASSETS: { fetch: (request: Request | URL) => Promise<Response> };\n}\n\nexport default {\n async fetch(request: Request, env: WorkerEnv): Promise<Response> {\n const url = new URL(request.url);\n const pathname = url.pathname;\n\n // 1. Non-HTML requests → serve static assets directly\n if (!request.headers.get('accept')?.includes('text/html')) {\n return env.ASSETS.fetch(request);\n }\n\n // 2. Check if route has loader (needs SSR)\n const match = matchRoute(pathname);\n const needsSSR = match?.route?.loader;\n\n // 3. No SSR needed → serve pre-built static HTML\n if (!needsSSR) {\n const staticPath = pathname === '/' ? '/index.html' : `${pathname}/index.html`;\n try {\n const staticResponse = await env.ASSETS.fetch(new URL(staticPath, url));\n if (staticResponse.ok) {\n return new Response(staticResponse.body, {\n status: 200,\n headers: { 'Content-Type': 'text/html; charset=utf-8' }\n });\n }\n } catch {}\n \n // Fallback to 404.html\n try {\n const notFoundResponse = await env.ASSETS.fetch(new URL('/404.html', url));\n return new Response(notFoundResponse.body, { \n status: 404, \n headers: { 'Content-Type': 'text/html; charset=utf-8' } \n });\n } catch {}\n \n return new Response('Not Found', { status: 404 });\n }\n\n // 4. Route has loader → run SSR\n let loaderData: Record<string, unknown> | undefined;\n\n try {\n const result = await match.route.loader({\n request,\n params: match.params\n });\n\n if (!(result instanceof Response)) {\n loaderData = result;\n }\n } catch (error) {\n console.error('[Olova] Loader error:', error);\n }\n\n // 5. Render with loader data\n const { html: appHtml, queryState } = await render(pathname, loaderData);\n\n // Build full HTML document\n const html = `<!DOCTYPE html>${appHtml}<script>window.__QUERY_STATE__=${JSON.stringify(queryState)}</script><script type=\"module\" src=\"/assets/_olova/main.js\"></script>`;\n\n return new Response(html, {\n headers: { 'Content-Type': 'text/html; charset=utf-8' }\n });\n }\n};\n\n// Export for SSG builds\nexport { render, matchRoute };\n"]}
|
package/dist/main.cjs
CHANGED
|
@@ -1,43 +1,18 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
require('@/index.css');
|
|
4
|
-
var route_tree = require('@/route.tree');
|
|
5
3
|
var react = require('react');
|
|
6
4
|
var client = require('react-dom/client');
|
|
7
|
-
var
|
|
5
|
+
var virtual_olovaApp = require('virtual:olova-app');
|
|
8
6
|
var jsxRuntime = require('react/jsx-runtime');
|
|
9
7
|
|
|
10
|
-
// main.tsx
|
|
11
|
-
var
|
|
8
|
+
// src/main.tsx
|
|
9
|
+
var wrappedLayouts = virtual_olovaApp.layouts.map((item) => ({
|
|
12
10
|
...item,
|
|
13
|
-
layout: (props) => /* @__PURE__ */ jsxRuntime.jsx(item.layout, { ...props, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
11
|
+
layout: (props) => /* @__PURE__ */ jsxRuntime.jsx(item.layout, { ...props, children: /* @__PURE__ */ jsxRuntime.jsx(virtual_olovaApp.Outlet, {}) })
|
|
14
12
|
}));
|
|
15
13
|
var isBrowser = typeof window !== "undefined" && !undefined.SSR;
|
|
16
|
-
function getOlova() {
|
|
17
|
-
if (typeof globalThis === "undefined") return null;
|
|
18
|
-
return globalThis.$OLOVA || null;
|
|
19
|
-
}
|
|
20
|
-
function getQueryState() {
|
|
21
|
-
const olova = getOlova();
|
|
22
|
-
return olova?.$query?.state || null;
|
|
23
|
-
}
|
|
24
14
|
if (isBrowser) {
|
|
25
|
-
|
|
26
|
-
const olova = getOlova();
|
|
27
|
-
if (olova) {
|
|
28
|
-
console.log("[Olova] Flight hydrated:", Object.keys(olova));
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
const queryState = getQueryState();
|
|
32
|
-
const queryClient = new reactQuery.QueryClient({
|
|
33
|
-
defaultOptions: {
|
|
34
|
-
queries: {
|
|
35
|
-
staleTime: 1e3 * 60 * 5,
|
|
36
|
-
gcTime: 1e3 * 60 * 30
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
});
|
|
40
|
-
client.hydrateRoot(document, /* @__PURE__ */ jsxRuntime.jsx(react.StrictMode, { children: /* @__PURE__ */ jsxRuntime.jsx(reactQuery.QueryClientProvider, { client: queryClient, children: /* @__PURE__ */ jsxRuntime.jsx(reactQuery.HydrationBoundary, { state: queryState || {}, children: /* @__PURE__ */ jsxRuntime.jsx(route_tree.OlovaRouter, { routes: route_tree.routes, layouts, notFoundPages: route_tree.notFoundPages }) }) }) }));
|
|
15
|
+
client.hydrateRoot(document, /* @__PURE__ */ jsxRuntime.jsx(react.StrictMode, { children: /* @__PURE__ */ jsxRuntime.jsx(virtual_olovaApp.OlovaRouter, { routes: virtual_olovaApp.routes, layouts: wrappedLayouts, notFoundPages: virtual_olovaApp.notFoundPages }) }));
|
|
41
16
|
}
|
|
42
17
|
//# sourceMappingURL=main.cjs.map
|
|
43
18
|
//# sourceMappingURL=main.cjs.map
|
package/dist/main.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../main.tsx"],"names":["
|
|
1
|
+
{"version":3,"sources":["../src/main.tsx"],"names":["layouts","jsx","Outlet","hydrateRoot","StrictMode","OlovaRouter","routes","notFoundPages"],"mappings":";;;;;;;;AAMA,IAAM,cAAA,GAAiBA,wBAAA,CAAQ,GAAA,CAAI,CAAC,IAAA,MAAe;AAAA,EACjD,GAAG,IAAA;AAAA,EACH,MAAA,EAAQ,CAAC,KAAA,qBACPC,cAAA,CAAC,IAAA,CAAK,MAAA,EAAL,EAAa,GAAG,KAAA,EACf,QAAA,kBAAAA,cAAA,CAACC,uBAAA,EAAA,EAAO,CAAA,EACV;AAEJ,CAAA,CAAE,CAAA;AAEF,IAAM,YAAY,OAAO,MAAA,KAAW,WAAA,IAAe,CAAE,SAAoB,CAAI,GAAA;AAE7E,IAAI,SAAA,EAAW;AACb,EAAAC,kBAAA,CAAY,QAAA,kBACVF,cAAA,CAACG,gBAAA,EAAA,EACC,QAAA,kBAAAH,cAAA,CAACI,4BAAA,EAAA,UAAYC,yBAAgB,OAAA,EAAS,cAAA,iBAAgBC,8BAAA,EAA8B,CAAA,EACtF,CACD,CAAA;AACH","file":"main.cjs","sourcesContent":["import { StrictMode } from 'react';\r\nimport { hydrateRoot } from 'react-dom/client';\r\n// @ts-expect-error - Virtual module resolved by vite-plugin-olova\r\nimport { layouts, notFoundPages, OlovaRouter, Outlet, routes } from 'virtual:olova-app';\r\n\r\n// Wrapper to support \"children\" prop style layouts (Next.js style)\r\nconst wrappedLayouts = layouts.map((item: any) => ({\r\n ...item,\r\n layout: (props: any) => (\r\n <item.layout {...props}>\r\n <Outlet />\r\n </item.layout>\r\n )\r\n}));\r\n\r\nconst isBrowser = typeof window !== 'undefined' && !(import.meta as any).env.SSR;\r\n\r\nif (isBrowser) {\r\n hydrateRoot(document, (\r\n <StrictMode>\r\n <OlovaRouter routes={routes} layouts={wrappedLayouts} notFoundPages={notFoundPages} />\r\n </StrictMode>\r\n ));\r\n}\r\n"]}
|
package/dist/main.js
CHANGED
|
@@ -1,41 +1,16 @@
|
|
|
1
|
-
import '@/index.css';
|
|
2
|
-
import { layouts as layouts$1, Outlet, OlovaRouter, notFoundPages, routes } from '@/route.tree';
|
|
3
1
|
import { StrictMode } from 'react';
|
|
4
2
|
import { hydrateRoot } from 'react-dom/client';
|
|
5
|
-
import {
|
|
3
|
+
import { layouts, Outlet, OlovaRouter, notFoundPages, routes } from 'virtual:olova-app';
|
|
6
4
|
import { jsx } from 'react/jsx-runtime';
|
|
7
5
|
|
|
8
|
-
// main.tsx
|
|
9
|
-
var
|
|
6
|
+
// src/main.tsx
|
|
7
|
+
var wrappedLayouts = layouts.map((item) => ({
|
|
10
8
|
...item,
|
|
11
9
|
layout: (props) => /* @__PURE__ */ jsx(item.layout, { ...props, children: /* @__PURE__ */ jsx(Outlet, {}) })
|
|
12
10
|
}));
|
|
13
11
|
var isBrowser = typeof window !== "undefined" && !import.meta.env.SSR;
|
|
14
|
-
function getOlova() {
|
|
15
|
-
if (typeof globalThis === "undefined") return null;
|
|
16
|
-
return globalThis.$OLOVA || null;
|
|
17
|
-
}
|
|
18
|
-
function getQueryState() {
|
|
19
|
-
const olova = getOlova();
|
|
20
|
-
return olova?.$query?.state || null;
|
|
21
|
-
}
|
|
22
12
|
if (isBrowser) {
|
|
23
|
-
|
|
24
|
-
const olova = getOlova();
|
|
25
|
-
if (olova) {
|
|
26
|
-
console.log("[Olova] Flight hydrated:", Object.keys(olova));
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
const queryState = getQueryState();
|
|
30
|
-
const queryClient = new QueryClient({
|
|
31
|
-
defaultOptions: {
|
|
32
|
-
queries: {
|
|
33
|
-
staleTime: 1e3 * 60 * 5,
|
|
34
|
-
gcTime: 1e3 * 60 * 30
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
});
|
|
38
|
-
hydrateRoot(document, /* @__PURE__ */ jsx(StrictMode, { children: /* @__PURE__ */ jsx(QueryClientProvider, { client: queryClient, children: /* @__PURE__ */ jsx(HydrationBoundary, { state: queryState || {}, children: /* @__PURE__ */ jsx(OlovaRouter, { routes, layouts, notFoundPages }) }) }) }));
|
|
13
|
+
hydrateRoot(document, /* @__PURE__ */ jsx(StrictMode, { children: /* @__PURE__ */ jsx(OlovaRouter, { routes, layouts: wrappedLayouts, notFoundPages }) }));
|
|
39
14
|
}
|
|
40
15
|
//# sourceMappingURL=main.js.map
|
|
41
16
|
//# sourceMappingURL=main.js.map
|
package/dist/main.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../main.tsx"],"names":[
|
|
1
|
+
{"version":3,"sources":["../src/main.tsx"],"names":[],"mappings":";;;;;;AAMA,IAAM,cAAA,GAAiB,OAAA,CAAQ,GAAA,CAAI,CAAC,IAAA,MAAe;AAAA,EACjD,GAAG,IAAA;AAAA,EACH,MAAA,EAAQ,CAAC,KAAA,qBACP,GAAA,CAAC,IAAA,CAAK,MAAA,EAAL,EAAa,GAAG,KAAA,EACf,QAAA,kBAAA,GAAA,CAAC,MAAA,EAAA,EAAO,CAAA,EACV;AAEJ,CAAA,CAAE,CAAA;AAEF,IAAM,YAAY,OAAO,MAAA,KAAW,WAAA,IAAe,CAAE,YAAoB,GAAA,CAAI,GAAA;AAE7E,IAAI,SAAA,EAAW;AACb,EAAA,WAAA,CAAY,QAAA,kBACV,GAAA,CAAC,UAAA,EAAA,EACC,QAAA,kBAAA,GAAA,CAAC,WAAA,EAAA,EAAY,QAAgB,OAAA,EAAS,cAAA,EAAgB,aAAA,EAA8B,CAAA,EACtF,CACD,CAAA;AACH","file":"main.js","sourcesContent":["import { StrictMode } from 'react';\r\nimport { hydrateRoot } from 'react-dom/client';\r\n// @ts-expect-error - Virtual module resolved by vite-plugin-olova\r\nimport { layouts, notFoundPages, OlovaRouter, Outlet, routes } from 'virtual:olova-app';\r\n\r\n// Wrapper to support \"children\" prop style layouts (Next.js style)\r\nconst wrappedLayouts = layouts.map((item: any) => ({\r\n ...item,\r\n layout: (props: any) => (\r\n <item.layout {...props}>\r\n <Outlet />\r\n </item.layout>\r\n )\r\n}));\r\n\r\nconst isBrowser = typeof window !== 'undefined' && !(import.meta as any).env.SSR;\r\n\r\nif (isBrowser) {\r\n hydrateRoot(document, (\r\n <StrictMode>\r\n <OlovaRouter routes={routes} layouts={wrappedLayouts} notFoundPages={notFoundPages} />\r\n </StrictMode>\r\n ));\r\n}\r\n"]}
|
package/dist/olova.cjs
CHANGED
|
@@ -19,7 +19,7 @@ var mdx__default = /*#__PURE__*/_interopDefault(mdx);
|
|
|
19
19
|
var pc__default = /*#__PURE__*/_interopDefault(pc);
|
|
20
20
|
var zlib__default = /*#__PURE__*/_interopDefault(zlib);
|
|
21
21
|
|
|
22
|
-
// node_modules
|
|
22
|
+
// node_modules/tsup/assets/cjs_shims.js
|
|
23
23
|
var getImportMetaUrl = () => typeof document === "undefined" ? new URL(`file:${__filename}`).href : document.currentScript && document.currentScript.tagName.toUpperCase() === "SCRIPT" ? document.currentScript.src : new URL("main.js", document.baseURI).href;
|
|
24
24
|
var importMetaUrl = /* @__PURE__ */ getImportMetaUrl();
|
|
25
25
|
function extractBalancedBraces(content, startIndex) {
|
|
@@ -206,7 +206,7 @@ function generateRouteTree(routes, notFoundPages, layouts, loadingPages, errorPa
|
|
|
206
206
|
};
|
|
207
207
|
const routeNames = [];
|
|
208
208
|
const routeImports = routes.map((route) => {
|
|
209
|
-
const relativePath = stripImportExtension("./" + path5__default.default.relative(srcDir, route.component).replace(/\\/g, "/"));
|
|
209
|
+
const relativePath = stripImportExtension("./app/" + path5__default.default.relative(srcDir, route.component).replace(/\\/g, "/"));
|
|
210
210
|
const moduleName = getRouteName2(route.component, "RouteModule");
|
|
211
211
|
const lazyName = getRouteName2(route.component, "Route");
|
|
212
212
|
routeNames.push({ moduleName, lazyName, eager: true });
|
|
@@ -214,7 +214,7 @@ function generateRouteTree(routes, notFoundPages, layouts, loadingPages, errorPa
|
|
|
214
214
|
}).join("\n");
|
|
215
215
|
const notFoundNames = [];
|
|
216
216
|
const notFoundImports = notFoundPages.map((nf) => {
|
|
217
|
-
const relativePath = stripImportExtension("./" + path5__default.default.relative(srcDir, nf.filePath).replace(/\\/g, "/"));
|
|
217
|
+
const relativePath = stripImportExtension("./app/" + path5__default.default.relative(srcDir, nf.filePath).replace(/\\/g, "/"));
|
|
218
218
|
if (nf.hasMetadata) {
|
|
219
219
|
const moduleName = getRouteName2(nf.filePath, "NotFoundModule");
|
|
220
220
|
notFoundNames.push(moduleName);
|
|
@@ -228,7 +228,7 @@ function generateRouteTree(routes, notFoundPages, layouts, loadingPages, errorPa
|
|
|
228
228
|
}).join("\n");
|
|
229
229
|
const layoutNames = [];
|
|
230
230
|
const layoutImports = layouts.map((layout) => {
|
|
231
|
-
const relativePath = stripImportExtension("./" + path5__default.default.relative(srcDir, layout.filePath).replace(/\\/g, "/"));
|
|
231
|
+
const relativePath = stripImportExtension("./app/" + path5__default.default.relative(srcDir, layout.filePath).replace(/\\/g, "/"));
|
|
232
232
|
if (layout.hasMetadata) {
|
|
233
233
|
const moduleName = getRouteName2(layout.filePath, "LayoutModule");
|
|
234
234
|
layoutNames.push(moduleName);
|
|
@@ -242,7 +242,7 @@ function generateRouteTree(routes, notFoundPages, layouts, loadingPages, errorPa
|
|
|
242
242
|
}).join("\n");
|
|
243
243
|
const loadingNames = [];
|
|
244
244
|
const loadingImports = loadingPages.map((lp) => {
|
|
245
|
-
const relativePath = stripImportExtension("./" + path5__default.default.relative(srcDir, lp.filePath).replace(/\\/g, "/"));
|
|
245
|
+
const relativePath = stripImportExtension("./app/" + path5__default.default.relative(srcDir, lp.filePath).replace(/\\/g, "/"));
|
|
246
246
|
const importName = getRouteName2(lp.filePath, "Loading");
|
|
247
247
|
loadingNames.push(importName);
|
|
248
248
|
if (lp.hasDefault) return `import ${importName} from '${relativePath}';`;
|
|
@@ -251,7 +251,7 @@ function generateRouteTree(routes, notFoundPages, layouts, loadingPages, errorPa
|
|
|
251
251
|
}).join("\n");
|
|
252
252
|
const errorNames = [];
|
|
253
253
|
const errorImports = errorPages.map((ep) => {
|
|
254
|
-
const relativePath = stripImportExtension("./" + path5__default.default.relative(srcDir, ep.filePath).replace(/\\/g, "/"));
|
|
254
|
+
const relativePath = stripImportExtension("./app/" + path5__default.default.relative(srcDir, ep.filePath).replace(/\\/g, "/"));
|
|
255
255
|
const importName = getRouteName2(ep.filePath, "Error");
|
|
256
256
|
errorNames.push(importName);
|
|
257
257
|
if (ep.hasDefault) return `import ${importName} from '${relativePath}';`;
|
|
@@ -260,7 +260,7 @@ function generateRouteTree(routes, notFoundPages, layouts, loadingPages, errorPa
|
|
|
260
260
|
}).join("\n");
|
|
261
261
|
const middlewareNames = [];
|
|
262
262
|
const middlewareImports = middlewares.map((mw) => {
|
|
263
|
-
const relativePath = stripImportExtension("./" + path5__default.default.relative(srcDir, mw.filePath).replace(/\\/g, "/"));
|
|
263
|
+
const relativePath = stripImportExtension("./app/" + path5__default.default.relative(srcDir, mw.filePath).replace(/\\/g, "/"));
|
|
264
264
|
const importName = getRouteName2(mw.filePath, "Middleware");
|
|
265
265
|
middlewareNames.push(importName);
|
|
266
266
|
if (mw.hasDefault) return `import ${importName} from '${relativePath}';`;
|
|
@@ -490,14 +490,12 @@ export type {
|
|
|
490
490
|
`;
|
|
491
491
|
}
|
|
492
492
|
var RESERVED_NAMES = /* @__PURE__ */ new Set([
|
|
493
|
-
"
|
|
493
|
+
"page",
|
|
494
494
|
"layout",
|
|
495
495
|
"loading",
|
|
496
496
|
"error",
|
|
497
|
-
"
|
|
497
|
+
"not-found",
|
|
498
498
|
"middleware",
|
|
499
|
-
"App",
|
|
500
|
-
"main",
|
|
501
499
|
"route.tree"
|
|
502
500
|
]);
|
|
503
501
|
function scanDirectory(dir, rootDir, extensions, routes, notFoundPages, layouts, loadingPages, errorPages, middlewares, isRoot = false) {
|
|
@@ -539,15 +537,13 @@ function scanDirectory(dir, rootDir, extensions, routes, notFoundPages, layouts,
|
|
|
539
537
|
path: isRoot ? "/" : routePath,
|
|
540
538
|
filePath: fullPath
|
|
541
539
|
});
|
|
542
|
-
} else if (baseName === "404" && extensions.includes(ext)) {
|
|
540
|
+
} else if ((baseName === "not-found" || baseName === "404") && extensions.includes(ext)) {
|
|
543
541
|
const relativeParts = path5__default.default.relative(rootDir, dir).split(path5__default.default.sep).filter(Boolean);
|
|
544
542
|
const filteredParts = relativeParts.filter((p) => !isRouteGroup(p));
|
|
545
543
|
const pathPrefix = isRoot ? "" : "/" + filteredParts.join("/");
|
|
546
544
|
notFoundPages.push({ pathPrefix: pathPrefix || "", filePath: fullPath });
|
|
547
|
-
} else if (
|
|
548
|
-
|
|
549
|
-
} else if (!isRoot && baseName === "index" && extensions.includes(ext)) {
|
|
550
|
-
const relativePath = path5__default.default.relative(rootDir, path5__default.default.dirname(fullPath));
|
|
545
|
+
} else if (baseName === "page" && extensions.includes(ext)) {
|
|
546
|
+
const relativePath = path5__default.default.relative(rootDir, dir);
|
|
551
547
|
const { routePath, params } = pathToRoute(relativePath, path5__default.default.sep);
|
|
552
548
|
routes.push({ path: routePath, filePath: fullPath, isDynamic: params.length > 0, params });
|
|
553
549
|
} else if (!RESERVED_NAMES.has(baseName) && !baseName.endsWith(".d") && !baseName.startsWith("_") && extensions.includes(ext)) {
|
|
@@ -582,7 +578,7 @@ function scanRoutes(rootDir, extensions) {
|
|
|
582
578
|
|
|
583
579
|
// src/plugin/index.ts
|
|
584
580
|
function olovaRouter(options = {}) {
|
|
585
|
-
const rootDir = options.rootDir || "src";
|
|
581
|
+
const rootDir = options.rootDir || "src/app";
|
|
586
582
|
const extensions = options.extensions || [".tsx", ".ts", ".mdx"];
|
|
587
583
|
const packageName = options.packageName || "olovastart";
|
|
588
584
|
let config;
|
|
@@ -661,7 +657,7 @@ function olovaRouter(options = {}) {
|
|
|
661
657
|
};
|
|
662
658
|
});
|
|
663
659
|
const content = generateRouteTree(routeConfigs, notFoundConfigs, layoutConfigs, loadingConfigs, errorConfigs, middlewareConfigs, absoluteRootDir, packageName);
|
|
664
|
-
const treePath = path5__default.default.resolve(
|
|
660
|
+
const treePath = path5__default.default.resolve(config.root, "src", "route.tree.ts");
|
|
665
661
|
const existing = fs3__default.default.existsSync(treePath) ? fs3__default.default.readFileSync(treePath, "utf-8") : "";
|
|
666
662
|
if (existing !== content) {
|
|
667
663
|
fs3__default.default.writeFileSync(treePath, content);
|
|
@@ -675,9 +671,9 @@ function olovaRouter(options = {}) {
|
|
|
675
671
|
if (filename.includes("route.tree.ts")) return;
|
|
676
672
|
const ext = path5__default.default.extname(filename);
|
|
677
673
|
const isConfiguredExtension = extensions.includes(ext);
|
|
678
|
-
const
|
|
679
|
-
const isAppFile = filename.includes("App") && isConfiguredExtension;
|
|
674
|
+
const isPageFile = filename.includes("page") && isConfiguredExtension;
|
|
680
675
|
const is404File = filename.includes("404") && isConfiguredExtension;
|
|
676
|
+
const isNotFoundFile = filename.includes("not-found") && isConfiguredExtension;
|
|
681
677
|
const isLayoutFile = filename.includes("layout") && isConfiguredExtension;
|
|
682
678
|
const isLoadingFile = filename.includes("loading") && isConfiguredExtension;
|
|
683
679
|
const isErrorFile = filename.includes("error") && isConfiguredExtension;
|
|
@@ -685,8 +681,8 @@ function olovaRouter(options = {}) {
|
|
|
685
681
|
const isDirectory = !filename.includes(".");
|
|
686
682
|
const isDynamicSegment = filename.includes("[");
|
|
687
683
|
const isRenameEvent = eventType === "rename";
|
|
688
|
-
if (
|
|
689
|
-
if (
|
|
684
|
+
if (isPageFile || is404File || isNotFoundFile || isLayoutFile || isLoadingFile || isErrorFile || isMiddlewareFile || isDirectory || isDynamicSegment || isRenameEvent) {
|
|
685
|
+
if (isPageFile && filename) {
|
|
690
686
|
const fullPath = path5__default.default.join(absoluteRootDir, filename);
|
|
691
687
|
if (fs3__default.default.existsSync(fullPath)) {
|
|
692
688
|
const stat = fs3__default.default.statSync(fullPath);
|