stream-chat 5.3.0 → 6.0.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 (43) hide show
  1. package/README.md +21 -13
  2. package/dist/browser.es.js +290 -149
  3. package/dist/browser.es.js.map +1 -1
  4. package/dist/browser.full-bundle.min.js +1 -1
  5. package/dist/browser.full-bundle.min.js.map +1 -1
  6. package/dist/browser.js +290 -149
  7. package/dist/browser.js.map +1 -1
  8. package/dist/index.es.js +290 -149
  9. package/dist/index.es.js.map +1 -1
  10. package/dist/index.js +290 -149
  11. package/dist/index.js.map +1 -1
  12. package/dist/types/channel.d.ts +127 -123
  13. package/dist/types/channel.d.ts.map +1 -1
  14. package/dist/types/channel_state.d.ts +41 -41
  15. package/dist/types/channel_state.d.ts.map +1 -1
  16. package/dist/types/client.d.ts +200 -170
  17. package/dist/types/client.d.ts.map +1 -1
  18. package/dist/types/client_state.d.ts +6 -6
  19. package/dist/types/client_state.d.ts.map +1 -1
  20. package/dist/types/connection.d.ts +10 -10
  21. package/dist/types/connection.d.ts.map +1 -1
  22. package/dist/types/connection_fallback.d.ts +7 -7
  23. package/dist/types/connection_fallback.d.ts.map +1 -1
  24. package/dist/types/events.d.ts +1 -0
  25. package/dist/types/events.d.ts.map +1 -1
  26. package/dist/types/insights.d.ts +2 -2
  27. package/dist/types/token_manager.d.ts +6 -6
  28. package/dist/types/token_manager.d.ts.map +1 -1
  29. package/dist/types/types.d.ts +370 -234
  30. package/dist/types/types.d.ts.map +1 -1
  31. package/dist/types/utils.d.ts +2 -2
  32. package/dist/types/utils.d.ts.map +1 -1
  33. package/package.json +4 -4
  34. package/src/channel.ts +195 -290
  35. package/src/channel_state.ts +54 -219
  36. package/src/client.ts +300 -521
  37. package/src/client_state.ts +6 -6
  38. package/src/connection.ts +10 -23
  39. package/src/connection_fallback.ts +9 -21
  40. package/src/events.ts +1 -0
  41. package/src/token_manager.ts +6 -6
  42. package/src/types.ts +482 -528
  43. package/src/utils.ts +7 -11
@@ -1,11 +1,11 @@
1
- import { UR, UserResponse } from './types';
1
+ import { UserResponse, ExtendableGenerics, DefaultGenerics } from './types';
2
2
 
3
3
  /**
4
4
  * ClientState - A container class for the client state.
5
5
  */
