oorja 1.5.0 → 1.6.2

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 (46) hide show
  1. package/README.md +10 -4
  2. package/bin/oorja +5 -0
  3. package/lib/commands/signout.js +2 -2
  4. package/lib/commands/teletype/index.js +3 -3
  5. package/lib/lib/config.d.ts +5 -6
  6. package/lib/lib/config.js +12 -7
  7. package/lib/lib/encryption.d.ts +1 -1
  8. package/lib/lib/encryption.js +12 -7
  9. package/lib/lib/index.js +1 -0
  10. package/lib/lib/oorja/index.js +14 -13
  11. package/lib/lib/oorja/preflight.d.ts +1 -1
  12. package/lib/lib/oorja/preflight.js +17 -11
  13. package/lib/lib/surya/index.d.ts +2 -2
  14. package/lib/lib/surya/index.js +15 -13
  15. package/lib/lib/surya/types.d.ts +10 -10
  16. package/lib/lib/surya/vendor/phoenix/ajax.d.ts +8 -0
  17. package/lib/lib/surya/vendor/phoenix/ajax.js +85 -0
  18. package/lib/lib/surya/vendor/phoenix/channel.d.ts +154 -0
  19. package/lib/lib/surya/vendor/phoenix/channel.js +311 -0
  20. package/lib/lib/surya/vendor/phoenix/constants.d.ts +33 -0
  21. package/lib/lib/surya/vendor/phoenix/constants.js +32 -0
  22. package/lib/lib/surya/vendor/phoenix/index.d.ts +199 -0
  23. package/lib/lib/surya/vendor/phoenix/index.js +207 -0
  24. package/lib/lib/surya/vendor/phoenix/longpoll.d.ts +12 -0
  25. package/lib/lib/surya/vendor/phoenix/longpoll.js +129 -0
  26. package/lib/lib/surya/vendor/phoenix/presence.d.ts +44 -0
  27. package/lib/lib/surya/vendor/phoenix/presence.js +155 -0
  28. package/lib/lib/surya/vendor/phoenix/push.d.ts +57 -0
  29. package/lib/lib/surya/vendor/phoenix/push.js +125 -0
  30. package/lib/lib/surya/vendor/phoenix/serializer.d.ts +53 -0
  31. package/lib/lib/surya/vendor/phoenix/serializer.js +102 -0
  32. package/lib/lib/surya/vendor/phoenix/socket.d.ts +222 -0
  33. package/lib/lib/surya/vendor/phoenix/socket.js +544 -0
  34. package/lib/lib/surya/vendor/phoenix/timer.d.ts +25 -0
  35. package/lib/lib/surya/vendor/phoenix/timer.js +43 -0
  36. package/lib/lib/surya/vendor/phoenix/utils.d.ts +1 -0
  37. package/lib/lib/surya/vendor/phoenix/utils.js +15 -0
  38. package/lib/lib/teletype/auxiliary.d.ts +1 -1
  39. package/lib/lib/teletype/auxiliary.js +8 -4
  40. package/lib/lib/teletype/index.d.ts +1 -1
  41. package/lib/lib/teletype/index.js +13 -12
  42. package/lib/lib/utils.js +2 -1
  43. package/oclif.manifest.json +1 -1
  44. package/package.json +10 -9
  45. package/lib/lib/surya/vendor/phoenix.d.ts +0 -486
  46. package/lib/lib/surya/vendor/phoenix.js +0 -1299
