@whereby.com/core 1.1.5 → 1.1.7
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/dist/index.cjs +1 -1
- package/dist/index.mjs +1 -1
- package/dist/legacy-esm.js +1 -1
- package/dist/redux/index.cjs +726 -3
- package/dist/redux/index.d.cts +1 -1
- package/dist/redux/index.d.mts +1 -1
- package/dist/redux/index.d.ts +1 -1
- package/dist/redux/index.js +725 -3
- package/dist/redux/index.mjs +725 -3
- package/package.json +3 -3
package/dist/redux/index.mjs
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { createAsyncThunk, createListenerMiddleware, addListener, createSlice, createAction, createSelector, isAnyOf, combineReducers, configureStore } from '@reduxjs/toolkit';
|
|
2
|
-
import { ServerSocket, getDeviceData, getStream, getUpdatedDevices, RtcManagerDispatcher, setClientProvider, subscribeIssues } from '@whereby.com/media';
|
|
2
|
+
import { ServerSocket, getDeviceData, getStream, getUpdatedDevices, RtcManagerDispatcher, setClientProvider, subscribeIssues, assert, fromLocation } from '@whereby.com/media';
|
|
3
3
|
import { EventEmitter } from 'events';
|
|
4
|
+
import nodeBtoa from 'btoa';
|
|
5
|
+
import axios from 'axios';
|
|
4
6
|
|
|
5
7
|
function createAppAsyncThunk(typePrefix, payloadCreator) {
|
|
6
8
|
return createAsyncThunk(typePrefix, payloadCreator);
|
|
@@ -71,7 +73,7 @@ const createReactor = (selectors, callback) => {
|
|
|
71
73
|
});
|
|
72
74
|
};
|
|
73
75
|
|
|
74
|
-
const coreVersion = "1.1.
|
|
76
|
+
const coreVersion = "1.1.7";
|
|
75
77
|
|
|
76
78
|
const initialState = {
|
|
77
79
|
isNodeSdk: false,
|
|
@@ -3017,4 +3019,724 @@ const observeStore = (store, select, onChange) => {
|
|
|
3017
3019
|
return unsubscribe;
|
|
3018
3020
|
};
|
|
3019
3021
|
|
|
3020
|
-
|
|
3022
|
+
class Response {
|
|
3023
|
+
constructor(initialValues = {}) {
|
|
3024
|
+
this.data = initialValues.data === undefined ? {} : initialValues.data;
|
|
3025
|
+
this.headers = initialValues.headers || {};
|
|
3026
|
+
this.status = initialValues.status || 200;
|
|
3027
|
+
this.statusText = initialValues.statusText || "OK";
|
|
3028
|
+
this.url = initialValues.url || null;
|
|
3029
|
+
}
|
|
3030
|
+
}
|
|
3031
|
+
|
|
3032
|
+
function assertTruthy(value, parameterName) {
|
|
3033
|
+
assert.ok(value, `${parameterName} is required`);
|
|
3034
|
+
return value;
|
|
3035
|
+
}
|
|
3036
|
+
function assertBoolean(value, parameterName) {
|
|
3037
|
+
assert.ok(typeof value === "boolean", `${parameterName}<boolean> is required`);
|
|
3038
|
+
return value;
|
|
3039
|
+
}
|
|
3040
|
+
function assertNumber(value, parameterName) {
|
|
3041
|
+
assert.ok(typeof value === "number", `${parameterName}<number> is required`);
|
|
3042
|
+
return value;
|
|
3043
|
+
}
|
|
3044
|
+
function assertString(value, parameterName) {
|
|
3045
|
+
assert.ok(typeof value === "string", `${parameterName}<string> is required`);
|
|
3046
|
+
return value;
|
|
3047
|
+
}
|
|
3048
|
+
function assertInstanceOf(value, type, parameterName) {
|
|
3049
|
+
const resolvedParameterName = parameterName || type.name[0].toLowerCase() + type.name.substring(1);
|
|
3050
|
+
assert.ok(value instanceof type, `${resolvedParameterName}<${type.name}> is required`);
|
|
3051
|
+
return value;
|
|
3052
|
+
}
|
|
3053
|
+
function assertArray(array, parameterName) {
|
|
3054
|
+
assert.ok(Array.isArray(array), `${parameterName}<array> is required`);
|
|
3055
|
+
return array;
|
|
3056
|
+
}
|
|
3057
|
+
function assertRecord(ref, name) {
|
|
3058
|
+
if (ref === null || ref === undefined || typeof ref !== "object" || Array.isArray(ref)) {
|
|
3059
|
+
throw new Error(`${name} must be a record. ${JSON.stringify(ref)}`);
|
|
3060
|
+
}
|
|
3061
|
+
return ref;
|
|
3062
|
+
}
|
|
3063
|
+
function assertNullOrType(ref, type, name, message) {
|
|
3064
|
+
assertString(name, "name");
|
|
3065
|
+
const errorMessage = `${name} must be null or of type ${type}`;
|
|
3066
|
+
assert.ok(ref === null || typeof ref === type, errorMessage);
|
|
3067
|
+
}
|
|
3068
|
+
function assertNullOrString(ref, name, message) {
|
|
3069
|
+
assertString(name, "name");
|
|
3070
|
+
assertNullOrType(ref, "string", name);
|
|
3071
|
+
}
|
|
3072
|
+
|
|
3073
|
+
function _getAbsoluteUrl({ baseUrl, url }) {
|
|
3074
|
+
return baseUrl ? baseUrl + url : url;
|
|
3075
|
+
}
|
|
3076
|
+
class HttpClient {
|
|
3077
|
+
constructor({ baseUrl }) {
|
|
3078
|
+
assertString(baseUrl, "baseUrl");
|
|
3079
|
+
this._baseUrl = baseUrl;
|
|
3080
|
+
}
|
|
3081
|
+
_requestAxios(url, options) {
|
|
3082
|
+
const axiosOptions = Object.assign({}, options, {
|
|
3083
|
+
url,
|
|
3084
|
+
baseURL: this._baseUrl,
|
|
3085
|
+
});
|
|
3086
|
+
return axios.request(axiosOptions);
|
|
3087
|
+
}
|
|
3088
|
+
request(url, options) {
|
|
3089
|
+
assertString(url, "url");
|
|
3090
|
+
assert.ok(url[0] === "/", 'url<String> only accepts relative URLs beginning with "/".');
|
|
3091
|
+
assert.ok(options, "options are required");
|
|
3092
|
+
return this._requestAxios(url, options)
|
|
3093
|
+
.then((response) => {
|
|
3094
|
+
const { data, headers, status, statusText, config } = response;
|
|
3095
|
+
const requestUrl = config && config.url ? _getAbsoluteUrl({ baseUrl: config.baseURL, url: config.url }) : null;
|
|
3096
|
+
return new Response({
|
|
3097
|
+
data,
|
|
3098
|
+
headers,
|
|
3099
|
+
status,
|
|
3100
|
+
statusText,
|
|
3101
|
+
url: requestUrl,
|
|
3102
|
+
});
|
|
3103
|
+
})
|
|
3104
|
+
.catch((error) => {
|
|
3105
|
+
const responseObject = error.response;
|
|
3106
|
+
if (!responseObject) {
|
|
3107
|
+
throw new Error("Could not make the request.");
|
|
3108
|
+
}
|
|
3109
|
+
const { data, headers, status, statusText, config } = responseObject;
|
|
3110
|
+
const requestUrl = config && config.url ? _getAbsoluteUrl({ baseUrl: config.baseURL, url: config.url }) : null;
|
|
3111
|
+
return Promise.reject(new Response({
|
|
3112
|
+
data,
|
|
3113
|
+
headers,
|
|
3114
|
+
status,
|
|
3115
|
+
statusText,
|
|
3116
|
+
url: requestUrl,
|
|
3117
|
+
}));
|
|
3118
|
+
});
|
|
3119
|
+
}
|
|
3120
|
+
}
|
|
3121
|
+
|
|
3122
|
+
class MultipartHttpClient {
|
|
3123
|
+
constructor({ httpClient }) {
|
|
3124
|
+
assert.ok(httpClient, "httpClient is required");
|
|
3125
|
+
this._httpClient = httpClient;
|
|
3126
|
+
}
|
|
3127
|
+
static dataToFormData(data) {
|
|
3128
|
+
assert.ok(data, "data is required");
|
|
3129
|
+
const fd = new FormData();
|
|
3130
|
+
Object.keys(data).forEach((key) => {
|
|
3131
|
+
const value = data[key];
|
|
3132
|
+
fd.append(key, value);
|
|
3133
|
+
});
|
|
3134
|
+
return fd;
|
|
3135
|
+
}
|
|
3136
|
+
request(url, options = {}) {
|
|
3137
|
+
const headers = Object.assign(options.headers || {}, {
|
|
3138
|
+
"Content-Type": undefined,
|
|
3139
|
+
});
|
|
3140
|
+
return this._httpClient.request(url, Object.assign(options, {
|
|
3141
|
+
headers,
|
|
3142
|
+
transformRequest: MultipartHttpClient.dataToFormData,
|
|
3143
|
+
}));
|
|
3144
|
+
}
|
|
3145
|
+
}
|
|
3146
|
+
|
|
3147
|
+
let btoa;
|
|
3148
|
+
if (typeof window === "object") {
|
|
3149
|
+
btoa = window.btoa || nodeBtoa;
|
|
3150
|
+
}
|
|
3151
|
+
else if (typeof global === "object") {
|
|
3152
|
+
btoa = global.btoa || nodeBtoa;
|
|
3153
|
+
}
|
|
3154
|
+
else {
|
|
3155
|
+
btoa = nodeBtoa;
|
|
3156
|
+
}
|
|
3157
|
+
function _getAuthHeader(credentials) {
|
|
3158
|
+
if (credentials && credentials.credentials) {
|
|
3159
|
+
const btoaStr = `${credentials.credentials.uuid}:${credentials.hmac}`;
|
|
3160
|
+
return { Authorization: `Basic ${btoa(btoaStr)}` };
|
|
3161
|
+
}
|
|
3162
|
+
return {};
|
|
3163
|
+
}
|
|
3164
|
+
const noCredentials = () => Promise.resolve(null);
|
|
3165
|
+
class AuthenticatedHttpClient {
|
|
3166
|
+
constructor({ httpClient, fetchDeviceCredentials }) {
|
|
3167
|
+
this._httpClient = httpClient;
|
|
3168
|
+
this._fetchDeviceCredentials = fetchDeviceCredentials;
|
|
3169
|
+
}
|
|
3170
|
+
request(url, options) {
|
|
3171
|
+
return this._fetchDeviceCredentials().then((credentials) => {
|
|
3172
|
+
const headers = Object.assign({}, options.headers, _getAuthHeader(credentials), {
|
|
3173
|
+
"X-Appearin-Device-Platform": "web",
|
|
3174
|
+
});
|
|
3175
|
+
const httpClientOptions = Object.assign({}, options, { headers });
|
|
3176
|
+
return this._httpClient.request(url, httpClientOptions);
|
|
3177
|
+
});
|
|
3178
|
+
}
|
|
3179
|
+
}
|
|
3180
|
+
class ApiClient {
|
|
3181
|
+
constructor({ baseUrl = "https://api.appearin.net", fetchDeviceCredentials = noCredentials, } = {}) {
|
|
3182
|
+
this.authenticatedHttpClient = new AuthenticatedHttpClient({
|
|
3183
|
+
httpClient: new HttpClient({
|
|
3184
|
+
baseUrl,
|
|
3185
|
+
}),
|
|
3186
|
+
fetchDeviceCredentials,
|
|
3187
|
+
});
|
|
3188
|
+
this.authenticatedFormDataHttpClient = new MultipartHttpClient({ httpClient: this.authenticatedHttpClient });
|
|
3189
|
+
}
|
|
3190
|
+
request(url, options) {
|
|
3191
|
+
assertString(url, "url");
|
|
3192
|
+
assert.ok(url[0] === "/", 'url<String> only accepts relative URLs beginning with "/".');
|
|
3193
|
+
assert.ok(options, "options are required");
|
|
3194
|
+
return this.authenticatedHttpClient.request(url, options);
|
|
3195
|
+
}
|
|
3196
|
+
requestMultipart(url, options) {
|
|
3197
|
+
assertString(url, "url");
|
|
3198
|
+
assert.ok(url[0] === "/", 'url<String> only accepts relative URLs beginning with "/".');
|
|
3199
|
+
assert.ok(options, "options are required");
|
|
3200
|
+
return this.authenticatedFormDataHttpClient.request(url, options);
|
|
3201
|
+
}
|
|
3202
|
+
}
|
|
3203
|
+
|
|
3204
|
+
function nullOrExtract(extract) {
|
|
3205
|
+
return (data, propertyName) => {
|
|
3206
|
+
const record = assertRecord(data, "data");
|
|
3207
|
+
const value = record[propertyName];
|
|
3208
|
+
return value === null || value === undefined ? null : extract(data, propertyName);
|
|
3209
|
+
};
|
|
3210
|
+
}
|
|
3211
|
+
function extractString(data, propertyName) {
|
|
3212
|
+
const record = assertRecord(data, "data");
|
|
3213
|
+
return assertString(record[propertyName], propertyName);
|
|
3214
|
+
}
|
|
3215
|
+
const extractNullOrString = nullOrExtract(extractString);
|
|
3216
|
+
function extractArrayOfJson(data, propertyName) {
|
|
3217
|
+
const record = assertRecord(data, "data");
|
|
3218
|
+
return assertArray(record[propertyName], propertyName);
|
|
3219
|
+
}
|
|
3220
|
+
function extractArray(data, propertyName, transformer) {
|
|
3221
|
+
return extractArrayOfJson(data, propertyName).map((value) => transformer(value));
|
|
3222
|
+
}
|
|
3223
|
+
function extractJson(data, propertyName) {
|
|
3224
|
+
const record = assertRecord(data, "data");
|
|
3225
|
+
const value = record[propertyName];
|
|
3226
|
+
return value === undefined ? null : value;
|
|
3227
|
+
}
|
|
3228
|
+
|
|
3229
|
+
class Credentials {
|
|
3230
|
+
constructor(uuid, hmac, userId = undefined) {
|
|
3231
|
+
this.credentials = {
|
|
3232
|
+
uuid,
|
|
3233
|
+
};
|
|
3234
|
+
this.hmac = hmac;
|
|
3235
|
+
this.userId = userId;
|
|
3236
|
+
}
|
|
3237
|
+
toJson() {
|
|
3238
|
+
return Object.assign({ credentials: this.credentials, hmac: this.hmac }, (this.userId && { userId: this.userId }));
|
|
3239
|
+
}
|
|
3240
|
+
static fromJson(json) {
|
|
3241
|
+
return new Credentials(extractString(extractJson(json, "credentials"), "uuid"), extractString(json, "hmac"), extractNullOrString(json, "userId") || undefined);
|
|
3242
|
+
}
|
|
3243
|
+
}
|
|
3244
|
+
|
|
3245
|
+
class DeviceService {
|
|
3246
|
+
constructor({ apiClient }) {
|
|
3247
|
+
this._apiClient = apiClient;
|
|
3248
|
+
}
|
|
3249
|
+
getCredentials() {
|
|
3250
|
+
return this._apiClient
|
|
3251
|
+
.request("/devices", {
|
|
3252
|
+
method: "post",
|
|
3253
|
+
})
|
|
3254
|
+
.then(({ data }) => {
|
|
3255
|
+
return Credentials.fromJson(data);
|
|
3256
|
+
})
|
|
3257
|
+
.catch((error) => {
|
|
3258
|
+
if (error.response) {
|
|
3259
|
+
if (error.response.status === 404) {
|
|
3260
|
+
return null;
|
|
3261
|
+
}
|
|
3262
|
+
}
|
|
3263
|
+
throw error;
|
|
3264
|
+
});
|
|
3265
|
+
}
|
|
3266
|
+
}
|
|
3267
|
+
|
|
3268
|
+
class ChromeStorageStore {
|
|
3269
|
+
constructor(key, chromeStorage) {
|
|
3270
|
+
this._key = key;
|
|
3271
|
+
this._chromeStorage = chromeStorage;
|
|
3272
|
+
}
|
|
3273
|
+
loadOrDefault(defaultValue) {
|
|
3274
|
+
return new Promise((resolve) => {
|
|
3275
|
+
this._chromeStorage.get(this._key, (result) => {
|
|
3276
|
+
const unknownResult = result;
|
|
3277
|
+
resolve(unknownResult[this._key] || defaultValue);
|
|
3278
|
+
});
|
|
3279
|
+
});
|
|
3280
|
+
}
|
|
3281
|
+
save(value) {
|
|
3282
|
+
return new Promise((resolve) => {
|
|
3283
|
+
this._chromeStorage.set({ [this._key]: value }, () => {
|
|
3284
|
+
resolve();
|
|
3285
|
+
});
|
|
3286
|
+
});
|
|
3287
|
+
}
|
|
3288
|
+
}
|
|
3289
|
+
|
|
3290
|
+
class LocalStorageStore {
|
|
3291
|
+
constructor(key, localStorage) {
|
|
3292
|
+
assertTruthy(localStorage, "localStorage");
|
|
3293
|
+
this._key = assertString(key, "key");
|
|
3294
|
+
this._localStorage = localStorage;
|
|
3295
|
+
}
|
|
3296
|
+
loadOrDefault(defaultValue) {
|
|
3297
|
+
try {
|
|
3298
|
+
const value = this._localStorage.getItem(this._key);
|
|
3299
|
+
if (value) {
|
|
3300
|
+
try {
|
|
3301
|
+
return Promise.resolve(JSON.parse(value));
|
|
3302
|
+
}
|
|
3303
|
+
catch (_a) {
|
|
3304
|
+
}
|
|
3305
|
+
}
|
|
3306
|
+
return Promise.resolve(defaultValue);
|
|
3307
|
+
}
|
|
3308
|
+
catch (e) {
|
|
3309
|
+
console.warn("Error getting access to storage. Are cookies blocked?", e);
|
|
3310
|
+
return Promise.resolve(defaultValue);
|
|
3311
|
+
}
|
|
3312
|
+
}
|
|
3313
|
+
save(value) {
|
|
3314
|
+
try {
|
|
3315
|
+
this._localStorage.setItem(this._key, JSON.stringify(value));
|
|
3316
|
+
return Promise.resolve();
|
|
3317
|
+
}
|
|
3318
|
+
catch (e) {
|
|
3319
|
+
console.warn("Error getting access to storage. Are cookies blocked?", e);
|
|
3320
|
+
return Promise.reject(e);
|
|
3321
|
+
}
|
|
3322
|
+
}
|
|
3323
|
+
}
|
|
3324
|
+
|
|
3325
|
+
let localStorage;
|
|
3326
|
+
try {
|
|
3327
|
+
localStorage = self.localStorage;
|
|
3328
|
+
}
|
|
3329
|
+
catch (_a) {
|
|
3330
|
+
localStorage = {
|
|
3331
|
+
getItem: () => undefined,
|
|
3332
|
+
key: () => undefined,
|
|
3333
|
+
setItem: () => undefined,
|
|
3334
|
+
removeItem: () => undefined,
|
|
3335
|
+
hasOwnProperty: () => undefined,
|
|
3336
|
+
length: 0,
|
|
3337
|
+
};
|
|
3338
|
+
}
|
|
3339
|
+
var localStorage$1 = localStorage;
|
|
3340
|
+
|
|
3341
|
+
const events = {
|
|
3342
|
+
CREDENTIALS_SAVED: "credentials_saved",
|
|
3343
|
+
};
|
|
3344
|
+
class CredentialsService extends EventEmitter {
|
|
3345
|
+
constructor({ deviceService, credentialsStore, }) {
|
|
3346
|
+
super();
|
|
3347
|
+
this._deviceService = deviceService;
|
|
3348
|
+
this._credentialsStore = credentialsStore;
|
|
3349
|
+
}
|
|
3350
|
+
static create({ baseUrl, storeName = "CredentialsStorage", storeType = "localStorage", }) {
|
|
3351
|
+
const deviceService = new DeviceService({
|
|
3352
|
+
apiClient: new ApiClient({ baseUrl }),
|
|
3353
|
+
});
|
|
3354
|
+
let credentialsStore = null;
|
|
3355
|
+
if (storeType === "localStorage") {
|
|
3356
|
+
credentialsStore = new LocalStorageStore(storeName, localStorage$1);
|
|
3357
|
+
}
|
|
3358
|
+
else if (storeType === "chromeStorage") {
|
|
3359
|
+
credentialsStore = new ChromeStorageStore(storeName, window["chrome"].storage.local);
|
|
3360
|
+
}
|
|
3361
|
+
else {
|
|
3362
|
+
throw new Error(`Unknown store type: ${storeType}`);
|
|
3363
|
+
}
|
|
3364
|
+
return new CredentialsService({
|
|
3365
|
+
deviceService,
|
|
3366
|
+
credentialsStore,
|
|
3367
|
+
});
|
|
3368
|
+
}
|
|
3369
|
+
_fetchNewCredentialsFromApi() {
|
|
3370
|
+
const credentialsStore = this._credentialsStore;
|
|
3371
|
+
return new Promise((resolve) => {
|
|
3372
|
+
const fetchCredentials = () => {
|
|
3373
|
+
this._deviceService
|
|
3374
|
+
.getCredentials()
|
|
3375
|
+
.then((credentials) => {
|
|
3376
|
+
return credentialsStore
|
|
3377
|
+
.save(credentials ? credentials.toJson() : null)
|
|
3378
|
+
.then(() => resolve(credentials));
|
|
3379
|
+
})
|
|
3380
|
+
.catch(() => {
|
|
3381
|
+
setTimeout(fetchCredentials, 2000);
|
|
3382
|
+
});
|
|
3383
|
+
};
|
|
3384
|
+
fetchCredentials();
|
|
3385
|
+
});
|
|
3386
|
+
}
|
|
3387
|
+
getCurrentCredentials() {
|
|
3388
|
+
return this._credentialsStore.loadOrDefault(null).then((json) => (json ? Credentials.fromJson(json) : null));
|
|
3389
|
+
}
|
|
3390
|
+
getCredentials() {
|
|
3391
|
+
if (!this.credentialsPromise) {
|
|
3392
|
+
this.credentialsPromise = this.getCurrentCredentials().then((storedCredentials) => {
|
|
3393
|
+
if (storedCredentials) {
|
|
3394
|
+
return storedCredentials;
|
|
3395
|
+
}
|
|
3396
|
+
return this._fetchNewCredentialsFromApi();
|
|
3397
|
+
});
|
|
3398
|
+
}
|
|
3399
|
+
return this.credentialsPromise;
|
|
3400
|
+
}
|
|
3401
|
+
saveCredentials(credentials) {
|
|
3402
|
+
this.credentialsPromise = undefined;
|
|
3403
|
+
return this._credentialsStore.save(credentials.toJson()).then(() => {
|
|
3404
|
+
this.emit(events.CREDENTIALS_SAVED, credentials);
|
|
3405
|
+
return credentials;
|
|
3406
|
+
});
|
|
3407
|
+
}
|
|
3408
|
+
setUserId(userId) {
|
|
3409
|
+
return this.getCurrentCredentials()
|
|
3410
|
+
.then((storedCredentials) => {
|
|
3411
|
+
if (!storedCredentials) {
|
|
3412
|
+
console.error("Illegal state: no credentials to set user id for.");
|
|
3413
|
+
}
|
|
3414
|
+
const userIdChangedFromLocalStorage = storedCredentials === null || storedCredentials.userId !== userId;
|
|
3415
|
+
if (!userIdChangedFromLocalStorage) {
|
|
3416
|
+
return undefined;
|
|
3417
|
+
}
|
|
3418
|
+
return this._credentialsStore.save(Object.assign({}, storedCredentials === null || storedCredentials === void 0 ? void 0 : storedCredentials.toJson(), { userId }));
|
|
3419
|
+
})
|
|
3420
|
+
.then(() => undefined);
|
|
3421
|
+
}
|
|
3422
|
+
}
|
|
3423
|
+
|
|
3424
|
+
class EmbeddedFreeTierStatus {
|
|
3425
|
+
constructor({ isExhausted, renewsAt, totalMinutesLimit, totalMinutesUsed, }) {
|
|
3426
|
+
this.isExhausted = isExhausted;
|
|
3427
|
+
this.renewsAt = renewsAt;
|
|
3428
|
+
this.totalMinutesLimit = totalMinutesLimit;
|
|
3429
|
+
this.totalMinutesUsed = totalMinutesUsed;
|
|
3430
|
+
}
|
|
3431
|
+
static fromJson(data) {
|
|
3432
|
+
return new EmbeddedFreeTierStatus({
|
|
3433
|
+
isExhausted: assertBoolean(data.isExhausted, "isExhausted"),
|
|
3434
|
+
renewsAt: new Date(assertString(data.renewsAt, "renewsAt")),
|
|
3435
|
+
totalMinutesLimit: assertNumber(data.totalMinutesLimit, "totalMinutesLimit"),
|
|
3436
|
+
totalMinutesUsed: assertNumber(data.totalMinutesUsed, "totalMinutesUsed"),
|
|
3437
|
+
});
|
|
3438
|
+
}
|
|
3439
|
+
}
|
|
3440
|
+
|
|
3441
|
+
class Account {
|
|
3442
|
+
constructor({ basePlanId, embeddedFreeTierStatus, isDeactivated, isOnTrial, onTrialUntil, trialStatus, }) {
|
|
3443
|
+
this.basePlanId = basePlanId;
|
|
3444
|
+
this.isDeactivated = isDeactivated;
|
|
3445
|
+
this.isOnTrial = isOnTrial;
|
|
3446
|
+
this.onTrialUntil = onTrialUntil || null;
|
|
3447
|
+
this.trialStatus = trialStatus || null;
|
|
3448
|
+
this.embeddedFreeTierStatus = embeddedFreeTierStatus || null;
|
|
3449
|
+
}
|
|
3450
|
+
static fromJson(data) {
|
|
3451
|
+
return new Account({
|
|
3452
|
+
basePlanId: typeof data.basePlanId === "string" ? data.basePlanId : null,
|
|
3453
|
+
isDeactivated: assertBoolean(data.isDeactivated, "isDeactivated"),
|
|
3454
|
+
isOnTrial: assertBoolean(data.isOnTrial, "isOnTrial"),
|
|
3455
|
+
onTrialUntil: typeof data.onTrialUntil === "string" ? new Date(data.onTrialUntil) : null,
|
|
3456
|
+
trialStatus: typeof data.trialStatus === "string" ? data.trialStatus : null,
|
|
3457
|
+
embeddedFreeTierStatus: data.embeddedFreeTierStatus
|
|
3458
|
+
? EmbeddedFreeTierStatus.fromJson(data.embeddedFreeTierStatus)
|
|
3459
|
+
: null,
|
|
3460
|
+
});
|
|
3461
|
+
}
|
|
3462
|
+
}
|
|
3463
|
+
|
|
3464
|
+
function hasValue(value) {
|
|
3465
|
+
return value !== null && value !== undefined;
|
|
3466
|
+
}
|
|
3467
|
+
function createOrganizationLimits(limits = {}) {
|
|
3468
|
+
return {
|
|
3469
|
+
maxNumberOfInvitationsAndUsers: hasValue(limits === null || limits === void 0 ? void 0 : limits.maxNumberOfInvitationsAndUsers)
|
|
3470
|
+
? Number(limits === null || limits === void 0 ? void 0 : limits.maxNumberOfInvitationsAndUsers)
|
|
3471
|
+
: null,
|
|
3472
|
+
maxNumberOfClaimedRooms: hasValue(limits === null || limits === void 0 ? void 0 : limits.maxNumberOfClaimedRooms)
|
|
3473
|
+
? Number(limits === null || limits === void 0 ? void 0 : limits.maxNumberOfClaimedRooms)
|
|
3474
|
+
: null,
|
|
3475
|
+
maxRoomLimitPerOrganization: hasValue(limits === null || limits === void 0 ? void 0 : limits.maxRoomLimitPerOrganization)
|
|
3476
|
+
? Number(limits === null || limits === void 0 ? void 0 : limits.maxRoomLimitPerOrganization)
|
|
3477
|
+
: null,
|
|
3478
|
+
trialMinutesLimit: hasValue(limits === null || limits === void 0 ? void 0 : limits.trialMinutesLimit) ? Number(limits === null || limits === void 0 ? void 0 : limits.trialMinutesLimit) : null,
|
|
3479
|
+
includedUnits: hasValue(limits === null || limits === void 0 ? void 0 : limits.includedUnits) ? Number(limits === null || limits === void 0 ? void 0 : limits.includedUnits) : null,
|
|
3480
|
+
};
|
|
3481
|
+
}
|
|
3482
|
+
class Organization {
|
|
3483
|
+
constructor(properties) {
|
|
3484
|
+
this.logoImageUrl = null;
|
|
3485
|
+
this.roomBackgroundImageUrl = null;
|
|
3486
|
+
this.roomBackgroundThumbnailUrl = null;
|
|
3487
|
+
this.roomKnockPageBackgroundImageUrl = null;
|
|
3488
|
+
this.roomKnockPageBackgroundThumbnailUrl = null;
|
|
3489
|
+
this.preferences = null;
|
|
3490
|
+
this.onboardingSurvey = null;
|
|
3491
|
+
this.type = null;
|
|
3492
|
+
assertInstanceOf(properties, Object, "properties");
|
|
3493
|
+
assertString(properties.organizationId, "organizationId");
|
|
3494
|
+
assertString(properties.organizationName, "organizationName");
|
|
3495
|
+
assertString(properties.subdomain, "subdomain");
|
|
3496
|
+
assertInstanceOf(properties.permissions, Object, "permissions");
|
|
3497
|
+
assertInstanceOf(properties.limits, Object, "limits");
|
|
3498
|
+
this.organizationId = properties.organizationId;
|
|
3499
|
+
this.organizationName = properties.organizationName;
|
|
3500
|
+
this.subdomain = properties.subdomain;
|
|
3501
|
+
this.permissions = properties.permissions;
|
|
3502
|
+
this.limits = properties.limits;
|
|
3503
|
+
this.account = properties.account ? new Account(properties.account) : null;
|
|
3504
|
+
this.logoImageUrl = properties.logoImageUrl;
|
|
3505
|
+
this.roomBackgroundImageUrl = properties.roomBackgroundImageUrl;
|
|
3506
|
+
this.roomBackgroundThumbnailUrl = properties.roomBackgroundThumbnailUrl;
|
|
3507
|
+
this.roomKnockPageBackgroundImageUrl = properties.roomKnockPageBackgroundImageUrl;
|
|
3508
|
+
this.roomKnockPageBackgroundThumbnailUrl = properties.roomKnockPageBackgroundThumbnailUrl;
|
|
3509
|
+
this.preferences = properties.preferences;
|
|
3510
|
+
this.onboardingSurvey = properties.onboardingSurvey;
|
|
3511
|
+
this.type = properties.type;
|
|
3512
|
+
}
|
|
3513
|
+
static fromJson(data) {
|
|
3514
|
+
const parsedData = assertInstanceOf(data, Object, "data");
|
|
3515
|
+
const preferences = ((parsedData === null || parsedData === void 0 ? void 0 : parsedData.preferences) || {});
|
|
3516
|
+
const onboardingSurvey = ((parsedData === null || parsedData === void 0 ? void 0 : parsedData.onboardingSurvey) || null);
|
|
3517
|
+
const permissions = assertInstanceOf(parsedData.permissions, Object, "permissions");
|
|
3518
|
+
return new Organization({
|
|
3519
|
+
organizationId: assertString(parsedData.organizationId, "organizationId"),
|
|
3520
|
+
organizationName: assertString(parsedData.organizationName, "organizationName"),
|
|
3521
|
+
subdomain: assertString(parsedData.subdomain, "subdomain"),
|
|
3522
|
+
permissions,
|
|
3523
|
+
limits: createOrganizationLimits(assertInstanceOf(parsedData.limits, Object, "limits")),
|
|
3524
|
+
account: parsedData.account ? Account.fromJson(parsedData.account) : null,
|
|
3525
|
+
logoImageUrl: typeof parsedData.logoImageUrl === "string" ? parsedData.logoImageUrl : null,
|
|
3526
|
+
roomBackgroundImageUrl: typeof parsedData.roomBackgroundImageUrl === "string" ? parsedData.roomBackgroundImageUrl : null,
|
|
3527
|
+
roomBackgroundThumbnailUrl: typeof parsedData.roomBackgroundThumbnailUrl === "string"
|
|
3528
|
+
? parsedData.roomBackgroundThumbnailUrl
|
|
3529
|
+
: null,
|
|
3530
|
+
roomKnockPageBackgroundImageUrl: typeof parsedData.roomKnockPageBackgroundImageUrl === "string"
|
|
3531
|
+
? parsedData.roomKnockPageBackgroundImageUrl
|
|
3532
|
+
: null,
|
|
3533
|
+
roomKnockPageBackgroundThumbnailUrl: typeof parsedData.roomKnockPageBackgroundThumbnailUrl === "string"
|
|
3534
|
+
? parsedData.roomKnockPageBackgroundThumbnailUrl
|
|
3535
|
+
: null,
|
|
3536
|
+
preferences,
|
|
3537
|
+
onboardingSurvey,
|
|
3538
|
+
type: typeof parsedData.type === "string" ? parsedData.type : null,
|
|
3539
|
+
});
|
|
3540
|
+
}
|
|
3541
|
+
}
|
|
3542
|
+
Organization.GLOBAL_ORGANIZATION_ID = "1";
|
|
3543
|
+
|
|
3544
|
+
class OrganizationService {
|
|
3545
|
+
constructor({ apiClient }) {
|
|
3546
|
+
this._apiClient = apiClient;
|
|
3547
|
+
}
|
|
3548
|
+
createOrganization({ organizationName, subdomain, owner, }) {
|
|
3549
|
+
const { displayName, consents } = owner || {};
|
|
3550
|
+
const email = "email" in owner
|
|
3551
|
+
? {
|
|
3552
|
+
value: owner.email,
|
|
3553
|
+
verificationCode: assertString(owner.verificationCode, "owner.verificationCode"),
|
|
3554
|
+
}
|
|
3555
|
+
: null;
|
|
3556
|
+
const idToken = "idToken" in owner ? owner.idToken : null;
|
|
3557
|
+
assertString(subdomain, "subdomain");
|
|
3558
|
+
assertString(organizationName, "organizationName");
|
|
3559
|
+
assertString(displayName, "owner.displayName");
|
|
3560
|
+
assert.ok(email || idToken, "owner.email or owner.idToken is required");
|
|
3561
|
+
if (consents) {
|
|
3562
|
+
assertArray(consents, "consents");
|
|
3563
|
+
for (const { consentRevisionId, action } of consents) {
|
|
3564
|
+
assertString(consentRevisionId, "consentRevisionId");
|
|
3565
|
+
assertNullOrString(action, "action");
|
|
3566
|
+
}
|
|
3567
|
+
}
|
|
3568
|
+
return this._apiClient
|
|
3569
|
+
.request(`/organizations`, {
|
|
3570
|
+
method: "POST",
|
|
3571
|
+
data: {
|
|
3572
|
+
organizationName,
|
|
3573
|
+
type: "private",
|
|
3574
|
+
subdomain,
|
|
3575
|
+
owner: Object.assign(Object.assign(Object.assign(Object.assign({}, (email && { email })), (idToken && { idToken })), (consents && { consents })), { displayName }),
|
|
3576
|
+
},
|
|
3577
|
+
})
|
|
3578
|
+
.then(({ data }) => {
|
|
3579
|
+
return extractString(data, "organizationId");
|
|
3580
|
+
});
|
|
3581
|
+
}
|
|
3582
|
+
getOrganizationBySubdomain(subdomain) {
|
|
3583
|
+
assertString(subdomain, "subdomain");
|
|
3584
|
+
return this._apiClient
|
|
3585
|
+
.request(`/organization-subdomains/${encodeURIComponent(subdomain)}/?fields=permissions,account,onboardingSurvey`, {
|
|
3586
|
+
method: "GET",
|
|
3587
|
+
})
|
|
3588
|
+
.then(({ data }) => {
|
|
3589
|
+
return Organization.fromJson(data);
|
|
3590
|
+
})
|
|
3591
|
+
.catch((res) => {
|
|
3592
|
+
if (res instanceof Response) {
|
|
3593
|
+
if (res.status === 404) {
|
|
3594
|
+
return null;
|
|
3595
|
+
}
|
|
3596
|
+
throw new Error(res.statusText);
|
|
3597
|
+
}
|
|
3598
|
+
throw res;
|
|
3599
|
+
});
|
|
3600
|
+
}
|
|
3601
|
+
getOrganizationByOrganizationId(organizationId) {
|
|
3602
|
+
assertString(organizationId, "organizationId");
|
|
3603
|
+
return this._apiClient
|
|
3604
|
+
.request(`/organizations/${encodeURIComponent(organizationId)}?fields=permissions,account`, {
|
|
3605
|
+
method: "GET",
|
|
3606
|
+
})
|
|
3607
|
+
.then(({ data }) => {
|
|
3608
|
+
return Organization.fromJson(data);
|
|
3609
|
+
})
|
|
3610
|
+
.catch((res) => {
|
|
3611
|
+
if (res instanceof Response) {
|
|
3612
|
+
if (res.status === 404) {
|
|
3613
|
+
return null;
|
|
3614
|
+
}
|
|
3615
|
+
throw new Error(res.statusText);
|
|
3616
|
+
}
|
|
3617
|
+
throw res;
|
|
3618
|
+
});
|
|
3619
|
+
}
|
|
3620
|
+
getOrganizationsByContactPoint(options) {
|
|
3621
|
+
const { code } = options;
|
|
3622
|
+
const email = "email" in options ? options.email : null;
|
|
3623
|
+
const phoneNumber = "phoneNumber" in options ? options.phoneNumber : null;
|
|
3624
|
+
assert.ok((email || phoneNumber) && !(email && phoneNumber), "either email or phoneNumber is required");
|
|
3625
|
+
assertString(code, "code");
|
|
3626
|
+
const contactPoint = email ? { type: "email", value: email } : { type: "phoneNumber", value: phoneNumber };
|
|
3627
|
+
return this._apiClient
|
|
3628
|
+
.request("/organization-queries", {
|
|
3629
|
+
method: "POST",
|
|
3630
|
+
data: {
|
|
3631
|
+
contactPoint,
|
|
3632
|
+
code,
|
|
3633
|
+
},
|
|
3634
|
+
})
|
|
3635
|
+
.then(({ data }) => {
|
|
3636
|
+
return extractArray(data, "organizations", (organization) => Organization.fromJson(organization));
|
|
3637
|
+
});
|
|
3638
|
+
}
|
|
3639
|
+
getOrganizationsByIdToken({ idToken }) {
|
|
3640
|
+
assertString(idToken, "idToken");
|
|
3641
|
+
return this._apiClient
|
|
3642
|
+
.request("/organization-queries", {
|
|
3643
|
+
method: "POST",
|
|
3644
|
+
data: {
|
|
3645
|
+
idToken,
|
|
3646
|
+
},
|
|
3647
|
+
})
|
|
3648
|
+
.then(({ data }) => {
|
|
3649
|
+
return extractArray(data, "organizations", (organization) => {
|
|
3650
|
+
return Organization.fromJson(Object.assign({ permissions: {}, limits: {} }, assertRecord(organization, "organization")));
|
|
3651
|
+
});
|
|
3652
|
+
});
|
|
3653
|
+
}
|
|
3654
|
+
getOrganizationsByLoggedInUser() {
|
|
3655
|
+
return this._apiClient
|
|
3656
|
+
.request("/user/organizations", {
|
|
3657
|
+
method: "GET",
|
|
3658
|
+
})
|
|
3659
|
+
.then(({ data }) => {
|
|
3660
|
+
return extractArray(data, "organizations", (o) => {
|
|
3661
|
+
return Organization.fromJson(Object.assign({ permissions: {}, limits: {} }, assertRecord(o, "organization")));
|
|
3662
|
+
});
|
|
3663
|
+
});
|
|
3664
|
+
}
|
|
3665
|
+
getSubdomainAvailability(subdomain) {
|
|
3666
|
+
assertString(subdomain, "subdomain");
|
|
3667
|
+
return this._apiClient
|
|
3668
|
+
.request(`/organization-subdomains/${encodeURIComponent(subdomain)}/availability`, {
|
|
3669
|
+
method: "GET",
|
|
3670
|
+
})
|
|
3671
|
+
.then(({ data }) => {
|
|
3672
|
+
assertInstanceOf(data, Object, "data");
|
|
3673
|
+
return {
|
|
3674
|
+
status: extractString(data, "status"),
|
|
3675
|
+
};
|
|
3676
|
+
});
|
|
3677
|
+
}
|
|
3678
|
+
updatePreferences({ organizationId, preferences, }) {
|
|
3679
|
+
assertTruthy(organizationId, "organizationId");
|
|
3680
|
+
assertTruthy(preferences, "preferences");
|
|
3681
|
+
return this._apiClient
|
|
3682
|
+
.request(`/organizations/${encodeURIComponent(organizationId)}/preferences`, {
|
|
3683
|
+
method: "PATCH",
|
|
3684
|
+
data: preferences,
|
|
3685
|
+
})
|
|
3686
|
+
.then(() => undefined);
|
|
3687
|
+
}
|
|
3688
|
+
deleteOrganization({ organizationId }) {
|
|
3689
|
+
assertTruthy(organizationId, "organizationId");
|
|
3690
|
+
return this._apiClient
|
|
3691
|
+
.request(`/organizations/${encodeURIComponent(organizationId)}`, {
|
|
3692
|
+
method: "DELETE",
|
|
3693
|
+
})
|
|
3694
|
+
.then(() => undefined);
|
|
3695
|
+
}
|
|
3696
|
+
}
|
|
3697
|
+
|
|
3698
|
+
class OrganizationServiceCache {
|
|
3699
|
+
constructor({ organizationService, subdomain }) {
|
|
3700
|
+
this._organizationService = organizationService;
|
|
3701
|
+
this._subdomain = subdomain;
|
|
3702
|
+
this._organizationPromise = null;
|
|
3703
|
+
}
|
|
3704
|
+
initOrganization() {
|
|
3705
|
+
return this.fetchOrganization().then(() => undefined);
|
|
3706
|
+
}
|
|
3707
|
+
fetchOrganization() {
|
|
3708
|
+
if (!this._organizationPromise) {
|
|
3709
|
+
this._organizationPromise = this._organizationService.getOrganizationBySubdomain(this._subdomain);
|
|
3710
|
+
}
|
|
3711
|
+
return this._organizationPromise;
|
|
3712
|
+
}
|
|
3713
|
+
}
|
|
3714
|
+
|
|
3715
|
+
const API_BASE_URL = "https://api.whereby.dev";
|
|
3716
|
+
function createServices() {
|
|
3717
|
+
const credentialsService = CredentialsService.create({
|
|
3718
|
+
baseUrl: API_BASE_URL,
|
|
3719
|
+
});
|
|
3720
|
+
const apiClient = new ApiClient({
|
|
3721
|
+
fetchDeviceCredentials: credentialsService.getCredentials.bind(credentialsService),
|
|
3722
|
+
baseUrl: API_BASE_URL,
|
|
3723
|
+
});
|
|
3724
|
+
const organizationService = new OrganizationService({ apiClient });
|
|
3725
|
+
const fetchOrganizationFromRoomUrl = (roomUrl) => {
|
|
3726
|
+
const roomUrlObj = new URL(roomUrl);
|
|
3727
|
+
const urls = fromLocation({ host: roomUrlObj.host });
|
|
3728
|
+
const organizationServiceCache = new OrganizationServiceCache({
|
|
3729
|
+
organizationService,
|
|
3730
|
+
subdomain: urls.subdomain,
|
|
3731
|
+
});
|
|
3732
|
+
return organizationServiceCache.fetchOrganization();
|
|
3733
|
+
};
|
|
3734
|
+
return {
|
|
3735
|
+
credentialsService,
|
|
3736
|
+
apiClient,
|
|
3737
|
+
organizationService,
|
|
3738
|
+
fetchOrganizationFromRoomUrl,
|
|
3739
|
+
};
|
|
3740
|
+
}
|
|
3741
|
+
|
|
3742
|
+
export { addAppListener, addSpotlight, appSlice, authorizationSlice, authorizationSliceInitialState, breakoutSlice, breakoutSliceInitialState, chatSlice, chatSliceInitialState, cloudRecordingSlice, connectionMonitorSlice, connectionMonitorSliceInitialState, connectionMonitorStarted, connectionMonitorStopped, createAppAsyncThunk, createAppAuthorizedThunk, createAppThunk, createAsyncRoomConnectedThunk, createAuthorizedRoomConnectedThunk, createReactor, createRemoteParticipant, createRoomConnectedThunk, createServices, createStore, createWebRtcEmitter, deviceBusy, deviceCredentialsSlice, deviceCredentialsSliceInitialState, deviceIdentified, deviceIdentifying, doAcceptWaitingParticipant, doAppStart, doAppStop, doBreakoutJoin, doClearNotifications, doConnectRoom, doConnectRtc, doDisconnectRtc, doEnableAudio, doEnableVideo, doEndMeeting, doGetDeviceCredentials, doHandleAcceptStreams, doHandleStreamingStarted, doHandleStreamingStopped, doKickParticipant, doKnockRoom, doLockRoom, doOrganizationFetch, doRejectWaitingParticipant, doRemoveSpotlight, doRequestAudioEnable, doRequestVideoEnable, doRtcAnalyticsCustomEventsInitialize, doRtcManagerCreated, doRtcManagerInitialize, doRtcReportStreamResolution, doSendChatMessage, doSendClientMetadata, doSetDevice, doSetDisplayName, doSetLocalStickyReaction, doSetNotification, doSignalConnect, doSignalDisconnect, doSignalIdentifyDevice, doSpotlightParticipant, doStartCloudRecording, doStartConnectionMonitor, doStartLocalMedia, doStartScreenshare, doStopCloudRecording, doStopConnectionMonitor, doStopLocalMedia, doStopScreenshare, doSwitchLocalStream, doToggleCamera, doToggleLowDataMode, doUpdateDeviceList, initialCloudRecordingState, initialLocalMediaState, initialNotificationsState, initialState, isAcceptingStreams, isClientSpotlighted, listenerMiddleware, localMediaSlice, localMediaStopped, localParticipantSlice, localParticipantSliceInitialState, localScreenshareSlice, localScreenshareSliceInitialState, localStreamMetadataUpdated, notificationsSlice, observeStore, organizationSlice, organizationSliceInitialState, participantStreamAdded, participantStreamIdAdded, recordingRequestStarted, remoteParticipantsSlice, remoteParticipantsSliceInitialState, removeSpotlight, resolutionReported, roomConnectionSlice, roomConnectionSliceInitialState, roomSlice, roomSliceInitialState, rootReducer, rtcAnalyticsCustomEvents, rtcAnalyticsSlice, rtcAnalyticsSliceInitialState, rtcClientConnectionStatusChanged, rtcConnectionSlice, rtcConnectionSliceInitialState, rtcDisconnected, rtcDispatcherCreated, rtcEvents, rtcManagerCreated, rtcManagerDestroyed, rtcManagerInitialized, selectAllClientViews, selectAllClientViewsInCurrentGroup, selectAppDisplayName, selectAppExternalId, selectAppIgnoreBreakoutGroups, selectAppInitialConfig, selectAppIsActive, selectAppIsDialIn, selectAppIsNodeSdk, selectAppRaw, selectAppRoomName, selectAppRoomUrl, selectAppUserAgent, selectAuthorizationRoleName, selectBreakoutActive, selectBreakoutAssignments, selectBreakoutCurrentGroup, selectBreakoutCurrentId, selectBreakoutGroupedParticipants, selectBreakoutGroups, selectBreakoutInitiatedBy, selectBreakoutRaw, selectBusyDeviceIds, selectCameraDeviceError, selectCameraDevices, selectChatMessages, selectChatRaw, selectCloudRecordingError, selectCloudRecordingIsInitiator, selectCloudRecordingRaw, selectCloudRecordingStartedAt, selectCloudRecordingStatus, selectConnectionMonitorIsRunning, selectCurrentCameraDeviceId, selectCurrentMicrophoneDeviceId, selectCurrentSpeakerDeviceId, selectDeviceCredentialsRaw, selectDeviceId, selectHasFetchedDeviceCredentials, selectIsAcceptingStreams, selectIsAuthorizedToAskToSpeak, selectIsAuthorizedToEndMeeting, selectIsAuthorizedToKickClient, selectIsAuthorizedToLockRoom, selectIsAuthorizedToRequestAudioEnable, selectIsAuthorizedToRequestVideoEnable, selectIsAuthorizedToSpotlight, selectIsCameraEnabled, selectIsCloudRecording, selectIsLocalMediaStarting, selectIsLocalParticipantSpotlighted, selectIsLowDataModeEnabled, selectIsMicrophoneEnabled, selectIsSettingCameraDevice, selectIsSettingMicrophoneDevice, selectIsToggleCamera, selectLocalMediaConstraintsOptions, selectLocalMediaDevices, selectLocalMediaIsSwitchingStream, selectLocalMediaOptions, selectLocalMediaOwnsStream, selectLocalMediaRaw, selectLocalMediaShouldStartWithOptions, selectLocalMediaShouldStop, selectLocalMediaStartError, selectLocalMediaStatus, selectLocalMediaStream, selectLocalParticipantBreakoutAssigned, selectLocalParticipantBreakoutGroup, selectLocalParticipantClientClaim, selectLocalParticipantDisplayName, selectLocalParticipantIsScreenSharing, selectLocalParticipantRaw, selectLocalParticipantStickyReaction, selectLocalParticipantView, selectLocalScreenshareRaw, selectLocalScreenshareStatus, selectLocalScreenshareStream, selectMicrophoneDeviceError, selectMicrophoneDevices, selectNotificationsEmitter, selectNotificationsEvents, selectNotificationsRaw, selectNumClients, selectNumParticipants, selectOrganizationId, selectOrganizationPreferences, selectOrganizationRaw, selectRemoteClientViews, selectRemoteClients, selectRemoteParticipants, selectRemoteParticipantsRaw, selectRoomConnectionError, selectRoomConnectionRaw, selectRoomConnectionSession, selectRoomConnectionSessionId, selectRoomConnectionStatus, selectRoomIsLocked, selectRoomKey, selectRtcConnectionRaw, selectRtcDispatcherCreated, selectRtcIsCreatingDispatcher, selectRtcManager, selectRtcManagerInitialized, selectRtcStatus, selectScreenshares, selectSelfId, selectShouldConnectRoom, selectShouldConnectRtc, selectShouldConnectSignal, selectShouldDisconnectRtc, selectShouldFetchDeviceCredentials, selectShouldFetchOrganization, selectShouldIdentifyDevice, selectShouldInitializeRtc, selectShouldStartConnectionMonitor, selectShouldStopConnectionMonitor, selectSignalConnectionDeviceIdentified, selectSignalConnectionRaw, selectSignalConnectionSocket, selectSignalIsIdentifyingDevice, selectSignalStatus, selectSpeakerDevices, selectSpotlightedClientViews, selectSpotlights, selectSpotlightsRaw, selectStopCallbackFunction, selectStreamingRaw, selectStreamsToAccept, selectWaitingParticipants, selectWaitingParticipantsRaw, setBreakoutGroupAssigned, setCurrentCameraDeviceId, setCurrentMicrophoneDeviceId, setCurrentSpeakerDeviceId, setDisplayName, setLocalMediaOptions, setLocalMediaStream, setRoomKey, signalConnectionSlice, signalConnectionSliceInitialState, signalEvents, socketConnected, socketConnecting, socketDisconnected, socketReconnecting, spotlightsSlice, spotlightsSliceInitialState, startAppListening, stopScreenshare, streamIdForClient, streamStatusUpdated, streamingSlice, streamingSliceInitialState, toggleCameraEnabled, toggleLowDataModeEnabled, toggleMicrophoneEnabled, updateReportedValues, waitingParticipantsSlice, waitingParticipantsSliceInitialState };
|