http-request-manager 18.3.3 → 18.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/README.md +478 -255
  2. package/esm2022/lib/http-request-manager.module.mjs +20 -47
  3. package/esm2022/lib/http-request-services-demo/database-data-demo/database-data-demo.component.mjs +113 -32
  4. package/esm2022/lib/http-request-services-demo/http-request-services-demo.component.mjs +11 -8
  5. package/esm2022/lib/http-request-services-demo/request-manager-state-demo/request-manager-state-demo.component.mjs +3 -6
  6. package/esm2022/lib/http-request-services-demo/request-manager-ws-demo/models/oidc-client.model.mjs +13 -0
  7. package/esm2022/lib/http-request-services-demo/request-manager-ws-demo/models/user-data.model.mjs +13 -0
  8. package/esm2022/lib/http-request-services-demo/request-manager-ws-demo/request-manager-ws-demo.component.mjs +128 -0
  9. package/esm2022/lib/http-request-services-demo/request-manager-ws-demo/services/state-request.service.mjs +74 -0
  10. package/esm2022/lib/http-request-services-demo/store-state-manager-demo/services/settings-state.service.mjs +4 -1
  11. package/esm2022/lib/models/database-storage.model.mjs +1 -1
  12. package/esm2022/lib/services/database-manager-service/database.manager.service.mjs +171 -0
  13. package/esm2022/lib/services/database-manager-service/db.storage.service.mjs +183 -0
  14. package/esm2022/lib/services/database-manager-service/index.mjs +4 -0
  15. package/esm2022/lib/services/database-manager-service/models/table-schema.mjs +19 -0
  16. package/esm2022/lib/services/index.mjs +1 -2
  17. package/esm2022/lib/services/local-storage-manager-service/local-storage-manager.service.mjs +7 -1
  18. package/esm2022/lib/services/local-storage-manager-service/models/storage-option.model.mjs +4 -3
  19. package/esm2022/lib/services/request-manager-services/request.service.mjs +2 -2
  20. package/esm2022/lib/services/request-manager-state-service/http-manager-state.store.mjs +272 -84
  21. package/esm2022/lib/services/request-manager-state-service/models/ws-options.model.mjs +6 -3
  22. package/esm2022/lib/services/request-manager-state-service/models/ws-user.model.mjs +10 -0
  23. package/esm2022/lib/services/store-state-manager-service/store-state-manager.service.mjs +4 -4
  24. package/esm2022/lib/services/utils/utils.service.mjs +14 -14
  25. package/esm2022/lib/services/ws-manager-service/index.mjs +2 -2
  26. package/esm2022/lib/services/ws-manager-service/models/channel-notification.model.mjs +5 -3
  27. package/esm2022/lib/services/ws-manager-service/models/communication-type.enum.mjs +7 -0
  28. package/esm2022/lib/services/ws-manager-service/models/index.mjs +2 -3
  29. package/esm2022/lib/services/ws-manager-service/models/user-message.model.mjs +1 -1
  30. package/esm2022/lib/services/ws-manager-service/services/websocket.service.mjs +178 -0
  31. package/fesm2022/http-request-manager.mjs +2600 -2024
  32. package/fesm2022/http-request-manager.mjs.map +1 -1
  33. package/http-request-manager-18.4.0.tgz +0 -0
  34. package/lib/http-request-manager.module.d.ts +25 -22
  35. package/lib/http-request-services-demo/database-data-demo/database-data-demo.component.d.ts +39 -12
  36. package/lib/http-request-services-demo/request-manager-state-demo/request-manager-state-demo.component.d.ts +0 -1
  37. package/lib/http-request-services-demo/request-manager-ws-demo/models/oidc-client.model.d.ts +16 -0
  38. package/lib/http-request-services-demo/request-manager-ws-demo/models/user-data.model.d.ts +14 -0
  39. package/lib/http-request-services-demo/request-manager-ws-demo/request-manager-ws-demo.component.d.ts +39 -0
  40. package/lib/http-request-services-demo/request-manager-ws-demo/services/state-request.service.d.ts +14 -0
  41. package/lib/http-request-services-demo/store-state-manager-demo/services/settings-state.service.d.ts +1 -0
  42. package/lib/services/{database-manager-services → database-manager-service}/database.manager.service.d.ts +9 -7
  43. package/lib/services/{database-manager-services → database-manager-service}/db.storage.service.d.ts +14 -14
  44. package/lib/services/index.d.ts +0 -1
  45. package/lib/services/local-storage-manager-service/models/storage-option.model.d.ts +3 -1
  46. package/lib/services/request-manager-services/request.service.d.ts +1 -1
  47. package/lib/services/request-manager-state-service/http-manager-state.store.d.ts +34 -19
  48. package/lib/services/request-manager-state-service/models/ws-options.model.d.ts +9 -1
  49. package/lib/services/request-manager-state-service/models/ws-user.model.d.ts +10 -0
  50. package/lib/services/store-state-manager-service/store-state-manager.service.d.ts +3 -2
  51. package/lib/services/ws-manager-service/index.d.ts +1 -1
  52. package/lib/services/ws-manager-service/models/channel-notification.model.d.ts +4 -1
  53. package/lib/services/ws-manager-service/models/communication-type.enum.d.ts +5 -0
  54. package/lib/services/ws-manager-service/models/index.d.ts +1 -2
  55. package/lib/services/ws-manager-service/models/user-message.model.d.ts +5 -6
  56. package/lib/services/ws-manager-service/{websocket.service.d.ts → services/websocket.service.d.ts} +5 -2
  57. package/package.json +1 -1
  58. package/esm2022/lib/services/database-manager-services/database.manager.service.mjs +0 -119
  59. package/esm2022/lib/services/database-manager-services/db.storage.service.mjs +0 -143
  60. package/esm2022/lib/services/database-manager-services/index.mjs +0 -4
  61. package/esm2022/lib/services/database-manager-services/models/table-schema.mjs +0 -20
  62. package/esm2022/lib/services/ws-manager-service/models/user-info.model.mjs +0 -11
  63. package/esm2022/lib/services/ws-manager-service/models/user-name-info.model.mjs +0 -12
  64. package/esm2022/lib/services/ws-manager-service/websocket.service.mjs +0 -133
  65. package/http-request-manager-18.3.3.tgz +0 -0
  66. package/lib/services/ws-manager-service/models/user-info.model.d.ts +0 -11
  67. package/lib/services/ws-manager-service/models/user-name-info.model.d.ts +0 -14
  68. /package/lib/services/{database-manager-services → database-manager-service}/index.d.ts +0 -0
  69. /package/lib/services/{database-manager-services → database-manager-service}/models/table-schema.d.ts +0 -0
