stream-chat 8.56.0 → 8.57.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/dist/cjs/index.browser.cjs +11101 -0
  2. package/dist/cjs/index.browser.cjs.map +7 -0
  3. package/dist/cjs/index.node.cjs +22510 -0
  4. package/dist/cjs/index.node.cjs.map +7 -0
  5. package/dist/esm/index.js +11097 -0
  6. package/dist/esm/index.js.map +7 -0
  7. package/dist/types/base64.d.ts +0 -1
  8. package/dist/types/campaign.d.ts +18 -3
  9. package/dist/types/channel.d.ts +3 -5
  10. package/dist/types/channel_manager.d.ts +11 -12
  11. package/dist/types/channel_state.d.ts +6 -7
  12. package/dist/types/client.d.ts +110 -141
  13. package/dist/types/client_state.d.ts +0 -1
  14. package/dist/types/connection.d.ts +3 -6
  15. package/dist/types/connection_fallback.d.ts +0 -1
  16. package/dist/types/constants.d.ts +0 -1
  17. package/dist/types/errors.d.ts +1 -2
  18. package/dist/types/events.d.ts +0 -1
  19. package/dist/types/index.d.ts +0 -1
  20. package/dist/types/insights.d.ts +3 -5
  21. package/dist/types/moderation.d.ts +0 -1
  22. package/dist/types/permissions.d.ts +2 -3
  23. package/dist/types/poll.d.ts +9 -10
  24. package/dist/types/poll_manager.d.ts +1 -2
  25. package/dist/types/search_controller.d.ts +17 -18
  26. package/dist/types/segment.d.ts +3 -4
  27. package/dist/types/signing.d.ts +3 -5
  28. package/dist/types/store.d.ts +5 -6
  29. package/dist/types/thread.d.ts +9 -10
  30. package/dist/types/thread_manager.d.ts +3 -4
  31. package/dist/types/token_manager.d.ts +4 -5
  32. package/dist/types/types.d.ts +400 -387
  33. package/dist/types/utils.d.ts +14 -15
  34. package/package.json +53 -58
  35. package/src/campaign.ts +3 -3
  36. package/src/channel_manager.ts +21 -10
  37. package/src/client.ts +69 -19
  38. package/src/connection.ts +14 -7
  39. package/src/connection_fallback.ts +9 -7
  40. package/src/signing.ts +10 -5
  41. package/src/token_manager.ts +5 -4
  42. package/src/types.ts +9 -0
  43. package/src/utils.ts +21 -0
  44. package/dist/browser.es.js +0 -19194
  45. package/dist/browser.es.js.map +0 -1
  46. package/dist/browser.full-bundle.min.js +0 -2
  47. package/dist/browser.full-bundle.min.js.map +0 -1
  48. package/dist/browser.js +0 -19275
  49. package/dist/browser.js.map +0 -1
  50. package/dist/index.es.js +0 -19197
  51. package/dist/index.es.js.map +0 -1
  52. package/dist/index.js +0 -19281
  53. package/dist/index.js.map +0 -1
  54. package/dist/types/base64.d.ts.map +0 -1
  55. package/dist/types/campaign.d.ts.map +0 -1
  56. package/dist/types/channel.d.ts.map +0 -1
  57. package/dist/types/channel_manager.d.ts.map +0 -1
  58. package/dist/types/channel_state.d.ts.map +0 -1
  59. package/dist/types/client.d.ts.map +0 -1
  60. package/dist/types/client_state.d.ts.map +0 -1
  61. package/dist/types/connection.d.ts.map +0 -1
  62. package/dist/types/connection_fallback.d.ts.map +0 -1
  63. package/dist/types/constants.d.ts.map +0 -1
  64. package/dist/types/errors.d.ts.map +0 -1
  65. package/dist/types/events.d.ts.map +0 -1
  66. package/dist/types/index.d.ts.map +0 -1
  67. package/dist/types/insights.d.ts.map +0 -1
  68. package/dist/types/moderation.d.ts.map +0 -1
  69. package/dist/types/permissions.d.ts.map +0 -1
  70. package/dist/types/poll.d.ts.map +0 -1
  71. package/dist/types/poll_manager.d.ts.map +0 -1
  72. package/dist/types/search_controller.d.ts.map +0 -1
  73. package/dist/types/segment.d.ts.map +0 -1
  74. package/dist/types/signing.d.ts.map +0 -1
  75. package/dist/types/store.d.ts.map +0 -1
  76. package/dist/types/thread.d.ts.map +0 -1
  77. package/dist/types/thread_manager.d.ts.map +0 -1
  78. package/dist/types/token_manager.d.ts.map +0 -1
  79. package/dist/types/types.d.ts.map +0 -1
  80. package/dist/types/utils.d.ts.map +0 -1
@@ -1,4 +1,3 @@
1
- /// <reference types="node" />
2
1
  import FormData from 'form-data';
3
2
  import { AscDesc, ExtendableGenerics, DefaultGenerics, Logger, OwnUserResponse, UserResponse, MessageResponse, FormatMessageResponse, MessageSet, MessagePaginationOptions, ChannelQueryOptions, ChannelSort, ChannelFilters, ChannelSortBase, PromoteChannelParams } from './types';
4
3
  import { StreamChat } from './client';
@@ -66,7 +65,7 @@ export declare const findIndexInSortedArray: <T, L>({ needle, sortedArray, selec
66
65
  * selectKey: (message) => message.id
67
66
  * ```
68
67
  */
69
- selectKey?: ((arrayElement: T) => string) | undefined;
68
+ selectKey?: (arrayElement: T) => string;
70
69
  /**
71
70
  * In an array of objects (like messages), pick a specific
72
71
  * property to compare the needle value to.
@@ -76,7 +75,7 @@ export declare const findIndexInSortedArray: <T, L>({ needle, sortedArray, selec
76
75
  * selectValueToCompare: (message) => message.created_at.getTime()
77
76
  * ```
78
77
  */
79
- selectValueToCompare?: ((arrayElement: T) => T | L) | undefined;
78
+ selectValueToCompare?: (arrayElement: T) => L | T;
80
79
  /**
81
80
  * @default ascending
82
81
  * @description
@@ -85,7 +84,7 @@ export declare const findIndexInSortedArray: <T, L>({ needle, sortedArray, selec
85
84
  * descending - [...5,4,3,2,1]
86
85
  * ```
87
86
  */
88
- sortDirection?: "ascending" | "descending" | undefined;
87
+ sortDirection?: "ascending" | "descending";
89
88
  }) => number;
90
89
  export declare function addToMessageList<T extends FormatMessageResponse>(messages: readonly T[], newMessage: T, timestampChanged?: boolean, sortBy?: 'pinned_at' | 'created_at', addIfDoesNotExist?: boolean): T[];
91
90
  export interface DebouncedFunc<T extends (...args: any[]) => any> {
@@ -113,14 +112,15 @@ export interface DebouncedFunc<T extends (...args: any[]) => any> {
113
112
  flush(): ReturnType<T> | undefined;
114
113
  }
115
114
  export declare const debounce: <T extends (...args: any[]) => any>(fn: T, timeout?: number, { leading, trailing }?: {
116
- leading?: boolean | undefined;
117
- trailing?: boolean | undefined;
115
+ leading?: boolean;
116
+ trailing?: boolean;
118
117
  }) => DebouncedFunc<T>;
119
118
  export declare const throttle: <T extends (...args: unknown[]) => unknown>(fn: T, timeout?: number, { leading, trailing }?: {
120
- leading?: boolean | undefined;
121
- trailing?: boolean | undefined;
119
+ leading?: boolean;
120
+ trailing?: boolean;
122
121
  }) => (...args: Parameters<T>) => void;
123
- declare type MessagePaginationUpdatedParams<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {
122
+ export declare const uniqBy: <T>(array: T[] | unknown, iteratee: ((item: T) => unknown) | keyof T) => T[];
123
+ type MessagePaginationUpdatedParams<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {
124
124
  parentSet: MessageSet;
125
125
  requestedPageSize: number;
126
126
  returnedPage: MessageResponse<StreamChatGenerics>[];
@@ -134,7 +134,7 @@ export declare const messageSetPagination: <StreamChatGenerics extends Extendabl
134
134
  hasNext: boolean;
135
135
  hasPrev: boolean;
136
136
  };
137
- declare type GetChannelParams<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {
137
+ type GetChannelParams<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {
138
138
  client: StreamChat<StreamChatGenerics>;
139
139
  channel?: Channel<StreamChatGenerics>;
140
140
  id?: string;
@@ -187,9 +187,9 @@ export declare const shouldConsiderArchivedChannels: <StreamChatGenerics extends
187
187
  */
188
188
  export declare const extractSortValue: <StreamChatGenerics extends ExtendableGenerics = DefaultGenerics>({ atIndex, sort, targetKey, }: {
189
189
  atIndex: number;
190
- targetKey: "unread_count" | "created_at" | "pinned_at" | "updated_at" | "last_message_at" | "member_count" | keyof StreamChatGenerics["channelType"] | "has_unread" | "last_updated";
191
- sort?: ChannelSort<StreamChatGenerics> | undefined;
192
- }) => NonNullable<NonNullable<ChannelSortBase<StreamChatGenerics>>["unread_count" | "created_at" | "pinned_at" | "updated_at" | "last_message_at" | "member_count" | keyof StreamChatGenerics["channelType"] | "has_unread" | "last_updated"]> | null;
190
+ targetKey: keyof ChannelSortBase<StreamChatGenerics>;
191
+ sort?: ChannelSort<StreamChatGenerics>;
192
+ }) => NonNullable<ChannelSortBase<StreamChatGenerics>["unread_count" | "created_at" | "pinned_at" | "updated_at" | "last_message_at" | "member_count" | keyof StreamChatGenerics["channelType"] | "has_unread" | "last_updated"]> | null;
193
193
  /**
194
194
  * Returns true only if `{ pinned_at: -1 }` or `{ pinned_at: 1 }` option is first within the `sort` array.
195
195
  */
@@ -201,7 +201,7 @@ export declare const shouldConsiderPinnedChannels: <StreamChatGenerics extends E
201
201
  */
202
202
  export declare const findPinnedAtSortOrder: <StreamChatGenerics extends ExtendableGenerics = DefaultGenerics>({ sort, }: {
203
203
  sort: ChannelSort<StreamChatGenerics>;
204
- }) => NonNullable<NonNullable<ChannelSortBase<StreamChatGenerics>>["unread_count" | "created_at" | "pinned_at" | "updated_at" | "last_message_at" | "member_count" | "has_unread" | "last_updated" | keyof StreamChatGenerics["channelType"]]> | null;
204
+ }) => NonNullable<ChannelSortBase<StreamChatGenerics>["unread_count" | "created_at" | "pinned_at" | "updated_at" | "last_message_at" | "member_count" | "has_unread" | "last_updated" | keyof StreamChatGenerics["channelType"]]> | null;
205
205
  /**
206
206
  * Finds the index of the last consecutively pinned channel, starting from the start of the
207
207
  * array. Will not consider any pinned channels after the contiguous subsequence at the
@@ -222,4 +222,3 @@ export declare const findLastPinnedChannelIndex: <StreamChatGenerics extends Ext
222
222
  */
