UNPKG

actionhero

Version:

The reusable, scalable, and quick node.js API server for stateless and stateful applications

146 lines (133 loc) 3.73 kB
import { api, redis, Initializer, Connection } from "../index"; /** * ```js *var connectionMiddleware = { *name: 'connection middleware', *priority: 1000, *create: (connection) => { * // do stuff *}, *destroy:(connection) => { * // do stuff *} *} * ``` */ export interface ConnectionMiddleware { /**Unique name for the middleware. */ name: string; /**Module load order. Defaults to `api.config.general.defaultMiddlewarePriority`. */ priority?: number; /**Called for each new connection when it is created. Connection is passed to the event handler*/ create?: Function; /**Called for each connection before it is destroyed. Connection is passed to the event handler*/ destroy?: Function; } export interface ConnectionsApi { connections: { [key: string]: Connection; }; middleware: { [key: string]: ConnectionMiddleware; }; globalMiddleware: Array<string>; allowedVerbs: Array<string>; cleanConnection: Function; apply: ( connectionId: string, method?: string, args?: any ) => Promise<Connection>; addMiddleware: (ConnectionMiddleware) => void; } export class Connections extends Initializer { constructor() { super(); this.name = "connections"; this.loadPriority = 400; } async initialize(config) { api.connections = <ConnectionsApi>{ connections: {}, middleware: {}, globalMiddleware: [], allowedVerbs: [ "quit", "exit", "documentation", "paramAdd", "paramDelete", "paramView", "paramsView", "paramsDelete", "roomAdd", "roomLeave", "roomView", "detailsView", "say", ], /** * Find a connection on any server in the cluster and call a method on it. */ apply: async (connectionId: string, method: string, args: any) => { return redis.doCluster( "api.connections.applyResponder", [connectionId, method, args], connectionId, true ); }, applyResponder: async (connectionId, method, args) => { const connection: Connection = api.connections.connections[connectionId]; if (!connection) { return; } if (method && args) { if (method === "sendMessage" || method === "sendFile") { await connection[method](args); } else { await connection[method].apply(connection, args); } } return api.connections.cleanConnection(connection); }, /** * Add a middleware component to connection handling. */ addMiddleware: (data: ConnectionMiddleware) => { if (!data.name) { throw new Error("middleware.name is required"); } if (!data.priority) { data.priority = config.general.defaultMiddlewarePriority; } data.priority = Number(data.priority); api.connections.middleware[data.name] = data; api.connections.globalMiddleware.push(data.name); api.connections.globalMiddleware.sort((a, b) => { if ( api.connections.middleware[a].priority > api.connections.middleware[b].priority ) { return 1; } else { return -1; } }); }, cleanConnection: (connection: Connection) => { const clean = {}; for (const i in connection) { if (i !== "rawConnection" && i !== "api") { try { JSON.stringify(connection[i]); clean[i] = connection[i]; } catch (error) {} } } return clean; }, }; } }