package/README.md CHANGED
@@ -1,333 +1,556 @@
1
1
  # Request Manager Service Documentation
2
2
 
3
- ## Summary of the Lib
4
- The HTTPManagerService is a collection of 4 services for HTTP and Local Storage management.
5
-
6
- ## Installation
7
-
8
- `npm install http-request-manager`
3
+ ## Summary
4
+ The `http-request-manager` library provides a comprehensive set of services for handling HTTP requests, state management, local storage, and WebSocket communications in Angular applications.
5
+
6
+ ## Initialization
7
+
8
+ ### 1. Module Initialization (`forRoot`)
9
+ To use the library, import `HttpRequestManagerModule` in your `AppModule` and configure it using the `forRoot` method.
10
+
11
+ #### Configuration Options (`ConfigOptions`)
12
+
13
+ | Option | Type | Description | Default |
14
+ | :--- | :--- | :--- | :--- |
15
+ | `httpRequestOptions` | `ConfigHTTPOptions` | Global configuration for HTTP requests. | `undefined` |
16
+ | `LocalStorageOptions` | `LocalStorageOptions` | Global configuration for Local Storage management. | `undefined` |
17
+
18
+ #### HTTP Options (`ConfigHTTPOptions`)
19
+
20
+ | Option | Type | Description | Default |
21
+ | :--- | :--- | :--- | :--- |
22
+ | `server` | `string` | The base URL for API requests. | `''` |
23
+ | `path` | `any[]` | Default path segments to append to the server URL. | `[]` |
24
+ | `headers` | `any` | Default headers to include in every request. | `{}` |
25
+ | `polling` | `number` | Default polling interval in seconds (0 = disabled). | `0` |
26
+ | `retry` | `RetryOptions` | Default retry configuration. | `{ times: 0, delay: 3 }` |
27
+ | `stream` | `boolean` | Whether to enable streaming by default. | `false` |
28
+ | `displayError` | `boolean` | Whether to display toast notifications for errors by default. | `false` |
29
+
30
+ #### Retry Options (`RetryOptions`)
31
+
32
+ | Option | Type | Description | Default |
33
+ | :--- | :--- | :--- | :--- |
34
+ | `times` | `number` | The number of retry attempts. | `0` |
35
+ | `delay` | `number` | The delay between retries in seconds. | `3` |
36
+
37
+ #### Local Storage Options (`LocalStorageOptions`)
38
+
39
+ | Option | Type | Description | Default |
40
+ | :--- | :--- | :--- | :--- |
41
+ | `storageName` | `string` | The key used to store data in localStorage/sessionStorage. | `'storage'` |
42
+ | `storageSettingsName` | `string` | The key used to store settings metadata. | `'global-storage'` |
43
+ | `options` | `SettingOptions` | Default settings for stored items. | `{ storage: StorageType.GLOBAL, expires: 0, expiresIn: '', encrypted: false }` |
44
+
45
+ #### Setting Options (`SettingOptions`)
46
+
47
+ | Option | Type | Description | Default |
48
+ | :--- | :--- | :--- | :--- |
49
+ | `storage` | `StorageType` | The type of storage to use (`StorageType.GLOBAL` or `StorageType.SESSION`). | `StorageType.GLOBAL` |
50
+ | `expires` | `number` | Expiration timestamp (epoch). Usually calculated from `expiresIn`. | `0` |
51
+ | `expiresIn` | `string` | Duration string (e.g., '1d', '2h') for expiration. | `''` |
52
+ | `encrypted` | `boolean` | Whether to encrypt the stored data. | `false` |
53
+
54
+ #### Example
55
+
56
+ ```typescript
57
+ import { HttpRequestManagerModule } from 'http-request-manager';
58
+
59
+ @NgModule({
60
+ imports: [
61
+ HttpRequestManagerModule.forRoot({
62
+ httpRequestOptions: {
63
+ server: 'https://api.example.com',
64
+ headers: { 'Authorization': 'Bearer token' },
65
+ retry: { times: 3, delay: 2 },
66
+ displayError: true
67
+ },
68
+ LocalStorageOptions: {
69
+ storageName: 'my-app-data',
70
+ storageSettingsName: 'my-app-settings',
71
+ options: {
72
+ encrypted: true,
73
+ expiresIn: '7d'
74
+ }
75
+ }
76
+ })
77
+ ],
78
+ // ...
79
+ })
80
+ export class AppModule { }
81
+ ```
9
82
 
10
- ## Services
83
+ ### 2. AppService Initialization
84
+ The `AppService` (used by `LocalStorageManagerService` for encryption) requires a unique `APP_ID` to be provided in your `AppModule`.
85
+
86
+ ```typescript
87
+ import { APP_ID } from '@angular/core';
88
+
89
+ @NgModule({
90
+ providers: [
91
+ {
92
+ provide: APP_ID,
93
+ useValue: "your-unique-guid-here", // e.g., "056991ac-3537-43ab-b5b9-83edf6554eff"
94
+ },
95
+ // ...
96
+ ],
97
+ // ...
98
+ })
99
+ export class AppModule { }
100
+ ```
11
101
 
