websocket-ts 1.1.1 → 2.1.1
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.
- package/LICENSE +1 -1
- package/README.md +157 -93
- package/package.json +27 -14
- package/src/backoff/backoff.ts +21 -13
- package/src/backoff/constantbackoff.ts +29 -11
- package/src/backoff/exponentialbackoff.ts +68 -28
- package/src/backoff/linearbackoff.ts +77 -26
- package/src/index.ts +23 -9
- package/src/queue/array_queue.ts +41 -0
- package/src/queue/queue.ts +46 -0
- package/src/queue/ring_queue.ts +69 -0
- package/src/websocket.ts +463 -138
- package/src/websocket_buffer.ts +18 -0
- package/src/websocket_builder.ts +274 -0
- package/src/websocket_event.ts +88 -0
- package/src/websocket_options.ts +23 -0
- package/src/websocket_retry_options.ts +22 -0
- package/{tsconfig.json → tsconfig.cjs.json} +8 -8
- package/tsconfig.esm.json +71 -0
- package/jest.config.js +0 -9
- package/lib/backoff/backoff.d.ts +0 -18
- package/lib/backoff/backoff.d.ts.map +0 -1
- package/lib/backoff/backoff.js +0 -3
- package/lib/backoff/backoff.js.map +0 -1
- package/lib/backoff/constantbackoff.d.ts +0 -11
- package/lib/backoff/constantbackoff.d.ts.map +0 -1
- package/lib/backoff/constantbackoff.js +0 -20
- package/lib/backoff/constantbackoff.js.map +0 -1
- package/lib/backoff/exponentialbackoff.d.ts +0 -22
- package/lib/backoff/exponentialbackoff.d.ts.map +0 -1
- package/lib/backoff/exponentialbackoff.js +0 -35
- package/lib/backoff/exponentialbackoff.js.map +0 -1
- package/lib/backoff/linearbackoff.d.ts +0 -19
- package/lib/backoff/linearbackoff.d.ts.map +0 -1
- package/lib/backoff/linearbackoff.js +0 -34
- package/lib/backoff/linearbackoff.js.map +0 -1
- package/lib/buffer/buffer.d.ts +0 -41
- package/lib/buffer/buffer.d.ts.map +0 -1
- package/lib/buffer/buffer.js +0 -3
- package/lib/buffer/buffer.js.map +0 -1
- package/lib/buffer/lrubuffer.d.ts +0 -24
- package/lib/buffer/lrubuffer.d.ts.map +0 -1
- package/lib/buffer/lrubuffer.js +0 -76
- package/lib/buffer/lrubuffer.js.map +0 -1
- package/lib/buffer/timebuffer.d.ts +0 -25
- package/lib/buffer/timebuffer.d.ts.map +0 -1
- package/lib/buffer/timebuffer.js +0 -92
- package/lib/buffer/timebuffer.js.map +0 -1
- package/lib/index.d.ts +0 -10
- package/lib/index.d.ts.map +0 -1
- package/lib/index.js +0 -22
- package/lib/index.js.map +0 -1
- package/lib/websocket.d.ts +0 -47
- package/lib/websocket.d.ts.map +0 -1
- package/lib/websocket.js +0 -120
- package/lib/websocket.js.map +0 -1
- package/lib/websocketBuilder.d.ts +0 -32
- package/lib/websocketBuilder.d.ts.map +0 -1
- package/lib/websocketBuilder.js +0 -68
- package/lib/websocketBuilder.js.map +0 -1
- package/src/buffer/buffer.ts +0 -45
- package/src/buffer/lrubuffer.ts +0 -80
- package/src/buffer/timebuffer.ts +0 -105
- package/src/websocketBuilder.ts +0 -98
- package/test/backoff/constantbackoff.test.ts +0 -21
- package/test/backoff/exponentialbackoff.test.ts +0 -13
- package/test/backoff/linearbackoff.test.ts +0 -32
- package/test/buffer/common.ts +0 -10
- package/test/buffer/lrubuffer.test.ts +0 -128
- package/test/buffer/timebuffer.test.ts +0 -115
- package/test/websocket.test.ts +0 -341
- package/test/websocketBuilder.test.ts +0 -36
package/lib/websocketBuilder.js
DELETED
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.WebsocketBuilder = void 0;
|
|
4
|
-
var websocket_1 = require("./websocket");
|
|
5
|
-
/**
|
|
6
|
-
* Used to build Websocket-instances.
|
|
7
|
-
*/
|
|
8
|
-
var WebsocketBuilder = /** @class */ (function () {
|
|
9
|
-
function WebsocketBuilder(url) {
|
|
10
|
-
this.ws = null;
|
|
11
|
-
this.onOpenListeners = [];
|
|
12
|
-
this.onCloseListeners = [];
|
|
13
|
-
this.onErrorListeners = [];
|
|
14
|
-
this.onMessageListeners = [];
|
|
15
|
-
this.onRetryListeners = [];
|
|
16
|
-
this.url = url;
|
|
17
|
-
}
|
|
18
|
-
WebsocketBuilder.prototype.withProtocols = function (p) {
|
|
19
|
-
this.protocols = p;
|
|
20
|
-
return this;
|
|
21
|
-
};
|
|
22
|
-
WebsocketBuilder.prototype.withBackoff = function (backoff) {
|
|
23
|
-
this.backoff = backoff;
|
|
24
|
-
return this;
|
|
25
|
-
};
|
|
26
|
-
WebsocketBuilder.prototype.withBuffer = function (buffer) {
|
|
27
|
-
this.buffer = buffer;
|
|
28
|
-
return this;
|
|
29
|
-
};
|
|
30
|
-
WebsocketBuilder.prototype.onOpen = function (listener, options) {
|
|
31
|
-
this.onOpenListeners.push({ listener: listener, options: options });
|
|
32
|
-
return this;
|
|
33
|
-
};
|
|
34
|
-
WebsocketBuilder.prototype.onClose = function (listener, options) {
|
|
35
|
-
this.onCloseListeners.push({ listener: listener, options: options });
|
|
36
|
-
return this;
|
|
37
|
-
};
|
|
38
|
-
WebsocketBuilder.prototype.onError = function (listener, options) {
|
|
39
|
-
this.onErrorListeners.push({ listener: listener, options: options });
|
|
40
|
-
return this;
|
|
41
|
-
};
|
|
42
|
-
WebsocketBuilder.prototype.onMessage = function (listener, options) {
|
|
43
|
-
this.onMessageListeners.push({ listener: listener, options: options });
|
|
44
|
-
return this;
|
|
45
|
-
};
|
|
46
|
-
WebsocketBuilder.prototype.onRetry = function (listener, options) {
|
|
47
|
-
this.onRetryListeners.push({ listener: listener, options: options });
|
|
48
|
-
return this;
|
|
49
|
-
};
|
|
50
|
-
/**
|
|
51
|
-
* Multiple calls to build() will always return the same websocket-instance.
|
|
52
|
-
*/
|
|
53
|
-
WebsocketBuilder.prototype.build = function () {
|
|
54
|
-
var _this = this;
|
|
55
|
-
if (this.ws !== null)
|
|
56
|
-
return this.ws;
|
|
57
|
-
this.ws = new websocket_1.Websocket(this.url, this.protocols, this.buffer, this.backoff);
|
|
58
|
-
this.onOpenListeners.forEach(function (h) { var _a; return (_a = _this.ws) === null || _a === void 0 ? void 0 : _a.addEventListener(websocket_1.WebsocketEvents.open, h.listener, h.options); });
|
|
59
|
-
this.onCloseListeners.forEach(function (h) { var _a; return (_a = _this.ws) === null || _a === void 0 ? void 0 : _a.addEventListener(websocket_1.WebsocketEvents.close, h.listener, h.options); });
|
|
60
|
-
this.onErrorListeners.forEach(function (h) { var _a; return (_a = _this.ws) === null || _a === void 0 ? void 0 : _a.addEventListener(websocket_1.WebsocketEvents.error, h.listener, h.options); });
|
|
61
|
-
this.onMessageListeners.forEach(function (h) { var _a; return (_a = _this.ws) === null || _a === void 0 ? void 0 : _a.addEventListener(websocket_1.WebsocketEvents.message, h.listener, h.options); });
|
|
62
|
-
this.onRetryListeners.forEach(function (h) { var _a; return (_a = _this.ws) === null || _a === void 0 ? void 0 : _a.addEventListener(websocket_1.WebsocketEvents.retry, h.listener, h.options); });
|
|
63
|
-
return this.ws;
|
|
64
|
-
};
|
|
65
|
-
return WebsocketBuilder;
|
|
66
|
-
}());
|
|
67
|
-
exports.WebsocketBuilder = WebsocketBuilder;
|
|
68
|
-
//# sourceMappingURL=websocketBuilder.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"websocketBuilder.js","sourceRoot":"","sources":["../src/websocketBuilder.ts"],"names":[],"mappings":";;;AAEA,yCAA0E;AAE1E;;GAEG;AACH;IA2BI,0BAAY,GAAW;QAzBf,OAAE,GAAqB,IAAI,CAAC;QAI5B,oBAAe,GAGhB,EAAE,CAAC;QACF,qBAAgB,GAGjB,EAAE,CAAC;QACF,qBAAgB,GAGjB,EAAE,CAAC;QACF,uBAAkB,GAGnB,EAAE,CAAC;QACF,qBAAgB,GAGjB,EAAE,CAAC;QAGN,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;IACnB,CAAC;IAEM,wCAAa,GAApB,UAAqB,CAAoB;QACrC,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC;QACnB,OAAO,IAAI,CAAC;IAChB,CAAC;IAEM,sCAAW,GAAlB,UAAmB,OAAgB;QAC/B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,OAAO,IAAI,CAAC;IAChB,CAAC;IAEM,qCAAU,GAAjB,UAAkB,MAAmB;QACjC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,OAAO,IAAI,CAAC;IAChB,CAAC;IAEM,iCAAM,GAAb,UAAc,QAAiD,EACjD,OAAwC;QAClD,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,EAAC,QAAQ,UAAA,EAAE,OAAO,SAAA,EAAC,CAAC,CAAC;QAC/C,OAAO,IAAI,CAAC;IAChB,CAAC;IAEM,kCAAO,GAAd,UAAe,QAAsD,EACtD,OAAwC;QACnD,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,EAAC,QAAQ,UAAA,EAAE,OAAO,SAAA,EAAC,CAAC,CAAC;QAChD,OAAO,IAAI,CAAC;IAChB,CAAC;IAEM,kCAAO,GAAd,UAAe,QAAiD,EACjD,OAAwC;QACnD,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,EAAC,QAAQ,UAAA,EAAE,OAAO,SAAA,EAAC,CAAC,CAAC;QAChD,OAAO,IAAI,CAAC;IAChB,CAAC;IAEM,oCAAS,GAAhB,UAAiB,QAAwD,EACxD,OAAwC;QACrD,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,EAAC,QAAQ,UAAA,EAAE,OAAO,SAAA,EAAC,CAAC,CAAC;QAClD,OAAO,IAAI,CAAC;IAChB,CAAC;IAEM,kCAAO,GAAd,UAAe,QAA0E,EAC1E,OAAwC;QACnD,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,EAAC,QAAQ,UAAA,EAAE,OAAO,SAAA,EAAC,CAAC,CAAC;QAChD,OAAO,IAAI,CAAC;IAChB,CAAC;IAED;;OAEG;IACI,gCAAK,GAAZ;QAAA,iBAUC;QATG,IAAI,IAAI,CAAC,EAAE,KAAK,IAAI;YAChB,OAAO,IAAI,CAAC,EAAE,CAAC;QACnB,IAAI,CAAC,EAAE,GAAG,IAAI,qBAAS,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;QAC7E,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,UAAA,CAAC,YAAI,OAAA,MAAA,KAAI,CAAC,EAAE,0CAAE,gBAAgB,CAAC,2BAAe,CAAC,IAAI,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,OAAO,CAAC,CAAA,EAAA,CAAC,CAAC;QAC1G,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,UAAA,CAAC,YAAI,OAAA,MAAA,KAAI,CAAC,EAAE,0CAAE,gBAAgB,CAAC,2BAAe,CAAC,KAAK,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,OAAO,CAAC,CAAA,EAAA,CAAC,CAAC;QAC5G,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,UAAA,CAAC,YAAI,OAAA,MAAA,KAAI,CAAC,EAAE,0CAAE,gBAAgB,CAAC,2BAAe,CAAC,KAAK,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,OAAO,CAAC,CAAA,EAAA,CAAC,CAAC;QAC5G,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,UAAA,CAAC,YAAI,OAAA,MAAA,KAAI,CAAC,EAAE,0CAAE,gBAAgB,CAAC,2BAAe,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,OAAO,CAAC,CAAA,EAAA,CAAC,CAAC;QAChH,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,UAAA,CAAC,YAAI,OAAA,MAAA,KAAI,CAAC,EAAE,0CAAE,gBAAgB,CAAC,2BAAe,CAAC,KAAK,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,OAAO,CAAC,CAAA,EAAA,CAAC,CAAC;QAC5G,OAAO,IAAI,CAAC,EAAE,CAAC;IACnB,CAAC;IACL,uBAAC;AAAD,CAAC,AA1FD,IA0FC;AA1FY,4CAAgB"}
|
package/src/buffer/buffer.ts
DELETED
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Temporary container for generic elements.
|
|
3
|
-
*/
|
|
4
|
-
export interface Buffer<E> {
|
|
5
|
-
/**
|
|
6
|
-
* Length of the buffer, the count of elements
|
|
7
|
-
* that can be read from the buffer.
|
|
8
|
-
* @return the length of the buffer
|
|
9
|
-
*/
|
|
10
|
-
len(): number
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Capacity of the buffer, the total amount of
|
|
14
|
-
* elements the buffer can contain.
|
|
15
|
-
* @return the capacity of the buffer
|
|
16
|
-
*/
|
|
17
|
-
cap(): number
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Reads elements from the buffer.
|
|
21
|
-
* @param es array to read into from the buffer
|
|
22
|
-
* @return the count of elements that were read
|
|
23
|
-
*/
|
|
24
|
-
read(es: E[]): number
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Writes elements to the buffer.
|
|
28
|
-
* @param es array to write to the buffer
|
|
29
|
-
* @return the count of elements that were written
|
|
30
|
-
*/
|
|
31
|
-
write(es: E[]): number
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Applies a function to every element in the buffer.
|
|
35
|
-
* @param fn the function to apply to every element
|
|
36
|
-
* @return: the count of elements that were used
|
|
37
|
-
*/
|
|
38
|
-
forEach(fn: (e: E) => any): number
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Clears the buffer. This effectively removes all
|
|
42
|
-
* items in the buffer.
|
|
43
|
-
*/
|
|
44
|
-
clear(): void
|
|
45
|
-
}
|
package/src/buffer/lrubuffer.ts
DELETED
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
import {Buffer} from "./buffer";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* LRUBuffer is a buffer that keeps the last n elements. When it is
|
|
5
|
-
* full and written to, the oldest element in the buffer will be
|
|
6
|
-
* replaced. When reading from the LRUBuffer, elements are returned
|
|
7
|
-
* in FIFO-order (queue).
|
|
8
|
-
*
|
|
9
|
-
* LRUBuffer has linear space- and time-requirements. Internally
|
|
10
|
-
* an array is used as a circular-buffer. All memory is allocated
|
|
11
|
-
* on initialization.
|
|
12
|
-
*/
|
|
13
|
-
export class LRUBuffer<E> implements Buffer<E> {
|
|
14
|
-
private readonly buffer: E[];
|
|
15
|
-
private writePtr: number = 0;
|
|
16
|
-
private wrapped: boolean = false;
|
|
17
|
-
|
|
18
|
-
constructor(len: number) {
|
|
19
|
-
this.buffer = Array<E>(len);
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
len(): number {
|
|
23
|
-
return this.wrapped ? this.buffer.length : this.writePtr;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
cap(): number {
|
|
27
|
-
return this.buffer.length;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
read(es: E[]): number {
|
|
31
|
-
if (es === null || es === undefined || es.length === 0 || this.buffer.length === 0)
|
|
32
|
-
return 0;
|
|
33
|
-
if (this.writePtr === 0 && !this.wrapped)
|
|
34
|
-
return 0;
|
|
35
|
-
const first = this.wrapped ? this.writePtr : 0;
|
|
36
|
-
const last = (first - 1) < 0 ?
|
|
37
|
-
this.buffer.length - 1 :
|
|
38
|
-
first - 1;
|
|
39
|
-
for (let i = 0; i < es.length; i++) {
|
|
40
|
-
let r = (first + i) % this.buffer.length;
|
|
41
|
-
es[i] = this.buffer[r];
|
|
42
|
-
if (r === last)
|
|
43
|
-
return i + 1;
|
|
44
|
-
}
|
|
45
|
-
return es.length;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
write(es: E[]): number {
|
|
49
|
-
if (es === null || es === undefined || es.length === 0 || this.buffer.length === 0)
|
|
50
|
-
return 0;
|
|
51
|
-
const start = es.length > this.buffer.length ? es.length - this.buffer.length : 0;
|
|
52
|
-
for (let i = 0; i < es.length - start; i++) {
|
|
53
|
-
this.buffer[this.writePtr] = es[start + i];
|
|
54
|
-
this.writePtr = (this.writePtr + 1) % this.buffer.length;
|
|
55
|
-
if (this.writePtr === 0)
|
|
56
|
-
this.wrapped = true;
|
|
57
|
-
}
|
|
58
|
-
return es.length;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
forEach(fn: (e: E) => any): number {
|
|
62
|
-
if (this.writePtr === 0 && !this.wrapped)
|
|
63
|
-
return 0;
|
|
64
|
-
let cur = this.wrapped ? this.writePtr : 0;
|
|
65
|
-
const last = this.wrapped ? (cur - 1) < 0 ? this.buffer.length - 1 : cur - 1 : this.writePtr - 1;
|
|
66
|
-
const len = this.len();
|
|
67
|
-
while (true) {
|
|
68
|
-
fn(this.buffer[cur]);
|
|
69
|
-
if (cur === last)
|
|
70
|
-
break;
|
|
71
|
-
cur = (cur + 1) % this.buffer.length;
|
|
72
|
-
}
|
|
73
|
-
return len;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
clear(): void {
|
|
77
|
-
this.writePtr = 0;
|
|
78
|
-
this.wrapped = false;
|
|
79
|
-
}
|
|
80
|
-
}
|
package/src/buffer/timebuffer.ts
DELETED
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
import {Buffer} from "./buffer";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* TimeBuffer keeps the elements that were written to the buffer
|
|
5
|
-
* within maxAge milliseconds. For example, to keep items in the
|
|
6
|
-
* buffer that are less than a minute old, create the buffer with
|
|
7
|
-
* maxAge equal to 60.000.
|
|
8
|
-
*
|
|
9
|
-
* When reading from the TimeBuffer, elements will be returned
|
|
10
|
-
* in FIFO-order (queue).
|
|
11
|
-
*/
|
|
12
|
-
export class TimeBuffer<E> implements Buffer<E> {
|
|
13
|
-
private readonly maxAge: number;
|
|
14
|
-
private tail?: elementWithTimestamp<E>;
|
|
15
|
-
private head?: elementWithTimestamp<E>;
|
|
16
|
-
|
|
17
|
-
constructor(maxAge: number) {
|
|
18
|
-
this.maxAge = maxAge;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
cap(): number {
|
|
22
|
-
return Number.POSITIVE_INFINITY;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
len(): number {
|
|
26
|
-
this.forwardTail();
|
|
27
|
-
let cur = this.tail;
|
|
28
|
-
let i = 0;
|
|
29
|
-
while (cur !== undefined) {
|
|
30
|
-
i++;
|
|
31
|
-
cur = cur.n;
|
|
32
|
-
}
|
|
33
|
-
return i;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
read(es: E[]): number {
|
|
37
|
-
this.forwardTail();
|
|
38
|
-
if (es.length === 0)
|
|
39
|
-
return 0;
|
|
40
|
-
let cur = this.tail;
|
|
41
|
-
let i = 0;
|
|
42
|
-
while (cur !== undefined) {
|
|
43
|
-
es[i++] = cur.e;
|
|
44
|
-
if (i === es.length)
|
|
45
|
-
break;
|
|
46
|
-
cur = cur.n;
|
|
47
|
-
}
|
|
48
|
-
return i;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
write(es: E[]): number {
|
|
52
|
-
for (let i = 0; i < es.length; i++)
|
|
53
|
-
this.putElement(es[i]);
|
|
54
|
-
return es.length;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
forEach(fn: (e: E) => any): number {
|
|
58
|
-
this.forwardTail();
|
|
59
|
-
let cur = this.tail;
|
|
60
|
-
let i = 0;
|
|
61
|
-
while (cur !== undefined) {
|
|
62
|
-
fn(cur.e);
|
|
63
|
-
i++;
|
|
64
|
-
cur = cur.n;
|
|
65
|
-
}
|
|
66
|
-
return i;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
private putElement(e: E) {
|
|
70
|
-
const newElement = {e, t: Date.now(), n: undefined} as elementWithTimestamp<E>;
|
|
71
|
-
if (this.tail === undefined)
|
|
72
|
-
this.tail = newElement;
|
|
73
|
-
if (this.head === undefined)
|
|
74
|
-
this.head = newElement
|
|
75
|
-
else {
|
|
76
|
-
this.head.n = newElement;
|
|
77
|
-
this.head = newElement;
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
private forwardTail() {
|
|
82
|
-
if (this.tail === undefined)
|
|
83
|
-
return;
|
|
84
|
-
const d = Date.now();
|
|
85
|
-
while (d - this.tail.t > this.maxAge) {
|
|
86
|
-
if (this.tail === this.head) {
|
|
87
|
-
this.tail = undefined;
|
|
88
|
-
this.head = undefined;
|
|
89
|
-
} else
|
|
90
|
-
this.tail = this.tail.n;
|
|
91
|
-
if (this.tail === undefined)
|
|
92
|
-
break;
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
clear(): void {
|
|
97
|
-
// TODO
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
type elementWithTimestamp<E> = {
|
|
102
|
-
e: E,
|
|
103
|
-
t: number,
|
|
104
|
-
n?: elementWithTimestamp<E>
|
|
105
|
-
}
|
package/src/websocketBuilder.ts
DELETED
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
import {Backoff} from "./backoff/backoff";
|
|
2
|
-
import {Buffer} from "./buffer/buffer";
|
|
3
|
-
import {RetryEventDetails, Websocket, WebsocketEvents} from "./websocket";
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Used to build Websocket-instances.
|
|
7
|
-
*/
|
|
8
|
-
export class WebsocketBuilder {
|
|
9
|
-
private readonly url: string;
|
|
10
|
-
private ws: Websocket | null = null;
|
|
11
|
-
private protocols?: string | string[];
|
|
12
|
-
private backoff?: Backoff;
|
|
13
|
-
private buffer?: Buffer<string | ArrayBufferLike | Blob | ArrayBufferView>;
|
|
14
|
-
private onOpenListeners: ({
|
|
15
|
-
listener: (instance: Websocket, ev: Event) => any,
|
|
16
|
-
options?: boolean | EventListenerOptions
|
|
17
|
-
})[] = [];
|
|
18
|
-
private onCloseListeners: ({
|
|
19
|
-
listener: (instance: Websocket, ev: CloseEvent) => any,
|
|
20
|
-
options?: boolean | EventListenerOptions
|
|
21
|
-
})[] = [];
|
|
22
|
-
private onErrorListeners: ({
|
|
23
|
-
listener: (instance: Websocket, ev: Event) => any,
|
|
24
|
-
options?: boolean | EventListenerOptions
|
|
25
|
-
})[] = [];
|
|
26
|
-
private onMessageListeners: ({
|
|
27
|
-
listener: (instance: Websocket, ev: MessageEvent) => any,
|
|
28
|
-
options?: boolean | EventListenerOptions
|
|
29
|
-
})[] = [];
|
|
30
|
-
private onRetryListeners: ({
|
|
31
|
-
listener: (instance: Websocket, ev: CustomEvent<RetryEventDetails>) => any,
|
|
32
|
-
options?: boolean | EventListenerOptions
|
|
33
|
-
})[] = [];
|
|
34
|
-
|
|
35
|
-
constructor(url: string) {
|
|
36
|
-
this.url = url;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
public withProtocols(p: string | string[]): WebsocketBuilder {
|
|
40
|
-
this.protocols = p;
|
|
41
|
-
return this;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
public withBackoff(backoff: Backoff): WebsocketBuilder {
|
|
45
|
-
this.backoff = backoff;
|
|
46
|
-
return this;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
public withBuffer(buffer: Buffer<any>): WebsocketBuilder {
|
|
50
|
-
this.buffer = buffer;
|
|
51
|
-
return this;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
public onOpen(listener: (instance: Websocket, ev: Event) => any,
|
|
55
|
-
options?: boolean | EventListenerOptions): WebsocketBuilder {
|
|
56
|
-
this.onOpenListeners.push({listener, options});
|
|
57
|
-
return this;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
public onClose(listener: (instance: Websocket, ev: CloseEvent) => any,
|
|
61
|
-
options?: boolean | EventListenerOptions): WebsocketBuilder {
|
|
62
|
-
this.onCloseListeners.push({listener, options});
|
|
63
|
-
return this;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
public onError(listener: (instance: Websocket, ev: Event) => any,
|
|
67
|
-
options?: boolean | EventListenerOptions): WebsocketBuilder {
|
|
68
|
-
this.onErrorListeners.push({listener, options});
|
|
69
|
-
return this;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
public onMessage(listener: (instance: Websocket, ev: MessageEvent) => any,
|
|
73
|
-
options?: boolean | EventListenerOptions): WebsocketBuilder {
|
|
74
|
-
this.onMessageListeners.push({listener, options});
|
|
75
|
-
return this;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
public onRetry(listener: (instance: Websocket, ev: CustomEvent<RetryEventDetails>) => any,
|
|
79
|
-
options?: boolean | EventListenerOptions): WebsocketBuilder {
|
|
80
|
-
this.onRetryListeners.push({listener, options});
|
|
81
|
-
return this;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
/**
|
|
85
|
-
* Multiple calls to build() will always return the same websocket-instance.
|
|
86
|
-
*/
|
|
87
|
-
public build(): Websocket {
|
|
88
|
-
if (this.ws !== null)
|
|
89
|
-
return this.ws;
|
|
90
|
-
this.ws = new Websocket(this.url, this.protocols, this.buffer, this.backoff);
|
|
91
|
-
this.onOpenListeners.forEach(h => this.ws?.addEventListener(WebsocketEvents.open, h.listener, h.options));
|
|
92
|
-
this.onCloseListeners.forEach(h => this.ws?.addEventListener(WebsocketEvents.close, h.listener, h.options));
|
|
93
|
-
this.onErrorListeners.forEach(h => this.ws?.addEventListener(WebsocketEvents.error, h.listener, h.options));
|
|
94
|
-
this.onMessageListeners.forEach(h => this.ws?.addEventListener(WebsocketEvents.message, h.listener, h.options));
|
|
95
|
-
this.onRetryListeners.forEach(h => this.ws?.addEventListener(WebsocketEvents.retry, h.listener, h.options));
|
|
96
|
-
return this.ws;
|
|
97
|
-
}
|
|
98
|
-
}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import {ConstantBackoff} from "../../src";
|
|
2
|
-
|
|
3
|
-
describe("Testsuite for ConstantBackoff", () => {
|
|
4
|
-
test("ConstantBackoff should always return the same value 0", () => {
|
|
5
|
-
const sut = new ConstantBackoff(0);
|
|
6
|
-
for (let i = 0; i < 10; i++)
|
|
7
|
-
expect(sut.next()).toBe(0);
|
|
8
|
-
sut.reset();
|
|
9
|
-
for (let i = 0; i < 10; i++)
|
|
10
|
-
expect(sut.next()).toBe(0);
|
|
11
|
-
});
|
|
12
|
-
|
|
13
|
-
test("ConstantBackoff should always return the same value 1000", () => {
|
|
14
|
-
const sut = new ConstantBackoff(1000);
|
|
15
|
-
for (let i = 0; i < 10; i++)
|
|
16
|
-
expect(sut.next()).toBe(1000);
|
|
17
|
-
sut.reset();
|
|
18
|
-
for (let i = 0; i < 10; i++)
|
|
19
|
-
expect(sut.next()).toBe(1000);
|
|
20
|
-
});
|
|
21
|
-
})
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import {ExponentialBackoff} from "../../src/";
|
|
2
|
-
|
|
3
|
-
describe("Testsuite for ExponentialBackoff", () => {
|
|
4
|
-
test("ExponentialBackoff should produce an exponentially increasing series", () => {
|
|
5
|
-
const sut = new ExponentialBackoff(100, 7);
|
|
6
|
-
const expected = [100, 200, 400, 800, 1600, 3200, 6400, 6400, 6400, 6400];
|
|
7
|
-
for (let i = 0; i < expected.length; i++)
|
|
8
|
-
expect(sut.next()).toBe(expected[i]);
|
|
9
|
-
sut.reset()
|
|
10
|
-
for (let i = 0; i < expected.length; i++)
|
|
11
|
-
expect(sut.next()).toBe(expected[i]);
|
|
12
|
-
});
|
|
13
|
-
});
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import {LinearBackoff} from "../../src";
|
|
2
|
-
|
|
3
|
-
describe("Testsuite for LinearBackoff", () => {
|
|
4
|
-
test("LinearBackoff should produce a linearly increasing series starting with 0", () => {
|
|
5
|
-
const sut = new LinearBackoff(0, 2000, 8000);
|
|
6
|
-
const expected = [0, 2000, 4000, 6000, 8000, 8000, 8000, 8000, 8000, 8000];
|
|
7
|
-
for (let i = 0; i < 10; i++)
|
|
8
|
-
expect(sut.next()).toBe(expected[i]);
|
|
9
|
-
sut.reset();
|
|
10
|
-
for (let i = 0; i < 10; i++)
|
|
11
|
-
expect(sut.next()).toBe(expected[i]);
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
test("LinearBackoff should produce a linearly increasing series starting with 1000", () => {
|
|
15
|
-
const sut = new LinearBackoff(1000, 3000, 10000);
|
|
16
|
-
const expected = [1000, 4000, 7000, 10000, 10000, 10000, 10000, 10000, 10000, 10000];
|
|
17
|
-
for (let i = 0; i < 10; i++)
|
|
18
|
-
expect(sut.next()).toBe(expected[i]);
|
|
19
|
-
sut.reset();
|
|
20
|
-
for (let i = 0; i < 10; i++)
|
|
21
|
-
expect(sut.next()).toBe(expected[i]);
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
test("LinearBackoff with undefined maximum should increase without bounds", () => {
|
|
25
|
-
const sut = new LinearBackoff(1000, 1000);
|
|
26
|
-
for (let i = 0; i < 100; i++)
|
|
27
|
-
expect(sut.next()).toBe(1000 + 1000 * i);
|
|
28
|
-
sut.reset();
|
|
29
|
-
for (let i = 0; i < 100; i++)
|
|
30
|
-
expect(sut.next()).toBe(1000 + 1000 * i);
|
|
31
|
-
})
|
|
32
|
-
})
|
package/test/buffer/common.ts
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
export const createEmptyArray = (len: number): Array<number> => {
|
|
2
|
-
return new Array<number>(len);
|
|
3
|
-
}
|
|
4
|
-
|
|
5
|
-
export const createSequentialArray = (len: number): Array<number> => {
|
|
6
|
-
const arr = new Array<number>(len);
|
|
7
|
-
for (let i = 0; i < arr.length; i++)
|
|
8
|
-
arr[i] = i;
|
|
9
|
-
return arr;
|
|
10
|
-
}
|
|
@@ -1,128 +0,0 @@
|
|
|
1
|
-
import {LRUBuffer} from "../../src";
|
|
2
|
-
|
|
3
|
-
describe("Testsuite for LRUBuffer", () => {
|
|
4
|
-
const capacity = 5;
|
|
5
|
-
|
|
6
|
-
test("LRUBuffer should return correct capacity", () => {
|
|
7
|
-
const sut = new LRUBuffer<number>(capacity);
|
|
8
|
-
expect(sut.cap()).toBe(capacity);
|
|
9
|
-
})
|
|
10
|
-
|
|
11
|
-
test("LRUBuffer should return correct length", () => {
|
|
12
|
-
const sut = new LRUBuffer<number>(capacity);
|
|
13
|
-
expect(sut.len()).toBe(0);
|
|
14
|
-
for (let i = 0; i <= 2 * capacity; i++) {
|
|
15
|
-
expect(sut.write([i])).toBe(1);
|
|
16
|
-
expect(sut.len()).toBe(i >= capacity ? capacity : i + 1);
|
|
17
|
-
}
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
test("LRUBuffer read/write zero elements", () => {
|
|
21
|
-
const sut1 = new LRUBuffer<number>(capacity);
|
|
22
|
-
const writeArr1 = createSequentialArray(0);
|
|
23
|
-
const readArr1 = createEmptyArray(0);
|
|
24
|
-
expect(sut1.write(writeArr1)).toBe(writeArr1.length);
|
|
25
|
-
expect(sut1.len()).toBe(writeArr1.length);
|
|
26
|
-
expect(sut1.read(readArr1)).toBe(writeArr1.length);
|
|
27
|
-
expect(readArr1).toEqual(writeArr1);
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
test("LRUBuffer read/write single elements", () => {
|
|
31
|
-
const sut = new LRUBuffer<number>(capacity)
|
|
32
|
-
const expected = [] as number[];
|
|
33
|
-
for (let i = 0; i < capacity * 3 + 2; i++) {
|
|
34
|
-
// write new element to buffer
|
|
35
|
-
expect(sut.write([i])).toBe(1);
|
|
36
|
-
expected.push(i);
|
|
37
|
-
|
|
38
|
-
// drop the last written element from expected if we exceed capacity
|
|
39
|
-
if (i > capacity - 1)
|
|
40
|
-
expected.shift();
|
|
41
|
-
|
|
42
|
-
// read actual elements
|
|
43
|
-
const r = createEmptyArray(i);
|
|
44
|
-
expect(sut.read(r)).toBe(i > capacity ? capacity : i);
|
|
45
|
-
for (let j = 0; j < i; j++) {
|
|
46
|
-
if (j > capacity - 1)
|
|
47
|
-
expect(r[j]).toBeUndefined();
|
|
48
|
-
else
|
|
49
|
-
expect(r[j]).toBe(expected[j]);
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
test("LRUBuffer read/write multiple elements", () => {
|
|
55
|
-
for (let i = 0; i < 2 * capacity; i++) {
|
|
56
|
-
const sut = new LRUBuffer<number>(capacity);
|
|
57
|
-
const writeArr = createSequentialArray(i);
|
|
58
|
-
const readArr = createEmptyArray(i);
|
|
59
|
-
expect(sut.write(writeArr)).toBe(i);
|
|
60
|
-
expect(sut.read(readArr)).toBe(i > capacity ? capacity : i);
|
|
61
|
-
for (let j = 0; j < i; j++) {
|
|
62
|
-
if (j > capacity - 1)
|
|
63
|
-
expect(readArr[j]).toBeUndefined();
|
|
64
|
-
else
|
|
65
|
-
expect(readArr[j]).toBe(writeArr[i > capacity ? j - (capacity - i) : j]);
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
test("LRUBuffer read/write on buffer with zero capacity should always return zero", () => {
|
|
71
|
-
const sut = new LRUBuffer<number>(0);
|
|
72
|
-
expect(sut.write([1])).toBe(0);
|
|
73
|
-
expect(sut.read([0])).toBe(0);
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
test("LRUBuffer read from empty buffer should return zero elements", () => {
|
|
77
|
-
const sut = new LRUBuffer<number>(capacity);
|
|
78
|
-
const readArr = new Array<number>(capacity);
|
|
79
|
-
expect(sut.read(readArr)).toBe(0);
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
test("LRUBuffer forEach should apply function to every element in the buffer", () => {
|
|
83
|
-
const sut = new LRUBuffer<number>(capacity);
|
|
84
|
-
const es = [] as number[];
|
|
85
|
-
sut.write([0]);
|
|
86
|
-
sut.forEach(e => es.push(e));
|
|
87
|
-
expect(es).toEqual([0]);
|
|
88
|
-
|
|
89
|
-
const es2 = [] as number[];
|
|
90
|
-
sut.write([1, 2, 3, 4]);
|
|
91
|
-
sut.forEach(e => es2.push(e));
|
|
92
|
-
expect(es2).toEqual([0, 1, 2, 3, 4]);
|
|
93
|
-
|
|
94
|
-
const es3 = [] as number[];
|
|
95
|
-
sut.write([5, 6]);
|
|
96
|
-
sut.forEach(e => es3.push(e));
|
|
97
|
-
expect(es3).toEqual([2, 3, 4, 5, 6]);
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
test("LRUBuffer forEach on empty buffer should do nothing", () => {
|
|
101
|
-
const sut = new LRUBuffer<number>(capacity);
|
|
102
|
-
const es = [] as number[];
|
|
103
|
-
sut.forEach(e => es.push(e));
|
|
104
|
-
expect(es.length).toBe(0);
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
test("LRUBuffer should contain zero items when cleared", () => {
|
|
108
|
-
const sut = new LRUBuffer<number>(capacity);
|
|
109
|
-
const writeArr = createSequentialArray(capacity);
|
|
110
|
-
const readArr = createEmptyArray(capacity);
|
|
111
|
-
sut.write(writeArr);
|
|
112
|
-
sut.clear();
|
|
113
|
-
expect(sut.len()).toBe(0);
|
|
114
|
-
expect(sut.read(readArr)).toBe(0);
|
|
115
|
-
expect(readArr).toEqual(createEmptyArray(capacity));
|
|
116
|
-
});
|
|
117
|
-
});
|
|
118
|
-
|
|
119
|
-
const createEmptyArray = (len: number): Array<number> => {
|
|
120
|
-
return new Array<number>(len);
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
const createSequentialArray = (len: number): Array<number> => {
|
|
124
|
-
const arr = new Array<number>(len);
|
|
125
|
-
for (let i = 0; i < arr.length; i++)
|
|
126
|
-
arr[i] = i;
|
|
127
|
-
return arr;
|
|
128
|
-
}
|