reconnecting-eventsource 1.2.0 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,42 @@
1
+ /// <reference types="node" />
2
+ export interface ReconnectingEventSourceInit extends EventSourceInit {
3
+ max_retry_time?: number;
4
+ eventSourceClass?: typeof EventSource;
5
+ lastEventId?: string;
6
+ }
7
+ export declare class EventSourceNotAvailableError extends Error {
8
+ constructor();
9
+ }
10
+ declare type Listeners = {
11
+ [K in keyof EventSourceEventMap]: ((this: EventSource, ev: EventSourceEventMap[K]) => any)[];
12
+ };
13
+ export default class ReconnectingEventSource implements EventSource {
14
+ readonly _configuration: ReconnectingEventSourceInit | undefined;
15
+ readonly CONNECTING = 0;
16
+ readonly OPEN = 1;
17
+ readonly CLOSED = 2;
18
+ _eventSource: EventSource | null;
19
+ _lastEventId: string | null;
20
+ _timer: NodeJS.Timer | null;
21
+ _listeners: Listeners;
22
+ _onevent_wrapped: (this: EventSource, ev: Event) => any;
23
+ readyState: 0 | 1 | 2;
24
+ url: string;
25
+ withCredentials: boolean;
26
+ readonly max_retry_time: number;
27
+ eventSourceClass: typeof EventSource;
28
+ constructor(url: string | URL, configuration?: ReconnectingEventSourceInit);
29
+ dispatchEvent(event: Event): boolean;
30
+ _start(): void;
31
+ _onopen(event: Event): void;
32
+ _onerror(event: Event): void;
33
+ _onevent(event: Event): void;
34
+ onopen(event: Event): void;
35
+ onerror(event: Event): void;
36
+ onmessage(event: MessageEvent): void;
37
+ close(): void;
38
+ addEventListener<K extends keyof EventSourceEventMap>(type: K, callback: (this: EventSource, ev: EventSourceEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
39
+ removeEventListener<K extends keyof EventSourceEventMap>(type: K, callback: (this: EventSource, ev: EventSourceEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
40
+ }
41
+ export {};
42
+ //# sourceMappingURL=reconnecting-eventsource.d.ts.map
@@ -0,0 +1,172 @@
1
+ "use strict";
2
+ // MIT License:
3
+ //
4
+ // Copyright (C) 2022 Fanout, Inc.
5
+ //
6
+ // Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ // of this software and associated documentation files (the "Software"), to
8
+ // deal in the Software without restriction, including without limitation the
9
+ // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10
+ // sell copies of the Software, and to permit persons to whom the Software is
11
+ // furnished to do so, subject to the following conditions:
12
+ //
13
+ // The above copyright notice and this permission notice shall be included in
14
+ // all copies or substantial portions of the Software.
15
+ //
16
+ // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
+ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22
+ // IN THE SOFTWARE.
23
+ Object.defineProperty(exports, "__esModule", { value: true });
24
+ exports.EventSourceNotAvailableError = void 0;
25
+ class EventSourceNotAvailableError extends Error {
26
+ constructor() {
27
+ super('EventSource not available.\n' +
28
+ 'Consider loading an EventSource polyfill and making it available globally as EventSource, ' +
29
+ 'or passing one in as eventSourceClass to the ReconnectingEventSource constructor.');
30
+ }
31
+ }
32
+ exports.EventSourceNotAvailableError = EventSourceNotAvailableError;
33
+ class ReconnectingEventSource {
34
+ constructor(url, configuration) {
35
+ this.CONNECTING = 0;
36
+ this.OPEN = 1;
37
+ this.CLOSED = 2;
38
+ this._configuration = configuration != null ? Object.assign({}, configuration) : undefined;
39
+ this.withCredentials = false;
40
+ this._eventSource = null;
41
+ this._lastEventId = null;
42
+ this._timer = null;
43
+ this._listeners = {
44
+ open: [],
45
+ error: [],
46
+ message: [],
47
+ };
48
+ this.url = url.toString();
49
+ this.readyState = this.CONNECTING;
50
+ this.max_retry_time = 3000;
51
+ this.eventSourceClass = globalThis.EventSource;
52
+ if (this._configuration != null) {
53
+ if (this._configuration.lastEventId) {
54
+ this._lastEventId = this._configuration.lastEventId;
55
+ delete this._configuration['lastEventId'];
56
+ }
57
+ if (this._configuration.max_retry_time) {
58
+ this.max_retry_time = this._configuration.max_retry_time;
59
+ delete this._configuration['max_retry_time'];
60
+ }
61
+ if (this._configuration.eventSourceClass) {
62
+ this.eventSourceClass = this._configuration.eventSourceClass;
63
+ delete this._configuration['eventSourceClass'];
64
+ }
65
+ }
66
+ if (this.eventSourceClass == null || typeof this.eventSourceClass !== 'function') {
67
+ throw new EventSourceNotAvailableError();
68
+ }
69
+ this._onevent_wrapped = (event) => { this._onevent(event); };
70
+ this._start();
71
+ }
72
+ dispatchEvent(event) {
73
+ throw new Error("Method not implemented.");
74
+ }
75
+ _start() {
76
+ let url = this.url;
77
+ if (this._lastEventId) {
78
+ if (url.indexOf('?') === -1) {
79
+ url += '?';
80
+ }
81
+ else {
82
+ url += '&';
83
+ }
84
+ url += 'lastEventId=' + encodeURIComponent(this._lastEventId);
85
+ }
86
+ this._eventSource = new this.eventSourceClass(url, this._configuration);
87
+ this._eventSource.onopen = (event) => { this._onopen(event); };
88
+ this._eventSource.onerror = (event) => { this._onerror(event); };
89
+ this._eventSource.onmessage = (event) => { this.onmessage(event); };
90
+ // apply listen types
91
+ for (const type of Object.keys(this._listeners)) {
92
+ this._eventSource.addEventListener(type, this._onevent_wrapped);
93
+ }
94
+ }
95
+ _onopen(event) {
96
+ if (this.readyState === 0) {
97
+ this.readyState = 1;
98
+ this.onopen(event);
99
+ }
100
+ }
101
+ _onerror(event) {
102
+ if (this.readyState === 1) {
103
+ this.readyState = 0;
104
+ this.onerror(event);
105
+ }
106
+ if (this._eventSource) {
107
+ if (this._eventSource.readyState === 2) {
108
+ // reconnect with new object
109
+ this._eventSource.close();
110
+ this._eventSource = null;
111
+ // reconnect after random timeout < max_retry_time
112
+ const timeout = Math.round(this.max_retry_time * Math.random());
113
+ this._timer = setTimeout(() => this._start(), timeout);
114
+ }
115
+ }
116
+ }
117
+ _onevent(event) {
118
+ if (event instanceof MessageEvent) {
119
+ this._lastEventId = event.lastEventId;
120
+ }
121
+ const listenersForType = this._listeners[event.type];
122
+ if (listenersForType != null) {
123
+ // operate on a copy
124
+ for (const listener of [...listenersForType]) {
125
+ listener.call(this, event);
126
+ }
127
+ }
128
+ if (event.type === 'message') {
129
+ this.onmessage(event);
130
+ }
131
+ }
132
+ onopen(event) {
133
+ // may be overridden
134
+ }
135
+ onerror(event) {
136
+ // may be overridden
137
+ }
138
+ onmessage(event) {
139
+ // may be overridden
140
+ }
141
+ close() {
142
+ if (this._timer) {
143
+ clearTimeout(this._timer);
144
+ this._timer = null;
145
+ }
146
+ if (this._eventSource) {
147
+ this._eventSource.close();
148
+ this._eventSource = null;
149
+ }
150
+ this.readyState = 2;
151
+ }
152
+ addEventListener(type, callback, options) {
153
+ // We don't support options at the moment
154
+ if (this._listeners[type] == null) {
155
+ this._listeners[type] = [];
156
+ if (this._eventSource != null) {
157
+ this._eventSource.addEventListener(type, this._onevent_wrapped);
158
+ }
159
+ }
160
+ const listenersForType = this._listeners[type];
161
+ if (!listenersForType.includes(callback)) {
162
+ this._listeners[type] = [...listenersForType, callback];
163
+ }
164
+ }
165
+ removeEventListener(type, callback, options) {
166
+ // We don't support options at the moment
167
+ const listenersForType = this._listeners[type];
168
+ this._listeners[type] = listenersForType.filter(l => l !== callback);
169
+ }
170
+ }
171
+ exports.default = ReconnectingEventSource;
172
+ //# sourceMappingURL=reconnecting-eventsource.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reconnecting-eventsource.js","sourceRoot":"","sources":["../../src/reconnecting-eventsource.ts"],"names":[],"mappings":"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","sourcesContent":["// MIT License:\n//\n// Copyright (C) 2022 Fanout, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal in the Software without restriction, including without limitation the\n// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n// sell copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n// IN THE SOFTWARE.\n\nexport interface ReconnectingEventSourceInit extends EventSourceInit {\n // the maximum time to wait before attempting to reconnect in ms, default `3000`\n // note: wait time is randomised to prevent all clients from attempting to reconnect simultaneously\n max_retry_time?: number;\n\n // the EventSource class to wrap. This allows the use of a polyfill or alternate\n // implementation instead of the platform-provided EventSource class.\n eventSourceClass?: typeof EventSource;\n\n // the last event\n lastEventId?: string;\n}\n\nexport class EventSourceNotAvailableError extends Error {\n constructor() {\n super(\n 'EventSource not available.\\n' +\n 'Consider loading an EventSource polyfill and making it available globally as EventSource, ' +\n 'or passing one in as eventSourceClass to the ReconnectingEventSource constructor.'\n );\n }\n}\n\ntype Listeners = {\n [K in keyof EventSourceEventMap]: ((this: EventSource, ev: EventSourceEventMap[K]) => any)[];\n};\n\nexport default class ReconnectingEventSource implements EventSource {\n\n readonly _configuration: ReconnectingEventSourceInit | undefined;\n readonly CONNECTING = 0;\n readonly OPEN = 1;\n readonly CLOSED = 2;\n\n _eventSource: EventSource | null;\n _lastEventId: string | null;\n _timer: NodeJS.Timer | null;\n _listeners: Listeners;\n _onevent_wrapped: (this: EventSource, ev: Event) => any;\n\n readyState: 0 | 1 | 2;\n url: string;\n withCredentials: boolean;\n\n readonly max_retry_time: number;\n eventSourceClass: typeof EventSource;\n\n constructor(url: string | URL, configuration?: ReconnectingEventSourceInit) {\n this._configuration = configuration != null ? Object.assign({}, configuration) : undefined;\n this.withCredentials = false;\n\n this._eventSource = null;\n this._lastEventId = null;\n this._timer = null;\n this._listeners = {\n open: [],\n error: [],\n message: [],\n };\n\n this.url = url.toString();\n this.readyState = this.CONNECTING;\n this.max_retry_time = 3000;\n this.eventSourceClass = globalThis.EventSource;\n\n if (this._configuration != null) {\n if (this._configuration.lastEventId) {\n this._lastEventId = this._configuration.lastEventId;\n delete this._configuration['lastEventId'];\n }\n\n if (this._configuration.max_retry_time) {\n this.max_retry_time = this._configuration.max_retry_time;\n delete this._configuration['max_retry_time'];\n }\n\n if (this._configuration.eventSourceClass) {\n this.eventSourceClass = this._configuration.eventSourceClass;\n delete this._configuration['eventSourceClass'];\n }\n }\n\n if(this.eventSourceClass == null || typeof this.eventSourceClass !== 'function') {\n throw new EventSourceNotAvailableError();\n }\n\n this._onevent_wrapped = (event) => { this._onevent(event); };\n\n this._start();\n }\n\n dispatchEvent(event: Event): boolean {\n throw new Error(\"Method not implemented.\");\n }\n\n _start() {\n let url = this.url;\n\n if (this._lastEventId) {\n if (url.indexOf('?') === -1) {\n url += '?';\n } else {\n url += '&';\n }\n url += 'lastEventId=' + encodeURIComponent(this._lastEventId);\n }\n\n this._eventSource = new this.eventSourceClass(url, this._configuration);\n\n this._eventSource.onopen = (event) => { this._onopen(event); };\n this._eventSource.onerror = (event) => { this._onerror(event); };\n this._eventSource.onmessage = (event) => { this.onmessage(event); };\n\n // apply listen types\n for (const type of Object.keys(this._listeners)) {\n this._eventSource.addEventListener(type, this._onevent_wrapped);\n }\n }\n\n _onopen(event: Event) {\n if (this.readyState === 0) {\n this.readyState = 1;\n this.onopen(event);\n }\n }\n\n _onerror(event: Event) {\n if (this.readyState === 1) {\n this.readyState = 0;\n this.onerror(event);\n }\n\n if (this._eventSource) {\n if(this._eventSource.readyState === 2) {\n // reconnect with new object\n this._eventSource.close();\n this._eventSource = null;\n\n // reconnect after random timeout < max_retry_time\n const timeout = Math.round(this.max_retry_time * Math.random());\n this._timer = setTimeout(() => this._start(), timeout);\n }\n }\n }\n\n _onevent(event: Event) {\n if (event instanceof MessageEvent) {\n this._lastEventId = event.lastEventId;\n }\n\n const listenersForType = this._listeners[event.type as keyof typeof this._listeners] as ((this:EventSource, ev: Event) => any)[];\n if (listenersForType != null) {\n // operate on a copy\n for (const listener of [...listenersForType]) {\n listener.call(this, event);\n }\n }\n\n if (event.type === 'message') {\n this.onmessage(event as MessageEvent);\n }\n }\n\n onopen(event: Event) {\n // may be overridden\n }\n\n onerror(event: Event) {\n // may be overridden\n }\n\n onmessage(event: MessageEvent) {\n // may be overridden\n }\n\n close() {\n if (this._timer) {\n clearTimeout(this._timer);\n this._timer = null;\n }\n\n if (this._eventSource) {\n this._eventSource.close();\n this._eventSource = null;\n }\n\n this.readyState = 2;\n }\n\n addEventListener<K extends keyof EventSourceEventMap>(type: K, callback: (this: EventSource, ev: EventSourceEventMap[K]) => any, options?: boolean | AddEventListenerOptions) {\n // We don't support options at the moment\n\n if (this._listeners[type] == null) {\n this._listeners[type] = [];\n if (this._eventSource != null) {\n this._eventSource.addEventListener(type, this._onevent_wrapped);\n }\n }\n\n const listenersForType = this._listeners[type];\n if (!listenersForType.includes(callback)) {\n this._listeners[type] = [...listenersForType, callback] as Listeners[typeof type];\n }\n }\n\n removeEventListener<K extends keyof EventSourceEventMap>(type: K, callback: (this: EventSource, ev: EventSourceEventMap[K]) => any, options?: boolean | AddEventListenerOptions) {\n // We don't support options at the moment\n\n const listenersForType = this._listeners[type];\n this._listeners[type] = listenersForType.filter(l => l !== callback) as Listeners[typeof type];\n }\n}\n"]}
@@ -1 +1,2 @@
1
- var ReconnectingEventSource=function(e){var t={};function n(r){if(t[r])return t[r].exports;var i=t[r]={i:r,l:!1,exports:{}};return e[r].call(i.exports,i,i.exports,n),i.l=!0,i.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var i in e)n.d(r,i,function(t){return e[t]}.bind(null,i));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=0)}([function(e,t,n){var r,i,o;i=[e,n(1)],void 0===(o="function"==typeof(r=function(e,t){"use strict";var n,r=(n=t)&&n.__esModule?n:{default:n};e.exports=r.default})?r.apply(t,i):r)||(e.exports=o)},function(e,t,n){var r,i,o;i=[t],void 0===(o="function"==typeof(r=function(e){"use strict";function t(e){if(Array.isArray(e)){for(var t=0,n=Array(e.length);t<e.length;t++)n[t]=e[t];return n}return Array.from(e)}Object.defineProperty(e,"__esModule",{value:!0});var n=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}(),r=function(){function e(t,n){var r=this;!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this._configuration=null!=n?Object.assign({},n):null,this._eventSource=null,this._lastEventId=null,this._timer=null,this._listeners={},this.url=t,this.readyState=0,this.max_retry_time=3e3,null!=this._configuration&&(this._configuration.lastEventId&&(this._lastEventId=this._configuration.lastEventId,delete this._configuration.lastEventId),this._configuration.max_retry_time&&(this.max_retry_time=this._configuration.max_retry_time,delete this._configuration.max_retry_time)),this._onevent_wrapped=function(e){r._onevent(e)},this._start()}return n(e,[{key:"_start",value:function(){var e=this,t=this.url;this._lastEventId&&(-1===t.indexOf("?")?t+="?":t+="&",t+="lastEventId="+encodeURIComponent(this._lastEventId)),this._eventSource=new EventSource(t,this._configuration),this._eventSource.onopen=function(t){e._onopen(t)},this._eventSource.onerror=function(t){e._onerror(t)},this._eventSource.onmessage=function(t){e.onmessage(t)};var n=!0,r=!1,i=void 0;try{for(var o,s=Object.keys(this._listeners)[Symbol.iterator]();!(n=(o=s.next()).done);n=!0){var u=o.value;this._eventSource.addEventListener(u,this._onevent_wrapped)}}catch(e){r=!0,i=e}finally{try{!n&&s.return&&s.return()}finally{if(r)throw i}}}},{key:"_onopen",value:function(e){0===this.readyState&&(this.readyState=1,this.onopen(e))}},{key:"_onerror",value:function(e){var t=this;if(1===this.readyState&&(this.readyState=0,this.onerror(e)),this._eventSource&&2===this._eventSource.readyState){this._eventSource.close(),this._eventSource=null;var n=Math.round(this.max_retry_time*Math.random());this._timer=setTimeout((function(){return t._start()}),n)}}},{key:"_onevent",value:function(e){e.lastEventId&&(this._lastEventId=e.lastEventId);var n=this._listeners[e.type];if(null!=n)for(var r=[].concat(t(n)),i=0;i<r.length;i++)(0,r[i])(e);"message"===e.type&&this.onmessage(e)}},{key:"onopen",value:function(e){}},{key:"onerror",value:function(e){}},{key:"onmessage",value:function(e){}},{key:"close",value:function(){this._timer&&(clearTimeout(this._timer),this._timer=null),this._eventSource&&(this._eventSource.close(),this._eventSource=null),this.readyState=2}},{key:"addEventListener",value:function(e,n){var r=e.toString();r in this._listeners||(this._listeners[r]=[],this._eventSource&&this._eventSource.addEventListener(r,this._onevent_wrapped));var i=this._listeners[r];i.includes(n)||(this._listeners[r]=[].concat(t(i),[n]))}},{key:"removeEventListener",value:function(e,t){var n=e.toString();if(n in this._listeners){var r=this._listeners[n].filter((function(e){return e!==t}));r.length>0?this._listeners[n]=r:(delete this._listeners[n],this._eventSource&&this._eventSource.removeEventListener(n,this._onevent_wrapped))}}}]),e}();e.default=r})?r.apply(t,i):r)||(e.exports=o)}]);
1
+ var _ReconnectingEventSource;(()=>{"use strict";var e={19:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.EventSourceNotAvailableError=void 0;class n extends Error{constructor(){super("EventSource not available.\nConsider loading an EventSource polyfill and making it available globally as EventSource, or passing one in as eventSourceClass to the ReconnectingEventSource constructor.")}}t.EventSourceNotAvailableError=n,t.default=class{constructor(e,t){if(this.CONNECTING=0,this.OPEN=1,this.CLOSED=2,this._configuration=null!=t?Object.assign({},t):void 0,this.withCredentials=!1,this._eventSource=null,this._lastEventId=null,this._timer=null,this._listeners={open:[],error:[],message:[]},this.url=e.toString(),this.readyState=this.CONNECTING,this.max_retry_time=3e3,this.eventSourceClass=globalThis.EventSource,null!=this._configuration&&(this._configuration.lastEventId&&(this._lastEventId=this._configuration.lastEventId,delete this._configuration.lastEventId),this._configuration.max_retry_time&&(this.max_retry_time=this._configuration.max_retry_time,delete this._configuration.max_retry_time),this._configuration.eventSourceClass&&(this.eventSourceClass=this._configuration.eventSourceClass,delete this._configuration.eventSourceClass)),null==this.eventSourceClass||"function"!=typeof this.eventSourceClass)throw new n;this._onevent_wrapped=e=>{this._onevent(e)},this._start()}dispatchEvent(e){throw new Error("Method not implemented.")}_start(){let e=this.url;this._lastEventId&&(-1===e.indexOf("?")?e+="?":e+="&",e+="lastEventId="+encodeURIComponent(this._lastEventId)),this._eventSource=new this.eventSourceClass(e,this._configuration),this._eventSource.onopen=e=>{this._onopen(e)},this._eventSource.onerror=e=>{this._onerror(e)},this._eventSource.onmessage=e=>{this.onmessage(e)};for(const e of Object.keys(this._listeners))this._eventSource.addEventListener(e,this._onevent_wrapped)}_onopen(e){0===this.readyState&&(this.readyState=1,this.onopen(e))}_onerror(e){if(1===this.readyState&&(this.readyState=0,this.onerror(e)),this._eventSource&&2===this._eventSource.readyState){this._eventSource.close(),this._eventSource=null;const e=Math.round(this.max_retry_time*Math.random());this._timer=setTimeout((()=>this._start()),e)}}_onevent(e){e instanceof MessageEvent&&(this._lastEventId=e.lastEventId);const t=this._listeners[e.type];if(null!=t)for(const n of[...t])n.call(this,e);"message"===e.type&&this.onmessage(e)}onopen(e){}onerror(e){}onmessage(e){}close(){this._timer&&(clearTimeout(this._timer),this._timer=null),this._eventSource&&(this._eventSource.close(),this._eventSource=null),this.readyState=2}addEventListener(e,t,n){null==this._listeners[e]&&(this._listeners[e]=[],null!=this._eventSource&&this._eventSource.addEventListener(e,this._onevent_wrapped));const s=this._listeners[e];s.includes(t)||(this._listeners[e]=[...s,t])}removeEventListener(e,t,n){const s=this._listeners[e];this._listeners[e]=s.filter((e=>e!==t))}}}},t={};function n(s){var i=t[s];if(void 0!==i)return i.exports;var r=t[s]={exports:{}};return e[s](r,r.exports,n),r.exports}var s={};(()=>{var e=s;Object.defineProperty(e,"__esModule",{value:!0});const t=n(19);Object.assign(window,{ReconnectingEventSource:t.default,EventSourceNotAvailableError:t.EventSourceNotAvailableError})})(),_ReconnectingEventSource=s})();
2
+ //# sourceMappingURL=ReconnectingEventSource.min.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ReconnectingEventSource.min.js","mappings":"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","sources":["webpack://_ReconnectingEventSource/./src/reconnecting-eventsource.ts","webpack://_ReconnectingEventSource/webpack/bootstrap","webpack://_ReconnectingEventSource/./src/main.browser.ts"],"sourcesContent":["// MIT License:\n//\n// Copyright (C) 2022 Fanout, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal in the Software without restriction, including without limitation the\n// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n// sell copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n// IN THE SOFTWARE.\n\nexport interface ReconnectingEventSourceInit extends EventSourceInit {\n // the maximum time to wait before attempting to reconnect in ms, default `3000`\n // note: wait time is randomised to prevent all clients from attempting to reconnect simultaneously\n max_retry_time?: number;\n\n // the EventSource class to wrap. This allows the use of a polyfill or alternate\n // implementation instead of the platform-provided EventSource class.\n eventSourceClass?: typeof EventSource;\n\n // the last event\n lastEventId?: string;\n}\n\nexport class EventSourceNotAvailableError extends Error {\n constructor() {\n super(\n 'EventSource not available.\\n' +\n 'Consider loading an EventSource polyfill and making it available globally as EventSource, ' +\n 'or passing one in as eventSourceClass to the ReconnectingEventSource constructor.'\n );\n }\n}\n\ntype Listeners = {\n [K in keyof EventSourceEventMap]: ((this: EventSource, ev: EventSourceEventMap[K]) => any)[];\n};\n\nexport default class ReconnectingEventSource implements EventSource {\n\n readonly _configuration: ReconnectingEventSourceInit | undefined;\n readonly CONNECTING = 0;\n readonly OPEN = 1;\n readonly CLOSED = 2;\n\n _eventSource: EventSource | null;\n _lastEventId: string | null;\n _timer: NodeJS.Timer | null;\n _listeners: Listeners;\n _onevent_wrapped: (this: EventSource, ev: Event) => any;\n\n readyState: 0 | 1 | 2;\n url: string;\n withCredentials: boolean;\n\n readonly max_retry_time: number;\n eventSourceClass: typeof EventSource;\n\n constructor(url: string | URL, configuration?: ReconnectingEventSourceInit) {\n this._configuration = configuration != null ? Object.assign({}, configuration) : undefined;\n this.withCredentials = false;\n\n this._eventSource = null;\n this._lastEventId = null;\n this._timer = null;\n this._listeners = {\n open: [],\n error: [],\n message: [],\n };\n\n this.url = url.toString();\n this.readyState = this.CONNECTING;\n this.max_retry_time = 3000;\n this.eventSourceClass = globalThis.EventSource;\n\n if (this._configuration != null) {\n if (this._configuration.lastEventId) {\n this._lastEventId = this._configuration.lastEventId;\n delete this._configuration['lastEventId'];\n }\n\n if (this._configuration.max_retry_time) {\n this.max_retry_time = this._configuration.max_retry_time;\n delete this._configuration['max_retry_time'];\n }\n\n if (this._configuration.eventSourceClass) {\n this.eventSourceClass = this._configuration.eventSourceClass;\n delete this._configuration['eventSourceClass'];\n }\n }\n\n if(this.eventSourceClass == null || typeof this.eventSourceClass !== 'function') {\n throw new EventSourceNotAvailableError();\n }\n\n this._onevent_wrapped = (event) => { this._onevent(event); };\n\n this._start();\n }\n\n dispatchEvent(event: Event): boolean {\n throw new Error(\"Method not implemented.\");\n }\n\n _start() {\n let url = this.url;\n\n if (this._lastEventId) {\n if (url.indexOf('?') === -1) {\n url += '?';\n } else {\n url += '&';\n }\n url += 'lastEventId=' + encodeURIComponent(this._lastEventId);\n }\n\n this._eventSource = new this.eventSourceClass(url, this._configuration);\n\n this._eventSource.onopen = (event) => { this._onopen(event); };\n this._eventSource.onerror = (event) => { this._onerror(event); };\n this._eventSource.onmessage = (event) => { this.onmessage(event); };\n\n // apply listen types\n for (const type of Object.keys(this._listeners)) {\n this._eventSource.addEventListener(type, this._onevent_wrapped);\n }\n }\n\n _onopen(event: Event) {\n if (this.readyState === 0) {\n this.readyState = 1;\n this.onopen(event);\n }\n }\n\n _onerror(event: Event) {\n if (this.readyState === 1) {\n this.readyState = 0;\n this.onerror(event);\n }\n\n if (this._eventSource) {\n if(this._eventSource.readyState === 2) {\n // reconnect with new object\n this._eventSource.close();\n this._eventSource = null;\n\n // reconnect after random timeout < max_retry_time\n const timeout = Math.round(this.max_retry_time * Math.random());\n this._timer = setTimeout(() => this._start(), timeout);\n }\n }\n }\n\n _onevent(event: Event) {\n if (event instanceof MessageEvent) {\n this._lastEventId = event.lastEventId;\n }\n\n const listenersForType = this._listeners[event.type as keyof typeof this._listeners] as ((this:EventSource, ev: Event) => any)[];\n if (listenersForType != null) {\n // operate on a copy\n for (const listener of [...listenersForType]) {\n listener.call(this, event);\n }\n }\n\n if (event.type === 'message') {\n this.onmessage(event as MessageEvent);\n }\n }\n\n onopen(event: Event) {\n // may be overridden\n }\n\n onerror(event: Event) {\n // may be overridden\n }\n\n onmessage(event: MessageEvent) {\n // may be overridden\n }\n\n close() {\n if (this._timer) {\n clearTimeout(this._timer);\n this._timer = null;\n }\n\n if (this._eventSource) {\n this._eventSource.close();\n this._eventSource = null;\n }\n\n this.readyState = 2;\n }\n\n addEventListener<K extends keyof EventSourceEventMap>(type: K, callback: (this: EventSource, ev: EventSourceEventMap[K]) => any, options?: boolean | AddEventListenerOptions) {\n // We don't support options at the moment\n\n if (this._listeners[type] == null) {\n this._listeners[type] = [];\n if (this._eventSource != null) {\n this._eventSource.addEventListener(type, this._onevent_wrapped);\n }\n }\n\n const listenersForType = this._listeners[type];\n if (!listenersForType.includes(callback)) {\n this._listeners[type] = [...listenersForType, callback] as Listeners[typeof type];\n }\n }\n\n removeEventListener<K extends keyof EventSourceEventMap>(type: K, callback: (this: EventSource, ev: EventSourceEventMap[K]) => any, options?: boolean | AddEventListenerOptions) {\n // We don't support options at the moment\n\n const listenersForType = this._listeners[type];\n this._listeners[type] = listenersForType.filter(l => l !== callback) as Listeners[typeof type];\n }\n}\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","import ReconnectingEventSource, { EventSourceNotAvailableError } from './reconnecting-eventsource';\nObject.assign(window, {\n ReconnectingEventSource,\n EventSourceNotAvailableError,\n});\n"],"names":["EventSourceNotAvailableError","Error","constructor","super","url","configuration","CONNECTING","OPEN","CLOSED","this","_configuration","Object","assign","undefined","withCredentials","_eventSource","_lastEventId","_timer","_listeners","open","error","message","toString","readyState","max_retry_time","eventSourceClass","globalThis","EventSource","lastEventId","_onevent_wrapped","event","_onevent","_start","dispatchEvent","indexOf","encodeURIComponent","onopen","_onopen","onerror","_onerror","onmessage","type","keys","addEventListener","close","timeout","Math","round","random","setTimeout","MessageEvent","listenersForType","listener","call","clearTimeout","callback","options","includes","removeEventListener","filter","l","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","exports","module","__webpack_modules__","window","ReconnectingEventSource"],"sourceRoot":""}
package/package.json CHANGED
@@ -1,18 +1,20 @@
1
1
  {
2
2
  "name": "reconnecting-eventsource",
3
- "version": "1.2.0",
3
+ "version": "1.5.0",
4
4
  "description": "wrapper library around the JavaScript EventSource API to ensure it maintains a connection to the server.",
5
- "main": "lib/index.js",
6
- "typings": "reconnecting-eventsource.d.ts",
5
+ "main": "build/src/reconnecting-eventsource.js",
6
+ "module": "build/esm/reconnecting-eventsource.js",
7
+ "esnext": "build/esnext/reconnecting-eventsource.js",
8
+ "types": "build/src/reconnecting-eventsource.d.ts",
7
9
  "scripts": {
8
- "clean": "rimraf lib dist",
9
- "build": "npm run build:commonjs && npm run build:umd && npm run build:umd:min",
10
- "build:commonjs": "cross-env BUILD_TARGET=commonjs webpack",
11
- "build:umd": "cross-env BUILD_TARGET=umd webpack",
12
- "build:umd:min": "cross-env BUILD_TARGET=umd-min webpack",
13
- "check:src": "npm run lint",
14
- "lint": "eslint src",
15
- "prepublishOnly": "npm run clean && npm run check:src && npm run build",
10
+ "clean": "rimraf build browser",
11
+ "build": "npm run build:commonjs && npm run build:esm && npm run build:esnext && npm run build:browser",
12
+ "build:commonjs": "tsc --project tsconfig.json",
13
+ "build:esm": "tsc --project tsconfig.esm.json",
14
+ "build:esnext": "tsc --project tsconfig.esnext.json",
15
+ "build:browser": "webpack",
16
+ "lint": "eslint src --ext .ts",
17
+ "prepublishOnly": "npm run clean && npm run lint && npm run build",
16
18
  "test": "npm run build && node test"
17
19
  },
18
20
  "repository": {
@@ -39,19 +41,33 @@
39
41
  },
40
42
  "homepage": "https://github.com/fanout/reconnecting-eventsource#readme",
41
43
  "devDependencies": {
42
- "babel": "^6.23.0",
43
- "babel-core": "^6.26.3",
44
- "babel-eslint": "^7.2.3",
45
- "babel-loader": "^7.1.1",
46
- "babel-plugin-transform-es2015-modules-umd": "^6.24.1",
47
- "babel-preset-env": "^1.7.0",
48
- "cross-env": "^5.0.1",
49
- "eslint": "^6.6.0",
50
- "eventsource": "^1.0.7",
44
+ "@typescript-eslint/eslint-plugin": "^5.30.5",
45
+ "@typescript-eslint/parser": "^5.30.5",
46
+ "eslint": "^8.19.0",
47
+ "eventsource": "^2.0.2",
51
48
  "rimraf": "^2.6.1",
52
49
  "sse": "0.0.8",
53
50
  "stoppable": "^1.1.0",
54
- "webpack": "^4.41.2",
55
- "webpack-cli": "^3.3.10"
56
- }
51
+ "ts-loader": "^9.3.1",
52
+ "typescript": "^4.7.4",
53
+ "webpack-cli": "^4.10.0"
54
+ },
55
+ "engines": {
56
+ "node": ">=12.0.0"
57
+ },
58
+ "files": [
59
+ "build/esm/**/*.js",
60
+ "build/esm/**/*.js.map",
61
+ "build/esm/**/*.d.ts",
62
+ "build/esnext/**/*.js",
63
+ "build/esnext/**/*.js.map",
64
+ "build/esnext/**/*.d.ts",
65
+ "build/src/**/*.js",
66
+ "build/src/**/*.js.map",
67
+ "build/src/**/*.d.ts",
68
+ "dist/**/*.js",
69
+ "dist/**/*.js.map",
70
+ "COPYING",
71
+ "README.md"
72
+ ]
57
73
  }
