stream-chat 9.50.2 → 10.0.0-rc.1

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.
Files changed (229) hide show
  1. package/dist/cjs/index.browser.js +18869 -13986
  2. package/dist/cjs/index.browser.js.map +4 -4
  3. package/dist/cjs/index.node.js +18888 -13992
  4. package/dist/cjs/index.node.js.map +4 -4
  5. package/dist/esm/index.mjs +18866 -13983
  6. package/dist/esm/index.mjs.map +4 -4
  7. package/dist/types/ChannelPaginatorsOrchestrator.d.ts +130 -0
  8. package/dist/types/EventHandlerPipeline.d.ts +104 -0
  9. package/dist/types/api-client.d.ts +26 -0
  10. package/dist/types/campaign.d.ts +0 -44
  11. package/dist/types/channel.d.ts +436 -480
  12. package/dist/types/channel_batch_updater.d.ts +0 -93
  13. package/dist/types/channel_manager.d.ts +8 -10
  14. package/dist/types/channel_state.d.ts +53 -201
  15. package/dist/types/client.d.ts +440 -1910
  16. package/dist/types/client_state.d.ts +4 -4
  17. package/dist/types/configuration/InstanceConfigurationService.d.ts +26 -0
  18. package/dist/types/configuration/index.d.ts +1 -0
  19. package/dist/types/configuration/types.d.ts +53 -0
  20. package/dist/types/connection.d.ts +49 -41
  21. package/dist/types/connection_fallback.d.ts +6 -4
  22. package/dist/types/constants.d.ts +0 -4
  23. package/dist/types/custom_types.d.ts +2 -0
  24. package/dist/types/errors.d.ts +2 -2
  25. package/dist/types/gen/chat/ChannelApi.d.ts +45 -0
  26. package/dist/types/gen/chat/ChatApi.d.ts +334 -0
  27. package/dist/types/gen/model-decoders/decoders.d.ts +3 -0
  28. package/dist/types/gen/model-decoders/event-decoder-mapping.d.ts +6 -0
  29. package/dist/types/gen/models/index.d.ts +8836 -0
  30. package/dist/types/gen/moderation/ModerationApi.d.ts +50 -0
  31. package/dist/types/gen-imports.d.ts +3 -0
  32. package/dist/types/index.d.ts +5 -5
  33. package/dist/types/insights.d.ts +7 -6
  34. package/dist/types/logger.d.ts +9 -0
  35. package/dist/types/messageComposer/LocationComposer.d.ts +7 -4
  36. package/dist/types/messageComposer/attachmentIdentity.d.ts +2 -2
  37. package/dist/types/messageComposer/attachmentManager.d.ts +8 -4
  38. package/dist/types/messageComposer/configuration/types.d.ts +11 -11
  39. package/dist/types/messageComposer/linkPreviewsManager.d.ts +25 -13
  40. package/dist/types/messageComposer/messageComposer.d.ts +10 -10
  41. package/dist/types/messageComposer/middleware/messageComposer/types.d.ts +3 -3
  42. package/dist/types/messageComposer/middleware/pollComposer/types.d.ts +4 -7
  43. package/dist/types/messageComposer/middleware/textComposer/commandUtils.d.ts +3 -3
  44. package/dist/types/messageComposer/middleware/textComposer/commands.d.ts +7 -7
  45. package/dist/types/messageComposer/middleware/textComposer/mentions.d.ts +218 -4
  46. package/dist/types/messageComposer/middleware/textComposer/types.d.ts +9 -4
  47. package/dist/types/messageComposer/pollComposer.d.ts +5 -4
  48. package/dist/types/messageComposer/textComposer.d.ts +8 -3
  49. package/dist/types/messageComposer/types.d.ts +6 -28
  50. package/dist/types/messageDelivery/MessageDeliveryReporter.d.ts +40 -25
  51. package/dist/types/messageDelivery/MessageReceiptsTracker.d.ts +53 -12
  52. package/dist/types/messageOperations/MessageOperationStatePolicy.d.ts +19 -0
  53. package/dist/types/messageOperations/MessageOperations.d.ts +17 -0
  54. package/dist/types/messageOperations/index.d.ts +3 -0
  55. package/dist/types/messageOperations/types.d.ts +49 -0
  56. package/dist/types/moderation.d.ts +21 -203
  57. package/dist/types/notifications/types.d.ts +8 -7
  58. package/dist/types/offline-support/offline_support_api.d.ts +110 -87
  59. package/dist/types/offline-support/types.d.ts +19 -23
  60. package/dist/types/offline-support/util.d.ts +4 -2
  61. package/dist/types/pagination/FilterBuilder.d.ts +1 -1
  62. package/dist/types/pagination/ItemIndex.d.ts +82 -0
  63. package/dist/types/pagination/cursorDerivation/createdAtAroundPaginationFlags.d.ts +9 -0
  64. package/dist/types/pagination/cursorDerivation/idAroundPaginationFlags.d.ts +6 -0
  65. package/dist/types/pagination/cursorDerivation/index.d.ts +1 -0
  66. package/dist/types/pagination/cursorDerivation/linearPaginationFlags.d.ts +6 -0
  67. package/dist/types/pagination/filterCompiler.d.ts +7 -0
  68. package/dist/types/pagination/index.d.ts +1 -3
  69. package/dist/types/pagination/paginators/BasePaginator.d.ts +709 -0
  70. package/dist/types/pagination/paginators/ChannelPaginator.d.ts +58 -0
  71. package/dist/types/pagination/paginators/MessageIntervalPaginator.d.ts +260 -0
  72. package/dist/types/pagination/paginators/MessagePaginator.d.ts +208 -0
  73. package/dist/types/pagination/paginators/PinnedMessagePaginator.d.ts +39 -0
  74. package/dist/types/pagination/paginators/ReminderPaginator.d.ts +19 -0
  75. package/dist/types/pagination/paginators/UserGroupPaginator.d.ts +24 -0
  76. package/dist/types/pagination/paginators/index.d.ts +7 -0
  77. package/dist/types/pagination/sortCompiler.d.ts +49 -0
  78. package/dist/types/pagination/types.normalization.d.ts +11 -0
  79. package/dist/types/pagination/utility.normalization.d.ts +18 -0
  80. package/dist/types/pagination/utility.queryChannel.d.ts +26 -0
  81. package/dist/types/pagination/utility.search.d.ts +13 -0
  82. package/dist/types/permissions.d.ts +1 -1
  83. package/dist/types/poll.d.ts +29 -32
  84. package/dist/types/poll_manager.d.ts +2 -2
  85. package/dist/types/reminders/Reminder.d.ts +2 -5
  86. package/dist/types/reminders/ReminderManager.d.ts +2 -9
  87. package/dist/types/search/MessageSearchSource.d.ts +4 -4
  88. package/dist/types/search/UserSearchSource.d.ts +1 -1
  89. package/dist/types/search/types.d.ts +3 -3
  90. package/dist/types/segment.d.ts +0 -34
  91. package/dist/types/signing.d.ts +105 -65
  92. package/dist/types/store.d.ts +1 -0
  93. package/dist/types/thread.d.ts +51 -34
  94. package/dist/types/thread_manager.d.ts +3 -3
  95. package/dist/types/token_manager.d.ts +15 -10
  96. package/dist/types/types.d.ts +196 -3384
  97. package/dist/types/utils/FixedSizeQueueCache.d.ts +12 -6
  98. package/dist/types/utils/WithSubscriptions.d.ts +2 -1
  99. package/dist/types/utils/concurrency.d.ts +4 -4
  100. package/dist/types/utils/mergeWith/mergeWith.d.ts +3 -3
  101. package/dist/types/utils/mergeWith/mergeWithCore.d.ts +8 -3
  102. package/dist/types/utils/retryable.d.ts +34 -0
  103. package/dist/types/utils.d.ts +104 -137
  104. package/package.json +7 -3
  105. package/src/ChannelPaginatorsOrchestrator.ts +545 -0
  106. package/src/CooldownTimer.ts +2 -2
  107. package/src/EventHandlerPipeline.ts +228 -0
  108. package/src/LiveLocationManager.ts +12 -11
  109. package/src/api-client.ts +275 -0
  110. package/src/campaign.ts +1 -77
  111. package/src/channel.ts +1262 -1277
  112. package/src/channel_batch_updater.ts +1 -211
  113. package/src/channel_manager.ts +92 -88
  114. package/src/channel_state.ts +144 -1013
  115. package/src/client.ts +888 -3944
  116. package/src/client_state.ts +4 -4
  117. package/src/configuration/InstanceConfigurationService.ts +73 -0
  118. package/src/configuration/index.ts +1 -0
  119. package/src/configuration/types.ts +81 -0
  120. package/src/connection.ts +145 -94
  121. package/src/connection_fallback.ts +29 -27
  122. package/src/constants.ts +1 -5
  123. package/src/custom_types.ts +4 -1
  124. package/src/errors.ts +2 -2
  125. package/src/gen/chat/ChannelApi.ts +275 -0
  126. package/src/gen/chat/ChatApi.ts +2554 -0
  127. package/src/gen/model-decoders/decoders.ts +2680 -0
  128. package/src/gen/model-decoders/event-decoder-mapping.ts +198 -0
  129. package/src/gen/models/index.ts +12673 -0
  130. package/src/gen/moderation/ModerationApi.ts +607 -0
  131. package/src/gen-imports.ts +3 -0
  132. package/src/index.ts +5 -10
  133. package/src/insights.ts +6 -5
  134. package/src/logger.ts +28 -0
  135. package/src/messageComposer/LocationComposer.ts +9 -5
  136. package/src/messageComposer/MessageComposerEffectHandlers.ts +1 -0
  137. package/src/messageComposer/attachmentIdentity.ts +16 -9
  138. package/src/messageComposer/attachmentManager.ts +13 -8
  139. package/src/messageComposer/configuration/types.ts +11 -11
  140. package/src/messageComposer/linkPreviewsManager.ts +9 -10
  141. package/src/messageComposer/messageComposer.ts +57 -53
  142. package/src/messageComposer/middleware/messageComposer/attachments.ts +1 -2
  143. package/src/messageComposer/middleware/messageComposer/cleanData.ts +1 -1
  144. package/src/messageComposer/middleware/messageComposer/compositionValidation.ts +2 -2
  145. package/src/messageComposer/middleware/messageComposer/messageComposerState.ts +2 -2
  146. package/src/messageComposer/middleware/messageComposer/sharedLocation.ts +4 -3
  147. package/src/messageComposer/middleware/messageComposer/textComposer.ts +2 -2
  148. package/src/messageComposer/middleware/messageComposer/types.ts +3 -4
  149. package/src/messageComposer/middleware/messageComposer/userDataInjection.ts +9 -5
  150. package/src/messageComposer/middleware/pollComposer/state.ts +0 -2
  151. package/src/messageComposer/middleware/pollComposer/types.ts +4 -7
  152. package/src/messageComposer/middleware/textComposer/TextComposerMiddlewareExecutor.ts +10 -1
  153. package/src/messageComposer/middleware/textComposer/commandEffects.ts +4 -4
  154. package/src/messageComposer/middleware/textComposer/commandUtils.ts +3 -6
  155. package/src/messageComposer/middleware/textComposer/commands.ts +3 -3
  156. package/src/messageComposer/middleware/textComposer/mentionUtils.ts +1 -1
  157. package/src/messageComposer/middleware/textComposer/mentions.ts +31 -15
  158. package/src/messageComposer/middleware/textComposer/types.ts +9 -4
  159. package/src/messageComposer/pollComposer.ts +6 -8
  160. package/src/messageComposer/textComposer.ts +27 -2
  161. package/src/messageComposer/types.ts +6 -28
  162. package/src/messageDelivery/MessageDeliveryReporter.ts +101 -45
  163. package/src/messageDelivery/MessageReceiptsTracker.ts +294 -21
  164. package/src/messageOperations/MessageOperationStatePolicy.ts +77 -0
  165. package/src/messageOperations/MessageOperations.ts +212 -0
  166. package/src/messageOperations/index.ts +10 -0
  167. package/src/messageOperations/types.ts +64 -0
  168. package/src/moderation.ts +38 -431
  169. package/src/notifications/types.ts +8 -7
  170. package/src/offline-support/offline_support_api.ts +198 -132
  171. package/src/offline-support/offline_sync_manager.ts +17 -7
  172. package/src/offline-support/types.ts +23 -26
  173. package/src/offline-support/util.ts +5 -4
  174. package/src/pagination/FilterBuilder.ts +4 -1
  175. package/src/pagination/ItemIndex.ts +112 -0
  176. package/src/pagination/cursorDerivation/createdAtAroundPaginationFlags.ts +73 -0
  177. package/src/pagination/cursorDerivation/idAroundPaginationFlags.ts +53 -0
  178. package/src/pagination/cursorDerivation/index.ts +1 -0
  179. package/src/pagination/cursorDerivation/linearPaginationFlags.ts +86 -0
  180. package/src/pagination/filterCompiler.ts +196 -0
  181. package/src/pagination/index.ts +1 -3
  182. package/src/pagination/paginators/BasePaginator.ts +2393 -0
  183. package/src/pagination/paginators/ChannelPaginator.ts +427 -0
  184. package/src/pagination/paginators/MessageIntervalPaginator.ts +1073 -0
  185. package/src/pagination/paginators/MessagePaginator.ts +496 -0
  186. package/src/pagination/paginators/PinnedMessagePaginator.ts +105 -0
  187. package/src/pagination/paginators/ReminderPaginator.ts +105 -0
  188. package/src/pagination/paginators/UserGroupPaginator.ts +125 -0
  189. package/src/pagination/paginators/index.ts +7 -0
  190. package/src/pagination/sortCompiler.ts +178 -0
  191. package/src/pagination/types.normalization.ts +14 -0
  192. package/src/pagination/utility.normalization.ts +106 -0
  193. package/src/pagination/utility.queryChannel.ts +84 -0
  194. package/src/pagination/utility.search.ts +80 -0
  195. package/src/permissions.ts +7 -8
  196. package/src/poll.ts +101 -110
  197. package/src/poll_manager.ts +14 -8
  198. package/src/reminders/Reminder.ts +2 -5
  199. package/src/reminders/ReminderManager.ts +19 -21
  200. package/src/search/BaseSearchSource.ts +0 -3
  201. package/src/search/ChannelMemberSearchSource.ts +7 -1
  202. package/src/search/ChannelSearchSource.ts +10 -3
  203. package/src/search/MessageSearchSource.ts +29 -30
  204. package/src/search/UserSearchSource.ts +12 -8
  205. package/src/search/types.ts +3 -4
  206. package/src/segment.ts +1 -95
  207. package/src/signing.ts +107 -67
  208. package/src/store.ts +2 -1
  209. package/src/thread.ts +439 -236
  210. package/src/thread_manager.ts +36 -15
  211. package/src/token_manager.ts +21 -10
  212. package/src/types.ts +375 -4524
  213. package/src/uploadManager.ts +8 -0
  214. package/src/utils/FixedSizeQueueCache.ts +12 -6
  215. package/src/utils/WithSubscriptions.ts +2 -1
  216. package/src/utils/concurrency.ts +4 -4
  217. package/src/utils/mergeWith/mergeWith.ts +3 -3
  218. package/src/utils/mergeWith/mergeWithCore.ts +140 -164
  219. package/src/utils/mergeWith/mergeWithDiff.ts +3 -3
  220. package/src/utils/retryable.ts +117 -0
  221. package/src/utils.ts +133 -524
  222. package/dist/types/events.d.ts +0 -72
  223. package/dist/types/pagination/BasePaginator.d.ts +0 -69
  224. package/dist/types/pagination/ReminderPaginator.d.ts +0 -16
  225. package/dist/types/pagination/UserGroupPaginator.d.ts +0 -21
  226. package/src/events.ts +0 -75
  227. package/src/pagination/BasePaginator.ts +0 -184
  228. package/src/pagination/ReminderPaginator.ts +0 -56
  229. package/src/pagination/UserGroupPaginator.ts +0 -93
