@socket-mesh/core 1.0.3 → 1.0.4
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/dist/index.d.ts +10 -10
- package/dist/index.js +10 -10
- package/dist/maps/handler-map.d.ts +2 -2
- package/dist/maps/index.d.ts +2 -2
- package/dist/maps/index.js +2 -2
- package/dist/maps/method-map.d.ts +8 -8
- package/dist/maps/method-map.js +1 -0
- package/dist/packet.d.ts +15 -15
- package/dist/packet.js +3 -1
- package/dist/plugins/index.d.ts +1 -1
- package/dist/plugins/index.js +1 -1
- package/dist/plugins/plugin.d.ts +27 -27
- package/dist/request-handler.d.ts +7 -7
- package/dist/request-handler.js +9 -2
- package/dist/request.d.ts +39 -39
- package/dist/request.js +13 -11
- package/dist/response.d.ts +14 -14
- package/dist/response.js +3 -1
- package/dist/socket-event.d.ts +21 -24
- package/dist/socket-transport.d.ts +39 -41
- package/dist/socket-transport.js +218 -195
- package/dist/socket.d.ts +25 -25
- package/dist/socket.js +21 -16
- package/dist/utils.d.ts +1 -1
- package/dist/utils.js +3 -3
- package/package.json +15 -12
package/dist/socket-transport.js
CHANGED
|
@@ -1,15 +1,35 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import { toArray, wait } from
|
|
1
|
+
import { extractAuthTokenData } from '@socket-mesh/auth';
|
|
2
|
+
import { AbortError, AuthError, BadConnectionError, dehydrateError, hydrateError, InvalidActionError, InvalidArgumentsError, PluginBlockedError, SocketClosedError, SocketProtocolError, SocketProtocolErrorStatuses, SocketProtocolIgnoreStatuses, TimeoutError } from '@socket-mesh/errors';
|
|
3
|
+
import defaultCodec from '@socket-mesh/formatter';
|
|
4
|
+
import ws from 'isomorphic-ws';
|
|
5
|
+
import { isRequestPacket } from './packet.js';
|
|
6
|
+
import { RequestHandlerArgs } from './request-handler.js';
|
|
7
|
+
import { abortRequest, isRequestDone } from './request.js';
|
|
8
|
+
import { isResponsePacket } from './response.js';
|
|
9
|
+
import { toArray, wait } from './utils.js';
|
|
10
10
|
export class SocketTransport {
|
|
11
|
+
_authToken;
|
|
12
|
+
_callbackMap;
|
|
13
|
+
_callIdGenerator;
|
|
14
|
+
_handlers;
|
|
15
|
+
_inboundProcessedMessageCount;
|
|
16
|
+
_inboundReceivedMessageCount;
|
|
17
|
+
_isReady;
|
|
18
|
+
_outboundPreparedMessageCount;
|
|
19
|
+
_outboundSentMessageCount;
|
|
20
|
+
_pingTimeoutRef;
|
|
21
|
+
_signedAuthToken;
|
|
22
|
+
_socket;
|
|
23
|
+
_webSocket;
|
|
24
|
+
ackTimeoutMs;
|
|
25
|
+
codecEngine;
|
|
26
|
+
id;
|
|
27
|
+
plugins;
|
|
28
|
+
streamCleanupMode;
|
|
11
29
|
constructor(options) {
|
|
12
30
|
let cid = 1;
|
|
31
|
+
this._authToken = null;
|
|
32
|
+
this._signedAuthToken = null;
|
|
13
33
|
this.ackTimeoutMs = options?.ackTimeoutMs ?? 10000;
|
|
14
34
|
this._callIdGenerator = options?.callIdGenerator || (() => {
|
|
15
35
|
return cid++;
|
|
@@ -42,10 +62,10 @@ export class SocketTransport {
|
|
|
42
62
|
const signedAuthToken = this._signedAuthToken;
|
|
43
63
|
this._authToken = null;
|
|
44
64
|
this._signedAuthToken = null;
|
|
45
|
-
this._socket.emit('authStateChange', {
|
|
65
|
+
this._socket.emit('authStateChange', { isAuthenticated: false, wasAuthenticated: true });
|
|
46
66
|
// In order for the events to trigger we need to wait for the next tick.
|
|
47
67
|
await wait(0);
|
|
48
|
-
this._socket.emit('deauthenticate', {
|
|
68
|
+
this._socket.emit('deauthenticate', { authToken, signedAuthToken });
|
|
49
69
|
for (const plugin of this.plugins) {
|
|
50
70
|
if (plugin.onDeauthenticate) {
|
|
51
71
|
plugin.onDeauthenticate({ socket: this.socket, transport: this });
|
|
@@ -92,14 +112,14 @@ export class SocketTransport {
|
|
|
92
112
|
try {
|
|
93
113
|
for (const plugin of this.plugins) {
|
|
94
114
|
if (plugin.onMessage) {
|
|
95
|
-
curPacket = await plugin.onMessage({
|
|
115
|
+
curPacket = await plugin.onMessage({ packet: curPacket, socket: this.socket, timestamp: timestamp, transport: this });
|
|
96
116
|
}
|
|
97
117
|
}
|
|
98
118
|
}
|
|
99
119
|
catch (err) {
|
|
100
120
|
pluginError = err;
|
|
101
121
|
}
|
|
102
|
-
// Check to see if it is a request or response packet.
|
|
122
|
+
// Check to see if it is a request or response packet.
|
|
103
123
|
if (isResponsePacket(curPacket)) {
|
|
104
124
|
this.onResponse(curPacket, pluginError);
|
|
105
125
|
}
|
|
@@ -111,19 +131,105 @@ export class SocketTransport {
|
|
|
111
131
|
}
|
|
112
132
|
}
|
|
113
133
|
}
|
|
134
|
+
invoke(methodOptions, arg) {
|
|
135
|
+
let methodRequest;
|
|
136
|
+
let serviceRequest;
|
|
137
|
+
let service;
|
|
138
|
+
let ackTimeoutMs;
|
|
139
|
+
if (typeof methodOptions === 'object' && !Array.isArray(methodOptions)) {
|
|
140
|
+
ackTimeoutMs = methodOptions.ackTimeoutMs;
|
|
141
|
+
}
|
|
142
|
+
if (typeof methodOptions === 'object' && (Array.isArray(methodOptions) || 'service' in methodOptions)) {
|
|
143
|
+
let serviceMethod;
|
|
144
|
+
if (Array.isArray(methodOptions)) {
|
|
145
|
+
service = methodOptions[0];
|
|
146
|
+
serviceMethod = methodOptions[1];
|
|
147
|
+
ackTimeoutMs = methodOptions[2];
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
service = methodOptions.service;
|
|
151
|
+
serviceMethod = methodOptions.method;
|
|
152
|
+
}
|
|
153
|
+
serviceRequest = {
|
|
154
|
+
ackTimeoutMs: ackTimeoutMs || this.ackTimeoutMs,
|
|
155
|
+
callback: null,
|
|
156
|
+
cid: this._callIdGenerator(),
|
|
157
|
+
data: arg,
|
|
158
|
+
method: serviceMethod,
|
|
159
|
+
service
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
else {
|
|
163
|
+
methodRequest = {
|
|
164
|
+
ackTimeoutMs: ackTimeoutMs || this.ackTimeoutMs,
|
|
165
|
+
callback: null,
|
|
166
|
+
cid: this._callIdGenerator(),
|
|
167
|
+
data: arg,
|
|
168
|
+
method: ((typeof methodOptions === 'object') ? methodOptions.method : methodOptions)
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
const callbackMap = this._callbackMap;
|
|
172
|
+
let abort;
|
|
173
|
+
const baseRequest = (serviceRequest || methodRequest);
|
|
174
|
+
const promise = new Promise((resolve, reject) => {
|
|
175
|
+
if (baseRequest.ackTimeoutMs) {
|
|
176
|
+
baseRequest.timeoutId = setTimeout(() => {
|
|
177
|
+
delete callbackMap[baseRequest.cid];
|
|
178
|
+
baseRequest.callback = null;
|
|
179
|
+
clearTimeout(baseRequest.timeoutId);
|
|
180
|
+
delete baseRequest.timeoutId;
|
|
181
|
+
reject(new TimeoutError(`Method '${[service, baseRequest.method].filter(Boolean).join('.')}' timed out.`));
|
|
182
|
+
}, baseRequest.ackTimeoutMs);
|
|
183
|
+
}
|
|
184
|
+
abort = () => {
|
|
185
|
+
delete callbackMap[baseRequest.cid];
|
|
186
|
+
if (baseRequest.timeoutId) {
|
|
187
|
+
clearTimeout(baseRequest.timeoutId);
|
|
188
|
+
delete baseRequest.timeoutId;
|
|
189
|
+
}
|
|
190
|
+
if (baseRequest.callback) {
|
|
191
|
+
baseRequest.callback = null;
|
|
192
|
+
reject(new AbortError(`Method '${[service, baseRequest.method].filter(Boolean).join('.')}' was aborted.`));
|
|
193
|
+
}
|
|
194
|
+
};
|
|
195
|
+
baseRequest.callback = (err, result) => {
|
|
196
|
+
delete callbackMap[baseRequest.cid];
|
|
197
|
+
baseRequest.callback = null;
|
|
198
|
+
if (baseRequest.timeoutId) {
|
|
199
|
+
clearTimeout(baseRequest.timeoutId);
|
|
200
|
+
delete baseRequest.timeoutId;
|
|
201
|
+
}
|
|
202
|
+
if (err) {
|
|
203
|
+
reject(err);
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
resolve(result);
|
|
207
|
+
};
|
|
208
|
+
baseRequest.sentCallback = () => {
|
|
209
|
+
delete baseRequest.sentCallback;
|
|
210
|
+
this._outboundSentMessageCount++;
|
|
211
|
+
};
|
|
212
|
+
});
|
|
213
|
+
this._outboundPreparedMessageCount++;
|
|
214
|
+
const request = Object.assign(baseRequest, { promise });
|
|
215
|
+
this.onInvoke(request);
|
|
216
|
+
return [promise, abort];
|
|
217
|
+
}
|
|
114
218
|
onClose(code, reason) {
|
|
115
219
|
const prevStatus = this.status;
|
|
116
220
|
this.webSocket = null;
|
|
117
221
|
this._isReady = false;
|
|
118
|
-
|
|
119
|
-
|
|
222
|
+
if (this._pingTimeoutRef) {
|
|
223
|
+
clearTimeout(this._pingTimeoutRef);
|
|
224
|
+
this._pingTimeoutRef = null;
|
|
225
|
+
}
|
|
120
226
|
this.abortAllPendingCallbacksDueToBadConnection(prevStatus);
|
|
121
227
|
for (const plugin of this.plugins) {
|
|
122
228
|
if (plugin.onClose) {
|
|
123
229
|
plugin.onClose({ socket: this.socket, transport: this });
|
|
124
230
|
}
|
|
125
231
|
}
|
|
126
|
-
if (!
|
|
232
|
+
if (!SocketProtocolIgnoreStatuses[code]) {
|
|
127
233
|
let closeMessage;
|
|
128
234
|
if (typeof reason === 'string') {
|
|
129
235
|
closeMessage = `Socket connection closed with status code ${code} and reason: ${reason}`;
|
|
@@ -131,9 +237,9 @@ export class SocketTransport {
|
|
|
131
237
|
else {
|
|
132
238
|
closeMessage = `Socket connection closed with status code ${code}`;
|
|
133
239
|
}
|
|
134
|
-
this.onError(new SocketProtocolError(
|
|
240
|
+
this.onError(new SocketProtocolError(SocketProtocolErrorStatuses[code] || closeMessage, code));
|
|
135
241
|
}
|
|
136
|
-
const strReason = reason?.toString() ||
|
|
242
|
+
const strReason = reason?.toString() || SocketProtocolErrorStatuses[code];
|
|
137
243
|
this._socket.emit('close', { code, reason: strReason });
|
|
138
244
|
}
|
|
139
245
|
onDisconnect(status, code, reason) {
|
|
@@ -145,7 +251,7 @@ export class SocketTransport {
|
|
|
145
251
|
}
|
|
146
252
|
for (const plugin of this.plugins) {
|
|
147
253
|
if (plugin.onDisconnected) {
|
|
148
|
-
plugin.onDisconnected({ socket: this.socket, transport: this
|
|
254
|
+
plugin.onDisconnected({ code, reason, socket: this.socket, status, transport: this });
|
|
149
255
|
}
|
|
150
256
|
}
|
|
151
257
|
}
|
|
@@ -172,19 +278,19 @@ export class SocketTransport {
|
|
|
172
278
|
this._inboundReceivedMessageCount++;
|
|
173
279
|
for (let i = 0; i < this.plugins.length; i++) {
|
|
174
280
|
const plugin = this.plugins[i];
|
|
175
|
-
if (plugin
|
|
176
|
-
p = p.then(message => {
|
|
177
|
-
return plugin.onMessageRaw({ socket: this.socket, transport: this
|
|
281
|
+
if (plugin?.onMessageRaw) {
|
|
282
|
+
p = p.then((message) => {
|
|
283
|
+
return plugin.onMessageRaw({ message, promise, socket: this.socket, timestamp, transport: this });
|
|
178
284
|
});
|
|
179
285
|
}
|
|
180
286
|
}
|
|
181
|
-
p.then(data => {
|
|
287
|
+
p.then((data) => {
|
|
182
288
|
const packet = this.decode(data);
|
|
183
289
|
this._socket.emit('message', { data, isBinary });
|
|
184
290
|
return this.handleInboudMessage({ packet, timestamp });
|
|
185
291
|
})
|
|
186
292
|
.then(resolve)
|
|
187
|
-
.catch(err => {
|
|
293
|
+
.catch((err) => {
|
|
188
294
|
reject(err);
|
|
189
295
|
if (!(err instanceof PluginBlockedError)) {
|
|
190
296
|
this.onError(err);
|
|
@@ -204,14 +310,16 @@ export class SocketTransport {
|
|
|
204
310
|
onPingPong() { }
|
|
205
311
|
async onRequest(packet, timestamp, pluginError) {
|
|
206
312
|
this._socket.emit('request', { request: packet });
|
|
207
|
-
const timeoutAt = typeof packet.ackTimeoutMs === 'number' ? new Date(timestamp.valueOf() + packet.ackTimeoutMs) :
|
|
313
|
+
const timeoutAt = typeof packet.ackTimeoutMs === 'number' ? new Date(timestamp.valueOf() + packet.ackTimeoutMs) : undefined;
|
|
208
314
|
let wasHandled = false;
|
|
209
315
|
let response;
|
|
210
316
|
let error;
|
|
211
317
|
if (pluginError) {
|
|
212
318
|
wasHandled = true;
|
|
213
319
|
error = pluginError;
|
|
214
|
-
|
|
320
|
+
if (packet.cid) {
|
|
321
|
+
response = { error: pluginError, rid: packet.cid, timeoutAt };
|
|
322
|
+
}
|
|
215
323
|
}
|
|
216
324
|
else {
|
|
217
325
|
const handler = this._handlers[packet.method];
|
|
@@ -221,19 +329,19 @@ export class SocketTransport {
|
|
|
221
329
|
const data = await handler(new RequestHandlerArgs({
|
|
222
330
|
isRpc: !!packet.cid,
|
|
223
331
|
method: packet.method.toString(),
|
|
224
|
-
|
|
332
|
+
options: packet.data,
|
|
225
333
|
socket: this._socket,
|
|
226
|
-
|
|
227
|
-
|
|
334
|
+
timeoutMs: packet.ackTimeoutMs,
|
|
335
|
+
transport: this
|
|
228
336
|
}));
|
|
229
337
|
if (packet.cid) {
|
|
230
|
-
response = { rid: packet.cid, timeoutAt
|
|
338
|
+
response = { data, rid: packet.cid, timeoutAt };
|
|
231
339
|
}
|
|
232
340
|
}
|
|
233
341
|
catch (err) {
|
|
234
342
|
error = err;
|
|
235
343
|
if (packet.cid) {
|
|
236
|
-
response = { rid: packet.cid, timeoutAt
|
|
344
|
+
response = { error, rid: packet.cid, timeoutAt };
|
|
237
345
|
}
|
|
238
346
|
}
|
|
239
347
|
}
|
|
@@ -267,7 +375,7 @@ export class SocketTransport {
|
|
|
267
375
|
}
|
|
268
376
|
}
|
|
269
377
|
if (pluginError) {
|
|
270
|
-
this._socket.emit('response', { response: { rid: response.rid
|
|
378
|
+
this._socket.emit('response', { response: { error: pluginError, rid: response.rid } });
|
|
271
379
|
}
|
|
272
380
|
else {
|
|
273
381
|
this._socket.emit('response', { response });
|
|
@@ -286,9 +394,6 @@ export class SocketTransport {
|
|
|
286
394
|
this.sendRequest([request]);
|
|
287
395
|
}
|
|
288
396
|
onUnhandledRequest(packet) {
|
|
289
|
-
if (this._onUnhandledRequest) {
|
|
290
|
-
return this._onUnhandledRequest(this, packet);
|
|
291
|
-
}
|
|
292
397
|
return false;
|
|
293
398
|
}
|
|
294
399
|
resetPingTimeout(timeoutMs, code) {
|
|
@@ -302,24 +407,25 @@ export class SocketTransport {
|
|
|
302
407
|
// Delay should be equal to the interval at which your server
|
|
303
408
|
// sends out pings plus a conservative assumption of the latency.
|
|
304
409
|
this._pingTimeoutRef = setTimeout(() => {
|
|
305
|
-
this.
|
|
410
|
+
if (this._webSocket) {
|
|
411
|
+
this._webSocket.close(code);
|
|
412
|
+
}
|
|
306
413
|
}, timeoutMs);
|
|
307
414
|
}
|
|
308
415
|
}
|
|
309
416
|
send(data) {
|
|
310
417
|
return new Promise((resolve, reject) => {
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
reject(err);
|
|
315
|
-
return;
|
|
316
|
-
}
|
|
317
|
-
resolve();
|
|
318
|
-
});
|
|
319
|
-
}
|
|
320
|
-
catch (err) {
|
|
321
|
-
throw err;
|
|
418
|
+
if (!this._webSocket) {
|
|
419
|
+
reject(new SocketClosedError('Web socket is closed.'));
|
|
420
|
+
return;
|
|
322
421
|
}
|
|
422
|
+
this._webSocket.send(data, (err) => {
|
|
423
|
+
if (err) {
|
|
424
|
+
reject(err);
|
|
425
|
+
return;
|
|
426
|
+
}
|
|
427
|
+
resolve();
|
|
428
|
+
});
|
|
323
429
|
});
|
|
324
430
|
}
|
|
325
431
|
sendRequest(index, requests) {
|
|
@@ -327,6 +433,9 @@ export class SocketTransport {
|
|
|
327
433
|
requests = index;
|
|
328
434
|
index = 0;
|
|
329
435
|
}
|
|
436
|
+
if (!requests) {
|
|
437
|
+
return; // Shouldn't happen
|
|
438
|
+
}
|
|
330
439
|
// Filter out any requests that have already timed out.
|
|
331
440
|
if (requests.some(request => isRequestDone(request))) {
|
|
332
441
|
requests = requests.filter(req => isRequestDone(req));
|
|
@@ -336,14 +445,14 @@ export class SocketTransport {
|
|
|
336
445
|
}
|
|
337
446
|
for (; index < this.plugins.length; index++) {
|
|
338
447
|
const plugin = this.plugins[index];
|
|
339
|
-
if (
|
|
448
|
+
if (plugin?.sendRequest) {
|
|
340
449
|
index++;
|
|
341
450
|
try {
|
|
342
451
|
plugin.sendRequest({
|
|
343
|
-
|
|
344
|
-
transport: this,
|
|
452
|
+
cont: this.sendRequest.bind(this, index),
|
|
345
453
|
requests,
|
|
346
|
-
|
|
454
|
+
socket: this.socket,
|
|
455
|
+
transport: this
|
|
347
456
|
});
|
|
348
457
|
}
|
|
349
458
|
catch (err) {
|
|
@@ -363,13 +472,13 @@ export class SocketTransport {
|
|
|
363
472
|
}
|
|
364
473
|
return;
|
|
365
474
|
}
|
|
366
|
-
const encode = requests.map(req => {
|
|
367
|
-
if ('callback' in req) {
|
|
475
|
+
const encode = requests.map((req) => {
|
|
476
|
+
if ('callback' in req && req.callback) {
|
|
368
477
|
const { callback, promise, timeoutId, ...rest } = req;
|
|
369
478
|
this._callbackMap[req.cid] = {
|
|
479
|
+
callback: req.callback,
|
|
370
480
|
method: ['service' in req ? req.service : '', req.method].filter(Boolean).join('.'),
|
|
371
|
-
timeoutId: req.timeoutId
|
|
372
|
-
callback: req.callback
|
|
481
|
+
timeoutId: req.timeoutId
|
|
373
482
|
};
|
|
374
483
|
return rest;
|
|
375
484
|
}
|
|
@@ -377,7 +486,7 @@ export class SocketTransport {
|
|
|
377
486
|
return rest;
|
|
378
487
|
});
|
|
379
488
|
let sendErr;
|
|
380
|
-
this.send(this.codecEngine.encode(encode.length === 1 ? encode[0] : encode)).catch(err => {
|
|
489
|
+
this.send(this.codecEngine.encode(encode.length === 1 ? encode[0] : encode)).catch((err) => {
|
|
381
490
|
sendErr = err;
|
|
382
491
|
}).then(() => {
|
|
383
492
|
const errCode = sendErr?.code;
|
|
@@ -388,11 +497,11 @@ export class SocketTransport {
|
|
|
388
497
|
if (req.sentCallback) {
|
|
389
498
|
req.sentCallback(sendErr);
|
|
390
499
|
}
|
|
391
|
-
if (sendErr && 'callback' in req) {
|
|
500
|
+
if (sendErr && 'callback' in req && req.callback) {
|
|
392
501
|
req.callback(sendErr);
|
|
393
502
|
}
|
|
394
503
|
}
|
|
395
|
-
}).catch(err => {
|
|
504
|
+
}).catch((err) => {
|
|
396
505
|
this.onError(err);
|
|
397
506
|
});
|
|
398
507
|
}
|
|
@@ -401,24 +510,27 @@ export class SocketTransport {
|
|
|
401
510
|
responses = index;
|
|
402
511
|
index = 0;
|
|
403
512
|
}
|
|
513
|
+
if (!responses) {
|
|
514
|
+
return; // shouldn't happen
|
|
515
|
+
}
|
|
404
516
|
// Remove any response that has timed out
|
|
405
517
|
if (!(responses = responses.filter(item => !item.timeoutAt || item.timeoutAt > new Date())).length) {
|
|
406
518
|
return;
|
|
407
519
|
}
|
|
408
520
|
for (; index < this.plugins.length; index++) {
|
|
409
521
|
const plugin = this.plugins[index];
|
|
410
|
-
if ('sendResponse' in plugin) {
|
|
522
|
+
if (plugin && 'sendResponse' in plugin && plugin.sendResponse) {
|
|
411
523
|
index++;
|
|
412
524
|
try {
|
|
413
525
|
plugin.sendResponse({
|
|
414
|
-
|
|
415
|
-
transport: this,
|
|
526
|
+
cont: this.sendResponse.bind(this, index),
|
|
416
527
|
responses,
|
|
417
|
-
|
|
528
|
+
socket: this.socket,
|
|
529
|
+
transport: this
|
|
418
530
|
});
|
|
419
531
|
}
|
|
420
532
|
catch (err) {
|
|
421
|
-
this.sendResponse(index, responses.map(item => ({ rid: item.rid, timeoutAt: item.timeoutAt
|
|
533
|
+
this.sendResponse(index, responses.map(item => ({ error: err, rid: item.rid, timeoutAt: item.timeoutAt })));
|
|
422
534
|
}
|
|
423
535
|
return;
|
|
424
536
|
}
|
|
@@ -436,25 +548,23 @@ export class SocketTransport {
|
|
|
436
548
|
}
|
|
437
549
|
delete response.timeoutAt;
|
|
438
550
|
}
|
|
439
|
-
//timeoutId?: NodeJS.Timeout;
|
|
440
|
-
//callback: (err: Error, result?: U) => void | null
|
|
441
|
-
this.send(this.codecEngine.encode(responses.length === 1 ? responses[0] : responses)).catch(err => {
|
|
551
|
+
// timeoutId?: NodeJS.Timeout;
|
|
552
|
+
// callback: (err: Error, result?: U) => void | null
|
|
553
|
+
this.send(this.codecEngine.encode(responses.length === 1 ? responses[0] : responses)).catch((err) => {
|
|
442
554
|
this.onError(err);
|
|
443
555
|
});
|
|
444
556
|
}
|
|
445
557
|
async setAuthorization(signedAuthToken, authToken) {
|
|
446
|
-
if (typeof signedAuthToken !== 'string') {
|
|
447
|
-
throw new InvalidArgumentsError('SignedAuthToken must be type string.');
|
|
448
|
-
}
|
|
449
558
|
if (signedAuthToken !== this._signedAuthToken) {
|
|
450
|
-
|
|
559
|
+
let newAuthToken = authToken;
|
|
560
|
+
if (!newAuthToken) {
|
|
451
561
|
const extractedAuthToken = extractAuthTokenData(signedAuthToken);
|
|
452
562
|
if (typeof extractedAuthToken === 'string') {
|
|
453
563
|
throw new InvalidArgumentsError('Invalid authToken.');
|
|
454
564
|
}
|
|
455
|
-
|
|
565
|
+
newAuthToken = extractedAuthToken;
|
|
456
566
|
}
|
|
457
|
-
this._authToken =
|
|
567
|
+
this._authToken = newAuthToken;
|
|
458
568
|
this._signedAuthToken = signedAuthToken;
|
|
459
569
|
return true;
|
|
460
570
|
}
|
|
@@ -470,7 +580,7 @@ export class SocketTransport {
|
|
|
470
580
|
plugin.onReady({ socket: this.socket, transport: this });
|
|
471
581
|
}
|
|
472
582
|
}
|
|
473
|
-
this._socket.emit('connect', { id: this.id,
|
|
583
|
+
this._socket.emit('connect', { authError, id: this.id, isAuthenticated: !!this.signedAuthToken, pingTimeoutMs });
|
|
474
584
|
}
|
|
475
585
|
get signedAuthToken() {
|
|
476
586
|
return this._signedAuthToken;
|
|
@@ -489,48 +599,35 @@ export class SocketTransport {
|
|
|
489
599
|
return 'ready';
|
|
490
600
|
}
|
|
491
601
|
switch (this._webSocket.readyState) {
|
|
602
|
+
case ws.CLOSING:
|
|
603
|
+
return 'closing';
|
|
492
604
|
case ws.CONNECTING:
|
|
493
605
|
case ws.OPEN:
|
|
494
606
|
return 'connecting';
|
|
495
|
-
case ws.CLOSING:
|
|
496
|
-
return 'closing';
|
|
497
607
|
default:
|
|
498
608
|
return 'closed';
|
|
499
609
|
}
|
|
500
610
|
}
|
|
501
|
-
triggerAuthenticationEvents(wasSigned, wasAuthenticated) {
|
|
502
|
-
this._socket.emit('authStateChange', { wasAuthenticated, isAuthenticated: true, authToken: this._authToken, signedAuthToken: this._signedAuthToken });
|
|
503
|
-
this._socket.emit('authenticate', { wasSigned, signedAuthToken: this._signedAuthToken, authToken: this._authToken });
|
|
504
|
-
for (const plugin of this.plugins) {
|
|
505
|
-
if (plugin.onAuthenticated) {
|
|
506
|
-
plugin.onAuthenticated({ socket: this.socket, transport: this });
|
|
507
|
-
}
|
|
508
|
-
}
|
|
509
|
-
}
|
|
510
611
|
transmit(serviceAndMethod, arg) {
|
|
511
|
-
let
|
|
512
|
-
let
|
|
513
|
-
let method;
|
|
612
|
+
let serviceRequest;
|
|
613
|
+
let methodRequest;
|
|
514
614
|
if (Array.isArray(serviceAndMethod)) {
|
|
515
|
-
|
|
516
|
-
|
|
615
|
+
serviceRequest = {
|
|
616
|
+
data: arg,
|
|
617
|
+
method: serviceAndMethod[1],
|
|
618
|
+
service: serviceAndMethod[0]
|
|
619
|
+
};
|
|
517
620
|
}
|
|
518
621
|
else {
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
method,
|
|
529
|
-
promise: null
|
|
530
|
-
};
|
|
531
|
-
const promise = request.promise = new Promise((resolve, reject) => {
|
|
532
|
-
request.sentCallback = (err) => {
|
|
533
|
-
delete request.sentCallback;
|
|
622
|
+
methodRequest = {
|
|
623
|
+
data: arg,
|
|
624
|
+
method: serviceAndMethod
|
|
625
|
+
};
|
|
626
|
+
}
|
|
627
|
+
const baseRequest = (serviceRequest || methodRequest);
|
|
628
|
+
const promise = new Promise((resolve, reject) => {
|
|
629
|
+
baseRequest.sentCallback = (err) => {
|
|
630
|
+
delete baseRequest.sentCallback;
|
|
534
631
|
this._outboundSentMessageCount++;
|
|
535
632
|
if (err) {
|
|
536
633
|
reject(err);
|
|
@@ -540,94 +637,24 @@ export class SocketTransport {
|
|
|
540
637
|
};
|
|
541
638
|
});
|
|
542
639
|
this._outboundPreparedMessageCount++;
|
|
640
|
+
const request = Object.assign(baseRequest, { promise });
|
|
543
641
|
this.onTransmit(request);
|
|
544
|
-
return promise;
|
|
642
|
+
return request.promise;
|
|
545
643
|
}
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
let method;
|
|
550
|
-
let ackTimeoutMs;
|
|
551
|
-
if (typeof methodOptions === 'object') {
|
|
552
|
-
if (Array.isArray(methodOptions)) {
|
|
553
|
-
service = methodOptions[0];
|
|
554
|
-
serviceMethod = methodOptions[1];
|
|
555
|
-
ackTimeoutMs = methodOptions[2];
|
|
556
|
-
}
|
|
557
|
-
else {
|
|
558
|
-
if ('service' in methodOptions) {
|
|
559
|
-
service = methodOptions.service;
|
|
560
|
-
serviceMethod = methodOptions.method;
|
|
561
|
-
}
|
|
562
|
-
else {
|
|
563
|
-
method = methodOptions.method;
|
|
564
|
-
}
|
|
565
|
-
ackTimeoutMs = methodOptions.ackTimeoutMs;
|
|
566
|
-
}
|
|
644
|
+
triggerAuthenticationEvents(wasSigned, wasAuthenticated) {
|
|
645
|
+
if (!this._signedAuthToken) {
|
|
646
|
+
throw new AuthError('Signed auth token should be set to trigger authentication events');
|
|
567
647
|
}
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
cid: this._callIdGenerator(),
|
|
574
|
-
ackTimeoutMs: ackTimeoutMs ?? this.ackTimeoutMs,
|
|
575
|
-
callback: null,
|
|
576
|
-
promise: null
|
|
577
|
-
}, service ? {
|
|
578
|
-
service,
|
|
579
|
-
method: serviceMethod,
|
|
580
|
-
data: arg
|
|
581
|
-
} : {
|
|
582
|
-
method: method,
|
|
583
|
-
data: arg
|
|
584
|
-
});
|
|
585
|
-
let abort;
|
|
586
|
-
const promise = request.promise = new Promise((resolve, reject) => {
|
|
587
|
-
if (request.ackTimeoutMs) {
|
|
588
|
-
request.timeoutId = setTimeout(() => {
|
|
589
|
-
delete callbackMap[request.cid];
|
|
590
|
-
request.callback = null;
|
|
591
|
-
clearTimeout(request.timeoutId);
|
|
592
|
-
delete request.timeoutId;
|
|
593
|
-
reject(new TimeoutError(`Method \'${[service, request.method].filter(Boolean).join('.')}\' timed out.`));
|
|
594
|
-
}, request.ackTimeoutMs);
|
|
648
|
+
this._socket.emit('authStateChange', { authToken: this._authToken, isAuthenticated: true, signedAuthToken: this._signedAuthToken, wasAuthenticated });
|
|
649
|
+
this._socket.emit('authenticate', { authToken: this._authToken, signedAuthToken: this._signedAuthToken, wasSigned });
|
|
650
|
+
for (const plugin of this.plugins) {
|
|
651
|
+
if (plugin.onAuthenticated) {
|
|
652
|
+
plugin.onAuthenticated({ socket: this.socket, transport: this });
|
|
595
653
|
}
|
|
596
|
-
|
|
597
|
-
delete callbackMap[request.cid];
|
|
598
|
-
if (request.timeoutId) {
|
|
599
|
-
clearTimeout(request.timeoutId);
|
|
600
|
-
delete request.timeoutId;
|
|
601
|
-
}
|
|
602
|
-
if (request.callback) {
|
|
603
|
-
request.callback = null;
|
|
604
|
-
reject(new AbortError(`Method \'${[service, request.method].filter(Boolean).join('.')}\' was aborted.`));
|
|
605
|
-
}
|
|
606
|
-
};
|
|
607
|
-
request.callback = (err, result) => {
|
|
608
|
-
delete callbackMap[request.cid];
|
|
609
|
-
request.callback = null;
|
|
610
|
-
if (request.timeoutId) {
|
|
611
|
-
clearTimeout(request.timeoutId);
|
|
612
|
-
delete request.timeoutId;
|
|
613
|
-
}
|
|
614
|
-
if (err) {
|
|
615
|
-
reject(err);
|
|
616
|
-
return;
|
|
617
|
-
}
|
|
618
|
-
resolve(result);
|
|
619
|
-
};
|
|
620
|
-
request.sentCallback = () => {
|
|
621
|
-
delete request.sentCallback;
|
|
622
|
-
this._outboundSentMessageCount++;
|
|
623
|
-
};
|
|
624
|
-
});
|
|
625
|
-
this._outboundPreparedMessageCount++;
|
|
626
|
-
this.onInvoke(request);
|
|
627
|
-
return [promise, abort];
|
|
654
|
+
}
|
|
628
655
|
}
|
|
629
656
|
get url() {
|
|
630
|
-
return this._webSocket
|
|
657
|
+
return this._webSocket?.url || '';
|
|
631
658
|
}
|
|
632
659
|
get webSocket() {
|
|
633
660
|
return this._webSocket;
|
|
@@ -638,17 +665,13 @@ export class SocketTransport {
|
|
|
638
665
|
this._webSocket.onerror = null;
|
|
639
666
|
this._webSocket.onmessage = null;
|
|
640
667
|
this._webSocket.onopen = null;
|
|
641
|
-
delete this.onSocketClose;
|
|
642
|
-
delete this.onSocketError;
|
|
643
|
-
delete this.onSocketMessage;
|
|
644
|
-
delete this.onOpen;
|
|
645
668
|
}
|
|
646
669
|
this._webSocket = value;
|
|
647
|
-
if (
|
|
648
|
-
this._webSocket.onclose = this.onSocketClose
|
|
649
|
-
this._webSocket.onopen = this.onOpen
|
|
650
|
-
this._webSocket.onerror = this.onSocketError
|
|
651
|
-
this._webSocket.onmessage = this.onSocketMessage
|
|
670
|
+
if (this._webSocket) {
|
|
671
|
+
this._webSocket.onclose = this.onSocketClose.bind(this);
|
|
672
|
+
this._webSocket.onopen = this.onOpen.bind(this);
|
|
673
|
+
this._webSocket.onerror = this.onSocketError.bind(this);
|
|
674
|
+
this._webSocket.onmessage = this.onSocketMessage.bind(this);
|
|
652
675
|
}
|
|
653
676
|
}
|
|
654
677
|
}
|