stream-chat 9.47.1 → 9.48.0

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.
@@ -4,7 +4,7 @@ import { CooldownTimer } from './CooldownTimer';
4
4
  import { MessageComposer } from './messageComposer';
5
5
  import { MessageReceiptsTracker } from './messageDelivery';
6
6
  import type { StreamChat } from './client';
7
- import type { AIState, APIResponse, AscDesc, BanUserOptions, ChannelAPIResponse, ChannelData, ChannelMemberAPIResponse, ChannelMemberResponse, ChannelQueryOptions, ChannelResponse, ChannelUpdateOptions, CreateDraftResponse, DeleteChannelAPIResponse, DraftMessagePayload, Event, EventAPIResponse, EventHandler, EventTypes, GetDraftResponse, GetMultipleMessagesAPIResponse, GetReactionsAPIResponse, GetRepliesAPIResponse, LiveLocationPayload, LocalMessage, MarkReadOptions, MarkUnreadOptions, MemberFilters, MemberSort, Message, MessageFilters, MessageOptions, MessagePaginationOptions, MessageResponse, MessageSetType, MuteChannelAPIResponse, NewMemberPayload, PartialUpdateChannel, PartialUpdateChannelAPIResponse, PartialUpdateMember, PartialUpdateMemberAPIResponse, PinnedMessagePaginationOptions, PinnedMessagesSort, PollVoteData, PushPreference, QueryChannelAPIResponse, QueryMembersOptions, Reaction, ReactionAPIResponse, SearchAPIResponse, SearchOptions, SendMessageAPIResponse, SendMessageOptions, SendReactionOptions, StaticLocationPayload, TruncateChannelAPIResponse, TruncateOptions, UnBanUserOptions, UpdateChannelAPIResponse, UpdateChannelOptions, UpdateLocationPayload, UserResponse } from './types';
7
+ import type { AIState, APIResponse, AscDesc, BanUserOptions, ChannelAPIResponse, ChannelData, ChannelMemberAPIResponse, ChannelMemberResponse, ChannelPushPreference, ChannelQueryOptions, ChannelResponse, ChannelUpdateOptions, CreateDraftResponse, DeleteChannelAPIResponse, DraftMessagePayload, Event, EventAPIResponse, EventHandler, EventTypes, GetDraftResponse, GetMultipleMessagesAPIResponse, GetReactionsAPIResponse, GetRepliesAPIResponse, LiveLocationPayload, LocalMessage, MarkReadOptions, MarkUnreadOptions, MemberFilters, MemberSort, Message, MessageFilters, MessageOptions, MessagePaginationOptions, MessageResponse, MessageSetType, MuteChannelAPIResponse, NewMemberPayload, PartialUpdateChannel, PartialUpdateChannelAPIResponse, PartialUpdateMember, PartialUpdateMemberAPIResponse, PinnedMessagePaginationOptions, PinnedMessagesSort, PollVoteData, QueryChannelAPIResponse, QueryMembersOptions, Reaction, ReactionAPIResponse, SearchAPIResponse, SearchOptions, SendMessageAPIResponse, SendMessageOptions, SendReactionOptions, StaticLocationPayload, TruncateChannelAPIResponse, TruncateOptions, UnBanUserOptions, UpdateChannelAPIResponse, UpdateChannelOptions, UpdateLocationPayload, UserResponse } from './types';
8
8
  import type { Role } from './permissions';
