stream-chat 9.42.3 → 9.43.1

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 (45) hide show
  1. package/dist/cjs/index.browser.js +1457 -1178
  2. package/dist/cjs/index.browser.js.map +3 -3
  3. package/dist/cjs/index.node.js +1458 -1180
  4. package/dist/cjs/index.node.js.map +3 -3
  5. package/dist/esm/index.mjs +1457 -1178
  6. package/dist/esm/index.mjs.map +3 -3
  7. package/dist/types/client.d.ts +4 -2
  8. package/dist/types/messageComposer/CustomDataManager.d.ts +3 -0
  9. package/dist/types/messageComposer/LocationComposer.d.ts +3 -0
  10. package/dist/types/messageComposer/MessageComposerEffectHandlers.d.ts +17 -0
  11. package/dist/types/messageComposer/attachmentManager.d.ts +7 -0
  12. package/dist/types/messageComposer/linkPreviewsManager.d.ts +4 -1
  13. package/dist/types/messageComposer/messageComposer.d.ts +39 -1
  14. package/dist/types/messageComposer/middleware/textComposer/TextComposerMiddlewareExecutor.d.ts +2 -1
  15. package/dist/types/messageComposer/middleware/textComposer/commandEffects.d.ts +5 -0
  16. package/dist/types/messageComposer/middleware/textComposer/commandUtils.d.ts +7 -0
  17. package/dist/types/messageComposer/middleware/textComposer/commands.d.ts +2 -0
  18. package/dist/types/messageComposer/middleware/textComposer/index.d.ts +1 -0
  19. package/dist/types/messageComposer/middleware/textComposer/textMiddlewareUtils.d.ts +0 -34
  20. package/dist/types/messageComposer/middleware/textComposer/types.d.ts +13 -0
  21. package/dist/types/messageComposer/pollComposer.d.ts +3 -0
  22. package/dist/types/messageComposer/textComposer.d.ts +5 -1
  23. package/dist/types/types.d.ts +19 -4
  24. package/dist/types/utils.d.ts +4 -2
  25. package/package.json +1 -1
  26. package/src/client.ts +0 -8
  27. package/src/connection.ts +5 -4
  28. package/src/messageComposer/CustomDataManager.ts +8 -0
  29. package/src/messageComposer/LocationComposer.ts +8 -0
  30. package/src/messageComposer/MessageComposerEffectHandlers.ts +89 -0
  31. package/src/messageComposer/attachmentManager.ts +54 -0
  32. package/src/messageComposer/linkPreviewsManager.ts +12 -3
  33. package/src/messageComposer/messageComposer.ts +107 -0
  34. package/src/messageComposer/middleware/messageComposer/compositionValidation.ts +58 -18
  35. package/src/messageComposer/middleware/textComposer/TextComposerMiddlewareExecutor.ts +7 -1
  36. package/src/messageComposer/middleware/textComposer/commandEffects.ts +51 -0
  37. package/src/messageComposer/middleware/textComposer/commandStringExtraction.ts +1 -4
  38. package/src/messageComposer/middleware/textComposer/commandUtils.ts +48 -0
  39. package/src/messageComposer/middleware/textComposer/commands.ts +15 -7
  40. package/src/messageComposer/middleware/textComposer/index.ts +1 -0
  41. package/src/messageComposer/middleware/textComposer/textMiddlewareUtils.ts +3 -46
  42. package/src/messageComposer/middleware/textComposer/types.ts +20 -0
  43. package/src/messageComposer/pollComposer.ts +8 -0
  44. package/src/messageComposer/textComposer.ts +54 -6
  45. package/src/types.ts +27 -4
