Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

better-sse

Package Overview
Dependencies
Maintainers
1
Versions
18
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

better-sse - npm Package Compare versions

Comparing version 0.4.0 to 0.5.0

build/Channel.d.ts

2

build/index.d.ts
export { default as Session } from "./Session";
export { default as createSession } from "./createSession";
export { default as Channel } from "./Channel";
export { default as createChannel } from "./createChannel";

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 i=t();for(var s in i)("object"==typeof exports?exports:e)[s]=i[s]}}(global,(function(){return(()=>{"use strict";var e={n:t=>{var i=t&&t.__esModule?()=>t.default:()=>t;return e.d(i,{a:i}),i},d:(t,i)=>{for(var s in i)e.o(i,s)&&!e.o(t,s)&&Object.defineProperty(t,s,{enumerable:!0,get:i[s]})},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,{Session:()=>h,createSession:()=>a});const i=require("events");var s=e.n(i);const n=require("crypto"),r=e=>JSON.stringify(e),o=e=>{let t=e;return t=t.replace(/(\r\n|\r|\n)/g,"\n"),t=t.replace(/\n+$/g,""),t};class l extends(s()){constructor(e,t,i={}){var s,l,h,a,d,c,u;super(),this.lastId="",this.isConnected=!1,this.onConnected=()=>{var e;if(this.trustClientEventId){const t=null!==(e=this.req.headers["last-event-id"])&&void 0!==e?e:"";this.lastId=t}Object.entries(this.headers).forEach((([e,t])=>{this.res.setHeader(e,null!=t?t:"")})),this.res.statusCode=this.statusCode,this.res.setHeader("Content-Type","text/event-stream"),this.res.setHeader("Cache-Control","no-cache, no-transform"),this.res.setHeader("Connection","keep-alive"),this.res.flushHeaders(),null!==this.initialRetry&&this.retry(this.initialRetry).dispatch(),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 i=`${e}:${this.sanitize(t)}\n`;return this.res.write(i),this},this.keepAlive=()=>{this.comment().dispatch()},this.dispatch=()=>(this.res.write("\n"),this),this.data=e=>{const t=this.serialize(e);return this.writeField("data",t),this},this.id=e=>{const t=e||"";return this.writeField("id",t),this.lastId=t,this},this.retry=e=>{const t=e.toString();return this.writeField("retry",t),this},this.comment=e=>(this.writeField("",null!=e?e:""),this),this.push=(e,t)=>{let i,s;e&&void 0===t?(i="message",s=e):(i=e.toString(),s=t);const r=(0,n.randomBytes)(4).toString("hex");return this.event(i).id(r).data(s).dispatch(),this},this.stream=async(e,t={})=>{const{event:i="stream"}=t;return new Promise(((t,s)=>{e.on("data",(e=>{let t;t=Buffer.isBuffer(e)?e.toString():e,this.push(i,t)})),e.once("end",(()=>t(!0))),e.once("close",(()=>t(!0))),e.once("error",(e=>s(e)))}))},this.req=e,this.res=t,this.serialize=null!==(s=i.serializer)&&void 0!==s?s:r,this.sanitize=null!==(l=i.sanitizer)&&void 0!==l?l:o,this.trustClientEventId=null===(h=i.trustClientEventId)||void 0===h||h,this.initialRetry=null===i.retry?null:null!==(a=i.retry)&&void 0!==a?a:2e3,this.keepAliveInterval=null===i.keepAlive?null:null!==(d=i.keepAlive)&&void 0!==d?d:1e4,this.statusCode=null!==(c=i.statusCode)&&void 0!==c?c:200,this.headers=null!==(u=i.headers)&&void 0!==u?u:{},this.req.on("close",this.onDisconnected),setImmediate(this.onConnected)}event(e){return this.writeField("event",e),this}}const h=l,a=(...e)=>new Promise((t=>{const i=new h(...e);i.once("connected",(()=>{t(i)}))}));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,(function(){return(()=>{"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:()=>c,Session:()=>l,createChannel:()=>u,createSession:()=>a});const s=require("events");var i=e.n(s);const n=require("crypto"),r=e=>JSON.stringify(e),o=e=>{let t=e;return t=t.replace(/(\r\n|\r|\n)/g,"\n"),t=t.replace(/\n+$/g,""),t};class h extends(i()){constructor(e,t,s={}){var i,h,l,a,d,c,u;super(),this.lastId="",this.isConnected=!1,this.state={},this.onConnected=()=>{var e,t,s;const i=`http://${this.req.headers.host}${this.req.url}`,n=new URL(i).searchParams;if(this.trustClientEventId){const i=null!==(s=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!==s?s:"";this.lastId=i}Object.entries(this.headers).forEach((([e,t])=>{this.res.setHeader(e,null!=t?t:"")})),this.res.statusCode=this.statusCode,this.res.setHeader("Content-Type","text/event-stream"),this.res.setHeader("Cache-Control","no-cache, no-transform"),this.res.setHeader("Connection","keep-alive"),this.res.flushHeaders(),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(),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=`${e}:${this.sanitize(t)}\n`;return this.res.write(s),this},this.keepAlive=()=>{this.comment().dispatch()},this.dispatch=()=>(this.res.write("\n"),this),this.data=e=>{const t=this.serialize(e);return this.writeField("data",t),this},this.id=e=>{const t=e||"";return this.writeField("id",t),this.lastId=t,this},this.retry=e=>{const t=e.toString();return this.writeField("retry",t),this},this.comment=e=>(this.writeField("",null!=e?e:""),this),this.push=(e,t)=>{let s,i;e&&void 0===t?(s="message",i=e):(s=e.toString(),i=t);const r=(0,n.randomBytes)(4).toString("hex");return this.event(s).id(r).data(i).dispatch(),this},this.stream=async(e,t={})=>{const{event:s="stream"}=t;return new Promise(((t,i)=>{e.on("data",(e=>{let t;t=Buffer.isBuffer(e)?e.toString():e,this.push(s,t)})),e.once("end",(()=>t(!0))),e.once("close",(()=>t(!0))),e.once("error",(e=>i(e)))}))},this.req=e,this.res=t,this.serialize=null!==(i=s.serializer)&&void 0!==i?i:r,this.sanitize=null!==(h=s.sanitizer)&&void 0!==h?h:o,this.trustClientEventId=null===(l=s.trustClientEventId)||void 0===l||l,this.initialRetry=null===s.retry?null:null!==(a=s.retry)&&void 0!==a?a:2e3,this.keepAliveInterval=null===s.keepAlive?null:null!==(d=s.keepAlive)&&void 0!==d?d:1e4,this.statusCode=null!==(c=s.statusCode)&&void 0!==c?c:200,this.headers=null!==(u=s.headers)&&void 0!==u?u:{},this.req.on("close",this.onDisconnected),setImmediate(this.onConnected)}event(e){return this.writeField("event",e),this}}const l=h,a=(...e)=>new Promise((t=>{const s=new l(...e);s.once("connected",(()=>{t(s)}))}));class d extends(i()){constructor(){super(),this.sessions=[]}get activeSessions(){return this.sessions}get sessionCount(){return this.sessions.length}register(e){if(!e.isConnected)throw new Error("Cannot register a non-active session.");return e.once("disconnected",(()=>{this.deregister(e),this.emit("session-disconnected",e)})),this.sessions.push(e),this.emit("session-registered",e),this}deregister(e){return this.sessions=this.sessions.filter((t=>t!==e)),this.emit("session-deregistered",e),this}broadcast(e,t,s={}){for(const i of this.sessions)s.filter&&!s.filter(i)||i.push(e,t);return this.emit("broadcast",e,t),this}}const c=d,u=(...e)=>new c(...e);return t})()}));
//# sourceMappingURL=index.js.map

@@ -7,3 +7,3 @@ /// <reference types="node" />

import { SanitizerFunction } from "./lib/sanitize";
export interface SessionOptions {
interface SessionOptions {
/**

@@ -68,3 +68,3 @@ * Serialize data to a string that can be written.

}
export interface StreamOptions {
interface StreamOptions {
/**

@@ -93,4 +93,17 @@ * Event name/type to be emitted when stream data is sent to the client.

* This is initialized to the last event ID given by the user, and otherwise is equal to the last number given to the `.id` method.
*
* @readonly
*/
lastId: string;
/**
* Indicates whether the session and connection is open or not.
*
* @readonly
*/
isConnected: boolean;
/**
* Custom state for this session.
* Use this object to safely store information related to the session and user.
*/
state: Record<string, unknown>;
private req;

@@ -106,3 +119,2 @@ private res;

private headers;
isConnected: boolean;
constructor(req: IncomingMessage, res: ServerResponse, options?: SessionOptions);

@@ -181,2 +193,3 @@ private onConnected;

}
export type { SessionOptions };
export default Session;
{
"name": "better-sse",
"description": "Dead simple, dependency-less, spec-compliant server-side events implementation for Node, written in TypeScript.",
"version": "0.4.0",
"version": "0.5.0",
"main": "./build/index.js",

@@ -21,3 +21,3 @@ "types": "./build/index.d.ts",

"files": [
"build/",
"build",
"!build/**/*.map"

@@ -53,3 +53,3 @@ ],

"dev": "webpack --env development",
"test": "jest",
"test": "jest --forceExit",
"clean": "rimraf ./build",

@@ -56,0 +56,0 @@ "format": "prettier --write ./src/**/*.ts",

@@ -26,8 +26,11 @@ # Better SSE

* [Comprehensively documented](./docs) with guides and API documentation.
* [Channels](./docs/channels.md) allow you to broadcast events to many clients at once.
* Configurable reconnection time.
* Configurable message serialization and data sanitization (but with good defaults).
* Trust or ignore the client-given last event ID.
* Automatically send keep-alive pings to keep connections open.
* 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 sending full events with simple helpers.
* Pipe [streams](https://nodejs.org/api/stream.html#stream_readable_streams) directly from the server to the client as a stream of events.
* 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).

@@ -53,3 +56,3 @@ # Installation

See the Recipes section of the documentation for use with other frameworks and libraries.
See the [Recipes](./docs/recipes.md) section of the documentation for use with other frameworks and libraries.

@@ -62,2 +65,3 @@ ```javascript

const session = await createSession(req, res);
session.push("Hello world!");

@@ -71,8 +75,8 @@ });

sse.addEventListener("message", (event) => {
console.log(event.data);
sse.addEventListener("message", ({data}) => {
console.log(data);
});
```
Check [the API documentation](https://github.com/MatthewWid/better-sse/blob/master/docs/api.md) and [live examples](https://github.com/MatthewWid/better-sse/tree/master/examples) for information on getting more fine-tuned control over your data such as managing event IDs, data serialization, streams, dispatch controls and more!
Check [the API documentation](./docs/api.md) and [live examples](https://github.com/MatthewWid/better-sse/tree/master/examples) for information on getting more fine-tuned control over your data such as managing event IDs, data serialization, streams, dispatch controls and more!

@@ -79,0 +83,0 @@ # Documentation

SocketSocket SOC 2 Logo

Product

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

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc