@cloudflare/realtimekit-react-native 1.2.0-staging.3 → 1.2.0-staging.5

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.
Files changed (84) hide show
  1. package/RealtimeKitCore.podspec +1 -1
  2. package/ios/scripts/screenshare_sources.rb +74 -0
  3. package/lib/commonjs/AudioSampleHandler.js +1 -7
  4. package/lib/commonjs/AudioSampleHandler.js.map +1 -1
  5. package/lib/commonjs/BackgroundHandler.js +0 -7
  6. package/lib/commonjs/BackgroundHandler.js.map +1 -1
  7. package/lib/commonjs/DeviceInfo.js +0 -4
  8. package/lib/commonjs/DeviceInfo.js.map +1 -1
  9. package/lib/commonjs/LocalMediaError.js +0 -4
  10. package/lib/commonjs/LocalMediaError.js.map +1 -1
  11. package/lib/commonjs/LocalMediaHandler.js +135 -186
  12. package/lib/commonjs/LocalMediaHandler.js.map +1 -1
  13. package/lib/commonjs/LocalMediaInterfaces.js.map +1 -1
  14. package/lib/commonjs/LocalMediaUtils.js +19 -27
  15. package/lib/commonjs/LocalMediaUtils.js.map +1 -1
  16. package/lib/commonjs/NativeAudioManager.js +3 -3
  17. package/lib/commonjs/NativeAudioManager.js.map +1 -1
  18. package/lib/commonjs/PermissionHandler.js.map +1 -1
  19. package/lib/commonjs/ReactContext.js +39 -43
  20. package/lib/commonjs/ReactContext.js.map +1 -1
  21. package/lib/commonjs/ReactHooks.js +7 -9
  22. package/lib/commonjs/ReactHooks.js.map +1 -1
  23. package/lib/commonjs/index.js.map +1 -1
  24. package/lib/commonjs/package.json +1 -0
  25. package/lib/commonjs/utils/crypto.js.map +1 -1
  26. package/lib/commonjs/utils/version.js +1 -1
  27. package/lib/commonjs/utils/version.js.map +1 -1
  28. package/lib/module/AudioSampleHandler.js +3 -7
  29. package/lib/module/AudioSampleHandler.js.map +1 -1
  30. package/lib/module/BackgroundHandler.js +2 -7
  31. package/lib/module/BackgroundHandler.js.map +1 -1
  32. package/lib/module/DeviceInfo.js +2 -4
  33. package/lib/module/DeviceInfo.js.map +1 -1
  34. package/lib/module/LocalMediaError.js +2 -4
  35. package/lib/module/LocalMediaError.js.map +1 -1
  36. package/lib/module/LocalMediaHandler.js +135 -186
  37. package/lib/module/LocalMediaHandler.js.map +1 -1
  38. package/lib/module/LocalMediaInterfaces.js +1 -1
  39. package/lib/module/LocalMediaInterfaces.js.map +1 -1
  40. package/lib/module/LocalMediaUtils.js +21 -27
  41. package/lib/module/LocalMediaUtils.js.map +1 -1
  42. package/lib/module/NativeAudioManager.js +5 -3
  43. package/lib/module/NativeAudioManager.js.map +1 -1
  44. package/lib/module/PermissionHandler.js +2 -0
  45. package/lib/module/PermissionHandler.js.map +1 -1
  46. package/lib/module/ReactContext.js +39 -43
  47. package/lib/module/ReactContext.js.map +1 -1
  48. package/lib/module/ReactHooks.js +9 -9
  49. package/lib/module/ReactHooks.js.map +1 -1
  50. package/lib/module/index.js +2 -0
  51. package/lib/module/index.js.map +1 -1
  52. package/lib/module/utils/crypto.js +2 -0
  53. package/lib/module/utils/crypto.js.map +1 -1
  54. package/lib/module/utils/version.js +3 -1
  55. package/lib/module/utils/version.js.map +1 -1
  56. package/lib/typescript/AudioSampleHandler.d.ts +1 -0
  57. package/lib/typescript/AudioSampleHandler.d.ts.map +1 -0
  58. package/lib/typescript/BackgroundHandler.d.ts +1 -0
  59. package/lib/typescript/BackgroundHandler.d.ts.map +1 -0
  60. package/lib/typescript/DeviceInfo.d.ts +1 -0
  61. package/lib/typescript/DeviceInfo.d.ts.map +1 -0
  62. package/lib/typescript/LocalMediaError.d.ts +1 -0
  63. package/lib/typescript/LocalMediaError.d.ts.map +1 -0
  64. package/lib/typescript/LocalMediaHandler.d.ts +1 -0
  65. package/lib/typescript/LocalMediaHandler.d.ts.map +1 -0
  66. package/lib/typescript/LocalMediaInterfaces.d.ts +1 -0
  67. package/lib/typescript/LocalMediaInterfaces.d.ts.map +1 -0
  68. package/lib/typescript/LocalMediaUtils.d.ts +1 -0
  69. package/lib/typescript/LocalMediaUtils.d.ts.map +1 -0
  70. package/lib/typescript/NativeAudioManager.d.ts +1 -0
  71. package/lib/typescript/NativeAudioManager.d.ts.map +1 -0
  72. package/lib/typescript/PermissionHandler.d.ts +1 -0
  73. package/lib/typescript/PermissionHandler.d.ts.map +1 -0
  74. package/lib/typescript/ReactContext.d.ts +1 -0
  75. package/lib/typescript/ReactContext.d.ts.map +1 -0
  76. package/lib/typescript/ReactHooks.d.ts +1 -0
  77. package/lib/typescript/ReactHooks.d.ts.map +1 -0
  78. package/lib/typescript/index.d.ts +1 -0
  79. package/lib/typescript/index.d.ts.map +1 -0
  80. package/lib/typescript/utils/crypto.d.ts +1 -0
  81. package/lib/typescript/utils/crypto.d.ts.map +1 -0
  82. package/lib/typescript/utils/version.d.ts +2 -1
  83. package/lib/typescript/utils/version.d.ts.map +1 -0
  84. package/package.json +3 -3