12
- ### HTTP Manager Service:
102
+ ## Services Documentation
103
+
104
+ ### 1. Request Manager Service (`HTTPManagerService`)
105
+ **Path:** `request-manager-services/http-manager.service.ts`
106
+
107
+ A robust HTTP client service using RxJS `BehaviorSubject` for state management.
108
+
109
+ **What it does:**
110
+ This service acts as a wrapper around Angular's `HttpClient`, providing a centralized way to manage HTTP requests. It handles the entire lifecycle of a request, including loading states, error handling, and data updates, exposing them as Observables.
111
+
112
+ **Features:**
113
+ - **State Management:** Exposes `data$`, `isPending$`, `error$`, and `countdown$` observables.
114
+ - **Polling:** Supports automatic polling of endpoints with a configurable interval and countdown timer.
115
+ - **Retries:** Automatically retries failed requests based on configuration (number of attempts and delay).
116
+ - **Adapters & Mappers:** Supports `adapter` functions to transform incoming data and `mapper` functions for outgoing payloads.
117
+ - **Streaming:** Handles streaming responses when configured.
118
+ - **Error Handling:** Centralized error handling with optional Toast notifications.
119
+ - **CRUD Support:** Provides methods for `getRequest`, `postRequest`, `putRequest`, `deleteRequest`, and `downloadRequest`.
120
+
121
+ **Usage:**
122
+ Inject `HTTPManagerService` to make API requests. It handles loading state, errors, and data updates via Observables.
123
+
124
+ #### API Request Options (`ApiRequest`)
125
+
126
+ | Option | Type | Description | Default |
127
+ | :--- | :--- | :--- | :--- |
128
+ | `server` | `string` | The base URL for the request. | `''` |
129
+ | `path` | `any[]` | Path segments to append to the URL. | `[]` |
130
+ | `headers` | `any` | Custom headers for the request. | `{}` |
131
+ | `adapter` | `function` | Function to transform the response data. | `undefined` |
132
+ | `mapper` | `function` | Function to transform the request payload. | `undefined` |
133
+ | `polling` | `number` | Polling interval in seconds (0 = disabled). | `0` |
134
+ | `retry` | `RetryOptions` | Retry configuration. | `{ times: 0, delay: 3 }` |
135
+ | `stream` | `boolean` | Enable streaming response handling. | `false` |
136
+ | `displayError` | `boolean` | Show toast notification on error. | `false` |
137
+ | `saveAs` | `string` | Filename for file downloads. | `undefined` |
138
+ | `ws` | `WSOptions` | WebSocket configuration options. | `undefined` |
139
+
140
+ #### Example
141
+
142
+ ```typescript
143
+ export class MyComponent {
144
+ httpManager = inject(HTTPManagerService);
145
+
146
+ data$ = this.httpManager.data$;
147
+ isLoading$ = this.httpManager.isPending$;
148
+ error$ = this.httpManager.error$;
149
+
150
+ fetchData() {
151
+ const options = ApiRequest.adapt({
152
+ path: ['users'],
153
+ polling: 5, // Poll every 5 seconds
154
+ retry: { times: 3, delay: 1 },
155
+ adapter: User.adapt // Transform response to User model
156
+ });
13
157
 
14
- Http service simplifies http requests in the following ways
15
- - Define a fixed endpoint service
16
- - Provide a fixed set of headers or add to the headers on request
17
- - Proxy Config Support
18
- - Adapter for strict type checking for incoming data
19
- - Mapper for data transformation for outgoing data
20
- - Polling requests automatically
21
- - Retry requests if failure
22
- - Stream http requests from endpoint service
23
- - Display Error provides a Toast (Snackbar) notification on error
158
+ this.httpManager.getRequest(options).subscribe();
159
+ }
160
+ }
161
+ ```
24
162
 
25
- ### HTTP State Manager Service
163
+ #### Advanced Features
164
+
165
+ | Feature | Description | Configuration |
166
+ | :--- | :--- | :--- |
167
+ | **Streaming** | Handle streaming responses (e.g., NDJSON). | Set `stream: true` in `ApiRequest`. |
168
+ | **Polling** | Automatically poll the endpoint at a specified interval. | Set `polling: number` (seconds) in `ApiRequest`. |
169
+ | **Retry** | Automatically retry failed requests. | Configure `retry: { times: 3, delay: 3 }` in `ApiRequest`. |
170
+ | **Adapters** | Transform incoming API response data before it reaches the state. | Use `adapter: (data) => transformedData` in `ApiRequest`. |
171
+ | **Mappers** | Transform outgoing payload data before sending to the API. | Use `mapper: (data) => transformedData` in `ApiRequest`. |
172
+
173
+ ```typescript
174
+ const options = ApiRequest.adapt({
175
+ path: ['users'],
176
+ polling: 5, // Poll every 5 seconds
177
+ retry: { times: 3, delay: 1 },
178
+ adapter: User.adapt // Transform response to User model
179
+ });
180
+ ```
26
181
 
27
- Http service simplifies http request state management in the following ways
28
- - Inherits from HTTP Manager Service for config options
29
- - Creates a Component Store state (NGRX)
30
- - Selectors for data and selecting data records
31
- - Create, Update and Delete automatically updates data by endpoint and state on success
32
- - Get keeps state of records
182
+ ### 2. Request Manager Signal Service (`HTTPManagerSignalsService`)
183
+ **Path:** `request-manager-services/http-manager-signals.service.ts`
33
184
 