6
- export class ClientState<UserType = UR> {
6
+ export class ClientState<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> {
7
7
  users: {
8
- [key: string]: UserResponse<UserType>;
8
+ [key: string]: UserResponse<StreamChatGenerics>;
9
9
  };
10
10
  userChannelReferences: { [key: string]: { [key: string]: boolean } };
11
11
  constructor() {
@@ -16,19 +16,19 @@ export class ClientState<UserType = UR> {
16
16
  this.userChannelReferences = {};
17
17
  }
18
18
 
19
- updateUsers(users: UserResponse<UserType>[]) {
19
+ updateUsers(users: UserResponse<StreamChatGenerics>[]) {
20
20
  for (const user of users) {
21
21
  this.updateUser(user);
22
22
  }
23
23
  }
24
24
 
25
- updateUser(user?: UserResponse<UserType>) {
25
+ updateUser(user?: UserResponse<StreamChatGenerics>) {
26
26
  if (user != null) {
27
27
  this.users[user.id] = user;
28
28
  }
29
29
  }
30
30
 
31
- updateUserReference(user: UserResponse<UserType>, channelID: string) {
31
+ updateUserReference(user: UserResponse<StreamChatGenerics>, channelID: string) {
32
32
  if (user == null) {
33
33
  return;
34
34
  }
package/src/connection.ts CHANGED
@@ -9,7 +9,7 @@ import {
9
9
  addConnectionEventListeners,
10
10
  } from './utils';
11
11
  import { buildWsFatalInsight, buildWsSuccessAfterFailureInsight, postInsights } from './insights';
12
- import { ConnectAPIResponse, ConnectionOpen, LiteralStringForUnion, UR, LogLevel } from './types';
12
+ import { ConnectAPIResponse, ConnectionOpen, ExtendableGenerics, DefaultGenerics, UR, LogLevel } from './types';
13
13
  import { StreamChat } from './client';
14
14
 
15
15
  // Type guards to check WebSocket error type
@@ -36,22 +36,13 @@ const isErrorEvent = (res: WebSocket.CloseEvent | WebSocket.Data | WebSocket.Err
36
36
  * - state can be recovered by querying the channel again
37
37
  * - if the servers fails to publish a message to the client, the WS connection is destroyed
38
38
  */
39
- export class StableWSConnection<
40
- // CAUTION: generics are out of usual order here
41
- ChannelType extends UR = UR,
42
- CommandType extends string = LiteralStringForUnion,
43
- UserType extends UR = UR,
44
- AttachmentType extends UR = UR,
45
- EventType extends UR = UR,
46
- MessageType extends UR = UR,
47
- ReactionType extends UR = UR
48
- > {
39
+ export class StableWSConnection<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> {
49
40
  // global from constructor
50
- client: StreamChat<AttachmentType, ChannelType, CommandType, EventType, MessageType, ReactionType, UserType>;
41
+ client: StreamChat<StreamChatGenerics>;
51
42
 
52
43
  // local vars
53
44
  connectionID?: string;
54
- connectionOpen?: ConnectAPIResponse<ChannelType, CommandType, UserType>;
45
+ connectionOpen?: ConnectAPIResponse<StreamChatGenerics>;
55
46
  consecutiveFailures: number;
56
47
  pingInterval: number;
57
48
  healthCheckTimeoutRef?: NodeJS.Timeout;
@@ -66,16 +57,12 @@ export class StableWSConnection<
66
57
  reason?: Error & { code?: string | number; isWSFailure?: boolean; StatusCode?: string | number },
67
58
  ) => void;
68
59
  requestID: string | undefined;
69
- resolvePromise?: (value: ConnectionOpen<ChannelType, CommandType, UserType>) => void;
60
+ resolvePromise?: (value: ConnectionOpen<StreamChatGenerics>) => void;
70
61
  totalFailures: number;
71
62
  ws?: WebSocket;
72
63
  wsID: number;
73
64
 
74
- constructor({
75
- client,
76
- }: {
77
- client: StreamChat<AttachmentType, ChannelType, CommandType, EventType, MessageType, ReactionType, UserType>;
78
- }) {
65
+ constructor({ client }: { client: StreamChat<StreamChatGenerics> }) {
79
66
  /** StreamChat client */
80
67
  this.client = client;
81
68
  /** consecutive failures influence the duration of the timeout */
@@ -271,9 +258,11 @@ export class StableWSConnection<
271
258
  this.requestID = randomId();
272
259
  this.client.insightMetrics.connectionStartTimestamp = new Date().getTime();
273
260
  try {
261
+ this._log(`_connect() - waiting for token`);
274
262
  await this.client.tokenManager.tokenReady();
275
263
  this._setupConnectionPromise();
276
264
  const wsURL = this._buildUrl();
265
+ this._log(`_connect() - Connecting to ${wsURL}`, { wsURL, requestID: this.requestID });
277
266
  this.ws = new WebSocket(wsURL);
278
267
  this.ws.onopen = this.onopen.bind(this, this.wsID);
279
268
  this.ws.onclose = this.onclose.bind(this, this.wsID);
@@ -412,6 +401,7 @@ export class StableWSConnection<
412
401
  onmessage = (wsID: number, event: WebSocket.MessageEvent) => {
413
402
  if (this.wsID !== wsID) return;
414
403
 
404
+ this._log('onmessage() - onmessage callback', { event, wsID });
415
405
  const data = typeof event.data === 'string' ? JSON.parse(event.data) : null;
416
406
 
417
407
  // we wait till the first message before we consider the connection open..
@@ -430,7 +420,6 @@ export class StableWSConnection<
430
420
 
431
421
  // trigger the event..
432
422
  this.lastEvent = new Date();
433
- this._log('onmessage() - onmessage callback', { event, wsID });
434
423
 
435
424
  if (data && data.type === 'health.check') {
436
425
  this.scheduleNextPing();
@@ -499,7 +488,6 @@ export class StableWSConnection<
499
488
  this.isHealthy = healthy;
500
489
 
501
490
  if (this.isHealthy) {
502
- //@ts-expect-error
503
491
  this.client.dispatchEvent({ type: 'connection.changed', online: this.isHealthy });
504
492
  return;
505
493
  }
@@ -507,7 +495,6 @@ export class StableWSConnection<
507
495
  // we're offline, wait few seconds and fire and event if still offline
508
496
  setTimeout(() => {
509
497
  if (this.isHealthy) return;
510
- //@ts-expect-error
511
498
  this.client.dispatchEvent({ type: 'connection.changed', online: this.isHealthy });
512
499
  }, 5000);
513
500
  };
@@ -573,7 +560,7 @@ export class StableWSConnection<
573
560
  _setupConnectionPromise = () => {
574
561
  this.isResolved = false;
575
562
  /** a promise that is resolved once ws.open is called */
576
- this.connectionOpen = new Promise<ConnectionOpen<ChannelType, CommandType, UserType>>((resolve, reject) => {
563
+ this.connectionOpen = new Promise<ConnectionOpen<StreamChatGenerics>>((resolve, reject) => {
577
564
  this.resolvePromise = resolve;
578
565
  this.rejectPromise = reject;
579
566
  });
@@ -2,7 +2,7 @@ import axios, { AxiosRequestConfig, CancelTokenSource } from 'axios';
2
2
  import { StreamChat } from './client';
3
3
  import { addConnectionEventListeners, removeConnectionEventListeners, retryInterval, sleep } from './utils';
4
4
  import { isAPIError, isConnectionIDError, isErrorRetryable } from './errors';
5
- import { ConnectionOpen, Event, UnknownType, UR, LiteralStringForUnion, LogLevel } from './types';
5
+ import { ConnectionOpen, Event, UR, ExtendableGenerics, DefaultGenerics, LogLevel } from './types';
6
6
 
7
7
  export enum ConnectionState {
8
8
  Closed = 'CLOSED',
@@ -12,26 +12,14 @@ export enum ConnectionState {
12
12
  Init = 'INIT',
13
13
  }
14
14
 
15
- export class WSConnectionFallback<
16
- AttachmentType extends UR = UR,
17
- ChannelType extends UR = UR,
18
- CommandType extends string = LiteralStringForUnion,
19
- EventType extends UR = UR,
20
- MessageType extends UR = UR,
21
- ReactionType extends UR = UR,
22
- UserType extends UR = UR
23
- > {
24
- client: StreamChat<AttachmentType, ChannelType, CommandType, EventType, MessageType, ReactionType, UserType>;
15
+ export class WSConnectionFallback<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> {
16
+ client: StreamChat<StreamChatGenerics>;
25
17
  state: ConnectionState;
26
18
  consecutiveFailures: number;
27
19
  connectionID?: string;
28
20
  cancelToken?: CancelTokenSource;
29
21
 
30
- constructor({
31
- client,
32
- }: {
33
- client: StreamChat<AttachmentType, ChannelType, CommandType, EventType, MessageType, ReactionType, UserType>;
34
- }) {
22
+ constructor({ client }: { client: StreamChat<StreamChatGenerics> }) {
35
23
  this.client = client;
36
24
  this.state = ConnectionState.Init;
37
25
  this.consecutiveFailures = 0;
@@ -48,12 +36,10 @@ export class WSConnectionFallback<
48
36
 
49
37
  // transition from connecting => connected
50
38
  if (this.state === ConnectionState.Connecting && state === ConnectionState.Connected) {
51
- //@ts-expect-error
52
39
  this.client.dispatchEvent({ type: 'connection.changed', online: true });
53
40
  }
54
41
 
55
42
  if (state === ConnectionState.Closed || state === ConnectionState.Disconnected) {
56
- //@ts-expect-error
57
43
  this.client.dispatchEvent({ type: 'connection.changed', online: false });
58
44
  }
59
45
 
@@ -77,7 +63,7 @@ export class WSConnectionFallback<
77
63
  };
78
64
 
79
65
  /** @private */
80
- _req = async <T = UR>(params: UnknownType, config: AxiosRequestConfig, retry: boolean): Promise<T> => {
66
+ _req = async <T = UR>(params: UR, config: AxiosRequestConfig, retry: boolean): Promise<T> => {
81
67
  if (!this.cancelToken && !params.close) {
82
68
  this.cancelToken = axios.CancelToken.source();
83
69
  }
@@ -113,7 +99,7 @@ export class WSConnectionFallback<
113
99
  while (this.state === ConnectionState.Connected) {
114
100
  try {
115
101
  const data = await this._req<{
116
- events: Event<AttachmentType, ChannelType, CommandType, EventType, MessageType, ReactionType, UserType>[];
102
+ events: Event<StreamChatGenerics>[];
117
103
  }>({}, { timeout: 30000 }, true); // 30s => API responds in 20s if there is no event
118
104
 
119
105
  if (data.events?.length) {
@@ -163,7 +149,7 @@ export class WSConnectionFallback<
163
149
  this._setState(ConnectionState.Connecting);
164
150
  this.connectionID = undefined; // connect should be sent with empty connection_id so API creates one
165
151
  try {
166
- const { event } = await this._req<{ event: ConnectionOpen<ChannelType, CommandType, UserType> }>(
152
+ const { event } = await this._req<{ event: ConnectionOpen<StreamChatGenerics> }>(
167
153
  { json: this.client._buildWSPayload() },
168
154
  { timeout: 8000 }, // 8s
169
155
  reconnect,
@@ -171,6 +157,8 @@ export class WSConnectionFallback<
171
157
 
172
158
  this._setState(ConnectionState.Connected);
173
159
  this.connectionID = event.connection_id;
160
+ // @ts-expect-error
161
+ this.client.dispatchEvent(event);
174
162
  this._poll();
175
163
  if (reconnect) {
176
164
  this.client.recoverState();
package/src/events.ts CHANGED
@@ -43,6 +43,7 @@ export const EVENT_MAP = {
43
43
  // local events
44
44
  'connection.changed': true,
45
45
  'connection.recovered': true,
46
+ 'transport.changed': true,
46
47
  };
47
48
 
48
49
  const IS_VALID_EVENT_MAP_TYPE = { ...EVENT_MAP, all: true };
@@ -1,20 +1,20 @@
1
1
  import { Secret } from 'jsonwebtoken';
2
2
  import { UserFromToken, JWTServerToken, JWTUserToken } from './signing';
3
3
  import { isFunction } from './utils';
4
- import { TokenOrProvider, UR, UserResponse } from './types';
4
+ import { TokenOrProvider, ExtendableGenerics, DefaultGenerics, UserResponse } from './types';
5
5
 
6
6
  /**
7
7
  * TokenManager
8
8
  *
9
9
  * Handles all the operations around user token.
10
10
  */
11
- export class TokenManager<UserType extends UR = UR> {
11
+ export class TokenManager<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> {
12
12
  loadTokenPromise: Promise<string> | null;
13
13
  type: 'static' | 'provider';
14
14
  secret?: Secret;
15
15
  token?: string;
16
16
  tokenProvider?: TokenOrProvider;
17
- user?: UserResponse<UserType>;
17
+ user?: UserResponse<StreamChatGenerics>;
18
18
  /**
19
19
  * Constructor
20
20
  *
@@ -38,9 +38,9 @@ export class TokenManager<UserType extends UR = UR> {
38
38
  * Token provider should return a token string or a promise which resolves to string token.
39
39
  *
40
40
  * @param {TokenOrProvider} tokenOrProvider
41
- * @param {UserResponse<UserType>} user
41
+ * @param {UserResponse<StreamChatGenerics>} user
42
42
  */
43
- setTokenOrProvider = async (tokenOrProvider: TokenOrProvider, user: UserResponse<UserType>) => {
43
+ setTokenOrProvider = async (tokenOrProvider: TokenOrProvider, user: UserResponse<StreamChatGenerics>) => {
44
44
  this.validateToken(tokenOrProvider, user);
45
45
  this.user = user;
46
46
 
@@ -73,7 +73,7 @@ export class TokenManager<UserType extends UR = UR> {
73
73
  };
74
74
 
75
75
  // Validates the user token.
76
- validateToken = (tokenOrProvider: TokenOrProvider, user: UserResponse<UserType>) => {
76
+ validateToken = (tokenOrProvider: TokenOrProvider, user: UserResponse<StreamChatGenerics>) => {
77
77
  // allow empty token for anon user
78
78
  if (user && user.anon && !tokenOrProvider) return;
79
79