@waitaya.buc/client-js 0.1.0-alpha.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.
Files changed (166) hide show
  1. package/README.md +179 -0
  2. package/dist/adapters/livekit/api/recording.api.d.ts +15 -0
  3. package/dist/adapters/livekit/api/recording.api.d.ts.map +1 -0
  4. package/dist/adapters/livekit/api/recording.api.js +61 -0
  5. package/dist/adapters/livekit/api/recording.api.js.map +1 -0
  6. package/dist/adapters/livekit/index.d.ts +18 -0
  7. package/dist/adapters/livekit/index.d.ts.map +1 -0
  8. package/dist/adapters/livekit/index.js +26 -0
  9. package/dist/adapters/livekit/index.js.map +1 -0
  10. package/dist/adapters/livekit/livekit.adapter.d.ts +85 -0
  11. package/dist/adapters/livekit/livekit.adapter.d.ts.map +1 -0
  12. package/dist/adapters/livekit/livekit.adapter.js +531 -0
  13. package/dist/adapters/livekit/livekit.adapter.js.map +1 -0
  14. package/dist/adapters/livekit/livekit.mapper.d.ts +36 -0
  15. package/dist/adapters/livekit/livekit.mapper.d.ts.map +1 -0
  16. package/dist/adapters/livekit/livekit.mapper.js +108 -0
  17. package/dist/adapters/livekit/livekit.mapper.js.map +1 -0
  18. package/dist/adapters/livekit/livekit.types.d.ts +22 -0
  19. package/dist/adapters/livekit/livekit.types.d.ts.map +1 -0
  20. package/dist/adapters/livekit/livekit.types.js +10 -0
  21. package/dist/adapters/livekit/livekit.types.js.map +1 -0
  22. package/dist/adapters/livekit/service-adapters/index.d.ts +4 -0
  23. package/dist/adapters/livekit/service-adapters/index.d.ts.map +1 -0
  24. package/dist/adapters/livekit/service-adapters/index.js +4 -0
  25. package/dist/adapters/livekit/service-adapters/index.js.map +1 -0
  26. package/dist/adapters/livekit/service-adapters/recording.adapter.d.ts +19 -0
  27. package/dist/adapters/livekit/service-adapters/recording.adapter.d.ts.map +1 -0
  28. package/dist/adapters/livekit/service-adapters/recording.adapter.js +30 -0
  29. package/dist/adapters/livekit/service-adapters/recording.adapter.js.map +1 -0
  30. package/dist/adapters/livekit/service-adapters/stats.adapter.d.ts +21 -0
  31. package/dist/adapters/livekit/service-adapters/stats.adapter.d.ts.map +1 -0
  32. package/dist/adapters/livekit/service-adapters/stats.adapter.js +54 -0
  33. package/dist/adapters/livekit/service-adapters/stats.adapter.js.map +1 -0
  34. package/dist/adapters/livekit/service-adapters/track-attachment.adapter.d.ts +79 -0
  35. package/dist/adapters/livekit/service-adapters/track-attachment.adapter.d.ts.map +1 -0
  36. package/dist/adapters/livekit/service-adapters/track-attachment.adapter.js +348 -0
  37. package/dist/adapters/livekit/service-adapters/track-attachment.adapter.js.map +1 -0
  38. package/dist/adapters/livekit/services/index.d.ts +3 -0
  39. package/dist/adapters/livekit/services/index.d.ts.map +1 -0
  40. package/dist/adapters/livekit/services/index.js +3 -0
  41. package/dist/adapters/livekit/services/index.js.map +1 -0
  42. package/dist/adapters/livekit/services/recording.service.d.ts +29 -0
  43. package/dist/adapters/livekit/services/recording.service.d.ts.map +1 -0
  44. package/dist/adapters/livekit/services/recording.service.js +34 -0
  45. package/dist/adapters/livekit/services/recording.service.js.map +1 -0
  46. package/dist/adapters/livekit/services/stats.service.d.ts +24 -0
  47. package/dist/adapters/livekit/services/stats.service.d.ts.map +1 -0
  48. package/dist/adapters/livekit/services/stats.service.js +56 -0
  49. package/dist/adapters/livekit/services/stats.service.js.map +1 -0
  50. package/dist/core/api/auth.api.d.ts +52 -0
  51. package/dist/core/api/auth.api.d.ts.map +1 -0
  52. package/dist/core/api/auth.api.js +59 -0
  53. package/dist/core/api/auth.api.js.map +1 -0
  54. package/dist/core/api/http.d.ts +86 -0
  55. package/dist/core/api/http.d.ts.map +1 -0
  56. package/dist/core/api/http.js +146 -0
  57. package/dist/core/api/http.js.map +1 -0
  58. package/dist/core/errors/error-codes.d.ts +43 -0
  59. package/dist/core/errors/error-codes.d.ts.map +1 -0
  60. package/dist/core/errors/error-codes.js +42 -0
  61. package/dist/core/errors/error-codes.js.map +1 -0
  62. package/dist/core/errors/vroom.error.d.ts +99 -0
  63. package/dist/core/errors/vroom.error.d.ts.map +1 -0
  64. package/dist/core/errors/vroom.error.js +141 -0
  65. package/dist/core/errors/vroom.error.js.map +1 -0
  66. package/dist/core/ports/outbound/provider-adapter-factory.port.d.ts +41 -0
  67. package/dist/core/ports/outbound/provider-adapter-factory.port.d.ts.map +1 -0
  68. package/dist/core/ports/outbound/provider-adapter-factory.port.js +2 -0
  69. package/dist/core/ports/outbound/provider-adapter-factory.port.js.map +1 -0
  70. package/dist/core/ports/outbound/provider-adapter.port.d.ts +130 -0
  71. package/dist/core/ports/outbound/provider-adapter.port.d.ts.map +1 -0
  72. package/dist/core/ports/outbound/provider-adapter.port.js +2 -0
  73. package/dist/core/ports/outbound/provider-adapter.port.js.map +1 -0
  74. package/dist/core/ports/outbound/recording-adapter.port.d.ts +40 -0
  75. package/dist/core/ports/outbound/recording-adapter.port.d.ts.map +1 -0
  76. package/dist/core/ports/outbound/recording-adapter.port.js +2 -0
  77. package/dist/core/ports/outbound/recording-adapter.port.js.map +1 -0
  78. package/dist/core/ports/outbound/stats-adapter.port.d.ts +31 -0
  79. package/dist/core/ports/outbound/stats-adapter.port.d.ts.map +1 -0
  80. package/dist/core/ports/outbound/stats-adapter.port.js +2 -0
  81. package/dist/core/ports/outbound/stats-adapter.port.js.map +1 -0
  82. package/dist/core/ports/outbound/track-attachment-adapter.port.d.ts +86 -0
  83. package/dist/core/ports/outbound/track-attachment-adapter.port.d.ts.map +1 -0
  84. package/dist/core/ports/outbound/track-attachment-adapter.port.js +2 -0
  85. package/dist/core/ports/outbound/track-attachment-adapter.port.js.map +1 -0
  86. package/dist/core/provider-registry.d.ts +29 -0
  87. package/dist/core/provider-registry.d.ts.map +1 -0
  88. package/dist/core/provider-registry.js +45 -0
  89. package/dist/core/provider-registry.js.map +1 -0
  90. package/dist/core/services/base.service.d.ts +15 -0
  91. package/dist/core/services/base.service.d.ts.map +1 -0
  92. package/dist/core/services/base.service.js +10 -0
  93. package/dist/core/services/base.service.js.map +1 -0
  94. package/dist/core/services/recording.service.d.ts +50 -0
  95. package/dist/core/services/recording.service.d.ts.map +1 -0
  96. package/dist/core/services/recording.service.js +89 -0
  97. package/dist/core/services/recording.service.js.map +1 -0
  98. package/dist/core/services/stats.service.d.ts +32 -0
  99. package/dist/core/services/stats.service.d.ts.map +1 -0
  100. package/dist/core/services/stats.service.js +69 -0
  101. package/dist/core/services/stats.service.js.map +1 -0
  102. package/dist/core/session.d.ts +142 -0
  103. package/dist/core/session.d.ts.map +1 -0
  104. package/dist/core/session.js +248 -0
  105. package/dist/core/session.js.map +1 -0
  106. package/dist/core/types/events.types.d.ts +263 -0
  107. package/dist/core/types/events.types.d.ts.map +1 -0
  108. package/dist/core/types/events.types.js +76 -0
  109. package/dist/core/types/events.types.js.map +1 -0
  110. package/dist/core/types/media.types.d.ts +81 -0
  111. package/dist/core/types/media.types.d.ts.map +1 -0
  112. package/dist/core/types/media.types.js +12 -0
  113. package/dist/core/types/media.types.js.map +1 -0
  114. package/dist/core/types/participant.types.d.ts +11 -0
  115. package/dist/core/types/participant.types.d.ts.map +1 -0
  116. package/dist/core/types/participant.types.js +2 -0
  117. package/dist/core/types/participant.types.js.map +1 -0
  118. package/dist/core/types/recording.types.d.ts +60 -0
  119. package/dist/core/types/recording.types.d.ts.map +1 -0
  120. package/dist/core/types/recording.types.js +7 -0
  121. package/dist/core/types/recording.types.js.map +1 -0
  122. package/dist/core/types/service-adapters.types.d.ts +46 -0
  123. package/dist/core/types/service-adapters.types.d.ts.map +1 -0
  124. package/dist/core/types/service-adapters.types.js +2 -0
  125. package/dist/core/types/service-adapters.types.js.map +1 -0
  126. package/dist/core/types/session.types.d.ts +57 -0
  127. package/dist/core/types/session.types.d.ts.map +1 -0
  128. package/dist/core/types/session.types.js +2 -0
  129. package/dist/core/types/session.types.js.map +1 -0
  130. package/dist/core/types/stats.types.d.ts +20 -0
  131. package/dist/core/types/stats.types.d.ts.map +1 -0
  132. package/dist/core/types/stats.types.js +7 -0
  133. package/dist/core/types/stats.types.js.map +1 -0
  134. package/dist/core/types/token.types.d.ts +82 -0
  135. package/dist/core/types/token.types.d.ts.map +1 -0
  136. package/dist/core/types/token.types.js +27 -0
  137. package/dist/core/types/token.types.js.map +1 -0
  138. package/dist/core/types/track.types.d.ts +39 -0
  139. package/dist/core/types/track.types.d.ts.map +1 -0
  140. package/dist/core/types/track.types.js +9 -0
  141. package/dist/core/types/track.types.js.map +1 -0
  142. package/dist/core/types/user.types.d.ts +23 -0
  143. package/dist/core/types/user.types.d.ts.map +1 -0
  144. package/dist/core/types/user.types.js +2 -0
  145. package/dist/core/types/user.types.js.map +1 -0
  146. package/dist/core/types/vroom.types.d.ts +86 -0
  147. package/dist/core/types/vroom.types.d.ts.map +1 -0
  148. package/dist/core/types/vroom.types.js +12 -0
  149. package/dist/core/types/vroom.types.js.map +1 -0
  150. package/dist/core/utils/token.d.ts +77 -0
  151. package/dist/core/utils/token.d.ts.map +1 -0
  152. package/dist/core/utils/token.js +127 -0
  153. package/dist/core/utils/token.js.map +1 -0
  154. package/dist/core/vroom.d.ts +90 -0
  155. package/dist/core/vroom.d.ts.map +1 -0
  156. package/dist/core/vroom.js +219 -0
  157. package/dist/core/vroom.js.map +1 -0
  158. package/dist/index.d.ts +25 -0
  159. package/dist/index.d.ts.map +1 -0
  160. package/dist/index.js +17 -0
  161. package/dist/index.js.map +1 -0
  162. package/dist/react-native.d.ts +21 -0
  163. package/dist/react-native.d.ts.map +1 -0
  164. package/dist/react-native.js +32 -0
  165. package/dist/react-native.js.map +1 -0
  166. package/package.json +50 -0
