stream-chat 9.0.0 → 9.1.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.
@@ -2523,28 +2523,29 @@ var DEFAULT_MESSAGE_SET_PAGINATION = { hasNext: false, hasPrev: false };
2523
2523
  var DEFAULT_UPLOAD_SIZE_LIMIT_BYTES = 100 * 1024 * 1024;
2524
2524
  var API_MAX_FILES_ALLOWED_PER_MESSAGE = 10;
2525
2525
  var MAX_CHANNEL_MEMBER_COUNT_IN_CHANNEL_QUERY = 100;
2526
- var RESERVED_UPDATED_MESSAGE_FIELDS = [
2526
+ var RESERVED_UPDATED_MESSAGE_FIELDS = {
2527
2527
  // Dates should not be converted back to ISO strings as JS looses precision on them (milliseconds)
2528
- "created_at",
2529
- "deleted_at",
2530
- "pinned_at",
2531
- "updated_at",
2532
- "command",
2528
+ created_at: true,
2529
+ deleted_at: true,
2530
+ pinned_at: true,
2531
+ updated_at: true,
2532
+ command: true,
2533
2533
  // Back-end enriches these fields
2534
- "mentioned_users",
2535
- "quoted_message",
2534
+ mentioned_users: true,
2535
+ quoted_message: true,
2536
2536
  // Client-specific fields
2537
- "latest_reactions",
2538
- "own_reactions",
2539
- "reaction_counts",
2540
- "reply_count",
2537
+ latest_reactions: true,
2538
+ own_reactions: true,
2539
+ reaction_counts: true,
2540
+ reply_count: true,
2541
2541
  // Message text related fields that shouldn't be in update
2542
- "i18n",
2543
- "type",
2544
- "html",
2545
- "__html"
2546
- ];
2547
- var LOCAL_MESSAGE_FIELDS = ["error"];
2542
+ i18n: true,
2543
+ type: true,
2544
+ html: true,
2545
+ __html: true,
2546
+ user: true
2547
+ };
2548
+ var LOCAL_MESSAGE_FIELDS = { error: true };
2548
2549
 
2549
2550
  // src/utils.ts
2550
2551
  function logChatPromiseExecution(promise, name) {
@@ -2771,11 +2772,13 @@ var localMessageToNewMessagePayload = (localMessage) => {
2771
2772
  };
2772
2773
  };
2773
2774
  var toUpdatedMessagePayload = (message) => {
2775
+ const reservedKeys = {
2776
+ ...RESERVED_UPDATED_MESSAGE_FIELDS,
2777
+ ...LOCAL_MESSAGE_FIELDS
2778
+ };
2774
2779
  const messageFields = Object.fromEntries(
2775
2780
  Object.entries(message).filter(
2776
- ([key]) => ![...RESERVED_UPDATED_MESSAGE_FIELDS, ...LOCAL_MESSAGE_FIELDS].includes(
2777
- key
2778
- )
2781
+ ([key]) => !reservedKeys[key]
2779
2782
  )
2780
2783
  );
2781
2784
  return {
@@ -2783,8 +2786,7 @@ var toUpdatedMessagePayload = (message) => {
2783
2786
  pinned: !!message.pinned_at,
2784
2787
  mentioned_users: message.mentioned_users?.map(
2785
2788
  (user) => typeof user === "string" ? user : user.id
2786
- ),
2787
- user_id: message.user?.id ?? message.user_id
2789
+ )
2788
2790
  };
2789
2791
  };
