@voltkit-rtc/react-native 0.0.0-stage → 0.1.1

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 (225) hide show
  1. package/CHANGELOG.md +121 -0
  2. package/LICENSE +21 -0
  3. package/README.md +1608 -2
  4. package/android/build.gradle +70 -0
  5. package/android/consumer-rules.pro +21 -0
  6. package/android/src/main/AndroidManifest.xml +25 -0
  7. package/android/src/main/java/com/voltkit/rtc/reactnative/AppVisibility.kt +67 -0
  8. package/android/src/main/java/com/voltkit/rtc/reactnative/AudioDevices.kt +67 -0
  9. package/android/src/main/java/com/voltkit/rtc/reactnative/AudioRouter.kt +487 -0
  10. package/android/src/main/java/com/voltkit/rtc/reactnative/CallServiceTypes.kt +120 -0
  11. package/android/src/main/java/com/voltkit/rtc/reactnative/NativeTimers.kt +106 -0
  12. package/android/src/main/java/com/voltkit/rtc/reactnative/NetworkWatch.kt +120 -0
  13. package/android/src/main/java/com/voltkit/rtc/reactnative/OutputChoice.kt +65 -0
  14. package/android/src/main/java/com/voltkit/rtc/reactnative/RtcConfig.kt +83 -0
  15. package/android/src/main/java/com/voltkit/rtc/reactnative/ScoLink.kt +61 -0
  16. package/android/src/main/java/com/voltkit/rtc/reactnative/VoltkitCallService.kt +287 -0
  17. package/android/src/main/java/com/voltkit/rtc/reactnative/VoltkitRtcInitProvider.kt +215 -0
  18. package/android/src/main/java/com/voltkit/rtc/reactnative/VoltkitRtcModule.kt +313 -0
  19. package/android/src/main/java/com/voltkit/rtc/reactnative/VoltkitRtcPackage.kt +30 -0
  20. package/android/src/main/res/drawable/voltkit_rtc_default_call_icon.xml +15 -0
  21. package/android/src/main/res/raw/voltkit_rtc_keep.xml +7 -0
  22. package/app.plugin.js +17 -0
  23. package/lib/commonjs/audio.js +215 -0
  24. package/lib/commonjs/audio.js.map +1 -0
  25. package/lib/commonjs/components.js +207 -0
  26. package/lib/commonjs/components.js.map +1 -0
  27. package/lib/commonjs/create-client.js +47 -0
  28. package/lib/commonjs/create-client.js.map +1 -0
  29. package/lib/commonjs/errors.js +99 -0
  30. package/lib/commonjs/errors.js.map +1 -0
  31. package/lib/commonjs/globals.js +61 -0
  32. package/lib/commonjs/globals.js.map +1 -0
  33. package/lib/commonjs/index.js +234 -0
  34. package/lib/commonjs/index.js.map +1 -0
  35. package/lib/commonjs/local-media.js +392 -0
  36. package/lib/commonjs/local-media.js.map +1 -0
  37. package/lib/commonjs/native-session.js +365 -0
  38. package/lib/commonjs/native-session.js.map +1 -0
  39. package/lib/commonjs/native.js +99 -0
  40. package/lib/commonjs/native.js.map +1 -0
  41. package/lib/commonjs/package.json +1 -0
  42. package/lib/commonjs/permissions.js +166 -0
  43. package/lib/commonjs/permissions.js.map +1 -0
  44. package/lib/commonjs/platform/android.js +126 -0
  45. package/lib/commonjs/platform/android.js.map +1 -0
  46. package/lib/commonjs/platform/common.js +138 -0
  47. package/lib/commonjs/platform/common.js.map +1 -0
  48. package/lib/commonjs/platform/devices.js +151 -0
  49. package/lib/commonjs/platform/devices.js.map +1 -0
  50. package/lib/commonjs/platform/index.js +35 -0
  51. package/lib/commonjs/platform/index.js.map +1 -0
  52. package/lib/commonjs/platform/ios.js +54 -0
  53. package/lib/commonjs/platform/ios.js.map +1 -0
  54. package/lib/commonjs/platform/streams.js +273 -0
  55. package/lib/commonjs/platform/streams.js.map +1 -0
  56. package/lib/commonjs/platform/timers.js +71 -0
  57. package/lib/commonjs/platform/timers.js.map +1 -0
  58. package/lib/commonjs/platform/visibility.js +60 -0
  59. package/lib/commonjs/platform/visibility.js.map +1 -0
  60. package/lib/commonjs/preflight.js +77 -0
  61. package/lib/commonjs/preflight.js.map +1 -0
  62. package/lib/commonjs/provider.js +75 -0
  63. package/lib/commonjs/provider.js.map +1 -0
  64. package/lib/commonjs/specs/NativeVoltkitRtc.js +29 -0
  65. package/lib/commonjs/specs/NativeVoltkitRtc.js.map +1 -0
  66. package/lib/module/audio.js +207 -0
  67. package/lib/module/audio.js.map +1 -0
  68. package/lib/module/components.js +200 -0
  69. package/lib/module/components.js.map +1 -0
  70. package/lib/module/create-client.js +42 -0
  71. package/lib/module/create-client.js.map +1 -0
  72. package/lib/module/errors.js +87 -0
  73. package/lib/module/errors.js.map +1 -0
  74. package/lib/module/globals.js +53 -0
  75. package/lib/module/globals.js.map +1 -0
  76. package/lib/module/index.js +33 -0
  77. package/lib/module/index.js.map +1 -0
  78. package/lib/module/local-media.js +387 -0
  79. package/lib/module/local-media.js.map +1 -0
  80. package/lib/module/native-session.js +360 -0
  81. package/lib/module/native-session.js.map +1 -0
  82. package/lib/module/native.js +87 -0
  83. package/lib/module/native.js.map +1 -0
  84. package/lib/module/package.json +1 -0
  85. package/lib/module/permissions.js +160 -0
  86. package/lib/module/permissions.js.map +1 -0
  87. package/lib/module/platform/android.js +122 -0
  88. package/lib/module/platform/android.js.map +1 -0
  89. package/lib/module/platform/common.js +128 -0
  90. package/lib/module/platform/common.js.map +1 -0
  91. package/lib/module/platform/devices.js +142 -0
  92. package/lib/module/platform/devices.js.map +1 -0
  93. package/lib/module/platform/index.js +24 -0
  94. package/lib/module/platform/index.js.map +1 -0
  95. package/lib/module/platform/ios.js +49 -0
  96. package/lib/module/platform/ios.js.map +1 -0
  97. package/lib/module/platform/streams.js +268 -0
  98. package/lib/module/platform/streams.js.map +1 -0
  99. package/lib/module/platform/timers.js +67 -0
  100. package/lib/module/platform/timers.js.map +1 -0
  101. package/lib/module/platform/visibility.js +54 -0
  102. package/lib/module/platform/visibility.js.map +1 -0
  103. package/lib/module/preflight.js +72 -0
  104. package/lib/module/preflight.js.map +1 -0
  105. package/lib/module/provider.js +70 -0
  106. package/lib/module/provider.js.map +1 -0
  107. package/lib/module/specs/NativeVoltkitRtc.js +37 -0
  108. package/lib/module/specs/NativeVoltkitRtc.js.map +1 -0
  109. package/lib/typescript/commonjs/audio.d.ts +58 -0
  110. package/lib/typescript/commonjs/audio.d.ts.map +1 -0
  111. package/lib/typescript/commonjs/components.d.ts +58 -0
  112. package/lib/typescript/commonjs/components.d.ts.map +1 -0
  113. package/lib/typescript/commonjs/create-client.d.ts +35 -0
  114. package/lib/typescript/commonjs/create-client.d.ts.map +1 -0
  115. package/lib/typescript/commonjs/errors.d.ts +34 -0
  116. package/lib/typescript/commonjs/errors.d.ts.map +1 -0
  117. package/lib/typescript/commonjs/globals.d.ts +16 -0
  118. package/lib/typescript/commonjs/globals.d.ts.map +1 -0
  119. package/lib/typescript/commonjs/index.d.ts +24 -0
  120. package/lib/typescript/commonjs/index.d.ts.map +1 -0
  121. package/lib/typescript/commonjs/local-media.d.ts +86 -0
  122. package/lib/typescript/commonjs/local-media.d.ts.map +1 -0
  123. package/lib/typescript/commonjs/native-session.d.ts +38 -0
  124. package/lib/typescript/commonjs/native-session.d.ts.map +1 -0
  125. package/lib/typescript/commonjs/native.d.ts +18 -0
  126. package/lib/typescript/commonjs/native.d.ts.map +1 -0
  127. package/lib/typescript/commonjs/package.json +1 -0
  128. package/lib/typescript/commonjs/permissions.d.ts +30 -0
  129. package/lib/typescript/commonjs/permissions.d.ts.map +1 -0
  130. package/lib/typescript/commonjs/platform/android.d.ts +4 -0
  131. package/lib/typescript/commonjs/platform/android.d.ts.map +1 -0
  132. package/lib/typescript/commonjs/platform/common.d.ts +101 -0
  133. package/lib/typescript/commonjs/platform/common.d.ts.map +1 -0
  134. package/lib/typescript/commonjs/platform/devices.d.ts +42 -0
  135. package/lib/typescript/commonjs/platform/devices.d.ts.map +1 -0
  136. package/lib/typescript/commonjs/platform/index.d.ts +6 -0
  137. package/lib/typescript/commonjs/platform/index.d.ts.map +1 -0
  138. package/lib/typescript/commonjs/platform/ios.d.ts +4 -0
  139. package/lib/typescript/commonjs/platform/ios.d.ts.map +1 -0
  140. package/lib/typescript/commonjs/platform/streams.d.ts +82 -0
  141. package/lib/typescript/commonjs/platform/streams.d.ts.map +1 -0
  142. package/lib/typescript/commonjs/platform/timers.d.ts +19 -0
  143. package/lib/typescript/commonjs/platform/timers.d.ts.map +1 -0
  144. package/lib/typescript/commonjs/platform/visibility.d.ts +11 -0
  145. package/lib/typescript/commonjs/platform/visibility.d.ts.map +1 -0
  146. package/lib/typescript/commonjs/preflight.d.ts +19 -0
  147. package/lib/typescript/commonjs/preflight.d.ts.map +1 -0
  148. package/lib/typescript/commonjs/provider.d.ts +35 -0
  149. package/lib/typescript/commonjs/provider.d.ts.map +1 -0
  150. package/lib/typescript/commonjs/specs/NativeVoltkitRtc.d.ts +157 -0
  151. package/lib/typescript/commonjs/specs/NativeVoltkitRtc.d.ts.map +1 -0
  152. package/lib/typescript/module/audio.d.ts +58 -0
  153. package/lib/typescript/module/audio.d.ts.map +1 -0
  154. package/lib/typescript/module/components.d.ts +58 -0
  155. package/lib/typescript/module/components.d.ts.map +1 -0
  156. package/lib/typescript/module/create-client.d.ts +35 -0
  157. package/lib/typescript/module/create-client.d.ts.map +1 -0
  158. package/lib/typescript/module/errors.d.ts +34 -0
  159. package/lib/typescript/module/errors.d.ts.map +1 -0
  160. package/lib/typescript/module/globals.d.ts +16 -0
  161. package/lib/typescript/module/globals.d.ts.map +1 -0
  162. package/lib/typescript/module/index.d.ts +24 -0
  163. package/lib/typescript/module/index.d.ts.map +1 -0
  164. package/lib/typescript/module/local-media.d.ts +86 -0
  165. package/lib/typescript/module/local-media.d.ts.map +1 -0
  166. package/lib/typescript/module/native-session.d.ts +38 -0
  167. package/lib/typescript/module/native-session.d.ts.map +1 -0
  168. package/lib/typescript/module/native.d.ts +18 -0
  169. package/lib/typescript/module/native.d.ts.map +1 -0
  170. package/lib/typescript/module/package.json +1 -0
  171. package/lib/typescript/module/permissions.d.ts +30 -0
  172. package/lib/typescript/module/permissions.d.ts.map +1 -0
  173. package/lib/typescript/module/platform/android.d.ts +4 -0
  174. package/lib/typescript/module/platform/android.d.ts.map +1 -0
  175. package/lib/typescript/module/platform/common.d.ts +101 -0
  176. package/lib/typescript/module/platform/common.d.ts.map +1 -0
  177. package/lib/typescript/module/platform/devices.d.ts +42 -0
  178. package/lib/typescript/module/platform/devices.d.ts.map +1 -0
  179. package/lib/typescript/module/platform/index.d.ts +6 -0
  180. package/lib/typescript/module/platform/index.d.ts.map +1 -0
  181. package/lib/typescript/module/platform/ios.d.ts +4 -0
  182. package/lib/typescript/module/platform/ios.d.ts.map +1 -0
  183. package/lib/typescript/module/platform/streams.d.ts +82 -0
  184. package/lib/typescript/module/platform/streams.d.ts.map +1 -0
  185. package/lib/typescript/module/platform/timers.d.ts +19 -0
  186. package/lib/typescript/module/platform/timers.d.ts.map +1 -0
  187. package/lib/typescript/module/platform/visibility.d.ts +11 -0
  188. package/lib/typescript/module/platform/visibility.d.ts.map +1 -0
  189. package/lib/typescript/module/preflight.d.ts +19 -0
  190. package/lib/typescript/module/preflight.d.ts.map +1 -0
  191. package/lib/typescript/module/provider.d.ts +35 -0
  192. package/lib/typescript/module/provider.d.ts.map +1 -0
  193. package/lib/typescript/module/specs/NativeVoltkitRtc.d.ts +157 -0
  194. package/lib/typescript/module/specs/NativeVoltkitRtc.d.ts.map +1 -0
  195. package/package.json +140 -4
  196. package/plugin/build/android.d.ts +36 -0
  197. package/plugin/build/android.js +265 -0
  198. package/plugin/build/index.d.ts +9 -0
  199. package/plugin/build/index.js +54 -0
  200. package/plugin/build/ios.d.ts +4 -0
  201. package/plugin/build/ios.js +43 -0
  202. package/plugin/build/options.d.ts +93 -0
  203. package/plugin/build/options.js +140 -0
  204. package/react-native.config.js +11 -0
  205. package/src/audio.ts +221 -0
  206. package/src/components.tsx +233 -0
  207. package/src/create-client.ts +53 -0
  208. package/src/errors.ts +81 -0
  209. package/src/globals.ts +54 -0
  210. package/src/index.ts +95 -0
  211. package/src/local-media.ts +420 -0
  212. package/src/native-session.tsx +384 -0
  213. package/src/native.ts +84 -0
  214. package/src/permissions.ts +173 -0
  215. package/src/platform/android.ts +128 -0
  216. package/src/platform/common.ts +157 -0
  217. package/src/platform/devices.ts +148 -0
  218. package/src/platform/index.ts +22 -0
  219. package/src/platform/ios.ts +48 -0
  220. package/src/platform/streams.ts +285 -0
  221. package/src/platform/timers.ts +72 -0
  222. package/src/platform/visibility.ts +59 -0
  223. package/src/preflight.ts +60 -0
  224. package/src/provider.tsx +88 -0
  225. package/src/specs/NativeVoltkitRtc.ts +180 -0