package/.eslintignore DELETED
@@ -1 +0,0 @@
1
- *.d.ts
package/.eslintrc.json DELETED
@@ -1,13 +0,0 @@
1
- {
2
- "parser": "babel-eslint",
3
- "parserOptions": {
4
- "ecmaVersion": 2017,
5
- "sourceType": "module"
6
- },
7
- "env": {
8
- "es6": true
9
- },
10
- "rules": {
11
- "semi": 2
12
- }
13
- }
package/.travis.yml DELETED
@@ -1,10 +0,0 @@
1
- language: node_js
2
- node_js:
3
- - "10"
4
- - "9"
5
- - "8"
6
-
7
- install:
8
- - npm install
9
- - npm run build
10
-
@@ -1 +0,0 @@
1
- var ReconnectingEventSource=function(e){var t={};function n(r){if(t[r])return t[r].exports;var i=t[r]={i:r,l:!1,exports:{}};return e[r].call(i.exports,i,i.exports,n),i.l=!0,i.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var i in e)n.d(r,i,function(t){return e[t]}.bind(null,i));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=0)}([function(e,t,n){var r,i,o;i=[e,n(1)],void 0===(o="function"==typeof(r=function(e,t){"use strict";var n,r=(n=t)&&n.__esModule?n:{default:n};e.exports=r.default})?r.apply(t,i):r)||(e.exports=o)},function(e,t,n){var r,i,o;i=[t],void 0===(o="function"==typeof(r=function(e){"use strict";function t(e){if(Array.isArray(e)){for(var t=0,n=Array(e.length);t<e.length;t++)n[t]=e[t];return n}return Array.from(e)}Object.defineProperty(e,"__esModule",{value:!0});var n=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}(),r=function(){function e(t,n){var r=this;!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this._configuration=null!=n?Object.assign({},n):null,this._eventSource=null,this._lastEventId=null,this._timer=null,this._listeners={},this.url=t,this.readyState=0,this.max_retry_time=3e3,null!=this._configuration&&(this._configuration.lastEventId&&(this._lastEventId=this._configuration.lastEventId,delete this._configuration.lastEventId),this._configuration.max_retry_time&&(this.max_retry_time=this._configuration.max_retry_time,delete this._configuration.max_retry_time)),this._onevent_wrapped=function(e){r._onevent(e)},this._start()}return n(e,[{key:"_start",value:function(){var e=this,t=this.url;this._lastEventId&&(-1===t.indexOf("?")?t+="?":t+="&",t+="lastEventId="+encodeURIComponent(this._lastEventId)),this._eventSource=new EventSource(t,this._configuration),this._eventSource.onopen=function(t){e._onopen(t)},this._eventSource.onerror=function(t){e._onerror(t)},this._eventSource.onmessage=function(t){e.onmessage(t)};var n=!0,r=!1,i=void 0;try{for(var o,s=Object.keys(this._listeners)[Symbol.iterator]();!(n=(o=s.next()).done);n=!0){var u=o.value;this._eventSource.addEventListener(u,this._onevent_wrapped)}}catch(e){r=!0,i=e}finally{try{!n&&s.return&&s.return()}finally{if(r)throw i}}}},{key:"_onopen",value:function(e){0===this.readyState&&(this.readyState=1,this.onopen(e))}},{key:"_onerror",value:function(e){var t=this;if(1===this.readyState&&(this.readyState=0,this.onerror(e)),this._eventSource&&2===this._eventSource.readyState){this._eventSource.close(),this._eventSource=null;var n=Math.round(this.max_retry_time*Math.random());this._timer=setTimeout((function(){return t._start()}),n)}}},{key:"_onevent",value:function(e){e.lastEventId&&(this._lastEventId=e.lastEventId);var n=this._listeners[e.type];if(null!=n)for(var r=[].concat(t(n)),i=0;i<r.length;i++)(0,r[i])(e);"message"===e.type&&this.onmessage(e)}},{key:"onopen",value:function(e){}},{key:"onerror",value:function(e){}},{key:"onmessage",value:function(e){}},{key:"close",value:function(){this._timer&&(clearTimeout(this._timer),this._timer=null),this._eventSource&&(this._eventSource.close(),this._eventSource=null),this.readyState=2}},{key:"addEventListener",value:function(e,n){var r=e.toString();r in this._listeners||(this._listeners[r]=[],this._eventSource&&this._eventSource.addEventListener(r,this._onevent_wrapped));var i=this._listeners[r];i.includes(n)||(this._listeners[r]=[].concat(t(i),[n]))}},{key:"removeEventListener",value:function(e,t){var n=e.toString();if(n in this._listeners){var r=this._listeners[n].filter((function(e){return e!==t}));r.length>0?this._listeners[n]=r:(delete this._listeners[n],this._eventSource&&this._eventSource.removeEventListener(n,this._onevent_wrapped))}}}]),e}();e.default=r})?r.apply(t,i):r)||(e.exports=o)}]);
package/lib/index.js DELETED
@@ -1 +0,0 @@
1
- module.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var i=t[r]={i:r,l:!1,exports:{}};return e[r].call(i.exports,i,i.exports,n),i.l=!0,i.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var i in e)n.d(r,i,function(t){return e[t]}.bind(null,i));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=0)}([function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r,i=n(1),o=(r=i)&&r.__esModule?r:{default:r};t.default=o.default},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}();function i(e){if(Array.isArray(e)){for(var t=0,n=Array(e.length);t<e.length;t++)n[t]=e[t];return n}return Array.from(e)}var o=function(){function e(t,n){var r=this;!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this._configuration=null!=n?Object.assign({},n):null,this._eventSource=null,this._lastEventId=null,this._timer=null,this._listeners={},this.url=t,this.readyState=0,this.max_retry_time=3e3,null!=this._configuration&&(this._configuration.lastEventId&&(this._lastEventId=this._configuration.lastEventId,delete this._configuration.lastEventId),this._configuration.max_retry_time&&(this.max_retry_time=this._configuration.max_retry_time,delete this._configuration.max_retry_time)),this._onevent_wrapped=function(e){r._onevent(e)},this._start()}return r(e,[{key:"_start",value:function(){var e=this,t=this.url;this._lastEventId&&(-1===t.indexOf("?")?t+="?":t+="&",t+="lastEventId="+encodeURIComponent(this._lastEventId)),this._eventSource=new EventSource(t,this._configuration),this._eventSource.onopen=function(t){e._onopen(t)},this._eventSource.onerror=function(t){e._onerror(t)},this._eventSource.onmessage=function(t){e.onmessage(t)};var n=!0,r=!1,i=void 0;try{for(var o,s=Object.keys(this._listeners)[Symbol.iterator]();!(n=(o=s.next()).done);n=!0){var u=o.value;this._eventSource.addEventListener(u,this._onevent_wrapped)}}catch(e){r=!0,i=e}finally{try{!n&&s.return&&s.return()}finally{if(r)throw i}}}},{key:"_onopen",value:function(e){0===this.readyState&&(this.readyState=1,this.onopen(e))}},{key:"_onerror",value:function(e){var t=this;if(1===this.readyState&&(this.readyState=0,this.onerror(e)),this._eventSource&&2===this._eventSource.readyState){this._eventSource.close(),this._eventSource=null;var n=Math.round(this.max_retry_time*Math.random());this._timer=setTimeout((function(){return t._start()}),n)}}},{key:"_onevent",value:function(e){e.lastEventId&&(this._lastEventId=e.lastEventId);var t=this._listeners[e.type];if(null!=t)for(var n=[].concat(i(t)),r=0;r<n.length;r++){(0,n[r])(e)}"message"===e.type&&this.onmessage(e)}},{key:"onopen",value:function(e){}},{key:"onerror",value:function(e){}},{key:"onmessage",value:function(e){}},{key:"close",value:function(){this._timer&&(clearTimeout(this._timer),this._timer=null),this._eventSource&&(this._eventSource.close(),this._eventSource=null),this.readyState=2}},{key:"addEventListener",value:function(e,t){var n=e.toString();n in this._listeners||(this._listeners[n]=[],this._eventSource&&this._eventSource.addEventListener(n,this._onevent_wrapped));var r=this._listeners[n];r.includes(t)||(this._listeners[n]=[].concat(i(r),[t]))}},{key:"removeEventListener",value:function(e,t){var n=e.toString();if(n in this._listeners){var r=this._listeners[n].filter((function(e){return e!==t}));r.length>0?this._listeners[n]=r:(delete this._listeners[n],this._eventSource&&this._eventSource.removeEventListener(n,this._onevent_wrapped))}}}]),e}();t.default=o}]);
@@ -1,11 +0,0 @@
1
- export interface ReconnectableEventSourceInit extends EventSourceInit {
2
- // the maximum time to wait before attempting to reconnect in ms, default `3000`
3
- // note: wait time is randomised to prevent all clients from attempting to reconnect simultaneously
4
- max_retry_time?: number;
5
- }
6
-
7
- export default class ReconnectingEventSource extends EventSource {
8
- constructor(url: string, configuration?: ReconnectableEventSourceInit);
9
-
10
- readonly max_retry_time: number;
11
- }
package/src/index-umd.js DELETED
@@ -1,2 +0,0 @@
1
- import ReconnectingEventSource from "./reconnecting-eventsource";
2
- module.exports = ReconnectingEventSource;
package/src/index.js DELETED
@@ -1,2 +0,0 @@
1
- import ReconnectingEventSource from "./reconnecting-eventsource";
2
- export default ReconnectingEventSource;
package/test.js DELETED
@@ -1,108 +0,0 @@
1
- EventSource = require('eventsource');
2
- const ReconnectingEventSource = require('.').default;
3
- const http = require('http');
4
- const SSE = require('sse');
5
- const stoppable = require('stoppable');
6
- const EventEmitter = require('events').EventEmitter;
7
-
8
- // Return an EventEmitter that emits an event named 'event' every second
9
- const clockEvents = () => {
10
- const events = new EventEmitter;
11
- const emitSecond = () => events.emit('event', new Date);
12
- emitSecond();
13
- const interval = setInterval(emitSecond, 1000);
14
- return {
15
- events,
16
- destroy: () => {
17
- clearInterval(interval);
18
- events.removeAllListeners();
19
- }
20
- };
21
- };
22
-
23
- // Return an HTTP server that serves SSE at /sse
24
- const createSseServer = (eventEmitter, name) => {
25
- const server = http.createServer(function(req, res) {
26
- res.writeHead(200, {'Content-Type': 'text/plain'});
27
- res.end('server-sent events are at /sse');
28
- });
29
- const sseServer = new SSE(server);
30
- sseServer.on('connection', function(client) {
31
- const listener = (event) => {
32
- client.send(`${name || 'sseServer'}: ${String(event)}`);
33
- };
34
- eventEmitter.addListener('event', listener);
35
- client.once('close', () => {
36
- eventEmitter.removeListener('event', listener);
37
- });
38
- });
39
- return server;
40
- };
41
-
42
- const onceEvent = (eventTarget, eventName) => new Promise((resolve, reject) => {
43
- const onceEventListener = function(event) {
44
- eventTarget.removeEventListener(eventName, onceEventListener);
45
- return resolve(event);
46
- };
47
- eventTarget.addEventListener(eventName, onceEventListener);
48
- });
49
-
50
- const main = async () => {
51
- const clock = clockEvents();
52
-
53
- // Create server1
54
- const server1 = stoppable(createSseServer(clock.events, 'server1'), 0);
55
- await new Promise(async (resolve, reject) => {
56
- server1.listen(0, (error) => error ? reject(error) : resolve());
57
- });
58
- const server1Port = server1.address().port;
59
- const server1SseUrl = `http://localhost:${server1.address().port}/sse`;
60
-
61
- // Set up Eventsource
62
- const eventSource = new ReconnectingEventSource(server1SseUrl);
63
- eventSource.addEventListener('error', (error) => {
64
- console.error('eventSource error', error);
65
- });
66
- eventSource.addEventListener('open', () => {
67
- console.debug('eventSource open');
68
- });
69
-
70
- // await an event
71
- const event1 = await onceEvent(eventSource, 'message');
72
- console.debug('event1', event1.data);
73
-
74
- // Close server1, triggering reconnect
75
- console.debug('Closing server1');
76
- await new Promise((resolve, reject) => {
77
- server1.stop(error => error ? reject(error) : resolve());
78
- });
79
- console.debug('server1 closed');
80
-
81
- // Make server2, which eventSource should reconnect to
82
- const server2 = createSseServer(clock.events, 'server2');
83
- const server2Port = server1Port;
84
- await new Promise(async (resolve, reject) => {
85
- server2.listen(server2Port, (error) => error ? reject(error) : resolve());
86
- });
87
- console.debug('server2 is listening');
88
-
89
- // we should have reconnected and be able to get an event
90
- const event2 = await onceEvent(eventSource, 'message');
91
- console.debug('event2', event2.data);
92
- server2.close();
93
-
94
- // clean up
95
- eventSource.close();
96
- clock.destroy();
97
-
98
- // test construction with config
99
- const eventSource2 = new ReconnectingEventSource(server1SseUrl, {
100
- lastEventId: 'abc',
101
- max_retry_time: 5000,
102
- });
103
- eventSource2.close();
104
- };
105
-
106
- if (require.main === module) {
107
- main().catch((error) => { throw error; });
108
- }
package/tsconfig.json DELETED
@@ -1,8 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "lib": [
4
- "esnext",
5
- "dom"
6
- ]
7
- }
8
- }