@@ -0,0 +1,348 @@
1
+ import { RoomEvent, RemoteVideoTrack, } from 'livekit-client';
2
+ /**
3
+ * ElementInfo implementation for mobile platforms (React Native, etc.).
4
+ *
5
+ * This class implements LiveKit's ElementInfo interface to enable adaptive streaming
6
+ * on mobile platforms where there's no DOM element to observe.
7
+ *
8
+ * @see https://github.com/livekit/client-sdk-react-native
9
+ */
10
+ class MobileViewElementInfo {
11
+ constructor(width = 0, height = 0, visible = true) {
12
+ this.element = {};
13
+ this._observing = false;
14
+ this.pictureInPicture = false;
15
+ this.width = () => this._width;
16
+ this.height = () => this._height;
17
+ this._width = width;
18
+ this._height = height;
19
+ this.visible = visible;
20
+ }
21
+ observe() {
22
+ this._observing = true;
23
+ }
24
+ stopObserving() {
25
+ this._observing = false;
26
+ }
27
+ /**
28
+ * Update dimensions when layout changes
29
+ */
30
+ setDimensions(width, height) {
31
+ this._width = width;
32
+ this._height = height;
33
+ if (this._observing) {
34
+ this.handleResize?.();
35
+ }
36
+ }
37
+ /**
38
+ * Update visibility state
39
+ */
40
+ setVisible(visible) {
41
+ if (this.visible !== visible) {
42
+ this.visible = visible;
43
+ this.visibilityChangedAt = Date.now();
44
+ if (this._observing) {
45
+ this.handleVisibilityChanged?.();
46
+ }
47
+ }
48
+ }
49
+ }
50
+ /**
51
+ * LiveKit implementation of TrackAttachmentAdapter.
52
+ *
53
+ * Uses LiveKit's track.attach() method to properly attach tracks to elements.
54
+ * This is necessary because LiveKit uses adaptive streaming that requires
55
+ * knowing which elements are displaying tracks for proper frame delivery.
56
+ *
57
+ * Features:
58
+ * - Automatic pending queue: If attach() is called before track is subscribed,
59
+ * the request is queued and automatically fulfilled when track becomes available.
60
+ * - Handles race conditions between TrackAdded event and actual track subscription.
61
+ * - React Native support via registerTrackView/unregisterTrackView methods.
62
+ */
63
+ export class LiveKitTrackAttachmentAdapter {
64
+ constructor(room) {
65
+ /** Pending attachments waiting for tracks to be subscribed (Web) */
66
+ this.pendingAttachments = new Map();
67
+ /** Pending view registrations waiting for tracks to be subscribed (Mobile) */
68
+ this.pendingViews = new Map();
69
+ /** Active view registrations (Mobile) */
70
+ this.activeViews = new Map();
71
+ /** ElementInfo instances for each view (Mobile) - Map<trackId, Map<viewId, ElementInfo>> */
72
+ this.elementInfos = new Map();
73
+ /** Cleanup functions for event listeners */
74
+ this.cleanupFns = [];
75
+ this.room = room;
76
+ this.setupEventListeners();
77
+ }
78
+ attach(trackId, element) {
79
+ const lkTrack = this.findLiveKitTrack(trackId);
80
+ if (lkTrack) {
81
+ lkTrack.attach(element);
82
+ }
83
+ else {
84
+ // Queue for later when track becomes available
85
+ if (!this.pendingAttachments.has(trackId)) {
86
+ this.pendingAttachments.set(trackId, new Set());
87
+ }
88
+ this.pendingAttachments.get(trackId).add(element);
89
+ }
90
+ }
91
+ detach(trackId, element) {
92
+ // Remove from pending queue first
93
+ if (element) {
94
+ const pendingSet = this.pendingAttachments.get(trackId);
95
+ if (pendingSet) {
96
+ pendingSet.delete(element);
97
+ // Cleanup empty entry to prevent memory buildup
98
+ if (pendingSet.size === 0) {
99
+ this.pendingAttachments.delete(trackId);
100
+ }
101
+ }
102
+ }
103
+ else {
104
+ this.pendingAttachments.delete(trackId);
105
+ }
106
+ // Then detach from actual track if available
107
+ const lkTrack = this.findLiveKitTrack(trackId);
108
+ if (lkTrack) {
109
+ if (element) {
110
+ lkTrack.detach(element);
111
+ }
112
+ else {
113
+ lkTrack.detach();
114
+ }
115
+ }
116
+ }
117
+ registerTrackView(trackId, viewId, options) {
118
+ const lkTrack = this.findLiveKitTrack(trackId);
119
+ if (lkTrack) {
120
+ // Track is available - register view and setup adaptive streaming
121
+ this.addActiveView(trackId, viewId);
122
+ this.observeTrackIfNeeded(trackId, viewId, lkTrack, options);
123
+ return this.getStreamUrl(lkTrack);
124
+ }
125
+ // Track not ready yet - queue for later with options
126
+ if (!this.pendingViews.has(trackId)) {
127
+ this.pendingViews.set(trackId, new Map());
128
+ }
129
+ this.pendingViews.get(trackId).set(viewId, {
130
+ viewId,
131
+ width: options?.width,
132
+ height: options?.height,
133
+ visible: options?.visible,
134
+ onReady: options?.onReady,
135
+ });
136
+ return null;
137
+ }
138
+ unregisterTrackView(trackId, viewId) {
139
+ if (viewId) {
140
+ // Remove specific view
141
+ this.pendingViews.get(trackId)?.delete(viewId);
142
+ if (this.pendingViews.get(trackId)?.size === 0) {
143
+ this.pendingViews.delete(trackId);
144
+ }
145
+ // Stop observing and cleanup ElementInfo
146
+ this.stopObservingTrack(trackId, viewId);
147
+ this.activeViews.get(trackId)?.delete(viewId);
148
+ if (this.activeViews.get(trackId)?.size === 0) {
149
+ this.activeViews.delete(trackId);
150
+ }
151
+ }
152
+ else {
153
+ // Remove all views for this track
154
+ this.pendingViews.delete(trackId);
155
+ // Stop observing all ElementInfos for this track
156
+ const viewInfos = this.elementInfos.get(trackId);
157
+ if (viewInfos) {
158
+ for (const vid of viewInfos.keys()) {
159
+ this.stopObservingTrack(trackId, vid);
160
+ }
161
+ }
162
+ this.activeViews.delete(trackId);
163
+ }
164
+ }
165
+ updateTrackViewLayout(trackId, viewId, width, height) {
166
+ const elementInfo = this.elementInfos.get(trackId)?.get(viewId);
167
+ if (elementInfo) {
168
+ elementInfo.setDimensions(width, height);
169
+ }
170
+ }
171
+ updateTrackViewVisibility(trackId, viewId, visible) {
172
+ const elementInfo = this.elementInfos.get(trackId)?.get(viewId);
173
+ if (elementInfo) {
174
+ elementInfo.setVisible(visible);
175
+ }
176
+ }
177
+ destroy() {
178
+ // Cleanup all event listeners
179
+ this.cleanupFns.forEach((fn) => fn());
180
+ this.cleanupFns = [];
181
+ // Stop observing all ElementInfos
182
+ for (const [trackId, viewInfos] of this.elementInfos) {
183
+ const lkTrack = this.findLiveKitTrack(trackId);
184
+ if (lkTrack instanceof RemoteVideoTrack) {
185
+ for (const elementInfo of viewInfos.values()) {
186
+ lkTrack.stopObservingElementInfo(elementInfo);
187
+ }
188
+ }
189
+ }
190
+ // Clear pending queues
191
+ this.pendingAttachments.clear();
192
+ this.pendingViews.clear();
193
+ this.activeViews.clear();
194
+ this.elementInfos.clear();
195
+ }
196
+ /**
197
+ * Setup event listeners for track lifecycle management.
198
+ * - TrackSubscribed: Fulfill pending attachment requests (Web) and pending view registrations (Mobile)
199
+ * - TrackUnsubscribed: Cleanup pending requests that will never arrive
200
+ */
201
+ setupEventListeners() {
202
+ // Handle track subscribed - fulfill pending attachments and views
203
+ const onTrackSubscribed = (track) => {
204
+ const trackId = track.sid;
205
+ if (!trackId)
206
+ return;
207
+ // Fulfill pending Web attachments
208
+ if (this.pendingAttachments.has(trackId)) {
209
+ const elements = this.pendingAttachments.get(trackId);
210
+ elements.forEach((el) => track.attach(el));
211
+ this.pendingAttachments.delete(trackId);
212
+ }
213
+ // Fulfill pending mobile view registrations
214
+ if (this.pendingViews.has(trackId)) {
215
+ const views = this.pendingViews.get(trackId);
216
+ const streamUrl = this.getStreamUrl(track);
217
+ views.forEach((pendingView) => {
218
+ this.addActiveView(trackId, pendingView.viewId);
219
+ // Setup adaptive streaming observation with pending options
220
+ this.observeTrackIfNeeded(trackId, pendingView.viewId, track, {
221
+ width: pendingView.width,
222
+ height: pendingView.height,
223
+ visible: pendingView.visible,
224
+ });
225
+ pendingView.onReady?.(streamUrl);
226
+ });
227
+ this.pendingViews.delete(trackId);
228
+ }
229
+ };
230
+ // Handle track unsubscribed - cleanup pending requests that will never be fulfilled
231
+ const onTrackUnsubscribed = (track) => {
232
+ const trackId = track.sid;
233
+ if (trackId) {
234
+ this.pendingAttachments.delete(trackId);
235
+ this.pendingViews.delete(trackId);
236
+ this.activeViews.delete(trackId);
237
+ // Cleanup all ElementInfos for this track
238
+ const viewInfos = this.elementInfos.get(trackId);
239
+ if (viewInfos) {
240
+ for (const elementInfo of viewInfos.values()) {
241
+ if (track instanceof RemoteVideoTrack) {
242
+ track.stopObservingElementInfo(elementInfo);
243
+ }
244
+ }
245
+ this.elementInfos.delete(trackId);
246
+ }
247
+ }
248
+ };
249
+ this.room.on(RoomEvent.TrackSubscribed, onTrackSubscribed);
250
+ this.room.on(RoomEvent.TrackUnsubscribed, onTrackUnsubscribed);
251
+ this.cleanupFns.push(() => this.room.off(RoomEvent.TrackSubscribed, onTrackSubscribed), () => this.room.off(RoomEvent.TrackUnsubscribed, onTrackUnsubscribed));
252
+ }
253
+ /**
254
+ * Find LiveKit Track by track SID from all participants
255
+ */
256
+ findLiveKitTrack(trackId) {
257
+ // Search in local participant
258
+ for (const pub of this.room.localParticipant.trackPublications.values()) {
259
+ if (pub.trackSid === trackId && pub.track) {
260
+ return pub.track;
261
+ }
262
+ }
263
+ // Search in remote participants
264
+ for (const participant of this.room.remoteParticipants.values()) {
265
+ for (const pub of participant.trackPublications.values()) {
266
+ if (pub.trackSid === trackId && pub.track) {
267
+ return pub.track;
268
+ }
269
+ }
270
+ }
271
+ return undefined;
272
+ }
273
+ /**
274
+ * Add a view to the active views set for a track
275
+ */
276
+ addActiveView(trackId, viewId) {
277
+ if (!this.activeViews.has(trackId)) {
278
+ this.activeViews.set(trackId, new Set());
279
+ }
280
+ this.activeViews.get(trackId).add(viewId);
281
+ }
282
+ /**
283
+ * Setup adaptive streaming observation for a track view.
284
+ *
285
+ * For RemoteVideoTrack with adaptive streaming enabled, this creates an ElementInfo
286
+ * and calls observeElementInfo() to tell LiveKit that a view is displaying the track.
287
+ * This is critical for adaptive streaming to work on mobile platforms.
288
+ *
289
+ * @see https://github.com/livekit/client-sdk-react-native
290
+ */
291
+ observeTrackIfNeeded(trackId, viewId, lkTrack, options) {
292
+ // Only observe RemoteVideoTrack with adaptive streaming
293
+ if (!(lkTrack instanceof RemoteVideoTrack)) {
294
+ return;
295
+ }
296
+ // Check if adaptive streaming is enabled
297
+ if (!lkTrack.isAdaptiveStream) {
298
+ return;
299
+ }
300
+ // Create ElementInfo for this view
301
+ const elementInfo = new MobileViewElementInfo(options?.width ?? 0, options?.height ?? 0, options?.visible ?? true);
302
+ // Store the ElementInfo
303
+ if (!this.elementInfos.has(trackId)) {
304
+ this.elementInfos.set(trackId, new Map());
305
+ }
306
+ this.elementInfos.get(trackId).set(viewId, elementInfo);
307
+ // Tell LiveKit to observe this ElementInfo for adaptive streaming
308
+ lkTrack.observeElementInfo(elementInfo);
309
+ }
310
+ /**
311
+ * Stop observing a track view for adaptive streaming.
312
+ */
313
+ stopObservingTrack(trackId, viewId) {
314
+ const elementInfo = this.elementInfos.get(trackId)?.get(viewId);
315
+ if (!elementInfo) {
316
+ return;
317
+ }
318
+ // Find the LiveKit track and stop observing
319
+ const lkTrack = this.findLiveKitTrack(trackId);
320
+ if (lkTrack instanceof RemoteVideoTrack) {
321
+ lkTrack.stopObservingElementInfo(elementInfo);
322
+ }
323
+ // Cleanup ElementInfo
324
+ this.elementInfos.get(trackId)?.delete(viewId);
325
+ if (this.elementInfos.get(trackId)?.size === 0) {
326
+ this.elementInfos.delete(trackId);
327
+ }
328
+ }
329
+ /**
330
+ * Get stream URL from a LiveKit track for mobile video views.
331
+ *
332
+ * Uses MediaStream.toURL() which is the correct approach for React Native.
333
+ * LiveKit's official @livekit/react-native also uses this method.
334
+ *
335
+ * @see https://github.com/livekit/client-sdk-react-native
336
+ */
337
+ getStreamUrl(track) {
338
+ // Use mediaStream.toURL() - this is the correct approach for React Native
339
+ // LiveKit's track.mediaStream is a MediaStream that wraps the MediaStreamTrack
340
+ const mediaStream = track.mediaStream;
341
+ if (mediaStream && 'toURL' in mediaStream) {
342
+ return mediaStream.toURL();
343
+ }
344
+ // Fallback: return stream id (for web or unsupported platforms)
345
+ return mediaStream?.id ?? '';
346
+ }
347
+ }
348
+ //# sourceMappingURL=track-attachment.adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"track-attachment.adapter.js","sourceRoot":"","sources":["../../../../src/adapters/livekit/service-adapters/track-attachment.adapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,SAAS,EAET,gBAAgB,GAEjB,MAAM,gBAAgB,CAAA;AAavB;;;;;;;GAOG;AACH,MAAM,qBAAqB;IAWzB,YAAY,KAAK,GAAG,CAAC,EAAE,MAAM,GAAG,CAAC,EAAE,OAAO,GAAG,IAAI;QAVjD,YAAO,GAAW,EAAE,CAAA;QAGZ,eAAU,GAAG,KAAK,CAAA;QAG1B,qBAAgB,GAAG,KAAK,CAAA;QAUxB,UAAK,GAAG,GAAW,EAAE,CAAC,IAAI,CAAC,MAAM,CAAA;QACjC,WAAM,GAAG,GAAW,EAAE,CAAC,IAAI,CAAC,OAAO,CAAA;QANjC,IAAI,CAAC,MAAM,GAAG,KAAK,CAAA;QACnB,IAAI,CAAC,OAAO,GAAG,MAAM,CAAA;QACrB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAA;IACxB,CAAC;IAKD,OAAO;QACL,IAAI,CAAC,UAAU,GAAG,IAAI,CAAA;IACxB,CAAC;IAED,aAAa;QACX,IAAI,CAAC,UAAU,GAAG,KAAK,CAAA;IACzB,CAAC;IAED;;OAEG;IACH,aAAa,CAAC,KAAa,EAAE,MAAc;QACzC,IAAI,CAAC,MAAM,GAAG,KAAK,CAAA;QACnB,IAAI,CAAC,OAAO,GAAG,MAAM,CAAA;QACrB,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACpB,IAAI,CAAC,YAAY,EAAE,EAAE,CAAA;QACvB,CAAC;IACH,CAAC;IAED;;OAEG;IACH,UAAU,CAAC,OAAgB;QACzB,IAAI,IAAI,CAAC,OAAO,KAAK,OAAO,EAAE,CAAC;YAC7B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAA;YACtB,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;YACrC,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;gBACpB,IAAI,CAAC,uBAAuB,EAAE,EAAE,CAAA;YAClC,CAAC;QACH,CAAC;IACH,CAAC;CACF;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,OAAO,6BAA6B;IAaxC,YAAY,IAAU;QAXtB,oEAAoE;QAC5D,uBAAkB,GAAuC,IAAI,GAAG,EAAE,CAAA;QAC1E,8EAA8E;QACtE,iBAAY,GAA0C,IAAI,GAAG,EAAE,CAAA;QACvE,yCAAyC;QACjC,gBAAW,GAA6B,IAAI,GAAG,EAAE,CAAA;QACzD,4FAA4F;QACpF,iBAAY,GAAoD,IAAI,GAAG,EAAE,CAAA;QACjF,4CAA4C;QACpC,eAAU,GAAsB,EAAE,CAAA;QAGxC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;QAChB,IAAI,CAAC,mBAAmB,EAAE,CAAA;IAC5B,CAAC;IAED,MAAM,CAAC,OAAe,EAAE,OAAyB;QAC/C,MAAM,OAAO,GAAG,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAA;QAC9C,IAAI,OAAO,EAAE,CAAC;YACZ,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;QACzB,CAAC;aAAM,CAAC;YACN,+CAA+C;YAC/C,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC1C,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,GAAG,EAAE,CAAC,CAAA;YACjD,CAAC;YACD,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,OAAO,CAAE,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;QACpD,CAAC;IACH,CAAC;IAED,MAAM,CAAC,OAAe,EAAE,OAA0B;QAChD,kCAAkC;QAClC,IAAI,OAAO,EAAE,CAAC;YACZ,MAAM,UAAU,GAAG,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;YACvD,IAAI,UAAU,EAAE,CAAC;gBACf,UAAU,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;gBAC1B,gDAAgD;gBAChD,IAAI,UAAU,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;oBAC1B,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;gBACzC,CAAC;YACH,CAAC;QACH,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;QACzC,CAAC;QAED,6CAA6C;QAC7C,MAAM,OAAO,GAAG,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAA;QAC9C,IAAI,OAAO,EAAE,CAAC;YACZ,IAAI,OAAO,EAAE,CAAC;gBACZ,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;YACzB,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,MAAM,EAAE,CAAA;YAClB,CAAC;QACH,CAAC;IACH,CAAC;IAED,iBAAiB,CACf,OAAe,EACf,MAAc,EACd,OAKC;QAED,MAAM,OAAO,GAAG,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAA;QAE9C,IAAI,OAAO,EAAE,CAAC;YACZ,kEAAkE;YAClE,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE,MAAM,CAAC,CAAA;YACnC,IAAI,CAAC,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,CAAA;YAC5D,OAAO,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,CAAA;QACnC,CAAC;QAED,qDAAqD;QACrD,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;YACpC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,GAAG,EAAE,CAAC,CAAA;QAC3C,CAAC;QACD,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAE,CAAC,GAAG,CAAC,MAAM,EAAE;YAC1C,MAAM;YACN,KAAK,EAAE,OAAO,EAAE,KAAK;YACrB,MAAM,EAAE,OAAO,EAAE,MAAM;YACvB,OAAO,EAAE,OAAO,EAAE,OAAO;YACzB,OAAO,EAAE,OAAO,EAAE,OAAO;SAC1B,CAAC,CAAA;QAEF,OAAO,IAAI,CAAA;IACb,CAAC;IAED,mBAAmB,CAAC,OAAe,EAAE,MAAe;QAClD,IAAI,MAAM,EAAE,CAAC;YACX,uBAAuB;YACvB,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,CAAA;YAC9C,IAAI,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,IAAI,KAAK,CAAC,EAAE,CAAC;gBAC/C,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;YACnC,CAAC;YAED,yCAAyC;YACzC,IAAI,CAAC,kBAAkB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAA;YAExC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,CAAA;YAC7C,IAAI,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,IAAI,KAAK,CAAC,EAAE,CAAC;gBAC9C,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;YAClC,CAAC;QACH,CAAC;aAAM,CAAC;YACN,kCAAkC;YAClC,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;YAEjC,iDAAiD;YACjD,MAAM,SAAS,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;YAChD,IAAI,SAAS,EAAE,CAAC;gBACd,KAAK,MAAM,GAAG,IAAI,SAAS,CAAC,IAAI,EAAE,EAAE,CAAC;oBACnC,IAAI,CAAC,kBAAkB,CAAC,OAAO,EAAE,GAAG,CAAC,CAAA;gBACvC,CAAC;YACH,CAAC;YAED,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;QAClC,CAAC;IACH,CAAC;IAED,qBAAqB,CACnB,OAAe,EACf,MAAc,EACd,KAAa,EACb,MAAc;QAEd,MAAM,WAAW,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;QAC/D,IAAI,WAAW,EAAE,CAAC;YAChB,WAAW,CAAC,aAAa,CAAC,KAAK,EAAE,MAAM,CAAC,CAAA;QAC1C,CAAC;IACH,CAAC;IAED,yBAAyB,CACvB,OAAe,EACf,MAAc,EACd,OAAgB;QAEhB,MAAM,WAAW,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;QAC/D,IAAI,WAAW,EAAE,CAAC;YAChB,WAAW,CAAC,UAAU,CAAC,OAAO,CAAC,CAAA;QACjC,CAAC;IACH,CAAC;IAED,OAAO;QACL,8BAA8B;QAC9B,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAA;QACrC,IAAI,CAAC,UAAU,GAAG,EAAE,CAAA;QAEpB,kCAAkC;QAClC,KAAK,MAAM,CAAC,OAAO,EAAE,SAAS,CAAC,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACrD,MAAM,OAAO,GAAG,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAA;YAC9C,IAAI,OAAO,YAAY,gBAAgB,EAAE,CAAC;gBACxC,KAAK,MAAM,WAAW,IAAI,SAAS,CAAC,MAAM,EAAE,EAAE,CAAC;oBAC7C,OAAO,CAAC,wBAAwB,CAAC,WAAW,CAAC,CAAA;gBAC/C,CAAC;YACH,CAAC;QACH,CAAC;QAED,uBAAuB;QACvB,IAAI,CAAC,kBAAkB,CAAC,KAAK,EAAE,CAAA;QAC/B,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,CAAA;QACzB,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,CAAA;QACxB,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,CAAA;IAC3B,CAAC;IAED;;;;OAIG;IACK,mBAAmB;QACzB,kEAAkE;QAClE,MAAM,iBAAiB,GAAG,CAAC,KAAc,EAAE,EAAE;YAC3C,MAAM,OAAO,GAAG,KAAK,CAAC,GAAG,CAAA;YACzB,IAAI,CAAC,OAAO;gBAAE,OAAM;YAEpB,kCAAkC;YAClC,IAAI,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;gBACzC,MAAM,QAAQ,GAAG,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,OAAO,CAAE,CAAA;gBACtD,QAAQ,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAA;gBAC1C,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;YACzC,CAAC;YAED,4CAA4C;YAC5C,IAAI,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;gBACnC,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAE,CAAA;gBAC7C,MAAM,SAAS,GAAG,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAA;gBAE1C,KAAK,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,EAAE;oBAC5B,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;oBAC/C,4DAA4D;oBAC5D,IAAI,CAAC,oBAAoB,CAAC,OAAO,EAAE,WAAW,CAAC,MAAM,EAAE,KAAK,EAAE;wBAC5D,KAAK,EAAE,WAAW,CAAC,KAAK;wBACxB,MAAM,EAAE,WAAW,CAAC,MAAM;wBAC1B,OAAO,EAAE,WAAW,CAAC,OAAO;qBAC7B,CAAC,CAAA;oBACF,WAAW,CAAC,OAAO,EAAE,CAAC,SAAS,CAAC,CAAA;gBAClC,CAAC,CAAC,CAAA;gBACF,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;YACnC,CAAC;QACH,CAAC,CAAA;QAED,oFAAoF;QACpF,MAAM,mBAAmB,GAAG,CAAC,KAAc,EAAE,EAAE;YAC7C,MAAM,OAAO,GAAG,KAAK,CAAC,GAAG,CAAA;YACzB,IAAI,OAAO,EAAE,CAAC;gBACZ,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;gBACvC,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;gBACjC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;gBAEhC,0CAA0C;gBAC1C,MAAM,SAAS,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;gBAChD,IAAI,SAAS,EAAE,CAAC;oBACd,KAAK,MAAM,WAAW,IAAI,SAAS,CAAC,MAAM,EAAE,EAAE,CAAC;wBAC7C,IAAI,KAAK,YAAY,gBAAgB,EAAE,CAAC;4BACtC,KAAK,CAAC,wBAAwB,CAAC,WAAW,CAAC,CAAA;wBAC7C,CAAC;oBACH,CAAC;oBACD,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;gBACnC,CAAC;YACH,CAAC;QACH,CAAC,CAAA;QAED,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,eAAe,EAAE,iBAAiB,CAAC,CAAA;QAC1D,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,iBAAiB,EAAE,mBAAmB,CAAC,CAAA;QAE9D,IAAI,CAAC,UAAU,CAAC,IAAI,CAClB,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,eAAe,EAAE,iBAAiB,CAAC,EACjE,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,iBAAiB,EAAE,mBAAmB,CAAC,CACtE,CAAA;IACH,CAAC;IAED;;OAEG;IACK,gBAAgB,CAAC,OAAe;QACtC,8BAA8B;QAC9B,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,iBAAiB,CAAC,MAAM,EAAE,EAAE,CAAC;YACxE,IAAI,GAAG,CAAC,QAAQ,KAAK,OAAO,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC;gBAC1C,OAAO,GAAG,CAAC,KAAK,CAAA;YAClB,CAAC;QACH,CAAC;QAED,gCAAgC;QAChC,KAAK,MAAM,WAAW,IAAI,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAAC,MAAM,EAAE,EAAE,CAAC;YAChE,KAAK,MAAM,GAAG,IAAI,WAAW,CAAC,iBAAiB,CAAC,MAAM,EAAE,EAAE,CAAC;gBACzD,IAAI,GAAG,CAAC,QAAQ,KAAK,OAAO,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC;oBAC1C,OAAO,GAAG,CAAC,KAAK,CAAA;gBAClB,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO,SAAS,CAAA;IAClB,CAAC;IAED;;OAEG;IACK,aAAa,CAAC,OAAe,EAAE,MAAc;QACnD,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;YACnC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,GAAG,EAAE,CAAC,CAAA;QAC1C,CAAC;QACD,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,OAAO,CAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;IAC5C,CAAC;IAED;;;;;;;;OAQG;IACK,oBAAoB,CAC1B,OAAe,EACf,MAAc,EACd,OAAgB,EAChB,OAAgE;QAEhE,wDAAwD;QACxD,IAAI,CAAC,CAAC,OAAO,YAAY,gBAAgB,CAAC,EAAE,CAAC;YAC3C,OAAM;QACR,CAAC;QAED,yCAAyC;QACzC,IAAI,CAAC,OAAO,CAAC,gBAAgB,EAAE,CAAC;YAC9B,OAAM;QACR,CAAC;QAED,mCAAmC;QACnC,MAAM,WAAW,GAAG,IAAI,qBAAqB,CAC3C,OAAO,EAAE,KAAK,IAAI,CAAC,EACnB,OAAO,EAAE,MAAM,IAAI,CAAC,EACpB,OAAO,EAAE,OAAO,IAAI,IAAI,CACzB,CAAA;QAED,wBAAwB;QACxB,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;YACpC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,GAAG,EAAE,CAAC,CAAA;QAC3C,CAAC;QACD,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAE,CAAC,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAA;QAExD,kEAAkE;QAClE,OAAO,CAAC,kBAAkB,CAAC,WAAW,CAAC,CAAA;IACzC,CAAC;IAED;;OAEG;IACK,kBAAkB,CAAC,OAAe,EAAE,MAAc;QACxD,MAAM,WAAW,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;QAC/D,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,OAAM;QACR,CAAC;QAED,4CAA4C;QAC5C,MAAM,OAAO,GAAG,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAA;QAC9C,IAAI,OAAO,YAAY,gBAAgB,EAAE,CAAC;YACxC,OAAO,CAAC,wBAAwB,CAAC,WAAW,CAAC,CAAA;QAC/C,CAAC;QAED,sBAAsB;QACtB,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,CAAA;QAC9C,IAAI,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,IAAI,KAAK,CAAC,EAAE,CAAC;YAC/C,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;QACnC,CAAC;IACH,CAAC;IAED;;;;;;;OAOG;IACK,YAAY,CAAC,KAAc;QACjC,0EAA0E;QAC1E,+EAA+E;QAC/E,MAAM,WAAW,GAAG,KAAK,CAAC,WAAW,CAAA;QACrC,IAAI,WAAW,IAAI,OAAO,IAAI,WAAW,EAAE,CAAC;YAC1C,OAAQ,WAAqD,CAAC,KAAK,EAAE,CAAA;QACvE,CAAC;QAED,gEAAgE;QAChE,OAAO,WAAW,EAAE,EAAE,IAAI,EAAE,CAAA;IAC9B,CAAC;CACF"}
@@ -0,0 +1,3 @@
1
+ export * as StatsService from './stats.service';
2
+ export * as RecordingService from './recording.service';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/adapters/livekit/services/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,YAAY,MAAM,iBAAiB,CAAA;AAC/C,OAAO,KAAK,gBAAgB,MAAM,qBAAqB,CAAA"}
@@ -0,0 +1,3 @@
1
+ export * as StatsService from './stats.service';
2
+ export * as RecordingService from './recording.service';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/adapters/livekit/services/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,YAAY,MAAM,iBAAiB,CAAA;AAC/C,OAAO,KAAK,gBAAgB,MAAM,qBAAqB,CAAA"}
@@ -0,0 +1,29 @@
1
+ import type { ServiceContext } from '../../../core/types/service-adapters.types';
2
+ import type { RecordingStartOptions, RecordingStatus } from '../../../core/types/recording.types';
3
+ /**
4
+ * Start recording for the session.
5
+ *
6
+ * @param context - Service context with sessionToken and apiEndpoint
7
+ * @param options - Recording options (layout, audioOnly, resolution)
8
+ * @returns Recording ID
9
+ * @throws RecordingStartError if recording fails to start (e.g., already recording)
10
+ * @throws PermissionDeniedError if no recording permission or insufficient role
11
+ */
12
+ export declare function startRecording(context: ServiceContext, options?: RecordingStartOptions): Promise<string>;
13
+ /**
14
+ * Stop recording.
15
+ *
16
+ * @param context - Service context with sessionToken and apiEndpoint
17
+ * @param recordingId - ID of the recording to stop
18
+ * @throws PermissionDeniedError if insufficient role
19
+ */
20
+ export declare function stopRecording(context: ServiceContext, recordingId: string): Promise<void>;
21
+ /**
22
+ * Get recording status.
23
+ *
24
+ * @param context - Service context with sessionToken and apiEndpoint
25
+ * @param recordingId - ID of the recording
26
+ * @returns Recording status
27
+ */
28
+ export declare function getRecordingStatus(context: ServiceContext, recordingId: string): Promise<RecordingStatus>;
29
+ //# sourceMappingURL=recording.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recording.service.d.ts","sourceRoot":"","sources":["../../../../src/adapters/livekit/services/recording.service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4CAA4C,CAAA;AAChF,OAAO,KAAK,EACV,qBAAqB,EACrB,eAAe,EAChB,MAAM,qCAAqC,CAAA;AAO5C;;;;;;;;GAQG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,cAAc,EACvB,OAAO,CAAC,EAAE,qBAAqB,GAC9B,OAAO,CAAC,MAAM,CAAC,CAEjB;AAED;;;;;;GAMG;AACH,wBAAsB,aAAa,CACjC,OAAO,EAAE,cAAc,EACvB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,IAAI,CAAC,CAEf;AAED;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,cAAc,EACvB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,eAAe,CAAC,CAE1B"}
@@ -0,0 +1,34 @@
1
+ import { postStartRecording, postStopRecording, getRecordingStatus as getRecordingStatusApi, } from '../api/recording.api';
2
+ /**
3
+ * Start recording for the session.
4
+ *
5
+ * @param context - Service context with sessionToken and apiEndpoint
6
+ * @param options - Recording options (layout, audioOnly, resolution)
7
+ * @returns Recording ID
8
+ * @throws RecordingStartError if recording fails to start (e.g., already recording)
9
+ * @throws PermissionDeniedError if no recording permission or insufficient role
10
+ */
11
+ export async function startRecording(context, options) {
12
+ return postStartRecording(context, options);
13
+ }
14
+ /**
15
+ * Stop recording.
16
+ *
17
+ * @param context - Service context with sessionToken and apiEndpoint
18
+ * @param recordingId - ID of the recording to stop
19
+ * @throws PermissionDeniedError if insufficient role
20
+ */
21
+ export async function stopRecording(context, recordingId) {
22
+ return postStopRecording(context, recordingId);
23
+ }
24
+ /**
25
+ * Get recording status.
26
+ *
27
+ * @param context - Service context with sessionToken and apiEndpoint
28
+ * @param recordingId - ID of the recording
29
+ * @returns Recording status
30
+ */
31
+ export async function getRecordingStatus(context, recordingId) {
32
+ return getRecordingStatusApi(context, recordingId);
33
+ }
34
+ //# sourceMappingURL=recording.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recording.service.js","sourceRoot":"","sources":["../../../../src/adapters/livekit/services/recording.service.ts"],"names":[],"mappings":"AAKA,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,IAAI,qBAAqB,GAC5C,MAAM,sBAAsB,CAAA;AAE7B;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,OAAuB,EACvB,OAA+B;IAE/B,OAAO,kBAAkB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;AAC7C,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,OAAuB,EACvB,WAAmB;IAEnB,OAAO,iBAAiB,CAAC,OAAO,EAAE,WAAW,CAAC,CAAA;AAChD,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,OAAuB,EACvB,WAAmB;IAEnB,OAAO,qBAAqB,CAAC,OAAO,EAAE,WAAW,CAAC,CAAA;AACpD,CAAC"}
@@ -0,0 +1,24 @@
1
+ import type { Room } from 'livekit-client';
2
+ import type { NetworkQuality } from '../../../core/types/events.types';
3
+ /**
4
+ * Get native RTC stats report from peer connection(s).
5
+ *
6
+ * LiveKit supports multiple PC modes:
7
+ * - publisher-only: single PC for both outbound and inbound
8
+ * - subscriber-primary / publisher-primary: separate PCs
9
+ *
10
+ * This method handles both cases by checking if subscriber PC exists.
11
+ *
12
+ * Note: This uses LiveKit's internal API (room.engine.pcManager) which may
13
+ * change in future versions. If this breaks, update the path or fallback
14
+ * to track-based stats collection.
15
+ *
16
+ * @returns RTCStatsReport containing stats for all tracks
17
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/RTCStatsReport
18
+ */
19
+ export declare function getStats(room: Room | null): Promise<RTCStatsReport>;
20
+ /**
21
+ * Get current network quality based on local participant's connection quality.
22
+ */
23
+ export declare function getNetworkQuality(room: Room | null): NetworkQuality;
24
+ //# sourceMappingURL=stats.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stats.service.d.ts","sourceRoot":"","sources":["../../../../src/adapters/livekit/services/stats.service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAA;AAE1C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAA;AAGtE;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,QAAQ,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,OAAO,CAAC,cAAc,CAAC,CAiCzE;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,cAAc,CAOnE"}
@@ -0,0 +1,56 @@
1
+ import { LiveKitMapper } from '../livekit.mapper';
2
+ /**
3
+ * Get native RTC stats report from peer connection(s).
4
+ *
5
+ * LiveKit supports multiple PC modes:
6
+ * - publisher-only: single PC for both outbound and inbound
7
+ * - subscriber-primary / publisher-primary: separate PCs
8
+ *
9
+ * This method handles both cases by checking if subscriber PC exists.
10
+ *
11
+ * Note: This uses LiveKit's internal API (room.engine.pcManager) which may
12
+ * change in future versions. If this breaks, update the path or fallback
13
+ * to track-based stats collection.
14
+ *
15
+ * @returns RTCStatsReport containing stats for all tracks
16
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/RTCStatsReport
17
+ */
18
+ export async function getStats(room) {
19
+ if (!room) {
20
+ return new Map();
21
+ }
22
+ // Access peer connections via internal API
23
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
24
+ const pcManager = room.engine?.pcManager;
25
+ const publisherPC = pcManager?.publisher?.pc;
26
+ const subscriberPC = pcManager?.subscriber?.pc;
27
+ // If no publisher PC, return empty stats
28
+ if (!publisherPC) {
29
+ return new Map();
30
+ }
31
+ // If no subscriber PC (publisher-only mode), publisher has all stats
32
+ if (!subscriberPC) {
33
+ return publisherPC.getStats();
34
+ }
35
+ // If both PCs exist, merge stats from both
36
+ const mergedStats = new Map();
37
+ const publisherStats = await publisherPC.getStats();
38
+ publisherStats.forEach((value, key) => mergedStats.set(key, value));
39
+ const subscriberStats = await subscriberPC.getStats();
40
+ subscriberStats.forEach((value, key) => {
41
+ if (!mergedStats.has(key))
42
+ mergedStats.set(key, value);
43
+ });
44
+ return mergedStats;
45
+ }
46
+ /**
47
+ * Get current network quality based on local participant's connection quality.
48
+ */
49
+ export function getNetworkQuality(room) {
50
+ if (!room) {
51
+ return 'unknown';
52
+ }
53
+ const quality = room.localParticipant.connectionQuality;
54
+ return LiveKitMapper.toNetworkQuality(quality);
55
+ }
56
+ //# sourceMappingURL=stats.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stats.service.js","sourceRoot":"","sources":["../../../../src/adapters/livekit/services/stats.service.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAEjD;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,IAAiB;IAC9C,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,IAAI,GAAG,EAAoB,CAAA;IACpC,CAAC;IAED,2CAA2C;IAC3C,8DAA8D;IAC9D,MAAM,SAAS,GAAI,IAAI,CAAC,MAAc,EAAE,SAAS,CAAA;IACjD,MAAM,WAAW,GAAG,SAAS,EAAE,SAAS,EAAE,EAAmC,CAAA;IAC7E,MAAM,YAAY,GAAG,SAAS,EAAE,UAAU,EAAE,EAAmC,CAAA;IAE/E,yCAAyC;IACzC,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,OAAO,IAAI,GAAG,EAAoB,CAAA;IACpC,CAAC;IAED,qEAAqE;IACrE,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,OAAO,WAAW,CAAC,QAAQ,EAAE,CAAA;IAC/B,CAAC;IAED,2CAA2C;IAC3C,MAAM,WAAW,GAAG,IAAI,GAAG,EAAoB,CAAA;IAE/C,MAAM,cAAc,GAAG,MAAM,WAAW,CAAC,QAAQ,EAAE,CAAA;IACnD,cAAc,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAA;IAEnE,MAAM,eAAe,GAAG,MAAM,YAAY,CAAC,QAAQ,EAAE,CAAA;IACrD,eAAe,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;QACrC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,WAAW,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAA;IACxD,CAAC,CAAC,CAAA;IAEF,OAAO,WAA6B,CAAA;AACtC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAiB;IACjD,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,SAAS,CAAA;IAClB,CAAC;IAED,MAAM,OAAO,GAAG,IAAI,CAAC,gBAAgB,CAAC,iBAAiB,CAAA;IACvD,OAAO,aAAa,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAA;AAChD,CAAC"}
@@ -0,0 +1,52 @@
1
+ import { type VroomInitConfig, type VroomInitConfigInternal, type ProviderType } from '../types/vroom.types';
2
+ /**
3
+ * Auth init response from POST /v1/auth/init
4
+ */
5
+ export interface AuthInitResponse {
6
+ authToken: string;
7
+ expiresAt: number;
8
+ }
9
+ /**
10
+ * RTC token response from POST /v1/rtc/token
11
+ */
12
+ export interface RtcTokenResponse {
13
+ /** Provider-specific token (e.g., LiveKit JWT) */
14
+ token: string;
15
+ /** Vroom session token (JWT with feat[], role, etc.) */
16
+ sessionToken: string;
17
+ /** RTC provider type */
18
+ provider: ProviderType;
19
+ /** Provider endpoint URL */
20
+ endpoint: string;
21
+ /** User role in the room */
22
+ role: string;
23
+ /** Token expiration time (Unix timestamp) */
24
+ expiresAt: number;
25
+ }
26
+ /**
27
+ * RTC token request params
28
+ */
29
+ export interface RtcTokenRequest {
30
+ authToken: string;
31
+ userId: string;
32
+ roomName: string;
33
+ role: string;
34
+ }
35
+ /**
36
+ * Vroom API Client
37
+ *
38
+ * Handles all HTTP communication with Vroom backend.
39
+ */
40
+ export declare class VroomApiClient {
41
+ private readonly endpoint;
42
+ constructor(config: VroomInitConfig);
43
+ /**
44
+ * POST /v1/auth/init - Validate API key and get authToken
45
+ */
46
+ authInit(config: VroomInitConfigInternal): Promise<AuthInitResponse>;
47
+ /**
48
+ * POST /v1/rtc/token - Get provider-specific token for room
49
+ */
50
+ getRtcToken(params: RtcTokenRequest): Promise<RtcTokenResponse>;
51
+ }
52
+ //# sourceMappingURL=auth.api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.api.d.ts","sourceRoot":"","sources":["../../../src/core/api/auth.api.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,eAAe,EACpB,KAAK,uBAAuB,EAC5B,KAAK,YAAY,EAClB,MAAM,sBAAsB,CAAA;AAQ7B;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,kDAAkD;IAClD,KAAK,EAAE,MAAM,CAAA;IACb,wDAAwD;IACxD,YAAY,EAAE,MAAM,CAAA;IACpB,wBAAwB;IACxB,QAAQ,EAAE,YAAY,CAAA;IACtB,4BAA4B;IAC5B,QAAQ,EAAE,MAAM,CAAA;IAChB,4BAA4B;IAC5B,IAAI,EAAE,MAAM,CAAA;IACZ,6CAA6C;IAC7C,SAAS,EAAE,MAAM,CAAA;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,EAAE,MAAM,CAAA;CACb;AAiBD;;;;GAIG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAQ;gBAErB,MAAM,EAAE,eAAe;IAInC;;OAEG;IACG,QAAQ,CAAC,MAAM,EAAE,uBAAuB,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAW1E;;OAEG;IACG,WAAW,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,gBAAgB,CAAC;CActE"}
@@ -0,0 +1,59 @@
1
+ import { DEFAULT_VROOM_ENDPOINT, } from '../types/vroom.types';
2
+ import { InvalidApiKeyError, UnauthorizedError, } from '../errors/vroom.error';
3
+ import { ErrorCodes } from '../errors/error-codes';
4
+ import { request } from './http';
5
+ /**
6
+ * Custom error handler for auth endpoints.
7
+ * Handles auth-specific errors: InvalidApiKey, Unauthorized
8
+ */
9
+ const authErrorHandler = ({ code, message }) => {
10
+ switch (code) {
11
+ case ErrorCodes.E_INVALID_API_KEY:
12
+ return new InvalidApiKeyError(message);
13
+ case ErrorCodes.E_UNAUTHORIZED:
14
+ return new UnauthorizedError(message);
15
+ default:
16
+ return null; // Fallback to common error handling
17
+ }
18
+ };
19
+ /**
20
+ * Vroom API Client
21
+ *
22
+ * Handles all HTTP communication with Vroom backend.
23
+ */
24
+ export class VroomApiClient {
25
+ constructor(config) {
26
+ this.endpoint = config.endpoint ?? DEFAULT_VROOM_ENDPOINT;
27
+ }
28
+ /**
29
+ * POST /v1/auth/init - Validate API key and get authToken
30
+ */
31
+ async authInit(config) {
32
+ return request({
33
+ method: 'POST',
34
+ url: `${this.endpoint}/v1/auth/init`,
35
+ headers: { 'X-API-Key': config.apiKey },
36
+ body: { platformInfo: config.platformInfo },
37
+ customErrorHandler: authErrorHandler,
38
+ errorMessage: 'Failed to connect to Vroom API',
39
+ });
40
+ }
41
+ /**
42
+ * POST /v1/rtc/token - Get provider-specific token for room
43
+ */
44
+ async getRtcToken(params) {
45
+ return request({
46
+ method: 'POST',
47
+ url: `${this.endpoint}/v1/rtc/token`,
48
+ headers: { Authorization: `Bearer ${params.authToken}` },
49
+ body: {
50
+ userId: params.userId,
51
+ roomName: params.roomName,
52
+ role: params.role,
53
+ },
54
+ customErrorHandler: authErrorHandler,
55
+ errorMessage: 'Failed to get RTC token',
56
+ });
57
+ }
58
+ }
59
+ //# sourceMappingURL=auth.api.js.map