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.
- package/README.md +21 -13
- package/dist/browser.es.js +290 -149
- package/dist/browser.es.js.map +1 -1
- package/dist/browser.full-bundle.min.js +1 -1
- package/dist/browser.full-bundle.min.js.map +1 -1
- package/dist/browser.js +290 -149
- package/dist/browser.js.map +1 -1
- package/dist/index.es.js +290 -149
- package/dist/index.es.js.map +1 -1
- package/dist/index.js +290 -149
- package/dist/index.js.map +1 -1
- package/dist/types/channel.d.ts +127 -123
- package/dist/types/channel.d.ts.map +1 -1
- package/dist/types/channel_state.d.ts +41 -41
- package/dist/types/channel_state.d.ts.map +1 -1
- package/dist/types/client.d.ts +200 -170
- package/dist/types/client.d.ts.map +1 -1
- package/dist/types/client_state.d.ts +6 -6
- package/dist/types/client_state.d.ts.map +1 -1
- package/dist/types/connection.d.ts +10 -10
- package/dist/types/connection.d.ts.map +1 -1
- package/dist/types/connection_fallback.d.ts +7 -7
- package/dist/types/connection_fallback.d.ts.map +1 -1
- package/dist/types/events.d.ts +1 -0
- package/dist/types/events.d.ts.map +1 -1
- package/dist/types/insights.d.ts +2 -2
- package/dist/types/token_manager.d.ts +6 -6
- package/dist/types/token_manager.d.ts.map +1 -1
- package/dist/types/types.d.ts +370 -234
- package/dist/types/types.d.ts.map +1 -1
- package/dist/types/utils.d.ts +2 -2
- package/dist/types/utils.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/channel.ts +195 -290
- package/src/channel_state.ts +54 -219
- package/src/client.ts +300 -521
- package/src/client_state.ts +6 -6
- package/src/connection.ts +10 -23
- package/src/connection_fallback.ts +9 -21
- package/src/events.ts +1 -0
- package/src/token_manager.ts +6 -6
- package/src/types.ts +482 -528
- package/src/utils.ts +7 -11
package/src/client_state.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import {
|
|
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<
|
|
6
|
+
export class ClientState<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> {
|
|
7
7
|
users: {
|
|
8
|
-
[key: string]: UserResponse<
|
|
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<
|
|
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<
|
|
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<
|
|
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,
|
|
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<
|
|
41
|
+
client: StreamChat<StreamChatGenerics>;
|
|
51
42
|
|
|
52
43
|
// local vars
|
|
53
44
|
connectionID?: string;
|
|
54
|
-
connectionOpen?: ConnectAPIResponse<
|
|
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<
|
|
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<
|
|
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,
|
|
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
|
-
|
|
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:
|
|
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<
|
|
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<
|
|
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
package/src/token_manager.ts
CHANGED
|
@@ -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,
|
|
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<
|
|
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<
|
|
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<
|
|
41
|
+
* @param {UserResponse<StreamChatGenerics>} user
|
|
42
42
|
*/
|
|
43
|
-
setTokenOrProvider = async (tokenOrProvider: TokenOrProvider, user: UserResponse<
|
|
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<
|
|
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
|
|