@@ -1,11 +1,5 @@
1
- function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
2
- function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
3
- function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
4
- function _classPrivateFieldInitSpec(e, t, a) { _checkPrivateRedeclaration(e, t), t.set(e, a); }
5
- function _checkPrivateRedeclaration(e, t) { if (t.has(e)) throw new TypeError("Cannot initialize the same private elements twice on an object"); }
6
- function _classPrivateFieldSet(s, a, r) { return s.set(_assertClassBrand(s, a), r), r; }
7
- function _classPrivateFieldGet(s, a) { return s.get(_assertClassBrand(s, a)); }
8
- function _assertClassBrand(e, t, n) { if ("function" == typeof e ? e === t : e.has(t)) return arguments.length < 3 ? t : n; throw new TypeError("Private element is not present on this object"); }
1
+ "use strict";
2
+
9
3
  /* eslint-disable @typescript-eslint/no-unused-vars */
10
4
  import { EventEmitter } from 'events';
11
5
  import LocalMediaUtils from './LocalMediaUtils';
@@ -31,8 +25,6 @@ let _meetingServiceConfig = {
31
25
  channelId: 'rtk_meeting',
32
26
  channelName: 'Ongoing Meeting'
33
27
  };
34
-
35
- // eslint-disable-next-line no-shadow
36
28
  export let MediaEvents = /*#__PURE__*/function (MediaEvents) {
37
29
  MediaEvents[MediaEvents["AUDIO_TRACK_CHANGE"] = 0] = "AUDIO_TRACK_CHANGE";
38
30
  MediaEvents[MediaEvents["VIDEO_TRACK_CHANGE"] = 1] = "VIDEO_TRACK_CHANGE";
@@ -48,76 +40,50 @@ function checkIfAudioTrackIsSilent(track) {
48
40
  //TODO
49
41
  return !!track;
50
42
  }
51
- var _localMediaUtils = /*#__PURE__*/new WeakMap();
52
- var _appState = /*#__PURE__*/new WeakMap();
53
- var _appStateSubscription = /*#__PURE__*/new WeakMap();
54
- var _interval = /*#__PURE__*/new WeakMap();
55
- var _screenShareState = /*#__PURE__*/new WeakMap();
56
- var _deviceRemovalTimeout = /*#__PURE__*/new WeakMap();
57
- var _broadcastEmitter = /*#__PURE__*/new WeakMap();
58
- var _broadcastStartedSubscription = /*#__PURE__*/new WeakMap();
59
- var _broadcastStoppedSubscription = /*#__PURE__*/new WeakMap();
60
43
  export default class LocalMediaHandler extends EventEmitter {
44
+ #localMediaUtils;
45
+ #appState;
46
+ #appStateSubscription;
47
+ #interval;
48
+ #screenShareState;
49
+ _pendingScreenShare = false;
50
+ #deviceRemovalTimeout = null;
51
+ #broadcastEmitter;
52
+ #broadcastStartedSubscription;
53
+ #broadcastStoppedSubscription;
54
+ _handleAppStateChange = nextAppState => {
55
+ const prevAppState = this.#appState;
56
+ this.#appState = nextAppState;
57
+ if (prevAppState.match(/inactive|background/) && nextAppState === 'active') {
58
+ // App returned to foreground — stop the background keep-alive timer
59
+ // and kick the video track to recover the camera feed.
60
+ if (this.#interval !== null) {
61
+ BackgroundTimer.clearInterval(this.#interval);
62
+ this.#interval = null;
63
+ }
64
+ if (this.videoTrack) {
65
+ this.videoTrack.enabled = false;
66
+ setTimeout(() => {
67
+ if (this.videoTrack) {
68
+ this.videoTrack.enabled = true;
69
+ }
70
+ }, 100);
71
+ }
72
+ } else if (nextAppState.match(/inactive|background/)) {
73
+ // App moved to background — start a recurring no-op timer to keep the
74
+ // JS thread alive so WebRTC/native events continue to be processed.
75
+ // Clear any existing interval first to avoid accumulation.
76
+ if (this.#interval !== null) {
77
+ BackgroundTimer.clearInterval(this.#interval);
78
+ }
79
+ this.#interval = BackgroundTimer.setInterval(() => {}, 1000);
80
+ }
81
+ };
61
82
  constructor(localMediaUtils) {
62
83
  super();
63
- _classPrivateFieldInitSpec(this, _localMediaUtils, void 0);
64
- _classPrivateFieldInitSpec(this, _appState, void 0);
65
- _classPrivateFieldInitSpec(this, _appStateSubscription, void 0);
66
- _classPrivateFieldInitSpec(this, _interval, void 0);
67
- _classPrivateFieldInitSpec(this, _screenShareState, void 0);
68
- _defineProperty(this, "audioTrack", void 0);
69
- _defineProperty(this, "rawAudioTrack", void 0);
70
- _defineProperty(this, "videoTrack", void 0);
71
- _defineProperty(this, "rawVideoTrack", void 0);
72
- _defineProperty(this, "screenShareTracks", void 0);
73
- _defineProperty(this, "audioEnabled", void 0);
74
- _defineProperty(this, "videoEnabled", void 0);
75
- _defineProperty(this, "screenShareEnabled", void 0);
76
- _defineProperty(this, "_pendingScreenShare", false);
77
- _defineProperty(this, "currentDevices", void 0);
78
- _defineProperty(this, "permissions", void 0);
79
- _classPrivateFieldInitSpec(this, _deviceRemovalTimeout, null);
80
- _classPrivateFieldInitSpec(this, _broadcastEmitter, void 0);
81
- _classPrivateFieldInitSpec(this, _broadcastStartedSubscription, void 0);
82
- _classPrivateFieldInitSpec(this, _broadcastStoppedSubscription, void 0);
83
- _defineProperty(this, "_handleAppStateChange", nextAppState => {
84
- const prevAppState = _classPrivateFieldGet(_appState, this);
85
- _classPrivateFieldSet(_appState, this, nextAppState);
86
- if (prevAppState.match(/inactive|background/) && nextAppState === 'active') {
87
- // App returned to foreground — stop the background keep-alive timer
88
- // and kick the video track to recover the camera feed.
89
- if (_classPrivateFieldGet(_interval, this) !== null) {
90
- BackgroundTimer.clearInterval(_classPrivateFieldGet(_interval, this));
91
- _classPrivateFieldSet(_interval, this, null);
92
- }
93
- if (this.videoTrack) {
94
- this.videoTrack.enabled = false;
95
- setTimeout(() => {
96
- if (this.videoTrack) {
97
- this.videoTrack.enabled = true;
98
- }
99
- }, 100);
100
- }
101
- } else if (nextAppState.match(/inactive|background/)) {
102
- // App moved to background — start a recurring no-op timer to keep the
103
- // JS thread alive so WebRTC/native events continue to be processed.
104
- // Clear any existing interval first to avoid accumulation.
105
- if (_classPrivateFieldGet(_interval, this) !== null) {
106
- BackgroundTimer.clearInterval(_classPrivateFieldGet(_interval, this));
107
- }
108
- _classPrivateFieldSet(_interval, this, BackgroundTimer.setInterval(() => {}, 1000));
109
- }
110
- });
111
- // Arrow function so `this` is stable — the same reference is used in both
112
- // addEventListener (setScreenShareTracks) and removeEventListener
113
- // (removeScreenShareTracks). A regular method + .bind(this) creates a new
114
- // function object on every call, making removeEventListener a no-op.
115
- _defineProperty(this, "onScreenShareEnded", () => {
116
- this.emit('SCREENSHARE_ENDED');
117
- });
118
- _classPrivateFieldSet(_localMediaUtils, this, localMediaUtils);
119
- _classPrivateFieldSet(_broadcastEmitter, this, broadcastEmitter);
120
- _classPrivateFieldSet(_appState, this, '');
84
+ this.#localMediaUtils = localMediaUtils;
85
+ this.#broadcastEmitter = broadcastEmitter;
86
+ this.#appState = '';
121
87
  this.audioEnabled = true;
122
88
  this.videoEnabled = true;
123
89
  this.screenShareEnabled = false;
@@ -135,16 +101,16 @@ export default class LocalMediaHandler extends EventEmitter {
135
101
  speaker: undefined
136
102
  };
137
103
  // LocalMediaUtils onDeviceChange with callback from native onAudioDeviceChanged events
138
- _classPrivateFieldGet(_localMediaUtils, this).onDeviceChange(async changedDevices => {
104
+ this.#localMediaUtils.onDeviceChange(async changedDevices => {
139
105
  await this.onDeviceChange(changedDevices, false);
140
106
  });
141
107
  if (Platform.OS === 'ios') {
142
- _classPrivateFieldSet(_broadcastStartedSubscription, this, _classPrivateFieldGet(_broadcastEmitter, this).addListener('iOS_BroadcastStarted', () => {
108
+ this.#broadcastStartedSubscription = this.#broadcastEmitter.addListener('iOS_BroadcastStarted', () => {
143
109
  this.oniOSBroadcastStart();
144
- }));
145
- _classPrivateFieldSet(_broadcastStoppedSubscription, this, _classPrivateFieldGet(_broadcastEmitter, this).addListener('iOS_BroadcastStopped', () => {
110
+ });
111
+ this.#broadcastStoppedSubscription = this.#broadcastEmitter.addListener('iOS_BroadcastStopped', () => {
146
112
  this.oniOSBroadcastStop();
147
- }));
113
+ });
148
114
  }
149
115
  NativeAudioManager.start({
150
116
  media: 'video'
@@ -154,27 +120,20 @@ export default class LocalMediaHandler extends EventEmitter {
154
120
  if (!this.currentDevices.audio || !this.audioEnabled) {
155
121
  return;
156
122
  }
157
- await Promise.race([new Promise(resolve => {
158
- var _this$audioTrack;
159
- return (_this$audioTrack = this.audioTrack) === null || _this$audioTrack === void 0 ? void 0 : _this$audioTrack.addEventListener('unmute', e => {
160
- resolve(e);
161
- });
162
- }), new Promise(resolve => setTimeout(resolve, 50))]);
123
+ await Promise.race([new Promise(resolve => this.audioTrack?.addEventListener('unmute', e => {
124
+ resolve(e);
125
+ })), new Promise(resolve => setTimeout(resolve, 50))]);
163
126
  const reacquireTrack = await this.shouldReacquireTrack('audio');
164
127
  if (reacquireTrack) {
165
- var _this$currentDevices$;
166
128
  this.removeMediaStreamTrackListeners(this.audioTrack);
167
- await this.setupAudioStream((_this$currentDevices$ = this.currentDevices.audio) === null || _this$currentDevices$ === void 0 ? void 0 : _this$currentDevices$.deviceId);
129
+ await this.setupAudioStream(this.currentDevices.audio?.deviceId);
168
130
  this.addMediaStreamTrackListeners(this.audioTrack);
169
131
  this.emit('AUDIO_TRACK_CHANGE');
170
132
  }
171
133
  }
172
134
  async conditionallyRestartVideo() {
173
135
  if (!this.currentDevices.video || !this.videoEnabled) return;
174
- await Promise.race([new Promise(resolve => {
175
- var _this$videoTrack;
176
- return (_this$videoTrack = this.videoTrack) === null || _this$videoTrack === void 0 ? void 0 : _this$videoTrack.addEventListener('unmute', resolve);
177
- }), new Promise(resolve => setTimeout(resolve, 50))]);
136
+ await Promise.race([new Promise(resolve => this.videoTrack?.addEventListener('unmute', resolve)), new Promise(resolve => setTimeout(resolve, 50))]);
178
137
  const reacquireTrack = await this.shouldReacquireTrack('video');
179
138
  if (reacquireTrack) {
180
139
  this.removeMediaStreamTrackListeners(this.videoTrack);
@@ -230,8 +189,7 @@ export default class LocalMediaHandler extends EventEmitter {
230
189
  return mediaStreamTrack;
231
190
  }
232
191
  async setupAudioStream(deviceId, forceStopTrack = false) {
233
- var _this$currentDevices$2;
234
- const audioDevices = await _classPrivateFieldGet(_localMediaUtils, this).getAudioDevices();
192
+ const audioDevices = await this.#localMediaUtils.getAudioDevices();
235
193
  if (!audioDevices.length) {
236
194
  return;
237
195
  }
@@ -239,13 +197,12 @@ export default class LocalMediaHandler extends EventEmitter {
239
197
  if (!audioDeviceId) {
240
198
  audioDeviceId = (await this.getOperationalMicDeviceId()).deviceId;
241
199
  }
242
- if (((_this$currentDevices$2 = this.currentDevices.audio) === null || _this$currentDevices$2 === void 0 ? void 0 : _this$currentDevices$2.deviceId) !== audioDeviceId) {
243
- this.currentDevices.audio = _classPrivateFieldGet(_localMediaUtils, this).getDeviceById(audioDeviceId, 'audioinput');
200
+ if (this.currentDevices.audio?.deviceId !== audioDeviceId) {
201
+ this.currentDevices.audio = this.#localMediaUtils.getDeviceById(audioDeviceId, 'audioinput');
244
202
  }
245
203
  if (forceStopTrack) {
246
- var _this$audioTrack2, _this$rawAudioTrack;
247
- (_this$audioTrack2 = this.audioTrack) === null || _this$audioTrack2 === void 0 || _this$audioTrack2.stop();
248
- (_this$rawAudioTrack = this.rawAudioTrack) === null || _this$rawAudioTrack === void 0 || _this$rawAudioTrack.stop();
204
+ this.audioTrack?.stop();
205
+ this.rawAudioTrack?.stop();
249
206
  }
250
207
  try {
251
208
  this.rawAudioTrack = await LocalMediaUtils.getAudioTrack();
@@ -263,7 +220,7 @@ export default class LocalMediaHandler extends EventEmitter {
263
220
  * So, we need to repopulate the devices once permission is granted.
264
221
  */
265
222
  if (this.audioTrack && this.permissions.audio === 'NOT_REQUESTED') {
266
- await _classPrivateFieldGet(_localMediaUtils, this).repopulateAvailableDevices();
223
+ await this.#localMediaUtils.repopulateAvailableDevices();
267
224
  }
268
225
 
269
226
  // Force update audio devices on iOS after audio session is active
@@ -277,8 +234,7 @@ export default class LocalMediaHandler extends EventEmitter {
277
234
  // pass
278
235
  }
279
236
  async setupVideoStream(deviceId, forceStopTrack = false) {
280
- var _this$currentDevices$3;
281
- const videoDevices = await _classPrivateFieldGet(_localMediaUtils, this).getVideoDevices();
237
+ const videoDevices = await this.#localMediaUtils.getVideoDevices();
282
238
  if (!videoDevices.length) {
283
239
  return;
284
240
  }
@@ -286,8 +242,8 @@ export default class LocalMediaHandler extends EventEmitter {
286
242
  if (!videoDeviceId) {
287
243
  videoDeviceId = (await this.getOperationalWebcamDeviceId()).deviceId;
288
244
  }
289
- if (((_this$currentDevices$3 = this.currentDevices.video) === null || _this$currentDevices$3 === void 0 ? void 0 : _this$currentDevices$3.deviceId) !== videoDeviceId) {
290
- this.currentDevices.video = _classPrivateFieldGet(_localMediaUtils, this).getDeviceById(videoDeviceId, 'videoinput');
245
+ if (this.currentDevices.video?.deviceId !== videoDeviceId) {
246
+ this.currentDevices.video = this.#localMediaUtils.getDeviceById(videoDeviceId, 'videoinput');
291
247
  }
292
248
 
293
249
  /**
@@ -311,24 +267,22 @@ export default class LocalMediaHandler extends EventEmitter {
311
267
  this.emit('VIDEO_TRACK_CHANGE');
312
268
  }
313
269
  if (forceStopTrack) {
314
- var _this$videoTrack2, _this$rawVideoTrack;
315
- (_this$videoTrack2 = this.videoTrack) === null || _this$videoTrack2 === void 0 || _this$videoTrack2.stop();
316
- (_this$rawVideoTrack = this.rawVideoTrack) === null || _this$rawVideoTrack === void 0 || _this$rawVideoTrack.stop();
270
+ this.videoTrack?.stop();
271
+ this.rawVideoTrack?.stop();
317
272
  }
318
273
  /**
319
274
  * NOTE(roerohan): Firefox does not show device labels until permissions are granted.
320
275
  * So, we need to repopulate the devices once permission is granted.
321
276
  */
322
277
  if (this.videoTrack && this.permissions.video === 'NOT_REQUESTED') {
323
- await _classPrivateFieldGet(_localMediaUtils, this).repopulateAvailableDevices();
278
+ await this.#localMediaUtils.repopulateAvailableDevices();
324
279
  }
325
280
  this.emit('DEVICE_CHANGE', {
326
281
  device: this.currentDevices.video
327
282
  });
328
283
  }
329
284
  async setupSpeaker(deviceId) {
330
- var _this$currentDevices$5;
331
- const speakerDevices = await _classPrivateFieldGet(_localMediaUtils, this).getSpeakerDevices();
285
+ const speakerDevices = await this.#localMediaUtils.getSpeakerDevices();
332
286
  if (!speakerDevices.length) {
333
287
  return;
334
288
  }
@@ -338,10 +292,7 @@ export default class LocalMediaHandler extends EventEmitter {
338
292
  speakerDeviceId = deviceId;
339
293
  } else {
340
294
  // Prefer current device if it's still available
341
- const currentDeviceStillAvailable = speakerDevices.find(d => {
342
- var _this$currentDevices$4;
343
- return d.deviceId === ((_this$currentDevices$4 = this.currentDevices.speaker) === null || _this$currentDevices$4 === void 0 ? void 0 : _this$currentDevices$4.deviceId);
344
- });
295
+ const currentDeviceStillAvailable = speakerDevices.find(d => d.deviceId === this.currentDevices.speaker?.deviceId);
345
296
  if (currentDeviceStillAvailable) {
346
297
  // Keep current device if it's still connected
347
298
  speakerDeviceId = this.currentDevices.speaker.deviceId;
@@ -350,12 +301,12 @@ export default class LocalMediaHandler extends EventEmitter {
350
301
  const bluetoothDevice = speakerDevices.find(d => d.deviceId === 'bluetooth');
351
302
  const wiredDevice = speakerDevices.find(d => d.deviceId === 'wired');
352
303
  const speakerDevice = speakerDevices.find(d => d.deviceId === 'speaker');
353
- speakerDeviceId = (bluetoothDevice === null || bluetoothDevice === void 0 ? void 0 : bluetoothDevice.deviceId) ?? (wiredDevice === null || wiredDevice === void 0 ? void 0 : wiredDevice.deviceId) ?? (speakerDevice === null || speakerDevice === void 0 ? void 0 : speakerDevice.deviceId) ?? speakerDevices[0].deviceId;
304
+ speakerDeviceId = bluetoothDevice?.deviceId ?? wiredDevice?.deviceId ?? speakerDevice?.deviceId ?? speakerDevices[0].deviceId;
354
305
  }
355
306
  }
356
- if (((_this$currentDevices$5 = this.currentDevices.speaker) === null || _this$currentDevices$5 === void 0 ? void 0 : _this$currentDevices$5.deviceId) !== speakerDeviceId) {
307
+ if (this.currentDevices.speaker?.deviceId !== speakerDeviceId) {
357
308
  // Audio Input devices are same as output devices in mobile
358
- this.currentDevices.audio = _classPrivateFieldGet(_localMediaUtils, this).getDeviceById(speakerDeviceId, 'audioinput');
309
+ this.currentDevices.audio = this.#localMediaUtils.getDeviceById(speakerDeviceId, 'audioinput');
359
310
  this.currentDevices.speaker = this.currentDevices.audio;
360
311
  }
361
312
  await this.setDevice(this.currentDevices.audio);
@@ -364,7 +315,7 @@ export default class LocalMediaHandler extends EventEmitter {
364
315
  });
365
316
  }
366
317
  async getOperationalWebcamDeviceId() {
367
- let videoDevices = await _classPrivateFieldGet(_localMediaUtils, this).getVideoDevices();
318
+ let videoDevices = await this.#localMediaUtils.getVideoDevices();
368
319
  if (!videoDevices.length) {
369
320
  return {
370
321
  isOperational: false,
@@ -395,7 +346,7 @@ export default class LocalMediaHandler extends EventEmitter {
395
346
  };
396
347
  }
397
348
  async getOperationalMicDeviceId() {
398
- let audioDevices = await _classPrivateFieldGet(_localMediaUtils, this).getAudioDevices();
349
+ let audioDevices = await this.#localMediaUtils.getAudioDevices();
399
350
  if (!audioDevices.length) {
400
351
  return {
401
352
  isOperational: false,
@@ -461,18 +412,18 @@ export default class LocalMediaHandler extends EventEmitter {
461
412
  };
462
413
  }
463
414
  if (audio) {
464
- const audioDevices = await _classPrivateFieldGet(_localMediaUtils, this).getAudioDevices();
415
+ const audioDevices = await this.#localMediaUtils.getAudioDevices();
465
416
  if (audioDevices.length !== 0) {
466
417
  const audioDeviceId = (await this.getOperationalMicDeviceId()).deviceId;
467
- this.currentDevices.audio = _classPrivateFieldGet(_localMediaUtils, this).getDeviceById(audioDeviceId, 'audioinput');
418
+ this.currentDevices.audio = this.#localMediaUtils.getDeviceById(audioDeviceId, 'audioinput');
468
419
  constraints.audio = true;
469
420
  }
470
421
  }
471
422
  if (video) {
472
- const videoDevices = await _classPrivateFieldGet(_localMediaUtils, this).getVideoDevices();
423
+ const videoDevices = await this.#localMediaUtils.getVideoDevices();
473
424
  if (videoDevices.length !== 0) {
474
425
  const videoDeviceId = (await this.getOperationalWebcamDeviceId()).deviceId;
475
- this.currentDevices.video = _classPrivateFieldGet(_localMediaUtils, this).getDeviceById(videoDeviceId, 'videoinput');
426
+ this.currentDevices.video = this.#localMediaUtils.getDeviceById(videoDeviceId, 'videoinput');
476
427
  const videoConstraints = LocalMediaUtils.getVideoConstraints({
477
428
  videoDeviceId
478
429
  });
@@ -490,7 +441,7 @@ export default class LocalMediaHandler extends EventEmitter {
490
441
 
491
442
  // Setup Foreground Service after handling permissions
492
443
  if (Platform.OS === 'android') {
493
- _classPrivateFieldSet(_appStateSubscription, this, AppState.addEventListener('change', this._handleAppStateChange));
444
+ this.#appStateSubscription = AppState.addEventListener('change', this._handleAppStateChange);
494
445
  }
495
446
 
496
447
  // Start the meeting foreground service so Android keeps the app alive
@@ -504,22 +455,19 @@ export default class LocalMediaHandler extends EventEmitter {
504
455
  video = true
505
456
  } = tracks;
506
457
  if (audio) {
507
- var _this$screenShareTrac, _this$screenShareTrac2;
508
- (_this$screenShareTrac = this.screenShareTracks) === null || _this$screenShareTrac === void 0 || (_this$screenShareTrac = _this$screenShareTrac.audio) === null || _this$screenShareTrac === void 0 || _this$screenShareTrac.stop();
509
- (_this$screenShareTrac2 = this.screenShareTracks) === null || _this$screenShareTrac2 === void 0 || (_this$screenShareTrac2 = _this$screenShareTrac2.audio) === null || _this$screenShareTrac2 === void 0 || _this$screenShareTrac2.release();
458
+ this.screenShareTracks?.audio?.stop();
459
+ this.screenShareTracks?.audio?.release();
510
460
  }
511
461
  if (video) {
512
- var _this$screenShareTrac3, _this$screenShareTrac4;
513
- (_this$screenShareTrac3 = this.screenShareTracks) === null || _this$screenShareTrac3 === void 0 || (_this$screenShareTrac3 = _this$screenShareTrac3.video) === null || _this$screenShareTrac3 === void 0 || _this$screenShareTrac3.stop();
514
- (_this$screenShareTrac4 = this.screenShareTracks) === null || _this$screenShareTrac4 === void 0 || (_this$screenShareTrac4 = _this$screenShareTrac4.video) === null || _this$screenShareTrac4 === void 0 || _this$screenShareTrac4.release();
462
+ this.screenShareTracks?.video?.stop();
463
+ this.screenShareTracks?.video?.release();
515
464
  }
516
465
  if (audio && video) {
517
466
  this.screenShareEnabled = false;
518
467
  }
519
468
  }
520
469
  removeScreenShareTracks(tracks) {
521
- var _this$screenShareTrac5;
522
- (_this$screenShareTrac5 = this.screenShareTracks.video) === null || _this$screenShareTrac5 === void 0 || _this$screenShareTrac5.removeEventListener('ended', this.onScreenShareEnded);
470
+ this.screenShareTracks.video?.removeEventListener('ended', this.onScreenShareEnded);
523
471
  this.stopScreenShareTracks(tracks);
524
472
  this.screenShareTracks = {
525
473
  audio: undefined,
@@ -531,9 +479,8 @@ export default class LocalMediaHandler extends EventEmitter {
531
479
  return;
532
480
  }
533
481
  if (audioTrack === undefined) {
534
- var _this$rawAudioTrack2, _this$rawAudioTrack3;
535
- (_this$rawAudioTrack2 = this.rawAudioTrack) === null || _this$rawAudioTrack2 === void 0 || _this$rawAudioTrack2.stop();
536
- (_this$rawAudioTrack3 = this.rawAudioTrack) === null || _this$rawAudioTrack3 === void 0 || _this$rawAudioTrack3.release();
482
+ this.rawAudioTrack?.stop();
483
+ this.rawAudioTrack?.release();
537
484
  this.rawAudioTrack = undefined;
538
485
  }
539
486
  this.audioTrack = audioTrack;
@@ -543,15 +490,13 @@ export default class LocalMediaHandler extends EventEmitter {
543
490
  return;
544
491
  }
545
492
  if (videoTrack === undefined) {
546
- var _this$rawVideoTrack2, _this$rawVideoTrack3;
547
- (_this$rawVideoTrack2 = this.rawVideoTrack) === null || _this$rawVideoTrack2 === void 0 || _this$rawVideoTrack2.stop();
548
- (_this$rawVideoTrack3 = this.rawVideoTrack) === null || _this$rawVideoTrack3 === void 0 || _this$rawVideoTrack3.release();
493
+ this.rawVideoTrack?.stop();
494
+ this.rawVideoTrack?.release();
549
495
  this.rawVideoTrack = undefined;
550
496
  }
551
497
  this.videoTrack = videoTrack;
552
498
  }
553
499
  setScreenShareTracks(tracks) {
554
- var _this$screenShareTrac6;
555
500
  const {
556
501
  audio,
557
502
  video
@@ -563,8 +508,16 @@ export default class LocalMediaHandler extends EventEmitter {
563
508
  });
564
509
  }
565
510
  this.screenShareTracks = tracks;
566
- (_this$screenShareTrac6 = this.screenShareTracks.video) === null || _this$screenShareTrac6 === void 0 || _this$screenShareTrac6.addEventListener('ended', this.onScreenShareEnded);
511
+ this.screenShareTracks.video?.addEventListener('ended', this.onScreenShareEnded);
567
512
  }
513
+
514
+ // Arrow function so `this` is stable — the same reference is used in both
515
+ // addEventListener (setScreenShareTracks) and removeEventListener
516
+ // (removeScreenShareTracks). A regular method + .bind(this) creates a new
517
+ // function object on every call, making removeEventListener a no-op.
518
+ onScreenShareEnded = () => {
519
+ this.emit('SCREENSHARE_ENDED');
520
+ };
568
521
  async disableAudio() {
569
522
  await this.toggleAudio();
570
523
  }
@@ -597,12 +550,15 @@ export default class LocalMediaHandler extends EventEmitter {
597
550
  }
598
551
  try {
599
552
  /**
600
- * NOTE (@madhugb): We need to setup new stream,
601
- * if the audio track is not preset or it has ended
553
+ * NOTE: audioEnabled is set to true BEFORE setupAudioStream so that the
554
+ * AUDIO_TRACK_CHANGE event (emitted inside setupAudioStream) sees the
555
+ * correct enabled state and the Self.ts handler calls shareMic()
556
+ * immediately.
557
+ * If track acquisition fails, audioEnabled is rolled back to false below.
602
558
  */
559
+ this.audioEnabled = true;
603
560
  if (!this.audioTrack || this.audioTrack.readyState === 'ended') {
604
- var _this$currentDevices$6;
605
- await this.setupAudioStream((_this$currentDevices$6 = this.currentDevices.audio) === null || _this$currentDevices$6 === void 0 ? void 0 : _this$currentDevices$6.deviceId);
561
+ await this.setupAudioStream(this.currentDevices.audio?.deviceId);
606
562
  }
607
563
  // if we still can't get a track after setting up audio stream
608
564
  // do not toggle the audio state
@@ -610,7 +566,6 @@ export default class LocalMediaHandler extends EventEmitter {
610
566
  this.audioEnabled = false;
611
567
  return;
612
568
  }
613
- this.audioEnabled = true;
614
569
  } catch (ex) {
615
570
  this.audioEnabled = false;
616
571
  this.audioTrack = undefined;
@@ -627,7 +582,6 @@ export default class LocalMediaHandler extends EventEmitter {
627
582
  await this.toggleVideo();
628
583
  }
629
584
  async toggleVideo() {
630
- var _this$currentDevices$7;
631
585
  if (this.permissions.video !== 'ACCEPTED') {
632
586
  try {
633
587
  const permResult = await setupPermissions(false, true);
@@ -645,9 +599,8 @@ export default class LocalMediaHandler extends EventEmitter {
645
599
  return;
646
600
  }
647
601
  if (this.videoEnabled) {
648
- var _this$rawVideoTrack4, _this$rawVideoTrack5;
649
- (_this$rawVideoTrack4 = this.rawVideoTrack) === null || _this$rawVideoTrack4 === void 0 || _this$rawVideoTrack4.stop();
650
- (_this$rawVideoTrack5 = this.rawVideoTrack) === null || _this$rawVideoTrack5 === void 0 || _this$rawVideoTrack5.release();
602
+ this.rawVideoTrack?.stop();
603
+ this.rawVideoTrack?.release();
651
604
  this.rawVideoTrack = undefined;
652
605
  this.videoEnabled = false;
653
606
  return;
@@ -657,16 +610,15 @@ export default class LocalMediaHandler extends EventEmitter {
657
610
  * hence it must be set to true first.
658
611
  */
659
612
  this.videoEnabled = true;
660
- await this.setupVideoStream((_this$currentDevices$7 = this.currentDevices.video) === null || _this$currentDevices$7 === void 0 ? void 0 : _this$currentDevices$7.deviceId);
613
+ await this.setupVideoStream(this.currentDevices.video?.deviceId);
661
614
  }
662
615
  async setAudioDevice(device) {
663
616
  await this.setupAudioStream(device.deviceId);
664
617
  }
665
618
  async setVideoDevice(device) {
666
619
  if (this.videoEnabled) {
667
- var _this$rawVideoTrack6, _this$rawVideoTrack7;
668
- (_this$rawVideoTrack6 = this.rawVideoTrack) === null || _this$rawVideoTrack6 === void 0 || _this$rawVideoTrack6.stop();
669
- (_this$rawVideoTrack7 = this.rawVideoTrack) === null || _this$rawVideoTrack7 === void 0 || _this$rawVideoTrack7.release();
620
+ this.rawVideoTrack?.stop();
621
+ this.rawVideoTrack?.release();
670
622
  this.rawVideoTrack = undefined;
671
623
  }
672
624
  await this.setupVideoStream(device.deviceId);
@@ -675,15 +627,15 @@ export default class LocalMediaHandler extends EventEmitter {
675
627
  await this.setupSpeaker(device.deviceId);
676
628
  }
677
629
  async setDevice(route) {
678
- await _classPrivateFieldGet(_localMediaUtils, this).chooseAudioRoute(route.deviceId);
630
+ await this.#localMediaUtils.chooseAudioRoute(route.deviceId);
679
631
  }
680
632
  async oniOSBroadcastStart() {
681
633
  this.setScreenShareTracks(await LocalMediaUtils.getScreenShareTracks());
682
634
  this.screenShareEnabled = true;
683
- _classPrivateFieldSet(_screenShareState, this, 'STARTED');
635
+ this.#screenShareState = 'STARTED';
684
636
  }
685
637
  async oniOSBroadcastStop() {
686
- _classPrivateFieldSet(_screenShareState, this, 'STOPPED');
638
+ this.#screenShareState = 'STOPPED';
687
639
  if (this.screenShareEnabled) {
688
640
  this.removeScreenShareTracks();
689
641
  return;
@@ -707,13 +659,13 @@ export default class LocalMediaHandler extends EventEmitter {
707
659
  }
708
660
  }
709
661
  if (Platform.OS === 'ios') {
710
- _classPrivateFieldSet(_screenShareState, this, 'PENDING');
662
+ this.#screenShareState = 'PENDING';
711
663
  NativeModules.RTKScreensharePickerView.showScreenSharePickerView();
712
664
  await new Promise((resolve, reject) => {
713
665
  let timeoutId;
714
666
  let time = 0;
715
667
  timeoutId = setInterval(() => {
716
- if (_classPrivateFieldGet(_screenShareState, this) === 'STARTED') {
668
+ if (this.#screenShareState === 'STARTED') {
717
669
  clearInterval(timeoutId);
718
670
  resolve();
719
671
  }
@@ -736,12 +688,12 @@ export default class LocalMediaHandler extends EventEmitter {
736
688
 
737
689
  // iOS: trigger the broadcast picker to stop the extension.
738
690
  NativeModules.RTKScreensharePickerView.showScreenSharePickerView();
739
- _classPrivateFieldSet(_screenShareState, this, 'PENDING');
691
+ this.#screenShareState = 'PENDING';
740
692
  await new Promise((resolve, reject) => {
741
693
  let timeoutId;
742
694
  let time = 0;
743
695
  timeoutId = setInterval(() => {
744
- if (_classPrivateFieldGet(_screenShareState, this) === 'STOPPED') {
696
+ if (this.#screenShareState === 'STOPPED') {
745
697
  clearInterval(timeoutId);
746
698
  resolve();
747
699
  }
@@ -754,22 +706,22 @@ export default class LocalMediaHandler extends EventEmitter {
754
706
  });
755
707
  }
756
708
  getAllDevices() {
757
- return _classPrivateFieldGet(_localMediaUtils, this).availableDevices;
709
+ return this.#localMediaUtils.availableDevices;
758
710
  }
759
711
  getCurrentDevices() {
760
712
  return this.currentDevices;
761
713
  }
762
714
  getDeviceById(deviceId, kind) {
763
- return _classPrivateFieldGet(_localMediaUtils, this).getDeviceById(deviceId, kind);
715
+ return this.#localMediaUtils.getDeviceById(deviceId, kind);
764
716
  }
765
717
  async getAudioDevices() {
766
- const devices = await _classPrivateFieldGet(_localMediaUtils, this).getAudioDevices();
718
+ const devices = await this.#localMediaUtils.getAudioDevices();
767
719
 
768
720
  // Update current audio device from native layer
769
721
  try {
770
722
  const currentDeviceId = await NativeAudioManager.getCurrentAudioDevice();
771
723
  if (currentDeviceId) {
772
- const currentDevice = _classPrivateFieldGet(_localMediaUtils, this).getDeviceById(currentDeviceId, 'audioinput');
724
+ const currentDevice = this.#localMediaUtils.getDeviceById(currentDeviceId, 'audioinput');
773
725
  if (currentDevice) {
774
726
  this.currentDevices.audio = currentDevice;
775
727
  }
@@ -780,16 +732,16 @@ export default class LocalMediaHandler extends EventEmitter {
780
732
  return devices;
781
733
  }
782
734
  async getVideoDevices() {
783
- return await _classPrivateFieldGet(_localMediaUtils, this).getVideoDevices();
735
+ return await this.#localMediaUtils.getVideoDevices();
784
736
  }
785
737
  async getSpeakerDevices() {
786
- const devices = await _classPrivateFieldGet(_localMediaUtils, this).getSpeakerDevices();
738
+ const devices = await this.#localMediaUtils.getSpeakerDevices();
787
739
 
788
740
  // Update current speaker device from native layer
789
741
  try {
790
742
  const currentDeviceId = await NativeAudioManager.getCurrentAudioDevice();
791
743
  if (currentDeviceId) {
792
- const currentDevice = _classPrivateFieldGet(_localMediaUtils, this).getDeviceById(currentDeviceId, 'audioinput');
744
+ const currentDevice = this.#localMediaUtils.getDeviceById(currentDeviceId, 'audioinput');
793
745
  if (currentDevice) {
794
746
  this.currentDevices.speaker = currentDevice;
795
747
  this.currentDevices.audio = currentDevice;
@@ -808,7 +760,7 @@ export default class LocalMediaHandler extends EventEmitter {
808
760
 
809
761
  // Update currentDevices.speaker when platform reports selected device change
810
762
  if (changedDevices.selectedDevice) {
811
- const selectedDeviceInfo = _classPrivateFieldGet(_localMediaUtils, this).getDeviceById(changedDevices.selectedDevice, 'audioinput');
763
+ const selectedDeviceInfo = this.#localMediaUtils.getDeviceById(changedDevices.selectedDevice, 'audioinput');
812
764
  if (selectedDeviceInfo) {
813
765
  this.currentDevices.speaker = selectedDeviceInfo;
814
766
  this.currentDevices.audio = selectedDeviceInfo;
@@ -822,9 +774,9 @@ export default class LocalMediaHandler extends EventEmitter {
822
774
  */
823
775
  if (addedDevice) {
824
776
  // Clear any pending device removal timeout when a device is added
825
- if (_classPrivateFieldGet(_deviceRemovalTimeout, this)) {
826
- clearTimeout(_classPrivateFieldGet(_deviceRemovalTimeout, this));
827
- _classPrivateFieldSet(_deviceRemovalTimeout, this, null);
777
+ if (this.#deviceRemovalTimeout) {
778
+ clearTimeout(this.#deviceRemovalTimeout);
779
+ this.#deviceRemovalTimeout = null;
828
780
  }
829
781
  if (addedDevice.kind === 'audioinput') {
830
782
  if (this.permissions.audio === 'DENIED' || this.permissions.audio === 'NOT_REQUESTED') {
@@ -862,7 +814,7 @@ export default class LocalMediaHandler extends EventEmitter {
862
814
  };
863
815
  if (isBluetoothRemoved) {
864
816
  // Wait 500ms before switching away from Bluetooth to allow for reconnection
865
- _classPrivateFieldSet(_deviceRemovalTimeout, this, setTimeout(handleRemoval, 500));
817
+ this.#deviceRemovalTimeout = setTimeout(handleRemoval, 500);
866
818
  } else {
867
819
  // For other devices, handle removal immediately
868
820
  await handleRemoval();
@@ -924,28 +876,25 @@ export default class LocalMediaHandler extends EventEmitter {
924
876
  return super.on(event, listener);
925
877
  }
926
878
  destruct() {
927
- var _classPrivateFieldGet2;
928
879
  this.stopAudioTrack();
929
880
  this.stopVideoTrack();
930
881
  this.stopScreenShareTracks();
931
- if (Platform.OS === 'android') (_classPrivateFieldGet2 = _classPrivateFieldGet(_appStateSubscription, this)) === null || _classPrivateFieldGet2 === void 0 || _classPrivateFieldGet2.remove();
882
+ if (Platform.OS === 'android') this.#appStateSubscription?.remove();
932
883
  }
933
884
  stopAudioTrack() {
934
- var _this$rawAudioTrack4, _this$audioTrack3, _this$rawAudioTrack5, _this$audioTrack4;
935
- (_this$rawAudioTrack4 = this.rawAudioTrack) === null || _this$rawAudioTrack4 === void 0 || _this$rawAudioTrack4.stop();
936
- (_this$audioTrack3 = this.audioTrack) === null || _this$audioTrack3 === void 0 || _this$audioTrack3.stop();
937
- (_this$rawAudioTrack5 = this.rawAudioTrack) === null || _this$rawAudioTrack5 === void 0 || _this$rawAudioTrack5.release();
938
- (_this$audioTrack4 = this.audioTrack) === null || _this$audioTrack4 === void 0 || _this$audioTrack4.release();
885
+ this.rawAudioTrack?.stop();
886
+ this.audioTrack?.stop();
887
+ this.rawAudioTrack?.release();
888
+ this.audioTrack?.release();
939
889
  this.audioEnabled = false;
940
890
  this.audioTrack = undefined;
941
891
  this.rawAudioTrack = undefined;
942
892
  }
943
893
  stopVideoTrack() {
944
- var _this$rawVideoTrack8, _this$videoTrack3, _this$rawVideoTrack9, _this$videoTrack4;
945
- (_this$rawVideoTrack8 = this.rawVideoTrack) === null || _this$rawVideoTrack8 === void 0 || _this$rawVideoTrack8.stop();
946
- (_this$videoTrack3 = this.videoTrack) === null || _this$videoTrack3 === void 0 || _this$videoTrack3.stop();
947
- (_this$rawVideoTrack9 = this.rawVideoTrack) === null || _this$rawVideoTrack9 === void 0 || _this$rawVideoTrack9.release();
948
- (_this$videoTrack4 = this.videoTrack) === null || _this$videoTrack4 === void 0 || _this$videoTrack4.release();
894
+ this.rawVideoTrack?.stop();
895
+ this.videoTrack?.stop();
896
+ this.rawVideoTrack?.release();
897
+ this.videoTrack?.release();
949
898
  this.videoTrack = undefined;
950
899
  this.rawVideoTrack = undefined;
951
900
  }