import * as plugins from '../plugins.js'; import type { ISmartServeOptions, ISmartServeInstance, IRequestContext, IConnectionInfo, IServerStats, TRuntime, THttpMethod, } from '../core/smartserve.interfaces.js'; /** * Adapter characteristics - what each runtime supports */ export interface IAdapterCharacteristics { /** Zero-copy streaming support */ zeroCopyStreaming: boolean; /** HTTP/2 support */ http2Support: boolean; /** Maximum concurrent connections */ maxConnections: number | 'unlimited'; /** Native WebSocket upgrade support */ nativeWebSocket: boolean; } /** * Handler function that receives web standard Request and returns Response */ export type TRequestHandler = ( request: Request, info: IConnectionInfo ) => Response | Promise; /** * Abstract base adapter for all runtime implementations */ export abstract class BaseAdapter { protected options: ISmartServeOptions; protected handler: TRequestHandler | null = null; protected stats: IServerStats = { uptime: 0, requestsTotal: 0, requestsActive: 0, connectionsTotal: 0, connectionsActive: 0, bytesReceived: 0, bytesSent: 0, }; protected startTime: number = 0; constructor(options: ISmartServeOptions) { this.options = options; } /** * Runtime name */ abstract get name(): TRuntime; /** * Adapter characteristics */ abstract get characteristics(): IAdapterCharacteristics; /** * Check if this adapter is supported in current runtime */ abstract isSupported(): boolean; /** * Start the server */ abstract start(handler: TRequestHandler): Promise; /** * Stop the server */ abstract stop(): Promise; /** * Get current server statistics */ getStats(): IServerStats { return { ...this.stats, uptime: this.startTime > 0 ? Date.now() - this.startTime : 0, }; } /** * Create ISmartServeInstance from adapter */ protected createInstance(): ISmartServeInstance { return { port: this.options.port, hostname: this.options.hostname ?? '0.0.0.0', secure: !!this.options.tls, runtime: this.name, stop: () => this.stop(), stats: () => this.getStats(), }; } /** * Parse URL from request for cross-platform compatibility */ protected parseUrl(request: Request): URL { return new URL(request.url); } /** * Parse query parameters from URL */ protected parseQuery(url: URL): Record { const query: Record = {}; url.searchParams.forEach((value, key) => { query[key] = value; }); return query; } /** * Get HTTP method from request */ protected parseMethod(request: Request): THttpMethod { const method = request.method.toUpperCase(); if (['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'HEAD', 'OPTIONS'].includes(method)) { return method as THttpMethod; } return 'GET'; } }