@brainstack/bridge-server
Advanced tools
Comparing version 1.0.6 to 2.0.1
"use strict"; | ||
// import { Server } from "ws"; | ||
// import {BridgeServerOption } from "../abstraction"; | ||
// import { createBridgeServer} from "../implementation"; | ||
// import { Logger, LoggerIntegration } from "@brainstack/log"; | ||
// import { EventHub } from "@brainstack/hub"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const ws_1 = require("ws"); | ||
const implementation_1 = require("../implementation"); | ||
// Mock the WebSocket server instance | ||
jest.mock("ws", () => ({ | ||
Server: jest.fn().mockImplementation(() => ({ | ||
on: jest.fn(), | ||
close: jest.fn(), | ||
})), | ||
})); | ||
describe("createBridgeServer", () => { | ||
let ws_server; | ||
beforeEach(() => { | ||
// Reset the mock WebSocket server instance before each test | ||
ws_1.Server.mockClear(); | ||
ws_server = new ws_1.Server(); | ||
}); | ||
it("creates a bridge server instance with default options", () => { | ||
const server = (0, implementation_1.createBridgeServer)(); | ||
expect(server.logger).toBeDefined(); | ||
expect(server.hub).toBeDefined(); | ||
expect(server.ws_server).toBeUndefined(); | ||
}); | ||
it("creates a bridge server instance with custom options", () => { | ||
const logger = { | ||
info: jest.fn(), | ||
error: jest.fn(), | ||
log: jest.fn(), | ||
integrations: [], | ||
level: 0, | ||
changeLogLevel: jest.fn(), | ||
addIntegration: jest.fn(), | ||
removeIntegration: jest.fn(), | ||
warn: function (...message) { | ||
throw new Error("Function not implemented."); | ||
}, | ||
verbose: jest.fn() | ||
}; | ||
const hub = { | ||
emit: jest.fn(), | ||
on: jest.fn(), | ||
uuid: "" | ||
}; | ||
const options = { | ||
logger, | ||
hub, | ||
ws_server, | ||
}; | ||
const server = (0, implementation_1.createBridgeServer)(options); | ||
expect(server.logger).toBe(logger); | ||
expect(server.hub).toBe(hub); | ||
expect(server.ws_server).toBe(ws_server); | ||
}); | ||
it("starts listening for incoming connections", () => { | ||
const server = (0, implementation_1.createBridgeServer)({ ws_server }); | ||
const options = { host: "localhost", port: 3000 }; | ||
server.listen(options); | ||
expect(ws_server.on).toHaveBeenCalledWith("listening", expect.any(Function)); | ||
expect(ws_server.on).toHaveBeenCalledWith("connection", expect.any(Function)); | ||
expect(ws_server.on).toHaveBeenCalledWith("close", expect.any(Function)); | ||
expect(ws_server.on).toHaveBeenCalledWith("error", expect.any(Function)); | ||
}); | ||
it("closes the WebSocket server instance", () => { | ||
const server = (0, implementation_1.createBridgeServer)({ ws_server }); | ||
server.close(); | ||
expect(ws_server.close).toHaveBeenCalled(); | ||
}); | ||
}); |
@@ -1,61 +0,11 @@ | ||
import { Server } from "ws"; | ||
import { EventHub } from "@brainstack/hub"; | ||
import { WebSocket } from "ws"; | ||
import { Logger } from "@brainstack/log"; | ||
/** | ||
* Interface representing a bridge server. | ||
*/ | ||
export interface BridgeServer { | ||
/** | ||
* Starts listening on the specified socket configuration. | ||
* @param config - The socket configuration for the server. | ||
* @returns The WebSocket server instance. | ||
*/ | ||
listen: (options: { | ||
host: string; | ||
port: number; | ||
}) => Server; | ||
/** | ||
* Closes the bridge server. | ||
*/ | ||
close: () => void; | ||
/** | ||
* The logger instance for the bridge server. | ||
*/ | ||
logger: Logger; | ||
/** | ||
* The event hub instance for the bridge server. | ||
*/ | ||
hub: EventHub; | ||
/** | ||
* The WebSocket server instance. | ||
*/ | ||
ws_server: Server | undefined; | ||
} | ||
/** | ||
* Options for configuring the bridge server. | ||
*/ | ||
export interface BridgeServerOption { | ||
/** | ||
* The logger instance for the bridge server. | ||
*/ | ||
export interface BridgeServerOptions { | ||
port?: number; | ||
host?: string; | ||
onConnection?: (socket: WebSocket) => void; | ||
onError?: (error: Error) => void; | ||
onClose?: () => void; | ||
logger?: Logger; | ||
/** | ||
* The event hub instance for the bridge server. | ||
*/ | ||
hub?: EventHub; | ||
/** | ||
* The WebSocket server instance. | ||
*/ | ||
ws_server?: Server; | ||
} | ||
/** | ||
* Factory function for creating a bridge server. | ||
*/ | ||
export interface BridgeServerFactory { | ||
/** | ||
* Creates a bridge server with the provided options. | ||
* @param options - The options for configuring the bridge server. | ||
* @returns The created bridge server instance. | ||
*/ | ||
(options?: BridgeServerOption): BridgeServer; | ||
} | ||
export type EventHandler = (data: any, socket: WebSocket) => void; |
@@ -1,12 +0,16 @@ | ||
import { BridgeServerFactory } from './abstraction'; | ||
/** | ||
* Factory function that creates a bridge server instance. | ||
* | ||
* @function | ||
* @param {BridgeServerOption} [options] - Optional configuration options for the bridge server. | ||
* @param {Logger} [options.logger] - Optional logger instance to use for logging. | ||
* @param {EventHub} [options.hub] - Optional event hub instance to use for communication. | ||
* @param {WebSocket.Server} [options.ws_server] - Optional WebSocket server instance to use for connections. | ||
* @returns {BridgeServerInstance} - An instance of the bridge server. | ||
*/ | ||
export declare const createBridgeServer: BridgeServerFactory; | ||
import { BridgeServerOptions, EventHandler } from './abstraction'; | ||
declare class BridgeServer { | ||
private port; | ||
private host; | ||
private wss?; | ||
private eventHandlers; | ||
private options; | ||
private logger; | ||
constructor(options: BridgeServerOptions); | ||
private setupListeners; | ||
private processMessage; | ||
on(event: string, handler: EventHandler): void; | ||
start(): void; | ||
emit(event: string, data: any): void; | ||
} | ||
export { BridgeServer }; |
"use strict"; | ||
var __rest = (this && this.__rest) || function (s, e) { | ||
var t = {}; | ||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) | ||
t[p] = s[p]; | ||
if (s != null && typeof Object.getOwnPropertySymbols === "function") | ||
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { | ||
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) | ||
t[p[i]] = s[p[i]]; | ||
} | ||
return t; | ||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
var desc = Object.getOwnPropertyDescriptor(m, k); | ||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { | ||
desc = { enumerable: true, get: function() { return m[k]; } }; | ||
} | ||
Object.defineProperty(o, k2, desc); | ||
}) : (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
o[k2] = m[k]; | ||
})); | ||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { | ||
Object.defineProperty(o, "default", { enumerable: true, value: v }); | ||
}) : function(o, v) { | ||
o["default"] = v; | ||
}); | ||
var __importStar = (this && this.__importStar) || function (mod) { | ||
if (mod && mod.__esModule) return mod; | ||
var result = {}; | ||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); | ||
__setModuleDefault(result, mod); | ||
return result; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.createBridgeServer = void 0; | ||
const ws_1 = require("ws"); | ||
const hub_1 = require("@brainstack/hub"); | ||
exports.BridgeServer = void 0; | ||
const log_1 = require("@brainstack/log"); | ||
/** | ||
* Handles the "listening" event of the WebSocket server. | ||
* @param logger - The logger instance for the bridge server. | ||
* @param hub - The event hub instance for the bridge server. | ||
* @param options - The socket configuration for the server. | ||
*/ | ||
const onListening = (logger, hub, options) => { | ||
logger.info(`π Bridge server started on `, options.host, options.port); | ||
hub.emit('start'); | ||
}; | ||
/** | ||
* Handles the "connection" event of the WebSocket server. | ||
* @param logger - The logger instance for the bridge server. | ||
* @param hub - The event hub instance for the bridge server. | ||
* @param ws - The WebSocket instance for the connection. | ||
*/ | ||
const onConnection = (logger, hub, ws) => { | ||
const { url } = ws; | ||
logger.info(`π Client connected: `, url); | ||
hub.emit('connection', ws); | ||
ws.on('message', (message) => { | ||
const ws_1 = __importStar(require("ws")); | ||
class BridgeServer { | ||
constructor(options) { | ||
this.port = options.port || 3000; | ||
this.host = options.host || 'localhost'; | ||
this.options = options; | ||
this.logger = options.logger || (0, log_1.createLogger)(); | ||
this.eventHandlers = new Map(); | ||
} | ||
setupListeners() { | ||
var _a; | ||
logger.log(`π¬ Message Received: `, message); | ||
(_a = this.wss) === null || _a === void 0 ? void 0 : _a.on('connection', (ws) => { | ||
var _a, _b; | ||
this.logger.log('π Client connected'); | ||
(_b = (_a = this.options).onConnection) === null || _b === void 0 ? void 0 : _b.call(_a, ws); | ||
ws.on('message', (message) => { | ||
this.logger.log('π¬ Message Received: ', message); | ||
this.processMessage(message, ws); | ||
}); | ||
ws.on('close', () => { | ||
var _a, _b; | ||
this.logger.log('β οΈ Connection closed'); | ||
(_b = (_a = this.options).onClose) === null || _b === void 0 ? void 0 : _b.call(_a); | ||
}); | ||
ws.on('error', (error) => { | ||
var _a, _b; | ||
this.logger.error('β Error:', error); | ||
(_b = (_a = this.options).onError) === null || _b === void 0 ? void 0 : _b.call(_a, error); | ||
}); | ||
}); | ||
} | ||
processMessage(message, socket) { | ||
let parsedMessage; | ||
try { | ||
const _b = JSON.parse(((_a = message === null || message === void 0 ? void 0 : message.data) === null || _a === void 0 ? void 0 : _a.toString()) || '{}'), { event = 'unknown' } = _b, payload = __rest(_b, ["event"]); | ||
hub.emit(event, payload); | ||
parsedMessage = JSON.parse(message); | ||
} | ||
catch (err) { | ||
hub.emit("message", message); | ||
catch (error) { | ||
this.logger.error('Error parsing message:', message); | ||
return; | ||
} | ||
}); | ||
}; | ||
/** | ||
* Handles the "close" event of the WebSocket server. | ||
* @param logger - The logger instance for the bridge server. | ||
* @param hub - The event hub instance for the bridge server. | ||
*/ | ||
const onClose = (logger, hub) => { | ||
logger.info(`β οΈ Bridge server closed`); | ||
hub.emit('close'); | ||
}; | ||
/** | ||
* Handles the "error" event of the WebSocket server. | ||
* @param logger - The logger instance for the bridge server. | ||
* @param hub - The event hub instance for the bridge server. | ||
* @param error - The error that occurred. | ||
*/ | ||
const onError = (logger, hub, error) => { | ||
logger.error(`βBridge server error: ${error}`); | ||
hub.emit('error', error); | ||
}; | ||
/** | ||
* Factory function that creates a bridge server instance. | ||
* | ||
* @function | ||
* @param {BridgeServerOption} [options] - Optional configuration options for the bridge server. | ||
* @param {Logger} [options.logger] - Optional logger instance to use for logging. | ||
* @param {EventHub} [options.hub] - Optional event hub instance to use for communication. | ||
* @param {WebSocket.Server} [options.ws_server] - Optional WebSocket server instance to use for connections. | ||
* @returns {BridgeServerInstance} - An instance of the bridge server. | ||
*/ | ||
const createBridgeServer = (options) => { | ||
var _a, _b; | ||
const logger = (_a = options === null || options === void 0 ? void 0 : options.logger) !== null && _a !== void 0 ? _a : (0, log_1.createLogger)(); | ||
const hub = (_b = options === null || options === void 0 ? void 0 : options.hub) !== null && _b !== void 0 ? _b : (0, hub_1.createEventHub)(); | ||
const ws_server = options === null || options === void 0 ? void 0 : options.ws_server; | ||
/** | ||
* Starts listening for incoming connections on the specified host and port. | ||
* | ||
* @function | ||
* @param {object} options - Configuration options for the server. | ||
* @param {string} options.host - Host address to listen on. | ||
* @param {number} options.port - Port number to listen on. | ||
* @returns {WebSocket.Server} - The WebSocket server instance used for connections. | ||
*/ | ||
const listen = (options) => { | ||
const server = ws_server || new ws_1.Server(options); | ||
server.on('listening', () => onListening(logger, hub, options)); | ||
server.on('connection', (ws) => onConnection(logger, hub, ws)); | ||
server.on('close', () => onClose(logger, hub)); | ||
server.on('error', (error) => onError(logger, hub, error)); | ||
return server; | ||
}; | ||
const close = () => { | ||
if (ws_server) { | ||
ws_server.close(); | ||
if (parsedMessage && parsedMessage.event) { | ||
const handlers = this.eventHandlers.get(parsedMessage.event); | ||
handlers === null || handlers === void 0 ? void 0 : handlers.forEach(handler => handler(parsedMessage.data, socket)); | ||
} | ||
}; | ||
return { listen, close, logger, hub, ws_server }; | ||
}; | ||
exports.createBridgeServer = createBridgeServer; | ||
} | ||
on(event, handler) { | ||
var _a; | ||
if (!this.eventHandlers.has(event)) { | ||
this.eventHandlers.set(event, []); | ||
} | ||
(_a = this.eventHandlers.get(event)) === null || _a === void 0 ? void 0 : _a.push(handler); | ||
} | ||
start() { | ||
this.wss = new ws_1.Server({ port: this.port, host: this.host }); | ||
this.setupListeners(); | ||
this.logger.log(`Server started at ws://${this.host}:${this.port}`); | ||
} | ||
emit(event, data) { | ||
var _a; | ||
(_a = this.wss) === null || _a === void 0 ? void 0 : _a.clients.forEach((client) => { | ||
if (client.readyState === ws_1.default.OPEN) { | ||
client.send(JSON.stringify({ event, data })); | ||
} | ||
}); | ||
} | ||
} | ||
exports.BridgeServer = BridgeServer; |
{ | ||
"name": "@brainstack/bridge-server", | ||
"version": "1.0.6", | ||
"version": "2.0.1", | ||
"description": "Brainstack Bridge Server", | ||
@@ -31,7 +31,7 @@ "main": "dist/index.js", | ||
"dependencies": { | ||
"@brainstack/hub": "^1.1.49", | ||
"@brainstack/log": "^1.1.52", | ||
"@brainstack/hub": "^1.1.50", | ||
"@brainstack/log": "^1.1.53", | ||
"ws": "^8.13.0" | ||
}, | ||
"gitHead": "3be7f14f6fa3f3f36d5c963b569660925c556bcc" | ||
"gitHead": "dde98573038f0dc167e149d4a2abd47d084e3966" | ||
} |
@@ -1,89 +0,91 @@ | ||
import { Server } from "ws"; | ||
import {BridgeServerOption } from "../abstraction"; | ||
import { createBridgeServer} from "../implementation"; | ||
import { Logger, LoggerIntegration } from "@brainstack/log"; | ||
import { EventHub } from "@brainstack/hub"; | ||
// import { Server } from "ws"; | ||
// import {BridgeServerOption } from "../abstraction"; | ||
// import { createBridgeServer} from "../implementation"; | ||
// import { Logger, LoggerIntegration } from "@brainstack/log"; | ||
// import { EventHub } from "@brainstack/hub"; | ||
// Mock the WebSocket server instance | ||
jest.mock("ws", () => ({ | ||
Server: jest.fn().mockImplementation(() => ({ | ||
on: jest.fn(), | ||
close: jest.fn(), | ||
})), | ||
})); | ||
// // Mock the WebSocket server instance | ||
// jest.mock("ws", () => ({ | ||
// Server: jest.fn().mockImplementation(() => ({ | ||
// on: jest.fn(), | ||
// close: jest.fn(), | ||
// })), | ||
// })); | ||
describe("createBridgeServer", () => { | ||
let ws_server: Server; | ||
// describe("createBridgeServer", () => { | ||
// let ws_server: Server; | ||
beforeEach(() => { | ||
// Reset the mock WebSocket server instance before each test | ||
(Server as unknown as jest.Mock).mockClear(); | ||
ws_server = new Server(); | ||
}); | ||
// beforeEach(() => { | ||
// // Reset the mock WebSocket server instance before each test | ||
// (Server as unknown as jest.Mock).mockClear(); | ||
// ws_server = new Server(); | ||
// }); | ||
it("creates a bridge server instance with default options", () => { | ||
const server = createBridgeServer(); | ||
expect(server.logger).toBeDefined(); | ||
expect(server.hub).toBeDefined(); | ||
expect(server.ws_server).toBeUndefined(); | ||
}); | ||
// it("creates a bridge server instance with default options", () => { | ||
// const server = createBridgeServer(); | ||
// expect(server.logger).toBeDefined(); | ||
// expect(server.hub).toBeDefined(); | ||
// expect(server.ws_server).toBeUndefined(); | ||
// }); | ||
it("creates a bridge server instance with custom options", () => { | ||
const logger:Logger = { | ||
info: jest.fn(), | ||
error: jest.fn(), | ||
log: jest.fn(), | ||
integrations: [], | ||
level: 0, | ||
changeLogLevel: jest.fn(), | ||
addIntegration: jest.fn(), | ||
removeIntegration: jest.fn(), | ||
warn: function (...message: any[]): void { | ||
throw new Error("Function not implemented."); | ||
}, | ||
verbose: jest.fn() | ||
}; | ||
const hub: EventHub = { | ||
emit: jest.fn(), | ||
on:jest.fn(), | ||
uuid: "" | ||
}; | ||
const options: BridgeServerOption = { | ||
logger, | ||
hub, | ||
ws_server, | ||
}; | ||
const server = createBridgeServer(options); | ||
expect(server.logger).toBe(logger); | ||
expect(server.hub).toBe(hub); | ||
expect(server.ws_server).toBe(ws_server); | ||
}); | ||
// it("creates a bridge server instance with custom options", () => { | ||
// const logger:Logger = { | ||
// info: jest.fn(), | ||
// error: jest.fn(), | ||
// log: jest.fn(), | ||
// integrations: [], | ||
// level: 0, | ||
// changeLogLevel: jest.fn(), | ||
// addIntegration: jest.fn(), | ||
// removeIntegration: jest.fn(), | ||
// warn: function (...message: any[]): void { | ||
// throw new Error("Function not implemented."); | ||
// }, | ||
// verbose: jest.fn() | ||
// }; | ||
// const hub: EventHub = { | ||
// emit: jest.fn(), | ||
// on:jest.fn(), | ||
// uuid: "" | ||
// }; | ||
// const options: BridgeServerOption = { | ||
// logger, | ||
// hub, | ||
// ws_server, | ||
// }; | ||
// const server = createBridgeServer(options); | ||
// expect(server.logger).toBe(logger); | ||
// expect(server.hub).toBe(hub); | ||
// expect(server.ws_server).toBe(ws_server); | ||
// }); | ||
it("starts listening for incoming connections", () => { | ||
const server = createBridgeServer({ws_server}); | ||
const options = { host: "localhost", port: 3000 }; | ||
server.listen(options); | ||
expect(ws_server.on).toHaveBeenCalledWith( | ||
"listening", | ||
expect.any(Function) | ||
); | ||
expect(ws_server.on).toHaveBeenCalledWith( | ||
"connection", | ||
expect.any(Function) | ||
); | ||
expect(ws_server.on).toHaveBeenCalledWith( | ||
"close", | ||
expect.any(Function) | ||
); | ||
expect(ws_server.on).toHaveBeenCalledWith( | ||
"error", | ||
expect.any(Function) | ||
); | ||
}); | ||
// it("starts listening for incoming connections", () => { | ||
// const server = createBridgeServer({ws_server}); | ||
// const options = { host: "localhost", port: 3000 }; | ||
// server.listen(options); | ||
// expect(ws_server.on).toHaveBeenCalledWith( | ||
// "listening", | ||
// expect.any(Function) | ||
// ); | ||
// expect(ws_server.on).toHaveBeenCalledWith( | ||
// "connection", | ||
// expect.any(Function) | ||
// ); | ||
// expect(ws_server.on).toHaveBeenCalledWith( | ||
// "close", | ||
// expect.any(Function) | ||
// ); | ||
// expect(ws_server.on).toHaveBeenCalledWith( | ||
// "error", | ||
// expect.any(Function) | ||
// ); | ||
// }); | ||
it("closes the WebSocket server instance", () => { | ||
const server = createBridgeServer({ ws_server }); | ||
server.close(); | ||
expect(ws_server.close).toHaveBeenCalled(); | ||
}); | ||
}); | ||
// it("closes the WebSocket server instance", () => { | ||
// const server = createBridgeServer({ ws_server }); | ||
// server.close(); | ||
// expect(ws_server.close).toHaveBeenCalled(); | ||
// }); | ||
// }); | ||
export {} |
@@ -5,64 +5,11 @@ import { WebSocket, Server } from "ws"; | ||
/** | ||
* Interface representing a bridge server. | ||
*/ | ||
export interface BridgeServer { | ||
/** | ||
* Starts listening on the specified socket configuration. | ||
* @param config - The socket configuration for the server. | ||
* @returns The WebSocket server instance. | ||
*/ | ||
listen: (options: { host: string; port: number }) => Server; | ||
/** | ||
* Closes the bridge server. | ||
*/ | ||
close: () => void; | ||
/** | ||
* The logger instance for the bridge server. | ||
*/ | ||
logger: Logger; | ||
/** | ||
* The event hub instance for the bridge server. | ||
*/ | ||
hub: EventHub; | ||
/** | ||
* The WebSocket server instance. | ||
*/ | ||
ws_server: Server | undefined; | ||
} | ||
/** | ||
* Options for configuring the bridge server. | ||
*/ | ||
export interface BridgeServerOption { | ||
/** | ||
* The logger instance for the bridge server. | ||
*/ | ||
export interface BridgeServerOptions { | ||
port?: number; | ||
host?: string; | ||
onConnection?: (socket: WebSocket) => void; | ||
onError?: (error: Error) => void; | ||
onClose?: () => void; | ||
logger?: Logger; | ||
/** | ||
* The event hub instance for the bridge server. | ||
*/ | ||
hub?: EventHub; | ||
/** | ||
* The WebSocket server instance. | ||
*/ | ||
ws_server?: Server; | ||
} | ||
/** | ||
* Factory function for creating a bridge server. | ||
*/ | ||
export interface BridgeServerFactory { | ||
/** | ||
* Creates a bridge server with the provided options. | ||
* @param options - The options for configuring the bridge server. | ||
* @returns The created bridge server instance. | ||
*/ | ||
(options?: BridgeServerOption): BridgeServer; | ||
} | ||
export type EventHandler = (data: any, socket: WebSocket) => void |
@@ -1,116 +0,81 @@ | ||
import { WebSocket, Server } from 'ws'; | ||
import { createEventHub, EventHub } from '@brainstack/hub'; | ||
import { Logger, createLogger } from '@brainstack/log'; | ||
import { BridgeServerFactory, BridgeServerOption } from './abstraction'; | ||
import { BridgeServerOptions, EventHandler } from './abstraction'; | ||
import WebSocket, { Server as WebSocketServer } from 'ws'; | ||
/** | ||
* Handles the "listening" event of the WebSocket server. | ||
* @param logger - The logger instance for the bridge server. | ||
* @param hub - The event hub instance for the bridge server. | ||
* @param options - The socket configuration for the server. | ||
*/ | ||
const onListening = ( | ||
logger: Logger, | ||
hub: EventHub, | ||
options: { host: string; port: number } | ||
): void => { | ||
logger.info(`π Bridge server started on `, options.host, options.port); | ||
hub.emit('start'); | ||
}; | ||
class BridgeServer { | ||
private port: number; | ||
private host: string; | ||
private wss?: WebSocketServer; | ||
private eventHandlers: Map<string, EventHandler[]>; | ||
private options: BridgeServerOptions; | ||
private logger: Logger; | ||
/** | ||
* Handles the "connection" event of the WebSocket server. | ||
* @param logger - The logger instance for the bridge server. | ||
* @param hub - The event hub instance for the bridge server. | ||
* @param ws - The WebSocket instance for the connection. | ||
*/ | ||
const onConnection = (logger: Logger, hub: EventHub, ws: WebSocket): void => { | ||
const { url } = ws; | ||
constructor(options: BridgeServerOptions) { | ||
this.port = options.port || 3000; | ||
this.host = options.host || 'localhost'; | ||
this.options = options; | ||
this.logger = options.logger || createLogger() | ||
this.eventHandlers = new Map(); | ||
} | ||
logger.info(`π Client connected: `, url); | ||
hub.emit('connection', ws); | ||
private setupListeners(): void { | ||
this.wss?.on('connection', (ws: WebSocket) => { | ||
this.logger.log('π Client connected'); | ||
this.options.onConnection?.(ws); | ||
ws.on('message', (message: any) => { | ||
logger.log(`π¬ Message Received: `, message); | ||
ws.on('message', (message: string) => { | ||
this.logger.log('π¬ Message Received: ', message); | ||
this.processMessage(message, ws); | ||
}); | ||
try{ | ||
const { event = 'unknown', ...payload } = JSON.parse( | ||
message?.data?.toString() || '{}' | ||
); | ||
hub.emit(event, payload); | ||
}catch(err){ | ||
hub.emit("message", message); | ||
} | ||
}); | ||
}; | ||
ws.on('close', () => { | ||
this.logger.log('β οΈ Connection closed'); | ||
this.options.onClose?.(); | ||
}); | ||
/** | ||
* Handles the "close" event of the WebSocket server. | ||
* @param logger - The logger instance for the bridge server. | ||
* @param hub - The event hub instance for the bridge server. | ||
*/ | ||
const onClose = (logger: Logger, hub: EventHub): void => { | ||
logger.info(`β οΈ Bridge server closed`); | ||
hub.emit('close'); | ||
}; | ||
ws.on('error', (error: Error) => { | ||
this.logger.error('β Error:', error); | ||
this.options.onError?.(error); | ||
}); | ||
}); | ||
} | ||
/** | ||
* Handles the "error" event of the WebSocket server. | ||
* @param logger - The logger instance for the bridge server. | ||
* @param hub - The event hub instance for the bridge server. | ||
* @param error - The error that occurred. | ||
*/ | ||
const onError = (logger: Logger, hub: EventHub, error: any): void => { | ||
logger.error(`βBridge server error: ${error}`); | ||
hub.emit('error', error); | ||
}; | ||
private processMessage(message: string, socket: WebSocket): void { | ||
let parsedMessage; | ||
try { | ||
parsedMessage = JSON.parse(message); | ||
} catch (error) { | ||
this.logger.error('Error parsing message:', message); | ||
return; | ||
} | ||
/** | ||
* Factory function that creates a bridge server instance. | ||
* | ||
* @function | ||
* @param {BridgeServerOption} [options] - Optional configuration options for the bridge server. | ||
* @param {Logger} [options.logger] - Optional logger instance to use for logging. | ||
* @param {EventHub} [options.hub] - Optional event hub instance to use for communication. | ||
* @param {WebSocket.Server} [options.ws_server] - Optional WebSocket server instance to use for connections. | ||
* @returns {BridgeServerInstance} - An instance of the bridge server. | ||
*/ | ||
if (parsedMessage && parsedMessage.event) { | ||
const handlers = this.eventHandlers.get(parsedMessage.event); | ||
handlers?.forEach(handler => handler(parsedMessage.data, socket)); | ||
} | ||
} | ||
export const createBridgeServer: BridgeServerFactory = ( | ||
options?: BridgeServerOption | ||
) => { | ||
const logger = options?.logger ?? createLogger(); | ||
const hub = options?.hub ?? createEventHub(); | ||
const ws_server = options?.ws_server; | ||
public on(event: string, handler: EventHandler): void { | ||
if (!this.eventHandlers.has(event)) { | ||
this.eventHandlers.set(event, []); | ||
} | ||
this.eventHandlers.get(event)?.push(handler); | ||
} | ||
/** | ||
* Starts listening for incoming connections on the specified host and port. | ||
* | ||
* @function | ||
* @param {object} options - Configuration options for the server. | ||
* @param {string} options.host - Host address to listen on. | ||
* @param {number} options.port - Port number to listen on. | ||
* @returns {WebSocket.Server} - The WebSocket server instance used for connections. | ||
*/ | ||
const listen = (options: { host: string; port: number }): Server => { | ||
const server = ws_server || new Server(options); | ||
public start(): void { | ||
this.wss = new WebSocketServer({ port: this.port, host: this.host }); | ||
this.setupListeners(); | ||
this.logger.log(`Server started at ws://${this.host}:${this.port}`); | ||
} | ||
server.on('listening', () => onListening(logger, hub, options)); | ||
public emit(event: string, data: any): void { | ||
this.wss?.clients.forEach((client) => { | ||
if (client.readyState === WebSocket.OPEN) { | ||
client.send(JSON.stringify({ event, data })); | ||
} | ||
}); | ||
} | ||
} | ||
server.on('connection', (ws: WebSocket) => onConnection(logger, hub, ws)); | ||
server.on('close', () => onClose(logger, hub)); | ||
server.on('error', (error: any) => onError(logger, hub, error)); | ||
return server; | ||
}; | ||
const close = (): void => { | ||
if (ws_server) { | ||
ws_server.close(); | ||
} | ||
}; | ||
return { listen, close, logger, hub, ws_server }; | ||
}; | ||
export { BridgeServer }; |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
17747
395
1
Updated@brainstack/hub@^1.1.50
Updated@brainstack/log@^1.1.53