react-native-audio-browser 0.2.0-next.8 → 0.2.0-next.9

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.
@@ -90,6 +90,7 @@ import kotlin.coroutines.suspendCoroutine
90
90
  import kotlinx.coroutines.CancellationException
91
91
  import kotlinx.coroutines.Job
92
92
  import kotlinx.coroutines.MainScope
93
+ import kotlinx.coroutines.cancel
93
94
  import kotlinx.coroutines.cancelChildren
94
95
  import kotlinx.coroutines.delay
95
96
  import kotlinx.coroutines.launch
@@ -100,10 +101,37 @@ import timber.log.Timber
100
101
  @DoNotStrip
101
102
  class AudioBrowser : HybridAudioBrowserSpec(), ServiceConnection {
102
103
 
103
- /** Called by Nitro when the JS object is destroyed (incl. JS runtime reloads). */
104
+ /**
105
+ * Called by Nitro when the JS object is destroyed (incl. JS runtime reloads).
106
+ *
107
+ * The Service outlives this object, so everything registered in `init` or on connect has to be
108
+ * undone here. Left alone, the running [Player] goes on invoking callbacks into a dead JSI
109
+ * runtime, and every reload strands another ServiceConnection and lifecycle observer, each
110
+ * retaining a BrowserManager.
111
+ */
104
112
  override fun dispose() {
105
113
  systemVolumeMonitor.destroy()
106
114
  outputMonitor.destroy()
115
+
116
+ connectedService?.let { service ->
117
+ service.player.setCallbacks(null)
118
+ service.player.browser = null
119
+ service.onBatteryWarningPendingChanged = null
120
+ }
121
+ connectedService = null
122
+ mediaBrowserFuture = null
123
+
124
+ serviceBinding.unbind(this)
125
+
126
+ // Only when still ours: on a reload the replacement instance may already own the slot.
127
+ if (carConnectionTarget === onCarConnectedChanged) carConnectionTarget = null
128
+
129
+ // Drop queued work first, then post the removal — LifecycleRegistry is main-thread only,
130
+ // which is why the observer is added the same way.
131
+ handler.removeCallbacksAndMessages(null)
132
+ handler.post { ProcessLifecycleOwner.get().lifecycle.removeObserver(lifecycleObserver) }
133
+
134
+ mainScope.cancel()
107
135
  super.dispose()
108
136
  }
109
137
 
@@ -150,6 +178,8 @@ class AudioBrowser : HybridAudioBrowserSpec(), ServiceConnection {
150
178
  private var mediaBrowserFuture: ListenableFuture<MediaBrowser>? = null
151
179
  private var setupOptions = PlayerSetupOptions()
152
180
  private var connectedService: Service? = null
181
+
182
+ private val serviceBinding = ServiceBinding(context)
153
183
  private var setupPromise: ((Unit) -> Unit)? = null
154
184
 
155
185
  // Initial player state staged before the player exists — from setup options or the imperative
@@ -244,7 +274,7 @@ class AudioBrowser : HybridAudioBrowserSpec(), ServiceConnection {
244
274
  try {
245
275
  Timber.d("Attempting to auto-bind to existing AudioBrowserService from AudioBrowser")
246
276
  val intent = Intent(context, Service::class.java)
247
- val bound = context.bindService(intent, this@AudioBrowser, Context.BIND_AUTO_CREATE)
277
+ val bound = serviceBinding.bind(intent, this@AudioBrowser)
248
278
  Timber.d("Auto-bind result: $bound")
249
279
 
250
280
  if (!bound) {
@@ -811,12 +841,7 @@ class AudioBrowser : HybridAudioBrowserSpec(), ServiceConnection {
811
841
  // Service not connected yet, bind to service
812
842
  suspendCoroutine<Unit> { continuation ->
813
843
  Timber.d("Binding to AudioBrowserService")
814
- val bound =
815
- context.bindService(
816
- Intent(context, Service::class.java),
817
- this@AudioBrowser,
818
- Context.BIND_AUTO_CREATE,
819
- )
844
+ val bound = serviceBinding.bind(Intent(context, Service::class.java), this@AudioBrowser)
820
845
 
821
846
  if (!bound) {
822
847
  continuation.resumeWithException(
@@ -0,0 +1,46 @@
1
+ package com.audiobrowser
2
+
3
+ import android.content.Context
4
+ import android.content.Intent
5
+ import android.content.ServiceConnection
6
+ import timber.log.Timber
7
+
8
+ /**
9
+ * Exactly-once bookkeeping for a [ServiceConnection].
10
+ *
11
+ * `bindService` may be called from more than one place — an auto-bind at construction and again
12
+ * from setup — but the binding must be released exactly once, and only if one was ever taken:
13
+ * [Context.unbindService] throws when the connection was never registered. Kept apart from the
14
+ * caller so the rule is one object's job, and so it can be tested without a JSI runtime.
15
+ */
16
+ internal class ServiceBinding(private val context: Context) {
17
+
18
+ @Volatile
19
+ var isBound: Boolean = false
20
+ private set
21
+
22
+ /**
23
+ * Binds if not already bound, and returns whether a binding is held afterwards. A second call
24
+ * while bound is a no-op: Android would otherwise count the extra bind and expect a matching
25
+ * unbind.
26
+ */
27
+ fun bind(intent: Intent, connection: ServiceConnection): Boolean {
28
+ if (isBound) return true
29
+ val bound = context.bindService(intent, connection, Context.BIND_AUTO_CREATE)
30
+ if (bound) isBound = true
31
+ return bound
32
+ }
33
+
34
+ /**
35
+ * Releases the binding if one is held. Safe to call repeatedly, and safe when the service has
36
+ * already died — [onServiceDisconnected][ServiceConnection.onServiceDisconnected] means the
37
+ * service went away, not that the binding did, so the unbind is still required.
38
+ */
39
+ fun unbind(connection: ServiceConnection) {
40
+ if (!isBound) return
41
+ isBound = false
42
+ // Throws if the binding is somehow already gone, which is the outcome we wanted anyway.
43
+ runCatching { context.unbindService(connection) }
44
+ .onFailure { Timber.w(it, "unbindService failed") }
45
+ }
46
+ }
@@ -0,0 +1,68 @@
1
+ package com.audiobrowser
2
+
3
+ import android.content.ComponentName
4
+ import android.content.Intent
5
+ import android.content.ServiceConnection
6
+ import android.os.IBinder
7
+ import org.junit.Assert.assertEquals
8
+ import org.junit.Assert.assertFalse
9
+ import org.junit.Assert.assertTrue
10
+ import org.junit.Test
11
+ import org.junit.runner.RunWith
12
+ import org.robolectric.RobolectricTestRunner
13
+ import org.robolectric.RuntimeEnvironment
14
+ import org.robolectric.Shadows.shadowOf
15
+
16
+ // Robolectric: bindService/unbindService only exist under the framework, and ShadowApplication
17
+ // records both sides — which is precisely the leak being guarded against.
18
+ @RunWith(RobolectricTestRunner::class)
19
+ class ServiceBindingTest {
20
+
21
+ private val app = RuntimeEnvironment.getApplication()
22
+ private val intent = Intent(app, Service::class.java)
23
+
24
+ private val connection =
25
+ object : ServiceConnection {
26
+ override fun onServiceConnected(name: ComponentName?, service: IBinder?) = Unit
27
+
28
+ override fun onServiceDisconnected(name: ComponentName?) = Unit
29
+ }
30
+
31
+ /** Both the auto-bind at construction and setup's bind reach the same object. */
32
+ @Test
33
+ fun bindingTwiceTakesOnlyOneBinding() {
34
+ val binding = ServiceBinding(app)
35
+
36
+ assertTrue(binding.bind(intent, connection))
37
+ assertTrue(binding.bind(intent, connection))
38
+
39
+ assertEquals(1, shadowOf(app).boundServiceConnections.size)
40
+
41
+ binding.unbind(connection)
42
+
43
+ assertTrue(shadowOf(app).boundServiceConnections.isEmpty())
44
+ assertEquals(1, shadowOf(app).unboundServiceConnections.size)
45
+ }
46
+
47
+ /** dispose() must not throw, and Android throws when unbinding a connection it never had. */
48
+ @Test
49
+ fun unbindWithoutBindIsANoOp() {
50
+ val binding = ServiceBinding(app)
51
+
52
+ binding.unbind(connection)
53
+
54
+ assertFalse(binding.isBound)
55
+ assertTrue(shadowOf(app).unboundServiceConnections.isEmpty())
56
+ }
57
+
58
+ @Test
59
+ fun unbindIsIdempotent() {
60
+ val binding = ServiceBinding(app)
61
+ binding.bind(intent, connection)
62
+
63
+ binding.unbind(connection)
64
+ binding.unbind(connection)
65
+
66
+ assertEquals(1, shadowOf(app).unboundServiceConnections.size)
67
+ }
68
+ }
@@ -16,6 +16,10 @@ import os.log
16
16
  /// Only safe when the caller blocks until the MainActor work completes (DispatchQueue.main.sync).
17
17
  private struct UncheckedSendableBox<T>: @unchecked Sendable { let value: T }
18
18
 
19
+ /// `@unchecked Sendable` because it must be: the spec's requirements are all
20
+ /// nonisolated and Nitro calls them synchronously on the JS thread, so the class
21
+ /// can't be `@MainActor`. Isolation is therefore per-property, and `@unchecked`
22
+ /// means the compiler won't tell you when a new one needs it.
19
23
  public class HybridAudioBrowser: HybridAudioBrowserSpec, @unchecked Sendable {
20
24
  private let logger = Logger(subsystem: "com.audiobrowser", category: "AudioBrowser")
21
25
 
@@ -32,6 +36,8 @@ public class HybridAudioBrowser: HybridAudioBrowserSpec, @unchecked Sendable {
32
36
 
33
37
  // MARK: - Private Properties
34
38
 
39
+ /// Main-confined by convention, not annotation: `deinit` reads it as a
40
+ /// safety net and can't hop. Reach it from `onMainActor` / `@MainActor`.
35
41
  private var player: TrackPlayer?
36
42
  private let networkMonitor = NetworkMonitor()
37
43
  private let playbackStateStore = PlaybackStateStore()
@@ -43,27 +49,31 @@ public class HybridAudioBrowser: HybridAudioBrowserSpec, @unchecked Sendable {
43
49
  private var mediaServicesResetObserver: NSObjectProtocol?
44
50
  /// Re-applies our resolved audio-session category. Captured at setup so a
45
51
  /// media-services reset (which clears the category) can restore it.
46
- private var applyAudioSessionCategory: () -> Void = {}
47
- private var nowPlayingOverride: NowPlayingUpdate?
52
+ @MainActor private var applyAudioSessionCategory: () -> Void = {}
53
+ @MainActor private var nowPlayingOverride: NowPlayingUpdate?
48
54
  /// When false, the now-playing surface uses the raw track fields (override + formatter ignored).
49
- private var nowPlayingMetadataEnabled = true
55
+ @MainActor private var nowPlayingMetadataEnabled = true
50
56
  /// Customizes the now-playing title/subtitle from the track + live timed metadata + playback state.
51
- private var nowPlayingMetadataFormatter: ((_ params: FormatNowPlayingParams) -> Promise<NowPlayingUpdate?>)?
52
- /// Keep the media session controllable through a terminal error (see `keepSessionAliveOnError`).
53
- private var keepSessionAliveOnError = true
57
+ @MainActor private var nowPlayingMetadataFormatter: ((_ params: FormatNowPlayingParams) -> Promise<NowPlayingUpdate?>)?
54
58
  /// Initial player state staged before the player exists — from setup options or the imperative
55
59
  /// setters called pre-setup. Strict last-write-wins; consumed when the player comes up.
56
- private var pendingPlayWhenReady: Bool?
57
- private var pendingRepeatMode: RepeatMode?
60
+ @MainActor private var pendingPlayWhenReady: Bool?
61
+ @MainActor private var pendingRepeatMode: RepeatMode?
58
62
  /// Latest live timed (ICY/ID3) metadata, passed to the formatter. Cleared on track change.
59
- private var latestTimedMetadata: TimedMetadata?
60
- private let playerOptions = PlayerUpdateOptions()
63
+ @MainActor private var latestTimedMetadata: TimedMetadata?
64
+ @MainActor private let playerOptions = PlayerUpdateOptions()
61
65
 
62
66
  /// Configured playback rates for the playback-rate capability (for CarPlay rate cycling)
63
- var playbackRates: [Double] { playerOptions.playbackRates }
64
- var carPlayUpNextButton: Bool { playerOptions.carPlayUpNextButton }
65
- var carPlayNowPlayingButtons: [CarPlayNowPlayingButton] { playerOptions.carPlayNowPlayingButtons }
66
- private var lastNavigationError: NavigationError? {
67
+ @MainActor var playbackRates: [Double] { playerOptions.playbackRates }
68
+ @MainActor var carPlayUpNextButton: Bool { playerOptions.carPlayUpNextButton }
69
+ @MainActor var carPlayNowPlayingButtons: [CarPlayNowPlayingButton] {
70
+ playerOptions.carPlayNowPlayingButtons
71
+ }
72
+
73
+ /// Written from the JS thread, the cooperative pool and MainActor, with a
74
+ /// `didSet` that calls back into Nitro. MainActor-isolated so the compiler
75
+ /// requires an `onMainActor` hop at every access.
76
+ @MainActor private var lastNavigationError: NavigationError? {
67
77
  didSet {
68
78
  // Skip if both nil (no real change)
69
79
  guard oldValue != nil || lastNavigationError != nil else { return }
@@ -71,7 +81,8 @@ public class HybridAudioBrowser: HybridAudioBrowserSpec, @unchecked Sendable {
71
81
  }
72
82
  }
73
83
 
74
- private var lastFormattedNavigationError: FormattedNavigationError? {
84
+ /// Isolated for the same reason as ``lastNavigationError``.
85
+ @MainActor private var lastFormattedNavigationError: FormattedNavigationError? {
75
86
  didSet {
76
87
  // Skip if both nil (no real change)
77
88
  guard oldValue != nil || lastFormattedNavigationError != nil else { return }
@@ -156,6 +167,10 @@ public class HybridAudioBrowser: HybridAudioBrowserSpec, @unchecked Sendable {
156
167
  androidControllerOfflineError: nil, carPlayLoadingTitle: nil, resolveAlbumUrl: nil, formatNavigationError: nil,
157
168
  ) {
158
169
  didSet {
170
+ // Copied here, on the setter's thread: the Task below outlives this call,
171
+ // and Nitro can reassign `configuration` — a C++ struct holding
172
+ // std::string/std::function — from the JS thread while it runs.
173
+ let configuredPath = configuration.path
159
174
  onMainActor { browserManager.config = BrowserConfig(from: configuration) }
160
175
 
161
176
  // Query tabs and navigate to initial path after config is set (matches Kotlin behavior)
@@ -166,12 +181,9 @@ public class HybridAudioBrowser: HybridAudioBrowserSpec, @unchecked Sendable {
166
181
  Task {
167
182
  let tabs = try? await browserManager.queryTabs()
168
183
  // Navigate to configured path, first tab, or "/"
169
- let initialPath = configuration.path ?? tabs?.first?.url ?? "/"
184
+ let initialPath = configuredPath ?? tabs?.first?.url ?? "/"
170
185
  // Clear error before navigation (matches Kotlin clearNavigationError())
171
- await MainActor.run {
172
- lastNavigationError = nil
173
- lastFormattedNavigationError = nil
174
- }
186
+ clearNavigationError()
175
187
  do {
176
188
  try await browserManager.navigate(initialPath)
177
189
  } catch {
@@ -370,7 +382,7 @@ public class HybridAudioBrowser: HybridAudioBrowserSpec, @unchecked Sendable {
370
382
  private func handleNavigationError(_ error: Error, path: String) {
371
383
  let navError = NavigationError.from(error)
372
384
 
373
- lastNavigationError = navError
385
+ onMainActor { lastNavigationError = navError }
374
386
 
375
387
  // Format the error (async if using JS callback, sync for defaults)
376
388
  let defaultFormatted = navError.defaultFormatted()
@@ -380,27 +392,40 @@ public class HybridAudioBrowser: HybridAudioBrowserSpec, @unchecked Sendable {
380
392
  // The result callbacks are @Sendable: a plain closure would inherit MainActor
381
393
  // isolation from this block, and Nitro resolves its promises synchronously on the
382
394
  // JS thread — Swift 6.2's dynamic isolation check then traps on closure entry.
383
- // The property is JS-thread-touched elsewhere too, so no hop back is needed.
395
+ // They therefore hop back explicitly, like every other writer.
384
396
  DispatchQueue.main.async { [weak self] in
385
397
  formatter(params)
386
398
  .then { @Sendable [weak self] customDisplay in
387
- self?.lastFormattedNavigationError = customDisplay ?? defaultFormatted
399
+ self?.setFormattedNavigationError(customDisplay ?? defaultFormatted)
388
400
  }
389
401
  .catch { @Sendable [weak self] _ in
390
- self?.lastFormattedNavigationError = defaultFormatted
402
+ self?.setFormattedNavigationError(defaultFormatted)
391
403
  }
392
404
  }
393
405
  } else {
394
- lastFormattedNavigationError = defaultFormatted
406
+ setFormattedNavigationError(defaultFormatted)
407
+ }
408
+ }
409
+
410
+ /// Callable from any thread — the Nitro promise callbacks below resolve on
411
+ /// the JS thread.
412
+ private func setFormattedNavigationError(_ formatted: FormattedNavigationError?) {
413
+ onMainActor { lastFormattedNavigationError = formatted }
414
+ }
415
+
416
+ /// Synchronous on purpose: the `didSet`s notify JS, which has to happen
417
+ /// before the navigation that may set them again.
418
+ private func clearNavigationError() {
419
+ onMainActor {
420
+ lastNavigationError = nil
421
+ lastFormattedNavigationError = nil
395
422
  }
396
423
  }
397
424
 
398
425
  // MARK: - Browser Methods
399
426
 
400
427
  public func navigatePath(path: String) throws {
401
- // Clear error synchronously before starting navigation (didSet notifies JS)
402
- lastNavigationError = nil
403
- lastFormattedNavigationError = nil
428
+ clearNavigationError()
404
429
  Task {
405
430
  do {
406
431
  try await browserManager.navigate(path)
@@ -411,7 +436,10 @@ public class HybridAudioBrowser: HybridAudioBrowserSpec, @unchecked Sendable {
411
436
  }
412
437
 
413
438
  public func navigateTrack(track: Track) throws {
414
- Task {
439
+ // @MainActor: `player` is main-confined, and `trackSelector.select` is
440
+ // MainActor anyway — a bare Task read the reference off the cooperative
441
+ // pool, racing the assignment in `setupPlayer`.
442
+ Task { @MainActor in
415
443
  guard let player else { return }
416
444
  let result = await trackSelector.select(track: track, player: player)
417
445
  switch result {
@@ -445,9 +473,7 @@ public class HybridAudioBrowser: HybridAudioBrowserSpec, @unchecked Sendable {
445
473
  }
446
474
 
447
475
  private func navigateToBrowsableUrl(_ url: String) {
448
- // Clear error synchronously before starting navigation (didSet notifies JS)
449
- lastNavigationError = nil
450
- lastFormattedNavigationError = nil
476
+ clearNavigationError()
451
477
  Task {
452
478
  do {
453
479
  try await browserManager.navigate(url)
@@ -470,11 +496,11 @@ public class HybridAudioBrowser: HybridAudioBrowserSpec, @unchecked Sendable {
470
496
  }
471
497
 
472
498
  public func getNavigationError() throws -> NavigationError? {
473
- lastNavigationError
499
+ onMainActor { lastNavigationError }
474
500
  }
475
501
 
476
502
  public func getFormattedNavigationError() throws -> FormattedNavigationError? {
477
- lastFormattedNavigationError
503
+ onMainActor { lastFormattedNavigationError }
478
504
  }
479
505
 
480
506
  /// Internal signal sent on `externalContentChangedEmitter` to tell CarPlay to
@@ -733,16 +759,16 @@ public class HybridAudioBrowser: HybridAudioBrowserSpec, @unchecked Sendable {
733
759
  self?.onSleepTimerChanged(state)
734
760
  }
735
761
 
736
- // Now-playing: whether to manage metadata, the optional formatter that owns the rendered
737
- // lines, and whether to keep the session alive through a terminal error.
762
+ // Now-playing: whether to manage metadata, and the optional formatter that owns the
763
+ // rendered lines.
738
764
  nowPlayingMetadataEnabled = options.autoUpdateNowPlayingMetadata ?? true
739
765
  nowPlayingMetadataFormatter = options.nowPlayingMetadataFormatter
740
- // Stored for API symmetry, but iOS needs no masking: a terminal error resolves the playback
741
- // state to *paused* (PlaybackCoordinator.applySideEffects), the now-playing info is retained
742
- // (never cleared on error), and next/previous stay enabled (gated on queue position, not
743
- // state). So the session stays controllable through errors by default — the behavior Android
744
- // achieves via InterceptingPlayer is already the iOS norm.
745
- keepSessionAliveOnError = options.keepSessionAliveOnError ?? true
766
+ // `options.keepSessionAliveOnError` is deliberately ignored here: iOS needs no masking.
767
+ // A terminal error resolves the playback state to *paused*
768
+ // (PlaybackCoordinator.applySideEffects), the now-playing info is retained (never cleared
769
+ // on error), and next/previous stay enabled (gated on queue position, not state). So the
770
+ // session stays controllable through errors by default — the behavior Android achieves via
771
+ // InterceptingPlayer is already the iOS norm.
746
772
 
747
773
  // The bundled runtime options and initial state are part of the atomic launch
748
774
  // description. Stage the state first so setup options and earlier pre-setup setter
@@ -819,7 +845,7 @@ public class HybridAudioBrowser: HybridAudioBrowserSpec, @unchecked Sendable {
819
845
  }
820
846
 
821
847
  public func getOptions() throws -> Options {
822
- playerOptions.toOptions()
848
+ onMainActor { playerOptions.toOptions() }
823
849
  }
824
850
 
825
851
  public func setPlaybackIntervalEnabled(enabled: Bool) {
@@ -1121,11 +1147,11 @@ public class HybridAudioBrowser: HybridAudioBrowserSpec, @unchecked Sendable {
1121
1147
  /// metadata can't stomp it mid-flash. Reverted by a NATIVE timer — JS
1122
1148
  /// timers pause with a backgrounded host on Android, and the lock screen
1123
1149
  /// is exactly the backgrounded case — and cleared early on track change.
1124
- private var nowPlayingFlash: NowPlayingUpdate?
1125
- private var nowPlayingFlashRevert: DispatchWorkItem?
1150
+ @MainActor private var nowPlayingFlash: NowPlayingUpdate?
1151
+ @MainActor private var nowPlayingFlashRevert: DispatchWorkItem?
1126
1152
 
1127
1153
  /// Pending debounced audio-session release (see `playerShouldReleaseSession`).
1128
- private var sessionReleaseWork: DispatchWorkItem?
1154
+ @MainActor private var sessionReleaseWork: DispatchWorkItem?
1129
1155
 
1130
1156
  public func flashNowPlaying(update: NowPlayingUpdate, durationMs: Double) throws {
1131
1157
  onMainActor {
@@ -1151,6 +1177,7 @@ public class HybridAudioBrowser: HybridAudioBrowserSpec, @unchecked Sendable {
1151
1177
  }
1152
1178
  }
1153
1179
 
1180
+ @MainActor
1154
1181
  private func cancelNowPlayingFlash() {
1155
1182
  nowPlayingFlashRevert?.cancel()
1156
1183
  nowPlayingFlashRevert = nil
@@ -1354,8 +1381,10 @@ public class HybridAudioBrowser: HybridAudioBrowserSpec, @unchecked Sendable {
1354
1381
  guard let self else { return }
1355
1382
  // Re-apply our category (the reset cleared it), then have the player
1356
1383
  // recreate itself and reconnect the current stream.
1357
- self.applyAudioSessionCategory()
1358
- self.onMainActor { self.player?.handleMediaServicesReset() }
1384
+ self.onMainActor {
1385
+ self.applyAudioSessionCategory()
1386
+ self.player?.handleMediaServicesReset()
1387
+ }
1359
1388
  }
1360
1389
  }
1361
1390
 
@@ -1586,6 +1615,7 @@ extension HybridAudioBrowser: TrackPlayerCallbacks {
1586
1615
  DispatchQueue.main.asyncAfter(deadline: .now() + 3, execute: release)
1587
1616
  }
1588
1617
 
1618
+ @MainActor
1589
1619
  private func cancelSessionRelease() {
1590
1620
  sessionReleaseWork?.cancel()
1591
1621
  sessionReleaseWork = nil
@@ -8,9 +8,9 @@ exports.onOptionsChanged = void 0;
8
8
  exports.updateOptions = updateOptions;
9
9
  exports.useOptions = useOptions;
10
10
  var _native = require("../../native");
11
- var _validateOptions = require("./validateOptions");
12
11
  var _NativeUpdatedValue = require("../../utils/NativeUpdatedValue");
13
12
  var _useNativeUpdatedValue = require("../../utils/useNativeUpdatedValue");
13
+ var _validateOptions = require("./validateOptions");
14
14
  // MARK: - Types
15
15
 
16
16
  /**
@@ -1 +1 @@
1
- {"version":3,"names":["_native","require","_validateOptions","_NativeUpdatedValue","_useNativeUpdatedValue","updateOptions","options","validateIOSUpdateOptions","ios","nativeBrowser","getOptions","onOptionsChanged","exports","NativeUpdatedValue","emitterize","cb","useOptions","useNativeUpdatedValue"],"sourceRoot":"../../../../src","sources":["features/player/options.ts"],"mappings":";;;;;;;;;AAEA,IAAAA,OAAA,GAAAC,OAAA;AACA,IAAAC,gBAAA,GAAAD,OAAA;AACA,IAAAE,mBAAA,GAAAF,OAAA;AACA,IAAAG,sBAAA,GAAAH,OAAA;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAgGA;AACA;AACA;AACA;AACA;;AAQA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAaA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AA4CA;AACA;AACA;AACA;;AA4EA;AACA;AACA;AACA;;AAOA;AACA;AACA;AACA;;AA6BA;AACA;AACA;AACA;;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAuDA;AACA;AACA;AACA;;AAwCA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAASI,aAAaA,CAACC,OAAsB,EAAQ;EAC1D,IAAAC,yCAAwB,EAACD,OAAO,CAACE,GAAG,CAAC;EACrCC,qBAAa,CAACJ,aAAa,CAACC,OAAO,CAAC;AACtC;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAASI,UAAUA,CAAA,EAAY;EACpC,OAAOD,qBAAa,CAACC,UAAU,CAAC,CAAC;AACnC;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACO,MAAMC,gBAAgB,GAAAC,OAAA,CAAAD,gBAAA,GAAGE,sCAAkB,CAACC,UAAU,CAC1DC,EAAE,IAAMN,qBAAa,CAACE,gBAAgB,GAAGI,EAC5C,CAAC;;AAED;;AAEA;AACA;AACA;AACA;AACO,SAASC,UAAUA,CAAA,EAAY;EACpC,OAAO,IAAAC,4CAAqB,EAACP,UAAU,EAAEC,gBAAgB,CAAC;AAC5D","ignoreList":[]}
1
+ {"version":3,"names":["_native","require","_NativeUpdatedValue","_useNativeUpdatedValue","_validateOptions","updateOptions","options","validateIOSUpdateOptions","ios","nativeBrowser","getOptions","onOptionsChanged","exports","NativeUpdatedValue","emitterize","cb","useOptions","useNativeUpdatedValue"],"sourceRoot":"../../../../src","sources":["features/player/options.ts"],"mappings":";;;;;;;;;AAEA,IAAAA,OAAA,GAAAC,OAAA;AACA,IAAAC,mBAAA,GAAAD,OAAA;AACA,IAAAE,sBAAA,GAAAF,OAAA;AACA,IAAAG,gBAAA,GAAAH,OAAA;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAgGA;AACA;AACA;AACA;AACA;;AAQA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAaA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AA4CA;AACA;AACA;AACA;;AA4EA;AACA;AACA;AACA;;AAOA;AACA;AACA;AACA;;AA6BA;AACA;AACA;AACA;;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAuDA;AACA;AACA;AACA;;AAwCA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAASI,aAAaA,CAACC,OAAsB,EAAQ;EAC1D,IAAAC,yCAAwB,EAACD,OAAO,CAACE,GAAG,CAAC;EACrCC,qBAAa,CAACJ,aAAa,CAACC,OAAO,CAAC;AACtC;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAASI,UAAUA,CAAA,EAAY;EACpC,OAAOD,qBAAa,CAACC,UAAU,CAAC,CAAC;AACnC;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACO,MAAMC,gBAAgB,GAAAC,OAAA,CAAAD,gBAAA,GAAGE,sCAAkB,CAACC,UAAU,CAC1DC,EAAE,IAAMN,qBAAa,CAACE,gBAAgB,GAAGI,EAC5C,CAAC;;AAED;;AAEA;AACA;AACA;AACA;AACO,SAASC,UAAUA,CAAA,EAAY;EACpC,OAAO,IAAAC,4CAAqB,EAACP,UAAU,EAAEC,gBAAgB,CAAC;AAC5D","ignoreList":[]}
@@ -1,9 +1,9 @@
1
1
  "use strict";
2
2
 
3
3
  import { nativeBrowser } from '../../native';
4
- import { validateIOSUpdateOptions } from './validateOptions';
5
4
  import { NativeUpdatedValue } from '../../utils/NativeUpdatedValue';
6
5
  import { useNativeUpdatedValue } from '../../utils/useNativeUpdatedValue';
6
+ import { validateIOSUpdateOptions } from './validateOptions';
7
7
 
8
8
  // MARK: - Types
9
9
 
@@ -1 +1 @@
1
- {"version":3,"names":["nativeBrowser","validateIOSUpdateOptions","NativeUpdatedValue","useNativeUpdatedValue","updateOptions","options","ios","getOptions","onOptionsChanged","emitterize","cb","useOptions"],"sourceRoot":"../../../../src","sources":["features/player/options.ts"],"mappings":";;AAEA,SAASA,aAAa,QAAQ,cAAc;AAC5C,SAASC,wBAAwB,QAAQ,mBAAmB;AAC5D,SAASC,kBAAkB,QAAQ,gCAAgC;AACnE,SAASC,qBAAqB,QAAQ,mCAAmC;;AAEzE;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAgGA;AACA;AACA;AACA;AACA;;AAQA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAaA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AA4CA;AACA;AACA;AACA;;AA4EA;AACA;AACA;AACA;;AAOA;AACA;AACA;AACA;;AA6BA;AACA;AACA;AACA;;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAuDA;AACA;AACA;AACA;;AAwCA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,aAAaA,CAACC,OAAsB,EAAQ;EAC1DJ,wBAAwB,CAACI,OAAO,CAACC,GAAG,CAAC;EACrCN,aAAa,CAACI,aAAa,CAACC,OAAO,CAAC;AACtC;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASE,UAAUA,CAAA,EAAY;EACpC,OAAOP,aAAa,CAACO,UAAU,CAAC,CAAC;AACnC;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,gBAAgB,GAAGN,kBAAkB,CAACO,UAAU,CAC1DC,EAAE,IAAMV,aAAa,CAACQ,gBAAgB,GAAGE,EAC5C,CAAC;;AAED;;AAEA;AACA;AACA;AACA;AACA,OAAO,SAASC,UAAUA,CAAA,EAAY;EACpC,OAAOR,qBAAqB,CAACI,UAAU,EAAEC,gBAAgB,CAAC;AAC5D","ignoreList":[]}
1
+ {"version":3,"names":["nativeBrowser","NativeUpdatedValue","useNativeUpdatedValue","validateIOSUpdateOptions","updateOptions","options","ios","getOptions","onOptionsChanged","emitterize","cb","useOptions"],"sourceRoot":"../../../../src","sources":["features/player/options.ts"],"mappings":";;AAEA,SAASA,aAAa,QAAQ,cAAc;AAC5C,SAASC,kBAAkB,QAAQ,gCAAgC;AACnE,SAASC,qBAAqB,QAAQ,mCAAmC;AACzE,SAASC,wBAAwB,QAAQ,mBAAmB;;AAE5D;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAgGA;AACA;AACA;AACA;AACA;;AAQA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAaA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AA4CA;AACA;AACA;AACA;;AA4EA;AACA;AACA;AACA;;AAOA;AACA;AACA;AACA;;AA6BA;AACA;AACA;AACA;;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAuDA;AACA;AACA;AACA;;AAwCA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,aAAaA,CAACC,OAAsB,EAAQ;EAC1DF,wBAAwB,CAACE,OAAO,CAACC,GAAG,CAAC;EACrCN,aAAa,CAACI,aAAa,CAACC,OAAO,CAAC;AACtC;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASE,UAAUA,CAAA,EAAY;EACpC,OAAOP,aAAa,CAACO,UAAU,CAAC,CAAC;AACnC;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,gBAAgB,GAAGP,kBAAkB,CAACQ,UAAU,CAC1DC,EAAE,IAAMV,aAAa,CAACQ,gBAAgB,GAAGE,EAC5C,CAAC;;AAED;;AAEA;AACA;AACA;AACA;AACA,OAAO,SAASC,UAAUA,CAAA,EAAY;EACpC,OAAOT,qBAAqB,CAACK,UAAU,EAAEC,gBAAgB,CAAC;AAC5D","ignoreList":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../../../../../src/features/player/options.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../../../../../src/features/player/options.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-audio-browser",
3
- "version": "0.2.0-next.8",
3
+ "version": "0.2.0-next.9",
4
4
  "description": "react-native-audio-browser is a react native package built with Nitro",
5
5
  "keywords": [
6
6
  "react-native",
@@ -1,9 +1,9 @@
1
1
  import type { FavoriteConfig } from '../../types'
2
2
  import type { CarPlayNowPlayingButton } from '../../types/browser'
3
3
  import { nativeBrowser } from '../../native'
4
- import { validateIOSUpdateOptions } from './validateOptions'
5
4
  import { NativeUpdatedValue } from '../../utils/NativeUpdatedValue'
6
5
  import { useNativeUpdatedValue } from '../../utils/useNativeUpdatedValue'
6
+ import { validateIOSUpdateOptions } from './validateOptions'
7
7
 
8
8
  // MARK: - Types
9
9
 
@@ -27,7 +27,14 @@ import { describe, it, expect } from 'vitest'
27
27
  const SRC = join(process.cwd(), 'src')
28
28
  const ENTRY = join(SRC, 'index.ts')
29
29
 
30
- const VALUE_KINDS = new Set(['const', 'let', 'var', 'function', 'class', 'enum'])
30
+ const VALUE_KINDS = new Set([
31
+ 'const',
32
+ 'let',
33
+ 'var',
34
+ 'function',
35
+ 'class',
36
+ 'enum'
37
+ ])
31
38
 
32
39
  function resolveModule(fromFile: string, spec: string): string | undefined {
33
40
  const base = resolve(dirname(fromFile), spec.replace(/\.tsx?$/, ''))