http-request-manager 18.7.7 → 18.7.9

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
@@ -1,5 +1,91 @@
1
1
  # Request Manager Service Documentation
2
2
 
3
+ ## Overview
4
+
5
+ The `http-request-manager` is a comprehensive Angular library that provides enterprise-grade HTTP request management, state management, real-time communication, and local data persistence. It simplifies complex data flows and provides a unified API for handling HTTP, WebSocket, and storage operations.
6
+
7
+ ### Core Capabilities
8
+
9
+ #### 🌐 HTTP Request Management
10
+
11
+ - **Observable-based** service (`HTTPManagerService`) for reactive programming
12
+ - **Signal-based** service (`HTTPManagerSignalsService`) for modern Angular applications
13
+ - Automatic retry logic with configurable attempts and delays
14
+ - Polling support with countdown timers
15
+ - Streaming response handling (NDJSON, Server-Sent Events)
16
+ - Request/response adapters and mappers for data transformation
17
+ - Built-in error handling with optional toast notifications
18
+ - File download support with progress tracking
19
+
20
+ #### 🔄 State Management
21
+
22
+ - **ComponentStore integration** (`HTTPManagerStateService`) for robust state management
23
+ - Automatic CRUD state updates (Create, Read, Update, Delete)
24
+ - Built-in selectors for data access and filtering
25
+ - Pagination support with state tracking
26
+ - Real-time state synchronization via WebSocket
27
+ - IndexedDB caching for offline-first applications
28
+ - Persistent state with LocalStorage/SessionStorage
29
+
30
+ #### 💬 Real-Time Communication (WebSocket)
31
+
32
+ - **Dual-mode messaging system:**
33
+ - **Messaging (PUB- channels)**: Real-time chat/collaboration
34
+ - **Notifications (MES- channels)**: Database-persisted notifications with date-range queries
35
+ - Automatic reconnection with exponential backoff
36
+ - JWT authentication support
37
+ - Channel-based architecture (STATE, MESSAGE, NOTIFICATION)
38
+ - Subscribe/unsubscribe to channels dynamically
39
+ - Broadcast, channel, and user-specific messaging
40
+ - Connection status monitoring
41
+ - Session persistence across reconnections
42
+
43
+ #### 💾 Data Persistence
44
+
45
+ - **LocalStorage/SessionStorage** with encryption and expiration
46
+ - **IndexedDB** integration via Dexie.js for complex queries
47
+ - Automatic cache invalidation based on time
48
+ - Secure encryption using symmetrical encryption service
49
+ - Reactive storage observables for UI synchronization
50
+
51
+ #### 🎯 Advanced Features
52
+
53
+ - Request interception (credentials, headers, error handling)
54
+ - Automatic loading state management
55
+ - Database-backed notification history with epoch filtering
56
+ - Define and load previous day's notification channels
57
+ - Bulk operations for IndexedDB
58
+ - Model adapters for type safety
59
+ - Configurable global defaults via `forRoot()`
60
+
61
+ ### Key Benefits
62
+
63
+ ✅ **Reduced Boilerplate** - Eliminates repetitive HTTP and state management code
64
+ ✅ **Type-Safe** - Full TypeScript support with generics
65
+ ✅ **Offline-First** - Built-in IndexedDB caching for resilient applications
66
+ ✅ **Real-Time Ready** - Seamless WebSocket integration with state management
67
+ ✅ **Secure** - Encryption support for sensitive local data
68
+ ✅ **Scalable** - ComponentStore-based architecture for complex state
69
+ ✅ **Flexible** - Works with Observables or Signals based on preference
70
+ ✅ **Battle-Tested** - Production-ready with comprehensive error handling
71
+
72
+ ### Use Cases
73
+
74
+ | Scenario | Solution |
75
+ |----------|----------|
76
+ | Simple API calls with loading states | `HTTPManagerService` |
77
+ | Modern reactive UI with Signals | `HTTPManagerSignalsService` |
78
+ | CRUD operations with auto state sync | `HTTPManagerStateService` |
79
+ | Real-time chat/collaboration | `HTTPManagerStateService` + WebSocket (PUB- channels) |
80
+ | Persistent notifications/alerts | `HTTPManagerStateService` + WebSocket (MES- channels) |
81
+ | User preferences/settings | `LocalStorageManagerService` |
82
+ | Offline-first data access | `DatabaseManagerService` + `HTTPManagerStateService` |
83
+ | Large local datasets | `DatabaseManagerService` with Dexie.js |
84
+ | Polling for live updates | `HTTPManagerService` with polling |
85
+ | File downloads | `HTTPManagerService.downloadRequest()` |
86
+
87
+ ---
88
+
3
89
  ## Demo Component (`HttpRequestServicesDemoComponent`)
