@stream-io/video-client 0.1.4 → 0.1.6
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/CHANGELOG.md +14 -0
- package/README.md +54 -8
- package/dist/index.browser.es.js +40 -61
- package/dist/index.browser.es.js.map +1 -1
- package/dist/index.cjs.js +39 -60
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.es.js +40 -61
- package/dist/index.es.js.map +1 -1
- package/dist/src/Call.d.ts +2 -2
- package/dist/src/StreamVideoClient.d.ts +4 -5
- package/dist/src/__tests__/server-side/call-types.test.d.ts +1 -0
- package/dist/src/__tests__/server-side/call.test.d.ts +1 -0
- package/dist/src/__tests__/server-side/create-token.test.d.ts +1 -0
- package/dist/src/__tests__/server-side/server-side-user.test.d.ts +1 -0
- package/dist/src/coordinator/connection/client.d.ts +0 -6
- package/dist/version.d.ts +1 -1
- package/package.json +1 -1
- package/src/Call.ts +18 -11
- package/src/StreamVideoClient.ts +33 -31
- package/src/__tests__/StreamVideoClient.test.ts +9 -9
- package/src/__tests__/server-side/call-members.test.ts +93 -0
- package/src/__tests__/server-side/call-types.test.ts +78 -0
- package/src/__tests__/server-side/call.test.ts +147 -0
- package/src/__tests__/server-side/create-token.test.ts +44 -0
- package/src/__tests__/server-side/server-side-user.test.ts +28 -0
- package/src/coordinator/connection/client.ts +2 -29
- package/src/__tests__/StreamVideoServerClient.test.ts +0 -110
- /package/dist/src/__tests__/{StreamVideoServerClient.test.d.ts → server-side/call-members.test.d.ts} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver).
|
|
4
4
|
|
|
5
|
+
### [0.1.6](https://github.com/GetStream/stream-video-js/compare/client0.1.5...client0.1.6) (2023-07-26)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Documentation
|
|
9
|
+
|
|
10
|
+
* Readme for js client, contributing guide ([#858](https://github.com/GetStream/stream-video-js/issues/858)) ([4d25c90](https://github.com/GetStream/stream-video-js/commit/4d25c909d2db3c5f98f89ad37dd810fc4ab7cc95))
|
|
11
|
+
|
|
12
|
+
### [0.1.5](https://github.com/GetStream/stream-video-js/compare/client0.1.4...client0.1.5) (2023-07-21)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
### Bug Fixes
|
|
16
|
+
|
|
17
|
+
* strict mode issue ([#740](https://github.com/GetStream/stream-video-js/issues/740)) ([c39e4e4](https://github.com/GetStream/stream-video-js/commit/c39e4e4041a2326393478ad808b2aa791d50f8ce))
|
|
18
|
+
|
|
5
19
|
### [0.1.4](https://github.com/GetStream/stream-video-js/compare/client0.1.3...client0.1.4) (2023-07-21)
|
|
6
20
|
|
|
7
21
|
|
package/README.md
CHANGED
|
@@ -1,14 +1,60 @@
|
|
|
1
1
|
# @stream-io/video-client
|
|
2
2
|
|
|
3
|
-
🚧 **WARNING** This package is not yet stable, it is for internal use only. For more information check out our [video product page](https://getstream.io/video/).
|
|
3
|
+
🚧 **WARNING** This package is not yet stable, it is for internal use only. For more information check out our [video product page](https://getstream.io/video/). 🚧
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Low-level video client for browser and Node.js integrations.
|
|
6
6
|
|
|
7
|
-
##
|
|
7
|
+
## **Quick Links**
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
- [Register](https://getstream.io/chat/trial/) to get an API key for Stream Video
|
|
10
|
+
TODO: add links to docs and tutorials
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
## What is Stream?
|
|
13
|
+
|
|
14
|
+
Stream allows developers to rapidly deploy scalable feeds, chat messaging and video with an industry leading 99.999% uptime SLA guarantee.
|
|
15
|
+
|
|
16
|
+
With Stream's video components, you can use their SDK to build in-app video calling, audio rooms, audio calls, or live streaming. The best place to get started is with their tutorials:
|
|
17
|
+
|
|
18
|
+
- Video & Audio Calling Tutorial
|
|
19
|
+
- Audio Rooms Tutorial
|
|
20
|
+
- Livestreaming Tutorial
|
|
21
|
+
|
|
22
|
+
Stream provides UI components and state handling that make it easy to build video calling for your app. All calls run on Stream's network of edge servers around the world, ensuring optimal latency and reliability.
|
|
23
|
+
|
|
24
|
+
## 👩💻 Free for Makers 👨💻
|
|
25
|
+
|
|
26
|
+
Stream is free for most side and hobby projects. To qualify, your project/company needs to have < 5 team members and < $10k in monthly revenue. Makers get $100 in monthly credit for video for free.
|
|
27
|
+
|
|
28
|
+
## 💡Supported Features💡
|
|
29
|
+
|
|
30
|
+
Here are some of the features we support:
|
|
31
|
+
|
|
32
|
+
- Developer experience: Great SDKs, docs, tutorials and support so you can build quickly
|
|
33
|
+
- Edge network: Servers around the world ensure optimal latency and reliability
|
|
34
|
+
- Chat: Stored chat, reactions, threads, typing indicators, URL previews etc
|
|
35
|
+
- Security & Privacy: Based in USA and EU, Soc2 certified, GDPR compliant
|
|
36
|
+
- Dynascale: Automatically switch resolutions, fps, bitrate, codecs and paginate video on large calls
|
|
37
|
+
- Screen sharing
|
|
38
|
+
- Picture in picture support
|
|
39
|
+
- Active speaker
|
|
40
|
+
- Custom events
|
|
41
|
+
- Geofencing
|
|
42
|
+
- Notifications and ringing calls
|
|
43
|
+
- Opus DTX & Red for reliable audio
|
|
44
|
+
- Webhooks & SQS
|
|
45
|
+
- Backstage mode
|
|
46
|
+
- Flexible permissions system
|
|
47
|
+
- Joining calls by ID, link or invite
|
|
48
|
+
- Enabling and disabling audio and video when in calls
|
|
49
|
+
- Flipping, Enabling and disabling camera in calls
|
|
50
|
+
- Enabling and disabling speakerphone in calls
|
|
51
|
+
- Push notification providers support
|
|
52
|
+
- Call recording
|
|
53
|
+
- Broadcasting to HLS
|
|
54
|
+
|
|
55
|
+
## Contributing
|
|
56
|
+
|
|
57
|
+
- How can I submit a sample app?
|
|
58
|
+
- Apps submissions are always welcome. 🥳 Open a PR with a proper description and we'll review it as soon as possible.
|
|
59
|
+
- Spot a bug 🕷 ?
|
|
60
|
+
- We welcome code changes that improve the apps or fix a problem. Please make sure to follow all best practices and add tests if applicable before submitting a Pull Request on Github.
|
package/dist/index.browser.es.js
CHANGED
|
@@ -4,7 +4,7 @@ import { ServiceType, stackIntercept } from '@protobuf-ts/runtime-rpc';
|
|
|
4
4
|
import axios, { AxiosHeaders } from 'axios';
|
|
5
5
|
export { AxiosError } from 'axios';
|
|
6
6
|
import { TwirpFetchTransport } from '@protobuf-ts/twirp-transport';
|
|
7
|
-
import { ReplaySubject, BehaviorSubject, takeWhile, pairwise, tap, debounce, timer, map as map$2, Observable, debounceTime, concatMap, from, shareReplay, merge, combineLatest
|
|
7
|
+
import { ReplaySubject, BehaviorSubject, takeWhile, filter, pairwise, tap, debounce, timer, map as map$2, Observable, debounceTime, concatMap, from, shareReplay, merge, combineLatest } from 'rxjs';
|
|
8
8
|
import * as SDP from 'sdp-transform';
|
|
9
9
|
import WebSocket from 'isomorphic-ws';
|
|
10
10
|
import { take, map as map$1, distinctUntilChanged } from 'rxjs/operators';
|
|
@@ -9465,11 +9465,13 @@ class Call {
|
|
|
9465
9465
|
*/
|
|
9466
9466
|
this.leave = ({ reject = false } = {}) => __awaiter(this, void 0, void 0, function* () {
|
|
9467
9467
|
var _a, _b, _c, _d;
|
|
9468
|
-
// TODO: handle case when leave is called during JOINING
|
|
9469
9468
|
const callingState = this.state.callingState;
|
|
9470
9469
|
if (callingState === CallingState.LEFT) {
|
|
9471
9470
|
throw new Error('Cannot leave call that has already been left.');
|
|
9472
9471
|
}
|
|
9472
|
+
if (callingState === CallingState.JOINING) {
|
|
9473
|
+
yield this.assertCallJoined();
|
|
9474
|
+
}
|
|
9473
9475
|
if (this.ringing) {
|
|
9474
9476
|
// I'm the one who started the call, so I should cancel it.
|
|
9475
9477
|
const hasOtherParticipants = this.state.remoteParticipants.length > 0;
|
|
@@ -9875,13 +9877,6 @@ class Call {
|
|
|
9875
9877
|
}, timeout);
|
|
9876
9878
|
});
|
|
9877
9879
|
};
|
|
9878
|
-
this.assertCallJoined = () => {
|
|
9879
|
-
return new Promise((resolve) => {
|
|
9880
|
-
this.state.callingState$
|
|
9881
|
-
.pipe(takeWhile((state) => state !== CallingState.JOINED, true))
|
|
9882
|
-
.subscribe(() => resolve());
|
|
9883
|
-
});
|
|
9884
|
-
};
|
|
9885
9880
|
/**
|
|
9886
9881
|
* Starts publishing the given video stream to the call.
|
|
9887
9882
|
* The stream will be stopped if the user changes an input device, or if the user leaves the call.
|
|
@@ -10112,6 +10107,13 @@ class Call {
|
|
|
10112
10107
|
var _h;
|
|
10113
10108
|
return (_h = this.publisher) === null || _h === void 0 ? void 0 : _h.updateVideoPublishQuality(enabledRids);
|
|
10114
10109
|
});
|
|
10110
|
+
this.assertCallJoined = () => {
|
|
10111
|
+
return new Promise((resolve) => {
|
|
10112
|
+
this.state.callingState$
|
|
10113
|
+
.pipe(takeWhile((state) => state !== CallingState.JOINED, true), filter((s) => s === CallingState.JOINED))
|
|
10114
|
+
.subscribe(() => resolve());
|
|
10115
|
+
});
|
|
10116
|
+
};
|
|
10115
10117
|
/**
|
|
10116
10118
|
* Sends a reaction to the other call participants.
|
|
10117
10119
|
*
|
|
@@ -10323,7 +10325,7 @@ class Call {
|
|
|
10323
10325
|
* @returns
|
|
10324
10326
|
*/
|
|
10325
10327
|
this.queryMembers = (request) => {
|
|
10326
|
-
return this.streamClient.post('/call/members', Object.assign(Object.assign({}, request), { id: this.id, type: this.type }));
|
|
10328
|
+
return this.streamClient.post('/call/members', Object.assign(Object.assign({}, (request || {})), { id: this.id, type: this.type }));
|
|
10327
10329
|
};
|
|
10328
10330
|
/**
|
|
10329
10331
|
* Will update the call members.
|
|
@@ -11634,7 +11636,7 @@ class WSConnectionFallback {
|
|
|
11634
11636
|
}
|
|
11635
11637
|
}
|
|
11636
11638
|
|
|
11637
|
-
const version = '0.1.
|
|
11639
|
+
const version = '0.1.6';
|
|
11638
11640
|
|
|
11639
11641
|
const logger = getLogger(['location']);
|
|
11640
11642
|
const HINT_URL = `https://hint.stream-io-video.com/`;
|
|
@@ -11697,14 +11699,6 @@ class StreamClient {
|
|
|
11697
11699
|
});
|
|
11698
11700
|
this._getConnectionID = () => { var _a, _b; return ((_a = this.wsConnection) === null || _a === void 0 ? void 0 : _a.connectionID) || ((_b = this.wsFallback) === null || _b === void 0 ? void 0 : _b.connectionID); };
|
|
11699
11701
|
this._hasConnectionID = () => Boolean(this._getConnectionID());
|
|
11700
|
-
/**
|
|
11701
|
-
* This will start a promise to hold API calls until `connectUser` is called, useful when user is set in `StreamVideoClient constructor`
|
|
11702
|
-
*/
|
|
11703
|
-
this.startWaitingForConnection = () => {
|
|
11704
|
-
this.waitForConnectPromise = new Promise((resolve) => {
|
|
11705
|
-
this.resolveConnectPromise = resolve;
|
|
11706
|
-
});
|
|
11707
|
-
};
|
|
11708
11702
|
/**
|
|
11709
11703
|
* connectUser - Set the current user and open a WebSocket connection
|
|
11710
11704
|
*
|
|
@@ -11739,11 +11733,6 @@ class StreamClient {
|
|
|
11739
11733
|
this._setUser(user);
|
|
11740
11734
|
const wsPromise = this.openConnection();
|
|
11741
11735
|
this.setUserPromise = Promise.all([setTokenPromise, wsPromise]).then((result) => result[1]);
|
|
11742
|
-
if (this.resolveConnectPromise) {
|
|
11743
|
-
this.resolveConnectPromise();
|
|
11744
|
-
this.waitForConnectPromise = undefined;
|
|
11745
|
-
this.resolveConnectPromise = undefined;
|
|
11746
|
-
}
|
|
11747
11736
|
try {
|
|
11748
11737
|
return yield this.setUserPromise;
|
|
11749
11738
|
}
|
|
@@ -11858,11 +11847,6 @@ class StreamClient {
|
|
|
11858
11847
|
});
|
|
11859
11848
|
this.anonymous = true;
|
|
11860
11849
|
yield this._setToken(user, tokenOrProvider, this.anonymous);
|
|
11861
|
-
if (this.resolveConnectPromise) {
|
|
11862
|
-
this.resolveConnectPromise();
|
|
11863
|
-
this.waitForConnectPromise = undefined;
|
|
11864
|
-
this.resolveConnectPromise = undefined;
|
|
11865
|
-
}
|
|
11866
11850
|
this._setUser(user);
|
|
11867
11851
|
// some endpoints require a connection_id to be resolved.
|
|
11868
11852
|
// as anonymous users aren't allowed to open WS connections, we just
|
|
@@ -11919,9 +11903,6 @@ class StreamClient {
|
|
|
11919
11903
|
this.logger('trace', `client:${type} - Response - url: ${url} > status ${response.status}`, {
|
|
11920
11904
|
response,
|
|
11921
11905
|
});
|
|
11922
|
-
this.logger('trace', `client:${type} - Response payload`, {
|
|
11923
|
-
response,
|
|
11924
|
-
});
|
|
11925
11906
|
};
|
|
11926
11907
|
this._logApiError = (type, url, error) => {
|
|
11927
11908
|
this.logger('error', `client:${type} - Error - url: ${url}`, {
|
|
@@ -11932,9 +11913,6 @@ class StreamClient {
|
|
|
11932
11913
|
this.doAxiosRequest = (type, url, data, options = {}) => __awaiter(this, void 0, void 0, function* () {
|
|
11933
11914
|
var _h;
|
|
11934
11915
|
if (!options.publicEndpoint) {
|
|
11935
|
-
if (this.waitForConnectPromise) {
|
|
11936
|
-
yield this.waitForConnectPromise;
|
|
11937
|
-
}
|
|
11938
11916
|
yield Promise.all([
|
|
11939
11917
|
this.tokenManager.tokenReady(),
|
|
11940
11918
|
this.connectionIdPromise,
|
|
@@ -11973,9 +11951,9 @@ class StreamClient {
|
|
|
11973
11951
|
}
|
|
11974
11952
|
catch (e /**TODO: generalize error types */) {
|
|
11975
11953
|
e.client_request_id = (_h = requestConfig.headers) === null || _h === void 0 ? void 0 : _h['x-client-request-id'];
|
|
11976
|
-
this._logApiError(type, url, e);
|
|
11977
11954
|
this.consecutiveFailures += 1;
|
|
11978
11955
|
if (e.response) {
|
|
11956
|
+
this._logApiError(type, url, e.response);
|
|
11979
11957
|
/** connection_fallback depends on this token expiration logic */
|
|
11980
11958
|
if (e.response.data.code === KnownCodes.TOKEN_EXPIRED &&
|
|
11981
11959
|
!this.tokenManager.isStatic()) {
|
|
@@ -11988,6 +11966,7 @@ class StreamClient {
|
|
|
11988
11966
|
return this.handleResponse(e.response);
|
|
11989
11967
|
}
|
|
11990
11968
|
else {
|
|
11969
|
+
this._logApiError(type, url, e);
|
|
11991
11970
|
// eslint-disable-next-line no-throw-literal
|
|
11992
11971
|
throw e;
|
|
11993
11972
|
}
|
|
@@ -12272,6 +12251,7 @@ class StreamClient {
|
|
|
12272
12251
|
class StreamVideoClient {
|
|
12273
12252
|
constructor(apiKeyOrArgs, opts) {
|
|
12274
12253
|
var _a, _b;
|
|
12254
|
+
this.logLevel = 'warn';
|
|
12275
12255
|
this.eventHandlersToUnregister = [];
|
|
12276
12256
|
/**
|
|
12277
12257
|
* Disconnects the currently connected user from the client.
|
|
@@ -12282,7 +12262,7 @@ class StreamVideoClient {
|
|
|
12282
12262
|
* https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent
|
|
12283
12263
|
*/
|
|
12284
12264
|
this.disconnectUser = (timeout) => __awaiter(this, void 0, void 0, function* () {
|
|
12285
|
-
if (!this.streamClient.user) {
|
|
12265
|
+
if (!this.streamClient.user && !this.connectionPromise) {
|
|
12286
12266
|
return;
|
|
12287
12267
|
}
|
|
12288
12268
|
const disconnectUser = () => this.streamClient.disconnectUser(timeout);
|
|
@@ -12343,7 +12323,7 @@ class StreamVideoClient {
|
|
|
12343
12323
|
*
|
|
12344
12324
|
* @param data the query data.
|
|
12345
12325
|
*/
|
|
12346
|
-
this.queryCalls = (data) => __awaiter(this, void 0, void 0, function* () {
|
|
12326
|
+
this.queryCalls = (data = {}) => __awaiter(this, void 0, void 0, function* () {
|
|
12347
12327
|
const response = yield this.streamClient.post('/calls', data);
|
|
12348
12328
|
const calls = response.calls.map((c) => {
|
|
12349
12329
|
const call = new Call({
|
|
@@ -12459,14 +12439,16 @@ class StreamVideoClient {
|
|
|
12459
12439
|
this.streamClient.setUserAgent(this.streamClient.getUserAgent() +
|
|
12460
12440
|
`-video-${SdkType[sdkInfo.type].toLowerCase()}-sdk-${sdkInfo.major}.${sdkInfo.minor}.${sdkInfo.patch}`);
|
|
12461
12441
|
}
|
|
12462
|
-
this.user = apiKeyOrArgs.user;
|
|
12463
|
-
this.token = apiKeyOrArgs.token || apiKeyOrArgs.tokenProvider;
|
|
12464
|
-
if (this.user) {
|
|
12465
|
-
this.streamClient.startWaitingForConnection();
|
|
12466
|
-
}
|
|
12467
12442
|
}
|
|
12468
12443
|
this.writeableStateStore = new StreamVideoWriteableStateStore();
|
|
12469
12444
|
this.readOnlyStateStore = new StreamVideoReadOnlyStateStore(this.writeableStateStore);
|
|
12445
|
+
if (typeof apiKeyOrArgs !== 'string') {
|
|
12446
|
+
const user = apiKeyOrArgs.user;
|
|
12447
|
+
const token = apiKeyOrArgs.token || apiKeyOrArgs.tokenProvider;
|
|
12448
|
+
if (user) {
|
|
12449
|
+
this.connectUser(user, token);
|
|
12450
|
+
}
|
|
12451
|
+
}
|
|
12470
12452
|
}
|
|
12471
12453
|
/**
|
|
12472
12454
|
* Connects the given user to the client.
|
|
@@ -12479,24 +12461,21 @@ class StreamVideoClient {
|
|
|
12479
12461
|
connectUser(user, token) {
|
|
12480
12462
|
var _a;
|
|
12481
12463
|
return __awaiter(this, void 0, void 0, function* () {
|
|
12482
|
-
|
|
12483
|
-
|
|
12484
|
-
|
|
12485
|
-
throw new Error('Connect user is called without user');
|
|
12486
|
-
}
|
|
12487
|
-
if (userToConnect.type === 'anonymous') {
|
|
12488
|
-
userToConnect.id = '!anon';
|
|
12489
|
-
return this.connectAnonymousUser(userToConnect, tokenToUse);
|
|
12490
|
-
}
|
|
12491
|
-
if (userToConnect.type === 'guest') {
|
|
12492
|
-
const response = yield this.createGuestUser({
|
|
12493
|
-
user: Object.assign(Object.assign({}, userToConnect), { role: 'guest' }),
|
|
12494
|
-
});
|
|
12495
|
-
return this.connectUser(response.user, response.access_token);
|
|
12464
|
+
if (user.type === 'anonymous') {
|
|
12465
|
+
user.id = '!anon';
|
|
12466
|
+
return this.connectAnonymousUser(user, token);
|
|
12496
12467
|
}
|
|
12497
|
-
|
|
12498
|
-
return this.streamClient.connectUser(
|
|
12468
|
+
let connectUser = () => {
|
|
12469
|
+
return this.streamClient.connectUser(user, token);
|
|
12499
12470
|
};
|
|
12471
|
+
if (user.type === 'guest') {
|
|
12472
|
+
connectUser = () => __awaiter(this, void 0, void 0, function* () {
|
|
12473
|
+
const response = yield this.createGuestUser({
|
|
12474
|
+
user: Object.assign(Object.assign({}, user), { role: 'guest' }),
|
|
12475
|
+
});
|
|
12476
|
+
return this.streamClient.connectUser(response.user, response.access_token);
|
|
12477
|
+
});
|
|
12478
|
+
}
|
|
12500
12479
|
this.connectionPromise = this.disconnectionPromise
|
|
12501
12480
|
? this.disconnectionPromise.then(() => connectUser())
|
|
12502
12481
|
: connectUser();
|
|
@@ -12530,7 +12509,7 @@ class StreamVideoClient {
|
|
|
12530
12509
|
if (event.type !== 'call.created')
|
|
12531
12510
|
return;
|
|
12532
12511
|
const { call, members } = event;
|
|
12533
|
-
if (
|
|
12512
|
+
if (user.id === call.created_by.id) {
|
|
12534
12513
|
this.logger('warn', 'Received `call.created` sent by the current user');
|
|
12535
12514
|
return;
|
|
12536
12515
|
}
|
|
@@ -12548,7 +12527,7 @@ class StreamVideoClient {
|
|
|
12548
12527
|
if (event.type !== 'call.ring')
|
|
12549
12528
|
return;
|
|
12550
12529
|
const { call, members } = event;
|
|
12551
|
-
if (
|
|
12530
|
+
if (user.id === call.created_by.id) {
|
|
12552
12531
|
this.logger('debug', 'Received `call.ring` sent by the current user so ignoring the event');
|
|
12553
12532
|
return;
|
|
12554
12533
|
}
|