133 lines
2.9 KiB
TypeScript
133 lines
2.9 KiB
TypeScript
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<Response>;
|
|
|
|
/**
|
|
* 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<ISmartServeInstance>;
|
|
|
|
/**
|
|
* Stop the server
|
|
*/
|
|
abstract stop(): Promise<void>;
|
|
|
|
/**
|
|
* 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<string, string> {
|
|
const query: Record<string, string> = {};
|
|
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';
|
|
}
|
|
}
|