http-request-manager 18.15.29 β 18.15.32
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.
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { inject, Injectable, APP_ID, Inject, InjectionToken, isDevMode, signal, effect, computed, Injector, Optional, EventEmitter, Input, Output, ViewEncapsulation, Component, NgModule, ViewChild } from '@angular/core';
|
|
2
|
+
import { inject, Injectable, APP_ID, Inject, InjectionToken, isDevMode, signal, effect, computed, Injector, Optional, DestroyRef, EventEmitter, Input, Output, ViewEncapsulation, Component, NgModule, ViewChild } from '@angular/core';
|
|
3
3
|
import { ComponentStore } from '@ngrx/component-store';
|
|
4
|
-
import { map, catchError, filter, tap, finalize, takeWhile, retry, startWith, mergeMap, takeUntil, concatMap, toArray, withLatestFrom, switchMap,
|
|
4
|
+
import { map, catchError, filter, take, tap, finalize, takeWhile, retry, startWith, mergeMap, takeUntil, concatMap, toArray, withLatestFrom, switchMap, delay, scan, distinctUntilChanged } from 'rxjs/operators';
|
|
5
5
|
import { HttpClient, HttpHeaders, HttpEventType, HttpHeaderResponse, HttpErrorResponse, HTTP_INTERCEPTORS } from '@angular/common/http';
|
|
6
6
|
import * as CryptoJS from 'crypto-js';
|
|
7
|
-
import { from, BehaviorSubject, EMPTY, throwError, defer, interval,
|
|
8
|
-
import { toObservable } from '@angular/core/rxjs-interop';
|
|
7
|
+
import { from, BehaviorSubject, EMPTY, timer, throwError, defer, interval, Subject, of, merge, Subscription, take as take$1, catchError as catchError$1, map as map$1, tap as tap$1, switchMap as switchMap$1, startWith as startWith$1, distinctUntilChanged as distinctUntilChanged$1, combineLatest, filter as filter$1, takeUntil as takeUntil$1, ReplaySubject } from 'rxjs';
|
|
8
|
+
import { toObservable, takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
9
9
|
import { ToastMessageDisplayService, ToastDisplay, ToastColors, ToastMessageDisplayModule } from 'toast-message-display';
|
|
10
10
|
import Dexie from 'dexie';
|
|
11
11
|
import * as i1 from '@ngx-translate/core';
|
|
@@ -1655,7 +1655,7 @@ class WebsocketService {
|
|
|
1655
1655
|
}
|
|
1656
1656
|
sendMessageInChannel(channel, content) {
|
|
1657
1657
|
if (this.socket?.readyState === WebSocket.OPEN) {
|
|
1658
|
-
this.socket.send(JSON.stringify({ type: '
|
|
1658
|
+
this.socket.send(JSON.stringify({ type: 'statemanagerMessage', subscribedChannel: channel, content }));
|
|
1659
1659
|
this.logger.debug('WebSocket', `π¬ Send message`, { channel, content });
|
|
1660
1660
|
}
|
|
1661
1661
|
else {
|
|
@@ -1854,6 +1854,8 @@ i0.Ι΅Ι΅ngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
1854
1854
|
*/
|
|
1855
1855
|
class WebSocketManagerService {
|
|
1856
1856
|
constructor() {
|
|
1857
|
+
this.retryCount$ = WebSocketManagerService.retryCountSubject.asObservable();
|
|
1858
|
+
this.maxRetries$ = WebSocketManagerService.maxRetriesSubject.asObservable();
|
|
1857
1859
|
this.messages$ = WebSocketManagerService.messages.asObservable();
|
|
1858
1860
|
this.connectionStatus$ = WebSocketManagerService.connectionStatus.asObservable();
|
|
1859
1861
|
this.subscribedChannels$ = WebSocketManagerService.subscribedChannels.asObservable();
|
|
@@ -1870,7 +1872,12 @@ class WebSocketManagerService {
|
|
|
1870
1872
|
static { this.lastJwtToken = ''; }
|
|
1871
1873
|
// Retry configuration
|
|
1872
1874
|
static { this.retryCount = 0; }
|
|
1873
|
-
static { this.
|
|
1875
|
+
static { this.retryDelay = 5000; }
|
|
1876
|
+
static { this.retrySubscription = null; }
|
|
1877
|
+
static { this.maxRetries = 10; }
|
|
1878
|
+
static { this.connectionReadyNotified = false; }
|
|
1879
|
+
static { this.retryCountSubject = new BehaviorSubject(0); }
|
|
1880
|
+
static { this.maxRetriesSubject = new BehaviorSubject(10); }
|
|
1874
1881
|
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
1875
1882
|
// INSTANCE OBSERVABLES (Shared across ALL instances via static BehaviorSubjects)
|
|
1876
1883
|
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
@@ -1915,6 +1922,9 @@ class WebSocketManagerService {
|
|
|
1915
1922
|
* @param jwtToken - Optional JWT token for authentication
|
|
1916
1923
|
*/
|
|
1917
1924
|
connect(options, jwtToken) {
|
|
1925
|
+
// Cancel any pending retry timer before attempting a new connection
|
|
1926
|
+
WebSocketManagerService.retrySubscription?.unsubscribe();
|
|
1927
|
+
WebSocketManagerService.retrySubscription = null;
|
|
1918
1928
|
// Check if connection already exists and is open
|
|
1919
1929
|
if (WebSocketManagerService.socket) {
|
|
1920
1930
|
if (WebSocketManagerService.socket.readyState === WebSocket.OPEN) {
|
|
@@ -1941,82 +1951,111 @@ class WebSocketManagerService {
|
|
|
1941
1951
|
// Store jwt token for retry
|
|
1942
1952
|
WebSocketManagerService.lastJwtToken = jwtToken;
|
|
1943
1953
|
WebSocketManagerService.lastOptions = options;
|
|
1944
|
-
|
|
1945
|
-
|
|
1954
|
+
// Always set maxRetries and delay from latest options
|
|
1955
|
+
if (options?.retry?.times) {
|
|
1956
|
+
WebSocketManagerService.maxRetries = options.retry.times;
|
|
1957
|
+
WebSocketManagerService.maxRetriesSubject.next(options.retry.times);
|
|
1958
|
+
}
|
|
1959
|
+
else {
|
|
1960
|
+
WebSocketManagerService.maxRetries = 10;
|
|
1961
|
+
WebSocketManagerService.maxRetriesSubject.next(10);
|
|
1962
|
+
}
|
|
1963
|
+
if (options?.retry?.delay) {
|
|
1964
|
+
WebSocketManagerService.retryDelay = options.retry.delay * 1000;
|
|
1965
|
+
}
|
|
1966
|
+
else {
|
|
1967
|
+
WebSocketManagerService.retryDelay = 5000;
|
|
1968
|
+
}
|
|
1969
|
+
// Mark as connecting β connectionStatus true while connecting/retrying, false only when exhausted
|
|
1946
1970
|
WebSocketManagerService.isConnecting = true;
|
|
1947
1971
|
WebSocketManagerService.isSubscribed = false;
|
|
1972
|
+
WebSocketManagerService.connectionReadyNotified = false;
|
|
1948
1973
|
WebSocketManagerService.subscribedChannels.next(new Set());
|
|
1974
|
+
WebSocketManagerService.connectionStatus.next(true);
|
|
1949
1975
|
const sessionId = this.getSessionId();
|
|
1950
1976
|
const URL = (jwtToken) ? `${options.wsServer}?token=${jwtToken}&sessionId=${sessionId}` : `${options.wsServer}?sessionId=${sessionId}`;
|
|
1951
1977
|
console.log(`π Initiating WebSocket connection to: ${options.wsServer}`);
|
|
1952
1978
|
// Create new WebSocket instance (static)
|
|
1953
1979
|
WebSocketManagerService.socket = new WebSocket(URL);
|
|
1954
1980
|
WebSocketManagerService.socket.onopen = () => {
|
|
1955
|
-
console.log(`π‘
|
|
1981
|
+
console.log(`π‘ WebSocket handshake complete β awaiting server confirmation`);
|
|
1956
1982
|
// Force clear subscribedChannels on new connection - server lost our subscriptions
|
|
1957
1983
|
console.log('π§Ή Clearing subscribedChannels on connect (was:', WebSocketManagerService.subscribedChannels.value.size, 'channels)');
|
|
1958
1984
|
WebSocketManagerService.subscribedChannels.next(new Set());
|
|
1959
|
-
|
|
1960
|
-
|
|
1985
|
+
// Do NOT reset retryCount here β reset happens only on confirmed stable connection
|
|
1986
|
+
// (onmessage first valid response). Resetting here would cause the counter to always
|
|
1987
|
+
// show 1/N because onopen fires before onclose increments the counter.
|
|
1961
1988
|
WebSocketManagerService.isConnecting = false;
|
|
1962
1989
|
WebSocketManagerService.connectionInitialized = true;
|
|
1963
|
-
// Emit reconnect event - MessageTrackerService will handle subscriptions with lastSeenId
|
|
1964
|
-
console.log(`π Emitting reconnect event for MessageTrackerService`);
|
|
1965
|
-
WebSocketManagerService.onReconnect.next();
|
|
1966
1990
|
};
|
|
1967
1991
|
WebSocketManagerService.socket.onmessage = (event) => {
|
|
1968
1992
|
try {
|
|
1969
1993
|
const data = JSON.parse(event.data);
|
|
1970
|
-
if (data.error
|
|
1971
|
-
console.error(`π« ${data.error}: ${data.message || 'Authentication error'}`);
|
|
1972
|
-
WebSocketManagerService.jwtInvalidClose = true;
|
|
1994
|
+
if (data.error) {
|
|
1973
1995
|
WebSocketManagerService.messages.next(data);
|
|
1974
|
-
|
|
1996
|
+
// Log the server error and close β onclose will drive the retry logic
|
|
1997
|
+
if (data.error === 'JWT_INVALID' || data.error === 'AUTH_BLOCKED') {
|
|
1998
|
+
console.error(`π« ${data.error}: ${data.message || 'Authentication error'} β will retry`);
|
|
1999
|
+
}
|
|
2000
|
+
else {
|
|
2001
|
+
console.error(`β Server error: ${data.error} β will retry`);
|
|
2002
|
+
}
|
|
1975
2003
|
WebSocketManagerService.socket?.close();
|
|
1976
2004
|
return;
|
|
1977
2005
|
}
|
|
2006
|
+
// First valid (non-error) message confirms the server accepted auth.
|
|
2007
|
+
// Notify readiness once per connection so pending intended subscriptions
|
|
2008
|
+
// are replayed after the socket is actually usable.
|
|
2009
|
+
if (!WebSocketManagerService.connectionReadyNotified) {
|
|
2010
|
+
if (WebSocketManagerService.retryCount > 0) {
|
|
2011
|
+
console.log(`β
Server confirmed connection after ${WebSocketManagerService.retryCount} retries.`);
|
|
2012
|
+
WebSocketManagerService.retryCount = 0;
|
|
2013
|
+
WebSocketManagerService.retryCountSubject.next(0);
|
|
2014
|
+
}
|
|
2015
|
+
WebSocketManagerService.connectionReadyNotified = true;
|
|
2016
|
+
console.log(`π Emitting reconnect event for MessageTrackerService`);
|
|
2017
|
+
WebSocketManagerService.onReconnect.next();
|
|
2018
|
+
}
|
|
1978
2019
|
WebSocketManagerService.messages.next(data);
|
|
1979
2020
|
}
|
|
1980
2021
|
catch (error) {
|
|
1981
2022
|
console.error('Error parsing WebSocket message:', event.data);
|
|
1982
2023
|
}
|
|
1983
2024
|
};
|
|
1984
|
-
WebSocketManagerService.socket.onclose = () => {
|
|
1985
|
-
console.log(
|
|
1986
|
-
console.log('π§Ή Clearing subscribedChannels (was:', WebSocketManagerService.subscribedChannels.value.size, 'channels)');
|
|
1987
|
-
WebSocketManagerService.connectionStatus.next(false);
|
|
2025
|
+
WebSocketManagerService.socket.onclose = (event) => {
|
|
2026
|
+
console.log(`π΄ WebSocket closed (code: ${event.code})`);
|
|
1988
2027
|
WebSocketManagerService.isConnecting = false;
|
|
2028
|
+
WebSocketManagerService.connectionReadyNotified = false;
|
|
1989
2029
|
WebSocketManagerService.socket = null;
|
|
1990
|
-
// Clear subscribed channels - server lost our subscriptions
|
|
1991
2030
|
WebSocketManagerService.subscribedChannels.next(new Set());
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
console.error('π« WebSocket closed due to authentication block/invalid token. Not retrying.');
|
|
1995
|
-
WebSocketManagerService.retryCount = 0;
|
|
1996
|
-
return;
|
|
1997
|
-
}
|
|
1998
|
-
const maxRetries = WebSocketManagerService.lastOptions?.retry?.times || 3;
|
|
1999
|
-
const retryDelay = (WebSocketManagerService.lastOptions?.retry?.delay && WebSocketManagerService.lastOptions.retry.delay * 1000) || 5000;
|
|
2031
|
+
const maxRetries = WebSocketManagerService.maxRetries;
|
|
2032
|
+
const retryDelay = WebSocketManagerService.retryDelay;
|
|
2000
2033
|
if (WebSocketManagerService.lastOptions && WebSocketManagerService.retryCount < maxRetries) {
|
|
2001
2034
|
WebSocketManagerService.retryCount++;
|
|
2035
|
+
WebSocketManagerService.retryCountSubject.next(WebSocketManagerService.retryCount);
|
|
2002
2036
|
console.log(`π Reconnect attempt ${WebSocketManagerService.retryCount}/${maxRetries}...`);
|
|
2003
|
-
|
|
2037
|
+
// connectionStatus stays true β still actively retrying
|
|
2038
|
+
WebSocketManagerService.retrySubscription = timer(retryDelay).pipe(take(1)).subscribe(() => this.connect(WebSocketManagerService.lastOptions, WebSocketManagerService.lastJwtToken));
|
|
2004
2039
|
}
|
|
2005
|
-
else
|
|
2006
|
-
console.error(`β WebSocket failed after ${maxRetries}
|
|
2007
|
-
WebSocketManagerService.
|
|
2040
|
+
else {
|
|
2041
|
+
console.error(`β WebSocket failed after ${maxRetries} retries. Giving up.`);
|
|
2042
|
+
WebSocketManagerService.connectionStatus.next(false);
|
|
2043
|
+
WebSocketManagerService.retryCount = maxRetries;
|
|
2044
|
+
WebSocketManagerService.retryCountSubject.next(maxRetries);
|
|
2008
2045
|
}
|
|
2009
2046
|
};
|
|
2010
2047
|
WebSocketManagerService.socket.onerror = (error) => {
|
|
2011
2048
|
console.error('β WebSocket error:', error);
|
|
2012
|
-
WebSocketManagerService.connectionStatus.next(false);
|
|
2013
2049
|
WebSocketManagerService.isConnecting = false;
|
|
2050
|
+
// onclose will fire after onerror and drive retry/give-up logic
|
|
2014
2051
|
};
|
|
2015
2052
|
}
|
|
2016
2053
|
/**
|
|
2017
2054
|
* Disconnect from WebSocket server
|
|
2018
2055
|
*/
|
|
2019
2056
|
disconnect() {
|
|
2057
|
+
WebSocketManagerService.retrySubscription?.unsubscribe();
|
|
2058
|
+
WebSocketManagerService.retrySubscription = null;
|
|
2020
2059
|
if (WebSocketManagerService.socket) {
|
|
2021
2060
|
console.log('π Disconnecting WebSocket...');
|
|
2022
2061
|
WebSocketManagerService.socket.close();
|
|
@@ -2180,7 +2219,7 @@ class WebSocketManagerService {
|
|
|
2180
2219
|
sendMessageInChannel(channel, content) {
|
|
2181
2220
|
if (WebSocketManagerService.socket?.readyState === WebSocket.OPEN) {
|
|
2182
2221
|
const message = {
|
|
2183
|
-
type: '
|
|
2222
|
+
type: 'statemanagerMessage',
|
|
2184
2223
|
subscribedChannel: channel,
|
|
2185
2224
|
content
|
|
2186
2225
|
};
|
|
@@ -3374,10 +3413,10 @@ class MessageTrackerService {
|
|
|
3374
3413
|
* Map<channel, retryCount>
|
|
3375
3414
|
*/
|
|
3376
3415
|
this.gapRetryCount = new Map();
|
|
3377
|
-
/** Batch acknowledgment timer */
|
|
3378
|
-
this.batchAckTimer = null;
|
|
3379
3416
|
/** Subscription to WebSocket messages */
|
|
3380
3417
|
this.messagesSubscription = null;
|
|
3418
|
+
/** Subject to signal destroy for takeUntil */
|
|
3419
|
+
this.destroy$ = new Subject();
|
|
3381
3420
|
/**
|
|
3382
3421
|
* Track channels we want to be subscribed to (survives disconnect/reconnect)
|
|
3383
3422
|
* This is separate from WebSocketManagerService.subscribedChannels which tracks
|
|
@@ -3391,7 +3430,9 @@ class MessageTrackerService {
|
|
|
3391
3430
|
this.restoreLastSeen();
|
|
3392
3431
|
this.restoreIntendedChannels();
|
|
3393
3432
|
// Start batch acknowledgment timer
|
|
3394
|
-
this.
|
|
3433
|
+
interval(this.BATCH_ACK_INTERVAL_MS)
|
|
3434
|
+
.pipe(takeUntil(this.destroy$))
|
|
3435
|
+
.subscribe(() => this.sendAllBatchAcks());
|
|
3395
3436
|
// Subscribe to all incoming WebSocket messages
|
|
3396
3437
|
this.messagesSubscription = this.wsManager.messages$.subscribe(msg => {
|
|
3397
3438
|
if (msg) {
|
|
@@ -3406,7 +3447,8 @@ class MessageTrackerService {
|
|
|
3406
3447
|
console.log('β
MessageTrackerService initialized');
|
|
3407
3448
|
}
|
|
3408
3449
|
ngOnDestroy() {
|
|
3409
|
-
this.
|
|
3450
|
+
this.destroy$.next();
|
|
3451
|
+
this.destroy$.complete();
|
|
3410
3452
|
this.persistLastSeen(); // This now also persists intendedChannels
|
|
3411
3453
|
this.messagesSubscription?.unsubscribe();
|
|
3412
3454
|
console.log('π MessageTrackerService destroyed');
|
|
@@ -3492,23 +3534,6 @@ class MessageTrackerService {
|
|
|
3492
3534
|
}
|
|
3493
3535
|
this.pendingAcks.get(channel).add(messageId);
|
|
3494
3536
|
}
|
|
3495
|
-
/**
|
|
3496
|
-
* Start batch acknowledgment timer
|
|
3497
|
-
*/
|
|
3498
|
-
startBatchAckTimer() {
|
|
3499
|
-
this.batchAckTimer = setInterval(() => {
|
|
3500
|
-
this.sendAllBatchAcks();
|
|
3501
|
-
}, this.BATCH_ACK_INTERVAL_MS);
|
|
3502
|
-
}
|
|
3503
|
-
/**
|
|
3504
|
-
* Stop batch acknowledgment timer
|
|
3505
|
-
*/
|
|
3506
|
-
stopBatchAckTimer() {
|
|
3507
|
-
if (this.batchAckTimer) {
|
|
3508
|
-
clearInterval(this.batchAckTimer);
|
|
3509
|
-
this.batchAckTimer = null;
|
|
3510
|
-
}
|
|
3511
|
-
}
|
|
3512
3537
|
/**
|
|
3513
3538
|
* Send batch acknowledgments for all channels with pending acks
|
|
3514
3539
|
*/
|
|
@@ -3745,6 +3770,8 @@ class HTTPManagerService extends RequestService {
|
|
|
3745
3770
|
this.connectionStatus$ = this.wsManager.connectionStatus$;
|
|
3746
3771
|
this.messages$ = this.messageTracker.messages$; // Messages flow through MessageTrackerService
|
|
3747
3772
|
this.subscribedChannels$ = this.wsManager.subscribedChannels$;
|
|
3773
|
+
this.retryCount$ = this.wsManager.retryCount$;
|
|
3774
|
+
this.maxRetries$ = this.wsManager.maxRetries$;
|
|
3748
3775
|
this.countdown = new BehaviorSubject(0);
|
|
3749
3776
|
this.countdown$ = this.countdown.asObservable();
|
|
3750
3777
|
this.error = new BehaviorSubject(false);
|
|
@@ -5664,6 +5691,7 @@ class LocalStorageSignalsManagerService {
|
|
|
5664
5691
|
this.defaultOptions = SettingOptions.adapt();
|
|
5665
5692
|
this.stateRetrieved = false;
|
|
5666
5693
|
this.encrypted = false;
|
|
5694
|
+
this.destroyRef = inject(DestroyRef);
|
|
5667
5695
|
this.app = inject(AppService);
|
|
5668
5696
|
this.utils = inject(UtilsService);
|
|
5669
5697
|
this.objectMergerService = inject(ObjectMergerService);
|
|
@@ -5726,7 +5754,7 @@ class LocalStorageSignalsManagerService {
|
|
|
5726
5754
|
}
|
|
5727
5755
|
});
|
|
5728
5756
|
// Expiration timer every 3s
|
|
5729
|
-
|
|
5757
|
+
interval(3000).pipe(takeUntilDestroyed(this.destroyRef)).subscribe(() => {
|
|
5730
5758
|
const state = this.state();
|
|
5731
5759
|
const expired = this.expired(state);
|
|
5732
5760
|
if (expired.length > 0) {
|
|
@@ -5740,7 +5768,7 @@ class LocalStorageSignalsManagerService {
|
|
|
5740
5768
|
this.state.set(updated);
|
|
5741
5769
|
this.persistState(updated);
|
|
5742
5770
|
}
|
|
5743
|
-
}
|
|
5771
|
+
});
|
|
5744
5772
|
}
|
|
5745
5773
|
// --- STATE MUTATORS ---
|
|
5746
5774
|
setStore(store) {
|
|
@@ -6943,6 +6971,8 @@ class HTTPManagerStateService extends ComponentStore {
|
|
|
6943
6971
|
this.wsOptions = WSOptions.adapt();
|
|
6944
6972
|
// Expose raw WS connection status directly to UI (from singleton WebSocketManagerService)
|
|
6945
6973
|
this.connectionStatus$ = this.httpManagerService.connectionStatus$;
|
|
6974
|
+
this.wsRetryCount$ = this.httpManagerService.retryCount$;
|
|
6975
|
+
this.wsMaxRetries$ = this.httpManagerService.maxRetries$;
|
|
6946
6976
|
// WebSocket
|
|
6947
6977
|
this.initWS = this.effect((wsOptions$) => wsOptions$.pipe(switchMap((wsOptions) => merge(this.httpManagerService.connectionStatus$.pipe(tap((isConnected) => {
|
|
6948
6978
|
if (isConnected) {
|
|
@@ -7042,6 +7072,7 @@ class HTTPManagerStateService extends ComponentStore {
|
|
|
7042
7072
|
WebSocketManagerService.addSubscribedChannel(channelName);
|
|
7043
7073
|
}
|
|
7044
7074
|
break;
|
|
7075
|
+
case 'statemanagerMessage':
|
|
7045
7076
|
case 'stateMangerMessage':
|
|
7046
7077
|
// CRITICAL DEBUG: Log channel comparison
|
|
7047
7078
|
console.log('π [STATE STORE] stateMangerMessage received:', {
|
|
@@ -11688,11 +11719,8 @@ class WsMessagingComponent {
|
|
|
11688
11719
|
this.stateService.updateConnection(this.server, this.wsServer, this.jwtToken, this.user, this.path);
|
|
11689
11720
|
// Only trigger once when connection becomes true
|
|
11690
11721
|
this.connectionStatus$.pipe(filter$1(status => status === true), take$1(1), takeUntil$1(this.destroy$)).subscribe(() => {
|
|
11691
|
-
|
|
11692
|
-
|
|
11693
|
-
console.log('π Fetching channels after connection...');
|
|
11694
|
-
this.messageService.getAllChannels();
|
|
11695
|
-
}, 500); // 500ms delay to ensure subscription is processed
|
|
11722
|
+
console.log('π Fetching channels after connection...');
|
|
11723
|
+
this.messageService.getAllChannels();
|
|
11696
11724
|
});
|
|
11697
11725
|
// Subscribe to latest messages and display using rule-based routing
|
|
11698
11726
|
this.latestCommunicationMessages$.pipe(filter$1(message => !!message), takeUntil$1(this.destroy$)).subscribe((message) => {
|
|
@@ -12038,8 +12066,8 @@ class RequestManagerWsDemoComponent {
|
|
|
12038
12066
|
this.fb = inject(FormBuilder);
|
|
12039
12067
|
this.path = ['ai', 'tests'];
|
|
12040
12068
|
this.user$ = this.stateService.user$;
|
|
12041
|
-
this.
|
|
12042
|
-
this.
|
|
12069
|
+
this.retryCount$ = this.stateService.wsRetryCount$;
|
|
12070
|
+
this.maxRetries$ = this.stateService.wsMaxRetries$;
|
|
12043
12071
|
this.connectionStatus$ = this.stateService.connectionStatus$;
|
|
12044
12072
|
this.data$ = this.stateService.data$;
|
|
12045
12073
|
this.isPending$ = this.stateService.isPending$;
|
|
@@ -12048,11 +12076,11 @@ class RequestManagerWsDemoComponent {
|
|
|
12048
12076
|
this.stateService.updateConnection(this.server, this.wsServer, this.jwtToken, this.user, this.path);
|
|
12049
12077
|
}
|
|
12050
12078
|
static { this.Ι΅fac = i0.Ι΅Ι΅ngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: RequestManagerWsDemoComponent, deps: [], target: i0.Ι΅Ι΅FactoryTarget.Component }); }
|
|
12051
|
-
static { this.Ι΅cmp = i0.Ι΅Ι΅ngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: RequestManagerWsDemoComponent, selector: "app-request-manager-ws-demo", inputs: { server: "server", wsServer: "wsServer", jwtToken: "jwtToken", user: "user", path: "path" }, ngImport: i0, template: "<div style=\"margin: 2rem;\">\n\n <h2 style=\"display: flex;\">\n <span style=\"flex:1\">HTTP Request State Manager - Websockets</span>\n @if ((connectionStatus$ | async); as connected) {\n <span>\n WS -\n <span style=\"color: green;\">Connected</span>\n </span>\n } @else {\n <span style=\"color: red;\">Disconnected {{
|
|
12079
|
+
static { this.Ι΅cmp = i0.Ι΅Ι΅ngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: RequestManagerWsDemoComponent, selector: "app-request-manager-ws-demo", inputs: { server: "server", wsServer: "wsServer", jwtToken: "jwtToken", user: "user", path: "path" }, ngImport: i0, template: "<div style=\"margin: 2rem;\">\n\n <h2 style=\"display: flex;\">\n <span style=\"flex:1\">HTTP Request State Manager - Websockets</span>\n @if ((connectionStatus$ | async); as connected) {\n <span>\n WS -\n <span style=\"color: green;\">Connected</span>\n </span>\n } @else {\n <span style=\"color: red;\">Disconnected {{ retryCount$ | async }} / {{ maxRetries$ | async }}</span>\n }\n </h2>\n\n <div>\n\n @if ((user$ | async); as userInfo) {\n <div>\n <mat-toolbar>\n <div style=\"display: flex; flex:1\">\n <div style=\"flex:1\">{{ userInfo.name }}</div>\n <div>({{ userInfo.ldap }})</div>\n </div>\n </mat-toolbar>\n </div>\n }\n\n @if (!(connectionStatus$ | async) && ((retryCount$ | async) ?? 0) < ((maxRetries$ | async) ?? 0)) {\n <div>\n <mat-progress-bar mode=\"indeterminate\"></mat-progress-bar>\n </div>\n }\n\n <mat-tab-group animationDuration=\"0ms\" [selectedIndex]=\"1\">\n\n <mat-tab label=\"WS - Data Control\" [disabled]=\"!(connectionStatus$ | async)\">\n <!-- DATA CONTROL -->\n <app-ws-data-control\n [server]=\"server\"\n [wsServer]=\"wsServer\"\n [jwtToken]=\"jwtToken\"\n [user]=\"user\"\n [path]=\"path\"\n ></app-ws-data-control>\n\n </mat-tab>\n\n <mat-tab label=\"WS - Messaging\" [disabled]=\"!(connectionStatus$ | async)\">\n <!-- MESSAGING -->\n <app-ws-messaging\n [server]=\"server\"\n [wsServer]=\"wsServer\"\n [jwtToken]=\"jwtToken\"\n [user]=\"user\"\n [path]=\"path\"\n ></app-ws-messaging>\n\n </mat-tab>\n\n <mat-tab label=\"WS - Notifications\" [disabled]=\"!(connectionStatus$ | async)\">\n <!-- WS - Notifications -->\n <app-ws-notifications\n [server]=\"server\"\n [wsServer]=\"wsServer\"\n [jwtToken]=\"jwtToken\"\n [user]=\"user\"\n ></app-ws-notifications>\n </mat-tab>\n\n <mat-tab label=\"WS - Chats\" [disabled]=\"true\">\n <!-- WS - Chats -->\n <app-ws-chats></app-ws-chats>\n </mat-tab>\n\n <mat-tab label=\"WS - AI Messaging\" [disabled]=\"true\">\n <!-- WS - AI Messaging -->\n <app-ws-ai-messaging></app-ws-ai-messaging>\n </mat-tab>\n\n </mat-tab-group>\n</div>\n\n</div>\n\n", styles: [""], dependencies: [{ kind: "component", type: i1$2.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass"], exportAs: ["matTab"] }, { kind: "component", type: i1$2.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "fitInkBarToContent", "mat-stretch-tabs", "dynamicHeight", "selectedIndex", "headerPosition", "animationDuration", "contentTabIndex", "disablePagination", "disableRipple", "preserveContent", "backgroundColor", "aria-label", "aria-labelledby"], outputs: ["selectedIndexChange", "focusChange", "animationDone", "selectedTabChange"], exportAs: ["matTabGroup"] }, { kind: "component", type: i8$1.MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }, { kind: "component", type: i3$2.MatToolbar, selector: "mat-toolbar", inputs: ["color"], exportAs: ["matToolbar"] }, { kind: "component", type: WsDataControlComponent, selector: "app-ws-data-control", inputs: ["server", "wsServer", "jwtToken", "user", "path"] }, { kind: "component", type: WsMessagingComponent, selector: "app-ws-messaging", inputs: ["server", "wsServer", "jwtToken", "user", "path"] }, { kind: "component", type: WsNotificationsComponent, selector: "app-ws-notifications", inputs: ["server", "wsServer", "jwtToken", "user"] }, { kind: "component", type: WsAiMessagingComponent, selector: "app-ws-ai-messaging" }, { kind: "component", type: WsChatsComponent, selector: "app-ws-chats" }, { kind: "pipe", type: i1$1.AsyncPipe, name: "async" }] }); }
|
|
12052
12080
|
}
|
|
12053
12081
|
i0.Ι΅Ι΅ngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: RequestManagerWsDemoComponent, decorators: [{
|
|
12054
12082
|
type: Component,
|
|
12055
|
-
args: [{ selector: 'app-request-manager-ws-demo', standalone: false, template: "<div style=\"margin: 2rem;\">\n\n <h2 style=\"display: flex;\">\n <span style=\"flex:1\">HTTP Request State Manager - Websockets</span>\n @if ((connectionStatus$ | async); as connected) {\n <span>\n WS -\n <span style=\"color: green;\">Connected</span>\n </span>\n } @else {\n <span style=\"color: red;\">Disconnected {{
|
|
12083
|
+
args: [{ selector: 'app-request-manager-ws-demo', standalone: false, template: "<div style=\"margin: 2rem;\">\n\n <h2 style=\"display: flex;\">\n <span style=\"flex:1\">HTTP Request State Manager - Websockets</span>\n @if ((connectionStatus$ | async); as connected) {\n <span>\n WS -\n <span style=\"color: green;\">Connected</span>\n </span>\n } @else {\n <span style=\"color: red;\">Disconnected {{ retryCount$ | async }} / {{ maxRetries$ | async }}</span>\n }\n </h2>\n\n <div>\n\n @if ((user$ | async); as userInfo) {\n <div>\n <mat-toolbar>\n <div style=\"display: flex; flex:1\">\n <div style=\"flex:1\">{{ userInfo.name }}</div>\n <div>({{ userInfo.ldap }})</div>\n </div>\n </mat-toolbar>\n </div>\n }\n\n @if (!(connectionStatus$ | async) && ((retryCount$ | async) ?? 0) < ((maxRetries$ | async) ?? 0)) {\n <div>\n <mat-progress-bar mode=\"indeterminate\"></mat-progress-bar>\n </div>\n }\n\n <mat-tab-group animationDuration=\"0ms\" [selectedIndex]=\"1\">\n\n <mat-tab label=\"WS - Data Control\" [disabled]=\"!(connectionStatus$ | async)\">\n <!-- DATA CONTROL -->\n <app-ws-data-control\n [server]=\"server\"\n [wsServer]=\"wsServer\"\n [jwtToken]=\"jwtToken\"\n [user]=\"user\"\n [path]=\"path\"\n ></app-ws-data-control>\n\n </mat-tab>\n\n <mat-tab label=\"WS - Messaging\" [disabled]=\"!(connectionStatus$ | async)\">\n <!-- MESSAGING -->\n <app-ws-messaging\n [server]=\"server\"\n [wsServer]=\"wsServer\"\n [jwtToken]=\"jwtToken\"\n [user]=\"user\"\n [path]=\"path\"\n ></app-ws-messaging>\n\n </mat-tab>\n\n <mat-tab label=\"WS - Notifications\" [disabled]=\"!(connectionStatus$ | async)\">\n <!-- WS - Notifications -->\n <app-ws-notifications\n [server]=\"server\"\n [wsServer]=\"wsServer\"\n [jwtToken]=\"jwtToken\"\n [user]=\"user\"\n ></app-ws-notifications>\n </mat-tab>\n\n <mat-tab label=\"WS - Chats\" [disabled]=\"true\">\n <!-- WS - Chats -->\n <app-ws-chats></app-ws-chats>\n </mat-tab>\n\n <mat-tab label=\"WS - AI Messaging\" [disabled]=\"true\">\n <!-- WS - AI Messaging -->\n <app-ws-ai-messaging></app-ws-ai-messaging>\n </mat-tab>\n\n </mat-tab-group>\n</div>\n\n</div>\n\n" }]
|
|
12056
12084
|
}], propDecorators: { server: [{
|
|
12057
12085
|
type: Input
|
|
12058
12086
|
}], wsServer: [{
|