@@ -0,0 +1,427 @@
1
+ import type {
2
+ PaginationQueryParams,
3
+ PaginationQueryReturnValue,
4
+ PaginationQueryShapeChangeIdentifier,
5
+ PaginatorOptions,
6
+ PaginatorState,
7
+ SetPaginatorItemsParams,
8
+ } from './BasePaginator';
9
+ import { BasePaginator } from './BasePaginator';
10
+ import { chatLoggerSystem } from '../../logger';
11
+ import type { FilterBuilderOptions } from '../FilterBuilder';
12
+ import { FilterBuilder } from '../FilterBuilder';
13
+ import { makeComparator } from '../sortCompiler';
14
+ import { ItemIndex } from '../ItemIndex';
15
+ import { generateUUIDv4 } from '../../utils';
16
+ import type { StreamChat } from '../../client';
17
+ import type { Channel } from '../../channel';
18
+ import type {
19
+ ChannelFilters,
20
+ ChannelOptions,
21
+ ChannelSort,
22
+ ChannelStateOptions,
23
+ } from '../../types';
24
+ import type { FieldToDataResolver, PathResolver } from '../types.normalization';
25
+ import { resolveDotPathValue } from '../utility.normalization';
26
+ import { isEqual } from '../../utils/mergeWith/mergeWithCore';
27
+
28
+ const DEFAULT_BACKEND_SORT: ChannelSort = [
29
+ { direction: -1, field: 'last_message_at' },
30
+ { direction: -1, field: 'updated_at' },
31
+ ];
32
+
33
+ export type ChannelQueryShape = {
34
+ filters: ChannelFilters;
35
+ sort?: ChannelSort;
36
+ options?: ChannelOptions;
37
+ stateOptions?: ChannelStateOptions;
38
+ };
39
+
40
+ export type ChannelPaginatorState = PaginatorState<Channel>;
41
+
42
+ export type ChannelPaginatorRequestOptions = Partial<
43
+ Omit<ChannelOptions, 'offset' | 'limit'>
44
+ >;
45
+
46
+ export type ChannelPaginatorOptions = {
47
+ client: StreamChat;
48
+ channelStateOptions?: ChannelStateOptions;
49
+ filterBuilderOptions?: FilterBuilderOptions<ChannelFilters>;
50
+ filters?: ChannelFilters;
51
+ id?: string;
52
+ paginatorOptions?: PaginatorOptions<Channel, ChannelQueryShape>;
53
+ requestOptions?: ChannelPaginatorRequestOptions;
54
+ sort?: ChannelSort;
55
+ };
56
+
57
+ const getQueryShapeRelevantChannelOptions = (options: ChannelOptions) => {
58
+ const {
59
+ limit: _,
60
+ member_limit: __,
61
+ message_limit: ___,
62
+ offset: ____,
63
+
64
+ ...relevantShape
65
+ } = options;
66
+ return relevantShape;
67
+ };
68
+
69
+ const hasPaginationQueryShapeChanged: PaginationQueryShapeChangeIdentifier<
70
+ ChannelQueryShape
71
+ > = (prevQueryShape, nextQueryShape) =>
72
+ !isEqual(
73
+ {
74
+ ...prevQueryShape,
75
+ options: getQueryShapeRelevantChannelOptions(prevQueryShape?.options ?? {}),
76
+ },
77
+ {
78
+ ...nextQueryShape,
79
+ options: getQueryShapeRelevantChannelOptions(nextQueryShape?.options ?? {}),
80
+ },
81
+ );
82
+
83
+ const archivedFilterResolver: FieldToDataResolver<Channel> = {
84
+ matchesField: (field) => field === 'archived',
85
+ resolve: (channel) => !!channel.state.membership.archived_at,
86
+ };
87
+
88
+ const appBannedFilterResolver: FieldToDataResolver<Channel> = {
89
+ matchesField: (field) => field === 'app_banned',
90
+ resolve: (channel) => {
91
+ const ownUserId = channel.getClient().user?.id;
92
+ const otherMembers = Object.values(channel.state.members).filter(
93
+ ({ user }) => user?.id !== ownUserId,
94
+ );
95
+ // Only applies to channels with exactly 2 members.
96
+ if (otherMembers.length !== 1) return false;
97
+ const otherMember = otherMembers[0];
98
+ return otherMember.user?.banned ? 'only' : 'excluded';
99
+ },
100
+ };
101
+
102
+ const hasUnreadFilterResolver: FieldToDataResolver<Channel> = {
103
+ matchesField: (field) => field === 'has_unread',
104
+ resolve: (channel) => {
105
+ const ownUserId = channel.getClient().user?.id;
106
+ return (
107
+ ownUserId &&
108
+ channel.state.read[ownUserId] &&
109
+ channel.state.read[ownUserId].unread_messages > 0
110
+ );
111
+ },
112
+ };
113
+
114
+ const lastUpdatedFilterResolver: FieldToDataResolver<Channel> = {
115
+ matchesField: (field) => field === 'last_updated',
116
+ resolve: (channel) => {
117
+ // combination of last_message_at and updated_at
118
+ const lastMessageAt = channel.messagePaginator.lastMessageAt?.getTime() ?? null;
119
+ const updatedAt = channel.data?.updated_at
120
+ ? new Date(channel.data?.updated_at).getTime()
121
+ : undefined;
122
+ return lastMessageAt !== null && updatedAt !== undefined
123
+ ? Math.max(lastMessageAt, updatedAt)
124
+ : (lastMessageAt ?? updatedAt);
125
+ },
126
+ };
127
+
128
+ const membersFilterResolver: FieldToDataResolver<Channel> = {
129
+ matchesField: (field) => field === 'members',
130
+ resolve: (channel) =>
131
+ channel.state.members
132
+ ? Object.values(channel.state.members).reduce<string[]>((ids, member) => {
133
+ if (member.user?.id) {
134
+ ids.push(member.user?.id);
135
+ }
136
+ return ids;
137
+ }, [])
138
+ : [],
139
+ };
140
+
141
+ const memberUserNameFilterResolver: FieldToDataResolver<Channel> = {
142
+ matchesField: (field) => field === 'member.user.name',
143
+ resolve: (channel) =>
144
+ channel.state.members
145
+ ? Object.values(channel.state.members).reduce<string[]>((names, member) => {
146
+ if (member.user?.name) {
147
+ names.push(member.user.name);
148
+ }
149
+ return names;
150
+ }, [])
151
+ : [],
152
+ };
153
+
154
+ const pinnedFilterResolver: FieldToDataResolver<Channel> = {
155
+ matchesField: (field) => field === 'pinned',
156
+ resolve: (channel) => !!channel.state.membership.pinned_at,
157
+ };
158
+
159
+ const mutedFilterResolver: FieldToDataResolver<Channel> = {
160
+ matchesField: (field) => field === 'muted',
161
+ // UserMuteResponse state lives on the client (client.mutedChannels), not on channel.data — resolve it via
162
+ // the client so `{ muted: true/false }` matches client-side, rather than letting the generic
163
+ // data resolver read a non-existent `channel.data.muted` (which would resolve to undefined and
164
+ // never equal a boolean filter value).
165
+ resolve: (channel) => channel.getClient()._muteStatus(channel.cid).muted,
166
+ };
167
+
168
+ const dataFieldFilterResolver: FieldToDataResolver<Channel> = {
169
+ matchesField: () => true,
170
+ resolve: (channel, path) => resolveDotPathValue(channel.data, path),
171
+ };
172
+
173
+ // very, very unfortunately channel data is dispersed btw Channel.data and Channel.state
174
+ const channelSortPathResolver: PathResolver<Channel> = (channel, path) => {
175
+ switch (path) {
176
+ case 'last_message_at':
177
+ return channel.messagePaginator.lastMessageAt;
178
+ case 'has_unread': {
179
+ return hasUnreadFilterResolver.resolve(channel, path);
180
+ }
181
+ case 'last_updated': {
182
+ return lastUpdatedFilterResolver.resolve(channel, path) ?? 0;
183
+ }
184
+ case 'pinned_at':
185
+ return channel.state.membership.pinned_at;
186
+ case 'unread_count': {
187
+ const userId = channel.getClient().user?.id;
188
+ return userId ? channel.state.read[userId].unread_messages : 0;
189
+ }
190
+ default:
191
+ return resolveDotPathValue(channel.data, path);
192
+ }
193
+ };
194
+
195
+ // todo: maybe items could be just an array of {cid: string} and the data would be retrieved from client.activeChannels
196
+ // todo: maybe we should introduce client._cache.channels that would be reactive and orchestrator would subscribe to client._cache.channels state to keep all the dependent state in sync
197
+ export class ChannelPaginator extends BasePaginator<Channel, ChannelQueryShape> {
198
+ private readonly _id: string;
199
+ private client: StreamChat;
200
+ protected _staticFilters: ChannelFilters | undefined;
201
+ protected _sort: ChannelSort | undefined;
202
+ protected _options: ChannelPaginatorRequestOptions | undefined;
203
+ protected _channelStateOptions: ChannelStateOptions | undefined;
204
+ protected _nextQueryShape: ChannelQueryShape | undefined;
205
+ sortComparator: (a: Channel, b: Channel) => number;
206
+ filterBuilder: FilterBuilder<ChannelFilters>;
207
+
208
+ constructor({
209
+ channelStateOptions,
210
+ client,
211
+ id,
212
+ filterBuilderOptions,
213
+ filters,
214
+ paginatorOptions,
215
+ requestOptions,
216
+ sort,
217
+ }: ChannelPaginatorOptions) {
218
+ super({
219
+ hasPaginationQueryShapeChanged,
220
+ itemIndex: new ItemIndex<Channel>({ getId: (channel) => channel.cid }),
221
+ ...paginatorOptions,
222
+ });
223
+ const definedSort = sort ?? DEFAULT_BACKEND_SORT;
224
+ this.client = client;
225
+ this._id = id ?? `channel-paginator-${generateUUIDv4()}`;
226
+ this._sort = definedSort;
227
+ this._staticFilters = filters;
228
+ this._options = requestOptions;
229
+ this._channelStateOptions = channelStateOptions;
230
+ this.filterBuilder = new FilterBuilder<ChannelFilters>(filterBuilderOptions);
231
+ this.sortComparator = makeComparator<Channel>({
232
+ sort: definedSort,
233
+ resolvePathValue: channelSortPathResolver,
234
+ tiebreaker: (l, r) => {
235
+ const leftId = this.getItemId(l);
236
+ const rightId = this.getItemId(r);
237
+ return leftId < rightId ? -1 : leftId > rightId ? 1 : 0;
238
+ },
239
+ });
240
+ this.setFilterResolvers([
241
+ archivedFilterResolver,
242
+ appBannedFilterResolver,
243
+ hasUnreadFilterResolver,
244
+ lastUpdatedFilterResolver,
245
+ pinnedFilterResolver,
246
+ mutedFilterResolver,
247
+ membersFilterResolver,
248
+ memberUserNameFilterResolver,
249
+ dataFieldFilterResolver,
250
+ ]);
251
+ }
252
+
253
+ get id() {
254
+ return this._id;
255
+ }
256
+
257
+ get isOfflineSupportEnabled() {
258
+ return !!this.client.offlineDb;
259
+ }
260
+
261
+ get staticFilters(): ChannelFilters | undefined {
262
+ return this._staticFilters;
263
+ }
264
+
265
+ get sort(): ChannelSort {
266
+ return this._sort ?? DEFAULT_BACKEND_SORT;
267
+ }
268
+
269
+ get options(): ChannelOptions | undefined {
270
+ return this._options;
271
+ }
272
+
273
+ get channelStateOptions(): ChannelStateOptions | undefined {
274
+ return this._channelStateOptions;
275
+ }
276
+
277
+ set staticFilters(filters: ChannelFilters | undefined) {
278
+ this._staticFilters = filters;
279
+ }
280
+
281
+ set sort(sort: ChannelSort | undefined) {
282
+ this._sort = sort;
283
+ this.sortComparator = makeComparator<Channel>({
284
+ sort: this.sort ?? DEFAULT_BACKEND_SORT,
285
+ });
286
+ }
287
+
288
+ set options(options: ChannelPaginatorRequestOptions | undefined) {
289
+ this._options = options;
290
+ }
291
+
292
+ set channelStateOptions(options: ChannelStateOptions | undefined) {
293
+ this._channelStateOptions = options;
294
+ }
295
+
296
+ getItemId(item: Channel): string {
297
+ return item.cid;
298
+ }
299
+
300
+ buildFilters = (): ChannelFilters =>
301
+ this.filterBuilder.buildFilters({
302
+ baseFilters: { ...this.staticFilters },
303
+ });
304
+
305
+ // invoked inside BasePaginator.executeQuery() to keep it as a query descriptor;
306
+ protected getNextQueryShape(): ChannelQueryShape {
307
+ const shape: ChannelQueryShape = {
308
+ filters: this.buildFilters(),
309
+ options: {
310
+ ...this.options,
311
+ limit: this.pageSize,
312
+ offset: this.offset,
313
+ },
314
+ };
315
+
316
+ if (this.sort) {
317
+ shape.sort = this.sort;
318
+ }
319
+
320
+ if (this.channelStateOptions) {
321
+ shape.stateOptions = this.channelStateOptions;
322
+ }
323
+ return shape;
324
+ }
325
+
326
+ preloadFirstPageFromOfflineDb = async ({
327
+ direction,
328
+ queryShape,
329
+ reset,
330
+ }: PaginationQueryParams<ChannelQueryShape>) => {
331
+ if (
332
+ !this.client.offlineDb?.getChannelsForQuery ||
333
+ !this.client.user?.id ||
334
+ !queryShape
335
+ )
336
+ return undefined;
337
+
338
+ try {
339
+ const channelsFromDB = await this.client.offlineDb.getChannelsForQuery({
340
+ userId: this.client.user.id,
341
+ options: { filter_conditions: queryShape.filters, sort: queryShape.sort },
342
+ });
343
+
344
+ if (channelsFromDB) {
345
+ const offlineChannels = this.client.hydrateActiveChannels(channelsFromDB, {
346
+ offlineMode: true,
347
+ skipInitialization: [], // passing empty array will clear out the existing messages from channel state, this removes the possibility of duplicate messages
348
+ });
349
+
350
+ return offlineChannels;
351
+ }
352
+
353
+ if (!this.client.offlineDb.syncManager.syncStatus) {
354
+ this.client.offlineDb.syncManager.scheduleSyncStatusChangeCallback(
355
+ this.id,
356
+ async () => {
357
+ await this.executeQuery({ direction, queryShape, reset });
358
+ },
359
+ );
360
+ return;
361
+ }
362
+ } catch (error) {
363
+ chatLoggerSystem.getLogger('channel').error((error as Error).message);
364
+ if (this.config.throwErrors) throw error;
365
+ }
366
+ return;
367
+ };
368
+
369
+ populateOfflineDbAfterQuery = ({
370
+ items,
371
+ queryShape,
372
+ }: {
373
+ items?: Channel[];
374
+ queryShape?: ChannelQueryShape;
375
+ }) => {
376
+ if (!items || !queryShape) return undefined;
377
+
378
+ this.client.offlineDb?.executeQuerySafely(
379
+ (db) =>
380
+ db.upsertCidsForQuery({
381
+ cids: items.map((channel) => channel.cid),
382
+ filters: queryShape.filters,
383
+ sort: queryShape.sort,
384
+ }),
385
+ { method: 'upsertCidsForQuery' },
386
+ );
387
+ };
388
+
389
+ query = async (): Promise<PaginationQueryReturnValue<Channel>> => {
390
+ // get the params only if they were not generated previously
391
+ if (!this._nextQueryShape) {
392
+ this._nextQueryShape = this.getNextQueryShape();
393
+ }
394
+ const { filters, sort, options, stateOptions } = this._nextQueryShape;
395
+ let items: Channel[];
396
+ if (this.config.doRequest) {
397
+ items = (await this.config.doRequest(this._nextQueryShape)).items;
398
+ } else {
399
+ items = await this.client.queryChannelsAndHydrate(
400
+ { filter_conditions: filters, sort, ...options },
401
+ stateOptions,
402
+ );
403
+ }
404
+ return { items };
405
+ };
406
+
407
+ filterQueryResults = (items: Channel[]) => items;
408
+
409
+ setItems(params: SetPaginatorItemsParams<Channel>) {
410
+ super.setItems(params);
411
+
412
+ if (!this.client.offlineDb) return;
413
+
414
+ const { items: channels = [], sort } = this;
415
+ const filters = this.buildFilters();
416
+
417
+ this.client.offlineDb?.executeQuerySafely(
418
+ (db) =>
419
+ db.upsertCidsForQuery({
420
+ cids: channels.map((channel) => channel.cid),
421
+ filters,
422
+ sort,
423
+ }),
424
+ { method: 'upsertCidsForQuery' },
425
+ );
426
+ }
427
+ }