Socket
Socket
Sign inDemoInstall

better-sse

Package Overview
Dependencies
0
Maintainers
1
Versions
15
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.9.0 to 0.10.0

build/createEventBuffer.d.ts

2

./build/index.js

@@ -1,2 +0,2 @@

!function(e,t){if("object"==typeof exports&&"object"==typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var s=t();for(var i in s)("object"==typeof exports?exports:e)[i]=s[i]}}(global,(()=>(()=>{"use strict";var e={n:t=>{var s=t&&t.__esModule?()=>t.default:()=>t;return e.d(s,{a:s}),s},d:(t,s)=>{for(var i in s)e.o(s,i)&&!e.o(t,i)&&Object.defineProperty(t,i,{enumerable:!0,get:s[i]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r:e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})}},t={};e.r(t),e.d(t,{Channel:()=>f,Session:()=>u,createChannel:()=>v,createSession:()=>p});const s=require("http"),i=require("events");var r=e.n(i);class n extends(r()){addListener(e,t){return super.addListener(e,t)}prependListener(e,t){return super.prependListener(e,t)}prependOnceListener(e,t){return super.prependOnceListener(e,t)}on(e,t){return super.on(e,t)}once(e,t){return super.once(e,t)}emit(e,...t){return super.emit(e,...t)}off(e,t){return super.off(e,t)}removeListener(e,t){return super.removeListener(e,t)}}const o=e=>JSON.stringify(e),a=/(\r\n|\r|\n)/g,h=/\n+$/g,l=e=>{let t=e;return t=t.replace(a,"\n"),t=t.replace(h,""),t},d=require("crypto");let c;c=d.randomUUID?()=>(0,d.randomUUID)():()=>(0,d.randomBytes)(4).toString("hex");class u extends n{constructor(e,t,i={}){var r,n,a,h,d,u,p;super(),this.lastId="",this.isConnected=!1,this.state={},this.buffer="",this.initialize=()=>{var e,t,i;const r=`http://${this.req.headers.host}${this.req.url}`,n=new URL(r).searchParams;if(this.trustClientEventId){const s=null!==(i=null!==(t=null!==(e=this.req.headers["last-event-id"])&&void 0!==e?e:n.get("lastEventId"))&&void 0!==t?t:n.get("evs_last_event_id"))&&void 0!==i?i:"";this.lastId=s}const o={};this.res instanceof s.ServerResponse?(o["Content-Type"]="text/event-stream",o["Cache-Control"]="private, no-cache, no-store, no-transform, must-revalidate, max-age=0",o.Connection="keep-alive",o.Pragma="no-cache",o["X-Accel-Buffering"]="no"):(o["content-type"]="text/event-stream",o["cache-control"]="private, no-cache, no-store, no-transform, must-revalidate, max-age=0",o.pragma="no-cache",o["x-accel-buffering"]="no");for(const[e,t]of Object.entries(this.headers))o[e]=null!=t?t:"";this.res.writeHead(this.statusCode,o),n.has("padding")&&this.comment(" ".repeat(2049)).dispatch(),n.has("evs_preamble")&&this.comment(" ".repeat(2056)).dispatch(),null!==this.initialRetry&&this.retry(this.initialRetry).dispatch(),this.flush(),null!==this.keepAliveInterval&&(this.keepAliveTimer=setInterval(this.keepAlive,this.keepAliveInterval)),this.isConnected=!0,this.emit("connected")},this.onDisconnected=()=>{this.keepAliveTimer&&clearInterval(this.keepAliveTimer),this.isConnected=!1,this.emit("disconnected")},this.writeField=(e,t)=>{const s=this.sanitize(t);return this.buffer+=e+":"+s+"\n",this},this.keepAlive=()=>{this.comment().dispatch().flush()},this.data=e=>{const t=this.serialize(e);return this.writeField("data",t),this},this.id=(e="")=>(this.writeField("id",e),this.lastId=e,this),this.retry=e=>{const t=e.toString();return this.writeField("retry",t),this},this.comment=(e="")=>(this.writeField("",e),this),this.dispatch=()=>(this.buffer+="\n",this),this.flush=()=>(this.res.write(this.buffer),this.buffer="",this),this.push=(e,t="message",s=c())=>(this.event(t).id(s).data(e).dispatch().flush(),this.emit("push",e,t,s),this),this.stream=async(e,t={})=>{const{eventName:s="stream"}=t;return new Promise(((t,i)=>{e.on("data",(e=>{let t;t=Buffer.isBuffer(e)?e.toString():e,this.push(t,s)})),e.once("end",(()=>t(!0))),e.once("close",(()=>t(!0))),e.once("error",(e=>i(e)))}))},this.iterate=async(e,t={})=>{const{eventName:s="iteration"}=t;for await(const t of e)this.push(t,s)},this.req=e,this.res=t,this.serialize=null!==(r=i.serializer)&&void 0!==r?r:o,this.sanitize=null!==(n=i.sanitizer)&&void 0!==n?n:l,this.trustClientEventId=null===(a=i.trustClientEventId)||void 0===a||a,this.initialRetry=null===i.retry?null:null!==(h=i.retry)&&void 0!==h?h:2e3,this.keepAliveInterval=null===i.keepAlive?null:null!==(d=i.keepAlive)&&void 0!==d?d:1e4,this.statusCode=null!==(u=i.statusCode)&&void 0!==u?u:200,this.headers=null!==(p=i.headers)&&void 0!==p?p:{},this.req.once("close",this.onDisconnected),setImmediate(this.initialize)}event(e){return this.writeField("event",e),this}}const p=(...e)=>new Promise((t=>{const s=new u(...e);s.once("connected",(()=>{t(s)}))}));class f extends n{constructor(){super(),this.state={},this.sessions=new Set,this.broadcast=(e,t="message",s={})=>{const i=c();let r;r=s.filter?Array.from(this.sessions).filter(s.filter):this.sessions;for(const s of r)s.push(e,t,i);return this.emit("broadcast",e,t,i),this}}get activeSessions(){return Array.from(this.sessions)}get sessionCount(){return this.sessions.size}register(e){if(this.sessions.has(e))return this;if(!e.isConnected)throw new Error("Cannot register a non-active session.");return e.once("disconnected",(()=>{this.emit("session-disconnected",e),this.deregister(e)})),this.sessions.add(e),this.emit("session-registered",e),this}deregister(e){return this.sessions.has(e)?(this.sessions.delete(e),this.emit("session-deregistered",e),this):this}}const v=(...e)=>new f(...e);return t})()));
!function(e,t){if("object"==typeof exports&&"object"==typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var s=t();for(var i in s)("object"==typeof exports?exports:e)[i]=s[i]}}(global,(()=>(()=>{"use strict";var e={n:t=>{var s=t&&t.__esModule?()=>t.default:()=>t;return e.d(s,{a:s}),s},d:(t,s)=>{for(var i in s)e.o(s,i)&&!e.o(t,i)&&Object.defineProperty(t,i,{enumerable:!0,get:s[i]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r:e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})}},t={};e.r(t),e.d(t,{Channel:()=>b,EventBuffer:()=>d,Session:()=>v,createChannel:()=>g,createEventBuffer:()=>y,createSession:()=>m});const s=require("http"),i=e=>JSON.stringify(e),r=/(\r\n|\r|\n)/g,n=/\n+$/g,h=e=>{let t=e;return t=t.replace(r,"\n"),t=t.replace(n,""),t},o=require("crypto");let a;a=o.randomUUID?()=>(0,o.randomUUID)():()=>(0,o.randomBytes)(4).toString("hex");const l=e=>async(t,s={})=>{const{eventName:i="stream"}=s;return await new Promise(((s,r)=>{t.on("data",(t=>{let s;s=Buffer.isBuffer(t)?t.toString():t,e(s,i)})),t.once("end",(()=>s(!0))),t.once("close",(()=>s(!0))),t.once("error",(e=>r(e)))}))},c=e=>async(t,s={})=>{const{eventName:i="iteration"}=s;for await(const s of t)e(s,i)};class d{constructor(e={}){var t,s;this.buffer="",this.writeField=(e,t)=>{const s=this.sanitize(t);return this.buffer+=e+":"+s+"\n",this},this.data=e=>{const t=this.serialize(e);return this.writeField("data",t),this},this.id=(e="")=>(this.writeField("id",e),this),this.retry=e=>{const t=e.toString();return this.writeField("retry",t),this},this.comment=(e="")=>(this.writeField("",e),this),this.dispatch=()=>(this.buffer+="\n",this),this.push=(e,t="message",s=a())=>(this.event(t).id(s).data(e).dispatch(),this),this.stream=l(this.push),this.iterate=c(this.push),this.clear=()=>(this.buffer="",this),this.read=()=>this.buffer,this.serialize=null!==(t=e.serializer)&&void 0!==t?t:i,this.sanitize=null!==(s=e.sanitizer)&&void 0!==s?s:h}event(e){return this.writeField("event",e),this}}const u=require("events");var f=e.n(u);class p extends(f()){addListener(e,t){return super.addListener(e,t)}prependListener(e,t){return super.prependListener(e,t)}prependOnceListener(e,t){return super.prependOnceListener(e,t)}on(e,t){return super.on(e,t)}once(e,t){return super.once(e,t)}emit(e,...t){return super.emit(e,...t)}off(e,t){return super.off(e,t)}removeListener(e,t){return super.removeListener(e,t)}}class v extends p{constructor(e,t,r={}){var n,o,u,f,p,v,m;super(),this.lastId="",this.isConnected=!1,this.state={},this.initialize=()=>{var e,t,i;const r=`http://${this.req.headers.host}${this.req.url}`,n=new URL(r).searchParams;if(this.trustClientEventId){const s=null!==(i=null!==(t=null!==(e=this.req.headers["last-event-id"])&&void 0!==e?e:n.get("lastEventId"))&&void 0!==t?t:n.get("evs_last_event_id"))&&void 0!==i?i:"";this.lastId=s}const h={};this.res instanceof s.ServerResponse?(h["Content-Type"]="text/event-stream",h["Cache-Control"]="private, no-cache, no-store, no-transform, must-revalidate, max-age=0",h.Connection="keep-alive",h.Pragma="no-cache",h["X-Accel-Buffering"]="no"):(h["content-type"]="text/event-stream",h["cache-control"]="private, no-cache, no-store, no-transform, must-revalidate, max-age=0",h.pragma="no-cache",h["x-accel-buffering"]="no");for(const[e,t]of Object.entries(this.headers))h[e]=null!=t?t:"";this.res.writeHead(this.statusCode,h),n.has("padding")&&this.buffer.comment(" ".repeat(2049)).dispatch(),n.has("evs_preamble")&&this.buffer.comment(" ".repeat(2056)).dispatch(),null!==this.initialRetry&&this.buffer.retry(this.initialRetry).dispatch(),this.flush(),null!==this.keepAliveInterval&&(this.keepAliveTimer=setInterval(this.keepAlive,this.keepAliveInterval)),this.isConnected=!0,this.emit("connected")},this.onDisconnected=()=>{this.keepAliveTimer&&clearInterval(this.keepAliveTimer),this.isConnected=!1,this.emit("disconnected")},this.keepAlive=()=>{this.buffer.comment().dispatch(),this.flush()},this.data=e=>(this.buffer.data(e),this),this.id=(e="")=>(this.buffer.id(e),this.lastId=e,this),this.retry=e=>(this.buffer.retry(e),this),this.comment=e=>(this.buffer.comment(e),this),this.dispatch=()=>(this.buffer.dispatch(),this),this.flush=()=>(this.res.write(this.buffer.read()),this.buffer.clear(),this),this.push=(e,t="message",s=a())=>(this.buffer.push(e,t,s),this.flush(),this.lastId=s,this.emit("push",e,t,s),this),this.stream=l(this.push),this.iterate=c(this.push),this.batch=async e=>{if(e instanceof d)this.res.write(e.read());else{const t=new d({serializer:this.serialize,sanitizer:this.sanitize});await e(t),this.res.write(t.read())}},this.req=e,this.res=t;const b=null!==(n=r.serializer)&&void 0!==n?n:i,g=null!==(o=r.sanitizer)&&void 0!==o?o:h;this.serialize=b,this.sanitize=g,this.buffer=new d({serializer:b,sanitizer:g}),this.trustClientEventId=null===(u=r.trustClientEventId)||void 0===u||u,this.initialRetry=null===r.retry?null:null!==(f=r.retry)&&void 0!==f?f:2e3,this.keepAliveInterval=null===r.keepAlive?null:null!==(p=r.keepAlive)&&void 0!==p?p:1e4,this.statusCode=null!==(v=r.statusCode)&&void 0!==v?v:200,this.headers=null!==(m=r.headers)&&void 0!==m?m:{},this.req.once("close",this.onDisconnected),setImmediate(this.initialize)}event(e){return this.buffer.event(e),this}}const m=(...e)=>new Promise((t=>{const s=new v(...e);s.once("connected",(()=>{t(s)}))}));class b extends p{constructor(){super(),this.state={},this.sessions=new Set,this.broadcast=(e,t="message",s={})=>{const i=a(),r=s.filter?this.activeSessions.filter(s.filter):this.sessions;for(const s of r)s.push(e,t,i);return this.emit("broadcast",e,t,i),this}}get activeSessions(){return Array.from(this.sessions)}get sessionCount(){return this.sessions.size}register(e){if(this.sessions.has(e))return this;if(!e.isConnected)throw new Error("Cannot register a non-active session.");return e.once("disconnected",(()=>{this.emit("session-disconnected",e),this.deregister(e)})),this.sessions.add(e),this.emit("session-registered",e),this}deregister(e){return this.sessions.has(e)?(this.sessions.delete(e),this.emit("session-deregistered",e),this):this}}const g=(...e)=>new b(...e),y=(...e)=>new d(...e);return t})()));
//# sourceMappingURL=index.js.map