34
- ### Database Storage Manager (Coming soon)
35
- - Inherits from HTTP State Manager Service for config options
36
- - Manages HTTP Requests caching data in local DB (IndexedDB) using DixieJS
37
- - Requests check first local DB and if data is not stale, request is made and updates DB
38
- - Expiry time/date can be set for DB records for caching
185
+ A modern alternative to `HTTPManagerService` using Angular Signals for state management.
39
186
 
40
- ### Local/Session Storage
41
- - Allows for Local and Storage management for data Persistence
42
- - Component Store (NGRX) State for changes on storage
43
- - Encryption for data
44
- - Expiry time/date can be set for stores
187
+ **What it does:**
188
+ This service provides the same functionality as `HTTPManagerService` but exposes state using Angular Signals instead of RxJS Observables. This is ideal for modern Angular applications leveraging fine-grained reactivity.
45
189
 
46
- ## Using the Services
190
+ **Features:**
191
+ - **Signal-Based State:** Exposes `data`, `isPending`, `error`, and `countdown` as Signals.
192
+ - **Feature Parity:** Supports all features of `HTTPManagerService` including polling, retries, adapters, and streaming.
193
+ - **Optimized for Signals:** Designed to work seamlessly with Angular's Signal-based components and templates.
47
194
 
48
- There are three ways to use the service, depending on your needs:
195
+ **Usage:**
196
+ Ideal for components using Angular Signals.
49
197
 
50
- ### Injecting the Service (Single Usage)
198
+ ```typescript
199
+ export class MyComponent {
200
+ httpManager = inject(HTTPManagerSignalsService);
51
201
 
52
- ```ts
53
- httpManagerService = inject(HTTPManagerService)
54
- ```
202
+ data = this.httpManager.data; // Signal
203
+ isLoading = this.httpManager.isPending; // Signal
204
+ error = this.httpManager.error; // Signal
55
205
 
56
- - This approach provides a singleton state for the service, as services are provided in root (@Injectable({ providedIn: 'root' })).
57
- - Any components or services that inject this service will share the same state, meaning they all have access to:
58
- - data$ (observable for data)
59
- - isPending$ (loading state)
60
- - countDown$ (loading state)
61
- - error$ (error state)
62
- - Methods associated with the service
63
- - Since there is only one shared state, it can be reused across components without creating new instances.
64
-
65
- Here is a very simple example
66
-
67
- ```ts
68
- //Define your API request details using the `ApiRequest` adapter
69
- const apiOptions = ApiRequest.adapt({
70
- server: 'myApiUrl/rest/clients' // or ['myApiUrl', 'rest', 'clients']
71
- })
206
+ fetchData() {
207
+ const options = ApiRequest.adapt({ path: ['users'] });
208
+ this.httpManager.getRequest(options).subscribe();
209
+ }
210
+ }
211
+ ```
72
212
 
73
- onFetchData() {
213
+ ### 3. Request Manager State Service (`HTTPManagerStateService`)
214
+ **Path:** `request-manager-state-service/http-manager-state.store.ts`
215
+
216
+ An extension of `ComponentStore` designed for managing entity state (CRUD) with built-in HTTP request handling and WebSocket integration.
217
+
218
+ **What it does:**
219
+ This service combines HTTP requests with local state management. It automatically updates the local store when CRUD operations succeed, eliminating the need to manually refresh data. It also integrates with WebSockets to keep the state synchronized with server-side changes.
220
+
221
+ **Features:**
222
+ - **ComponentStore Integration:** Extends NGRX `ComponentStore` for robust state management.
223
+ - **Automatic CRUD Updates:** `createRecord`, `updateRecord`, and `deleteRecord` automatically update the local state upon success.
224
+ - **WebSocket Sync:** Listens for WebSocket messages to update, create, or delete records in real-time.
225
+ - **Database Support:** Can be configured to use IndexedDB for caching (via `DatabaseStorage`).
226
+ - **Selectors:** Provides selectors like `data$` and `selectRecord$(id)` for easy data access.
227
+ - **Pagination Support:** Includes state for pagination (`page$`, `totalPages$`).
228
+
229
+ **Usage:**
230
+ Extend this service to create a store for a specific feature. You must call `super()` with `ApiRequest`, `DataType`, and `DatabaseStorage`.
231
+
232
+ ```typescript
233
+ @Injectable()
234
+ export class UsersStore extends HTTPManagerStateService<User> {
235
+ constructor() {
236
+ super(
237
+ ApiRequest.adapt({
238
+ server: 'api',
239
+ path: ['users'],
240
+ adapter: User.adapt // Required for Database Storage
241
+ }),
242
+ DataType.ARRAY,
243
+ DatabaseStorage.adapt({
244
+ table: 'users-cache',
245
+ expiresIn: '1d'
246
+ })
247
+ );
248
+ }
74
249
 
75
- this.httpManagerService.getRequest<any>(apiOptions)
76
- .pipe(
77
- catchError(error => {
78
- return throwError(() => this.errorHandling(error, 'GET'))
79
- })
80
- ).subscribe(data => console.log(data)))
250
+ // Wrap CRUD methods for cleaner component usage
251
+ getUsers() {
252
+ this.fetchRecords();
253
+ }
81
254
 
82
- }
83
- ```
255
+ addUser(user: User) {
256
+ this.createRecord(user);
257
+ }
258
+ }
259
+ ```
84
260
 
