npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

http-request-manager

v22.1.4

Published

This is an Angular Module containing Components/Services using Material

Readme

HTTP Request Manager - Angular Library

TypeScript Angular RxJS

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 key
  • createJwtAuth(process.env.JWT_SECRET_KEY) — JWT (re-use your HTTP API's secret)
  • createCookieAuth(validateSession) — BFF session cookie
  • createRateLimitedAuth(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 call databaseManager.clearDatabase() (no .subscribe() required). The method also clears related localStorage metadata via LocalStorageManagerService.
  • Clear a specific table (Observable): To remove records from a specific table, use DatabaseManagerService.clearTableRecords(tableName) which returns an Observable<void>; callers should .subscribe() or use RxJS operators to react to completion.

�️ 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

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 (DatabaseStorage configured): 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: true always 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 && hasExpiredclearRequestCacheMetadata + 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:

  • DatabaseStorage must be configured with a valid table name (database storage enabled).
  • deltaSync: true must be set on the DatabaseStorage config.
  • expiresIn controls the TTL for periodic full re-syncs. Set expiresIn: '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:

  1. First call with no savedAt (GATE 1, initial fetch): full fetch, DB populated via createTableRecords, savedAt written to localStorage as Date.now(), hasInitialFetch set to true.
  2. First call with savedAt (GATE 1, subsequent session/page reload with valid cursor): deltaFetch(savedAt, ...) runs — sends X-Modified-Since: floor(savedAt / 1000) header.
    • Records returned: upserted to IndexedDB via bulkPut, merged into state via mergeDeltaData$, savedAt advanced.
    • Empty response []: state/DB unchanged, savedAt advanced to current time.
    • Error: state/DB unchanged, savedAt NOT advanced — next call retries from the same timestamp; serves from DB.
  3. 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) → fetchFromAPI fallback (full fetch repopulates).
  4. TTL expiry (when expiresIn is non-zero, GATE 3a): clearRequestCacheMetadata(table) deletes savedAt from localStorage → hasInitialFetch=false + clearSessionFlagclearTable wipes DB → fetchFromAPI repopulates and writes new savedAt. Next call falls through to GATE 1.
  5. Schema mismatch (GATE 3b): same flow as TTL expiry but also calls createDatabaseTable to recreate the table with the current adapter's schema before fetchFromAPI.
  6. forceRefresh: true: full fetch bypasses delta and serve-from-DB entirely (checks the flag inside the hasInitialFetch=true block, before GATE 4).
  7. WebSocket pushes (fetchRecord(UPDATE/CREATE/DELETE)): after each successful IndexedDB write (updateTableRecord, createTableRecord, createTableRecords bulkPut, deleteTableRecord), saveRequestCacheMetadata advances savedAt. When hasDatabase is false (no DB configured), saveRequestCacheMetadata is NOT called.

fetchStream delta sync

fetchStream mirrors the fetchRecords delta flow using the STREAM cursor:

  1. Init call, deltaSync=false: full fetchStreamFromAPI (existing tracker/DB-cache flow unchanged).
  2. Init call, deltaSync=true, no STREAM.savedAt: fetchStreamFromAPI full stream — populates DB and writes requestCache.STREAM.savedAt.
  3. Init call, deltaSync=true, STREAM.savedAt set, not expired: deltaFetch(streamSavedAt, ..., 'STREAM') — sends X-Modified-Since: floor(streamSavedAt / 1000), sets requestOptions.stream=true, upserts response via createTableRecords (bulkPut), calls saveRequestCacheMetadata(tableName, 'STREAM', ...).
  4. Init call, deltaSync=true, expired TTL: clearRequestCacheMetadata + clearSessionFlag + clearTable + full fetchStreamFromAPI (no X-Modified-Since).
  5. Non-init call, deltaSync=true, not expired, hasInitialFetch=true: serves DB-only — getTableRecords → records > 0 → setData$ + return { data, fromCache: true } packet; records = 0 → fetchStreamFromAPI fallback. 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 to utils.expires(expiresIn) — resets the TTL clock so the next full re-sync is scheduled from the last DB write.
  • requestCache.GET.savedAt: set to Date.now() — the cursor for the next delta request's X-Modified-Since header.

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-Since is added to volatileHeaders so 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 savedAt timestamp (used as the X-Modified-Since value) is the last time data was successfully written to the DB — it represents the last DB sync time, not the last API call time.
  • savedAt is cleared alongside the DB on TTL expiry and schema mismatch (via clearRequestCacheMetadata), then rewritten by the next full fetchFromAPI. Within a TTL window, only GATE 1 (initial fetch with savedAt) sends the X-Modified-Since header — once hasInitialFetch=true, GATE 4 serves from DB without HTTP. WS pushes advance savedAt so 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: true is 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_ID is used as the encryption key for SymmetricalEncryptionService. 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:

📋 Architecture Documentation

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:

📋 Interceptors Documentation

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

🎮 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 structures
  • ClientInfo - Client details
  • SessionData - Session management
  • AIMessage - AI chat messages
  • Notification - 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.json declares an engines.node of >=20.19.0 to 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.