@@ -61,5 +61,12 @@ import { TypedEmitter, EventMap } from "./lib/TypedEmitter";

/**
* Broadcast an event with the given data and name to every active session registered with this channel.
* Broadcast an event to every active session registered with this channel.
*
* Under the hood this calls the `push` method on every active session.
*
* If no event name is given, the event name is set to `"message"`.
*
* Note that the broadcasted event will have the same ID across all receiving sessions instead of generating a unique ID for each.
*
* @param data - Data to write.
* @param eventName - Event name to write.
*/

@@ -66,0 +73,0 @@ broadcast: (data: unknown, eventName?: string, options?: BroadcastOptions<SessionState>) => this;

@@ -5,1 +5,5 @@ export * from "./Session";

export * from "./createChannel";
export * from "./EventBuffer";
export * from "./createEventBuffer";
export type { StreamOptions } from "./lib/createPushFromStream";
export type { IterateOptions } from "./lib/createPushFromIterable";

@@ -1,2 +0,2 @@

!function(e,t){if("object"==typeof exports&&"object"==typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var s=t();for(var i in s)("object"==typeof exports?exports:e)[i]=s[i]}}(global,(()=>(()=>{"use strict";var e={n:t=>{var s=t&&t.__esModule?()=>t.default:()=>t;return e.d(s,{a:s}),s},d:(t,s)=>{for(var i in s)e.o(s,i)&&!e.o(t,i)&&Object.defineProperty(t,i,{enumerable:!0,get:s[i]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r:e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})}},t={};e.r(t),e.d(t,{Channel:()=>f,Session:()=>u,createChannel:()=>v,createSession:()=>p});const s=require("http"),i=require("events");var r=e.n(i);class n extends(r()){addListener(e,t){return super.addListener(e,t)}prependListener(e,t){return super.prependListener(e,t)}prependOnceListener(e,t){return super.prependOnceListener(e,t)}on(e,t){return super.on(e,t)}once(e,t){return super.once(e,t)}emit(e,...t){return super.emit(e,...t)}off(e,t){return super.off(e,t)}removeListener(e,t){return super.removeListener(e,t)}}const o=e=>JSON.stringify(e),a=/(\r\n|\r|\n)/g,h=/\n+$/g,l=e=>{let t=e;return t=t.replace(a,"\n"),t=t.replace(h,""),t},d=require("crypto");let c;c=d.randomUUID?()=>(0,d.randomUUID)():()=>(0,d.randomBytes)(4).toString("hex");class u extends n{constructor(e,t,i={}){var r,n,a,h,d,u,p;super(),this.lastId="",this.isConnected=!1,this.state={},this.buffer="",this.initialize=()=>{var e,t,i;const r=`http://${this.req.headers.host}${this.req.url}`,n=new URL(r).searchParams;if(this.trustClientEventId){const s=null!==(i=null!==(t=null!==(e=this.req.headers["last-event-id"])&&void 0!==e?e:n.get("lastEventId"))&&void 0!==t?t:n.get("evs_last_event_id"))&&void 0!==i?i:"";this.lastId=s}const o={};this.res instanceof s.ServerResponse?(o["Content-Type"]="text/event-stream",o["Cache-Control"]="private, no-cache, no-store, no-transform, must-revalidate, max-age=0",o.Connection="keep-alive",o.Pragma="no-cache",o["X-Accel-Buffering"]="no"):(o["content-type"]="text/event-stream",o["cache-control"]="private, no-cache, no-store, no-transform, must-revalidate, max-age=0",o.pragma="no-cache",o["x-accel-buffering"]="no");for(const[e,t]of Object.entries(this.headers))o[e]=null!=t?t:"";this.res.writeHead(this.statusCode,o),n.has("padding")&&this.comment(" ".repeat(2049)).dispatch(),n.has("evs_preamble")&&this.comment(" ".repeat(2056)).dispatch(),null!==this.initialRetry&&this.retry(this.initialRetry).dispatch(),this.flush(),null!==this.keepAliveInterval&&(this.keepAliveTimer=setInterval(this.keepAlive,this.keepAliveInterval)),this.isConnected=!0,this.emit("connected")},this.onDisconnected=()=>{this.keepAliveTimer&&clearInterval(this.keepAliveTimer),this.isConnected=!1,this.emit("disconnected")},this.writeField=(e,t)=>{const s=this.sanitize(t);return this.buffer+=e+":"+s+"\n",this},this.keepAlive=()=>{this.comment().dispatch().flush()},this.data=e=>{const t=this.serialize(e);return this.writeField("data",t),this},this.id=(e="")=>(this.writeField("id",e),this.lastId=e,this),this.retry=e=>{const t=e.toString();return this.writeField("retry",t),this},this.comment=(e="")=>(this.writeField("",e),this),this.dispatch=()=>(this.buffer+="\n",this),this.flush=()=>(this.res.write(this.buffer),this.buffer="",this),this.push=(e,t="message",s=c())=>(this.event(t).id(s).data(e).dispatch().flush(),this.emit("push",e,t,s),this),this.stream=async(e,t={})=>{const{eventName:s="stream"}=t;return new Promise(((t,i)=>{e.on("data",(e=>{let t;t=Buffer.isBuffer(e)?e.toString():e,this.push(t,s)})),e.once("end",(()=>t(!0))),e.once("close",(()=>t(!0))),e.once("error",(e=>i(e)))}))},this.iterate=async(e,t={})=>{const{eventName:s="iteration"}=t;for await(const t of e)this.push(t,s)},this.req=e,this.res=t,this.serialize=null!==(r=i.serializer)&&void 0!==r?r:o,this.sanitize=null!==(n=i.sanitizer)&&void 0!==n?n:l,this.trustClientEventId=null===(a=i.trustClientEventId)||void 0===a||a,this.initialRetry=null===i.retry?null:null!==(h=i.retry)&&void 0!==h?h:2e3,this.keepAliveInterval=null===i.keepAlive?null:null!==(d=i.keepAlive)&&void 0!==d?d:1e4,this.statusCode=null!==(u=i.statusCode)&&void 0!==u?u:200,this.headers=null!==(p=i.headers)&&void 0!==p?p:{},this.req.once("close",this.onDisconnected),setImmediate(this.initialize)}event(e){return this.writeField("event",e),this}}const p=(...e)=>new Promise((t=>{const s=new u(...e);s.once("connected",(()=>{t(s)}))}));class f extends n{constructor(){super(),this.state={},this.sessions=new Set,this.broadcast=(e,t="message",s={})=>{const i=c();let r;r=s.filter?Array.from(this.sessions).filter(s.filter):this.sessions;for(const s of r)s.push(e,t,i);return this.emit("broadcast",e,t,i),this}}get activeSessions(){return Array.from(this.sessions)}get sessionCount(){return this.sessions.size}register(e){if(this.sessions.has(e))return this;if(!e.isConnected)throw new Error("Cannot register a non-active session.");return e.once("disconnected",(()=>{this.emit("session-disconnected",e),this.deregister(e)})),this.sessions.add(e),this.emit("session-registered",e),this}deregister(e){return this.sessions.has(e)?(this.sessions.delete(e),this.emit("session-deregistered",e),this):this}}const v=(...e)=>new f(...e);return t})()));
!function(e,t){if("object"==typeof exports&&"object"==typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var s=t();for(var i in s)("object"==typeof exports?exports:e)[i]=s[i]}}(global,(()=>(()=>{"use strict";var e={n:t=>{var s=t&&t.__esModule?()=>t.default:()=>t;return e.d(s,{a:s}),s},d:(t,s)=>{for(var i in s)e.o(s,i)&&!e.o(t,i)&&Object.defineProperty(t,i,{enumerable:!0,get:s[i]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r:e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})}},t={};e.r(t),e.d(t,{Channel:()=>b,EventBuffer:()=>d,Session:()=>v,createChannel:()=>g,createEventBuffer:()=>y,createSession:()=>m});const s=require("http"),i=e=>JSON.stringify(e),r=/(\r\n|\r|\n)/g,n=/\n+$/g,h=e=>{let t=e;return t=t.replace(r,"\n"),t=t.replace(n,""),t},o=require("crypto");let a;a=o.randomUUID?()=>(0,o.randomUUID)():()=>(0,o.randomBytes)(4).toString("hex");const l=e=>async(t,s={})=>{const{eventName:i="stream"}=s;return await new Promise(((s,r)=>{t.on("data",(t=>{let s;s=Buffer.isBuffer(t)?t.toString():t,e(s,i)})),t.once("end",(()=>s(!0))),t.once("close",(()=>s(!0))),t.once("error",(e=>r(e)))}))},c=e=>async(t,s={})=>{const{eventName:i="iteration"}=s;for await(const s of t)e(s,i)};class d{constructor(e={}){var t,s;this.buffer="",this.writeField=(e,t)=>{const s=this.sanitize(t);return this.buffer+=e+":"+s+"\n",this},this.data=e=>{const t=this.serialize(e);return this.writeField("data",t),this},this.id=(e="")=>(this.writeField("id",e),this),this.retry=e=>{const t=e.toString();return this.writeField("retry",t),this},this.comment=(e="")=>(this.writeField("",e),this),this.dispatch=()=>(this.buffer+="\n",this),this.push=(e,t="message",s=a())=>(this.event(t).id(s).data(e).dispatch(),this),this.stream=l(this.push),this.iterate=c(this.push),this.clear=()=>(this.buffer="",this),this.read=()=>this.buffer,this.serialize=null!==(t=e.serializer)&&void 0!==t?t:i,this.sanitize=null!==(s=e.sanitizer)&&void 0!==s?s:h}event(e){return this.writeField("event",e),this}}const u=require("events");var f=e.n(u);class p extends(f()){addListener(e,t){return super.addListener(e,t)}prependListener(e,t){return super.prependListener(e,t)}prependOnceListener(e,t){return super.prependOnceListener(e,t)}on(e,t){return super.on(e,t)}once(e,t){return super.once(e,t)}emit(e,...t){return super.emit(e,...t)}off(e,t){return super.off(e,t)}removeListener(e,t){return super.removeListener(e,t)}}class v extends p{constructor(e,t,r={}){var n,o,u,f,p,v,m;super(),this.lastId="",this.isConnected=!1,this.state={},this.initialize=()=>{var e,t,i;const r=`http://${this.req.headers.host}${this.req.url}`,n=new URL(r).searchParams;if(this.trustClientEventId){const s=null!==(i=null!==(t=null!==(e=this.req.headers["last-event-id"])&&void 0!==e?e:n.get("lastEventId"))&&void 0!==t?t:n.get("evs_last_event_id"))&&void 0!==i?i:"";this.lastId=s}const h={};this.res instanceof s.ServerResponse?(h["Content-Type"]="text/event-stream",h["Cache-Control"]="private, no-cache, no-store, no-transform, must-revalidate, max-age=0",h.Connection="keep-alive",h.Pragma="no-cache",h["X-Accel-Buffering"]="no"):(h["content-type"]="text/event-stream",h["cache-control"]="private, no-cache, no-store, no-transform, must-revalidate, max-age=0",h.pragma="no-cache",h["x-accel-buffering"]="no");for(const[e,t]of Object.entries(this.headers))h[e]=null!=t?t:"";this.res.writeHead(this.statusCode,h),n.has("padding")&&this.buffer.comment(" ".repeat(2049)).dispatch(),n.has("evs_preamble")&&this.buffer.comment(" ".repeat(2056)).dispatch(),null!==this.initialRetry&&this.buffer.retry(this.initialRetry).dispatch(),this.flush(),null!==this.keepAliveInterval&&(this.keepAliveTimer=setInterval(this.keepAlive,this.keepAliveInterval)),this.isConnected=!0,this.emit("connected")},this.onDisconnected=()=>{this.keepAliveTimer&&clearInterval(this.keepAliveTimer),this.isConnected=!1,this.emit("disconnected")},this.keepAlive=()=>{this.buffer.comment().dispatch(),this.flush()},this.data=e=>(this.buffer.data(e),this),this.id=(e="")=>(this.buffer.id(e),this.lastId=e,this),this.retry=e=>(this.buffer.retry(e),this),this.comment=e=>(this.buffer.comment(e),this),this.dispatch=()=>(this.buffer.dispatch(),this),this.flush=()=>(this.res.write(this.buffer.read()),this.buffer.clear(),this),this.push=(e,t="message",s=a())=>(this.buffer.push(e,t,s),this.flush(),this.lastId=s,this.emit("push",e,t,s),this),this.stream=l(this.push),this.iterate=c(this.push),this.batch=async e=>{if(e instanceof d)this.res.write(e.read());else{const t=new d({serializer:this.serialize,sanitizer:this.sanitize});await e(t),this.res.write(t.read())}},this.req=e,this.res=t;const b=null!==(n=r.serializer)&&void 0!==n?n:i,g=null!==(o=r.sanitizer)&&void 0!==o?o:h;this.serialize=b,this.sanitize=g,this.buffer=new d({serializer:b,sanitizer:g}),this.trustClientEventId=null===(u=r.trustClientEventId)||void 0===u||u,this.initialRetry=null===r.retry?null:null!==(f=r.retry)&&void 0!==f?f:2e3,this.keepAliveInterval=null===r.keepAlive?null:null!==(p=r.keepAlive)&&void 0!==p?p:1e4,this.statusCode=null!==(v=r.statusCode)&&void 0!==v?v:200,this.headers=null!==(m=r.headers)&&void 0!==m?m:{},this.req.once("close",this.onDisconnected),setImmediate(this.initialize)}event(e){return this.buffer.event(e),this}}const m=(...e)=>new Promise((t=>{const s=new v(...e);s.once("connected",(()=>{t(s)}))}));class b extends p{constructor(){super(),this.state={},this.sessions=new Set,this.broadcast=(e,t="message",s={})=>{const i=a(),r=s.filter?this.activeSessions.filter(s.filter):this.sessions;for(const s of r)s.push(e,t,i);return this.emit("broadcast",e,t,i),this}}get activeSessions(){return Array.from(this.sessions)}get sessionCount(){return this.sessions.size}register(e){if(this.sessions.has(e))return this;if(!e.isConnected)throw new Error("Cannot register a non-active session.");return e.once("disconnected",(()=>{this.emit("session-disconnected",e),this.deregister(e)})),this.sessions.add(e),this.emit("session-registered",e),this}deregister(e){return this.sessions.has(e)?(this.sessions.delete(e),this.emit("session-deregistered",e),this):this}}const g=(...e)=>new b(...e),y=(...e)=>new d(...e);return t})()));
//# sourceMappingURL=index.js.map