@@ -0,0 +1,544 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ // @ts-nocheck
4
+ const constants_1 = require("./constants");
5
+ const utils_1 = require("./utils");
6
+ const ajax_1 = require("./ajax");
7
+ const channel_1 = require("./channel");
8
+ const longpoll_1 = require("./longpoll");
9
+ const serializer_1 = require("./serializer");
10
+ const timer_1 = require("./timer");
11
+ const ws_1 = require("ws");
12
+ /** Initializes the Socket *
13
+ *
14
+ * For IE8 support use an ES5-shim (https://github.com/es-shims/es5-shim)
15
+ *
16
+ * @param {string} endPoint - The string WebSocket endpoint, ie, `"ws://example.com/socket"`,
17
+ * `"wss://example.com"`
18
+ * `"/socket"` (inherited host & protocol)
19
+ * @param {Object} [opts] - Optional configuration
20
+ * @param {Function} [opts.transport] - The Websocket Transport, for example WebSocket or Phoenix.LongPoll.
21
+ *
22
+ * Defaults to WebSocket with automatic LongPoll fallback.
23
+ * @param {Function} [opts.encode] - The function to encode outgoing messages.
24
+ *
25
+ * Defaults to JSON encoder.
26
+ *
27
+ * @param {Function} [opts.decode] - The function to decode incoming messages.
28
+ *
29
+ * Defaults to JSON:
30
+ *
31
+ * ```javascript
32
+ * (payload, callback) => callback(JSON.parse(payload))
33
+ * ```
34
+ *
35
+ * @param {number} [opts.timeout] - The default timeout in milliseconds to trigger push timeouts.
36
+ *
37
+ * Defaults `DEFAULT_TIMEOUT`
38
+ * @param {number} [opts.heartbeatIntervalMs] - The millisec interval to send a heartbeat message
39
+ * @param {number} [opts.reconnectAfterMs] - The optional function that returns the millisec
40
+ * socket reconnect interval.
41
+ *
42
+ * Defaults to stepped backoff of:
43
+ *
44
+ * ```javascript
45
+ * function(tries){
46
+ * return [10, 50, 100, 150, 200, 250, 500, 1000, 2000][tries - 1] || 5000
47
+ * }
48
+ * ````
49
+ *
50
+ * @param {number} [opts.rejoinAfterMs] - The optional function that returns the millisec
51
+ * rejoin interval for individual channels.
52
+ *
53
+ * ```javascript
54
+ * function(tries){
55
+ * return [1000, 2000, 5000][tries - 1] || 10000
56
+ * }
57
+ * ````
58
+ *
59
+ * @param {Function} [opts.logger] - The optional function for specialized logging, ie:
60
+ *
61
+ * ```javascript
62
+ * function(kind, msg, data) {
63
+ * console.log(`${kind}: ${msg}`, data)
64
+ * }
65
+ * ```
66
+ *
67
+ * @param {number} [opts.longpollerTimeout] - The maximum timeout of a long poll AJAX request.
68
+ *
69
+ * Defaults to 20s (double the server long poll timer).
70
+ *
71
+ * @param {(Object|function)} [opts.params] - The optional params to pass when connecting
72
+ * @param {string} [opts.binaryType] - The binary type to use for binary WebSocket frames.
73
+ *
74
+ * Defaults to "arraybuffer"
75
+ *
76
+ * @param {vsn} [opts.vsn] - The serializer's protocol version to send on connect.
77
+ *
78
+ * Defaults to DEFAULT_VSN.
79
+ */
80
+ class Socket {
81
+ constructor(endPoint, opts = {}) {
82
+ this.stateChangeCallbacks = { open: [], close: [], error: [], message: [] };
83
+ this.channels = [];
84
+ this.sendBuffer = [];
85
+ this.ref = 0;
86
+ this.timeout = opts.timeout || constants_1.DEFAULT_TIMEOUT;
87
+ this.transport = ws_1.WebSocket;
88
+ this.establishedConnections = 0;
89
+ this.defaultEncoder = serializer_1.default.encode.bind(serializer_1.default);
90
+ this.defaultDecoder = serializer_1.default.decode.bind(serializer_1.default);
91
+ this.closeWasClean = false;
92
+ this.binaryType = opts.binaryType || "arraybuffer";
93
+ this.connectClock = 1;
94
+ if (this.transport !== longpoll_1.default) {
95
+ this.encode = opts.encode || this.defaultEncoder;
96
+ this.decode = opts.decode || this.defaultDecoder;
97
+ }
98
+ else {
99
+ this.encode = this.defaultEncoder;
100
+ this.decode = this.defaultDecoder;
101
+ }
102
+ let awaitingConnectionOnPageShow = null;
103
+ if (constants_1.phxWindow && constants_1.phxWindow.addEventListener) {
104
+ constants_1.phxWindow.addEventListener("pagehide", _e => {
105
+ if (this.conn) {
106
+ this.disconnect();
107
+ awaitingConnectionOnPageShow = this.connectClock;
108
+ }
109
+ });
110
+ constants_1.phxWindow.addEventListener("pageshow", _e => {
111
+ if (awaitingConnectionOnPageShow === this.connectClock) {
112
+ awaitingConnectionOnPageShow = null;
113
+ this.connect();
114
+ }
115
+ });
116
+ }
117
+ this.heartbeatIntervalMs = opts.heartbeatIntervalMs || 30000;
118
+ this.rejoinAfterMs = (tries) => {
119
+ if (opts.rejoinAfterMs) {
120
+ return opts.rejoinAfterMs(tries);
121
+ }
122
+ else {
123
+ return [1000, 2000, 5000][tries - 1] || 10000;
124
+ }
125
+ };
126
+ this.reconnectAfterMs = (tries) => {
127
+ if (opts.reconnectAfterMs) {
128
+ return opts.reconnectAfterMs(tries);
129
+ }
130
+ else {
131
+ return [10, 50, 100, 150, 200, 250, 500, 1000, 2000][tries - 1] || 5000;
132
+ }
133
+ };
134
+ this.logger = opts.logger || null;
135
+ this.longpollerTimeout = opts.longpollerTimeout || 20000;
136
+ this.params = (0, utils_1.closure)(opts.params || {});
137
+ this.endPoint = `${endPoint}/${constants_1.TRANSPORTS.websocket}`;
138
+ this.vsn = opts.vsn || constants_1.DEFAULT_VSN;
139
+ this.heartbeatTimeoutTimer = null;
140
+ this.heartbeatTimer = null;
141
+ this.pendingHeartbeatRef = null;
142
+ this.reconnectTimer = new timer_1.default(() => {
143
+ this.teardown(() => this.connect());
144
+ }, this.reconnectAfterMs);
145
+ }
146
+ /**
147
+ * Returns the LongPoll transport reference
148
+ */
149
+ getLongPollTransport() { return longpoll_1.default; }
150
+ /**
151
+ * Disconnects and replaces the active transport
152
+ *
153
+ * @param {Function} newTransport - The new transport class to instantiate
154
+ *
155
+ */
156
+ replaceTransport(newTransport) {
157
+ this.connectClock++;
158
+ this.closeWasClean = true;
159
+ this.reconnectTimer.reset();
160
+ this.sendBuffer = [];
161
+ if (this.conn) {
162
+ this.conn.close();
163
+ this.conn = null;
164
+ }
165
+ this.transport = newTransport;
166
+ }
167
+ /**
168
+ * Returns the socket protocol
169
+ *
170
+ * @returns {string}
171
+ */
172
+ protocol() { return location.protocol.match(/^https/) ? "wss" : "ws"; }
173
+ /**
174
+ * The fully qualified socket url
175
+ *
176
+ * @returns {string}
177
+ */
178
+ endPointURL() {
179
+ let uri = ajax_1.default.appendParams(ajax_1.default.appendParams(this.endPoint, this.params()), { vsn: this.vsn });
180
+ if (uri.charAt(0) !== "/") {
181
+ return uri;
182
+ }
183
+ if (uri.charAt(1) === "/") {
184
+ return `${this.protocol()}:${uri}`;
185
+ }
186
+ return `${this.protocol()}://${location.host}${uri}`;
187
+ }
188
+ /**
189
+ * Disconnects the socket
190
+ *
191
+ * See https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent#Status_codes for valid status codes.
192
+ *
193
+ * @param {Function} callback - Optional callback which is called after socket is disconnected.
194
+ * @param {integer} code - A status code for disconnection (Optional).
195
+ * @param {string} reason - A textual description of the reason to disconnect. (Optional)
196
+ */
197
+ disconnect(callback, code, reason) {
198
+ this.connectClock++;
199
+ this.closeWasClean = true;
200
+ this.reconnectTimer.reset();
201
+ this.teardown(callback, code, reason);
202
+ }
203
+ /**
204
+ *
205
+ * @param {Object} params - The params to send when connecting, for example `{user_id: userToken}`
206
+ *
207
+ * Passing params to connect is deprecated; pass them in the Socket constructor instead:
208
+ * `new Socket("/socket", {params: {user_id: userToken}})`.
209
+ */
210
+ connect(params) {
211
+ if (params) {
212
+ console && console.log("passing params to connect is deprecated. Instead pass :params to the Socket constructor");
213
+ this.params = (0, utils_1.closure)(params);
214
+ }
215
+ if (this.conn) {
216
+ return;
217
+ }
218
+ this.connectClock++;
219
+ this.closeWasClean = false;
220
+ this.conn = new ws_1.WebSocket(this.endPointURL());
221
+ this.conn.binaryType = this.binaryType;
222
+ this.conn.timeout = this.longpollerTimeout;
223
+ this.conn.onopen = () => this.onConnOpen();
224
+ this.conn.onerror = error => this.onConnError(error);
225
+ this.conn.onmessage = event => this.onConnMessage(event);
226
+ this.conn.onclose = event => this.onConnClose(event);
227
+ }
228
+ /**
229
+ * Logs the message. Override `this.logger` for specialized logging. noops by default
230
+ * @param {string} kind
231
+ * @param {string} msg
232
+ * @param {Object} data
233
+ */
234
+ log(kind, msg, data) { this.logger(kind, msg, data); }
235
+ /**
236
+ * Returns true if a logger has been set on this socket.
237
+ */
238
+ hasLogger() { return this.logger !== null; }
239
+ /**
240
+ * Registers callbacks for connection open events
241
+ *
242
+ * @example socket.onOpen(function(){ console.info("the socket was opened") })
243
+ *
244
+ * @param {Function} callback
245
+ */
246
+ onOpen(callback) {
247
+ let ref = this.makeRef();
248
+ this.stateChangeCallbacks.open.push([ref, callback]);
249
+ return ref;
250
+ }
251
+ /**
252
+ * Registers callbacks for connection close events
253
+ * @param {Function} callback
254
+ */
255
+ onClose(callback) {
256
+ let ref = this.makeRef();
257
+ this.stateChangeCallbacks.close.push([ref, callback]);
258
+ return ref;
259
+ }
260
+ /**
261
+ * Registers callbacks for connection error events
262
+ *
263
+ * @example socket.onError(function(error){ alert("An error occurred") })
264
+ *
265
+ * @param {Function} callback
266
+ */
267
+ onError(callback) {
268
+ let ref = this.makeRef();
269
+ this.stateChangeCallbacks.error.push([ref, callback]);
270
+ return ref;
271
+ }
272
+ /**
273
+ * Registers callbacks for connection message events
274
+ * @param {Function} callback
275
+ */
276
+ onMessage(callback) {
277
+ let ref = this.makeRef();
278
+ this.stateChangeCallbacks.message.push([ref, callback]);
279
+ return ref;
280
+ }
281
+ /**
282
+ * Pings the server and invokes the callback with the RTT in milliseconds
283
+ * @param {Function} callback
284
+ *
285
+ * Returns true if the ping was pushed or false if unable to be pushed.
286
+ */
287
+ ping(callback) {
288
+ if (!this.isConnected()) {
289
+ return false;
290
+ }
291
+ let ref = this.makeRef();
292
+ let startTime = Date.now();
293
+ this.push({ topic: "phoenix", event: "heartbeat", payload: {}, ref: ref });
294
+ let onMsgRef = this.onMessage(msg => {
295
+ if (msg.ref === ref) {
296
+ this.off([onMsgRef]);
297
+ callback(Date.now() - startTime);
298
+ }
299
+ });
300
+ return true;
301
+ }
302
+ /**
303
+ * @private
304
+ */
305
+ clearHeartbeats() {
306
+ clearTimeout(this.heartbeatTimer);
307
+ clearTimeout(this.heartbeatTimeoutTimer);
308
+ }
309
+ onConnOpen() {
310
+ if (this.hasLogger())
311
+ this.log("transport", `connected to ${this.endPointURL()}`);
312
+ this.closeWasClean = false;
313
+ this.establishedConnections++;
314
+ this.flushSendBuffer();
315
+ this.reconnectTimer.reset();
316
+ this.resetHeartbeat();
317
+ this.stateChangeCallbacks.open.forEach(([, callback]) => callback());
318
+ }
319
+ /**
320
+ * @private
321
+ */
322
+ heartbeatTimeout() {
323
+ if (this.pendingHeartbeatRef) {
324
+ this.pendingHeartbeatRef = null;
325
+ if (this.hasLogger()) {
326
+ this.log("transport", "heartbeat timeout. Attempting to re-establish connection");
327
+ }
328
+ this.triggerChanError();
329
+ this.closeWasClean = false;
330
+ this.teardown(() => this.reconnectTimer.scheduleTimeout(), constants_1.WS_CLOSE_NORMAL, "heartbeat timeout");
331
+ }
332
+ }
333
+ resetHeartbeat() {
334
+ if (this.conn && this.conn.skipHeartbeat) {
335
+ return;
336
+ }
337
+ this.pendingHeartbeatRef = null;
338
+ this.clearHeartbeats();
339
+ this.heartbeatTimer = setTimeout(() => this.sendHeartbeat(), this.heartbeatIntervalMs);
340
+ }
341
+ teardown(callback, code, reason) {
342
+ if (!this.conn) {
343
+ return callback && callback();
344
+ }
345
+ this.waitForBufferDone(() => {
346
+ if (this.conn) {
347
+ if (code) {
348
+ this.conn.close(code, reason || "");
349
+ }
350
+ else {
351
+ this.conn.close();
352
+ }
353
+ }
354
+ this.waitForSocketClosed(() => {
355
+ if (this.conn) {
356
+ this.conn.onopen = function () { }; // noop
357
+ this.conn.onerror = function () { }; // noop
358
+ this.conn.onmessage = function () { }; // noop
359
+ this.conn.onclose = function () { }; // noop
360
+ this.conn = null;
361
+ }
362
+ callback && callback();
363
+ });
364
+ });
365
+ }
366
+ waitForBufferDone(callback, tries = 1) {
367
+ if (tries === 5 || !this.conn || !this.conn.bufferedAmount) {
368
+ callback();
369
+ return;
370
+ }
371
+ setTimeout(() => {
372
+ this.waitForBufferDone(callback, tries + 1);
373
+ }, 150 * tries);
374
+ }
375
+ waitForSocketClosed(callback, tries = 1) {
376
+ if (tries === 5 || !this.conn || this.conn.readyState === constants_1.SOCKET_STATES.closed) {
377
+ callback();
378
+ return;
379
+ }
380
+ setTimeout(() => {
381
+ this.waitForSocketClosed(callback, tries + 1);
382
+ }, 150 * tries);
383
+ }
384
+ onConnClose(event) {
385
+ let closeCode = event && event.code;
386
+ if (this.hasLogger())
387
+ this.log("transport", "close", event);
388
+ this.triggerChanError();
389
+ this.clearHeartbeats();
390
+ if (!this.closeWasClean && closeCode !== 1000) {
391
+ this.reconnectTimer.scheduleTimeout();
392
+ }
393
+ this.stateChangeCallbacks.close.forEach(([, callback]) => callback(event));
394
+ }
395
+ /**
396
+ * @private
397
+ */
398
+ onConnError(error) {
399
+ if (this.hasLogger())
400
+ this.log("transport", error);
401
+ let transportBefore = this.transport;
402
+ let establishedBefore = this.establishedConnections;
403
+ this.stateChangeCallbacks.error.forEach(([, callback]) => {
404
+ callback(error, transportBefore, establishedBefore);
405
+ });
406
+ if (transportBefore === this.transport || establishedBefore > 0) {
407
+ this.triggerChanError();
408
+ }
409
+ }
410
+ /**
411
+ * @private
412
+ */
413
+ triggerChanError() {
414
+ this.channels.forEach(channel => {
415
+ if (!(channel.isErrored() || channel.isLeaving() || channel.isClosed())) {
416
+ channel.trigger(constants_1.CHANNEL_EVENTS.error);
417
+ }
418
+ });
419
+ }
420
+ /**
421
+ * @returns {string}
422
+ */
423
+ connectionState() {
424
+ switch (this.conn && this.conn.readyState) {
425
+ case constants_1.SOCKET_STATES.connecting: return "connecting";
426
+ case constants_1.SOCKET_STATES.open: return "open";
427
+ case constants_1.SOCKET_STATES.closing: return "closing";
428
+ default: return "closed";
429
+ }
430
+ }
431
+ /**
432
+ * @returns {boolean}
433
+ */
434
+ isConnected() { return this.connectionState() === "open"; }
435
+ /**
436
+ * @private
437
+ *
438
+ * @param {Channel}
439
+ */
440
+ remove(channel) {
441
+ this.off(channel.stateChangeRefs);
442
+ this.channels = this.channels.filter(c => c.joinRef() !== channel.joinRef());
443
+ }
444
+ /**
445
+ * Removes `onOpen`, `onClose`, `onError,` and `onMessage` registrations.
446
+ *
447
+ * @param {refs} - list of refs returned by calls to
448
+ * `onOpen`, `onClose`, `onError,` and `onMessage`
449
+ */
450
+ off(refs) {
451
+ for (let key in this.stateChangeCallbacks) {
452
+ this.stateChangeCallbacks[key] = this.stateChangeCallbacks[key].filter(([ref]) => {
453
+ return refs.indexOf(ref) === -1;
454
+ });
455
+ }
456
+ }
457
+ /**
458
+ * Initiates a new channel for the given topic
459
+ *
460
+ * @param {string} topic
461
+ * @param {Object} chanParams - Parameters for the channel
462
+ * @returns {Channel}
463
+ */
464
+ channel(topic, chanParams = {}) {
465
+ let chan = new channel_1.default(topic, chanParams, this);
466
+ this.channels.push(chan);
467
+ return chan;
468
+ }
469
+ /**
470
+ * @param {Object} data
471
+ */
472
+ push(data) {
473
+ if (this.hasLogger()) {
474
+ let { topic, event, payload, ref, join_ref } = data;
475
+ this.log("push", `${topic} ${event} (${join_ref}, ${ref})`, payload);
476
+ }
477
+ if (this.isConnected()) {
478
+ this.encode(data, result => this.conn.send(result));
479
+ }
480
+ else {
481
+ this.sendBuffer.push(() => this.encode(data, result => this.conn.send(result)));
482
+ }
483
+ }
484
+ /**
485
+ * Return the next message ref, accounting for overflows
486
+ * @returns {string}
487
+ */
488
+ makeRef() {
489
+ let newRef = this.ref + 1;
490
+ if (newRef === this.ref) {
491
+ this.ref = 0;
492
+ }
493
+ else {
494
+ this.ref = newRef;
495
+ }
496
+ return this.ref.toString();
497
+ }
498
+ sendHeartbeat() {
499
+ if (this.pendingHeartbeatRef && !this.isConnected()) {
500
+ return;
501
+ }
502
+ this.pendingHeartbeatRef = this.makeRef();
503
+ this.push({ topic: "phoenix", event: "heartbeat", payload: {}, ref: this.pendingHeartbeatRef });
504
+ this.heartbeatTimeoutTimer = setTimeout(() => this.heartbeatTimeout(), this.heartbeatIntervalMs);
505
+ }
506
+ flushSendBuffer() {
507
+ if (this.isConnected() && this.sendBuffer.length > 0) {
508
+ this.sendBuffer.forEach(callback => callback());
509
+ this.sendBuffer = [];
510
+ }
511
+ }
512
+ onConnMessage(rawMessage) {
513
+ this.decode(rawMessage.data, msg => {
514
+ let { topic, event, payload, ref, join_ref } = msg;
515
+ if (ref && ref === this.pendingHeartbeatRef) {
516
+ this.clearHeartbeats();
517
+ this.pendingHeartbeatRef = null;
518
+ this.heartbeatTimer = setTimeout(() => this.sendHeartbeat(), this.heartbeatIntervalMs);
519
+ }
520
+ if (this.hasLogger())
521
+ this.log("receive", `${payload.status || ""} ${topic} ${event} ${ref && "(" + ref + ")" || ""}`, payload);
522
+ for (let i = 0; i < this.channels.length; i++) {
523
+ const channel = this.channels[i];
524
+ if (!channel.isMember(topic, event, payload, join_ref)) {
525
+ continue;
526
+ }
527
+ channel.trigger(event, payload, ref, join_ref);
528
+ }
529
+ for (let i = 0; i < this.stateChangeCallbacks.message.length; i++) {
530
+ let [, callback] = this.stateChangeCallbacks.message[i];
531
+ callback(msg);
532
+ }
533
+ });
534
+ }
535
+ leaveOpenTopic(topic) {
536
+ let dupChannel = this.channels.find(c => c.topic === topic && (c.isJoined() || c.isJoining()));
537
+ if (dupChannel) {
538
+ if (this.hasLogger())
539
+ this.log("transport", `leaving duplicate topic "${topic}"`);
540
+ dupChannel.leave();
541
+ }
542
+ }
543
+ }
544
+ exports.default = Socket;
@@ -0,0 +1,25 @@
1
+ /**
2
+ *
3
+ * Creates a timer that accepts a `timerCalc` function to perform
4
+ * calculated timeout retries, such as exponential backoff.
5
+ *
6
+ * @example
7
+ * let reconnectTimer = new Timer(() => this.connect(), function(tries){
8
+ * return [1000, 5000, 10000][tries - 1] || 10000
9
+ * })
10
+ * reconnectTimer.scheduleTimeout() // fires after 1000
11
+ * reconnectTimer.scheduleTimeout() // fires after 5000
12
+ * reconnectTimer.reset()
13
+ * reconnectTimer.scheduleTimeout() // fires after 1000
14
+ *
15
+ * @param {Function} callback
16
+ * @param {Function} timerCalc
17
+ */
18
+ export default class Timer {
19
+ constructor(callback: any, timerCalc: any);
20
+ reset(): void;
21
+ /**
22
+ * Cancels any previous scheduleTimeout and schedules callback
23
+ */
24
+ scheduleTimeout(): void;
25
+ }
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ // @ts-nocheck
4
+ /**
5
+ *
6
+ * Creates a timer that accepts a `timerCalc` function to perform
7
+ * calculated timeout retries, such as exponential backoff.
8
+ *
9
+ * @example
10
+ * let reconnectTimer = new Timer(() => this.connect(), function(tries){
11
+ * return [1000, 5000, 10000][tries - 1] || 10000
12
+ * })
13
+ * reconnectTimer.scheduleTimeout() // fires after 1000
14
+ * reconnectTimer.scheduleTimeout() // fires after 5000
15
+ * reconnectTimer.reset()
16
+ * reconnectTimer.scheduleTimeout() // fires after 1000
17
+ *
18
+ * @param {Function} callback
19
+ * @param {Function} timerCalc
20
+ */
21
+ class Timer {
22
+ constructor(callback, timerCalc) {
23
+ this.callback = callback;
24
+ this.timerCalc = timerCalc;
25
+ this.timer = null;
26
+ this.tries = 0;
27
+ }
28
+ reset() {
29
+ this.tries = 0;
30
+ clearTimeout(this.timer);
31
+ }
32
+ /**
33
+ * Cancels any previous scheduleTimeout and schedules callback
34
+ */
35
+ scheduleTimeout() {
36
+ clearTimeout(this.timer);
37
+ this.timer = setTimeout(() => {
38
+ this.tries = this.tries + 1;
39
+ this.callback();
40
+ }, this.timerCalc(this.tries + 1));
41
+ }
42
+ }
43
+ exports.default = Timer;
@@ -0,0 +1 @@
1
+ export declare let closure: (value: any) => any;
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.closure = void 0;
4
+ // @ts-nocheck
5
+ // wraps value in closure or returns closure
6
+ let closure = (value) => {
7
+ if (typeof value === "function") {
8
+ return value;
9
+ }
10
+ else {
11
+ let closure = function () { return value; };
12
+ return closure;
13
+ }
14
+ };
15
+ exports.closure = closure;
@@ -1,7 +1,7 @@
1
1
  import { IPty } from "node-pty";
