relayx-webjs 1.0.2 → 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +3 -0
- package/example/chat-app/package.json +2 -1
- package/example/stand-alone/example_chat.js +111 -0
- package/package.json +1 -1
- package/realtime/realtime.js +111 -92
package/CHANGELOG.md
CHANGED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { Realtime, CONNECTED, RECONNECT, DISCONNECTED, MESSAGE_RESEND } from "../../realtime/realtime.js"
|
|
2
|
+
import * as readline from 'readline';
|
|
3
|
+
|
|
4
|
+
const rl = readline.createInterface({
|
|
5
|
+
input: process.stdin,
|
|
6
|
+
output: process.stdout
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
async function run(){
|
|
10
|
+
var realtime = new Realtime({
|
|
11
|
+
api_key: process.env.AUTH_JWT,
|
|
12
|
+
secret: process.env.AUTH_SECRET
|
|
13
|
+
});
|
|
14
|
+
await realtime.init(false, {
|
|
15
|
+
max_retries: 2,
|
|
16
|
+
debug: true
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
realtime.on(CONNECTED, async () => {
|
|
20
|
+
console.log("[IMPL] => CONNECTED!");
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
realtime.on(RECONNECT, (status) => {
|
|
24
|
+
console.log(`[IMPL] RECONNECT => ${status}`)
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
realtime.on(DISCONNECTED, () => {
|
|
28
|
+
console.log(`[IMPL] DISONNECT`)
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
await realtime.on("power-telemetry", (data) => {
|
|
32
|
+
console.log("power-telemetry", data);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
await realtime.on("hello.>", async (data) => {
|
|
36
|
+
console.log("hello.>", data);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
// await realtime.on("hello.hey.*", (data) => {
|
|
40
|
+
// console.log("hell.hey.*", data);
|
|
41
|
+
// });
|
|
42
|
+
|
|
43
|
+
// await realtime.on("hello.hey.>", (data) => {
|
|
44
|
+
// console.log("hello.hey.>", data);
|
|
45
|
+
// });
|
|
46
|
+
|
|
47
|
+
realtime.on(MESSAGE_RESEND, (data) => {
|
|
48
|
+
console.log(`[MSG RESEND] => ${data}`)
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
rl.on('line', async (input) => {
|
|
52
|
+
console.log(`You entered: ${input}`);
|
|
53
|
+
|
|
54
|
+
if(input == "exit"){
|
|
55
|
+
var output = await realtime.off("hello");
|
|
56
|
+
console.log(output);
|
|
57
|
+
|
|
58
|
+
realtime.close();
|
|
59
|
+
|
|
60
|
+
process.exit();
|
|
61
|
+
}else if(input == "history"){
|
|
62
|
+
rl.question("topic: ", async (topic) => {
|
|
63
|
+
var start = new Date();
|
|
64
|
+
var past = start.setDate(start.getDate() - 4)
|
|
65
|
+
var pastDate = new Date(past)
|
|
66
|
+
|
|
67
|
+
var end = new Date();
|
|
68
|
+
var past = end.setDate(end.getDate())
|
|
69
|
+
var endDate = new Date(past)
|
|
70
|
+
|
|
71
|
+
var history = await realtime.history(topic, pastDate)
|
|
72
|
+
console.log(history)
|
|
73
|
+
})
|
|
74
|
+
}else if(input == "off"){
|
|
75
|
+
rl.question("topic to off(): ", async (topic) => {
|
|
76
|
+
await realtime.off(topic);
|
|
77
|
+
console.log("off() executed")
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
}else if(input == "close"){
|
|
82
|
+
realtime.close();
|
|
83
|
+
console.log("Connection closed");
|
|
84
|
+
}else if(input == "init"){
|
|
85
|
+
await realtime.connect()
|
|
86
|
+
}else if(input == "on"){
|
|
87
|
+
rl.question("topic: ", async (topic) => {
|
|
88
|
+
await realtime.on(topic, (data) => {
|
|
89
|
+
console.log(topic, data);
|
|
90
|
+
});
|
|
91
|
+
})
|
|
92
|
+
}else{
|
|
93
|
+
rl.question("topic: ", async (topic) => {
|
|
94
|
+
var output = await realtime.publish(topic, input);
|
|
95
|
+
})
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
realtime.connect();
|
|
100
|
+
|
|
101
|
+
process.on('SIGINT', async () => {
|
|
102
|
+
console.log('Keyboard interrupt detected (Ctrl+C). Cleaning up...');
|
|
103
|
+
// Perform any necessary cleanup here
|
|
104
|
+
|
|
105
|
+
// Exit the process
|
|
106
|
+
process.exit();
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
await run();
|
package/package.json
CHANGED
package/realtime/realtime.js
CHANGED
|
@@ -21,6 +21,8 @@ export class Realtime {
|
|
|
21
21
|
#RECONNECTED = "RECONNECTED";
|
|
22
22
|
#RECONN_FAIL = "RECONN_FAIL";
|
|
23
23
|
|
|
24
|
+
#reservedSystemTopics = [CONNECTED, DISCONNECTED, RECONNECT, this.#RECONNECTED, this.#RECONNECTING, this.#RECONN_FAIL, MESSAGE_RESEND, SERVER_DISCONNECT];
|
|
25
|
+
|
|
24
26
|
setRemoteUserAttempts = 0;
|
|
25
27
|
setRemoteUserRetries = 5;
|
|
26
28
|
|
|
@@ -40,6 +42,8 @@ export class Realtime {
|
|
|
40
42
|
|
|
41
43
|
#maxPublishRetries = 5;
|
|
42
44
|
|
|
45
|
+
#connectCalled = false;
|
|
46
|
+
|
|
43
47
|
constructor(config){
|
|
44
48
|
if(typeof config != "object"){
|
|
45
49
|
throw new Error("Realtime($config). $config not object => {}")
|
|
@@ -95,10 +99,13 @@ export class Realtime {
|
|
|
95
99
|
if(arguments[0] instanceof Object){
|
|
96
100
|
opts = arguments[0];
|
|
97
101
|
staging = false;
|
|
98
|
-
}else{
|
|
102
|
+
}else if(typeof arguments[0] == "boolean"){
|
|
99
103
|
opts = {};
|
|
100
104
|
staging = arguments[0];
|
|
101
105
|
this.#log(staging)
|
|
106
|
+
}else{
|
|
107
|
+
opts = {};
|
|
108
|
+
staging = false
|
|
102
109
|
}
|
|
103
110
|
}else{
|
|
104
111
|
staging = false;
|
|
@@ -108,23 +115,27 @@ export class Realtime {
|
|
|
108
115
|
this.staging = staging;
|
|
109
116
|
this.opts = opts;
|
|
110
117
|
|
|
111
|
-
if
|
|
112
|
-
this.#baseUrl =
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
+
if(process.env.PROXY){
|
|
119
|
+
this.#baseUrl = ["wss://api2.relay-x.io:8666"];
|
|
120
|
+
}else{
|
|
121
|
+
if (staging !== undefined || staging !== null){
|
|
122
|
+
this.#baseUrl = staging ? [
|
|
123
|
+
"nats://0.0.0.0:4421",
|
|
124
|
+
"nats://0.0.0.0:4422",
|
|
125
|
+
"nats://0.0.0.0:4423"
|
|
126
|
+
] :
|
|
127
|
+
[
|
|
128
|
+
`wss://api.relay-x.io:4421`,
|
|
129
|
+
`wss://api.relay-x.io:4422`,
|
|
130
|
+
`wss://api.relay-x.io:4423`
|
|
131
|
+
];
|
|
132
|
+
}else{
|
|
133
|
+
this.#baseUrl = [
|
|
118
134
|
`wss://api.relay-x.io:4421`,
|
|
119
135
|
`wss://api.relay-x.io:4422`,
|
|
120
136
|
`wss://api.relay-x.io:4423`
|
|
121
137
|
];
|
|
122
|
-
|
|
123
|
-
this.#baseUrl = [
|
|
124
|
-
`wss://api.relay-x.io:4421`,
|
|
125
|
-
`wss://api.relay-x.io:4422`,
|
|
126
|
-
`wss://api.relay-x.io:4423`
|
|
127
|
-
];
|
|
138
|
+
}
|
|
128
139
|
}
|
|
129
140
|
|
|
130
141
|
this.#log(this.#baseUrl);
|
|
@@ -164,6 +175,10 @@ export class Realtime {
|
|
|
164
175
|
* Connects to the relay network
|
|
165
176
|
*/
|
|
166
177
|
async connect(){
|
|
178
|
+
if(this.#connectCalled){
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
|
|
167
182
|
this.SEVER_URL = this.#baseUrl;
|
|
168
183
|
|
|
169
184
|
var credsFile = this.#getUserCreds(this.api_key, this.secret)
|
|
@@ -178,7 +193,7 @@ export class Realtime {
|
|
|
178
193
|
maxReconnectAttempts: 1200,
|
|
179
194
|
reconnectTimeWait: 1000,
|
|
180
195
|
authenticator: credsAuth,
|
|
181
|
-
token: this.api_key
|
|
196
|
+
token: this.api_key
|
|
182
197
|
});
|
|
183
198
|
|
|
184
199
|
this.#jetstream = await jetstream(this.#natsClient);
|
|
@@ -186,6 +201,7 @@ export class Realtime {
|
|
|
186
201
|
await this.#getNameSpace()
|
|
187
202
|
|
|
188
203
|
this.connected = true;
|
|
204
|
+
this.#connectCalled = true;
|
|
189
205
|
}catch(err){
|
|
190
206
|
this.#log("ERR")
|
|
191
207
|
this.#log(err);
|
|
@@ -196,17 +212,13 @@ export class Realtime {
|
|
|
196
212
|
if (this.connected == true){
|
|
197
213
|
this.#log("Connected to server!");
|
|
198
214
|
|
|
199
|
-
// Callback on client side
|
|
200
|
-
if (CONNECTED in this.#event_func){
|
|
201
|
-
if (this.#event_func[CONNECTED] !== null || this.#event_func[CONNECTED] !== undefined){
|
|
202
|
-
this.#event_func[CONNECTED]()
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
|
|
206
215
|
this.#natsClient.closed().then(() => {
|
|
207
216
|
this.#log("the connection closed!");
|
|
208
217
|
|
|
209
218
|
this.#offlineMessageBuffer.length = 0;
|
|
219
|
+
this.connected = false;
|
|
220
|
+
this.reconnecting = false;
|
|
221
|
+
this.#connectCalled = false;
|
|
210
222
|
|
|
211
223
|
if (DISCONNECTED in this.#event_func){
|
|
212
224
|
if (this.#event_func[DISCONNECTED] !== null || this.#event_func[DISCONNECTED] !== undefined){
|
|
@@ -224,12 +236,6 @@ export class Realtime {
|
|
|
224
236
|
this.#log(`client disconnected - ${s.data}`);
|
|
225
237
|
|
|
226
238
|
this.connected = false;
|
|
227
|
-
|
|
228
|
-
if (DISCONNECTED in this.#event_func){
|
|
229
|
-
if (this.#event_func[DISCONNECTED] !== null || this.#event_func[DISCONNECTED] !== undefined){
|
|
230
|
-
this.#event_func[DISCONNECTED]()
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
239
|
break;
|
|
234
240
|
case Events.LDM:
|
|
235
241
|
this.#log("client has been requested to reconnect");
|
|
@@ -259,6 +265,7 @@ export class Realtime {
|
|
|
259
265
|
this.#log("client is attempting to reconnect");
|
|
260
266
|
|
|
261
267
|
this.reconnecting = true;
|
|
268
|
+
this.connected = false;
|
|
262
269
|
|
|
263
270
|
if(RECONNECT in this.#event_func && this.reconnecting){
|
|
264
271
|
this.#event_func[RECONNECT](this.#RECONNECTING);
|
|
@@ -276,6 +283,13 @@ export class Realtime {
|
|
|
276
283
|
// Subscribe to topics
|
|
277
284
|
this.#subscribeToTopics();
|
|
278
285
|
this.#log("Subscribed to topics");
|
|
286
|
+
|
|
287
|
+
// Callback on client side
|
|
288
|
+
if (CONNECTED in this.#event_func){
|
|
289
|
+
if (this.#event_func[CONNECTED] !== null || this.#event_func[CONNECTED] !== undefined){
|
|
290
|
+
this.#event_func[CONNECTED]()
|
|
291
|
+
}
|
|
292
|
+
}
|
|
279
293
|
}
|
|
280
294
|
}
|
|
281
295
|
|
|
@@ -286,10 +300,11 @@ export class Realtime {
|
|
|
286
300
|
if(this.#natsClient !== null){
|
|
287
301
|
this.reconnected = false;
|
|
288
302
|
this.disconnected = true;
|
|
303
|
+
this.#connectCalled = false;
|
|
289
304
|
|
|
290
305
|
this.#offlineMessageBuffer.length = 0;
|
|
291
306
|
|
|
292
|
-
await this.#
|
|
307
|
+
await this.#deleteAllConsumers();
|
|
293
308
|
|
|
294
309
|
this.#natsClient.close();
|
|
295
310
|
}else{
|
|
@@ -301,8 +316,20 @@ export class Realtime {
|
|
|
301
316
|
* Start consumers for topics initialized by user
|
|
302
317
|
*/
|
|
303
318
|
async #subscribeToTopics(){
|
|
304
|
-
|
|
305
|
-
|
|
319
|
+
this.#topicMap.forEach(async (topic) => {
|
|
320
|
+
// Subscribe to stream
|
|
321
|
+
await this.#startConsumer(topic);
|
|
322
|
+
});
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
/**
|
|
326
|
+
* Delete consumers for topics initialized by user
|
|
327
|
+
*/
|
|
328
|
+
async #deleteAllConsumers(){
|
|
329
|
+
for(let i = 0; i < this.#topicMap.length; i++){
|
|
330
|
+
let topic = this.#topicMap[i];
|
|
331
|
+
|
|
332
|
+
await this.#deleteConsumer(topic);
|
|
306
333
|
}
|
|
307
334
|
}
|
|
308
335
|
|
|
@@ -324,6 +351,8 @@ export class Realtime {
|
|
|
324
351
|
this.#topicMap = this.#topicMap.filter(item => item !== topic);
|
|
325
352
|
|
|
326
353
|
delete this.#event_func[topic];
|
|
354
|
+
|
|
355
|
+
return await this.#deleteConsumer(topic);
|
|
327
356
|
}
|
|
328
357
|
|
|
329
358
|
/**
|
|
@@ -349,31 +378,23 @@ export class Realtime {
|
|
|
349
378
|
throw new Error(`Expected $topic type -> string. Instead receieved -> ${typeof topic}`);
|
|
350
379
|
}
|
|
351
380
|
|
|
352
|
-
if(
|
|
353
|
-
this.#event_func[topic] = func;
|
|
354
|
-
}else{
|
|
381
|
+
if(topic in this.#event_func || this.#topicMap.includes(topic)){
|
|
355
382
|
return false
|
|
356
383
|
}
|
|
357
384
|
|
|
358
|
-
|
|
359
|
-
this.#RECONNECTING, this.#RECONN_FAIL, MESSAGE_RESEND, SERVER_DISCONNECT].includes(topic)){
|
|
360
|
-
if(!this.isTopicValid(topic)){
|
|
361
|
-
// We have an invalid topic, lets remove it
|
|
362
|
-
if(topic in this.#event_func){
|
|
363
|
-
delete this.#event_func[topic];
|
|
364
|
-
}
|
|
385
|
+
this.#event_func[topic] = func;
|
|
365
386
|
|
|
366
|
-
|
|
367
|
-
|
|
387
|
+
if (!this.#reservedSystemTopics.includes(topic)){
|
|
388
|
+
if(!this.isTopicValid(topic)){
|
|
389
|
+
throw new Error("Invalid topic, use isTopicValid($topic) to validate topic")
|
|
390
|
+
}
|
|
368
391
|
|
|
369
|
-
|
|
370
|
-
this.#topicMap.push(topic);
|
|
371
|
-
}
|
|
392
|
+
this.#topicMap.push(topic);
|
|
372
393
|
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
394
|
+
if(this.connected){
|
|
395
|
+
// Connected we need to create a topic in a stream
|
|
396
|
+
await this.#startConsumer(topic);
|
|
397
|
+
}
|
|
377
398
|
}
|
|
378
399
|
|
|
379
400
|
return true;
|
|
@@ -403,7 +424,7 @@ export class Realtime {
|
|
|
403
424
|
throw new Error("Invalid topic, use isTopicValid($topic) to validate topic")
|
|
404
425
|
}
|
|
405
426
|
|
|
406
|
-
if(!this
|
|
427
|
+
if(!this.isMessageValid(data)){
|
|
407
428
|
throw new Error("$message must be JSON, string or number")
|
|
408
429
|
}
|
|
409
430
|
|
|
@@ -418,15 +439,9 @@ export class Realtime {
|
|
|
418
439
|
"start": Date.now()
|
|
419
440
|
}
|
|
420
441
|
|
|
421
|
-
this.#log("Encoding message via msg pack...")
|
|
422
|
-
var encodedMessage = encode(message);
|
|
423
|
-
|
|
424
442
|
if(this.connected){
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
}else{
|
|
428
|
-
this.#log(`${topic} exists locally, moving on...`)
|
|
429
|
-
}
|
|
443
|
+
this.#log("Encoding message via msg pack...")
|
|
444
|
+
var encodedMessage = encode(message);
|
|
430
445
|
|
|
431
446
|
this.#log(`Publishing to topic => ${this.#getStreamTopic(topic)}`)
|
|
432
447
|
|
|
@@ -453,7 +468,6 @@ export class Realtime {
|
|
|
453
468
|
* @param {string} topic
|
|
454
469
|
*/
|
|
455
470
|
async history(topic, start, end){
|
|
456
|
-
this.#log(start)
|
|
457
471
|
if(topic == null || topic == undefined){
|
|
458
472
|
throw new Error("$topic is null or undefined");
|
|
459
473
|
}
|
|
@@ -490,11 +504,16 @@ export class Realtime {
|
|
|
490
504
|
end = end.toISOString();
|
|
491
505
|
}
|
|
492
506
|
|
|
507
|
+
if(!this.connected){
|
|
508
|
+
return [];
|
|
509
|
+
}
|
|
510
|
+
|
|
493
511
|
var opts = {
|
|
494
|
-
name:
|
|
512
|
+
name: `webjs_${topic}_${uuidv4()}_history_consumer`,
|
|
495
513
|
filter_subjects: [this.#getStreamTopic(topic)],
|
|
496
514
|
replay_policy: ReplayPolicy.Instant,
|
|
497
515
|
opt_start_time: start,
|
|
516
|
+
delivery_policy: DeliverPolicy.StartTime,
|
|
498
517
|
ack_policy: AckPolicy.Explicit,
|
|
499
518
|
}
|
|
500
519
|
|
|
@@ -523,7 +542,12 @@ export class Realtime {
|
|
|
523
542
|
var data = decode(msg.data);
|
|
524
543
|
this.#log(data);
|
|
525
544
|
|
|
526
|
-
history.push(
|
|
545
|
+
history.push({
|
|
546
|
+
"id": data.id,
|
|
547
|
+
"topic": data.room,
|
|
548
|
+
"message": data.message,
|
|
549
|
+
"timestamp": msg.timestamp
|
|
550
|
+
});
|
|
527
551
|
}
|
|
528
552
|
|
|
529
553
|
var del = await consumer.delete();
|
|
@@ -571,46 +595,42 @@ export class Realtime {
|
|
|
571
595
|
* @param {string} topic
|
|
572
596
|
*/
|
|
573
597
|
async #startConsumer(topic){
|
|
574
|
-
|
|
575
|
-
return;
|
|
576
|
-
}
|
|
577
|
-
|
|
578
|
-
this.#log(`Starting consumer for topic: ${topic}_${uuidv4()}`)
|
|
598
|
+
const consumerName = `webjs_${topic}_${uuidv4()}_consumer`;
|
|
579
599
|
|
|
580
600
|
var opts = {
|
|
581
|
-
name:
|
|
582
|
-
filter_subjects: [this.#getStreamTopic(
|
|
601
|
+
name: consumerName,
|
|
602
|
+
filter_subjects: [this.#getStreamTopic(topic)],
|
|
583
603
|
replay_policy: ReplayPolicy.Instant,
|
|
584
604
|
opt_start_time: new Date(),
|
|
585
605
|
ack_policy: AckPolicy.Explicit,
|
|
586
606
|
delivery_policy: DeliverPolicy.New
|
|
587
607
|
}
|
|
588
608
|
|
|
589
|
-
|
|
609
|
+
const consumer = await this.#jetstream.consumers.get(this.#getStreamName(), opts);
|
|
590
610
|
this.#log(this.#topicMap)
|
|
591
611
|
|
|
592
|
-
|
|
612
|
+
this.#consumerMap[topic] = consumer;
|
|
613
|
+
|
|
614
|
+
await consumer.consume({
|
|
593
615
|
callback: async (msg) => {
|
|
594
616
|
try{
|
|
595
617
|
const now = Date.now();
|
|
618
|
+
msg.working()
|
|
596
619
|
this.#log("Decoding msgpack message...")
|
|
597
620
|
var data = decode(msg.data);
|
|
598
621
|
|
|
599
|
-
var
|
|
622
|
+
var msgTopic = this.#stripStreamHash(msg.subject);
|
|
600
623
|
|
|
601
624
|
this.#log(data);
|
|
602
625
|
|
|
603
626
|
// Push topic message to main thread
|
|
604
627
|
if (data.client_id != this.#getClientId()){
|
|
605
|
-
var
|
|
606
|
-
this.#log(topics)
|
|
607
|
-
|
|
608
|
-
for(let i = 0; i < topics.length; i++){
|
|
609
|
-
var top = topics[i];
|
|
628
|
+
var topicMatch = this.#topicPatternMatcher(topic, msgTopic)
|
|
610
629
|
|
|
611
|
-
|
|
630
|
+
if(topicMatch){
|
|
631
|
+
this.#event_func[topic]({
|
|
612
632
|
"id": data.id,
|
|
613
|
-
"topic":
|
|
633
|
+
"topic": msgTopic,
|
|
614
634
|
"data": data.message
|
|
615
635
|
});
|
|
616
636
|
}
|
|
@@ -632,15 +652,20 @@ export class Realtime {
|
|
|
632
652
|
* Deletes consumer
|
|
633
653
|
* @param {string} topic
|
|
634
654
|
*/
|
|
635
|
-
async #deleteConsumer(){
|
|
655
|
+
async #deleteConsumer(topic){
|
|
656
|
+
this.#log(topic)
|
|
657
|
+
const consumer = this.#consumerMap[topic]
|
|
658
|
+
|
|
636
659
|
var del = false;
|
|
637
660
|
|
|
638
|
-
if (
|
|
639
|
-
del = await
|
|
661
|
+
if (consumer != null && consumer != undefined){
|
|
662
|
+
del = await consumer.delete();
|
|
640
663
|
}else{
|
|
641
664
|
del = false
|
|
642
665
|
}
|
|
643
666
|
|
|
667
|
+
delete this.#consumerMap[topic];
|
|
668
|
+
|
|
644
669
|
return del;
|
|
645
670
|
}
|
|
646
671
|
|
|
@@ -650,11 +675,6 @@ export class Realtime {
|
|
|
650
675
|
return;
|
|
651
676
|
}
|
|
652
677
|
|
|
653
|
-
if(this.#latency.length >= 100){
|
|
654
|
-
this.#log("Latency array is full, skipping log");
|
|
655
|
-
return;
|
|
656
|
-
}
|
|
657
|
-
|
|
658
678
|
const timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
659
679
|
|
|
660
680
|
this.#log(`Timezone: ${timeZone}`);
|
|
@@ -671,7 +691,7 @@ export class Realtime {
|
|
|
671
691
|
this.#latencyPush = setTimeout(async () => {
|
|
672
692
|
this.#log("setTimeout called");
|
|
673
693
|
|
|
674
|
-
if(this.#latency.length > 0){
|
|
694
|
+
if(this.#latency.length > 0 && this.connected && !this.#isSendingLatency){
|
|
675
695
|
this.#log("Push from setTimeout")
|
|
676
696
|
await this.#pushLatencyData({
|
|
677
697
|
timezone: timeZone,
|
|
@@ -684,7 +704,7 @@ export class Realtime {
|
|
|
684
704
|
}, 30000);
|
|
685
705
|
}
|
|
686
706
|
|
|
687
|
-
if(this.#latency.length
|
|
707
|
+
if(this.#latency.length >= 100 && !this.#isSendingLatency){
|
|
688
708
|
this.#log("Push from Length Check: " + this.#latency.length);
|
|
689
709
|
await this.#pushLatencyData({
|
|
690
710
|
timezone: timeZone,
|
|
@@ -740,8 +760,7 @@ export class Realtime {
|
|
|
740
760
|
*/
|
|
741
761
|
isTopicValid(topic){
|
|
742
762
|
if(topic !== null && topic !== undefined && (typeof topic) == "string"){
|
|
743
|
-
var arrayCheck = !
|
|
744
|
-
this.#RECONNECTING, this.#RECONN_FAIL, MESSAGE_RESEND, SERVER_DISCONNECT].includes(topic);
|
|
763
|
+
var arrayCheck = !this.#reservedSystemTopics.includes(topic);
|
|
745
764
|
|
|
746
765
|
const TOPIC_REGEX = /^(?!.*\$)(?:[A-Za-z0-9_*~-]+(?:\.[A-Za-z0-9_*~-]+)*(?:\.>)?|>)$/u;
|
|
747
766
|
|
|
@@ -753,7 +772,7 @@ export class Realtime {
|
|
|
753
772
|
}
|
|
754
773
|
}
|
|
755
774
|
|
|
756
|
-
|
|
775
|
+
isMessageValid(message){
|
|
757
776
|
if(message == null || message == undefined){
|
|
758
777
|
throw new Error("$message cannot be null / undefined")
|
|
759
778
|
}
|