stream-chat 9.24.0 → 9.26.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.
@@ -1181,10 +1181,8 @@ var ChannelState = class {
1181
1181
  if (initializing && message.id && this.threads[message.id]) {
1182
1182
  delete this.threads[message.id];
1183
1183
  }
1184
- if (!this.last_message_at) {
1185
- this.last_message_at = new Date(message.created_at.getTime());
1186
- }
1187
- if (message.created_at.getTime() > this.last_message_at.getTime()) {
1184
+ const shouldSkipLastMessageAtUpdate = this._channel.getConfig()?.skip_last_msg_update_for_system_msgs && message.type === "system";
1185
+ if (!shouldSkipLastMessageAtUpdate && (!this.last_message_at || message.created_at.getTime() > this.last_message_at.getTime())) {
1188
1186
  this.last_message_at = new Date(message.created_at.getTime());
1189
1187
  }
1190
1188
  }
@@ -4470,6 +4468,62 @@ var createActiveCommandGuardMiddleware = () => ({
4470
4468
  id: "stream-io/text-composer/active-command-guard"
4471
4469
  });
4472
4470
 
4471
+ // src/errors.ts
4472
+ var APIErrorCodes = {
4473
+ "-1": { name: "InternalSystemError", retryable: true },
4474
+ "2": { name: "AccessKeyError", retryable: false },
4475
+ "3": { name: "AuthenticationFailedError", retryable: true },
4476
+ "4": { name: "InputError", retryable: false },
4477
+ "6": { name: "DuplicateUsernameError", retryable: false },
4478
+ "9": { name: "RateLimitError", retryable: true },
4479
+ "16": { name: "DoesNotExistError", retryable: false },
4480
+ "17": { name: "NotAllowedError", retryable: false },
4481
+ "18": { name: "EventNotSupportedError", retryable: false },
4482
+ "19": { name: "ChannelFeatureNotSupportedError", retryable: false },
4483
+ "20": { name: "MessageTooLongError", retryable: false },
4484
+ "21": { name: "MultipleNestingLevelError", retryable: false },
4485
+ "22": { name: "PayloadTooBigError", retryable: false },
4486
+ "23": { name: "RequestTimeoutError", retryable: true },
4487
+ "24": { name: "MaxHeaderSizeExceededError", retryable: false },
4488
+ "40": { name: "AuthErrorTokenExpired", retryable: false },
4489
+ "41": { name: "AuthErrorTokenNotValidYet", retryable: false },
4490
+ "42": { name: "AuthErrorTokenUsedBeforeIssuedAt", retryable: false },
4491
+ "43": { name: "AuthErrorTokenSignatureInvalid", retryable: false },
4492
+ "44": { name: "CustomCommandEndpointMissingError", retryable: false },
4493
+ "45": { name: "CustomCommandEndpointCallError", retryable: true },
4494
+ "46": { name: "ConnectionIDNotFoundError", retryable: false },
4495
+ "60": { name: "CoolDownError", retryable: true },
4496
+ "69": { name: "ErrWrongRegion", retryable: false },
4497
+ "70": { name: "ErrQueryChannelPermissions", retryable: false },
4498
+ "71": { name: "ErrTooManyConnections", retryable: true },
4499
+ "99": { name: "AppSuspendedError", retryable: false }
4500
+ };
4501
+ function isAPIError(error) {
4502
+ return error.code !== void 0;
4503
+ }
4504
+ function isErrorRetryable(error) {
4505
+ if (!error.code) return false;
4506
+ const err = APIErrorCodes[`${error.code}`];
4507
+ if (!err) return false;
4508
+ return err.retryable;
4509
+ }
4510
+ function isConnectionIDError(error) {
4511
+ return error.code === 46;
4512
+ }
4513
+ function isWSFailure(err) {
4514
+ if (typeof err.isWSFailure === "boolean") {
4515
+ return err.isWSFailure;
4516
+ }
4517
+ try {
4518
+ return JSON.parse(err.message).isWSFailure;
4519
+ } catch (_) {
4520
+ return false;
4521
+ }
4522
+ }
4523
+ function isErrorResponse(res) {
4524
+ return !res.status || res.status < 200 || 300 <= res.status;
4525
+ }
4526
+
4473
4527
  // src/search/BaseSearchSource.ts
4474
4528
  var DEFAULT_SEARCH_SOURCE_OPTIONS = {
4475
4529
  debounceMs: 300,
@@ -4604,6 +4658,9 @@ var BaseSearchSource = class extends BaseSearchSourceBase {
4604
4658
  stateUpdate.items = await this.filterQueryResults(items);
4605
4659
  } catch (e) {
4606
4660
  stateUpdate.lastQueryError = e;
4661
+ if (isAPIError(e) && !isErrorRetryable(e)) {
4662
+ stateUpdate.hasNext = false;
4663
+ }
4607
4664
  } finally {
4608
4665
  this.state.next(this.getStateAfterQuery(stateUpdate, hasNewSearchQuery));
4609
4666
  }
@@ -4634,6 +4691,9 @@ var BaseSearchSourceSync = class extends BaseSearchSourceBase {
4634
4691
  stateUpdate.items = this.filterQueryResults(items);
4635
4692
  } catch (e) {
4636
4693
  stateUpdate.lastQueryError = e;
4694
+ if (isAPIError(e) && !isErrorRetryable(e)) {
4695
+ stateUpdate.hasNext = false;
4696
+ }
4637
4697
  } finally {
4638
4698
  this.state.next(this.getStateAfterQuery(stateUpdate, hasNewSearchQuery));
4639
4699
  }
@@ -6995,7 +7055,7 @@ var MARK_AS_DELIVERED_BUFFER_TIMEOUT = 1e3;
6995
7055
  var MARK_AS_READ_THROTTLE_TIMEOUT2 = 1e3;
6996
7056
  var isChannel = (item) => item instanceof Channel;
6997
7057
  var isThread = (item) => item instanceof Thread;
6998
- var MessageDeliveryReporter = class {
7058
+ var MessageDeliveryReporter = class _MessageDeliveryReporter {
6999
7059
  constructor({ client }) {
7000
7060
  this.deliveryReportCandidates = /* @__PURE__ */ new Map();
7001
7061
  this.nextDeliveryReportCandidates = /* @__PURE__ */ new Map();
@@ -7109,6 +7169,10 @@ var MessageDeliveryReporter = class {
7109
7169
  get hasDeliveryCandidates() {
7110
7170
  return this.deliveryReportCandidates.size > 0;
7111
7171
  }
7172
+ static hasPermissionToReportDeliveryFor(collection) {
7173
+ if (isChannel(collection)) return !!collection.getConfig()?.delivery_events;
7174
+ if (isThread(collection)) return !!collection.channel.getConfig()?.delivery_events;
7175
+ }
7112
7176
  /**
7113
7177
  * Build latest_delivered_messages payload from an arbitrary buffer (deliveryReportCandidates / nextDeliveryReportCandidates)
7114
7178
  */
@@ -7140,8 +7204,7 @@ var MessageDeliveryReporter = class {
7140
7204
  * @param collection
7141
7205
  */
7142
7206
  trackDeliveredCandidate(collection) {
7143
- if (isChannel(collection) && !collection.getConfig()?.read_events) return;
7144
- if (isThread(collection) && !collection.channel.getConfig()?.read_events) return;
7207
+ if (!_MessageDeliveryReporter.hasPermissionToReportDeliveryFor(collection)) return;
7145
7208
  const candidate = this.getNextDeliveryReportCandidate(collection);
7146
7209
  if (!candidate?.key) return;
7147
7210
  const buffer = this.markDeliveredRequestInFlight ? this.nextDeliveryReportCandidates : this.deliveryReportCandidates;
@@ -8013,6 +8076,28 @@ var Channel = class {
8013
8076
  async addMembers(members, message, options = {}) {
8014
8077
  return await this._update({ add_members: members, message, ...options });
8015
8078
  }
8079
+ /**
8080
+ * addFilterTags - add filter tags to the channel
8081
+ *
8082
+ * @param {string[]} tags An array of tags to add to the channel
8083
+ * @param {Message} [message] Optional message object for channel members notification
8084
+ * @param {ChannelUpdateOptions} [options] Option object, configuration to control the behavior while updating
8085
+ * @return {Promise<UpdateChannelAPIResponse>} The server response
8086
+ */
8087
+ async addFilterTags(tags, message, options = {}) {
8088
+ return await this._update({ add_filter_tags: tags, message, ...options });
8089
+ }
8090
+ /**
8091
+ * removeFilterTags - remove filter tags from the channel
8092
+ *
8093
+ * @param {string[]} tags An array of tags to remove from the channel
8094
+ * @param {Message} [message] Optional message object for channel members notification
8095
+ * @param {ChannelUpdateOptions} [options] Option object, configuration to control the behavior while updating
8096
+ * @return {Promise<UpdateChannelAPIResponse>} The server response
8097
+ */
8098
+ async removeFilterTags(tags, message, options = {}) {
8099
+ return await this._update({ remove_filter_tags: tags, message, ...options });
8100
+ }
8016
8101
  /**
8017
8102
  * addModerators - add moderators to the channel
8018
8103
  *
@@ -8956,6 +9041,11 @@ var Channel = class {
8956
9041
  deliveredAt: event.created_at,
8957
9042
  lastDeliveredMessageId: event.last_delivered_message_id
8958
9043
  });
9044
+ const client = this.getClient();
9045
+ const isOwnEvent = event.user?.id === client.user?.id;
9046
+ if (isOwnEvent) {
9047
+ client.syncDeliveredCandidates([this]);
9048
+ }
8959
9049
  }
8960
9050
  break;
8961
9051
  case "user.watching.start":
@@ -10059,64 +10149,6 @@ var TokenManager = class {
10059
10149
 
10060
10150
  // src/connection_fallback.ts
10061
10151
  import axios2 from "axios";
10062
-
10063
- // src/errors.ts
10064
- var APIErrorCodes = {
10065
- "-1": { name: "InternalSystemError", retryable: true },
10066
- "2": { name: "AccessKeyError", retryable: false },
10067
- "3": { name: "AuthenticationFailedError", retryable: true },
10068
- "4": { name: "InputError", retryable: false },
10069
- "6": { name: "DuplicateUsernameError", retryable: false },
10070
- "9": { name: "RateLimitError", retryable: true },
10071
- "16": { name: "DoesNotExistError", retryable: false },
10072
- "17": { name: "NotAllowedError", retryable: false },
10073
- "18": { name: "EventNotSupportedError", retryable: false },
10074
- "19": { name: "ChannelFeatureNotSupportedError", retryable: false },
10075
- "20": { name: "MessageTooLongError", retryable: false },
10076
- "21": { name: "MultipleNestingLevelError", retryable: false },
10077
- "22": { name: "PayloadTooBigError", retryable: false },
10078
- "23": { name: "RequestTimeoutError", retryable: true },
10079
- "24": { name: "MaxHeaderSizeExceededError", retryable: false },
10080
- "40": { name: "AuthErrorTokenExpired", retryable: false },
10081
- "41": { name: "AuthErrorTokenNotValidYet", retryable: false },
10082
- "42": { name: "AuthErrorTokenUsedBeforeIssuedAt", retryable: false },
10083
- "43": { name: "AuthErrorTokenSignatureInvalid", retryable: false },
10084
- "44": { name: "CustomCommandEndpointMissingError", retryable: false },
10085
- "45": { name: "CustomCommandEndpointCallError", retryable: true },
10086
- "46": { name: "ConnectionIDNotFoundError", retryable: false },
10087
- "60": { name: "CoolDownError", retryable: true },
10088
- "69": { name: "ErrWrongRegion", retryable: false },
10089
- "70": { name: "ErrQueryChannelPermissions", retryable: false },
10090
- "71": { name: "ErrTooManyConnections", retryable: true },
10091
- "99": { name: "AppSuspendedError", retryable: false }
10092
- };
10093
- function isAPIError(error) {
10094
- return error.code !== void 0;
10095
- }
10096
- function isErrorRetryable(error) {
10097
- if (!error.code) return false;
10098
- const err = APIErrorCodes[`${error.code}`];
10099
- if (!err) return false;
10100
- return err.retryable;
10101
- }
10102
- function isConnectionIDError(error) {
10103
- return error.code === 46;
10104
- }
10105
- function isWSFailure(err) {
10106
- if (typeof err.isWSFailure === "boolean") {
10107
- return err.isWSFailure;
10108
- }
10109
- try {
10110
- return JSON.parse(err.message).isWSFailure;
10111
- } catch (_) {
10112
- return false;
10113
- }
10114
- }
10115
- function isErrorResponse(res) {
10116
- return !res.status || res.status < 200 || 300 <= res.status;
10117
- }
10118
-
10119
- // src/connection_fallback.ts
10120
10152
  var WSConnectionFallback = class {
10121
10153
  constructor({ client }) {
10122
10154
  /** @private */
@@ -14458,7 +14490,7 @@ var StreamChat = class _StreamChat {
14458
14490
  if (this.userAgent) {
14459
14491
  return this.userAgent;
14460
14492
  }
14461
- const version = "9.24.0";
14493
+ const version = "9.26.0";
14462
14494
  const clientBundle = "browser-esm";
14463
14495
  let userAgentString = "";
14464
14496
  if (this.sdkIdentifier) {
@@ -15607,17 +15639,14 @@ var StreamChat = class _StreamChat {
15607
15639
  return this.delete(`${this.baseURL}/uploads/image`, { url });
15608
15640
  }
15609
15641
  /**
15610
- * Send the mark delivered event for this user
15642
+ * Mark the channels delivered for the given messages and the user
15611
15643
  *
15612
15644
  * @param {MarkDeliveredOptions} data
15613
15645
  * @return {Promise<EventAPIResponse | void>} Description
15614
15646
  */
15615
15647
  async markChannelsDelivered(data) {
15616
15648
  if (!data?.latest_delivered_messages?.length) return;
15617
- return await this.post(
15618
- this.baseURL + "/channels/delivered",
15619
- data ?? {}
15620
- );
15649
+ return await this.post(this.baseURL + "/channels/delivered", data);
15621
15650
  }
15622
15651
  syncDeliveredCandidates(collections) {
15623
15652
  this.messageDeliveryReporter.syncDeliveredCandidates(collections);