@flight-framework/core 0.2.2 → 0.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/server/index.ts"],"names":[],"mappings":"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","file":"chunk-6LYV4VQX.js","sourcesContent":["/**\r\n * Flight Server - Main server factory\r\n * \r\n * Creates a Flight server instance that handles routing, middleware, and rendering.\r\n * This is the primary entry point for Flight applications.\r\n * \r\n * @example\r\n * ```typescript\r\n * import { createServer } from '@flight-framework/core';\r\n * \r\n * const server = createServer();\r\n * \r\n * server.get('/api/health', () => Response.json({ status: 'ok' }));\r\n * \r\n * // Just works! Auto-detects Node.js, Bun, or Deno\r\n * server.listen(3000);\r\n * ```\r\n */\r\n\r\nimport { createRouter, type Router } from '../router/index.js';\r\nimport {\r\n createMiddlewareChain,\r\n createContextFromRequest,\r\n createResponseFromContext,\r\n type MiddlewareChain,\r\n type Middleware,\r\n} from '../middleware/index.js';\r\nimport { type FlightConfig, type FlightUserConfig, resolveConfig } from '../config/index.js';\r\nimport type { FlightAdapter } from '../adapters/index.js';\r\n\r\n// ============================================================================\r\n// Types\r\n// ============================================================================\r\n\r\n/** Route handler function signature */\r\nexport type RouteHandler = (context: RouteHandlerContext) => Promise<Response> | Response;\r\n\r\n/** Context passed to route handlers */\r\nexport interface RouteHandlerContext {\r\n /** The incoming request */\r\n request: Request;\r\n /** URL parameters from routing */\r\n params: Record<string, string | string[]>;\r\n /** Query parameters */\r\n query: URLSearchParams;\r\n /** Parsed URL */\r\n url: URL;\r\n /** Local data from middleware */\r\n locals: Record<string, unknown>;\r\n /** Database instance (if configured) */\r\n db?: unknown;\r\n /** Auth instance (if configured) */\r\n auth?: unknown;\r\n /** Email instance (if configured) */\r\n email?: unknown;\r\n}\r\n\r\n/** Server options */\r\nexport interface ServerOptions {\r\n /** Server configuration */\r\n config?: FlightUserConfig;\r\n /** Deployment adapter */\r\n adapter?: FlightAdapter;\r\n /** Database instance */\r\n db?: unknown;\r\n /** Auth instance */\r\n auth?: unknown;\r\n /** Email instance */\r\n email?: unknown;\r\n}\r\n\r\n/** Route definition for the server */\r\nexport interface ServerRoute {\r\n /** HTTP method (GET, POST, etc.) */\r\n method: string | string[];\r\n /** Route path pattern */\r\n path: string;\r\n /** Route handler */\r\n handler: RouteHandler;\r\n}\r\n\r\n/** Listen options */\r\nexport interface ListenOptions {\r\n /** Port to listen on (default: 3000) */\r\n port?: number;\r\n /** Hostname to bind to (default: 'localhost') */\r\n hostname?: string;\r\n /** Callback when server starts */\r\n onListen?: (info: { port: number; hostname: string }) => void;\r\n}\r\n\r\n/** Flight Server instance */\r\nexport interface FlightServer {\r\n /** Add a route */\r\n route(method: string | string[], path: string, handler: RouteHandler): FlightServer;\r\n\r\n /** Convenience methods for common HTTP methods */\r\n get(path: string, handler: RouteHandler): FlightServer;\r\n post(path: string, handler: RouteHandler): FlightServer;\r\n put(path: string, handler: RouteHandler): FlightServer;\r\n delete(path: string, handler: RouteHandler): FlightServer;\r\n patch(path: string, handler: RouteHandler): FlightServer;\r\n\r\n /** Add middleware */\r\n use(middleware: Middleware): FlightServer;\r\n use(path: string, middleware: Middleware): FlightServer;\r\n\r\n /** Handle incoming request (Web standard Request/Response) */\r\n handle(request: Request): Promise<Response>;\r\n\r\n /** \r\n * Start the HTTP server\r\n * Auto-detects runtime: Node.js, Bun, or Deno\r\n */\r\n listen(port?: number | ListenOptions): Promise<void>;\r\n\r\n /** Fetch handler for Bun.serve() and Deno.serve() */\r\n fetch(request: Request): Promise<Response>;\r\n\r\n /** Get the resolved configuration */\r\n readonly config: FlightConfig;\r\n\r\n /** Get the router instance */\r\n readonly router: Router<RouteHandler>;\r\n\r\n /** Get the middleware chain */\r\n readonly middleware: MiddlewareChain;\r\n}\r\n\r\n// ============================================================================\r\n// Runtime Detection\r\n// ============================================================================\r\n\r\ntype Runtime = 'node' | 'bun' | 'deno' | 'unknown';\r\n\r\nfunction detectRuntime(): Runtime {\r\n // @ts-expect-error - Bun global\r\n if (typeof Bun !== 'undefined') return 'bun';\r\n // @ts-expect-error - Deno global \r\n if (typeof Deno !== 'undefined') return 'deno';\r\n if (typeof process !== 'undefined' && process.versions?.node) return 'node';\r\n return 'unknown';\r\n}\r\n\r\n// ============================================================================\r\n// Server Implementation\r\n// ============================================================================\r\n\r\ninterface RouteEntry {\r\n methods: Set<string>;\r\n handler: RouteHandler;\r\n}\r\n\r\n/**\r\n * Create a new Flight server instance\r\n * \r\n * @example\r\n * ```typescript\r\n * import { createServer } from '@flight-framework/core';\r\n * \r\n * const server = createServer();\r\n * \r\n * server.get('/api/users', async ({ db }) => {\r\n * const users = await db.query('SELECT * FROM users');\r\n * return Response.json(users);\r\n * });\r\n * \r\n * // Works on Node.js, Bun, and Deno!\r\n * server.listen(3000);\r\n * ```\r\n */\r\nexport function createServer(options: ServerOptions = {}): FlightServer {\r\n const config = resolveConfig(options.config ?? {});\r\n const router = createRouter<RouteEntry>();\r\n const middlewareChain = createMiddlewareChain();\r\n\r\n // Store dependencies\r\n const deps = {\r\n db: options.db,\r\n auth: options.auth,\r\n email: options.email,\r\n };\r\n\r\n function addRoute(method: string | string[], path: string, handler: RouteHandler): FlightServer {\r\n const methods = Array.isArray(method) ? method : [method];\r\n const methodSet = new Set(methods.map(m => m.toUpperCase()));\r\n\r\n // Check if route already exists\r\n const existingMatch = router.match(path);\r\n if (existingMatch && existingMatch.route.path === path) {\r\n // Merge methods\r\n for (const m of methodSet) {\r\n existingMatch.route.handler.methods.add(m);\r\n }\r\n existingMatch.route.handler.handler = handler;\r\n } else {\r\n router.add({\r\n path,\r\n handler: { methods: methodSet, handler },\r\n });\r\n }\r\n\r\n return server;\r\n }\r\n\r\n function useMiddleware(\r\n pathOrMiddleware: string | Middleware,\r\n maybeMiddleware?: Middleware\r\n ): FlightServer {\r\n if (typeof pathOrMiddleware === 'string' && maybeMiddleware) {\r\n middlewareChain.use(pathOrMiddleware, maybeMiddleware);\r\n } else if (typeof pathOrMiddleware === 'function') {\r\n middlewareChain.use(pathOrMiddleware);\r\n }\r\n return server;\r\n }\r\n\r\n async function handle(request: Request): Promise<Response> {\r\n const url = new URL(request.url);\r\n const method = request.method.toUpperCase();\r\n\r\n // Run middleware\r\n const ctx = createContextFromRequest(request);\r\n await middlewareChain.execute(ctx);\r\n\r\n // If middleware already set a response, return it\r\n if (ctx.responseBody !== undefined) {\r\n return createResponseFromContext(ctx);\r\n }\r\n\r\n // Match route\r\n const match = router.match(url.pathname);\r\n if (!match) {\r\n return new Response('Not Found', { status: 404 });\r\n }\r\n\r\n // Check method\r\n if (!match.route.handler.methods.has(method) && !match.route.handler.methods.has('*')) {\r\n return new Response('Method Not Allowed', { status: 405 });\r\n }\r\n\r\n // Build handler context\r\n const handlerContext: RouteHandlerContext = {\r\n request,\r\n params: match.params,\r\n query: url.searchParams,\r\n url,\r\n locals: ctx.locals,\r\n ...deps,\r\n };\r\n\r\n try {\r\n return await match.route.handler.handler(handlerContext);\r\n } catch (error) {\r\n console.error('Route handler error:', error);\r\n return new Response('Internal Server Error', { status: 500 });\r\n }\r\n }\r\n\r\n /**\r\n * Start the HTTP server\r\n * Auto-detects the runtime and uses the appropriate server\r\n */\r\n async function listen(portOrOptions?: number | ListenOptions): Promise<void> {\r\n const opts: ListenOptions = typeof portOrOptions === 'number'\r\n ? { port: portOrOptions }\r\n : portOrOptions ?? {};\r\n\r\n const port = opts.port ?? config.dev.port ?? 3000;\r\n const hostname = opts.hostname ?? 'localhost';\r\n\r\n // Check for custom adapter first\r\n const adapter = options.adapter ?? config.adapter;\r\n if (adapter?.listen) {\r\n await adapter.listen(server, port);\r\n return;\r\n }\r\n\r\n const runtime = detectRuntime();\r\n\r\n switch (runtime) {\r\n case 'bun':\r\n await startBunServer(port, hostname, opts.onListen);\r\n break;\r\n case 'deno':\r\n await startDenoServer(port, hostname, opts.onListen);\r\n break;\r\n case 'node':\r\n default:\r\n await startNodeServer(port, hostname, opts.onListen);\r\n break;\r\n }\r\n }\r\n\r\n /**\r\n * Start Node.js HTTP server\r\n */\r\n async function startNodeServer(port: number, hostname: string, onListen?: ListenOptions['onListen']): Promise<void> {\r\n const { createServer: createHttpServer } = await import('node:http');\r\n\r\n const httpServer = createHttpServer(async (req, res) => {\r\n const url = new URL(req.url || '/', `http://${hostname}:${port}`);\r\n\r\n // Build headers\r\n const headers = new Headers();\r\n for (const [key, value] of Object.entries(req.headers)) {\r\n if (value) {\r\n const headerValue = Array.isArray(value) ? value[0] : value;\r\n if (headerValue) headers.set(key, headerValue);\r\n }\r\n }\r\n\r\n // Read body for POST/PUT/PATCH\r\n let body: string | undefined;\r\n if (['POST', 'PUT', 'PATCH'].includes(req.method || '')) {\r\n body = await new Promise<string>((resolve) => {\r\n let data = '';\r\n req.on('data', chunk => data += chunk);\r\n req.on('end', () => resolve(data));\r\n });\r\n }\r\n\r\n const request = new Request(url.toString(), {\r\n method: req.method,\r\n headers,\r\n body: body || undefined,\r\n });\r\n\r\n try {\r\n const response = await handle(request);\r\n\r\n res.statusCode = response.status;\r\n response.headers.forEach((value, key) => {\r\n res.setHeader(key, value);\r\n });\r\n\r\n const responseBody = await response.text();\r\n res.end(responseBody);\r\n } catch (error) {\r\n console.error('Server error:', error);\r\n res.statusCode = 500;\r\n res.setHeader('Content-Type', 'application/json');\r\n res.end(JSON.stringify({ error: 'Internal Server Error' }));\r\n }\r\n });\r\n\r\n return new Promise((resolve) => {\r\n httpServer.listen(port, hostname, () => {\r\n const info = { port, hostname };\r\n if (onListen) {\r\n onListen(info);\r\n } else {\r\n console.log(`\r\n╔═══════════════════════════════════════════════════════════╗\r\n║ Flight Server (Node.js) ║\r\n╠═══════════════════════════════════════════════════════════╣\r\n║ Server: http://${hostname}:${port.toString().padEnd(37)}║\r\n╚═══════════════════════════════════════════════════════════╝\r\n`);\r\n }\r\n resolve();\r\n });\r\n });\r\n }\r\n\r\n /**\r\n * Start Bun server\r\n */\r\n async function startBunServer(port: number, hostname: string, onListen?: ListenOptions['onListen']): Promise<void> {\r\n // @ts-expect-error - Bun types\r\n Bun.serve({\r\n port,\r\n hostname,\r\n fetch: handle,\r\n });\r\n\r\n const info = { port, hostname };\r\n if (onListen) {\r\n onListen(info);\r\n } else {\r\n console.log(`\r\n╔═══════════════════════════════════════════════════════════╗\r\n║ Flight Server (Bun) ║\r\n╠═══════════════════════════════════════════════════════════╣\r\n║ Server: http://${hostname}:${port.toString().padEnd(37)}║\r\n╚═══════════════════════════════════════════════════════════╝\r\n`);\r\n }\r\n }\r\n\r\n /**\r\n * Start Deno server\r\n */\r\n async function startDenoServer(port: number, hostname: string, onListen?: ListenOptions['onListen']): Promise<void> {\r\n // @ts-expect-error - Deno types\r\n Deno.serve({ port, hostname }, handle);\r\n\r\n const info = { port, hostname };\r\n if (onListen) {\r\n onListen(info);\r\n } else {\r\n console.log(`\r\n╔═══════════════════════════════════════════════════════════╗\r\n║ Flight Server (Deno) ║\r\n╠═══════════════════════════════════════════════════════════╣\r\n║ Server: http://${hostname}:${port.toString().padEnd(37)}║\r\n╚═══════════════════════════════════════════════════════════╝\r\n`);\r\n }\r\n }\r\n\r\n const server: FlightServer = {\r\n route: addRoute,\r\n get: (path, handler) => addRoute('GET', path, handler),\r\n post: (path, handler) => addRoute('POST', path, handler),\r\n put: (path, handler) => addRoute('PUT', path, handler),\r\n delete: (path, handler) => addRoute('DELETE', path, handler),\r\n patch: (path, handler) => addRoute('PATCH', path, handler),\r\n use: useMiddleware as FlightServer['use'],\r\n handle,\r\n listen,\r\n fetch: handle, // Alias for Bun/Deno compatibility\r\n get config() { return config; },\r\n get router() { return router as unknown as Router<RouteHandler>; },\r\n get middleware() { return middlewareChain; },\r\n };\r\n\r\n return server;\r\n}\r\n\r\n// ============================================================================\r\n// Helper Exports\r\n// ============================================================================\r\n\r\n/** Type guard to check if an object is a FlightServer */\r\nexport function isFlightServer(obj: unknown): obj is FlightServer {\r\n return (\r\n typeof obj === 'object' &&\r\n obj !== null &&\r\n 'handle' in obj &&\r\n 'route' in obj &&\r\n typeof (obj as FlightServer).handle === 'function'\r\n );\r\n}\r\n\r\n/** Get current runtime */\r\nexport function getRuntime(): Runtime {\r\n return detectRuntime();\r\n}\r\n\r\n"]}
1
+ {"version":3,"sources":["../src/server/index.ts"],"names":[],"mappings":"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","file":"chunk-VOBQDQKX.js","sourcesContent":["/**\r\n * Flight Server - Main server factory\r\n * \r\n * Creates a Flight server instance that handles routing, middleware, and rendering.\r\n * This is the primary entry point for Flight applications.\r\n * \r\n * @example\r\n * ```typescript\r\n * import { createServer } from '@flight-framework/core';\r\n * \r\n * const server = createServer();\r\n * \r\n * server.get('/api/health', () => Response.json({ status: 'ok' }));\r\n * \r\n * // Just works! Auto-detects Node.js, Bun, or Deno\r\n * server.listen(3000);\r\n * ```\r\n */\r\n\r\nimport { createRouter, type Router } from '../router/index.js';\r\nimport {\r\n createMiddlewareChain,\r\n createContextFromRequest,\r\n createResponseFromContext,\r\n type MiddlewareChain,\r\n type Middleware,\r\n} from '../middleware/index.js';\r\nimport { type FlightConfig, type FlightUserConfig, resolveConfig } from '../config/index.js';\r\nimport type { FlightAdapter } from '../adapters/index.js';\r\n\r\n// ============================================================================\r\n// Types\r\n// ============================================================================\r\n\r\n/** Route handler function signature */\r\nexport type RouteHandler = (context: RouteHandlerContext) => Promise<Response> | Response;\r\n\r\n/** Context passed to route handlers */\r\nexport interface RouteHandlerContext {\r\n /** The incoming request */\r\n request: Request;\r\n /** URL parameters from routing */\r\n params: Record<string, string | string[]>;\r\n /** Query parameters */\r\n query: URLSearchParams;\r\n /** Parsed URL */\r\n url: URL;\r\n /** Local data from middleware */\r\n locals: Record<string, unknown>;\r\n /** Database instance (if configured) */\r\n db?: unknown;\r\n /** Auth instance (if configured) */\r\n auth?: unknown;\r\n /** Email instance (if configured) */\r\n email?: unknown;\r\n}\r\n\r\n/** Server options */\r\nexport interface ServerOptions {\r\n /** Server configuration */\r\n config?: FlightUserConfig;\r\n /** Deployment adapter */\r\n adapter?: FlightAdapter;\r\n /** Database instance */\r\n db?: unknown;\r\n /** Auth instance */\r\n auth?: unknown;\r\n /** Email instance */\r\n email?: unknown;\r\n}\r\n\r\n/** Route definition for the server */\r\nexport interface ServerRoute {\r\n /** HTTP method (GET, POST, etc.) */\r\n method: string | string[];\r\n /** Route path pattern */\r\n path: string;\r\n /** Route handler */\r\n handler: RouteHandler;\r\n}\r\n\r\n/** Listen options */\r\nexport interface ListenOptions {\r\n /** Port to listen on (default: 3000) */\r\n port?: number;\r\n /** Hostname to bind to (default: 'localhost') */\r\n hostname?: string;\r\n /** Callback when server starts */\r\n onListen?: (info: { port: number; hostname: string }) => void;\r\n}\r\n\r\n/** Flight Server instance */\r\nexport interface FlightServer {\r\n /** Add a route */\r\n route(method: string | string[], path: string, handler: RouteHandler): FlightServer;\r\n\r\n /** Convenience methods for common HTTP methods */\r\n get(path: string, handler: RouteHandler): FlightServer;\r\n post(path: string, handler: RouteHandler): FlightServer;\r\n put(path: string, handler: RouteHandler): FlightServer;\r\n delete(path: string, handler: RouteHandler): FlightServer;\r\n patch(path: string, handler: RouteHandler): FlightServer;\r\n\r\n /** Add middleware */\r\n use(middleware: Middleware): FlightServer;\r\n use(path: string, middleware: Middleware): FlightServer;\r\n\r\n /** Handle incoming request (Web standard Request/Response) */\r\n handle(request: Request): Promise<Response>;\r\n\r\n /** \r\n * Start the HTTP server\r\n * Auto-detects runtime: Node.js, Bun, or Deno\r\n */\r\n listen(port?: number | ListenOptions): Promise<void>;\r\n\r\n /** Fetch handler for Bun.serve() and Deno.serve() */\r\n fetch(request: Request): Promise<Response>;\r\n\r\n /** Get the resolved configuration */\r\n readonly config: FlightConfig;\r\n\r\n /** Get the router instance */\r\n readonly router: Router<RouteHandler>;\r\n\r\n /** Get the middleware chain */\r\n readonly middleware: MiddlewareChain;\r\n}\r\n\r\n// ============================================================================\r\n// Runtime Detection\r\n// ============================================================================\r\n\r\ntype Runtime = 'node' | 'bun' | 'deno' | 'unknown';\r\n\r\nfunction detectRuntime(): Runtime {\r\n // @ts-expect-error - Bun global\r\n if (typeof Bun !== 'undefined') return 'bun';\r\n // @ts-expect-error - Deno global \r\n if (typeof Deno !== 'undefined') return 'deno';\r\n if (typeof process !== 'undefined' && process.versions?.node) return 'node';\r\n return 'unknown';\r\n}\r\n\r\n// ============================================================================\r\n// Server Implementation\r\n// ============================================================================\r\n\r\ninterface RouteEntry {\r\n methods: Set<string>;\r\n handler: RouteHandler;\r\n}\r\n\r\n/**\r\n * Create a new Flight server instance\r\n * \r\n * @example\r\n * ```typescript\r\n * import { createServer } from '@flight-framework/core';\r\n * \r\n * const server = createServer();\r\n * \r\n * server.get('/api/users', async ({ db }) => {\r\n * const users = await db.query('SELECT * FROM users');\r\n * return Response.json(users);\r\n * });\r\n * \r\n * // Works on Node.js, Bun, and Deno!\r\n * server.listen(3000);\r\n * ```\r\n */\r\nexport function createServer(options: ServerOptions = {}): FlightServer {\r\n const config = resolveConfig(options.config ?? {});\r\n const router = createRouter<RouteEntry>();\r\n const middlewareChain = createMiddlewareChain();\r\n\r\n // Store dependencies\r\n const deps = {\r\n db: options.db,\r\n auth: options.auth,\r\n email: options.email,\r\n };\r\n\r\n function addRoute(method: string | string[], path: string, handler: RouteHandler): FlightServer {\r\n const methods = Array.isArray(method) ? method : [method];\r\n const methodSet = new Set(methods.map(m => m.toUpperCase()));\r\n\r\n // Check if route already exists\r\n const existingMatch = router.match(path);\r\n if (existingMatch && existingMatch.route.path === path) {\r\n // Merge methods\r\n for (const m of methodSet) {\r\n existingMatch.route.handler.methods.add(m);\r\n }\r\n existingMatch.route.handler.handler = handler;\r\n } else {\r\n router.add({\r\n path,\r\n handler: { methods: methodSet, handler },\r\n });\r\n }\r\n\r\n return server;\r\n }\r\n\r\n function useMiddleware(\r\n pathOrMiddleware: string | Middleware,\r\n maybeMiddleware?: Middleware\r\n ): FlightServer {\r\n if (typeof pathOrMiddleware === 'string' && maybeMiddleware) {\r\n middlewareChain.use(pathOrMiddleware, maybeMiddleware);\r\n } else if (typeof pathOrMiddleware === 'function') {\r\n middlewareChain.use(pathOrMiddleware);\r\n }\r\n return server;\r\n }\r\n\r\n async function handle(request: Request): Promise<Response> {\r\n const url = new URL(request.url);\r\n const method = request.method.toUpperCase();\r\n\r\n // Run middleware\r\n const ctx = createContextFromRequest(request);\r\n await middlewareChain.execute(ctx);\r\n\r\n // If middleware already set a response, return it\r\n if (ctx.responseBody !== undefined) {\r\n return createResponseFromContext(ctx);\r\n }\r\n\r\n // Match route\r\n const match = router.match(url.pathname);\r\n if (!match) {\r\n return new Response('Not Found', { status: 404 });\r\n }\r\n\r\n // Check method\r\n if (!match.route.handler.methods.has(method) && !match.route.handler.methods.has('*')) {\r\n return new Response('Method Not Allowed', { status: 405 });\r\n }\r\n\r\n // Build handler context\r\n const handlerContext: RouteHandlerContext = {\r\n request,\r\n params: match.params,\r\n query: url.searchParams,\r\n url,\r\n locals: ctx.locals,\r\n ...deps,\r\n };\r\n\r\n try {\r\n return await match.route.handler.handler(handlerContext);\r\n } catch (error) {\r\n console.error('Route handler error:', error);\r\n return new Response('Internal Server Error', { status: 500 });\r\n }\r\n }\r\n\r\n /**\r\n * Start the HTTP server\r\n * Auto-detects the runtime and uses the appropriate server\r\n */\r\n async function listen(portOrOptions?: number | ListenOptions): Promise<void> {\r\n const opts: ListenOptions = typeof portOrOptions === 'number'\r\n ? { port: portOrOptions }\r\n : portOrOptions ?? {};\r\n\r\n const port = opts.port ?? config.dev.port ?? 3000;\r\n const hostname = opts.hostname ?? 'localhost';\r\n\r\n // Check for custom adapter first\r\n const adapter = options.adapter ?? config.adapter;\r\n if (adapter?.listen) {\r\n await adapter.listen(server, port);\r\n return;\r\n }\r\n\r\n const runtime = detectRuntime();\r\n\r\n switch (runtime) {\r\n case 'bun':\r\n await startBunServer(port, hostname, opts.onListen);\r\n break;\r\n case 'deno':\r\n await startDenoServer(port, hostname, opts.onListen);\r\n break;\r\n case 'node':\r\n default:\r\n await startNodeServer(port, hostname, opts.onListen);\r\n break;\r\n }\r\n }\r\n\r\n /**\r\n * Start Node.js HTTP server\r\n */\r\n async function startNodeServer(port: number, hostname: string, onListen?: ListenOptions['onListen']): Promise<void> {\r\n const { createServer: createHttpServer } = await import('node:http');\r\n\r\n const httpServer = createHttpServer(async (req, res) => {\r\n const url = new URL(req.url || '/', `http://${hostname}:${port}`);\r\n\r\n // Build headers\r\n const headers = new Headers();\r\n for (const [key, value] of Object.entries(req.headers)) {\r\n if (value) {\r\n const headerValue = Array.isArray(value) ? value[0] : value;\r\n if (headerValue) headers.set(key, headerValue);\r\n }\r\n }\r\n\r\n // Read body for POST/PUT/PATCH\r\n let body: string | undefined;\r\n if (['POST', 'PUT', 'PATCH'].includes(req.method || '')) {\r\n body = await new Promise<string>((resolve) => {\r\n let data = '';\r\n req.on('data', chunk => data += chunk);\r\n req.on('end', () => resolve(data));\r\n });\r\n }\r\n\r\n const request = new Request(url.toString(), {\r\n method: req.method,\r\n headers,\r\n body: body || undefined,\r\n });\r\n\r\n try {\r\n const response = await handle(request);\r\n\r\n res.statusCode = response.status;\r\n response.headers.forEach((value, key) => {\r\n res.setHeader(key, value);\r\n });\r\n\r\n const responseBody = await response.text();\r\n res.end(responseBody);\r\n } catch (error) {\r\n console.error('Server error:', error);\r\n res.statusCode = 500;\r\n res.setHeader('Content-Type', 'application/json');\r\n res.end(JSON.stringify({ error: 'Internal Server Error' }));\r\n }\r\n });\r\n\r\n return new Promise((resolve) => {\r\n httpServer.listen(port, hostname, () => {\r\n const info = { port, hostname };\r\n if (onListen) {\r\n onListen(info);\r\n } else {\r\n console.log(`\r\n╔═══════════════════════════════════════════════════════════╗\r\n║ Flight Server (Node.js) ║\r\n╠═══════════════════════════════════════════════════════════╣\r\n║ Server: http://${hostname}:${port.toString().padEnd(37)}║\r\n╚═══════════════════════════════════════════════════════════╝\r\n`);\r\n }\r\n resolve();\r\n });\r\n });\r\n }\r\n\r\n /**\r\n * Start Bun server\r\n */\r\n async function startBunServer(port: number, hostname: string, onListen?: ListenOptions['onListen']): Promise<void> {\r\n // @ts-expect-error - Bun types\r\n Bun.serve({\r\n port,\r\n hostname,\r\n fetch: handle,\r\n });\r\n\r\n const info = { port, hostname };\r\n if (onListen) {\r\n onListen(info);\r\n } else {\r\n console.log(`\r\n╔═══════════════════════════════════════════════════════════╗\r\n║ Flight Server (Bun) ║\r\n╠═══════════════════════════════════════════════════════════╣\r\n║ Server: http://${hostname}:${port.toString().padEnd(37)}║\r\n╚═══════════════════════════════════════════════════════════╝\r\n`);\r\n }\r\n }\r\n\r\n /**\r\n * Start Deno server\r\n */\r\n async function startDenoServer(port: number, hostname: string, onListen?: ListenOptions['onListen']): Promise<void> {\r\n // @ts-expect-error - Deno types\r\n Deno.serve({ port, hostname }, handle);\r\n\r\n const info = { port, hostname };\r\n if (onListen) {\r\n onListen(info);\r\n } else {\r\n console.log(`\r\n╔═══════════════════════════════════════════════════════════╗\r\n║ Flight Server (Deno) ║\r\n╠═══════════════════════════════════════════════════════════╣\r\n║ Server: http://${hostname}:${port.toString().padEnd(37)}║\r\n╚═══════════════════════════════════════════════════════════╝\r\n`);\r\n }\r\n }\r\n\r\n const server: FlightServer = {\r\n route: addRoute,\r\n get: (path, handler) => addRoute('GET', path, handler),\r\n post: (path, handler) => addRoute('POST', path, handler),\r\n put: (path, handler) => addRoute('PUT', path, handler),\r\n delete: (path, handler) => addRoute('DELETE', path, handler),\r\n patch: (path, handler) => addRoute('PATCH', path, handler),\r\n use: useMiddleware as FlightServer['use'],\r\n handle,\r\n listen,\r\n fetch: handle, // Alias for Bun/Deno compatibility\r\n get config() { return config; },\r\n get router() { return router as unknown as Router<RouteHandler>; },\r\n get middleware() { return middlewareChain; },\r\n };\r\n\r\n return server;\r\n}\r\n\r\n// ============================================================================\r\n// Helper Exports\r\n// ============================================================================\r\n\r\n/** Type guard to check if an object is a FlightServer */\r\nexport function isFlightServer(obj: unknown): obj is FlightServer {\r\n return (\r\n typeof obj === 'object' &&\r\n obj !== null &&\r\n 'handle' in obj &&\r\n 'route' in obj &&\r\n typeof (obj as FlightServer).handle === 'function'\r\n );\r\n}\r\n\r\n/** Get current runtime */\r\nexport function getRuntime(): Runtime {\r\n return detectRuntime();\r\n}\r\n\r\n"]}
@@ -5,6 +5,22 @@ import { FlightAdapter } from '../adapters/index.js';
5
5
  * Flight Configuration - User configuration system
