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.
@@ -1341,10 +1341,8 @@ var ChannelState = class {
1341
1341
  if (initializing && message.id && this.threads[message.id]) {
1342
1342
  delete this.threads[message.id];
1343
1343
  }
1344
- if (!this.last_message_at) {
1345
- this.last_message_at = new Date(message.created_at.getTime());
1346
- }
1347
- if (message.created_at.getTime() > this.last_message_at.getTime()) {
1344
+ const shouldSkipLastMessageAtUpdate = this._channel.getConfig()?.skip_last_msg_update_for_system_msgs && message.type === "system";
1345
+ if (!shouldSkipLastMessageAtUpdate && (!this.last_message_at || message.created_at.getTime() > this.last_message_at.getTime())) {
1348
1346
  this.last_message_at = new Date(message.created_at.getTime());
1349
1347
  }
1350
1348
  }
@@ -4630,6 +4628,62 @@ var createActiveCommandGuardMiddleware = () => ({
4630
4628
  id: "stream-io/text-composer/active-command-guard"
4631
4629
  });
4632
4630
 
4631
+ // src/errors.ts
4632
+ var APIErrorCodes = {
4633
+ "-1": { name: "InternalSystemError", retryable: true },
4634
+ "2": { name: "AccessKeyError", retryable: false },
4635
+ "3": { name: "AuthenticationFailedError", retryable: true },
4636
+ "4": { name: "InputError", retryable: false },
4637
+ "6": { name: "DuplicateUsernameError", retryable: false },
4638
+ "9": { name: "RateLimitError", retryable: true },
4639
+ "16": { name: "DoesNotExistError", retryable: false },
4640
+ "17": { name: "NotAllowedError", retryable: false },
4641
+ "18": { name: "EventNotSupportedError", retryable: false },
4642
+ "19": { name: "ChannelFeatureNotSupportedError", retryable: false },
4643
+ "20": { name: "MessageTooLongError", retryable: false },
4644
+ "21": { name: "MultipleNestingLevelError", retryable: false },
4645
+ "22": { name: "PayloadTooBigError", retryable: false },
4646
+ "23": { name: "RequestTimeoutError", retryable: true },
4647
+ "24": { name: "MaxHeaderSizeExceededError", retryable: false },
4648
+ "40": { name: "AuthErrorTokenExpired", retryable: false },
4649
+ "41": { name: "AuthErrorTokenNotValidYet", retryable: false },
4650
+ "42": { name: "AuthErrorTokenUsedBeforeIssuedAt", retryable: false },
4651
+ "43": { name: "AuthErrorTokenSignatureInvalid", retryable: false },
4652
+ "44": { name: "CustomCommandEndpointMissingError", retryable: false },
4653
+ "45": { name: "CustomCommandEndpointCallError", retryable: true },
4654
+ "46": { name: "ConnectionIDNotFoundError", retryable: false },
4655
+ "60": { name: "CoolDownError", retryable: true },
4656
+ "69": { name: "ErrWrongRegion", retryable: false },
4657
+ "70": { name: "ErrQueryChannelPermissions", retryable: false },
4658
+ "71": { name: "ErrTooManyConnections", retryable: true },
4659
+ "99": { name: "AppSuspendedError", retryable: false }
4660
+ };
4661
+ function isAPIError(error) {
4662
+ return error.code !== void 0;
4663
+ }
4664
+ function isErrorRetryable(error) {
4665
+ if (!error.code) return false;
4666
+ const err = APIErrorCodes[`${error.code}`];
4667
+ if (!err) return false;
4668
+ return err.retryable;
4669
+ }
4670
+ function isConnectionIDError(error) {
4671
+ return error.code === 46;
4672
+ }
4673
+ function isWSFailure(err) {
4674
+ if (typeof err.isWSFailure === "boolean") {
4675
+ return err.isWSFailure;
4676
+ }
4677
+ try {
4678
+ return JSON.parse(err.message).isWSFailure;
4679
+ } catch (_) {
4680
+ return false;
4681
+ }
4682
+ }
4683
+ function isErrorResponse(res) {
4684
+ return !res.status || res.status < 200 || 300 <= res.status;
4685
+ }
4686
+
4633
4687
  // src/search/BaseSearchSource.ts
4634
4688
  var DEFAULT_SEARCH_SOURCE_OPTIONS = {
4635
4689
  debounceMs: 300,
@@ -4764,6 +4818,9 @@ var BaseSearchSource = class extends BaseSearchSourceBase {
4764
4818
  stateUpdate.items = await this.filterQueryResults(items);
4765
4819
  } catch (e) {
4766
4820
  stateUpdate.lastQueryError = e;
4821
+ if (isAPIError(e) && !isErrorRetryable(e)) {
4822
+ stateUpdate.hasNext = false;
4823
+ }
4767
4824
  } finally {
4768
4825
  this.state.next(this.getStateAfterQuery(stateUpdate, hasNewSearchQuery));
4769
4826
  }
@@ -4794,6 +4851,9 @@ var BaseSearchSourceSync = class extends BaseSearchSourceBase {
4794
4851
  stateUpdate.items = this.filterQueryResults(items);
4795
4852
  } catch (e) {
4796
4853
  stateUpdate.lastQueryError = e;
4854
+ if (isAPIError(e) && !isErrorRetryable(e)) {
4855
+ stateUpdate.hasNext = false;
4856
+ }
4797
4857
  } finally {
4798
4858
  this.state.next(this.getStateAfterQuery(stateUpdate, hasNewSearchQuery));
4799
4859
  }
@@ -7155,7 +7215,7 @@ var MARK_AS_DELIVERED_BUFFER_TIMEOUT = 1e3;
7155
7215
  var MARK_AS_READ_THROTTLE_TIMEOUT2 = 1e3;
7156
7216
  var isChannel = (item) => item instanceof Channel;
7157
7217
  var isThread = (item) => item instanceof Thread;
7158
- var MessageDeliveryReporter = class {
7218
+ var MessageDeliveryReporter = class _MessageDeliveryReporter {
7159
7219
  constructor({ client }) {
7160
7220
  this.deliveryReportCandidates = /* @__PURE__ */ new Map();
7161
7221
  this.nextDeliveryReportCandidates = /* @__PURE__ */ new Map();
@@ -7269,6 +7329,10 @@ var MessageDeliveryReporter = class {
7269
7329
  get hasDeliveryCandidates() {
7270
7330
  return this.deliveryReportCandidates.size > 0;
7271
7331
  }
7332
+ static hasPermissionToReportDeliveryFor(collection) {
7333
+ if (isChannel(collection)) return !!collection.getConfig()?.delivery_events;
7334
+ if (isThread(collection)) return !!collection.channel.getConfig()?.delivery_events;
7335
+ }
7272
7336
  /**
7273
7337
  * Build latest_delivered_messages payload from an arbitrary buffer (deliveryReportCandidates / nextDeliveryReportCandidates)
7274
7338
  */
@@ -7300,8 +7364,7 @@ var MessageDeliveryReporter = class {
7300
7364
  * @param collection
7301
7365
  */
7302
7366
  trackDeliveredCandidate(collection) {
7303
- if (isChannel(collection) && !collection.getConfig()?.read_events) return;
7304
- if (isThread(collection) && !collection.channel.getConfig()?.read_events) return;
7367
+ if (!_MessageDeliveryReporter.hasPermissionToReportDeliveryFor(collection)) return;
7305
7368
  const candidate = this.getNextDeliveryReportCandidate(collection);
7306
7369
  if (!candidate?.key) return;
7307
7370
  const buffer = this.markDeliveredRequestInFlight ? this.nextDeliveryReportCandidates : this.deliveryReportCandidates;
@@ -8173,6 +8236,28 @@ var Channel = class {
8173
8236
  async addMembers(members, message, options = {}) {
8174
8237
  return await this._update({ add_members: members, message, ...options });
8175
8238
  }
8239
+ /**
8240
+ * addFilterTags - add filter tags to the channel
8241
+ *
8242
+ * @param {string[]} tags An array of tags to add to the channel
8243
+ * @param {Message} [message] Optional message object for channel members notification
8244
+ * @param {ChannelUpdateOptions} [options] Option object, configuration to control the behavior while updating
8245
+ * @return {Promise<UpdateChannelAPIResponse>} The server response
8246
+ */
8247
+ async addFilterTags(tags, message, options = {}) {
8248
+ return await this._update({ add_filter_tags: tags, message, ...options });
8249
+ }
8250
+ /**
8251
+ * removeFilterTags - remove filter tags from the channel
8252
+ *
8253
+ * @param {string[]} tags An array of tags to remove from the channel
8254
+ * @param {Message} [message] Optional message object for channel members notification
8255
+ * @param {ChannelUpdateOptions} [options] Option object, configuration to control the behavior while updating
8256
+ * @return {Promise<UpdateChannelAPIResponse>} The server response
8257
+ */
8258
+ async removeFilterTags(tags, message, options = {}) {
8259
+ return await this._update({ remove_filter_tags: tags, message, ...options });
8260
+ }
8176
8261
  /**
8177
8262
  * addModerators - add moderators to the channel
8178
8263
  *
@@ -9116,6 +9201,11 @@ var Channel = class {
9116
9201
  deliveredAt: event.created_at,
9117
9202
  lastDeliveredMessageId: event.last_delivered_message_id
9118
9203
  });
9204
+ const client = this.getClient();
9205
+ const isOwnEvent = event.user?.id === client.user?.id;
9206
+ if (isOwnEvent) {
9207
+ client.syncDeliveredCandidates([this]);
9208
+ }
9119
9209
  }
9120
9210
  break;
9121
9211
  case "user.watching.start":
@@ -10219,64 +10309,6 @@ var TokenManager = class {
10219
10309
 
10220
10310
  // src/connection_fallback.ts
10221
10311
  var import_axios2 = __toESM(require("axios"));
10222
-
10223
- // src/errors.ts
10224
- var APIErrorCodes = {
10225
- "-1": { name: "InternalSystemError", retryable: true },
10226
- "2": { name: "AccessKeyError", retryable: false },
10227
- "3": { name: "AuthenticationFailedError", retryable: true },
10228
- "4": { name: "InputError", retryable: false },
10229
- "6": { name: "DuplicateUsernameError", retryable: false },
10230
- "9": { name: "RateLimitError", retryable: true },
10231
- "16": { name: "DoesNotExistError", retryable: false },
10232
- "17": { name: "NotAllowedError", retryable: false },
10233
- "18": { name: "EventNotSupportedError", retryable: false },
10234
- "19": { name: "ChannelFeatureNotSupportedError", retryable: false },
10235
- "20": { name: "MessageTooLongError", retryable: false },
10236
- "21": { name: "MultipleNestingLevelError", retryable: false },
10237
- "22": { name: "PayloadTooBigError", retryable: false },
10238
- "23": { name: "RequestTimeoutError", retryable: true },
10239
- "24": { name: "MaxHeaderSizeExceededError", retryable: false },
10240
- "40": { name: "AuthErrorTokenExpired", retryable: false },
10241
- "41": { name: "AuthErrorTokenNotValidYet", retryable: false },
10242
- "42": { name: "AuthErrorTokenUsedBeforeIssuedAt", retryable: false },
10243
- "43": { name: "AuthErrorTokenSignatureInvalid", retryable: false },
10244
- "44": { name: "CustomCommandEndpointMissingError", retryable: false },
10245
- "45": { name: "CustomCommandEndpointCallError", retryable: true },
10246
- "46": { name: "ConnectionIDNotFoundError", retryable: false },
10247
- "60": { name: "CoolDownError", retryable: true },
10248
- "69": { name: "ErrWrongRegion", retryable: false },
10249
- "70": { name: "ErrQueryChannelPermissions", retryable: false },
10250
- "71": { name: "ErrTooManyConnections", retryable: true },
10251
- "99": { name: "AppSuspendedError", retryable: false }
10252
- };
10253
- function isAPIError(error) {
10254
- return error.code !== void 0;
10255
- }
10256
- function isErrorRetryable(error) {
10257
- if (!error.code) return false;
10258
- const err = APIErrorCodes[`${error.code}`];
10259
- if (!err) return false;
10260
- return err.retryable;
10261
- }
10262
- function isConnectionIDError(error) {
10263
- return error.code === 46;
10264
- }
10265
- function isWSFailure(err) {
10266
- if (typeof err.isWSFailure === "boolean") {
10267
- return err.isWSFailure;
10268
- }
10269
- try {
10270
- return JSON.parse(err.message).isWSFailure;
10271
- } catch (_) {
10272
- return false;
10273
- }
10274
- }
10275
- function isErrorResponse(res) {
10276
- return !res.status || res.status < 200 || 300 <= res.status;
10277
- }
10278
-
10279
- // src/connection_fallback.ts
10280
10312
  var WSConnectionFallback = class {
10281
10313
  constructor({ client }) {
10282
10314
  /** @private */
@@ -14618,7 +14650,7 @@ var StreamChat = class _StreamChat {
14618
14650
  if (this.userAgent) {
14619
14651
  return this.userAgent;
14620
14652
  }
14621
- const version = "9.24.0";
14653
+ const version = "9.26.0";
14622
14654
  const clientBundle = "node-cjs";
14623
14655
  let userAgentString = "";
14624
14656
  if (this.sdkIdentifier) {
@@ -15767,17 +15799,14 @@ var StreamChat = class _StreamChat {
15767
15799
  return this.delete(`${this.baseURL}/uploads/image`, { url });
15768
15800
  }
15769
15801
  /**
15770
- * Send the mark delivered event for this user
15802
+ * Mark the channels delivered for the given messages and the user
15771
15803
  *
15772
15804
  * @param {MarkDeliveredOptions} data
15773
15805
  * @return {Promise<EventAPIResponse | void>} Description
15774
15806
  */
15775
15807
  async markChannelsDelivered(data) {
15776
15808
  if (!data?.latest_delivered_messages?.length) return;
15777
- return await this.post(
15778
- this.baseURL + "/channels/delivered",
15779
- data ?? {}
15780
- );
15809
+ return await this.post(this.baseURL + "/channels/delivered", data);
15781
15810
  }
15782
15811
  syncDeliveredCandidates(collections) {
15783
15812
  this.messageDeliveryReporter.syncDeliveredCandidates(collections);