@rc-ex/ws 1.2.2 → 1.3.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.
Files changed (80) hide show
  1. package/lib/esm/exceptions/ClosedException.js +7 -0
  2. package/lib/esm/exceptions/ClosedException.js.map +1 -0
  3. package/{src → lib/esm}/exceptions/ConnectionException.d.ts +1 -1
  4. package/lib/esm/exceptions/ConnectionException.js +13 -0
  5. package/lib/esm/exceptions/ConnectionException.js.map +1 -0
  6. package/lib/esm/exceptions/TimeoutException.js +7 -0
  7. package/lib/esm/exceptions/TimeoutException.js.map +1 -0
  8. package/{src → lib/esm}/index.d.ts +5 -5
  9. package/lib/{index.js → esm/index.js} +62 -63
  10. package/lib/esm/index.js.map +1 -0
  11. package/{src → lib/esm}/rest.d.ts +2 -2
  12. package/lib/{rest.js → esm/rest.js} +10 -17
  13. package/lib/esm/rest.js.map +1 -0
  14. package/{src → lib/esm}/subscription.d.ts +3 -3
  15. package/{src → lib/esm}/subscription.js +9 -9
  16. package/lib/esm/subscription.js.map +1 -0
  17. package/{src → lib/esm}/types.d.ts +1 -1
  18. package/lib/esm/types.js +2 -0
  19. package/lib/esm/types.js.map +1 -0
  20. package/{src → lib/esm}/utils.d.ts +1 -1
  21. package/lib/{utils.js → esm/utils.js} +5 -10
  22. package/lib/esm/utils.js.map +1 -0
  23. package/lib/exceptions/ClosedException.cjs +26 -0
  24. package/lib/exceptions/ClosedException.js.map +1 -1
  25. package/lib/exceptions/ConnectionException.cjs +35 -0
  26. package/lib/exceptions/ConnectionException.d.ts +1 -1
  27. package/lib/exceptions/ConnectionException.js.map +1 -1
  28. package/lib/exceptions/TimeoutException.cjs +26 -0
  29. package/lib/exceptions/TimeoutException.js.map +1 -1
  30. package/lib/index.cjs +515 -0
  31. package/lib/index.d.ts +5 -5
  32. package/lib/index.js.map +1 -1
  33. package/lib/rest.cjs +104 -0
  34. package/lib/rest.d.ts +2 -2
  35. package/lib/rest.js.map +1 -1
  36. package/lib/subscription.cjs +178 -0
  37. package/lib/subscription.d.ts +3 -3
  38. package/lib/subscription.js.map +1 -1
  39. package/lib/types.d.ts +1 -1
  40. package/lib/types.js.map +1 -1
  41. package/lib/utils.cjs +116 -0
  42. package/lib/utils.d.ts +1 -1
  43. package/lib/utils.js.map +1 -1
  44. package/package.json +10 -5
  45. package/src/exceptions/ConnectionException.ts +2 -2
  46. package/src/index.ts +15 -12
  47. package/src/rest.ts +4 -4
  48. package/src/subscription.ts +9 -5
  49. package/src/types.ts +1 -1
  50. package/src/utils.ts +3 -3
  51. package/lib/exceptions/ClosedException.js +0 -9
  52. package/lib/exceptions/ClosedException.ts +0 -7
  53. package/lib/exceptions/ConnectionException.js +0 -16
  54. package/lib/exceptions/ConnectionException.ts +0 -17
  55. package/lib/exceptions/TimeoutException.js +0 -9
  56. package/lib/exceptions/TimeoutException.ts +0 -7
  57. package/lib/index.ts +0 -418
  58. package/lib/rest.ts +0 -71
  59. package/lib/subscription.js +0 -91
  60. package/lib/subscription.ts +0 -131
  61. package/lib/types.ts +0 -85
  62. package/lib/utils.ts +0 -82
  63. package/src/exceptions/ClosedException.js +0 -9
  64. package/src/exceptions/ClosedException.js.map +0 -1
  65. package/src/exceptions/ConnectionException.js +0 -16
  66. package/src/exceptions/ConnectionException.js.map +0 -1
  67. package/src/exceptions/TimeoutException.js +0 -9
  68. package/src/exceptions/TimeoutException.js.map +0 -1
  69. package/src/index.js +0 -329
  70. package/src/index.js.map +0 -1
  71. package/src/rest.js +0 -55
  72. package/src/rest.js.map +0 -1
  73. package/src/subscription.js.map +0 -1
  74. package/src/types.js +0 -3
  75. package/src/types.js.map +0 -1
  76. package/src/utils.js +0 -72
  77. package/src/utils.js.map +0 -1
  78. /package/{src → lib/esm}/exceptions/ClosedException.d.ts +0 -0
  79. /package/{src → lib/esm}/exceptions/TimeoutException.d.ts +0 -0
  80. /package/lib/{types.js → types.cjs} +0 -0
