http-request-manager 18.7.1 → 18.7.3

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
@@ -468,21 +468,45 @@ this.wsService.getUsersInChannel('PUB-my-channel');
468
468
 
469
469
  #### Channel Naming Conventions
470
470
 
471
- The WebSocket service supports channel prefixes for organizing communication:
471
+ The WebSocket service and state manager use a **channel type system** to organize communication. Channel prefixes are managed automatically by the state service.
472
472
 
473
- | Prefix | Description | Visibility |
474
- | :--- | :--- | :--- |
475
- | `PUB-` | Public channels for user messaging | Visible to users |
476
- | `SYS-` | System channels for internal communication | Hidden from users |
473
+ ##### Channel Types (`ChannelType` Enum)
474
+
475
+ ```typescript
476
+ import { ChannelType, createChannelName } from 'http-request-manager';
477
+
478
+ export enum ChannelType {
479
+ STATE = 'SYS', // Private state synchronization channels
480
+ MESSAGE = 'MES', // Messaging/communication channels (persisted notifications)
481
+ NOTIFICATION = 'PUB' // Public notification/broadcast channels
482
+ }
483
+
484
+ // Utility function to create prefixed channel name
485
+ createChannelName(ChannelType.STATE, 'USERS123'); // Returns 'SYS-USERS123'
486
+ createChannelName(ChannelType.MESSAGE, 'alerts'); // Returns 'MES-alerts'
487
+ createChannelName(ChannelType.NOTIFICATION, 'chat'); // Returns 'PUB-chat'
488
+ ```
489
+
490
+ | Channel Type | Prefix | Description | Visibility | Persistence |
491
+ | :--- | :--- | :--- | :--- | :--- |
492
+ | `STATE` | `SYS-` | Private channels for state synchronization (CRUD operations) | Hidden from users | In-memory only |
493
+ | `MESSAGE` | `MES-` | Messaging channels for notifications (persisted to database) | Visible to users | Database persisted |
494
+ | `NOTIFICATION` | `PUB-` | Public channels for real-time messaging/chat | Visible to users | In-memory only |
495
+
496
+ **Important:** When using `HTTPManagerStateService`, channel prefixes are automatically managed. You only need to provide the base channel name.
477
497
 
478
498
  **Example:**
479
499
 
480
500
  ```typescript
481
- // Create a public channel (visible in UI)
482
- this.wsService.createChannel('PUB-general-chat');
501
+ // State service automatically adds SYS- prefix for state channels
502
+ // User provides: 'USERS123'
503
+ // State service uses: 'SYS-USERS123'
483
504
 
484
- // Create a system channel (hidden from UI)
485
- this.wsService.createChannel('SYS-internal-notifications');
505
+ // For messaging channels, use subscribeToMessageChannel()
506
+ stateService.subscribeToMessageChannel('alerts'); // Uses 'MES-alerts'
507
+
508
+ // For notification channels, use subscribeToNotificationChannel()
509
+ stateService.subscribeToNotificationChannel('announcements'); // Uses 'PUB-announcements'
486
510
  ```
487
511
 
488
512
  #### WebSocket Message Types
@@ -543,6 +567,326 @@ export class UsersStore extends HTTPManagerStateService<User> {
543
567
  }