9
9
  /**
10
10
  * Channel - The Channel class manages it's own state.
@@ -40,7 +40,7 @@ export declare class Channel {
40
40
  lastTypingEvent: Date | null;
41
41
  isTyping: boolean;
42
42
  disconnected: boolean;
43
- push_preferences?: PushPreference;
43
+ push_preferences?: ChannelPushPreference;
44
44
  readonly messageComposer: MessageComposer;
45
45
  readonly messageReceiptsTracker: MessageReceiptsTracker;
46
46
  readonly cooldownTimer: CooldownTimer;
@@ -6,6 +6,8 @@ export interface CustomCommandData {
6
6
  }
7
7
  export interface CustomEventData {
8
8
  }
9
+ export interface CustomEventTypes {
10
+ }
9
11
  export interface CustomMemberData {
10
12
  }
11
13
  export interface CustomMessageData {
@@ -32,6 +32,6 @@ export * from './uploadManager';
32
32
  export * from './channel_manager';
33
33
  export * from './offline-support';
34
34
  export * from './LiveLocationManager';
35
- export type { CustomAttachmentData, CustomChannelData, CustomCommandData, CustomEventData, CustomMemberData, CustomMessageComposerData, CustomMessageData, CustomPollOptionData, CustomPollData, CustomReactionData, CustomUserData, CustomThreadData, } from './custom_types';
35
+ export type { CustomAttachmentData, CustomChannelData, CustomCommandData, CustomEventData, CustomEventTypes, CustomMemberData, CustomMessageComposerData, CustomMessageData, CustomPollOptionData, CustomPollData, CustomReactionData, CustomUserData, CustomThreadData, } from './custom_types';
36
36
  export { isOwnUser, chatCodes, logChatPromiseExecution, localMessageToNewMessagePayload, formatMessage, promoteChannel, } from './utils';
37
37
  export { FixedSizeQueueCache } from './utils/FixedSizeQueueCache';
@@ -49,6 +49,7 @@ export type ThreadUserReadState = {
49
49
  unreadMessageCount: number;
50
50
  user: UserResponse;
51
51
  lastReadMessageId?: string;
52
+ firstUnreadMessageId?: string;
52
53
  };
53
54
  export type ThreadReadState = Record<string, ThreadUserReadState | undefined>;
54
55
  export declare const THREAD_RESPONSE_RESERVED_KEYS: Record<keyof ThreadResponse, true>;
@@ -74,6 +75,7 @@ export declare class Thread extends WithSubscriptions {
74
75
  private subscribeMarkActiveThreadRead;
75
76
  private subscribeReloadActiveStaleThread;
76
77
  private subscribeMarkThreadStale;
78
+ private subscribeRepliesUnread;
77
79
  private subscribeNewReplies;
78
80
  private subscribeRepliesRead;
79
81
  private subscribeMessageDeleted;
@@ -3,7 +3,7 @@ import type { Channel } from './channel';
3
3
  import type { AxiosRequestConfig, AxiosResponse } from 'axios';
4
4
  import type { StableWSConnection } from './connection';
5
5
  import type { Role } from './permissions';
6
- import type { CustomAttachmentData, CustomChannelData, CustomCommandData, CustomEventData, CustomMemberData, CustomMessageData, CustomPollData, CustomPollOptionData, CustomReactionData, CustomThreadData, CustomUserData } from './custom_types';
6
+ import type { CustomAttachmentData, CustomChannelData, CustomCommandData, CustomEventData, CustomEventTypes, CustomMemberData, CustomMessageData, CustomPollData, CustomPollOptionData, CustomReactionData, CustomThreadData, CustomUserData } from './custom_types';
7
7
  import type { NotificationManager } from './notifications';
8
8
  import type { RESERVED_UPDATED_MESSAGE_FIELDS } from './constants';
9
9
  /**
@@ -314,7 +314,7 @@ export type ChannelAPIResponse = {
314
314
  hidden?: boolean;
315
315
  membership?: ChannelMemberResponse | null;
316
316
  pending_messages?: PendingMessageResponse[];
317
- push_preferences?: PushPreference;
317
+ push_preferences?: ChannelPushPreference;
318
318
  read?: ReadResponse[];
319
319
  threads?: ThreadResponse[];
320
320
  watcher_count?: number;
@@ -571,21 +571,51 @@ export type GetUnreadCountAPIResponse = APIResponse & {
571
571
  total_unread_threads_count: number;
572
572
  total_unread_count_by_team?: Record<string, number>;
573
573
  };
574
- export type ChatLevelPushPreference = 'all' | 'none' | 'mentions' | (string & {});
574
+ export type ChatLevelPushPreference = 'all' | 'mentions' | 'direct_mentions' | 'all_mentions' | 'none' | 'default' | (string & {});
575
+ export type CallLevelPushPreference = 'all' | 'none' | 'default' | (string & {});
576
+ /** Granular all/none toggle used by the chat sub-preferences. */
577
+ export type PushPreferenceLevel = 'all' | 'none' | (string & {});
578
+ /** Per-mention-type chat push preferences (matches OpenAPI `ChatPreferencesInput`). */
579
+ export type ChatPreferences = {
580
+ channel_mentions?: PushPreferenceLevel;
581
+ default_preference?: PushPreferenceLevel;
582
+ direct_mentions?: PushPreferenceLevel;
583
+ group_mentions?: PushPreferenceLevel;
584
+ here_mentions?: PushPreferenceLevel;
585
+ role_mentions?: PushPreferenceLevel;
586
+ thread_replies?: PushPreferenceLevel;
587
+ };
588
+ /**
589
+ * Input accepted by {@link StreamChat.setPushPreferences} (matches OpenAPI `PushPreferenceInput`).
590
+ *
591
+ * Set `channel_cid` to scope the preference to a single channel; leave it empty to
592
+ * set the user-level default. `user_id` is required for server-side auth and
593
+ * defaults to the connected user for client-side auth.
594
+ */
575
595
  export type PushPreference = {
576
- callLevel?: 'all' | 'none' | (string & {});
577
- chatLevel?: ChatLevelPushPreference;
578
- disabledUntil?: string;
579
- removeDisable?: boolean;
596
+ call_level?: CallLevelPushPreference;
597
+ channel_cid?: string;
598
+ chat_level?: ChatLevelPushPreference;
599
+ chat_preferences?: ChatPreferences;
600
+ disabled_until?: string;
601
+ remove_disable?: boolean;
602
+ user_id?: string;
580
603
  };
