@socket-mesh/core 1.0.3 → 2.0.0

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