@lmjs/core 1.0.6 → 2.0.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.
package/src/ws.js ADDED
@@ -0,0 +1,1162 @@
1
+ class AbstractWebSocket {
2
+ constructor(url, connectionTimeout = 5000) {
3
+ this.url = url;
4
+ this.socket = null;
5
+ this.reconnectInterval = 3000;
6
+ this.reconnectTimeout = null;
7
+ this.connectionTimeout = connectionTimeout;
8
+ this.connectionTimeoutId = null;
9
+ this.connected = false;
10
+ this.messageQueue = [];
11
+ }
12
+
13
+ connect() {
14
+ this.socket = new WebSocket(this.url);
15
+
16
+ this.connectionTimeoutId = setTimeout(() => {
17
+ this.handleConnectionTimeout();
18
+ }, this.connectionTimeout);
19
+
20
+ this.socket.onopen = () => {
21
+ clearTimeout(this.connectionTimeoutId);
22
+ this.connected = true;
23
+ this.onOpen();
24
+ this.processMessageQueue();
25
+ };
26
+
27
+ this.socket.onmessage = (event) => {
28
+ this.onMessage(event.data);
29
+ };
30
+
31
+ this.socket.onclose = (event) => {
32
+ clearTimeout(this.connectionTimeoutId);
33
+ this.connected = false;
34
+ this.onClose(event.code);
35
+ this.reconnect();
36
+ };
37
+
38
+ this.socket.onerror = (error) => {
39
+ clearTimeout(this.connectionTimeoutId);
40
+ this.onError(error);
41
+ };
42
+ }
43
+
44
+ send(message) {
45
+ cl("Sending ", message);
46
+ if (this.connected) {
47
+ this.socket.send(message);
48
+ } else {
49
+ this.messageQueue.push(message);
50
+ console.error("WebSocket is not open. Unable to send message.");
51
+ }
52
+ }
53
+
54
+ processMessageQueue() {
55
+ while (this.messageQueue.length > 0) {
56
+ const message = this.messageQueue.shift();
57
+ cl("Sending From Queue ", message);
58
+ this.socket.send(message);
59
+ }
60
+ }
61
+
62
+ handleConnectionTimeout() {
63
+ this.socket.close();
64
+ }
65
+
66
+ disconnect() {
67
+ if (this.socket) {
68
+ this.socket.close();
69
+ }
70
+ clearTimeout(this.reconnectTimeout);
71
+ }
72
+
73
+ onOpen() {
74
+ }
75
+
76
+ onMessage(message) {
77
+ }
78
+
79
+ onClose(code) {
80
+ }
81
+
82
+ onError(error) {
83
+ }
84
+
85
+ reconnect() {
86
+ clearTimeout(this.reconnectTimeout);
87
+ this.reconnectTimeout = setTimeout(() => {
88
+ this.connect();
89
+ }, this.reconnectInterval);
90
+ }
91
+ }
92
+
93
+ class MyWebSocket extends AbstractWebSocket {
94
+ constructor(url) {
95
+ super(url);
96
+ }
97
+
98
+ onOpen() {
99
+ super.onOpen();
100
+ }
101
+
102
+ onMessage(message) {
103
+ super.onMessage(message);
104
+ }
105
+
106
+ onClose(code) {
107
+ super.onClose(code);
108
+ // Additional logic specific to your WebSocket implementation
109
+ }
110
+
111
+ onError(error) {
112
+ super.onError(error);
113
+ // Additional logic specific to your WebSocket implementation
114
+ }
115
+ }
116
+
117
+ // // Create an instance of your WebSocket class and connect
118
+ // const myWebSocket = new MyWebSocket("wss://beaapis.com");
119
+ // myWebSocket.connect();
120
+
121
+ // // Send messages
122
+ // myWebSocket.send("Hello, WebSocket!");
123
+
124
+
125
+
126
+
127
+
128
+
129
+ class Nuclear {
130
+ _iter = 0;
131
+ reconnectAttempts = 0;
132
+ timeoutInterval = 4000;
133
+ cbs = {};
134
+ _cbs = {};
135
+ lstnrs = {};
136
+ _ws;
137
+ srvr = undefined;
138
+
139
+ constructor(srvr) {
140
+ this.srvr = srvr;
141
+
142
+ this.init();
143
+ return this;
144
+ }
145
+
146
+ on(e, cb) {
147
+ // _cbs = {
148
+ // persitstant: {
149
+ // cbs...
150
+ // }
151
+ // normal: {
152
+ // cbs...
153
+ // }
154
+ // }
155
+ // off does not delete persistant cbs
156
+ if (!this.lstnrs.hasOwnProperty(e)) this.lstnrs[e] = [];
157
+ this.lstnrs[e].push(cb);
158
+ if (e == "open" && this._ws?.readyState == 1) {
159
+ this.trigger("open", this._ws);
160
+ }
161
+ return this;
162
+ }
163
+
164
+ off(e) {
165
+ if (e == "connect") return this;
166
+ if (this.lstnrs.hasOwnProperty(e)) delete this.lstnrs[e];
167
+ return this;
168
+ }
169
+
170
+ subscribe(e, cb) {
171
+ return this.on(e, cb);
172
+ }
173
+
174
+ unsubscribe(e, cb) {
175
+ return this.off(e, cb);
176
+ }
177
+
178
+ trigger(n, e) {
179
+ if (this.lstnrs.hasOwnProperty(n)) {
180
+ for (let x = 0; x < this.lstnrs[n].length; x++) {
181
+ this.lstnrs[n][x](e);
182
+ }
183
+ }
184
+ return this;
185
+ }
186
+
187
+ emit(e, data, cb) {
188
+ try {
189
+ this._iter++;
190
+ if (cb) this.cbs["cb_" + this._iter] = cb;
191
+ if (this.ready()) {
192
+ this._ws.send(JSON.stringify({ e: e, payload: data, _iter: this._iter }));
193
+ } else {
194
+ this._send(JSON.stringify({ e: e, payload: data, _iter: this._iter }));
195
+ }
196
+ } catch (error) {
197
+ if (_debugMode) cl(error);
198
+ }
199
+ return this;
200
+ }
201
+
202
+ _emit(e, data) {
203
+ this._iter++;
204
+ let prom = defer();
205
+ this._cbs["cb_" + this._iter] = prom;
206
+ if (this.ready()) {
207
+ this._ws.send(JSON.stringify({ e: e, payload: data, _iter: this._iter }));
208
+ } else {
209
+ this._send(JSON.stringify({ e: e, payload: data, _iter: this._iter }));
210
+ }
211
+ return prom;
212
+ }
213
+
214
+ _send(m) {
215
+ let _s = this;
216
+ setTimeout(function () {
217
+ if (_s.ready()) _s._ws.send(m);
218
+ else _s._send(m);
219
+ }, 500);
220
+ }
221
+
222
+ ready() {
223
+ return this._ws !== undefined && this._ws.readyState == WebSocket.OPEN;
224
+ }
225
+
226
+ connecting() {
227
+ return this._ws !== undefined && this._ws.readyState == WebSocket.CONNECTING;
228
+ }
229
+
230
+ init() {
231
+ var _s = this;
232
+
233
+ // if (_s.ready() || _s.connecting()) {
234
+ // return;
235
+ // }
236
+
237
+ // if (_s.connecting()) {
238
+ // setTimeout(function () {
239
+ // if (_s.ready()) {
240
+
241
+ // } else _s.init();
242
+ // }, 500);
243
+ // return;
244
+ // }
245
+
246
+ this._ws = new ReconnectingWebSocket(this.srvr ? this.srvr : "wss://www.beaapis.com/");
247
+ this._ws.addEventListener("error", (event) => {
248
+ // console.log("WebSocket error: ", event);
249
+ return false;
250
+ });
251
+ // var localws = this._ws;
252
+ // var timeout = setTimeout(function () {
253
+ // _gn = 0;
254
+ // barSet(1, 200);
255
+ // if (!(_s.ready() || _s.connecting())) localws.close();
256
+ // }, this.timeoutInterval);
257
+
258
+ this._ws.onopen = function (e) {
259
+ // clearTimeout(timeout);
260
+ _s.trigger("connect", e);
261
+ _s.trigger("open", e);
262
+ };
263
+
264
+ this._ws.onclose = function (e) {
265
+ // clearTimeout(timeout);
266
+ // _s._ws = undefined;
267
+ _s._iter = 0;
268
+ _s.cbs = {};
269
+
270
+ _gn = 0;
271
+ barSet(1, 200);
272
+
273
+ // setTimeout(function () {
274
+ _s.reconnectAttempts++;
275
+ // _s.init();
276
+ // }, 1000);
277
+ };
278
+
279
+ this._ws.onmessage = function (e) {
280
+ try {
281
+ let data = JSON.parse(e.data);
282
+ if (data.hasOwnProperty("e")) {
283
+ let event = data["e"];
284
+ let iter = data["_iter"];
285
+ const customEvent = new CustomEvent(event, {
286
+ detail: data["payload"],
287
+ });
288
+ customEvent.data = data["payload"];
289
+ if (event != "rooms") _s.trigger(event, customEvent);
290
+ if (_s.cbs["cb_" + iter]) _s.cbs["cb_" + iter](customEvent);
291
+ // 2026-09-14, real bug found testing a real dev server
292
+ // end-to-end: this used to be unconditional
293
+ // (`_s._cbs["cb_" + iter].resolve(...)`), but `_cbs` is
294
+ // only ever populated by `_emit()` (the promise-based
295
+ // variant) — every plain `emit()` response hit
296
+ // `_cbs["cb_" + iter]` being undefined here and threw,
297
+ // silently swallowed by this function's own empty
298
+ // catch below. The real callback on the line above
299
+ // already ran by this point, so this specific crash
300
+ // wasn't blocking that callback — but it silently
301
+ // masked any OTHER error too (including a real bug in
302
+ // the caller's own callback), which is worse.
303
+ if (_s._cbs["cb_" + iter]) _s._cbs["cb_" + iter].resolve(customEvent);
304
+ }
305
+ } catch (e) { if (_debugMode) cl(e); }
306
+ };
307
+ this._ws.onerror = function (e) {
308
+ _gn = 0;
309
+ barSet(1, 200);
310
+ // if (_s._ws) {
311
+ // _s._ws.close();
312
+ // }
313
+ };
314
+ }
315
+ }
316
+
317
+ class _Ticker {
318
+ id = "";
319
+ tick = 1000;
320
+ duration = 10000;
321
+ data = {};
322
+ status = 'created';
323
+ user = undefined;
324
+ channel = undefined;
325
+ _cbs = {};
326
+
327
+ constructor(obj, channel, user) {
328
+
329
+ this.id = obj.id;
330
+ this.tick = obj?.tick ?? 1000;
331
+ this.duration = obj?.duration ?? 10000;
332
+ this.data = obj?.data ?? {};
333
+ this.user = user;
334
+ this.channel = channel;
335
+ this.user.id = this.user.id;
336
+ this.init();
337
+ return this;
338
+ }
339
+
340
+ init(opts, lstnrs) {
341
+
342
+ let t = this.tick;
343
+ let d = this.duration;
344
+ let data = this.data;
345
+ if (opts) {
346
+ if (opts.hasOwnProperty("tick")) t = opts.tick;
347
+ if (opts.hasOwnProperty("duration")) d = opts.duration;
348
+ if (opts.hasOwnProperty("data")) data = opts.data;
349
+ }
350
+
351
+ this.user.nuke.emit("subscribe", {
352
+ type: "ticker",
353
+ ticker: this.id,
354
+ channel: this.channel.id,
355
+ user: this.user.id,
356
+ data: {
357
+ tick: t,
358
+ duration: d,
359
+ data: data
360
+ }
361
+ });
362
+
363
+ if (!this.user.nuke._tickers.hasOwnProperty(this.channel.id))
364
+ this.user.nuke._tickers[this.channel.id] = {};
365
+ this.user.nuke._tickers[this.channel.id][this.id] = this;
366
+
367
+ if (!lstnrs) {
368
+ var self = this;
369
+
370
+ this.on("create.class", function (e) {
371
+ self.status = 'created';
372
+ });
373
+
374
+ this.on("start.class", function (e) {
375
+ self.status = 'started';
376
+ });
377
+
378
+ this.on("tick.class", function (e) {
379
+ self.status = 'started';
380
+ });
381
+
382
+ this.on("pause.class", function (e) {
383
+ self.status = 'paused';
384
+ });
385
+
386
+ this.on("finish.class", function (e) {
387
+ self.status = 'finished';
388
+ });
389
+ }
390
+ }
391
+
392
+ start() {
393
+ if (this.status == 'started') {
394
+ setError(null, `This ticker is already started`);
395
+ return this;
396
+ }
397
+
398
+ if (this.status == 'finished') {
399
+ setError(null, `This ticker is finished`);
400
+ return this;
401
+ }
402
+
403
+ this.user.nuke.emit("ticker", {
404
+ ticker: this.id,
405
+ channel: this.channel.id,
406
+ user: this.user.id,
407
+ ev: "start",
408
+ });
409
+ }
410
+
411
+ pause() {
412
+ if (this.status == 'paused') {
413
+ setError(null, `This ticker is already paused`);
414
+ return this;
415
+ }
416
+
417
+ if (this.status != 'started') {
418
+ setError(null, `This ticker is not started yet!`);
419
+ return this;
420
+ }
421
+
422
+ this.user.nuke.emit("ticker", {
423
+ ticker: this.id,
424
+ channel: this.channel.id,
425
+ user: this.user.id,
426
+ ev: "pause",
427
+ });
428
+ }
429
+
430
+ restart(opts) {
431
+ if (this.status != 'finished') {
432
+ setError(null, `This ticker is not finished yet!`);
433
+ return this;
434
+ }
435
+
436
+ this.init(opts, true);
437
+ }
438
+
439
+ delete() {
440
+ this.user.nuke.emit("unsubscribe", {
441
+ type: "ticker",
442
+ ticker: this.id,
443
+ channel: this.channel.id,
444
+ user: this.user.id,
445
+ ev: "delete",
446
+ });
447
+
448
+ // This must be in the then
449
+
450
+ // this = undefined;
451
+ // if (this.user.nuke._tickers.hasOwnProperty(this.channel.id)) {
452
+ // delete this.user.nuke._tickers[this.channel.id][this.id];
453
+ // }
454
+
455
+ }
456
+
457
+ extend(t) {
458
+ this.user.nuke.emit("ticker", {
459
+ ticker: this.id,
460
+ channel: this.channel.id,
461
+ user: this.user.id,
462
+ ev: "extend",
463
+ data: {
464
+ time: t
465
+ }
466
+ });
467
+ }
468
+
469
+ on(e, cb) {
470
+ let myRef2 = document.createElement("live");
471
+ myRef2.dataset['cb'] = cb;
472
+ document.body.append(myRef2);
473
+ if (this._cbs.hasOwnProperty(e)) {
474
+ this._cbs[e].push(cb);
475
+ } else this._cbs[e] = [cb];
476
+ return this;
477
+ }
478
+
479
+ off(e) {
480
+ if (this._cbs.hasOwnProperty(e)) delete this._cbs[e];
481
+ return this;
482
+ }
483
+
484
+ trigger(e, customEvent) {
485
+ if (this._cbs.hasOwnProperty(e)) {
486
+ for (let i = 0; i < this._cbs[e].length; i++) {
487
+ const cb = this._cbs[e][i];
488
+ cb(customEvent);
489
+ }
490
+ }
491
+ return this;
492
+ }
493
+
494
+ }
495
+
496
+ class _Channel {
497
+ id = "/";
498
+ user = undefined;
499
+ type = "room";
500
+ _cbs = {};
501
+
502
+ constructor(id, type, user) {
503
+ this.id = id;
504
+ this.type = type;
505
+ this.user = user;
506
+ this.user.id = this.user.id ?? "Guest";
507
+ return this;
508
+ }
509
+
510
+ trigger(e, customEvent) {
511
+ if (this._cbs.hasOwnProperty(e)) {
512
+ for (let i = 0; i < this._cbs[e].length; i++) {
513
+ const cb = this._cbs[e][i];
514
+ cb(customEvent);
515
+ }
516
+ }
517
+ return this;
518
+ }
519
+
520
+ join() {
521
+ this.user.nuke.emit("subscribe", {
522
+ type: this.type,
523
+ channel: this.id,
524
+ user: this.user.id,
525
+ });
526
+
527
+ if (!this.user.nuke._chnls.hasOwnProperty(this.user.id))
528
+ this.user.nuke._chnls[this.user.id] = {};
529
+ this.user.nuke._chnls[this.user.id][this.id] = this;
530
+ }
531
+
532
+ leave() {
533
+ this.user.nuke.emit("unsubscribe", {
534
+ type: this.type,
535
+ channel: this.id,
536
+ user: this.user.id,
537
+ ev: "leave",
538
+ });
539
+ if (this.user.nuke._chnls.hasOwnProperty(this.user.id)) {
540
+ delete this.user.nuke._chnls[this.user.id][this.id];
541
+ }
542
+ }
543
+
544
+ broadcast(ev, options) {
545
+ this.user.nuke.emit("broadcast", {
546
+ type: "room",
547
+ channel: this.id,
548
+ user: this.user.id,
549
+ ev: ev,
550
+ includeMe: options?.includeMe ?? true,
551
+ data: options?.data ?? {},
552
+ });
553
+ }
554
+
555
+ off(e) {
556
+ if (e == "connect") return this;
557
+ if (this._cbs.hasOwnProperty(e)) delete this._cbs[e];
558
+ return this;
559
+ }
560
+
561
+ on(e, cb) {
562
+ let myRef2 = document.createElement("live");
563
+ myRef2.dataset['cb'] = cb;
564
+ document.body.append(myRef2);
565
+ if (this._cbs.hasOwnProperty(e)) {
566
+ this._cbs[e].push(cb);
567
+ } else this._cbs[e] = [cb];
568
+ return this;
569
+ }
570
+
571
+ createTicker(obj) {
572
+ if (!this.user.nuke._tickers.hasOwnProperty(this.id)) {
573
+ this.user.nuke._tickers[this.id] = {};
574
+ }
575
+
576
+ // if (this.user.nuke._tickers[this.id].hasOwnProperty(obj.id)) {
577
+ // setError(null, `This ticker already exsists`);
578
+ // return this.user.nuke._tickers[this.id][obj.id];
579
+ // }
580
+
581
+ let t = new _Ticker(obj, this, this.user);
582
+ return t;
583
+ }
584
+
585
+ getTicker(id) {
586
+ this.user.nuke.emit("get", {
587
+ type: "ticker",
588
+ channel: this.id,
589
+ user: this.user.id,
590
+ ticker: id
591
+ });
592
+ }
593
+ }
594
+
595
+ class _User {
596
+ id = "";
597
+ nuke = undefined;
598
+ _cbs = {};
599
+
600
+ constructor(id, nuke) {
601
+ this.id = id;
602
+ this.nuke = nuke;
603
+ this.init();
604
+ return this;
605
+ }
606
+ init() {
607
+ this.nuke.emit("subscribe", {
608
+ type: "user",
609
+ channel: this.id,
610
+ user: this.id,
611
+ });
612
+ if (!this.nuke._users.hasOwnProperty("/" + this.id))
613
+ this.nuke._users["/" + this.id] = this;
614
+ }
615
+
616
+ on(e, cb) {
617
+ if (this.nuke._users["/" + this.id]._cbs.hasOwnProperty(e)) {
618
+ this.nuke._users["/" + this.id]._cbs[e].push(cb);
619
+ } else this.nuke._users["/" + this.id]._cbs[e] = [cb];
620
+ return this;
621
+ }
622
+
623
+ off(e) {
624
+ if (this._cbs.hasOwnProperty(e)) delete this._cbs[e];
625
+ return this;
626
+ }
627
+
628
+ broadcast(ev, options) {
629
+ this.nuke.emit("broadcast", {
630
+ type: "user",
631
+ channel: this.id,
632
+ user: this.id,
633
+ ev: ev,
634
+ includeMe: options?.includeMe ?? true,
635
+ data: options?.data ?? {},
636
+ });
637
+ }
638
+
639
+ trigger(e, customEvent) {
640
+ if (this._cbs.hasOwnProperty(e)) {
641
+ for (let i = 0; i < this._cbs[e].length; i++) {
642
+ const cb = this._cbs[e][i];
643
+ cb(customEvent);
644
+ }
645
+ }
646
+ return this;
647
+ }
648
+
649
+ _broadcastToAll(IDs, e, d, t) {
650
+ this.nuke.emit("broadcast", {
651
+ type: t == "u" ? "user" : "room",
652
+ user: this.id,
653
+ ev: e,
654
+ includeMe: d["includeMe"] ?? true,
655
+ data: d["data"],
656
+ ...(t == "u" ? { users: IDs.join(",") } : { channels: IDs.join(",") }),
657
+ });
658
+ }
659
+
660
+ broadcastToUsers(uIDs, e, d) {
661
+ this._broadcastToAll(uIDs, e, d, "u");
662
+ }
663
+
664
+ broadcastToChannels(cIDs, e, d) {
665
+ this._broadcastToAll(cIDs, e, d, "c");
666
+ }
667
+
668
+ unsubscribe(c) {
669
+ if (this.nuke._chnls.hasOwnProperty(this.id)) {
670
+ if (this.nuke._chnls[this.id].hasOwnProperty(c))
671
+ this.nuke._chnls[this.id][c].leave();
672
+ }
673
+ }
674
+
675
+ subscribe(e, cb) {
676
+ if (!this.nuke._chnls.hasOwnProperty(this.id)) {
677
+ this.nuke._chnls[this.id] = {};
678
+ }
679
+
680
+ // if (this.nuke._chnls[this.id].hasOwnProperty(e)) {
681
+ // setError(null, `You are already subscribed to ${e} as ${this.id}`);
682
+ // return this.nuke._chnls[this.id][e];
683
+ // }
684
+ let channel = new _Channel(e, "room", this);
685
+ channel.join();
686
+ return channel;
687
+ }
688
+
689
+ destroy() {
690
+ this._cbs = {};
691
+ if (this.nuke._chnls.hasOwnProperty(this.id)) {
692
+ let chnls = this.nuke._chnls[this.id];
693
+ for (const chnl in chnls) {
694
+ this.unsubscribe(chnl);
695
+ }
696
+ }
697
+ }
698
+ }
699
+
700
+ class _Live {
701
+ _chnls = {};
702
+ _users = {};
703
+ _tickers = {};
704
+ _iter = 0;
705
+ reconnectAttempts = 0;
706
+ timeoutInterval = 4000;
707
+ cbs = {};
708
+ _cbs = {};
709
+ lstnrs = {};
710
+ _ws;
711
+ srvr = undefined;
712
+
713
+ constructor(srvr) {
714
+ this.srvr = srvr;
715
+
716
+ this.init();
717
+ return this;
718
+ }
719
+
720
+ on(e, cb) {
721
+ if (!this.lstnrs.hasOwnProperty(e)) this.lstnrs[e] = [];
722
+ this.lstnrs[e].push(cb);
723
+ if (e == "open" && this._ws?.readyState == 1) {
724
+ this.trigger("open", this._ws);
725
+ }
726
+ return this;
727
+ }
728
+
729
+ off(e) {
730
+ if (e == "connect") return this;
731
+ if (this.lstnrs.hasOwnProperty(e)) delete this.lstnrs[e];
732
+ return this;
733
+ }
734
+
735
+ createUser(id) {
736
+ let user = new _User(id, this);
737
+ return user;
738
+ }
739
+
740
+ subscribe(e, cb) {
741
+ return this.on(e, cb);
742
+ }
743
+
744
+ unsubscribe(e, cb) {
745
+ return this.off(e, cb);
746
+ }
747
+
748
+ trigger(n, e) {
749
+ if (this.lstnrs.hasOwnProperty(n)) {
750
+ for (let x = 0; x < this.lstnrs[n].length; x++) {
751
+ this.lstnrs[n][x](e);
752
+ }
753
+ }
754
+ return this;
755
+ }
756
+
757
+ emit(e, data, cb) {
758
+ try {
759
+ this._iter++;
760
+ if (cb) this.cbs["cb_" + this._iter] = cb;
761
+ if (this.ready()) {
762
+ this._ws.send(JSON.stringify({ e: e, payload: data, _iter: this._iter }));
763
+ } else {
764
+ this._send(JSON.stringify({ e: e, payload: data, _iter: this._iter }));
765
+ }
766
+ } catch (error) {
767
+ if (_debugMode) cl(error);
768
+ }
769
+ return this;
770
+ }
771
+
772
+ _emit(e, data) {
773
+ this._iter++;
774
+ let prom = defer();
775
+ this._cbs["cb_" + this._iter] = prom;
776
+ if (this.ready()) {
777
+ this._ws.send(JSON.stringify({ e: e, payload: data, _iter: this._iter }));
778
+ } else {
779
+ this._send(JSON.stringify({ e: e, payload: data, _iter: this._iter }));
780
+ }
781
+ return prom;
782
+ }
783
+
784
+ _send(m) {
785
+ let _s = this;
786
+ setTimeout(function () {
787
+ if (_s.ready()) _s._ws.send(m);
788
+ else _s._send(m);
789
+ }, 500);
790
+ }
791
+
792
+ ready() {
793
+ return this._ws !== undefined && this._ws.readyState == WebSocket.OPEN;
794
+ }
795
+
796
+ connecting() {
797
+ return this._ws !== undefined && this._ws.readyState == WebSocket.CONNECTING;
798
+ }
799
+
800
+ init() {
801
+ var _s = this;
802
+
803
+ if (_s.ready() || _s.connecting()) {
804
+ return;
805
+ }
806
+
807
+ // if (_s.connecting()) {
808
+ // setTimeout(function () {
809
+ // if (_s.ready()) {
810
+
811
+ // } else _s.init();
812
+ // }, 500);
813
+ // return;
814
+ // }
815
+
816
+ this._ws = new ReconnectingWebSocket(
817
+ this.srvr ? this.srvr : "wss://www.beaapis.com/"
818
+ );
819
+ this._ws.addEventListener("error", (event) => {
820
+ // console.log("WebSocketƒ2 error: ", event);
821
+ });
822
+
823
+ // var localws = this._ws;
824
+ // var timeout = setTimeout(function () {
825
+ // _gn = 0;
826
+ // barSet(1, 200);
827
+ // if (!(_s.ready() || _s.connecting())) localws.close();
828
+ // }, this.timeoutInterval);
829
+
830
+ this._ws.onopen = function (e) {
831
+ // clearTimeout(timeout);
832
+ _s.trigger("connect", e);
833
+ _s.trigger("open", e);
834
+ };
835
+
836
+ this._ws.onclose = function (e) {
837
+ // clearTimeout(timeout);
838
+ // _s._ws = undefined;
839
+ _s._iter = 0;
840
+ _s.cbs = {};
841
+
842
+ _gn = 0;
843
+ barSet(1, 200);
844
+
845
+ // setTimeout(function () {
846
+ _s.reconnectAttempts++;
847
+ // _s.init();
848
+ // }, 1000);
849
+ };
850
+
851
+ this._ws.onmessage = function (e) {
852
+ try {
853
+ let data = JSON.parse(e.data);
854
+ if (data.hasOwnProperty("for")) {
855
+ let t = data["type"] ?? "room";
856
+ let ev = data["ev"] ?? "message";
857
+ const customEvent = new CustomEvent(ev, {
858
+ detail: data["payload"],
859
+ });
860
+ customEvent.data = data["payload"];
861
+ let payload = data["payload"];
862
+ if (payload.hasOwnProperty("user")) {
863
+ if (t == "user") {
864
+ // cl([t,_s._users],data["for"],ev,_s._users[data["for"]].trigger(ev, customEvent));
865
+ _s._users[data["for"]].trigger(ev, customEvent);
866
+ } else if (t == "room")
867
+ _s._chnls[payload.user.id][data["for"]].trigger(
868
+ ev,
869
+ customEvent
870
+ );
871
+ else if (t == "ticker") {
872
+ _s._tickers[data["for"]][payload?.ticker?.id].trigger(
873
+ ev,
874
+ customEvent
875
+ );
876
+ _s._tickers[data["for"]][payload?.ticker?.id].trigger(
877
+ ev + ".class",
878
+ customEvent
879
+ );
880
+ }
881
+ }
882
+ } else if (data.hasOwnProperty("e")) {
883
+ let event = data["e"];
884
+ let iter = data["_iter"];
885
+ const customEvent = new CustomEvent(event, {
886
+ detail: data["payload"],
887
+ });
888
+ customEvent.data = data["payload"];
889
+ if (event != "rooms") _s.trigger(event, customEvent);
890
+ if (_s.cbs["cb_" + iter]) _s.cbs["cb_" + iter](customEvent);
891
+ // 2026-09-14, real bug found testing a real dev server
892
+ // end-to-end: this used to be unconditional
893
+ // (`_s._cbs["cb_" + iter].resolve(...)`), but `_cbs` is
894
+ // only ever populated by `_emit()` (the promise-based
895
+ // variant) — every plain `emit()` response hit
896
+ // `_cbs["cb_" + iter]` being undefined here and threw,
897
+ // silently swallowed by this function's own empty
898
+ // catch below. The real callback on the line above
899
+ // already ran by this point, so this specific crash
900
+ // wasn't blocking that callback — but it silently
901
+ // masked any OTHER error too (including a real bug in
902
+ // the caller's own callback), which is worse.
903
+ if (_s._cbs["cb_" + iter]) _s._cbs["cb_" + iter].resolve(customEvent);
904
+ }
905
+ } catch (e) { if (_debugMode) cl(e); }
906
+ };
907
+ this._ws.onerror = function (e) {
908
+ _gn = 0;
909
+ barSet(1, 200);
910
+ // cl("Zikoo");
911
+ // if (_s._ws) {
912
+ // _s._ws.close();
913
+ // }
914
+ };
915
+ }
916
+ }
917
+ let LIVE;
918
+ let Nuke;
919
+ // window.onload = function () {
920
+ LIVE = new _Live("wss://www.beaapis.com/");
921
+ Nuke = new Nuclear(
922
+ _beaTn
923
+ ? undefined
924
+ : (window.location.protocol === "https:" ? "wss://" : "ws://") +
925
+ window.location.hostname +
926
+ (window.location.port ? ":" + window.location.port : "")
927
+ );
928
+ let _ovcD, _vcD;
929
+
930
+ // index.js's dev bootstrap now lives in index-bootstrap.js, concatenated at
931
+ // the very FRONT of this bundle (see build/bundle.js) — it has to run
932
+ // before vendor/reconnecting-websocket.js's $(document).ready() handler
933
+ // can fire (which it can do synchronously, mid-script), not merely before
934
+ // this file. See that file's comment for the full reasoning; this used to
935
+ // live here and raced that ready handler.
936
+
937
+ // Fetches all views/layouts and diffs against the previous copy, targeted
938
+ // re-rendering only whatever view/layout actually changed. Originally only
939
+ // ran on the socket's "connect" event (meaning a full nodemon process
940
+ // restart — see @lmjs_v2/cli's old startServer() — was the only way to
941
+ // trigger it, dropping every client connection in the process). Pulled out
942
+ // into its own function 2026-09-14 so a lighter, in-process "files-changed"
943
+ // push (chokidar-based, no restart, no dropped connection — see app.js) can
944
+ // trigger the exact same logic without needing a reconnect at all.
945
+ function syncViewFiles() {
946
+ Nuke.emit("getfiles", {}, function (e) {
947
+ var _files = e.data;
948
+ let views = _files["views"];
949
+ let layouts = _files["layouts"];
950
+ // var HST = new _hst(views['c3JjL3ZpZXdzL2hvbWUudmlldw==']);
951
+ // cl(HST);
952
+ _vcD = _files;
953
+ if (!_ovcD) _ovcD = clone(_vcD);
954
+ else {
955
+ for (var key in views) {
956
+ if (_ovcD['views'].hasOwnProperty(key)) {
957
+ if (!deepCompare(clone(_ovcD['views'][key]), clone(views[key]))) {
958
+ cl("Changed the " + "view " + atob(key));
959
+ let n = atob(key)
960
+ .split("src/views/")
961
+ .join("")
962
+ .split(".view")
963
+ .join("");
964
+ let nodes = getURLNodes();
965
+ _ovcD['views'][key] = views[key];
966
+ cl("view", n, atob(key));
967
+ if (nodes[0] == n) {
968
+ renderView(nodes[0], null, View.props ?? {});
969
+ } else {
970
+ renderView(n, true, {});
971
+ // if (n.indexOf("widgets/") > -1) {
972
+ // $('[kd="' + key + '"]').addClass("_render");
973
+ // renderWidget(n.split("widgets/").join(""), "kd='" + key + "'");
974
+ // globalWatch();
975
+ // } else {
976
+ // $('[view="' + n + '"]')
977
+ // .removeData("_status")
978
+ // .removeData("_re");
979
+ // globalWatch();
980
+ // }
981
+ }
982
+ }
983
+ }
984
+ }
985
+ for (var key in layouts) {
986
+ if (_ovcD['layouts'].hasOwnProperty(key)) {
987
+ if (!deepCompare(clone(_ovcD['layouts'][key]), clone(layouts[key]))) {
988
+ cl("Changed the " + "layout " + atob(key));
989
+ let n = atob(key)
990
+ .split("src/layouts/")
991
+ .join("")
992
+ .split(".layout")
993
+ .join("");
994
+ let nodes = getURLNodes();
995
+ _ovcD['layouts'][key] = layouts[key];
996
+ cl("layout", n, atob(key));
997
+ // if (nodes[0] == n) {
998
+ // renderView(nodes[0], null, View.props ?? {});
999
+ // } else {
1000
+ renderView(n, false, {}, 'layouts');
1001
+ // if (n.indexOf("widgets/") > -1) {
1002
+ // $('[kd="' + key + '"]').addClass("_render");
1003
+ // renderWidget(n.split("widgets/").join(""), "kd='" + key + "'");
1004
+ // globalWatch();
1005
+ // } else {
1006
+ // $('[view="' + n + '"]')
1007
+ // .removeData("_status")
1008
+ // .removeData("_re");
1009
+ // globalWatch();
1010
+ // }
1011
+ // }
1012
+ }
1013
+ }
1014
+ }
1015
+ // for (var key in tpls) {
1016
+ // if (_ovcD['tpls'].hasOwnProperty(key)) {
1017
+ // if (!deepCompare(_ovcD['tpls'][key], tpls[key])) {
1018
+ // cl("Changed the " + "tpl " + atob(key));
1019
+ // _ovcD['tpls'][key] = tpls[key];
1020
+ // let n = atob(key)
1021
+ // .split("src/tpls/")
1022
+ // .join("")
1023
+ // .split(".tpl")
1024
+ // .join("");
1025
+ // $('[tpl="' + n + '"]')
1026
+ // .removeData("_status")
1027
+ // .removeData("_re");
1028
+ // globalWatch();
1029
+ // }
1030
+ // }
1031
+ // }
1032
+ }
1033
+ });
1034
+ }
1035
+
1036
+ Nuke.on("connect", function () {
1037
+ if (_beaTn) {
1038
+ Nuke.emit(
1039
+ "get_uniquer",
1040
+ {
1041
+ beajsToken: _beaTn,
1042
+ uniquer: globals.uniquer,
1043
+ },
1044
+ function (e) {
1045
+ let d = e.data;
1046
+ let data = d.uniquer;
1047
+ globals.uniquer = data;
1048
+ }
1049
+ );
1050
+ } else {
1051
+ syncViewFiles();
1052
+ }
1053
+ });
1054
+
1055
+ // Dev-only: pushed by the local server the instant chokidar detects a
1056
+ // src/views or src/layouts change (see @lmjs_v2/cli's app.js) — no process
1057
+ // restart, no dropped connection, unlike the old nodemon-restart-triggered
1058
+ // "connect" path above. Same fetch-and-diff, just a lighter trigger.
1059
+ Nuke.on("files-changed", function () {
1060
+ if (!_beaTn) syncViewFiles();
1061
+ });
1062
+ // };
1063
+
1064
+
1065
+ var API = {
1066
+ get: function (u, d, h, a, opts) {
1067
+ return this.req(u, d, h, "GET", a, opts);
1068
+ },
1069
+ put: function (u, d, h, a, opts) {
1070
+ return this.req(u, d, h, "PUT", a, opts);
1071
+ },
1072
+ post: function (u, d, h, a, opts) {
1073
+ return this.req(u, d, h, "POST", a, opts);
1074
+ },
1075
+ delete: function (u, d, h, a, opts) {
1076
+ return this.req(u, d, h, "DELETE", a, opts);
1077
+ },
1078
+ patch: function (u, d, h, a, opts) {
1079
+ return this.req(u, d, h, "PATCH", a, opts);
1080
+ },
1081
+ req: function (u, d, h, m, a, opts, _prom) {
1082
+ if (!opts) opts = { full: false, progress: true };
1083
+ let prog = opts.hasOwnProperty("progress") ? opts.progress : true;
1084
+ let full = opts.hasOwnProperty("full") ? opts.full : false;
1085
+
1086
+ let prom = _prom ? _prom : defer();
1087
+ try {
1088
+ return prom;
1089
+ } finally {
1090
+ if (
1091
+ Nuke &&
1092
+ Nuke._ws &&
1093
+ Nuke._ws.readyState == 1 &&
1094
+ (_beaTn ? globals.uniquer > 0 : true)
1095
+ ) {
1096
+ if (prog) {
1097
+ _gn = 0;
1098
+ _work();
1099
+ }
1100
+ Nuke.emit(
1101
+ "request",
1102
+ {
1103
+ body: {
1104
+ method: m,
1105
+ path: u,
1106
+ api: a ?? 0,
1107
+ headers: h,
1108
+ full: full,
1109
+ },
1110
+ uniquer: globals.uniquer ?? 0,
1111
+ data: d,
1112
+ },
1113
+ function (e) {
1114
+ // cl(e);
1115
+ if (prog) {
1116
+ _gn = 0;
1117
+ barSet(1, 200);
1118
+ }
1119
+ var r = e.data;
1120
+ prom.resolve(r);
1121
+ }
1122
+ );
1123
+ } else {
1124
+
1125
+ if (_beaTn && _beaTn != "") {
1126
+ $.ajax({
1127
+ "url": "https://www.beaapis.com/req",
1128
+ headers: {},
1129
+ type: "POST",
1130
+ dataType: "json",
1131
+ data: {
1132
+ body: {
1133
+ method: m,
1134
+ path: u,
1135
+ api: a ?? 0,
1136
+ headers: h,
1137
+ full: full,
1138
+ },
1139
+ uniquer: globals.uniquer ?? 0,
1140
+ _beaTn: _beaTn,
1141
+ data: d,
1142
+ },
1143
+ cache: false,
1144
+ success: function (r, s) {
1145
+ prom.resolve(r);
1146
+ },
1147
+ error: function () {
1148
+ prom.reject("error");
1149
+ }
1150
+ });
1151
+ } else {
1152
+ setTimeout(() => {
1153
+ this.req(u, d, h, m, a, opts, prom);
1154
+ }, _tickTime);
1155
+ }
1156
+ // API22.req(u, d, h, m, a, opts, prom);
1157
+
1158
+ // prom.resolve(r);
1159
+ }
1160
+ }
1161
+ },
1162
+ };