qws-browser 1.0.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/README.md +15 -0
- package/dist/browser/messageencode.d.ts +10 -0
- package/dist/browser/messageencode.js +113 -0
- package/dist/browser/messageencode.js.map +1 -0
- package/dist/browser/wrappedws.d.ts +42 -0
- package/dist/browser/wrappedws.js +95 -0
- package/dist/browser/wrappedws.js.map +1 -0
- package/dist/common/discriminator.d.ts +1 -0
- package/dist/common/discriminator.js +5 -0
- package/dist/common/discriminator.js.map +1 -0
- package/dist/common/logger.d.ts +31 -0
- package/dist/common/logger.js +44 -0
- package/dist/common/logger.js.map +1 -0
- package/dist/common/message.d.ts +124 -0
- package/dist/common/message.js +9 -0
- package/dist/common/message.js.map +1 -0
- package/dist/common/queryparser.d.ts +5 -0
- package/dist/common/queryparser.js +86 -0
- package/dist/common/queryparser.js.map +1 -0
- package/dist/common/queue.d.ts +35 -0
- package/dist/common/queue.js +70 -0
- package/dist/common/queue.js.map +1 -0
- package/dist/common/queuews.d.ts +70 -0
- package/dist/common/queuews.js +351 -0
- package/dist/common/queuews.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +22 -0
- package/dist/index.js.map +1 -0
- package/package.json +62 -0
package/README.md
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# WSQ (WebSocket Queue)
|
|
2
|
+
|
|
3
|
+
Safe queueing with auto-reconnect for WebSockets
|
|
4
|
+
|
|
5
|
+
- Wrapper for built-in `WebSocket`
|
|
6
|
+
- Works in browser and node (via [ws](https://github.com/websockets/ws))
|
|
7
|
+
- Automatic reconnect
|
|
8
|
+
- Message queueing with retainment
|
|
9
|
+
- Automatic two-way acknowledgment stream of messages - all messages are retained in-memory until acknowledgment is provided
|
|
10
|
+
- Configurable headers per message, even when body is binary
|
|
11
|
+
- Simple message routing (via [route-recognizer](https://github.com/tildeio/route-recognizer))
|
|
12
|
+
|
|
13
|
+
# Examples
|
|
14
|
+
|
|
15
|
+
TODO
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { QwsMessage } from '../common/message';
|
|
2
|
+
/**
|
|
3
|
+
* Convert binary data received through underlying WS into WSQ message
|
|
4
|
+
* Changes type based on type header
|
|
5
|
+
*/
|
|
6
|
+
export declare function deserializeMessage(blob: Blob): Promise<QwsMessage>;
|
|
7
|
+
/**
|
|
8
|
+
* Converts WSQ message into Blob to be sent through underlying WebSocket
|
|
9
|
+
*/
|
|
10
|
+
export declare function serializeMessage(message: QwsMessage): Blob;
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.serializeMessage = exports.deserializeMessage = void 0;
|
|
16
|
+
const logger_1 = __importDefault(require("../common/logger"));
|
|
17
|
+
/**
|
|
18
|
+
* Converts generic object into base64-encoded JSON.
|
|
19
|
+
* Used in headers and optionally JSON-style body.
|
|
20
|
+
*/
|
|
21
|
+
function objectToJsonBinary(object) {
|
|
22
|
+
const objectJson = JSON.stringify(object);
|
|
23
|
+
return btoa(unescape(encodeURIComponent(objectJson)));
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Deserializes base64-json buffers
|
|
27
|
+
* Used in headers and optionally JSON-style body.
|
|
28
|
+
*/
|
|
29
|
+
function jsonBinaryToObject(jsonBinary) {
|
|
30
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
31
|
+
const jsonBinaryText = yield jsonBinary.text();
|
|
32
|
+
const objectJson = decodeURIComponent(escape(atob(jsonBinaryText)));
|
|
33
|
+
return JSON.parse(objectJson);
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Convert binary data received through underlying WS into WSQ message
|
|
38
|
+
* Changes type based on type header
|
|
39
|
+
*/
|
|
40
|
+
function deserializeMessage(blob) {
|
|
41
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
42
|
+
if (blob.size < 4) {
|
|
43
|
+
logger_1.default.error('Invalid blob size');
|
|
44
|
+
return {
|
|
45
|
+
headers: { type: 'bin' },
|
|
46
|
+
body: blob,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
// take first 4 bytes from header, check if not a too large size
|
|
50
|
+
const headersSizeBlob = yield blob.slice(0, 4).arrayBuffer();
|
|
51
|
+
const headersSizeArray = new Uint32Array(headersSizeBlob);
|
|
52
|
+
const headersSize = headersSizeArray[0];
|
|
53
|
+
if (headersSize > blob.size - 4) {
|
|
54
|
+
logger_1.default.error(`Invalid header size ${headersSize} > ${blob.size - 4}`);
|
|
55
|
+
return {
|
|
56
|
+
headers: { type: 'bin' },
|
|
57
|
+
body: blob,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
try {
|
|
61
|
+
// decode base64-JSON header
|
|
62
|
+
const headers = yield jsonBinaryToObject(blob.slice(4, headersSize + 4));
|
|
63
|
+
const bodyBlob = blob.slice(headersSize + 4);
|
|
64
|
+
const type = headers.type || 'bin';
|
|
65
|
+
// body is either JSON Blob, original binary data or nothing
|
|
66
|
+
let body;
|
|
67
|
+
switch (type) {
|
|
68
|
+
case 'bin':
|
|
69
|
+
body = bodyBlob;
|
|
70
|
+
break;
|
|
71
|
+
case 'json':
|
|
72
|
+
body = yield jsonBinaryToObject(bodyBlob);
|
|
73
|
+
break;
|
|
74
|
+
default:
|
|
75
|
+
}
|
|
76
|
+
return { headers, body };
|
|
77
|
+
}
|
|
78
|
+
catch (ex) {
|
|
79
|
+
logger_1.default.error('Could not decode message', ex);
|
|
80
|
+
return {
|
|
81
|
+
headers: { type: 'bin' },
|
|
82
|
+
body: blob,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
exports.deserializeMessage = deserializeMessage;
|
|
88
|
+
/**
|
|
89
|
+
* Converts WSQ message into Blob to be sent through underlying WebSocket
|
|
90
|
+
*/
|
|
91
|
+
function serializeMessage(message) {
|
|
92
|
+
// headers encoded into base64(json)
|
|
93
|
+
const headersEncoded = objectToJsonBinary(message.headers);
|
|
94
|
+
const headersSize = Uint32Array.from([headersEncoded.length]);
|
|
95
|
+
// body is either JSON Blob, original binary data or nothing
|
|
96
|
+
let bodyEncoded;
|
|
97
|
+
switch (message.headers.type) {
|
|
98
|
+
case 'bin':
|
|
99
|
+
bodyEncoded = message.body;
|
|
100
|
+
break;
|
|
101
|
+
case 'json':
|
|
102
|
+
bodyEncoded = objectToJsonBinary(message.body);
|
|
103
|
+
break;
|
|
104
|
+
default:
|
|
105
|
+
}
|
|
106
|
+
return new Blob([
|
|
107
|
+
headersSize,
|
|
108
|
+
headersEncoded,
|
|
109
|
+
bodyEncoded, // binary, json or null body
|
|
110
|
+
], { type: 'application/octet-stream' });
|
|
111
|
+
}
|
|
112
|
+
exports.serializeMessage = serializeMessage;
|
|
113
|
+
//# sourceMappingURL=messageencode.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"messageencode.js","sourceRoot":"","sources":["../../src/browser/messageencode.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { QwsMessage, AckQwsMessage, BinaryQwsMessage, ErrorQwsMessage, JsonQwsMessage, ReadyQwsMessage } from '../common/message';
|
|
2
|
+
import { Binary } from '../common/discriminator';
|
|
3
|
+
/**
|
|
4
|
+
* Wrapper around WebSocket, built to serialize/deserialize
|
|
5
|
+
* WSQ formatted messages.
|
|
6
|
+
*/
|
|
7
|
+
export default class WrappedWebSocket {
|
|
8
|
+
ws: WebSocket;
|
|
9
|
+
callbacks: {
|
|
10
|
+
bin?: (message: BinaryQwsMessage) => void;
|
|
11
|
+
json?: (message: JsonQwsMessage) => void;
|
|
12
|
+
ready?: (message: ReadyQwsMessage) => void;
|
|
13
|
+
ack?: (message: AckQwsMessage) => void;
|
|
14
|
+
err?: (message: ErrorQwsMessage) => void;
|
|
15
|
+
};
|
|
16
|
+
constructor(wsOrUrl: WebSocket | string);
|
|
17
|
+
/**
|
|
18
|
+
* Proxy callbacks
|
|
19
|
+
*/
|
|
20
|
+
onWsOpen(callback: () => void): void;
|
|
21
|
+
onWsClose(callback: () => void): void;
|
|
22
|
+
onWsError(callback: (event: Event) => void): void;
|
|
23
|
+
/**
|
|
24
|
+
* Proxy others
|
|
25
|
+
*/
|
|
26
|
+
get readyState(): number;
|
|
27
|
+
get bufferedAmount(): number;
|
|
28
|
+
/**
|
|
29
|
+
* Concrete message type callbacks
|
|
30
|
+
*/
|
|
31
|
+
onBin(callback: (message: BinaryQwsMessage) => void): void;
|
|
32
|
+
onJson(callback: (message: JsonQwsMessage) => void): void;
|
|
33
|
+
onReady(callback: (message: ReadyQwsMessage) => void): void;
|
|
34
|
+
onAck(callback: (message: AckQwsMessage) => void): void;
|
|
35
|
+
onErr(callback: (message: ErrorQwsMessage) => void): void;
|
|
36
|
+
/**
|
|
37
|
+
* Proxy methods
|
|
38
|
+
*/
|
|
39
|
+
send(message: QwsMessage): void;
|
|
40
|
+
sendRaw(data: Binary): void;
|
|
41
|
+
close(): void;
|
|
42
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
const auto_bind_1 = __importDefault(require("auto-bind"));
|
|
16
|
+
const messageencode_1 = require("./messageencode");
|
|
17
|
+
/**
|
|
18
|
+
* Wrapper around WebSocket, built to serialize/deserialize
|
|
19
|
+
* WSQ formatted messages.
|
|
20
|
+
*/
|
|
21
|
+
class WrappedWebSocket {
|
|
22
|
+
constructor(wsOrUrl) {
|
|
23
|
+
var _a;
|
|
24
|
+
this.callbacks = {};
|
|
25
|
+
if (wsOrUrl instanceof WebSocket || ((_a = wsOrUrl === null || wsOrUrl === void 0 ? void 0 : wsOrUrl.constructor) === null || _a === void 0 ? void 0 : _a.name) === 'WebSocket') {
|
|
26
|
+
this.ws = wsOrUrl;
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
this.ws = new WebSocket(wsOrUrl);
|
|
30
|
+
}
|
|
31
|
+
this.ws.onmessage = (event) => __awaiter(this, void 0, void 0, function* () {
|
|
32
|
+
const message = yield (0, messageencode_1.deserializeMessage)(event.data);
|
|
33
|
+
// logger.info('WRAPPER received', message);
|
|
34
|
+
const callback = this.callbacks[message.headers.type];
|
|
35
|
+
callback === null || callback === void 0 ? void 0 : callback(message);
|
|
36
|
+
});
|
|
37
|
+
(0, auto_bind_1.default)(this);
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Proxy callbacks
|
|
41
|
+
*/
|
|
42
|
+
onWsOpen(callback) {
|
|
43
|
+
this.ws.onopen = callback;
|
|
44
|
+
}
|
|
45
|
+
onWsClose(callback) {
|
|
46
|
+
this.ws.onclose = callback;
|
|
47
|
+
}
|
|
48
|
+
onWsError(callback) {
|
|
49
|
+
this.ws.onerror = callback;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Proxy others
|
|
53
|
+
*/
|
|
54
|
+
get readyState() {
|
|
55
|
+
return this.ws.readyState;
|
|
56
|
+
}
|
|
57
|
+
get bufferedAmount() {
|
|
58
|
+
return this.ws.bufferedAmount;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Concrete message type callbacks
|
|
62
|
+
*/
|
|
63
|
+
onBin(callback) {
|
|
64
|
+
this.callbacks.bin = callback;
|
|
65
|
+
}
|
|
66
|
+
onJson(callback) {
|
|
67
|
+
this.callbacks.json = callback;
|
|
68
|
+
}
|
|
69
|
+
onReady(callback) {
|
|
70
|
+
this.callbacks.ready = callback;
|
|
71
|
+
}
|
|
72
|
+
onAck(callback) {
|
|
73
|
+
this.callbacks.ack = callback;
|
|
74
|
+
}
|
|
75
|
+
onErr(callback) {
|
|
76
|
+
this.callbacks.err = callback;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Proxy methods
|
|
80
|
+
*/
|
|
81
|
+
send(message) {
|
|
82
|
+
// logger.info('WRAPPER sending', message);
|
|
83
|
+
const data = (0, messageencode_1.serializeMessage)(message);
|
|
84
|
+
this.ws.send(data);
|
|
85
|
+
}
|
|
86
|
+
sendRaw(data) {
|
|
87
|
+
// logger.info('WRAPPER send raw', data.toString());
|
|
88
|
+
this.ws.send(data);
|
|
89
|
+
}
|
|
90
|
+
close() {
|
|
91
|
+
this.ws.close();
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
exports.default = WrappedWebSocket;
|
|
95
|
+
//# sourceMappingURL=wrappedws.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wrappedws.js","sourceRoot":"","sources":["../../src/browser/wrappedws.ts"],"names":[],"mappings":";;;;;;;;;;;;;;AAAA,0DAAiC;AAGjC,mDAAuE;AAGvE;;;GAGG;AACH,MAAqB,gBAAgB;IAWnC,YAAY,OAA2B;;QACrC,IAAI,CAAC,SAAS,GAAG,EAAE,CAAC;QAEpB,IAAI,OAAO,YAAY,SAAS,IAAI,CAAA,MAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,WAAW,0CAAE,IAAI,MAAK,WAAW,EAAE;YAC9E,IAAI,CAAC,EAAE,GAAG,OAAoB,CAAC;SAChC;aAAM;YACL,IAAI,CAAC,EAAE,GAAG,IAAI,SAAS,CAAC,OAAO,CAAC,CAAC;SAClC;QAED,IAAI,CAAC,EAAE,CAAC,SAAS,GAAG,CAAO,KAA2B,EAAE,EAAE;YACxD,MAAM,OAAO,GAAG,MAAM,IAAA,kCAAkB,EAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YACrD,4CAA4C;YAC5C,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAA8B,CAAC;YACnF,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAG,OAAO,CAAC,CAAC;QACtB,CAAC,CAAA,CAAC;QAEF,IAAA,mBAAQ,EAAC,IAAI,CAAC,CAAC;IACjB,CAAC;IAED;;OAEG;IAEH,QAAQ,CAAC,QAAoB;QAC3B,IAAI,CAAC,EAAE,CAAC,MAAM,GAAG,QAAQ,CAAC;IAC5B,CAAC;IAED,SAAS,CAAC,QAAoB;QAC5B,IAAI,CAAC,EAAE,CAAC,OAAO,GAAG,QAAQ,CAAC;IAC7B,CAAC;IAED,SAAS,CAAC,QAAgC;QACxC,IAAI,CAAC,EAAE,CAAC,OAAO,GAAG,QAAQ,CAAC;IAC7B,CAAC;IAED;;OAEG;IACH,IAAI,UAAU;QACZ,OAAO,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC;IAC5B,CAAC;IAED,IAAI,cAAc;QAChB,OAAO,IAAI,CAAC,EAAE,CAAC,cAAc,CAAC;IAChC,CAAC;IAED;;OAEG;IAEH,KAAK,CAAC,QAA6C;QACjD,IAAI,CAAC,SAAS,CAAC,GAAG,GAAG,QAAQ,CAAC;IAChC,CAAC;IAED,MAAM,CAAC,QAA2C;QAChD,IAAI,CAAC,SAAS,CAAC,IAAI,GAAG,QAAQ,CAAC;IACjC,CAAC;IAED,OAAO,CAAC,QAA4C;QAClD,IAAI,CAAC,SAAS,CAAC,KAAK,GAAG,QAAQ,CAAC;IAClC,CAAC;IAED,KAAK,CAAC,QAA0C;QAC9C,IAAI,CAAC,SAAS,CAAC,GAAG,GAAG,QAAQ,CAAC;IAChC,CAAC;IAED,KAAK,CAAC,QAA4C;QAChD,IAAI,CAAC,SAAS,CAAC,GAAG,GAAG,QAAQ,CAAC;IAChC,CAAC;IAED;;OAEG;IACH,IAAI,CAAC,OAAmB;QACtB,2CAA2C;QAC3C,MAAM,IAAI,GAAG,IAAA,gCAAgB,EAAC,OAAO,CAAC,CAAC;QACvC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACrB,CAAC;IAED,OAAO,CAAC,IAAY;QAClB,oDAAoD;QACpD,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACrB,CAAC;IAED,KAAK;QACH,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC;IAClB,CAAC;CACF;AAlGD,mCAkGC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare type Binary = Blob;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discriminator.js","sourceRoot":"","sources":["../../src/common/discriminator.ts"],"names":[],"mappings":";AAAA,OAAO;AACP,+BAA+B"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pluggable logger interface
|
|
3
|
+
*/
|
|
4
|
+
export interface QwsLogger {
|
|
5
|
+
debug(...data: any[]): void;
|
|
6
|
+
info(...data: any[]): void;
|
|
7
|
+
warn(...data: any[]): void;
|
|
8
|
+
error(...data: any[]): void;
|
|
9
|
+
}
|
|
10
|
+
export declare class QwsLoggerWrapper implements QwsLogger {
|
|
11
|
+
backend: QwsLogger;
|
|
12
|
+
constructor(logger?: QwsLogger);
|
|
13
|
+
debug(...data: any[]): void;
|
|
14
|
+
info(...data: any[]): void;
|
|
15
|
+
warn(...data: any[]): void;
|
|
16
|
+
error(...data: any[]): void;
|
|
17
|
+
/**
|
|
18
|
+
* Overwrite default logger used by qws, which is the console.
|
|
19
|
+
* Allows plugging of external tools, such as yall2
|
|
20
|
+
*/
|
|
21
|
+
setBackend(newBackend: QwsLogger): void;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Export default instance
|
|
25
|
+
*/
|
|
26
|
+
declare const logger: QwsLoggerWrapper;
|
|
27
|
+
export default logger;
|
|
28
|
+
/**
|
|
29
|
+
* Export setBackend method for easy external setup
|
|
30
|
+
*/
|
|
31
|
+
export declare const setQwsLoggingBackend: (newBackend: QwsLogger) => void;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.setQwsLoggingBackend = exports.QwsLoggerWrapper = void 0;
|
|
7
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
8
|
+
const auto_bind_1 = __importDefault(require("auto-bind"));
|
|
9
|
+
class QwsLoggerWrapper {
|
|
10
|
+
constructor(logger = console) {
|
|
11
|
+
this.backend = logger;
|
|
12
|
+
(0, auto_bind_1.default)(this);
|
|
13
|
+
}
|
|
14
|
+
debug(...data) {
|
|
15
|
+
this.backend.debug(...data);
|
|
16
|
+
}
|
|
17
|
+
info(...data) {
|
|
18
|
+
this.backend.info(...data);
|
|
19
|
+
}
|
|
20
|
+
warn(...data) {
|
|
21
|
+
this.backend.warn(...data);
|
|
22
|
+
}
|
|
23
|
+
error(...data) {
|
|
24
|
+
this.backend.error(...data);
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Overwrite default logger used by qws, which is the console.
|
|
28
|
+
* Allows plugging of external tools, such as yall2
|
|
29
|
+
*/
|
|
30
|
+
setBackend(newBackend) {
|
|
31
|
+
this.backend = newBackend;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
exports.QwsLoggerWrapper = QwsLoggerWrapper;
|
|
35
|
+
/**
|
|
36
|
+
* Export default instance
|
|
37
|
+
*/
|
|
38
|
+
const logger = new QwsLoggerWrapper();
|
|
39
|
+
exports.default = logger;
|
|
40
|
+
/**
|
|
41
|
+
* Export setBackend method for easy external setup
|
|
42
|
+
*/
|
|
43
|
+
exports.setQwsLoggingBackend = logger.setBackend;
|
|
44
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/common/logger.ts"],"names":[],"mappings":";;;;;;AAAA,uDAAuD;AACvD,0DAAiC;AAYjC,MAAa,gBAAgB;IAG3B,YAAY,SAAoB,OAAO;QACrC,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;QACtB,IAAA,mBAAQ,EAAC,IAAI,CAAC,CAAC;IACjB,CAAC;IAED,KAAK,CAAC,GAAG,IAAW;QAClB,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,CAAC;IAC9B,CAAC;IAED,IAAI,CAAC,GAAG,IAAW;QACjB,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;IAC7B,CAAC;IAED,IAAI,CAAC,GAAG,IAAW;QACjB,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;IAC7B,CAAC;IAED,KAAK,CAAC,GAAG,IAAW;QAClB,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,CAAC;IAC9B,CAAC;IAED;;;OAGG;IACH,UAAU,CAAC,UAAqB;QAC9B,IAAI,CAAC,OAAO,GAAG,UAAU,CAAC;IAC5B,CAAC;CACF;AA/BD,4CA+BC;AAED;;GAEG;AACH,MAAM,MAAM,GAAG,IAAI,gBAAgB,EAAE,CAAC;AACtC,kBAAe,MAAM,CAAC;AAEtB;;GAEG;AACU,QAAA,oBAAoB,GAAG,MAAM,CAAC,UAAU,CAAC"}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Custom message format for WSQ messages:
|
|
3
|
+
* - first 4 bytes: uint32 saying how long the header information is
|
|
4
|
+
* - next n bytes: base64(json)-encoded headers
|
|
5
|
+
* - remaining bytes: actual body - could be binary or base64(json), denoted in headers
|
|
6
|
+
*/
|
|
7
|
+
import { Binary } from './discriminator';
|
|
8
|
+
/**
|
|
9
|
+
* Denotes message type, must be included in header.
|
|
10
|
+
* 'bin' - payload message with binary body
|
|
11
|
+
* 'json' - payload message with JSON body
|
|
12
|
+
* 'ready' - ready message sent after connection and setup
|
|
13
|
+
* 'ack' - acknowledgment message for a payload message received from other side
|
|
14
|
+
* 'err' - error
|
|
15
|
+
*/
|
|
16
|
+
export declare type QwsMessageType = 'bin' | 'json' | 'ready' | 'ack' | 'err';
|
|
17
|
+
/**
|
|
18
|
+
* Headers are sent in base64(json) format.
|
|
19
|
+
*/
|
|
20
|
+
export declare type QwsMessageExtraHeaders = {
|
|
21
|
+
/**
|
|
22
|
+
* Other X-headers
|
|
23
|
+
*/
|
|
24
|
+
[key: string]: unknown;
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Path parameters decodable with route-recognizer when using routed messages.
|
|
28
|
+
*/
|
|
29
|
+
export declare type QwsParams = {
|
|
30
|
+
/**
|
|
31
|
+
* Other X-headers
|
|
32
|
+
*/
|
|
33
|
+
[key: string]: string;
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Message types
|
|
37
|
+
*/
|
|
38
|
+
/**
|
|
39
|
+
* Binary payload messages
|
|
40
|
+
* Contain binary body (like video data)
|
|
41
|
+
*/
|
|
42
|
+
export declare type BinaryQwsMessageHeaders = QwsMessageExtraHeaders & {
|
|
43
|
+
type: 'bin';
|
|
44
|
+
/**
|
|
45
|
+
* Message index in order. Helps in acknowledgments
|
|
46
|
+
*/
|
|
47
|
+
idx?: number;
|
|
48
|
+
/**
|
|
49
|
+
* Routing key for message
|
|
50
|
+
*/
|
|
51
|
+
route?: string;
|
|
52
|
+
};
|
|
53
|
+
export declare type BinaryQwsMessage = {
|
|
54
|
+
headers: BinaryQwsMessageHeaders;
|
|
55
|
+
body: Binary;
|
|
56
|
+
};
|
|
57
|
+
/**
|
|
58
|
+
* JSON payload message
|
|
59
|
+
* Contain base64-JSON encoded data
|
|
60
|
+
*/
|
|
61
|
+
export declare type JsonQwsMessageHeaders = QwsMessageExtraHeaders & {
|
|
62
|
+
type: 'json';
|
|
63
|
+
/**
|
|
64
|
+
* Message index in order. Helps in acknowledgments
|
|
65
|
+
*/
|
|
66
|
+
idx: number;
|
|
67
|
+
/**
|
|
68
|
+
* Routing key for message
|
|
69
|
+
*/
|
|
70
|
+
route?: string;
|
|
71
|
+
};
|
|
72
|
+
export declare type JsonQwsMessage = {
|
|
73
|
+
headers: JsonQwsMessageHeaders;
|
|
74
|
+
body: Record<string, unknown>;
|
|
75
|
+
};
|
|
76
|
+
/**
|
|
77
|
+
* Ready message
|
|
78
|
+
* Sent back after successful connect, signalling we are ready to receive events
|
|
79
|
+
* Optionally contains a message index denoting how many messages we already have received previously
|
|
80
|
+
*/
|
|
81
|
+
export declare type ReadyQwsMessageHeaders = QwsMessageExtraHeaders & {
|
|
82
|
+
type: 'ready';
|
|
83
|
+
/**
|
|
84
|
+
* Message index we have already received previously that may be omitted.
|
|
85
|
+
*/
|
|
86
|
+
readyIdx: number;
|
|
87
|
+
};
|
|
88
|
+
export declare type ReadyQwsMessage = {
|
|
89
|
+
headers: ReadyQwsMessageHeaders;
|
|
90
|
+
};
|
|
91
|
+
/**
|
|
92
|
+
* Acknowledgment message
|
|
93
|
+
* Sent back for every payload message
|
|
94
|
+
*/
|
|
95
|
+
export declare type AckQwsMessageHeaders = {
|
|
96
|
+
type: 'ack';
|
|
97
|
+
/**
|
|
98
|
+
* Message index from other side we are acknowledging
|
|
99
|
+
*/
|
|
100
|
+
ackIdx: number;
|
|
101
|
+
};
|
|
102
|
+
export declare type AckQwsMessage = {
|
|
103
|
+
headers: AckQwsMessageHeaders;
|
|
104
|
+
};
|
|
105
|
+
/**
|
|
106
|
+
* Error message
|
|
107
|
+
* Sent back if processing a message is unsuccessful
|
|
108
|
+
*/
|
|
109
|
+
export declare type ErrorQwsMessageHeaders = {
|
|
110
|
+
type: 'err';
|
|
111
|
+
/**
|
|
112
|
+
* Message of error
|
|
113
|
+
*/
|
|
114
|
+
error: string;
|
|
115
|
+
};
|
|
116
|
+
export declare type ErrorQwsMessage = {
|
|
117
|
+
headers: ErrorQwsMessageHeaders;
|
|
118
|
+
};
|
|
119
|
+
/**
|
|
120
|
+
* Common names for WSQ message
|
|
121
|
+
*/
|
|
122
|
+
export declare type PayloadQwsMessage = BinaryQwsMessage | JsonQwsMessage;
|
|
123
|
+
export declare type QwsMessage = BinaryQwsMessage | JsonQwsMessage | ReadyQwsMessage | AckQwsMessage | ErrorQwsMessage;
|
|
124
|
+
export declare type QwsMessageHeader = BinaryQwsMessageHeaders | JsonQwsMessageHeaders | ReadyQwsMessageHeaders | AckQwsMessageHeaders | ErrorQwsMessageHeaders;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Custom message format for WSQ messages:
|
|
4
|
+
* - first 4 bytes: uint32 saying how long the header information is
|
|
5
|
+
* - next n bytes: base64(json)-encoded headers
|
|
6
|
+
* - remaining bytes: actual body - could be binary or base64(json), denoted in headers
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
//# sourceMappingURL=message.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message.js","sourceRoot":"","sources":["../../src/common/message.ts"],"names":[],"mappings":";AAAA;;;;;GAKG"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare const parseUrl: (urlString: string) => Record<string, string>;
|
|
2
|
+
export declare const parseQuery: (search: string) => Record<string, string>;
|
|
3
|
+
export declare const addQueryParamsToUrl: (urlString: string, params: Record<string, unknown>) => string;
|
|
4
|
+
export declare const addQueryParameters: (search: string, params?: {}, defaultParams?: {}) => string;
|
|
5
|
+
export declare const toUrlParams: (query?: {}, defaultParams?: {}) => string;
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.toUrlParams = exports.addQueryParameters = exports.addQueryParamsToUrl = exports.parseQuery = exports.parseUrl = void 0;
|
|
4
|
+
// parse query parameters from URL
|
|
5
|
+
const parseUrl = (urlString) => {
|
|
6
|
+
const url = new URL(urlString);
|
|
7
|
+
const query = {};
|
|
8
|
+
url.searchParams.forEach((val, key) => {
|
|
9
|
+
query[key] = val;
|
|
10
|
+
});
|
|
11
|
+
return query;
|
|
12
|
+
};
|
|
13
|
+
exports.parseUrl = parseUrl;
|
|
14
|
+
// parse query parameters from location
|
|
15
|
+
const parseQuery = (search) => {
|
|
16
|
+
const params = new URLSearchParams(search);
|
|
17
|
+
const query = {};
|
|
18
|
+
params.forEach((val, key) => {
|
|
19
|
+
query[key] = val;
|
|
20
|
+
});
|
|
21
|
+
return query;
|
|
22
|
+
};
|
|
23
|
+
exports.parseQuery = parseQuery;
|
|
24
|
+
// parse query parameters from URL
|
|
25
|
+
const addQueryParamsToUrl = (urlString, params) => {
|
|
26
|
+
const url = new URL(urlString);
|
|
27
|
+
Object.entries(params).forEach(([key, val]) => {
|
|
28
|
+
url.searchParams.set(key, `${val}`);
|
|
29
|
+
});
|
|
30
|
+
return url.toString();
|
|
31
|
+
};
|
|
32
|
+
exports.addQueryParamsToUrl = addQueryParamsToUrl;
|
|
33
|
+
// add extra query parameters to location
|
|
34
|
+
const addQueryParameters = (search, params = {}, defaultParams = {}) => {
|
|
35
|
+
const query = (0, exports.parseQuery)(search);
|
|
36
|
+
let changed = false;
|
|
37
|
+
Object.entries(params).forEach(([key, val]) => {
|
|
38
|
+
if (key in defaultParams) {
|
|
39
|
+
// has default
|
|
40
|
+
if (val !== defaultParams[key]) {
|
|
41
|
+
query[key] = `${val}`;
|
|
42
|
+
changed = true;
|
|
43
|
+
}
|
|
44
|
+
else if (key in query) {
|
|
45
|
+
delete query[key];
|
|
46
|
+
changed = true;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
// no default
|
|
51
|
+
// eslint-disable-next-line no-lonely-if
|
|
52
|
+
if (val !== undefined && val !== null && val !== '') {
|
|
53
|
+
query[key] = `${val}`;
|
|
54
|
+
changed = true;
|
|
55
|
+
}
|
|
56
|
+
else if (key in query) {
|
|
57
|
+
delete query[key];
|
|
58
|
+
changed = true;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
if (!changed) {
|
|
63
|
+
return search;
|
|
64
|
+
}
|
|
65
|
+
return `?${new URLSearchParams(query).toString()}`;
|
|
66
|
+
};
|
|
67
|
+
exports.addQueryParameters = addQueryParameters;
|
|
68
|
+
// parse into URLParams
|
|
69
|
+
const toUrlParams = (query = {}, defaultParams = {}) => {
|
|
70
|
+
const params = {};
|
|
71
|
+
Object.entries(query).forEach(([key, val]) => {
|
|
72
|
+
// omit default values
|
|
73
|
+
if (key in defaultParams && defaultParams[key] === val) {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
if (Array.isArray(val)) {
|
|
77
|
+
params[key] = val.join(',');
|
|
78
|
+
}
|
|
79
|
+
else if (val !== undefined && val !== null && val !== '' && !Number.isNaN(val)) {
|
|
80
|
+
params[key] = `${val}`;
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
return new URLSearchParams(params).toString();
|
|
84
|
+
};
|
|
85
|
+
exports.toUrlParams = toUrlParams;
|
|
86
|
+
//# sourceMappingURL=queryparser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queryparser.js","sourceRoot":"","sources":["../../src/common/queryparser.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { PayloadQwsMessage } from './message';
|
|
2
|
+
import { Binary } from './discriminator';
|
|
3
|
+
/**
|
|
4
|
+
* FIFO data structure implementation for outgoing qws messages
|
|
5
|
+
* Implements acknowledgment system, so no messages are deleted until acknowledged,
|
|
6
|
+
* but new messages may be added while waiting for ack.
|
|
7
|
+
*/
|
|
8
|
+
export default class QwsMessageQueue {
|
|
9
|
+
messages: Record<number, Binary>;
|
|
10
|
+
readIdx: number;
|
|
11
|
+
ackIdx: number;
|
|
12
|
+
writeIdx: number;
|
|
13
|
+
numUnsentMessages: number;
|
|
14
|
+
numUnsentBytes: number;
|
|
15
|
+
numUnackMessages: number;
|
|
16
|
+
numUnackBytes: number;
|
|
17
|
+
constructor();
|
|
18
|
+
/**
|
|
19
|
+
* Push message to write end of queue
|
|
20
|
+
*/
|
|
21
|
+
produce(message: PayloadQwsMessage): number;
|
|
22
|
+
/**
|
|
23
|
+
* Pop message from read end of queue.
|
|
24
|
+
* Returns idx of message, along with its content.
|
|
25
|
+
*/
|
|
26
|
+
consume(): [number, Binary];
|
|
27
|
+
/**
|
|
28
|
+
* When ack is received, we can forget messages up to that point
|
|
29
|
+
*/
|
|
30
|
+
acknowledge(idx: number): void;
|
|
31
|
+
/**
|
|
32
|
+
* When ack fails, we must revert to a previous point
|
|
33
|
+
*/
|
|
34
|
+
revert(idx: number): void;
|
|
35
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const messageencode_1 = require("../browser/messageencode");
|
|
4
|
+
/**
|
|
5
|
+
* FIFO data structure implementation for outgoing qws messages
|
|
6
|
+
* Implements acknowledgment system, so no messages are deleted until acknowledged,
|
|
7
|
+
* but new messages may be added while waiting for ack.
|
|
8
|
+
*/
|
|
9
|
+
class QwsMessageQueue {
|
|
10
|
+
constructor() {
|
|
11
|
+
this.messages = {};
|
|
12
|
+
this.readIdx = 0;
|
|
13
|
+
this.ackIdx = 0;
|
|
14
|
+
this.writeIdx = 0;
|
|
15
|
+
this.numUnsentMessages = 0;
|
|
16
|
+
this.numUnsentBytes = 0;
|
|
17
|
+
this.numUnackMessages = 0;
|
|
18
|
+
this.numUnackBytes = 0;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Push message to write end of queue
|
|
22
|
+
*/
|
|
23
|
+
produce(message) {
|
|
24
|
+
const idx = this.writeIdx;
|
|
25
|
+
message.headers.idx = idx;
|
|
26
|
+
const data = (0, messageencode_1.serializeMessage)(message);
|
|
27
|
+
this.messages[idx] = data;
|
|
28
|
+
this.numUnsentMessages += 1;
|
|
29
|
+
this.numUnsentBytes += data.size;
|
|
30
|
+
this.numUnackMessages += 1;
|
|
31
|
+
this.numUnackBytes += data.size;
|
|
32
|
+
this.writeIdx += 1;
|
|
33
|
+
return idx;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Pop message from read end of queue.
|
|
37
|
+
* Returns idx of message, along with its content.
|
|
38
|
+
*/
|
|
39
|
+
consume() {
|
|
40
|
+
const idx = this.readIdx;
|
|
41
|
+
const ret = this.messages[idx];
|
|
42
|
+
this.numUnsentMessages -= 1;
|
|
43
|
+
this.numUnsentBytes -= ret.size;
|
|
44
|
+
this.readIdx += 1;
|
|
45
|
+
return [idx, ret];
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* When ack is received, we can forget messages up to that point
|
|
49
|
+
*/
|
|
50
|
+
acknowledge(idx) {
|
|
51
|
+
while (this.ackIdx <= idx) {
|
|
52
|
+
this.numUnackMessages -= 1;
|
|
53
|
+
this.numUnackBytes -= this.messages[this.ackIdx].size;
|
|
54
|
+
delete this.messages[this.ackIdx];
|
|
55
|
+
this.ackIdx += 1;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* When ack fails, we must revert to a previous point
|
|
60
|
+
*/
|
|
61
|
+
revert(idx) {
|
|
62
|
+
while (this.readIdx > idx) {
|
|
63
|
+
this.readIdx -= 1;
|
|
64
|
+
this.numUnsentMessages += 1;
|
|
65
|
+
this.numUnsentBytes += this.messages[this.readIdx].size;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
exports.default = QwsMessageQueue;
|
|
70
|
+
//# sourceMappingURL=queue.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queue.js","sourceRoot":"","sources":["../../src/common/queue.ts"],"names":[],"mappings":";;AACA,4DAA4D;AAG5D;;;;GAIG;AACH,MAAqB,eAAe;IAWlC;QACE,IAAI,CAAC,QAAQ,GAAG,EAAE,CAAC;QACnB,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC;QACjB,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;QAChB,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC;QAElB,IAAI,CAAC,iBAAiB,GAAG,CAAC,CAAC;QAC3B,IAAI,CAAC,cAAc,GAAG,CAAC,CAAC;QACxB,IAAI,CAAC,gBAAgB,GAAG,CAAC,CAAC;QAC1B,IAAI,CAAC,aAAa,GAAG,CAAC,CAAC;IACzB,CAAC;IAED;;OAEG;IACH,OAAO,CAAC,OAA0B;QAChC,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC1B,OAAO,CAAC,OAAO,CAAC,GAAG,GAAG,GAAG,CAAC;QAC1B,MAAM,IAAI,GAAG,IAAA,gCAAgB,EAAC,OAAO,CAAC,CAAC;QACvC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;QAE1B,IAAI,CAAC,iBAAiB,IAAI,CAAC,CAAC;QAC5B,IAAI,CAAC,cAAc,IAAI,IAAI,CAAC,IAAI,CAAC;QACjC,IAAI,CAAC,gBAAgB,IAAI,CAAC,CAAC;QAC3B,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,IAAI,CAAC;QAEhC,IAAI,CAAC,QAAQ,IAAI,CAAC,CAAC;QACnB,OAAO,GAAG,CAAC;IACb,CAAC;IAED;;;OAGG;IACH,OAAO;QACL,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC;QACzB,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;QAE/B,IAAI,CAAC,iBAAiB,IAAI,CAAC,CAAC;QAC5B,IAAI,CAAC,cAAc,IAAI,GAAG,CAAC,IAAI,CAAC;QAChC,IAAI,CAAC,OAAO,IAAI,CAAC,CAAC;QAClB,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IACpB,CAAC;IAED;;OAEG;IACH,WAAW,CAAC,GAAW;QACrB,OAAO,IAAI,CAAC,MAAM,IAAI,GAAG,EAAE;YACzB,IAAI,CAAC,gBAAgB,IAAI,CAAC,CAAC;YAC3B,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC;YACtD,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAClC,IAAI,CAAC,MAAM,IAAI,CAAC,CAAC;SAClB;IACH,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,GAAW;QAChB,OAAO,IAAI,CAAC,OAAO,GAAG,GAAG,EAAE;YACzB,IAAI,CAAC,OAAO,IAAI,CAAC,CAAC;YAClB,IAAI,CAAC,iBAAiB,IAAI,CAAC,CAAC;YAC5B,IAAI,CAAC,cAAc,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC;SACzD;IACH,CAAC;CACF;AA7ED,kCA6EC"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import RouteRecognizer from 'route-recognizer';
|
|
2
|
+
import { Binary } from './discriminator';
|
|
3
|
+
import { QwsMessageExtraHeaders, BinaryQwsMessageHeaders, JsonQwsMessageHeaders, ReadyQwsMessageHeaders, QwsParams } from './message';
|
|
4
|
+
import WebSocketMessageQueue from './queue';
|
|
5
|
+
import WrappedWebSocket from '../browser/wrappedws';
|
|
6
|
+
/**
|
|
7
|
+
* Callback types
|
|
8
|
+
*/
|
|
9
|
+
export declare type ConnectCallback = () => void | number | Promise<void> | Promise<number>;
|
|
10
|
+
export declare type BinCallback = (body: Binary, headers?: BinaryQwsMessageHeaders, params?: QwsParams) => void | Promise<void>;
|
|
11
|
+
export declare type JsonCallback<T> = (body: T, headers?: JsonQwsMessageHeaders, params?: QwsParams) => void | Promise<void>;
|
|
12
|
+
export declare type ReadyCallback = (headers?: ReadyQwsMessageHeaders) => void | Promise<void>;
|
|
13
|
+
/**
|
|
14
|
+
* Connection options
|
|
15
|
+
*/
|
|
16
|
+
declare type QWebSocketOptions = {
|
|
17
|
+
name?: string;
|
|
18
|
+
extraConnectArgs?: Record<string, unknown>;
|
|
19
|
+
reconnect?: boolean;
|
|
20
|
+
reconnectNumTries?: number;
|
|
21
|
+
reconnectIntervalMillis?: number;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Actual queued WebSocket
|
|
25
|
+
*/
|
|
26
|
+
export default class QWebSocket {
|
|
27
|
+
wsOrUrl: WebSocket | string;
|
|
28
|
+
name: string;
|
|
29
|
+
options: QWebSocketOptions;
|
|
30
|
+
queue: WebSocketMessageQueue;
|
|
31
|
+
reconnectionAttempts: number;
|
|
32
|
+
needed: boolean;
|
|
33
|
+
wws: WrappedWebSocket;
|
|
34
|
+
ready: boolean;
|
|
35
|
+
callbacks: {
|
|
36
|
+
onConnect?: ConnectCallback;
|
|
37
|
+
onBin: RouteRecognizer;
|
|
38
|
+
onJson: RouteRecognizer;
|
|
39
|
+
onReady?: ReadyCallback;
|
|
40
|
+
onErroneousDisconnect?: (message: string) => void | Promise<void>;
|
|
41
|
+
onError?: (message: string) => void | Promise<void>;
|
|
42
|
+
onClose?: () => void | Promise<void>;
|
|
43
|
+
};
|
|
44
|
+
constructor(wsOrUrl: WebSocket | string, options?: QWebSocketOptions);
|
|
45
|
+
/**
|
|
46
|
+
* Public callback assignments for client
|
|
47
|
+
*/
|
|
48
|
+
onConnect(callback: ConnectCallback): void;
|
|
49
|
+
onBinRoute(routePattern: string, callback: BinCallback): void;
|
|
50
|
+
onBin(callback: BinCallback): void;
|
|
51
|
+
onJsonRoute<T>(routePattern: string, callback: JsonCallback<T>): void;
|
|
52
|
+
onJson<T>(callback: JsonCallback<T>): void;
|
|
53
|
+
onReady(callback: ReadyCallback): void;
|
|
54
|
+
onErroneousDisconnect(callback: () => void): void;
|
|
55
|
+
onError(callback: (message: string) => void): void;
|
|
56
|
+
onClose(callback: () => void): void;
|
|
57
|
+
/**
|
|
58
|
+
* Main logic
|
|
59
|
+
*/
|
|
60
|
+
setUp(): void;
|
|
61
|
+
flush(): void;
|
|
62
|
+
send(body: Binary | Record<string, unknown>, extraHeaders?: QwsMessageExtraHeaders): number;
|
|
63
|
+
sendToRoute(route: string, body: Binary | Record<string, unknown>, extraHeaders?: QwsMessageExtraHeaders): number;
|
|
64
|
+
/**
|
|
65
|
+
* Closes WS and sets promise resolution as callback.
|
|
66
|
+
* Overwrites any manually set up callback for onClose.
|
|
67
|
+
*/
|
|
68
|
+
close(): Promise<void>;
|
|
69
|
+
}
|
|
70
|
+
export {};
|
|
@@ -0,0 +1,351 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
const auto_bind_1 = __importDefault(require("auto-bind"));
|
|
16
|
+
const route_recognizer_1 = __importDefault(require("route-recognizer"));
|
|
17
|
+
const queue_1 = __importDefault(require("./queue"));
|
|
18
|
+
const wrappedws_1 = __importDefault(require("../browser/wrappedws"));
|
|
19
|
+
const queryparser_1 = require("./queryparser");
|
|
20
|
+
const logger_1 = __importDefault(require("./logger"));
|
|
21
|
+
const decodeErrorMessage = (event) => {
|
|
22
|
+
if (event === null || event === void 0 ? void 0 : event.message) {
|
|
23
|
+
return event.message;
|
|
24
|
+
}
|
|
25
|
+
if (event) {
|
|
26
|
+
return event.toString();
|
|
27
|
+
}
|
|
28
|
+
return 'Unknown error';
|
|
29
|
+
};
|
|
30
|
+
const defaultOpts = {
|
|
31
|
+
extraConnectArgs: {},
|
|
32
|
+
reconnect: true,
|
|
33
|
+
reconnectNumTries: 12,
|
|
34
|
+
reconnectIntervalMillis: 5000,
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* Actual queued WebSocket
|
|
38
|
+
*/
|
|
39
|
+
class QWebSocket {
|
|
40
|
+
constructor(wsOrUrl, options = {}) {
|
|
41
|
+
this.wsOrUrl = wsOrUrl;
|
|
42
|
+
this.options = Object.assign(Object.assign({}, defaultOpts), options);
|
|
43
|
+
this.name = options.name || 'websocket';
|
|
44
|
+
this.callbacks = {
|
|
45
|
+
onBin: new route_recognizer_1.default(),
|
|
46
|
+
onJson: new route_recognizer_1.default(),
|
|
47
|
+
};
|
|
48
|
+
this.queue = new queue_1.default();
|
|
49
|
+
this.reconnectionAttempts = 0;
|
|
50
|
+
this.needed = true;
|
|
51
|
+
this.wws = null;
|
|
52
|
+
this.ready = false;
|
|
53
|
+
(0, auto_bind_1.default)(this);
|
|
54
|
+
this.setUp();
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Public callback assignments for client
|
|
58
|
+
*/
|
|
59
|
+
onConnect(callback) {
|
|
60
|
+
this.callbacks.onConnect = callback;
|
|
61
|
+
}
|
|
62
|
+
onBinRoute(routePattern, callback) {
|
|
63
|
+
this.callbacks.onBin.add([{ path: routePattern, handler: callback }]);
|
|
64
|
+
}
|
|
65
|
+
onBin(callback) {
|
|
66
|
+
this.onBinRoute('', callback);
|
|
67
|
+
}
|
|
68
|
+
onJsonRoute(routePattern, callback) {
|
|
69
|
+
this.callbacks.onJson.add([{ path: routePattern, handler: callback }]);
|
|
70
|
+
}
|
|
71
|
+
onJson(callback) {
|
|
72
|
+
this.onJsonRoute('', callback);
|
|
73
|
+
}
|
|
74
|
+
onReady(callback) {
|
|
75
|
+
this.callbacks.onReady = callback;
|
|
76
|
+
}
|
|
77
|
+
onErroneousDisconnect(callback) {
|
|
78
|
+
this.callbacks.onErroneousDisconnect = callback;
|
|
79
|
+
}
|
|
80
|
+
onError(callback) {
|
|
81
|
+
this.callbacks.onError = callback;
|
|
82
|
+
}
|
|
83
|
+
onClose(callback) {
|
|
84
|
+
this.callbacks.onClose = callback;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Main logic
|
|
88
|
+
*/
|
|
89
|
+
// eslint-disable-next-line max-lines-per-function
|
|
90
|
+
setUp() {
|
|
91
|
+
var _a, _b, _c, _d;
|
|
92
|
+
if (this.wws && this.wws.readyState <= 1) {
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
this.reconnectionAttempts += 1;
|
|
96
|
+
const { reconnect, reconnectNumTries, reconnectIntervalMillis, extraConnectArgs } = this.options;
|
|
97
|
+
// timeout for too many reconnection attempts
|
|
98
|
+
if (reconnect && this.reconnectionAttempts > reconnectNumTries) {
|
|
99
|
+
logger_1.default.error(`${this.name}: Connection timed out, should re-connect entirely`);
|
|
100
|
+
(_b = (_a = this.callbacks).onError) === null || _b === void 0 ? void 0 : _b.call(_a, `WS connection timeout, max tries (${reconnectNumTries}) exceeded`);
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Actual WebSocket opening
|
|
105
|
+
*/
|
|
106
|
+
if (this.wsOrUrl instanceof WebSocket || ((_d = (_c = this.wsOrUrl) === null || _c === void 0 ? void 0 : _c.constructor) === null || _d === void 0 ? void 0 : _d.name) === 'WebSocket') {
|
|
107
|
+
const ws = this.wsOrUrl;
|
|
108
|
+
this.wws = new wrappedws_1.default(ws);
|
|
109
|
+
// TODO what if this is a reconnect? No reconnection was attempted, it's just the old reference
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
const connectUrl = (0, queryparser_1.addQueryParamsToUrl)(this.wsOrUrl, Object.assign(Object.assign({}, extraConnectArgs), { idx: this.queue.ackIdx }));
|
|
113
|
+
this.wws = new wrappedws_1.default(connectUrl);
|
|
114
|
+
}
|
|
115
|
+
this.wws.onWsError((event) => __awaiter(this, void 0, void 0, function* () {
|
|
116
|
+
var _e, _f, _g, _h;
|
|
117
|
+
// ws error will prompt reconnection which can time out, don't reject instantly
|
|
118
|
+
const message = decodeErrorMessage(event);
|
|
119
|
+
logger_1.default.error(`${this.name}: WS error occurred: ${message}`);
|
|
120
|
+
if (reconnect) {
|
|
121
|
+
yield ((_f = (_e = this.callbacks).onErroneousDisconnect) === null || _f === void 0 ? void 0 : _f.call(_e, message));
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
yield ((_h = (_g = this.callbacks).onError) === null || _h === void 0 ? void 0 : _h.call(_g, message));
|
|
125
|
+
}
|
|
126
|
+
}));
|
|
127
|
+
this.wws.onWsOpen(() => __awaiter(this, void 0, void 0, function* () {
|
|
128
|
+
var _j, _k;
|
|
129
|
+
this.reconnectionAttempts = 0;
|
|
130
|
+
if (reconnect) {
|
|
131
|
+
logger_1.default.info(`${this.name}: Connection established after ${this.reconnectionAttempts} tries`);
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
logger_1.default.info(`${this.name}: Connection established`);
|
|
135
|
+
}
|
|
136
|
+
try {
|
|
137
|
+
// call post-connect method, this may give previously acked messages
|
|
138
|
+
const readyIdx = yield ((_k = (_j = this.callbacks).onConnect) === null || _k === void 0 ? void 0 : _k.call(_j));
|
|
139
|
+
// send back readiness ack
|
|
140
|
+
this.wws.send({
|
|
141
|
+
headers: {
|
|
142
|
+
type: 'ready',
|
|
143
|
+
readyIdx,
|
|
144
|
+
},
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
catch (err) {
|
|
148
|
+
// error occurred during initialization phase, send error right away, no "ready" message
|
|
149
|
+
this.wws.send({
|
|
150
|
+
headers: {
|
|
151
|
+
type: 'err',
|
|
152
|
+
error: decodeErrorMessage(err),
|
|
153
|
+
},
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
}));
|
|
157
|
+
this.wws.onReady((message) => __awaiter(this, void 0, void 0, function* () {
|
|
158
|
+
var _l, _m;
|
|
159
|
+
// ready to send messages from given message index
|
|
160
|
+
const { readyIdx } = message.headers;
|
|
161
|
+
logger_1.default.info(`${this.name}: Socket ready to send${readyIdx ? `from chunk ${readyIdx}` : ''}`);
|
|
162
|
+
// if server sent chunk index to resume from, move queue cursors appropriately
|
|
163
|
+
if (readyIdx !== undefined) {
|
|
164
|
+
this.queue.acknowledge(readyIdx - 1);
|
|
165
|
+
this.queue.revert(readyIdx);
|
|
166
|
+
}
|
|
167
|
+
this.ready = true;
|
|
168
|
+
// flush if any messages in queue for it
|
|
169
|
+
this.flush();
|
|
170
|
+
try {
|
|
171
|
+
// call post-ready method
|
|
172
|
+
yield ((_m = (_l = this.callbacks).onReady) === null || _m === void 0 ? void 0 : _m.call(_l, message.headers));
|
|
173
|
+
}
|
|
174
|
+
catch (err) {
|
|
175
|
+
// error occurred during initialization phase, send error right away, no "ready" message
|
|
176
|
+
this.wws.send({
|
|
177
|
+
headers: {
|
|
178
|
+
type: 'err',
|
|
179
|
+
error: decodeErrorMessage(err),
|
|
180
|
+
},
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
}));
|
|
184
|
+
this.wws.onBin((message) => __awaiter(this, void 0, void 0, function* () {
|
|
185
|
+
// received binary message
|
|
186
|
+
const { headers, body } = message;
|
|
187
|
+
try {
|
|
188
|
+
// check callback
|
|
189
|
+
const routeResults = this.callbacks.onBin.recognize(headers.route || '');
|
|
190
|
+
if (routeResults) {
|
|
191
|
+
const handler = routeResults[0].handler;
|
|
192
|
+
const params = routeResults[0].params;
|
|
193
|
+
yield (handler === null || handler === void 0 ? void 0 : handler(body, headers, params));
|
|
194
|
+
}
|
|
195
|
+
// send back acknowledgment
|
|
196
|
+
this.wws.send({
|
|
197
|
+
headers: {
|
|
198
|
+
type: 'ack',
|
|
199
|
+
ackIdx: headers.idx,
|
|
200
|
+
},
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
catch (err) {
|
|
204
|
+
// error occurred during processing binary message, send error
|
|
205
|
+
this.wws.send({
|
|
206
|
+
headers: {
|
|
207
|
+
type: 'err',
|
|
208
|
+
error: decodeErrorMessage(err),
|
|
209
|
+
},
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
}));
|
|
213
|
+
this.wws.onJson((message) => __awaiter(this, void 0, void 0, function* () {
|
|
214
|
+
// received binary message
|
|
215
|
+
const { headers, body } = message;
|
|
216
|
+
try {
|
|
217
|
+
// check callback
|
|
218
|
+
const routeResults = this.callbacks.onJson.recognize(headers.route || '');
|
|
219
|
+
if (routeResults) {
|
|
220
|
+
const handler = routeResults[0].handler;
|
|
221
|
+
const params = routeResults[0].params;
|
|
222
|
+
yield (handler === null || handler === void 0 ? void 0 : handler(body, headers, params));
|
|
223
|
+
}
|
|
224
|
+
// send back acknowledgment
|
|
225
|
+
this.wws.send({
|
|
226
|
+
headers: {
|
|
227
|
+
type: 'ack',
|
|
228
|
+
ackIdx: headers.idx,
|
|
229
|
+
},
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
catch (err) {
|
|
233
|
+
// error occurred during processing json message, send error
|
|
234
|
+
this.wws.send({
|
|
235
|
+
headers: {
|
|
236
|
+
type: 'err',
|
|
237
|
+
error: decodeErrorMessage(err),
|
|
238
|
+
},
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
}));
|
|
242
|
+
this.wws.onAck((message) => {
|
|
243
|
+
// acknowledgment received
|
|
244
|
+
this.queue.acknowledge(message.headers.ackIdx);
|
|
245
|
+
if (!this.queue.numUnackMessages && !this.needed) {
|
|
246
|
+
this.wws.close();
|
|
247
|
+
}
|
|
248
|
+
});
|
|
249
|
+
this.wws.onErr((message) => __awaiter(this, void 0, void 0, function* () {
|
|
250
|
+
var _o, _p;
|
|
251
|
+
// handle error
|
|
252
|
+
logger_1.default.error(`${this.name}: Error occurred: ${message.headers.error}`);
|
|
253
|
+
yield ((_p = (_o = this.callbacks).onError) === null || _p === void 0 ? void 0 : _p.call(_o, message.headers.error));
|
|
254
|
+
}));
|
|
255
|
+
this.wws.onWsClose(() => __awaiter(this, void 0, void 0, function* () {
|
|
256
|
+
var _q, _r, _s, _t, _u, _v, _w, _x;
|
|
257
|
+
if (reconnect && this.needed) {
|
|
258
|
+
// if locally closed, needed should be false
|
|
259
|
+
// if it's true, it means we lost the connection and should try to re-connect
|
|
260
|
+
logger_1.default.info(`${this.name}: Closed pre-maturely, trying to reconnect after ${reconnectIntervalMillis}ms...`);
|
|
261
|
+
setTimeout(() => this.setUp(), reconnectIntervalMillis);
|
|
262
|
+
yield ((_r = (_q = this.callbacks).onErroneousDisconnect) === null || _r === void 0 ? void 0 : _r.call(_q, 'Closed pre-maturely'));
|
|
263
|
+
}
|
|
264
|
+
else if (reconnect && this.queue.numUnackMessages) {
|
|
265
|
+
// if there are still messages left to be sent and we should reconnect
|
|
266
|
+
logger_1.default.info(`${this.name}: Closed with messages still in queue, reconnecting in ${reconnectIntervalMillis}ms...`);
|
|
267
|
+
setTimeout(() => this.setUp(), reconnectIntervalMillis);
|
|
268
|
+
yield ((_t = (_s = this.callbacks).onErroneousDisconnect) === null || _t === void 0 ? void 0 : _t.call(_s, 'Closed with messages still in queue'));
|
|
269
|
+
}
|
|
270
|
+
else if (this.queue.numUnackMessages) {
|
|
271
|
+
// if there are still messages left to be sent, but we should not reconnect
|
|
272
|
+
logger_1.default.info(`${this.name}: Closed with messages still in queue`);
|
|
273
|
+
yield ((_v = (_u = this.callbacks).onError) === null || _v === void 0 ? void 0 : _v.call(_u, 'Closed with messages still in queue'));
|
|
274
|
+
}
|
|
275
|
+
else {
|
|
276
|
+
// all is well
|
|
277
|
+
logger_1.default.info(`${this.name}: Closed correctly`);
|
|
278
|
+
yield ((_x = (_w = this.callbacks).onClose) === null || _x === void 0 ? void 0 : _x.call(_w));
|
|
279
|
+
}
|
|
280
|
+
}));
|
|
281
|
+
}
|
|
282
|
+
flush() {
|
|
283
|
+
// connection is not open
|
|
284
|
+
if (this.wws.readyState !== WebSocket.OPEN || !this.ready) {
|
|
285
|
+
return;
|
|
286
|
+
}
|
|
287
|
+
// there is at least one message
|
|
288
|
+
if (this.queue.numUnsentMessages) {
|
|
289
|
+
// pop a message
|
|
290
|
+
const [idx, data] = this.queue.consume();
|
|
291
|
+
logger_1.default.debug(`${this.name}: Sending chunk ${idx} of size ${data.size}`);
|
|
292
|
+
this.wws.sendRaw(data);
|
|
293
|
+
logger_1.default.debug(`${this.name}: MQ decreased to size ${this.queue.numUnsentMessages} messages / ${this.queue.numUnsentBytes} bytes`);
|
|
294
|
+
this.flush();
|
|
295
|
+
}
|
|
296
|
+
else {
|
|
297
|
+
logger_1.default.debug(`${this.name}: Flushing complete, no ws messages backed up`);
|
|
298
|
+
// if not needed anymore after flush, close it
|
|
299
|
+
// send close event to ws, don't de-cache yet, wait for event
|
|
300
|
+
if (!this.queue.numUnackMessages && !this.needed) {
|
|
301
|
+
this.wws.close();
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
send(body, extraHeaders = {}) {
|
|
306
|
+
return this.sendToRoute(undefined, body, extraHeaders);
|
|
307
|
+
}
|
|
308
|
+
sendToRoute(route, body, extraHeaders = {}) {
|
|
309
|
+
// encode into payload message based on body type
|
|
310
|
+
let message;
|
|
311
|
+
if (body instanceof Blob) {
|
|
312
|
+
message = {
|
|
313
|
+
headers: Object.assign({ type: 'bin', route }, extraHeaders),
|
|
314
|
+
body,
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
else {
|
|
318
|
+
message = {
|
|
319
|
+
headers: Object.assign({ type: 'json', route }, extraHeaders),
|
|
320
|
+
body,
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
// add message to fifo queue
|
|
324
|
+
const { numUnsentMessages } = this.queue;
|
|
325
|
+
const idx = this.queue.produce(message);
|
|
326
|
+
// ready state should either be CONNECTING or OPEN at this point to flush instantly
|
|
327
|
+
if (this.wws.readyState === WebSocket.OPEN && this.ready && !numUnsentMessages) {
|
|
328
|
+
this.flush();
|
|
329
|
+
}
|
|
330
|
+
return idx;
|
|
331
|
+
}
|
|
332
|
+
/**
|
|
333
|
+
* Closes WS and sets promise resolution as callback.
|
|
334
|
+
* Overwrites any manually set up callback for onClose.
|
|
335
|
+
*/
|
|
336
|
+
close() {
|
|
337
|
+
return new Promise((resolve) => {
|
|
338
|
+
this.needed = false;
|
|
339
|
+
// wrap original onClose to resolve this promise
|
|
340
|
+
const { onClose } = this.callbacks;
|
|
341
|
+
this.callbacks.onClose = () => __awaiter(this, void 0, void 0, function* () {
|
|
342
|
+
yield (onClose === null || onClose === void 0 ? void 0 : onClose());
|
|
343
|
+
resolve();
|
|
344
|
+
});
|
|
345
|
+
// flush if any messages in queue
|
|
346
|
+
this.flush();
|
|
347
|
+
});
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
exports.default = QWebSocket;
|
|
351
|
+
//# sourceMappingURL=queuews.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queuews.js","sourceRoot":"","sources":["../../src/common/queuews.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
5
|
+
}) : (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
o[k2] = m[k];
|
|
8
|
+
}));
|
|
9
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
10
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
11
|
+
};
|
|
12
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
13
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
14
|
+
};
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
const queuews_1 = __importDefault(require("./common/queuews"));
|
|
17
|
+
__exportStar(require("./common/logger"), exports);
|
|
18
|
+
__exportStar(require("./common/message"), exports);
|
|
19
|
+
__exportStar(require("./common/queuews"), exports);
|
|
20
|
+
__exportStar(require("./browser/messageencode"), exports);
|
|
21
|
+
exports.default = queuews_1.default;
|
|
22
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,+DAA0C;AAE1C,kDAAgC;AAChC,mDAAiC;AACjC,mDAAiC;AACjC,0DAAwC;AAExC,kBAAe,iBAAU,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "qws-browser",
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"description": "Safe queueing with auto-reconnect for WebSockets",
|
|
5
|
+
"author": "Csaba Sulyok <csaba.sulyok@gmail.com>",
|
|
6
|
+
"license": "ISC",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"main": "./dist/index.js",
|
|
9
|
+
"files": [
|
|
10
|
+
"dist"
|
|
11
|
+
],
|
|
12
|
+
"repository": {
|
|
13
|
+
"type": "git",
|
|
14
|
+
"url": "git+https://github.com/csabasulyok/qws-browser.git"
|
|
15
|
+
},
|
|
16
|
+
"publishConfig": {
|
|
17
|
+
"registry": "https://registry.npmjs.org/"
|
|
18
|
+
},
|
|
19
|
+
"dependencies": {
|
|
20
|
+
"auto-bind": "^4.0.0",
|
|
21
|
+
"route-recognizer": "^0.3.4"
|
|
22
|
+
},
|
|
23
|
+
"devDependencies": {
|
|
24
|
+
"@typescript-eslint/eslint-plugin": "^4.29.3",
|
|
25
|
+
"@typescript-eslint/parser": "^4.29.3",
|
|
26
|
+
"eslint": "^7.32.0",
|
|
27
|
+
"eslint-config-airbnb": "^18.2.1",
|
|
28
|
+
"eslint-config-prettier": "^8.3.0",
|
|
29
|
+
"eslint-import-resolver-typescript": "^2.4.0",
|
|
30
|
+
"eslint-plugin-import": "^2.24.1",
|
|
31
|
+
"eslint-plugin-prettier": "^3.4.1",
|
|
32
|
+
"nodemon": "^2.0.12",
|
|
33
|
+
"prettier": "^2.3.2",
|
|
34
|
+
"rimraf": "^3.0.2",
|
|
35
|
+
"ts-node": "^10.2.1",
|
|
36
|
+
"typescript": "^4.3.5"
|
|
37
|
+
},
|
|
38
|
+
"lint-staged": {
|
|
39
|
+
"*.{js,ts,jsx,tsx}": [
|
|
40
|
+
"npm run lint",
|
|
41
|
+
"git add"
|
|
42
|
+
]
|
|
43
|
+
},
|
|
44
|
+
"husky": {
|
|
45
|
+
"hooks": {
|
|
46
|
+
"pre-commit": "lint-staged"
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
"nodemonConfig": {
|
|
50
|
+
"watch": [
|
|
51
|
+
".env",
|
|
52
|
+
"src/*.*",
|
|
53
|
+
"examples/*.*"
|
|
54
|
+
]
|
|
55
|
+
},
|
|
56
|
+
"scripts": {
|
|
57
|
+
"clean": "rimraf dist *.tsbuildinfo",
|
|
58
|
+
"build": "tsc -p tsconfig.build.json",
|
|
59
|
+
"cb": "pnpm clean && pnpm build",
|
|
60
|
+
"lint": "eslint 'src/**/*.{js,ts,jsx,tsx}' --quiet --fix"
|
|
61
|
+
}
|
|
62
|
+
}
|