85
- ### Example
86
- In this example, we define the endpoint URL as myApiUrl. This will return the data from the observable for your use case.
261
+ **Features:**
262
+ - **Automatic State Updates:** `createRecord`, `updateRecord`, and `deleteRecord` automatically update the local state upon success.
263
+ - **Selectors:** `data$`, `selectRecord$(id)`.
264
+ - **WebSocket Integration:** Automatically connects to WS if configured in `ApiRequest`. Syncs state on 'create', 'update', 'delete' events from WS.
265
+ - **Runtime Configuration:** Use `setApiRequestOptions()` to update API or WS settings dynamically.
266
+
267
+ ### 4. Request Manager Signal State Service
268
+ *Note: Currently, the state management service (`HTTPManagerStateService`) is based on `ComponentStore` (RxJS). A dedicated Signal-based state manager is not yet available in this library.*
269
+
270
+ ### 5. Local Storage Manager Service (`LocalStorageManagerService`)
271
+ **Path:** `local-storage-manager-service/local-storage-manager.service.ts`
272
+
273
+ Manages `localStorage` and `sessionStorage` with encryption and expiration support.
274
+
275
+ **What it does:**
276
+ This service provides a secure and managed way to interact with browser storage. It treats storage as a state, allowing you to subscribe to changes. It also handles data encryption and expiration automatically.
277
+
278
+ **Features:**
279
+ - **Encryption:** Encrypts data before saving to storage using `SymmetricalEncryptionService` (requires `APP_ID`).
280
+ - **Expiration:** Supports setting an expiration time (`expiresIn`) for stored items. Automatically cleans up expired items.
281
+ - **Storage Types:** Supports both `localStorage` (Global) and `sessionStorage` (Session).
282
+ - **Reactive:** Exposes storage items as Observables, allowing components to react to storage changes.
283
+ - **Metadata Management:** Keeps track of storage settings (encryption, expiration) separately from the data.
284
+
285
+ **Usage:**
286
+ ```typescript
287
+ localStorageManager = inject(LocalStorageManagerService);
288
+
289
+ // Create/Set a store
290
+ this.localStorageManager.setStore({
291
+ name: 'user-settings',
292
+ data: { theme: 'dark' },
293
+ options: {
294
+ storage: StorageType.GLOBAL, // or StorageType.SESSION
295
+ encrypted: true,
296
+ expiresIn: '1d'
297
+ }
298
+ });
87
299
 
88
- The endpoint can be:
300
+ // Select a store (returns data)
301
+ settings$ = this.localStorageManager.store$('user-settings');
89
302
 
90
- A direct URL (e.g., https://apple.com/clients).
91
- A proxy-config file (recommended to avoid CORS issues).
92
- A string, an array of strings, or numbers—similar to Angular’s Router.navigate() API.
93
- The HTTP Service Manager automatically sanitizes the endpoint by removing redundant `/` characters and validating the URL.
303
+ // Select store settings (returns metadata)
304
+ meta$ = this.localStorageManager.setting$('user-settings');
94
305
 
95
- You can also add query parameters by passing an object:
306
+ // Reset all stores
307
+ this.localStorageManager.resetStore();
308
+ ```
96
309
 
97
- ```ts
98
- { sortBy: 'asc', filter: ['samples', 'testing'] }
99
- ```
310
+ ### 6. Store State Manager Service (`StoreStateManagerService`)
311
+ **Path:** `store-state-manager-service/store-state-manager.service.ts`
312
+
313
+ A service that extends `ComponentStore` to provide persistent state management synchronized with local or session storage.
314
+
315
+ **What it does:**
316
+ This service bridges the gap between in-memory state (ComponentStore) and persistent storage. It ensures that your state is automatically saved to storage when it changes and restored from storage when the service is initialized.
317
+
318
+ **Features:**
319
+ - **Persistence:** Automatically saves state changes to `localStorage` or `sessionStorage`.
320
+ - **State Restoration:** Restores state from storage on initialization.
321
+ - **Reactivity:** Extends `ComponentStore`, providing all its benefits (selectors, updaters, effects).
322
+ - **Encryption Support:** Leverages `LocalStorageManagerService` for optional encryption.
323
+ - **Model Adaptation:** Supports using a model adapter to ensure state structure.
324
+
325
+ **Usage:**
326
+ Extend this service to create a persistent store.
327
+
328
+ ```typescript
329
+ @Injectable({
330
+ providedIn: 'root'
331
+ })
332
+ export class SettingsStateService extends StoreStateManagerService {
333
+
334
+ constructor() {
335
+ super(
336
+ StateStorageOptions.adapt({
337
+ store: 'my-settings-store', // Unique store name
338
+ options: SettingOptions.adapt({
339
+ storage: StorageType.SESSION, // or StorageType.GLOBAL (Local Storage)
340
+ encrypted: false
341
+ }),
342
+ model: Settings.adapt, // Model adapter for initial state
343
+ })
344
+ );
345
+ }
100
346
 
101
- This translates to: `https://apple.com/clients?sortBy=asc&filter=samples,testing`
347
+ // Update specific part of state
348
+ updateSetting(value: any) {
349
+ this.updateData(value);
350
+ }
102
351
 
