stream-chat 9.16.0 → 9.18.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.
@@ -189,6 +189,7 @@ __export(index_exports, {
189
189
  DevToken: () => DevToken,
190
190
  EVENT_MAP: () => EVENT_MAP,
191
191
  ErrorFromResponse: () => ErrorFromResponse,
192
+ FilterBuilder: () => FilterBuilder,
192
193
  FixedSizeQueueCache: () => FixedSizeQueueCache,
193
194
  InsightMetrics: () => InsightMetrics,
194
195
  JWTServerToken: () => JWTServerToken,
@@ -2837,6 +2838,58 @@ var toUpdatedMessagePayload = (message) => {
2837
2838
  )
2838
2839
  };
2839
2840
  };
2841
+ var toDeletedMessage = ({
2842
+ message,
2843
+ deletedAt,
2844
+ hardDelete = false
2845
+ }) => {
2846
+ if (hardDelete) {
2847
+ return {
2848
+ attachments: [],
2849
+ cid: message.cid,
2850
+ created_at: message.created_at,
2851
+ deleted_at: deletedAt,
2852
+ id: message.id,
2853
+ latest_reactions: [],
2854
+ mentioned_users: [],
2855
+ own_reactions: [],
2856
+ parent_id: message.parent_id,
2857
+ reply_count: message.reply_count,
2858
+ status: message.status,
2859
+ thread_participants: message.thread_participants,
2860
+ type: "deleted",
2861
+ updated_at: message.updated_at,
2862
+ user: message.user
2863
+ };
2864
+ } else {
2865
+ return {
2866
+ ...message,
2867
+ attachments: [],
2868
+ type: "deleted",
2869
+ deleted_at: deletedAt
2870
+ };
2871
+ }
2872
+ };
2873
+ var deleteUserMessages = ({
2874
+ messages,
2875
+ user,
2876
+ hardDelete = false,
2877
+ deletedAt
2878
+ }) => {
2879
+ for (let i = 0; i < messages.length; i++) {
2880
+ const message = messages[i];
2881
+ if (message.user?.id === user.id) {
2882
+ messages[i] = message.type === "deleted" ? message : toDeletedMessage({ message, hardDelete, deletedAt });
2883
+ }
2884
+ if (message.quoted_message?.user?.id === user.id) {
2885
+ messages[i].quoted_message = message.quoted_message.type === "deleted" ? message.quoted_message : toDeletedMessage({
2886
+ message: messages[i].quoted_message,
2887
+ hardDelete,
2888
+ deletedAt
2889
+ });
2890
+ }
2891
+ }
2892
+ };
2840
2893
  var findIndexInSortedArray = ({
2841
2894
  needle,
2842
2895
  sortedArray,
@@ -3371,46 +3424,24 @@ var ChannelState = class {
3371
3424
  * @param {UserResponse} user
3372
3425
  * @param {boolean} hardDelete
3373
3426
  */
3374
- this.deleteUserMessages = (user, hardDelete = false) => {
3375
- const _deleteUserMessages = (messages, user2, hardDelete2 = false) => {
3376
- for (let i = 0; i < messages.length; i++) {
3377
- const m = messages[i];
3378
- if (m.user?.id !== user2.id) {
3379
- continue;
3380
- }
3381
- if (hardDelete2) {
3382
- messages[i] = {
3383
- cid: m.cid,
3384
- created_at: m.created_at,
3385
- deleted_at: user2.deleted_at,
3386
- id: m.id,
3387
- latest_reactions: [],
3388
- mentioned_users: [],
3389
- own_reactions: [],
3390
- parent_id: m.parent_id,
3391
- reply_count: m.reply_count,
3392
- status: m.status,
3393
- thread_participants: m.thread_participants,
3394
- type: "deleted",
3395
- updated_at: m.updated_at,
3396
- user: m.user
3397
- };
3398
- } else {
3399
- messages[i] = {
3400
- ...m,
3401
- type: "deleted",
3402
- deleted_at: user2.deleted_at ? new Date(user2.deleted_at) : null
3403
- };
3404
- }
3405
- }
3406
- };
3427
+ this.deleteUserMessages = (user, hardDelete = false, deletedAt) => {
3407
3428
  this.messageSets.forEach(
3408
- (set) => _deleteUserMessages(set.messages, user, hardDelete)
3429
+ ({ messages }) => deleteUserMessages({ messages, user, hardDelete, deletedAt: deletedAt ?? null })
3409
3430
  );
3410
3431
  for (const parentId in this.threads) {
3411
- _deleteUserMessages(this.threads[parentId], user, hardDelete);
3432
+ deleteUserMessages({
3433
+ messages: this.threads[parentId],
3434
+ user,
3435
+ hardDelete,
3436
+ deletedAt: deletedAt ?? null
3437
+ });
3412
3438
  }
3413
- _deleteUserMessages(this.pinnedMessages, user, hardDelete);
3439
+ deleteUserMessages({
3440
+ messages: this.pinnedMessages,
3441
+ user,
3442
+ hardDelete,
3443
+ deletedAt: deletedAt ?? null
3444
+ });
3414
3445
  };
3415
3446
  this._channel = channel;
3416
3447
  this.watcher_count = 0;
@@ -7001,21 +7032,242 @@ var SearchController = class {
7001
7032
  }
7002
7033
  };
7003
7034
 
7035
+ // src/pagination/BasePaginator.ts
7036
+ var DEFAULT_PAGINATION_OPTIONS = {
7037
+ debounceMs: 300,
7038
+ pageSize: 10
7039
+ };
7040
+ var BasePaginator = class {
7041
+ constructor(options) {
7042
+ this._isCursorPagination = false;
7043
+ this.setDebounceOptions = ({ debounceMs }) => {
7044
+ this._executeQueryDebounced = debounce(this.executeQuery.bind(this), debounceMs);
7045
+ };
7046
+ this.canExecuteQuery = (direction) => !this.isLoading && direction === "next" && this.hasNext || direction === "prev" && this.hasPrev;
7047
+ this.next = () => this.executeQuery({ direction: "next" });
7048
+ this.prev = () => this.executeQuery({ direction: "prev" });
7049
+ this.nextDebounced = () => {
7050
+ this._executeQueryDebounced({ direction: "next" });
7051
+ };
7052
+ this.prevDebounced = () => {
7053
+ this._executeQueryDebounced({ direction: "prev" });
7054
+ };
7055
+ const { debounceMs, pageSize } = { ...DEFAULT_PAGINATION_OPTIONS, ...options };
7056
+ this.pageSize = pageSize;
7057
+ this.state = new StateStore(this.initialState);
7058
+ this.setDebounceOptions({ debounceMs });
7059
+ }
7060
+ get lastQueryError() {
7061
+ return this.state.getLatestValue().lastQueryError;
7062
+ }
7063
+ get hasNext() {
7064
+ return this.state.getLatestValue().hasNext;
7065
+ }
7066
+ get hasPrev() {
7067
+ return this.state.getLatestValue().hasPrev;
7068
+ }
7069
+ get hasResults() {
7070
+ return Array.isArray(this.state.getLatestValue().items);
7071
+ }
7072
+ get isLoading() {
7073
+ return this.state.getLatestValue().isLoading;
7074
+ }
7075
+ get initialState() {
7076
+ return {
7077
+ hasNext: true,
7078
+ hasPrev: true,
7079
+ //todo: check if optimistic value does not cause problems in UI
7080
+ isLoading: false,
7081
+ items: void 0,
7082
+ lastQueryError: void 0,
7083
+ cursor: void 0,
7084
+ offset: 0
7085
+ };
7086
+ }
7087
+ get items() {
7088
+ return this.state.getLatestValue().items;
7089
+ }
7090
+ get cursor() {
7091
+ return this.state.getLatestValue().cursor;
7092
+ }
7093
+ get offset() {
7094
+ return this.state.getLatestValue().offset;
7095
+ }
7096
+ getStateBeforeFirstQuery() {
7097
+ return {
7098
+ ...this.initialState,
7099
+ isLoading: true
7100
+ };
7101
+ }
7102
+ getStateAfterQuery(stateUpdate, isFirstPage) {
7103
+ const current = this.state.getLatestValue();
7104
+ return {
7105
+ ...current,
7106
+ lastQueryError: void 0,
7107
+ // reset lastQueryError that can be overridden by the stateUpdate
7108
+ ...stateUpdate,
7109
+ isLoading: false,
7110
+ items: isFirstPage ? stateUpdate.items : [...this.items ?? [], ...stateUpdate.items || []]
7111
+ };
7112
+ }
7113
+ async executeQuery({ direction }) {
7114
+ if (!this.canExecuteQuery(direction)) return;
7115
+ const isFirstPage = typeof this.items === "undefined";
7116
+ if (isFirstPage) {
7117
+ this.state.next(this.getStateBeforeFirstQuery());
7118
+ } else {
7119
+ this.state.partialNext({ isLoading: true });
7120
+ }
7121
+ const stateUpdate = {};
7122
+ try {
7123
+ const results = await this.query({ direction });
7124
+ if (!results) return;
7125
+ const { items, next, prev } = results;
7126
+ if (isFirstPage && (next || prev)) {
7127
+ this._isCursorPagination = true;
7128
+ }
7129
+ if (this._isCursorPagination) {
7130
+ stateUpdate.cursor = { next: next || null, prev: prev || null };
7131
+ stateUpdate.hasNext = !!next;
7132
+ stateUpdate.hasPrev = !!prev;
7133
+ } else {
7134
+ stateUpdate.offset = (this.offset ?? 0) + items.length;
7135
+ stateUpdate.hasNext = items.length === this.pageSize;
7136
+ }
7137
+ stateUpdate.items = await this.filterQueryResults(items);
7138
+ } catch (e) {
7139
+ stateUpdate.lastQueryError = e;
7140
+ } finally {
7141
+ this.state.next(this.getStateAfterQuery(stateUpdate, isFirstPage));
7142
+ }
7143
+ }
7144
+ cancelScheduledQuery() {
7145
+ this._executeQueryDebounced.cancel();
7146
+ }
7147
+ resetState() {
7148
+ this.state.next(this.initialState);
7149
+ }
7150
+ };
7151
+
7152
+ // src/pagination/FilterBuilder.ts
7153
+ var FilterBuilder = class {
7154
+ constructor(params) {
7155
+ this.context = new StateStore(params?.initialContext ?? {});
7156
+ this.filterConfig = new StateStore(
7157
+ params?.initialFilterConfig ?? {}
7158
+ );
7159
+ }
7160
+ updateFilterConfig(config) {
7161
+ this.filterConfig.partialNext(config);
7162
+ }
7163
+ enableFilter(filterKey) {
7164
+ const config = this.filterConfig.getLatestValue();
7165
+ if (config[filterKey]) {
7166
+ this.filterConfig.partialNext({
7167
+ [filterKey]: {
7168
+ ...config[filterKey],
7169
+ enabled: true
7170
+ }
7171
+ });
7172
+ }
7173
+ }
7174
+ disableFilter(filterKey) {
7175
+ const config = this.filterConfig.getLatestValue();
7176
+ if (config[filterKey]) {
7177
+ this.filterConfig.partialNext({
7178
+ [filterKey]: {
7179
+ ...config[filterKey],
7180
+ enabled: false
7181
+ }
7182
+ });
7183
+ }
7184
+ }
7185
+ updateContext(newContext) {
7186
+ this.context.partialNext(newContext);
7187
+ }
7188
+ buildFilters(params) {
7189
+ const filters = {
7190
+ ...params?.baseFilters ?? {}
7191
+ };
7192
+ const filterConfig = this.filterConfig.getLatestValue();
7193
+ for (const key in filterConfig) {
7194
+ const configItem = filterConfig[key];
7195
+ if (!configItem?.enabled) continue;
7196
+ const generated = configItem.generate({
7197
+ ...this.context.getLatestValue(),
7198
+ ...params?.context ?? {}
7199
+ });
7200
+ if (generated) Object.assign(filters, generated);
7201
+ }
7202
+ return filters;
7203
+ }
7204
+ };
7205
+
7206
+ // src/pagination/ReminderPaginator.ts
7207
+ var ReminderPaginator = class extends BasePaginator {
7208
+ constructor(client, options) {
7209
+ super(options);
7210
+ this.query = async ({
7211
+ direction
7212
+ }) => {
7213
+ const cursor = this.cursor?.[direction];
7214
+ const {
7215
+ reminders: items,
7216
+ next,
7217
+ prev
7218
+ } = await this.client.queryReminders({
7219
+ filter: this.filters,
7220
+ sort: this.sort,
7221
+ limit: this.pageSize,
7222
+ [direction]: cursor
7223
+ });
7224
+ return { items, next, prev };
7225
+ };
7226
+ this.filterQueryResults = (items) => items;
7227
+ this.client = client;
7228
+ }
7229
+ get filters() {
7230
+ return this._filters;
7231
+ }
7232
+ get sort() {
7233
+ return this._sort;
7234
+ }
7235
+ set filters(filters) {
7236
+ this._filters = filters;
7237
+ this.resetState();
7238
+ }
7239
+ set sort(sort) {
7240
+ this._sort = sort;
7241
+ this.resetState();
7242
+ }
7243
+ };
7244
+
7004
7245
  // src/search/UserSearchSource.ts
7005
7246
  var UserSearchSource = class extends BaseSearchSource {
7006
- constructor(client, options) {
7247
+ constructor(client, options, filterBuilderOptions = {}) {
7007
7248
  super(options);
7008
7249
  this.type = "users";
7009
7250
  this.client = client;
7251
+ this.filterBuilder = new FilterBuilder({
7252
+ initialFilterConfig: {
7253
+ $or: {
7254
+ enabled: true,
7255
+ generate: ({ searchQuery }) => searchQuery ? {
7256
+ $or: [
7257
+ { id: { $autocomplete: searchQuery } },
7258
+ { name: { $autocomplete: searchQuery } }
7259
+ ]
7260
+ } : null
7261
+ }
7262
+ },
7263
+ ...filterBuilderOptions
7264
+ });
7010
7265
  }
7011
7266
  async query(searchQuery) {
7012
- const filters = {
7013
- $or: [
7014
- { id: { $autocomplete: searchQuery } },
7015
- { name: { $autocomplete: searchQuery } }
7016
- ],
7017
- ...this.filters
7018
- };
7267
+ const filters = this.filterBuilder.buildFilters({
7268
+ baseFilters: this.filters,
7269
+ context: { searchQuery }
7270
+ });
7019
7271
  const sort = { id: 1, ...this.sort };
7020
7272
  const options = { ...this.searchOptions, limit: this.pageSize, offset: this.offset };
7021
7273
  const { users } = await this.client.queryUsers(filters, sort, options);
@@ -7028,17 +7280,29 @@ var UserSearchSource = class extends BaseSearchSource {
7028
7280
 
7029
7281
  // src/search/ChannelSearchSource.ts
7030
7282
  var ChannelSearchSource = class extends BaseSearchSource {
7031
- constructor(client, options) {
7283
+ constructor(client, options, filterBuilderOptions = {}) {
7032
7284
  super(options);
7033
7285
  this.type = "channels";
7034
7286
  this.client = client;
7287
+ this.filterBuilder = new FilterBuilder({
7288
+ ...filterBuilderOptions,
7289
+ initialFilterConfig: {
7290
+ name: {
7291
+ enabled: true,
7292
+ generate: ({ searchQuery }) => searchQuery ? { name: { $autocomplete: searchQuery } } : null
7293
+ },
7294
+ ...filterBuilderOptions.initialFilterConfig
7295
+ }
7296
+ });
7035
7297
  }
7036
7298
  async query(searchQuery) {
7037
- const filters = {
7038
- members: { $in: [this.client.userID] },
7039
- name: { $autocomplete: searchQuery },
7040
- ...this.filters
7041
- };
7299
+ const filters = this.filterBuilder.buildFilters({
7300
+ baseFilters: {
7301
+ ...this.client.userID ? { members: { $in: [this.client.userID] } } : {},
7302
+ ...this.filters
7303
+ },
7304
+ context: { searchQuery }
7305
+ });
7042
7306
  const sort = this.sort ?? {};
7043
7307
  const options = { ...this.searchOptions, limit: this.pageSize, offset: this.offset };
7044
7308
  const items = await this.client.queryChannels(filters, sort, options);
@@ -7051,23 +7315,48 @@ var ChannelSearchSource = class extends BaseSearchSource {
7051
7315
 
7052
7316
  // src/search/MessageSearchSource.ts
7053
7317
  var MessageSearchSource = class extends BaseSearchSource {
7054
- constructor(client, options) {
7318
+ constructor(client, options, filterBuilderOptions) {
7055
7319
  super(options);
7056
7320
  this.type = "messages";
7057
7321
  this.client = client;
7322
+ this.messageSearchChannelFilterBuilder = new FilterBuilder(filterBuilderOptions?.messageSearchChannel);
7323
+ this.messageSearchFilterBuilder = new FilterBuilder({
7324
+ ...filterBuilderOptions?.messageSearch,
7325
+ initialFilterConfig: {
7326
+ text: {
7327
+ enabled: true,
7328
+ generate: ({ searchQuery }) => searchQuery ? { text: searchQuery } : null
7329
+ },
7330
+ ...filterBuilderOptions?.messageSearch?.initialFilterConfig
7331
+ }
7332
+ });
7333
+ this.channelQueryFilterBuilder = new FilterBuilder({
7334
+ ...filterBuilderOptions?.channelQuery,
7335
+ initialFilterConfig: {
7336
+ cid: {
7337
+ enabled: true,
7338
+ generate: ({ cids }) => cids ? { cid: { $in: cids } } : null
7339
+ },
7340
+ ...filterBuilderOptions?.channelQuery?.initialFilterConfig
7341
+ }
7342
+ });
7058
7343
  }
7059
7344
  async query(searchQuery) {
7060
- if (!this.client.userID) return { items: [] };
7061
- const channelFilters = {
7062
- members: { $in: [this.client.userID] },
7063
- ...this.messageSearchChannelFilters
7064
- };
7065
- const messageFilters = {
7066
- text: searchQuery,
7067
- type: "regular",
7068
- // FIXME: type: 'reply' resp. do not filter by type and allow to jump to a message in a thread - missing support
7069
- ...this.messageSearchFilters
7070
- };
7345
+ if (!this.client.userID || !searchQuery || this.next === null) return { items: [] };
7346
+ const channelFilters = this.messageSearchChannelFilterBuilder.buildFilters({
7347
+ baseFilters: {
7348
+ ...this.client.userID ? { members: { $in: [this.client.userID] } } : {},
7349
+ ...this.messageSearchChannelFilters
7350
+ },
7351
+ context: { searchQuery }
7352
+ });
7353
+ const messageFilters = this.messageSearchFilterBuilder.buildFilters({
7354
+ baseFilters: {
7355
+ type: "regular",
7356
+ ...this.messageSearchFilters
7357
+ },
7358
+ context: { searchQuery }
7359
+ });
7071
7360
  const sort = {
7072
7361
  created_at: -1,
7073
7362
  ...this.messageSearchSort
@@ -7088,15 +7377,14 @@ var MessageSearchSource = class extends BaseSearchSource {
7088
7377
  if (message.cid && !this.client.activeChannels[message.cid]) acc.add(message.cid);
7089
7378
  return acc;
7090
7379
  }, /* @__PURE__ */ new Set())
7091
- // keep the cids unique
7092
7380
  );
7093
- const allChannelsLoadedLocally = cids.length === 0;
7094
- if (!allChannelsLoadedLocally) {
7381
+ if (cids.length > 0) {
7382
+ const channelQueryFilters = this.channelQueryFilterBuilder.buildFilters({
7383
+ baseFilters: this.channelQueryFilters,
7384
+ context: { cids }
7385
+ });
7095
7386
  await this.client.queryChannels(
7096
- {
7097
- cid: { $in: cids },
7098
- ...this.channelQueryFilters
7099
- },
7387
+ channelQueryFilters,
7100
7388
  {
7101
7389
  last_message_at: -1,
7102
7390
  ...this.channelQuerySort
@@ -10494,6 +10782,15 @@ var Channel = class {
10494
10782
  }
10495
10783
  }
10496
10784
  break;
10785
+ case "user.messages.deleted":
10786
+ if (event.user) {
10787
+ this.state.deleteUserMessages(
10788
+ event.user,
10789
+ !!event.hard_delete,
10790
+ new Date(event.created_at ?? Date.now())
10791
+ );
10792
+ }
10793
+ break;
10497
10794
  case "message.new":
10498
10795
  if (event.message) {
10499
10796
  const ownMessage = event.user?.id === this.getClient().user?.id;
@@ -12096,6 +12393,54 @@ var Moderation = class {
12096
12393
  flags
12097
12394
  );
12098
12395
  }
12396
+ /**
12397
+ * Create or update a moderation rule
12398
+ * @param {ModerationRuleRequest} rule Rule configuration to be upserted
12399
+ * @returns
12400
+ */
12401
+ async upsertModerationRule(rule) {
12402
+ return await this.client.post(
12403
+ this.client.baseURL + "/api/v2/moderation/moderation_rule",
12404
+ rule
12405
+ );
12406
+ }
12407
+ /**
12408
+ * Query moderation rules
12409
+ * @param {QueryModerationRulesFilters} filterConditions Filter conditions for querying moderation rules
12410
+ * @param {QueryModerationRulesSort} sort Sort conditions for querying moderation rules
12411
+ * @param {Pager} options Pagination options for querying moderation rules
12412
+ * @returns
12413
+ */
12414
+ async queryModerationRules(filterConditions = {}, sort = [], options = {}) {
12415
+ return await this.client.post(
12416
+ this.client.baseURL + "/api/v2/moderation/moderation_rules",
12417
+ {
12418
+ filter: filterConditions,
12419
+ sort,
12420
+ ...options
12421
+ }
12422
+ );
12423
+ }
12424
+ /**
12425
+ * Get a specific moderation rule by ID
12426
+ * @param {string} id ID of the moderation rule to fetch
12427
+ * @returns
12428
+ */
12429
+ async getModerationRule(id) {
12430
+ return await this.client.get(
12431
+ this.client.baseURL + "/api/v2/moderation/moderation_rule/" + id
12432
+ );
12433
+ }
12434
+ /**
12435
+ * Delete a moderation rule by ID
12436
+ * @param {string} id ID of the moderation rule to delete
12437
+ * @returns
12438
+ */
12439
+ async deleteModerationRule(id) {
12440
+ return await this.client.delete(
12441
+ this.client.baseURL + "/api/v2/moderation/moderation_rule/" + id
12442
+ );
12443
+ }
12099
12444
  };
12100
12445
 
12101
12446
  // src/thread_manager.ts
@@ -13412,162 +13757,6 @@ _Reminder.toStateValue = (data) => ({
13412
13757
  });
13413
13758
  var Reminder = _Reminder;
13414
13759
 
13415
- // src/pagination/BasePaginator.ts
13416
- var DEFAULT_PAGINATION_OPTIONS = {
13417
- debounceMs: 300,
13418
- pageSize: 10
13419
- };
13420
- var BasePaginator = class {
13421
- constructor(options) {
13422
- this._isCursorPagination = false;
13423
- this.setDebounceOptions = ({ debounceMs }) => {
13424
- this._executeQueryDebounced = debounce(this.executeQuery.bind(this), debounceMs);
13425
- };
13426
- this.canExecuteQuery = (direction) => !this.isLoading && direction === "next" && this.hasNext || direction === "prev" && this.hasPrev;
13427
- this.next = () => this.executeQuery({ direction: "next" });
13428
- this.prev = () => this.executeQuery({ direction: "prev" });
13429
- this.nextDebounced = () => {
13430
- this._executeQueryDebounced({ direction: "next" });
13431
- };
13432
- this.prevDebounced = () => {
13433
- this._executeQueryDebounced({ direction: "prev" });
13434
- };
13435
- const { debounceMs, pageSize } = { ...DEFAULT_PAGINATION_OPTIONS, ...options };
13436
- this.pageSize = pageSize;
13437
- this.state = new StateStore(this.initialState);
13438
- this.setDebounceOptions({ debounceMs });
13439
- }
13440
- get lastQueryError() {
13441
- return this.state.getLatestValue().lastQueryError;
13442
- }
13443
- get hasNext() {
13444
- return this.state.getLatestValue().hasNext;
13445
- }
13446
- get hasPrev() {
13447
- return this.state.getLatestValue().hasPrev;
13448
- }
13449
- get hasResults() {
13450
- return Array.isArray(this.state.getLatestValue().items);
13451
- }
13452
- get isLoading() {
13453
- return this.state.getLatestValue().isLoading;
13454
- }
13455
- get initialState() {
13456
- return {
13457
- hasNext: true,
13458
- hasPrev: true,
13459
- //todo: check if optimistic value does not cause problems in UI
13460
- isLoading: false,
13461
- items: void 0,
13462
- lastQueryError: void 0,
13463
- cursor: void 0,
13464
- offset: 0
13465
- };
13466
- }
13467
- get items() {
13468
- return this.state.getLatestValue().items;
13469
- }
13470
- get cursor() {
13471
- return this.state.getLatestValue().cursor;
13472
- }
13473
- get offset() {
13474
- return this.state.getLatestValue().offset;
13475
- }
13476
- getStateBeforeFirstQuery() {
13477
- return {
13478
- ...this.initialState,
13479
- isLoading: true
13480
- };
13481
- }
13482
- getStateAfterQuery(stateUpdate, isFirstPage) {
13483
- const current = this.state.getLatestValue();
13484
- return {
13485
- ...current,
13486
- lastQueryError: void 0,
13487
- // reset lastQueryError that can be overridden by the stateUpdate
13488
- ...stateUpdate,
13489
- isLoading: false,
13490
- items: isFirstPage ? stateUpdate.items : [...this.items ?? [], ...stateUpdate.items || []]
13491
- };
13492
- }
13493
- async executeQuery({ direction }) {
13494
- if (!this.canExecuteQuery(direction)) return;
13495
- const isFirstPage = typeof this.items === "undefined";
13496
- if (isFirstPage) {
13497
- this.state.next(this.getStateBeforeFirstQuery());
13498
- } else {
13499
- this.state.partialNext({ isLoading: true });
13500
- }
13501
- const stateUpdate = {};
13502
- try {
13503
- const results = await this.query({ direction });
13504
- if (!results) return;
13505
- const { items, next, prev } = results;
13506
- if (isFirstPage && (next || prev)) {
13507
- this._isCursorPagination = true;
13508
- }
13509
- if (this._isCursorPagination) {
13510
- stateUpdate.cursor = { next: next || null, prev: prev || null };
13511
- stateUpdate.hasNext = !!next;
13512
- stateUpdate.hasPrev = !!prev;
13513
- } else {
13514
- stateUpdate.offset = (this.offset ?? 0) + items.length;
13515
- stateUpdate.hasNext = items.length === this.pageSize;
13516
- }
13517
- stateUpdate.items = await this.filterQueryResults(items);
13518
- } catch (e) {
13519
- stateUpdate.lastQueryError = e;
13520
- } finally {
13521
- this.state.next(this.getStateAfterQuery(stateUpdate, isFirstPage));
13522
- }
13523
- }
13524
- cancelScheduledQuery() {
13525
- this._executeQueryDebounced.cancel();
13526
- }
13527
- resetState() {
13528
- this.state.next(this.initialState);
13529
- }
13530
- };
13531
-
13532
- // src/pagination/ReminderPaginator.ts
13533
- var ReminderPaginator = class extends BasePaginator {
13534
- constructor(client, options) {
13535
- super(options);
13536
- this.query = async ({
13537
- direction
13538
- }) => {
13539
- const cursor = this.cursor?.[direction];
13540
- const {
13541
- reminders: items,
13542
- next,
13543
- prev
13544
- } = await this.client.queryReminders({
13545
- filter: this.filters,
13546
- sort: this.sort,
13547
- limit: this.pageSize,
13548
- [direction]: cursor
13549
- });
13550
- return { items, next, prev };
13551
- };
13552
- this.filterQueryResults = (items) => items;
13553
- this.client = client;
13554
- }
13555
- get filters() {
13556
- return this._filters;
13557
- }
13558
- get sort() {
13559
- return this._sort;
13560
- }
13561
- set filters(filters) {
13562
- this._filters = filters;
13563
- this.resetState();
13564
- }
13565
- set sort(sort) {
13566
- this._sort = sort;
13567
- this.resetState();
13568
- }
13569
- };
13570
-
13571
13760
  // src/reminders/ReminderManager.ts
13572
13761
  var oneMinute2 = 60 * 1e3;
13573
13762
  var oneHour2 = 60 * oneMinute2;
@@ -14130,13 +14319,13 @@ var StreamChat = class _StreamChat {
14130
14319
  * @param {UserResponse} user
14131
14320
  * @param {boolean} hardDelete
14132
14321
  */
14133
- this._deleteUserMessageReference = (user, hardDelete = false) => {
14322
+ this._deleteUserMessageReference = (user, hardDelete = false, deletedAt) => {
14134
14323
  const refMap = this.state.userChannelReferences[user.id] || {};
14135
14324
  for (const channelID in refMap) {
14136
14325
  const channel = this.activeChannels[channelID];
14137
14326
  if (channel) {
14138
14327
  const state = channel.state;
14139
- state?.deleteUserMessages(user, hardDelete);
14328
+ state?.deleteUserMessages(user, hardDelete, deletedAt);
14140
14329
  }
14141
14330
  }
14142
14331
  };
@@ -14182,7 +14371,11 @@ var StreamChat = class _StreamChat {
14182
14371
  this._updateUserMessageReferences(event.user);
14183
14372
  }
14184
14373
  if (event.type === "user.deleted" && event.user.deleted_at && (event.mark_messages_deleted || event.hard_delete)) {
14185
- this._deleteUserMessageReference(event.user, event.hard_delete);
14374
+ this._deleteUserMessageReference(
14375
+ event.user,
14376
+ event.hard_delete,
14377
+ event.user.deleted_at ? new Date(event.user.deleted_at) : null
14378
+ );
14186
14379
  }
14187
14380
  };
14188
14381
  this._callClientListeners = (event) => {
@@ -14752,6 +14945,13 @@ var StreamChat = class _StreamChat {
14752
14945
  if (event.type === "user.presence.changed" || event.type === "user.updated" || event.type === "user.deleted") {
14753
14946
  this._handleUserEvent(event);
14754
14947
  }
14948
+ if (event.type === "user.messages.deleted" && !event.cid && event.user) {
14949
+ this._deleteUserMessageReference(
14950
+ event.user,
14951
+ event.hard_delete,
14952
+ event.created_at ? new Date(event.created_at) : null
14953
+ );
14954
+ }
14755
14955
  if (event.type === "health.check" && event.me) {
14756
14956
  client.user = event.me;
14757
14957
  client.state.updateUser(event.me);
@@ -16012,7 +16212,7 @@ var StreamChat = class _StreamChat {
16012
16212
  if (this.userAgent) {
16013
16213
  return this.userAgent;
16014
16214
  }
16015
- const version = "9.16.0";
16215
+ const version = "9.18.0";
16016
16216
  const clientBundle = "browser-cjs";
16017
16217
  let userAgentString = "";
16018
16218
  if (this.sdkIdentifier) {
@@ -17210,6 +17410,7 @@ var EVENT_MAP = {
17210
17410
  "typing.stop": true,
17211
17411
  "user.banned": true,
17212
17412
  "user.deleted": true,
17413
+ "user.messages.deleted": true,
17213
17414
  "user.presence.changed": true,
17214
17415
  "user.unbanned": true,
17215
17416
  "user.unread_message_reminder": true,