@@ -5,2 +5,3 @@ import http from "http";

import { Session } from "../Session";
import { EventBuffer } from "../EventBuffer";
declare const createHttpServer: () => Promise<http.Server>;

@@ -11,2 +12,3 @@ declare const createHttp2Server: () => Promise<http2.Http2Server>;

declare const waitForConnect: (session: Session) => Promise<void>;
export { createHttpServer, createHttp2Server, closeServer, getUrl, waitForConnect, };
declare const getBuffer: (session: Session) => EventBuffer;
export { createHttpServer, createHttp2Server, closeServer, getUrl, waitForConnect, getBuffer, };
/// <reference types="node" />
/// <reference types="node" />
import { Readable } from "stream";
import { IncomingMessage as Http1ServerRequest, ServerResponse as Http1ServerResponse, OutgoingHttpHeaders } from "http";
import { Http2ServerRequest, Http2ServerResponse } from "http2";
import { EventBuffer, EventBufferOptions } from "./EventBuffer";
import { TypedEmitter, EventMap } from "./lib/TypedEmitter";
import { SerializerFunction } from "./lib/serialize";
import { SanitizerFunction } from "./lib/sanitize";
interface SessionOptions {
interface SessionOptions extends Pick<EventBufferOptions, "serializer" | "sanitizer"> {
/**
* Serialize data to a string that can be written.
*
* Note that only values written with `.data()` or `.push()` are serialized, as everything else is assumed to already be a string.
*
* Defaults to `JSON.stringify`.
*/
serializer?: SerializerFunction;
/**
* Sanitize values so as to not prematurely dispatch events when writing fields whose text inadvertently contains newlines.
*
* By default, CR, LF and CRLF characters are replaced with a single LF character (`\n`) and then any trailing LF characters are stripped so as to prevent a blank line being written and accidentally dispatching the event before `.dispatch()` is called.
*/
sanitizer?: SanitizerFunction;
/**
* Whether to trust or ignore the last event ID given by the client in the `Last-Event-ID` request header.

@@ -70,18 +54,2 @@ *

}
interface StreamOptions {
/**
* Event name/type to be emitted when stream data is sent to the client.
*
* Defaults to `"stream"`.
*/
eventName?: string;
}
interface IterateOptions {
/**
* Event name/type to be emitted when iterable data is sent to the client.
*
* Defaults to `"iteration"`.
*/
eventName?: string;
}
interface DefaultSessionState {

@@ -106,6 +74,2 @@ [key: string]: unknown;

*
* As a performance optimisation, all events and data are first written to an internal buffer
* where it is stored until it is flushed to the client by calling the `flush` method. This is
* done for you when using the `push` helper method.
*
* @param req - The Node HTTP {@link https://nodejs.org/api/http.html#http_class_http_incomingmessage | ServerResponse} object.

@@ -121,3 +85,3 @@ * @param res - The Node HTTP {@link https://nodejs.org/api/http.html#http_class_http_serverresponse | IncomingMessage} object.

*
* For security reasons, keep in mind that the client can provide *any* initial ID here. Use the `trustClientEventId` to ignore the client-given initial ID.
* For security reasons, keep in mind that the client can provide *any* initial ID here. Use the `trustClientEventId` constructor option to ignore the client-given initial ID.
*

@@ -142,7 +106,2 @@ * @readonly

state: State;
/**
* Internal buffer used to store raw data from written fields.
*
* When Session#dispatch is called its buffer data will be flushed.
*/
private buffer;

@@ -169,59 +128,39 @@ /**

private onDisconnected;
/**
* Write a line with a field key and value appended with a newline character.
*/
private writeField;
private keepAlive;
/**
* Set the event to the given name (also referred to as the event "type" in the specification).
*
* @param type - Event name/type.
* @deprecated see https://github.com/MatthewWid/better-sse/issues/52
*/
event(type: string): this;
/**
* Write an arbitrary data field that is automatically serialized to a string using the given `serializer` function option or JSON stringification by default.
*
* @param data - Data to serialize and write.
* @deprecated see https://github.com/MatthewWid/better-sse/issues/52
*/
data: (data: unknown) => this;
/**
* Set the event ID to the given string.
*
* Defaults to an empty string if no argument is given.
*
* @param id - Identification string to write.
* @deprecated see https://github.com/MatthewWid/better-sse/issues/52
*/
id: (id?: string) => this;
/**
* Set the suggested reconnection time to the given milliseconds.
*
* @param time - Time in milliseconds to retry.
* @deprecated see https://github.com/MatthewWid/better-sse/issues/52
*/
retry: (time: number) => this;
/**
* Write a comment (an ignored field).
*
* This will not fire an event, but is often used to keep the connection alive.
*
* @param text - Text of the comment. Otherwise writes an empty field value.
* @deprecated see https://github.com/MatthewWid/better-sse/issues/52
*/
comment: (text?: string) => this;
/**
* Indicate that the event has finished being created by writing an additional newline character.
*
* Note that this does **not** send the written data to the client. Use `flush` to flush the internal buffer.
* @deprecated see https://github.com/MatthewWid/better-sse/issues/52
*/
dispatch: () => this;
/**
* Flush the buffered data to the client and clear the buffer.
* Flush the contents of the internal buffer to the client and clear the buffer.
*
* @deprecated see https://github.com/MatthewWid/better-sse/issues/52
*/
flush: () => this;
/**
* Create, write, dispatch and flush an event with the given data to the client all at once.
* Push an event to the client.
*
* This is equivalent to calling the methods `event`, `id`, `data`, `dispatch` and `flush` in that order.
*
* If no event name is given, the event name is set to `"message"`.
*
* If no event ID is given, the event ID (and thus the `lastid` property) is set to a unique string generated using a cryptographic pseudorandom number generator.
* If no event ID is given, the event ID (and thus the `lastId` property) is set to a unique string generated using a cryptographic pseudorandom number generator.
*

@@ -236,11 +175,9 @@ * Emits the `push` event with the given data, event name and event ID in that order.

/**
* Pipe readable stream data to the client.
* Pipe readable stream data as a series of events to the client.
*
* Each data emission by the stream pushes a new event to the client.
*
* This uses the `push` method under the hood.
*
* If no event name is given in the options object, the event name is set to `"stream"`.
* If no event name is given in the `options` object, the event name is set to `"stream"`.
*
* @param stream - Readable stream to consume from.
* @param stream - Readable stream to consume data from.
* @param options - Options to alter how the stream is flushed to the client.

@@ -250,19 +187,32 @@ *

*/
stream: (stream: Readable, options?: StreamOptions) => Promise<boolean>;
stream: (stream: import("stream").Readable, options?: import("./lib/createPushFromStream").StreamOptions) => Promise<boolean>;
/**
* Iterate over an iterable and send yielded values to the client.
* Iterate over an iterable and send yielded values as events to the client.
*
* Each yield pushes a new event to the client.
*
* This uses the `push` method under the hood.
*
* If no event name is given in the options object, the event name is set to `"iteration"`.
* If no event name is given in the `options` object, the event name is set to `"iteration"`.
*
* @param iterable - Iterable to consume data from.
*
* @returns A promise that resolves once all the data has been yielded from the iterable.
* @returns A promise that resolves once all data has been successfully yielded from the iterable.
*/
iterate: <DataType = unknown>(iterable: Iterable<DataType> | AsyncIterable<DataType>, options?: IterateOptions) => Promise<void>;
iterate: <DataType = unknown>(iterable: Iterable<DataType> | AsyncIterable<DataType>, options?: import("./lib/createPushFromIterable").IterateOptions) => Promise<void>;
/**
* Batch and send multiple events at once.
*
* If given an `EventBuffer` instance, its contents will be sent to the client.
*
* If given a callback, it will be passed an instance of `EventBuffer` which uses the same serializer and sanitizer as the session.
* Once its execution completes - or once it resolves if it returns a promise - the contents of the passed `EventBuffer` will be sent to the client.
*
* @param batcher - Event buffer to get contents from, or callback that takes an event buffer to write to.
*
* @returns A promise that resolves once all data from the event buffer has been successfully sent to the client.
*
* @see EventBuffer
*/
batch: (batcher: EventBuffer | ((buffer: EventBuffer) => void | Promise<void>)) => Promise<void>;
}
export type { SessionOptions, StreamOptions, IterateOptions, SessionEvents, DefaultSessionState, };
export type { SessionOptions, SessionEvents, DefaultSessionState };
export { Session };
{
"name": "better-sse",
"description": "Dead simple, dependency-less, spec-compliant server-side events implementation for Node, written in TypeScript.",
"version": "0.9.0",
"version": "0.10.0",
"main": "./build/index.js",

@@ -6,0 +6,0 @@ "types": "./build/index.d.ts",

@@ -39,3 +39,3 @@ # Better SSE

* Add or override the response status code and headers.
* Fine-grained control by either sending [individual fields](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events#fields) of events or by sending full events with simple helpers.
* Fine-grained control by either sending [individual fields](./docs/api.md#eventbuffer) of events or by sending [full events with simple helpers](./docs/api.md#sessionpush-data-unknown-eventname-string-eventid-string--this).
* Pipe [streams](https://nodejs.org/api/stream.html#stream_readable_streams) and [iterables](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators) directly from the server to the client as a series of events.

@@ -143,7 +143,7 @@ * Support for popular EventStream polyfills [`event-source-polyfill`](https://www.npmjs.com/package/event-source-polyfill) and [`eventsource-polyfill`](https://www.npmjs.com/package/eventsource-polyfill).

This library is always open to contributions, whether it be code, bug reports, documentation or anything else.
This library is always open to contributions whether it be code, bug reports, documentation or anything else.
Please submit suggestions, bugs and issues to the [GitHub issues page](https://github.com/MatthewWid/better-sse/issues).
For code or documentation changes, [submit a pull request on GitHub](https://github.com/MatthewWid/better-sse/pulls).
For code or documentation changes [submit a pull request on GitHub](https://github.com/MatthewWid/better-sse/pulls).

@@ -150,0 +150,0 @@ ## Local Development

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc