stream-chat 9.43.0 → 9.43.2

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.
@@ -1,5 +1,4 @@
1
1
  import type { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios';
2
- import type WebSocket from 'isomorphic-ws';
3
2
  import { Channel } from './channel';
4
3
  import { ClientState } from './client_state';
5
4
  import { StableWSConnection } from './connection';
@@ -409,7 +408,6 @@ export declare class StreamChat {
409
408
  errorFromResponse(response: AxiosResponse<APIErrorResponse>): ErrorFromResponse<APIErrorResponse>;
410
409
  handleResponse<T>(response: AxiosResponse<T>): T;
411
410
  dispatchEvent: (event: Event) => void;
412
- handleEvent: (messageEvent: WebSocket.MessageEvent) => void;
413
411
  /**
414
412
  * Updates the members, watchers and read references of the currently active channels that contain this user
415
413
  *
@@ -1033,6 +1031,8 @@ export declare class StreamChat {
1033
1031
  member?: import("./types").ChannelMemberResponse;
1034
1032
  mentioned_users?: UserResponse[];
1035
1033
  mentioned_channel?: boolean;
1034
+ mentioned_here?: boolean;
1035
+ mentioned_roles?: string[];
1036
1036
  message_text_updated_at?: string;
1037
1037
  moderation?: import("./types").ModerationResponse;
1038
1038
  moderation_details?: import("./types").ModerationDetailsResponse;
@@ -1730,6 +1730,8 @@ export declare class StreamChat {
1730
1730
  member?: import("./types").ChannelMemberResponse;
1731
1731
  mentioned_users?: UserResponse[];
1732
1732
  mentioned_channel?: boolean;
1733
+ mentioned_here?: boolean;
1734
+ mentioned_roles?: string[];
1733
1735
  message_text_updated_at?: string;
1734
1736
  moderation?: import("./types").ModerationResponse;
1735
1737
  moderation_details?: import("./types").ModerationDetailsResponse;
@@ -2037,7 +2039,7 @@ export declare class StreamChat {
2037
2039
  *
2038
2040
  * @return {Promise<PredefinedFilterResponse>} The created predefined filter
2039
2041
  */
2040
- createPredefinedFilter(options: CreatePredefinedFilterOptions): Promise<PredefinedFilterResponse>;
2042
+ createPredefinedFilter<F extends Record<string, unknown> = Record<string, unknown>>(options: CreatePredefinedFilterOptions<F>): Promise<PredefinedFilterResponse<F>>;
2041
2043
  /**
2042
2044
  * getPredefinedFilter - Gets a predefined filter by name (server-side only)
2043
2045
  *
@@ -2045,7 +2047,7 @@ export declare class StreamChat {
2045
2047
  *
2046
2048
  * @return {Promise<PredefinedFilterResponse>} The predefined filter
2047
2049
  */
2048
- getPredefinedFilter(name: string): Promise<PredefinedFilterResponse>;
2050
+ getPredefinedFilter<F extends Record<string, unknown> = Record<string, unknown>>(name: string): Promise<PredefinedFilterResponse<F>>;
2049
2051
  /**
2050
2052
  * updatePredefinedFilter - Updates a predefined filter (server-side only)
2051
2053
  *
@@ -2054,7 +2056,7 @@ export declare class StreamChat {
2054
2056
  *
2055
2057
  * @return {Promise<PredefinedFilterResponse>} The updated predefined filter
2056
2058
  */
2057
- updatePredefinedFilter(name: string, options: UpdatePredefinedFilterOptions): Promise<PredefinedFilterResponse>;
2059
+ updatePredefinedFilter<F extends Record<string, unknown> = Record<string, unknown>>(name: string, options: UpdatePredefinedFilterOptions<F>): Promise<PredefinedFilterResponse<F>>;
2058
2060
  /**
2059
2061
  * deletePredefinedFilter - Deletes a predefined filter (server-side only)
2060
2062
  *
@@ -2070,7 +2072,7 @@ export declare class StreamChat {
2070
2072
  *
2071
2073
  * @return {Promise<ListPredefinedFiltersResponse>} The list of predefined filters
2072
2074
  */
2073
- listPredefinedFilters(options?: ListPredefinedFiltersOptions): Promise<ListPredefinedFiltersResponse>;
2075
+ listPredefinedFilters<F extends Record<string, unknown> = Record<string, unknown>>(options?: ListPredefinedFiltersOptions): Promise<ListPredefinedFiltersResponse<F>>;
2074
2076
  /**
2075
2077
  * setRetentionPolicy - Creates or updates a retention policy for the app.
2076
2078
  * Server-side only.
@@ -42,7 +42,7 @@ export declare class AttachmentManager {
42
42
  get pendingUploadsCount(): number;
43
43
  get availableUploadSlots(): number;
44
44
  getUploadsByState(state: AttachmentLoadingState): LocalAttachment[];
45
- private cancelAttachmentUploads;
45
+ cancelAttachmentUploads: (attachments?: LocalAttachment[]) => void;
46
46
  private normalizeSnapshotAttachment;
47
47
  initState: ({ message }?: {
48
48
  message?: DraftMessage | LocalMessage;
@@ -2,6 +2,7 @@ export * from './activeCommandGuard';
2
2
  export * from './commands';
3
3
  export * from './commandEffects';
4
4
  export * from './commandStringExtraction';
5
+ export * from './commandUtils';
5
6
  export * from './mentions';
6
7
  export * from './validation';
7
8
  export * from './TextComposerMiddlewareExecutor';
@@ -81,6 +81,7 @@ export type AppSettingsAPIResponse = APIResponse & {
81
81
  uploads?: boolean;
82
82
  url_enrichment?: boolean;
83
83
  user_message_reminders?: boolean;
84
+ push_level?: 'all' | 'all_mentions' | 'direct_mentions' | 'mentions' | 'none' | '';
84
85
  }>;
85
86
  reminders_interval: number;
86
87
  async_moderation_config?: AsyncModerationOptions;
@@ -115,9 +116,11 @@ export type AppSettingsAPIResponse = APIResponse & {
115
116
  max_aggregated_activities_length?: number;
116
117
  moderation_bulk_submit_action_enabled?: boolean;
117
118
  moderation_dashboard_preferences?: Record<string, unknown> | null;
119
+ moderation_audio_call_moderation_enabled?: boolean;
118
120
  moderation_enabled?: boolean;
119
121
  moderation_llm_configurability_enabled?: boolean;
120
122
  moderation_multitenant_blocklist_enabled?: boolean;
123
+ moderation_video_call_moderation_enabled?: boolean;
121
124
  moderation_webhook_url?: string;
122
125
  multi_tenant_enabled?: boolean;
123
126
  name?: string;
@@ -450,8 +453,8 @@ export type LocalMessageBase = Omit<MessageResponseBase, 'created_at' | 'deleted
450
453
  updated_at: Date;
451
454
  };
452
455
  export type LocalMessage = LocalMessageBase & {
453
- error?: ErrorFromResponse<APIErrorResponse>;
454
- quoted_message?: LocalMessageBase;
456
+ error?: ErrorFromResponse<APIErrorResponse> | null;
457
+ quoted_message?: LocalMessageBase | null;
455
458
  };
456
459
  /**
457
460
  * @deprecated in favor of LocalMessage
@@ -627,6 +630,8 @@ export type MessageResponseBase = MessageBase & {
627
630
  member?: ChannelMemberResponse;
628
631
  mentioned_users?: UserResponse[];
629
632
  mentioned_channel?: boolean;
633
+ mentioned_here?: boolean;
634
+ mentioned_roles?: string[];
630
635
  message_text_updated_at?: string;
631
636
  moderation?: ModerationResponse;
632
637
  moderation_details?: ModerationDetailsResponse;
@@ -658,6 +663,12 @@ export type ReactionGroupResponse = {
658
663
  sum_scores: number;
659
664
  first_reaction_at?: string;
660
665
  last_reaction_at?: string;
666
+ latest_reactions_by?: ReactionGroupUserResponse[];
667
+ };
668
+ export type ReactionGroupUserResponse = {
669
+ created_at: string;
670
+ user_id: string;
671
+ user?: UserResponse;
661
672
  };
662
673
  export type ModerationDetailsResponse = {
663
674
  action: 'MESSAGE_RESPONSE_ACTION_BOUNCE' | (string & {});
@@ -889,13 +900,29 @@ export type ChannelOptions = {
889
900
  user_id?: string;
890
901
  watch?: boolean;
891
902
  /**
892
- * Name of a predefined filter to use instead of filter_conditions.
893
- * When provided, filter_conditions and sort parameters are ignored.
903
+ * Name of a predefined filter to use instead of sending raw
904
+ * `filter_conditions`.
905
+ *
906
+ * The backend resolves the filter template by name and interpolates it using
907
+ * `filter_values`.
908
+ *
909
+ * A regular `sort` can still be passed to `queryChannels()`, but backend
910
+ * precedence rules apply:
911
+ *
912
+ * - if the predefined filter has its own stored sort template, that stored
913
+ * sort takes precedence and the request `sort` is ignored
914
+ * - if the predefined filter does not define a sort template, the request
915
+ * `sort` can still be used
894
916
  */
895
917
  predefined_filter?: string;
896
918
  /**
897
- * Values to interpolate into the predefined filter template placeholders.
898
- * Only used when predefined_filter is provided.
919
+ * Values used to interpolate placeholders inside the predefined filter's
920
+ * `filter` template.
921
+ *
922
+ * Example: a template value like `{{user_id}}` can be resolved with
923
+ * `{ user_id: 'alice' }`.
924
+ *
925
+ * Only used when `predefined_filter` is provided.
899
926
  */
900
927
  filter_values?: Record<string, unknown>;
901
928
  /**
@@ -1964,6 +1991,7 @@ export type ChannelConfigFields = {
1964
1991
  uploads?: boolean;
1965
1992
  url_enrichment?: boolean;
1966
1993
  user_message_reminders?: boolean;
1994
+ push_level?: 'all' | 'all_mentions' | 'direct_mentions' | 'mentions' | 'none' | '';
1967
1995
  };
1968
1996
  export type ChannelConfigWithInfo = ChannelConfigFields & CreatedAtUpdatedAt & {
1969
1997
  commands?: CommandResponse[];
@@ -2184,9 +2212,12 @@ export type Mute = {
2184
2212
  updated_at: string;
2185
2213
  user: UserResponse;
2186
2214
  };
2215
+ export type PartialUpdateChannelFields = Partial<ChannelResponse> & {
2216
+ config_overrides?: Partial<ChannelConfigFields>;
2217
+ };
2187
2218
  export type PartialUpdateChannel = {
2188
- set?: Partial<ChannelResponse>;
2189
- unset?: Array<keyof ChannelResponse>;
2219
+ set?: PartialUpdateChannelFields;
2220
+ unset?: Array<keyof PartialUpdateChannelFields>;
2190
2221
  };
2191
2222
  export type PartialUpdateMember = {
2192
2223
  set?: ChannelMemberUpdates;
@@ -3495,33 +3526,114 @@ export type UpdateChannelsBatchResponse = {
3495
3526
  */
3496
3527
  export type PredefinedFilterOperation = 'QueryChannels';
3497
3528
  export type PredefinedFilterSortParam = {
3529
+ /**
3530
+ * Field name to sort by.
3531
+ *
3532
+ * This may be a literal field name such as `created_at`, or a placeholder
3533
+ * template such as `{{sort_field}}` that will be interpolated server-side.
3534
+ */
3498
3535
  field: string;
3536
+ /**
3537
+ * Sort direction. `1` means ascending and `-1` means descending.
3538
+ *
3539
+ * The backend defaults this to `1` when omitted.
3540
+ */
3499
3541
  direction?: AscDesc;
3542
+ /**
3543
+ * Optional server-side hint describing how the sort field value should be
3544
+ * interpreted.
3545
+ *
3546
+ * This is mainly relevant for predefined-filter sort templates and is not
3547
+ * part of the regular `queryChannels()` sort shape. Omitting it uses the
3548
+ * backend default string behavior. Known backend values include:
3549
+ *
3550
+ * - `number`: cast custom-field values to numeric before sorting
3551
+ * - `boolean`: cast custom-field values to boolean before sorting
3552
+ *
3553
+ * Other values are backend-defined. In most cases this should be omitted
3554
+ * unless you are sorting by a custom field whose stored JSON value is not
3555
+ * string-like.
3556
+ */
3500
3557
  type?: string;
3501
3558
  };
3502
- export type PredefinedFilter = {
3559
+ /**
3560
+ * Stored predefined filter definition as returned by the server.
3561
+ *
3562
+ * `F` represents the raw filter template shape. It defaults to a generic record
3563
+ * because predefined filters are server-managed templates and may include
3564
+ * placeholders or app-specific structures.
3565
+ */
3566
+ export type PredefinedFilter<F extends Record<string, unknown> = Record<string, unknown>> = {
3567
+ /**
3568
+ * Unique predefined filter name within the app.
3569
+ */
3503
3570
  name: string;
3571
+ /**
3572
+ * Operation this predefined filter is valid for.
3573
+ */
3504
3574
  operation: PredefinedFilterOperation;
3505
- filter: Record<string, unknown>;
3575
+ /**
3576
+ * Filter template stored on the server.
3577
+ *
3578
+ * This is not necessarily the fully interpolated runtime filter; placeholder
3579
+ * values such as `{{user_id}}` may still be present.
3580
+ */
3581
+ filter: F;
3582
+ /**
3583
+ * Server creation timestamp in ISO-8601 format.
3584
+ */
3506
3585
  created_at: string;
3586
+ /**
3587
+ * Server update timestamp in ISO-8601 format.
3588
+ */
3507
3589
  updated_at: string;
3590
+ /**
3591
+ * Optional human-readable description.
3592
+ */
3508
3593
  description?: string;
3594
+ /**
3595
+ * Optional sort template stored with the predefined filter.
3596
+ */
3509
3597
  sort?: PredefinedFilterSortParam[];
3598
+ /**
3599
+ * Query identifier generated by the backend for the filter/sort pattern.
3600
+ *
3601
+ * The exact value is backend-generated and primarily useful for correlating
3602
+ * predefined filters with query analysis / query performance data.
3603
+ */
3510
3604
  query_id?: number;
3511
3605
  };
3512
- export type CreatePredefinedFilterOptions = {
3606
+ export type CreatePredefinedFilterOptions<F extends Record<string, unknown> = Record<string, unknown>> = {
3607
+ /**
3608
+ * Unique predefined filter name.
3609
+ */
3513
3610
  name: string;
3611
+ /**
3612
+ * Operation this predefined filter will be used with.
3613
+ */
3514
3614
  operation: PredefinedFilterOperation;
3515
- filter: Record<string, unknown>;
3615
+ /**
3616
+ * Filter template to store on the server.
3617
+ */
3618
+ filter: F;
3619
+ /**
3620
+ * Optional human-readable description.
3621
+ */
3516
3622
  description?: string;
3623
+ /**
3624
+ * Optional sort template stored with the predefined filter.
3625
+ */
3517
3626
  sort?: PredefinedFilterSortParam[];
3518
3627
  };
3519
- export type UpdatePredefinedFilterOptions = Omit<CreatePredefinedFilterOptions, 'name'>;
3520
- export type PredefinedFilterResponse = APIResponse & {
3521
- predefined_filter: PredefinedFilter;
3628
+ export type UpdatePredefinedFilterOptions<F extends Record<string, unknown> = Record<string, unknown>> = Omit<CreatePredefinedFilterOptions<F>, 'name'>;
3629
+ export type PredefinedFilterResponse<F extends Record<string, unknown> = Record<string, unknown>> = APIResponse & {
3630
+ predefined_filter: PredefinedFilter<F>;
3522
3631
  };
3523
- export type ListPredefinedFiltersResponse = APIResponse & {
3524
- predefined_filters: PredefinedFilter[];
3632
+ /**
3633
+ * Paginated response returned when listing predefined filters.
3634
+ */
3635
+ export type ListPredefinedFiltersResponse<F extends Record<string, unknown> = Record<string, unknown>> = APIResponse & {
3636
+ predefined_filters: PredefinedFilter<F>[];
3525
3637
  next?: string;
3526
3638
  prev?: string;
3527
3639
  };
@@ -3529,9 +3641,18 @@ export type ListPredefinedFiltersResponse = APIResponse & {
3529
3641
  * Contains the interpolated filter and sort from a predefined filter.
3530
3642
  * This is returned in the QueryChannels response when using a predefined filter.
3531
3643
  */
3532
- export type ParsedPredefinedFilterResponse = {
3644
+ export type ParsedPredefinedFilterResponse<F extends Record<string, unknown> = Record<string, unknown>> = {
3645
+ /**
3646
+ * Name of the predefined filter that was resolved.
3647
+ */
3533
3648
  name: string;
3534
- filter: Record<string, unknown>;
3649
+ /**
3650
+ * Fully interpolated filter that the backend executed.
3651
+ */
3652
+ filter: F;
3653
+ /**
3654
+ * Fully interpolated sort parameters resolved from the predefined filter.
3655
+ */
3535
3656
  sort?: PredefinedFilterSortParam[];
3536
3657
  };
3537
3658
  export type PredefinedFilterSort = SortParam[];
@@ -122,6 +122,8 @@ export declare const toDeletedMessage: ({ message, deletedAt, hardDelete, }: {
122
122
  deleted_reply_count?: number | undefined;
123
123
  member?: import("./types").ChannelMemberResponse | undefined;
124
124
  mentioned_channel?: boolean | undefined;
125
+ mentioned_here?: boolean | undefined;
126
+ mentioned_roles?: string[] | undefined;
125
127
  message_text_updated_at?: string | undefined;
126
128
  moderation?: import("./types").ModerationResponse | undefined;
127
129
  moderation_details?: import("./types").ModerationDetailsResponse | undefined;
@@ -142,8 +144,8 @@ export declare const toDeletedMessage: ({ message, deletedAt, hardDelete, }: {
142
144
  pinned_at: Date | null;
143
145
  status: string;
144
146
  updated_at: Date;
145
- error?: import("./types").ErrorFromResponse<import("./types").APIErrorResponse>;
146
- quoted_message?: LocalMessageBase;
147
+ error?: import("./types").ErrorFromResponse<import("./types").APIErrorResponse> | null;
148
+ quoted_message?: LocalMessageBase | null;
147
149
  };
148
150
  export declare const deleteUserMessages: ({ messages, user, hardDelete, deletedAt, }: {
149
151
  messages: Array<LocalMessage>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "stream-chat",
3
- "version": "9.43.0",
3
+ "version": "9.43.2",
4
4
  "description": "JS SDK for the Stream Chat API",
5
5
  "homepage": "https://getstream.io/chat/",
6
6
  "author": {
package/src/client.ts CHANGED
@@ -4,7 +4,6 @@
4
4
  import type { AxiosError, AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios';
5
5
  import axios from 'axios';
6
6
  import https from 'https';
7
- import type WebSocket from 'isomorphic-ws';
8
7
 
9
8
  import { Channel } from './channel';
10
9
  import { ClientState } from './client_state';
@@ -1381,13 +1380,6 @@ export class StreamChat {
1381
1380
  });
1382
1381
  };
1383
1382
 
1384
- handleEvent = (messageEvent: WebSocket.MessageEvent) => {
1385
- // dispatch the event to the channel listeners
1386
- const jsonString = messageEvent.data as string;
1387
- const event = JSON.parse(jsonString) as Event;
1388
- this.dispatchEvent(event);
1389
- };
1390
-
1391
1383
  /**
1392
1384
  * Updates the members, watchers and read references of the currently active channels that contain this user
1393
1385
  *
@@ -1915,6 +1907,7 @@ export class StreamChat {
1915
1907
  }
1916
1908
 
1917
1909
  const { predefined_filter, filter_values, sort_values, ...restOptions } = options;
1910
+ const normalizedSort = normalizeQuerySort(sort);
1918
1911
 
1919
1912
  // Build payload based on whether we're using a predefined filter or traditional filters
1920
1913
  const payload = predefined_filter
@@ -1922,12 +1915,13 @@ export class StreamChat {
1922
1915
  predefined_filter,
1923
1916
  filter_values,
1924
1917
  sort_values,
1918
+ sort: normalizedSort,
1925
1919
  ...defaultOptions,
1926
1920
  ...restOptions,
1927
1921
  }
1928
1922
  : {
1929
1923
  filter_conditions: filterConditions,
1930
- sort: normalizeQuerySort(sort),
1924
+ sort: normalizedSort,
1931
1925
  ...defaultOptions,
1932
1926
  ...restOptions,
1933
1927
  };
@@ -1937,6 +1931,9 @@ export class StreamChat {
1937
1931
  payload,
1938
1932
  );
1939
1933
 
1934
+ // FIXME: In the next major release, return the full QueryChannelsAPIResponse
1935
+ // instead of only `data.channels` so top-level metadata such as
1936
+ // `predefined_filter` is not lost.
1940
1937
  return data.channels;
1941
1938
  }
1942
1939
 
@@ -4989,9 +4986,11 @@ export class StreamChat {
4989
4986
  *
4990
4987
  * @return {Promise<PredefinedFilterResponse>} The created predefined filter
4991
4988
  */
4992
- async createPredefinedFilter(options: CreatePredefinedFilterOptions) {
4989
+ async createPredefinedFilter<
4990
+ F extends Record<string, unknown> = Record<string, unknown>,
4991
+ >(options: CreatePredefinedFilterOptions<F>) {
4993
4992
  this.validateServerSideAuth();
4994
- return await this.post<PredefinedFilterResponse>(
4993
+ return await this.post<PredefinedFilterResponse<F>>(
4995
4994
  `${this.baseURL}/predefined_filters`,
4996
4995
  options,
4997
4996
  );
@@ -5004,9 +5003,11 @@ export class StreamChat {
5004
5003
  *
5005
5004
  * @return {Promise<PredefinedFilterResponse>} The predefined filter
5006
5005
  */
5007
- async getPredefinedFilter(name: string) {
5006
+ async getPredefinedFilter<F extends Record<string, unknown> = Record<string, unknown>>(
5007
+ name: string,
5008
+ ) {
5008
5009
  this.validateServerSideAuth();
5009
- return await this.get<PredefinedFilterResponse>(
5010
+ return await this.get<PredefinedFilterResponse<F>>(
5010
5011
  `${this.baseURL}/predefined_filters/${encodeURIComponent(name)}`,
5011
5012
  );
5012
5013
  }
@@ -5019,9 +5020,11 @@ export class StreamChat {
5019
5020
  *
5020
5021
  * @return {Promise<PredefinedFilterResponse>} The updated predefined filter
5021
5022
  */
5022
- async updatePredefinedFilter(name: string, options: UpdatePredefinedFilterOptions) {
5023
+ async updatePredefinedFilter<
5024
+ F extends Record<string, unknown> = Record<string, unknown>,
5025
+ >(name: string, options: UpdatePredefinedFilterOptions<F>) {
5023
5026
  this.validateServerSideAuth();
5024
- return await this.put<PredefinedFilterResponse>(
5027
+ return await this.put<PredefinedFilterResponse<F>>(
5025
5028
  `${this.baseURL}/predefined_filters/${encodeURIComponent(name)}`,
5026
5029
  options,
5027
5030
  );
@@ -5048,10 +5051,12 @@ export class StreamChat {
5048
5051
  *
5049
5052
  * @return {Promise<ListPredefinedFiltersResponse>} The list of predefined filters
5050
5053
  */
5051
- async listPredefinedFilters(options: ListPredefinedFiltersOptions = {}) {
5054
+ async listPredefinedFilters<
5055
+ F extends Record<string, unknown> = Record<string, unknown>,
5056
+ >(options: ListPredefinedFiltersOptions = {}) {
5052
5057
  this.validateServerSideAuth();
5053
5058
  const { sort, ...paginationOptions } = options;
5054
- return await this.get<ListPredefinedFiltersResponse>(
5059
+ return await this.get<ListPredefinedFiltersResponse<F>>(
5055
5060
  `${this.baseURL}/predefined_filters`,
5056
5061
  {
5057
5062
  ...paginationOptions,
package/src/connection.ts CHANGED
@@ -477,12 +477,13 @@ export class StableWSConnection {
477
477
  if (this.wsID !== wsID) return;
478
478
 
479
479
  this._log('onmessage() - onmessage callback', { event, wsID });
480
- const data = typeof event.data === 'string' ? JSON.parse(event.data) : null;
480
+ if (typeof event.data !== 'string') return;
481
+ const data = JSON.parse(event.data);
481
482
 
482
483
  // we wait till the first message before we consider the connection open..
483
484
  // the reason for this is that auth errors and similar errors trigger a ws.onopen and immediately
484
485
  // after that a ws.onclose..
485
- if (!this.isResolved && data) {
486
+ if (!this.isResolved) {
486
487
  this.isResolved = true;
487
488
  if (data.error) {
488
489
  this.rejectPromise?.(this._errorFromWSEvent(data, false));
@@ -496,11 +497,11 @@ export class StableWSConnection {
496
497
  // trigger the event..
497
498
  this.lastEvent = new Date();
498
499
 
499
- if (data && data.type === 'health.check') {
500
+ if (data.type === 'health.check') {
500
501
  this.scheduleNextPing();
501
502
  }
502
503
 
503
- this.client.handleEvent(event);
504
+ this.client.dispatchEvent(data);
504
505
  this.scheduleConnectionCheck();
505
506
  };
506
507
 
@@ -34,7 +34,9 @@ const applyCommandActivationEffect: MessageComposerEffectHandler<
34
34
  selection: { start: 0, end: 0 },
35
35
  text: '',
36
36
  });
37
+ const attachmentsToCancel = composer.attachmentManager.attachments;
37
38
  composer.attachmentManager.initState();
39
+ composer.attachmentManager.cancelAttachmentUploads(attachmentsToCancel);
38
40
  composer.linkPreviewsManager.initState();
39
41
  composer.locationComposer.initState();
40
42
  composer.pollComposer.initState();
@@ -210,7 +210,7 @@ export class AttachmentManager {
210
210
  );
211
211
  }
212
212
 
213
- private cancelAttachmentUploads = (attachments: LocalAttachment[]) => {
213
+ cancelAttachmentUploads = (attachments: LocalAttachment[] = this.attachments) => {
214
214
  for (const { localMetadata } of attachments) {
215
215
  this.client.uploadManager.deleteUploadRecord(localMetadata.id);
216
216
  }
@@ -232,7 +232,6 @@ export class AttachmentManager {
232
232
  };
233
233
 
234
234
  initState = ({ message }: { message?: DraftMessage | LocalMessage } = {}) => {
235
- this.cancelAttachmentUploads(this.attachments);
236
235
  this.state.next(initState({ message }));
237
236
  };
238
237
 
@@ -2,6 +2,7 @@ export * from './activeCommandGuard';
2
2
  export * from './commands';
3
3
  export * from './commandEffects';
4
4
  export * from './commandStringExtraction';
5
+ export * from './commandUtils';
5
6
  export * from './mentions';
6
7
  export * from './validation';
7
8
  export * from './TextComposerMiddlewareExecutor';