223
223
  export declare const promoteChannel: <StreamChatGenerics extends ExtendableGenerics = DefaultGenerics>({ channels, channelToMove, channelToMoveIndexWithinChannels, sort, }: PromoteChannelParams<StreamChatGenerics>) => Channel<StreamChatGenerics>[];
224
224
  export {};
225
- //# sourceMappingURL=utils.d.ts.map
package/package.json CHANGED
@@ -1,23 +1,39 @@
1
1
  {
2
2
  "name": "stream-chat",
3
- "version": "8.56.0",
3
+ "version": "8.57.0",
4
4
  "description": "JS SDK for the Stream Chat API",
5
- "author": "GetStream",
6
5
  "homepage": "https://getstream.io/chat/",
7
- "repository": "https://github.com/GetStream/stream-chat-js.git",
8
- "main": "./dist/index.js",
9
- "module": "./dist/index.es.js",
10
- "jsnext:main": "./dist/index.es.js",
6
+ "author": {
7
+ "name": "GetStream.io, Inc.",
8
+ "url": "https://getstream.io/team/"
9
+ },
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "https://github.com/GetStream/stream-chat-js.git"
13
+ },
11
14
  "types": "./dist/types/index.d.ts",
12
- "browser": {
13
- "./dist/index.es.js": "./dist/browser.es.js",
14
- "./dist/index.js": "./dist/browser.js"
15
+ "main": "./dist/esm/index.js",
16
+ "exports": {
17
+ ".": {
18
+ "types": "./dist/types/index.d.ts",
19
+ "browser": {
20
+ "import": "./dist/esm/index.js",
21
+ "require": "./dist/cjs/index.browser.cjs"
22
+ },
23
+ "react-native": {
24
+ "import": "./dist/esm/index.js",
25
+ "require": "./dist/cjs/index.browser.cjs"
26
+ },
27
+ "node": "./dist/cjs/index.node.cjs",
28
+ "default": "./dist/esm/index.js"
29
+ }
15
30
  },
16
- "react-native": {
17
- "./dist/index.es.js": "./dist/browser.es.js",
18
- "./dist/index.js": "./dist/browser.js"
31
+ "browser": {
32
+ "https": false,
33
+ "crypto": false,
34
+ "jsonwebtoken": false,
35
+ "ws": false
19
36
  },
20
- "jsdelivr": "./dist/browser.full-bundle.min.js",
21
37
  "license": "SEE LICENSE IN LICENSE",
22
38
  "keywords": [
23
39
  "chat",
@@ -30,41 +46,24 @@
30
46
  ],
31
47
  "files": [
32
48
  "/dist",
33
- "/src",
34
- "readme.md",
35
- "license"
49
+ "/src"
36
50
  ],
37
51
  "dependencies": {
38
- "@babel/runtime": "^7.16.3",
39
- "@types/jsonwebtoken": "~9.0.0",
40
- "@types/ws": "^7.4.0",
52
+ "@types/jsonwebtoken": "^9.0.8",
53
+ "@types/ws": "^8.5.14",
41
54
  "axios": "^1.6.0",
42
55
  "base64-js": "^1.5.1",
43
56
  "form-data": "^4.0.0",
44
- "isomorphic-ws": "^4.0.1",
45
- "jsonwebtoken": "~9.0.0",
46
- "ws": "^7.5.10"
57
+ "isomorphic-ws": "^5.0.0",
58
+ "jsonwebtoken": "^9.0.2",
59
+ "ws": "^8.18.1"
47
60
  },
48
61
  "devDependencies": {
49
- "@babel/cli": "^7.16.0",
50
- "@babel/core": "^7.16.0",
51
- "@babel/eslint-parser": "^7.17.0",
52
- "@babel/node": "^7.16.0",
53
- "@babel/plugin-proposal-class-properties": "^7.16.0",
54
- "@babel/plugin-proposal-object-rest-spread": "^7.16.0",
55
- "@babel/plugin-transform-async-to-generator": "^7.16.0",
56
- "@babel/plugin-transform-object-assign": "^7.16.0",
57
- "@babel/plugin-transform-runtime": "^7.16.4",
58
- "@babel/preset-env": "^7.16.4",
59
- "@babel/preset-typescript": "^7.16.0",
60
- "@babel/register": "^7.16.0",
61
62
  "@commitlint/cli": "^16.0.2",
62
63
  "@commitlint/config-conventional": "^16.0.0",
63
- "@rollup/plugin-babel": "^5.3.0",
64
- "@rollup/plugin-commonjs": "^17.1.0",
65
- "@rollup/plugin-node-resolve": "^11.2.0",
66
- "@rollup/plugin-replace": "^3.0.1",
67
- "@types/babel__core": "^7.1.16",
64
+ "@semantic-release/changelog": "^6.0.3",
65
+ "@semantic-release/exec": "^7.0.3",
66
+ "@semantic-release/git": "^10.0.1",
68
67
  "@types/base64-js": "^1.3.0",
69
68
  "@types/chai": "^4.2.15",
70
69
  "@types/chai-arrays": "^2.0.0",
@@ -74,10 +73,8 @@
74
73
  "@types/mocha": "^9.0.0",
75
74
  "@types/node": "^16.11.11",
76
75
  "@types/prettier": "^2.2.2",
77
- "@types/rollup-plugin-json": "^3.0.2",
78
- "@types/rollup-plugin-peer-deps-external": "^2.2.0",
79
- "@types/rollup-plugin-url": "^2.2.0",
80
76
  "@types/sinon": "^10.0.6",
77
+ "@types/uuid": "^10.0.0",
81
78
  "@typescript-eslint/eslint-plugin": "^4.17.0",
82
79
  "@typescript-eslint/parser": "^4.17.0",
83
80
  "chai": "^4.3.4",
@@ -85,50 +82,48 @@
85
82
  "chai-as-promised": "^7.1.1",
86
83
  "chai-like": "^1.1.1",
87
84
  "chai-sorted": "^0.2.0",
85
+ "concurrently": "^9.1.2",
86
+ "conventional-changelog-conventionalcommits": "^8.0.0",
88
87
  "dotenv": "^8.2.0",
88
+ "esbuild": "^0.25.0",
89
89
  "eslint": "7.21.0",
90
90
  "eslint-config-prettier": "^8.1.0",
91
- "eslint-plugin-babel": "^5.3.1",
92
91
  "eslint-plugin-markdown": "^2.0.0",
93
92
  "eslint-plugin-prettier": "^3.3.1",
94
93
  "eslint-plugin-sonarjs": "^0.6.0",
95
94
  "eslint-plugin-typescript-sort-keys": "1.5.0",
96
95
  "husky": "^4.3.8",
97
96
  "lint-staged": "^15.2.2",
98
- "mocha": "^10.7.0",
97
+ "mocha": "^11.1.0",
99
98
  "nyc": "^15.1.0",
100
99
  "prettier": "^2.2.1",
101
- "rollup": "^2.41.0",
102
- "rollup-plugin-peer-deps-external": "^2.2.4",
103
- "rollup-plugin-terser": "^7.0.2",
100
+ "semantic-release": "^24.2.3",
104
101
  "sinon": "^12.0.1",
105
102
  "standard-version": "^9.3.2",
106
- "typescript": "4.2.3",
103
+ "ts-node": "^10.9.2",
104
+ "tslib": "^2.8.1",
105
+ "typescript": "^5.7.3",
107
106
  "uuid": "^8.3.2"
108
107
  },
109
108
  "scripts": {
110
- "start": "yarn run compile -w",
111
- "compile": "rollup -c",
112
- "changelog": "standard-version --release-as $VERSION --skip.tag --skip.commit --tag-prefix=v",
109
+ "start": "tsc --watch",
113
110
  "commitlinter": "commitlint",
114
- "build": "rm -rf dist && yarn run types && yarn run compile",
115
- "types": "tsc --emitDeclarationOnly true",
111
+ "build": "rm -rf dist && yarn bundle",
112
+ "bundle": "concurrently 'tsc --declaration --emitDeclarationOnly --outDir ./dist/types' ./scripts/bundle.mjs",
113
+ "types": "tsc --noEmit",
116
114
  "prettier": "prettier --check '**/*.{js,ts,md,css,scss,json}' .eslintrc.json .prettierrc .babelrc",
117
115
  "prettier-fix": "npx prettier --write '**/*.{js,ts,md,css,scss,json}' .eslintrc.json .prettierrc .babelrc",
118
116
  "test-types": "node test/typescript/index.js && tsc --esModuleInterop true --noEmit true --strictNullChecks true --noImplicitAny true --strict true test/typescript/*.ts",
119
117
  "eslint": "eslint '**/*.{js,md,ts}' --max-warnings 0 --ignore-path ./.eslintignore",
120
118
  "eslint-fix": "npx eslint --fix '**/*.{js,md,ts}' --max-warnings 0 --ignore-path ./.eslintignore",
121
- "test-unit": "NODE_ENV=test mocha --exit --bail --timeout 20000 --require ./babel-register test/unit/*.{js,test.ts}",
119
+ "test-unit": "NODE_ENV=test TS_NODE_PROJECT=tsconfig.test.json mocha test/unit/*.{js,test.ts}",
122
120
  "test-coverage": "nyc yarn test-unit",
123
121
  "test": "yarn test-unit",
124
122
  "testwatch": "NODE_ENV=test nodemon ./node_modules/.bin/mocha --timeout 20000 --require test-entry.js test/test.js",
125
123
  "lint": "yarn run prettier && yarn run eslint",
126
124
  "lint-fix": "yarn run prettier-fix && yarn run eslint-fix",
127
125
  "fix-staged": "lint-staged --config .lintstagedrc.fix.json --concurrent 1",
128
- "prepare": "yarn run build",
129
- "preversion": "yarn && yarn lint && yarn test-unit",
130
- "version": "git add yarn.lock",
131
- "postversion": "git push && git push --tags && npm publish"
126
+ "semantic-release": "semantic-release"
132
127
  },
133
128
  "engines": {
134
129
  "node": ">=16"
package/src/campaign.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { StreamChat } from './client';
2
- import { CampaignData, DefaultGenerics, ExtendableGenerics } from './types';
2
+ import { CampaignData, DefaultGenerics, ExtendableGenerics, GetCampaignOptions } from './types';
3
3
 
4
4
  export class Campaign<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> {
5
5
  id: string | null;
@@ -65,9 +65,9 @@ export class Campaign<StreamChatGenerics extends ExtendableGenerics = DefaultGen
65
65
  return this.client.stopCampaign(this.id as string);
66
66
  }
67
67
 
68
- async get() {
68
+ async get(options?: GetCampaignOptions) {
69
69
  this.verifyCampaignId();
70
70
 
71
- return this.client.getCampaign(this.id as string);
71
+ return this.client.getCampaign(this.id as string, options);
72
72
  }
73
73
  }
@@ -19,6 +19,7 @@ import {
19
19
  promoteChannel,
20
20
  shouldConsiderArchivedChannels,
21
21
  shouldConsiderPinnedChannels,
22
+ uniqBy,
22
23
  } from './utils';
23
24
 
24
25
  export type ChannelManagerPagination<SCG extends ExtendableGenerics = DefaultGenerics> = {
@@ -66,12 +67,14 @@ export type ChannelManagerEventTypes =
66
67
  | 'channel.deleted'
67
68
  | 'channel.hidden'
68
69
  | 'channel.truncated'
69
- | 'channel.visible';
70
+ | 'channel.visible'
71
+ | 'channel.updated';
70
72
 
71
73
  export type ChannelManagerEventHandlerNames =
72
74
  | 'channelDeletedHandler'
73
75
  | 'channelHiddenHandler'
74
76
  | 'channelTruncatedHandler'
77
+ | 'channelUpdatedHandler'
75
78
  | 'channelVisibleHandler'
76
79
  | 'newMessageHandler'
77
80
  | 'memberUpdatedHandler'
@@ -89,6 +92,7 @@ export const channelManagerEventToHandlerMapping: {
89
92
  'channel.deleted': 'channelDeletedHandler',
90
93
  'channel.hidden': 'channelHiddenHandler',
91
94
  'channel.truncated': 'channelTruncatedHandler',
95
+ 'channel.updated': 'channelUpdatedHandler',
92
96
  'channel.visible': 'channelVisibleHandler',
93
97
  'message.new': 'newMessageHandler',
94
98
  'member.updated': 'memberUpdatedHandler',
@@ -275,7 +279,7 @@ export class ChannelManager<SCG extends ExtendableGenerics = DefaultGenerics> {
275
279
  };
276
280
 
277
281
  public loadNext = async () => {
278
- const { pagination, channels, initialized } = this.state.getLatestValue();
282
+ const { pagination, initialized } = this.state.getLatestValue();
279
283
  const { filters, sort, options, isLoadingNext, hasNext } = pagination;
280
284
 
281
285
  if (!initialized || isLoadingNext || !hasNext) {
@@ -288,11 +292,12 @@ export class ChannelManager<SCG extends ExtendableGenerics = DefaultGenerics> {
288
292
  pagination: { ...pagination, isLoading: false, isLoadingNext: true },
289
293
  });
290
294
  const nextChannels = await this.client.queryChannels(filters, sort, options, this.stateOptions);
295
+ const { channels } = this.state.getLatestValue();
291
296
  const newOffset = offset + (nextChannels?.length ?? 0);
292
297
  const newOptions = { ...options, offset: newOffset };
293
298
 
294
299
  this.state.partialNext({
295
- channels: [...(channels || []), ...nextChannels],
300
+ channels: uniqBy<Channel<SCG>>([...(channels || []), ...nextChannels], 'cid'),
296
301
  pagination: {
297
302
  ...pagination,
298
303
  hasNext: (nextChannels?.length ?? 0) >= limit,
@@ -313,9 +318,11 @@ export class ChannelManager<SCG extends ExtendableGenerics = DefaultGenerics> {
313
318
 
314
319
  private notificationAddedToChannelHandler = async (event: Event<SCG>) => {
315
320
  const { id, type, members } = event?.channel ?? {};
321
+
316
322
  if (!type || !this.options.allowNotLoadedChannelPromotionForEvent?.['notification.added_to_channel']) {
317
323
  return;
318
324
  }
325
+
319
326
  const channel = await getAndWatchChannel({
320
327
  client: this.client,
321
328
  id,
@@ -328,6 +335,7 @@ export class ChannelManager<SCG extends ExtendableGenerics = DefaultGenerics> {
328
335
  }, []),
329
336
  type,
330
337
  });
338
+
331
339
  const { pagination, channels } = this.state.getLatestValue();
332
340
  if (!channels) {
333
341
  return;
@@ -415,10 +423,7 @@ export class ChannelManager<SCG extends ExtendableGenerics = DefaultGenerics> {
415
423
  private notificationNewMessageHandler = async (event: Event<SCG>) => {
416
424
  const { id, type } = event?.channel ?? {};
417
425
 
418
- const { channels, pagination } = this.state.getLatestValue();
419
- const { filters, sort } = pagination ?? {};
420
-
421
- if (!channels || !id || !type) {
426
+ if (!id || !type) {
422
427
  return;
423
428
  }
424
429
 
@@ -428,10 +433,14 @@ export class ChannelManager<SCG extends ExtendableGenerics = DefaultGenerics> {
428
433
  type,
429
434
  });
430
435
 
436
+ const { channels, pagination } = this.state.getLatestValue();
437
+ const { filters, sort } = pagination ?? {};
438
+
431
439
  const considerArchivedChannels = shouldConsiderArchivedChannels(filters);
432
440
  const isTargetChannelArchived = isChannelArchived(channel);
433
441
 
434
442
  if (
443
+ !channels ||
435
444
  (considerArchivedChannels && isTargetChannelArchived && !filters.archived) ||
436
445
  (considerArchivedChannels && !isTargetChannelArchived && filters.archived) ||
437
446
  !this.options.allowNotLoadedChannelPromotionForEvent?.['notification.message_new']
@@ -449,11 +458,9 @@ export class ChannelManager<SCG extends ExtendableGenerics = DefaultGenerics> {
449
458
  };
450
459
 
451
460
  private channelVisibleHandler = async (event: Event<SCG>) => {
452
- const { channels, pagination } = this.state.getLatestValue();
453
- const { sort, filters } = pagination ?? {};
454
461
  const { channel_type: channelType, channel_id: channelId } = event;
455
462
 
456
- if (!channels || !channelType || !channelId) {
463
+ if (!channelType || !channelId) {
457
464
  return;
458
465
  }
459
466
 
@@ -463,10 +470,14 @@ export class ChannelManager<SCG extends ExtendableGenerics = DefaultGenerics> {
463
470
  type: event.channel_type,
464
471
  });
465
472
 
473
+ const { channels, pagination } = this.state.getLatestValue();
474
+ const { sort, filters } = pagination ?? {};
475
+
466
476
  const considerArchivedChannels = shouldConsiderArchivedChannels(filters);
467
477
  const isTargetChannelArchived = isChannelArchived(channel);
468
478
 
469
479
  if (
480
+ !channels ||
470
481
  (considerArchivedChannels && isTargetChannelArchived && !filters.archived) ||
471
482
  (considerArchivedChannels && !isTargetChannelArchived && filters.archived) ||
472
483
  !this.options.allowNotLoadedChannelPromotionForEvent?.['channel.visible']
package/src/client.ts CHANGED
@@ -3,7 +3,7 @@
3
3
 
4
4
  import axios, { AxiosError, AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios';
5
5
  import https from 'https';
6
- import WebSocket from 'isomorphic-ws';
6
+ import type WebSocket from 'isomorphic-ws';
7
7
 
8
8
  import { Channel } from './channel';
9
9
  import { ClientState } from './client_state';
@@ -100,6 +100,7 @@ import {
100
100
  FlagUserResponse,
101
101
  GetBlockedUsersAPIResponse,
102
102
  GetCallTokenResponse,
103
+ GetCampaignOptions,
103
104
  GetChannelTypeResponse,
104
105
  GetCommandResponse,
105
106
  GetImportResponse,
@@ -173,6 +174,7 @@ import {
173
174
  ReservedMessageFields,
174
175
  ReviewFlagReportOptions,
175
176
  ReviewFlagReportResponse,
177
+ SdkIdentifier,
176
178
  SearchAPIResponse,
177
179
  SearchMessageSortBase,
178
180
  SearchOptions,
@@ -274,6 +276,7 @@ export class StreamChat<StreamChatGenerics extends ExtendableGenerics = DefaultG
274
276
  insightMetrics: InsightMetrics;
275
277
  defaultWSTimeoutWithFallback: number;
276
278
  defaultWSTimeout: number;
279
+ sdkIdentifier?: SdkIdentifier;
277
280
  private nextRequestAbortController: AbortController | null = null;
278
281
 
279
282
  /**
@@ -1472,10 +1475,11 @@ export class StreamChat<StreamChatGenerics extends ExtendableGenerics = DefaultG
1472
1475
  return await this.wsConnection.connect(
1473
1476
  this.options.enableWSFallback ? this.defaultWSTimeoutWithFallback : this.defaultWSTimeout,
1474
1477
  );
1475
- } catch (err) {
1478
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1479
+ } catch (error: any) {
1476
1480
  // run fallback only if it's WS/Network error and not a normal API error
1477
1481
  // make sure browser is online before even trying the longpoll
1478
- if (this.options.enableWSFallback && isWSFailure(err) && isOnline()) {
1482
+ if (this.options.enableWSFallback && isWSFailure(error) && isOnline()) {
1479
1483
  this.logger('info', 'client:connect() - WS failed, fallback to longpoll', { tags: ['connection', 'client'] });
1480
1484
  this.dispatchEvent({ type: 'transport.changed', mode: 'longpoll' });
1481
1485
 
@@ -1487,7 +1491,7 @@ export class StreamChat<StreamChatGenerics extends ExtendableGenerics = DefaultG
1487
1491
  return await this.wsFallback.connect();
1488
1492
  }
1489
1493
 
1490
- throw err;
1494
+ throw error;
1491
1495
  }
1492
1496
  }
1493
1497
 
@@ -2916,11 +2920,32 @@ export class StreamChat<StreamChatGenerics extends ExtendableGenerics = DefaultG
2916
2920
  }
2917
2921
 
2918
2922
  getUserAgent() {
2919
- return (
2920
- this.userAgent || `stream-chat-javascript-client-${this.node ? 'node' : 'browser'}-${process.env.PKG_VERSION}`
2921
- );
2923
+ if (this.userAgent) {
2924
+ return this.userAgent;
2925
+ }
2926
+
2927
+ const version = process.env.PKG_VERSION;
2928
+ const clientBundle = process.env.CLIENT_BUNDLE;
2929
+
2930
+ let userAgentString = '';
2931
+ if (this.sdkIdentifier) {
2932
+ userAgentString = `stream-chat-${this.sdkIdentifier.name}-v${this.sdkIdentifier.version}-llc-v${version}`;
2933
+ } else {
2934
+ userAgentString = `stream-chat-js-v${version}-${this.node ? 'node' : 'browser'}`;
2935
+ }
2936
+
2937
+ const additionalOptions = ([
2938
+ // reports which bundle is being picked from the exports
2939
+ ['client_bundle', clientBundle],
2940
+ ] as const).map(([key, value]) => `${key}=${value ?? ''}`);
2941
+
2942
+ return [userAgentString, ...additionalOptions].join('|');
2922
2943
  }
2923
2944
 
2945
+ /**
2946
+ * @deprecated use sdkIdentifier instead
2947
+ * @param userAgent
2948
+ */
2924
2949
  setUserAgent(userAgent: string) {
2925
2950
  this.userAgent = userAgent;
2926
2951
  }
@@ -3407,25 +3432,44 @@ export class StreamChat<StreamChatGenerics extends ExtendableGenerics = DefaultG
3407
3432
  */
3408
3433
  async createCampaign(params: CampaignData) {
3409
3434
  this.validateServerSideAuth();
3410
- return this.post<{ campaign: CampaignResponse } & APIResponse>(this.baseURL + `/campaigns`, { ...params });
3435
+ return this.post<
3436
+ {
3437
+ campaign: CampaignResponse;
3438
+ users: {
3439
+ next?: string;
3440
+ prev?: string;
3441
+ };
3442
+ } & APIResponse
3443
+ >(this.baseURL + `/campaigns`, { ...params });
3411
3444
  }
3412
3445
 
3413
- async getCampaign(id: string) {
3446
+ async getCampaign(id: string, options?: GetCampaignOptions) {
3414
3447
  this.validateServerSideAuth();
3415
- return this.get<{ campaign: CampaignResponse } & APIResponse>(
3416
- this.baseURL + `/campaigns/${encodeURIComponent(id)}`,
3417
- );
3448
+ return this.get<
3449
+ {
3450
+ campaign: CampaignResponse;
3451
+ users: {
3452
+ next?: string;
3453
+ prev?: string;
3454
+ };
3455
+ } & APIResponse
3456
+ >(this.baseURL + `/campaigns/${encodeURIComponent(id)}`, { ...options?.users });
3418
3457
  }
3419
3458
 
3420
3459
  async startCampaign(id: string, options?: { scheduledFor?: string; stopAt?: string }) {
3421
3460
  this.validateServerSideAuth();
3422
- return this.post<{ campaign: CampaignResponse } & APIResponse>(
3423
- this.baseURL + `/campaigns/${encodeURIComponent(id)}/start`,
3461
+ return this.post<
3424
3462
  {
3425
- scheduled_for: options?.scheduledFor,
3426
- stop_at: options?.stopAt,
3427
- },
3428
- );
3463
+ campaign: CampaignResponse;
3464
+ users: {
3465
+ next?: string;
3466
+ prev?: string;
3467
+ };
3468
+ } & APIResponse
3469
+ >(this.baseURL + `/campaigns/${encodeURIComponent(id)}/start`, {
3470
+ scheduled_for: options?.scheduledFor,
3471
+ stop_at: options?.stopAt,
3472
+ });
3429
3473
  }
3430
3474
  /**
3431
3475
  * queryCampaigns - Query Campaigns
@@ -3458,7 +3502,13 @@ export class StreamChat<StreamChatGenerics extends ExtendableGenerics = DefaultG
3458
3502
  */
3459
3503
  async updateCampaign(id: string, params: Partial<CampaignData>) {
3460
3504
  this.validateServerSideAuth();
3461
- return this.put<{ campaign: CampaignResponse }>(this.baseURL + `/campaigns/${encodeURIComponent(id)}`, params);
3505
+ return this.put<{
3506
+ campaign: CampaignResponse;
3507
+ users: {
3508
+ next?: string;
3509
+ prev?: string;
3510
+ };
3511
+ }>(this.baseURL + `/campaigns/${encodeURIComponent(id)}`, params);
3462
3512
  }
3463
3513
 
3464
3514
  /**
package/src/connection.ts CHANGED
@@ -113,7 +113,8 @@ export class StableWSConnection<StreamChatGenerics extends ExtendableGenerics =
113
113
  this.consecutiveFailures = 0;
114
114
 
115
115
  this._log(`connect() - Established ws connection with healthcheck: ${healthCheck}`);
116
- } catch (error) {
116
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
117
+ } catch (error: any) {
117
118
  this.isHealthy = false;
118
119
  this.consecutiveFailures += 1;
119
120
 
@@ -148,7 +149,8 @@ export class StableWSConnection<StreamChatGenerics extends ExtendableGenerics =
148
149
  for (let i = 0; i <= timeout; i += interval) {
149
150
  try {
150
151
  return await this.connectionOpen;
151
- } catch (error) {
152
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
153
+ } catch (error: any) {
152
154
  if (i === timeout) {
153
155
  throw new Error(
154
156
  JSON.stringify({
@@ -298,17 +300,21 @@ export class StableWSConnection<StreamChatGenerics extends ExtendableGenerics =
298
300
  }
299
301
  return response;
300
302
  }
301
- } catch (err) {
303
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
304
+ } catch (error: any) {
302
305
  this.isConnecting = false;
303
- this._log(`_connect() - Error - `, err);
306
+ this._log(`_connect() - Error - `, error);
304
307
  if (this.client.options.enableInsights) {
305
308
  this.client.insightMetrics.wsConsecutiveFailures++;
306
309
  this.client.insightMetrics.wsTotalFailures++;
307
310
 
308
- const insights = buildWsFatalInsight((this as unknown) as StableWSConnection, convertErrorToJson(err as Error));
311
+ const insights = buildWsFatalInsight(
312
+ (this as unknown) as StableWSConnection,
313
+ convertErrorToJson(error as Error),
314
+ );
309
315
  postInsights?.('ws_fatal', insights);
310
316
  }
311
- throw err;
317
+ throw error;
312
318
  }
313
319
  }
314
320
 
@@ -366,7 +372,8 @@ export class StableWSConnection<StreamChatGenerics extends ExtendableGenerics =
366
372
  this._log('_reconnect() - Finished recoverCallBack');
367
373
 
368
374
  this.consecutiveFailures = 0;
369
- } catch (error) {
375
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
376
+ } catch (error: any) {
370
377
  this.isHealthy = false;
371
378
  this.consecutiveFailures += 1;
372
379
  if (error.code === chatCodes.TOKEN_EXPIRED && !this.client.tokenManager.isStatic()) {