604
+ /** Per-user push preferences returned by the API (matches OpenAPI `PushPreferencesResponse`). */
605
+ export type PushPreferencesResponse = {
606
+ call_level?: CallLevelPushPreference;
607
+ chat_level?: ChatLevelPushPreference;
608
+ chat_preferences?: ChatPreferences;
609
+ disabled_until?: string;
610
+ };
611
+ /** Per-channel push preferences returned by the API (matches OpenAPI `ChannelPushPreferencesResponse`). */
581
612
  export type ChannelPushPreference = {
582
- chatLevel?: ChatLevelPushPreference;
583
- disabledUntil?: string;
584
- removeDisable?: boolean;
613
+ chat_level?: ChatLevelPushPreference;
614
+ disabled_until?: string;
585
615
  };
586
616
  export type UpsertPushPreferencesResponse = APIResponse & {
587
- userChannelPreferences: Record<string, Record<string, ChannelPushPreference>>;
588
- userPreferences: Record<string, PushPreference>;
617
+ user_channel_preferences: Record<string, Record<string, ChannelPushPreference>>;
618
+ user_preferences: Record<string, PushPreferencesResponse>;
589
619
  };
590
620
  export type GetUnreadCountBatchAPIResponse = APIResponse & {
591
621
  counts_by_user: {
@@ -731,7 +761,7 @@ export type OwnUserBase = {
731
761
  unread_threads: number;
732
762
  invisible?: boolean;
733
763
  privacy_settings?: PrivacySettings;
734
- push_preferences?: PushPreference;
764
+ push_preferences?: PushPreferencesResponse;
735
765
  roles?: string[];
736
766
  total_unread_count_by_team?: Record<string, number> | null;
737
767
  };
@@ -1473,12 +1503,13 @@ export type Event = CustomEventData & {
1473
1503
  watcher_count?: number;
1474
1504
  channel_last_message_at?: string;
1475
1505
  app?: Record<string, unknown>;
1506
+ thread_id?: string;
1476
1507
  };
1477
1508
  export type UserCustomEvent = CustomEventData & {
1478
1509
  type: string;
1479
1510
  };
1480
1511
  export type EventHandler = (event: Event) => void;
1481
- export type EventTypes = 'all' | keyof typeof EVENT_MAP;
1512
+ export type EventTypes = 'all' | keyof typeof EVENT_MAP | keyof CustomEventTypes;
1482
1513
  /**
1483
1514
  * Filter Types
1484
1515
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "stream-chat",
3
- "version": "9.47.1",
3
+ "version": "9.48.0",
4
4
  "description": "JS SDK for the Stream Chat API",
5
5
  "homepage": "https://getstream.io/chat/",
6
6
  "author": {
package/src/channel.ts CHANGED
@@ -21,6 +21,7 @@ import type {
21
21
  ChannelFilters,
22
22
  ChannelMemberAPIResponse,
23
23
  ChannelMemberResponse,
24
+ ChannelPushPreference,
24
25
  ChannelQueryOptions,
25
26
  ChannelResponse,
26
27
  ChannelUpdateOptions,
@@ -56,7 +57,6 @@ import type {
56
57
  PinnedMessagePaginationOptions,
57
58
  PinnedMessagesSort,
58
59
  PollVoteData,
59
- PushPreference,
60
60
  QueryChannelAPIResponse,
61
61
  QueryMembersOptions,
62
62
  Reaction,
@@ -112,7 +112,7 @@ export class Channel {
112
112
  lastTypingEvent: Date | null;
113
113
  isTyping: boolean;
114
114
  disconnected: boolean;
115
- push_preferences?: PushPreference;
115
+ push_preferences?: ChannelPushPreference;
116
116
  public readonly messageComposer: MessageComposer;
117
117
  public readonly messageReceiptsTracker: MessageReceiptsTracker;
118
118
  public readonly cooldownTimer: CooldownTimer;
@@ -2,6 +2,7 @@ export interface CustomAttachmentData {}
2
2
  export interface CustomChannelData {}
3
3
  export interface CustomCommandData {}
4
4
  export interface CustomEventData {}
5
+ export interface CustomEventTypes {}
5
6
  export interface CustomMemberData {}
6
7
  export interface CustomMessageData {}
7
8
  export interface CustomPollOptionData {}
package/src/index.ts CHANGED
@@ -43,6 +43,7 @@ export type {
43
43
  CustomChannelData,
44
44
  CustomCommandData,
45
45
  CustomEventData,
46
+ CustomEventTypes,
46
47
  CustomMemberData,
47
48
  CustomMessageComposerData,
48
49
  CustomMessageData,
package/src/thread.ts CHANGED
@@ -63,6 +63,7 @@ export type ThreadUserReadState = {
63
63
  unreadMessageCount: number;
64
64
  user: UserResponse;
65
65
  lastReadMessageId?: string;
66
+ firstUnreadMessageId?: string;
66
67
  };
67
68
 
68
69
  export type ThreadReadState = Record<string, ThreadUserReadState | undefined>;
@@ -272,6 +273,7 @@ export class Thread extends WithSubscriptions {
272
273
  this.addUnsubscribeFunction(this.subscribeMarkThreadStale());
273
274
  this.addUnsubscribeFunction(this.subscribeNewReplies());
274
275
  this.addUnsubscribeFunction(this.subscribeRepliesRead());
276
+ this.addUnsubscribeFunction(this.subscribeRepliesUnread());
275
277
  this.addUnsubscribeFunction(this.subscribeMessageDeleted());
276
278
  this.addUnsubscribeFunction(this.subscribeMessageUpdated());
277
279
  };
@@ -330,6 +332,33 @@ export class Thread extends WithSubscriptions {
330
332
  this.state.partialNext({ isStateStale: true });
331
333
  }).unsubscribe;
332
334
 
335
+ private subscribeRepliesUnread = () =>
336
+ this.client.on('notification.mark_unread', (event) => {
337
+ if (!event.user || !event.created_at || !event.thread_id) return;
338
+ if (event.thread_id !== this.id) return;
339
+
340
+ const userId = event.user.id;
341
+ const createdAt = event.created_at;
342
+ const user = event.user;
343
+
344
+ this.state.next((current) => ({
345
+ ...current,
346
+ read: {
347
+ ...current.read,
348
+ [userId]: {
349
+ ...current.read[userId],
350
+ lastReadAt:
351
+ typeof event.last_read_at !== 'undefined'
352
+ ? new Date(event.last_read_at)
353
+ : new Date(createdAt),
354
+ user,
355
+ firstUnreadMessageId: event.first_unread_message_id,
356
+ unreadMessageCount: event.unread_messages ?? 0,
357
+ },
358
+ },
359
+ }));
360
+ }).unsubscribe;
361
+
333
362
  private subscribeNewReplies = () =>
334
363
  this.client.on('message.new', (event) => {
335
364
  if (!this.client.userID || event.message?.parent_id !== this.id) {
@@ -117,6 +117,7 @@ export class ThreadManager extends WithSubscriptions {
117
117
  const unsubscribeFunctions = [
118
118
  'health.check',
119
119
  'notification.mark_read',
120
+ 'notification.mark_unread',
120
121
  'notification.thread_message_new',
121
122
  'notification.channel_deleted',
122
123
  ].map(
package/src/types.ts CHANGED
@@ -8,6 +8,7 @@ import type {
8
8
  CustomChannelData,
9
9
  CustomCommandData,
10
10
  CustomEventData,
11
+ CustomEventTypes,
11
12
  CustomMemberData,
12
13
  CustomMessageData,
13
14
  CustomPollData,
@@ -379,7 +380,7 @@ export type ChannelAPIResponse = {
379
380
  hidden?: boolean;
380
381
  membership?: ChannelMemberResponse | null;
381
382
  pending_messages?: PendingMessageResponse[];
382
- push_preferences?: PushPreference;
383
+ push_preferences?: ChannelPushPreference;
383
384
  read?: ReadResponse[];
384
385
  threads?: ThreadResponse[];
385
386
  watcher_count?: number;
@@ -684,25 +685,67 @@ export type GetUnreadCountAPIResponse = APIResponse & {
684
685
  total_unread_count_by_team?: Record<string, number>;
685
686
  };
686
687
 
687
- export type ChatLevelPushPreference = 'all' | 'none' | 'mentions' | (string & {});
688
+ export type ChatLevelPushPreference =
689
+ | 'all'
690
+ | 'mentions' // deprecated by the API in favor of 'direct_mentions'
691
+ | 'direct_mentions'
692
+ | 'all_mentions'
693
+ | 'none'
694
+ | 'default'
695
+ | (string & {});
696
+
697
+ export type CallLevelPushPreference = 'all' | 'none' | 'default' | (string & {});
698
+
699
+ /** Granular all/none toggle used by the chat sub-preferences. */
700
+ export type PushPreferenceLevel = 'all' | 'none' | (string & {});
688
701
 
702
+ /** Per-mention-type chat push preferences (matches OpenAPI `ChatPreferencesInput`). */
703
+ export type ChatPreferences = {
704
+ channel_mentions?: PushPreferenceLevel;
705
+ default_preference?: PushPreferenceLevel;
706
+ direct_mentions?: PushPreferenceLevel;
707
+ group_mentions?: PushPreferenceLevel;
708
+ here_mentions?: PushPreferenceLevel;
709
+ role_mentions?: PushPreferenceLevel;
710
+ thread_replies?: PushPreferenceLevel;
711
+ };
712
+
713
+ /**
714
+ * Input accepted by {@link StreamChat.setPushPreferences} (matches OpenAPI `PushPreferenceInput`).
715
+ *
716
+ * Set `channel_cid` to scope the preference to a single channel; leave it empty to
717
+ * set the user-level default. `user_id` is required for server-side auth and
718
+ * defaults to the connected user for client-side auth.
719
+ */
689
720
  export type PushPreference = {
690
- callLevel?: 'all' | 'none' | (string & {});
691
- chatLevel?: ChatLevelPushPreference;
692
- disabledUntil?: string; // snooze till this time
693
- removeDisable?: boolean; // Temporary flag for resetting disabledUntil
721
+ call_level?: CallLevelPushPreference;
722
+ channel_cid?: string;
723
+ chat_level?: ChatLevelPushPreference;
724
+ chat_preferences?: ChatPreferences;
725
+ disabled_until?: string; // snooze until this time
726
+ remove_disable?: boolean; // stop snoozing (clears disabled_until)
727
+ user_id?: string;
694
728
  };
695
729
 
730
+ /** Per-user push preferences returned by the API (matches OpenAPI `PushPreferencesResponse`). */
731
+ export type PushPreferencesResponse = {
732
+ call_level?: CallLevelPushPreference;
733
+ chat_level?: ChatLevelPushPreference;
734
+ chat_preferences?: ChatPreferences;
735
+ disabled_until?: string;
736
+ };
737
+
738
+ /** Per-channel push preferences returned by the API (matches OpenAPI `ChannelPushPreferencesResponse`). */
696
739
  export type ChannelPushPreference = {
697
- chatLevel?: ChatLevelPushPreference; // "all", "none", "mentions", or other custom strings
698
- disabledUntil?: string;
699
- removeDisable?: boolean; // Temporary flag for resetting disabledUntil
740
+ chat_level?: ChatLevelPushPreference; // "all", "mentions", "direct_mentions", "all_mentions", "none", "default" or other custom strings
741
+ disabled_until?: string;
700
742
  };
701
743
 
702
744
  export type UpsertPushPreferencesResponse = APIResponse & {
703
- // Mapping of user IDs to their push preferences
704
- userChannelPreferences: Record<string, Record<string, ChannelPushPreference>>;
705
- userPreferences: Record<string, PushPreference>; // Mapping of user -> channel id -> push preferences
745
+ // Mapping of user id -> channel cid -> channel push preferences
746
+ user_channel_preferences: Record<string, Record<string, ChannelPushPreference>>;
747
+ // Mapping of user id -> user push preferences
748
+ user_preferences: Record<string, PushPreferencesResponse>;
706
749
  };
707
750
 
708
751
  export type GetUnreadCountBatchAPIResponse = APIResponse & {
@@ -861,7 +904,7 @@ export type OwnUserBase = {
861
904
  unread_threads: number;
862
905
  invisible?: boolean;
863
906
  privacy_settings?: PrivacySettings;
864
- push_preferences?: PushPreference;
907
+ push_preferences?: PushPreferencesResponse;
865
908
  roles?: string[];
866
909
  total_unread_count_by_team?: Record<string, number> | null;
867
910
  };
@@ -1694,6 +1737,7 @@ export type Event = CustomEventData & {
1694
1737
  watcher_count?: number;
1695
1738
  channel_last_message_at?: string;
1696
1739
  app?: Record<string, unknown>; // TODO: further specify type
1740
+ thread_id?: string;
1697
1741
  };
1698
1742
 
1699
1743
  export type UserCustomEvent = CustomEventData & {
@@ -1702,7 +1746,7 @@ export type UserCustomEvent = CustomEventData & {
1702
1746
 
1703
1747
  export type EventHandler = (event: Event) => void;
1704
1748
 
1705
- export type EventTypes = 'all' | keyof typeof EVENT_MAP;
1749
+ export type EventTypes = 'all' | keyof typeof EVENT_MAP | keyof CustomEventTypes;
1706
1750
 
1707
1751
  /**
1708
1752
  * Filter Types