stream-chat 10.0.0-rc.13 → 10.0.0-rc.15

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 (57) hide show
  1. package/dist/cjs/index.browser.js +43 -21
  2. package/dist/cjs/index.browser.js.map +2 -2
  3. package/dist/cjs/index.node.js +44 -21
  4. package/dist/cjs/index.node.js.map +2 -2
  5. package/dist/esm/index.mjs +43 -21
  6. package/dist/esm/index.mjs.map +2 -2
  7. package/dist/types/CooldownTimer.d.ts +4 -3
  8. package/dist/types/channel.d.ts +16 -10
  9. package/dist/types/channel_state.d.ts +5 -5
  10. package/dist/types/client.d.ts +14 -3
  11. package/dist/types/gen/chat/ChatApi.d.ts +2 -2
  12. package/dist/types/gen/models/index.d.ts +492 -369
  13. package/dist/types/gen/models/timestamp-guard.d.ts +22 -0
  14. package/dist/types/index.d.ts +2 -1
  15. package/dist/types/messageComposer/messageComposer.d.ts +3 -3
  16. package/dist/types/messageComposer/middleware/textComposer/commands.d.ts +2 -2
  17. package/dist/types/messageComposer/middleware/textComposer/mentions.d.ts +8 -0
  18. package/dist/types/messageDelivery/MessageDeliveryReporter.d.ts +3 -2
  19. package/dist/types/messageDelivery/MessageReceiptsTracker.d.ts +8 -8
  20. package/dist/types/offline-support/types.d.ts +2 -2
  21. package/dist/types/pagination/cursorDerivation/createdAtAroundPaginationFlags.d.ts +2 -1
  22. package/dist/types/pagination/cursorDerivation/linearPaginationFlags.d.ts +2 -1
  23. package/dist/types/pagination/paginators/MessageIntervalPaginator.d.ts +6 -6
  24. package/dist/types/pagination/paginators/MessagePaginator.d.ts +5 -5
  25. package/dist/types/poll.d.ts +2 -2
  26. package/dist/types/reminders/Reminder.d.ts +6 -6
  27. package/dist/types/thread.d.ts +5 -5
  28. package/dist/types/types.d.ts +5 -11
  29. package/dist/types/utils/time.d.ts +23 -7
  30. package/dist/types/utils.d.ts +9 -9
  31. package/package.json +6 -4
  32. package/src/CooldownTimer.ts +5 -5
  33. package/src/api-client.ts +5 -2
  34. package/src/channel.ts +20 -16
  35. package/src/channel_state.ts +5 -4
  36. package/src/client.ts +19 -7
  37. package/src/configuration/shape.ts +6 -0
  38. package/src/gen/chat/ChatApi.ts +4 -2
  39. package/src/gen/models/index.ts +502 -3217
  40. package/src/gen/models/timestamp-guard.ts +27 -0
  41. package/src/gen/moderation/ModerationApi.ts +1 -0
  42. package/src/index.ts +6 -0
  43. package/src/messageComposer/messageComposer.ts +5 -1
  44. package/src/messageDelivery/MessageDeliveryReporter.ts +21 -9
  45. package/src/messageDelivery/MessageReceiptsTracker.ts +17 -13
  46. package/src/offline-support/offline_support_api.ts +10 -1
  47. package/src/offline-support/types.ts +2 -1
  48. package/src/pagination/cursorDerivation/createdAtAroundPaginationFlags.ts +2 -1
  49. package/src/pagination/cursorDerivation/linearPaginationFlags.ts +2 -2
  50. package/src/pagination/paginators/MessageIntervalPaginator.ts +6 -5
  51. package/src/pagination/paginators/MessagePaginator.ts +7 -7
  52. package/src/poll.ts +6 -2
  53. package/src/reminders/Reminder.ts +10 -5
  54. package/src/thread.ts +9 -5
  55. package/src/types.ts +5 -10
  56. package/src/utils/time.ts +27 -7
  57. package/src/utils.ts +1 -2