6
6
  */
7
7
 
8
+ /**
9
+ * Bundler adapter interface.
10
+ * Import the full type from @flight-framework/bundler for implementation.
11
+ */
12
+ interface BundlerAdapter {
13
+ /** Adapter identifier */
14
+ name: string;
15
+ /** Bundler name (vite, esbuild, rolldown, etc.) */
16
+ bundler: string;
17
+ /** Bundler-specific options */
18
+ options?: Record<string, unknown>;
19
+ /** Create dev server */
20
+ createDevServer(config: FlightConfig): Promise<unknown>;
21
+ /** Build for production */
22
+ build(config: FlightConfig): Promise<unknown>;
23
+ }
8
24
  /** UI Framework configuration */
9
25
  interface UIConfig {
10
26
  /** The UI framework to use */
@@ -62,6 +78,8 @@ interface FlightConfig {
62
78
  root: string;
63
79
  /** Deployment adapter */
64
80
  adapter: FlightAdapter | null;
81
+ /** Bundler adapter (Vite, esbuild, Rolldown, etc.) */
82
+ bundler: BundlerAdapter | null;
65
83
  /** UI framework configuration */
66
84
  ui: UIConfig;
67
85
  /** Rendering configuration */
@@ -70,7 +88,9 @@ interface FlightConfig {
70
88
  dev: Required<DevConfig>;
71
89
  /** Build configuration */
72
90
  build: Required<BuildConfig>;
73
- /** Vite configuration overrides */
91
+ /** Bundler-specific configuration (passed to adapter) */
92
+ bundlerOptions?: Record<string, unknown>;
93
+ /** @deprecated Use bundler adapter instead */
74
94
  vite?: Record<string, unknown>;
75
95
  /** Plugin configurations */
76
96
  plugins: FlightPlugin[];
@@ -94,6 +114,8 @@ interface FlightUserConfig {
94
114
  root?: string;
95
115
  /** Deployment adapter */
96
116
  adapter?: FlightAdapter;
117
+ /** Bundler adapter (Vite, esbuild, Rolldown, etc.) */
118
+ bundler?: BundlerAdapter;
97
119
  /** UI framework configuration */
98
120
  ui?: UIConfig;
99
121
  /** Rendering configuration */
@@ -102,7 +124,9 @@ interface FlightUserConfig {
102
124
  dev?: DevConfig;
103
125
  /** Build configuration */
104
126
  build?: BuildConfig;
105
- /** Vite configuration overrides */
127
+ /** Bundler-specific configuration */
128
+ bundlerOptions?: Record<string, unknown>;
129
+ /** @deprecated Use bundler adapter instead */
106
130
  vite?: Record<string, unknown>;
107
131
  /** Plugins */
108
132
  plugins?: FlightPlugin[];
@@ -143,4 +167,4 @@ declare function findConfigFile(root: string): Promise<string | null>;
143
167
  */
144
168
  declare function loadConfig(root?: string): Promise<FlightConfig>;
145
169
 
146
- export { type BuildConfig, type DevConfig, type FlightConfig, type FlightPlugin, type FlightUserConfig, type RenderConfig, type UIConfig, defineConfig, findConfigFile, loadConfig, resolveConfig };
170
+ export { type BuildConfig, type BundlerAdapter, type DevConfig, type FlightConfig, type FlightPlugin, type FlightUserConfig, type RenderConfig, type UIConfig, defineConfig, findConfigFile, loadConfig, resolveConfig };
@@ -1,3 +1,3 @@
1
- export { defineConfig, findConfigFile, loadConfig, resolveConfig } from '../chunk-3TPAA52K.js';
1
+ export { defineConfig, findConfigFile, loadConfig, resolveConfig } from '../chunk-IXMD5QH2.js';
2
2
  //# sourceMappingURL=index.js.map
3
3
  //# sourceMappingURL=index.js.map
package/dist/index.d.ts CHANGED
@@ -3,7 +3,7 @@ export { Route, RouteMatch, RouteParams, Router, createRouter } from './router/i
3
3
  export { FlightServer, RouteHandler, RouteHandlerContext, ServerOptions, ServerRoute, createServer } from './server/index.js';
4
4
  export { RenderContext, RenderMode, RenderResult } from './render/index.js';
5
5
  import { CacheOptions, Cache } from './cache/index.js';
6
- export { createCache } from './cache/index.js';
6
+ export { CacheAdapter, CacheEntry, CacheStats, CreateCacheOptions, Serializer, cacheKey, cached, createCache, dedupe, jsonSerializer, memory } from './cache/index.js';
7
7
  export { Middleware, MiddlewareContext, MiddlewareNext, createMiddlewareChain } from './middleware/index.js';
8
8
  export { AdapterBuilder, FlightAdapter } from './adapters/index.js';
9
9
  export { FileRoute, FileRouter, FileRouterOptions, ScanResult, createFileRouter, loadRoutes, scanRoutes } from './file-router/index.js';
package/dist/index.js CHANGED
@@ -5,7 +5,7 @@ export { MetricsAggregator, createHttpObserver, createInstrumentedStream, create
5
5
  export { DEFAULT_BOT_PATTERNS, addStreamingHeaders, createConditionalStreamer, createStreamingResponse as createConditionalStreamingResponse, createStaticResponse, isBot, isSlowConnection, prefersNoStream, streamIf, supportsStreaming } from './chunk-XOIYNY4I.js';
6
6
  export { createHTMXStreamAdapter, createReactStreamAdapter, createSolidStreamAdapter, createStreamAdapter, createSvelteStreamAdapter, createVueStreamAdapter } from './chunk-MQQLYWZZ.js';
7
7
  export { createFileRouter, loadRoutes, scanRoutes } from './chunk-54HPVE7N.js';
8
- export { RedirectError, redirect as actionRedirect, cookies, executeAction, executeFormAction, getAction, handleActionRequest, isRedirectError, parseFormData, registerAction } from './chunk-JIW55ZVD.js';
8
+ export { RedirectError, redirect as actionRedirect, cookies, executeAction, executeFormAction, getAction, handleActionRequest, isRedirectError, parseFormData, registerAction } from './chunk-3QP3E7HS.js';
9
9
  export { createRouteContext, error, json, parseBody, redirect } from './chunk-W6D62JCI.js';
10
10
  export { createLazyContent, createStreamingResponse, createStreamingSSR, renderWithStreaming, streamParallel, streamSequential } from './chunk-RSVA2EYO.js';
11
11
  import './chunk-63SCEXD7.js';
@@ -22,12 +22,12 @@ import './chunk-K2CQZPCG.js';
22
22
  export { detectBoundaryType, hasUseClientDirective, hasUseServerDirective } from './chunk-PDW5WCMW.js';
23
23
  export { createServerContext, isNotFoundError, isRedirectError as isRscRedirectError, notFound, redirect as rscRedirect } from './chunk-62C7LX2E.js';
24
24
  import './chunk-ZVC3ZWLM.js';
25
- export { createCache } from './chunk-3AIQVGTM.js';
25
+ export { cacheKey, cached, createCache, dedupe, jsonSerializer, memory } from './chunk-R7SQAREQ.js';
26
26
  import './chunk-SUILH4ID.js';
27
- export { createServer } from './chunk-6LYV4VQX.js';
27
+ export { createServer } from './chunk-VOBQDQKX.js';
28
28
  export { createRouter } from './chunk-GCQZ4FHI.js';
29
29
  export { createMiddlewareChain } from './chunk-KWFX6WHG.js';
30
- export { defineConfig } from './chunk-3TPAA52K.js';
30
+ export { defineConfig } from './chunk-IXMD5QH2.js';
31
31
  import { promises } from 'fs';
32
32
  import { dirname, join } from 'path';
33
33
 
@@ -488,17 +488,17 @@ async function generateAllStaticPaths(pageModules) {
488
488
  }
489
489
  var pageCache = /* @__PURE__ */ new Map();
490
490
  async function getOrGeneratePage(path, generateFn, revalidate) {
491
- const cached = pageCache.get(path);
491
+ const cached2 = pageCache.get(path);
492
492
  const now = Date.now();
493
- if (cached) {
493
+ if (cached2) {
494
494
  if (revalidate === false) {
495
- return { html: cached.html, fromCache: true };
495
+ return { html: cached2.html, fromCache: true };
496
496
  }
497
- if (now < cached.revalidateAfter) {
498
- return { html: cached.html, fromCache: true };
497
+ if (now < cached2.revalidateAfter) {
498
+ return { html: cached2.html, fromCache: true };
499
499
  }
500
500
  regeneratePageInBackground(path, generateFn, revalidate || 60);
501
- return { html: cached.html, fromCache: true };
501
+ return { html: cached2.html, fromCache: true };
502
502
  }
503
503
  const html = await generateFn();
504
504
  if (revalidate !== false) {