2790
2792
  var findIndexInSortedArray = ({
@@ -5086,6 +5088,10 @@ var pollStateChangeValidators = {
5086
5088
  max_votes_allowed: ({ data, value }) => {
5087
5089
  if (data.enforce_unique_vote && value)
5088
5090
  return { max_votes_allowed: "Enforce unique vote is enabled" };
5091
+ const numericMatch = value.match(/^[0-9]+$/);
5092
+ if (!numericMatch && value) {
5093
+ return { max_votes_allowed: "Only numbers are allowed" };
5094
+ }
5089
5095
  if (value?.length > 1 && !value.match(VALID_MAX_VOTES_VALUE_REGEX))
5090
5096
  return { max_votes_allowed: "Type a number from 2 to 10" };
5091
5097
  return { max_votes_allowed: void 0 };
@@ -5200,7 +5206,7 @@ var createPollComposerStateMiddleware = ({
5200
5206
  forward
5201
5207
  }) => {
5202
5208
  if (!state.targetFields) return forward();
5203
- const { previousState } = state;
5209
+ const { previousState, injectedFieldErrors } = state;
5204
5210
  const finalValidators = {
5205
5211
  ...pollStateChangeValidators,
5206
5212
  ...defaultPollFieldChangeEventValidators,
@@ -5220,7 +5226,7 @@ var createPollComposerStateMiddleware = ({
5220
5226
  nextState: {
5221
5227
  ...previousState,
5222
5228
  data: { ...previousState.data, ...newData },
5223
- errors: { ...previousState.errors, ...newErrors }
5229
+ errors: { ...previousState.errors, ...newErrors, ...injectedFieldErrors }
5224
5230
  }
5225
5231
  });
5226
5232
  },
@@ -5246,7 +5252,11 @@ var createPollComposerStateMiddleware = ({
5246
5252
  nextState: {
5247
5253
  ...previousState,
5248
5254
  data: { ...previousState.data, ...newData },
5249
- errors: { ...previousState.errors, ...newErrors }
5255
+ errors: {
5256
+ ...previousState.errors,
5257
+ ...newErrors,
5258
+ ...state.injectedFieldErrors
5259
+ }
5250
5260
  }
5251
5261
  });
5252
5262
  }
@@ -5307,13 +5317,20 @@ var PollComposer = class {
5307
5317
  this.initState = () => {
5308
5318
  this.state.next(this.initialState);
5309
5319
  };
5310
- this.updateFields = async (data) => {
5320
+ /**
5321
+ * Updates specified fields and generates relevant errors
5322
+ * @param data
5323
+ * @param injectedFieldErrors - errors produced externally that will take precedence over the errors generated in the middleware chaing
5324
+ */
5325
+ // FIXME: change method params to a single object with the next major release
5326
+ this.updateFields = async (data, injectedFieldErrors) => {
5311
5327
  const { state, status } = await this.stateMiddlewareExecutor.execute({
5312
5328
  eventName: "handleFieldChange",
5313
5329
  initialValue: {
5314
5330
  nextState: { ...this.state.getLatestValue() },
5315
5331
  previousState: { ...this.state.getLatestValue() },
5316
- targetFields: data
5332
+ targetFields: data,
5333
+ injectedFieldErrors
5317
5334
  }
5318
5335
  });
5319
5336
  if (status === "discard") return;
@@ -5785,11 +5802,48 @@ var createDraftMessageComposerStateCompositionMiddleware = (composer) => ({
5785
5802
  }
5786
5803
  });
5787
5804
 
5805
+ // src/messageComposer/middleware/messageComposer/pollOnly.ts
5806
+ var pollLocalMessageNullifiedFields = {
5807
+ attachments: [],
5808
+ mentioned_users: [],
5809
+ parent_id: void 0,
5810
+ quoted_message: void 0,
5811
+ text: ""
5812
+ };
5813
+ var createPollOnlyCompositionMiddleware = (composer) => ({
5814
+ id: "stream-io/message-composer-middleware/poll-only",
5815
+ handlers: {
5816
+ compose: ({
5817
+ state,
5818
+ complete,
5819
+ forward
5820
+ }) => {
5821
+ const pollId = composer.pollId;
5822
+ const isEditingMessage = !!composer.editedMessage;
5823
+ const isComposingThreadReply = !!composer.threadId;
5824
+ if (!pollId || isComposingThreadReply || isEditingMessage) return forward();
5825
+ return complete({
5826
+ ...state,
5827
+ localMessage: {
5828
+ ...state.localMessage,
5829
+ ...pollLocalMessageNullifiedFields,
5830
+ poll_id: pollId
5831
+ },
5832
+ message: {
5833
+ id: state.localMessage.id,
5834
+ poll_id: pollId
5835
+ }
5836
+ });
5837
+ }
5838
+ }
5839
+ });
5840
+
5788
5841
  // src/messageComposer/middleware/messageComposer/MessageComposerMiddlewareExecutor.ts
5789
5842
  var MessageComposerMiddlewareExecutor = class extends MiddlewareExecutor {
5790
5843
  constructor({ composer }) {
5791
5844
  super();
5792
5845
  this.use([
5846
+ createPollOnlyCompositionMiddleware(composer),
5793
5847
  createTextComposerCompositionMiddleware(composer),
5794
5848
  createAttachmentsCompositionMiddleware(composer),
5795
5849
  createLinkPreviewsCompositionMiddleware(composer),
@@ -6641,27 +6695,8 @@ var TextComposerMiddlewareExecutor = class extends MiddlewareExecutor {
6641
6695
  eventName,
6642
6696
  initialValue: initialState
6643
6697
  });
6644
- if (result && result.state.suggestions) {
6645
- try {
6646
- const searchResult = await withCancellation(
6647
- "textComposer-suggestions-search",
6648
- async () => {
6649
- await result.state.suggestions?.searchSource.search(
6650
- result.state.suggestions?.query
6651
- );
6652
- }
6653
- );
6654
- if (searchResult === "canceled") return { ...result, status: "discard" };
6655
- } catch (error) {
6656
- return {
6657
- ...result,
6658
- state: {
6659
- ...result.state,
6660
- suggestions: void 0
6661
- }
6662
- };
6663
- }
6664
- }
6698
+ const { query, searchSource } = result.state.suggestions ?? {};
6699
+ searchSource?.search(query)?.catch(console.error);
6665
6700
  return result;
6666
6701
  }
6667
6702
  };
@@ -7339,15 +7374,17 @@ var initState5 = (composition) => {
7339
7374
  const quotedMessage = composition.quoted_message;
7340
7375
  let message;
7341
7376
  let draftId = null;
7377
+ let id = MessageComposer.generateId();
7342
7378
  if (compositionIsDraftResponse(composition)) {
7343
7379
  message = composition.message;
7344
7380
  draftId = composition.message.id;
7345
7381
  } else {
7346
7382
  message = composition;
7383
+ id = composition.id;
7347
7384
  }
7348
7385
  return {
7349
7386
  draftId,
7350
- id: message.id,
7387
+ id,
7351
7388
  quotedMessage: quotedMessage ? formatMessage(quotedMessage) : null,
7352
7389
  pollId: message.poll_id ?? null
7353
7390
  };
@@ -7370,6 +7407,7 @@ var _MessageComposer = class _MessageComposer {
7370
7407
  this.attachmentManager.initState({ message });
7371
7408
  this.linkPreviewsManager.initState({ message });
7372
7409
  this.textComposer.initState({ message });
7410
+ this.pollComposer.initState();
7373
7411
  this.customDataManager.initState({ message });
7374
7412
  this.state.next(initState5(composition));
7375
7413
  if (composition && !compositionIsDraftResponse(composition) && message && isLocalMessage(message)) {
@@ -7530,11 +7568,6 @@ var _MessageComposer = class _MessageComposer {
7530
7568
  this.state.partialNext({ quotedMessage });
7531
7569
  };
7532
7570
  this.clear = () => {
7533
- this.attachmentManager.initState();
7534
- this.linkPreviewsManager.initState();
7535
- this.textComposer.initState();
7536
- this.pollComposer.initState();
7537
- this.customDataManager.initState();
7538
7571
  this.initState();
7539
7572
  };
7540
7573
  this.restore = () => {
@@ -7609,6 +7642,7 @@ var _MessageComposer = class _MessageComposer {
7609
7642
  try {
7610
7643
  const { poll } = await this.client.createPoll(composition.data);
7611
7644
  this.state.partialNext({ pollId: poll.id });
7645
+ this.pollComposer.initState();
7612
7646
  } catch (error) {
7613
7647
  this.client.notifications.add({
7614
7648
  message: "Failed to create the poll",
@@ -13628,24 +13662,20 @@ var StreamChat = class _StreamChat {
13628
13662
  * updateMessage - Update the given message
13629
13663
  *
13630
13664
  * @param {Omit<MessageResponse, 'mentioned_users'> & { mentioned_users?: string[] }} message object, id needs to be specified
13631
- * @param {string | { id: string }} [userId]
13665
+ * @param {string | { id: string }} [partialUserOrUserId]
13632
13666
  * @param {boolean} [options.skip_enrich_url] Do not try to enrich the URLs within message
13633
13667
  *
13634
13668
  * @return {{ message: LocalMessage | MessageResponse }} Response that includes the message
13635
13669
  */
13636
- async updateMessage(message, userId, options) {
13670
+ async updateMessage(message, partialUserOrUserId, options) {
13637
13671
  if (!message.id) {
13638
- throw Error("Please specify the message id when calling updateMessage");
13672
+ throw Error("Please specify the message.id when calling updateMessage");
13639
13673
  }
13640
13674
  const payload = toUpdatedMessagePayload(message);
13641
- if (userId != null) {
13642
- if (isString3(userId)) {
13643
- payload.user_id = userId;
13644
- } else {
13645
- payload.user = {
13646
- id: userId.id
13647
- };
13648
- }
13675
+ if (typeof partialUserOrUserId === "string") {
13676
+ payload.user_id = partialUserOrUserId;
13677
+ } else if (typeof partialUserOrUserId?.id === "string") {
13678
+ payload.user_id = partialUserOrUserId.id;
13649
13679
  }
13650
13680
  return await this.post(
13651
13681
  this.baseURL + `/messages/${encodeURIComponent(message.id)}`,
@@ -13668,13 +13698,15 @@ var StreamChat = class _StreamChat {
13668
13698
  *
13669
13699
  * @return {{ message: MessageResponse }} Response that includes the updated message
13670
13700
  */
13671
- async partialUpdateMessage(id, partialMessageObject, userId, options) {
13701
+ async partialUpdateMessage(id, partialMessageObject, partialUserOrUserId, options) {
13672
13702
  if (!id) {
13673
- throw Error("Please specify the message id when calling partialUpdateMessage");
13703
+ throw Error("Please specify the message.id when calling partialUpdateMessage");
13674
13704
  }
13675
- let user = userId;
13676
- if (userId != null && isString3(userId)) {
13677
- user = { id: userId };
13705
+ let user = void 0;
13706
+ if (typeof partialUserOrUserId === "string") {
13707
+ user = { id: partialUserOrUserId };
13708
+ } else if (typeof partialUserOrUserId?.id === "string") {
13709
+ user = { id: partialUserOrUserId.id };
13678
13710
  }
13679
13711
  return await this.put(
13680
13712
  this.baseURL + `/messages/${encodeURIComponent(id)}`,
@@ -13829,7 +13861,7 @@ var StreamChat = class _StreamChat {
13829
13861
  if (this.userAgent) {
13830
13862
  return this.userAgent;
13831
13863
  }
13832
- const version = "9.0.0";
13864
+ const version = "9.1.0";
13833
13865
  const clientBundle = "browser-cjs";
13834
13866
  let userAgentString = "";
13835
13867
  if (this.sdkIdentifier) {