@@ -137,6 +137,7 @@ __export(src_exports, {
137
137
  WS_NETWORK_RECOVERY_RETRY_MS: () => WS_NETWORK_RECOVERY_RETRY_MS,
138
138
  ZERO_PAGE_CURSOR: () => ZERO_PAGE_CURSOR,
139
139
  accentsMap: () => accentsMap,
140
+ asTimestampNS: () => asTimestampNS,
140
141
  browserNetworkStatusReporter: () => browserNetworkStatusReporter,
141
142
  calculateLevenshtein: () => calculateLevenshtein,
142
143
  chatCodes: () => chatCodes,
@@ -407,8 +408,9 @@ var chatLoggerSystem = scopedLogger.createLoggerSystem();
407
408
 
408
409
  // src/utils/time.ts
409
410
  var NS_PER_MS = 1e6;
411
+ var asTimestampNS = (ns) => ns;
410
412
  var nsToMs = (ns) => Math.floor(ns / NS_PER_MS);
411
- var msToNs = (ms) => ms * NS_PER_MS;
413
+ var msToNs = (ms) => asTimestampNS(ms * NS_PER_MS);
412
414
  var nowNs = () => msToNs(Date.now());
413
415
  var nsToDate = (ns) => new Date(nsToMs(ns));
414
416
  var nsToRfc3339 = (ns) => {
@@ -550,7 +552,7 @@ var channelHasReadEvents = (channel) => {
550
552
  const ownCapabilities = channel?.data?.own_capabilities;
551
553
  return !(Array.isArray(ownCapabilities) && !ownCapabilities.includes("read-events"));
552
554
  };
553
- var channelTracksReadLocally = (channel) => !channelHasReadEvents(channel) && !!channel?.getClient().options.isLocalUnreadCountEnabled;
555
+ var channelTracksReadLocally = (channel) => !channelHasReadEvents(channel) && !!channel?.config.readEvents.localUnreadCountEnabled;
554
556
  function retryInterval(numberOfFailures) {
555
557
  const max = Math.min(500 + numberOfFailures * 2e3, 25e3);
556
558
  const min = Math.min(Math.max(250, (numberOfFailures - 1) * 2e3), 25e3);
@@ -8663,7 +8665,7 @@ var MessagePaginator = class extends MessageIntervalPaginator {
8663
8665
  const { lastMessage, seededLastMessageAt } = this.aggregateState.getLatestValue();
8664
8666
  const fromMessage = getMessageCreatedAtTimestamp(lastMessage);
8665
8667
  if (fromMessage !== null && seededLastMessageAt !== null) {
8666
- return Math.max(fromMessage, seededLastMessageAt);
8668
+ return asTimestampNS(Math.max(fromMessage, seededLastMessageAt));
8667
8669
  }
8668
8670
  return fromMessage ?? seededLastMessageAt;
8669
8671
  }
@@ -14476,11 +14478,12 @@ var MessageDeliveryReporter = class _MessageDeliveryReporter {
14476
14478
  }, this.requestTimeoutMs);
14477
14479
  };
14478
14480
  /**
14479
- * Delegates the mark-read call to the Channel or Thread instance.
14481
+ * Delegates the mark-read call to the Channel or Thread instance. A channel whose read events are
14482
+ * disabled is marked read locally instead, when the client opted into counting unread itself.
14480
14483
  *
14481
14484
  * @param collection - The channel or thread to mark as read.
14482
14485
  * @param options - Flags forwarded to the underlying `markRead` call (optional).
14483
- * @returns The server response, or `null` when the collection is unsupported.
14486
+ * @returns The server response, or `null` when no request went out.
14484
14487
  */
14485
14488
  this.markRead = async (collection, options) => {
14486
14489
  const isThreadCollection = isThread(collection);
@@ -14494,8 +14497,15 @@ var MessageDeliveryReporter = class _MessageDeliveryReporter {
14494
14497
  thread: collection
14495
14498
  }) ?? null : await channel.markRead(requestOptions);
14496
14499
  } else {
14497
- const markReadRequestHandler = channel.configState.getLatestValue().requestHandlers?.markReadRequest;
14498
- result = markReadRequestHandler ? await markReadRequestHandler({ channel, options: requestOptions }) ?? null : await channel.markRead(requestOptions);
14500
+ const { readEvents, requestHandlers } = channel.configState.getLatestValue();
14501
+ const markReadRequestHandler = requestHandlers?.markReadRequest;
14502
+ if (markReadRequestHandler) {
14503
+ result = await markReadRequestHandler({ channel, options: requestOptions }) ?? null;
14504
+ } else if (!readEvents.enabled && readEvents.localUnreadCountEnabled) {
14505
+ channel.markReadLocally();
14506
+ } else {
14507
+ result = await channel.markRead(requestOptions);
14508
+ }
14499
14509
  }
14500
14510
  if (result) this.removeCandidateFor(collection);
14501
14511
  return result;
@@ -14669,7 +14679,10 @@ var MessageDeliveryReporter = class _MessageDeliveryReporter {
14669
14679
 
14670
14680
  // src/messageDelivery/MessageReceiptsTracker.ts
14671
14681
  var import_state_store20 = require("@stream-io/state-store");
14672
- var MIN_REF = { timestamp: Number.NEGATIVE_INFINITY, msgId: "" };
14682
+ var MIN_REF = {
14683
+ timestamp: asTimestampNS(Number.NEGATIVE_INFINITY),
14684
+ msgId: ""
14685
+ };
14673
14686
  var isValidReadState = (readState) => !!readState?.user && Number.isFinite(readState.last_read);
14674
14687
  var compareRefsAsc = (a, b) => a.timestamp !== b.timestamp ? a.timestamp - b.timestamp : 0;
14675
14688
  var findIndex = (arr, target, keyOf) => {
@@ -15446,7 +15459,7 @@ var ownDeclarativeConfig = (slice) => {
15446
15459
  var DEFAULT_CHANNEL_CONFIG = deepFreezeConfig({
15447
15460
  availableCommands: [],
15448
15461
  deliveryEvents: { enabled: true },
15449
- readEvents: { enabled: true },
15462
+ readEvents: { enabled: true, localUnreadCountEnabled: false },
15450
15463
  replies: { enabled: true },
15451
15464
  typingEvents: { enabled: true },
15452
15465
  userMessageReminders: { enabled: true }
@@ -16200,7 +16213,7 @@ var Channel = class extends WithMessageOperations(ChannelApi) {
16200
16213
  /**
16201
16214
  * Returns the mute status for the current channel.
16202
16215
  *
16203
- * @returns An object of the form `{ muted: true | false, createdAt: number | null, expiresAt: number | null }`,
16216
+ * @returns An object of the form `{ muted: true | false, createdAt: TimestampNS | null, expiresAt: TimestampNS | null }`,
16204
16217
  * where the timestamps are unix nanoseconds as the API sends them.
16205
16218
  */
16206
16219
  muteStatus() {
@@ -16473,7 +16486,7 @@ var Channel = class extends WithMessageOperations(ChannelApi) {
16473
16486
  /**
16474
16487
  * Resets this user's unread count locally, without any backend call. Intended for
16475
16488
  * channels that have read events disabled (e.g. livestreams) when the client is created with the
16476
- * `isLocalUnreadCountEnabled` option. Dispatches a dedicated, client-only `message.read_locally` event
16489
+ * `readEvents.localUnreadCountEnabled` configuration. Dispatches a dedicated, client-only `message.read_locally` event
16477
16490
  * that runs through the same `_handleChannelEvent` read logic as a real `message.read` (minus the
16478
16491
  * delivery-report network sync), so the read-state update lives in one place. When offline support
16479
16492
  * is enabled, the offline DB persists the reset for read-events-disabled channels, so the local
@@ -16635,7 +16648,7 @@ var Channel = class extends WithMessageOperations(ChannelApi) {
16635
16648
  if (message.user?.id === this.getClient().userId) return false;
16636
16649
  if (message.user?.id && this.getClient().userMuteStatus(message.user.id))
16637
16650
  return false;
16638
- if (!this.getClient().options.isLocalUnreadCountEnabled && !channelHasReadEvents(this)) {
16651
+ if (!this.config.readEvents.localUnreadCountEnabled && !channelHasReadEvents(this)) {
16639
16652
  return false;
16640
16653
  }
16641
16654
  if (this.muteStatus().muted) return false;
@@ -17153,7 +17166,7 @@ var Channel = class extends WithMessageOperations(ChannelApi) {
17153
17166
  }
17154
17167
  if (ownUserId && countsAsOwnUnread && !currentReadState[ownUserId]) {
17155
17168
  nextReadState[ownUserId] = {
17156
- last_read: 0,
17169
+ last_read: asTimestampNS(0),
17157
17170
  unread_messages: 1,
17158
17171
  user: client.user ?? { id: ownUserId }
17159
17172
  };
@@ -17769,8 +17782,9 @@ var ApiClient = class {
17769
17782
  if (limit) rateLimit.rate_limit = parseInt(limit, 10);
17770
17783
  const remaining = headers["x-ratelimit-remaining"];
17771
17784
  if (remaining) rateLimit.rate_limit_remaining = parseInt(remaining, 10);
17772
- const reset = headers["x-ratelimit-reset"];
17773
- if (reset) rateLimit.rate_limit_reset = new Date(reset);
17785
+ const reset = Number(headers["x-ratelimit-reset"]);
17786
+ if (Number.isFinite(reset) && reset > 0)
17787
+ rateLimit.rate_limit_reset = new Date(reset * 1e3);
17774
17788
  return {
17775
17789
  response_headers: headers,
17776
17790
  rate_limit: rateLimit,
@@ -17971,6 +17985,7 @@ var ModerationApi = class {
17971
17985
  appeal_reason: request?.appeal_reason,
17972
17986
  entity_id: request?.entity_id,
17973
17987
  entity_type: request?.entity_type,
17988
+ channel_cid: request?.channel_cid,
17974
17989
  review_queue_item_id: request?.review_queue_item_id,
17975
17990
  attachments: request?.attachments
17976
17991
  };
@@ -23317,6 +23332,7 @@ var ChatApi = class {
23317
23332
  id: request?.id,
23318
23333
  is_closed: request?.is_closed,
23319
23334
  max_votes_allowed: request?.max_votes_allowed,
23335
+ team: request?.team,
23320
23336
  voting_visibility: request?.voting_visibility,
23321
23337
  options: request?.options,
23322
23338
  custom: request?.custom
@@ -24404,7 +24420,7 @@ var StreamChat = class _StreamChat extends ChatApi {
24404
24420
  return this.userAgent;
24405
24421
  }
24406
24422
  if (!this.cachedUserAgent) {
24407
- const version = "10.0.0-rc.13";
24423
+ const version = "10.0.0-rc.15";
24408
24424
  const { name: sdkName, version: sdkVersion } = this.sdkIdentifier ?? {};
24409
24425
  const { name: appName, version: appVersion } = this.appIdentifier ?? {};
24410
24426
  const { os, model: deviceModel } = this.deviceIdentifier ?? {};
@@ -24460,10 +24476,7 @@ var StreamChat = class _StreamChat extends ChatApi {
24460
24476
  this.uploadManager = new UploadManager(this);
24461
24477
  this.browser = options.browser ?? typeof window !== "undefined";
24462
24478
  this.node = !this.browser;
24463
- this.options = {
24464
- isLocalUnreadCountEnabled: false,
24465
- ...options
24466
- };
24479
+ this.options = { ...options };
24467
24480
  this.axiosInstance = import_axios4.default.create({
24468
24481
  timeout: 3e3,
24469
24482
  withCredentials: false,
@@ -25222,6 +25235,10 @@ var StreamChat = class _StreamChat extends ChatApi {
25222
25235
  /**
25223
25236
  * Pins the message.
25224
25237
  *
25238
+ * A `number` is a relative offset in SECONDS, so a server-sent timestamp (`message.pinned_at`,
25239
+ * `message.pin_expires`) is rejected at compile time rather than read as ~1.79e18 seconds from now.
25240
+ * Hand one back as a date with `nsToDate(timestamp)`.
25241
+ *
25225
25242
  * @param messageOrMessageId - MessageRequest object or message ID.
25226
25243
  * @param timeoutOrExpirationDate - Expiration date or timeout. Use `number` to set the timeout
25227
25244
  * in seconds, `string` or `Date` to set the exact expiration date (optional).
@@ -25949,6 +25966,11 @@ var CHANNEL_FIELDS = {
25949
25966
  description: 'Allows marking the channel read or unread. The server must also allow it per channel type (`read_events`), and a server "no" wins.',
25950
25967
  kind: "value",
25951
25968
  type: "boolean"
25969
+ },
25970
+ localUnreadCountEnabled: {
25971
+ description: "Counts unread messages client-side when `enabled` is false, reset by `channel.markReadLocally()` instead of a request. Not subject to server authority.",
25972
+ kind: "value",
25973
+ type: "boolean"
25952
25974
  }
25953
25975
  },
25954
25976
  kind: "group"
@@ -26675,13 +26697,13 @@ var AbstractOfflineDB = class {
26675
26697
  execute = true
26676
26698
  }) => {
26677
26699
  const {
26678
- received_at: last_read = nowNs(),
26679
26700
  last_read_message_id,
26680
26701
  // @ts-expect-error property missing
26681
26702
  unread_messages = 0,
26682
26703
  user,
26683
26704
  cid
26684
26705
  } = event;
26706
+ const last_read = (event.type === "notification.mark_unread" ? event.last_read_at : void 0) ?? event.created_at ?? event.received_at ?? nowNs();
26685
26707
  const overriddenUnreadMessages = unreadMessages ?? unread_messages;
26686
26708
  if (user?.id && cid) {
26687
26709
  return await this.queriesWithChannelGuard(