http-request-manager 18.7.2 → 18.7.4

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`
@@ -829,6 +829,8 @@ class WebsocketService {
829
829
  }
830
830
  }
831
831
  this.isSubscribed = false;
832
+ // Clear tracked subscriptions for new connection
833
+ this.subscribedChannels.next(new Set());
832
834
  const sessionId = this.getSessionId();
833
835
  const URL = (jwtToken) ? `${options.wsServer}?token=${jwtToken}&sessionId=${sessionId}` : `${options.wsServer}?sessionId=${sessionId}`;
834
836
  this.socket = new WebSocket(URL);
@@ -2998,6 +3000,27 @@ class ChannelMessage {
2998
3000
  }
2999
3001
 
3000
3002
  const API_OPTS = new InjectionToken('API_OPTS');
3003
+ /**
3004
+ * Channel type enum for different communication purposes
3005
+ * - STATE: Private channels for state synchronization
3006
+ * - MESSAGE: Messaging/communication channels
3007
+ * - NOTIFICATION: Notification/broadcast channels
3008
+ */
3009
+ var ChannelType;
3010
+ (function (ChannelType) {
3011
+ ChannelType["STATE"] = "SYS";
3012
+ ChannelType["MESSAGE"] = "MES";
3013
+ ChannelType["NOTIFICATION"] = "PUB";
3014
+ })(ChannelType || (ChannelType = {}));
3015
+ /**
3016
+ * Utility function to create prefixed channel name
3017
+ * @param channelType - The type of channel
3018
+ * @param channelName - The base channel name
3019
+ * @returns Prefixed channel name (e.g., 'SYS-USERS123')
3020
+ */
3021
+ function createChannelName(channelType, channelName) {
3022
+ return `${channelType}-${channelName}`;
3023
+ }
3001
3024
  const defaultState = {
3002
3025
  data: [],
3003
3026
  dataObject: null,
@@ -3499,6 +3522,36 @@ class HTTPManagerStateService extends ComponentStore {
3499
3522
  this.initDBStorage();
3500
3523
  }
3501
3524
  }
3525
+ /**
3526
+ * Add appropriate prefix to a channel name if not already present
3527
+ */
3528
+ prefixChannel(channel, type) {
3529
+ const prefix = `${type}-`;
3530
+ if (channel.startsWith(prefix)) {
3531
+ return channel;
3532
+ }
3533
+ // Remove any other known prefix before adding the correct one
3534
+ const cleanChannel = this.stripChannelPrefix(channel);
3535
+ return `${type}-${cleanChannel}`;
3536
+ }
3537
+ /**
3538
+ * Remove any known prefix from a channel name
3539
+ */
3540
+ stripChannelPrefix(channel) {
3541
+ for (const type of Object.values(ChannelType)) {
3542
+ const prefix = `${type}-`;
3543
+ if (channel.startsWith(prefix)) {
3544
+ return channel.slice(prefix.length);
3545
+ }
3546
+ }
3547
+ return channel;
3548
+ }
3549
+ /**
3550
+ * Get the base channel name without prefix (for display/user reference)
3551
+ */
3552
+ getBaseChannelName(channel) {
3553
+ return this.stripChannelPrefix(channel);
3554
+ }
3502
3555
  setApiRequestOptions(apiOptions, dataType, database) {
3503
3556
  this.apiOptions = ApiRequest.adapt(apiOptions);
3504
3557
  this.dataType = (dataType) ? dataType : DataType.ARRAY;
@@ -3508,6 +3561,10 @@ class HTTPManagerStateService extends ComponentStore {
3508
3561
  this.databaseOptions = (this.hasDatabase) ? DatabaseStorage.adapt(database) : undefined;
3509
3562
  }
3510
3563
  if (this.apiOptions.ws && this.apiOptions.ws.id !== '') {
3564
+ // Auto-prefix channel ID for private state manager channels
3565
+ // This ensures state manager channels are separate from user-defined channels
3566
+ this.apiOptions.ws.id = this.prefixChannel(this.apiOptions.ws.id, ChannelType.STATE);
3567
+ console.log(`🔒 Private state channel: ${this.apiOptions.ws.id}`);
3511
3568
  // Update WebSocket retry settings when options change
3512
3569
  if (this.apiOptions.ws?.retry) {
3513
3570
  this.maxRetries = this.apiOptions.ws.retry.times || 3;
@@ -3657,12 +3714,19 @@ class HTTPManagerStateService extends ComponentStore {
3657
3714
  this.httpManagerService.sendMessageInChannel(wsServer, { method, path, user: this.apiOptions.ws.user });
3658
3715
  }
3659
3716
  }
3717
+ /**
3718
+ * Send a message to channel(s)
3719
+ * @param message - The message content
3720
+ * @param channels - Optional array of channel names (passed as-is, caller should include prefix)
3721
+ * Use 'allChannels' to broadcast to all
3722
+ */
3660
3723
  wsMessaging(message, channels) {
3661
3724
  const user = this.user.value;
3662
3725
  const messageInfo = ChannelMessage.adapt({ ...message, fromUser: user });
3663
3726
  console.log('📤 wsMessaging called with channels:', channels);
3664
3727
  if (this.wsConnection && this.apiOptions.ws) {
3665
3728
  // If specific channels provided, send to each channel
3729
+ // Channels are passed as-is - caller is responsible for including the correct prefix
3666
3730
  if (channels && channels.length > 0) {
3667
3731
  console.log(`📤 Sending to ${channels.length} channel(s):`, channels);
3668
3732
  channels.forEach(channel => {
@@ -3675,17 +3739,46 @@ class HTTPManagerStateService extends ComponentStore {
3675
3739
  });
3676
3740
  }
3677
3741
  else {
3678
- // Fallback to the primary WS channel
3742
+ // Fallback to the primary WS channel (already prefixed with SYS-)
3679
3743
  const wsChannel = this.apiOptions.ws.id;
3680
- console.log(`📤 Sending to fallback channel:`, wsChannel);
3744
+ console.log(`📤 Sending to state channel:`, wsChannel);
3681
3745
  this.httpManagerService.sendChannelMessage(wsChannel, messageInfo);
3682
3746
  }
3683
3747
  }
3684
3748
  }
3749
+ /**
3750
+ * Subscribe to a messaging channel
3751
+ * @param channel - Base channel name (MES- prefix added automatically)
3752
+ */
3753
+ subscribeToMessageChannel(channel) {
3754
+ if (this.wsConnection) {
3755
+ const prefixedChannel = this.prefixChannel(channel, ChannelType.MESSAGE);
3756
+ this.httpManagerService.subscribeToChannel(prefixedChannel);
3757
+ console.log(`💬 Subscribed to message channel: ${prefixedChannel}`);
3758
+ }
3759
+ else {
3760
+ console.warn('Cannot subscribe to message channel: WebSocket not connected.');
3761
+ }
3762
+ }
3763
+ /**
3764
+ * Unsubscribe from a messaging channel
3765
+ * @param channel - Base channel name (MES- prefix added automatically)
3766
+ */
3767
+ unsubscribeFromMessageChannel(channel) {
3768
+ if (this.wsConnection) {
3769
+ const prefixedChannel = this.prefixChannel(channel, ChannelType.MESSAGE);
3770
+ this.httpManagerService.unsubscribeFromChannel(prefixedChannel);
3771
+ console.log(`💬 Unsubscribed from message channel: ${prefixedChannel}`);
3772
+ }
3773
+ else {
3774
+ console.warn('Cannot unsubscribe from message channel: WebSocket not connected.');
3775
+ }
3776
+ }
3685
3777
  // --------------------------------------------------------------------------------------------------
3686
- // CHANNEL MANAGEMENT
3778
+ // CHANNEL MANAGEMENT (Raw channels - no automatic prefix)
3687
3779
  /**
3688
- * Subscribe to a single channel
3780
+ * Subscribe to a single channel (no automatic prefix)
3781
+ * Use subscribeToMessageChannel() for MES- prefixed channels
3689
3782
  */
3690
3783
  subscribeToChannel(channel) {
3691
3784
  if (this.wsConnection) {
@@ -3774,13 +3867,16 @@ class HTTPManagerStateService extends ComponentStore {
3774
3867
  }
3775
3868
  }
3776
3869
  // --------------------------------------------------------------------------------------------------
3777
- // NOTIFICATION CHANNELS (MES- prefix)
3870
+ // NOTIFICATION CHANNELS (PUB- prefix - managed automatically)
3778
3871
  /**
3779
3872
  * Create a notification channel on the server
3873
+ * @param channel - Base channel name (PUB- prefix added automatically)
3780
3874
  */
3781
3875
  createNotificationChannel(channel) {
3782
3876
  if (this.wsConnection) {
3783
- this.httpManagerService.createNotificationChannel(channel);
3877
+ const prefixedChannel = this.prefixChannel(channel, ChannelType.NOTIFICATION);
3878
+ this.httpManagerService.createNotificationChannel(prefixedChannel);
3879
+ console.log(`📢 Creating notification channel: ${prefixedChannel}`);
3784
3880
  }
3785
3881
  else {
3786
3882
  console.warn('Cannot create notification channel: WebSocket not connected.');
@@ -3811,10 +3907,13 @@ class HTTPManagerStateService extends ComponentStore {
3811
3907
  }
3812
3908
  /**
3813
3909
  * Subscribe to a notification channel with optional date filters
3910
+ * @param channel - Base channel name (PUB- prefix added automatically)
3814
3911
  */
3815
3912
  subscribeToNotificationChannel(channel, options, user) {
3816
3913
  if (this.wsConnection) {
3817
- this.httpManagerService.subscribeToNotificationChannel(channel, options, user);
3914
+ const prefixedChannel = this.prefixChannel(channel, ChannelType.NOTIFICATION);
3915
+ this.httpManagerService.subscribeToNotificationChannel(prefixedChannel, options, user);
3916
+ console.log(`📢 Subscribing to notification channel: ${prefixedChannel}`);
3818
3917
  }
3819
3918
  else {
3820
3919
  console.warn('Cannot subscribe to notification channel: WebSocket not connected.');
@@ -3822,10 +3921,13 @@ class HTTPManagerStateService extends ComponentStore {
3822
3921
  }
3823
3922
  /**
3824
3923
  * Unsubscribe from a notification channel
3924
+ * @param channel - Base channel name (PUB- prefix added automatically)
3825
3925
  */
3826
3926
  unsubscribeFromNotificationChannel(channel) {
3827
3927
  if (this.wsConnection) {
3828
- this.httpManagerService.unsubscribeFromNotificationChannel(channel);
3928
+ const prefixedChannel = this.prefixChannel(channel, ChannelType.NOTIFICATION);
3929
+ this.httpManagerService.unsubscribeFromNotificationChannel(prefixedChannel);
3930
+ console.log(`📢 Unsubscribing from notification channel: ${prefixedChannel}`);
3829
3931
  }
3830
3932
  else {
3831
3933
  console.warn('Cannot unsubscribe from notification channel: WebSocket not connected.');
@@ -3833,10 +3935,13 @@ class HTTPManagerStateService extends ComponentStore {
3833
3935
  }
3834
3936
  /**
3835
3937
  * Send a notification to a channel
3938
+ * @param channel - Base channel name (PUB- prefix added automatically)
3836
3939
  */
3837
3940
  sendNotification(channel, content) {
3838
3941
  if (this.wsConnection) {
3839
- this.httpManagerService.sendNotification(channel, content);
3942
+ const prefixedChannel = this.prefixChannel(channel, ChannelType.NOTIFICATION);
3943
+ this.httpManagerService.sendNotification(prefixedChannel, content);
3944
+ console.log(`📢 Sending notification to channel: ${prefixedChannel}`);
3840
3945
  }
3841
3946
  else {
3842
3947
  console.warn('Cannot send notification: WebSocket not connected.');
@@ -4530,7 +4635,7 @@ class StateServiceDemo extends HTTPManagerStateService {
4530
4635
  }),
4531
4636
  adapter: OIDCClient.adapt,
4532
4637
  ws: {
4533
- id: 'SYS-USERS123',
4638
+ id: 'USERS123',
4534
4639
  wsServer,
4535
4640
  jwtToken,
4536
4641
  user,
@@ -6994,5 +7099,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
6994
7099
  * Generated bundle index. Do not edit.
6995
7100
  */
6996
7101
 
6997
- export { ApiRequest, AppService, AsymmetricalEncryptionService, CONFIG_SETTINGS_TOKEN, ChannelInfo, CommunicationType, ConfigHTTPOptions, ConfigOptions, DataType, DatabaseDataDemoComponent, DatabaseManagerService, DatabaseStorage, DbService, ErrorDisplaySettings, GlobalStoreOptions, HTTPManagerService, HTTPManagerSignalsService, HTTPManagerStateService, HeadersService, HttpRequestManagerModule, HttpRequestServicesDemoComponent, LocalStorageDemoComponent, LocalStorageManagerService, LocalStorageOptions, LocalStorageSignalsManagerService, PathQueryService, Random, RandomNumber, RandomNumbers, RandomNumbersUnique, RandomSignature, RandomStr, RequestErrorInterceptor, RequestHeadersInterceptor, RequestManagerDemoComponent, RequestManagerStateDemoComponent, RequestOptions, RequestService, RequestSignalsService, RetryOptions, SettingOptions, StateStorageOptions, StorageData, StorageOption, StorageType, StoreStateManagerService, SymmetricalEncryptionService, TableSchemaDef, UUID, UUID_STR, UtilsService, WSOptions, WSUser, WebsocketService, WithCredentialsInterceptor, countdown, delayedRetry, requestPolling, requestStreaming };
7102
+ export { ApiRequest, AppService, AsymmetricalEncryptionService, CONFIG_SETTINGS_TOKEN, ChannelInfo, ChannelType, CommunicationType, ConfigHTTPOptions, ConfigOptions, DataType, DatabaseDataDemoComponent, DatabaseManagerService, DatabaseStorage, DbService, ErrorDisplaySettings, GlobalStoreOptions, HTTPManagerService, HTTPManagerSignalsService, HTTPManagerStateService, HeadersService, HttpRequestManagerModule, HttpRequestServicesDemoComponent, LocalStorageDemoComponent, LocalStorageManagerService, LocalStorageOptions, LocalStorageSignalsManagerService, PathQueryService, Random, RandomNumber, RandomNumbers, RandomNumbersUnique, RandomSignature, RandomStr, RequestErrorInterceptor, RequestHeadersInterceptor, RequestManagerDemoComponent, RequestManagerStateDemoComponent, RequestOptions, RequestService, RequestSignalsService, RetryOptions, SettingOptions, StateStorageOptions, StorageData, StorageOption, StorageType, StoreStateManagerService, SymmetricalEncryptionService, TableSchemaDef, UUID, UUID_STR, UtilsService, WSOptions, WSUser, WebsocketService, WithCredentialsInterceptor, countdown, createChannelName, delayedRetry, requestPolling, requestStreaming };
6998
7103
  //# sourceMappingURL=http-request-manager.mjs.map