@rc-ex/ws 1.2.0 → 1.2.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/lib/utils.js CHANGED
@@ -6,11 +6,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const ClosedException_1 = __importDefault(require("./exceptions/ClosedException"));
7
7
  const TimeoutException_1 = __importDefault(require("./exceptions/TimeoutException"));
8
8
  class Utils {
9
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
10
9
  static splitWsgData(wsgData) {
11
- if (wsgData.includes(',--Boundary')) {
12
- const index = wsgData.indexOf(',--Boundary');
13
- return [JSON.parse(wsgData.substring(1, index)), wsgData.substring(index + 1, wsgData.length - 1)];
10
+ if (wsgData.includes(",--Boundary")) {
11
+ const index = wsgData.indexOf(",--Boundary");
12
+ return [
13
+ JSON.parse(wsgData.substring(1, index)),
14
+ wsgData.substring(index + 1, wsgData.length - 1),
15
+ ];
14
16
  }
15
17
  return JSON.parse(wsgData);
16
18
  }
@@ -23,24 +25,23 @@ class Utils {
23
25
  ${JSON.stringify(JSON.parse(str), null, 2)}
24
26
  ******`);
25
27
  };
26
- ws.addEventListener('message', (mEvent) => {
28
+ ws.addEventListener("message", (mEvent) => {
27
29
  const event = mEvent;
28
30
  console.debug(`*** WebSocket incoming message: ***
29
31
  ${JSON.stringify(JSON.parse(event.data), null, 2)}
30
32
  ******`);
31
33
  });
32
- ws.addEventListener('open', (event) => {
33
- console.debug('WebSocket open event:', event);
34
+ ws.addEventListener("open", (event) => {
35
+ console.debug("WebSocket open event:", event);
34
36
  });
35
- ws.addEventListener('error', (event) => {
36
- console.debug('WebSocket error event:', event);
37
+ ws.addEventListener("error", (event) => {
38
+ console.debug("WebSocket error event:", event);
37
39
  });
38
- ws.addEventListener('close', (event) => {
39
- console.debug('WebSocket close event:', event);
40
+ ws.addEventListener("close", (event) => {
41
+ console.debug("WebSocket close event:", event);
40
42
  });
41
43
  }
42
44
  static waitForWebSocketMessage(ws, matchCondition, timeout = 60000) {
43
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
44
45
  return new Promise((resolve, reject) => {
45
46
  const checkHandle = setInterval(() => {
46
47
  if (ws.readyState === ws.CLOSED) {
@@ -49,8 +50,7 @@ ${JSON.stringify(JSON.parse(event.data), null, 2)}
49
50
  }
50
51
  }, 1000);
51
52
  const timeoutHandle = setTimeout(() => {
52
- // eslint-disable-next-line @typescript-eslint/no-use-before-define
53
- ws.removeEventListener('message', handler);
53
+ ws.removeEventListener("message", handler);
54
54
  clearInterval(checkHandle);
55
55
  reject(new TimeoutException_1.default());
56
56
  }, timeout);
@@ -58,13 +58,13 @@ ${JSON.stringify(JSON.parse(event.data), null, 2)}
58
58
  const event = mEvent;
59
59
  const [meta, body] = Utils.splitWsgData(event.data);
60
60
  if (matchCondition(meta)) {
61
- ws.removeEventListener('message', handler);
61
+ ws.removeEventListener("message", handler);
62
62
  clearInterval(checkHandle);
63
63
  clearTimeout(timeoutHandle);
64
64
  resolve([meta, body, event]);
65
65
  }
66
66
  };
67
- ws.addEventListener('message', handler);
67
+ ws.addEventListener("message", handler);
68
68
  });
69
69
  }
70
70
  }
package/lib/utils.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rc-ex/ws",
3
- "version": "1.2.0",
3
+ "version": "1.2.1",
4
4
  "description": "WebSocket extension for ringcentral-extensible project",
5
5
  "author": "Tyler Liu <tyler.liu@ringcentral.com>",
6
6
  "homepage": "https://github.com/ringcentral/ringcentral-extensible/tree/master/packages/extensions/ws",
@@ -18,7 +18,7 @@
18
18
  "access": "public"
19
19
  },
20
20
  "dependencies": {
21
- "@types/ws": "^8.5.13",
21
+ "@types/ws": "^8.5.14",
22
22
  "http-status-codes": "^2.3.0",
23
23
  "hyperid": "^3.3.0",
24
24
  "isomorphic-ws": "^5.0.0",
@@ -26,7 +26,7 @@
26
26
  "ws": "^8.18.0"
27
27
  },
28
28
  "devDependencies": {
29
- "@rc-ex/core": "^1.5.0"
29
+ "@rc-ex/core": "^1.5.1"
30
30
  },
31
- "gitHead": "03fab0f9fc3d924054df16abd6854a5063e19829"
31
+ "gitHead": "1a8a5becc832b92af73f1ad1f58b87f38fee3650"
32
32
  }
@@ -1,6 +1,6 @@
1
1
  class ClosedException extends Error {
2
2
  public constructor(message?: string) {
3
- super(message ?? 'WebSocket has been closed');
3
+ super(message ?? "WebSocket has been closed");
4
4
  }
5
5
  }
6
6
 
@@ -1,5 +1,5 @@
1
- import type { WsgError, WsgEvent, WsgMeta } from '../types';
2
- import Utils from '../utils';
1
+ import type { WsgError, WsgEvent, WsgMeta } from "../types";
2
+ import Utils from "../utils";
3
3
 
4
4
  class ConnectionException extends Error {
5
5
  public wsgEvent: WsgEvent;
@@ -1,6 +1,6 @@
1
1
  class TimeoutException extends Error {
2
2
  public constructor(message?: string) {
3
- super(message ?? 'Failed to receive expected WebSocket message in time.');
3
+ super(message ?? "Failed to receive expected WebSocket message in time.");
4
4
  }
5
5
  }
6
6
 
package/src/index.ts CHANGED
@@ -1,20 +1,30 @@
1
- /* eslint-disable no-console */
2
- import type RingCentral from '@rc-ex/core';
3
- import type { RestMethod, RestRequestConfig, RestResponse } from '@rc-ex/core/lib/types';
4
- import SdkExtension from '@rc-ex/core/lib/SdkExtension';
5
- import type { MessageEvent } from 'isomorphic-ws';
6
- import WS from 'isomorphic-ws';
7
- import hyperid from 'hyperid';
8
- import { EventEmitter } from 'events';
9
- import waitFor from 'wait-for-async';
10
- import RestException from '@rc-ex/core/lib/RestException';
11
- import type SubscriptionInfo from '@rc-ex/core/lib/definitions/SubscriptionInfo';
12
-
13
- import { request } from './rest';
14
- import type { WsToken, ConnectionDetails, WebSocketOptions, WsgEvent, Wsc, WebSocketExtensionInterface } from './types';
15
- import Subscription from './subscription';
16
- import ConnectionException from './exceptions/ConnectionException';
17
- import Utils from './utils';
1
+ import type RingCentral from "@rc-ex/core";
2
+ import type {
3
+ RestMethod,
4
+ RestRequestConfig,
5
+ RestResponse,
6
+ } from "@rc-ex/core/lib/types";
7
+ import SdkExtension from "@rc-ex/core/lib/SdkExtension";
8
+ import type { MessageEvent } from "isomorphic-ws";
9
+ import WS from "isomorphic-ws";
10
+ import hyperid from "hyperid";
11
+ import { EventEmitter } from "events";
12
+ import waitFor from "wait-for-async";
13
+ import RestException from "@rc-ex/core/lib/RestException";
14
+ import type SubscriptionInfo from "@rc-ex/core/lib/definitions/SubscriptionInfo";
15
+
16
+ import { request } from "./rest";
17
+ import type {
18
+ ConnectionDetails,
19
+ WebSocketExtensionInterface,
20
+ WebSocketOptions,
21
+ Wsc,
22
+ WsgEvent,
23
+ WsToken,
24
+ } from "./types";
25
+ import Subscription from "./subscription";
26
+ import ConnectionException from "./exceptions/ConnectionException";
27
+ import Utils from "./utils";
18
28
 
19
29
  const CONNECTING = 0;
20
30
  const OPEN = 1;
@@ -22,12 +32,12 @@ const OPEN = 1;
22
32
  const uuid = hyperid();
23
33
 
24
34
  export enum Events {
25
- autoRecoverSuccess = 'autoRecoverSuccess',
26
- autoRecoverFailed = 'autoRecoverFailed',
27
- autoRecoverError = 'autoRecoverError',
28
- newWebSocketObject = 'newWebSocketObject',
29
- newWsc = 'newWsc',
30
- connectionReady = 'connectionReady',
35
+ autoRecoverSuccess = "autoRecoverSuccess",
36
+ autoRecoverFailed = "autoRecoverFailed",
37
+ autoRecoverError = "autoRecoverError",
38
+ newWebSocketObject = "newWebSocketObject",
39
+ newWsc = "newWsc",
40
+ connectionReady = "connectionReady",
31
41
  }
32
42
 
33
43
  class WebSocketExtension extends SdkExtension {
@@ -94,16 +104,17 @@ class WebSocketExtension extends SdkExtension {
94
104
  content?: {},
95
105
  queryParams?: {},
96
106
  config?: RestRequestConfig,
97
- // eslint-disable-next-line max-params
98
107
  ): Promise<RestResponse<T>> => {
99
108
  if (!this.enabled || !this.options.restOverWebSocket) {
100
109
  return request(method, endpoint, content, queryParams, config);
101
110
  }
102
111
  if (
103
112
  // the following cannot be done with WebSocket
104
- config?.headers?.getContentType?.toString()?.includes('multipart/form-data') ||
105
- config?.responseType === 'arraybuffer' ||
106
- endpoint.startsWith('/restapi/oauth/') // token, revoke, wstoken
113
+ config?.headers?.getContentType?.toString()?.includes(
114
+ "multipart/form-data",
115
+ ) ||
116
+ config?.responseType === "arraybuffer" ||
117
+ endpoint.startsWith("/restapi/oauth/") // token, revoke, wstoken
107
118
  ) {
108
119
  return request(method, endpoint, content, queryParams, config);
109
120
  }
@@ -134,7 +145,7 @@ class WebSocketExtension extends SdkExtension {
134
145
  throw e; // such as InsufficientPermissions
135
146
  }
136
147
  if (this.options.debugMode) {
137
- console.debug('Initial connect failed:', e);
148
+ console.debug("Initial connect failed:", e);
138
149
  }
139
150
  }
140
151
  let retriesAttempted = 0;
@@ -156,10 +167,12 @@ class WebSocketExtension extends SdkExtension {
156
167
  await this.recover();
157
168
  retriesAttempted = 0;
158
169
  if (this.options.debugMode) {
159
- console.debug(`Auto recover done, recoveryState: ${this.connectionDetails.recoveryState}`);
170
+ console.debug(
171
+ `Auto recover done, recoveryState: ${this.connectionDetails.recoveryState}`,
172
+ );
160
173
  }
161
174
  this.eventEmitter.emit(
162
- this.connectionDetails.recoveryState === 'Successful'
175
+ this.connectionDetails.recoveryState === "Successful"
163
176
  ? Events.autoRecoverSuccess
164
177
  : Events.autoRecoverFailed,
165
178
  this.ws,
@@ -170,25 +183,31 @@ class WebSocketExtension extends SdkExtension {
170
183
  }
171
184
  retriesAttempted += 1;
172
185
  if (this.options.debugMode) {
173
- console.debug('Auto recover error:', e);
186
+ console.debug("Auto recover error:", e);
174
187
  }
175
188
  this.eventEmitter.emit(Events.autoRecoverError, e);
176
189
  }
177
- this.intervalHandle = setInterval(check, this.options.autoRecover!.checkInterval!(retriesAttempted));
190
+ this.intervalHandle = setInterval(
191
+ check,
192
+ this.options.autoRecover!.checkInterval!(retriesAttempted),
193
+ );
178
194
  }
179
195
  checking = false;
180
196
  };
181
- this.intervalHandle = setInterval(check, this.options.autoRecover!.checkInterval!(retriesAttempted));
197
+ this.intervalHandle = setInterval(
198
+ check,
199
+ this.options.autoRecover!.checkInterval!(retriesAttempted),
200
+ );
182
201
 
183
202
  // browser only code start
184
- if (typeof window !== 'undefined' && window.addEventListener) {
185
- window.addEventListener('offline', () => {
203
+ if (typeof window !== "undefined" && window.addEventListener) {
204
+ window.addEventListener("offline", () => {
186
205
  if (this.pingServerHandle) {
187
206
  clearTimeout(this.pingServerHandle);
188
207
  }
189
208
  this.ws?.close();
190
209
  });
191
- window.addEventListener('online', () => {
210
+ window.addEventListener("online", () => {
192
211
  check();
193
212
  });
194
213
  }
@@ -221,15 +240,16 @@ class WebSocketExtension extends SdkExtension {
221
240
  }
222
241
  if (
223
242
  this.connectionDetails !== undefined &&
224
- Date.now() - this.recoverTimestamp > this.connectionDetails.recoveryTimeout * 1000
243
+ Date.now() - this.recoverTimestamp >
244
+ this.connectionDetails.recoveryTimeout * 1000
225
245
  ) {
226
246
  if (this.options.debugMode) {
227
- console.debug('connect to WSG but do not recover');
247
+ console.debug("connect to WSG but do not recover");
228
248
  }
229
249
  await this.connect(false); // connect to WSG but do not recover
230
250
  } else {
231
251
  if (this.options.debugMode) {
232
- console.debug('connect to WSG and recover');
252
+ console.debug("connect to WSG and recover");
233
253
  }
234
254
  await this.connect(true); // connect to WSG and recover
235
255
  }
@@ -248,12 +268,11 @@ class WebSocketExtension extends SdkExtension {
248
268
  await this.ws.send(
249
269
  JSON.stringify([
250
270
  {
251
- type: 'Heartbeat',
271
+ type: "Heartbeat",
252
272
  messageId: uuid(),
253
273
  },
254
274
  ]),
255
275
  );
256
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
257
276
  } catch (e) {
258
277
  this.ws.close(); // Explicitly mark WS as closed
259
278
  }
@@ -274,12 +293,14 @@ class WebSocketExtension extends SdkExtension {
274
293
 
275
294
  public async _connect(recoverSession = false) {
276
295
  if (!this.wsToken || Date.now() > this.wsTokenExpiresAt) {
277
- const r = await this.rc.post('/restapi/oauth/wstoken');
296
+ const r = await this.rc.post("/restapi/oauth/wstoken");
278
297
  this.wsToken = r.data as WsToken;
279
298
  // `expires_in` default value is 600 seconds. That's why we `* 0.8`
280
299
  this.wsTokenExpiresAt = Date.now() + this.wsToken.expires_in * 0.8 * 1000;
281
300
  }
282
- let wsUri = `${this.wsToken!.uri}?access_token=${this.wsToken!.ws_access_token}`;
301
+ let wsUri = `${this.wsToken!.uri}?access_token=${
302
+ this.wsToken!.ws_access_token
303
+ }`;
283
304
  if (recoverSession && this.wsc) {
284
305
  wsUri += `&wsc=${this.wsc.token}`;
285
306
  }
@@ -299,11 +320,14 @@ class WebSocketExtension extends SdkExtension {
299
320
  };
300
321
 
301
322
  if (this.options.autoRecover?.enabled) {
302
- this.ws.addEventListener('message', () => {
323
+ this.ws.addEventListener("message", () => {
303
324
  if (this.pingServerHandle) {
304
325
  clearTimeout(this.pingServerHandle);
305
326
  }
306
- this.pingServerHandle = setTimeout(() => this.pingServer(), this.options.autoRecover!.pingServerInterval);
327
+ this.pingServerHandle = setTimeout(
328
+ () => this.pingServer(),
329
+ this.options.autoRecover!.pingServerInterval,
330
+ );
307
331
  });
308
332
  }
309
333
 
@@ -313,13 +337,13 @@ class WebSocketExtension extends SdkExtension {
313
337
  }
314
338
 
315
339
  // listen for new wsc data
316
- this.ws.addEventListener('message', (mEvent: MessageEvent) => {
340
+ this.ws.addEventListener("message", (mEvent: MessageEvent) => {
317
341
  const event = mEvent as WsgEvent;
318
342
  const [meta, body] = Utils.splitWsgData(event.data);
319
343
  if (
320
344
  meta.wsc &&
321
345
  (!this.wsc ||
322
- (meta.type === 'ConnectionDetails' && body.recoveryState) ||
346
+ (meta.type === "ConnectionDetails" && body.recoveryState) ||
323
347
  this.wsc.sequence < meta.wsc.sequence)
324
348
  ) {
325
349
  this.wsc = meta.wsc;
@@ -330,9 +354,9 @@ class WebSocketExtension extends SdkExtension {
330
354
  // get initial ConnectionDetails data
331
355
  const [meta, body, event] = await Utils.waitForWebSocketMessage(
332
356
  this.ws,
333
- (meta) => meta.type === 'ConnectionDetails' || meta.type === 'Error',
357
+ (meta) => meta.type === "ConnectionDetails" || meta.type === "Error",
334
358
  );
335
- if (meta.type === 'Error') {
359
+ if (meta.type === "Error") {
336
360
  throw new ConnectionException(event);
337
361
  }
338
362
  this.connectionDetails = body;
@@ -344,7 +368,9 @@ class WebSocketExtension extends SdkExtension {
344
368
  if (this.subscription && this.subscription.enabled) {
345
369
  // because we have a new ws object
346
370
  this.subscription.setupWsEventListener();
347
- if (!recoverSession || this.connectionDetails.recoveryState === 'Failed') {
371
+ if (
372
+ !recoverSession || this.connectionDetails.recoveryState === "Failed"
373
+ ) {
348
374
  // create new subscription if don't recover existing one
349
375
  await this.subscription.subscribe();
350
376
  }
@@ -373,7 +399,11 @@ class WebSocketExtension extends SdkExtension {
373
399
  callback: (event: {}) => void,
374
400
  cache: SubscriptionInfo | undefined | null = undefined,
375
401
  ) {
376
- const subscription = new Subscription(this as WebSocketExtensionInterface, eventFilters, callback);
402
+ const subscription = new Subscription(
403
+ this as WebSocketExtensionInterface,
404
+ eventFilters,
405
+ callback,
406
+ );
377
407
  if (cache === undefined || cache === null) {
378
408
  await subscription.subscribe();
379
409
  } else {
package/src/rest.ts CHANGED
@@ -1,16 +1,19 @@
1
- import type { RestMethod, RestRequestConfig, RestResponse } from '@rc-ex/core/lib/types';
2
- import RestException from '@rc-ex/core/lib/RestException';
3
- import hyperid from 'hyperid';
4
- import { getReasonPhrase } from 'http-status-codes';
1
+ import type {
2
+ RestMethod,
3
+ RestRequestConfig,
4
+ RestResponse,
5
+ } from "@rc-ex/core/lib/types";
6
+ import RestException from "@rc-ex/core/lib/RestException";
7
+ import hyperid from "hyperid";
8
+ import { getReasonPhrase } from "http-status-codes";
5
9
 
6
- import Utils from './utils';
7
- import type { WebSocketExtensionInterface } from './types';
10
+ import Utils from "./utils";
11
+ import type { WebSocketExtensionInterface } from "./types";
8
12
 
9
- const version = '0.16';
13
+ const version = "0.16";
10
14
 
11
15
  const uuid = hyperid();
12
16
 
13
- // eslint-disable-next-line max-params
14
17
  export async function request<T>(
15
18
  this: WebSocketExtensionInterface,
16
19
  method: RestMethod,
@@ -29,12 +32,14 @@ export async function request<T>(
29
32
  };
30
33
  newConfig.headers = {
31
34
  ...newConfig.headers,
32
- 'X-User-Agent': `${this.rc.rest!.appName}/${this.rc.rest!.appVersion} ringcentral-extensible/ws/${version}`,
35
+ "X-User-Agent": `${this.rc.rest!.appName}/${
36
+ this.rc.rest!.appVersion
37
+ } ringcentral-extensible/ws/${version}`,
33
38
  } as any;
34
39
  const messageId = uuid();
35
40
  const requestBody = [
36
41
  {
37
- type: 'ClientRequest',
42
+ type: "ClientRequest",
38
43
  messageId,
39
44
  method: newConfig.method,
40
45
  path: newConfig.url,
@@ -46,7 +51,10 @@ export async function request<T>(
46
51
  requestBody.push(newConfig.data);
47
52
  }
48
53
  await this.ws.send(JSON.stringify(requestBody));
49
- const [meta, body] = await Utils.waitForWebSocketMessage(this.ws, (_meta) => _meta.messageId === messageId);
54
+ const [meta, body] = await Utils.waitForWebSocketMessage(
55
+ this.ws,
56
+ (_meta) => _meta.messageId === messageId,
57
+ );
50
58
  const response: RestResponse = {
51
59
  data: body as T,
52
60
  status: meta.status,
@@ -54,7 +62,9 @@ export async function request<T>(
54
62
  headers: meta.headers,
55
63
  config: newConfig as any,
56
64
  };
57
- if (meta.type === 'ClientRequest' && meta.status >= 200 && meta.status < 300) {
65
+ if (
66
+ meta.type === "ClientRequest" && meta.status >= 200 && meta.status < 300
67
+ ) {
58
68
  return response;
59
69
  }
60
70
  throw new RestException(response);
@@ -1,11 +1,10 @@
1
- /* eslint-disable no-console */
2
- import type CreateSubscriptionRequest from '@rc-ex/core/lib/definitions/CreateSubscriptionRequest';
3
- import type SubscriptionInfo from '@rc-ex/core/lib/definitions/SubscriptionInfo';
4
- import type { RestResponse } from '@rc-ex/core/lib/types';
5
- import type { MessageEvent } from 'ws';
1
+ import type CreateSubscriptionRequest from "@rc-ex/core/lib/definitions/CreateSubscriptionRequest";
2
+ import type SubscriptionInfo from "@rc-ex/core/lib/definitions/SubscriptionInfo";
3
+ import type { RestResponse } from "@rc-ex/core/lib/types";
4
+ import type { MessageEvent } from "ws";
6
5
 
7
- import type { WsgEvent, WsgMeta, WebSocketExtensionInterface } from './types';
8
- import Utils from './utils';
6
+ import type { WebSocketExtensionInterface, WsgEvent, WsgMeta } from "./types";
7
+ import Utils from "./utils";
9
8
 
10
9
  class Subscription {
11
10
  public subscriptionInfo?: SubscriptionInfo;
@@ -20,13 +19,21 @@ class Subscription {
20
19
 
21
20
  public enabled = true;
22
21
 
23
- public constructor(wse: WebSocketExtensionInterface, eventFilters: string[], callback: (event: {}) => void) {
22
+ public constructor(
23
+ wse: WebSocketExtensionInterface,
24
+ eventFilters: string[],
25
+ callback: (event: {}) => void,
26
+ ) {
24
27
  this.wse = wse;
25
28
  this.eventFilters = eventFilters;
26
29
  this.eventListener = (mEvent: MessageEvent) => {
27
30
  const event = mEvent as WsgEvent;
28
- const [meta, body]: [WsgMeta, { subscriptionId: string }] = Utils.splitWsgData(event.data);
29
- if (this.enabled && meta.type === 'ServerNotification' && body.subscriptionId === this.subscriptionInfo!.id) {
31
+ const [meta, body]: [WsgMeta, { subscriptionId: string }] = Utils
32
+ .splitWsgData(event.data);
33
+ if (
34
+ this.enabled && meta.type === "ServerNotification" &&
35
+ body.subscriptionId === this.subscriptionInfo!.id
36
+ ) {
30
37
  callback(body);
31
38
  }
32
39
  };
@@ -34,19 +41,23 @@ class Subscription {
34
41
  }
35
42
 
36
43
  public setupWsEventListener() {
37
- this.wse.ws.addEventListener('message', this.eventListener);
44
+ this.wse.ws.addEventListener("message", this.eventListener);
38
45
  }
39
46
 
40
47
  public get requestBody(): CreateSubscriptionRequest {
41
48
  return {
42
- deliveryMode: { transportType: 'WebSocket' as any }, // because WebSocket is not in spec
49
+ deliveryMode: { transportType: "WebSocket" as any }, // because WebSocket is not in spec
43
50
  eventFilters: this.eventFilters,
44
51
  };
45
52
  }
46
53
 
47
54
  public async subscribe() {
48
55
  this.subscriptionInfo = (
49
- await this.wse.request<SubscriptionInfo>('POST', '/restapi/v1.0/subscription', this.requestBody)
56
+ await this.wse.request<SubscriptionInfo>(
57
+ "POST",
58
+ "/restapi/v1.0/subscription",
59
+ this.requestBody,
60
+ )
50
61
  ).data;
51
62
  }
52
63
 
@@ -57,7 +68,7 @@ class Subscription {
57
68
  try {
58
69
  this.subscriptionInfo = (
59
70
  await this.wse.request<SubscriptionInfo>(
60
- 'PUT',
71
+ "PUT",
61
72
  `/restapi/v1.0/subscription/${this.subscriptionInfo!.id}`,
62
73
  this.requestBody,
63
74
  )
@@ -76,18 +87,25 @@ class Subscription {
76
87
  return;
77
88
  }
78
89
  try {
79
- await this.wse.request<SubscriptionInfo>('DELETE', `/restapi/v1.0/subscription/${this.subscriptionInfo!.id}`);
90
+ await this.wse.request<SubscriptionInfo>(
91
+ "DELETE",
92
+ `/restapi/v1.0/subscription/${this.subscriptionInfo!.id}`,
93
+ );
80
94
  } catch (e) {
81
95
  const re = e as { response: RestResponse };
82
96
  if (re.response && re.response.status === 404) {
83
97
  // ignore
84
98
  if (this.wse.options.debugMode) {
85
- console.debug(`Subscription ${this.subscriptionInfo!.id} doesn't exist on server side`);
99
+ console.debug(
100
+ `Subscription ${
101
+ this.subscriptionInfo!.id
102
+ } doesn't exist on server side`,
103
+ );
86
104
  }
87
105
  } else if (re.response && re.response.status === 401) {
88
106
  // ignore
89
107
  if (this.wse.options.debugMode) {
90
- console.debug('Token invalid when trying to revoke subscription');
108
+ console.debug("Token invalid when trying to revoke subscription");
91
109
  }
92
110
  } else {
93
111
  throw e;
@@ -104,7 +122,7 @@ class Subscription {
104
122
  this.enabled = false;
105
123
  this.subscriptionInfo = undefined;
106
124
  if (this.wse.ws) {
107
- this.wse.ws.removeEventListener('message', this.eventListener);
125
+ this.wse.ws.removeEventListener("message", this.eventListener);
108
126
  }
109
127
  this.wse.subscription = undefined;
110
128
  }
package/src/types.ts CHANGED
@@ -1,6 +1,10 @@
1
- import type RingCentral from '@rc-ex/core';
2
- import type { RestMethod, RestRequestConfig, RestResponse } from '@rc-ex/core/lib/types';
3
- import type WS from 'isomorphic-ws';
1
+ import type RingCentral from "@rc-ex/core";
2
+ import type {
3
+ RestMethod,
4
+ RestRequestConfig,
5
+ RestResponse,
6
+ } from "@rc-ex/core/lib/types";
7
+ import type WS from "isomorphic-ws";
4
8
 
5
9
  export interface WsToken {
6
10
  uri: string;
@@ -30,7 +34,12 @@ export interface Wsc {
30
34
  }
31
35
 
32
36
  export interface WsgMeta {
33
- type: 'ClientRequest' | 'ServerNotification' | 'Error' | 'ConnectionDetails' | 'Heartbeat';
37
+ type:
38
+ | "ClientRequest"
39
+ | "ServerNotification"
40
+ | "Error"
41
+ | "ConnectionDetails"
42
+ | "Heartbeat";
34
43
  messageId: string;
35
44
  status: number;
36
45
  headers: {
@@ -52,7 +61,7 @@ export interface ConnectionDetails {
52
61
  idleTimeout: number;
53
62
  absoluteTimeout: number;
54
63
  maxActiveRequests: number;
55
- recoveryState?: 'Successful' | 'Failed';
64
+ recoveryState?: "Successful" | "Failed";
56
65
  recoveryErrorCode?: string;
57
66
  }
58
67