@@ -131,6 +131,7 @@ __export(index_exports, {
131
131
  createActiveCommandGuardMiddleware: () => createActiveCommandGuardMiddleware,
132
132
  createAttachmentsCompositionMiddleware: () => createAttachmentsCompositionMiddleware,
133
133
  createBlockedAttachmentUploadNotificationMiddleware: () => createBlockedAttachmentUploadNotificationMiddleware,
134
+ createCommandEffectsMiddleware: () => createCommandEffectsMiddleware,
134
135
  createCommandInjectionMiddleware: () => createCommandInjectionMiddleware,
135
136
  createCommandStringExtractionMiddleware: () => createCommandStringExtractionMiddleware,
136
137
  createCommandsMiddleware: () => createCommandsMiddleware,
@@ -160,13 +161,11 @@ __export(index_exports, {
160
161
  defaultPollFieldChangeEventValidators: () => defaultPollFieldChangeEventValidators,
161
162
  encodeBase64: () => encodeBase64,
162
163
  ensureIsLocalAttachment: () => ensureIsLocalAttachment,
163
- escapeRegExp: () => escapeRegExp,
164
164
  extractPollData: () => extractPollData,
165
165
  extractPollEnrichedData: () => extractPollEnrichedData,
166
166
  formatMessage: () => formatMessage,
167
167
  generateFileName: () => generateFileName,
168
168
  getAttachmentTypeFromMimeType: () => getAttachmentTypeFromMimeType,
169
- getCompleteCommandInString: () => getCompleteCommandInString,
170
169
  getExtensionFromMimeType: () => getExtensionFromMimeType,
171
170
  getTokenizedSuggestionDisplayName: () => getTokenizedSuggestionDisplayName,
172
171
  getTriggerCharWithToken: () => getTriggerCharWithToken,
@@ -3255,9 +3254,51 @@ var _AttachmentManager = class _AttachmentManager {
3255
3254
  this.setCustomUploadFn = (doUploadRequest) => {
3256
3255
  this.composer.updateConfig({ attachments: { doUploadRequest } });
3257
3256
  };
3257
+ this.cancelAttachmentUploads = (attachments = this.attachments) => {
3258
+ for (const { localMetadata } of attachments) {
3259
+ this.client.uploadManager.deleteUploadRecord(localMetadata.id);
3260
+ }
3261
+ };
3262
+ this.normalizeSnapshotAttachment = (attachment) => {
3263
+ if (attachment.localMetadata.uploadState !== "uploading") return attachment;
3264
+ this.client.uploadManager.deleteUploadRecord(attachment.localMetadata.id);
3265
+ return {
3266
+ ...attachment,
3267
+ localMetadata: {
3268
+ ...attachment.localMetadata,
3269
+ uploadProgress: void 0,
3270
+ uploadState: "failed"
3271
+ }
3272
+ };
3273
+ };
3258
3274
  this.initState = ({ message } = {}) => {
3259
3275
  this.state.next(initState({ message }));
3260
3276
  };
3277
+ this.getSnapshot = () => {
3278
+ const state = this.state.getLatestValue();
3279
+ let hasUpdates = false;
3280
+ const attachments = state.attachments.map(this.normalizeSnapshotAttachment);
3281
+ for (let i = 0; i < attachments.length; i++) {
3282
+ if (attachments[i] !== state.attachments[i]) {
3283
+ hasUpdates = true;
3284
+ break;
3285
+ }
3286
+ }
3287
+ return hasUpdates ? { ...state, attachments } : state;
3288
+ };
3289
+ this.restoreSnapshot = (snapshot) => {
3290
+ this.cancelAttachmentUploads(this.attachments);
3291
+ this.state.next(snapshot);
3292
+ };
3293
+ this.setAttachments = (attachments) => {
3294
+ this.state.partialNext({ attachments });
3295
+ };
3296
+ this.clearAttachments = () => {
3297
+ if (!this.attachments.length) return;
3298
+ this.removeAttachments(
3299
+ this.attachments.map((attachment) => attachment.localMetadata.id)
3300
+ );
3301
+ };
3261
3302
  this.getAttachmentIndex = (localId) => {
3262
3303
  const attachmentsById = this.attachmentsById;
3263
3304
  return this.attachments.indexOf(attachmentsById[localId]);
@@ -3778,6 +3819,10 @@ var CustomDataManager = class {
3778
3819
  this.initState = ({ message } = {}) => {
3779
3820
  this.state.next(initState2({ composer: this.composer, message }));
3780
3821
  };
3822
+ this.getSnapshot = () => this.state.getLatestValue();
3823
+ this.restoreSnapshot = (snapshot) => {
3824
+ this.state.next(snapshot);
3825
+ };
3781
3826
  this.composer = composer;
3782
3827
  this.state = new StateStore(initState2({ composer, message }));
3783
3828
  }
@@ -3833,8 +3878,13 @@ var _LinkPreviewsManager = class _LinkPreviewsManager {
3833
3878
  constructor({ composer, message }) {
3834
3879
  this.shouldDiscardEnrichQueries = false;
3835
3880
  this.initState = ({ message } = {}) => {
3881
+ this.cancelURLEnrichment();
3836
3882
  this.state.next(initState3({ message: this.enabled ? message : void 0 }));
3837
3883
  };
3884
+ this.getSnapshot = () => this.state.getLatestValue();
3885
+ this.restoreSnapshot = (snapshot) => {
3886
+ this.state.next(snapshot);
3887
+ };
3838
3888
  this._findAndEnrichUrls = async (text) => {
3839
3889
  if (!this.enabled) return;
3840
3890
  const urls = this.config.findURLFn(text);
@@ -3887,8 +3937,8 @@ var _LinkPreviewsManager = class _LinkPreviewsManager {
3887
3937
  );
3888
3938
  };
3889
3939
  this.cancelURLEnrichment = () => {
3890
- this.findAndEnrichUrls.cancel();
3891
- this.findAndEnrichUrls.flush();
3940
+ this.findAndEnrichUrls.cancel?.();
3941
+ this.findAndEnrichUrls.flush?.();
3892
3942
  };
3893
3943
  /**
3894
3944
  * Clears all non-dismissed previews when the text composer is cleared.
@@ -4030,6 +4080,10 @@ var LocationComposer = class {
4030
4080
  this.initState = ({ message } = {}) => {
4031
4081
  this.state.next(initState4({ message }));
4032
4082
  };
4083
+ this.getSnapshot = () => this.state.getLatestValue();
4084
+ this.restoreSnapshot = (snapshot) => {
4085
+ this.state.next(snapshot);
4086
+ };
4033
4087
  this.setData = (data) => {
4034
4088
  if (!this.config.enabled) return;
4035
4089
  if (!data.latitude || !data.longitude) return;
@@ -4066,6 +4120,65 @@ var LocationComposer = class {
4066
4120
  }
4067
4121
  };
4068
4122
 
4123
+ // src/messageComposer/MessageComposerEffectHandlers.ts
4124
+ var applyCommandActivationEffect = (effect, composer) => {
4125
+ const snapshot = composer.getSnapshot();
4126
+ if (effect.stateToRestore) {
4127
+ snapshot.textComposer = {
4128
+ ...snapshot.textComposer,
4129
+ ...effect.stateToRestore,
4130
+ command: null
4131
+ };
4132
+ }
4133
+ composer.captureSnapshot(snapshot);
4134
+ composer.textComposer.state.next({
4135
+ command: effect.command,
4136
+ mentionedUsers: [],
4137
+ suggestions: void 0,
4138
+ selection: { start: 0, end: 0 },
4139
+ text: ""
4140
+ });
4141
+ const attachmentsToCancel = composer.attachmentManager.attachments;
4142
+ composer.attachmentManager.initState();
4143
+ composer.attachmentManager.cancelAttachmentUploads(attachmentsToCancel);
4144
+ composer.linkPreviewsManager.initState();
4145
+ composer.locationComposer.initState();
4146
+ composer.pollComposer.initState();
4147
+ composer.customDataManager.initState();
4148
+ };
4149
+ var applyCommandClearEffect = (_, composer) => {
4150
+ const snapshot = composer.popSnapshot();
4151
+ if (!snapshot) return;
4152
+ composer.restoreSnapshot(snapshot);
4153
+ };
4154
+ var MessageComposerEffectHandlers = class {
4155
+ constructor(options) {
4156
+ this.options = options;
4157
+ this.handlers = /* @__PURE__ */ new Map();
4158
+ this.registerDefaultHandlers = () => {
4159
+ this.registerEffectHandler(
4160
+ "command.activate",
4161
+ applyCommandActivationEffect
4162
+ );
4163
+ this.registerEffectHandler(
4164
+ "command.clear",
4165
+ applyCommandClearEffect
4166
+ );
4167
+ };
4168
+ this.registerEffectHandler = (type, handler) => {
4169
+ this.handlers.set(type, handler);
4170
+ };
4171
+ this.applyEffects = (effects = []) => {
4172
+ effects.forEach((effect) => this.applyEffect(effect));
4173
+ };
4174
+ this.applyEffect = (effect) => {
4175
+ const handler = this.handlers.get(effect.type);
4176
+ handler?.(effect, this.options.composer);
4177
+ };
4178
+ this.registerDefaultHandlers();
4179
+ }
4180
+ };
4181
+
4069
4182
  // src/messageComposer/middleware/pollComposer/state.ts
4070
4183
  var VALID_MAX_VOTES_VALUE_REGEX = /^([2-9]|10)$/;
4071
4184
  var MAX_POLL_OPTIONS = 100;
@@ -4356,6 +4469,10 @@ var PollComposer = class {
4356
4469
  this.initState = () => {
4357
4470
  this.state.next(this.initialState);
4358
4471
  };
4472
+ this.getSnapshot = () => this.state.getLatestValue();
4473
+ this.restoreSnapshot = (snapshot) => {
4474
+ this.state.next(snapshot);
4475
+ };
4359
4476
  /**
4360
4477
  * Updates specified fields and generates relevant errors
4361
4478
  * @param data
@@ -4618,667 +4735,239 @@ var createDraftCustomDataCompositionMiddleware = (composer) => ({
4618
4735
  }
4619
4736
  });
4620
4737
 
4621
- // src/messageComposer/middleware/messageComposer/compositionValidation.ts
4622
- var createCompositionValidationMiddleware = (composer) => ({
4623
- id: "stream-io/message-composer-middleware/data-validation",
4624
- handlers: {
4625
- compose: async ({
4626
- state,
4627
- discard,
4628
- forward
4629
- }) => {
4630
- const { maxLengthOnSend } = composer.config.text ?? {};
4631
- const inputText = state.message.text ?? "";
4632
- const hasExceededMaxLength = typeof maxLengthOnSend === "number" && inputText.length > maxLengthOnSend;
4633
- if (composer.compositionIsEmpty || hasExceededMaxLength) {
4634
- return await discard();
4635
- }
4636
- return await forward();
4637
- }
4738
+ // src/errors.ts
4739
+ var APIErrorCodes = {
4740
+ "-1": { name: "InternalSystemError", retryable: true },
4741
+ "2": { name: "AccessKeyError", retryable: false },
4742
+ "3": { name: "AuthenticationFailedError", retryable: true },
4743
+ "4": { name: "InputError", retryable: false },
4744
+ "6": { name: "DuplicateUsernameError", retryable: false },
4745
+ "9": { name: "RateLimitError", retryable: true },
4746
+ "16": { name: "DoesNotExistError", retryable: false },
4747
+ "17": { name: "NotAllowedError", retryable: false },
4748
+ "18": { name: "EventNotSupportedError", retryable: false },
4749
+ "19": { name: "ChannelFeatureNotSupportedError", retryable: false },
4750
+ "20": { name: "MessageTooLongError", retryable: false },
4751
+ "21": { name: "MultipleNestingLevelError", retryable: false },
4752
+ "22": { name: "PayloadTooBigError", retryable: false },
4753
+ "23": { name: "RequestTimeoutError", retryable: true },
4754
+ "24": { name: "MaxHeaderSizeExceededError", retryable: false },
4755
+ "40": { name: "AuthErrorTokenExpired", retryable: false },
4756
+ "41": { name: "AuthErrorTokenNotValidYet", retryable: false },
4757
+ "42": { name: "AuthErrorTokenUsedBeforeIssuedAt", retryable: false },
4758
+ "43": { name: "AuthErrorTokenSignatureInvalid", retryable: false },
4759
+ "44": { name: "CustomCommandEndpointMissingError", retryable: false },
4760
+ "45": { name: "CustomCommandEndpointCallError", retryable: true },
4761
+ "46": { name: "ConnectionIDNotFoundError", retryable: false },
4762
+ "60": { name: "CoolDownError", retryable: true },
4763
+ "69": { name: "ErrWrongRegion", retryable: false },
4764
+ "70": { name: "ErrQueryChannelPermissions", retryable: false },
4765
+ "71": { name: "ErrTooManyConnections", retryable: true },
4766
+ "99": { name: "AppSuspendedError", retryable: false }
4767
+ };
4768
+ function isAPIError(error) {
4769
+ return error.code !== void 0;
4770
+ }
4771
+ function isErrorRetryable(error) {
4772
+ if (!error.code) return false;
4773
+ const err = APIErrorCodes[`${error.code}`];
4774
+ if (!err) return false;
4775
+ return err.retryable;
4776
+ }
4777
+ function isConnectionIDError(error) {
4778
+ return error.code === 46;
4779
+ }
4780
+ function isWSFailure(err) {
4781
+ if (typeof err.isWSFailure === "boolean") {
4782
+ return err.isWSFailure;
4638
4783
  }
4639
- });
4640
- var createDraftCompositionValidationMiddleware = (composer) => ({
4641
- id: "stream-io/message-composer-middleware/draft-data-validation",
4642
- handlers: {
4643
- compose: async ({
4644
- state,
4645
- discard,
4646
- forward
4647
- }) => {
4648
- const hasData = !textIsEmpty(state.draft.text ?? "") || state.draft.attachments?.length || state.draft.poll_id || state.draft.quoted_message_id;
4649
- const shouldCreateDraft = composer.lastChangeOriginIsLocal && hasData;
4650
- if (!shouldCreateDraft) {
4651
- return await discard();
4652
- }
4653
- return await forward();
4654
- }
4784
+ try {
4785
+ return JSON.parse(err.message).isWSFailure;
4786
+ } catch (_) {
4787
+ return false;
4655
4788
  }
4656
- });
4789
+ }
4790
+ function isErrorResponse(res) {
4791
+ return !res.status || res.status < 200 || 300 <= res.status;
4792
+ }
4657
4793
 
4658
- // src/messageComposer/middleware/messageComposer/linkPreviews.ts
4659
- var createLinkPreviewsCompositionMiddleware = (composer) => ({
4660
- id: "stream-io/message-composer-middleware/link-previews",
4661
- handlers: {
4662
- compose: ({
4663
- state,
4664
- next,
4665
- forward
4666
- }) => {
4667
- const { linkPreviewsManager } = composer;
4668
- if (!linkPreviewsManager) return forward();
4669
- linkPreviewsManager.cancelURLEnrichment();
4670
- const someLinkPreviewsLoading = linkPreviewsManager.loadingPreviews.length > 0;
4671
- const someLinkPreviewsDismissed = linkPreviewsManager.dismissedPreviews.length > 0;
4672
- const linkPreviews = linkPreviewsManager.loadingPreviews.length > 0 ? [] : linkPreviewsManager.loadedPreviews.map(
4673
- (preview) => LinkPreviewsManager.getPreviewData(preview)
4674
- );
4675
- const attachments = (state.message.attachments ?? []).concat(
4676
- linkPreviews
4677
- );
4678
- if (!attachments.length) return forward();
4679
- const sendOptions = { ...state.sendOptions };
4680
- const skip_enrich_url = !someLinkPreviewsLoading && linkPreviews.length > 0 || someLinkPreviewsDismissed;
4681
- if (skip_enrich_url) {
4682
- sendOptions.skip_enrich_url = true;
4683
- }
4684
- return next({
4685
- ...state,
4686
- message: {
4687
- ...state.message,
4688
- attachments
4689
- },
4690
- localMessage: {
4691
- ...state.localMessage,
4692
- attachments
4693
- },
4694
- sendOptions
4695
- });
4696
- }
4794
+ // src/search/BaseSearchSource.ts
4795
+ var DEFAULT_SEARCH_SOURCE_OPTIONS = {
4796
+ debounceMs: 300,
4797
+ pageSize: 10
4798
+ };
4799
+ var BaseSearchSourceBase = class {
4800
+ constructor(options) {
4801
+ this.activate = () => {
4802
+ if (this.isActive) return;
4803
+ this.state.partialNext({ isActive: true });
4804
+ };
4805
+ this.deactivate = () => {
4806
+ if (!this.isActive) return;
4807
+ this.state.partialNext({ isActive: false });
4808
+ };
4809
+ this.canExecuteQuery = (newSearchString) => {
4810
+ const hasNewSearchQuery = typeof newSearchString !== "undefined";
4811
+ const searchString = newSearchString ?? this.searchQuery;
4812
+ return !!(this.isActive && !this.isLoading && (this.hasNext || hasNewSearchQuery) && searchString);
4813
+ };
4814
+ const { pageSize } = { ...DEFAULT_SEARCH_SOURCE_OPTIONS, ...options };
4815
+ this.pageSize = pageSize;
4816
+ this.state = new StateStore(this.initialState);
4697
4817
  }
4698
- });
4699
- var createDraftLinkPreviewsCompositionMiddleware = (composer) => ({
4700
- id: "stream-io/message-composer-middleware/draft-link-previews",
4701
- handlers: {
4702
- compose: ({
4703
- state,
4704
- next,
4705
- forward
4706
- }) => {
4707
- const { linkPreviewsManager } = composer;
4708
- if (!linkPreviewsManager) return forward();
4709
- linkPreviewsManager.cancelURLEnrichment();
4710
- const linkPreviews = linkPreviewsManager.loadedPreviews.map(
4711
- (preview) => LinkPreviewsManager.getPreviewData(preview)
4712
- );
4713
- if (!linkPreviews.length) return forward();
4714
- return next({
4715
- ...state,
4716
- draft: {
4717
- ...state.draft,
4718
- attachments: (state.draft.attachments ?? []).concat(linkPreviews)
4719
- }
4720
- });
4721
- }
4818
+ get lastQueryError() {
4819
+ return this.state.getLatestValue().lastQueryError;
4722
4820
  }
4723
- });
4724
-
4725
- // src/messageComposer/middleware/messageComposer/textComposer.ts
4726
- var createTextComposerCompositionMiddleware = (composer) => ({
4727
- id: "stream-io/message-composer-middleware/text-composition",
4728
- handlers: {
4729
- compose: ({
4730
- state,
4731
- next,
4732
- forward
4733
- }) => {
4734
- if (!composer.textComposer) return forward();
4735
- const { mentionedUsers, text } = composer.textComposer;
4736
- const mentioned_users = Array.from(
4737
- new Set(
4738
- mentionedUsers.filter(
4739
- ({ id, name }) => text.includes(`@${id}`) || text.includes(`@${name}`)
4740
- )
4741
- )
4742
- );
4743
- if (!text && mentioned_users.length === 0) return forward();
4744
- return next({
4745
- ...state,
4746
- localMessage: {
4747
- ...state.localMessage,
4748
- mentioned_users,
4749
- text
4750
- },
4751
- message: {
4752
- ...state.message,
4753
- mentioned_users: mentioned_users.map((u) => u.id),
4754
- text
4755
- }
4756
- });
4757
- }
4821
+ get hasNext() {
4822
+ return this.state.getLatestValue().hasNext;
4758
4823
  }
4759
- });
4760
- var createDraftTextComposerCompositionMiddleware = (composer) => ({
4761
- id: "stream-io/message-composer-middleware/draft-text-composition",
4762
- handlers: {
4763
- compose: ({
4764
- state,
4765
- next,
4766
- forward
4767
- }) => {
4768
- if (!composer.textComposer) return forward();
4769
- const { maxLengthOnSend } = composer.config.text ?? {};
4770
- const { mentionedUsers, text: inputText } = composer.textComposer;
4771
- const mentioned_users = mentionedUsers.length ? Array.from(
4772
- new Set(
4773
- mentionedUsers.filter(
4774
- ({ id, name }) => inputText.includes(`@${id}`) || inputText.includes(`@${name}`)
4775
- )
4776
- )
4777
- ) : void 0;
4778
- const text = typeof maxLengthOnSend === "number" && inputText.length > maxLengthOnSend ? inputText.slice(0, maxLengthOnSend) : inputText;
4779
- return next({
4780
- ...state,
4781
- draft: {
4782
- ...state.draft,
4783
- mentioned_users: mentioned_users?.map((u) => u.id),
4784
- text
4785
- }
4786
- });
4824
+ get hasResults() {
4825
+ return Array.isArray(this.state.getLatestValue().items);
4826
+ }
4827
+ get isActive() {
4828
+ return this.state.getLatestValue().isActive;
4829
+ }
4830
+ get isLoading() {
4831
+ return this.state.getLatestValue().isLoading;
4832
+ }
4833
+ get initialState() {
4834
+ return {
4835
+ hasNext: true,
4836
+ isActive: false,
4837
+ isLoading: false,
4838
+ items: void 0,
4839
+ lastQueryError: void 0,
4840
+ next: void 0,
4841
+ offset: 0,
4842
+ searchQuery: ""
4843
+ };
4844
+ }
4845
+ get items() {
4846
+ return this.state.getLatestValue().items;
4847
+ }
4848
+ get next() {
4849
+ return this.state.getLatestValue().next;
4850
+ }
4851
+ get offset() {
4852
+ return this.state.getLatestValue().offset;
4853
+ }
4854
+ get searchQuery() {
4855
+ return this.state.getLatestValue().searchQuery;
4856
+ }
4857
+ getStateBeforeFirstQuery(newSearchString) {
4858
+ return {
4859
+ ...this.initialState,
4860
+ isActive: this.isActive,
4861
+ isLoading: true,
4862
+ searchQuery: newSearchString
4863
+ };
4864
+ }
4865
+ getStateAfterQuery(stateUpdate, isFirstPage) {
4866
+ const current = this.state.getLatestValue();
4867
+ return {
4868
+ ...current,
4869
+ lastQueryError: void 0,
4870
+ // reset lastQueryError that can be overridden by the stateUpdate
4871
+ ...stateUpdate,
4872
+ isLoading: false,
4873
+ items: isFirstPage ? stateUpdate.items : [...this.items ?? [], ...stateUpdate.items || []]
4874
+ };
4875
+ }
4876
+ prepareStateForQuery(newSearchString) {
4877
+ const hasNewSearchQuery = typeof newSearchString !== "undefined";
4878
+ const searchString = newSearchString ?? this.searchQuery;
4879
+ if (hasNewSearchQuery) {
4880
+ this.state.next(this.getStateBeforeFirstQuery(newSearchString ?? ""));
4881
+ } else {
4882
+ this.state.partialNext({ isLoading: true });
4787
4883
  }
4884
+ return { searchString, hasNewSearchQuery };
4788
4885
  }
4789
- });
4790
-
4791
- // src/messageComposer/middleware/messageComposer/messageComposerState.ts
4792
- var createMessageComposerStateCompositionMiddleware = (composer) => ({
4793
- id: "stream-io/message-composer-middleware/own-state",
4794
- handlers: {
4795
- compose: ({
4796
- state,
4797
- next
4798
- }) => {
4799
- const payload = {};
4800
- if (composer.quotedMessage) {
4801
- payload.quoted_message_id = composer.quotedMessage.id;
4802
- }
4803
- if (composer.pollId) {
4804
- payload.poll_id = composer.pollId;
4805
- }
4806
- if (composer.showReplyInChannel) {
4807
- payload.show_in_channel = true;
4808
- }
4809
- return next({
4810
- ...state,
4811
- localMessage: {
4812
- ...state.localMessage,
4813
- ...payload,
4814
- quoted_message: composer.quotedMessage ?? void 0
4815
- },
4816
- message: {
4817
- ...state.message,
4818
- ...payload
4819
- }
4820
- });
4886
+ updatePaginationStateFromQuery(result) {
4887
+ const { items, next } = result;
4888
+ const stateUpdate = {};
4889
+ if (Object.prototype.hasOwnProperty.call(result, "next")) {
4890
+ stateUpdate.next = next;
4891
+ stateUpdate.hasNext = !!next;
4892
+ } else {
4893
+ stateUpdate.offset = (this.offset ?? 0) + items.length;
4894
+ stateUpdate.hasNext = items.length === this.pageSize;
4821
4895
  }
4896
+ return stateUpdate;
4822
4897
  }
4823
- });
4824
- var createDraftMessageComposerStateCompositionMiddleware = (composer) => ({
4825
- id: "stream-io/message-composer-middleware/draft-own-state",
4826
- handlers: {
4827
- compose: ({
4828
- state,
4829
- next
4830
- }) => {
4831
- const payload = {};
4832
- if (composer.quotedMessage) {
4833
- payload.quoted_message_id = composer.quotedMessage.id;
4834
- }
4835
- if (composer.pollId) {
4836
- payload.poll_id = composer.pollId;
4837
- }
4838
- if (composer.showReplyInChannel) {
4839
- payload.show_in_channel = true;
4898
+ resetState() {
4899
+ this.state.next(this.initialState);
4900
+ }
4901
+ resetStateAndActivate() {
4902
+ this.resetState();
4903
+ this.activate();
4904
+ }
4905
+ };
4906
+ var BaseSearchSource = class extends BaseSearchSourceBase {
4907
+ constructor(options) {
4908
+ const { debounceMs } = { ...DEFAULT_SEARCH_SOURCE_OPTIONS, ...options };
4909
+ super(options);
4910
+ this.setDebounceOptions = ({ debounceMs }) => {
4911
+ this.searchDebounced = debounce(this.executeQuery.bind(this), debounceMs);
4912
+ };
4913
+ this.search = (searchQuery) => this.searchDebounced(searchQuery);
4914
+ this.setDebounceOptions({ debounceMs });
4915
+ }
4916
+ async executeQuery(newSearchString) {
4917
+ if (!this.canExecuteQuery(newSearchString)) return;
4918
+ const { hasNewSearchQuery, searchString } = this.prepareStateForQuery(newSearchString);
4919
+ let stateUpdate = {};
4920
+ try {
4921
+ const results = await this.query(searchString);
4922
+ if (!results) return;
4923
+ const { items } = results;
4924
+ stateUpdate = this.updatePaginationStateFromQuery(results);
4925
+ stateUpdate.items = await this.filterQueryResults(items);
4926
+ } catch (e) {
4927
+ stateUpdate.lastQueryError = e;
4928
+ if (isAPIError(e) && !isErrorRetryable(e)) {
4929
+ stateUpdate.hasNext = false;
4840
4930
  }
4841
- return next({
4842
- ...state,
4843
- draft: {
4844
- ...state.draft,
4845
- ...payload
4846
- }
4847
- });
4931
+ } finally {
4932
+ this.state.next(this.getStateAfterQuery(stateUpdate, hasNewSearchQuery));
4848
4933
  }
4849
4934
  }
4850
- });
4851
-
4852
- // src/messageComposer/middleware/messageComposer/userDataInjection.ts
4853
- var createUserDataInjectionMiddleware = (composer) => ({
4854
- id: "stream-io/message-composer-middleware/user-data-injection",
4855
- handlers: {
4856
- compose: ({
4857
- state,
4858
- next,
4859
- forward
4860
- }) => {
4861
- if (!composer.client.user) {
4862
- return forward();
4935
+ cancelScheduledQuery() {
4936
+ this.searchDebounced.cancel();
4937
+ }
4938
+ };
4939
+ var BaseSearchSourceSync = class extends BaseSearchSourceBase {
4940
+ constructor(options) {
4941
+ const { debounceMs } = { ...DEFAULT_SEARCH_SOURCE_OPTIONS, ...options };
4942
+ super(options);
4943
+ this.setDebounceOptions = ({ debounceMs }) => {
4944
+ this.searchDebounced = debounce(this.executeQuery.bind(this), debounceMs);
4945
+ };
4946
+ this.search = (searchQuery) => this.searchDebounced(searchQuery);
4947
+ this.setDebounceOptions({ debounceMs });
4948
+ }
4949
+ executeQuery(newSearchString) {
4950
+ if (!this.canExecuteQuery(newSearchString)) return;
4951
+ const { hasNewSearchQuery, searchString } = this.prepareStateForQuery(newSearchString);
4952
+ let stateUpdate = {};
4953
+ try {
4954
+ const results = this.query(searchString);
4955
+ if (!results) return;
4956
+ const { items } = results;
4957
+ stateUpdate = this.updatePaginationStateFromQuery(results);
4958
+ stateUpdate.items = this.filterQueryResults(items);
4959
+ } catch (e) {
4960
+ stateUpdate.lastQueryError = e;
4961
+ if (isAPIError(e) && !isErrorRetryable(e)) {
4962
+ stateUpdate.hasNext = false;
4863
4963
  }
4864
- const { channel_mutes, devices, mutes, ...messageUser } = composer.client.user;
4865
- return next({
4866
- ...state,
4867
- localMessage: {
4868
- ...state.localMessage,
4869
- user: messageUser,
4870
- user_id: messageUser.id
4871
- }
4872
- });
4964
+ } finally {
4965
+ this.state.next(this.getStateAfterQuery(stateUpdate, hasNewSearchQuery));
4873
4966
  }
4874
4967
  }
4875
- });
4876
-
4877
- // src/messageComposer/middleware/messageComposer/pollOnly.ts
4878
- var pollLocalMessageNullifiedFields = {
4879
- attachments: [],
4880
- mentioned_users: [],
4881
- parent_id: void 0,
4882
- quoted_message: void 0,
4883
- text: ""
4884
- };
4885
- var createPollOnlyCompositionMiddleware = (composer) => ({
4886
- id: "stream-io/message-composer-middleware/poll-only",
4887
- handlers: {
4888
- compose: ({
4889
- state,
4890
- complete,
4891
- forward
4892
- }) => {
4893
- const pollId = composer.pollId;
4894
- const isEditingMessage = !!composer.editedMessage;
4895
- const isComposingThreadReply = !!composer.threadId;
4896
- if (!pollId || isComposingThreadReply || isEditingMessage) return forward();
4897
- return complete({
4898
- ...state,
4899
- localMessage: {
4900
- ...state.localMessage,
4901
- ...pollLocalMessageNullifiedFields,
4902
- poll_id: pollId
4903
- },
4904
- message: {
4905
- id: state.localMessage.id,
4906
- poll_id: pollId
4907
- }
4908
- });
4909
- }
4910
- }
4911
- });
4912
-
4913
- // src/messageComposer/middleware/messageComposer/sharedLocation.ts
4914
- var createSharedLocationCompositionMiddleware = (composer) => ({
4915
- id: "stream-io/message-composer-middleware/shared-location",
4916
- handlers: {
4917
- compose: ({
4918
- state,
4919
- next,
4920
- forward
4921
- }) => {
4922
- const { locationComposer } = composer;
4923
- const location = locationComposer.validLocation;
4924
- if (!locationComposer || !location || !composer.client.user) return forward();
4925
- const timestamp = (/* @__PURE__ */ new Date()).toISOString();
4926
- return next({
4927
- ...state,
4928
- localMessage: {
4929
- ...state.localMessage,
4930
- shared_location: {
4931
- ...location,
4932
- channel_cid: composer.channel.cid,
4933
- created_at: timestamp,
4934
- updated_at: timestamp,
4935
- user_id: composer.client.user.id
4936
- }
4937
- },
4938
- message: {
4939
- ...state.message,
4940
- shared_location: location
4941
- }
4942
- });
4943
- }
4944
- }
4945
- });
4946
-
4947
- // src/messageComposer/middleware/messageComposer/MessageComposerMiddlewareExecutor.ts
4948
- var MessageComposerMiddlewareExecutor = class extends MiddlewareExecutor {
4949
- constructor({ composer }) {
4950
- super();
4951
- this.use([
4952
- createUserDataInjectionMiddleware(composer),
4953
- createPollOnlyCompositionMiddleware(composer),
4954
- createTextComposerCompositionMiddleware(composer),
4955
- createAttachmentsCompositionMiddleware(composer),
4956
- createLinkPreviewsCompositionMiddleware(composer),
4957
- createSharedLocationCompositionMiddleware(composer),
4958
- createMessageComposerStateCompositionMiddleware(composer),
4959
- createCustomDataCompositionMiddleware(composer),
4960
- createCompositionValidationMiddleware(composer),
4961
- createCompositionDataCleanupMiddleware(composer)
4962
- ]);
4963
- }
4964
- };
4965
- var MessageDraftComposerMiddlewareExecutor = class extends MiddlewareExecutor {
4966
- constructor({ composer }) {
4967
- super();
4968
- this.use([
4969
- createDraftTextComposerCompositionMiddleware(composer),
4970
- createDraftAttachmentsCompositionMiddleware(composer),
4971
- createDraftLinkPreviewsCompositionMiddleware(composer),
4972
- createDraftMessageComposerStateCompositionMiddleware(composer),
4973
- createDraftCustomDataCompositionMiddleware(composer),
4974
- createDraftCompositionValidationMiddleware(composer)
4975
- ]);
4976
- }
4977
- };
4978
-
4979
- // src/messageComposer/middleware/messageComposer/commandInjection.ts
4980
- var createCommandInjectionMiddleware = (composer) => ({
4981
- handlers: {
4982
- compose: ({
4983
- forward,
4984
- next,
4985
- state
4986
- }) => {
4987
- const command = composer.textComposer.command;
4988
- if (!command) {
4989
- return forward();
4990
- }
4991
- const { text } = state.localMessage;
4992
- const injection = `/${command?.name}`;
4993
- const enrichedText = `${injection} ${text}`;
4994
- return next({
4995
- ...state,
4996
- localMessage: {
4997
- ...state.localMessage,
4998
- text: enrichedText
4999
- },
5000
- message: {
5001
- ...state.message,
5002
- text: enrichedText
5003
- }
5004
- });
5005
- }
5006
- },
5007
- id: "stream-io/message-composer-middleware/command-string-injection"
5008
- });
5009
- var createDraftCommandInjectionMiddleware = (composer) => ({
5010
- handlers: {
5011
- compose: ({
5012
- forward,
5013
- next,
5014
- state
5015
- }) => {
5016
- const command = composer.textComposer.command;
5017
- if (!command) {
5018
- return forward();
5019
- }
5020
- const { text } = state.draft;
5021
- const injection = `/${command?.name}`;
5022
- const enrichedText = `${injection} ${text}`;
5023
- return next({
5024
- ...state,
5025
- draft: {
5026
- ...state.draft,
5027
- text: enrichedText
5028
- }
5029
- });
5030
- }
5031
- },
5032
- id: "stream-io/message-composer-middleware/draft-command-string-injection"
5033
- });
5034
-
5035
- // src/messageComposer/middleware/textComposer/activeCommandGuard.ts
5036
- var createActiveCommandGuardMiddleware = () => ({
5037
- handlers: {
5038
- onChange: ({ complete, forward, state }) => {
5039
- if (state.command) {
5040
- return complete(state);
5041
- }
5042
- return forward();
5043
- },
5044
- onSuggestionItemSelect: ({ forward }) => forward()
5045
- },
5046
- id: "stream-io/text-composer/active-command-guard"
5047
- });
5048
-
5049
- // src/errors.ts
5050
- var APIErrorCodes = {
5051
- "-1": { name: "InternalSystemError", retryable: true },
5052
- "2": { name: "AccessKeyError", retryable: false },
5053
- "3": { name: "AuthenticationFailedError", retryable: true },
5054
- "4": { name: "InputError", retryable: false },
5055
- "6": { name: "DuplicateUsernameError", retryable: false },
5056
- "9": { name: "RateLimitError", retryable: true },
5057
- "16": { name: "DoesNotExistError", retryable: false },
5058
- "17": { name: "NotAllowedError", retryable: false },
5059
- "18": { name: "EventNotSupportedError", retryable: false },
5060
- "19": { name: "ChannelFeatureNotSupportedError", retryable: false },
5061
- "20": { name: "MessageTooLongError", retryable: false },
5062
- "21": { name: "MultipleNestingLevelError", retryable: false },
5063
- "22": { name: "PayloadTooBigError", retryable: false },
5064
- "23": { name: "RequestTimeoutError", retryable: true },
5065
- "24": { name: "MaxHeaderSizeExceededError", retryable: false },
5066
- "40": { name: "AuthErrorTokenExpired", retryable: false },
5067
- "41": { name: "AuthErrorTokenNotValidYet", retryable: false },
5068
- "42": { name: "AuthErrorTokenUsedBeforeIssuedAt", retryable: false },
5069
- "43": { name: "AuthErrorTokenSignatureInvalid", retryable: false },
5070
- "44": { name: "CustomCommandEndpointMissingError", retryable: false },
5071
- "45": { name: "CustomCommandEndpointCallError", retryable: true },
5072
- "46": { name: "ConnectionIDNotFoundError", retryable: false },
5073
- "60": { name: "CoolDownError", retryable: true },
5074
- "69": { name: "ErrWrongRegion", retryable: false },
5075
- "70": { name: "ErrQueryChannelPermissions", retryable: false },
5076
- "71": { name: "ErrTooManyConnections", retryable: true },
5077
- "99": { name: "AppSuspendedError", retryable: false }
5078
- };
5079
- function isAPIError(error) {
5080
- return error.code !== void 0;
5081
- }
5082
- function isErrorRetryable(error) {
5083
- if (!error.code) return false;
5084
- const err = APIErrorCodes[`${error.code}`];
5085
- if (!err) return false;
5086
- return err.retryable;
5087
- }
5088
- function isConnectionIDError(error) {
5089
- return error.code === 46;
5090
- }
5091
- function isWSFailure(err) {
5092
- if (typeof err.isWSFailure === "boolean") {
5093
- return err.isWSFailure;
5094
- }
5095
- try {
5096
- return JSON.parse(err.message).isWSFailure;
5097
- } catch (_) {
5098
- return false;
5099
- }
5100
- }
5101
- function isErrorResponse(res) {
5102
- return !res.status || res.status < 200 || 300 <= res.status;
5103
- }
5104
-
5105
- // src/search/BaseSearchSource.ts
5106
- var DEFAULT_SEARCH_SOURCE_OPTIONS = {
5107
- debounceMs: 300,
5108
- pageSize: 10
5109
- };
5110
- var BaseSearchSourceBase = class {
5111
- constructor(options) {
5112
- this.activate = () => {
5113
- if (this.isActive) return;
5114
- this.state.partialNext({ isActive: true });
5115
- };
5116
- this.deactivate = () => {
5117
- if (!this.isActive) return;
5118
- this.state.partialNext({ isActive: false });
5119
- };
5120
- this.canExecuteQuery = (newSearchString) => {
5121
- const hasNewSearchQuery = typeof newSearchString !== "undefined";
5122
- const searchString = newSearchString ?? this.searchQuery;
5123
- return !!(this.isActive && !this.isLoading && (this.hasNext || hasNewSearchQuery) && searchString);
5124
- };
5125
- const { pageSize } = { ...DEFAULT_SEARCH_SOURCE_OPTIONS, ...options };
5126
- this.pageSize = pageSize;
5127
- this.state = new StateStore(this.initialState);
5128
- }
5129
- get lastQueryError() {
5130
- return this.state.getLatestValue().lastQueryError;
5131
- }
5132
- get hasNext() {
5133
- return this.state.getLatestValue().hasNext;
5134
- }
5135
- get hasResults() {
5136
- return Array.isArray(this.state.getLatestValue().items);
5137
- }
5138
- get isActive() {
5139
- return this.state.getLatestValue().isActive;
5140
- }
5141
- get isLoading() {
5142
- return this.state.getLatestValue().isLoading;
5143
- }
5144
- get initialState() {
5145
- return {
5146
- hasNext: true,
5147
- isActive: false,
5148
- isLoading: false,
5149
- items: void 0,
5150
- lastQueryError: void 0,
5151
- next: void 0,
5152
- offset: 0,
5153
- searchQuery: ""
5154
- };
5155
- }
5156
- get items() {
5157
- return this.state.getLatestValue().items;
5158
- }
5159
- get next() {
5160
- return this.state.getLatestValue().next;
5161
- }
5162
- get offset() {
5163
- return this.state.getLatestValue().offset;
5164
- }
5165
- get searchQuery() {
5166
- return this.state.getLatestValue().searchQuery;
5167
- }
5168
- getStateBeforeFirstQuery(newSearchString) {
5169
- return {
5170
- ...this.initialState,
5171
- isActive: this.isActive,
5172
- isLoading: true,
5173
- searchQuery: newSearchString
5174
- };
5175
- }
5176
- getStateAfterQuery(stateUpdate, isFirstPage) {
5177
- const current = this.state.getLatestValue();
5178
- return {
5179
- ...current,
5180
- lastQueryError: void 0,
5181
- // reset lastQueryError that can be overridden by the stateUpdate
5182
- ...stateUpdate,
5183
- isLoading: false,
5184
- items: isFirstPage ? stateUpdate.items : [...this.items ?? [], ...stateUpdate.items || []]
5185
- };
5186
- }
5187
- prepareStateForQuery(newSearchString) {
5188
- const hasNewSearchQuery = typeof newSearchString !== "undefined";
5189
- const searchString = newSearchString ?? this.searchQuery;
5190
- if (hasNewSearchQuery) {
5191
- this.state.next(this.getStateBeforeFirstQuery(newSearchString ?? ""));
5192
- } else {
5193
- this.state.partialNext({ isLoading: true });
5194
- }
5195
- return { searchString, hasNewSearchQuery };
5196
- }
5197
- updatePaginationStateFromQuery(result) {
5198
- const { items, next } = result;
5199
- const stateUpdate = {};
5200
- if (Object.prototype.hasOwnProperty.call(result, "next")) {
5201
- stateUpdate.next = next;
5202
- stateUpdate.hasNext = !!next;
5203
- } else {
5204
- stateUpdate.offset = (this.offset ?? 0) + items.length;
5205
- stateUpdate.hasNext = items.length === this.pageSize;
5206
- }
5207
- return stateUpdate;
5208
- }
5209
- resetState() {
5210
- this.state.next(this.initialState);
5211
- }
5212
- resetStateAndActivate() {
5213
- this.resetState();
5214
- this.activate();
5215
- }
5216
- };
5217
- var BaseSearchSource = class extends BaseSearchSourceBase {
5218
- constructor(options) {
5219
- const { debounceMs } = { ...DEFAULT_SEARCH_SOURCE_OPTIONS, ...options };
5220
- super(options);
5221
- this.setDebounceOptions = ({ debounceMs }) => {
5222
- this.searchDebounced = debounce(this.executeQuery.bind(this), debounceMs);
5223
- };
5224
- this.search = (searchQuery) => this.searchDebounced(searchQuery);
5225
- this.setDebounceOptions({ debounceMs });
5226
- }
5227
- async executeQuery(newSearchString) {
5228
- if (!this.canExecuteQuery(newSearchString)) return;
5229
- const { hasNewSearchQuery, searchString } = this.prepareStateForQuery(newSearchString);
5230
- let stateUpdate = {};
5231
- try {
5232
- const results = await this.query(searchString);
5233
- if (!results) return;
5234
- const { items } = results;
5235
- stateUpdate = this.updatePaginationStateFromQuery(results);
5236
- stateUpdate.items = await this.filterQueryResults(items);
5237
- } catch (e) {
5238
- stateUpdate.lastQueryError = e;
5239
- if (isAPIError(e) && !isErrorRetryable(e)) {
5240
- stateUpdate.hasNext = false;
5241
- }
5242
- } finally {
5243
- this.state.next(this.getStateAfterQuery(stateUpdate, hasNewSearchQuery));
5244
- }
5245
- }
5246
- cancelScheduledQuery() {
5247
- this.searchDebounced.cancel();
5248
- }
5249
- };
5250
- var BaseSearchSourceSync = class extends BaseSearchSourceBase {
5251
- constructor(options) {
5252
- const { debounceMs } = { ...DEFAULT_SEARCH_SOURCE_OPTIONS, ...options };
5253
- super(options);
5254
- this.setDebounceOptions = ({ debounceMs }) => {
5255
- this.searchDebounced = debounce(this.executeQuery.bind(this), debounceMs);
5256
- };
5257
- this.search = (searchQuery) => this.searchDebounced(searchQuery);
5258
- this.setDebounceOptions({ debounceMs });
5259
- }
5260
- executeQuery(newSearchString) {
5261
- if (!this.canExecuteQuery(newSearchString)) return;
5262
- const { hasNewSearchQuery, searchString } = this.prepareStateForQuery(newSearchString);
5263
- let stateUpdate = {};
5264
- try {
5265
- const results = this.query(searchString);
5266
- if (!results) return;
5267
- const { items } = results;
5268
- stateUpdate = this.updatePaginationStateFromQuery(results);
5269
- stateUpdate.items = this.filterQueryResults(items);
5270
- } catch (e) {
5271
- stateUpdate.lastQueryError = e;
5272
- if (isAPIError(e) && !isErrorRetryable(e)) {
5273
- stateUpdate.hasNext = false;
5274
- }
5275
- } finally {
5276
- this.state.next(this.getStateAfterQuery(stateUpdate, hasNewSearchQuery));
5277
- }
5278
- }
5279
- cancelScheduledQuery() {
5280
- this.searchDebounced.cancel();
5281
- }
4968
+ cancelScheduledQuery() {
4969
+ this.searchDebounced.cancel();
4970
+ }
5282
4971
  };
5283
4972
 
5284
4973
  // src/search/SearchController.ts
@@ -5374,586 +5063,1095 @@ var SearchController = class {
5374
5063
  get activeSources() {
5375
5064
  return this.state.getLatestValue().sources.filter((s) => s.isActive);
5376
5065
  }
5377
- get isActive() {
5378
- return this.state.getLatestValue().isActive;
5066
+ get isActive() {
5067
+ return this.state.getLatestValue().isActive;
5068
+ }
5069
+ get searchQuery() {
5070
+ return this.state.getLatestValue().searchQuery;
5071
+ }
5072
+ get searchSourceTypes() {
5073
+ return this.sources.map((s) => s.type);
5074
+ }
5075
+ };
5076
+
5077
+ // src/pagination/BasePaginator.ts
5078
+ var DEFAULT_PAGINATION_OPTIONS = {
5079
+ debounceMs: 300,
5080
+ pageSize: 10
5081
+ };
5082
+ var BasePaginator = class {
5083
+ constructor(options) {
5084
+ this._isCursorPagination = false;
5085
+ this.setDebounceOptions = ({ debounceMs }) => {
5086
+ this._executeQueryDebounced = debounce(this.executeQuery.bind(this), debounceMs);
5087
+ };
5088
+ this.canExecuteQuery = (direction) => !this.isLoading && direction === "next" && this.hasNext || direction === "prev" && this.hasPrev;
5089
+ this.next = () => this.executeQuery({ direction: "next" });
5090
+ this.prev = () => this.executeQuery({ direction: "prev" });
5091
+ this.nextDebounced = () => {
5092
+ this._executeQueryDebounced({ direction: "next" });
5093
+ };
5094
+ this.prevDebounced = () => {
5095
+ this._executeQueryDebounced({ direction: "prev" });
5096
+ };
5097
+ const { debounceMs, pageSize } = { ...DEFAULT_PAGINATION_OPTIONS, ...options };
5098
+ this.pageSize = pageSize;
5099
+ this.state = new StateStore(this.initialState);
5100
+ this.setDebounceOptions({ debounceMs });
5101
+ }
5102
+ get lastQueryError() {
5103
+ return this.state.getLatestValue().lastQueryError;
5104
+ }
5105
+ get hasNext() {
5106
+ return this.state.getLatestValue().hasNext;
5107
+ }
5108
+ get hasPrev() {
5109
+ return this.state.getLatestValue().hasPrev;
5110
+ }
5111
+ get hasResults() {
5112
+ return Array.isArray(this.state.getLatestValue().items);
5113
+ }
5114
+ get isLoading() {
5115
+ return this.state.getLatestValue().isLoading;
5116
+ }
5117
+ get initialState() {
5118
+ return {
5119
+ hasNext: true,
5120
+ hasPrev: true,
5121
+ //todo: check if optimistic value does not cause problems in UI
5122
+ isLoading: false,
5123
+ items: void 0,
5124
+ lastQueryError: void 0,
5125
+ cursor: void 0,
5126
+ offset: 0
5127
+ };
5128
+ }
5129
+ get items() {
5130
+ return this.state.getLatestValue().items;
5131
+ }
5132
+ get cursor() {
5133
+ return this.state.getLatestValue().cursor;
5134
+ }
5135
+ get offset() {
5136
+ return this.state.getLatestValue().offset;
5137
+ }
5138
+ getStateBeforeFirstQuery() {
5139
+ return {
5140
+ ...this.initialState,
5141
+ isLoading: true
5142
+ };
5143
+ }
5144
+ getStateAfterQuery(stateUpdate, isFirstPage) {
5145
+ const current = this.state.getLatestValue();
5146
+ return {
5147
+ ...current,
5148
+ lastQueryError: void 0,
5149
+ // reset lastQueryError that can be overridden by the stateUpdate
5150
+ ...stateUpdate,
5151
+ isLoading: false,
5152
+ items: isFirstPage ? stateUpdate.items : [...this.items ?? [], ...stateUpdate.items || []]
5153
+ };
5154
+ }
5155
+ async executeQuery({ direction }) {
5156
+ if (!this.canExecuteQuery(direction)) return;
5157
+ const isFirstPage = typeof this.items === "undefined";
5158
+ if (isFirstPage) {
5159
+ this.state.next(this.getStateBeforeFirstQuery());
5160
+ } else {
5161
+ this.state.partialNext({ isLoading: true });
5162
+ }
5163
+ const stateUpdate = {};
5164
+ try {
5165
+ const results = await this.query({ direction });
5166
+ if (!results) return;
5167
+ const { items, next, prev } = results;
5168
+ if (isFirstPage && (next || prev)) {
5169
+ this._isCursorPagination = true;
5170
+ }
5171
+ if (this._isCursorPagination) {
5172
+ stateUpdate.cursor = { next: next || null, prev: prev || null };
5173
+ stateUpdate.hasNext = !!next;
5174
+ stateUpdate.hasPrev = !!prev;
5175
+ } else {
5176
+ stateUpdate.offset = (this.offset ?? 0) + items.length;
5177
+ stateUpdate.hasNext = items.length === this.pageSize;
5178
+ }
5179
+ stateUpdate.items = await this.filterQueryResults(items);
5180
+ } catch (e) {
5181
+ stateUpdate.lastQueryError = e;
5182
+ } finally {
5183
+ this.state.next(this.getStateAfterQuery(stateUpdate, isFirstPage));
5184
+ }
5185
+ }
5186
+ cancelScheduledQuery() {
5187
+ this._executeQueryDebounced.cancel();
5188
+ }
5189
+ resetState() {
5190
+ this.state.next(this.initialState);
5191
+ }
5192
+ };
5193
+
5194
+ // src/pagination/FilterBuilder.ts
5195
+ var FilterBuilder = class {
5196
+ constructor(params) {
5197
+ this.context = new StateStore(params?.initialContext ?? {});
5198
+ this.filterConfig = new StateStore(
5199
+ params?.initialFilterConfig ?? {}
5200
+ );
5201
+ }
5202
+ updateFilterConfig(config) {
5203
+ this.filterConfig.partialNext(config);
5204
+ }
5205
+ enableFilter(filterKey) {
5206
+ const config = this.filterConfig.getLatestValue();
5207
+ if (config[filterKey]) {
5208
+ this.filterConfig.partialNext({
5209
+ [filterKey]: {
5210
+ ...config[filterKey],
5211
+ enabled: true
5212
+ }
5213
+ });
5214
+ }
5215
+ }
5216
+ disableFilter(filterKey) {
5217
+ const config = this.filterConfig.getLatestValue();
5218
+ if (config[filterKey]) {
5219
+ this.filterConfig.partialNext({
5220
+ [filterKey]: {
5221
+ ...config[filterKey],
5222
+ enabled: false
5223
+ }
5224
+ });
5225
+ }
5226
+ }
5227
+ updateContext(newContext) {
5228
+ this.context.partialNext(newContext);
5229
+ }
5230
+ buildFilters(params) {
5231
+ const filters = {
5232
+ ...params?.baseFilters ?? {}
5233
+ };
5234
+ const filterConfig = this.filterConfig.getLatestValue();
5235
+ for (const key in filterConfig) {
5236
+ const configItem = filterConfig[key];
5237
+ if (!configItem?.enabled) continue;
5238
+ const generated = configItem.generate({
5239
+ ...this.context.getLatestValue(),
5240
+ ...params?.context ?? {}
5241
+ });
5242
+ if (generated) Object.assign(filters, generated);
5243
+ }
5244
+ return filters;
5245
+ }
5246
+ };
5247
+
5248
+ // src/pagination/ReminderPaginator.ts
5249
+ var ReminderPaginator = class extends BasePaginator {
5250
+ constructor(client, options) {
5251
+ super(options);
5252
+ this.query = async ({
5253
+ direction
5254
+ }) => {
5255
+ const cursor = this.cursor?.[direction];
5256
+ const {
5257
+ reminders: items,
5258
+ next,
5259
+ prev
5260
+ } = await this.client.queryReminders({
5261
+ filter: this.filters,
5262
+ sort: this.sort,
5263
+ limit: this.pageSize,
5264
+ [direction]: cursor
5265
+ });
5266
+ return { items, next, prev };
5267
+ };
5268
+ this.filterQueryResults = (items) => items;
5269
+ this.client = client;
5270
+ }
5271
+ get filters() {
5272
+ return this._filters;
5273
+ }
5274
+ get sort() {
5275
+ return this._sort;
5379
5276
  }
5380
- get searchQuery() {
5381
- return this.state.getLatestValue().searchQuery;
5277
+ set filters(filters) {
5278
+ this._filters = filters;
5279
+ this.resetState();
5382
5280
  }
5383
- get searchSourceTypes() {
5384
- return this.sources.map((s) => s.type);
5281
+ set sort(sort) {
5282
+ this._sort = sort;
5283
+ this.resetState();
5385
5284
  }
5386
5285
  };
5387
5286
 
5388
- // src/pagination/BasePaginator.ts
5389
- var DEFAULT_PAGINATION_OPTIONS = {
5390
- debounceMs: 300,
5391
- pageSize: 10
5392
- };
5393
- var BasePaginator = class {
5394
- constructor(options) {
5395
- this._isCursorPagination = false;
5396
- this.setDebounceOptions = ({ debounceMs }) => {
5397
- this._executeQueryDebounced = debounce(this.executeQuery.bind(this), debounceMs);
5398
- };
5399
- this.canExecuteQuery = (direction) => !this.isLoading && direction === "next" && this.hasNext || direction === "prev" && this.hasPrev;
5400
- this.next = () => this.executeQuery({ direction: "next" });
5401
- this.prev = () => this.executeQuery({ direction: "prev" });
5402
- this.nextDebounced = () => {
5403
- this._executeQueryDebounced({ direction: "next" });
5404
- };
5405
- this.prevDebounced = () => {
5406
- this._executeQueryDebounced({ direction: "prev" });
5407
- };
5408
- const { debounceMs, pageSize } = { ...DEFAULT_PAGINATION_OPTIONS, ...options };
5409
- this.pageSize = pageSize;
5410
- this.state = new StateStore(this.initialState);
5411
- this.setDebounceOptions({ debounceMs });
5287
+ // src/search/UserSearchSource.ts
5288
+ var UserSearchSource = class extends BaseSearchSource {
5289
+ constructor(client, options, filterBuilderOptions = {}) {
5290
+ super(options);
5291
+ this.type = "users";
5292
+ this.client = client;
5293
+ this.filterBuilder = new FilterBuilder({
5294
+ initialFilterConfig: {
5295
+ $or: {
5296
+ enabled: true,
5297
+ generate: ({ searchQuery }) => searchQuery ? {
5298
+ $or: [
5299
+ { id: { $autocomplete: searchQuery } },
5300
+ { name: { $autocomplete: searchQuery } }
5301
+ ]
5302
+ } : null
5303
+ }
5304
+ },
5305
+ ...filterBuilderOptions
5306
+ });
5412
5307
  }
5413
- get lastQueryError() {
5414
- return this.state.getLatestValue().lastQueryError;
5308
+ async query(searchQuery) {
5309
+ const filters = this.filterBuilder.buildFilters({
5310
+ baseFilters: this.filters,
5311
+ context: { searchQuery }
5312
+ });
5313
+ const sort = { id: 1, ...this.sort };
5314
+ const options = { ...this.searchOptions, limit: this.pageSize, offset: this.offset };
5315
+ const { users } = await this.client.queryUsers(filters, sort, options);
5316
+ return { items: users };
5415
5317
  }
5416
- get hasNext() {
5417
- return this.state.getLatestValue().hasNext;
5318
+ filterQueryResults(items) {
5319
+ return items.filter((u) => u.id !== this.client.user?.id);
5418
5320
  }
5419
- get hasPrev() {
5420
- return this.state.getLatestValue().hasPrev;
5321
+ };
5322
+
5323
+ // src/search/ChannelSearchSource.ts
5324
+ var ChannelSearchSource = class extends BaseSearchSource {
5325
+ constructor(client, options, filterBuilderOptions = {}) {
5326
+ super(options);
5327
+ this.type = "channels";
5328
+ this.client = client;
5329
+ this.filterBuilder = new FilterBuilder({
5330
+ ...filterBuilderOptions,
5331
+ initialFilterConfig: {
5332
+ name: {
5333
+ enabled: true,
5334
+ generate: ({ searchQuery }) => searchQuery ? { name: { $autocomplete: searchQuery } } : null
5335
+ },
5336
+ ...filterBuilderOptions.initialFilterConfig
5337
+ }
5338
+ });
5421
5339
  }
5422
- get hasResults() {
5423
- return Array.isArray(this.state.getLatestValue().items);
5340
+ async query(searchQuery) {
5341
+ const filters = this.filterBuilder.buildFilters({
5342
+ baseFilters: {
5343
+ ...this.client.userID ? { members: { $in: [this.client.userID] } } : {},
5344
+ ...this.filters
5345
+ },
5346
+ context: { searchQuery }
5347
+ });
5348
+ const sort = this.sort ?? {};
5349
+ const options = { ...this.searchOptions, limit: this.pageSize, offset: this.offset };
5350
+ const items = await this.client.queryChannels(filters, sort, options);
5351
+ return { items };
5424
5352
  }
5425
- get isLoading() {
5426
- return this.state.getLatestValue().isLoading;
5353
+ filterQueryResults(items) {
5354
+ return items;
5427
5355
  }
5428
- get initialState() {
5429
- return {
5430
- hasNext: true,
5431
- hasPrev: true,
5432
- //todo: check if optimistic value does not cause problems in UI
5433
- isLoading: false,
5434
- items: void 0,
5435
- lastQueryError: void 0,
5436
- cursor: void 0,
5437
- offset: 0
5438
- };
5356
+ };
5357
+
5358
+ // src/search/MessageSearchSource.ts
5359
+ var MessageSearchSource = class extends BaseSearchSource {
5360
+ constructor(client, options, filterBuilderOptions) {
5361
+ super(options);
5362
+ this.type = "messages";
5363
+ this.client = client;
5364
+ this.messageSearchChannelFilterBuilder = new FilterBuilder(filterBuilderOptions?.messageSearchChannel);
5365
+ this.messageSearchFilterBuilder = new FilterBuilder({
5366
+ ...filterBuilderOptions?.messageSearch,
5367
+ initialFilterConfig: {
5368
+ text: {
5369
+ enabled: true,
5370
+ generate: ({ searchQuery }) => searchQuery ? { text: searchQuery } : null
5371
+ },
5372
+ ...filterBuilderOptions?.messageSearch?.initialFilterConfig
5373
+ }
5374
+ });
5375
+ this.channelQueryFilterBuilder = new FilterBuilder({
5376
+ ...filterBuilderOptions?.channelQuery,
5377
+ initialFilterConfig: {
5378
+ cid: {
5379
+ enabled: true,
5380
+ generate: ({ cids }) => cids ? { cid: { $in: cids } } : null
5381
+ },
5382
+ ...filterBuilderOptions?.channelQuery?.initialFilterConfig
5383
+ }
5384
+ });
5439
5385
  }
5440
- get items() {
5441
- return this.state.getLatestValue().items;
5386
+ async query(searchQuery) {
5387
+ if (!this.client.userID || !searchQuery || this.next === null) return { items: [] };
5388
+ const channelFilters = this.messageSearchChannelFilterBuilder.buildFilters({
5389
+ baseFilters: {
5390
+ ...this.client.userID ? { members: { $in: [this.client.userID] } } : {},
5391
+ ...this.messageSearchChannelFilters
5392
+ },
5393
+ context: { searchQuery }
5394
+ });
5395
+ const messageFilters = this.messageSearchFilterBuilder.buildFilters({
5396
+ baseFilters: {
5397
+ type: "regular",
5398
+ ...this.messageSearchFilters
5399
+ },
5400
+ context: { searchQuery }
5401
+ });
5402
+ const sort = {
5403
+ created_at: -1,
5404
+ ...this.messageSearchSort
5405
+ };
5406
+ const options = {
5407
+ limit: this.pageSize,
5408
+ next: this.next,
5409
+ sort
5410
+ };
5411
+ const { next, results } = await this.client.search(
5412
+ channelFilters,
5413
+ messageFilters,
5414
+ options
5415
+ );
5416
+ const items = results.map(({ message }) => message);
5417
+ const cids = Array.from(
5418
+ items.reduce((acc, message) => {
5419
+ if (message.cid && !this.client.activeChannels[message.cid]) acc.add(message.cid);
5420
+ return acc;
5421
+ }, /* @__PURE__ */ new Set())
5422
+ );
5423
+ if (cids.length > 0) {
5424
+ const channelQueryFilters = this.channelQueryFilterBuilder.buildFilters({
5425
+ baseFilters: this.channelQueryFilters,
5426
+ context: { cids }
5427
+ });
5428
+ await this.client.queryChannels(
5429
+ channelQueryFilters,
5430
+ {
5431
+ last_message_at: -1,
5432
+ ...this.channelQuerySort
5433
+ },
5434
+ this.channelQueryOptions
5435
+ );
5436
+ }
5437
+ return { items, next };
5442
5438
  }
5443
- get cursor() {
5444
- return this.state.getLatestValue().cursor;
5439
+ filterQueryResults(items) {
5440
+ return items;
5445
5441
  }
5446
- get offset() {
5447
- return this.state.getLatestValue().offset;
5442
+ };
5443
+
5444
+ // src/messageComposer/middleware/textComposer/commandUtils.ts
5445
+ function escapeCommandRegExp(text) {
5446
+ return text.replace(/[-[\]{}()*+?.,/\\^$|#]/g, "\\$&");
5447
+ }
5448
+ var getRawCommandName = (text) => text?.match(/^\/(\S+)(?:\s.*)?$/)?.[1];
5449
+ var getCompleteCommandInString = (text) => {
5450
+ const match = text.match(/^\/(\S+)\s+.*/);
5451
+ const commandName = match && match[1];
5452
+ return commandName;
5453
+ };
5454
+ var stripCommandFromText = (text, commandName) => text.replace(new RegExp(`^${escapeCommandRegExp(`/${commandName}`)}\\s*`), "");
5455
+ var notifyCommandDisabled = (composer, command) => {
5456
+ const disabledReason = composer.getCommandDisabledReason(command);
5457
+ if (!disabledReason) return;
5458
+ composer.client.notifications.addWarning({
5459
+ message: disabledReason === "editing" ? "Command not available while editing" : "Command not available while replying",
5460
+ origin: {
5461
+ emitter: "MessageComposer",
5462
+ context: { command, composer }
5463
+ },
5464
+ options: {
5465
+ type: "validation:command:disabled",
5466
+ metadata: {
5467
+ command: command.name,
5468
+ reason: disabledReason
5469
+ }
5470
+ }
5471
+ });
5472
+ return true;
5473
+ };
5474
+
5475
+ // src/messageComposer/middleware/textComposer/textMiddlewareUtils.ts
5476
+ var getTriggerCharWithToken = ({
5477
+ trigger,
5478
+ text,
5479
+ isCommand = false,
5480
+ acceptTrailingSpaces = true
5481
+ }) => {
5482
+ const escapedTrigger = escapeCommandRegExp(trigger);
5483
+ const triggerNorWhitespace = `[^\\s${escapedTrigger}]*`;
5484
+ const match = text.match(
5485
+ new RegExp(
5486
+ isCommand ? `^[${escapedTrigger}]${triggerNorWhitespace}$` : acceptTrailingSpaces ? `(?!^|\\W)?[${escapedTrigger}]${triggerNorWhitespace}\\s?${triggerNorWhitespace}$` : `(?!^|\\W)?[${escapedTrigger}]${triggerNorWhitespace}$`,
5487
+ "g"
5488
+ )
5489
+ );
5490
+ return match && match[match.length - 1].trim();
5491
+ };
5492
+ var insertItemWithTrigger = ({
5493
+ insertText,
5494
+ selection,
5495
+ text,
5496
+ trigger
5497
+ }) => {
5498
+ const beforeCursor = text.slice(0, selection.end);
5499
+ const afterCursor = text.slice(selection.end);
5500
+ const lastIndex = beforeCursor.lastIndexOf(trigger);
5501
+ const newText = beforeCursor.slice(0, lastIndex) + insertText + afterCursor;
5502
+ return {
5503
+ text: newText,
5504
+ selection: {
5505
+ start: lastIndex + insertText.length,
5506
+ end: lastIndex + insertText.length
5507
+ }
5508
+ };
5509
+ };
5510
+ var replaceWordWithEntity = async ({
5511
+ caretPosition,
5512
+ getEntityString,
5513
+ text
5514
+ }) => {
5515
+ const lastWordRegex = /([^\s]+)(\s*)$/;
5516
+ const match = lastWordRegex.exec(text.slice(0, caretPosition));
5517
+ if (!match) return text;
5518
+ const lastWord = match[1];
5519
+ if (!lastWord) return text;
5520
+ const spaces = match[2];
5521
+ const newWord = await getEntityString(lastWord);
5522
+ if (newWord == null) return text;
5523
+ const textBeforeWord = text.slice(0, caretPosition - match[0].length);
5524
+ const textAfterCaret = text.slice(caretPosition, -1);
5525
+ return textBeforeWord + newWord + spaces + textAfterCaret;
5526
+ };
5527
+ var getTokenizedSuggestionDisplayName = ({
5528
+ displayName,
5529
+ searchToken
5530
+ }) => ({
5531
+ tokenizedDisplayName: {
5532
+ token: searchToken,
5533
+ parts: searchToken ? displayName.split(new RegExp(`(${escapeCommandRegExp(searchToken)})`, "gi")).filter(Boolean) : [displayName]
5448
5534
  }
5449
- getStateBeforeFirstQuery() {
5450
- return {
5451
- ...this.initialState,
5452
- isLoading: true
5535
+ });
5536
+
5537
+ // src/messageComposer/middleware/textComposer/commands.ts
5538
+ var CommandSearchSource = class extends BaseSearchSourceSync {
5539
+ constructor(channel, options) {
5540
+ super(options);
5541
+ this.type = "commands";
5542
+ this.canExecuteQuery = (newSearchString) => {
5543
+ const hasNewSearchQuery = typeof newSearchString !== "undefined";
5544
+ return this.isActive && !this.isLoading && (this.hasNext || hasNewSearchQuery);
5453
5545
  };
5546
+ this.channel = channel;
5454
5547
  }
5455
- getStateAfterQuery(stateUpdate, isFirstPage) {
5456
- const current = this.state.getLatestValue();
5548
+ getStateBeforeFirstQuery(newSearchString) {
5549
+ const newState = super.getStateBeforeFirstQuery(newSearchString);
5550
+ const { items } = this.state.getLatestValue();
5457
5551
  return {
5458
- ...current,
5459
- lastQueryError: void 0,
5460
- // reset lastQueryError that can be overridden by the stateUpdate
5461
- ...stateUpdate,
5462
- isLoading: false,
5463
- items: isFirstPage ? stateUpdate.items : [...this.items ?? [], ...stateUpdate.items || []]
5552
+ ...newState,
5553
+ items
5554
+ // preserve items to avoid flickering
5464
5555
  };
5465
5556
  }
5466
- async executeQuery({ direction }) {
5467
- if (!this.canExecuteQuery(direction)) return;
5468
- const isFirstPage = typeof this.items === "undefined";
5469
- if (isFirstPage) {
5470
- this.state.next(this.getStateBeforeFirstQuery());
5471
- } else {
5472
- this.state.partialNext({ isLoading: true });
5473
- }
5474
- const stateUpdate = {};
5475
- try {
5476
- const results = await this.query({ direction });
5477
- if (!results) return;
5478
- const { items, next, prev } = results;
5479
- if (isFirstPage && (next || prev)) {
5480
- this._isCursorPagination = true;
5557
+ query(searchQuery) {
5558
+ const channelConfig = this.channel.getConfig();
5559
+ const commands = channelConfig?.commands || [];
5560
+ const selectedCommands = commands.filter(
5561
+ (command) => !!(command.name && command.name.toLowerCase().indexOf(searchQuery.toLowerCase()) !== -1)
5562
+ );
5563
+ selectedCommands.sort((a, b) => {
5564
+ let nameA = a.name?.toLowerCase();
5565
+ let nameB = b.name?.toLowerCase();
5566
+ if (nameA?.indexOf(searchQuery) === 0) {
5567
+ nameA = `0${nameA}`;
5481
5568
  }
5482
- if (this._isCursorPagination) {
5483
- stateUpdate.cursor = { next: next || null, prev: prev || null };
5484
- stateUpdate.hasNext = !!next;
5485
- stateUpdate.hasPrev = !!prev;
5486
- } else {
5487
- stateUpdate.offset = (this.offset ?? 0) + items.length;
5488
- stateUpdate.hasNext = items.length === this.pageSize;
5569
+ if (nameB?.indexOf(searchQuery) === 0) {
5570
+ nameB = `0${nameB}`;
5489
5571
  }
5490
- stateUpdate.items = await this.filterQueryResults(items);
5491
- } catch (e) {
5492
- stateUpdate.lastQueryError = e;
5493
- } finally {
5494
- this.state.next(this.getStateAfterQuery(stateUpdate, isFirstPage));
5495
- }
5572
+ if (nameA != null && nameB != null) {
5573
+ if (nameA < nameB) {
5574
+ return -1;
5575
+ }
5576
+ if (nameA > nameB) {
5577
+ return 1;
5578
+ }
5579
+ }
5580
+ return 0;
5581
+ });
5582
+ return {
5583
+ items: selectedCommands.map((command) => ({
5584
+ ...command,
5585
+ id: command.name
5586
+ })),
5587
+ next: null
5588
+ };
5496
5589
  }
5497
- cancelScheduledQuery() {
5498
- this._executeQueryDebounced.cancel();
5590
+ filterQueryResults(items) {
5591
+ return items;
5499
5592
  }
5500
- resetState() {
5501
- this.state.next(this.initialState);
5593
+ };
5594
+ var DEFAULT_OPTIONS = { minChars: 1, trigger: "/" };
5595
+ var createCommandsMiddleware = (channel, options) => {
5596
+ const finalOptions = mergeWith(DEFAULT_OPTIONS, options ?? {});
5597
+ let searchSource = new CommandSearchSource(channel);
5598
+ if (options?.searchSource) {
5599
+ searchSource = options.searchSource;
5600
+ searchSource.resetState();
5502
5601
  }
5602
+ searchSource.activate();
5603
+ return {
5604
+ id: "stream-io/text-composer/commands-middleware",
5605
+ handlers: {
5606
+ onChange: ({ state, next, complete, forward }) => {
5607
+ if (!state.selection) return forward();
5608
+ const finalText = state.text.slice(0, state.selection.end);
5609
+ const commandName = getCompleteCommandInString(finalText);
5610
+ if (commandName) {
5611
+ const command = searchSource?.query(commandName).items[0];
5612
+ const composer = options?.composer;
5613
+ if (command && !composer?.isCommandDisabled(command)) {
5614
+ return next({
5615
+ ...state,
5616
+ command,
5617
+ suggestions: void 0
5618
+ });
5619
+ }
5620
+ }
5621
+ const triggerWithToken = getTriggerCharWithToken({
5622
+ trigger: finalOptions.trigger,
5623
+ text: finalText,
5624
+ acceptTrailingSpaces: false,
5625
+ isCommand: true
5626
+ });
5627
+ const newSearchTriggerred = triggerWithToken && triggerWithToken.length === finalOptions.minChars;
5628
+ if (newSearchTriggerred) {
5629
+ searchSource.resetStateAndActivate();
5630
+ }
5631
+ const triggerWasRemoved = !triggerWithToken || triggerWithToken.length < finalOptions.minChars;
5632
+ if (triggerWasRemoved) {
5633
+ const hasStaleSuggestions = state.suggestions?.trigger === finalOptions.trigger;
5634
+ const newState = { ...state };
5635
+ if (hasStaleSuggestions) {
5636
+ delete newState.suggestions;
5637
+ }
5638
+ return next(newState);
5639
+ }
5640
+ return complete({
5641
+ ...state,
5642
+ command: null,
5643
+ suggestions: {
5644
+ query: triggerWithToken.slice(1),
5645
+ searchSource,
5646
+ trigger: finalOptions.trigger
5647
+ }
5648
+ });
5649
+ },
5650
+ onSuggestionItemSelect: ({ state, next, forward }) => {
5651
+ const { selectedSuggestion } = state.change ?? {};
5652
+ if (!selectedSuggestion || state.suggestions?.trigger !== finalOptions.trigger)
5653
+ return forward();
5654
+ const composer = options?.composer;
5655
+ if (composer && notifyCommandDisabled(composer, selectedSuggestion)) {
5656
+ return forward();
5657
+ }
5658
+ searchSource.resetStateAndActivate();
5659
+ return next({
5660
+ ...state,
5661
+ ...insertItemWithTrigger({
5662
+ insertText: `/${selectedSuggestion.name} `,
5663
+ selection: state.selection,
5664
+ text: state.text,
5665
+ trigger: finalOptions.trigger
5666
+ }),
5667
+ command: selectedSuggestion,
5668
+ suggestions: void 0
5669
+ });
5670
+ }
5671
+ }
5672
+ };
5503
5673
  };
5504
5674
 
5505
- // src/pagination/FilterBuilder.ts
5506
- var FilterBuilder = class {
5507
- constructor(params) {
5508
- this.context = new StateStore(params?.initialContext ?? {});
5509
- this.filterConfig = new StateStore(
5510
- params?.initialFilterConfig ?? {}
5511
- );
5512
- }
5513
- updateFilterConfig(config) {
5514
- this.filterConfig.partialNext(config);
5675
+ // src/messageComposer/middleware/messageComposer/compositionValidation.ts
5676
+ var getCommandByName = (searchSource, commandName) => {
5677
+ if (!commandName) return;
5678
+ const normalizedCommandName = commandName.toLowerCase();
5679
+ return searchSource.query(normalizedCommandName).items.find((command) => command.name?.toLowerCase() === normalizedCommandName);
5680
+ };
5681
+ var getDisabledRawCommand = (composer, searchSource, text) => {
5682
+ const rawCommand = getCommandByName(searchSource, getRawCommandName(text));
5683
+ if (rawCommand && composer.isCommandDisabled(rawCommand)) {
5684
+ return rawCommand;
5515
5685
  }
5516
- enableFilter(filterKey) {
5517
- const config = this.filterConfig.getLatestValue();
5518
- if (config[filterKey]) {
5519
- this.filterConfig.partialNext({
5520
- [filterKey]: {
5521
- ...config[filterKey],
5522
- enabled: true
5686
+ };
5687
+ var createCompositionValidationMiddleware = (composer) => {
5688
+ const commandSearchSource = new CommandSearchSource(composer.channel);
5689
+ return {
5690
+ id: "stream-io/message-composer-middleware/data-validation",
5691
+ handlers: {
5692
+ compose: async ({
5693
+ state,
5694
+ discard,
5695
+ forward
5696
+ }) => {
5697
+ const { maxLengthOnSend } = composer.config.text ?? {};
5698
+ const inputText = state.message.text ?? "";
5699
+ const disabledRawCommand = getDisabledRawCommand(
5700
+ composer,
5701
+ commandSearchSource,
5702
+ inputText
5703
+ );
5704
+ if (disabledRawCommand) {
5705
+ notifyCommandDisabled(composer, disabledRawCommand);
5706
+ return await discard();
5523
5707
  }
5708
+ const hasExceededMaxLength = typeof maxLengthOnSend === "number" && inputText.length > maxLengthOnSend;
5709
+ if (composer.compositionIsEmpty || hasExceededMaxLength) {
5710
+ return await discard();
5711
+ }
5712
+ return await forward();
5713
+ }
5714
+ }
5715
+ };
5716
+ };
5717
+ var createDraftCompositionValidationMiddleware = (composer) => ({
5718
+ id: "stream-io/message-composer-middleware/draft-data-validation",
5719
+ handlers: {
5720
+ compose: async ({
5721
+ state,
5722
+ discard,
5723
+ forward
5724
+ }) => {
5725
+ const hasData = !textIsEmpty(state.draft.text ?? "") || state.draft.attachments?.length || state.draft.poll_id || state.draft.quoted_message_id;
5726
+ const shouldCreateDraft = composer.lastChangeOriginIsLocal && hasData;
5727
+ if (!shouldCreateDraft) {
5728
+ return await discard();
5729
+ }
5730
+ return await forward();
5731
+ }
5732
+ }
5733
+ });
5734
+
5735
+ // src/messageComposer/middleware/messageComposer/linkPreviews.ts
5736
+ var createLinkPreviewsCompositionMiddleware = (composer) => ({
5737
+ id: "stream-io/message-composer-middleware/link-previews",
5738
+ handlers: {
5739
+ compose: ({
5740
+ state,
5741
+ next,
5742
+ forward
5743
+ }) => {
5744
+ const { linkPreviewsManager } = composer;
5745
+ if (!linkPreviewsManager) return forward();
5746
+ linkPreviewsManager.cancelURLEnrichment();
5747
+ const someLinkPreviewsLoading = linkPreviewsManager.loadingPreviews.length > 0;
5748
+ const someLinkPreviewsDismissed = linkPreviewsManager.dismissedPreviews.length > 0;
5749
+ const linkPreviews = linkPreviewsManager.loadingPreviews.length > 0 ? [] : linkPreviewsManager.loadedPreviews.map(
5750
+ (preview) => LinkPreviewsManager.getPreviewData(preview)
5751
+ );
5752
+ const attachments = (state.message.attachments ?? []).concat(
5753
+ linkPreviews
5754
+ );
5755
+ if (!attachments.length) return forward();
5756
+ const sendOptions = { ...state.sendOptions };
5757
+ const skip_enrich_url = !someLinkPreviewsLoading && linkPreviews.length > 0 || someLinkPreviewsDismissed;
5758
+ if (skip_enrich_url) {
5759
+ sendOptions.skip_enrich_url = true;
5760
+ }
5761
+ return next({
5762
+ ...state,
5763
+ message: {
5764
+ ...state.message,
5765
+ attachments
5766
+ },
5767
+ localMessage: {
5768
+ ...state.localMessage,
5769
+ attachments
5770
+ },
5771
+ sendOptions
5524
5772
  });
5525
5773
  }
5526
5774
  }
5527
- disableFilter(filterKey) {
5528
- const config = this.filterConfig.getLatestValue();
5529
- if (config[filterKey]) {
5530
- this.filterConfig.partialNext({
5531
- [filterKey]: {
5532
- ...config[filterKey],
5533
- enabled: false
5775
+ });
5776
+ var createDraftLinkPreviewsCompositionMiddleware = (composer) => ({
5777
+ id: "stream-io/message-composer-middleware/draft-link-previews",
5778
+ handlers: {
5779
+ compose: ({
5780
+ state,
5781
+ next,
5782
+ forward
5783
+ }) => {
5784
+ const { linkPreviewsManager } = composer;
5785
+ if (!linkPreviewsManager) return forward();
5786
+ linkPreviewsManager.cancelURLEnrichment();
5787
+ const linkPreviews = linkPreviewsManager.loadedPreviews.map(
5788
+ (preview) => LinkPreviewsManager.getPreviewData(preview)
5789
+ );
5790
+ if (!linkPreviews.length) return forward();
5791
+ return next({
5792
+ ...state,
5793
+ draft: {
5794
+ ...state.draft,
5795
+ attachments: (state.draft.attachments ?? []).concat(linkPreviews)
5534
5796
  }
5535
5797
  });
5536
5798
  }
5537
5799
  }
5538
- updateContext(newContext) {
5539
- this.context.partialNext(newContext);
5540
- }
5541
- buildFilters(params) {
5542
- const filters = {
5543
- ...params?.baseFilters ?? {}
5544
- };
5545
- const filterConfig = this.filterConfig.getLatestValue();
5546
- for (const key in filterConfig) {
5547
- const configItem = filterConfig[key];
5548
- if (!configItem?.enabled) continue;
5549
- const generated = configItem.generate({
5550
- ...this.context.getLatestValue(),
5551
- ...params?.context ?? {}
5552
- });
5553
- if (generated) Object.assign(filters, generated);
5554
- }
5555
- return filters;
5556
- }
5557
- };
5800
+ });
5558
5801
 
5559
- // src/pagination/ReminderPaginator.ts
5560
- var ReminderPaginator = class extends BasePaginator {
5561
- constructor(client, options) {
5562
- super(options);
5563
- this.query = async ({
5564
- direction
5802
+ // src/messageComposer/middleware/messageComposer/textComposer.ts
5803
+ var createTextComposerCompositionMiddleware = (composer) => ({
5804
+ id: "stream-io/message-composer-middleware/text-composition",
5805
+ handlers: {
5806
+ compose: ({
5807
+ state,
5808
+ next,
5809
+ forward
5565
5810
  }) => {
5566
- const cursor = this.cursor?.[direction];
5567
- const {
5568
- reminders: items,
5569
- next,
5570
- prev
5571
- } = await this.client.queryReminders({
5572
- filter: this.filters,
5573
- sort: this.sort,
5574
- limit: this.pageSize,
5575
- [direction]: cursor
5811
+ if (!composer.textComposer) return forward();
5812
+ const { mentionedUsers, text } = composer.textComposer;
5813
+ const mentioned_users = Array.from(
5814
+ new Set(
5815
+ mentionedUsers.filter(
5816
+ ({ id, name }) => text.includes(`@${id}`) || text.includes(`@${name}`)
5817
+ )
5818
+ )
5819
+ );
5820
+ if (!text && mentioned_users.length === 0) return forward();
5821
+ return next({
5822
+ ...state,
5823
+ localMessage: {
5824
+ ...state.localMessage,
5825
+ mentioned_users,
5826
+ text
5827
+ },
5828
+ message: {
5829
+ ...state.message,
5830
+ mentioned_users: mentioned_users.map((u) => u.id),
5831
+ text
5832
+ }
5576
5833
  });
5577
- return { items, next, prev };
5578
- };
5579
- this.filterQueryResults = (items) => items;
5580
- this.client = client;
5581
- }
5582
- get filters() {
5583
- return this._filters;
5584
- }
5585
- get sort() {
5586
- return this._sort;
5587
- }
5588
- set filters(filters) {
5589
- this._filters = filters;
5590
- this.resetState();
5591
- }
5592
- set sort(sort) {
5593
- this._sort = sort;
5594
- this.resetState();
5834
+ }
5595
5835
  }
5596
- };
5597
-
5598
- // src/search/UserSearchSource.ts
5599
- var UserSearchSource = class extends BaseSearchSource {
5600
- constructor(client, options, filterBuilderOptions = {}) {
5601
- super(options);
5602
- this.type = "users";
5603
- this.client = client;
5604
- this.filterBuilder = new FilterBuilder({
5605
- initialFilterConfig: {
5606
- $or: {
5607
- enabled: true,
5608
- generate: ({ searchQuery }) => searchQuery ? {
5609
- $or: [
5610
- { id: { $autocomplete: searchQuery } },
5611
- { name: { $autocomplete: searchQuery } }
5612
- ]
5613
- } : null
5836
+ });
5837
+ var createDraftTextComposerCompositionMiddleware = (composer) => ({
5838
+ id: "stream-io/message-composer-middleware/draft-text-composition",
5839
+ handlers: {
5840
+ compose: ({
5841
+ state,
5842
+ next,
5843
+ forward
5844
+ }) => {
5845
+ if (!composer.textComposer) return forward();
5846
+ const { maxLengthOnSend } = composer.config.text ?? {};
5847
+ const { mentionedUsers, text: inputText } = composer.textComposer;
5848
+ const mentioned_users = mentionedUsers.length ? Array.from(
5849
+ new Set(
5850
+ mentionedUsers.filter(
5851
+ ({ id, name }) => inputText.includes(`@${id}`) || inputText.includes(`@${name}`)
5852
+ )
5853
+ )
5854
+ ) : void 0;
5855
+ const text = typeof maxLengthOnSend === "number" && inputText.length > maxLengthOnSend ? inputText.slice(0, maxLengthOnSend) : inputText;
5856
+ return next({
5857
+ ...state,
5858
+ draft: {
5859
+ ...state.draft,
5860
+ mentioned_users: mentioned_users?.map((u) => u.id),
5861
+ text
5614
5862
  }
5615
- },
5616
- ...filterBuilderOptions
5617
- });
5618
- }
5619
- async query(searchQuery) {
5620
- const filters = this.filterBuilder.buildFilters({
5621
- baseFilters: this.filters,
5622
- context: { searchQuery }
5623
- });
5624
- const sort = { id: 1, ...this.sort };
5625
- const options = { ...this.searchOptions, limit: this.pageSize, offset: this.offset };
5626
- const { users } = await this.client.queryUsers(filters, sort, options);
5627
- return { items: users };
5628
- }
5629
- filterQueryResults(items) {
5630
- return items.filter((u) => u.id !== this.client.user?.id);
5631
- }
5632
- };
5633
-
5634
- // src/search/ChannelSearchSource.ts
5635
- var ChannelSearchSource = class extends BaseSearchSource {
5636
- constructor(client, options, filterBuilderOptions = {}) {
5637
- super(options);
5638
- this.type = "channels";
5639
- this.client = client;
5640
- this.filterBuilder = new FilterBuilder({
5641
- ...filterBuilderOptions,
5642
- initialFilterConfig: {
5643
- name: {
5644
- enabled: true,
5645
- generate: ({ searchQuery }) => searchQuery ? { name: { $autocomplete: searchQuery } } : null
5646
- },
5647
- ...filterBuilderOptions.initialFilterConfig
5648
- }
5649
- });
5650
- }
5651
- async query(searchQuery) {
5652
- const filters = this.filterBuilder.buildFilters({
5653
- baseFilters: {
5654
- ...this.client.userID ? { members: { $in: [this.client.userID] } } : {},
5655
- ...this.filters
5656
- },
5657
- context: { searchQuery }
5658
- });
5659
- const sort = this.sort ?? {};
5660
- const options = { ...this.searchOptions, limit: this.pageSize, offset: this.offset };
5661
- const items = await this.client.queryChannels(filters, sort, options);
5662
- return { items };
5663
- }
5664
- filterQueryResults(items) {
5665
- return items;
5863
+ });
5864
+ }
5666
5865
  }
5667
- };
5866
+ });
5668
5867
 
5669
- // src/search/MessageSearchSource.ts
5670
- var MessageSearchSource = class extends BaseSearchSource {
5671
- constructor(client, options, filterBuilderOptions) {
5672
- super(options);
5673
- this.type = "messages";
5674
- this.client = client;
5675
- this.messageSearchChannelFilterBuilder = new FilterBuilder(filterBuilderOptions?.messageSearchChannel);
5676
- this.messageSearchFilterBuilder = new FilterBuilder({
5677
- ...filterBuilderOptions?.messageSearch,
5678
- initialFilterConfig: {
5679
- text: {
5680
- enabled: true,
5681
- generate: ({ searchQuery }) => searchQuery ? { text: searchQuery } : null
5682
- },
5683
- ...filterBuilderOptions?.messageSearch?.initialFilterConfig
5868
+ // src/messageComposer/middleware/messageComposer/messageComposerState.ts
5869
+ var createMessageComposerStateCompositionMiddleware = (composer) => ({
5870
+ id: "stream-io/message-composer-middleware/own-state",
5871
+ handlers: {
5872
+ compose: ({
5873
+ state,
5874
+ next
5875
+ }) => {
5876
+ const payload = {};
5877
+ if (composer.quotedMessage) {
5878
+ payload.quoted_message_id = composer.quotedMessage.id;
5684
5879
  }
5685
- });
5686
- this.channelQueryFilterBuilder = new FilterBuilder({
5687
- ...filterBuilderOptions?.channelQuery,
5688
- initialFilterConfig: {
5689
- cid: {
5690
- enabled: true,
5691
- generate: ({ cids }) => cids ? { cid: { $in: cids } } : null
5692
- },
5693
- ...filterBuilderOptions?.channelQuery?.initialFilterConfig
5880
+ if (composer.pollId) {
5881
+ payload.poll_id = composer.pollId;
5694
5882
  }
5695
- });
5883
+ if (composer.showReplyInChannel) {
5884
+ payload.show_in_channel = true;
5885
+ }
5886
+ return next({
5887
+ ...state,
5888
+ localMessage: {
5889
+ ...state.localMessage,
5890
+ ...payload,
5891
+ quoted_message: composer.quotedMessage ?? void 0
5892
+ },
5893
+ message: {
5894
+ ...state.message,
5895
+ ...payload
5896
+ }
5897
+ });
5898
+ }
5696
5899
  }
5697
- async query(searchQuery) {
5698
- if (!this.client.userID || !searchQuery || this.next === null) return { items: [] };
5699
- const channelFilters = this.messageSearchChannelFilterBuilder.buildFilters({
5700
- baseFilters: {
5701
- ...this.client.userID ? { members: { $in: [this.client.userID] } } : {},
5702
- ...this.messageSearchChannelFilters
5703
- },
5704
- context: { searchQuery }
5705
- });
5706
- const messageFilters = this.messageSearchFilterBuilder.buildFilters({
5707
- baseFilters: {
5708
- type: "regular",
5709
- ...this.messageSearchFilters
5710
- },
5711
- context: { searchQuery }
5712
- });
5713
- const sort = {
5714
- created_at: -1,
5715
- ...this.messageSearchSort
5716
- };
5717
- const options = {
5718
- limit: this.pageSize,
5719
- next: this.next,
5720
- sort
5721
- };
5722
- const { next, results } = await this.client.search(
5723
- channelFilters,
5724
- messageFilters,
5725
- options
5726
- );
5727
- const items = results.map(({ message }) => message);
5728
- const cids = Array.from(
5729
- items.reduce((acc, message) => {
5730
- if (message.cid && !this.client.activeChannels[message.cid]) acc.add(message.cid);
5731
- return acc;
5732
- }, /* @__PURE__ */ new Set())
5733
- );
5734
- if (cids.length > 0) {
5735
- const channelQueryFilters = this.channelQueryFilterBuilder.buildFilters({
5736
- baseFilters: this.channelQueryFilters,
5737
- context: { cids }
5900
+ });
5901
+ var createDraftMessageComposerStateCompositionMiddleware = (composer) => ({
5902
+ id: "stream-io/message-composer-middleware/draft-own-state",
5903
+ handlers: {
5904
+ compose: ({
5905
+ state,
5906
+ next
5907
+ }) => {
5908
+ const payload = {};
5909
+ if (composer.quotedMessage) {
5910
+ payload.quoted_message_id = composer.quotedMessage.id;
5911
+ }
5912
+ if (composer.pollId) {
5913
+ payload.poll_id = composer.pollId;
5914
+ }
5915
+ if (composer.showReplyInChannel) {
5916
+ payload.show_in_channel = true;
5917
+ }
5918
+ return next({
5919
+ ...state,
5920
+ draft: {
5921
+ ...state.draft,
5922
+ ...payload
5923
+ }
5738
5924
  });
5739
- await this.client.queryChannels(
5740
- channelQueryFilters,
5741
- {
5742
- last_message_at: -1,
5743
- ...this.channelQuerySort
5744
- },
5745
- this.channelQueryOptions
5746
- );
5747
5925
  }
5748
- return { items, next };
5749
5926
  }
5750
- filterQueryResults(items) {
5751
- return items;
5927
+ });
5928
+
5929
+ // src/messageComposer/middleware/messageComposer/userDataInjection.ts
5930
+ var createUserDataInjectionMiddleware = (composer) => ({
5931
+ id: "stream-io/message-composer-middleware/user-data-injection",
5932
+ handlers: {
5933
+ compose: ({
5934
+ state,
5935
+ next,
5936
+ forward
5937
+ }) => {
5938
+ if (!composer.client.user) {
5939
+ return forward();
5940
+ }
5941
+ const { channel_mutes, devices, mutes, ...messageUser } = composer.client.user;
5942
+ return next({
5943
+ ...state,
5944
+ localMessage: {
5945
+ ...state.localMessage,
5946
+ user: messageUser,
5947
+ user_id: messageUser.id
5948
+ }
5949
+ });
5950
+ }
5752
5951
  }
5753
- };
5952
+ });
5754
5953
 
5755
- // src/messageComposer/middleware/textComposer/textMiddlewareUtils.ts
5756
- var getTriggerCharWithToken = ({
5757
- trigger,
5758
- text,
5759
- isCommand = false,
5760
- acceptTrailingSpaces = true
5761
- }) => {
5762
- const escapedTrigger = escapeRegExp(trigger);
5763
- const triggerNorWhitespace = `[^\\s${escapedTrigger}]*`;
5764
- const match = text.match(
5765
- new RegExp(
5766
- isCommand ? `^[${escapedTrigger}]${triggerNorWhitespace}$` : acceptTrailingSpaces ? `(?!^|\\W)?[${escapedTrigger}]${triggerNorWhitespace}\\s?${triggerNorWhitespace}$` : `(?!^|\\W)?[${escapedTrigger}]${triggerNorWhitespace}$`,
5767
- "g"
5768
- )
5769
- );
5770
- return match && match[match.length - 1].trim();
5771
- };
5772
- var getCompleteCommandInString = (text) => {
5773
- const match = text.match(/^\/(\S+)\s+.*/);
5774
- const commandName = match && match[1];
5775
- return commandName;
5954
+ // src/messageComposer/middleware/messageComposer/pollOnly.ts
5955
+ var pollLocalMessageNullifiedFields = {
5956
+ attachments: [],
5957
+ mentioned_users: [],
5958
+ parent_id: void 0,
5959
+ quoted_message: void 0,
5960
+ text: ""
5776
5961
  };
5777
- var insertItemWithTrigger = ({
5778
- insertText,
5779
- selection,
5780
- text,
5781
- trigger
5782
- }) => {
5783
- const beforeCursor = text.slice(0, selection.end);
5784
- const afterCursor = text.slice(selection.end);
5785
- const lastIndex = beforeCursor.lastIndexOf(trigger);
5786
- const newText = beforeCursor.slice(0, lastIndex) + insertText + afterCursor;
5787
- return {
5788
- text: newText,
5789
- selection: {
5790
- start: lastIndex + insertText.length,
5791
- end: lastIndex + insertText.length
5962
+ var createPollOnlyCompositionMiddleware = (composer) => ({
5963
+ id: "stream-io/message-composer-middleware/poll-only",
5964
+ handlers: {
5965
+ compose: ({
5966
+ state,
5967
+ complete,
5968
+ forward
5969
+ }) => {
5970
+ const pollId = composer.pollId;
5971
+ const isEditingMessage = !!composer.editedMessage;
5972
+ const isComposingThreadReply = !!composer.threadId;
5973
+ if (!pollId || isComposingThreadReply || isEditingMessage) return forward();
5974
+ return complete({
5975
+ ...state,
5976
+ localMessage: {
5977
+ ...state.localMessage,
5978
+ ...pollLocalMessageNullifiedFields,
5979
+ poll_id: pollId
5980
+ },
5981
+ message: {
5982
+ id: state.localMessage.id,
5983
+ poll_id: pollId
5984
+ }
5985
+ });
5986
+ }
5987
+ }
5988
+ });
5989
+
5990
+ // src/messageComposer/middleware/messageComposer/sharedLocation.ts
5991
+ var createSharedLocationCompositionMiddleware = (composer) => ({
5992
+ id: "stream-io/message-composer-middleware/shared-location",
5993
+ handlers: {
5994
+ compose: ({
5995
+ state,
5996
+ next,
5997
+ forward
5998
+ }) => {
5999
+ const { locationComposer } = composer;
6000
+ const location = locationComposer.validLocation;
6001
+ if (!locationComposer || !location || !composer.client.user) return forward();
6002
+ const timestamp = (/* @__PURE__ */ new Date()).toISOString();
6003
+ return next({
6004
+ ...state,
6005
+ localMessage: {
6006
+ ...state.localMessage,
6007
+ shared_location: {
6008
+ ...location,
6009
+ channel_cid: composer.channel.cid,
6010
+ created_at: timestamp,
6011
+ updated_at: timestamp,
6012
+ user_id: composer.client.user.id
6013
+ }
6014
+ },
6015
+ message: {
6016
+ ...state.message,
6017
+ shared_location: location
6018
+ }
6019
+ });
5792
6020
  }
5793
- };
5794
- };
5795
- var replaceWordWithEntity = async ({
5796
- caretPosition,
5797
- getEntityString,
5798
- text
5799
- }) => {
5800
- const lastWordRegex = /([^\s]+)(\s*)$/;
5801
- const match = lastWordRegex.exec(text.slice(0, caretPosition));
5802
- if (!match) return text;
5803
- const lastWord = match[1];
5804
- if (!lastWord) return text;
5805
- const spaces = match[2];
5806
- const newWord = await getEntityString(lastWord);
5807
- if (newWord == null) return text;
5808
- const textBeforeWord = text.slice(0, caretPosition - match[0].length);
5809
- const textAfterCaret = text.slice(caretPosition, -1);
5810
- return textBeforeWord + newWord + spaces + textAfterCaret;
5811
- };
5812
- function escapeRegExp(text) {
5813
- return text.replace(/[-[\]{}()*+?.,/\\^$|#]/g, "\\$&");
5814
- }
5815
- var getTokenizedSuggestionDisplayName = ({
5816
- displayName,
5817
- searchToken
5818
- }) => ({
5819
- tokenizedDisplayName: {
5820
- token: searchToken,
5821
- parts: searchToken ? displayName.split(new RegExp(`(${escapeRegExp(searchToken)})`, "gi")).filter(Boolean) : [displayName]
5822
6021
  }
5823
6022
  });
5824
6023
 
5825
- // src/messageComposer/middleware/textComposer/commands.ts
5826
- var CommandSearchSource = class extends BaseSearchSourceSync {
5827
- constructor(channel, options) {
5828
- super(options);
5829
- this.type = "commands";
5830
- this.canExecuteQuery = (newSearchString) => {
5831
- const hasNewSearchQuery = typeof newSearchString !== "undefined";
5832
- return this.isActive && !this.isLoading && (this.hasNext || hasNewSearchQuery);
5833
- };
5834
- this.channel = channel;
6024
+ // src/messageComposer/middleware/messageComposer/MessageComposerMiddlewareExecutor.ts
6025
+ var MessageComposerMiddlewareExecutor = class extends MiddlewareExecutor {
6026
+ constructor({ composer }) {
6027
+ super();
6028
+ this.use([
6029
+ createUserDataInjectionMiddleware(composer),
6030
+ createPollOnlyCompositionMiddleware(composer),
6031
+ createTextComposerCompositionMiddleware(composer),
6032
+ createAttachmentsCompositionMiddleware(composer),
6033
+ createLinkPreviewsCompositionMiddleware(composer),
6034
+ createSharedLocationCompositionMiddleware(composer),
6035
+ createMessageComposerStateCompositionMiddleware(composer),
6036
+ createCustomDataCompositionMiddleware(composer),
6037
+ createCompositionValidationMiddleware(composer),
6038
+ createCompositionDataCleanupMiddleware(composer)
6039
+ ]);
5835
6040
  }
5836
- getStateBeforeFirstQuery(newSearchString) {
5837
- const newState = super.getStateBeforeFirstQuery(newSearchString);
5838
- const { items } = this.state.getLatestValue();
5839
- return {
5840
- ...newState,
5841
- items
5842
- // preserve items to avoid flickering
5843
- };
6041
+ };
6042
+ var MessageDraftComposerMiddlewareExecutor = class extends MiddlewareExecutor {
6043
+ constructor({ composer }) {
6044
+ super();
6045
+ this.use([
6046
+ createDraftTextComposerCompositionMiddleware(composer),
6047
+ createDraftAttachmentsCompositionMiddleware(composer),
6048
+ createDraftLinkPreviewsCompositionMiddleware(composer),
6049
+ createDraftMessageComposerStateCompositionMiddleware(composer),
6050
+ createDraftCustomDataCompositionMiddleware(composer),
6051
+ createDraftCompositionValidationMiddleware(composer)
6052
+ ]);
5844
6053
  }
5845
- query(searchQuery) {
5846
- const channelConfig = this.channel.getConfig();
5847
- const commands = channelConfig?.commands || [];
5848
- const selectedCommands = commands.filter(
5849
- (command) => !!(command.name && command.name.toLowerCase().indexOf(searchQuery.toLowerCase()) !== -1)
5850
- );
5851
- selectedCommands.sort((a, b) => {
5852
- let nameA = a.name?.toLowerCase();
5853
- let nameB = b.name?.toLowerCase();
5854
- if (nameA?.indexOf(searchQuery) === 0) {
5855
- nameA = `0${nameA}`;
5856
- }
5857
- if (nameB?.indexOf(searchQuery) === 0) {
5858
- nameB = `0${nameB}`;
6054
+ };
6055
+
6056
+ // src/messageComposer/middleware/messageComposer/commandInjection.ts
6057
+ var createCommandInjectionMiddleware = (composer) => ({
6058
+ handlers: {
6059
+ compose: ({
6060
+ forward,
6061
+ next,
6062
+ state
6063
+ }) => {
6064
+ const command = composer.textComposer.command;
6065
+ if (!command) {
6066
+ return forward();
5859
6067
  }
5860
- if (nameA != null && nameB != null) {
5861
- if (nameA < nameB) {
5862
- return -1;
6068
+ const { text } = state.localMessage;
6069
+ const injection = `/${command?.name}`;
6070
+ const enrichedText = `${injection} ${text}`;
6071
+ return next({
6072
+ ...state,
6073
+ localMessage: {
6074
+ ...state.localMessage,
6075
+ text: enrichedText
6076
+ },
6077
+ message: {
6078
+ ...state.message,
6079
+ text: enrichedText
5863
6080
  }
5864
- if (nameA > nameB) {
5865
- return 1;
6081
+ });
6082
+ }
6083
+ },
6084
+ id: "stream-io/message-composer-middleware/command-string-injection"
6085
+ });
6086
+ var createDraftCommandInjectionMiddleware = (composer) => ({
6087
+ handlers: {
6088
+ compose: ({
6089
+ forward,
6090
+ next,
6091
+ state
6092
+ }) => {
6093
+ const command = composer.textComposer.command;
6094
+ if (!command) {
6095
+ return forward();
6096
+ }
6097
+ const { text } = state.draft;
6098
+ const injection = `/${command?.name}`;
6099
+ const enrichedText = `${injection} ${text}`;
6100
+ return next({
6101
+ ...state,
6102
+ draft: {
6103
+ ...state.draft,
6104
+ text: enrichedText
5866
6105
  }
6106
+ });
6107
+ }
6108
+ },
6109
+ id: "stream-io/message-composer-middleware/draft-command-string-injection"
6110
+ });
6111
+
6112
+ // src/messageComposer/middleware/textComposer/activeCommandGuard.ts
6113
+ var createActiveCommandGuardMiddleware = () => ({
6114
+ handlers: {
6115
+ onChange: ({ complete, forward, state }) => {
6116
+ if (state.command) {
6117
+ return complete(state);
5867
6118
  }
5868
- return 0;
5869
- });
5870
- return {
5871
- items: selectedCommands.map((c) => ({ ...c, id: c.name })),
5872
- next: null
5873
- };
5874
- }
5875
- filterQueryResults(items) {
5876
- return items;
5877
- }
6119
+ return forward();
6120
+ },
6121
+ onSuggestionItemSelect: ({ forward }) => forward()
6122
+ },
6123
+ id: "stream-io/text-composer/active-command-guard"
6124
+ });
6125
+
6126
+ // src/messageComposer/middleware/textComposer/commandEffects.ts
6127
+ var emptyCommandStateToRestore = {
6128
+ selection: { start: 0, end: 0 },
6129
+ text: ""
5878
6130
  };
5879
- var DEFAULT_OPTIONS = { minChars: 1, trigger: "/" };
5880
- var createCommandsMiddleware = (channel, options) => {
5881
- const finalOptions = mergeWith(DEFAULT_OPTIONS, options ?? {});
5882
- let searchSource = new CommandSearchSource(channel);
5883
- if (options?.searchSource) {
5884
- searchSource = options.searchSource;
5885
- searchSource.resetState();
5886
- }
5887
- searchSource.activate();
5888
- return {
5889
- id: "stream-io/text-composer/commands-middleware",
5890
- handlers: {
5891
- onChange: ({ state, next, complete, forward }) => {
5892
- if (!state.selection) return forward();
5893
- const finalText = state.text.slice(0, state.selection.end);
5894
- const commandName = getCompleteCommandInString(finalText);
5895
- if (commandName) {
5896
- const command = searchSource?.query(commandName).items[0];
5897
- if (command) {
5898
- return next({
5899
- ...state,
5900
- command,
5901
- suggestions: void 0
5902
- });
5903
- }
5904
- }
5905
- const triggerWithToken = getTriggerCharWithToken({
5906
- trigger: finalOptions.trigger,
5907
- text: finalText,
5908
- acceptTrailingSpaces: false,
5909
- isCommand: true
5910
- });
5911
- const newSearchTriggerred = triggerWithToken && triggerWithToken.length === finalOptions.minChars;
5912
- if (newSearchTriggerred) {
5913
- searchSource.resetStateAndActivate();
5914
- }
5915
- const triggerWasRemoved = !triggerWithToken || triggerWithToken.length < finalOptions.minChars;
5916
- if (triggerWasRemoved) {
5917
- const hasStaleSuggestions = state.suggestions?.trigger === finalOptions.trigger;
5918
- const newState = { ...state };
5919
- if (hasStaleSuggestions) {
5920
- delete newState.suggestions;
5921
- }
5922
- return next(newState);
5923
- }
5924
- return complete({
5925
- ...state,
5926
- command: null,
5927
- suggestions: {
5928
- query: triggerWithToken.slice(1),
5929
- searchSource,
5930
- trigger: finalOptions.trigger
5931
- }
5932
- });
5933
- },
5934
- onSuggestionItemSelect: ({ state, next, forward }) => {
5935
- const { selectedSuggestion } = state.change ?? {};
5936
- if (!selectedSuggestion || state.suggestions?.trigger !== finalOptions.trigger)
5937
- return forward();
5938
- searchSource.resetStateAndActivate();
5939
- return next({
5940
- ...state,
5941
- ...insertItemWithTrigger({
5942
- insertText: `/${selectedSuggestion.name} `,
5943
- selection: state.selection,
5944
- text: state.text,
5945
- trigger: finalOptions.trigger
5946
- }),
5947
- command: selectedSuggestion,
5948
- suggestions: void 0
5949
- });
6131
+ var createCommandActivationEffect = (command) => ({
6132
+ command,
6133
+ stateToRestore: emptyCommandStateToRestore,
6134
+ type: "command.activate"
6135
+ });
6136
+ var isCommandResponse = (suggestion) => typeof suggestion?.name === "string";
6137
+ var createCommandEffectsMiddleware = () => ({
6138
+ handlers: {
6139
+ onChange: ({ forward }) => forward(),
6140
+ onSuggestionItemSelect: ({ state, next, forward }) => {
6141
+ const { selectedSuggestion } = state.change ?? {};
6142
+ if (!isCommandResponse(selectedSuggestion) || !state.command || state.command.name !== selectedSuggestion.name) {
6143
+ return forward();
5950
6144
  }
6145
+ return next({
6146
+ ...state,
6147
+ effects: [...state.effects ?? [], createCommandActivationEffect(state.command)]
6148
+ });
5951
6149
  }
5952
- };
5953
- };
6150
+ },
6151
+ id: "stream-io/text-composer/command-effects-middleware"
6152
+ });
5954
6153
 
5955
6154
  // src/messageComposer/middleware/textComposer/commandStringExtraction.ts
5956
- var stripCommandFromText = (text, commandName) => text.replace(new RegExp(`^${escapeRegExp(`/${commandName}`)}\\s*`), "");
5957
6155
  var createCommandStringExtractionMiddleware = () => ({
5958
6156
  handlers: {
5959
6157
  onChange: ({ complete, forward, state }) => {
@@ -6293,7 +6491,10 @@ var TextComposerMiddlewareExecutor = class extends MiddlewareExecutor {
6293
6491
  this.use([
6294
6492
  createTextComposerPreValidationMiddleware(composer),
6295
6493
  createMentionsMiddleware(composer.channel),
6296
- createCommandsMiddleware(composer.channel)
6494
+ createCommandsMiddleware(composer.channel, {
6495
+ composer
6496
+ }),
6497
+ createCommandEffectsMiddleware()
6297
6498
  ]);
6298
6499
  }
6299
6500
  async execute({
@@ -6342,6 +6543,10 @@ var TextComposer = class {
6342
6543
  this.initState = ({ message } = {}) => {
6343
6544
  this.state.next(initState5({ composer: this.composer, message }));
6344
6545
  };
6546
+ this.getSnapshot = (state = this.state.getLatestValue()) => state;
6547
+ this.restoreSnapshot = (snapshot) => {
6548
+ this.state.next(snapshot);
6549
+ };
6345
6550
  this.upsertMentionedUser = (user) => {
6346
6551
  const mentionedUsers = [...this.mentionedUsers];
6347
6552
  const existingUserIndex = mentionedUsers.findIndex((u) => u.id === user.id);
@@ -6362,8 +6567,27 @@ var TextComposer = class {
6362
6567
  this.state.partialNext({ mentionedUsers });
6363
6568
  };
6364
6569
  this.setCommand = (command) => {
6365
- if (command?.name === this.command?.name) return;
6366
- this.state.partialNext({ command });
6570
+ if (!command) {
6571
+ this.clearCommand();
6572
+ return;
6573
+ }
6574
+ if (command.name === this.command?.name) return;
6575
+ if (this.composer.isCommandDisabled(command)) return;
6576
+ const stateToRestore = {
6577
+ command: null
6578
+ };
6579
+ this.commitState({
6580
+ ...this.state.getLatestValue(),
6581
+ command,
6582
+ effects: [
6583
+ {
6584
+ command,
6585
+ stateToRestore,
6586
+ type: "command.activate"
6587
+ }
6588
+ ],
6589
+ suggestions: void 0
6590
+ });
6367
6591
  };
6368
6592
  this.setText = (text) => {
6369
6593
  if (!this.enabled || text === this.text) return;
@@ -6430,6 +6654,12 @@ var TextComposer = class {
6430
6654
  this.state.partialNext({ suggestions: void 0 });
6431
6655
  };
6432
6656
  // --- END STATE API ---
6657
+ this.commitState = (state) => {
6658
+ const { change, effects, ...nextState } = state;
6659
+ void change;
6660
+ this.state.next(nextState);
6661
+ this.composer.applyEffects(effects);
6662
+ };
6433
6663
  // --- START TEXT PROCESSING ----
6434
6664
  this.handleChange = async ({
6435
6665
  text,
@@ -6445,7 +6675,7 @@ var TextComposer = class {
6445
6675
  }
6446
6676
  });
6447
6677
  if (output.status === "discard") return;
6448
- this.state.next(output.state);
6678
+ this.commitState(output.state);
6449
6679
  if (this.config.publishTypingEvents && text) {
6450
6680
  logChatPromiseExecution(
6451
6681
  this.channel.keystroke(this.composer.threadId ?? void 0),
@@ -6466,7 +6696,7 @@ var TextComposer = class {
6466
6696
  }
6467
6697
  });
6468
6698
  if (output?.status === "discard") return;
6469
- this.state.next(output.state);
6699
+ this.commitState(output.state);
6470
6700
  };
6471
6701
  this.composer = composer;
6472
6702
  this.state = new StateStore(initState5({ composer, message }));
@@ -6536,7 +6766,12 @@ var TextComposer = class {
6536
6766
  this.state.partialNext({ mentionedUsers: users });
6537
6767
  }
6538
6768
  clearCommand() {
6539
- this.state.partialNext({ command: null });
6769
+ if (!this.command) return;
6770
+ this.commitState({
6771
+ ...this.state.getLatestValue(),
6772
+ command: null,
6773
+ effects: [{ type: "command.clear" }]
6774
+ });
6540
6775
  }
6541
6776
  // --- END TEXT PROCESSING ----
6542
6777
  };
@@ -7027,15 +7262,28 @@ var _MessageComposer = class _MessageComposer extends WithSubscriptions {
7027
7262
  client
7028
7263
  }) {
7029
7264
  super();
7265
+ this.snapshots = [];
7030
7266
  this.setEditedMessage = (editedMessage) => {
7031
7267
  this.state.partialNext({ editedMessage: editedMessage ?? null });
7268
+ if (editedMessage) {
7269
+ this.textComposer.clearCommand();
7270
+ }
7271
+ };
7272
+ this.getCommandDisabledReason = (command) => {
7273
+ if (this.editedMessage) return "editing";
7274
+ if (this.quotedMessage && (command.set === "moderation_set" || command.name === "moderation_set")) {
7275
+ return "quoted_message";
7276
+ }
7277
+ return void 0;
7032
7278
  };
7279
+ this.isCommandDisabled = (command) => !!this.getCommandDisabledReason(command);
7033
7280
  this.refreshId = () => {
7034
7281
  this.state.partialNext({ id: _MessageComposer.generateId() });
7035
7282
  };
7036
7283
  this.initState = ({
7037
7284
  composition
7038
7285
  } = {}) => {
7286
+ this.clearSnapshots();
7039
7287
  this.editingAuditState.partialNext(this.initEditingAuditState(composition));
7040
7288
  const message = typeof composition === "undefined" ? composition : compositionIsDraftResponse(composition) ? composition.message : formatMessage(composition);
7041
7289
  this.attachmentManager.initState({ message });
@@ -7065,6 +7313,36 @@ var _MessageComposer = class _MessageComposer extends WithSubscriptions {
7065
7313
  }
7066
7314
  };
7067
7315
  this.initEditingAuditState = (composition) => initEditingAuditState(composition);
7316
+ this.clearSnapshots = () => {
7317
+ this.snapshots = [];
7318
+ };
7319
+ this.getSnapshot = () => ({
7320
+ attachmentManager: this.attachmentManager.getSnapshot(),
7321
+ customDataManager: this.customDataManager.getSnapshot(),
7322
+ linkPreviewsManager: this.linkPreviewsManager.getSnapshot(),
7323
+ locationComposer: this.locationComposer.getSnapshot(),
7324
+ pollComposer: this.pollComposer.getSnapshot(),
7325
+ textComposer: this.textComposer.getSnapshot()
7326
+ });
7327
+ this.restoreSnapshot = (snapshot) => {
7328
+ this.attachmentManager.restoreSnapshot(snapshot.attachmentManager);
7329
+ this.linkPreviewsManager.restoreSnapshot(snapshot.linkPreviewsManager);
7330
+ this.locationComposer.restoreSnapshot(snapshot.locationComposer);
7331
+ this.pollComposer.restoreSnapshot(snapshot.pollComposer);
7332
+ this.customDataManager.restoreSnapshot(snapshot.customDataManager);
7333
+ this.textComposer.restoreSnapshot(snapshot.textComposer);
7334
+ };
7335
+ this.captureSnapshot = (snapshot = this.getSnapshot()) => {
7336
+ if (this.snapshots.length) return;
7337
+ this.snapshots.push(snapshot);
7338
+ };
7339
+ this.popSnapshot = () => this.snapshots.pop();
7340
+ this.registerEffectHandler = (type, handler) => {
7341
+ this.effectHandlers.registerEffectHandler(type, handler);
7342
+ };
7343
+ this.applyEffects = (effects = []) => {
7344
+ this.effectHandlers.applyEffects(effects);
7345
+ };
7068
7346
  this.registerDraftEventSubscriptions = () => {
7069
7347
  const unsubscribeDraftUpdated = this.subscribeDraftUpdated();
7070
7348
  const unsubscribeDraftDeleted = this.subscribeDraftDeleted();
@@ -7244,6 +7522,10 @@ var _MessageComposer = class _MessageComposer extends WithSubscriptions {
7244
7522
  };
7245
7523
  this.setQuotedMessage = (quotedMessage) => {
7246
7524
  this.state.partialNext({ quotedMessage });
7525
+ const activeCommand = this.textComposer.command;
7526
+ if (quotedMessage && activeCommand && this.isCommandDisabled(activeCommand)) {
7527
+ this.textComposer.clearCommand();
7528
+ }
7247
7529
  };
7248
7530
  this.toggleShowReplyInChannel = () => {
7249
7531
  this.state.partialNext({ showReplyInChannel: !this.showReplyInChannel });
@@ -7478,6 +7760,7 @@ var _MessageComposer = class _MessageComposer extends WithSubscriptions {
7478
7760
  this.draftCompositionMiddlewareExecutor = new MessageDraftComposerMiddlewareExecutor({
7479
7761
  composer: this
7480
7762
  });
7763
+ this.effectHandlers = new MessageComposerEffectHandlers({ composer: this });
7481
7764
  }
7482
7765
  static evaluateContextType(compositionContext) {
7483
7766
  if (compositionContext instanceof Channel) {
@@ -10152,8 +10435,9 @@ var StableWSConnection = class {
10152
10435
  this.onmessage = (wsID, event) => {
10153
10436
  if (this.wsID !== wsID) return;
10154
10437
  this._log("onmessage() - onmessage callback", { event, wsID });
10155
- const data = typeof event.data === "string" ? JSON.parse(event.data) : null;
10156
- if (!this.isResolved && data) {
10438
+ if (typeof event.data !== "string") return;
10439
+ const data = JSON.parse(event.data);
10440
+ if (!this.isResolved) {
10157
10441
  this.isResolved = true;
10158
10442
  if (data.error) {
10159
10443
  this.rejectPromise?.(this._errorFromWSEvent(data, false));
@@ -10163,10 +10447,10 @@ var StableWSConnection = class {
10163
10447
  this._setHealth(true);
10164
10448
  }
10165
10449
  this.lastEvent = /* @__PURE__ */ new Date();
10166
- if (data && data.type === "health.check") {
10450
+ if (data.type === "health.check") {
10167
10451
  this.scheduleNextPing();
10168
10452
  }
10169
- this.client.handleEvent(event);
10453
+ this.client.dispatchEvent(data);
10170
10454
  this.scheduleConnectionCheck();
10171
10455
  };
10172
10456
  this.onclose = (wsID, event) => {
@@ -13269,11 +13553,6 @@ var StreamChat = class _StreamChat {
13269
13553
  method: `handleEvent;${event.type}`
13270
13554
  });
13271
13555
  };
13272
- this.handleEvent = (messageEvent) => {
13273
- const jsonString = messageEvent.data;
13274
- const event = JSON.parse(jsonString);
13275
- this.dispatchEvent(event);
13276
- };
13277
13556
  /**
13278
13557
  * Updates the members, watchers and read references of the currently active channels that contain this user
13279
13558
  *
@@ -15361,7 +15640,7 @@ var StreamChat = class _StreamChat {
15361
15640
  if (this.userAgent) {
15362
15641
  return this.userAgent;
15363
15642
  }
15364
- const version = "9.42.3";
15643
+ const version = "9.43.1";
15365
15644
  const clientBundle = "node-cjs";
15366
15645
  let userAgentString = "";
15367
15646
  if (this.sdkIdentifier) {
@@ -18065,6 +18344,7 @@ var FixedSizeQueueCache = class {
18065
18344
  createActiveCommandGuardMiddleware,
18066
18345
  createAttachmentsCompositionMiddleware,
18067
18346
  createBlockedAttachmentUploadNotificationMiddleware,
18347
+ createCommandEffectsMiddleware,
18068
18348
  createCommandInjectionMiddleware,
18069
18349
  createCommandStringExtractionMiddleware,
18070
18350
  createCommandsMiddleware,
@@ -18094,13 +18374,11 @@ var FixedSizeQueueCache = class {
18094
18374
  defaultPollFieldChangeEventValidators,
18095
18375
  encodeBase64,
18096
18376
  ensureIsLocalAttachment,
18097
- escapeRegExp,
18098
18377
  extractPollData,
18099
18378
  extractPollEnrichedData,
18100
18379
  formatMessage,
18101
18380
  generateFileName,
18102
18381
  getAttachmentTypeFromMimeType,
18103
- getCompleteCommandInString,
18104
18382
  getExtensionFromMimeType,
18105
18383
  getTokenizedSuggestionDisplayName,
18106
18384
  getTriggerCharWithToken,