relayx-webjs 1.0.2 → 1.0.3
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/example/chat-app/package.json +2 -1
- package/example/stand-alone/example_chat.js +111 -0
- package/package.json +1 -1
- package/realtime/dns_change.js +20 -0
- package/realtime/realtime.js +113 -92
|
@@ -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
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import dns from 'node:dns';
|
|
2
|
+
|
|
3
|
+
export function initDNSSpoof(){
|
|
4
|
+
const originalLookup = dns.lookup;
|
|
5
|
+
|
|
6
|
+
// Override for the whole process
|
|
7
|
+
dns.lookup = function patchedLookup(hostname, options, callback) {
|
|
8
|
+
|
|
9
|
+
// ── Our one special case ──────────────────────────────────
|
|
10
|
+
if (hostname === 'api2.relay-x.io') {
|
|
11
|
+
// Map to loop‑back; family 4 avoids ::1
|
|
12
|
+
return process.nextTick(() =>
|
|
13
|
+
callback(null, [{address: '127.0.0.1', family: 4}])
|
|
14
|
+
);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// Anything else → real DNS
|
|
18
|
+
return originalLookup.call(dns, hostname, options, callback);
|
|
19
|
+
};
|
|
20
|
+
}
|
package/realtime/realtime.js
CHANGED
|
@@ -2,6 +2,7 @@ import { connect, JSONCodec, Events, DebugEvents, AckPolicy, ReplayPolicy, creds
|
|
|
2
2
|
import { DeliverPolicy, jetstream } from "@nats-io/jetstream";
|
|
3
3
|
import { encode, decode } from "@msgpack/msgpack";
|
|
4
4
|
import { v4 as uuidv4 } from 'uuid';
|
|
5
|
+
import { initDNSSpoof } from "./dns_change.js";
|
|
5
6
|
|
|
6
7
|
export class Realtime {
|
|
7
8
|
|
|
@@ -21,6 +22,8 @@ export class Realtime {
|
|
|
21
22
|
#RECONNECTED = "RECONNECTED";
|
|
22
23
|
#RECONN_FAIL = "RECONN_FAIL";
|
|
23
24
|
|
|
25
|
+
#reservedSystemTopics = [CONNECTED, DISCONNECTED, RECONNECT, this.#RECONNECTED, this.#RECONNECTING, this.#RECONN_FAIL, MESSAGE_RESEND, SERVER_DISCONNECT];
|
|
26
|
+
|
|
24
27
|
setRemoteUserAttempts = 0;
|
|
25
28
|
setRemoteUserRetries = 5;
|
|
26
29
|
|
|
@@ -40,6 +43,8 @@ export class Realtime {
|
|
|
40
43
|
|
|
41
44
|
#maxPublishRetries = 5;
|
|
42
45
|
|
|
46
|
+
#connectCalled = false;
|
|
47
|
+
|
|
43
48
|
constructor(config){
|
|
44
49
|
if(typeof config != "object"){
|
|
45
50
|
throw new Error("Realtime($config). $config not object => {}")
|
|
@@ -95,10 +100,13 @@ export class Realtime {
|
|
|
95
100
|
if(arguments[0] instanceof Object){
|
|
96
101
|
opts = arguments[0];
|
|
97
102
|
staging = false;
|
|
98
|
-
}else{
|
|
103
|
+
}else if(typeof arguments[0] == "boolean"){
|
|
99
104
|
opts = {};
|
|
100
105
|
staging = arguments[0];
|
|
101
106
|
this.#log(staging)
|
|
107
|
+
}else{
|
|
108
|
+
opts = {};
|
|
109
|
+
staging = false
|
|
102
110
|
}
|
|
103
111
|
}else{
|
|
104
112
|
staging = false;
|
|
@@ -108,23 +116,28 @@ export class Realtime {
|
|
|
108
116
|
this.staging = staging;
|
|
109
117
|
this.opts = opts;
|
|
110
118
|
|
|
111
|
-
if
|
|
112
|
-
this.#baseUrl =
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
119
|
+
if(process.env.PROXY){
|
|
120
|
+
this.#baseUrl = ["wss://api2.relay-x.io:8666"];
|
|
121
|
+
initDNSSpoof();
|
|
122
|
+
}else{
|
|
123
|
+
if (staging !== undefined || staging !== null){
|
|
124
|
+
this.#baseUrl = staging ? [
|
|
125
|
+
"nats://0.0.0.0:4421",
|
|
126
|
+
"nats://0.0.0.0:4422",
|
|
127
|
+
"nats://0.0.0.0:4423"
|
|
128
|
+
] :
|
|
129
|
+
[
|
|
130
|
+
`wss://api.relay-x.io:4421`,
|
|
131
|
+
`wss://api.relay-x.io:4422`,
|
|
132
|
+
`wss://api.relay-x.io:4423`
|
|
133
|
+
];
|
|
134
|
+
}else{
|
|
135
|
+
this.#baseUrl = [
|
|
118
136
|
`wss://api.relay-x.io:4421`,
|
|
119
137
|
`wss://api.relay-x.io:4422`,
|
|
120
138
|
`wss://api.relay-x.io:4423`
|
|
121
139
|
];
|
|
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
|
-
];
|
|
140
|
+
}
|
|
128
141
|
}
|
|
129
142
|
|
|
130
143
|
this.#log(this.#baseUrl);
|
|
@@ -164,6 +177,10 @@ export class Realtime {
|
|
|
164
177
|
* Connects to the relay network
|
|
165
178
|
*/
|
|
166
179
|
async connect(){
|
|
180
|
+
if(this.#connectCalled){
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
|
|
167
184
|
this.SEVER_URL = this.#baseUrl;
|
|
168
185
|
|
|
169
186
|
var credsFile = this.#getUserCreds(this.api_key, this.secret)
|
|
@@ -178,7 +195,7 @@ export class Realtime {
|
|
|
178
195
|
maxReconnectAttempts: 1200,
|
|
179
196
|
reconnectTimeWait: 1000,
|
|
180
197
|
authenticator: credsAuth,
|
|
181
|
-
token: this.api_key
|
|
198
|
+
token: this.api_key
|
|
182
199
|
});
|
|
183
200
|
|
|
184
201
|
this.#jetstream = await jetstream(this.#natsClient);
|
|
@@ -186,6 +203,7 @@ export class Realtime {
|
|
|
186
203
|
await this.#getNameSpace()
|
|
187
204
|
|
|
188
205
|
this.connected = true;
|
|
206
|
+
this.#connectCalled = true;
|
|
189
207
|
}catch(err){
|
|
190
208
|
this.#log("ERR")
|
|
191
209
|
this.#log(err);
|
|
@@ -196,17 +214,13 @@ export class Realtime {
|
|
|
196
214
|
if (this.connected == true){
|
|
197
215
|
this.#log("Connected to server!");
|
|
198
216
|
|
|
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
217
|
this.#natsClient.closed().then(() => {
|
|
207
218
|
this.#log("the connection closed!");
|
|
208
219
|
|
|
209
220
|
this.#offlineMessageBuffer.length = 0;
|
|
221
|
+
this.connected = false;
|
|
222
|
+
this.reconnecting = false;
|
|
223
|
+
this.#connectCalled = false;
|
|
210
224
|
|
|
211
225
|
if (DISCONNECTED in this.#event_func){
|
|
212
226
|
if (this.#event_func[DISCONNECTED] !== null || this.#event_func[DISCONNECTED] !== undefined){
|
|
@@ -224,12 +238,6 @@ export class Realtime {
|
|
|
224
238
|
this.#log(`client disconnected - ${s.data}`);
|
|
225
239
|
|
|
226
240
|
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
241
|
break;
|
|
234
242
|
case Events.LDM:
|
|
235
243
|
this.#log("client has been requested to reconnect");
|
|
@@ -259,6 +267,7 @@ export class Realtime {
|
|
|
259
267
|
this.#log("client is attempting to reconnect");
|
|
260
268
|
|
|
261
269
|
this.reconnecting = true;
|
|
270
|
+
this.connected = false;
|
|
262
271
|
|
|
263
272
|
if(RECONNECT in this.#event_func && this.reconnecting){
|
|
264
273
|
this.#event_func[RECONNECT](this.#RECONNECTING);
|
|
@@ -276,6 +285,13 @@ export class Realtime {
|
|
|
276
285
|
// Subscribe to topics
|
|
277
286
|
this.#subscribeToTopics();
|
|
278
287
|
this.#log("Subscribed to topics");
|
|
288
|
+
|
|
289
|
+
// Callback on client side
|
|
290
|
+
if (CONNECTED in this.#event_func){
|
|
291
|
+
if (this.#event_func[CONNECTED] !== null || this.#event_func[CONNECTED] !== undefined){
|
|
292
|
+
this.#event_func[CONNECTED]()
|
|
293
|
+
}
|
|
294
|
+
}
|
|
279
295
|
}
|
|
280
296
|
}
|
|
281
297
|
|
|
@@ -286,10 +302,11 @@ export class Realtime {
|
|
|
286
302
|
if(this.#natsClient !== null){
|
|
287
303
|
this.reconnected = false;
|
|
288
304
|
this.disconnected = true;
|
|
305
|
+
this.#connectCalled = false;
|
|
289
306
|
|
|
290
307
|
this.#offlineMessageBuffer.length = 0;
|
|
291
308
|
|
|
292
|
-
await this.#
|
|
309
|
+
await this.#deleteAllConsumers();
|
|
293
310
|
|
|
294
311
|
this.#natsClient.close();
|
|
295
312
|
}else{
|
|
@@ -301,8 +318,20 @@ export class Realtime {
|
|
|
301
318
|
* Start consumers for topics initialized by user
|
|
302
319
|
*/
|
|
303
320
|
async #subscribeToTopics(){
|
|
304
|
-
|
|
305
|
-
|
|
321
|
+
this.#topicMap.forEach(async (topic) => {
|
|
322
|
+
// Subscribe to stream
|
|
323
|
+
await this.#startConsumer(topic);
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
/**
|
|
328
|
+
* Delete consumers for topics initialized by user
|
|
329
|
+
*/
|
|
330
|
+
async #deleteAllConsumers(){
|
|
331
|
+
for(let i = 0; i < this.#topicMap.length; i++){
|
|
332
|
+
let topic = this.#topicMap[i];
|
|
333
|
+
|
|
334
|
+
await this.#deleteConsumer(topic);
|
|
306
335
|
}
|
|
307
336
|
}
|
|
308
337
|
|
|
@@ -324,6 +353,8 @@ export class Realtime {
|
|
|
324
353
|
this.#topicMap = this.#topicMap.filter(item => item !== topic);
|
|
325
354
|
|
|
326
355
|
delete this.#event_func[topic];
|
|
356
|
+
|
|
357
|
+
return await this.#deleteConsumer(topic);
|
|
327
358
|
}
|
|
328
359
|
|
|
329
360
|
/**
|
|
@@ -349,31 +380,23 @@ export class Realtime {
|
|
|
349
380
|
throw new Error(`Expected $topic type -> string. Instead receieved -> ${typeof topic}`);
|
|
350
381
|
}
|
|
351
382
|
|
|
352
|
-
if(
|
|
353
|
-
this.#event_func[topic] = func;
|
|
354
|
-
}else{
|
|
383
|
+
if(topic in this.#event_func || this.#topicMap.includes(topic)){
|
|
355
384
|
return false
|
|
356
385
|
}
|
|
357
386
|
|
|
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
|
-
}
|
|
387
|
+
this.#event_func[topic] = func;
|
|
365
388
|
|
|
366
|
-
|
|
367
|
-
|
|
389
|
+
if (!this.#reservedSystemTopics.includes(topic)){
|
|
390
|
+
if(!this.isTopicValid(topic)){
|
|
391
|
+
throw new Error("Invalid topic, use isTopicValid($topic) to validate topic")
|
|
392
|
+
}
|
|
368
393
|
|
|
369
|
-
|
|
370
|
-
this.#topicMap.push(topic);
|
|
371
|
-
}
|
|
394
|
+
this.#topicMap.push(topic);
|
|
372
395
|
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
396
|
+
if(this.connected){
|
|
397
|
+
// Connected we need to create a topic in a stream
|
|
398
|
+
await this.#startConsumer(topic);
|
|
399
|
+
}
|
|
377
400
|
}
|
|
378
401
|
|
|
379
402
|
return true;
|
|
@@ -403,7 +426,7 @@ export class Realtime {
|
|
|
403
426
|
throw new Error("Invalid topic, use isTopicValid($topic) to validate topic")
|
|
404
427
|
}
|
|
405
428
|
|
|
406
|
-
if(!this
|
|
429
|
+
if(!this.isMessageValid(data)){
|
|
407
430
|
throw new Error("$message must be JSON, string or number")
|
|
408
431
|
}
|
|
409
432
|
|
|
@@ -418,15 +441,9 @@ export class Realtime {
|
|
|
418
441
|
"start": Date.now()
|
|
419
442
|
}
|
|
420
443
|
|
|
421
|
-
this.#log("Encoding message via msg pack...")
|
|
422
|
-
var encodedMessage = encode(message);
|
|
423
|
-
|
|
424
444
|
if(this.connected){
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
}else{
|
|
428
|
-
this.#log(`${topic} exists locally, moving on...`)
|
|
429
|
-
}
|
|
445
|
+
this.#log("Encoding message via msg pack...")
|
|
446
|
+
var encodedMessage = encode(message);
|
|
430
447
|
|
|
431
448
|
this.#log(`Publishing to topic => ${this.#getStreamTopic(topic)}`)
|
|
432
449
|
|
|
@@ -453,7 +470,6 @@ export class Realtime {
|
|
|
453
470
|
* @param {string} topic
|
|
454
471
|
*/
|
|
455
472
|
async history(topic, start, end){
|
|
456
|
-
this.#log(start)
|
|
457
473
|
if(topic == null || topic == undefined){
|
|
458
474
|
throw new Error("$topic is null or undefined");
|
|
459
475
|
}
|
|
@@ -490,11 +506,16 @@ export class Realtime {
|
|
|
490
506
|
end = end.toISOString();
|
|
491
507
|
}
|
|
492
508
|
|
|
509
|
+
if(!this.connected){
|
|
510
|
+
return [];
|
|
511
|
+
}
|
|
512
|
+
|
|
493
513
|
var opts = {
|
|
494
|
-
name:
|
|
514
|
+
name: `webjs_${topic}_${uuidv4()}_history_consumer`,
|
|
495
515
|
filter_subjects: [this.#getStreamTopic(topic)],
|
|
496
516
|
replay_policy: ReplayPolicy.Instant,
|
|
497
517
|
opt_start_time: start,
|
|
518
|
+
delivery_policy: DeliverPolicy.StartTime,
|
|
498
519
|
ack_policy: AckPolicy.Explicit,
|
|
499
520
|
}
|
|
500
521
|
|
|
@@ -523,7 +544,12 @@ export class Realtime {
|
|
|
523
544
|
var data = decode(msg.data);
|
|
524
545
|
this.#log(data);
|
|
525
546
|
|
|
526
|
-
history.push(
|
|
547
|
+
history.push({
|
|
548
|
+
"id": data.id,
|
|
549
|
+
"topic": data.room,
|
|
550
|
+
"message": data.message,
|
|
551
|
+
"timestamp": msg.timestamp
|
|
552
|
+
});
|
|
527
553
|
}
|
|
528
554
|
|
|
529
555
|
var del = await consumer.delete();
|
|
@@ -571,46 +597,42 @@ export class Realtime {
|
|
|
571
597
|
* @param {string} topic
|
|
572
598
|
*/
|
|
573
599
|
async #startConsumer(topic){
|
|
574
|
-
|
|
575
|
-
return;
|
|
576
|
-
}
|
|
577
|
-
|
|
578
|
-
this.#log(`Starting consumer for topic: ${topic}_${uuidv4()}`)
|
|
600
|
+
const consumerName = `webjs_${topic}_${uuidv4()}_consumer`;
|
|
579
601
|
|
|
580
602
|
var opts = {
|
|
581
|
-
name:
|
|
582
|
-
filter_subjects: [this.#getStreamTopic(
|
|
603
|
+
name: consumerName,
|
|
604
|
+
filter_subjects: [this.#getStreamTopic(topic)],
|
|
583
605
|
replay_policy: ReplayPolicy.Instant,
|
|
584
606
|
opt_start_time: new Date(),
|
|
585
607
|
ack_policy: AckPolicy.Explicit,
|
|
586
608
|
delivery_policy: DeliverPolicy.New
|
|
587
609
|
}
|
|
588
610
|
|
|
589
|
-
|
|
611
|
+
const consumer = await this.#jetstream.consumers.get(this.#getStreamName(), opts);
|
|
590
612
|
this.#log(this.#topicMap)
|
|
591
613
|
|
|
592
|
-
|
|
614
|
+
this.#consumerMap[topic] = consumer;
|
|
615
|
+
|
|
616
|
+
await consumer.consume({
|
|
593
617
|
callback: async (msg) => {
|
|
594
618
|
try{
|
|
595
619
|
const now = Date.now();
|
|
620
|
+
msg.working()
|
|
596
621
|
this.#log("Decoding msgpack message...")
|
|
597
622
|
var data = decode(msg.data);
|
|
598
623
|
|
|
599
|
-
var
|
|
624
|
+
var msgTopic = this.#stripStreamHash(msg.subject);
|
|
600
625
|
|
|
601
626
|
this.#log(data);
|
|
602
627
|
|
|
603
628
|
// Push topic message to main thread
|
|
604
629
|
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];
|
|
630
|
+
var topicMatch = this.#topicPatternMatcher(topic, msgTopic)
|
|
610
631
|
|
|
611
|
-
|
|
632
|
+
if(topicMatch){
|
|
633
|
+
this.#event_func[topic]({
|
|
612
634
|
"id": data.id,
|
|
613
|
-
"topic":
|
|
635
|
+
"topic": msgTopic,
|
|
614
636
|
"data": data.message
|
|
615
637
|
});
|
|
616
638
|
}
|
|
@@ -632,15 +654,20 @@ export class Realtime {
|
|
|
632
654
|
* Deletes consumer
|
|
633
655
|
* @param {string} topic
|
|
634
656
|
*/
|
|
635
|
-
async #deleteConsumer(){
|
|
657
|
+
async #deleteConsumer(topic){
|
|
658
|
+
this.#log(topic)
|
|
659
|
+
const consumer = this.#consumerMap[topic]
|
|
660
|
+
|
|
636
661
|
var del = false;
|
|
637
662
|
|
|
638
|
-
if (
|
|
639
|
-
del = await
|
|
663
|
+
if (consumer != null && consumer != undefined){
|
|
664
|
+
del = await consumer.delete();
|
|
640
665
|
}else{
|
|
641
666
|
del = false
|
|
642
667
|
}
|
|
643
668
|
|
|
669
|
+
delete this.#consumerMap[topic];
|
|
670
|
+
|
|
644
671
|
return del;
|
|
645
672
|
}
|
|
646
673
|
|
|
@@ -650,11 +677,6 @@ export class Realtime {
|
|
|
650
677
|
return;
|
|
651
678
|
}
|
|
652
679
|
|
|
653
|
-
if(this.#latency.length >= 100){
|
|
654
|
-
this.#log("Latency array is full, skipping log");
|
|
655
|
-
return;
|
|
656
|
-
}
|
|
657
|
-
|
|
658
680
|
const timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
659
681
|
|
|
660
682
|
this.#log(`Timezone: ${timeZone}`);
|
|
@@ -671,7 +693,7 @@ export class Realtime {
|
|
|
671
693
|
this.#latencyPush = setTimeout(async () => {
|
|
672
694
|
this.#log("setTimeout called");
|
|
673
695
|
|
|
674
|
-
if(this.#latency.length > 0){
|
|
696
|
+
if(this.#latency.length > 0 && this.connected && !this.#isSendingLatency){
|
|
675
697
|
this.#log("Push from setTimeout")
|
|
676
698
|
await this.#pushLatencyData({
|
|
677
699
|
timezone: timeZone,
|
|
@@ -684,7 +706,7 @@ export class Realtime {
|
|
|
684
706
|
}, 30000);
|
|
685
707
|
}
|
|
686
708
|
|
|
687
|
-
if(this.#latency.length
|
|
709
|
+
if(this.#latency.length >= 100 && !this.#isSendingLatency){
|
|
688
710
|
this.#log("Push from Length Check: " + this.#latency.length);
|
|
689
711
|
await this.#pushLatencyData({
|
|
690
712
|
timezone: timeZone,
|
|
@@ -740,8 +762,7 @@ export class Realtime {
|
|
|
740
762
|
*/
|
|
741
763
|
isTopicValid(topic){
|
|
742
764
|
if(topic !== null && topic !== undefined && (typeof topic) == "string"){
|
|
743
|
-
var arrayCheck = !
|
|
744
|
-
this.#RECONNECTING, this.#RECONN_FAIL, MESSAGE_RESEND, SERVER_DISCONNECT].includes(topic);
|
|
765
|
+
var arrayCheck = !this.#reservedSystemTopics.includes(topic);
|
|
745
766
|
|
|
746
767
|
const TOPIC_REGEX = /^(?!.*\$)(?:[A-Za-z0-9_*~-]+(?:\.[A-Za-z0-9_*~-]+)*(?:\.>)?|>)$/u;
|
|
747
768
|
|
|
@@ -753,7 +774,7 @@ export class Realtime {
|
|
|
753
774
|
}
|
|
754
775
|
}
|
|
755
776
|
|
|
756
|
-
|
|
777
|
+
isMessageValid(message){
|
|
757
778
|
if(message == null || message == undefined){
|
|
758
779
|
throw new Error("$message cannot be null / undefined")
|
|
759
780
|
}
|