UNPKG

@boringnode/transmit

Version:

A framework agnostic Server-Sent-Event library

53 lines (52 loc) 1.79 kB
/* * @boringnode/transmit * * @license MIT * @copyright Boring Node */ import { Transform } from 'node:stream'; import { dataToString } from './utils.js'; export class Stream extends Transform { #uid; constructor(uid, request) { super({ objectMode: true }); this.#uid = uid; if (request?.socket) { request.socket.setKeepAlive(true); request.socket.setNoDelay(true); request.socket.setTimeout(0); } } getUid() { return this.#uid; } pipe(destination, options, injectResponseHeaders = {}) { if (destination.writeHead) { // @see https://github.com/dunglas/mercure/blob/9e080c8dc9a141d4294412d14efdecfb15bf7f43/subscribe.go#L219 destination.writeHead(200, { ...injectResponseHeaders, 'Cache-Control': 'private, no-cache, no-store, must-revalidate, max-age=0, no-transform', 'Connection': 'keep-alive', 'Content-Type': 'text/event-stream', 'Expire': '0', 'Pragma': 'no-cache', // @see https://www.nginx.com/resources/wiki/start/topics/examples/x-accel/#x-accel-buffering 'X-Accel-Buffering': 'no', }); destination.flushHeaders?.(); } // Some clients (Safari) don't trigger onopen until the first frame is received. destination.write(':ok\n\n'); return super.pipe(destination, options); } _transform(message, _encoding, callback) { if (message.data) { this.push(dataToString(message.data)); } this.push('\n'); callback(); } writeMessage(message, encoding, cb) { return this.write(message, encoding, cb); } }