http-request-manager 18.16.2 → 18.16.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.
|
@@ -1872,6 +1872,7 @@ class WebSocketManagerService {
|
|
|
1872
1872
|
this.maxRetries$ = WebSocketManagerService.maxRetriesSubject.asObservable();
|
|
1873
1873
|
this.messages$ = WebSocketManagerService.messages.asObservable();
|
|
1874
1874
|
this.connectionStatus$ = WebSocketManagerService.connectionStatus.asObservable();
|
|
1875
|
+
this.connectionError$ = WebSocketManagerService.connectionError.asObservable();
|
|
1875
1876
|
this.subscribedChannels$ = WebSocketManagerService.subscribedChannels.asObservable();
|
|
1876
1877
|
this.onReconnect$ = WebSocketManagerService.onReconnect.asObservable();
|
|
1877
1878
|
}
|
|
@@ -1897,6 +1898,7 @@ class WebSocketManagerService {
|
|
|
1897
1898
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
1898
1899
|
static { this.messages = new BehaviorSubject(null); }
|
|
1899
1900
|
static { this.connectionStatus = new BehaviorSubject(false); }
|
|
1901
|
+
static { this.connectionError = new BehaviorSubject(null); }
|
|
1900
1902
|
static { this.isSubscribed = false; }
|
|
1901
1903
|
// Track currently subscribed channels
|
|
1902
1904
|
static { this.subscribedChannels = new BehaviorSubject(new Set()); }
|
|
@@ -1939,6 +1941,7 @@ class WebSocketManagerService {
|
|
|
1939
1941
|
// Cancel any pending retry timer before attempting a new connection
|
|
1940
1942
|
WebSocketManagerService.retrySubscription?.unsubscribe();
|
|
1941
1943
|
WebSocketManagerService.retrySubscription = null;
|
|
1944
|
+
WebSocketManagerService.connectionError.next(null);
|
|
1942
1945
|
// Check if connection already exists and is open
|
|
1943
1946
|
if (WebSocketManagerService.socket) {
|
|
1944
1947
|
if (WebSocketManagerService.socket.readyState === WebSocket.OPEN) {
|
|
@@ -2007,9 +2010,11 @@ class WebSocketManagerService {
|
|
|
2007
2010
|
const data = JSON.parse(event.data);
|
|
2008
2011
|
if (data.error) {
|
|
2009
2012
|
WebSocketManagerService.messages.next(data);
|
|
2010
|
-
// Log the server error and close — onclose will drive the retry logic
|
|
2011
2013
|
if (data.error === 'JWT_INVALID' || data.error === 'AUTH_BLOCKED') {
|
|
2012
|
-
console.error(`🚫 ${data.error}: ${data.message || 'Authentication error'} —
|
|
2014
|
+
console.error(`🚫 ${data.error}: ${data.message || 'Authentication error'} — stopping, no retry`);
|
|
2015
|
+
WebSocketManagerService.lastOptions = null;
|
|
2016
|
+
WebSocketManagerService.connectionError.next('Invalid or Expired JWT');
|
|
2017
|
+
WebSocketManagerService.connectionStatus.next(false);
|
|
2013
2018
|
}
|
|
2014
2019
|
else {
|
|
2015
2020
|
console.error(`❌ Server error: ${data.error} — will retry`);
|
|
@@ -2042,6 +2047,11 @@ class WebSocketManagerService {
|
|
|
2042
2047
|
WebSocketManagerService.connectionReadyNotified = false;
|
|
2043
2048
|
WebSocketManagerService.socket = null;
|
|
2044
2049
|
WebSocketManagerService.subscribedChannels.next(new Set());
|
|
2050
|
+
if (event.code === 4000 || event.code === 4001 || event.code === 4003) {
|
|
2051
|
+
WebSocketManagerService.connectionError.next('Invalid or Expired JWT');
|
|
2052
|
+
WebSocketManagerService.connectionStatus.next(false);
|
|
2053
|
+
return;
|
|
2054
|
+
}
|
|
2045
2055
|
const maxRetries = WebSocketManagerService.maxRetries;
|
|
2046
2056
|
const retryDelay = WebSocketManagerService.retryDelay;
|
|
2047
2057
|
if (WebSocketManagerService.lastOptions && WebSocketManagerService.retryCount < maxRetries) {
|
|
@@ -3786,6 +3796,7 @@ class HTTPManagerService extends RequestService {
|
|
|
3786
3796
|
this.subscribedChannels$ = this.wsManager.subscribedChannels$;
|
|
3787
3797
|
this.retryCount$ = this.wsManager.retryCount$;
|
|
3788
3798
|
this.maxRetries$ = this.wsManager.maxRetries$;
|
|
3799
|
+
this.connectionError$ = this.wsManager.connectionError$;
|
|
3789
3800
|
this.countdown = new BehaviorSubject(0);
|
|
3790
3801
|
this.countdown$ = this.countdown.asObservable();
|
|
3791
3802
|
this.error = new BehaviorSubject(false);
|
|
@@ -6649,6 +6660,7 @@ class HTTPManagerStateService extends ComponentStore {
|
|
|
6649
6660
|
this.connectionStatus$ = this.httpManagerService.connectionStatus$;
|
|
6650
6661
|
this.wsRetryCount$ = this.httpManagerService.retryCount$;
|
|
6651
6662
|
this.wsMaxRetries$ = this.httpManagerService.maxRetries$;
|
|
6663
|
+
this.connectionError$ = this.httpManagerService.connectionError$;
|
|
6652
6664
|
// WebSocket
|
|
6653
6665
|
this.initWS = this.effect((wsOptions$) => wsOptions$.pipe(switchMap((wsOptions) => merge(this.httpManagerService.connectionStatus$.pipe(tap((isConnected) => {
|
|
6654
6666
|
if (isConnected) {
|
|
@@ -12407,6 +12419,7 @@ class RequestManagerWsDemoComponent {
|
|
|
12407
12419
|
this.retryCount$ = this.stateService.wsRetryCount$;
|
|
12408
12420
|
this.maxRetries$ = this.stateService.wsMaxRetries$;
|
|
12409
12421
|
this.connectionStatus$ = this.stateService.connectionStatus$;
|
|
12422
|
+
this.connectionError$ = this.stateService.connectionError$;
|
|
12410
12423
|
this.data$ = this.stateService.data$;
|
|
12411
12424
|
this.isPending$ = this.stateService.isPending$;
|
|
12412
12425
|
}
|
|
@@ -12414,11 +12427,11 @@ class RequestManagerWsDemoComponent {
|
|
|
12414
12427
|
this.stateService.updateConnection(this.server, this.wsServer, this.jwtToken, this.user, this.path);
|
|
12415
12428
|
}
|
|
12416
12429
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: RequestManagerWsDemoComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
12417
|
-
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" }] }); }
|
|
12430
|
+
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) && !(connectionError$ | async) && ((retryCount$ | async) ?? 0) < ((maxRetries$ | async) ?? 0)) {\n <div>\n <mat-progress-bar mode=\"indeterminate\"></mat-progress-bar>\n </div>\n }\n\n @if (connectionError$ | async; as errorMsg) {\n <div style=\"padding: 0.75rem 1rem; background: #fdecea; color: #b00020; border-left: 4px solid #b00020; border-radius: 2px; margin-bottom: 0.5rem;\">\n {{ errorMsg }}\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" }] }); }
|
|
12418
12431
|
}
|
|
12419
12432
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: RequestManagerWsDemoComponent, decorators: [{
|
|
12420
12433
|
type: Component,
|
|
12421
|
-
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" }]
|
|
12434
|
+
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) && !(connectionError$ | async) && ((retryCount$ | async) ?? 0) < ((maxRetries$ | async) ?? 0)) {\n <div>\n <mat-progress-bar mode=\"indeterminate\"></mat-progress-bar>\n </div>\n }\n\n @if (connectionError$ | async; as errorMsg) {\n <div style=\"padding: 0.75rem 1rem; background: #fdecea; color: #b00020; border-left: 4px solid #b00020; border-radius: 2px; margin-bottom: 0.5rem;\">\n {{ errorMsg }}\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" }]
|
|
12422
12435
|
}], propDecorators: { server: [{
|
|
12423
12436
|
type: Input
|
|
12424
12437
|
}], wsServer: [{
|