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.
|
@@ -789,7 +789,9 @@ class WebsocketService {
|
|
|
789
789
|
})();
|
|
790
790
|
}
|
|
791
791
|
sendSubscribe(channelName, user) {
|
|
792
|
-
if (
|
|
792
|
+
// Check if already subscribed to THIS specific channel (not just any channel)
|
|
793
|
+
const alreadySubscribed = this.subscribedChannels.value.has(channelName);
|
|
794
|
+
if (this.socket?.readyState === WebSocket.OPEN && !alreadySubscribed) {
|
|
793
795
|
const message = {
|
|
794
796
|
type: 'subscribe',
|
|
795
797
|
subscribedChannel: channelName,
|
|
@@ -799,11 +801,15 @@ class WebsocketService {
|
|
|
799
801
|
}
|
|
800
802
|
};
|
|
801
803
|
this.socket.send(JSON.stringify(message));
|
|
802
|
-
|
|
804
|
+
// Track this channel as subscribed
|
|
805
|
+
const current = new Set(this.subscribedChannels.value);
|
|
806
|
+
current.add(channelName);
|
|
807
|
+
this.subscribedChannels.next(current);
|
|
808
|
+
this.isSubscribed = true; // Keep for backward compatibility
|
|
803
809
|
console.log(`[CLIENT] Sent initial subscription to: ${channelName}`);
|
|
804
810
|
}
|
|
805
811
|
else {
|
|
806
|
-
console.warn(`[CLIENT] Subscription prevented. Open: ${this.socket?.readyState === WebSocket.OPEN},
|
|
812
|
+
console.warn(`[CLIENT] Subscription prevented. Open: ${this.socket?.readyState === WebSocket.OPEN}, Already subscribed to ${channelName}: ${alreadySubscribed}`);
|
|
807
813
|
}
|
|
808
814
|
}
|
|
809
815
|
connect(options, jwtToken) {
|
|
@@ -823,6 +829,8 @@ class WebsocketService {
|
|
|
823
829
|
}
|
|
824
830
|
}
|
|
825
831
|
this.isSubscribed = false;
|
|
832
|
+
// Clear tracked subscriptions for new connection
|
|
833
|
+
this.subscribedChannels.next(new Set());
|
|
826
834
|
const sessionId = this.getSessionId();
|
|
827
835
|
const URL = (jwtToken) ? `${options.wsServer}?token=${jwtToken}&sessionId=${sessionId}` : `${options.wsServer}?sessionId=${sessionId}`;
|
|
828
836
|
this.socket = new WebSocket(URL);
|
|
@@ -2992,6 +3000,27 @@ class ChannelMessage {
|
|
|
2992
3000
|
}
|
|
2993
3001
|
|
|
2994
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
|
+
}
|
|
2995
3024
|
const defaultState = {
|
|
2996
3025
|
data: [],
|
|
2997
3026
|
dataObject: null,
|
|
@@ -3105,11 +3134,16 @@ class HTTPManagerStateService extends ComponentStore {
|
|
|
3105
3134
|
// Compare sender's session ID with current user's ID
|
|
3106
3135
|
// message.data.sessionId is an object with 'id' property from server
|
|
3107
3136
|
const stateManagerSenderId = message.data.sessionId?.id || message.data.sessionId;
|
|
3137
|
+
console.log('🔍 State Manager: Sender ID:', stateManagerSenderId, 'Current User ID:', this.user.value?.id);
|
|
3108
3138
|
if (stateManagerSenderId !== this.user.value?.id) {
|
|
3109
3139
|
console.log('💬 State Manager Message:', message.data);
|
|
3140
|
+
console.log('📥 Fetching record with path:', message.data.content.path, 'method:', message.data.content.method);
|
|
3110
3141
|
this.userAction.next(message.data);
|
|
3111
3142
|
this.fetchRecord(RequestOptions.adapt({ path: message.data.content.path }), message.data.content.method);
|
|
3112
3143
|
}
|
|
3144
|
+
else {
|
|
3145
|
+
console.log('⏭️ Skipping own message');
|
|
3146
|
+
}
|
|
3113
3147
|
break;
|
|
3114
3148
|
case 'channelMessage':
|
|
3115
3149
|
// Handle channel-based messages (from sendChannelMessage)
|
|
@@ -3339,19 +3373,27 @@ class HTTPManagerStateService extends ComponentStore {
|
|
|
3339
3373
|
return fetchFromAPI();
|
|
3340
3374
|
})));
|
|
3341
3375
|
// FETCH RECORD
|
|
3342
|
-
this.fetchRecord = (options, method) => this.effect(() => of(RequestOptions.adapt(options)).pipe(switchMap((options) => {
|
|
3376
|
+
this.fetchRecord = (options, method) => this.effect(() => of(RequestOptions.adapt(options)).pipe(tap(() => console.log('🔄 fetchRecord effect triggered with path:', options?.path, 'method:', method)), switchMap((options) => {
|
|
3343
3377
|
this.streamedResponse = [];
|
|
3344
3378
|
const requestOptions = this.updateRequestOptions(options?.headers);
|
|
3379
|
+
console.log('🌐 Making GET request to path:', options?.path);
|
|
3345
3380
|
return this.httpManagerService.getRequest(requestOptions, options?.path)
|
|
3346
3381
|
.pipe(tap((data) => {
|
|
3382
|
+
console.log('📦 fetchRecord received data:', data);
|
|
3347
3383
|
data = (!data) ? (this.dataType === DataType.ARRAY) ? [] : {} : data;
|
|
3348
3384
|
const id = options.path?.length ? options.path[options.path.length - 1] : null;
|
|
3349
|
-
if (method === 'DELETE')
|
|
3385
|
+
if (method === 'DELETE') {
|
|
3386
|
+
console.log('🗑️ Deleting record with id:', id);
|
|
3350
3387
|
this.deleteData$({ id });
|
|
3351
|
-
|
|
3388
|
+
}
|
|
3389
|
+
if (method === 'UPDATE') {
|
|
3390
|
+
console.log('✏️ Updating record:', data);
|
|
3352
3391
|
this.updateData$(data);
|
|
3353
|
-
|
|
3392
|
+
}
|
|
3393
|
+
if (method === 'CREATE') {
|
|
3394
|
+
console.log('➕ Adding record:', data);
|
|
3354
3395
|
this.addData$(data);
|
|
3396
|
+
}
|
|
3355
3397
|
}), concatMap((data) => {
|
|
3356
3398
|
if (this.hasDatabase && this.databaseOptions?.table) {
|
|
3357
3399
|
const id = options.path?.length ? options.path[options.path.length - 1] : null;
|
|
@@ -3480,6 +3522,36 @@ class HTTPManagerStateService extends ComponentStore {
|
|
|
3480
3522
|
this.initDBStorage();
|
|
3481
3523
|
}
|
|
3482
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
|
+
}
|
|
3483
3555
|
setApiRequestOptions(apiOptions, dataType, database) {
|
|
3484
3556
|
this.apiOptions = ApiRequest.adapt(apiOptions);
|
|
3485
3557
|
this.dataType = (dataType) ? dataType : DataType.ARRAY;
|
|
@@ -3489,6 +3561,10 @@ class HTTPManagerStateService extends ComponentStore {
|
|
|
3489
3561
|
this.databaseOptions = (this.hasDatabase) ? DatabaseStorage.adapt(database) : undefined;
|
|
3490
3562
|
}
|
|
3491
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}`);
|
|
3492
3568
|
// Update WebSocket retry settings when options change
|
|
3493
3569
|
if (this.apiOptions.ws?.retry) {
|
|
3494
3570
|
this.maxRetries = this.apiOptions.ws.retry.times || 3;
|
|
@@ -3638,6 +3714,12 @@ class HTTPManagerStateService extends ComponentStore {
|
|
|
3638
3714
|
this.httpManagerService.sendMessageInChannel(wsServer, { method, path, user: this.apiOptions.ws.user });
|
|
3639
3715
|
}
|
|
3640
3716
|
}
|
|
3717
|
+
/**
|
|
3718
|
+
* Send a message to channel(s)
|
|
3719
|
+
* @param message - The message content
|
|
3720
|
+
* @param channels - Optional array of channel names (MES- prefix added automatically)
|
|
3721
|
+
* Use 'allChannels' to broadcast to all
|
|
3722
|
+
*/
|
|
3641
3723
|
wsMessaging(message, channels) {
|
|
3642
3724
|
const user = this.user.value;
|
|
3643
3725
|
const messageInfo = ChannelMessage.adapt({ ...message, fromUser: user });
|
|
@@ -3645,8 +3727,9 @@ class HTTPManagerStateService extends ComponentStore {
|
|
|
3645
3727
|
if (this.wsConnection && this.apiOptions.ws) {
|
|
3646
3728
|
// If specific channels provided, send to each channel
|
|
3647
3729
|
if (channels && channels.length > 0) {
|
|
3648
|
-
|
|
3649
|
-
|
|
3730
|
+
const prefixedChannels = channels.map(ch => ch === 'allChannels' ? ch : this.prefixChannel(ch, ChannelType.MESSAGE));
|
|
3731
|
+
console.log(`📤 Sending to ${prefixedChannels.length} channel(s):`, prefixedChannels);
|
|
3732
|
+
prefixedChannels.forEach(channel => {
|
|
3650
3733
|
if (channel === 'allChannels') {
|
|
3651
3734
|
this.httpManagerService.sendBroadcast(messageInfo);
|
|
3652
3735
|
}
|
|
@@ -3656,17 +3739,46 @@ class HTTPManagerStateService extends ComponentStore {
|
|
|
3656
3739
|
});
|
|
3657
3740
|
}
|
|
3658
3741
|
else {
|
|
3659
|
-
// Fallback to the primary WS channel
|
|
3742
|
+
// Fallback to the primary WS channel (already prefixed with SYS-)
|
|
3660
3743
|
const wsChannel = this.apiOptions.ws.id;
|
|
3661
|
-
console.log(`📤 Sending to
|
|
3744
|
+
console.log(`📤 Sending to state channel:`, wsChannel);
|
|
3662
3745
|
this.httpManagerService.sendChannelMessage(wsChannel, messageInfo);
|
|
3663
3746
|
}
|
|
3664
3747
|
}
|
|
3665
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
|
+
}
|
|
3666
3777
|
// --------------------------------------------------------------------------------------------------
|
|
3667
|
-
// CHANNEL MANAGEMENT
|
|
3778
|
+
// CHANNEL MANAGEMENT (Raw channels - no automatic prefix)
|
|
3668
3779
|
/**
|
|
3669
|
-
* Subscribe to a single channel
|
|
3780
|
+
* Subscribe to a single channel (no automatic prefix)
|
|
3781
|
+
* Use subscribeToMessageChannel() for MES- prefixed channels
|
|
3670
3782
|
*/
|
|
3671
3783
|
subscribeToChannel(channel) {
|
|
3672
3784
|
if (this.wsConnection) {
|
|
@@ -3755,13 +3867,16 @@ class HTTPManagerStateService extends ComponentStore {
|
|
|
3755
3867
|
}
|
|
3756
3868
|
}
|
|
3757
3869
|
// --------------------------------------------------------------------------------------------------
|
|
3758
|
-
// NOTIFICATION CHANNELS (
|
|
3870
|
+
// NOTIFICATION CHANNELS (PUB- prefix - managed automatically)
|
|
3759
3871
|
/**
|
|
3760
3872
|
* Create a notification channel on the server
|
|
3873
|
+
* @param channel - Base channel name (PUB- prefix added automatically)
|
|
3761
3874
|
*/
|
|
3762
3875
|
createNotificationChannel(channel) {
|
|
3763
3876
|
if (this.wsConnection) {
|
|
3764
|
-
this.
|
|
3877
|
+
const prefixedChannel = this.prefixChannel(channel, ChannelType.NOTIFICATION);
|
|
3878
|
+
this.httpManagerService.createNotificationChannel(prefixedChannel);
|
|
3879
|
+
console.log(`📢 Creating notification channel: ${prefixedChannel}`);
|
|
3765
3880
|
}
|
|
3766
3881
|
else {
|
|
3767
3882
|
console.warn('Cannot create notification channel: WebSocket not connected.');
|
|
@@ -3792,10 +3907,13 @@ class HTTPManagerStateService extends ComponentStore {
|
|
|
3792
3907
|
}
|
|
3793
3908
|
/**
|
|
3794
3909
|
* Subscribe to a notification channel with optional date filters
|
|
3910
|
+
* @param channel - Base channel name (PUB- prefix added automatically)
|
|
3795
3911
|
*/
|
|
3796
3912
|
subscribeToNotificationChannel(channel, options, user) {
|
|
3797
3913
|
if (this.wsConnection) {
|
|
3798
|
-
this.
|
|
3914
|
+
const prefixedChannel = this.prefixChannel(channel, ChannelType.NOTIFICATION);
|
|
3915
|
+
this.httpManagerService.subscribeToNotificationChannel(prefixedChannel, options, user);
|
|
3916
|
+
console.log(`📢 Subscribing to notification channel: ${prefixedChannel}`);
|
|
3799
3917
|
}
|
|
3800
3918
|
else {
|
|
3801
3919
|
console.warn('Cannot subscribe to notification channel: WebSocket not connected.');
|
|
@@ -3803,10 +3921,13 @@ class HTTPManagerStateService extends ComponentStore {
|
|
|
3803
3921
|
}
|
|
3804
3922
|
/**
|
|
3805
3923
|
* Unsubscribe from a notification channel
|
|
3924
|
+
* @param channel - Base channel name (PUB- prefix added automatically)
|
|
3806
3925
|
*/
|
|
3807
3926
|
unsubscribeFromNotificationChannel(channel) {
|
|
3808
3927
|
if (this.wsConnection) {
|
|
3809
|
-
this.
|
|
3928
|
+
const prefixedChannel = this.prefixChannel(channel, ChannelType.NOTIFICATION);
|
|
3929
|
+
this.httpManagerService.unsubscribeFromNotificationChannel(prefixedChannel);
|
|
3930
|
+
console.log(`📢 Unsubscribing from notification channel: ${prefixedChannel}`);
|
|
3810
3931
|
}
|
|
3811
3932
|
else {
|
|
3812
3933
|
console.warn('Cannot unsubscribe from notification channel: WebSocket not connected.');
|
|
@@ -3814,10 +3935,13 @@ class HTTPManagerStateService extends ComponentStore {
|
|
|
3814
3935
|
}
|
|
3815
3936
|
/**
|
|
3816
3937
|
* Send a notification to a channel
|
|
3938
|
+
* @param channel - Base channel name (PUB- prefix added automatically)
|
|
3817
3939
|
*/
|
|
3818
3940
|
sendNotification(channel, content) {
|
|
3819
3941
|
if (this.wsConnection) {
|
|
3820
|
-
this.
|
|
3942
|
+
const prefixedChannel = this.prefixChannel(channel, ChannelType.NOTIFICATION);
|
|
3943
|
+
this.httpManagerService.sendNotification(prefixedChannel, content);
|
|
3944
|
+
console.log(`📢 Sending notification to channel: ${prefixedChannel}`);
|
|
3821
3945
|
}
|
|
3822
3946
|
else {
|
|
3823
3947
|
console.warn('Cannot send notification: WebSocket not connected.');
|
|
@@ -4511,7 +4635,7 @@ class StateServiceDemo extends HTTPManagerStateService {
|
|
|
4511
4635
|
}),
|
|
4512
4636
|
adapter: OIDCClient.adapt,
|
|
4513
4637
|
ws: {
|
|
4514
|
-
id: '
|
|
4638
|
+
id: 'USERS123',
|
|
4515
4639
|
wsServer,
|
|
4516
4640
|
jwtToken,
|
|
4517
4641
|
user,
|
|
@@ -6975,5 +7099,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
6975
7099
|
* Generated bundle index. Do not edit.
|
|
6976
7100
|
*/
|
|
6977
7101
|
|
|
6978
|
-
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 };
|
|
6979
7103
|
//# sourceMappingURL=http-request-manager.mjs.map
|