diff --git a/packages/nano-remix/CACHING.md b/packages/nano-remix/CACHING.md deleted file mode 100644 index 56d9c65..0000000 --- a/packages/nano-remix/CACHING.md +++ /dev/null @@ -1,96 +0,0 @@ -# Build Caching in Nano-Remix - -The nano-remix package now includes intelligent build caching to improve performance by avoiding unnecessary rebuilds. - -## How it Works - -The caching system tracks: - -- File modification timestamps -- Last build times -- Output file existence - -Routes are only rebuilt when: - -1. Source files have been modified since last build -2. Output files don't exist -3. Cache is explicitly disabled or forced - -## Usage Examples - -### Development Mode (with caching) - -```typescript -import { nanoRemix } from "@workshop/nano-remix" - -// Default behavior - uses intelligent caching -export default { - fetch: (req: Request) => nanoRemix(req), -} -``` - -### Development Mode (without caching) - -```typescript -import { nanoRemix } from "@workshop/nano-remix" - -// Disable caching for development if you want immediate rebuilds -export default { - fetch: (req: Request) => - nanoRemix(req, { - disableCache: true, - }), -} -``` - -### Production Setup - -```typescript -import { nanoRemix, preloadAllRoutes } from "@workshop/nano-remix" - -// Pre-build all routes on startup for production -const server = { - async fetch(req: Request) { - return nanoRemix(req) - }, -} - -// Build all routes once on server startup -await preloadAllRoutes() - -export default server -``` - -### Cache Management - -```typescript -import { clearBuildCache, getBuildCacheStats } from "@workshop/nano-remix" - -// Clear cache (useful for development) -clearBuildCache() - -// Get cache statistics for monitoring -const stats = getBuildCacheStats() -console.log("Cache entries:", stats.length) -``` - -## Configuration Options - -```typescript -type Options = { - routesDir?: string // Custom routes directory - distDir?: string // Custom output directory - disableCache?: boolean // Disable caching entirely -} -``` - -## Performance Impact - -With caching enabled: - -- ✅ First request to a route: Normal build time -- ✅ Subsequent requests: Near-instant response (no rebuild) -- ✅ File changes: Automatic rebuild on next request -- ✅ Production: Pre-build all routes once - -This should significantly improve your server performance, especially for routes that haven't changed! diff --git a/packages/nano-remix/src/buildRoute.ts b/packages/nano-remix/src/buildRoute.ts index 8c9c09b..d45eedb 100644 --- a/packages/nano-remix/src/buildRoute.ts +++ b/packages/nano-remix/src/buildRoute.ts @@ -1,4 +1,4 @@ -import { join, dirname } from "node:path" +import { join } from "node:path" type BuildRouteOptions = { distDir: string @@ -7,6 +7,7 @@ type BuildRouteOptions = { force?: boolean } +const cache = new Map() export const buildRoute = async ({ distDir, routeName, filepath, force = false }: BuildRouteOptions) => { if (!force && !(await needsBuild(routeName, distDir))) { return @@ -25,10 +26,9 @@ export const buildRoute = async ({ distDir, routeName, filepath, force = false } if (exitCode !== 0) { const stderr = await new Response(proc.stderr).text() throw new Error(`Build process failed with exit code ${exitCode}: ${stderr}`) + } else { + cache.set(distDir + routeName, true) } - - const stdout = await new Response(proc.stdout).text() - console.log(stdout) } const needsBuild = async (routeName: string, distDir: string) => { @@ -38,8 +38,10 @@ const needsBuild = async (routeName: string, distDir: string) => { try { const outputPath = join(distDir, routeName + ".js") + const exists = await Bun.file(outputPath).exists() + const inCache = cache.get(distDir + routeName) - return !(await Bun.file(outputPath).exists()) + return !exists || !inCache } catch (error) { return true } diff --git a/packages/nano-remix/src/main.ts b/packages/nano-remix/src/main.ts index 4dfab00..12d3e57 100644 --- a/packages/nano-remix/src/main.ts +++ b/packages/nano-remix/src/main.ts @@ -7,10 +7,7 @@ export type Loader = ( ) => Promise | Data export type LoaderProps = T extends Loader ? Awaited : never -export type Action = ( - req: Request, - params: Record -) => Promise +export type Action = (req: Request, params: any) => Promise export type Head = { title?: string diff --git a/packages/nano-remix/src/nanoRemix.ts b/packages/nano-remix/src/nanoRemix.ts index 26928db..34cad47 100644 --- a/packages/nano-remix/src/nanoRemix.ts +++ b/packages/nano-remix/src/nanoRemix.ts @@ -7,7 +7,6 @@ type Options = { routesDir?: string distDir?: string publicDir?: string - disableCache?: boolean } let defaultPublicDir: string | undefined @@ -54,7 +53,7 @@ export const nanoRemix = async (req: Request, options: Options = {}) => { // If the the route includes an extension it is a static file that we serve from the distDir if (!ext) { - await buildRoute({ distDir, routeName, filepath: route.filePath, force: options.disableCache }) + await buildRoute({ distDir, routeName, filepath: route.filePath }) return await renderServer(req, route) } else { const file = Bun.file(join(distDir, routeName + ext)) diff --git a/packages/todo/src/routes/todos/[id].tsx b/packages/todo/src/routes/todos/[id].tsx index 13ad305..a7c40a5 100644 --- a/packages/todo/src/routes/todos/[id].tsx +++ b/packages/todo/src/routes/todos/[id].tsx @@ -1,7 +1,7 @@ import KV from "@workshop/shared/kv" import { submitAction, useAction, type Head, type LoaderProps } from "@workshop/nano-remix" import { useCallback } from "hono/jsx/dom" -import { TodoEditor } from "@workshop/todo" +import { TodoEditor } from "../../todoEditor" import { debounce } from "@workshop/shared/utils" import "../../index.css"