@stream-io/video-client 0.0.6 → 0.0.8

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.
@@ -30,6 +30,12 @@ export declare class Call {
30
30
  * The state of this call.
31
31
  */
32
32
  readonly state: CallState;
33
+ private rejoinPromise;
34
+ /**
35
+ * A promise that exposes the reconnection logic
36
+ * The use-case is for the react-native platform where online/offline events are not available in the window
37
+ */
38
+ get rejoin(): (() => Promise<void>) | undefined;
33
39
  /**
34
40
  * Flag indicating whether this call is "watched" and receives
35
41
  * updates from the backend.
@@ -1,7 +1,7 @@
1
1
  import { Call } from './Call';
2
2
  import { StreamClient } from './coordinator/connection/client';
3
3
  import { StreamVideoReadOnlyStateStore } from './store';
4
- import type { CreateCallTypeRequest, CreateCallTypeResponse, CreateDeviceRequest, CreateGuestRequest, CreateGuestResponse, GetCallTypeResponse, GetEdgesResponse, ListCallTypeResponse, ListDevicesResponse, QueryCallsRequest, UpdateCallTypeRequest, UpdateCallTypeResponse } from './gen/coordinator';
4
+ import type { ConnectedEvent, CreateCallTypeRequest, CreateCallTypeResponse, CreateDeviceRequest, CreateGuestRequest, CreateGuestResponse, GetCallTypeResponse, GetEdgesResponse, ListCallTypeResponse, ListDevicesResponse, QueryCallsRequest, UpdateCallTypeRequest, UpdateCallTypeResponse } from './gen/coordinator';
5
5
  import type { EventHandler, EventTypes, StreamClientOptions, TokenOrProvider, User } from './coordinator/connection/types';
6
6
  /**
7
7
  * A `StreamVideoClient` instance lets you communicate with our API, and authenticate users.
@@ -14,6 +14,8 @@ export declare class StreamVideoClient {
14
14
  private readonly writeableStateStore;
15
15
  streamClient: StreamClient;
16
16
  private eventHandlersToUnregister;
17
+ private connectionPromise;
18
+ private disconnectionPromise;
17
19
  /**
18
20
  * You should create only one instance of `StreamVideoClient`.
19
21
  * @param apiKey your Stream API key
@@ -28,14 +30,14 @@ export declare class StreamVideoClient {
28
30
  * @param user the user to connect.
29
31
  * @param tokenOrProvider a token or a function that returns a token.
30
32
  */
31
- connectUser: (user: User, tokenOrProvider: TokenOrProvider) => Promise<void | import("./gen/coordinator").ConnectedEvent>;
33
+ connectUser: (user: User, tokenOrProvider: TokenOrProvider) => Promise<void | ConnectedEvent>;
32
34
  /**
33
35
  * Connects the given anonymous user to the client.
34
36
  *
35
37
  * @param user the user to connect.
36
38
  * @param tokenOrProvider a token or a function that returns a token.
37
39
  */
38
- connectAnonymousUser: (user: User, tokenOrProvider: TokenOrProvider) => Promise<void>;
40
+ connectAnonymousUser: (user: User, tokenOrProvider: TokenOrProvider) => Promise<void | ConnectedEvent>;
39
41
  /**
40
42
  * Disconnects the currently connected user from the client.
41
43
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stream-io/video-client",
3
- "version": "0.0.6",
3
+ "version": "0.0.8",
4
4
  "packageManager": "yarn@3.2.4",
5
5
  "main": "dist/index.cjs.js",
6
6
  "module": "dist/index.es.js",
package/src/Call.ts CHANGED
@@ -135,6 +135,16 @@ export class Call {
135
135
  */
136
136
  readonly state = new CallState();
137
137
 
138
+ private rejoinPromise: (() => Promise<void>) | undefined;
139
+
140
+ /**
141
+ * A promise that exposes the reconnection logic
142
+ * The use-case is for the react-native platform where online/offline events are not available in the window
143
+ */
144
+ get rejoin(): (() => Promise<void>) | undefined {
145
+ return this.rejoinPromise;
146
+ }
147
+
138
148
  /**
139
149
  * Flag indicating whether this call is "watched" and receives
140
150
  * updates from the backend.
@@ -370,6 +380,7 @@ export class Call {
370
380
  if (callingState === CallingState.LEFT) {
371
381
  throw new Error('Cannot leave call that has already been left.');
372
382
  }
383
+ this.rejoinPromise = undefined;
373
384
 
374
385
  if (this.ringing) {
375
386
  // I'm the one who started the call, so I should cancel it.
@@ -642,7 +653,7 @@ export class Call {
642
653
  await sleep(retryInterval(this.reconnectAttempts));
643
654
  await this.join(data);
644
655
  console.log(`Rejoin: ${this.reconnectAttempts} successful!`);
645
- if (localParticipant) {
656
+ if (localParticipant && !isReactNative()) {
646
657
  const {
647
658
  audioStream,
648
659
  videoStream,
@@ -657,6 +668,8 @@ export class Call {
657
668
  console.log(`Rejoin: state restored ${this.reconnectAttempts}`);
658
669
  };
659
670
 
671
+ this.rejoinPromise = rejoin;
672
+
660
673
  // reconnect if the connection was closed unexpectedly. example:
661
674
  // - SFU crash or restart
662
675
  // - network change
@@ -667,6 +680,8 @@ export class Call {
667
680
  // do nothing if the connection was closed because of a policy violation
668
681
  // e.g., the user has been blocked by an admin or moderator
669
682
  if (e.code === KnownCodes.WS_POLICY_VIOLATION) return;
683
+ // do nothing for react-native as its handled by SDK
684
+ if (isReactNative()) return;
670
685
  if (this.reconnectAttempts < this.maxReconnectAttempts) {
671
686
  rejoin().catch(() => {
672
687
  console.log(
@@ -5,6 +5,7 @@ import {
5
5
  StreamVideoWriteableStateStore,
6
6
  } from './store';
7
7
  import type {
8
+ ConnectedEvent,
8
9
  CreateCallTypeRequest,
9
10
  CreateCallTypeResponse,
10
11
  CreateDeviceRequest,
@@ -40,6 +41,8 @@ export class StreamVideoClient {
40
41
  streamClient: StreamClient;
41
42
 
42
43
  private eventHandlersToUnregister: Array<() => void> = [];
44
+ private connectionPromise: Promise<void | ConnectedEvent> | undefined;
45
+ private disconnectionPromise: Promise<void> | undefined;
43
46
 
44
47
  /**
45
48
  * You should create only one instance of `StreamVideoClient`.
@@ -67,11 +70,19 @@ export class StreamVideoClient {
67
70
  * @param tokenOrProvider a token or a function that returns a token.
68
71
  */
69
72
  connectUser = async (user: User, tokenOrProvider: TokenOrProvider) => {
70
- const connectUserResponse = await this.streamClient.connectUser(
71
- // @ts-expect-error
72
- user,
73
- tokenOrProvider,
74
- );
73
+ const connectUser = () => {
74
+ return this.streamClient.connectUser(
75
+ // @ts-expect-error
76
+ user,
77
+ tokenOrProvider,
78
+ );
79
+ };
80
+ this.connectionPromise = this.disconnectionPromise
81
+ ? this.disconnectionPromise.then(() => connectUser())
82
+ : connectUser();
83
+
84
+ this.connectionPromise?.finally(() => (this.connectionPromise = undefined));
85
+ const connectUserResponse = await this.connectionPromise;
75
86
  this.writeableStateStore.setConnectedUser(user);
76
87
 
77
88
  this.eventHandlersToUnregister.push(
@@ -163,8 +174,14 @@ export class StreamVideoClient {
163
174
  user: User,
164
175
  tokenOrProvider: TokenOrProvider,
165
176
  ) => {
166
- // @ts-expect-error
167
- return this.streamClient.connectAnonymousUser(user, tokenOrProvider);
177
+ const connectAnonymousUser = () =>
178
+ // @ts-expect-error
179
+ this.streamClient.connectAnonymousUser(user, tokenOrProvider);
180
+ this.connectionPromise = this.disconnectionPromise
181
+ ? this.disconnectionPromise.then(() => connectAnonymousUser())
182
+ : connectAnonymousUser();
183
+ this.connectionPromise.finally(() => (this.connectionPromise = undefined));
184
+ return this.connectionPromise;
168
185
  };
169
186
 
170
187
  /**
@@ -176,7 +193,14 @@ export class StreamVideoClient {
176
193
  * https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent
177
194
  */
178
195
  disconnectUser = async (timeout?: number) => {
179
- await this.streamClient.disconnectUser(timeout);
196
+ const disconnectUser = () => this.streamClient.disconnectUser(timeout);
197
+ this.disconnectionPromise = this.connectionPromise
198
+ ? this.connectionPromise.then(() => disconnectUser())
199
+ : disconnectUser();
200
+ this.disconnectionPromise.finally(
201
+ () => (this.disconnectionPromise = undefined),
202
+ );
203
+ await this.disconnectionPromise;
180
204
  this.eventHandlersToUnregister.forEach((unregister) => unregister());
181
205
  this.eventHandlersToUnregister = [];
182
206
  this.writeableStateStore.setConnectedUser(undefined);
package/src/rtc/signal.ts CHANGED
@@ -9,15 +9,15 @@ export const createWebSocketSignalChannel = (opts: {
9
9
  ws.binaryType = 'arraybuffer'; // do we need this?
10
10
 
11
11
  ws.addEventListener('error', (e) => {
12
- console.error('Error', e);
12
+ console.log('Signaling WS channel error', e);
13
13
  });
14
14
 
15
15
  ws.addEventListener('close', (e) => {
16
- console.warn('Signalling channel is closed', e);
16
+ console.log('Signaling WS channel is closed', e);
17
17
  });
18
18
 
19
19
  ws.addEventListener('open', (e) => {
20
- console.log('Signalling channel is open', e);
20
+ console.log('Signaling WS channel is open', e);
21
21
  });
22
22
 
23
23
  if (onMessage) {