Skip to content

Instantly share code, notes, and snippets.

@pretentious7
Created February 10, 2022 10:39
Show Gist options
  • Save pretentious7/eba1b83d151f086e4d9a6f4456b04f80 to your computer and use it in GitHub Desktop.
Save pretentious7/eba1b83d151f086e4d9a6f4456b04f80 to your computer and use it in GitHub Desktop.
nodejs event source
class EventSource extends EventEmitter {
_lastEventID;
_event = {
data: '',
eventType: '',
dispatch() {
super.emit(
this.eventType ? this.eventType : 'message',
this.data.endsWith('\n') ? this.data.slice(0, -1) : this.data
);
this.eventType = this.data = '';
},
};
constructor(options) {
super();
Object.setPrototypeOf(this._event, this);
this.req = https.request(options, (res) => {
const eventSourceLines = readline.createInterface({ input: res });
eventSourceLines.on('line', (l) => {
this._dispatchOnLine(l);
});
});
this.req.end();
}
//ref https://html.spec.whatwg.org/multipage/server-sent-events.html
_evalField(field, value) {
const field_dispatch = {
event: () => {
this._event.eventType = value;
},
data: () => {
this._event.data += value + '\n';
},
id: () => {
this._lastEventID = value;
},
retry() {},
};
field in field_dispatch ? field_dispatch[field]() : (() => {})();
}
_dispatchOnLine(evtLine) {
//first dispatch on first char in line
if (evtLine.length === 0) {
//emit accumulated event
this._event.dispatch();
} else if (evtLine[0] === ':') {
(() => {})();
} else if (evtLine.includes(':')) {
const indexOfColon = evtLine.indexOf(':');
const field = evtLine.slice(0, indexOfColon);
const value = evtLine.slice(indexOfColon + 1).trimStart();
this._evalField(field, value);
} else {
this._evalField(evtLine, '');
}
}
}
@pretentious7
Copy link
Author

simple nodejs based eventsource client implementation

MIT licensed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment