@signalwire/js 1.4.2-rc.1 → 1.5.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.
@@ -1,7 +1,10 @@
1
1
  import BaseSession from './BaseSession';
2
- import { ICacheDevices, IAudioSettings, IVideoSettings, BroadcastParams, SubscribeParams, IBladeConnectResult } from './util/interfaces';
2
+ import { ICacheDevices, IAudioSettings, IVideoSettings, BroadcastParams, SubscribeParams, IBladeConnectResult, ISignalWireBrowserOptions } from './util/interfaces';
3
3
  import { IWebRTCCall } from './webrtc/interfaces';
4
4
  export default abstract class BrowserSession extends BaseSession {
5
+ options: ISignalWireBrowserOptions;
6
+ constructor(options: ISignalWireBrowserOptions);
7
+ validateOptions(): boolean;
5
8
  calls: {
6
9
  [callId: string]: IWebRTCCall;
7
10
  };
@@ -60,7 +63,7 @@ export default abstract class BrowserSession extends BaseSession {
60
63
  get localElement(): HTMLMediaElement | string | Function;
61
64
  set remoteElement(tag: HTMLMediaElement | string | Function);
62
65
  get remoteElement(): HTMLMediaElement | string | Function;
63
- vertoBroadcast({ nodeId, channel: eventChannel, data }: BroadcastParams): void;
64
- vertoSubscribe({ nodeId, channels: eventChannel, handler }: SubscribeParams): Promise<any>;
65
- vertoUnsubscribe({ nodeId, channels: eventChannel }: SubscribeParams): Promise<any>;
66
+ vertoBroadcast({ nodeId, channel: eventChannel, data, }: BroadcastParams): void;
67
+ vertoSubscribe({ nodeId, channels: eventChannel, handler, }: SubscribeParams): Promise<any>;
68
+ vertoUnsubscribe({ nodeId, channels: eventChannel, }: SubscribeParams): Promise<any>;
66
69
  }
@@ -23,14 +23,16 @@ import BaseSession from './BaseSession';
23
23
  import { registerOnce, trigger } from './services/Handler';
24
24
  import { SwEvent, SESSION_ID } from './util/constants';
25
25
  import { State, DeviceType } from './webrtc/constants';
26
- import { getDevices, scanResolutions, removeUnsupportedConstraints, checkDeviceIdConstraints, destructSubscribeResponse, getUserMedia, assureDeviceId } from './webrtc/helpers';
26
+ import { getDevices, scanResolutions, removeUnsupportedConstraints, checkDeviceIdConstraints, destructSubscribeResponse, getUserMedia, assureDeviceId, } from './webrtc/helpers';
27
27
  import { findElementByType } from './util/helpers';
28
28
  import { Unsubscribe, Subscribe, Broadcast } from './messages/Verto';
29
29
  import { localStorage } from './util/storage/';
30
30
  import { stopStream } from './util/webrtc';
31
+ import { WebRTCOverridesManager } from './webrtc/WebRTC';
31
32
  export default class BrowserSession extends BaseSession {
32
- constructor() {
33
- super(...arguments);
33
+ constructor(options) {
34
+ super(options);
35
+ this.options = options;
34
36
  this.calls = {};
35
37
  this.autoRecoverCalls = true;
36
38
  this._iceServers = [];
@@ -41,6 +43,32 @@ export default class BrowserSession extends BaseSession {
41
43
  this._audioConstraints = true;
42
44
  this._videoConstraints = false;
43
45
  this._speaker = null;
46
+ WebRTCOverridesManager.getInstance().RTCPeerConnection =
47
+ options.RTCPeerConnection;
48
+ WebRTCOverridesManager.getInstance().enumerateDevices =
49
+ options.enumerateDevices;
50
+ WebRTCOverridesManager.getInstance().getUserMedia = options.getUserMedia;
51
+ WebRTCOverridesManager.getInstance().getDisplayMedia =
52
+ options.getDisplayMedia;
53
+ WebRTCOverridesManager.getInstance().getSupportedConstraints =
54
+ options.getSupportedConstraints;
55
+ WebRTCOverridesManager.getInstance().attachMediaStream =
56
+ options.attachMediaStream;
57
+ WebRTCOverridesManager.getInstance().streamIsValid = options.streamIsValid;
58
+ }
59
+ validateOptions() {
60
+ const { RTCPeerConnection, getDisplayMedia, getUserMedia, attachMediaStream, streamIsValid, } = this.options;
61
+ return (((!RTCPeerConnection &&
62
+ !getDisplayMedia &&
63
+ !getUserMedia &&
64
+ !attachMediaStream &&
65
+ !streamIsValid) ||
66
+ (!!RTCPeerConnection &&
67
+ !!getDisplayMedia &&
68
+ !!getUserMedia &&
69
+ !!attachMediaStream &&
70
+ !!streamIsValid)) &&
71
+ super.validateOptions());
44
72
  }
45
73
  get reconnectDelay() {
46
74
  return 1000;
@@ -78,18 +106,23 @@ export default class BrowserSession extends BaseSession {
78
106
  disconnect: { get: () => super.disconnect }
79
107
  });
80
108
  return __awaiter(this, void 0, void 0, function* () {
81
- Object.keys(this.calls).forEach(k => this.calls[k].setState(State.Purge));
109
+ Object.keys(this.calls).forEach((k) => this.calls[k].setState(State.Purge));
82
110
  this.calls = {};
83
111
  yield _super.disconnect.call(this);
84
112
  });
85
113
  }
86
114
  speedTest(bytes) {
87
115
  return new Promise((resolve, reject) => {
88
- registerOnce(SwEvent.SpeedTest, speedTestResult => {
116
+ registerOnce(SwEvent.SpeedTest, (speedTestResult) => {
89
117
  const { upDur, downDur } = speedTestResult;
90
- const upKps = upDur ? (((bytes * 8) / (upDur / 1000)) / 1024) : 0;
91
- const downKps = downDur ? (((bytes * 8) / (downDur / 1000)) / 1024) : 0;
92
- resolve({ upDur, downDur, upKps: upKps.toFixed(0), downKps: downKps.toFixed(0) });
118
+ const upKps = upDur ? (bytes * 8) / (upDur / 1000) / 1024 : 0;
119
+ const downKps = downDur ? (bytes * 8) / (downDur / 1000) / 1024 : 0;
120
+ resolve({
121
+ upDur,
122
+ downDur,
123
+ upKps: upKps.toFixed(0),
124
+ downKps: downKps.toFixed(0),
125
+ });
93
126
  }, this.uuid);
94
127
  bytes = Number(bytes);
95
128
  if (!bytes) {
@@ -108,25 +141,25 @@ export default class BrowserSession extends BaseSession {
108
141
  });
109
142
  }
110
143
  getDevices() {
111
- return getDevices().catch(error => {
144
+ return getDevices().catch((error) => {
112
145
  trigger(SwEvent.MediaError, error, this.uuid);
113
146
  return [];
114
147
  });
115
148
  }
116
149
  getVideoDevices() {
117
- return getDevices(DeviceType.Video).catch(error => {
150
+ return getDevices(DeviceType.Video).catch((error) => {
118
151
  trigger(SwEvent.MediaError, error, this.uuid);
119
152
  return [];
120
153
  });
121
154
  }
122
155
  getAudioInDevices() {
123
- return getDevices(DeviceType.AudioIn).catch(error => {
156
+ return getDevices(DeviceType.AudioIn).catch((error) => {
124
157
  trigger(SwEvent.MediaError, error, this.uuid);
125
158
  return [];
126
159
  });
127
160
  }
128
161
  getAudioOutDevices() {
129
- return getDevices(DeviceType.AudioOut).catch(error => {
162
+ return getDevices(DeviceType.AudioOut).catch((error) => {
130
163
  trigger(SwEvent.MediaError, error, this.uuid);
131
164
  return [];
132
165
  });
@@ -142,8 +175,8 @@ export default class BrowserSession extends BaseSession {
142
175
  cache[kind] = {};
143
176
  Object.defineProperty(cache[kind], 'toArray', {
144
177
  value: function () {
145
- return Object.keys(this).map(k => this[k]);
146
- }
178
+ return Object.keys(this).map((k) => this[k]);
179
+ },
147
180
  });
148
181
  });
149
182
  const devices = yield this.getDevices();
@@ -218,7 +251,9 @@ export default class BrowserSession extends BaseSession {
218
251
  }
219
252
  set iceServers(servers) {
220
253
  if (typeof servers === 'boolean') {
221
- this._iceServers = servers ? [{ urls: ['stun:stun.l.google.com:19302'] }] : [];
254
+ this._iceServers = servers
255
+ ? [{ urls: ['stun:stun.l.google.com:19302'] }]
256
+ : [];
222
257
  }
223
258
  else {
224
259
  this._iceServers = servers;
@@ -245,7 +280,7 @@ export default class BrowserSession extends BaseSession {
245
280
  get remoteElement() {
246
281
  return this._remoteElement;
247
282
  }
248
- vertoBroadcast({ nodeId, channel: eventChannel = '', data }) {
283
+ vertoBroadcast({ nodeId, channel: eventChannel = '', data, }) {
249
284
  if (!eventChannel) {
250
285
  throw new Error('Invalid channel for broadcast: ' + eventChannel);
251
286
  }
@@ -253,11 +288,11 @@ export default class BrowserSession extends BaseSession {
253
288
  if (nodeId) {
254
289
  msg.targetNodeId = nodeId;
255
290
  }
256
- this.execute(msg).catch(error => error);
291
+ this.execute(msg).catch((error) => error);
257
292
  }
258
- vertoSubscribe({ nodeId, channels: eventChannel = [], handler }) {
293
+ vertoSubscribe({ nodeId, channels: eventChannel = [], handler, }) {
259
294
  return __awaiter(this, void 0, void 0, function* () {
260
- eventChannel = eventChannel.filter(channel => channel && !this._existsSubscription(this.relayProtocol, channel));
295
+ eventChannel = eventChannel.filter((channel) => channel && !this._existsSubscription(this.relayProtocol, channel));
261
296
  if (!eventChannel.length) {
262
297
  return {};
263
298
  }
@@ -268,15 +303,15 @@ export default class BrowserSession extends BaseSession {
268
303
  const response = yield this.execute(msg);
269
304
  const { unauthorized = [], subscribed = [] } = destructSubscribeResponse(response);
270
305
  if (unauthorized.length) {
271
- unauthorized.forEach(channel => this._removeSubscription(this.relayProtocol, channel));
306
+ unauthorized.forEach((channel) => this._removeSubscription(this.relayProtocol, channel));
272
307
  }
273
- subscribed.forEach(channel => this._addSubscription(this.relayProtocol, handler, channel));
308
+ subscribed.forEach((channel) => this._addSubscription(this.relayProtocol, handler, channel));
274
309
  return response;
275
310
  });
276
311
  }
277
- vertoUnsubscribe({ nodeId, channels: eventChannel = [] }) {
312
+ vertoUnsubscribe({ nodeId, channels: eventChannel = [], }) {
278
313
  return __awaiter(this, void 0, void 0, function* () {
279
- eventChannel = eventChannel.filter(channel => channel && this._existsSubscription(this.relayProtocol, channel));
314
+ eventChannel = eventChannel.filter((channel) => channel && this._existsSubscription(this.relayProtocol, channel));
280
315
  if (!eventChannel.length) {
281
316
  return {};
282
317
  }
@@ -286,8 +321,8 @@ export default class BrowserSession extends BaseSession {
286
321
  }
287
322
  const response = yield this.execute(msg);
288
323
  const { unsubscribed = [], notSubscribed = [] } = destructSubscribeResponse(response);
289
- unsubscribed.forEach(channel => this._removeSubscription(this.relayProtocol, channel));
290
- notSubscribed.forEach(channel => this._removeSubscription(this.relayProtocol, channel));
324
+ unsubscribed.forEach((channel) => this._removeSubscription(this.relayProtocol, channel));
325
+ notSubscribed.forEach((channel) => this._removeSubscription(this.relayProtocol, channel));
291
326
  return response;
292
327
  });
293
328
  }
@@ -5,4 +5,4 @@ declare const registerOnce: (eventName: string, callback: Function, uniqueId?: s
5
5
  declare const deRegister: (eventName: string, callback?: Function | null, uniqueId?: string) => boolean;
6
6
  declare const trigger: (eventName: string, data: any, uniqueId?: string, globalPropagation?: boolean) => boolean;
7
7
  declare const deRegisterAll: (eventName: string) => void;
8
- export { trigger, register, registerOnce, deRegister, deRegisterAll, isQueued, queueLength };
8
+ export { trigger, register, registerOnce, deRegister, deRegisterAll, isQueued, queueLength, };
@@ -33,7 +33,8 @@ const deRegister = (eventName, callback, uniqueId = GLOBAL) => {
33
33
  const len = queue[eventName][uniqueId].length;
34
34
  for (let i = len - 1; i >= 0; i--) {
35
35
  const fn = queue[eventName][uniqueId][i];
36
- if (callback === fn || (fn.prototype && callback === fn.prototype.targetRef)) {
36
+ if (callback === fn ||
37
+ (fn.prototype && callback === fn.prototype.targetRef)) {
37
38
  queue[eventName][uniqueId].splice(i, 1);
38
39
  }
39
40
  }
@@ -75,4 +76,4 @@ const trigger = (eventName, data, uniqueId = GLOBAL, globalPropagation = true) =
75
76
  const deRegisterAll = (eventName) => {
76
77
  delete queue[eventName];
77
78
  };
78
- export { trigger, register, registerOnce, deRegister, deRegisterAll, isQueued, queueLength };
79
+ export { trigger, register, registerOnce, deRegister, deRegisterAll, isQueued, queueLength, };
@@ -18,3 +18,4 @@ export declare const destructResponse: (response: any, nodeId?: string) => {
18
18
  [key: string]: any;
19
19
  };
20
20
  export declare const randomInt: (min: number, max: number) => number;
21
+ export declare const normalizeAsyncAPIs: <T extends object>(target: T, promisifyTargetMethods?: string[], asyncAlternativeSuffix?: string) => T;
@@ -4,7 +4,7 @@ export const deepCopy = (obj) => JSON.parse(JSON.stringify(obj));
4
4
  export const objEmpty = (obj) => Object.keys(obj).length === 0;
5
5
  export const mutateStorageKey = (key) => `${STORAGE_PREFIX}${key}`;
6
6
  export const mutateLiveArrayData = (data) => {
7
- const [participantId, participantNumber, participantName, codec, mediaJson, participantData] = data;
7
+ const [participantId, participantNumber, participantName, codec, mediaJson, participantData,] = data;
8
8
  let media = {};
9
9
  try {
10
10
  media = JSON.parse(mediaJson.replace(/ID"/g, 'Id"'));
@@ -12,7 +12,14 @@ export const mutateLiveArrayData = (data) => {
12
12
  catch (error) {
13
13
  logger.warn('Verto LA invalid media JSON string:', mediaJson);
14
14
  }
15
- return { participantId: Number(participantId), participantNumber, participantName, codec, media, participantData };
15
+ return {
16
+ participantId: Number(participantId),
17
+ participantNumber,
18
+ participantName,
19
+ codec,
20
+ media,
21
+ participantData,
22
+ };
16
23
  };
17
24
  export const safeParseJson = (value) => {
18
25
  if (typeof value !== 'string') {
@@ -71,3 +78,28 @@ export const destructResponse = (response, nodeId = null) => {
71
78
  export const randomInt = (min, max) => {
72
79
  return Math.floor(Math.random() * (max - min + 1) + min);
73
80
  };
81
+ export const normalizeAsyncAPIs = (target, promisifyTargetMethods = [], asyncAlternativeSuffix = 'Async') => {
82
+ const promisify = new Set(promisifyTargetMethods);
83
+ return new Proxy(target, {
84
+ get(obj, prop) {
85
+ const descriptor = Object.getOwnPropertyDescriptor(obj, prop);
86
+ if (descriptor && descriptor.get) {
87
+ return Reflect.get(obj, prop);
88
+ }
89
+ if (typeof obj[prop] === 'function') {
90
+ const impl = obj[`${String(prop)}${asyncAlternativeSuffix}`] || obj[prop];
91
+ return (...args) => {
92
+ const result = impl.apply(obj, args);
93
+ if (promisify.has(String(prop)) && !(result instanceof Promise)) {
94
+ return Promise.resolve(result);
95
+ }
96
+ return result;
97
+ };
98
+ }
99
+ return Reflect.get(obj, prop);
100
+ },
101
+ set(obj, prop, value) {
102
+ return Reflect.set(obj, prop, value);
103
+ },
104
+ });
105
+ };
@@ -1,3 +1,4 @@
1
+ import { IWebRTCOverridesManager } from '../webrtc/WebRTC';
1
2
  interface IMessageBase {
2
3
  jsonrpc: string;
3
4
  id: string;
@@ -78,6 +79,7 @@ export interface ISignalWireOptions {
78
79
  password?: string;
79
80
  userVariables?: Object;
80
81
  }
82
+ export type ISignalWireBrowserOptions = ISignalWireOptions & Partial<IWebRTCOverridesManager>;
81
83
  export interface SubscribeParams {
82
84
  channels?: string[];
83
85
  protocol?: string;