2
2
  import { Hash } from "../surya/types";
3
3
  export declare const initScreen: (username: string, hostname: string, shell: string, multiplexed: boolean) => void;
4
- export declare type dimensions = {
4
+ export type dimensions = {
5
5
  rows: number;
6
6
  cols: number;
7
7
  };
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.resizeBestFit = exports.areDimensionEqual = exports.getDimensions = exports.initScreen = void 0;
4
4
  const chalk = require("chalk");
5
5
  const termSize = require("term-size");
6
- exports.initScreen = (username, hostname, shell, multiplexed) => {
6
+ const initScreen = (username, hostname, shell, multiplexed) => {
7
7
  console.log(chalk.bold(chalk.blueBright("TeleType")));
8
8
  if (multiplexed) {
9
9
  console.log(chalk.yellowBright("You have allowed room participants to write to your shell"));
@@ -13,16 +13,20 @@ exports.initScreen = (username, hostname, shell, multiplexed) => {
13
13
  This session is end-to-end encrypted.
14
14
  To terminate stream run ${chalk.yellowBright("exit")} or press ${chalk.yellowBright("ctrl-d")} \n`);
15
15
  };
16
- exports.getDimensions = () => {
16
+ exports.initScreen = initScreen;
17
+ const getDimensions = () => {
17
18
  const { rows, columns } = termSize();
18
19
  return { rows, cols: columns };
19
20
  };
20
- exports.areDimensionEqual = (a, b) => {
21
+ exports.getDimensions = getDimensions;
22
+ const areDimensionEqual = (a, b) => {
21
23
  return a.rows === b.rows && a.cols === b.cols;
22
24
  };
23
- exports.resizeBestFit = (term, userDimensions) => {
25
+ exports.areDimensionEqual = areDimensionEqual;
26
+ const resizeBestFit = (term, userDimensions) => {
24
27
  const allViewports = Object.values(userDimensions);
25
28
  const minrows = Math.min(...allViewports.map((d) => d.rows));
26
29
  const mincols = Math.min(...allViewports.map((d) => d.cols));
27
30
  term.resize(mincols, minrows);
28
31
  };
32
+ exports.resizeBestFit = resizeBestFit;
@@ -2,7 +2,7 @@
2
2
  import { RoomKey } from "../surya/types";
3
3
  import { JoinChannelOptions } from "../surya";
4
4
  import { Channel } from "../surya/vendor/phoenix";
5
- export declare type TeletypeOptions = {
5
+ export type TeletypeOptions = {
6
6
  userId: string;
7
7
  roomKey: RoomKey;
8
8
  shell: string;