/** * ThreadForge Built-in Plugins * * import { redis, postgres, s3, cors, cron, realtime } from 'threadforge/plugins'; */ import type { IncomingMessage, ServerResponse } from "node:http"; import type { Socket } from "node:net"; import type { HealthCheckResult, IoRedisLikeClient, NginxResult, PluginContext, PostgresOptions, RedisOptions } from "./types.js"; type RespValue = string | number | Buffer | null | Error | RespValue[]; interface PendingRequest { ok: (val: RespValue) => void; no: (err: Error) => void; } interface RedisClient { status: string; get(key: string): Promise; set(...args: string[]): Promise; del(...keys: string[]): Promise; hget(key: string, field: string): Promise; hset(key: string, field: string, value: string): Promise; hgetall(key: string): Promise>; keys(pattern: string): Promise; expire(key: string, seconds: string): Promise; ttl(key: string): Promise; ping(): Promise; incr(key: string): Promise; decr(key: string): Promise; lpush(key: string, ...values: string[]): Promise; rpush(key: string, ...values: string[]): Promise; lrange(key: string, start: string | number, end: string | number): Promise; sadd(key: string, ...members: string[]): Promise; smembers(key: string): Promise; publish(channel: string, message: string): Promise; subscribe(channel: string, callback: (message: string, channel: string) => void): Promise; psubscribe(pattern: string, callback: (message: string, channel: string, pattern: string) => void): Promise; quit(): Promise; disconnect(): void; _subSocket: Socket | null; _subConnected: boolean; _subBufChunks: Buffer[]; _subBufTotalLen: number; _subCallbacks: Map void>>; _psubCallbacks: Map void>>; _subSubscribedChannels: Set; _subSubscribedPatterns: Set; _subRq: PendingRequest[]; _ensureSubConnection(): Promise; _scheduleSubReconnect(): void; _subCmd(...args: string[]): Promise; _flushSub(): void; _poolConnections?: RedisClient[]; } interface RedisPlugin { name: "redis"; version: string; inject: "redis"; validate(): void; env(): Record; connect(ctx: PluginContext): Promise; healthCheck(c: RedisClient | IoRedisLikeClient): Promise; disconnect(c: RedisClient | IoRedisLikeClient): Promise; metrics(c: RedisClient | IoRedisLikeClient): Record; nginx(): NginxResult; } interface PgPool { query(...args: unknown[]): Promise; connect(): Promise<{ release(): void; }>; end(): Promise; totalCount: number; idleCount: number; waitingCount: number; } interface PostgresPlugin { name: "postgres"; version: string; inject: "pg"; injectAs: "postgres"; validate(): void; env(): Record; connect(ctx: PluginContext): Promise; healthCheck(pool: PgPool): Promise; disconnect(pool: PgPool): Promise; metrics(pool: PgPool): Record; nginx(): NginxResult; } interface S3Options { bucket?: string; endpoint?: string; region?: string; } interface S3RealClient { _isStub: false; _raw: unknown; _HeadBucketCommand: new (params: { Bucket: string; }) => unknown; put(key: string, body: Buffer | string, contentType?: string): Promise; get(key: string): Promise; del(key: string): Promise; url(key: string): string; bucket: string; } interface S3StubClient { _isStub: true; put(key: string, body: Buffer | string): Promise; get(key: string): Promise; del(key: string): Promise; url(key: string): string; bucket: string; } type S3Client = S3RealClient | S3StubClient; interface S3Plugin { name: "s3"; version: string; inject: "storage"; injectAs: "s3"; validate(): void; env(): Record; connect(ctx: PluginContext): Promise; healthCheck(s: S3Client): Promise; disconnect(): Promise; } interface CorsOptions { origins?: string[]; methods?: string[]; headers?: string[]; credentials?: boolean; maxAge?: number; } interface CorsConfig { origins: string[]; methods: string[]; headers: string[]; } type NextFunction = () => void; interface CorsPlugin { name: "cors"; version: string; inject: "_cors"; validate(): void; connect(): Promise; middleware(): (req: IncomingMessage, res: ServerResponse, next: NextFunction) => void; disconnect(): Promise; } interface WebSocketLike { send(data: string): void; sendBinary?(data: Buffer): void; close?(code?: number, reason?: string): void; socket?: Socket; _closed?: boolean; } interface RealtimeDecision { allow: boolean; statusCode?: number; reason?: string; closeCode?: number; closeReason?: string; headers?: Record; } interface AuthorizePayload { stage: string; ws?: WebSocketLike; req?: IncomingMessage; meta?: Record; [key: string]: unknown; } type AuthorizeHook = (payload: AuthorizePayload) => RealtimeDecision | boolean | null | undefined | Promise; interface RealtimeOptions { adapter?: "memory" | "redis"; redisUrl?: string; busChannel?: string; maxPayloadBytes?: number; maxConnections?: number; maxSocketBufferBytes?: number; backpressureStrategy?: "drop" | "close"; redisSubHealthcheckMs?: number; strictBusPublish?: boolean; authorize?: AuthorizeHook; authorizeUpgrade?: AuthorizeHook; authorizeConnect?: AuthorizeHook; allowedChannels?: string[]; } interface RealtimeMetrics { connections: number; channels: number; published: number; delivered: number; dropped: number; backpressureDropped: number; busPublishErrors: number; redisReconnects: number; } interface RealtimeAttachResult { join(channel: string): boolean; leave(channel: string): boolean; publish(channel: string, payload: unknown): Promise<{ delivered: number; busPublished: boolean; }>; detach(): void; } interface RealtimeClient { adapter: string; busChannel: string; join(ws: WebSocketLike, channel: string): boolean; leave(ws: WebSocketLike, channel: string): boolean; publish(channel: string, payload: unknown, opts?: { excludeWs?: WebSocketLike | null; }): Promise<{ delivered: number; busPublished: boolean; }>; broadcast(payload: unknown, opts?: { excludeWs?: WebSocketLike | null; }): Promise<{ delivered: number; busPublished: boolean; }>; attach(ws: WebSocketLike, attachOptions?: { req?: IncomingMessage | null; meta?: Record | null; channels?: string[]; }): RealtimeAttachResult; channels(): string[]; connectionCount(): number; _onWsUpgrade(hookCtx: Record): Promise; _onWsConnect(hookCtx: { ws: WebSocketLike; req?: IncomingMessage; meta?: Record; }): Promise; _registerConnection(ws: WebSocketLike, req?: IncomingMessage | null, meta?: Record | null): void; _cleanupConnection(ws: WebSocketLike): void; _metrics(): RealtimeMetrics; _shutdown(): Promise; } interface RealtimePlugin { name: "realtime"; version: string; inject: "realtime"; validate(): void; env(): Record; connect(ctx: PluginContext): Promise; disconnect(client: RealtimeClient): Promise; metrics(client: RealtimeClient): RealtimeMetrics; onWsUpgrade(client: RealtimeClient, ctx: Record): Promise | undefined; onWsConnect(client: RealtimeClient, ctx: Record): Promise; onWsClose(client: RealtimeClient, ctx: { ws: WebSocketLike; }): void; } interface CronOptions { leaderOnly?: boolean; } interface CronScheduleOptions { immediate?: boolean; timezone?: string; } interface CronJobEntry { expr: string; timer: ReturnType | ReturnType; _cancelComplex?: () => void; } interface CronClient { jobs: Map; schedule(name: string, expr: string, fn: () => Promise | void, options?: CronScheduleOptions): void; cancel(name: string): void; listJobs(): string[]; _timers: (ReturnType | ReturnType)[]; } interface CronPlugin { name: "cron"; version: string; inject: "cron"; connect(ctx: PluginContext): Promise; disconnect(c: CronClient): Promise; } export declare function redis(options?: RedisOptions): RedisPlugin; /** @internal Exported for testing only */ export declare function _mkRedis(url: string, ctx: PluginContext): Promise; export declare function postgres(options?: PostgresOptions): PostgresPlugin; export declare function s3(options?: S3Options): S3Plugin; export declare function cors(options?: CorsOptions): CorsPlugin; export declare function realtime(options?: RealtimeOptions): RealtimePlugin; export declare function cron(options?: CronOptions): CronPlugin; export {}; //# sourceMappingURL=index.d.ts.map