103
- There are a number of other options available in the `ApiRequest` adapter
352
+ // Select specific part of state
353
+ getSetting(key: string) {
354
+ return this.data$.pipe(map(state => state[key]));
355
+ }
356
+ }
357
+ ```
104
358
 
359
+ **Features:**
360
+ - **Persistence:** Automatically saves state changes to LocalStorage or SessionStorage.
361
+ - **Reactivity:** Extends `ComponentStore`, providing `data$` selector and `updater` methods.
362
+ - **Encryption:** Supports encrypted storage via `LocalStorageManagerService`.
105
363
 
106
- ### Extending a Component or Service with the Service (Multiple Instances - preferred method)
364
+ ### 7. WebSocket Manager Service (`WebsocketService`)
365
+ **Path:** `ws-manager-service/services/websocket.service.ts`
107
366
 
108
- This approach creates a new instance of the service for each component or service that extends it, ensuring each instance maintains its own independent state.
367
+ Handles WebSocket connections, channel subscriptions, and messaging. It is used internally by `HTTPManagerStateService` but can be used standalone.
109
368
 
110
- ### Observables
111
- - Similar to the first approach, instead of one instance of the state you are creating a new state instance
112
- - CRUD operations return Observables, similar to HttpClient.
113
- - This allows for custom error handling and executing additional actions after the request completes.
114
- - Since HTTP requests are asynchronous, you must subscribe to the Observable to receive data:
369
+ **What it does:**
370
+ This service manages the lifecycle of a WebSocket connection. It handles authentication, connection stability, and message routing. It supports a channel-based architecture for organizing communication.
115
371
 
116
- ```ts
117
- myService.getData().subscribe(response => {
118
- console.log(response);
119
- });
120
- ```
372
+ **Features:**
373
+ - **Connection Management:** Handles connecting, disconnecting, and reconnecting.
374
+ - **Authentication:** Supports JWT-based authentication for secure connections.
375
+ - **Channels:** Allows subscribing and unsubscribing to specific channels.
376
+ - **Messaging:** Supports sending messages to specific channels, users, or broadcasting to all.
377
+ - **Observables:** Exposes `messages$` stream and `connectionStatus$` for reactive integration.
121
378
 
122
- - Alternatively, you can use the async pipe for automatic subscription and cleanup:
379
+ **Usage:**
380
+ ```typescript
381
+ wsService = inject(WebsocketService);
123
382
 
124
- ```ts
125
- {{ myData$ | async }}
126
- ```
383
+ // Connect
384
+ this.wsService.connect('wss://api.example.com/ws', 'jwt-token');
127
385
 
128
- ### Example
129
- First we need to extend the Component or Service (recommended approach) with the `HTTPManagerService`
386
+ // Subscribe to channel
387
+ this.wsService.subscribeToChannel('my-channel');
130
388
 
131
- Component Example:
132
- ```ts
133
- export class RequestManagerDemoComponent extends HTTPManagerService<any> implements OnInit {
389
+ // Listen to messages
390
+ this.wsService.messages$.subscribe(msg => console.log(msg));
134
391
 
135
- constructor() {
136
- super()
137
- }
138
- }
139
- ```
140
-
141
- Service Example:
142
- ```ts
143
- @Injectable({
144
- providedIn: 'root'
145
- })
146
- export class myAPIService extends HTTPManagerService<any> {
147
-
148
- constructor() {
149
- super()
150
- }
392
+ // Send Message
393
+ this.wsService.sendMessageInChannel('my-channel', { text: 'hello' });
394
+ ```
151
395
 