4
90
 
5
91
  The `HttpRequestServicesDemoComponent` is a comprehensive demonstration component that showcases the various services available in the `http-request-manager` library. It allows you to interactively test and visualize the functionality of HTTP services, state management, WebSockets, and local storage.
@@ -34,6 +120,357 @@ To use the demo component in your application, simply add the selector to your t
34
120
 
35
121
  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.
36
122
 
123
+ ---
124
+
125
+ ## Quick Start Guide
126
+
127
+ ### Installation & Setup (2 minutes)
128
+
129
+ #### 1. Import Module
130
+
131
+ ```typescript
132
+ // app.module.ts
133
+ import { HttpRequestManagerModule } from 'http-request-manager';
134
+
135
+ @NgModule({
136
+ imports: [
137
+ HttpRequestManagerModule.forRoot({
138
+ httpRequestOptions: {
139
+ server: 'http://localhost:8080', // Your API base URL
140
+ retry: { times: 3, delay: 2 },
141
+ displayError: true
142
+ }
143
+ })
144
+ ]
145
+ })
146
+ export class AppModule { }
147
+ ```
148
+
149
+ #### 2. Provide APP_ID (if using encryption)
150
+
151
+ ```typescript
152
+ // app.module.ts
153
+ import { APP_ID } from '@angular/core';
154
+
155
+ @NgModule({
156
+ providers: [
157
+ { provide: APP_ID, useValue: "your-unique-guid-here" }
158
+ ]
159
+ })
160
+ export class AppModule { }
161
+ ```
162
+
163
+ ### Quick Examples
164
+
165
+ #### Example 1: Simple HTTP GET Request
166
+
167
+ ```typescript
168
+ import { Component, inject } from '@angular/core';
169
+ import { HTTPManagerService, ApiRequest } from 'http-request-manager';
170
+
171
+ @Component({
172
+ selector: 'app-users',
173
+ template: `
174
+ <div *ngIf="isLoading$ | async">Loading...</div>
175
+ <div *ngFor="let user of data$ | async">
176
+ {{ user.name }}
177
+ </div>
178
+ `
179
+ })
180
+ export class UsersComponent {
181
+ httpManager = inject(HTTPManagerService);
182
+
183
+ data$ = this.httpManager.data$;
184
+ isLoading$ = this.httpManager.isPending$;
185
+
186
+ ngOnInit() {
187
+ this.httpManager.getRequest(
188
+ ApiRequest.adapt({ path: ['users'] })
189
+ ).subscribe();
190
+ }
191
+ }
192
+ ```
193
+
194
+ #### Example 2: State Management with CRUD
195
+
196
+ ```typescript
197
+ import { Injectable } from '@angular/core';
198
+ import { HTTPManagerStateService, ApiRequest, DataType } from 'http-request-manager';
199
+
200
+ interface User {
201
+ id: number;
202
+ name: string;
203
+ email: string;
204
+ }
205
+
206
+ @Injectable({ providedIn: 'root' })
207
+ export class UsersStore extends HTTPManagerStateService<User> {
208
+
209
+ constructor() {
210
+ super(
211
+ ApiRequest.adapt({
212
+ server: 'http://localhost:8080',
213
+ path: ['users']
214
+ }),
215
+ DataType.ARRAY
216
+ );
217
+ }
218
+
219
+ // Public API
220
+ loadUsers() { this.fetchRecords(); }
221
+ addUser(user: User) { this.createRecord(user); }
222
+ updateUser(user: User) { this.updateRecord(user); }
223
+ deleteUser(id: number) { this.deleteRecord(id); }
224
+ }
225
+
226
+ // Component
227
+ @Component({
228
+ selector: 'app-users',
229
+ template: `
230
+ <button (click)="store.loadUsers()">Load</button>
231
+ <div *ngFor="let user of store.data$ | async">
232
+ {{ user.name }}
233
+ <button (click)="store.deleteUser(user.id)">Delete</button>
234
+ </div>
235
+ `
236
+ })
237
+ export class UsersComponent {
238
+ store = inject(UsersStore);
239
+ }
240
+ ```
241
+
242
+ #### Example 3: WebSocket Real-Time Messaging
243
+
244
+ ```typescript
245
+ @Injectable({ providedIn: 'root' })
246
+ export class ChatStore extends HTTPManagerStateService<Message> {
247
+
248
+ constructor() {
249
+ super(
250
+ ApiRequest.adapt({
251
+ server: 'http://localhost:8080',
252
+ path: ['messages'],
253
+ ws: {
254
+ id: 'CHAT_WS',
255
+ wsServer: 'ws://localhost:8080',
256
+ jwtToken: '' // Add token if needed
257
+ }
258
+ }),
259
+ DataType.ARRAY
260
+ );
261
+ }
262
+
263
+ joinChat(channel: string) {
264
+ this.createChannel(channel);
265
+ this.subscribeToChannel(channel);
266
+ }
267
+
268
+ sendMessage(channel: string, text: string, user: any) {
269
+ this.wsMessaging(
270
+ ChannelMessage.adapt({
271
+ sessionId: user,
272
+ content: { message: text }
273
+ }),
274
+ [channel]
275
+ );
276
+ }
277
+ }
278
+
279
+ // Component
280
+ @Component({
281
+ template: `
282
+ <div *ngFor="let msg of chatStore.communicationMessages$ | async">
283
+ {{ msg.content.message }}
284
+ </div>
285
+ <input [(ngModel)]="messageText">
286
+ <button (click)="send()">Send</button>
287
+ `
288
+ })
289
+ export class ChatComponent {
290
+ chatStore = inject(ChatStore);
291
+ messageText = '';
292
+
293
+ ngOnInit() {
294
+ this.chatStore.joinChat('general');
295
+ }
296
+
297
+ send() {
298
+ this.chatStore.sendMessage('general', this.messageText, {
299
+ id: 1,
300
+ name: 'John'
301
+ });
302
+ this.messageText = '';
303
+ }
304
+ }
305
+ ```
306
+
307
+ #### Example 4: Persistent Notifications with Database
308
+
309
+ ```typescript
310
+ @Injectable({ providedIn: 'root' })
311
+ export class NotificationStore extends HTTPManagerStateService<any> {
312
+
313
+ constructor() {
314
+ super(
315
+ ApiRequest.adapt({
316
+ server: 'http://localhost:8080',
317
+ ws: {
318
+ id: 'NOTIFICATIONS',
319
+ wsServer: 'ws://localhost:8080'
320
+ }
321
+ }),
322
+ DataType.ARRAY
323
+ );
324
+ }
325
+
326
+ initNotifications(user: any) {
327
+ // Get today's notification channels
328
+ this.getTodaysNotificationChannels();
329
+
330
+ // Subscribe to alerts with 24h history
331
+ this.subscribeToNotificationChannel('alerts', {
332
+ startEpoch: Math.floor(Date.now() / 1000) - 86400
333
+ }, user);
334
+ }
335
+
336
+ sendAlert(message: string, priority: 'low' | 'high') {
337
+ this.sendNotification('alerts', {
338
+ message,
339
+ priority,
340
+ timestamp: Date.now()
341
+ });
342
+ }
343
+
344
+ loadPreviousDayChannels() {
345
+ this.definePreviousNotificationChannels();
346
+ }
347
+ }
348
+
349
+ // Component
350
+ @Component({
351
+ template: `
352
+ <div *ngFor="let notif of store.notificationMessages$ | async">
353
+ <strong>{{ notif.user_name }}</strong>: {{ notif.content.message }}
354
+ <span>{{ notif.created * 1000 | date:'short' }}</span>
355
+ </div>
356
+ <button (click)="store.loadPreviousDayChannels()">
357
+ Load Previous Day Channels
358
+ </button>
359
+ `
360
+ })
361
+ export class NotificationsComponent {
362
+ store = inject(NotificationStore);
363
+
364
+ ngOnInit() {
365
+ this.store.initNotifications({
366
+ id: 1,
367
+ name: 'John',
368
+ email: 'john@example.com'
369
+ });
370
+ }
371
+ }
372
+ ```
373
+
374
+ #### Example 5: Local Storage with Encryption
375
+
376
+ ```typescript
377
+ import { Component, inject } from '@angular/core';
378
+ import { LocalStorageManagerService, SettingOptions } from 'http-request-manager';
379
+
380
+ @Component({
381
+ selector: 'app-settings'
382
+ })
383
+ export class SettingsComponent {
384
+ storage = inject(LocalStorageManagerService);
385
+
386
+ saveSettings(settings: any) {
387
+ this.storage.setItem(
388
+ 'user-preferences',
389
+ settings,
390
+ SettingOptions.adapt({
391
+ encrypted: true,
392
+ expiresIn: '30d'
393
+ })
394
+ );
395
+ }
396
+
397
+ loadSettings() {
398
+ return this.storage.getItem('user-preferences');
399
+ }
400
+
401
+ clearSettings() {
402
+ this.storage.removeItem('user-preferences');
403
+ }
404
+ }
405
+ ```
406
+
407
+ #### Example 6: IndexedDB Caching for Offline-First
408
+
409
+ ```typescript
410
+ @Injectable({ providedIn: 'root' })
411
+ export class ProductStore extends HTTPManagerStateService<Product> {
412
+
413
+ constructor() {
414
+ super(
415
+ ApiRequest.adapt({
416
+ server: 'http://localhost:8080',
417
+ path: ['products'],
418
+ adapter: (data: any) => data as Product // Required for DB
419
+ }),
420
+ DataType.ARRAY,
421
+ DatabaseStorage.adapt({
422
+ table: 'products-cache',
423
+ expiresIn: '1d' // Cache for 1 day
424
+ })
425
+ );
426
+ }
427
+
428
+ loadProducts() {
429
+ // First checks IndexedDB cache, then fetches from server if expired
430
+ this.fetchRecords();
431
+ }
432
+ }
433
+ ```
434
+
435
+ #### Example 7: Polling for Live Updates
436
+
437
+ ```typescript
438
+ export class StatusComponent {
439
+ httpManager = inject(HTTPManagerService);
440
+
441
+ status$ = this.httpManager.data$;
442
+ countdown$ = this.httpManager.countdown$;
443
+
444
+ ngOnInit() {
445
+ this.httpManager.getRequest(
446
+ ApiRequest.adapt({
447
+ path: ['server-status'],
448
+ polling: 10 // Poll every 10 seconds
449
+ })
450
+ ).subscribe();
451
+ }
452
+
453
+ ngOnDestroy() {
454
+ this.httpManager.stopPolling();
455
+ }
456
+ }
457
+ ```
458
+
459
+ ### Common Use Cases
460
+
461
+ | Use Case | Service to Use | Key Features |
462
+ |----------|---------------|--------------|
463
+ | Simple API calls | `HTTPManagerService` | Observables, retry, polling |
464
+ | Modern reactive UI | `HTTPManagerSignalsService` | Angular Signals |
465
+ | CRUD operations | `HTTPManagerStateService` | Auto state updates |
466
+ | Real-time chat | `HTTPManagerStateService` + WS | Messaging channels |
467
+ | Persistent notifications | `HTTPManagerStateService` + WS | Database-backed |
468
+ | User preferences | `LocalStorageManagerService` | Encryption, expiration |
469
+ | Offline-first | `DatabaseManagerService` | IndexedDB |
470
+ | Large local datasets | `DatabaseManagerService` | Querying, indexing |
471
+
472
+ ---
473
+
37
474
  ## Initialization
38
475
 
39
476
  ### 1. Module Initialization (`forRoot`)
@@ -680,6 +1117,11 @@ stateService.getNotificationChannels();
680
1117
  // Get today's notification channels (from database)
681
1118
  stateService.getTodaysNotificationChannels();
682
1119
 
1120
+ // Define and load previous day's notification channels
1121
+ // This retrieves channels from the previous day's database records,
1122
+ // creates them in memory if needed, and broadcasts the updated list
1123
+ stateService.definePreviousNotificationChannels();
1124
+
683
1125
  // Subscribe to notifications with optional date filter
684
1126
  stateService.subscribeToNotificationChannel('alerts', {
685
1127
  startEpoch: Math.floor(Date.now() / 1000) - 86400, // Last 24 hours
@@ -727,6 +1169,7 @@ The library includes a demo component showcasing notification functionality:
727
1169
 
728
1170
  - Create notification channels
729
1171
  - View today's notification channels (from database)
1172
+ - Define previous day's channels (loads channels from previous day's data)
730
1173
  - Subscribe with date range filters
731
1174
  - Connect/disconnect from channels
732
1175
  - Send notifications (persisted)