@@ -0,0 +1,268 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * Every native MediaStream this package makes, and the order in which streams and tracks are let go.
5
+ *
6
+ * In react-native-webrtc a MediaStream is a native object that holds its tracks. Releasing a stream after one of its
7
+ * tracks was disposed -- a local track released, or a remote one whose peer connection closed -- kills the app:
8
+ * `mediaStreamRemoveTrack` cannot find the track, so it stays in the native stream, and disposing the stream throws
9
+ * `IllegalStateException: MediaStreamTrack has been disposed` on the module's thread (Phase 0 finding 1, seen on a
10
+ * reconnect, a room closing and a plain release in the wrong order). So:
11
+ *
12
+ * - Views (VideoTrack) show a track through a wrapper stream made only here: one per track, shared by every view of it,
13
+ * released (`release(false)`, never the track) when the last view goes.
14
+ * - Before the client closes what receives remote tracks (a consumer, the receive transport, the session) it calls the
15
+ * platform's `detachTracks`: their wrappers are released then, while the peer connection still exists, and no new
16
+ * one is made for them.
17
+ * - `stop(track)` (the platform's stopTrack) releases the track's wrappers and takes it out of every other stream made
18
+ * here before it disposes the track; a capture stream left empty is released too. A stream the app got from
19
+ * getUserMedia through this package can therefore never be left holding a disposed track.
20
+ * - A stream the app gave the client (`client.publish(stream)` with a stream the app captured itself) is the app's: the
21
+ * client stops and releases its tracks but never the stream. Once told of it (`adoptAppStream`), `stop(track)` takes
22
+ * the track out of it too while the track is alive, so the app can still release it afterwards; this package never
23
+ * releases it. @voltkit-rtc/client 0.9.12's publish() and publishScreen({ stream }) call that hook.
24
+ * - A stream that would still be released while holding a disposed track (a remote track already ended, a track
25
+ * released elsewhere) is left alone instead: a small native leak, never a crash. A view wrapper whose track ended
26
+ * before the view let go is left the same way: only the end shows that an app released the track itself.
27
+ */
28
+
29
+ import { loadWebRTC } from "../globals.js";
30
+ import { logError, webrtcMissing } from "../errors.js";
31
+
32
+ /** What this module needs of a track: react-native-webrtc's MediaStreamTrack, or a test's stand-in. */
33
+
34
+ /** What this module needs of a stream: react-native-webrtc's MediaStream. */
35
+
36
+ /**
37
+ * Why a stream is kept: a capture (getUserMedia, getDisplayMedia), the client's own (createStream), a view, or the
38
+ * app's own that the client publishes (adoptAppStream: tracks taken out of it, never released here).
39
+ */
40
+
41
+ /** One view's hold on a track's wrapper stream. */
42
+
43
+ export class StreamBook {
44
+ live = new Set();
45
+ entries = new WeakMap();
46
+ views = new Map();
47
+ /** Local tracks this package disposed (released). */
48
+ disposed = new WeakSet();
49
+ /** Remote tracks whose connection is closing: no new view, their wrappers already released. */
50
+ detached = new WeakSet();
51
+ stopped = new WeakSet();
52
+ screens = new WeakSet();
53
+ /** Streams left unreleased because releasing them would have crashed the app. */
54
+ leaked = 0;
55
+ /** Called after a screen track is stopped and released (react-native-webrtc's MediaProjectionService then stops). */
56
+ onScreenStopped = null;
57
+ constructor(makeStream) {
58
+ this.makeStream = makeStream;
59
+ }
60
+
61
+ /** Keep `stream`, one the platform made (or the app's, `app`), to let go of in the right order. */
62
+ adopt(stream, role) {
63
+ const known = this.entries.get(stream);
64
+ if (known) {
65
+ // The app's stream given again (published once more): watched again.
66
+ if (known.role === 'app' && !known.released) this.live.add(known);
67
+ return;
68
+ }
69
+ const entry = {
70
+ stream,
71
+ role,
72
+ released: false
73
+ };
74
+ this.entries.set(stream, entry);
75
+ this.live.add(entry);
76
+ }
77
+
78
+ /** A stream of these tracks for the client's own use (ClientPlatform.createStream). */
79
+ create(tracks) {
80
+ const stream = this.makeStream(tracks);
81
+ this.adopt(stream, 'client');
82
+ return stream;
83
+ }
84
+
85
+ /** The tracks of `stream` are a screen capture's. */
86
+ markScreen(stream) {
87
+ for (const track of stream.getTracks()) this.screens.add(track);
88
+ }
89
+
90
+ /** Release `stream` without its tracks (ClientPlatform.releaseStream). Again does nothing. */
91
+ release(stream) {
92
+ let entry = this.entries.get(stream);
93
+ if (!entry) {
94
+ // Not one made here: released the same careful way.
95
+ entry = {
96
+ stream,
97
+ role: 'client',
98
+ released: false
99
+ };
100
+ this.entries.set(stream, entry);
101
+ }
102
+ this.releaseEntry(entry);
103
+ }
104
+
105
+ /**
106
+ * Stop and release `track` (ClientPlatform.stopTrack): its view wrappers are released and it leaves every stream
107
+ * kept here first (made here, or the app's adopted), while the native track still exists. Again does nothing. A
108
+ * remote track is only let go of: its connection owns it.
109
+ */
110
+ stop(track) {
111
+ if (this.stopped.has(track)) return;
112
+ this.stopped.add(track);
113
+ this.dropViews(track);
114
+ const safe = !this.unsafe(track);
115
+ for (const entry of [...this.live]) {
116
+ if (entry.role === 'view' || !entry.stream.getTracks().includes(track)) continue;
117
+ // A track the native side can no longer find stays where it is: the stream is then left, never released.
118
+ if (safe) {
119
+ try {
120
+ entry.stream.removeTrack(track);
121
+ } catch (err) {
122
+ logError('could not take a track out of a stream', err);
123
+ }
124
+ }
125
+ if (entry.stream.getTracks().length > 0) continue;
126
+ if (entry.role === 'capture') this.releaseEntry(entry);
127
+ // The app's, now empty: nothing in it can crash its release, which is the app's to do.
128
+ else if (entry.role === 'app') this.live.delete(entry);
129
+ }
130
+ if (track.remote) return;
131
+ try {
132
+ track.stop();
133
+ } catch (err) {
134
+ logError('could not stop a track', err);
135
+ }
136
+ try {
137
+ track.release?.();
138
+ } catch (err) {
139
+ logError('could not release a track', err);
140
+ }
141
+ this.disposed.add(track);
142
+ if (this.screens.has(track)) {
143
+ try {
144
+ this.onScreenStopped?.();
145
+ } catch (err) {
146
+ logError('could not stop the screen-share service', err);
147
+ }
148
+ }
149
+ }
150
+
151
+ /**
152
+ * The client is about to close what receives these remote tracks (ClientPlatform.detachTracks): release their
153
+ * wrappers now, while their peer connection still exists, and make no new ones.
154
+ */
155
+ detach(tracks) {
156
+ for (const track of tracks) {
157
+ this.dropViews(track);
158
+ this.detached.add(track);
159
+ }
160
+ }
161
+
162
+ /** A view of `track` (VideoTrack), or null when it cannot be shown: ended, stopped or detached. */
163
+ view(track) {
164
+ if (this.stopped.has(track) || this.detached.has(track) || this.unsafe(track) || track.readyState === 'ended') return null;
165
+ let view = this.views.get(track);
166
+ if (!view) {
167
+ let stream;
168
+ try {
169
+ stream = this.makeStream([track]);
170
+ } catch (err) {
171
+ logError('could not make a stream to show a track', err);
172
+ return null;
173
+ }
174
+ const entry = {
175
+ stream,
176
+ role: 'view',
177
+ released: false
178
+ };
179
+ this.entries.set(stream, entry);
180
+ this.live.add(entry);
181
+ view = {
182
+ entry,
183
+ refs: 0,
184
+ ended: new Set()
185
+ };
186
+ this.views.set(track, view);
187
+ }
188
+ view.refs += 1;
189
+ const held = view;
190
+ let done = false;
191
+ return {
192
+ url: held.entry.stream.toURL(),
193
+ onEnd: listener => {
194
+ held.ended.add(listener);
195
+ return () => {
196
+ held.ended.delete(listener);
197
+ };
198
+ },
199
+ release: () => {
200
+ if (done) return;
201
+ done = true;
202
+ held.refs -= 1;
203
+ if (held.refs > 0 || this.views.get(track) !== held) return;
204
+ this.views.delete(track);
205
+ this.releaseEntry(held.entry);
206
+ }
207
+ };
208
+ }
209
+
210
+ /** How many streams made here are not released yet, how many tracks have views, and how many were left unreleased. */
211
+ stats() {
212
+ return {
213
+ live: this.live.size,
214
+ views: this.views.size,
215
+ leaked: this.leaked
216
+ };
217
+ }
218
+
219
+ /** A track the native side may no longer have: disposed here, or remote and ended (its connection closed). */
220
+ unsafe(track) {
221
+ return this.disposed.has(track) || track.remote === true && track.readyState === 'ended';
222
+ }
223
+ dropViews(track) {
224
+ const view = this.views.get(track);
225
+ if (!view) return;
226
+ this.views.delete(track);
227
+ this.releaseEntry(view.entry);
228
+ for (const listener of [...view.ended]) {
229
+ try {
230
+ listener();
231
+ } catch (err) {
232
+ logError('listener for viewEnded threw', err);
233
+ }
234
+ }
235
+ }
236
+ releaseEntry(entry) {
237
+ if (entry.released) return;
238
+ entry.released = true;
239
+ this.live.delete(entry);
240
+ // A view's track that ended may have been released outside this package (an app's own stop() and release()),
241
+ // which only its end shows: its wrapper is left too. Views of live tracks are let go while their tracks live.
242
+ const hazard = entry.role === 'view' ? track => this.unsafe(track) || track.readyState === 'ended' : track => this.unsafe(track);
243
+ if (entry.stream.getTracks().some(hazard)) {
244
+ // Released, it would dispose a native stream that still holds a disposed track, and the app would die.
245
+ this.leaked += 1;
246
+ return;
247
+ }
248
+ try {
249
+ entry.stream.release(false);
250
+ } catch (err) {
251
+ logError('could not release a media stream', err);
252
+ }
253
+ }
254
+ }
255
+ let shared = null;
256
+
257
+ /** The process's book of streams (one for every client and view). */
258
+ export function streamBook() {
259
+ if (!shared) {
260
+ shared = new StreamBook(tracks => {
261
+ const webrtc = loadWebRTC();
262
+ if (!webrtc) throw webrtcMissing();
263
+ return new webrtc.MediaStream(tracks);
264
+ });
265
+ }
266
+ return shared;
267
+ }
268
+ //# sourceMappingURL=streams.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["loadWebRTC","logError","webrtcMissing","StreamBook","live","Set","entries","WeakMap","views","Map","disposed","WeakSet","detached","stopped","screens","leaked","onScreenStopped","constructor","makeStream","adopt","stream","role","known","get","released","add","entry","set","create","tracks","markScreen","track","getTracks","release","releaseEntry","stop","has","dropViews","safe","unsafe","includes","removeTrack","err","length","delete","remote","detach","view","readyState","refs","ended","held","done","url","toURL","onEnd","listener","stats","size","hazard","some","shared","streamBook","webrtc","MediaStream"],"sourceRoot":"../../../src","sources":["platform/streams.ts"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,67 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * The timers the client's own work runs on (reconnect backoff, socket liveness, request deadlines, sampling).
5
+ *
6
+ * React Native's JavaScript timers run on Choreographer frames, which stop when the app leaves the foreground, when
7
+ * the screen goes off even with the app in front, and while a permission dialog is open (Phase 0 S5): a call whose
8
+ * timers stop cannot notice a dead socket or reconnect. On Android they wait natively instead (the module's
9
+ * timerStart/timerStop on a thread of their own) and fire back through its onTimer event, which reaches JavaScript
10
+ * whether frames run or not. Without the native module (iOS, Expo Go) they are JavaScript's own.
11
+ */
12
+
13
+ import { listen } from "../native.js";
14
+ import { logError } from "../errors.js";
15
+
16
+ /** JavaScript's own timers, looked up at each call (a test's fake clock replaces them, and is used). */
17
+ export const jsTimers = Object.freeze({
18
+ setTimeout: (fn, ms) => setTimeout(fn, ms),
19
+ clearTimeout: handle => clearTimeout(handle),
20
+ setInterval: (fn, ms) => setInterval(fn, ms),
21
+ clearInterval: handle => clearInterval(handle)
22
+ });
23
+ /**
24
+ * Timers that wait natively. Ids are this side's and never reused, so a fire already on its way for a timer stopped
25
+ * since is recognised and ignored. One onTimer subscription for the whole process.
26
+ */
27
+ export function nativeTimers(module) {
28
+ const pending = new Map();
29
+ let next = 0;
30
+ let subscribed = false;
31
+ const fire = id => {
32
+ const timer = pending.get(id);
33
+ if (!timer) return;
34
+ if (!timer.repeat) pending.delete(id);
35
+ try {
36
+ timer.fn();
37
+ } catch (err) {
38
+ logError('a timer callback threw', err);
39
+ }
40
+ };
41
+ const start = (fn, ms, repeat) => {
42
+ if (!subscribed) {
43
+ subscribed = true;
44
+ listen(module.onTimer, 'onTimer', fire);
45
+ }
46
+ next += 1;
47
+ const id = next;
48
+ pending.set(id, {
49
+ fn,
50
+ repeat
51
+ });
52
+ const delay = typeof ms === 'number' && Number.isFinite(ms) && ms > 0 ? ms : 0;
53
+ module.timerStart(id, delay, repeat);
54
+ return id;
55
+ };
56
+ const stop = handle => {
57
+ if (typeof handle !== 'number' || !pending.delete(handle)) return;
58
+ module.timerStop(handle);
59
+ };
60
+ return Object.freeze({
61
+ setTimeout: (fn, ms) => start(fn, ms, false),
62
+ clearTimeout: stop,
63
+ setInterval: (fn, ms) => start(fn, ms, true),
64
+ clearInterval: stop
65
+ });
66
+ }
67
+ //# sourceMappingURL=timers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["listen","logError","jsTimers","Object","freeze","setTimeout","fn","ms","clearTimeout","handle","setInterval","clearInterval","nativeTimers","module","pending","Map","next","subscribed","fire","id","timer","get","repeat","delete","err","start","onTimer","set","delay","Number","isFinite","timerStart","stop","timerStop"],"sourceRoot":"../../../src","sources":["platform/timers.ts"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAGA,SAASA,MAAM,QAAQ,cAAW;AAClC,SAASC,QAAQ,QAAQ,cAAW;;AAEpC;AACA,OAAO,MAAMC,QAAwB,GAAGC,MAAM,CAACC,MAAM,CAAC;EACpDC,UAAU,EAAEA,CAACC,EAAc,EAAEC,EAAU,KAAcF,UAAU,CAACC,EAAE,EAAEC,EAAE,CAAC;EACvEC,YAAY,EAAGC,MAAe,IAAWD,YAAY,CAACC,MAAuC,CAAC;EAC9FC,WAAW,EAAEA,CAACJ,EAAc,EAAEC,EAAU,KAAcG,WAAW,CAACJ,EAAE,EAAEC,EAAE,CAAC;EACzEI,aAAa,EAAGF,MAAe,IAAWE,aAAa,CAACF,MAAwC;AAClG,CAAC,CAAC;AAOF;AACA;AACA;AACA;AACA,OAAO,SAASG,YAAYA,CAACC,MAAY,EAAkB;EACzD,MAAMC,OAAO,GAAG,IAAIC,GAAG,CAAkB,CAAC;EAC1C,IAAIC,IAAI,GAAG,CAAC;EACZ,IAAIC,UAAU,GAAG,KAAK;EAEtB,MAAMC,IAAI,GAAIC,EAAU,IAAK;IAC3B,MAAMC,KAAK,GAAGN,OAAO,CAACO,GAAG,CAACF,EAAE,CAAC;IAC7B,IAAI,CAACC,KAAK,EAAE;IACZ,IAAI,CAACA,KAAK,CAACE,MAAM,EAAER,OAAO,CAACS,MAAM,CAACJ,EAAE,CAAC;IACrC,IAAI;MACFC,KAAK,CAACd,EAAE,CAAC,CAAC;IACZ,CAAC,CAAC,OAAOkB,GAAG,EAAE;MACZvB,QAAQ,CAAC,wBAAwB,EAAEuB,GAAG,CAAC;IACzC;EACF,CAAC;EAED,MAAMC,KAAK,GAAGA,CAACnB,EAAc,EAAEC,EAAU,EAAEe,MAAe,KAAa;IACrE,IAAI,CAACL,UAAU,EAAE;MACfA,UAAU,GAAG,IAAI;MACjBjB,MAAM,CAACa,MAAM,CAACa,OAAO,EAAE,SAAS,EAAER,IAAI,CAAC;IACzC;IACAF,IAAI,IAAI,CAAC;IACT,MAAMG,EAAE,GAAGH,IAAI;IACfF,OAAO,CAACa,GAAG,CAACR,EAAE,EAAE;MAAEb,EAAE;MAAEgB;IAAO,CAAC,CAAC;IAC/B,MAAMM,KAAK,GAAG,OAAOrB,EAAE,KAAK,QAAQ,IAAIsB,MAAM,CAACC,QAAQ,CAACvB,EAAE,CAAC,IAAIA,EAAE,GAAG,CAAC,GAAGA,EAAE,GAAG,CAAC;IAC9EM,MAAM,CAACkB,UAAU,CAACZ,EAAE,EAAES,KAAK,EAAEN,MAAM,CAAC;IACpC,OAAOH,EAAE;EACX,CAAC;EAED,MAAMa,IAAI,GAAIvB,MAAe,IAAK;IAChC,IAAI,OAAOA,MAAM,KAAK,QAAQ,IAAI,CAACK,OAAO,CAACS,MAAM,CAACd,MAAM,CAAC,EAAE;IAC3DI,MAAM,CAACoB,SAAS,CAACxB,MAAM,CAAC;EAC1B,CAAC;EAED,OAAON,MAAM,CAACC,MAAM,CAAC;IACnBC,UAAU,EAAEA,CAACC,EAAc,EAAEC,EAAU,KAAckB,KAAK,CAACnB,EAAE,EAAEC,EAAE,EAAE,KAAK,CAAC;IACzEC,YAAY,EAAEwB,IAAI;IAClBtB,WAAW,EAAEA,CAACJ,EAAc,EAAEC,EAAU,KAAckB,KAAK,CAACnB,EAAE,EAAEC,EAAE,EAAE,IAAI,CAAC;IACzEI,aAAa,EAAEqB;EACjB,CAAC,CAAC;AACJ","ignoreList":[]}
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * Whether the app can be seen, for the background pause, adaptive stream and the call service.
5
+ *
6
+ * Android: from the process lifecycle (the native module's isAppVisible / onAppVisibilityChanged, ProcessLifecycleOwner):
7
+ * the app is visible while any of its activities is started. React Native's AppState is not used there: it says
8
+ * `background` while a permission dialog or the screen-share consent is open over the app (Phase 0 S8), which would
9
+ * pause the camera for a dialog.
10
+ *
11
+ * iOS (preview) and Android without the native module: AppState, with `inactive` (a call banner, the app switcher
12
+ * opening) counted as visible.
13
+ */
14
+ import { AppState } from 'react-native';
15
+ import { listen } from "../native.js";
16
+ import { logError } from "../errors.js";
17
+ const shown = state => state !== 'background';
18
+
19
+ /** From the process lifecycle (Android). */
20
+ export function nativeVisibility(module) {
21
+ return {
22
+ visible: () => {
23
+ try {
24
+ return module.isAppVisible();
25
+ } catch (err) {
26
+ logError('could not read the app\'s visibility', err);
27
+ return true;
28
+ }
29
+ },
30
+ subscribe: listener => listen(module.onAppVisibilityChanged, 'onAppVisibilityChanged', e => listener(e.visible))
31
+ };
32
+ }
33
+
34
+ /** From AppState: `active` and `inactive` are visible, `background` is not. */
35
+ export function appStateVisibility() {
36
+ return {
37
+ visible: () => shown(AppState.currentState),
38
+ subscribe: listener => {
39
+ let last = shown(AppState.currentState);
40
+ const subscription = AppState.addEventListener('change', state => {
41
+ const now = shown(state);
42
+ if (now === last) return;
43
+ last = now;
44
+ try {
45
+ listener(now);
46
+ } catch (err) {
47
+ logError('listener for appVisibility threw', err);
48
+ }
49
+ });
50
+ return () => subscription?.remove();
51
+ }
52
+ };
53
+ }
54
+ //# sourceMappingURL=visibility.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["AppState","listen","logError","shown","state","nativeVisibility","module","visible","isAppVisible","err","subscribe","listener","onAppVisibilityChanged","e","appStateVisibility","currentState","last","subscription","addEventListener","now","remove"],"sourceRoot":"../../../src","sources":["platform/visibility.ts"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAASA,QAAQ,QAA6B,cAAc;AAE5D,SAASC,MAAM,QAAQ,cAAW;AAClC,SAASC,QAAQ,QAAQ,cAAW;AAQpC,MAAMC,KAAK,GAAIC,KAAiD,IAAcA,KAAK,KAAK,YAAY;;AAEpG;AACA,OAAO,SAASC,gBAAgBA,CAACC,MAAY,EAAc;EACzD,OAAO;IACLC,OAAO,EAAEA,CAAA,KAAM;MACb,IAAI;QACF,OAAOD,MAAM,CAACE,YAAY,CAAC,CAAC;MAC9B,CAAC,CAAC,OAAOC,GAAG,EAAE;QACZP,QAAQ,CAAC,sCAAsC,EAAEO,GAAG,CAAC;QACrD,OAAO,IAAI;MACb;IACF,CAAC;IACDC,SAAS,EAAGC,QAAQ,IAAKV,MAAM,CAACK,MAAM,CAACM,sBAAsB,EAAE,wBAAwB,EAAGC,CAAC,IAAKF,QAAQ,CAACE,CAAC,CAACN,OAAO,CAAC;EACrH,CAAC;AACH;;AAEA;AACA,OAAO,SAASO,kBAAkBA,CAAA,EAAe;EAC/C,OAAO;IACLP,OAAO,EAAEA,CAAA,KAAMJ,KAAK,CAACH,QAAQ,CAACe,YAAY,CAAC;IAC3CL,SAAS,EAAGC,QAAQ,IAAK;MACvB,IAAIK,IAAI,GAAGb,KAAK,CAACH,QAAQ,CAACe,YAAY,CAAC;MACvC,MAAME,YAAY,GAAGjB,QAAQ,CAACkB,gBAAgB,CAAC,QAAQ,EAAGd,KAAK,IAAK;QAClE,MAAMe,GAAG,GAAGhB,KAAK,CAACC,KAAK,CAAC;QACxB,IAAIe,GAAG,KAAKH,IAAI,EAAE;QAClBA,IAAI,GAAGG,GAAG;QACV,IAAI;UACFR,QAAQ,CAACQ,GAAG,CAAC;QACf,CAAC,CAAC,OAAOV,GAAG,EAAE;UACZP,QAAQ,CAAC,kCAAkC,EAAEO,GAAG,CAAC;QACnD;MACF,CAAC,CAAC;MACF,OAAO,MAAMQ,YAAY,EAAEG,MAAM,CAAC,CAAC;IACrC;EACF,CAAC;AACH","ignoreList":[]}
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * The pre-call check on React Native: @voltkit-rtc/client's preflight with this package's platform. It joins the room
5
+ * the token names, publishes for a few seconds, measures and leaves, and never rejects: offline, a refused permission,
6
+ * a bad token or a missing native module all give a report whose steps say what failed.
7
+ *
8
+ * React Native cannot make a test tone or picture. Without `options.media` the check publishes the microphone, which
9
+ * it captures itself once joined (so nothing opens the microphone for a join that fails) and releases at the end. It
10
+ * never asks for the permission: where it is not granted, the join is still tested and the media step says why.
11
+ * Android shows its microphone indicator for those seconds.
12
+ */
13
+ import { StreamClient } from '@voltkit-rtc/client';
14
+ import { registerVoltkitGlobals } from "./globals.js";
15
+ import { describeError, webrtcMissing } from "./errors.js";
16
+ import { reactNativeClientOptions } from "./create-client.js";
17
+ /** A report for a check that could not even start. */
18
+ function failed(error) {
19
+ return {
20
+ ok: false,
21
+ steps: [{
22
+ name: 'join',
23
+ ok: false,
24
+ ms: null,
25
+ error: describeError(error)
26
+ }],
27
+ path: null,
28
+ rttMs: null,
29
+ lossPct: null,
30
+ uploadKbps: null,
31
+ level: null,
32
+ warnings: []
33
+ };
34
+ }
35
+
36
+ /**
37
+ * What the client's check reads from `options.media` on a platform that cannot copy tracks: which devices to capture
38
+ * again once joined (it never publishes the app's own tracks, which its close would stop). One microphone, the default
39
+ * one, and no camera; nothing native behind it.
40
+ */
41
+ const MICROPHONE_TRACK = Object.freeze({
42
+ kind: 'audio',
43
+ getSettings: () => ({})
44
+ });
45
+ const MICROPHONE_FOR_TEST = Object.freeze({
46
+ getTracks: () => [MICROPHONE_TRACK],
47
+ getAudioTracks: () => [MICROPHONE_TRACK],
48
+ getVideoTracks: () => []
49
+ });
50
+
51
+ /** Test the connection and the media path before a call. Never rejects. */
52
+ export async function preflight(wsUrl, token, options = {}) {
53
+ if (!registerVoltkitGlobals()) return failed(webrtcMissing());
54
+ const {
55
+ background,
56
+ clientOptions,
57
+ ...rest
58
+ } = options;
59
+ try {
60
+ return await StreamClient.preflight(wsUrl, token, {
61
+ ...rest,
62
+ media: rest.media ?? MICROPHONE_FOR_TEST,
63
+ clientOptions: reactNativeClientOptions({
64
+ background,
65
+ clientOptions
66
+ })
67
+ });
68
+ } catch (err) {
69
+ return failed(err);
70
+ }
71
+ }
72
+ //# sourceMappingURL=preflight.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["StreamClient","registerVoltkitGlobals","describeError","webrtcMissing","reactNativeClientOptions","failed","error","ok","steps","name","ms","path","rttMs","lossPct","uploadKbps","level","warnings","MICROPHONE_TRACK","Object","freeze","kind","getSettings","MICROPHONE_FOR_TEST","getTracks","getAudioTracks","getVideoTracks","preflight","wsUrl","token","options","background","clientOptions","rest","media","err"],"sourceRoot":"../../src","sources":["preflight.ts"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAASA,YAAY,QAAqD,qBAAqB;AAC/F,SAASC,sBAAsB,QAAQ,cAAW;AAClD,SAASC,aAAa,EAAEC,aAAa,QAAQ,aAAU;AACvD,SAASC,wBAAwB,QAAgC,oBAAiB;AAOlF;AACA,SAASC,MAAMA,CAACC,KAAc,EAAmB;EAC/C,OAAO;IACLC,EAAE,EAAE,KAAK;IACTC,KAAK,EAAE,CAAC;MAAEC,IAAI,EAAE,MAAM;MAAEF,EAAE,EAAE,KAAK;MAAEG,EAAE,EAAE,IAAI;MAAEJ,KAAK,EAAEJ,aAAa,CAACI,KAAK;IAAE,CAAC,CAAC;IAC3EK,IAAI,EAAE,IAAI;IACVC,KAAK,EAAE,IAAI;IACXC,OAAO,EAAE,IAAI;IACbC,UAAU,EAAE,IAAI;IAChBC,KAAK,EAAE,IAAI;IACXC,QAAQ,EAAE;EACZ,CAAC;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAMC,gBAAgB,GAAGC,MAAM,CAACC,MAAM,CAAC;EAAEC,IAAI,EAAE,OAAO;EAAEC,WAAW,EAAEA,CAAA,MAAO,CAAC,CAAC;AAAE,CAAC,CAAC;AAClF,MAAMC,mBAAmB,GAAGJ,MAAM,CAACC,MAAM,CAAC;EACxCI,SAAS,EAAEA,CAAA,KAAM,CAACN,gBAAgB,CAAC;EACnCO,cAAc,EAAEA,CAAA,KAAM,CAACP,gBAAgB,CAAC;EACxCQ,cAAc,EAAEA,CAAA,KAAM;AACxB,CAAC,CAAC;;AAEF;AACA,OAAO,eAAeC,SAASA,CAACC,KAAa,EAAEC,KAAa,EAAEC,OAAoC,GAAG,CAAC,CAAC,EAA4B;EACjI,IAAI,CAAC5B,sBAAsB,CAAC,CAAC,EAAE,OAAOI,MAAM,CAACF,aAAa,CAAC,CAAC,CAAC;EAC7D,MAAM;IAAE2B,UAAU;IAAEC,aAAa;IAAE,GAAGC;EAAK,CAAC,GAAGH,OAAO;EACtD,IAAI;IACF,OAAO,MAAM7B,YAAY,CAAC0B,SAAS,CAACC,KAAK,EAAEC,KAAK,EAAE;MAChD,GAAGI,IAAI;MACPC,KAAK,EAAED,IAAI,CAACC,KAAK,IAAKX,mBAA4D;MAClFS,aAAa,EAAE3B,wBAAwB,CAAC;QAAE0B,UAAU;QAAEC;MAAc,CAAC;IACvE,CAAC,CAAC;EACJ,CAAC,CAAC,OAAOG,GAAG,EAAE;IACZ,OAAO7B,MAAM,CAAC6B,GAAG,CAAC;EACpB;AACF","ignoreList":[]}
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * VoltkitProvider for React Native: @voltkit-rtc/react's provider (the same props, token hand-over and StrictMode
5
+ * behaviour, so every re-exported hook works below it) making its client with this package's platform, plus what a call
6
+ * needs from the device: the call audio, the call service and the background pause.
7
+ *
8
+ * In Expo Go, or an app not rebuilt after installing react-native-webrtc, no client is made: onError gets
9
+ * `media-unavailable` with `{ reason: 'webrtc-missing' }` (it needs a development build) and the hooks keep their
10
+ * defaults. Nothing throws.
11
+ */
12
+ import { useEffect, useMemo, useRef } from 'react';
13
+ import { Platform } from 'react-native';
14
+ import { VoltkitProvider as ReactVoltkitProvider } from '@voltkit-rtc/react';
15
+ import { registerVoltkitGlobals } from "./globals.js";
16
+ import { nativeModule } from "./native.js";
17
+ import { nativeMissing, webrtcMissing } from "./errors.js";
18
+ import { reactNativeClientOptions } from "./create-client.js";
19
+ import { NativeSession } from "./native-session.js";
20
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
21
+ /** One StreamClient for the components below, with the device's audio, the call service and the background pause. */
22
+ export function VoltkitProvider({
23
+ audio,
24
+ background,
25
+ callService,
26
+ clientOptions,
27
+ client,
28
+ wsUrl,
29
+ token,
30
+ onError,
31
+ children,
32
+ ...rest
33
+ }) {
34
+ const webrtc = useMemo(() => registerVoltkitGlobals(), []);
35
+ const errors = useRef(onError);
36
+ useEffect(() => {
37
+ errors.current = onError;
38
+ });
39
+ const wanted = Boolean(client || wsUrl && token);
40
+ useEffect(() => {
41
+ if (!wanted) return;
42
+ if (!webrtc) errors.current?.(webrtcMissing());else if (Platform.OS === 'android' && !nativeModule()) errors.current?.(nativeMissing('Background calls, audio routing and native timers'));
43
+ }, [webrtc, wanted]);
44
+
45
+ // Read when the provider makes a client, as @voltkit-rtc/react reads clientOptions: a later change does not remake it.
46
+ const options = useMemo(() => webrtc ? reactNativeClientOptions({
47
+ background,
48
+ clientOptions
49
+ }) : undefined,
50
+ // eslint-disable-next-line react-hooks/exhaustive-deps
51
+ [webrtc, wsUrl, token]);
52
+ // The call service reads the setting from the client it runs for (an app-made client has its own); this stands in
53
+ // when the client's options cannot be read.
54
+ const pauseCamera = options?.pauseCameraInBackground === true;
55
+ return /*#__PURE__*/_jsxs(ReactVoltkitProvider, {
56
+ ...rest,
57
+ wsUrl: webrtc ? wsUrl : undefined,
58
+ token: webrtc ? token : undefined,
59
+ client: webrtc ? client : null,
60
+ clientOptions: options,
61
+ onError: onError,
62
+ children: [webrtc ? /*#__PURE__*/_jsx(NativeSession, {
63
+ audio: audio,
64
+ callService: callService,
65
+ pauseCamera: pauseCamera,
66
+ onError: errors
67
+ }) : null, children]
68
+ });
69
+ }
70
+ //# sourceMappingURL=provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["useEffect","useMemo","useRef","Platform","VoltkitProvider","ReactVoltkitProvider","registerVoltkitGlobals","nativeModule","nativeMissing","webrtcMissing","reactNativeClientOptions","NativeSession","jsx","_jsx","jsxs","_jsxs","audio","background","callService","clientOptions","client","wsUrl","token","onError","children","rest","webrtc","errors","current","wanted","Boolean","OS","options","undefined","pauseCamera","pauseCameraInBackground"],"sourceRoot":"../../src","sources":["provider.tsx"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAASA,SAAS,EAAEC,OAAO,EAAEC,MAAM,QAA2B,OAAO;AACrE,SAASC,QAAQ,QAAQ,cAAc;AACvC,SAASC,eAAe,IAAIC,oBAAoB,QAAgE,oBAAoB;AACpI,SAASC,sBAAsB,QAAQ,cAAW;AAClD,SAASC,YAAY,QAAQ,aAAU;AACvC,SAASC,aAAa,EAAEC,aAAa,QAAQ,aAAU;AACvD,SAASC,wBAAwB,QAAgC,oBAAiB;AAClF,SAASC,aAAa,QAAwD,qBAAkB;AAAC,SAAAC,GAAA,IAAAC,IAAA,EAAAC,IAAA,IAAAC,KAAA;AAsBjG;AACA,OAAO,SAASX,eAAeA,CAAC;EAC9BY,KAAK;EACLC,UAAU;EACVC,WAAW;EACXC,aAAa;EACbC,MAAM;EACNC,KAAK;EACLC,KAAK;EACLC,OAAO;EACPC,QAAQ;EACR,GAAGC;AACiB,CAAC,EAAgB;EACrC,MAAMC,MAAM,GAAGzB,OAAO,CAAC,MAAMK,sBAAsB,CAAC,CAAC,EAAE,EAAE,CAAC;EAC1D,MAAMqB,MAAM,GAAGzB,MAAM,CAACqB,OAAO,CAAC;EAC9BvB,SAAS,CAAC,MAAM;IACd2B,MAAM,CAACC,OAAO,GAAGL,OAAO;EAC1B,CAAC,CAAC;EAEF,MAAMM,MAAM,GAAGC,OAAO,CAACV,MAAM,IAAKC,KAAK,IAAIC,KAAM,CAAC;EAClDtB,SAAS,CAAC,MAAM;IACd,IAAI,CAAC6B,MAAM,EAAE;IACb,IAAI,CAACH,MAAM,EAAEC,MAAM,CAACC,OAAO,GAAGnB,aAAa,CAAC,CAAC,CAAC,CAAC,KAC1C,IAAIN,QAAQ,CAAC4B,EAAE,KAAK,SAAS,IAAI,CAACxB,YAAY,CAAC,CAAC,EAAEoB,MAAM,CAACC,OAAO,GAAGpB,aAAa,CAAC,mDAAmD,CAAC,CAAC;EAC7I,CAAC,EAAE,CAACkB,MAAM,EAAEG,MAAM,CAAC,CAAC;;EAEpB;EACA,MAAMG,OAAO,GAAG/B,OAAO,CACrB,MAAOyB,MAAM,GAAGhB,wBAAwB,CAAC;IAAEO,UAAU;IAAEE;EAAc,CAAC,CAAC,GAAGc,SAAU;EACpF;EACA,CAACP,MAAM,EAAEL,KAAK,EAAEC,KAAK,CACvB,CAAC;EACD;EACA;EACA,MAAMY,WAAW,GAAGF,OAAO,EAAEG,uBAAuB,KAAK,IAAI;EAE7D,oBACEpB,KAAA,CAACV,oBAAoB;IAAA,GACfoB,IAAI;IACRJ,KAAK,EAAEK,MAAM,GAAGL,KAAK,GAAGY,SAAU;IAClCX,KAAK,EAAEI,MAAM,GAAGJ,KAAK,GAAGW,SAAU;IAClCb,MAAM,EAAEM,MAAM,GAAGN,MAAM,GAAG,IAAK;IAC/BD,aAAa,EAAEa,OAAQ;IACvBT,OAAO,EAAEA,OAAQ;IAAAC,QAAA,GAEhBE,MAAM,gBAAGb,IAAA,CAACF,aAAa;MAACK,KAAK,EAAEA,KAAM;MAACE,WAAW,EAAEA,WAAY;MAACgB,WAAW,EAAEA,WAAY;MAACX,OAAO,EAAEI;IAAO,CAAE,CAAC,GAAG,IAAI,EACpHH,QAAQ;EAAA,CACW,CAAC;AAE3B","ignoreList":[]}
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * The native side of @voltkit-rtc/react-native on Android, as one codegen TurboModule (plan §5.1): audio routing
5
+ * (ported from the Android SDK's AudioRouter), the call service, native timers, app visibility from the process
6
+ * lifecycle, the network, and stopping react-native-webrtc's screen-share service. iOS has no native module in 0.1.0.
7
+ *
8
+ * Read it through src/native.ts, never directly: this module is null in Expo Go, on iOS and wherever the app was not
9
+ * rebuilt after installing the package, and native.ts turns that into a typed error.
10
+ *
11
+ * Strings that hold one of a few values are typed `string` here, as codegen needs; the values are listed beside each.
12
+ */
13
+
14
+ import { TurboModuleRegistry } from 'react-native';
15
+
16
+ /** An audio input or output, as the Android SDK lists it (`MediaDevice`). */
17
+
18
+ /** Devices came or went while a client held the audio (a headset plugged in, Bluetooth connected). */
19
+
20
+ /** Where call audio plays now; null once the last client let the audio go. */
21
+
22
+ /** Audio focus, while a client holds the audio: `gain` | `loss` | `lossTransient` | `lossTransientCanDuck`. */
23
+
24
+ /** The audio device module could not open or keep the microphone. */
25
+
26
+ /** The app went to the foreground (any activity started) or the background, from ProcessLifecycleOwner. */
27
+
28
+ /** The network came back (`handover` false) or the default network changed, say Wi-Fi to mobile data (true). */
29
+
30
+ /** What the call service shows and the call it runs for: its foreground service types are worked out from these. */
31
+
32
+ /** The call service: whether the app declares it, and whether it runs, with which foreground service types. */
33
+
34
+ /** `started` | `updated` | `stopped` | `leave` (the notification's action) | `taskRemoved` | `failed`. */
35
+
36
+ export default TurboModuleRegistry.get('VoltkitRtc');
37
+ //# sourceMappingURL=NativeVoltkitRtc.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["TurboModuleRegistry","get"],"sourceRoot":"../../../src","sources":["specs/NativeVoltkitRtc.ts"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,SAASA,mBAAmB,QAAQ,cAAc;;AAElD;;AAcA;;AAOA;;AAKA;;AAKA;;AAKA;;AAKA;;AAKA;;AAeA;;AAQA;;AAiGA,eAAeA,mBAAmB,CAACC,GAAG,CAAO,YAAY,CAAC","ignoreList":[]}