544
568
  ```
545
569
 
570
+ ---
571
+
572
+ ## Real-Time Features
573
+
574
+ The `http-request-manager` library provides two distinct real-time communication features:
575
+
576
+ 1. **Messaging (PUB- channels)** - Real-time chat/messaging between users
577
+ 2. **Notifications (MES- channels)** - Persistent notifications stored in database
578
+
579
+ Both features integrate seamlessly with `HTTPManagerStateService` and automatically manage channel prefixes.
580
+
581
+ ### Messaging Feature (PUB- Channels)
582
+
583
+ **Purpose:** Real-time messaging/chat functionality for communication between users.
584
+
585
+ **Characteristics:**
586
+
587
+ - Messages are broadcast in real-time to subscribed users
588
+ - Messages are stored in-memory only (not persisted to database)
589
+ - Uses `PUB-` prefix (automatically added)
590
+ - Ideal for chat applications, live collaboration, etc.
591
+
592
+ #### Messaging Observables
593
+
594
+ | Observable | Type | Description |
595
+ | :--- | :--- | :--- |
596
+ | `channels$` | `Observable<string[]>` | List of all available channels |
597
+ | `communicationMessages$` | `Observable<any[]>` | All received messages |
598
+ | `latestCommunicationMessages$` | `Observable<any>` | Most recent message received |
599
+ | `connectionStatus$` | `Observable<boolean>` | WebSocket connection status |
600
+ | `user$` | `Observable<WSUser>` | Current user information |
601
+
602
+ #### Messaging Methods
603
+
604
+ ```typescript
605
+ // Create a new messaging channel
606
+ stateService.createChannel('general-chat'); // Creates PUB-general-chat
607
+
608
+ // Subscribe to a channel to receive messages
609
+ stateService.subscribeToChannel('general-chat'); // Subscribes to PUB-general-chat
610
+
611
+ // Unsubscribe from a channel
612
+ stateService.unsubscribeFromChannel('general-chat');
613
+
614
+ // Get all available channels
615
+ stateService.getAllChannels();
616
+
617
+ // Send a message to specific channels
618
+ stateService.wsMessaging(
619
+ ChannelMessage.adapt({
620
+ sessionId: currentUser,
621
+ content: { message: 'Hello everyone!' }
622
+ }),
623
+ ['general-chat', 'team-updates'] // Channels (PUB- prefix added automatically)
624
+ );
625
+ ```
626
+
627
+ #### Demo Component: `WsMessagingComponent`
628
+
629
+ The library includes a demo component showcasing messaging functionality:
630
+
631
+ ```html
632
+ <app-ws-messaging
633
+ [server]="'http://localhost:8080'"
634
+ [wsServer]="'ws://localhost:8080'"
635
+ [jwtToken]="'your-jwt-token'"
636
+ [user]="{ ldap: 'jdoe', name: 'John Doe', email: 'jdoe@example.com' }">
637
+ </app-ws-messaging>
638
+ ```
639
+
640
+ **Features demonstrated:**
641
+
642
+ - Create public channels
643
+ - Subscribe/unsubscribe to channels
644
+ - Send messages to multiple channels
645
+ - View real-time message stream
646
+ - Toast notifications for incoming messages
647
+
648
+ ---
649
+
650
+ ### Notifications Feature (MES- Channels)
651
+
652
+ **Purpose:** Persistent notifications that are stored in the database and can be retrieved with date filters.
653
+
654
+ **Characteristics:**
655
+
656
+ - Notifications are persisted to the server database
657
+ - Supports date-range queries (startEpoch, endEpoch)
658
+ - Uses `MES-` prefix (automatically added)
659
+ - Retrieves historical notifications on subscription
660
+ - Ideal for announcements, alerts, audit logs, etc.
661
+
662
+ #### Notification Observables
663
+
664
+ | Observable | Type | Description |
665
+ | :--- | :--- | :--- |
666
+ | `notificationChannels$` | `Observable<string[]>` | In-memory notification channels from server |
667
+ | `todaysNotificationChannels$` | `Observable<string[]>` | Channels with notifications posted today (from DB) |
668
+ | `notificationMessages$` | `Observable<any[]>` | All notification messages |
669
+ | `latestNotification$` | `Observable<any>` | Most recent notification received |
670
+
671
+ #### Notification Methods
672
+
673
+ ```typescript
674
+ // Create a notification channel
675
+ stateService.createNotificationChannel('alerts'); // Creates MES-alerts
676
+
677
+ // Get all notification channels (in-memory)
678
+ stateService.getNotificationChannels();
679
+
680
+ // Get today's notification channels (from database)
681
+ stateService.getTodaysNotificationChannels();
682
+
683
+ // Subscribe to notifications with optional date filter
684
+ stateService.subscribeToNotificationChannel('alerts', {
685
+ startEpoch: Math.floor(Date.now() / 1000) - 86400, // Last 24 hours
686
+ endEpoch: Math.floor(Date.now() / 1000)
687
+ });
688
+
689
+ // Unsubscribe from notifications
690
+ stateService.unsubscribeFromNotificationChannel('alerts');
691
+
692
+ // Send a notification (persisted to database)
693
+ stateService.sendNotification('alerts', {
694
+ title: 'System Alert',
695
+ message: 'Scheduled maintenance at midnight',
696
+ priority: 'high'
697
+ });
698
+ ```
699
+
700
+ #### Notification Message Structure
701
+
702
+ ```typescript
703
+ interface NotificationMessage {
704
+ id: number;
705
+ channel: string; // e.g., 'MES-alerts'
706
+ created: number; // epoch seconds
707
+ user_name: string; // sender's name
708
+ sessionId: any; // sender's session info
709
+ content: any; // notification payload
710
+ }
711
+ ```
712
+
713
+ #### Demo Component: `WsNotificationsComponent`
714
+
715
+ The library includes a demo component showcasing notification functionality:
716
+
717
+ ```html
718
+ <app-ws-notifications
719
+ [server]="'http://localhost:8080'"
720
+ [wsServer]="'ws://localhost:8080'"
721
+ [jwtToken]="'your-jwt-token'"
722
+ [user]="{ ldap: 'jdoe', name: 'John Doe', email: 'jdoe@example.com' }">
723
+ </app-ws-notifications>
724
+ ```
725
+
726
+ **Features demonstrated:**
727
+
728
+ - Create notification channels
729
+ - View today's notification channels (from database)
730
+ - Subscribe with date range filters
731
+ - Connect/disconnect from channels
732
+ - Send notifications (persisted)
733
+ - View historical notifications in a table
734
+
735
+ ---
736
+
737
+ ### Creating a Custom State Service with Messaging & Notifications
738
+
739
+ Here's a complete example of a state service that utilizes all real-time features:
740
+
741
+ ```typescript
742
+ import { Injectable } from '@angular/core';
743
+ import { HTTPManagerStateService, ChannelType, createChannelName } from 'http-request-manager';
744
+ import { ApiRequest, DataType, DatabaseStorage } from 'http-request-manager';
745
+
746
+ export interface User {
747
+ id: number;
748
+ name: string;
749
+ email: string;
750
+ }
751
+
752
+ @Injectable({
753
+ providedIn: 'root'
754
+ })
755
+ export class UserStateService extends HTTPManagerStateService<User> {
756
+
757
+ constructor() {
758
+ super(
759
+ ApiRequest.adapt({
760
+ server: 'http://localhost:8080',
761
+ path: ['api', 'users'],
762
+ adapter: (data: any) => data as User,
763
+ ws: {
764
+ id: 'USERS123', // Base name - automatically becomes SYS-USERS123
765
+ wsServer: 'ws://localhost:8080',
766
+ jwtToken: '',
767
+ retry: { times: 3, delay: 5 }
768
+ }
769
+ }),
770
+ DataType.ARRAY,
771
+ DatabaseStorage.adapt({ table: 'users-cache', expiresIn: '1d' })
772
+ );
773
+ }
774
+
775
+ // Initialize connection with user info
776
+ initializeConnection(wsServer: string, jwtToken: string, user: any) {
777
+ this.setApiRequestOptions(
778
+ ApiRequest.adapt({
779
+ ...this.ApiRequestOptions,
780
+ ws: {
781
+ ...this.ApiRequestOptions.ws,
782
+ wsServer,
783
+ jwtToken,
784
+ user
785
+ }
786
+ })
787
+ );
788
+ }
789
+
790
+ // === MESSAGING (PUB- channels) ===
791
+
792
+ createChatRoom(roomName: string) {
793
+ this.createChannel(roomName); // Creates PUB-{roomName}
794
+ }
795
+
796
+ joinChatRoom(roomName: string) {
797
+ this.subscribeToChannel(roomName);
798
+ }
799
+
800
+ leaveChatRoom(roomName: string) {
801
+ this.unsubscribeFromChannel(roomName);
802
+ }
803
+
804
+ sendChatMessage(content: string, rooms: string[]) {
805
+ this.wsMessaging(
806
+ { content: { message: content } },
807
+ rooms
808
+ );
809
+ }
810
+
811
+ // === NOTIFICATIONS (MES- channels) ===
812
+
813
+ createNotificationStream(streamName: string) {
814
+ this.createNotificationChannel(streamName); // Creates MES-{streamName}
815
+ }
816
+
817
+ subscribeToAlerts(streamName: string, lastHours: number = 24) {
818
+ const now = Math.floor(Date.now() / 1000);
819
+ const startEpoch = now - (lastHours * 3600);
820
+
821
+ this.subscribeToNotificationChannel(streamName, {
822
+ startEpoch,
823
+ endEpoch: now
824
+ });
825
+ }
826
+
827
+ sendAlert(streamName: string, alert: { title: string; message: string; priority: string }) {
828
+ this.sendNotification(streamName, alert);
829
+ }
830
+ }
831
+ ```
832
+
833
+ **Usage in Component:**
834
+
835
+ ```typescript
836
+ @Component({
837
+ selector: 'app-dashboard',
838
+ template: `
839
+ <div *ngIf="connectionStatus$ | async">
840
+ <!-- Chat Messages -->
841
+ <div *ngFor="let msg of chatMessages$ | async">
842
+ {{ msg.content.message }}
843
+ </div>
844
+
845
+ <!-- Notifications -->
846
+ <div *ngFor="let notification of notifications$ | async">
847
+ {{ notification.content.title }}: {{ notification.content.message }}
848
+ </div>
849
+ </div>
850
+ `
851
+ })
852
+ export class DashboardComponent implements OnInit {
853
+ userState = inject(UserStateService);
854
+
855
+ connectionStatus$ = this.userState.connectionStatus$;
856
+ chatMessages$ = this.userState.communicationMessages$;
857
+ notifications$ = this.userState.notificationMessages$;
858
+
859
+ ngOnInit() {
860
+ // Initialize WebSocket connection
861
+ this.userState.initializeConnection(
862
+ 'ws://localhost:8080',
863
+ 'jwt-token',
864
+ { ldap: 'jdoe', name: 'John Doe' }
865
+ );
866
+
867
+ // Join a chat room
868
+ this.userState.joinChatRoom('general');
869
+
870
+ // Subscribe to alerts from last 24 hours
871
+ this.userState.subscribeToAlerts('system-alerts', 24);
872
+ }
873
+
874
+ sendMessage(text: string) {
875
+ this.userState.sendChatMessage(text, ['general']);
876
+ }
877
+
878
+ sendAlert() {
879
+ this.userState.sendAlert('system-alerts', {
880
+ title: 'Update Available',
881
+ message: 'A new version is available',
882
+ priority: 'medium'
883
+ });
884
+ }
885
+ }
886
+ ```
887
+
888
+ ---
889
+
546
890
  ### 8. Database Manager Service (`DatabaseManagerService`)
547
891
 
548
892
  **Path:** `database-manager-service/database.manager.service.ts`