396
+ #### WebSocket Options (`WSOptions`)
397
+
398
+ | Option | Type | Description | Default |
399
+ | :--- | :--- | :--- | :--- |
400
+ | `id` | `string` | Unique identifier for the WebSocket connection. | `''` |
401
+ | `wsServer` | `string` | The WebSocket server URL. | `''` |
402
+ | `jwtToken` | `string` | JWT token for authentication. | `''` |
403
+ | `permissions` | `string[]` | List of permissions associated with the connection. | `[]` |
404
+ | `channels` | `string[]` | List of channels to subscribe to upon connection. | `undefined` |
405
+ | `userAdapter` | `WSUser` | Adapter for mapping user data. | `undefined` |
406
+ | `retry` | `RetryOptions` | Retry configuration for connection attempts. | `undefined` |
407
+
408
+ #### Integration with HTTPManagerStateService
409
+
410
+ You can configure `HTTPManagerStateService` to automatically handle WebSocket connections by providing `ws` options in `ApiRequest`.
411
+
412
+ ```typescript
413
+ @Injectable()
414
+ export class UsersStore extends HTTPManagerStateService<User> {
415
+ constructor() {
416
+ super(
417
+ ApiRequest.adapt({
418
+ server: 'api',
419
+ path: ['users'],
420
+ // WebSocket Configuration
421
+ ws: {
422
+ id: 'WS-USERS',
423
+ wsServer: 'wss://api.example.com/ws',
424
+ jwtToken: 'your-token',
425
+ wsChannels: ['allChannels'],
426
+ retry: { times: 3, delay: 5 }
427
+ }
428
+ }),
429
+ DataType.ARRAY,
430
+ DatabaseStorage.adapt()
431
+ );
152
432
  }
153
- ```
154
-
155
- In this example, we define the endpoint URL as myApiUrl. This will return the data from the observable for your use case.
156
-
157
- The endpoint can be:
158
-
159
- A direct URL (e.g., https://apple.com/clients).
160
- A proxy-config file (recommended to avoid CORS issues).
161
- A string, an array of strings, or numbers—similar to Angular’s Router.navigate() API.
162
- The HTTP Service Manager automatically sanitizes the endpoint by removing redundant `/` characters and validating the URL.
163
-
164
- You can also add query parameters by passing an object:
165
- ```ts
166
- { sortBy: 'asc', filter: ['samples', 'testing'] }
433
+ }
167
434
  ```
168
- This translates to: `https://apple.com/clients?sortBy=asc&filter=samples,testing`
169
435
 
170
- Lets define these query params as a variable called `PARAMS` and use them in the following request.
436
+ ### 8. Database Manager Service (`DatabaseManagerService`)
171
437
 
172
- There are a number of other options available in the `ApiRequest` adapter
438
+ **Path:** `database-manager-service/database.manager.service.ts`
173
439
 
174
- No we can define a method:
175
- In this example take note that the clientID has been passed to the method and the param after the apiOptions allows for further customization for the api request being made. In this case we extended the the base path defined in the `ApiRequest` options. We also added the `PARAMS` for query parameters.
440
+ A wrapper service for Dexie.js to manage IndexedDB interactions using RxJS Observables.
176
441
 
177
- Define your API request options using the 'ApiRequest' adapter
442
+ **What it does:**
178
443
 
179
- ```ts
180
- const apiOptions = ApiRequest.adapt({
181
- server: ['myApiUrl', 'rest', 'clients']
182
- })
444
+ This service simplifies interactions with IndexedDB by providing a clean, Observable-based API. It handles database initialization, table creation, and all standard CRUD operations. It is designed to work seamlessly with the `HTTPManagerStateService` for caching but can also be used independently.
183
445
 
184
- // Dynamically change these params
185
- const PARAMS = {
186
- sortBy: 'asc',
187
- filter: ['samples', 'testing']
188
- }
446
+ **Features:**
189
447
 
190
- onFetchData(clientId) {
448
+ - **Table Management:** Create and manage database tables with flexible schemas.
449
+ - **CRUD Operations:** Full support for Create, Read, Update, and Delete operations on single or multiple records.
450
+ - **Querying:** Find records by specific column values.
451
+ - **Bulk Operations:** Optimized methods for creating and deleting multiple records at once.
452
+ - **Schema Inspection:** Methods to check for table existence and retrieve schema definitions.
191
453
 
192
- this.httpManagerService.getRequest<any>(apiOptions, [clientId, this.PARAMS])
193
- .pipe(
194
- catchError(error => {
195
- return throwError(() => this.errorHandling(error, 'GET'))
196
- })
197
- ).subscribe(data => console.log(data)))
454
+ **Usage:**
198
455
 
199
- }
200
- ```
456
+ ```typescript
457
+ dbManager = inject(DatabaseManagerService);
201
458
 
459
+ // 1. Initialize Table
460
+ const tableDef = TableSchemaDef.adapt({
461
+ table: 'users',
462
+ schema: '++id, name, age' // Dexie.js schema syntax
463
+ });
202
464
 
203
- ### State Observable
204
- - When executing CRUD operations, their results are automatically pushed into the data$ observable within the service.
205
- - This means you can bind the data$ observable to a component to automatically update UI elements.
206
- - Using this approach enables state management across components and allows data refresh actions without needing additional logic.
465
+ this.dbManager.createDatabaseTable(tableDef).subscribe(() => {
466
+ console.log('Table initialized');
467
+ });
207
468
 
208
- ### Example
209
- First we need to extend the Component or Service (recommended approach) with the `HTTPManagerService`
469
+ // 2. CRUD Operations
470
+ // Create
471
+ this.dbManager.createTableRecord('users', { name: 'John', age: 30 }).subscribe();
210
472
 
211
- Component Example:
212
- The structure would be: Component extends `HTTPManagerService`
473
+ // Read
474
+ this.dbManager.getTableRecords('users').subscribe(users => console.log(users));
475
+ this.dbManager.getTableRecord('users', 1).subscribe(user => console.log(user));
213
476
 
214
- ```ts
215
- export class RequestManagerDemoComponent extends HTTPManagerService<any> implements OnInit {
477
+ // Update
478
+ this.dbManager.updateTableRecord('users', { id: 1, name: 'John Doe', age: 31 }).subscribe();
216
479
 
217
- constructor() {
218
- super()
219
- }
220
- }
221
- ```
480
+ // Delete
481
+ this.dbManager.deleteTableRecord('users', 1).subscribe();
222
482
 
223
- Service Example:
224
- The structure would be: Component injects a service call `clientsService` and `clientsService` extends `HTTPManagerService`
483
+ // 3. Bulk Operations
484
+ const users = [{ name: 'Alice', age: 25 }, { name: 'Bob', age: 28 }];
485
+ this.dbManager.createTableRecords('users', users).subscribe();
225
486
 
226
- ```ts
227
- @Injectable({
228
- providedIn: 'root'
229
- })
230
- export class myAPIService extends HTTPManagerService<any> {
487
+ // 4. Querying
488
+ this.dbManager.findTableRecords('users', 'age', 25).subscribe(results => console.log(results));
231
489
 
232
- constructor() {
233
- super()
234
- }
490
+ // 5. Metadata
491
+ this.dbManager.hasDatabaseTable('users').subscribe(exists => console.log(exists));
492
+ ```
235
493
 
236
- }
237
- ```
494
+ #### Database Storage Configuration (`DatabaseStorage`)
238
495
 
239
- In this example, we define the endpoint URL as myApiUrl.
496
+ When using `HTTPManagerStateService`, you can configure local database caching using `DatabaseStorage.adapt()`.
240
497
 
241
- Lets define these query params as a variable called `PARAMS` and use them in the following request.
498
+ ##### Options
242
499
 
243
- No we can define a method:
244
- In this example the clientID has been passed to the method.
245
- We also added the `PARAMS` for query parameters.
500
+ | Option | Type | Description | Default |
501
+ | :--- | :--- | :--- | :--- |
502
+ | `table` | `string` | The name of the table in IndexedDB where records will be stored. | `''` |
503
+ | `expiresIn` | `string` | The duration for which the data remains valid. Format: `'1d'` (days), `'1h'` (hours), `'30m'` (minutes). | `''` |
246
504
 
247
- Define your API request options using the 'ApiRequest' adapter
505
+ ##### Example
248
506
 
249
- ```ts
250
- const apiOptions = ApiRequest.adapt({
251
- server: ['myApiUrl', 'rest', 'clients']
252
- })
507
+ ```typescript
508
+ import { DatabaseStorage } from 'http-request-manager';
253
509
 
254
- // Dynamically change these params
255
- const PARAMS = {
256
- sortBy: 'asc',
257
- filter: ['samples', 'testing']
258
- }
510
+ const dbConfig = DatabaseStorage.adapt({
511
+ table: 'my-feature-cache',
512
+ expiresIn: '6h' // Cache expires in 6 hours
513
+ });
514
+ ```
259
515
 
260
- onFetchData(clientId: number) {
261
- this.httpManagerService.getRequest<any>(apiOptions, [clientId, this.PARAMS]).subscribe()
262
- }
263
- ```
516
+ ### 9. Utils (`UtilsService`)
517
+ **Path:** `utils/utils.service.ts`
264
518
 
265
- In the above case we are not using the data returning from the Observable but rather executing the api call, like a refresh if called again
519
+ Provides utility functions for common tasks.
266
520
 
267
- To access the data from the observable, you need to bind the observable if your using a component that injects the service that extends the `HTTPManagerService`
521
+ **What it does:**
522
+ A collection of helper functions used throughout the library and available for application use. It simplifies common tasks related to data manipulation, validation, and time calculations.
268
523
 
269
- In the component where the service was injected, we define
524
+ **Features:**
525
+ - **JSON Handling:** Safe `stringToJSON` and `JSONToString` methods.
526
+ - **Type Checking:** `isString`, `isObject`, `isJSON`.
527
+ - **Expiration:** `expires(string)` converts duration strings (e.g., '1d', '2h') to epoch timestamps. `hasExpired(timestamp)` checks if a timestamp has passed.
528
+ - **Conversions:** `base32ToHex`, `binaryToHex`.
529
+ - **Object Equality:** `objectsEqual` for deep comparison.
270
530
 
271
- ```ts
272
- data$ = this.clientsService.data$
273
- isPending$ = this.clientsService.isPending$
274
- error$ = this.clientsService.error$
275
- ```
276
- By doing this gives your component the state of the data and other feedback states for the request that now you can use in your template.
531
+ **Usage:**
532
+ ```typescript
533
+ utils = inject(UtilsService);
277
534
 
278
- ```ts
279
- {{ data$ | async }}
280
- {{ isPending$ | async }}
281
- {{ error$ | async }}
282
- ```
535
+ // Check expiration
536
+ const isExpired = this.utils.hasExpired(expiryTimestamp);
283
537
 
538
+ // Convert JSON
539
+ const json = this.utils.stringToJSON(jsonString);
284
540
 
285
- ### ApiRequest Options
286
- The following are the available options when configuring an ApiRequest object:
287
-
288
- ```ts
289
- apiRequest = ApiRequest.adapt({
290
- server: string,
291
- path: any[],
292
- headers: any,
293
- adapter?: any,
294
- mapper?: any,
295
- polling?: number, // in seconds (undefined | 0 = none)
296
- retry: RetryOptions,
297
- stream?: boolean
298
- displayError: boolean
299
- });
541
+ // Calculate Expiry
542
+ const expiryEpoch = this.utils.expires('1d'); // Returns epoch for 1 day from now
300
543
  ```
301
544
 
302
- | **Property** | **Description** | **Type** | **Required** |
303
- |--------------|--------------------------------------------------------------------------------|---------------------------|------------|
304
- | `server` | The base URL or service endpoint for the API request. | `string` | ✅ |
305
- | `path` | Additional paths to append to the base URL for constructing the full API endpoint. | `any[]` | ✅ |
306
- | `headers` | Custom headers to include in the request, provided as an object. | `any` | ✅ |
307
- | `adapter` | A model adapter used to transform incoming data (e.g., `DistrictData.adapt`). | `any` | ❌ |
308
- | `mapper` | A model adapter used to map outgoing data before sending it to the server (e.g., `DistrictData.mapper`). | `any` | ❌ |
309
- | `polling` | Enables periodic polling, where the request will be made every specified number of seconds. | `number` (seconds) | ❌ |
310
- | `retry` | Retry logic using `RetryOptions`, which includes: <br> - `times`: Number of retry attempts. <br> - `delay`: Delay in milliseconds between retries. | `RetryOptions` | ✅ |
311
- | `stream` | A flag to indicate whether the request expects a stream of data from the server. | `boolean` | ❌ |
312
- | `displayError` | A flag to indicate whether to present the error from the request in a snackbar notification. | `boolean` | ✅ |
313
-
314
-
315
- ### Additional Observables for Request Status
316
- - countdown$: If polling is active, this property gives feedback on when the next request will take place. It starts from the specified time in seconds and counts down to 0, triggering the next request and restarting the countdown.
317
- - error$: This returns any HTTP error that occurs during the request.
318
- - isPending$: This boolean value indicates whether the request is pending (true) or has been completed (false).
319
- - data$: You can access the data fetched in the request using the data$ observable. This provides the response from the server, which can be used for further processing or displaying in the UI.
545
+ ---
320
546
 
321
- ## Importing Module forRoot() Configuration
547
+ ## Available Interceptors
322
548
 
323
-
324
- # Available Interceptors
325
-
326
- There are 3 interceptors that you can import into your project for api requests.
549
+ There are 3 interceptors that you can import into your project for api requests.
327
550
 
328
551
  You may add these interceptors in your `AppModule` file as providers and import them into as providers.
329
552
 
330
- ```ts
553
+ ```typescript
331
554
  providers: [
332
555
  { provide: HTTP_INTERCEPTORS, useClass: WithCredentialsInterceptor, multi: true },
333
556
  { provide: HTTP_INTERCEPTORS, useClass: RequestHeadersInterceptor, multi: true },
@@ -343,9 +566,9 @@ This interceptor handles errors of type 400 and 500. This interceptor is applica
343
566
 
344
567
  - **WithCredentialsInterceptor**
345
568
 
346
- Adds to your request header
569
+ Adds to your request header
347
570
 
348
- ```json
571
+ ```json
349
572
  { credentials: true }
350
573
  ```
351
574