http-request-manager 18.16.4 → 18.16.8

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/README.md CHANGED
@@ -16,12 +16,13 @@ This README is the main documentation hub for the library. Detailed service guid
16
16
 
17
17
  | Feature | Description | Angular 14-18 / Observable + NgRx | Angular 19+ / Signals |
18
18
  |---------|-------------|----------------------------------|------------------------|
19
- | **🌐 HTTP Request Management** | Retry, polling, streaming, file downloads | [`HTTPManagerService`](https://github.com/micheleboni/npm-angular/tree/main/projects/http-request-manager/src/docs/HTTP_MANAGER_README.md) | [`HTTPManagerSignalsService`](https://github.com/micheleboni/npm-angular/tree/main/projects/http-request-manager/src/docs/HTTP_SINGNALS_MANAGER_README.md) |
19
+ | **🌐 HTTP Request Management** | Retry, polling, streaming, file downloads | [`HTTPManagerService`](https://github.com/micheleboni/npm-angular/tree/main/projects/http-request-manager/src/docs/HTTP_MANAGER_README.md) | [`HTTPManagerSignalsService`](https://github.com/micheleboni/npm-angular/tree/main/projects/http-request-manager/src/docs/HTTP_SIGNALS_MANAGER_README.md) |
20
20
  | **🔄 State Management** | CRUD state, persistence, derived state | [`HTTPManagerStateService`](https://github.com/micheleboni/npm-angular/tree/main/projects/http-request-manager/src/docs/HTTP_STATE_MANAGER_README.md) and [`StoreStateManagerService`](https://github.com/micheleboni/npm-angular/tree/main/projects/http-request-manager/src/docs/STORE_STATE_MANAGER_README.md) | [`StoreStateManagerSignalsService`](https://github.com/micheleboni/npm-angular/tree/main/projects/http-request-manager/src/docs/STORE_STATE_SIGNALS_README.md) |
21
21
  | **💬 Real-Time Communication** | WebSocket channels, tracking, messaging | [`WebSocketManagerService`](https://github.com/micheleboni/npm-angular/tree/main/projects/http-request-manager/src/docs/WS_MANAGER_README.md), [`WebSocketMessageService`](https://github.com/micheleboni/npm-angular/tree/main/projects/http-request-manager/src/docs/WEBSOCKET_MESSAGE_SERVICE.md), and [`MessageTrackerService`](https://github.com/micheleboni/npm-angular/tree/main/projects/http-request-manager/src/docs/MESSAGE_TRACKER_README.md) | [`WebSocketSignalsManagerService`](https://github.com/micheleboni/npm-angular/tree/main/projects/http-request-manager/src/docs/WEBSOCKET_SIGNALS_README.md) and [`MessageTrackerSignalsService`](https://github.com/micheleboni/npm-angular/tree/main/projects/http-request-manager/src/docs/MESSAGE_TRACKER_SIGNALS_README.md) |
22
22
  | **💾 Data Persistence** | Local/session storage and offline caching | [`LocalStorageManagerService`](https://github.com/micheleboni/npm-angular/tree/main/projects/http-request-manager/src/docs/LOCAL_STORAGE_README.md) and [`DatabaseManagerService`](https://github.com/micheleboni/npm-angular/tree/main/projects/http-request-manager/src/docs/DATABASE_README.md) | [`LocalStorageSignalsManagerService`](https://github.com/micheleboni/npm-angular/tree/main/projects/http-request-manager/src/docs/LOCAL_STORAGE_SIGNALS_README.md) |
23
- | **🗄️ SQL on IndexedDB** | MySQL-syntax SQL queries against DexieJS IndexedDB | [`DexieSqlService`](https://github.com/micheleboni/npm-angular/tree/main/projects/http-request-manager/src/docs/SQL_DIXIE_README.md) | Uses the same service |
23
+ | **🗄️ Database Queries** | MySQL-syntax SQL queries on IndexedDB — the recommended way to query data | [`DexieSqlService`](https://github.com/micheleboni/npm-angular/tree/main/projects/http-request-manager/src/docs/SQL_DIXIE_README.md) | Uses the same service |
24
24
  | **⚡ Utility Functions** | JSON handling, encryption, headers, validation, logging | [`UtilsService`](https://github.com/micheleboni/npm-angular/tree/main/projects/http-request-manager/src/docs/UTILS_README.md), [`Encryption`](https://github.com/micheleboni/npm-angular/tree/main/projects/http-request-manager/src/docs/ENCRYPTION_README.md), [`Logger`](https://github.com/micheleboni/npm-angular/tree/main/projects/http-request-manager/src/docs/LOGGER_README.md) | Uses the same utility layer |
25
+ | **🔧 Utility Services** | Headers, path/query, merging, base request classes | [`Utility Services`](https://github.com/micheleboni/npm-angular/tree/main/projects/http-request-manager/src/docs/UTILS_SERVICES_README.md) | Internal and helper services |
25
26
 
26
27
  ### Key Benefits
27
28
 
@@ -37,12 +38,28 @@ Note on clearing persisted data:
37
38
  - **Clear full DB (fire-and-forget)**: To wipe the entire IndexedDB for this library and its associated localStorage metadata, call `DatabaseManagerService.clearDatabase()`. This method subscribes internally and is intentionally fire-and-forget — callers should simply call `databaseManager.clearDatabase()` (no `.subscribe()` required). The method also clears related localStorage metadata via `LocalStorageManagerService`.
38
39
  - **Clear a specific table (Observable)**: To remove records from a specific table, use `DatabaseManagerService.clearTableRecords(tableName)` which returns an `Observable<void>`; callers should `.subscribe()` or use RxJS operators to react to completion.
39
40
 
40
- ### 🚀 Advanced Features
41
+ ### �️ Database Access
42
+
43
+ The library provides two complementary services for working with IndexedDB data:
44
+
45
+ | Task | Service | Example |
46
+ |------|---------|---------|
47
+ | **Query data** (recommended) | `DexieSqlService` | `sql.query('SELECT * FROM orders WHERE status = "open"')` |
48
+ | **Create tables** | `DatabaseManagerService` | `db.createDatabaseTable(tableDef)` |
49
+ | **Insert / update records** | `DatabaseManagerService` | `db.createTableRecord('orders', record)` |
50
+ | **Delete records** | `DatabaseManagerService` | `db.deleteTableRecord('orders', id)` |
51
+ | **Clear / reset database** | `DatabaseManagerService` | `db.clearDatabase()` |
52
+
53
+ Use `DexieSqlService` for all read queries — it supports SELECT with WHERE, JOIN, ORDER BY, LIMIT, COUNT, DISTINCT, and more. Use `DatabaseManagerService` for table creation and write operations.
54
+
55
+ See the full SQL syntax reference: [`DexieSqlService Guide`](https://github.com/micheleboni/npm-angular/tree/main/projects/http-request-manager/src/docs/SQL_DIXIE_README.md)
56
+
57
+ ### �🚀 Advanced Features
41
58
 
42
59
  | Feature | Description | Learn More |
43
60
  |---------|-------------|------------|
44
61
  | **🔐 Enterprise Encryption** | AES symmetric + RSA asymmetric encryption | [`Encryption Utils`](https://github.com/micheleboni/npm-angular/tree/main/projects/http-request-manager/src/docs/ENCRYPTION_README.md) |
45
- | **🗄️ SQL on IndexedDB** | MySQL-syntax SELECT queries against DexieJSfilters, joins, ORDER BY, LIMIT, COUNT | [`DexieSqlService`](https://github.com/micheleboni/npm-angular/tree/main/projects/http-request-manager/src/docs/SQL_DIXIE_README.md) |
62
+ | **🗄️ Database Queries** | MySQL-syntax SQL queries on IndexedDBthe recommended way to query data (SELECT, WHERE, JOIN, ORDER BY, LIMIT, COUNT, DISTINCT) | [`DexieSqlService`](https://github.com/micheleboni/npm-angular/tree/main/projects/http-request-manager/src/docs/SQL_DIXIE_README.md) |
46
63
  | **📡 Streaming Support** | NDJSON & Server-Sent Events (SSE) | [`HTTP Manager`](https://github.com/micheleboni/npm-angular/tree/main/projects/http-request-manager/src/docs/HTTP_MANAGER_README.md#streaming) |
47
64
  | **📄 File Downloads** | Progress tracking for large files | [`HTTP Manager`](https://github.com/micheleboni/npm-angular/tree/main/projects/http-request-manager/src/docs/HTTP_MANAGER_README.md#file-downloads) |
48
65
  | **📤 File Uploads** | Multi-file upload with progress, validation, and form-data config | [`Upload Request`](https://github.com/micheleboni/npm-angular/tree/main/projects/http-request-manager/src/docs/UPLOAD_REQUEST_README.md) |
@@ -270,6 +287,42 @@ export class AppModule { }
270
287
  | `times` | `number` | Number of retry attempts | `0` |
271
288
  | `delay` | `number` | Delay between retries (seconds) | `3` |
272
289
 
290
+ #### WebSocket Options (`WSOptions`)
291
+
292
+ | Option | Type | Description | Default |
293
+ |--------|------|-------------|---------|
294
+ | `id` | `string` | Channel identifier (used to construct channel names) | `''` |
295
+ | `wsServer` | `string` | WebSocket server URL | `''` |
296
+ | `jwtToken` | `string` | JWT token for authentication | `''` |
297
+ | `permissions` | `string[]` | Permission levels for the connection | `[]` |
298
+ | `channels` | `string[]` | Additional channels to subscribe to | `[]` |
299
+ | `user` | `any` | User information for presence tracking | `undefined` |
300
+ | `retry` | `RetryOptions` | Retry configuration for reconnection | `{ times: 0, delay: 3 }` |
301
+
302
+ ### Injection Tokens
303
+
304
+ | Token | Type | Purpose | Required |
305
+ |-------|------|---------|----------|
306
+ | `CONFIG_SETTINGS_TOKEN` | `ConfigOptions` | Global library configuration (provided by `forRoot()`) | Yes (via `forRoot()`) |
307
+ | `APP_ID` | `string` | Unique application ID for encryption key generation | Yes (if using encryption) |
308
+
309
+ ### Providing APP_ID
310
+
311
+ If using encryption features (localStorage encryption, AES/RSA encryption), you must provide a unique `APP_ID`:
312
+
313
+ ```typescript
314
+ import { APP_ID } from '@angular/core';
315
+
316
+ @NgModule({
317
+ providers: [
318
+ { provide: APP_ID, useValue: 'your-unique-app-guid-here' }
319
+ ]
320
+ })
321
+ export class AppModule { }
322
+ ```
323
+
324
+ > **Important:** The `APP_ID` is used as the encryption key for `SymmetricalEncryptionService`. Use a strong, unique value per application.
325
+
273
326
  ## 📚 Services Overview
274
327
 
275
328
  ### Angular 14-18: Observable + NgRx Services
@@ -289,7 +342,7 @@ export class AppModule { }
289
342
 
290
343
  | Service | Description | Use Case |
291
344
  |---------|-------------|----------|
292
- | [`HTTPManagerSignalsService`](https://github.com/micheleboni/npm-angular/tree/main/projects/http-request-manager/src/docs/HTTP_SINGNALS_MANAGER_README.md) | Signal-based HTTP client for modern reactive UI | Modern Angular with Signals |
345
+ | [`HTTPManagerSignalsService`](https://github.com/micheleboni/npm-angular/tree/main/projects/http-request-manager/src/docs/HTTP_SIGNALS_MANAGER_README.md) | Signal-based HTTP client for modern reactive UI | Modern Angular with Signals |
293
346
  | [`LocalStorageSignalsManagerService`](https://github.com/micheleboni/npm-angular/tree/main/projects/http-request-manager/src/docs/LOCAL_STORAGE_SIGNALS_README.md) | Signal-based local/session storage | Reactive persisted UI state |
294
347
  | [`StoreStateManagerSignalsService`](https://github.com/micheleboni/npm-angular/tree/main/projects/http-request-manager/src/docs/STORE_STATE_SIGNALS_README.md) | Signal-based persistent state service | App state persistence with computed derivations |
295
348
  | [`WebSocketSignalsManagerService`](https://github.com/micheleboni/npm-angular/tree/main/projects/http-request-manager/src/docs/WEBSOCKET_SIGNALS_README.md) | Signal-based WebSocket manager | Signal-driven real-time dashboards and messaging |
@@ -300,6 +353,7 @@ export class AppModule { }
300
353
  | Service | Description | Use Case |
301
354
  |---------|-------------|----------|
302
355
  | [`UtilsService`](https://github.com/micheleboni/npm-angular/tree/main/projects/http-request-manager/src/docs/UTILS_README.md) | Utilities: encryption, headers, merging, path/query | Helper functions |
356
+ | [`Utility Services`](https://github.com/micheleboni/npm-angular/tree/main/projects/http-request-manager/src/docs/UTILS_SERVICES_README.md) | Headers, path/query, merging, base request classes | Internal and helper services |
303
357
 
304
358
  ### Common Use Cases
305
359
 
@@ -339,7 +393,7 @@ All detailed service guides live in `src/docs/`. Use this README as the entry po
339
393
  | Category | Documentation |
340
394
  |----------|---------------|
341
395
  | Overview | [Signal Services Overview](https://github.com/micheleboni/npm-angular/tree/main/projects/http-request-manager/src/docs/SIGNAL_SERVICES_README.md) |
342
- | HTTP | [HTTP Manager Signals](https://github.com/micheleboni/npm-angular/tree/main/projects/http-request-manager/src/docs/HTTP_SINGNALS_MANAGER_README.md) |
396
+ | HTTP | [HTTP Manager Signals](https://github.com/micheleboni/npm-angular/tree/main/projects/http-request-manager/src/docs/HTTP_SIGNALS_MANAGER_README.md) |
343
397
  | State | [Store State Signals](https://github.com/micheleboni/npm-angular/tree/main/projects/http-request-manager/src/docs/STORE_STATE_SIGNALS_README.md) |
344
398
  | Real-Time | [WebSocket Signals](https://github.com/micheleboni/npm-angular/tree/main/projects/http-request-manager/src/docs/WEBSOCKET_SIGNALS_README.md) and [Message Tracker Signals](https://github.com/micheleboni/npm-angular/tree/main/projects/http-request-manager/src/docs/MESSAGE_TRACKER_SIGNALS_README.md) |
345
399
  | Persistence | [Local Storage Signals](https://github.com/micheleboni/npm-angular/tree/main/projects/http-request-manager/src/docs/LOCAL_STORAGE_SIGNALS_README.md) |
@@ -465,7 +519,7 @@ For in-depth documentation on each service and component, refer to the following
465
519
  | Documentation | Description |
466
520
  |---------------|-------------|
467
521
  | 📖 [Signal Services Overview](https://github.com/micheleboni/npm-angular/tree/main/projects/http-request-manager/src/docs/SIGNAL_SERVICES_README.md) | Overview of the signal-based service set and migration guidance |
468
- | 📖 [HTTP Manager Signals Service](https://github.com/micheleboni/npm-angular/tree/main/projects/http-request-manager/src/docs/HTTP_SINGNALS_MANAGER_README.md) | Signal-based HTTP client for modern reactive UI with Angular Signals |
522
+ | 📖 [HTTP Manager Signals Service](https://github.com/micheleboni/npm-angular/tree/main/projects/http-request-manager/src/docs/HTTP_SIGNALS_MANAGER_README.md) | Signal-based HTTP client for modern reactive UI with Angular Signals |
469
523
  | 📖 [Local Storage Signals Manager Service](https://github.com/micheleboni/npm-angular/tree/main/projects/http-request-manager/src/docs/LOCAL_STORAGE_SIGNALS_README.md) | Signal-based persisted storage patterns |
470
524
  | 📖 [Store State Signals Manager Service](https://github.com/micheleboni/npm-angular/tree/main/projects/http-request-manager/src/docs/STORE_STATE_SIGNALS_README.md) | Signal-based state persistence and computed state |
471
525
  | 📖 [WebSocket Signals Manager Service](https://github.com/micheleboni/npm-angular/tree/main/projects/http-request-manager/src/docs/WEBSOCKET_SIGNALS_README.md) | Signal-driven WebSocket connection and subscription management |
@@ -908,54 +908,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
908
908
  }]
909
909
  }], ctorParameters: () => [] });
910
910
 
911
- class NormalizedRequestOptionsModel {
912
- constructor(pathKey = '', query = {}, hasQuery = false) {
913
- this.pathKey = pathKey;
914
- this.query = query;
915
- this.hasQuery = hasQuery;
916
- }
917
- static adapt(item) {
918
- return new NormalizedRequestOptionsModel(item?.pathKey, item?.query, item?.hasQuery);
919
- }
920
- }
921
-
922
- class PathTrackerStateModel {
923
- constructor(consumedValuesByKey = {}, watchExpiresAt) {
924
- this.consumedValuesByKey = consumedValuesByKey;
925
- this.watchExpiresAt = watchExpiresAt;
926
- }
927
- static adapt(item) {
928
- return new PathTrackerStateModel(item?.consumedValuesByKey && typeof item.consumedValuesByKey === 'object' ? item.consumedValuesByKey : {}, item?.watchExpiresAt);
929
- }
930
- }
931
-
932
- class QueryTrackerStateModel {
933
- constructor(paths = {}) {
934
- this.paths = paths;
935
- }
936
- static adapt(item) {
937
- const paths = {};
938
- if (item?.paths && typeof item.paths === 'object') {
939
- Object.keys(item.paths).forEach((key) => {
940
- paths[key] = PathTrackerStateModel.adapt(item.paths[key]);
941
- });
942
- }
943
- return new QueryTrackerStateModel(paths);
944
- }
945
- }
946
-
947
- class QueryParamsTrackerOptionsModel {
948
- constructor(mode, watchParams, watchExpiresAt, watchParamsExpire) {
949
- this.mode = mode;
950
- this.watchParams = watchParams;
951
- this.watchExpiresAt = watchExpiresAt;
952
- this.watchParamsExpire = watchParamsExpire;
953
- }
954
- static adapt(item) {
955
- return new QueryParamsTrackerOptionsModel(item?.mode, Array.isArray(item?.watchParams) ? item.watchParams : [], item?.watchExpiresAt, item?.watchParamsExpire);
956
- }
957
- }
958
-
959
911
  class StreamConfigModel {
960
912
  constructor(streamType = StreamType.AI_STREAMING, totalHeader = 'X-Total-Count') {
961
913
  this.streamType = streamType;
@@ -5156,17 +5108,15 @@ class ApiRequest {
5156
5108
  }
5157
5109
 
5158
5110
  class RequestOptions {
5159
- constructor(path = [], headers = {}, forceRefresh, ignoreQueryParams, queryParamsExpiresIn, watchParams, watchExpiresAt) {
5111
+ constructor(path = [], headers = {}, forceRefresh, ignoreQueryParams, queryParamsExpiresIn) {
5160
5112
  this.path = path;
5161
5113
  this.headers = headers;
5162
5114
  this.forceRefresh = forceRefresh;
5163
5115
  this.ignoreQueryParams = ignoreQueryParams;
5164
5116
  this.queryParamsExpiresIn = queryParamsExpiresIn;
5165
- this.watchParams = watchParams;
5166
- this.watchExpiresAt = watchExpiresAt;
5167
5117
  }
5168
5118
  static adapt(item) {
5169
- return new RequestOptions(item?.path, item?.headers, item?.forceRefresh, Array.isArray(item?.ignoreQueryParams) ? item.ignoreQueryParams : [], item?.queryParamsExpiresIn, item?.watchParams, item?.watchExpiresAt);
5119
+ return new RequestOptions(item?.path, item?.headers, item?.forceRefresh, Array.isArray(item?.ignoreQueryParams) ? item.ignoreQueryParams : [], item?.queryParamsExpiresIn);
5170
5120
  }
5171
5121
  }
5172
5122
 
@@ -6573,7 +6523,6 @@ class ChannelMessage {
6573
6523
  }
6574
6524
  }
6575
6525
 
6576
- // import { QueryParamsTrackerService } from '../utils/query-params-tracker.service';
6577
6526
  const API_OPTS = new InjectionToken('API_OPTS');
6578
6527
  /**
6579
6528
  * Channel type enum for different communication purposes
@@ -6616,7 +6565,6 @@ class HTTPManagerStateService extends ComponentStore {
6616
6565
  this.localStorageManagerService = inject(LocalStorageManagerService);
6617
6566
  this.utils = inject(UtilsService);
6618
6567
  this.logger = inject(LoggerService);
6619
- // private queryParamsTrackerService = inject(QueryParamsTrackerService)
6620
6568
  this.error$ = this.httpManagerService.error$;
6621
6569
  this.isPending$ = this.httpManagerService.isPending$.pipe(delay(1));
6622
6570
  this.operationSuccess = new BehaviorSubject(null);
@@ -7240,7 +7188,8 @@ class HTTPManagerStateService extends ComponentStore {
7240
7188
  this.createRecord = (data, options) => this.effect(() => of(data).pipe(switchMap((data) => {
7241
7189
  this.streamedResponse = [];
7242
7190
  const requestOptions = this.updateRequestOptions(options?.headers);
7243
- return this.httpManagerService.postRequest(data, requestOptions, options?.path)
7191
+ const effectiveParams = this.getEffectiveParams(options?.path);
7192
+ return this.httpManagerService.postRequest(data, requestOptions, effectiveParams)
7244
7193
  .pipe(tap((data) => {
7245
7194
  data = (!data) ? (this.dataType === DataType.ARRAY) ? [] : {} : data;
7246
7195
  this.addData$(data);
@@ -7258,7 +7207,8 @@ class HTTPManagerStateService extends ComponentStore {
7258
7207
  this.updateRecord = (data, options) => this.effect(() => of(data).pipe(concatMap((data) => {
7259
7208
  this.streamedResponse = [];
7260
7209
  const requestOptions = this.updateRequestOptions(options?.headers);
7261
- return this.httpManagerService.putRequest(data, requestOptions, options?.path)
7210
+ const effectiveParams = this.getEffectiveParams(options?.path);
7211
+ return this.httpManagerService.putRequest(data, requestOptions, effectiveParams)
7262
7212
  .pipe(tap((data) => {
7263
7213
  data = (!data) ? (this.dataType === DataType.ARRAY) ? [] : {} : data;
7264
7214
  this.updateData$(data);
@@ -7276,7 +7226,8 @@ class HTTPManagerStateService extends ComponentStore {
7276
7226
  this.deleteRecord = (options) => this.effect(() => of(options).pipe(concatMap((data) => {
7277
7227
  this.streamedResponse = [];
7278
7228
  const requestOptions = this.updateRequestOptions(options?.headers);
7279
- return this.httpManagerService.deleteRequest(requestOptions, options?.path)
7229
+ const effectiveParams = this.getEffectiveParams(options?.path);
7230
+ return this.httpManagerService.deleteRequest(requestOptions, effectiveParams)
7280
7231
  .pipe(tap((data) => {
7281
7232
  data = (!data) ? (this.dataType === DataType.ARRAY) ? [] : {} : data;
7282
7233
  this.deleteData$(data);
@@ -7294,7 +7245,8 @@ class HTTPManagerStateService extends ComponentStore {
7294
7245
  // FETCH STREAM
7295
7246
  this.createStream = (data, options) => this.effect(() => of(data).pipe(tap(() => this.httpManagerService.isPending.next(true)), switchMap((data) => {
7296
7247
  const requestOptions = this.updateRequestOptions(options?.headers);
7297
- return this.httpManagerService.postRequest(data, requestOptions, options?.path)
7248
+ const effectiveParams = this.getEffectiveParams(options?.path);
7249
+ return this.httpManagerService.postRequest(data, requestOptions, effectiveParams)
7298
7250
  .pipe(tap((res) => {
7299
7251
  if (res.length > 0)
7300
7252
  this.setData$(res);
@@ -8091,12 +8043,9 @@ class HTTPManagerStateService extends ComponentStore {
8091
8043
  const effective = this.getEffectiveParams(params);
8092
8044
  return effective ? [...basePath, ...effective] : [...basePath];
8093
8045
  }
8094
- getEffectiveParams(params) {
8095
- if (!Array.isArray(params) || params.length === 0) {
8096
- return undefined;
8097
- }
8046
+ stripBasePathPrefix(params) {
8098
8047
  const basePath = Array.isArray(this.apiOptions.path) ? this.apiOptions.path : [];
8099
- if (basePath.length !== params.length) {
8048
+ if (basePath.length === 0 || params.length < basePath.length) {
8100
8049
  return params;
8101
8050
  }
8102
8051
  const normalizePart = (value) => {
@@ -8105,8 +8054,25 @@ class HTTPManagerStateService extends ComponentStore {
8105
8054
  }
8106
8055
  return String(value);
8107
8056
  };
8108
- const samePath = params.every((part, index) => normalizePart(part) === normalizePart(basePath[index]));
8109
- return samePath ? undefined : params;
8057
+ const startsWithBase = basePath.every((part, index) => normalizePart(part) === normalizePart(params[index]));
8058
+ return startsWithBase ? params.slice(basePath.length) : params;
8059
+ }
8060
+ getEffectiveParams(params) {
8061
+ if (!Array.isArray(params) || params.length === 0) {
8062
+ return undefined;
8063
+ }
8064
+ const basePath = Array.isArray(this.apiOptions.path) ? this.apiOptions.path : [];
8065
+ if (basePath.length === params.length) {
8066
+ const normalizePart = (value) => {
8067
+ if (value && typeof value === 'object') {
8068
+ return JSON.stringify(this.normalizeObject(value));
8069
+ }
8070
+ return String(value);
8071
+ };
8072
+ const samePath = params.every((part, index) => normalizePart(part) === normalizePart(basePath[index]));
8073
+ return samePath ? undefined : params;
8074
+ }
8075
+ return this.stripBasePathPrefix(params);
8110
8076
  }
8111
8077
  buildRequestSignature(method, requestOptions, params) {
8112
8078
  const signaturePayload = {
@@ -8161,6 +8127,9 @@ class HTTPManagerStateService extends ComponentStore {
8161
8127
  this._requestCachePaths.set(tableName, this.resolvePath(options?.path).filter(p => typeof p === 'string' || typeof p === 'number').map(String));
8162
8128
  this.localStorageManagerService.store$(tableName).pipe(take(1), tap((storeData) => {
8163
8129
  const currentCache = storeData?.requestCache || {};
8130
+ const currentEntry = currentCache[type] || {};
8131
+ const currentQueryParams = { ...(currentEntry.queryParams || {}) };
8132
+ const currentQueryParamsExpires = currentEntry.queryParamsExpires ?? null;
8164
8133
  this.localStorageManagerService.updateStore({
8165
8134
  name: tableName,
8166
8135
  data: {
@@ -8168,11 +8137,13 @@ class HTTPManagerStateService extends ComponentStore {
8168
8137
  requestCache: {
8169
8138
  ...currentCache,
8170
8139
  [type]: {
8171
- ...(currentCache[type] || {}),
8140
+ ...currentEntry,
8172
8141
  signature,
8173
8142
  savedAt: Date.now(),
8174
8143
  path: this.resolvePath(options?.path),
8175
- headers: this.filterHeaders(options?.headers)
8144
+ headers: this.filterHeaders(options?.headers),
8145
+ queryParams: currentQueryParams,
8146
+ queryParamsExpires: currentQueryParamsExpires,
8176
8147
  }
8177
8148
  }
8178
8149
  }
@@ -8192,7 +8163,6 @@ class HTTPManagerStateService extends ComponentStore {
8192
8163
  }
8193
8164
  }
8194
8165
  if (Array.isArray(pathArray) && pathArray.length > 0) {
8195
- // this.queryParamsTrackerService.clearTrackingForPath(pathArray.join('/'))
8196
8166
  this._requestCachePaths.delete(tableName);
8197
8167
  }
8198
8168
  if (!storeData)
@@ -8338,11 +8308,11 @@ class HTTPManagerStateService extends ComponentStore {
8338
8308
  accepted = true;
8339
8309
  }
8340
8310
  });
8341
- if (accepted) {
8342
- const newExpiry = this.trackerBuildExpiryEpoch(options?.queryParamsExpiresIn);
8343
- if (newExpiry !== null) {
8344
- queryParamsExpires = newExpiry;
8345
- }
8311
+ const newExpiry = this.trackerBuildExpiryEpoch(options?.queryParamsExpiresIn);
8312
+ if (newExpiry !== null) {
8313
+ queryParamsExpires = newExpiry;
8314
+ }
8315
+ if (accepted || newExpiry !== null) {
8346
8316
  this.localStorageManagerService.store$(tableName).pipe(take(1), tap((latestStoreData) => {
8347
8317
  const currentCache = latestStoreData?.requestCache || {};
8348
8318
  const currentEntry = currentCache[type] || {};
@@ -8714,10 +8684,11 @@ class SqlParser {
8714
8684
  if (ast.type !== 'select') {
8715
8685
  throw new SqlParseError('Only SELECT statements are supported');
8716
8686
  }
8687
+ const stripPrefix = (list) => list.map(entry => entry.split('::').pop() ?? entry);
8717
8688
  return {
8718
8689
  ast,
8719
- tableList: result.tableList ?? [],
8720
- columnList: result.columnList ?? [],
8690
+ tableList: stripPrefix(result.tableList ?? []),
8691
+ columnList: stripPrefix(result.columnList ?? []),
8721
8692
  };
8722
8693
  }
8723
8694
  }
@@ -8988,7 +8959,9 @@ class QueryPlanner {
8988
8959
  const where = ast.where;
8989
8960
  const boundedFilters = [];
8990
8961
  if (where) {
8991
- this._flattenAnd(where.operator === 'AND' ? where : { operator: 'AND', left: where, right: null })
8962
+ this._flattenAnd(where.operator === 'AND'
8963
+ ? where
8964
+ : { type: 'binary_expr', operator: 'AND', left: where, right: null })
8992
8965
  .filter(Boolean)
8993
8966
  .forEach((c) => boundedFilters.push(this._nodeToStep(c, aliases, mainTable)));
8994
8967
  }
@@ -9021,6 +8994,7 @@ class QueryPlanner {
9021
8994
  }
9022
8995
  else if (vals.length === 1) {
9023
8996
  plan.limit = vals[0].value;
8997
+ plan.offset = null;
9024
8998
  }
9025
8999
  }
9026
9000
  // Projection
@@ -10686,7 +10660,7 @@ class RequestManagerStateDemoComponent {
10686
10660
  const apiOptions = ApiRequest.adapt({ ...currentOptions, path: pathReq });
10687
10661
  return { apiOptions: apiOptions, path: pathReq };
10688
10662
  }
10689
- parseWatchParams(value) {
10663
+ parseIgnoreParams(value) {
10690
10664
  if (!value || typeof value !== 'string') {
10691
10665
  return [];
10692
10666
  }
@@ -10695,25 +10669,16 @@ class RequestManagerStateDemoComponent {
10695
10669
  .map((item) => item.trim())
10696
10670
  .filter((item) => item.length > 0);
10697
10671
  }
10698
- normalizeWatchExpiry(value) {
10699
- if (typeof value === 'undefined' || value === null || value === '') {
10700
- return undefined;
10701
- }
10702
- if (typeof value === 'string' && value.trim().toLowerCase() === 'never') {
10703
- return undefined;
10704
- }
10705
- return value;
10706
- }
10707
10672
  buildDemoRequestOptions(path, headers) {
10708
10673
  const dbValue = this.database || {};
10709
10674
  const isDbEnabled = !!this.DBState?.checked;
10710
- const parsedWatchParams = this.parseWatchParams(dbValue?.ignoreQueryParams);
10675
+ const parsedIgnoreQueryParams = this.parseIgnoreParams(dbValue?.ignoreQueryParams);
10711
10676
  return RequestOptions.adapt({
10712
10677
  path,
10713
10678
  headers,
10714
10679
  forceRefresh: false,
10715
- watchParams: isDbEnabled && parsedWatchParams.length > 0 ? parsedWatchParams : undefined,
10716
- watchExpiresAt: isDbEnabled ? this.normalizeWatchExpiry(dbValue?.queryParamsExpiresIn) : undefined,
10680
+ ignoreQueryParams: isDbEnabled && parsedIgnoreQueryParams.length > 0 ? parsedIgnoreQueryParams : undefined,
10681
+ queryParamsExpiresIn: isDbEnabled ? dbValue?.queryParamsExpiresIn : undefined,
10717
10682
  });
10718
10683
  }
10719
10684
  onSetStateOptions() {
@@ -11936,13 +11901,24 @@ class WsDataControlComponent {
11936
11901
  .pipe(switchMap$1((action) => timer(3 * 1000).pipe(map$1(() => null), startWith$1(action))));
11937
11902
  this.data$ = this.stateDataRequestService.data$;
11938
11903
  this.isUser = (user, userItem) => {
11939
- return user.sessionId === userItem.sessionId;
11904
+ return user.id === userItem?.id;
11905
+ };
11906
+ this.getUserLabel = (user) => {
11907
+ const name = user.name || user.ldap || 'Anonymous';
11908
+ const shortId = user.id ? user.id.substring(0, 8) : '';
11909
+ return shortId ? `${name} (${shortId})` : name;
11940
11910
  };
11941
11911
  }
11942
11912
  ngOnInit() {
11943
11913
  this.stateDataRequestService.updateConnection(this.server, this.wsServer, this.jwtToken, this.user, this.path);
11944
11914
  this.stateDataRequestService.getData();
11945
11915
  }
11916
+ ngOnChanges(changes) {
11917
+ if (changes['jwtToken'] && !changes['jwtToken'].firstChange) {
11918
+ this.stateDataRequestService.updateConnection(this.server, this.wsServer, this.jwtToken, this.user, this.path);
11919
+ this.stateDataRequestService.getData();
11920
+ }
11921
+ }
11946
11922
  onGetData() {
11947
11923
  this.stateDataRequestService.getData();
11948
11924
  }
@@ -11951,12 +11927,15 @@ class WsDataControlComponent {
11951
11927
  }
11952
11928
  onUpdateData(data) {
11953
11929
  const num = RandomNumber(1000, 9999);
11930
+ const firstName = this.user?.name?.split(' ')[0] || 'mike';
11931
+ const lastName = this.user?.name?.split(' ').slice(1).join(' ') || 'boni';
11932
+ const email = this.user?.email || 'mikeboni@hotmail.com';
11954
11933
  const newData = {
11955
11934
  "spiffe": `wavecoders.com/developer/${num}`,
11956
11935
  "id": 63,
11957
- "last_name": "boni",
11958
- "email": "mikeboni@hotmail.com",
11959
- "first_name": "mike"
11936
+ "last_name": lastName,
11937
+ "email": email,
11938
+ "first_name": firstName
11960
11939
  };
11961
11940
  this.stateDataRequestService.updateData(newData);
11962
11941
  }
@@ -12023,11 +12002,11 @@ class WsDataControlComponent {
12023
12002
  });
12024
12003
  }
12025
12004
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: WsDataControlComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
12026
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: WsDataControlComponent, selector: "app-ws-data-control", inputs: { server: "server", wsServer: "wsServer", jwtToken: "jwtToken", user: "user", path: "path" }, ngImport: i0, template: "@if ((data$ | async); as data) {\n <div style=\"margin: 1rem;\">\n @if ((users$ |async); as users) {\n <div>\n @if (users.length > 0) {\n <h3 style=\"margin: 0;\">Connected Users</h3>\n } @else {\n <h3 style=\"margin: 0;\">No Users</h3>\n }\n <mat-chip-set>\n @for (user of users; track $index) {\n <mat-chip\n [class.user-chip--primary]=\"isUser(user, (user$ | async))\"\n [style.color]=\"isUser(user, (user$ | async)) ? '#fff' : null\"\n [disableRipple]=\"true\"\n >\n {{ user.name || user.ldap || user.id || 'Anonymous' }}\n </mat-chip>\n }\n </mat-chip-set>\n </div>\n }\n <div style=\"margin-top: 1rem; margin-bottom: 1rem;\">\n <mat-divider></mat-divider>\n </div>\n\n <div class=\"box\" style=\"margin-bottom: 1rem;\" *ngIf=\"(userAction$ | async) as userAction\">\n {{ userAction?.content?.user?.name }} has {{ userAction?.content?.method }}\n </div>\n\n <h3 style=\"margin: 0;\">Data Actions</h3>\n <div style=\"display: flex; gap: 1rem; margin-bottom: 1rem;\">\n <button mat-stroked-button (click)=\"onGetData()\">Get Data</button>\n <div style=\"flex:1\"></div>\n <button mat-stroked-button color=\"accent\" (click)=\"onUpdateData(data)\">Update Data</button>\n <button mat-stroked-button color=\"warn\" (click)=\"onRemoveData(data)\">Remove Data</button>\n <button mat-stroked-button color=\"primary\" (click)=\"onAddData()\">Add Data</button>\n </div>\n\n <h3 style=\"margin: 0; margin-top: 1rem;\">WebSocketMessageService Test</h3>\n\n <p style=\"font-size: 0.875rem; color: #666; margin: 0;\">\n <strong>Note:</strong> \"Fake SessionId\" will be received and processed. \"Current SessionId\" will be filtered out (self-message).\n @if (data.length > 0) {\n <div>\n <table mat-table [dataSource]=\"data\" style=\"border: 1px solid grey;\">\n <ng-container matColumnDef=\"id\">\n <th mat-header-cell *matHeaderCellDef> ID </th>\n <td mat-cell *matCellDef=\"let element\"> {{element.id}} </td>\n </ng-container>\n <ng-container matColumnDef=\"spiffe\">\n <th mat-header-cell *matHeaderCellDef> Spiffe </th>\n <td mat-cell *matCellDef=\"let element\"> {{element.spiffe}} </td>\n </ng-container>\n <ng-container matColumnDef=\"name\">\n <th mat-header-cell *matHeaderCellDef> Name </th>\n <td mat-cell *matCellDef=\"let element\"> {{element.first_name}} {{element.last_name}}</td>\n </ng-container>\n <ng-container matColumnDef=\"email\">\n <th mat-header-cell *matHeaderCellDef> Email </th>\n <td mat-cell *matCellDef=\"let element\"> {{element.email}} </td>\n </ng-container>\n <tr mat-header-row *matHeaderRowDef=\"['id', 'spiffe', 'name', 'email']\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: ['id', 'spiffe', 'name', 'email'];\"></tr>\n </table>\n <div style=\"border: 1px solid grey; padding: .5rem; border-top: none;\">\n <h3 style=\"margin: 0;\">Total Records {{ data.length }}</h3>\n </div>\n </div>\n } @else {\n <div style=\"margin-top: 1rem; font-style: italic;\">\n No Data Available\n </div>\n }\n\n <div style=\"margin-bottom: 1rem; margin-top: 1rem;\">\n <mat-divider></mat-divider>\n </div>\n\n <div style=\"display: flex; gap: 0.5rem; margin-bottom: 1rem;\">\n <button mat-flat-button color=\"primary\" (click)=\"onTestDirectStateMessage(63, true)\">\n Test UPDATE (Fake Id)\n </button>\n <button mat-stroked-button (click)=\"onTestDirectStateMessage(63, false)\">\n Test UPDATE (Current Id)\n </button>\n <button mat-stroked-button (click)=\"onTestDirectStateMessage(63, false, 'custom-session-123')\">\n Test UPDATE (Custom Id)\n </button>\n </div>\n\n </div>\n}\n\n", styles: [".user-chip--primary{background-color:var(--mdc-theme-primary, var(--md-sys-color-primary, #3f51b5))!important;color:#fff!important;--mdc-evolution-chip-container-color: var(--mdc-theme-primary, var(--md-sys-color-primary, #3f51b5));--mdc-evolution-chip-label-text-color: #fff}.user-chip--primary :is(.mdc-evolution-chip__text-label,.mdc-evolution-chip__action,.mdc-evolution-chip__cell,.mat-mdc-chip-action-label){color:#fff!important}.user-chip--primary,.user-chip--primary *{color:#fff!important}:host ::ng-deep .user-chip--primary{background-color:var(--mdc-theme-primary, var(--md-sys-color-primary, #3f51b5))!important;color:#fff!important;--mdc-evolution-chip-container-color: var(--mdc-theme-primary, var(--md-sys-color-primary, #3f51b5));--mdc-evolution-chip-label-text-color: #fff}:host ::ng-deep .user-chip--primary .mdc-evolution-chip__text-label,:host ::ng-deep .user-chip--primary .mdc-evolution-chip__action,:host ::ng-deep .user-chip--primary .mdc-evolution-chip__cell,:host ::ng-deep .user-chip--primary .mat-mdc-chip-action-label,:host ::ng-deep .user-chip--primary *{color:#fff!important}.box{padding:.5rem;border:1px solid rgb(174,174,13);background-color:#ececaf}\n"], dependencies: [{ kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i3.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: i3$1.MatChip, selector: "mat-basic-chip, [mat-basic-chip], mat-chip, [mat-chip]", inputs: ["role", "id", "aria-label", "aria-description", "value", "color", "removable", "highlighted", "disableRipple", "disabled"], outputs: ["removed", "destroyed"], exportAs: ["matChip"] }, { kind: "component", type: i3$1.MatChipSet, selector: "mat-chip-set", inputs: ["disabled", "role", "tabIndex"] }, { kind: "component", type: i9.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i9.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i9.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i9.MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: i9.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i9.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i9.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i9.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i9.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i9.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "component", type: i12.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "pipe", type: i1$1.AsyncPipe, name: "async" }] }); }
12005
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: WsDataControlComponent, selector: "app-ws-data-control", inputs: { server: "server", wsServer: "wsServer", jwtToken: "jwtToken", user: "user", path: "path" }, usesOnChanges: true, ngImport: i0, template: "@if ((data$ | async); as data) {\n <div style=\"margin: 1rem;\">\n @if ((users$ |async); as users) {\n <div>\n @if (users.length > 0) {\n <h3 style=\"margin: 0;\">Connected Users</h3>\n } @else {\n <h3 style=\"margin: 0;\">No Users</h3>\n }\n <mat-chip-set>\n @for (user of users; track $index) {\n <mat-chip\n [class.user-chip--primary]=\"isUser(user, (user$ | async))\"\n [style.color]=\"isUser(user, (user$ | async)) ? '#fff' : null\"\n [disableRipple]=\"true\"\n >\n {{ getUserLabel(user) }}\n </mat-chip>\n }\n </mat-chip-set>\n </div>\n }\n <div style=\"margin-top: 1rem; margin-bottom: 1rem;\">\n <mat-divider></mat-divider>\n </div>\n\n <div class=\"box\" style=\"margin-bottom: 1rem;\" *ngIf=\"(userAction$ | async) as userAction\">\n {{ userAction?.content?.user?.name }} has {{ userAction?.content?.method }}\n </div>\n\n <h3 style=\"margin: 0;\">Data Actions</h3>\n <div style=\"display: flex; gap: 1rem; margin-bottom: 1rem;\">\n <button mat-stroked-button (click)=\"onGetData()\">Get Data</button>\n <div style=\"flex:1\"></div>\n <button mat-stroked-button color=\"accent\" (click)=\"onUpdateData(data)\">Update Data</button>\n <button mat-stroked-button color=\"warn\" (click)=\"onRemoveData(data)\">Remove Data</button>\n <button mat-stroked-button color=\"primary\" (click)=\"onAddData()\">Add Data</button>\n </div>\n\n <h3 style=\"margin: 0; margin-top: 1rem;\">WebSocketMessageService Test</h3>\n\n <p style=\"font-size: 0.875rem; color: #666; margin: 0;\">\n <strong>Note:</strong> \"Fake SessionId\" will be received and processed. \"Current SessionId\" will be filtered out (self-message).\n @if (data.length > 0) {\n <div>\n <table mat-table [dataSource]=\"data\" style=\"border: 1px solid grey;\">\n <ng-container matColumnDef=\"id\">\n <th mat-header-cell *matHeaderCellDef> ID </th>\n <td mat-cell *matCellDef=\"let element\"> {{element.id}} </td>\n </ng-container>\n <ng-container matColumnDef=\"spiffe\">\n <th mat-header-cell *matHeaderCellDef> Spiffe </th>\n <td mat-cell *matCellDef=\"let element\"> {{element.spiffe}} </td>\n </ng-container>\n <ng-container matColumnDef=\"name\">\n <th mat-header-cell *matHeaderCellDef> Name </th>\n <td mat-cell *matCellDef=\"let element\"> {{element.first_name}} {{element.last_name}}</td>\n </ng-container>\n <ng-container matColumnDef=\"email\">\n <th mat-header-cell *matHeaderCellDef> Email </th>\n <td mat-cell *matCellDef=\"let element\"> {{element.email}} </td>\n </ng-container>\n <tr mat-header-row *matHeaderRowDef=\"['id', 'spiffe', 'name', 'email']\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: ['id', 'spiffe', 'name', 'email'];\"></tr>\n </table>\n <div style=\"border: 1px solid grey; padding: .5rem; border-top: none;\">\n <h3 style=\"margin: 0;\">Total Records {{ data.length }}</h3>\n </div>\n </div>\n } @else {\n <div style=\"margin-top: 1rem; font-style: italic;\">\n No Data Available\n </div>\n }\n\n <div style=\"margin-bottom: 1rem; margin-top: 1rem;\">\n <mat-divider></mat-divider>\n </div>\n\n <div style=\"display: flex; gap: 0.5rem; margin-bottom: 1rem;\">\n <button mat-flat-button color=\"primary\" (click)=\"onTestDirectStateMessage(63, true)\">\n Test UPDATE (Fake Id)\n </button>\n <button mat-stroked-button (click)=\"onTestDirectStateMessage(63, false)\">\n Test UPDATE (Current Id)\n </button>\n <button mat-stroked-button (click)=\"onTestDirectStateMessage(63, false, 'custom-session-123')\">\n Test UPDATE (Custom Id)\n </button>\n </div>\n\n </div>\n}\n\n", styles: [".user-chip--primary{background-color:var(--mdc-theme-primary, var(--md-sys-color-primary, #3f51b5))!important;color:#fff!important;--mdc-evolution-chip-container-color: var(--mdc-theme-primary, var(--md-sys-color-primary, #3f51b5));--mdc-evolution-chip-label-text-color: #fff}.user-chip--primary :is(.mdc-evolution-chip__text-label,.mdc-evolution-chip__action,.mdc-evolution-chip__cell,.mat-mdc-chip-action-label){color:#fff!important}.user-chip--primary,.user-chip--primary *{color:#fff!important}:host ::ng-deep .user-chip--primary{background-color:var(--mdc-theme-primary, var(--md-sys-color-primary, #3f51b5))!important;color:#fff!important;--mdc-evolution-chip-container-color: var(--mdc-theme-primary, var(--md-sys-color-primary, #3f51b5));--mdc-evolution-chip-label-text-color: #fff}:host ::ng-deep .user-chip--primary .mdc-evolution-chip__text-label,:host ::ng-deep .user-chip--primary .mdc-evolution-chip__action,:host ::ng-deep .user-chip--primary .mdc-evolution-chip__cell,:host ::ng-deep .user-chip--primary .mat-mdc-chip-action-label,:host ::ng-deep .user-chip--primary *{color:#fff!important}.box{padding:.5rem;border:1px solid rgb(174,174,13);background-color:#ececaf}\n"], dependencies: [{ kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i3.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: i3$1.MatChip, selector: "mat-basic-chip, [mat-basic-chip], mat-chip, [mat-chip]", inputs: ["role", "id", "aria-label", "aria-description", "value", "color", "removable", "highlighted", "disableRipple", "disabled"], outputs: ["removed", "destroyed"], exportAs: ["matChip"] }, { kind: "component", type: i3$1.MatChipSet, selector: "mat-chip-set", inputs: ["disabled", "role", "tabIndex"] }, { kind: "component", type: i9.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i9.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i9.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i9.MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: i9.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i9.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i9.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i9.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i9.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i9.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "component", type: i12.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "pipe", type: i1$1.AsyncPipe, name: "async" }] }); }
12027
12006
  }
12028
12007
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: WsDataControlComponent, decorators: [{
12029
12008
  type: Component,
12030
- args: [{ selector: 'app-ws-data-control', standalone: false, template: "@if ((data$ | async); as data) {\n <div style=\"margin: 1rem;\">\n @if ((users$ |async); as users) {\n <div>\n @if (users.length > 0) {\n <h3 style=\"margin: 0;\">Connected Users</h3>\n } @else {\n <h3 style=\"margin: 0;\">No Users</h3>\n }\n <mat-chip-set>\n @for (user of users; track $index) {\n <mat-chip\n [class.user-chip--primary]=\"isUser(user, (user$ | async))\"\n [style.color]=\"isUser(user, (user$ | async)) ? '#fff' : null\"\n [disableRipple]=\"true\"\n >\n {{ user.name || user.ldap || user.id || 'Anonymous' }}\n </mat-chip>\n }\n </mat-chip-set>\n </div>\n }\n <div style=\"margin-top: 1rem; margin-bottom: 1rem;\">\n <mat-divider></mat-divider>\n </div>\n\n <div class=\"box\" style=\"margin-bottom: 1rem;\" *ngIf=\"(userAction$ | async) as userAction\">\n {{ userAction?.content?.user?.name }} has {{ userAction?.content?.method }}\n </div>\n\n <h3 style=\"margin: 0;\">Data Actions</h3>\n <div style=\"display: flex; gap: 1rem; margin-bottom: 1rem;\">\n <button mat-stroked-button (click)=\"onGetData()\">Get Data</button>\n <div style=\"flex:1\"></div>\n <button mat-stroked-button color=\"accent\" (click)=\"onUpdateData(data)\">Update Data</button>\n <button mat-stroked-button color=\"warn\" (click)=\"onRemoveData(data)\">Remove Data</button>\n <button mat-stroked-button color=\"primary\" (click)=\"onAddData()\">Add Data</button>\n </div>\n\n <h3 style=\"margin: 0; margin-top: 1rem;\">WebSocketMessageService Test</h3>\n\n <p style=\"font-size: 0.875rem; color: #666; margin: 0;\">\n <strong>Note:</strong> \"Fake SessionId\" will be received and processed. \"Current SessionId\" will be filtered out (self-message).\n @if (data.length > 0) {\n <div>\n <table mat-table [dataSource]=\"data\" style=\"border: 1px solid grey;\">\n <ng-container matColumnDef=\"id\">\n <th mat-header-cell *matHeaderCellDef> ID </th>\n <td mat-cell *matCellDef=\"let element\"> {{element.id}} </td>\n </ng-container>\n <ng-container matColumnDef=\"spiffe\">\n <th mat-header-cell *matHeaderCellDef> Spiffe </th>\n <td mat-cell *matCellDef=\"let element\"> {{element.spiffe}} </td>\n </ng-container>\n <ng-container matColumnDef=\"name\">\n <th mat-header-cell *matHeaderCellDef> Name </th>\n <td mat-cell *matCellDef=\"let element\"> {{element.first_name}} {{element.last_name}}</td>\n </ng-container>\n <ng-container matColumnDef=\"email\">\n <th mat-header-cell *matHeaderCellDef> Email </th>\n <td mat-cell *matCellDef=\"let element\"> {{element.email}} </td>\n </ng-container>\n <tr mat-header-row *matHeaderRowDef=\"['id', 'spiffe', 'name', 'email']\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: ['id', 'spiffe', 'name', 'email'];\"></tr>\n </table>\n <div style=\"border: 1px solid grey; padding: .5rem; border-top: none;\">\n <h3 style=\"margin: 0;\">Total Records {{ data.length }}</h3>\n </div>\n </div>\n } @else {\n <div style=\"margin-top: 1rem; font-style: italic;\">\n No Data Available\n </div>\n }\n\n <div style=\"margin-bottom: 1rem; margin-top: 1rem;\">\n <mat-divider></mat-divider>\n </div>\n\n <div style=\"display: flex; gap: 0.5rem; margin-bottom: 1rem;\">\n <button mat-flat-button color=\"primary\" (click)=\"onTestDirectStateMessage(63, true)\">\n Test UPDATE (Fake Id)\n </button>\n <button mat-stroked-button (click)=\"onTestDirectStateMessage(63, false)\">\n Test UPDATE (Current Id)\n </button>\n <button mat-stroked-button (click)=\"onTestDirectStateMessage(63, false, 'custom-session-123')\">\n Test UPDATE (Custom Id)\n </button>\n </div>\n\n </div>\n}\n\n", styles: [".user-chip--primary{background-color:var(--mdc-theme-primary, var(--md-sys-color-primary, #3f51b5))!important;color:#fff!important;--mdc-evolution-chip-container-color: var(--mdc-theme-primary, var(--md-sys-color-primary, #3f51b5));--mdc-evolution-chip-label-text-color: #fff}.user-chip--primary :is(.mdc-evolution-chip__text-label,.mdc-evolution-chip__action,.mdc-evolution-chip__cell,.mat-mdc-chip-action-label){color:#fff!important}.user-chip--primary,.user-chip--primary *{color:#fff!important}:host ::ng-deep .user-chip--primary{background-color:var(--mdc-theme-primary, var(--md-sys-color-primary, #3f51b5))!important;color:#fff!important;--mdc-evolution-chip-container-color: var(--mdc-theme-primary, var(--md-sys-color-primary, #3f51b5));--mdc-evolution-chip-label-text-color: #fff}:host ::ng-deep .user-chip--primary .mdc-evolution-chip__text-label,:host ::ng-deep .user-chip--primary .mdc-evolution-chip__action,:host ::ng-deep .user-chip--primary .mdc-evolution-chip__cell,:host ::ng-deep .user-chip--primary .mat-mdc-chip-action-label,:host ::ng-deep .user-chip--primary *{color:#fff!important}.box{padding:.5rem;border:1px solid rgb(174,174,13);background-color:#ececaf}\n"] }]
12009
+ args: [{ selector: 'app-ws-data-control', standalone: false, template: "@if ((data$ | async); as data) {\n <div style=\"margin: 1rem;\">\n @if ((users$ |async); as users) {\n <div>\n @if (users.length > 0) {\n <h3 style=\"margin: 0;\">Connected Users</h3>\n } @else {\n <h3 style=\"margin: 0;\">No Users</h3>\n }\n <mat-chip-set>\n @for (user of users; track $index) {\n <mat-chip\n [class.user-chip--primary]=\"isUser(user, (user$ | async))\"\n [style.color]=\"isUser(user, (user$ | async)) ? '#fff' : null\"\n [disableRipple]=\"true\"\n >\n {{ getUserLabel(user) }}\n </mat-chip>\n }\n </mat-chip-set>\n </div>\n }\n <div style=\"margin-top: 1rem; margin-bottom: 1rem;\">\n <mat-divider></mat-divider>\n </div>\n\n <div class=\"box\" style=\"margin-bottom: 1rem;\" *ngIf=\"(userAction$ | async) as userAction\">\n {{ userAction?.content?.user?.name }} has {{ userAction?.content?.method }}\n </div>\n\n <h3 style=\"margin: 0;\">Data Actions</h3>\n <div style=\"display: flex; gap: 1rem; margin-bottom: 1rem;\">\n <button mat-stroked-button (click)=\"onGetData()\">Get Data</button>\n <div style=\"flex:1\"></div>\n <button mat-stroked-button color=\"accent\" (click)=\"onUpdateData(data)\">Update Data</button>\n <button mat-stroked-button color=\"warn\" (click)=\"onRemoveData(data)\">Remove Data</button>\n <button mat-stroked-button color=\"primary\" (click)=\"onAddData()\">Add Data</button>\n </div>\n\n <h3 style=\"margin: 0; margin-top: 1rem;\">WebSocketMessageService Test</h3>\n\n <p style=\"font-size: 0.875rem; color: #666; margin: 0;\">\n <strong>Note:</strong> \"Fake SessionId\" will be received and processed. \"Current SessionId\" will be filtered out (self-message).\n @if (data.length > 0) {\n <div>\n <table mat-table [dataSource]=\"data\" style=\"border: 1px solid grey;\">\n <ng-container matColumnDef=\"id\">\n <th mat-header-cell *matHeaderCellDef> ID </th>\n <td mat-cell *matCellDef=\"let element\"> {{element.id}} </td>\n </ng-container>\n <ng-container matColumnDef=\"spiffe\">\n <th mat-header-cell *matHeaderCellDef> Spiffe </th>\n <td mat-cell *matCellDef=\"let element\"> {{element.spiffe}} </td>\n </ng-container>\n <ng-container matColumnDef=\"name\">\n <th mat-header-cell *matHeaderCellDef> Name </th>\n <td mat-cell *matCellDef=\"let element\"> {{element.first_name}} {{element.last_name}}</td>\n </ng-container>\n <ng-container matColumnDef=\"email\">\n <th mat-header-cell *matHeaderCellDef> Email </th>\n <td mat-cell *matCellDef=\"let element\"> {{element.email}} </td>\n </ng-container>\n <tr mat-header-row *matHeaderRowDef=\"['id', 'spiffe', 'name', 'email']\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: ['id', 'spiffe', 'name', 'email'];\"></tr>\n </table>\n <div style=\"border: 1px solid grey; padding: .5rem; border-top: none;\">\n <h3 style=\"margin: 0;\">Total Records {{ data.length }}</h3>\n </div>\n </div>\n } @else {\n <div style=\"margin-top: 1rem; font-style: italic;\">\n No Data Available\n </div>\n }\n\n <div style=\"margin-bottom: 1rem; margin-top: 1rem;\">\n <mat-divider></mat-divider>\n </div>\n\n <div style=\"display: flex; gap: 0.5rem; margin-bottom: 1rem;\">\n <button mat-flat-button color=\"primary\" (click)=\"onTestDirectStateMessage(63, true)\">\n Test UPDATE (Fake Id)\n </button>\n <button mat-stroked-button (click)=\"onTestDirectStateMessage(63, false)\">\n Test UPDATE (Current Id)\n </button>\n <button mat-stroked-button (click)=\"onTestDirectStateMessage(63, false, 'custom-session-123')\">\n Test UPDATE (Custom Id)\n </button>\n </div>\n\n </div>\n}\n\n", styles: [".user-chip--primary{background-color:var(--mdc-theme-primary, var(--md-sys-color-primary, #3f51b5))!important;color:#fff!important;--mdc-evolution-chip-container-color: var(--mdc-theme-primary, var(--md-sys-color-primary, #3f51b5));--mdc-evolution-chip-label-text-color: #fff}.user-chip--primary :is(.mdc-evolution-chip__text-label,.mdc-evolution-chip__action,.mdc-evolution-chip__cell,.mat-mdc-chip-action-label){color:#fff!important}.user-chip--primary,.user-chip--primary *{color:#fff!important}:host ::ng-deep .user-chip--primary{background-color:var(--mdc-theme-primary, var(--md-sys-color-primary, #3f51b5))!important;color:#fff!important;--mdc-evolution-chip-container-color: var(--mdc-theme-primary, var(--md-sys-color-primary, #3f51b5));--mdc-evolution-chip-label-text-color: #fff}:host ::ng-deep .user-chip--primary .mdc-evolution-chip__text-label,:host ::ng-deep .user-chip--primary .mdc-evolution-chip__action,:host ::ng-deep .user-chip--primary .mdc-evolution-chip__cell,:host ::ng-deep .user-chip--primary .mat-mdc-chip-action-label,:host ::ng-deep .user-chip--primary *{color:#fff!important}.box{padding:.5rem;border:1px solid rgb(174,174,13);background-color:#ececaf}\n"] }]
12031
12010
  }], propDecorators: { server: [{
12032
12011
  type: Input
12033
12012
  }], wsServer: [{
@@ -12448,8 +12427,13 @@ class RequestManagerWsDemoComponent {
12448
12427
  ngOnInit() {
12449
12428
  this.stateService.updateConnection(this.server, this.wsServer, this.jwtToken, this.user, this.path);
12450
12429
  }
12430
+ ngOnChanges(changes) {
12431
+ if (changes['jwtToken'] && !changes['jwtToken'].firstChange) {
12432
+ this.stateService.updateConnection(this.server, this.wsServer, this.jwtToken, this.user, this.path);
12433
+ }
12434
+ }
12451
12435
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: RequestManagerWsDemoComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
12452
- 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 if (connectionError$ | async) {\n <span style=\"color: red;\">{{ connectionError$ | async }}</span>\n } @else if (isConnecting$ | async) {\n <span style=\"color: orange;\">Connecting... {{ retryCount$ | async }} / {{ maxRetries$ | async }}</span>\n } @else {\n <span style=\"color: red;\">Disconnected</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 ((isConnecting$ | async) && !(connectionStatus$ | async) && !(connectionError$ | async)) {\n <div style=\"display: flex; align-items: center; gap: 1rem; padding: 0.5rem; background: #e3f2fd; border-radius: 4px; margin-bottom: 0.5rem;\">\n <span>Connecting to WebSocket...</span>\n <mat-progress-bar mode=\"indeterminate\" style=\"flex: 1;\"></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" }] }); }
12436
+ 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" }, usesOnChanges: true, 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 if (connectionError$ | async) {\n <span style=\"color: red;\">{{ connectionError$ | async }}</span>\n } @else if (isConnecting$ | async) {\n <span style=\"color: orange;\">Connecting... {{ retryCount$ | async }} / {{ maxRetries$ | async }}</span>\n } @else {\n <span style=\"color: red;\">Disconnected</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 ((isConnecting$ | async) && !(connectionStatus$ | async) && !(connectionError$ | async)) {\n <div style=\"display: flex; align-items: center; gap: 1rem; padding: 0.5rem; background: #e3f2fd; border-radius: 4px; margin-bottom: 0.5rem;\">\n <span>Connecting to WebSocket...</span>\n <mat-progress-bar mode=\"indeterminate\" style=\"flex: 1;\"></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" }] }); }
12453
12437
  }
12454
12438
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: RequestManagerWsDemoComponent, decorators: [{
12455
12439
  type: Component,
@@ -13693,5 +13677,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
13693
13677
  * Generated bundle index. Do not edit.
13694
13678
  */
13695
13679
 
13696
- export { ApiRequest, AppService, AsymmetricalEncryptionService, BatchOptions, BatchResult, CONFIG_SETTINGS_TOKEN, ChannelType, ConfigHTTPOptions, ConfigOptions, DataType, DatabaseDataDemoComponent, DatabaseManagerService, DatabaseStorage, DbService, DexieSqlService, ErrorDisplaySettings, ExecutionPlanType, GlobalStoreOptions, HTTPManagerService, HTTPManagerSignalsService, HTTPManagerStateService, HeadersService, HttpRequestManagerModule, HttpRequestServicesDemoComponent, InvalidFileInfoModel, LocalStorageDemoComponent, LocalStorageManagerService, LocalStorageOptions, LocalStorageSignalsDemoComponent, LocalStorageSignalsManagerService, LoggerService, NormalizedRequestOptionsModel, NotificationMessage, OperationResultModel, ParsingResultModel, PathQueryService, PathTrackerStateModel, PublicMessage, QueryParamsTrackerOptionsModel, QueryTrackerStateModel, Random, RandomHSLColor, RandomHexColor, RandomNumber, RandomNumbers, RandomNumbersUnique, RandomPaletteColor, RandomSignature, RandomStr, RandomVisibleColor, RequestErrorInterceptor, RequestHeadersInterceptor, RequestManagerDemoComponent, RequestManagerStateDemoComponent, RequestOptions, RequestService, RequestSignalsService, RetryOptions, SettingOptions, SqlParseError, SqlValidationError, StateMessage, StateOperationResult, StateStorageOptions, StorageData, StorageOption, StorageType, StoreStateManagerService, StoreStateManagerSignalsService, StoreStateSignalsDemoComponent, StreamConfigModel, StreamEventMetadataModel, StreamEventModel, StreamOutputModel, StreamProgressModel, StreamType, SymmetricalEncryptionService, TableSchemaDef, UUID, UUID_STR, UploadDemoComponent, UploadValidationErrorModel, UserData, UtilsService, WSOptions, WebSocketMessageService, WithCredentialsInterceptor, calculateBatchProgress, countdown, createChannelName, delayedRetry, isErrorState, isPendingState, isSuccessState, requestPolling, requestStreaming, streamAI, streamAuto, streamEvents, streamJSON, streamNDJSON };
13680
+ export { ApiRequest, AppService, AsymmetricalEncryptionService, BatchOptions, BatchResult, CONFIG_SETTINGS_TOKEN, ChannelType, ConfigHTTPOptions, ConfigOptions, DataType, DatabaseDataDemoComponent, DatabaseManagerService, DatabaseStorage, DbService, DexieSqlService, ErrorDisplaySettings, ExecutionPlanType, GlobalStoreOptions, HTTPManagerService, HTTPManagerSignalsService, HTTPManagerStateService, HeadersService, HttpRequestManagerModule, HttpRequestServicesDemoComponent, InvalidFileInfoModel, LocalStorageDemoComponent, LocalStorageManagerService, LocalStorageOptions, LocalStorageSignalsDemoComponent, LocalStorageSignalsManagerService, LoggerService, NotificationMessage, OperationResultModel, ParsingResultModel, PathQueryService, PublicMessage, Random, RandomHSLColor, RandomHexColor, RandomNumber, RandomNumbers, RandomNumbersUnique, RandomPaletteColor, RandomSignature, RandomStr, RandomVisibleColor, RequestErrorInterceptor, RequestHeadersInterceptor, RequestManagerDemoComponent, RequestManagerStateDemoComponent, RequestOptions, RequestService, RequestSignalsService, RetryOptions, SettingOptions, SqlParseError, SqlValidationError, StateMessage, StateOperationResult, StateStorageOptions, StorageData, StorageOption, StorageType, StoreStateManagerService, StoreStateManagerSignalsService, StoreStateSignalsDemoComponent, StreamConfigModel, StreamEventMetadataModel, StreamEventModel, StreamOutputModel, StreamProgressModel, StreamType, SymmetricalEncryptionService, TableSchemaDef, UUID, UUID_STR, UploadDemoComponent, UploadValidationErrorModel, UserData, UtilsService, WSOptions, WebSocketMessageService, WithCredentialsInterceptor, calculateBatchProgress, countdown, createChannelName, delayedRetry, isErrorState, isPendingState, isSuccessState, requestPolling, requestStreaming, streamAI, streamAuto, streamEvents, streamJSON, streamNDJSON };
13697
13681
  //# sourceMappingURL=http-request-manager.mjs.map