http-request-manager
v22.1.4
Published
This is an Angular Module containing Components/Services using Material
Readme
HTTP Request Manager - Angular Library
Supported Angular: 22.x (Angular 22 is the supported baseline. The library also retains the observable/NgRx track for older Angular 14-18 consumers and the signal track for Angular 19+ consumers, but the peer range and the toolchain target Angular 22.)
A comprehensive Angular library providing enterprise-grade HTTP request management, state management, real-time communication, and local data persistence.
This README is the main documentation hub for the library. Detailed service guides live in src/docs/, and this page links to the observable/ngrx services for older Angular applications and the signal-based services for newer Angular applications in parallel.
🚀 Features
Core Capabilities
| Feature | Description | Angular 14-18 / Observable + NgRx | Angular 19+ / Signals |
|---------|-------------|----------------------------------|------------------------|
| 🌐 HTTP Request Management | Retry, polling, streaming, file downloads | HTTPManagerService | HTTPManagerSignalsService |
| 🔄 State Management | CRUD state, persistence, derived state | HTTPManagerStateService and StoreStateManagerService | StoreStateManagerSignalsService |
| 💬 Real-Time Communication | WebSocket channels, tracking, messaging | WebSocketManagerService, WebSocketMessageService, and MessageTrackerService | WebSocketSignalsManagerService and MessageTrackerSignalsService |
| 💾 Data Persistence | Local/session storage and offline caching | LocalStorageManagerService and DatabaseManagerService | LocalStorageSignalsManagerService |
| 🗄️ Database Queries | MySQL-syntax SQL queries on IndexedDB — the recommended way to query data | DexieSqlService | Uses the same service |
| ⚡ Utility Functions | JSON handling, encryption, headers, validation, logging | UtilsService, Encryption, Logger | Uses the same utility layer |
| 🔧 Utility Services | Headers, path/query, merging, base request classes | Utility Services | Internal and helper services |
| 🖥️ Node.js WS Server | Companion ws-request-manager Node.js package — pluggable auth, IP rate limiting, channels, heartbeat, message replay | WebSocket Server Guide | Same protocol on both sides |
Key Benefits
- ✅ Type-Safe - Full TypeScript support with generics
- ✅ Offline-First - Built-in IndexedDB caching
- ✅ Real-Time Ready - Seamless WebSocket integration with companion Node.js server
- ✅ Secure - AES & RSA encryption support for sensitive data
- ✅ Scalable - ComponentStore-based architecture
- ✅ Flexible - Works with Observables or Signals
- ✅ Pluggable Auth on Server - You control auth (API key, JWT, cookie, BFF session) and rate limits on the Node.js side
🖥️ Server-Side Companion — ws-request-manager
The frontend http-request-manager speaks the full WebSocket protocol implemented by the Node.js package ws-request-manager. The server package is deliberately thin — it does not implement any auth strategy. Instead, you provide a WsAuthFn (an async function) and the library calls it on every WebSocket upgrade.
Quick start:
// server.js
const express = require('express');
const http = require('http');
const { register, registerServer, destroy, noAuth } = require('ws-request-manager');
const app = express();
app.use(express.json());
async function start() {
await register(app, noAuth); // mounts /ws/channels, /ws/connections, /ws/broadcast
const server = http.createServer(app);
await registerServer(server, noAuth); // attaches WS upgrade handler at /ws
server.listen(3000);
process.on('SIGTERM', async () => { await destroy(); server.close(); });
}
start();Swap noAuth for a custom WsAuthFn to gate access. Common patterns:
createApiKeyAuth(process.env.STATIC_API_KEY)— static API keycreateJwtAuth(process.env.JWT_SECRET_KEY)— JWT (re-use your HTTP API's secret)createCookieAuth(validateSession)— BFF session cookiecreateRateLimitedAuth(authFn, { maxFailures: 10, blockDurationMs: 300_000 })— IP-based rate limiting wrapper
👉 Full guide: WS_SERVER_README.md — covers configuration (env vars), auth patterns, rate limiting, full message protocol reference, HTTP REST routes, and the end-to-end BFF setup.
Note on clearing persisted data:
- 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 calldatabaseManager.clearDatabase()(no.subscribe()required). The method also clears related localStorage metadata viaLocalStorageManagerService. - Clear a specific table (Observable): To remove records from a specific table, use
DatabaseManagerService.clearTableRecords(tableName)which returns anObservable<void>; callers should.subscribe()or use RxJS operators to react to completion.
�️ Database Access
The library provides two complementary services for working with IndexedDB data:
| Task | Service | Example |
|------|---------|---------|
| Query data (recommended) | DexieSqlService | sql.query('SELECT * FROM orders WHERE status = "open"') |
| Create tables | DatabaseManagerService | db.createDatabaseTable(tableDef) |
| Insert / update records | DatabaseManagerService | db.createTableRecord('orders', record) |
| Delete records | DatabaseManagerService | db.deleteTableRecord('orders', id) |
| Clear / reset database | DatabaseManagerService | db.clearDatabase() |
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.
See the full SQL syntax reference: DexieSqlService Guide
�🚀 Advanced Features
| Feature | Description | Learn More |
|---------|-------------|------------|
| 🔐 Enterprise Encryption | AES symmetric + RSA asymmetric encryption | Encryption Utils |
| 🗄️ Database Queries | MySQL-syntax SQL queries on IndexedDB — the recommended way to query data (SELECT, WHERE, JOIN, ORDER BY, LIMIT, COUNT, DISTINCT) | DexieSqlService |
| 📡 Streaming Support | NDJSON & Server-Sent Events (SSE) | HTTP Manager |
| 📄 File Downloads | Progress tracking for large files | HTTP Manager |
| 📤 File Uploads | Multi-file upload with progress, validation, and form-data config | Upload Request |
| 📊 Pagination | Built-in pagination with page tracking | HTTP State Manager |
| 🔔 Smart Notifications | Persistent notifications with DB storage | WebSocket Guide |
| 👥 Presence Tracking | Real-time user presence by channel | WebSocket Guide |
| 🔄 Message Replay | Automatic message history on reconnect | WebSocket Guide and Message Tracker |
| 🏷️ Channel Architecture | SYS-, PUB-, MES- channel prefixes | WebSocket Guide |
| 🔌 Singleton WebSocket | Single connection across ALL instances | WebSocket Guide |
| ✨ Unified Message Service | Type-safe WebSocket messaging with auto prefixes | WebSocket Message Service |
| 🖥️ Node.js WS Server | Companion ws-request-manager package for Node.js — pluggable auth, rate limiting, channels, heartbeat | WebSocket Server Guide (npm) |
| 🚀 Batch Requests | Execute multiple HTTP requests with sequential/parallel modes | Batch Request Guide |
| 📝 Message Tracking | Guaranteed delivery with gap detection | Message Tracker |
| 🔍 Debug Logging | Context-aware logging with dev/prod modes | Logger Service |
📋 Table of Contents
- Quick Start
- Configuration
- Services Overview
- Documentation Paths
- Architecture
- Interceptors
- Advanced Features
- Batch Requests
- Detailed Documentation
- Demo Examples
- Migration Guide
🚀 Quick Start
Installation & Setup (2 minutes)
1. Import Module
// app.module.ts
import { HttpRequestManagerModule } from 'http-request-manager';
@NgModule({
imports: [
HttpRequestManagerModule.forRoot({
httpRequestOptions: {
server: 'http://localhost:8080', // Your API base URL
retry: { times: 3, delay: 2 },
displayError: true
}
})
]
})
export class AppModule { }2. Provide APP_ID (if using encryption)
// app.module.ts
import { APP_ID } from '@angular/core';
@NgModule({
providers: [
{ provide: APP_ID, useValue: "your-unique-guid-here" }
]
})
export class AppModule { }Simple Examples
Basic HTTP Request
import { Component, inject } from '@angular/core';
import { HTTPManagerService, ApiRequest } from 'http-request-manager';
@Component({
selector: 'app-users',
template: `
<div *ngIf="isLoading$ | async">Loading...</div>
<div *ngIf="error$ | async as error" class="error">
Error: {{ error.message }}
</div>
<div *ngFor="let user of data$ | async">
{{ user.name }}
</div>
`
})
export class UsersComponent {
httpManager = inject(HTTPManagerService);
data$ = this.httpManager.data$;
isLoading$ = this.httpManager.isPending$;
error$ = this.httpManager.error$;
ngOnInit() {
this.httpManager.getRequest(
ApiRequest.adapt({ path: ['users'], displaySuccess: true, successMessage: 'Loaded users!' })
).subscribe();
}
}State Management with CRUD
@Injectable({ providedIn: 'root' })
export class UsersStore extends HTTPManagerStateService<User> {
constructor() {
super(
ApiRequest.adapt({
server: 'http://localhost:8080',
path: ['users']
}),
DataType.ARRAY
);
}
// Public API
loadUsers() { this.fetchRecords(); }
addUser(user: User) { this.createRecord(user); }
updateUser(user: User) { this.updateRecord(user); }
deleteUser(id: number) { this.deleteRecord(id); }
}
// Component
@Component({
selector: 'app-users',
template: `
<button (click)="store.loadUsers()">Load</button>
<div *ngFor="let user of store.data$ | async">
{{ user.name }}
<button (click)="store.deleteUser(user.id)">Delete</button>
</div>
`
})
export class UsersComponent {
store = inject(UsersStore);
}Request Tracking Options (Database Mode)
HTTPManagerStateService supports request tracking options for fetchRecords and fetchStream when database caching is configured (DatabaseStorage provided in the service constructor).
service.fetchRecords(RequestOptions.adapt({
path: ['ai/pagination?page=0&size=25'],
ignoreQueryParams: ['page', 'size'],
queryParamsExpiresIn: '10s'
}));Supported request options:
ignoreQueryParams: Query keys to track for request-change behavior.queryParamsExpiresIn: Expiry window for tracked values (examples:10s,5mn,1h).
Behavior notes:
- Database enabled (
DatabaseStorageconfigured): tracker is active, repeated identical query values are blocked until expiry, then can call API again. - Database disabled: tracker is bypassed; requests call the API directly each time.
forceRefresh: truealways forces an API call.
Delta Sync (Incremental Fetch)
When deltaSync: true is set on DatabaseStorage, the store performs a delta fetch on the initial call within a TTL window (after savedAt cursor exists), then serves subsequent calls directly from the IndexedDB cache without making any HTTP request. The backend returns only records created or modified at or after the provided X-Modified-Since: <epoch> timestamp; the store merges them via upsert (IndexedDB bulkPut + mergeDeltaData$ state updater).
Both fetchRecords and fetchStream honor deltaSync. Each maintains its own savedAt cursor under requestCache.GET.savedAt and requestCache.STREAM.savedAt respectively; a stream delta fetch advances the STREAM cursor only and leaves the GET cursor untouched (and vice versa).
Gating flow:
The same gates apply to both fetchRecords (reads requestCache.GET.savedAt) and fetchStream (reads requestCache.STREAM.savedAt). Both paths honor expiresIn on the init call — an expired cursor triggers clearTable + full fetch instead of deltaFetch with a stale cursor.
| GATE | Condition | Behavior |
|------|-----------|----------|
| GATE 1 (initial fetch) | !hasInitialFetch && deltaSync=true | Init expiry guard: if expires > 0 && hasExpired → clearRequestCacheMetadata + clearSessionFlag + clearTable + full fetch (no X-Modified-Since). Else if DB table missing → initDBStorageAsync + full fetch. Else if savedAt exists → deltaFetch(savedAt, ...) (sends X-Modified-Since header). Else → full fetch. Sets hasInitialFetch=true on completion. |
| GATE 3a (TTL expiry) | hasExpired=true | clearRequestCacheMetadata(table) → clears savedAt from localStorage. clearSessionFlag() + hasInitialFetch=false. clearTable + full fetch (resets DB + writes new savedAt). Applies regardless of deltaSync. |
| GATE 3b (schema mismatch) | Stored schema ≠ current adapter schema | Same as GATE 3a but also calls createDatabaseTable to recreate with new schema before full fetch. |
| GATE 4 (subsequent fetch) | hasInitialFetch=true && deltaSync=true | Serve from DB — no API call. hasDatabaseTable(table) → if missing, initDBStorageAsync + fetchFromAPI. If exists → getTableRecords → if records exist, setData$ + return { data, fromCache: true } packet (stream) / adapted records (records); if empty, fetchFromAPI fallback. |
| GATE 5 (deltaSync=false) | deltaSync=false | Tracker + DB cache flow (unchanged, no delta). |
| forceRefresh | options.forceRefresh=true | Full fetch bypasses delta and serve-from-DB paths entirely. |
| WS push | fetchRecord(UPDATE/CREATE/DELETE) | After successful DB write, saveRequestCacheMetadata advances the GET savedAt (CRUD paths) so the next delta fetch (after TTL reset) uses the latest cursor. |
Requirements:
DatabaseStoragemust be configured with a validtablename (database storage enabled).deltaSync: truemust be set on theDatabaseStorageconfig.expiresIncontrols the TTL for periodic full re-syncs. SetexpiresIn: '0'to disable TTL expiry entirely — delta sync will run on every call without periodic full re-syncs. Use a non-zero value (e.g.,'1d') to periodically clear and re-fetch all data (corrects soft-delete drift).
// Delta sync with no TTL expiry (delta on every call, no periodic full re-sync)
const service = new HTTPManagerStateService(
ApiRequest.adapt({ server: 'https://api.example.com', path: ['api', 'items'] }),
DataType.ARRAY,
DatabaseStorage.adapt({ table: 'items', expiresIn: '0', deltaSync: true })
);
// Delta sync with daily full re-sync (delta between cycles, full fetch at TTL boundary)
const service2 = new HTTPManagerStateService(
ApiRequest.adapt({ server: 'https://api.example.com', path: ['api', 'items'] }),
DataType.ARRAY,
DatabaseStorage.adapt({ table: 'items', expiresIn: '1d', deltaSync: true })
);How it works:
- First call with no
savedAt(GATE 1, initial fetch): full fetch, DB populated viacreateTableRecords,savedAtwritten to localStorage asDate.now(),hasInitialFetchset totrue. - First call with
savedAt(GATE 1, subsequent session/page reload with valid cursor):deltaFetch(savedAt, ...)runs — sendsX-Modified-Since: floor(savedAt / 1000)header.- Records returned: upserted to IndexedDB via
bulkPut, merged into state viamergeDeltaData$,savedAtadvanced. - Empty response
[]: state/DB unchanged,savedAtadvanced to current time. - Error: state/DB unchanged,
savedAtNOT advanced — next call retries from the same timestamp; serves from DB.
- Records returned: upserted to IndexedDB via
- Subsequent calls with
hasInitialFetch=true(GATE 4): serves directly from IndexedDB — no HTTP request.- Table exists + records > 0 →
setData$+ return adapted records. - Table missing →
initDBStorageAsync+fetchFromAPI(table recreated, full fetch repopulates). - Empty DB (0 records) →
fetchFromAPIfallback (full fetch repopulates).
- Table exists + records > 0 →
- TTL expiry (when
expiresInis non-zero, GATE 3a):clearRequestCacheMetadata(table)deletessavedAtfrom localStorage →hasInitialFetch=false+clearSessionFlag→clearTablewipes DB →fetchFromAPIrepopulates and writes newsavedAt. Next call falls through to GATE 1. - Schema mismatch (GATE 3b): same flow as TTL expiry but also calls
createDatabaseTableto recreate the table with the current adapter's schema beforefetchFromAPI. forceRefresh: true: full fetch bypasses delta and serve-from-DB entirely (checks the flag inside thehasInitialFetch=trueblock, before GATE 4).- WebSocket pushes (
fetchRecord(UPDATE/CREATE/DELETE)): after each successful IndexedDB write (updateTableRecord,createTableRecord,createTableRecordsbulkPut,deleteTableRecord),saveRequestCacheMetadataadvancessavedAt. WhenhasDatabaseis false (no DB configured),saveRequestCacheMetadatais NOT called.
fetchStream delta sync
fetchStream mirrors the fetchRecords delta flow using the STREAM cursor:
- Init call,
deltaSync=false: fullfetchStreamFromAPI(existing tracker/DB-cache flow unchanged). - Init call,
deltaSync=true, noSTREAM.savedAt:fetchStreamFromAPIfull stream — populates DB and writesrequestCache.STREAM.savedAt. - Init call,
deltaSync=true,STREAM.savedAtset, not expired:deltaFetch(streamSavedAt, ..., 'STREAM')— sendsX-Modified-Since: floor(streamSavedAt / 1000), setsrequestOptions.stream=true, upserts response viacreateTableRecords(bulkPut), callssaveRequestCacheMetadata(tableName, 'STREAM', ...). - Init call,
deltaSync=true, expired TTL:clearRequestCacheMetadata+clearSessionFlag+clearTable+ fullfetchStreamFromAPI(noX-Modified-Since). - Non-init call,
deltaSync=true, not expired,hasInitialFetch=true: serves DB-only —getTableRecords→ records > 0 →setData$+ return{ data, fromCache: true }packet; records = 0 →fetchStreamFromAPIfallback. No HTTP.
Deletion contract (Option a — WS-driven deletes): The delta stream response contains upserts only — deletes are NOT conveyed in the delta payload. Use fetchRecord(DELETE) (or deleteRecord$) to remove records via WebSocket; deleteTableRecord advances savedAt so the next stream delta fetch's cursor is correct. Soft-delete drift is corrected at the next TTL boundary (GATE 3a) when the table is fully replaced.
localStorage updates on DB write:
When data is pushed to IndexedDB (full fetch, delta fetch, or WS push), the localStorage store for the table is updated with:
expires: refreshed toutils.expires(expiresIn)— resets the TTL clock so the next full re-sync is scheduled from the last DB write.requestCache.GET.savedAt: set toDate.now()— the cursor for the next delta request'sX-Modified-Sinceheader.
DatabaseStorage properties:
| Property | Type | Default | Description |
|----------|------|---------|-------------|
| table | string | '' | IndexedDB table name (required for delta sync) |
| expiresIn | string | '' | TTL for full re-sync. Use '0' to disable (delta sync only, no periodic full re-sync). Examples: '1m', '1h', '1d' |
| deltaSync | boolean | false | Enable incremental fetch with X-Modified-Since header |
Notes:
X-Modified-Sinceis added tovolatileHeadersso it's excluded from request signatures and cache metadata.- With
expiresIn: '0', TTL never expires — delta sync runs on every call. Use a non-zero value to periodically full re-sync and catch deleted records. - The
savedAttimestamp (used as theX-Modified-Sincevalue) is the last time data was successfully written to the DB — it represents the last DB sync time, not the last API call time. savedAtis cleared alongside the DB on TTL expiry and schema mismatch (viaclearRequestCacheMetadata), then rewritten by the next fullfetchFromAPI. Within a TTL window, only GATE 1 (initial fetch withsavedAt) sends theX-Modified-Sinceheader — oncehasInitialFetch=true, GATE 4 serves from DB without HTTP. WS pushes advancesavedAtso the next initial fetch (e.g., after a page reload within TTL) deltas from the latest WS write rather than re-fetching records that were already merged.- Fully backwards compatible — existing consumers see no behavior change unless
deltaSync: trueis set.
⚙️ Configuration
Module Initialization (forRoot)
Configure the library globally using the forRoot method:
import { HttpRequestManagerModule } from 'http-request-manager';
@NgModule({
imports: [
HttpRequestManagerModule.forRoot({
httpRequestOptions: {
server: 'https://api.example.com',
headers: { 'Authorization': 'Bearer token' },
retry: { times: 3, delay: 2 },
displayError: true
},
LocalStorageOptions: {
storageName: 'my-app-data',
storageSettingsName: 'my-app-settings',
options: {
encrypted: true,
expiresIn: '7d'
}
}
})
]
})
export class AppModule { }Configuration Options
HTTP Options (ConfigHTTPOptions)
| Option | Type | Description | Default |
|--------|------|-------------|---------|
| server | string | Base URL for API requests | '' |
| path | any[] | Default path segments | [] |
| headers | any | Default headers | {} |
| polling | number | Default polling interval (seconds) | 0 |
| retry | RetryOptions | Default retry configuration | { times: 0, delay: 3 } |
| stream | boolean | Enable streaming by default | false |
| displayError | boolean | Show toast errors by default | false |
| displaySuccess | boolean | Show toast on success by default | false |
| successMessage | string | Custom success toast message (optional) | undefined |
| errorMessage | string | Custom error toast message (optional, overrides default) | undefined |
Local Storage Options (LocalStorageOptions)
| Option | Type | Description | Default |
|--------|------|-------------|---------|
| storageName | string | Key for storing data | 'storage' |
| storageSettingsName | string | Key for settings metadata | 'global-storage' |
| options | SettingOptions | Default storage settings | { storage: StorageType.GLOBAL, expires: 0, expiresIn: '', encrypted: false } |
Retry Options (RetryOptions)
| Option | Type | Description | Default |
|--------|------|-------------|---------|
| times | number | Number of retry attempts | 0 |
| delay | number | Delay between retries (seconds) | 3 |
WebSocket Options (WSOptions)
| Option | Type | Description | Default |
|--------|------|-------------|---------|
| id | string | Channel identifier (used to construct channel names) | '' |
| wsServer | string | WebSocket server URL | '' |
| jwtToken | string | JWT token for authentication | '' |
| permissions | string[] | Permission levels for the connection | [] |
| channels | string[] | Additional channels to subscribe to | [] |
| user | any | User information for presence tracking | undefined |
| retry | RetryOptions | Retry configuration for reconnection | { times: 0, delay: 3 } |
Injection Tokens
| Token | Type | Purpose | Required |
|-------|------|---------|----------|
| CONFIG_SETTINGS_TOKEN | ConfigOptions | Global library configuration (provided by forRoot()) | Yes (via forRoot()) |
| APP_ID | string | Unique application ID for encryption key generation | Yes (if using encryption) |
Providing APP_ID
If using encryption features (localStorage encryption, AES/RSA encryption), you must provide a unique APP_ID:
import { APP_ID } from '@angular/core';
@NgModule({
providers: [
{ provide: APP_ID, useValue: 'your-unique-app-guid-here' }
]
})
export class AppModule { }Important: The
APP_IDis used as the encryption key forSymmetricalEncryptionService. Use a strong, unique value per application.
📚 Services Overview
Angular 14-18: Observable + NgRx Services
| Service | Description | Use Case |
|---------|-------------|----------|
| HTTPManagerService | Observable-based HTTP client with retry, polling, streaming | Simple API calls with loading states |
| HTTPManagerStateService | ComponentStore + HTTP + WebSocket + IndexedDB | CRUD with auto state sync and real-time updates |
| StoreStateManagerService | Persistent ComponentStore with localStorage sync | Application state persistence |
| WebSocketManagerService | Singleton WebSocket connection manager | Real-time messaging and notifications |
| WebSocketMessageService | Unified type-safe message sending service | Simplified WebSocket messaging with auto prefixes |
| MessageTrackerService | Guaranteed message delivery with gap detection | Message tracking and reconnection sync |
| LocalStorageManagerService | Secure local/session storage with encryption | User preferences and session data |
| DatabaseManagerService | IndexedDB wrapper via Dexie.js | Offline-first data access |
Angular 19+: Signal-Based Services
| Service | Description | Use Case |
|---------|-------------|----------|
| HTTPManagerSignalsService | Signal-based HTTP client for modern reactive UI | Modern Angular with Signals |
| LocalStorageSignalsManagerService | Signal-based local/session storage | Reactive persisted UI state |
| StoreStateManagerSignalsService | Signal-based persistent state service | App state persistence with computed derivations |
| WebSocketSignalsManagerService | Signal-based WebSocket manager | Signal-driven real-time dashboards and messaging |
| MessageTrackerSignalsService | Signal-based channel/message tracking (deprecated — use ChannelPresenceSignalsService) | Presence, counters, last-message views |
| ChannelPresenceSignalsService | Signal-based channel presence and metadata tracking | ✅ Recommended replacement for MessageTrackerSignalsService |
Message Display System
| Service | Description | Use Case |
|---------|-------------|----------|
| MessageDisplayRouterService | Rule-based message routing to display strategies | Routing messages to snackbar, dialog, or custom displays |
| SnackbarStrategy | Default toast notification display strategy | Showing toast messages via ToastMessageDisplayService |
Base Request Services (Internal)
| Service | Description | Use Case |
|---------|-------------|----------|
| RequestService | Base HTTP request class with BehaviorSubject state | Internal — extended by HTTPManagerService |
| RequestSignalsService | Base HTTP request class with Angular Signals | Internal — extended by HTTPManagerSignalsService |
Shared Utilities
| Service | Description | Use Case |
|---------|-------------|----------|
| UtilsService | Utilities: encryption, headers, merging, path/query | Helper functions |
| Utility Services | Headers, path/query, merging, base request classes | Internal and helper services |
Common Use Cases
| Use Case | Service to Use | Key Features |
|----------|---------------|--------------|
| Simple API calls | HTTPManagerService | Observables, retry, polling |
| Modern reactive UI | HTTPManagerSignalsService | Angular Signals |
| CRUD operations | HTTPManagerStateService | Auto state updates, pagination |
| Real-time chat | HTTPManagerStateService + WebSocket | PUB- messaging channels |
| Persistent notifications | HTTPManagerStateService + WebSocket | MES- channels with DB storage |
| State synchronization | HTTPManagerStateService + WebSocket | SYS- private channels |
| Unified WebSocket messaging | WebSocketMessageService | Type-safe, auto prefixes, validation |
| User preferences | LocalStorageManagerService | Encryption, expiration |
| Offline-first | DatabaseManagerService | IndexedDB caching, querying |
| Large local datasets | DatabaseManagerService | Bulk operations, indexing |
| Secure data storage | LocalStorageManagerService | AES encryption |
| File transfers | HTTPManagerService | Download progress tracking |
| Live data streams | HTTPManagerService | NDJSON, SSE streaming |
📖 Documentation Paths
All detailed service guides live in src/docs/. Use this README as the entry point, then choose the track that matches the Angular version in your app.
Angular 14-18: Observable + NgRx Track
| Category | Documentation | |----------|---------------| | HTTP | HTTP Manager | | State | HTTP State Manager and Store State Manager | | Real-Time | WebSocket Manager, WebSocket Message Service, and Message Tracker | | Persistence | Local Storage and Database | | Utilities | Utils, Encryption, Logger | | Reference | Models, Complete API Reference |
Angular 19+: Signal Track
| Category | Documentation | |----------|---------------| | Overview | Signal Services Overview | | HTTP | HTTP Manager Signals | | State | Store State Signals | | Real-Time | WebSocket Signals and Channel Presence Signals | | Message Tracking | Message Tracker Signals (deprecated — use Channel Presence Signals) |
Cross-Cutting
| Category | Documentation | |----------|---------------| | Message Display | Message Display System | | Interceptors | HTTP Interceptors | | Models | Models Reference | | Batch Requests | Batch Request Guide | | File Uploads | Upload Request Guide | | Encryption | Encryption Utils | | Logger | Logger Service | | SQL Queries | DexieSqlService Guide | | Persistence | Local Storage Signals |
🏗️ Architecture
For detailed system architecture, data flows, and design patterns, see:
System Overview
┌─────────────────────────────────────────────────────────────────┐
│ Angular Application │
├─────────────────────────────────────────────────────────────────┤
│ ┌────────────────┐ ┌────────────────┐ ┌──────────────────┐ │
│ │ Components │ │ Components │ │ Components │ │
│ │ (Signals) │ │ (Observables) │ │ (State Store) │ │
│ └───────┬────────┘ └───────┬────────┘ └────────┬─────────┘ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────────┐ │
│ │HTTPManager │ │HTTPManager │ │HTTPManager │ │
│ │SignalsService│ │Service │ │StateService │ │
│ └──────┬───────┘ └──────┬───────┘ └────────┬─────────┘ │
│ │ │ │ │
│ └───────────────────┴──────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ HttpClient │ │
│ │ (Angular) │ │
│ └────────┬────────┘ │
│ │ │
├─────────────────────────────┼───────────────────────────────────┤
│ │ │
│ ┌──────────────────────────┼──────────────────────┐ │
│ │ Storage Layer │ │
│ ├──────────────────────────┼──────────────────────┤ │
│ │ ┌────────────────┐ │ ┌─────────────┐ │ │
│ │ │LocalStorage │ │ │IndexedDB │ │ │
│ │ │Manager Service │ │ │(Dexie.js) │ │ │
│ │ └────────────────┘ │ └─────────────┘ │ │
│ └──────────────────────────┼──────────────────────┘ │
│ │ │
│ ┌──────────────────────────┼──────────────────────┐ │
│ │ WebSocket Layer │ │
│ ├──────────────────────────┼──────────────────────┤ │
│ │ ┌─────────────────────────────────────┐ │ │
│ │ │ WebsocketService │ │ │
│ │ └─────────────────────────────────────┘ │ │
│ └─────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘🔧 Interceptors
The library provides several HTTP interceptors that are automatically configured:
Available Interceptors
| Interceptor | Purpose | Automatically Applied |
|-------------|---------|----------------------|
| RequestErrorInterceptor | Handles 400/500 errors with toast notifications | ✅ Yes |
| RequestHeadersInterceptor | Adds Content-Type, Accept-Language, Current-Date | ✅ Yes |
| CredentialsInterceptor | Adds withCredentials: true for CORS | ✅ Yes |
| ProxyDebuggerInterceptor | Debug logging for development | ⚙️ Configurable |
Manual Configuration
// app.module.ts
providers: [
{ provide: HTTP_INTERCEPTORS, useClass: WithCredentialsInterceptor, multi: true },
{ provide: HTTP_INTERCEPTORS, useClass: RequestHeadersInterceptor, multi: true },
{ provide: HTTP_INTERCEPTORS, useClass: RequestErrorInterceptor, multi: true }
]Customization
Error handling can be customized with ErrorSettings:
import { ErrorSettings } from 'http-request-manager';
const customSettings: ErrorSettings = {
displayError: true,
displayWarning: true,
customHandler: (error) => {
// Custom error handling logic
}
};📚 Detailed Documentation
For in-depth documentation on each service and component, refer to the following detailed guides:
Detailed Docs for Angular 14-18
| Documentation | Description | |---------------|-------------| | 📖 HTTP Manager Service | Observable-based HTTP client with retry, polling, streaming, and error handling | | 📖 HTTP Manager State Service | ComponentStore integration with automatic CRUD state updates and WebSocket sync | | 📖 Store State Manager Service | Persistent ComponentStore synchronized with local/session storage | | 📖 WebSocket Manager Service | WebSocket connection management with channel-based messaging and notifications | | 📖 WebSocket Message Service | Type-safe WebSocket message sending with channel prefix helpers | | 📖 Message Tracker Service | Guaranteed message delivery with gap detection and reconnection sync | | 📖 Local Storage Manager Service | Secure local/session storage with encryption and expiration | | 📖 Database Manager Service | IndexedDB wrapper via Dexie.js with Observable API for offline-first apps | | 🚀 Batch Request Service | Execute multiple HTTP requests with sequential/parallel modes and configurable error handling | | 📤 Upload Request Service | Multi-file upload with progress tracking, validation, and form-data configuration | | 🔐 Encryption Utils | AES symmetric and RSA asymmetric encryption utilities | | 📝 Logger Service | Context-aware logging with automatic dev/prod mode detection | | 📚 Models Reference | Complete reference for all data models and configuration interfaces |
Detailed Docs for Angular 19+
| Documentation | Description | |---------------|-------------| | 📖 Signal Services Overview | Overview of the signal-based service set and migration guidance | | 📖 HTTP Manager Signals Service | Signal-based HTTP client for modern reactive UI with Angular Signals | | 📖 Local Storage Signals Manager Service | Signal-based persisted storage patterns | | 📖 Store State Signals Manager Service | Signal-based state persistence and computed state | | 📖 WebSocket Signals Manager Service | Signal-driven WebSocket connection and subscription management | | 📖 Message Tracker Signals Service | Signal-based message counting, presence, and channel metadata | | 🚀 Batch Request Service | Execute multiple HTTP requests with sequential/parallel modes and configurable error handling |
Shared Services
| Documentation | Description | |---------------|-------------| | 📖 Utils Service | Utility functions for JSON handling, encryption, headers, and validation |
Core Components
| Documentation | Description | |---------------|-------------| | 🏗️ Architecture | System architecture, data flows, and design patterns | | 🔧 Interceptors | HTTP interceptors for error handling, headers, authentication, and debugging |
Additional Resources
- Request Manager Services - Detailed API documentation for the request manager services (
src/lib/services/request-manager-services/README.md) - Encryption Utils - Encryption utility documentation (
src/lib/services/utils/encryption/README.md)
🎮 Demo Examples
Comprehensive demo components showcase all library features in action:
Available Demos
Located in src/lib/http-request-services-demo/:
| Demo Component | Features Demonstrated | |----------------|----------------------| | HttpRequestServicesDemoComponent | Main demo hub with service selection | | RequestManagerDemoComponent | HTTP CRUD, file downloads, streaming, polling, retry | | RequestManagerStateDemoComponent | State management, pagination, WebSocket sync, IndexedDB caching | | RequestManagerWsDemoComponent | Real-time chat, AI messaging, notifications, presence tracking | | LocalStorageDemoComponent | Encrypted storage, expiration, reactive signals | | LocalStorageSignalsDemoComponent | Signal-based localStorage API | | DatabaseDataDemoComponent | IndexedDB CRUD, querying, bulk operations | | RequestSignalsManagerDemoComponent | Signal-based HTTP with file downloads | | StoreStateManagerDemoComponent | Persistent state with localStorage sync |
Demo Features
HTTP Service Demos:
- ✅ Basic CRUD operations
- ✅ File download with progress tracking
- ✅ Streaming responses (NDJSON, SSE)
- ✅ Polling with countdown timers
- ✅ Retry logic with custom delays
- ✅ Error handling with toast notifications
State Management Demos:
- ✅ ComponentStore integration
- ✅ Automatic state updates
- ✅ Pagination controls
- ✅ WebSocket real-time sync
- ✅ IndexedDB caching
- ✅ Database clear/refresh
WebSocket Demos:
- ✅ Channel-based messaging (PUB- channels)
- ✅ Private state sync (SYS- channels)
- ✅ Persistent notifications (MES- channels)
- ✅ User presence tracking
- ✅ Message history & replay
- ✅ AI chat integration
- ✅ Multi-room support
Storage Demos:
- ✅ Encrypted localStorage
- ✅ SessionStorage usage
- ✅ Expiration management
- ✅ Signal-based API
- ✅ Reactive updates
Usage
<app-http-request-services-demo
[server]="'http://localhost:8080'"
[wsServer]="'ws://localhost:8080'"
[jwtToken]="'your-jwt-token'"
[adapter]="myAdapterFunction"
[mapper]="myMapperFunction">
</app-http-request-services-demo>Sample Models
Demo includes production-ready sample models:
User- User data structuresClientInfo- Client detailsSessionData- Session managementAIMessage- AI chat messagesNotification- Notification structures
📖 Migration Guide
From HttpClient to HTTPManagerService
Before:
http.get('api/users').subscribe(users => {
this.users = users;
this.loading = false;
});After:
httpManager.getRequest(
ApiRequest.adapt({ path: ['users'] })
).subscribe();
data$ = this.httpManager.data$;
isLoading$ = this.httpManager.isPending$;From Manual State to HTTPManagerStateService
Before:
users: User[] = [];
loading = false;
loadUsers() {
this.loading = true;
this.http.get('api/users').subscribe(users => {
this.users = users;
this.loading = false;
});
}
addUser(user: User) {
this.http.post('api/users', user).subscribe(newUser => {
this.users = [...this.users, newUser];
});
}After:
@Injectable()
export class UsersStore extends HTTPManagerStateService<User> {
constructor() {
super(ApiRequest.adapt({ path: ['users'] }), DataType.ARRAY);
}
loadUsers() { this.fetchRecords(); }
addUser(user: User) { this.createRecord(user); }
}
// Component
data$ = this.usersStore.data$;
isLoading$ = this.usersStore.isPending$;📋 API Reference
Core Models
All models follow the <Name>Interface + <Name>Model pattern with static adapt() methods.
| Model | Description | Documentation |
|-------|-------------|---------------|
| ApiRequest | HTTP request configuration | Models Guide |
| RetryOptions | Retry behavior settings | Models Guide |
| DataType | Data structure type (ARRAY, OBJECT) | Models Guide |
| DatabaseStorage | IndexedDB configuration | Models Guide |
| SettingOptions | Storage settings | Models Guide |
| WSOptions | WebSocket configuration | Models Guide |
| ConfigOptions | Global library configuration | Models Guide |
| StateStorageOptions | Persistent state configuration | Models Guide |
| TableSchemaDef | Database table schema | Models Guide |
| ChannelMessage | WebSocket message structure | Models Guide |
| WSUser | WebSocket user info | Models Guide |
Enums
| Enum | Values | Description |
|------|--------|-------------|
| DataType | ARRAY, OBJECT | Response data structure |
| StreamType | NDJSON, SSE | Streaming response types |
| StorageType | GLOBAL, SESSION | Storage scope |
| CommunicationType | subscribe, unsubscribe, message, notification, etc. | WebSocket message types |
| ChannelType | SYS, PUB, MES | Channel prefixes |
| ToastColors | SUCCESS, WARN, ERROR, INFO | Toast notification colors |
Configuration Tokens
| Token | Type | Purpose |
|-------|------|---------|
| CONFIG_SETTINGS_TOKEN | ConfigOptions | Global library configuration |
| APP_ID | string | Application ID for encryption |
Complete API Documentation
For comprehensive API reference with all methods, parameters, and examples: 📋 Complete API Reference
🧩 Angular 22 Support Matrix
This library is published with Angular 22 as the supported baseline. Older Angular tracks remain documented for reference, but the peer dependency range and toolchain target Angular 22.
| Angular Version | Track | Recommended Service |
|-----------------|-------|---------------------|
| 14-18 | Observable + NgRx | HTTPManagerService, HTTPManagerStateService, WebSocketManagerService |
| 19-21 | Signals | HTTPManagerSignalsService, StoreStateManagerSignalsService, WebSocketSignalsManagerService |
| 22 (supported) | Signals (default) + Observable | All of the above — module-based bootstrap |
Required Toolchain
| Tool | Version |
|------|---------|
| Angular | ^22.0.1 |
| Angular CLI / @angular-devkit/build-angular | ^22.0.1 |
| Angular CDK | ^22.0.1 |
| Angular Material | ^22.0.1 |
| @ngrx/component-store | ^21.1.1 |
| @ngx-translate/core | ^17.0.0 |
| TypeScript | ~6.0.0 |
| Node.js | >=20.19.0 (Angular 22 CLI requires >=22.22.3 / >=24.15.0 / >=26.0.0) |
| ng-packagr | ^22.0.0 |
| RxJS | ~7.8.0 |
| zone.js | ~0.16.2 |
The library's
package.jsondeclares anengines.nodeof>=20.19.0to match the Angular 22 toolchain requirements.
🤝 Contributing
This library is designed to be enterprise-ready and production-safe. All features include comprehensive error handling, TypeScript support, and extensive configuration options.
📄 License
This project is part of the Angular application library suite.
Need help? Check out the detailed documentation for each service, explore the demo examples, or review the architecture documentation for implementation guidance.
