From 2744f21f7d9743744fc64b3a88fe6c9c8c40d58f Mon Sep 17 00:00:00 2001 From: Pooya Parsa Date: Tue, 6 Aug 2024 20:49:15 +0200 Subject: [PATCH] refactor: better internal organization --- src/adapter.ts | 40 ++++++++++ src/adapters/bun.ts | 25 +++--- src/adapters/cloudflare-durable.ts | 23 +++--- src/adapters/cloudflare.ts | 24 +++--- src/adapters/deno.ts | 24 +++--- src/adapters/node.ts | 123 +++++++++++++++-------------- src/adapters/sse.ts | 21 ++--- src/adapters/uws.ts | 95 +++++++++++----------- src/hooks.ts | 101 +++++++++++++++++++++-- src/index.ts | 23 ++++-- src/message.ts | 2 +- src/types.ts | 119 ---------------------------- src/{_utils.ts => utils.ts} | 16 ---- test/unit.test.ts | 2 +- 14 files changed, 333 insertions(+), 305 deletions(-) create mode 100644 src/adapter.ts delete mode 100644 src/types.ts rename src/{_utils.ts => utils.ts} (74%) diff --git a/src/adapter.ts b/src/adapter.ts new file mode 100644 index 0000000..3e36e77 --- /dev/null +++ b/src/adapter.ts @@ -0,0 +1,40 @@ +import type { AdapterHooks, Hooks, ResolveHooks } from "./hooks.ts"; +import type { Peer } from "./peer.ts"; + +export function adapterUtils(peers: Set) { + return { + peers, + publish(topic: string, message: any, options) { + const firstPeer = peers.values().next().value as Peer; + if (firstPeer) { + firstPeer.send(message, options); + firstPeer.publish(topic, message, options); + } + }, + } satisfies AdapterInstance; +} + +// --- types --- + +export interface AdapterInstance { + readonly peers: Set; + readonly publish: Peer["publish"]; +} + +export interface AdapterOptions { + resolve?: ResolveHooks; + hooks?: Hooks; + adapterHooks?: AdapterHooks; +} + +export type Adapter< + AdapterT extends AdapterInstance = AdapterInstance, + Options extends AdapterOptions = AdapterOptions, +> = (options?: Options) => AdapterT; + +export function defineWebSocketAdapter< + AdapterT extends AdapterInstance = AdapterInstance, + Options extends AdapterOptions = AdapterOptions, +>(factory: Adapter) { + return factory; +} diff --git a/src/adapters/bun.ts b/src/adapters/bun.ts index 154fd55..b36624a 100644 --- a/src/adapters/bun.ts +++ b/src/adapters/bun.ts @@ -1,15 +1,13 @@ -// https://bun.sh/docs/api/websockets - import type { WebSocketHandler, ServerWebSocket, Server } from "bun"; -import { Message } from "../message"; -import { Peer } from "../peer"; -import { - AdapterOptions, - AdapterInstance, - defineWebSocketAdapter, -} from "../types"; -import { AdapterHookable } from "../hooks"; -import { adapterUtils, toBufferLike } from "../_utils"; + +import type { AdapterOptions, AdapterInstance } from "../adapter.ts"; +import { toBufferLike } from "../utils.ts"; +import { defineWebSocketAdapter, adapterUtils } from "../adapter.ts"; +import { AdapterHookable } from "../hooks.ts"; +import { Message } from "../message.ts"; +import { Peer } from "../peer.ts"; + +// --- types --- export interface BunAdapter extends AdapterInstance { websocket: WebSocketHandler; @@ -25,6 +23,9 @@ type ContextData = { server?: Server; }; +// --- adapter --- + +// https://bun.sh/docs/api/websockets export default defineWebSocketAdapter( (options = {}) => { const hooks = new AdapterHookable(options); @@ -82,6 +83,8 @@ export default defineWebSocketAdapter( }, ); +// --- peer --- + function getPeer( ws: ServerWebSocket, peers: Set, diff --git a/src/adapters/cloudflare-durable.ts b/src/adapters/cloudflare-durable.ts index f8fa39c..b3741b7 100644 --- a/src/adapters/cloudflare-durable.ts +++ b/src/adapters/cloudflare-durable.ts @@ -1,16 +1,14 @@ -// https://developers.cloudflare.com/durable-objects/examples/websocket-hibernation-server/ +import type { AdapterOptions, AdapterInstance } from "../adapter.ts"; +import { toBufferLike } from "../utils.ts"; +import { defineWebSocketAdapter, adapterUtils } from "../adapter.ts"; +import { AdapterHookable } from "../hooks.ts"; +import { Message } from "../message.ts"; +import { Peer } from "../peer.ts"; import type * as CF from "@cloudflare/workers-types"; import type { DurableObject } from "cloudflare:workers"; -import { - AdapterOptions, - AdapterInstance, - defineWebSocketAdapter, -} from "../types"; -import { Peer } from "../peer"; -import { Message } from "../message"; -import { AdapterHookable } from "../hooks"; -import { adapterUtils, toBufferLike } from "../_utils"; + +// --- types declare class DurableObjectPub extends DurableObject { public ctx: DurableObject["ctx"]; @@ -58,6 +56,9 @@ export interface CloudflareOptions extends AdapterOptions { instanceName?: string; } +// --- adapter --- + +// https://developers.cloudflare.com/durable-objects/examples/websocket-hibernation-server/ export default defineWebSocketAdapter< CloudflareDurableAdapter, CloudflareOptions @@ -133,6 +134,8 @@ function peerFromDurableEvent( return peer; } +// --- peer --- + class CloudflareDurablePeer extends Peer<{ peers?: never; cloudflare: { diff --git a/src/adapters/cloudflare.ts b/src/adapters/cloudflare.ts index 7e31258..acf8146 100644 --- a/src/adapters/cloudflare.ts +++ b/src/adapters/cloudflare.ts @@ -1,17 +1,14 @@ -// https://developers.cloudflare.com/workers/examples/websockets/ +import type { AdapterOptions, AdapterInstance } from "../adapter.ts"; +import { toBufferLike } from "../utils.ts"; +import { defineWebSocketAdapter, adapterUtils } from "../adapter.ts"; +import { AdapterHookable } from "../hooks.ts"; +import { Message } from "../message.ts"; +import { WSError } from "../error.ts"; +import { Peer } from "../peer.ts"; import type * as _cf from "@cloudflare/workers-types"; -import { Peer } from "../peer"; -import { - AdapterOptions, - AdapterInstance, - defineWebSocketAdapter, -} from "../types.js"; -import { Message } from "../message"; -import { WSError } from "../error"; -import { AdapterHookable } from "../hooks.js"; -import { adapterUtils, toBufferLike } from "../_utils"; +// --- types --- declare const WebSocketPair: typeof _cf.WebSocketPair; declare const Response: typeof _cf.Response; @@ -26,6 +23,9 @@ export interface CloudflareAdapter extends AdapterInstance { export interface CloudflareOptions extends AdapterOptions {} +// --- adapter --- + +// https://developers.cloudflare.com/workers/examples/websockets/ export default defineWebSocketAdapter( (options = {}) => { const hooks = new AdapterHookable(options); @@ -76,6 +76,8 @@ export default defineWebSocketAdapter( }, ); +// --- peer --- + class CloudflarePeer extends Peer<{ peers: Set; cloudflare: { diff --git a/src/adapters/deno.ts b/src/adapters/deno.ts index 31e5493..ace78d1 100644 --- a/src/adapters/deno.ts +++ b/src/adapters/deno.ts @@ -1,17 +1,12 @@ -// https://deno.land/api?s=WebSocket -// https://deno.land/api?s=Deno.upgradeWebSocket -// https://examples.deno.land/http-server-websocket - +import type { AdapterOptions, AdapterInstance } from "../adapter.ts"; +import { toBufferLike } from "../utils.ts"; +import { defineWebSocketAdapter, adapterUtils } from "../adapter.ts"; +import { AdapterHookable } from "../hooks.ts"; import { Message } from "../message.ts"; import { WSError } from "../error.ts"; import { Peer } from "../peer.ts"; -import { - AdapterOptions, - AdapterInstance, - defineWebSocketAdapter, -} from "../types.ts"; -import { AdapterHookable } from "../hooks.ts"; -import { adapterUtils, toBufferLike } from "../_utils.ts"; + +// --- types --- export interface DenoAdapter extends AdapterInstance { handleUpgrade(req: Request, info: ServeHandlerInfo): Promise; @@ -26,6 +21,11 @@ declare global { type WebSocketUpgrade = import("@deno/types").Deno.WebSocketUpgrade; type ServeHandlerInfo = unknown; // TODO +// --- adapter --- + +// https://deno.land/api?s=WebSocket +// https://deno.land/api?s=Deno.upgradeWebSocket +// https://examples.deno.land/http-server-websocket export default defineWebSocketAdapter( (options = {}) => { const hooks = new AdapterHookable(options); @@ -70,6 +70,8 @@ export default defineWebSocketAdapter( }, ); +// --- peer --- + class DenoPeer extends Peer<{ peers: Set; deno: { diff --git a/src/adapters/node.ts b/src/adapters/node.ts index 434d4f7..9c9bd65 100644 --- a/src/adapters/node.ts +++ b/src/adapters/node.ts @@ -1,5 +1,10 @@ -// https://github.com/websockets/ws -// https://github.com/websockets/ws/blob/master/doc/ws.md +import type { AdapterOptions, AdapterInstance } from "../adapter.ts"; +import { toBufferLike } from "../utils.ts"; +import { defineWebSocketAdapter, adapterUtils } from "../adapter.ts"; +import { AdapterHookable } from "../hooks.ts"; +import { Message } from "../message.ts"; +import { WSError } from "../error.ts"; +import { Peer } from "../peer.ts"; import type { ClientRequest, IncomingMessage } from "node:http"; import type { Duplex } from "node:stream"; @@ -10,16 +15,8 @@ import type { WebSocketServer, WebSocket as WebSocketT, } from "../../types/ws"; -import { Peer } from "../peer"; -import { Message } from "../message"; -import { WSError } from "../error"; -import { - AdapterOptions, - AdapterInstance, - defineWebSocketAdapter, -} from "../types"; -import { AdapterHookable } from "../hooks"; -import { adapterUtils, toBufferLike } from "../_utils"; + +// --- types --- type AugmentedReq = IncomingMessage & { _upgradeHeaders?: HeadersInit }; @@ -33,6 +30,10 @@ export interface NodeOptions extends AdapterOptions { serverOptions?: ServerOptions; } +// --- adapter --- + +// https://github.com/websockets/ws +// https://github.com/websockets/ws/blob/master/doc/ws.md export default defineWebSocketAdapter( (options = {}) => { const hooks = new AdapterHookable(options); @@ -123,53 +124,7 @@ export default defineWebSocketAdapter( }, ); -class NodeReqProxy { - _req: IncomingMessage; - _headers?: Headers; - _url?: string; - - constructor(req: IncomingMessage) { - this._req = req; - } - - get url(): string { - if (!this._url) { - const req = this._req; - const host = req.headers["host"] || "localhost"; - const isSecure = - (req.socket as any)?.encrypted ?? - req.headers["x-forwarded-proto"] === "https"; - this._url = `${isSecure ? "https" : "http"}://${host}${req.url}`; - } - return this._url; - } - - get headers(): Headers { - if (!this._headers) { - this._headers = new Headers(this._req.headers as HeadersInit); - } - return this._headers; - } -} - -async function sendResponse(socket: Duplex, res: Response) { - const head = [ - `HTTP/1.1 ${res.status || 200} ${res.statusText || ""}`, - ...[...res.headers.entries()].map( - ([key, value]) => - `${encodeURIComponent(key)}: ${encodeURIComponent(value)}`, - ), - ]; - socket.write(head.join("\r\n") + "\r\n\r\n"); - if (res.body) { - for await (const chunk of res.body) { - socket.write(chunk); - } - } - return new Promise((resolve) => { - socket.end(resolve); - }); -} +// --- peer --- class NodePeer extends Peer<{ peers: Set; @@ -246,3 +201,53 @@ class NodePeer extends Peer<{ this._internal.node.ws.terminate(); } } + +// --- web compat --- + +class NodeReqProxy { + _req: IncomingMessage; + _headers?: Headers; + _url?: string; + + constructor(req: IncomingMessage) { + this._req = req; + } + + get url(): string { + if (!this._url) { + const req = this._req; + const host = req.headers["host"] || "localhost"; + const isSecure = + (req.socket as any)?.encrypted ?? + req.headers["x-forwarded-proto"] === "https"; + this._url = `${isSecure ? "https" : "http"}://${host}${req.url}`; + } + return this._url; + } + + get headers(): Headers { + if (!this._headers) { + this._headers = new Headers(this._req.headers as HeadersInit); + } + return this._headers; + } +} + +async function sendResponse(socket: Duplex, res: Response) { + const head = [ + `HTTP/1.1 ${res.status || 200} ${res.statusText || ""}`, + ...[...res.headers.entries()].map( + ([key, value]) => + `${encodeURIComponent(key)}: ${encodeURIComponent(value)}`, + ), + ]; + socket.write(head.join("\r\n") + "\r\n\r\n"); + if (res.body) { + for await (const chunk of res.body) { + socket.write(chunk); + } + } + return new Promise((resolve) => { + socket.end(resolve); + }); +} diff --git a/src/adapters/sse.ts b/src/adapters/sse.ts index 54ac576..27a955e 100644 --- a/src/adapters/sse.ts +++ b/src/adapters/sse.ts @@ -1,14 +1,10 @@ -// https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events +import type { AdapterOptions, AdapterInstance } from "../adapter.ts"; +import { toBufferLike } from "../utils.ts"; +import { defineWebSocketAdapter, adapterUtils } from "../adapter.ts"; +import { AdapterHookable } from "../hooks.ts"; +import { Peer } from "../peer.ts"; -import { WebSocketServer as _WebSocketServer } from "ws"; -import { Peer } from "../peer"; -import { - AdapterOptions, - AdapterInstance, - defineWebSocketAdapter, -} from "../types"; -import { AdapterHookable } from "../hooks"; -import { adapterUtils, toBufferLike } from "../_utils"; +// --- types --- export interface SSEAdapter extends AdapterInstance { fetch(req: Request): Promise; @@ -16,6 +12,9 @@ export interface SSEAdapter extends AdapterInstance { export interface SSEOptions extends AdapterOptions {} +// --- adapter --- + +// https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events export default defineWebSocketAdapter( (options = {}) => { const hooks = new AdapterHookable(options); @@ -49,6 +48,8 @@ export default defineWebSocketAdapter( }, ); +// --- peer --- + class SSEPeer extends Peer<{ peers: Set; sse: { diff --git a/src/adapters/uws.ts b/src/adapters/uws.ts index ff5640b..603050e 100644 --- a/src/adapters/uws.ts +++ b/src/adapters/uws.ts @@ -1,5 +1,9 @@ -// https://github.com/websockets/ws -// https://github.com/websockets/ws/blob/master/doc/ws.md +import type { AdapterOptions, AdapterInstance } from "../adapter.ts"; +import { toBufferLike } from "../utils.ts"; +import { defineWebSocketAdapter, adapterUtils } from "../adapter.ts"; +import { AdapterHookable } from "../hooks.ts"; +import { Message } from "../message.ts"; +import { Peer } from "../peer.ts"; import type { WebSocketBehavior, @@ -8,15 +12,8 @@ import type { HttpResponse, RecognizedString, } from "uWebSockets.js"; -import { Peer } from "../peer"; -import { Message } from "../message"; -import { - AdapterOptions, - AdapterInstance, - defineWebSocketAdapter, -} from "../types"; -import { AdapterHookable } from "../hooks"; -import { adapterUtils, toBufferLike } from "../_utils"; + +// --- types --- type UserData = { _peer?: any; @@ -45,6 +42,10 @@ export interface UWSOptions extends AdapterOptions { >; } +// --- adapter --- + +// https://github.com/websockets/ws +// https://github.com/websockets/ws/blob/master/doc/ws.md export default defineWebSocketAdapter( (options = {}) => { const hooks = new AdapterHookable(options); @@ -149,40 +150,7 @@ export default defineWebSocketAdapter( }, ); -class UWSReqProxy { - private _headers?: Headers; - private _rawHeaders: [string, string][] = []; - url: string; - - constructor(_req: HttpRequest) { - // We need to precompute values since uws doesn't provide them after handler. - - // Headers - let host = "localhost"; - let proto = "http"; - // eslint-disable-next-line unicorn/no-array-for-each - _req.forEach((key, value) => { - if (key === "host") { - host = value; - } else if (key === "x-forwarded-proto" && value === "https") { - proto = "https"; - } - this._rawHeaders.push([key, value]); - }); - - // URL - const query = _req.getQuery(); - const pathname = _req.getUrl(); - this.url = `${proto}://${host}${pathname}${query ? `?${query}` : ""}`; - } - - get headers(): Headers { - if (!this._headers) { - this._headers = new Headers(this._rawHeaders); - } - return this._headers; - } -} +// --- peer --- function getPeer(ws: WebSocket, peers: Set): UWSPeer { const userData = ws.getUserData(); @@ -253,3 +221,40 @@ class UWSPeer extends Peer<{ this._internal.uws.ws.close(); } } + +// --- web compat --- + +class UWSReqProxy { + private _headers?: Headers; + private _rawHeaders: [string, string][] = []; + url: string; + + constructor(_req: HttpRequest) { + // We need to precompute values since uws doesn't provide them after handler. + + // Headers + let host = "localhost"; + let proto = "http"; + // eslint-disable-next-line unicorn/no-array-for-each + _req.forEach((key, value) => { + if (key === "host") { + host = value; + } else if (key === "x-forwarded-proto" && value === "https") { + proto = "https"; + } + this._rawHeaders.push([key, value]); + }); + + // URL + const query = _req.getQuery(); + const pathname = _req.getUrl(); + this.url = `${proto}://${host}${pathname}${query ? `?${query}` : ""}`; + } + + get headers(): Headers { + if (!this._headers) { + this._headers = new Headers(this._rawHeaders); + } + return this._headers; + } +} diff --git a/src/hooks.ts b/src/hooks.ts index 7aa1833..0ce263e 100644 --- a/src/hooks.ts +++ b/src/hooks.ts @@ -1,9 +1,7 @@ -import type { - AdapterHooks, - AdapterOptions, - Hooks, - MaybePromise, -} from "./types.ts"; +import type { AdapterOptions } from "./adapter.ts"; +import type { WSError } from "./error.ts"; +import type { Peer } from "./peer.ts"; +import type { Message } from "./message.ts"; export class AdapterHookable { options: AdapterOptions; @@ -49,3 +47,94 @@ export class AdapterHookable { return this.options.adapterHooks?.[name]?.apply(undefined, args); } } + +// --- types --- + +export function defineHooks = Partial>( + hooks: T, +): T { + return hooks; +} + +export type ResolveHooks = ( + info: RequestInit | Peer, +) => Partial | Promise>; + +export type MaybePromise = T | Promise; + +type HookFn = ( + info: Peer, + ...args: ArgsT +) => MaybePromise; + +export interface Hooks { + /** Upgrading */ + upgrade: ( + request: + | Request + | { + url: string; + headers: Headers; + }, + ) => MaybePromise; + + /** A message is received */ + message: (peer: Peer, message: Message) => MaybePromise; + + /** A socket is opened */ + open: (peer: Peer) => MaybePromise; + + /** A socket is closed */ + close: ( + peer: Peer, + details: { code?: number; reason?: string }, + ) => MaybePromise; + + /** An error occurs */ + error: (peer: Peer, error: WSError) => MaybePromise; +} + +export interface AdapterHooks extends Record> { + // Bun + "bun:message": HookFn<[ws: any, message: any]>; + "bun:open": HookFn<[ws: any]>; + "bun:close": HookFn<[ws: any]>; + "bun:drain": HookFn<[]>; + "bun:error": HookFn<[ws: any, error: any]>; + "bun:ping": HookFn<[ws: any, data: any]>; + "bun:pong": HookFn<[ws: any, data: any]>; + + // Cloudflare + "cloudflare:accept": HookFn<[]>; + "cloudflare:message": HookFn<[event: any]>; + "cloudflare:error": HookFn<[event: any]>; + "cloudflare:close": HookFn<[event: any]>; + + // Deno + "deno:open": HookFn<[]>; + "deno:message": HookFn<[event: any]>; + "deno:close": HookFn<[]>; + "deno:error": HookFn<[error: any]>; + + // ws (Node) + "node:open": HookFn<[]>; + "node:message": HookFn<[data: any, isBinary: boolean]>; + "node:close": HookFn<[code: number, reason: Buffer]>; + "node:error": HookFn<[error: any]>; + "node:ping": HookFn<[data: Buffer]>; + "node:pong": HookFn<[data: Buffer]>; + "node:unexpected-response": HookFn<[req: any, res: any]>; + "node:upgrade": HookFn<[req: any]>; + + // uws (Node) + "uws:open": HookFn<[ws: any]>; + "uws:message": HookFn<[ws: any, message: any, isBinary: boolean]>; + "uws:close": HookFn<[ws: any, code: number, message: any]>; + "uws:ping": HookFn<[ws: any, message: any]>; + "uws:pong": HookFn<[ws: any, message: any]>; + "uws:drain": HookFn<[ws: any]>; + "uws:upgrade": HookFn<[res: any, req: any, context: any]>; + "uws:subscription": HookFn< + [ws: any, topic: any, newCount: number, oldCount: number] + >; +} diff --git a/src/index.ts b/src/index.ts index 85cbcf3..848c52a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,18 @@ -export * from "./hooks.ts"; -export * from "./error.ts"; -export * from "./message.ts"; -export * from "./peer.ts"; -export * from "./types.ts"; +// Hooks +export { defineHooks } from "./hooks.ts"; +export type { Hooks, AdapterHooks, ResolveHooks } from "./hooks.ts"; + +// Adapter +export { defineWebSocketAdapter } from "./adapter.ts"; +export type { Adapter, AdapterInstance, AdapterOptions } from "./adapter.ts"; + +// Message +export type { Message } from "./message.ts"; + +// Peer +export type { Peer } from "./peer.ts"; + +// Error +export type { WSError } from "./error.ts"; + +// Removed from 0.2.x: createCrossWS, Caller, WSRequest, CrossWS diff --git a/src/message.ts b/src/message.ts index 400b75a..4dbe3d9 100644 --- a/src/message.ts +++ b/src/message.ts @@ -1,4 +1,4 @@ -import { toBufferLike } from "./_utils.ts"; +import { toBufferLike } from "./utils.ts"; export class Message { constructor( diff --git a/src/types.ts b/src/types.ts deleted file mode 100644 index a9069a2..0000000 --- a/src/types.ts +++ /dev/null @@ -1,119 +0,0 @@ -import { WSError } from "./error.ts"; -import type { Message } from "./message.ts"; -import type { Peer } from "./peer.ts"; - -// --- Adapter --- - -export interface AdapterInstance { - readonly peers: Set; - readonly publish: Peer["publish"]; -} - -export interface AdapterOptions { - resolve?: ResolveHooks; - hooks?: Hooks; - adapterHooks?: AdapterHooks; -} - -export type Adapter< - AdapterT extends AdapterInstance = AdapterInstance, - Options extends AdapterOptions = AdapterOptions, -> = (options?: Options) => AdapterT; - -export function defineWebSocketAdapter< - AdapterT extends AdapterInstance = AdapterInstance, - Options extends AdapterOptions = AdapterOptions, ->(factory: Adapter) { - return factory; -} - -// --- Hooks --- - -export function defineHooks = Partial>( - hooks: T, -): T { - return hooks; -} - -export type ResolveHooks = ( - info: RequestInit | Peer, -) => Partial | Promise>; - -export type MaybePromise = T | Promise; - -type HookFn = ( - info: Peer, - ...args: ArgsT -) => MaybePromise; - -export interface Hooks { - /** Upgrading */ - upgrade: ( - request: - | Request - | { - url: string; - headers: Headers; - }, - ) => MaybePromise; - - /** A message is received */ - message: (peer: Peer, message: Message) => MaybePromise; - - /** A socket is opened */ - open: (peer: Peer) => MaybePromise; - - /** A socket is closed */ - close: ( - peer: Peer, - details: { code?: number; reason?: string }, - ) => MaybePromise; - - /** An error occurs */ - error: (peer: Peer, error: WSError) => MaybePromise; -} - -export interface AdapterHooks extends Record> { - // Bun - "bun:message": HookFn<[ws: any, message: any]>; - "bun:open": HookFn<[ws: any]>; - "bun:close": HookFn<[ws: any]>; - "bun:drain": HookFn<[]>; - "bun:error": HookFn<[ws: any, error: any]>; - "bun:ping": HookFn<[ws: any, data: any]>; - "bun:pong": HookFn<[ws: any, data: any]>; - - // Cloudflare - "cloudflare:accept": HookFn<[]>; - "cloudflare:message": HookFn<[event: any]>; - "cloudflare:error": HookFn<[event: any]>; - "cloudflare:close": HookFn<[event: any]>; - - // Deno - "deno:open": HookFn<[]>; - "deno:message": HookFn<[event: any]>; - "deno:close": HookFn<[]>; - "deno:error": HookFn<[error: any]>; - - // ws (Node) - "node:open": HookFn<[]>; - "node:message": HookFn<[data: any, isBinary: boolean]>; - "node:close": HookFn<[code: number, reason: Buffer]>; - "node:error": HookFn<[error: any]>; - "node:ping": HookFn<[data: Buffer]>; - "node:pong": HookFn<[data: Buffer]>; - "node:unexpected-response": HookFn<[req: any, res: any]>; - "node:upgrade": HookFn<[req: any]>; - - // uws (Node) - "uws:open": HookFn<[ws: any]>; - "uws:message": HookFn<[ws: any, message: any, isBinary: boolean]>; - "uws:close": HookFn<[ws: any, code: number, message: any]>; - "uws:ping": HookFn<[ws: any, message: any]>; - "uws:pong": HookFn<[ws: any, message: any]>; - "uws:drain": HookFn<[ws: any]>; - "uws:upgrade": HookFn<[res: any, req: any, context: any]>; - "uws:subscription": HookFn< - [ws: any, topic: any, newCount: number, oldCount: number] - >; -} diff --git a/src/_utils.ts b/src/utils.ts similarity index 74% rename from src/_utils.ts rename to src/utils.ts index 029fdf0..d7f0b44 100644 --- a/src/_utils.ts +++ b/src/utils.ts @@ -1,6 +1,3 @@ -import type { Peer } from "./peer.ts"; -import { AdapterInstance } from "./types.ts"; - type BufferLike = string | Buffer | Uint8Array | ArrayBuffer; export function toBufferLike(val: any): BufferLike { @@ -60,16 +57,3 @@ export function isPlainObject(value: unknown): boolean { return true; } - -export function adapterUtils(peers: Set) { - return { - peers, - publish(topic: string, message: any, options) { - const firstPeer = peers.values().next().value as Peer; - if (firstPeer) { - firstPeer.send(message, options); - firstPeer.publish(topic, message, options); - } - }, - } satisfies AdapterInstance; -} diff --git a/test/unit.test.ts b/test/unit.test.ts index 8b9f145..39419b9 100644 --- a/test/unit.test.ts +++ b/test/unit.test.ts @@ -1,5 +1,5 @@ import { test, expect } from "vitest"; -import { toBufferLike } from "../src/_utils"; +import { toBufferLike } from "../src/utils"; test("toBufferLike", () => { expect(toBufferLike(undefined)).toBe("");