UNPKG

@boringnode/transmit

Version:

A framework agnostic Server-Sent-Event library

72 lines (71 loc) 2.2 kB
/* * @boringnode/transmit * * @license MIT * @copyright Boring Node */ import { Stream } from './stream.js'; import { Storage } from './storage.js'; export class StreamManager { #storage; #securedChannels = new Map(); constructor() { this.#storage = new Storage(); } createStream({ uid, context, request, response, injectResponseHeaders, onConnect, onDisconnect, }) { const stream = new Stream(uid, request); stream.pipe(response, undefined, injectResponseHeaders); this.#storage.add(stream); onConnect?.({ uid, context }); response.on('close', () => { this.#storage.remove(stream); onDisconnect?.({ uid, context }); }); return stream; } async subscribe({ uid, channel, context, skipAuthorization = false, onSubscribe, }) { if (!skipAuthorization) { const canAccessChannel = await this.verifyAccess(channel, context); if (!canAccessChannel) { return false; } } this.#storage.subscribe(uid, channel); onSubscribe?.({ uid, channel, context: context }); return true; } async unsubscribe({ uid, channel, context, onUnsubscribe }) { this.#storage.unsubscribe(uid, channel); onUnsubscribe?.({ uid, channel, context: context }); return true; } authorize(channel, callback) { this.#storage.secure(channel); this.#securedChannels.set(channel, callback); } async verifyAccess(channel, context) { const definitions = this.#storage.getSecuredChannelDefinition(channel); if (!definitions) { return true; } const callback = this.#securedChannels.get(definitions.channel); try { return await callback(context, definitions.params); } catch (e) { return false; } } /** * Get all subscribers */ getAllSubscribers() { return this.#storage.getAllSubscribers(); } /** * Find all subscribers to a channel */ findByChannel(channel) { return this.#storage.findByChannel(channel); } }