package/src/utils.ts CHANGED
@@ -1,9 +1,9 @@
1
1
  import type { MessageEvent } from "isomorphic-ws";
2
2
  import type WS from "isomorphic-ws";
3
3
 
4
- import type { WsgEvent, WsgMeta } from "./types";
5
- import ClosedException from "./exceptions/ClosedException";
6
- import TimeoutException from "./exceptions/TimeoutException";
4
+ import type { WsgEvent, WsgMeta } from "./types.js";
5
+ import ClosedException from "./exceptions/ClosedException.js";
6
+ import TimeoutException from "./exceptions/TimeoutException.js";
7
7
 
8
8
  class Utils {
9
9
  public static splitWsgData(wsgData: string): [WsgMeta, any] {
@@ -1,9 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- class ClosedException extends Error {
4
- constructor(message) {
5
- super(message !== null && message !== void 0 ? message : "WebSocket has been closed");
6
- }
7
- }
8
- exports.default = ClosedException;
9
- //# sourceMappingURL=ClosedException.js.map
@@ -1,7 +0,0 @@
1
- class ClosedException extends Error {
2
- public constructor(message?: string) {
3
- super(message ?? "WebSocket has been closed");
4
- }
5
- }
6
-
7
- export default ClosedException;
@@ -1,16 +0,0 @@
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
- const utils_1 = __importDefault(require("../utils"));
7
- class ConnectionException extends Error {
8
- constructor(wsgEvent) {
9
- const [, wsgError] = utils_1.default.splitWsgData(wsgEvent.data);
10
- super(JSON.stringify(wsgError, null, 2));
11
- this.wsgEvent = wsgEvent;
12
- this.wsgError = wsgError;
13
- }
14
- }
15
- exports.default = ConnectionException;
16
- //# sourceMappingURL=ConnectionException.js.map
@@ -1,17 +0,0 @@
1
- import type { WsgError, WsgEvent, WsgMeta } from "../types";
2
- import Utils from "../utils";
3
-
4
- class ConnectionException extends Error {
5
- public wsgEvent: WsgEvent;
6
-
7
- public wsgError: WsgError;
8
-
9
- public constructor(wsgEvent: WsgEvent) {
10
- const [, wsgError]: [WsgMeta, WsgError] = Utils.splitWsgData(wsgEvent.data);
11
- super(JSON.stringify(wsgError, null, 2));
12
- this.wsgEvent = wsgEvent;
13
- this.wsgError = wsgError;
14
- }
15
- }
16
-
17
- export default ConnectionException;
@@ -1,9 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- class TimeoutException extends Error {
4
- constructor(message) {
5
- super(message !== null && message !== void 0 ? message : "Failed to receive expected WebSocket message in time.");
6
- }
7
- }
8
- exports.default = TimeoutException;
9
- //# sourceMappingURL=TimeoutException.js.map
@@ -1,7 +0,0 @@
1
- class TimeoutException extends Error {
2
- public constructor(message?: string) {
3
- super(message ?? "Failed to receive expected WebSocket message in time.");
4
- }
5
- }
6
-
7
- export default TimeoutException;
package/lib/index.ts DELETED
@@ -1,418 +0,0 @@
1
- import type RingCentral from "@rc-ex/core";
2
- import type {
3
- RestMethod,
4
- RestRequestConfig,
5
- RestResponse,
6
- } from "@rc-ex/core/src/types";
7
- import SdkExtension from "@rc-ex/core/src/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/src/RestException";
14
- import type SubscriptionInfo from "@rc-ex/core/src/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";
28
-
29
- const CONNECTING = 0;
30
- const OPEN = 1;
31
-
32
- const uuid = hyperid();
33
-
34
- export enum Events {
35
- autoRecoverSuccess = "autoRecoverSuccess",
36
- autoRecoverFailed = "autoRecoverFailed",
37
- autoRecoverError = "autoRecoverError",
38
- newWebSocketObject = "newWebSocketObject",
39
- newWsc = "newWsc",
40
- connectionReady = "connectionReady",
41
- }
42
-
43
- class WebSocketExtension extends SdkExtension {
44
- public eventEmitter = new EventEmitter();
45
-
46
- public options: WebSocketOptions;
47
-
48
- public rc!: RingCentral;
49
-
50
- public wsToken?: WsToken;
51
-
52
- public wsTokenExpiresAt = 0;
53
-
54
- public ws!: WS;
55
-
56
- public connectionDetails!: ConnectionDetails;
57
-
58
- public wsc?: Wsc;
59
-
60
- public subscription?: Subscription;
61
-
62
- // for auto recover
63
- public intervalHandle?: NodeJS.Timeout;
64
-
65
- public recoverTimestamp?: number;
66
-
67
- public pingServerHandle?: NodeJS.Timeout;
68
-
69
- public _recoverPromise?: Promise<void>;
70
-
71
- public _connectPromise?: Promise<void>;
72
-
73
- public request = request; // request method was moved to another file to keep this file short
74
-
75
- public constructor(options: WebSocketOptions = {}) {
76
- super();
77
- this.options = options;
78
- this.options.restOverWebSocket ??= false;
79
- this.options.debugMode ??= false;
80
- this.options.autoRecover ??= {
81
- enabled: true,
82
- };
83
- this.options.autoRecover.checkInterval ??= (retriesAttempted) => {
84
- const interval = 2000 + 2000 * retriesAttempted;
85
- return Math.min(8000, interval);
86
- };
87
- this.options.autoRecover.pingServerInterval ??= 60000;
88
- }
89
-
90
- public disable() {
91
- super.disable();
92
- if (this.subscription) {
93
- this.subscription.enabled = false;
94
- }
95
- }
96
-
97
- public async install(rc: RingCentral) {
98
- this.rc = rc;
99
- if (this.options.restOverWebSocket) {
100
- const request = rc.request.bind(rc);
101
- rc.request = async <T>(
102
- method: RestMethod,
103
- endpoint: string,
104
- content?: {},
105
- queryParams?: {},
106
- config?: RestRequestConfig,
107
- ): Promise<RestResponse<T>> => {
108
- if (!this.enabled || !this.options.restOverWebSocket) {
109
- return request(method, endpoint, content, queryParams, config);
110
- }
111
- if (
112
- // the following cannot be done with WebSocket
113
- config?.headers?.getContentType?.toString()?.includes(
114
- "multipart/form-data",
115
- ) ||
116
- config?.responseType === "arraybuffer" ||
117
- endpoint.startsWith("/restapi/oauth/") // token, revoke, wstoken
118
- ) {
119
- return request(method, endpoint, content, queryParams, config);
120
- }
121
- return this.request<T>(method, endpoint, content, queryParams, config);
122
- };
123
- }
124
-
125
- // should recover if this.options.wscToken
126
- let connectMethod = this.connect.bind(this);
127
- if (this.options.wscToken) {
128
- this.wsc = {
129
- token: this.options.wscToken,
130
- sequence: 0,
131
- };
132
- connectMethod = this.recover.bind(this);
133
- }
134
-
135
- if (!this.options.autoRecover!.enabled) {
136
- await connectMethod();
137
- return;
138
- }
139
-
140
- // code after is for auto recover
141
- try {
142
- await connectMethod();
143
- } catch (e) {
144
- if (e instanceof RestException) {
145
- throw e; // such as InsufficientPermissions
146
- }
147
- if (this.options.debugMode) {
148
- console.debug("Initial connect failed:", e);
149
- }
150
- }
151
- let retriesAttempted = 0;
152
- let checking = false;
153
- const check = async () => {
154
- if (!this.enabled) {
155
- return;
156
- }
157
- if (this.options.autoRecover?.enabled !== true) {
158
- return;
159
- }
160
- if (checking) {
161
- return;
162
- }
163
- checking = true;
164
- if (this.ws?.readyState !== OPEN && this.ws?.readyState !== CONNECTING) {
165
- clearInterval(this.intervalHandle!);
166
- try {
167
- await this.recover();
168
- retriesAttempted = 0;
169
- if (this.options.debugMode) {
170
- console.debug(
171
- `Auto recover done, recoveryState: ${this.connectionDetails.recoveryState}`,
172
- );
173
- }
174
- this.eventEmitter.emit(
175
- this.connectionDetails.recoveryState === "Successful"
176
- ? Events.autoRecoverSuccess
177
- : Events.autoRecoverFailed,
178
- this.ws,
179
- );
180
- } catch (e) {
181
- if (e instanceof RestException) {
182
- throw e; // such as InsufficientPermissions
183
- }
184
- retriesAttempted += 1;
185
- if (this.options.debugMode) {
186
- console.debug("Auto recover error:", e);
187
- }
188
- this.eventEmitter.emit(Events.autoRecoverError, e);
189
- }
190
- this.intervalHandle = setInterval(
191
- check,
192
- this.options.autoRecover!.checkInterval!(retriesAttempted),
193
- );
194
- }
195
- checking = false;
196
- };
197
- this.intervalHandle = setInterval(
198
- check,
199
- this.options.autoRecover!.checkInterval!(retriesAttempted),
200
- );
201
-
202
- // browser only code start
203
- if (typeof window !== "undefined" && window.addEventListener) {
204
- window.addEventListener("offline", () => {
205
- if (this.pingServerHandle) {
206
- clearTimeout(this.pingServerHandle);
207
- }
208
- this.ws?.close();
209
- });
210
- window.addEventListener("online", () => {
211
- check();
212
- });
213
- }
214
- // browser only code end
215
- }
216
-
217
- public async recover() {
218
- if (this._recoverPromise) {
219
- return this._recoverPromise;
220
- }
221
- this._recoverPromise = this._recover();
222
- try {
223
- await this._recoverPromise;
224
- } finally {
225
- this._recoverPromise = undefined;
226
- }
227
- return undefined;
228
- }
229
-
230
- public async _recover() {
231
- if (this.ws?.readyState === OPEN || this.ws?.readyState === CONNECTING) {
232
- return;
233
- }
234
- if (!this.wsc || !this.wsc.token) {
235
- await this.connect(false); // connect to WSG but do not recover
236
- return;
237
- }
238
- if (this.recoverTimestamp === undefined) {
239
- this.recoverTimestamp = Date.now();
240
- }
241
- if (
242
- this.connectionDetails !== undefined &&
243
- Date.now() - this.recoverTimestamp >
244
- this.connectionDetails.recoveryTimeout * 1000
245
- ) {
246
- if (this.options.debugMode) {
247
- console.debug("connect to WSG but do not recover");
248
- }
249
- await this.connect(false); // connect to WSG but do not recover
250
- } else {
251
- if (this.options.debugMode) {
252
- console.debug("connect to WSG and recover");
253
- }
254
- await this.connect(true); // connect to WSG and recover
255
- }
256
- this.recoverTimestamp = undefined;
257
- this.enable();
258
- }
259
-
260
- public async pingServer() {
261
- if (this.options.autoRecover?.enabled !== true) {
262
- return;
263
- }
264
- if (this.ws?.readyState !== OPEN) {
265
- return;
266
- }
267
- try {
268
- await this.ws.send(
269
- JSON.stringify([
270
- {
271
- type: "Heartbeat",
272
- messageId: uuid(),
273
- },
274
- ]),
275
- );
276
- } catch (e) {
277
- this.ws.close(); // Explicitly mark WS as closed
278
- }
279
- }
280
-
281
- public async connect(recoverSession?: boolean) {
282
- if (this._connectPromise) {
283
- return this._connectPromise;
284
- }
285
- this._connectPromise = this._connect(recoverSession);
286
- try {
287
- await this._connectPromise;
288
- } finally {
289
- this._connectPromise = undefined;
290
- }
291
- return undefined;
292
- }
293
-
294
- public async _connect(recoverSession = false) {
295
- if (!this.wsToken || Date.now() > this.wsTokenExpiresAt) {
296
- const r = await this.rc.post("/restapi/oauth/wstoken");
297
- this.wsToken = r.data as WsToken;
298
- // `expires_in` default value is 600 seconds. That's why we `* 0.8`
299
- this.wsTokenExpiresAt = Date.now() + this.wsToken.expires_in * 0.8 * 1000;
300
- }
301
- let wsUri = `${this.wsToken!.uri}?access_token=${
302
- this.wsToken!.ws_access_token
303
- }`;
304
- if (recoverSession && this.wsc) {
305
- wsUri += `&wsc=${this.wsc.token}`;
306
- }
307
- this.ws = new WS(wsUri);
308
- this.eventEmitter.emit(Events.newWebSocketObject, this.ws);
309
-
310
- // override send method to wait for connecting
311
- const send = this.ws.send.bind(this.ws);
312
- this.ws.send = async (s: string) => {
313
- if (this.ws.readyState === CONNECTING) {
314
- await waitFor({
315
- interval: 100,
316
- condition: () => this.ws.readyState !== CONNECTING,
317
- });
318
- }
319
- await send(s);
320
- };
321
-
322
- if (this.options.autoRecover?.enabled) {
323
- this.ws.addEventListener("message", () => {
324
- if (this.pingServerHandle) {
325
- clearTimeout(this.pingServerHandle);
326
- }
327
- this.pingServerHandle = setTimeout(
328
- () => this.pingServer(),
329
- this.options.autoRecover!.pingServerInterval,
330
- );
331
- });
332
- }
333
-
334
- // debug mode to print all WebSocket traffic
335
- if (this.options.debugMode) {
336
- Utils.debugWebSocket(this.ws);
337
- }
338
-
339
- // listen for new wsc data
340
- this.ws.addEventListener("message", (mEvent: MessageEvent) => {
341
- const event = mEvent as WsgEvent;
342
- const [meta, body] = Utils.splitWsgData(event.data);
343
- if (
344
- meta.wsc &&
345
- (!this.wsc ||
346
- (meta.type === "ConnectionDetails" && body.recoveryState) ||
347
- this.wsc.sequence < meta.wsc.sequence)
348
- ) {
349
- this.wsc = meta.wsc;
350
- this.eventEmitter.emit(Events.newWsc, this.wsc);
351
- }
352
- });
353
-
354
- // get initial ConnectionDetails data
355
- const [meta, body, event] = await Utils.waitForWebSocketMessage(
356
- this.ws,
357
- (meta) => meta.type === "ConnectionDetails" || meta.type === "Error",
358
- );
359
- if (meta.type === "Error") {
360
- throw new ConnectionException(event);
361
- }
362
- this.connectionDetails = body;
363
-
364
- // fired when ws connection is ready for creating subscription
365
- this.eventEmitter.emit(Events.connectionReady, this.ws);
366
-
367
- // recover the subscription, if it exists and enabled
368
- if (this.subscription && this.subscription.enabled) {
369
- // because we have a new ws object
370
- this.subscription.setupWsEventListener();
371
- if (
372
- !recoverSession || this.connectionDetails.recoveryState === "Failed"
373
- ) {
374
- // create new subscription if don't recover existing one
375
- await this.subscription.subscribe();
376
- }
377
- }
378
- }
379
-
380
- // keepInterval means we do not clear the interval
381
- public async revoke(keepInterval = false) {
382
- await this.subscription?.revoke();
383
- this.subscription = undefined;
384
- if (!keepInterval && this.intervalHandle) {
385
- clearInterval(this.intervalHandle);
386
- }
387
- if (this.pingServerHandle) {
388
- clearTimeout(this.pingServerHandle);
389
- }
390
- this.ws?.close();
391
- this.wsc = undefined;
392
- this.wsToken = undefined;
393
- this.wsTokenExpiresAt = 0;
394
- this.disable();
395
- }
396
-
397
- public async subscribe(
398
- eventFilters: string[],
399
- callback: (event: {}) => void,
400
- cache: SubscriptionInfo | undefined | null = undefined,
401
- ) {
402
- const subscription = new Subscription(
403
- this as WebSocketExtensionInterface,
404
- eventFilters,
405
- callback,
406
- );
407
- if (cache === undefined || cache === null) {
408
- await subscription.subscribe();
409
- } else {
410
- subscription.subscriptionInfo = cache;
411
- await subscription.refresh();
412
- }
413
- this.subscription = subscription;
414
- return subscription;
415
- }
416
- }
417
-
418
- export default WebSocketExtension;
package/lib/rest.ts DELETED
@@ -1,71 +0,0 @@
1
- import type {
2
- RestMethod,
3
- RestRequestConfig,
4
- RestResponse,
5
- } from "@rc-ex/core/src/types";
6
- import RestException from "@rc-ex/core/src/RestException";
7
- import hyperid from "hyperid";
8
- import { getReasonPhrase } from "http-status-codes";
9
-
10
- import Utils from "./utils";
11
- import type { WebSocketExtensionInterface } from "./types";
12
-
13
- const version = "0.16";
14
-
15
- const uuid = hyperid();
16
-
17
- export async function request<T>(
18
- this: WebSocketExtensionInterface,
19
- method: RestMethod,
20
- endpoint: string,
21
- content?: {},
22
- queryParams?: {},
23
- config?: RestRequestConfig,
24
- ): Promise<RestResponse<T>> {
25
- const newConfig: RestRequestConfig = {
26
- method,
27
- baseURL: this.wsToken?.uri,
28
- url: endpoint,
29
- data: content,
30
- params: queryParams,
31
- ...config,
32
- };
33
- newConfig.headers = {
34
- ...newConfig.headers,
35
- "X-User-Agent": `${this.rc.rest!.appName}/${
36
- this.rc.rest!.appVersion
37
- } ringcentral-extensible/ws/${version}`,
38
- } as any;
39
- const messageId = uuid();
40
- const requestBody = [
41
- {
42
- type: "ClientRequest",
43
- messageId,
44
- method: newConfig.method,
45
- path: newConfig.url,
46
- headers: newConfig.headers,
47
- query: newConfig.params,
48
- },
49
- ];
50
- if (newConfig.data) {
51
- requestBody.push(newConfig.data);
52
- }
53
- await this.ws.send(JSON.stringify(requestBody));
54
- const [meta, body] = await Utils.waitForWebSocketMessage(
55
- this.ws,
56
- (_meta) => _meta.messageId === messageId,
57
- );
58
- const response: RestResponse = {
59
- data: body as T,
60
- status: meta.status,
61
- statusText: getReasonPhrase(meta.status),
62
- headers: meta.headers,
63
- config: newConfig as any,
64
- };
65
- if (
66
- meta.type === "ClientRequest" && meta.status >= 200 && meta.status < 300
67
- ) {
68
- return response;
69
- }
70
- throw new RestException(response);
71
- }
@@ -1,91 +0,0 @@
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
- const utils_1 = __importDefault(require("./utils"));
7
- class Subscription {
8
- constructor(wse, eventFilters, callback) {
9
- this.enabled = true;
10
- this.wse = wse;
11
- this.eventFilters = eventFilters;
12
- this.eventListener = (mEvent) => {
13
- const event = mEvent;
14
- const [meta, body] = utils_1.default
15
- .splitWsgData(event.data);
16
- if (this.enabled && meta.type === "ServerNotification" &&
17
- body.subscriptionId === this.subscriptionInfo.id) {
18
- callback(body);
19
- }
20
- };
21
- this.setupWsEventListener();
22
- }
23
- setupWsEventListener() {
24
- this.wse.ws.addEventListener("message", this.eventListener);
25
- }
26
- get requestBody() {
27
- return {
28
- deliveryMode: { transportType: "WebSocket" }, // because WebSocket is not in spec
29
- eventFilters: this.eventFilters,
30
- };
31
- }
32
- async subscribe() {
33
- this.subscriptionInfo = (await this.wse.request("POST", "/restapi/v1.0/subscription", this.requestBody)).data;
34
- }
35
- async refresh() {
36
- if (!this.subscriptionInfo) {
37
- return;
38
- }
39
- try {
40
- this.subscriptionInfo = (await this.wse.request("PUT", `/restapi/v1.0/subscription/${this.subscriptionInfo.id}`, this.requestBody)).data;
41
- }
42
- catch (e) {
43
- const re = e;
44
- if (re.response && re.response.status === 404) {
45
- // subscription expired
46
- await this.subscribe();
47
- }
48
- }
49
- }
50
- async revoke() {
51
- if (!this.subscriptionInfo) {
52
- return;
53
- }
54
- try {
55
- await this.wse.request("DELETE", `/restapi/v1.0/subscription/${this.subscriptionInfo.id}`);
56
- }
57
- catch (e) {
58
- const re = e;
59
- if (re.response && re.response.status === 404) {
60
- // ignore
61
- if (this.wse.options.debugMode) {
62
- console.debug(`Subscription ${this.subscriptionInfo.id} doesn't exist on server side`);
63
- }
64
- }
65
- else if (re.response && re.response.status === 401) {
66
- // ignore
67
- if (this.wse.options.debugMode) {
68
- console.debug("Token invalid when trying to revoke subscription");
69
- }
70
- }
71
- else {
72
- throw e;
73
- }
74
- }
75
- this.remove();
76
- }
77
- remove() {
78
- if (this.timeout) {
79
- global.clearTimeout(this.timeout);
80
- this.timeout = undefined;
81
- }
82
- this.enabled = false;
83
- this.subscriptionInfo = undefined;
84
- if (this.wse.ws) {
85
- this.wse.ws.removeEventListener("message", this.eventListener);
86
- }
87
- this.wse.subscription = undefined;
88
- }
89
- }
90
- exports.default = Subscription;
91
- //# sourceMappingURL=subscription.js.map