react-native-audio-browser 0.1.0 → 0.2.0-next.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 (902) hide show
  1. package/AudioBrowser.podspec +1 -1
  2. package/README.md +180 -2
  3. package/android/build.gradle +10 -0
  4. package/android/gradle.properties +1 -1
  5. package/android/src/main/AndroidManifest.xml +15 -0
  6. package/android/src/main/java/com/audiobrowser/AudioBrowser.kt +401 -141
  7. package/android/src/main/java/com/audiobrowser/Callbacks.kt +4 -6
  8. package/android/src/main/java/com/audiobrowser/Service.kt +67 -18
  9. package/android/src/main/java/com/audiobrowser/browser/ArtworkResolutionRegistry.kt +37 -0
  10. package/android/src/main/java/com/audiobrowser/browser/BrowseArtworkRegistry.kt +34 -0
  11. package/android/src/main/java/com/audiobrowser/browser/BrowserManager.kt +443 -178
  12. package/android/src/main/java/com/audiobrowser/browser/BrowserUrlResolution.kt +300 -0
  13. package/android/src/main/java/com/audiobrowser/browser/JsonArtwork.kt +79 -0
  14. package/android/src/main/java/com/audiobrowser/browser/JsonModels.kt +41 -4
  15. package/android/src/main/java/com/audiobrowser/browser/SectionScope.kt +43 -0
  16. package/android/src/main/java/com/audiobrowser/browser/TrackLoadHandler.kt +4 -4
  17. package/android/src/main/java/com/audiobrowser/extension/ResolvedTrackExt.kt +35 -0
  18. package/android/src/main/java/com/audiobrowser/http/RequestConfigBuilder.kt +109 -97
  19. package/android/src/main/java/com/audiobrowser/model/PlaybackMetadata.kt +6 -10
  20. package/android/src/main/java/com/audiobrowser/model/PlayerSetupOptions.kt +40 -8
  21. package/android/src/main/java/com/audiobrowser/model/PlayerUpdateOptions.kt +31 -37
  22. package/android/src/main/java/com/audiobrowser/player/AutomaticBufferManager.kt +4 -1
  23. package/android/src/main/java/com/audiobrowser/player/CapabilityControls.kt +119 -0
  24. package/android/src/main/java/com/audiobrowser/player/DynamicLoadControl.kt +18 -1
  25. package/android/src/main/java/com/audiobrowser/player/EqualizerController.kt +153 -0
  26. package/android/src/main/java/com/audiobrowser/player/InterceptingPlayer.kt +141 -0
  27. package/android/src/main/java/com/audiobrowser/player/MediaFactory.kt +15 -3
  28. package/android/src/main/java/com/audiobrowser/player/MediaSessionCallback.kt +415 -131
  29. package/android/src/main/java/com/audiobrowser/player/MediaSessionCommandManager.kt +154 -276
  30. package/android/src/main/java/com/audiobrowser/player/NowPlayingUpdater.kt +348 -0
  31. package/android/src/main/java/com/audiobrowser/player/PlaybackErrorClassifier.kt +129 -0
  32. package/android/src/main/java/com/audiobrowser/player/PlaybackStateMachine.kt +85 -0
  33. package/android/src/main/java/com/audiobrowser/player/PlaybackStateStore.kt +27 -5
  34. package/android/src/main/java/com/audiobrowser/player/PlaybackTimer.kt +56 -0
  35. package/android/src/main/java/com/audiobrowser/player/Player.kt +452 -576
  36. package/android/src/main/java/com/audiobrowser/player/PlayerCapabilitiesExt.kt +20 -0
  37. package/android/src/main/java/com/audiobrowser/player/PlayerEngineFactory.kt +130 -0
  38. package/android/src/main/java/com/audiobrowser/player/PlayerListener.kt +190 -67
  39. package/android/src/main/java/com/audiobrowser/player/RetryLoadErrorHandlingPolicy.kt +117 -53
  40. package/android/src/main/java/com/audiobrowser/player/SleepTimer.kt +37 -3
  41. package/android/src/main/java/com/audiobrowser/player/SleepTimerManager.kt +80 -0
  42. package/android/src/main/java/com/audiobrowser/player/StuckRecoveryPolicy.kt +50 -0
  43. package/android/src/main/java/com/audiobrowser/player/TransformingDataSource.kt +84 -34
  44. package/android/src/main/java/com/audiobrowser/player/VolumeFader.kt +81 -0
  45. package/android/src/main/java/com/audiobrowser/tls/AiaCertChaser.kt +141 -0
  46. package/android/src/main/java/com/audiobrowser/tls/AiaChasingTrustManager.kt +37 -0
  47. package/android/src/main/java/com/audiobrowser/tls/AiaTls.kt +41 -0
  48. package/android/src/main/java/com/audiobrowser/tls/CachingCertificateFetcher.kt +209 -0
  49. package/android/src/main/java/com/audiobrowser/util/ArtworkContentProvider.kt +161 -0
  50. package/android/src/main/java/com/audiobrowser/util/ArtworkUris.kt +28 -0
  51. package/android/src/main/java/com/audiobrowser/util/ArtworkVariant.kt +26 -0
  52. package/android/src/main/java/com/audiobrowser/util/BrowserPathHelper.kt +24 -0
  53. package/android/src/main/java/com/audiobrowser/util/CoilArtworkLoader.kt +49 -0
  54. package/android/src/main/java/com/audiobrowser/util/CoilArtworkLoaderHolder.kt +36 -0
  55. package/android/src/main/java/com/audiobrowser/util/CoilBitmapLoader.kt +23 -300
  56. package/android/src/main/java/com/audiobrowser/util/EqualizerManager.kt +13 -23
  57. package/android/src/main/java/com/audiobrowser/util/MediaExtrasBuilder.kt +2 -2
  58. package/android/src/main/java/com/audiobrowser/util/MetadataAdapter.kt +4 -3
  59. package/android/src/main/java/com/audiobrowser/util/OutputMonitor.kt +211 -0
  60. package/android/src/main/java/com/audiobrowser/util/OutputSwitcher.kt +58 -0
  61. package/android/src/main/java/com/audiobrowser/util/PlayingStateFactory.kt +2 -1
  62. package/android/src/main/java/com/audiobrowser/util/RatingFavorites.kt +14 -0
  63. package/android/src/main/java/com/audiobrowser/util/SvgArtworkRenderer.kt +6 -111
  64. package/android/src/main/java/com/audiobrowser/util/SystemVolumeMonitor.kt +22 -8
  65. package/android/src/main/java/com/audiobrowser/util/TrackFactory.kt +111 -80
  66. package/android/src/main/res/values/strings.xml +4 -0
  67. package/android/src/test/java/com/audiobrowser/TestFixtures.kt +166 -0
  68. package/android/src/test/java/com/audiobrowser/browser/ArtworkResolutionRegistryTest.kt +46 -0
  69. package/android/src/test/java/com/audiobrowser/browser/BrowseArtworkRegistryTest.kt +39 -0
  70. package/android/src/test/java/com/audiobrowser/browser/BrowserManagerBuildApiRequestTest.kt +114 -0
  71. package/android/src/test/java/com/audiobrowser/browser/BrowserManagerLayerResolutionTest.kt +141 -0
  72. package/android/src/test/java/com/audiobrowser/browser/BrowserManagerTest.kt +4 -0
  73. package/android/src/test/java/com/audiobrowser/browser/BrowserUrlResolutionTest.kt +177 -0
  74. package/android/src/test/java/com/audiobrowser/browser/JsonArtworkTest.kt +54 -0
  75. package/android/src/test/java/com/audiobrowser/browser/SectionScopeTest.kt +96 -0
  76. package/android/src/test/java/com/audiobrowser/browser/SimpleRouterTest.kt +1 -2
  77. package/android/src/test/java/com/audiobrowser/http/RequestConfigBuilderTest.kt +72 -0
  78. package/android/src/test/java/com/audiobrowser/player/CapabilityControlsTest.kt +159 -0
  79. package/android/src/test/java/com/audiobrowser/player/DynamicLoadControlTest.kt +56 -0
  80. package/android/src/test/java/com/audiobrowser/player/EqualizerControllerTest.kt +216 -0
  81. package/android/src/test/java/com/audiobrowser/player/NowPlayingUpdaterTest.kt +442 -0
  82. package/android/src/test/java/com/audiobrowser/player/PlaybackErrorClassifierTest.kt +191 -0
  83. package/android/src/test/java/com/audiobrowser/player/PlaybackStateMachineTest.kt +198 -0
  84. package/android/src/test/java/com/audiobrowser/player/PlaybackTimerTest.kt +137 -0
  85. package/android/src/test/java/com/audiobrowser/player/PlayerEngineFactoryTest.kt +36 -0
  86. package/android/src/test/java/com/audiobrowser/player/RetryLoadErrorHandlingPolicyTest.kt +268 -0
  87. package/android/src/test/java/com/audiobrowser/player/SessionErrorMaskTest.kt +68 -0
  88. package/android/src/test/java/com/audiobrowser/player/StuckRecoveryPolicyTest.kt +40 -0
  89. package/android/src/test/java/com/audiobrowser/player/TransformingDataSourceTest.kt +193 -0
  90. package/android/src/test/java/com/audiobrowser/tls/AiaCertChaserTest.kt +107 -0
  91. package/android/src/test/java/com/audiobrowser/tls/AiaChasingTrustManagerTest.kt +73 -0
  92. package/android/src/test/java/com/audiobrowser/tls/CachingCertificateFetcherTest.kt +75 -0
  93. package/android/src/test/java/com/audiobrowser/tls/CertFixtures.kt +18 -0
  94. package/android/src/test/java/com/audiobrowser/util/ArtworkContentProviderTest.kt +163 -0
  95. package/android/src/test/java/com/audiobrowser/util/ArtworkUrisTest.kt +34 -0
  96. package/android/src/test/java/com/audiobrowser/util/BrowserPathHelperTest.kt +28 -0
  97. package/android/src/test/java/com/audiobrowser/util/CoilArtworkLoaderHolderTest.kt +53 -0
  98. package/android/src/test/java/com/audiobrowser/util/CoilArtworkLoaderTest.kt +58 -0
  99. package/android/src/test/java/com/audiobrowser/util/FakeImageLoader.kt +57 -0
  100. package/android/src/test/java/com/audiobrowser/util/PlayingStateFactoryTest.kt +40 -0
  101. package/android/src/test/java/com/audiobrowser/util/RatingFavoritesTest.kt +34 -0
  102. package/android/src/test/java/com/audiobrowser/util/TrackFactoryBrowseTest.kt +50 -0
  103. package/android/src/test/java/com/audiobrowser/util/TrackFactoryMediaIdTest.kt +63 -0
  104. package/android/src/test/java/com/audiobrowser/util/TrackFactoryRatingTest.kt +35 -0
  105. package/android/src/test/resources/certs/isrg-root-x1.pem +31 -0
  106. package/android/src/test/resources/certs/letsencrypt-r13.der +0 -0
  107. package/android/src/test/resources/certs/letsencrypt-r13.pem +29 -0
  108. package/android/src/test/resources/certs/stationplaylist-leaf.pem +34 -0
  109. package/ios/Browser/BrowserConfig.swift +41 -11
  110. package/ios/Browser/BrowserManager+URLResolution.swift +213 -93
  111. package/ios/Browser/BrowserManager.swift +303 -110
  112. package/ios/Browser/BrowserPathHelper.swift +32 -3
  113. package/ios/Browser/JsonModels.swift +287 -66
  114. package/ios/Browser/MediaResolveComposer.swift +114 -0
  115. package/ios/Browser/SearchDrillIn.swift +44 -0
  116. package/ios/Browser/SectionScope.swift +35 -0
  117. package/ios/Browser/TabBarEntries.swift +15 -0
  118. package/ios/CarPlay/CPInterfaceController+Safe.swift +126 -0
  119. package/ios/CarPlay/CarPlayArtworkResolver.swift +6 -6
  120. package/ios/CarPlay/CarPlayController.swift +739 -149
  121. package/ios/CarPlay/CarPlayImageLoader.swift +57 -8
  122. package/ios/CarPlay/CarPlayListItemFactory.swift +44 -35
  123. package/ios/CarPlay/CarPlayNowPlayingManager.swift +180 -36
  124. package/ios/CarPlay/ImageRowItem+CarPlay.swift +19 -0
  125. package/ios/CarPlay/RNABAudioBrowser.h +15 -10
  126. package/ios/CarPlay/RNABAudioBrowser.m +15 -14
  127. package/ios/CarPlay/RNABCarPlaySceneDelegate.m +2 -0
  128. package/ios/CarPlay/RNABMediaAddHandler.swift +75 -0
  129. package/ios/CarPlay/RNABMediaAffinityHandler.swift +69 -0
  130. package/ios/CarPlay/RNABMediaIntentHandler.swift +53 -43
  131. package/ios/Extension/Capability+RemoteCommand.swift +7 -9
  132. package/ios/Extension/ChapterMetadata+AVFoundation.swift +1 -1
  133. package/ios/Extension/NavigationError+Conversion.swift +8 -1
  134. package/ios/Extension/PlayerCapabilities+Favorite.swift +20 -0
  135. package/ios/Extension/RequestConfig+Copying.swift +31 -0
  136. package/ios/Extension/ResolvedTrack+Copying.swift +10 -4
  137. package/ios/Extension/TimedMetadata+AVFoundation.swift +1 -1
  138. package/ios/Extension/Track+AVPlayer.swift +4 -4
  139. package/ios/Extension/Track+Copying.swift +9 -3
  140. package/ios/Extension/TrackMetadata+AVFoundation.swift +1 -1
  141. package/ios/Extension/Variant+Artwork.swift +49 -0
  142. package/ios/HybridAudioBrowser.swift +750 -173
  143. package/ios/Model/NitroTypeStubs.swift +299 -224
  144. package/ios/Model/PlayerUpdateOptions.swift +23 -23
  145. package/ios/Model/RemoteCommand.swift +6 -6
  146. package/ios/Model/TrackPlayerError.swift +82 -18
  147. package/ios/NowPlayingInfo/NowPlayingInfoController.swift +99 -121
  148. package/ios/NowPlayingInfo/SilentAudioPrimer.swift +73 -0
  149. package/ios/Observer/PlayerItemNotificationObserver.swift +45 -5
  150. package/ios/Observer/PlayerItemPropertyObserver.swift +27 -4
  151. package/ios/Observer/PlayerTimeObserver.swift +3 -53
  152. package/ios/Option/SessionCategories.swift +33 -11
  153. package/ios/Player/AirPlayStallJudgement.swift +25 -0
  154. package/ios/Player/EndOfTrackJudgement.swift +32 -0
  155. package/ios/Player/LoadSeekCoordinator.swift +16 -1
  156. package/ios/Player/MediaIntentCriteria.swift +139 -0
  157. package/ios/Player/MediaLoader.swift +28 -10
  158. package/ios/Player/NowPlayingUpdater.swift +119 -26
  159. package/ios/Player/PersistedPlaybackState.swift +11 -0
  160. package/ios/Player/PlaybackCoordinator.swift +282 -51
  161. package/ios/Player/PlaybackCoordinatorCallbacks.swift +6 -1
  162. package/ios/Player/PlaybackEffectHandler.swift +19 -9
  163. package/ios/Player/PlaybackErrorHandler.swift +97 -13
  164. package/ios/Player/PlaybackStateMachine.swift +18 -13
  165. package/ios/Player/PlaybackStateStore.swift +27 -0
  166. package/ios/Player/PlaybackTimer.swift +61 -0
  167. package/ios/Player/PlayingStateManager.swift +3 -2
  168. package/ios/Player/QueueManager.swift +67 -61
  169. package/ios/Player/RetryManager.swift +97 -21
  170. package/ios/Player/SleepTimerHandling.swift +8 -0
  171. package/ios/Player/SleepTimerManager.swift +38 -5
  172. package/ios/Player/VolumeFader.swift +77 -0
  173. package/ios/RemoteCommand/RemoteCommandController.swift +31 -15
  174. package/ios/Tests/AirPlayStallJudgementTests.swift +52 -0
  175. package/ios/Tests/BrowserPathHelperTests.swift +28 -0
  176. package/ios/Tests/CarPlayArtworkResolverTests.swift +39 -39
  177. package/ios/Tests/ChapterMetadataAVFoundationTests.swift +2 -2
  178. package/ios/Tests/EndOfTrackJudgementTests.swift +35 -0
  179. package/ios/Tests/JsonModelsTests.swift +58 -0
  180. package/ios/Tests/LoadSeekCoordinatorTests.swift +38 -7
  181. package/ios/Tests/MediaIntentCriteriaTests.swift +170 -0
  182. package/ios/Tests/MediaLoaderAssetOptionsTests.swift +46 -0
  183. package/ios/Tests/MediaLoaderTests.swift +23 -8
  184. package/ios/Tests/MediaResolveTests.swift +126 -0
  185. package/ios/Tests/OnceValueTests.swift +79 -0
  186. package/ios/Tests/PlaybackCoordinatorTests.swift +784 -13
  187. package/ios/Tests/PlaybackErrorHandlerTests.swift +380 -46
  188. package/ios/Tests/PlaybackStateMachineTests.swift +42 -10
  189. package/ios/Tests/PlaybackStateStoreTests.swift +48 -0
  190. package/ios/Tests/PlaybackTimerTests.swift +55 -0
  191. package/ios/Tests/PlayingStateManagerTests.swift +57 -0
  192. package/ios/Tests/QueueManagerTests.swift +149 -18
  193. package/ios/Tests/ResolvedTrackCopyingTests.swift +15 -8
  194. package/ios/Tests/RetryManagerTests.swift +89 -0
  195. package/ios/Tests/SearchDrillInTests.swift +63 -0
  196. package/ios/Tests/SectionScopeTests.swift +82 -0
  197. package/ios/Tests/SleepTimerManagerTests.swift +104 -0
  198. package/ios/Tests/Support/TestTypes.swift +61 -20
  199. package/ios/Tests/TabBarEntriesTests.swift +71 -0
  200. package/ios/Tests/TrackSelectorTests.swift +15 -15
  201. package/ios/TrackPlayer.swift +380 -58
  202. package/ios/TrackPlayerCallbacks.swift +0 -6
  203. package/ios/TrackSelector.swift +5 -5
  204. package/ios/Util/ArtworkImageFetcher.swift +4 -2
  205. package/ios/Util/NetworkMonitor.swift +7 -3
  206. package/ios/Util/OnceValue.swift +34 -0
  207. package/lib/commonjs/features/browser-config.js +227 -0
  208. package/lib/commonjs/features/browser-config.js.map +1 -0
  209. package/lib/commonjs/features/browser.js +59 -158
  210. package/lib/commonjs/features/browser.js.map +1 -1
  211. package/lib/commonjs/features/carConnection.js +42 -0
  212. package/lib/commonjs/features/carConnection.js.map +1 -0
  213. package/lib/commonjs/features/errors.js +34 -2
  214. package/lib/commonjs/features/errors.js.map +1 -1
  215. package/lib/commonjs/features/gate.js +149 -0
  216. package/lib/commonjs/features/gate.js.map +1 -0
  217. package/lib/commonjs/features/index.js +22 -0
  218. package/lib/commonjs/features/index.js.map +1 -1
  219. package/lib/commonjs/features/metadata.js.map +1 -1
  220. package/lib/commonjs/features/nowPlaying.js +35 -0
  221. package/lib/commonjs/features/nowPlaying.js.map +1 -1
  222. package/lib/commonjs/features/output.js +37 -23
  223. package/lib/commonjs/features/output.js.map +1 -1
  224. package/lib/commonjs/features/playback/controls.js +9 -0
  225. package/lib/commonjs/features/playback/controls.js.map +1 -1
  226. package/lib/commonjs/features/playback/index.js +11 -0
  227. package/lib/commonjs/features/playback/index.js.map +1 -1
  228. package/lib/commonjs/features/playback/progress.js +28 -12
  229. package/lib/commonjs/features/playback/progress.js.map +1 -1
  230. package/lib/commonjs/features/playback/trackPlaybackTime.js +92 -0
  231. package/lib/commonjs/features/playback/trackPlaybackTime.js.map +1 -0
  232. package/lib/commonjs/features/playback/volume.js +1 -1
  233. package/lib/commonjs/features/player/options.js +49 -13
  234. package/lib/commonjs/features/player/options.js.map +1 -1
  235. package/lib/commonjs/features/player/setup.js +249 -3
  236. package/lib/commonjs/features/player/setup.js.map +1 -1
  237. package/lib/commonjs/features/queue/queue.js +10 -3
  238. package/lib/commonjs/features/queue/queue.js.map +1 -1
  239. package/lib/commonjs/features/remoteControls.js +1 -12
  240. package/lib/commonjs/features/remoteControls.js.map +1 -1
  241. package/lib/commonjs/features/sleepTimer.js +9 -4
  242. package/lib/commonjs/features/sleepTimer.js.map +1 -1
  243. package/lib/commonjs/native.js +5 -0
  244. package/lib/commonjs/native.js.map +1 -1
  245. package/lib/commonjs/native.web.js +4 -1
  246. package/lib/commonjs/native.web.js.map +1 -1
  247. package/lib/commonjs/utils/LazyNativeEmitter.js +0 -3
  248. package/lib/commonjs/utils/LazyNativeEmitter.js.map +1 -1
  249. package/lib/commonjs/utils/NativeUpdatedValue.js +0 -3
  250. package/lib/commonjs/utils/NativeUpdatedValue.js.map +1 -1
  251. package/lib/commonjs/utils/artwork.js +31 -0
  252. package/lib/commonjs/utils/artwork.js.map +1 -0
  253. package/lib/commonjs/web/NativeAudioBrowser.js +301 -124
  254. package/lib/commonjs/web/NativeAudioBrowser.js.map +1 -1
  255. package/lib/commonjs/web/TrackPlayer/PlaybackStateMachine.js +71 -0
  256. package/lib/commonjs/web/TrackPlayer/PlaybackStateMachine.js.map +1 -0
  257. package/lib/commonjs/web/TrackPlayer/PlaybackTimer.js +34 -0
  258. package/lib/commonjs/web/TrackPlayer/PlaybackTimer.js.map +1 -0
  259. package/lib/commonjs/web/TrackPlayer/Player.js +90 -26
  260. package/lib/commonjs/web/TrackPlayer/Player.js.map +1 -1
  261. package/lib/commonjs/web/TrackPlayer/PlayingStateFactory.js +21 -0
  262. package/lib/commonjs/web/TrackPlayer/PlayingStateFactory.js.map +1 -0
  263. package/lib/commonjs/web/TrackPlayer/QueueManager.js +273 -0
  264. package/lib/commonjs/web/TrackPlayer/QueueManager.js.map +1 -0
  265. package/lib/commonjs/web/TrackPlayer/QueuePlayer.js +158 -0
  266. package/lib/commonjs/web/TrackPlayer/QueuePlayer.js.map +1 -0
  267. package/lib/commonjs/web/TrackPlayer/RepeatMode.js +1 -1
  268. package/lib/commonjs/web/TrackPlayer/RepeatMode.js.map +1 -1
  269. package/lib/commonjs/web/TrackPlayer/SleepTimer.js +34 -3
  270. package/lib/commonjs/web/TrackPlayer/SleepTimer.js.map +1 -1
  271. package/lib/commonjs/web/TrackPlayer/VolumeFader.js +75 -0
  272. package/lib/commonjs/web/TrackPlayer/VolumeFader.js.map +1 -0
  273. package/lib/commonjs/web/TrackPlayer/index.js +13 -5
  274. package/lib/commonjs/web/TrackPlayer/index.js.map +1 -1
  275. package/lib/commonjs/web/browser/BrowserManager.js +176 -50
  276. package/lib/commonjs/web/browser/BrowserManager.js.map +1 -1
  277. package/lib/commonjs/web/browser/NavigationErrorManager.js +3 -1
  278. package/lib/commonjs/web/browser/NavigationErrorManager.js.map +1 -1
  279. package/lib/commonjs/web/browser/SearchManager.js +11 -9
  280. package/lib/commonjs/web/browser/SearchManager.js.map +1 -1
  281. package/lib/commonjs/web/browser/assertBrowsePageShape.js +22 -0
  282. package/lib/commonjs/web/browser/assertBrowsePageShape.js.map +1 -0
  283. package/lib/commonjs/web/browser/classifyTrackNavigation.js +41 -0
  284. package/lib/commonjs/web/browser/classifyTrackNavigation.js.map +1 -0
  285. package/lib/commonjs/web/browser/parseSearchResponse.js +20 -0
  286. package/lib/commonjs/web/browser/parseSearchResponse.js.map +1 -0
  287. package/lib/commonjs/web/http/HttpClient.js +4 -23
  288. package/lib/commonjs/web/http/HttpClient.js.map +1 -1
  289. package/lib/commonjs/web/http/RequestConfigBuilder.js +107 -58
  290. package/lib/commonjs/web/http/RequestConfigBuilder.js.map +1 -1
  291. package/lib/commonjs/web/playbackErrorKind.js +57 -0
  292. package/lib/commonjs/web/playbackErrorKind.js.map +1 -0
  293. package/lib/commonjs/web/player/MediaSessionManager.js +121 -0
  294. package/lib/commonjs/web/player/MediaSessionManager.js.map +1 -0
  295. package/lib/commonjs/web/player/NowPlayingManager.js +6 -5
  296. package/lib/commonjs/web/player/NowPlayingManager.js.map +1 -1
  297. package/lib/commonjs/web/player/OptionsManager.js +9 -17
  298. package/lib/commonjs/web/player/OptionsManager.js.map +1 -1
  299. package/lib/commonjs/web/player/RemoteCommandController.js +96 -0
  300. package/lib/commonjs/web/player/RemoteCommandController.js.map +1 -0
  301. package/lib/module/features/browser-config.js +221 -0
  302. package/lib/module/features/browser-config.js.map +1 -0
  303. package/lib/module/features/browser.js +53 -156
  304. package/lib/module/features/browser.js.map +1 -1
  305. package/lib/module/features/carConnection.js +37 -0
  306. package/lib/module/features/carConnection.js.map +1 -0
  307. package/lib/module/features/errors.js +34 -2
  308. package/lib/module/features/errors.js.map +1 -1
  309. package/lib/module/features/gate.js +144 -0
  310. package/lib/module/features/gate.js.map +1 -0
  311. package/lib/module/features/index.js +2 -0
  312. package/lib/module/features/index.js.map +1 -1
  313. package/lib/module/features/metadata.js.map +1 -1
  314. package/lib/module/features/nowPlaying.js +33 -0
  315. package/lib/module/features/nowPlaying.js.map +1 -1
  316. package/lib/module/features/output.js +32 -19
  317. package/lib/module/features/output.js.map +1 -1
  318. package/lib/module/features/playback/controls.js +8 -0
  319. package/lib/module/features/playback/controls.js.map +1 -1
  320. package/lib/module/features/playback/index.js +1 -0
  321. package/lib/module/features/playback/index.js.map +1 -1
  322. package/lib/module/features/playback/progress.js +28 -12
  323. package/lib/module/features/playback/progress.js.map +1 -1
  324. package/lib/module/features/playback/trackPlaybackTime.js +88 -0
  325. package/lib/module/features/playback/trackPlaybackTime.js.map +1 -0
  326. package/lib/module/features/playback/volume.js +1 -1
  327. package/lib/module/features/player/options.js +48 -13
  328. package/lib/module/features/player/options.js.map +1 -1
  329. package/lib/module/features/player/setup.js +249 -3
  330. package/lib/module/features/player/setup.js.map +1 -1
  331. package/lib/module/features/queue/queue.js +10 -3
  332. package/lib/module/features/queue/queue.js.map +1 -1
  333. package/lib/module/features/remoteControls.js +0 -11
  334. package/lib/module/features/remoteControls.js.map +1 -1
  335. package/lib/module/features/sleepTimer.js +9 -4
  336. package/lib/module/features/sleepTimer.js.map +1 -1
  337. package/lib/module/native.js +5 -0
  338. package/lib/module/native.js.map +1 -1
  339. package/lib/module/native.web.js +4 -1
  340. package/lib/module/native.web.js.map +1 -1
  341. package/lib/module/utils/LazyNativeEmitter.js +0 -3
  342. package/lib/module/utils/LazyNativeEmitter.js.map +1 -1
  343. package/lib/module/utils/NativeUpdatedValue.js +0 -3
  344. package/lib/module/utils/NativeUpdatedValue.js.map +1 -1
  345. package/lib/module/utils/artwork.js +26 -0
  346. package/lib/module/utils/artwork.js.map +1 -0
  347. package/lib/module/web/NativeAudioBrowser.js +302 -125
  348. package/lib/module/web/NativeAudioBrowser.js.map +1 -1
  349. package/lib/module/web/TrackPlayer/PlaybackStateMachine.js +67 -0
  350. package/lib/module/web/TrackPlayer/PlaybackStateMachine.js.map +1 -0
  351. package/lib/module/web/TrackPlayer/PlaybackTimer.js +29 -0
  352. package/lib/module/web/TrackPlayer/PlaybackTimer.js.map +1 -0
  353. package/lib/module/web/TrackPlayer/Player.js +90 -26
  354. package/lib/module/web/TrackPlayer/Player.js.map +1 -1
  355. package/lib/module/web/TrackPlayer/PlayingStateFactory.js +17 -0
  356. package/lib/module/web/TrackPlayer/PlayingStateFactory.js.map +1 -0
  357. package/lib/module/web/TrackPlayer/QueueManager.js +269 -0
  358. package/lib/module/web/TrackPlayer/QueueManager.js.map +1 -0
  359. package/lib/module/web/TrackPlayer/QueuePlayer.js +154 -0
  360. package/lib/module/web/TrackPlayer/QueuePlayer.js.map +1 -0
  361. package/lib/module/web/TrackPlayer/RepeatMode.js +1 -1
  362. package/lib/module/web/TrackPlayer/RepeatMode.js.map +1 -1
  363. package/lib/module/web/TrackPlayer/SleepTimer.js +34 -3
  364. package/lib/module/web/TrackPlayer/SleepTimer.js.map +1 -1
  365. package/lib/module/web/TrackPlayer/VolumeFader.js +70 -0
  366. package/lib/module/web/TrackPlayer/VolumeFader.js.map +1 -0
  367. package/lib/module/web/TrackPlayer/index.js +2 -1
  368. package/lib/module/web/TrackPlayer/index.js.map +1 -1
  369. package/lib/module/web/browser/BrowserManager.js +176 -50
  370. package/lib/module/web/browser/BrowserManager.js.map +1 -1
  371. package/lib/module/web/browser/NavigationErrorManager.js +3 -1
  372. package/lib/module/web/browser/NavigationErrorManager.js.map +1 -1
  373. package/lib/module/web/browser/SearchManager.js +11 -9
  374. package/lib/module/web/browser/SearchManager.js.map +1 -1
  375. package/lib/module/web/browser/assertBrowsePageShape.js +18 -0
  376. package/lib/module/web/browser/assertBrowsePageShape.js.map +1 -0
  377. package/lib/module/web/browser/classifyTrackNavigation.js +38 -0
  378. package/lib/module/web/browser/classifyTrackNavigation.js.map +1 -0
  379. package/lib/module/web/browser/parseSearchResponse.js +16 -0
  380. package/lib/module/web/browser/parseSearchResponse.js.map +1 -0
  381. package/lib/module/web/http/HttpClient.js +4 -23
  382. package/lib/module/web/http/HttpClient.js.map +1 -1
  383. package/lib/module/web/http/RequestConfigBuilder.js +107 -58
  384. package/lib/module/web/http/RequestConfigBuilder.js.map +1 -1
  385. package/lib/module/web/playbackErrorKind.js +52 -0
  386. package/lib/module/web/playbackErrorKind.js.map +1 -0
  387. package/lib/module/web/player/MediaSessionManager.js +116 -0
  388. package/lib/module/web/player/MediaSessionManager.js.map +1 -0
  389. package/lib/module/web/player/NowPlayingManager.js +7 -5
  390. package/lib/module/web/player/NowPlayingManager.js.map +1 -1
  391. package/lib/module/web/player/OptionsManager.js +9 -17
  392. package/lib/module/web/player/OptionsManager.js.map +1 -1
  393. package/lib/module/web/player/RemoteCommandController.js +92 -0
  394. package/lib/module/web/player/RemoteCommandController.js.map +1 -0
  395. package/lib/typescript/src/features/browser-config.d.ts +12 -0
  396. package/lib/typescript/src/features/browser-config.d.ts.map +1 -0
  397. package/lib/typescript/src/features/browser.d.ts +40 -1
  398. package/lib/typescript/src/features/browser.d.ts.map +1 -1
  399. package/lib/typescript/src/features/carConnection.d.ts +20 -0
  400. package/lib/typescript/src/features/carConnection.d.ts.map +1 -0
  401. package/lib/typescript/src/features/errors.d.ts +58 -3
  402. package/lib/typescript/src/features/errors.d.ts.map +1 -1
  403. package/lib/typescript/src/features/gate.d.ts +77 -0
  404. package/lib/typescript/src/features/gate.d.ts.map +1 -0
  405. package/lib/typescript/src/features/index.d.ts +2 -0
  406. package/lib/typescript/src/features/index.d.ts.map +1 -1
  407. package/lib/typescript/src/features/metadata.d.ts +6 -4
  408. package/lib/typescript/src/features/metadata.d.ts.map +1 -1
  409. package/lib/typescript/src/features/nowPlaying.d.ts +27 -0
  410. package/lib/typescript/src/features/nowPlaying.d.ts.map +1 -1
  411. package/lib/typescript/src/features/output.d.ts +28 -18
  412. package/lib/typescript/src/features/output.d.ts.map +1 -1
  413. package/lib/typescript/src/features/playback/controls.d.ts +5 -0
  414. package/lib/typescript/src/features/playback/controls.d.ts.map +1 -1
  415. package/lib/typescript/src/features/playback/index.d.ts +1 -0
  416. package/lib/typescript/src/features/playback/index.d.ts.map +1 -1
  417. package/lib/typescript/src/features/playback/progress.d.ts +3 -0
  418. package/lib/typescript/src/features/playback/progress.d.ts.map +1 -1
  419. package/lib/typescript/src/features/playback/trackPlaybackTime.d.ts +34 -0
  420. package/lib/typescript/src/features/playback/trackPlaybackTime.d.ts.map +1 -0
  421. package/lib/typescript/src/features/playback/volume.d.ts +1 -1
  422. package/lib/typescript/src/features/player/options.d.ts +92 -93
  423. package/lib/typescript/src/features/player/options.d.ts.map +1 -1
  424. package/lib/typescript/src/features/player/setup.d.ts +206 -167
  425. package/lib/typescript/src/features/player/setup.d.ts.map +1 -1
  426. package/lib/typescript/src/features/queue/queue.d.ts +9 -2
  427. package/lib/typescript/src/features/queue/queue.d.ts.map +1 -1
  428. package/lib/typescript/src/features/remoteControls.d.ts +0 -13
  429. package/lib/typescript/src/features/remoteControls.d.ts.map +1 -1
  430. package/lib/typescript/src/features/sleepTimer.d.ts +18 -3
  431. package/lib/typescript/src/features/sleepTimer.d.ts.map +1 -1
  432. package/lib/typescript/src/index.d.ts.map +1 -1
  433. package/lib/typescript/src/native.d.ts +1 -2
  434. package/lib/typescript/src/native.d.ts.map +1 -1
  435. package/lib/typescript/src/specs/audio-browser.nitro.d.ts +17 -225
  436. package/lib/typescript/src/specs/audio-browser.nitro.d.ts.map +1 -1
  437. package/lib/typescript/src/types/browser-native.d.ts +9 -3
  438. package/lib/typescript/src/types/browser-native.d.ts.map +1 -1
  439. package/lib/typescript/src/types/browser-nodes.d.ts +145 -13
  440. package/lib/typescript/src/types/browser-nodes.d.ts.map +1 -1
  441. package/lib/typescript/src/types/browser.d.ts +349 -85
  442. package/lib/typescript/src/types/browser.d.ts.map +1 -1
  443. package/lib/typescript/src/utils/LazyNativeEmitter.d.ts +0 -2
  444. package/lib/typescript/src/utils/LazyNativeEmitter.d.ts.map +1 -1
  445. package/lib/typescript/src/utils/NativeUpdatedValue.d.ts +0 -2
  446. package/lib/typescript/src/utils/NativeUpdatedValue.d.ts.map +1 -1
  447. package/lib/typescript/src/utils/artwork.d.ts +19 -0
  448. package/lib/typescript/src/utils/artwork.d.ts.map +1 -0
  449. package/lib/typescript/src/utils/resolveAssetSource.d.ts.map +1 -1
  450. package/nitrogen/generated/android/AudioBrowser+autolinking.cmake +3 -1
  451. package/nitrogen/generated/android/AudioBrowserOnLoad.cpp +24 -10
  452. package/nitrogen/generated/android/c++/JAndroidAudioContentType.hpp +6 -6
  453. package/nitrogen/generated/android/c++/JAndroidOptions.hpp +1 -11
  454. package/nitrogen/generated/android/c++/JArtworkRequestConfig.hpp +33 -1
  455. package/nitrogen/generated/android/c++/JArtworkVariants.hpp +61 -0
  456. package/nitrogen/generated/android/c++/JBrowseResult.hpp +5 -0
  457. package/nitrogen/generated/android/c++/JCarPlayNowPlayingButton.hpp +3 -3
  458. package/nitrogen/generated/android/c++/JFavoriteChangedEvent.hpp +6 -0
  459. package/nitrogen/generated/android/c++/JFavoriteConfig.hpp +58 -0
  460. package/nitrogen/generated/android/c++/JFavoritesMatchMode.hpp +58 -0
  461. package/nitrogen/generated/android/c++/JFormatNowPlayingParams.hpp +100 -0
  462. package/nitrogen/generated/android/c++/JFormattedNavigationError.hpp +3 -2
  463. package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_RequestConfig___MediaTransformParams.hpp +112 -0
  464. package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_RequestConfig___RequestConfig_std__optional_std__unordered_map_std__string__std__string__.hpp +121 -0
  465. package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_RequestConfig___Track.hpp +123 -0
  466. package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__optional_NowPlayingUpdate____FormatNowPlayingParams.hpp +133 -0
  467. package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__optional_std__string____Track.hpp +121 -0
  468. package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__shared_ptr_Promise_GateDecision_____NativeGateRequest.hpp +139 -0
  469. package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__shared_ptr_Promise_RequestConfig_____Track.hpp +6 -0
  470. package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__shared_ptr_Promise_TransformableRequestConfig____.hpp +134 -0
  471. package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__shared_ptr_Promise_std__vector_Track______SearchParams.hpp +8 -0
  472. package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__shared_ptr_Promise_void_____TrackLoadEvent.hpp +6 -0
  473. package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__variant_ResolvedTrack__BrowseError__std__shared_ptr_Promise_std__variant_ResolvedTrack__BrowseError_______BrowserSourceCallbackParam.hpp +131 -0
  474. package/nitrogen/generated/android/c++/JFunc_void_FavoriteChangedEvent.hpp +6 -0
  475. package/nitrogen/generated/android/c++/JFunc_void_GateEvent.hpp +79 -0
  476. package/nitrogen/generated/android/c++/JFunc_void_NowPlayingMetadata.hpp +0 -10
  477. package/nitrogen/generated/android/c++/JFunc_void_Options.hpp +9 -4
  478. package/nitrogen/generated/android/c++/JFunc_void_Output.hpp +80 -0
  479. package/nitrogen/generated/android/c++/JFunc_void_Playback.hpp +2 -0
  480. package/nitrogen/generated/android/c++/JFunc_void_PlaybackActiveTrackChangedEvent.hpp +6 -0
  481. package/nitrogen/generated/android/c++/JFunc_void_PlaybackErrorEvent.hpp +2 -0
  482. package/nitrogen/generated/android/c++/JFunc_void_bool.hpp +10 -10
  483. package/nitrogen/generated/android/c++/JFunc_void_std__optional_ResolvedTrack_.hpp +6 -0
  484. package/nitrogen/generated/android/c++/JFunc_void_std__vector_Track_.hpp +6 -0
  485. package/nitrogen/generated/android/c++/JGate.hpp +62 -0
  486. package/nitrogen/generated/android/c++/JGateDecision.hpp +64 -0
  487. package/nitrogen/generated/android/c++/{JThumbsRating.hpp → JGateEvent.hpp} +16 -15
  488. package/nitrogen/generated/android/c++/JGateReason.hpp +58 -0
  489. package/nitrogen/generated/android/c++/JHybridAudioBrowserSpec.cpp +236 -212
  490. package/nitrogen/generated/android/c++/JHybridAudioBrowserSpec.hpp +25 -22
  491. package/nitrogen/generated/android/c++/JIOSOptions.hpp +95 -0
  492. package/nitrogen/generated/android/c++/JImageRowItem.hpp +33 -3
  493. package/nitrogen/generated/android/c++/JMediaReference.hpp +58 -0
  494. package/nitrogen/generated/android/c++/JMediaRequestConfig.hpp +33 -1
  495. package/nitrogen/generated/android/c++/{JPartialAndroidSetupPlayerOptions.hpp → JNativeAndroidSetupOptions.hpp} +10 -10
  496. package/nitrogen/generated/android/c++/JNativeBrowserConfiguration.hpp +61 -28
  497. package/nitrogen/generated/android/c++/JNativeGateRequest.hpp +74 -0
  498. package/nitrogen/generated/android/c++/{JPartialIOSSetupPlayerOptions.hpp → JNativeIOSSetupOptions.hpp} +10 -10
  499. package/nitrogen/generated/android/c++/JNativeRouteEntry.hpp +20 -9
  500. package/nitrogen/generated/android/c++/JNativeSetupPlayerOptions.hpp +182 -0
  501. package/nitrogen/generated/android/c++/JNativeUpdateOptions.hpp +16 -19
  502. package/nitrogen/generated/android/c++/JNavigationErrorType.hpp +6 -0
  503. package/nitrogen/generated/android/c++/JNitroAndroidUpdateOptions.hpp +1 -11
  504. package/nitrogen/generated/android/c++/JNitroIOSUpdateOptions.hpp +96 -0
  505. package/nitrogen/generated/android/c++/JNotificationButton.hpp +3 -3
  506. package/nitrogen/generated/android/c++/JNowPlayingMetadata.hpp +3 -17
  507. package/nitrogen/generated/android/c++/JNowPlayingUpdate.hpp +7 -3
  508. package/nitrogen/generated/android/c++/JOptions.hpp +14 -9
  509. package/nitrogen/generated/android/c++/{JIosOutput.hpp → JOutput.hpp} +15 -15
  510. package/nitrogen/generated/android/c++/JOutputType.hpp +82 -0
  511. package/nitrogen/generated/android/c++/JPlayback.hpp +2 -0
  512. package/nitrogen/generated/android/c++/JPlaybackActiveTrackChangedEvent.hpp +6 -0
  513. package/nitrogen/generated/android/c++/JPlaybackError.hpp +18 -3
  514. package/nitrogen/generated/android/c++/JPlaybackErrorEvent.hpp +2 -0
  515. package/nitrogen/generated/android/c++/JPlaybackErrorKind.hpp +76 -0
  516. package/nitrogen/generated/android/c++/JPlaybackState.hpp +3 -3
  517. package/nitrogen/generated/android/c++/JPlayerCapabilities.hpp +11 -5
  518. package/nitrogen/generated/android/c++/JResolvedTrack.hpp +23 -5
  519. package/nitrogen/generated/android/c++/JRetryConfig.hpp +11 -7
  520. package/nitrogen/generated/android/c++/JSearchMode.hpp +27 -9
  521. package/nitrogen/generated/android/c++/JSearchParams.hpp +9 -3
  522. package/nitrogen/generated/android/c++/JStallReason.hpp +58 -0
  523. package/nitrogen/generated/android/c++/JTrack.hpp +23 -5
  524. package/nitrogen/generated/android/c++/JTrackLoadEvent.hpp +6 -0
  525. package/nitrogen/generated/android/c++/JTrackRequest.hpp +93 -0
  526. package/nitrogen/generated/android/c++/JTransformableRequestConfig.hpp +14 -1
  527. package/nitrogen/generated/android/c++/JVariant_Boolean_FavoriteConfig.cpp +26 -0
  528. package/nitrogen/generated/android/c++/JVariant_Boolean_FavoriteConfig.hpp +71 -0
  529. package/nitrogen/generated/android/c++/JVariant_ResolvedTrack_BrowseError_Promise_BrowseResult_.cpp +41 -0
  530. package/nitrogen/generated/android/c++/JVariant_ResolvedTrack_BrowseError_Promise_BrowseResult_.hpp +121 -0
  531. package/nitrogen/generated/android/c++/JVariant_String_ArtworkVariants.cpp +26 -0
  532. package/nitrogen/generated/android/c++/JVariant_String_ArtworkVariants.hpp +70 -0
  533. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/AndroidAudioContentType.kt +4 -4
  534. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/AndroidOptions.kt +2 -8
  535. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/ArtworkRequestConfig.kt +10 -4
  536. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/ArtworkVariants.kt +41 -0
  537. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/CarPlayNowPlayingButton.kt +3 -3
  538. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/{ThumbsRating.kt → FavoriteConfig.kt} +6 -6
  539. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/{RatingType.kt → FavoritesMatchMode.kt} +5 -10
  540. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/FormatNowPlayingParams.kt +50 -0
  541. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/FormattedNavigationError.kt +2 -2
  542. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_std__shared_ptr_Promise_RequestConfig___MediaTransformParams.kt +80 -0
  543. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_std__shared_ptr_Promise_RequestConfig___RequestConfig_std__optional_std__unordered_map_std__string__std__string__.kt +80 -0
  544. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_std__shared_ptr_Promise_RequestConfig___Track.kt +80 -0
  545. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_std__shared_ptr_Promise_std__optional_NowPlayingUpdate____FormatNowPlayingParams.kt +80 -0
  546. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_std__shared_ptr_Promise_std__optional_std__string____Track.kt +80 -0
  547. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_std__shared_ptr_Promise_std__shared_ptr_Promise_GateDecision_____NativeGateRequest.kt +80 -0
  548. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_std__shared_ptr_Promise_std__shared_ptr_Promise_TransformableRequestConfig____.kt +80 -0
  549. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/{Func_std__shared_ptr_Promise_std__shared_ptr_Promise_std__variant_ResolvedTrack__BrowseError______BrowserSourceCallbackParam.kt → Func_std__shared_ptr_Promise_std__variant_ResolvedTrack__BrowseError__std__shared_ptr_Promise_std__variant_ResolvedTrack__BrowseError_______BrowserSourceCallbackParam.kt} +12 -12
  550. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/{Func_void_RemoteSetRatingEvent.kt → Func_void_GateEvent.kt} +9 -9
  551. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/{Func_void_IosOutput.kt → Func_void_Output.kt} +9 -9
  552. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_bool.kt +9 -9
  553. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/{HeartRating.kt → Gate.kt} +9 -6
  554. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/{PercentageRating.kt → GateDecision.kt} +9 -6
  555. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/{StarRating.kt → GateEvent.kt} +6 -6
  556. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/GateReason.kt +23 -0
  557. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/HybridAudioBrowserSpec.kt +103 -109
  558. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/IOSOptions.kt +44 -0
  559. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/ImageRowItem.kt +24 -3
  560. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/MediaReference.kt +23 -0
  561. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/MediaRequestConfig.kt +10 -4
  562. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/{PartialAndroidSetupPlayerOptions.kt → NativeAndroidSetupOptions.kt} +5 -5
  563. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NativeBrowserConfiguration.kt +18 -6
  564. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/{RemoteSetRatingEvent.kt → NativeGateRequest.kt} +12 -6
  565. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/{PartialIOSSetupPlayerOptions.kt → NativeIOSSetupOptions.kt} +5 -5
  566. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NativeRouteEntry.kt +4 -4
  567. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NativeSetupPlayerOptions.kt +66 -0
  568. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NativeUpdateOptions.kt +6 -6
  569. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NavigationErrorType.kt +3 -1
  570. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NitroAndroidUpdateOptions.kt +2 -8
  571. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NitroIOSUpdateOptions.kt +44 -0
  572. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NotificationButton.kt +5 -5
  573. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NowPlayingMetadata.kt +3 -6
  574. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NowPlayingUpdate.kt +6 -3
  575. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Options.kt +3 -3
  576. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/{IosOutput.kt → Output.kt} +6 -6
  577. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/OutputType.kt +31 -0
  578. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/PlaybackError.kt +12 -3
  579. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/PlaybackErrorKind.kt +29 -0
  580. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/PlaybackState.kt +6 -6
  581. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/PlayerCapabilities.kt +2 -2
  582. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/ResolvedTrack.kt +12 -3
  583. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/RetryConfig.kt +7 -4
  584. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/SearchMode.kt +12 -6
  585. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/SearchParams.kt +6 -3
  586. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/StallReason.kt +23 -0
  587. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Track.kt +12 -3
  588. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/TrackRequest.kt +44 -0
  589. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/TransformableRequestConfig.kt +7 -4
  590. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Variant_Boolean_FavoriteConfig.kt +53 -0
  591. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Variant_ResolvedTrack_BrowseError_Promise_BrowseResult_.kt +65 -0
  592. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Variant_String_ArtworkVariants.kt +53 -0
  593. package/nitrogen/generated/ios/AudioBrowser-Swift-Cxx-Bridge.cpp +139 -28
  594. package/nitrogen/generated/ios/AudioBrowser-Swift-Cxx-Bridge.hpp +1098 -447
  595. package/nitrogen/generated/ios/AudioBrowser-Swift-Cxx-Umbrella.hpp +60 -39
  596. package/nitrogen/generated/ios/c++/HybridAudioBrowserSpecSwift.hpp +170 -112
  597. package/nitrogen/generated/ios/swift/AndroidAudioContentType.swift +8 -8
  598. package/nitrogen/generated/ios/swift/AndroidOptions.swift +2 -12
  599. package/nitrogen/generated/ios/swift/ArtworkRequestConfig.swift +95 -1
  600. package/nitrogen/generated/ios/swift/ArtworkVariants.swift +34 -0
  601. package/nitrogen/generated/ios/swift/CarPlayNowPlayingButton.swift +4 -4
  602. package/nitrogen/generated/ios/swift/FavoriteConfig.swift +29 -0
  603. package/nitrogen/generated/ios/swift/FavoritesMatchMode.swift +40 -0
  604. package/nitrogen/generated/ios/swift/FormatNowPlayingParams.swift +67 -0
  605. package/nitrogen/generated/ios/swift/FormattedNavigationError.swift +17 -4
  606. package/nitrogen/generated/ios/swift/Func_std__shared_ptr_Promise_RequestConfig___MediaTransformParams.swift +54 -0
  607. package/nitrogen/generated/ios/swift/Func_std__shared_ptr_Promise_RequestConfig___RequestConfig_std__optional_std__unordered_map_std__string__std__string__.swift +69 -0
  608. package/nitrogen/generated/ios/swift/Func_std__shared_ptr_Promise_RequestConfig___Track.swift +54 -0
  609. package/nitrogen/generated/ios/swift/Func_std__shared_ptr_Promise_std__optional_NowPlayingUpdate____FormatNowPlayingParams.swift +60 -0
  610. package/nitrogen/generated/ios/swift/Func_std__shared_ptr_Promise_std__optional_std__string____Track.swift +60 -0
  611. package/nitrogen/generated/ios/swift/Func_std__shared_ptr_Promise_std__shared_ptr_Promise_GateDecision_____NativeGateRequest.swift +61 -0
  612. package/nitrogen/generated/ios/swift/Func_std__shared_ptr_Promise_std__shared_ptr_Promise_TransformableRequestConfig____.swift +61 -0
  613. package/nitrogen/generated/ios/swift/Func_std__shared_ptr_Promise_std__variant_ResolvedTrack__BrowseError__std__shared_ptr_Promise_std__variant_ResolvedTrack__BrowseError_______BrowserSourceCallbackParam.swift +77 -0
  614. package/nitrogen/generated/ios/swift/Func_void_GateDecision.swift +46 -0
  615. package/nitrogen/generated/ios/swift/{Func_void_RemoteSetRatingEvent.swift → Func_void_GateEvent.swift} +10 -10
  616. package/nitrogen/generated/ios/swift/{Func_void_IosOutput.swift → Func_void_Output.swift} +10 -10
  617. package/nitrogen/generated/ios/swift/Func_void_TransformableRequestConfig.swift +46 -0
  618. package/nitrogen/generated/ios/swift/Func_void_bool.swift +5 -5
  619. package/nitrogen/generated/ios/swift/Func_void_std__optional_NowPlayingUpdate_.swift +46 -0
  620. package/nitrogen/generated/ios/swift/Func_void_std__optional_std__string_.swift +53 -0
  621. package/nitrogen/generated/ios/swift/{Func_void_std__shared_ptr_Promise_std__variant_ResolvedTrack__BrowseError___.swift → Func_void_std__shared_ptr_Promise_GateDecision__.swift} +17 -17
  622. package/nitrogen/generated/ios/swift/Func_void_std__shared_ptr_Promise_TransformableRequestConfig__.swift +66 -0
  623. package/nitrogen/generated/ios/swift/Func_void_std__variant_ResolvedTrack__BrowseError__std__shared_ptr_Promise_std__variant_ResolvedTrack__BrowseError____.swift +81 -0
  624. package/nitrogen/generated/ios/swift/Gate.swift +47 -0
  625. package/nitrogen/generated/ios/swift/GateDecision.swift +40 -0
  626. package/nitrogen/generated/ios/swift/GateEvent.swift +29 -0
  627. package/nitrogen/generated/ios/swift/GateReason.swift +40 -0
  628. package/nitrogen/generated/ios/swift/HybridAudioBrowserSpec.swift +20 -14
  629. package/nitrogen/generated/ios/swift/HybridAudioBrowserSpec_cxx.swift +230 -197
  630. package/nitrogen/generated/ios/swift/IOSOptions.swift +51 -0
  631. package/nitrogen/generated/ios/swift/ImageRowItem.swift +121 -2
  632. package/nitrogen/generated/ios/swift/MediaReference.swift +40 -0
  633. package/nitrogen/generated/ios/swift/MediaRequestConfig.swift +107 -1
  634. package/nitrogen/generated/ios/swift/{PartialAndroidSetupPlayerOptions.swift → NativeAndroidSetupOptions.swift} +5 -5
  635. package/nitrogen/generated/ios/swift/NativeBrowserConfiguration.swift +161 -22
  636. package/nitrogen/generated/ios/swift/NativeGateRequest.swift +58 -0
  637. package/nitrogen/generated/ios/swift/{PartialIOSSetupPlayerOptions.swift → NativeIOSSetupOptions.swift} +5 -5
  638. package/nitrogen/generated/ios/swift/NativeRouteEntry.swift +19 -19
  639. package/nitrogen/generated/ios/swift/NativeSetupPlayerOptions.swift +206 -0
  640. package/nitrogen/generated/ios/swift/NativeUpdateOptions.swift +12 -25
  641. package/nitrogen/generated/ios/swift/NavigationErrorType.swift +8 -0
  642. package/nitrogen/generated/ios/swift/NitroAndroidUpdateOptions.swift +1 -30
  643. package/nitrogen/generated/ios/swift/NitroIOSUpdateOptions.swift +90 -0
  644. package/nitrogen/generated/ios/swift/NotificationButton.swift +4 -4
  645. package/nitrogen/generated/ios/swift/NowPlayingMetadata.swift +1 -48
  646. package/nitrogen/generated/ios/swift/NowPlayingUpdate.swift +19 -1
  647. package/nitrogen/generated/ios/swift/Options.swift +10 -4
  648. package/nitrogen/generated/ios/swift/{IosOutput.swift → Output.swift} +7 -7
  649. package/nitrogen/generated/ios/swift/OutputType.swift +72 -0
  650. package/nitrogen/generated/ios/swift/PlaybackError.swift +43 -2
  651. package/nitrogen/generated/ios/swift/PlaybackErrorKind.swift +64 -0
  652. package/nitrogen/generated/ios/swift/PlaybackState.swift +4 -4
  653. package/nitrogen/generated/ios/swift/PlayerCapabilities.swift +27 -8
  654. package/nitrogen/generated/ios/swift/ResolvedTrack.swift +74 -8
  655. package/nitrogen/generated/ios/swift/RetryConfig.swift +35 -4
  656. package/nitrogen/generated/ios/swift/SearchMode.swift +36 -12
  657. package/nitrogen/generated/ios/swift/SearchParams.swift +7 -2
  658. package/nitrogen/generated/ios/swift/StallReason.swift +40 -0
  659. package/nitrogen/generated/ios/swift/Track.swift +74 -8
  660. package/nitrogen/generated/ios/swift/TrackRequest.swift +106 -0
  661. package/nitrogen/generated/ios/swift/TransformableRequestConfig.swift +60 -1
  662. package/nitrogen/generated/ios/swift/Variant_Bool_FavoriteConfig.swift +18 -0
  663. package/nitrogen/generated/ios/swift/Variant_ResolvedTrack_BrowseError_Promise_BrowseResult_.swift +19 -0
  664. package/nitrogen/generated/ios/swift/Variant_String_ArtworkVariants.swift +18 -0
  665. package/nitrogen/generated/shared/c++/AndroidAudioContentType.hpp +10 -10
  666. package/nitrogen/generated/shared/c++/AndroidOptions.hpp +1 -12
  667. package/nitrogen/generated/shared/c++/ArtworkRequestConfig.hpp +10 -2
  668. package/nitrogen/generated/shared/c++/ArtworkVariants.hpp +87 -0
  669. package/nitrogen/generated/shared/c++/CarPlayNowPlayingButton.hpp +6 -6
  670. package/nitrogen/generated/shared/c++/EqualizerSettings.hpp +0 -2
  671. package/nitrogen/generated/shared/c++/{StarRating.hpp → FavoriteConfig.hpp} +18 -17
  672. package/nitrogen/generated/shared/c++/FavoritesMatchMode.hpp +76 -0
  673. package/nitrogen/generated/shared/c++/FormatNowPlayingParams.hpp +110 -0
  674. package/nitrogen/generated/shared/c++/FormattedNavigationError.hpp +6 -5
  675. package/nitrogen/generated/shared/c++/{HeartRating.hpp → Gate.hpp} +21 -16
  676. package/nitrogen/generated/shared/c++/{ThumbsRating.hpp → GateDecision.hpp} +23 -17
  677. package/nitrogen/generated/shared/c++/{PercentageRating.hpp → GateEvent.hpp} +18 -17
  678. package/nitrogen/generated/shared/c++/GateReason.hpp +76 -0
  679. package/nitrogen/generated/shared/c++/HybridAudioBrowserSpec.cpp +21 -18
  680. package/nitrogen/generated/shared/c++/HybridAudioBrowserSpec.hpp +44 -35
  681. package/nitrogen/generated/shared/c++/IOSOptions.hpp +91 -0
  682. package/nitrogen/generated/shared/c++/ImageRowItem.hpp +33 -2
  683. package/nitrogen/generated/shared/c++/MediaReference.hpp +76 -0
  684. package/nitrogen/generated/shared/c++/MediaRequestConfig.hpp +10 -2
  685. package/nitrogen/generated/shared/c++/{PartialAndroidSetupPlayerOptions.hpp → NativeAndroidSetupOptions.hpp} +11 -11
  686. package/nitrogen/generated/shared/c++/NativeBrowserConfiguration.hpp +31 -15
  687. package/nitrogen/generated/shared/c++/NativeGateRequest.hpp +97 -0
  688. package/nitrogen/generated/shared/c++/{PartialIOSSetupPlayerOptions.hpp → NativeIOSSetupOptions.hpp} +11 -11
  689. package/nitrogen/generated/shared/c++/NativeRouteEntry.hpp +5 -5
  690. package/nitrogen/generated/shared/c++/NativeSetupPlayerOptions.hpp +138 -0
  691. package/nitrogen/generated/shared/c++/NativeUpdateOptions.hpp +9 -7
  692. package/nitrogen/generated/shared/c++/NavigationErrorType.hpp +8 -0
  693. package/nitrogen/generated/shared/c++/NitroAndroidUpdateOptions.hpp +1 -12
  694. package/nitrogen/generated/shared/c++/NitroIOSUpdateOptions.hpp +92 -0
  695. package/nitrogen/generated/shared/c++/NotificationButton.hpp +8 -8
  696. package/nitrogen/generated/shared/c++/NowPlayingMetadata.hpp +3 -19
  697. package/nitrogen/generated/shared/c++/NowPlayingUpdate.hpp +6 -2
  698. package/nitrogen/generated/shared/c++/Options.hpp +8 -8
  699. package/nitrogen/generated/shared/c++/{IosOutput.hpp → Output.hpp} +18 -18
  700. package/nitrogen/generated/shared/c++/OutputType.hpp +108 -0
  701. package/nitrogen/generated/shared/c++/PlaybackError.hpp +18 -3
  702. package/nitrogen/generated/shared/c++/PlaybackErrorKind.hpp +100 -0
  703. package/nitrogen/generated/shared/c++/PlaybackState.hpp +9 -9
  704. package/nitrogen/generated/shared/c++/PlayerCapabilities.hpp +9 -6
  705. package/nitrogen/generated/shared/c++/ResolvedTrack.hpp +24 -5
  706. package/nitrogen/generated/shared/c++/RetryConfig.hpp +10 -6
  707. package/nitrogen/generated/shared/c++/SearchMode.hpp +39 -15
  708. package/nitrogen/generated/shared/c++/SearchParams.hpp +9 -2
  709. package/nitrogen/generated/shared/c++/StallReason.hpp +76 -0
  710. package/nitrogen/generated/shared/c++/Track.hpp +24 -5
  711. package/nitrogen/generated/shared/c++/TrackRequest.hpp +93 -0
  712. package/nitrogen/generated/shared/c++/TransformableRequestConfig.hpp +6 -2
  713. package/package.json +16 -16
  714. package/src/codegen-no-config-variant.test.ts +70 -0
  715. package/src/features/browser-config.test.ts +110 -0
  716. package/src/features/browser-config.ts +293 -0
  717. package/src/features/browser.test.ts +19 -0
  718. package/src/features/browser.ts +58 -201
  719. package/src/features/carConnection.ts +36 -0
  720. package/src/features/errors.ts +68 -2
  721. package/src/features/gate.test.ts +72 -0
  722. package/src/features/gate.ts +155 -0
  723. package/src/features/index.ts +2 -0
  724. package/src/features/metadata.ts +6 -12
  725. package/src/features/nowPlaying.ts +36 -0
  726. package/src/features/output.ts +35 -22
  727. package/src/features/playback/controls.ts +8 -0
  728. package/src/features/playback/index.ts +1 -0
  729. package/src/features/playback/progress.ts +31 -12
  730. package/src/features/playback/trackPlaybackTime.test.ts +66 -0
  731. package/src/features/playback/trackPlaybackTime.ts +106 -0
  732. package/src/features/playback/volume.ts +1 -1
  733. package/src/features/player/options.test.ts +38 -0
  734. package/src/features/player/options.ts +140 -75
  735. package/src/features/player/setup.test.ts +117 -0
  736. package/src/features/player/setup.ts +390 -175
  737. package/src/features/queue/queue.test.ts +36 -0
  738. package/src/features/queue/queue.ts +15 -4
  739. package/src/features/remoteControls.ts +0 -23
  740. package/src/features/sleepTimer.ts +23 -4
  741. package/src/native.ts +5 -0
  742. package/src/native.web.ts +4 -1
  743. package/src/specs/audio-browser.nitro.ts +131 -41
  744. package/src/types/browser-native.ts +19 -6
  745. package/src/types/browser-nodes.ts +160 -13
  746. package/src/types/browser.ts +377 -89
  747. package/src/utils/LazyNativeEmitter.ts +0 -2
  748. package/src/utils/NativeUpdatedValue.ts +0 -2
  749. package/src/utils/artwork.ts +30 -0
  750. package/src/web/NativeAudioBrowser.playWhenReady.test.ts +301 -0
  751. package/src/web/NativeAudioBrowser.ts +368 -157
  752. package/src/web/SimpleRouter.test.ts +9 -9
  753. package/src/web/TrackPlayer/PlaybackStateMachine.test.ts +139 -0
  754. package/src/web/TrackPlayer/PlaybackStateMachine.ts +82 -0
  755. package/src/web/TrackPlayer/PlaybackTimer.test.ts +67 -0
  756. package/src/web/TrackPlayer/PlaybackTimer.ts +33 -0
  757. package/src/web/TrackPlayer/Player.dispatch.test.ts +229 -0
  758. package/src/web/TrackPlayer/Player.load.test.ts +86 -0
  759. package/src/web/TrackPlayer/Player.ts +113 -39
  760. package/src/web/TrackPlayer/PlayingStateFactory.test.ts +51 -0
  761. package/src/web/TrackPlayer/PlayingStateFactory.ts +24 -0
  762. package/src/web/TrackPlayer/QueueManager.test.ts +289 -0
  763. package/src/web/TrackPlayer/QueueManager.ts +302 -0
  764. package/src/web/TrackPlayer/QueuePlayer.ts +188 -0
  765. package/src/web/TrackPlayer/RepeatMode.ts +1 -1
  766. package/src/web/TrackPlayer/SleepTimer.ts +38 -3
  767. package/src/web/TrackPlayer/VolumeFader.ts +74 -0
  768. package/src/web/TrackPlayer/index.ts +2 -1
  769. package/src/web/browser/BrowserManager.ts +231 -62
  770. package/src/web/browser/NavigationErrorManager.ts +3 -1
  771. package/src/web/browser/SearchManager.ts +11 -15
  772. package/src/web/browser/__tests__/layer-resolver.test.ts +69 -0
  773. package/src/web/browser/assertBrowsePageShape.test.ts +27 -0
  774. package/src/web/browser/assertBrowsePageShape.ts +27 -0
  775. package/src/web/browser/classifyTrackNavigation.test.ts +41 -0
  776. package/src/web/browser/classifyTrackNavigation.ts +35 -0
  777. package/src/web/browser/parseSearchResponse.test.ts +25 -0
  778. package/src/web/browser/parseSearchResponse.ts +15 -0
  779. package/src/web/http/HttpClient.ts +5 -35
  780. package/src/web/http/RequestConfigBuilder.test.ts +59 -0
  781. package/src/web/http/RequestConfigBuilder.ts +120 -63
  782. package/src/web/playbackErrorKind.test.ts +55 -0
  783. package/src/web/playbackErrorKind.ts +56 -0
  784. package/src/web/player/MediaSessionManager.test.ts +220 -0
  785. package/src/web/player/MediaSessionManager.ts +151 -0
  786. package/src/web/player/NowPlayingManager.test.ts +46 -0
  787. package/src/web/player/NowPlayingManager.ts +6 -5
  788. package/src/web/player/OptionsManager.ts +12 -18
  789. package/src/web/player/RemoteCommandController.test.ts +171 -0
  790. package/src/web/player/RemoteCommandController.ts +166 -0
  791. package/android/src/main/java/com/audiobrowser/player/PlaybackProgressUpdateManager.kt +0 -59
  792. package/android/src/main/java/com/audiobrowser/util/RatingFactory.kt +0 -72
  793. package/android/src/main/java/com/audiobrowser/util/ResolvedTrackFactory.kt +0 -36
  794. package/android/src/test/java/com/audiobrowser/player/PlaybackProgressUpdateManagerTest.kt +0 -146
  795. package/ios/CarPlay/Track+CarPlay.swift +0 -63
  796. package/ios/NowPlayingInfo/NowPlayingInfoCenter.swift +0 -9
  797. package/ios/Player/PlaybackProgressUpdateManager.swift +0 -68
  798. package/ios/Tests/PlaybackProgressUpdateManagerTests.swift +0 -166
  799. package/lib/commonjs/features/rating.js +0 -2
  800. package/lib/commonjs/features/rating.js.map +0 -1
  801. package/lib/commonjs/types/player.js +0 -2
  802. package/lib/commonjs/types/player.js.map +0 -1
  803. package/lib/commonjs/web/SimpleRouter.test.js +0 -174
  804. package/lib/commonjs/web/SimpleRouter.test.js.map +0 -1
  805. package/lib/commonjs/web/TrackPlayer/PlaylistPlayer.js +0 -293
  806. package/lib/commonjs/web/TrackPlayer/PlaylistPlayer.js.map +0 -1
  807. package/lib/module/features/rating.js +0 -2
  808. package/lib/module/features/rating.js.map +0 -1
  809. package/lib/module/types/player.js +0 -2
  810. package/lib/module/types/player.js.map +0 -1
  811. package/lib/module/web/SimpleRouter.test.js +0 -174
  812. package/lib/module/web/SimpleRouter.test.js.map +0 -1
  813. package/lib/module/web/TrackPlayer/PlaylistPlayer.js +0 -288
  814. package/lib/module/web/TrackPlayer/PlaylistPlayer.js.map +0 -1
  815. package/lib/typescript/src/features/rating.d.ts +0 -14
  816. package/lib/typescript/src/features/rating.d.ts.map +0 -1
  817. package/lib/typescript/src/native.web.d.ts +0 -3
  818. package/lib/typescript/src/native.web.d.ts.map +0 -1
  819. package/lib/typescript/src/types/player.d.ts +0 -64
  820. package/lib/typescript/src/types/player.d.ts.map +0 -1
  821. package/lib/typescript/src/web/NativeAudioBrowser.d.ts +0 -188
  822. package/lib/typescript/src/web/NativeAudioBrowser.d.ts.map +0 -1
  823. package/lib/typescript/src/web/SimpleRouter.d.ts +0 -40
  824. package/lib/typescript/src/web/SimpleRouter.d.ts.map +0 -1
  825. package/lib/typescript/src/web/SimpleRouter.test.d.ts +0 -2
  826. package/lib/typescript/src/web/SimpleRouter.test.d.ts.map +0 -1
  827. package/lib/typescript/src/web/TrackPlayer/Event.d.ts +0 -11
  828. package/lib/typescript/src/web/TrackPlayer/Event.d.ts.map +0 -1
  829. package/lib/typescript/src/web/TrackPlayer/Player.d.ts +0 -59
  830. package/lib/typescript/src/web/TrackPlayer/Player.d.ts.map +0 -1
  831. package/lib/typescript/src/web/TrackPlayer/PlaylistPlayer.d.ts +0 -39
  832. package/lib/typescript/src/web/TrackPlayer/PlaylistPlayer.d.ts.map +0 -1
  833. package/lib/typescript/src/web/TrackPlayer/RepeatMode.d.ts +0 -6
  834. package/lib/typescript/src/web/TrackPlayer/RepeatMode.d.ts.map +0 -1
  835. package/lib/typescript/src/web/TrackPlayer/SetupNotCalledError.d.ts +0 -4
  836. package/lib/typescript/src/web/TrackPlayer/SetupNotCalledError.d.ts.map +0 -1
  837. package/lib/typescript/src/web/TrackPlayer/SleepTimer.d.ts +0 -34
  838. package/lib/typescript/src/web/TrackPlayer/SleepTimer.d.ts.map +0 -1
  839. package/lib/typescript/src/web/TrackPlayer/State.d.ts +0 -13
  840. package/lib/typescript/src/web/TrackPlayer/State.d.ts.map +0 -1
  841. package/lib/typescript/src/web/TrackPlayer/index.d.ts +0 -5
  842. package/lib/typescript/src/web/TrackPlayer/index.d.ts.map +0 -1
  843. package/lib/typescript/src/web/browser/BrowserManager.d.ts +0 -154
  844. package/lib/typescript/src/web/browser/BrowserManager.d.ts.map +0 -1
  845. package/lib/typescript/src/web/browser/FavoriteManager.d.ts +0 -42
  846. package/lib/typescript/src/web/browser/FavoriteManager.d.ts.map +0 -1
  847. package/lib/typescript/src/web/browser/NavigationErrorManager.d.ts +0 -40
  848. package/lib/typescript/src/web/browser/NavigationErrorManager.d.ts.map +0 -1
  849. package/lib/typescript/src/web/browser/SearchManager.d.ts +0 -22
  850. package/lib/typescript/src/web/browser/SearchManager.d.ts.map +0 -1
  851. package/lib/typescript/src/web/http/HttpClient.d.ts +0 -25
  852. package/lib/typescript/src/web/http/HttpClient.d.ts.map +0 -1
  853. package/lib/typescript/src/web/http/RequestConfigBuilder.d.ts +0 -98
  854. package/lib/typescript/src/web/http/RequestConfigBuilder.d.ts.map +0 -1
  855. package/lib/typescript/src/web/player/NowPlayingManager.d.ts +0 -34
  856. package/lib/typescript/src/web/player/NowPlayingManager.d.ts.map +0 -1
  857. package/lib/typescript/src/web/player/OptionsManager.d.ts +0 -32
  858. package/lib/typescript/src/web/player/OptionsManager.d.ts.map +0 -1
  859. package/lib/typescript/src/web/util/BrowserPathHelper.d.ts +0 -69
  860. package/lib/typescript/src/web/util/BrowserPathHelper.d.ts.map +0 -1
  861. package/lib/typescript/src/web/util/shuffle.d.ts +0 -8
  862. package/lib/typescript/src/web/util/shuffle.d.ts.map +0 -1
  863. package/nitrogen/generated/android/c++/JAndroidUpdateOptions.hpp +0 -86
  864. package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__shared_ptr_Promise_std__variant_ResolvedTrack__BrowseError______BrowserSourceCallbackParam.hpp +0 -147
  865. package/nitrogen/generated/android/c++/JFunc_void_IosOutput.hpp +0 -80
  866. package/nitrogen/generated/android/c++/JFunc_void_RemoteSetRatingEvent.hpp +0 -87
  867. package/nitrogen/generated/android/c++/JHeartRating.hpp +0 -57
  868. package/nitrogen/generated/android/c++/JIosOutputType.hpp +0 -85
  869. package/nitrogen/generated/android/c++/JPartialSetupPlayerOptions.hpp +0 -96
  870. package/nitrogen/generated/android/c++/JPercentageRating.hpp +0 -57
  871. package/nitrogen/generated/android/c++/JRatingType.hpp +0 -73
  872. package/nitrogen/generated/android/c++/JRemoteSetRatingEvent.hpp +0 -66
  873. package/nitrogen/generated/android/c++/JStarRating.hpp +0 -57
  874. package/nitrogen/generated/android/c++/JUpdateOptions.hpp +0 -105
  875. package/nitrogen/generated/android/c++/JVariant_HeartRating_ThumbsRating_StarRating_PercentageRating.cpp +0 -34
  876. package/nitrogen/generated/android/c++/JVariant_HeartRating_ThumbsRating_StarRating_PercentageRating.hpp +0 -105
  877. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/AndroidUpdateOptions.kt +0 -50
  878. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/IosOutputType.kt +0 -32
  879. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/PartialSetupPlayerOptions.kt +0 -47
  880. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/UpdateOptions.kt +0 -53
  881. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Variant_HeartRating_ThumbsRating_StarRating_PercentageRating.kt +0 -77
  882. package/nitrogen/generated/ios/swift/AndroidUpdateOptions.swift +0 -119
  883. package/nitrogen/generated/ios/swift/Func_std__shared_ptr_Promise_std__shared_ptr_Promise_std__variant_ResolvedTrack__BrowseError______BrowserSourceCallbackParam.swift +0 -68
  884. package/nitrogen/generated/ios/swift/HeartRating.swift +0 -29
  885. package/nitrogen/generated/ios/swift/IosOutputType.swift +0 -76
  886. package/nitrogen/generated/ios/swift/PartialSetupPlayerOptions.swift +0 -101
  887. package/nitrogen/generated/ios/swift/PercentageRating.swift +0 -29
  888. package/nitrogen/generated/ios/swift/RatingType.swift +0 -60
  889. package/nitrogen/generated/ios/swift/RemoteSetRatingEvent.swift +0 -58
  890. package/nitrogen/generated/ios/swift/StarRating.swift +0 -29
  891. package/nitrogen/generated/ios/swift/ThumbsRating.swift +0 -29
  892. package/nitrogen/generated/ios/swift/UpdateOptions.swift +0 -143
  893. package/nitrogen/generated/ios/swift/Variant_HeartRating_ThumbsRating_StarRating_PercentageRating.swift +0 -20
  894. package/nitrogen/generated/shared/c++/AndroidUpdateOptions.hpp +0 -109
  895. package/nitrogen/generated/shared/c++/IosOutputType.hpp +0 -112
  896. package/nitrogen/generated/shared/c++/PartialSetupPlayerOptions.hpp +0 -104
  897. package/nitrogen/generated/shared/c++/RatingType.hpp +0 -96
  898. package/nitrogen/generated/shared/c++/RemoteSetRatingEvent.hpp +0 -94
  899. package/nitrogen/generated/shared/c++/UpdateOptions.hpp +0 -111
  900. package/src/features/rating.ts +0 -17
  901. package/src/types/player.ts +0 -69
  902. package/src/web/TrackPlayer/PlaylistPlayer.ts +0 -346
@@ -7,7 +7,6 @@ import type {
7
7
  PlayingState,
8
8
  RepeatModeChangedEvent,
9
9
  NativeUpdateOptions,
10
- UpdateOptions,
11
10
  Options,
12
11
  Playback,
13
12
  PlaybackActiveTrackChangedEvent,
@@ -20,11 +19,14 @@ import type {
20
19
  RemotePlayIdEvent,
21
20
  RemotePlaySearchEvent,
22
21
  RemoteSeekEvent,
23
- RemoteSetRatingEvent,
24
22
  RemoteSkipEvent,
25
23
  SleepTimer,
26
24
  SleepTimerChangedEvent,
27
25
  FavoriteChangedEvent,
26
+ NativeGate,
27
+ NativeGateRequest,
28
+ GateDecision,
29
+ GateEvent,
28
30
  NavigationError,
29
31
  NavigationErrorEvent,
30
32
  FormattedNavigationError,
@@ -34,15 +36,16 @@ import type {
34
36
  BatteryOptimizationStatus,
35
37
  BatteryOptimizationStatusChangedEvent,
36
38
  BatteryWarningPendingChangedEvent,
37
- PartialSetupPlayerOptions
39
+ NativeSetupPlayerOptions
38
40
  } from '../features'
39
41
  import type {
40
42
  AudioBrowser as AudioBrowserSpec,
41
- IosOutput
43
+ Output
42
44
  } from '../specs/audio-browser.nitro'
43
45
  import type { ResolvedTrack, Track, TrackLoadEvent } from '../types'
44
46
  import type { NativeBrowserConfiguration } from '../types/browser-native'
45
47
  import { BrowserManager } from './browser/BrowserManager'
48
+ import { classifyTrackNavigation } from './browser/classifyTrackNavigation'
46
49
  import { FavoriteManager } from './browser/FavoriteManager'
47
50
  import { NavigationErrorManager } from './browser/NavigationErrorManager'
48
51
  import { SearchManager } from './browser/SearchManager'
@@ -50,14 +53,16 @@ import { HttpClient } from './http/HttpClient'
50
53
  import { RequestConfigBuilder } from './http/RequestConfigBuilder'
51
54
  import { NowPlayingManager } from './player/NowPlayingManager'
52
55
  import { OptionsManager } from './player/OptionsManager'
53
- import { PlaylistPlayer, SleepTimerManager } from './TrackPlayer'
54
- import { BrowserPathHelper } from './util/BrowserPathHelper'
56
+ import { RemoteCommandController } from './player/RemoteCommandController'
57
+ import { QueuePlayer, SleepTimerManager, VolumeFader } from './TrackPlayer'
58
+ import { PlaybackTimer } from './TrackPlayer/PlaybackTimer'
59
+ import { derivePlayingState } from './TrackPlayer/PlayingStateFactory'
55
60
 
56
61
  /**
57
62
  * Web implementation of AudioBrowser (unified browser + player)
58
63
  */
59
64
  export class NativeAudioBrowser
60
- extends PlaylistPlayer
65
+ extends QueuePlayer
61
66
  implements AudioBrowserSpec
62
67
  {
63
68
  // HybridObject stuff
@@ -67,6 +72,8 @@ export class NativeAudioBrowser
67
72
  }
68
73
  dispose() {
69
74
  this.clearUpdateEventInterval()
75
+ this.setPlaybackIntervalEnabled(false)
76
+ this.remoteCommands.dispose()
70
77
  // Remove window event listeners to prevent memory leaks
71
78
  if (typeof window !== 'undefined' && this.onlineHandler) {
72
79
  window.removeEventListener('online', this.onlineHandler)
@@ -84,23 +91,35 @@ export class NativeAudioBrowser
84
91
  private searchManager: SearchManager
85
92
  private optionsManager: OptionsManager
86
93
  private nowPlayingManager: NowPlayingManager
94
+ private remoteCommands: RemoteCommandController
87
95
 
88
96
  // Player state
89
97
  private currentLoadId = 0
90
- private progressUpdateEventInterval: NodeJS.Timeout | undefined
98
+ private progressTimer = new PlaybackTimer()
99
+ private intervalTimer = new PlaybackTimer()
91
100
  private _online: boolean =
92
101
  typeof navigator !== 'undefined' ? navigator.onLine : true
93
102
  private onlineHandler: (() => void) | undefined
94
103
  private offlineHandler: (() => void) | undefined
104
+ private sleepFader = new VolumeFader(
105
+ () => this.getVolume(),
106
+ (volume) => this.setVolume(volume)
107
+ )
95
108
  private sleepTimer = new (class extends SleepTimerManager {
96
109
  constructor(private parent: NativeAudioBrowser) {
97
110
  super()
98
111
  }
99
112
  protected onComplete(): void {
100
- console.log('Sleep timer completed, stopping playback')
101
- this.parent.stop()
113
+ console.log('Sleep timer completed, pausing playback')
114
+ this.parent.sleepFader.resolve(() => this.parent.pause())
102
115
  this.parent.onSleepTimerChanged(null)
103
116
  }
117
+ protected onFadeStart(durationSeconds: number): void {
118
+ this.parent.sleepFader.start(durationSeconds)
119
+ }
120
+ protected onFadeCancel(): void {
121
+ this.parent.sleepFader.cancel(true)
122
+ }
104
123
  })(this)
105
124
 
106
125
  // MARK: Browser properties
@@ -151,17 +170,15 @@ export class NativeAudioBrowser
151
170
  onPlaybackPlayingState: (data: PlayingState) => void = () => {}
152
171
  onPlaybackProgressUpdated: (data: PlaybackProgressUpdatedEvent) => void =
153
172
  () => {}
173
+ onPlaybackInterval: () => void = () => {}
154
174
  onPlaybackQueueEnded: (data: PlaybackQueueEndedEvent) => void = () => {}
155
175
  onPlaybackQueueChanged: (queue: Track[]) => void = () => {}
156
176
  onPlaybackRepeatModeChanged: (data: RepeatModeChangedEvent) => void = () => {}
157
177
  onPlaybackShuffleModeChanged: (enabled: boolean) => void = () => {}
158
178
  onSleepTimerChanged: (data: SleepTimerChangedEvent) => void = () => {}
159
179
  onPlaybackChanged: (data: Playback) => void = () => {}
160
- onRemoteBookmark: () => void = () => {}
161
- onRemoteDislike: () => void = () => {}
162
180
  onRemoteJumpBackward: (event: RemoteJumpBackwardEvent) => void = () => {}
163
181
  onRemoteJumpForward: (event: RemoteJumpForwardEvent) => void = () => {}
164
- onRemoteLike: () => void = () => {}
165
182
  onRemoteNext: () => void = () => {}
166
183
  onRemotePause: () => void = () => {}
167
184
  onRemotePlay: () => void = () => {}
@@ -169,7 +186,6 @@ export class NativeAudioBrowser
169
186
  onRemotePlaySearch: (event: RemotePlaySearchEvent) => void = () => {}
170
187
  onRemotePrevious: () => void = () => {}
171
188
  onRemoteSeek: (event: RemoteSeekEvent) => void = () => {}
172
- onRemoteSetRating: (event: RemoteSetRatingEvent) => void = () => {}
173
189
  onRemoteSkip: (event: RemoteSkipEvent) => void = () => {}
174
190
  onRemoteStop: () => void = () => {}
175
191
  onOptionsChanged: (event: Options) => void = () => {}
@@ -184,18 +200,22 @@ export class NativeAudioBrowser
184
200
  event: BatteryOptimizationStatusChangedEvent
185
201
  ) => void = () => {}
186
202
  onSystemVolumeChanged: (volume: number) => void = () => {}
187
- onIosOutputChanged: (output: IosOutput) => void = () => {}
203
+ onOutputChanged: (output: Output) => void = () => {}
204
+ onGate: (event: GateEvent) => void = () => {}
205
+ // Fail closed by default: only reachable in the init window before gate.ts
206
+ // re-binds resolveGate. Web has no serve sites, so this is never called in
207
+ // practice, but the default must agree with the fail-closed contract.
208
+ resolveGate: (request: NativeGateRequest) => Promise<GateDecision> =
209
+ async () => ({ gated: true })
210
+ onCarConnectedChanged: (connected: boolean) => void = () => {}
188
211
 
189
212
  // MARK: Remote handlers
190
- handleRemoteBookmark: (() => void) | undefined = undefined
191
- handleRemoteDislike: (() => void) | undefined = undefined
192
213
  handleRemoteJumpBackward:
193
214
  | ((event: RemoteJumpBackwardEvent) => void)
194
215
  | undefined = undefined
195
216
  handleRemoteJumpForward:
196
217
  | ((event: RemoteJumpForwardEvent) => void)
197
218
  | undefined = undefined
198
- handleRemoteLike: (() => void) | undefined = undefined
199
219
  handleRemoteNext: (() => void) | undefined = undefined
200
220
  handleRemotePause: (() => void) | undefined = undefined
201
221
  handleRemotePlay: (() => void) | undefined = undefined
@@ -205,8 +225,6 @@ export class NativeAudioBrowser
205
225
  undefined
206
226
  handleRemotePrevious: (() => void) | undefined = undefined
207
227
  handleRemoteSeek: ((event: RemoteSeekEvent) => void) | undefined = undefined
208
- handleRemoteSetRating: ((event: RemoteSetRatingEvent) => void) | undefined =
209
- undefined
210
228
  handleRemoteSkip: (() => void) | undefined = undefined
211
229
  handleRemoteStop: (() => void) | undefined = undefined
212
230
 
@@ -220,6 +238,7 @@ export class NativeAudioBrowser
220
238
  this.navigationErrorManager = new NavigationErrorManager()
221
239
  this.optionsManager = new OptionsManager()
222
240
  this.nowPlayingManager = new NowPlayingManager()
241
+ this.remoteCommands = new RemoteCommandController(this)
223
242
 
224
243
  this.browserManager = new BrowserManager(
225
244
  this.httpClient,
@@ -227,7 +246,7 @@ export class NativeAudioBrowser
227
246
  this.navigationErrorManager
228
247
  )
229
248
 
230
- this.searchManager = new SearchManager(this.browserManager, this.httpClient)
249
+ this.searchManager = new SearchManager(this.browserManager)
231
250
 
232
251
  // Wire up event callbacks from managers to class callbacks
233
252
  this.browserManager.onPathChanged = (path) => this.onPathChanged(path)
@@ -241,7 +260,7 @@ export class NativeAudioBrowser
241
260
  this.optionsManager.onOptionsChanged = (options) =>
242
261
  this.onOptionsChanged(options)
243
262
  this.nowPlayingManager.onNowPlayingChanged = (metadata) =>
244
- this.onNowPlayingChanged(metadata)
263
+ this.publishNowPlaying(metadata)
245
264
 
246
265
  // Setup online/offline listeners
247
266
  if (typeof window !== 'undefined') {
@@ -280,60 +299,81 @@ export class NativeAudioBrowser
280
299
 
281
300
  // Call callbacks
282
301
  this.onPlaybackChanged(newState)
283
- this.onPlaybackPlayingState(this.getPlayingStateFromPlayback(newState))
302
+ this.refreshPlayingState()
303
+ this.remoteCommands.syncPlaybackState()
284
304
 
285
305
  if (newState.state === 'error' && newState.error) {
286
306
  this.onPlaybackError({ error: newState.error })
287
307
  }
288
308
  }
289
309
 
310
+ private lastPlayingState?: PlayingState
311
+
290
312
  /**
291
- * Derives PlayingState from playback state and playWhenReady.
292
- * Matches Android's PlayingStateFactory.derive() logic.
313
+ * Re-derives the playing state and emits on change. Called from both of its
314
+ * inputs' change points — the state setter and the playWhenReady setter —
315
+ * with a dedupe so identical derivations don't double-emit (parity with
316
+ * Android's refreshPlayingState / iOS's PlayingStateManager).
293
317
  */
294
- private getPlayingStateFromPlayback(playback: Playback): PlayingState {
295
- const state = playback.state
296
- const pwr = this._playWhenReady
297
- return {
298
- playing:
299
- pwr && state !== 'error' && state !== 'ended' && state !== 'none',
300
- buffering:
301
- pwr && (state === 'loading' || state === 'buffering')
318
+ private refreshPlayingState(): void {
319
+ const next = derivePlayingState(this._playWhenReady, this.state.state)
320
+ if (
321
+ this.lastPlayingState !== undefined &&
322
+ this.lastPlayingState.playing === next.playing &&
323
+ this.lastPlayingState.buffering === next.buffering
324
+ ) {
325
+ return
302
326
  }
327
+ this.lastPlayingState = next
328
+ this.onPlaybackPlayingState(next)
329
+ }
330
+
331
+ /**
332
+ * Emits now-playing metadata to JS consumers and mirrors it to the OS media
333
+ * controls (lockscreen / notification / media keys).
334
+ */
335
+ private publishNowPlaying(metadata: NowPlayingMetadata): void {
336
+ this.onNowPlayingChanged(metadata)
337
+ this.remoteCommands.setMetadata(metadata)
303
338
  }
304
339
 
305
340
  protected setupProgressUpdates(interval?: number) {
306
- this.clearUpdateEventInterval()
307
- if (interval) {
308
- this.progressUpdateEventInterval = setInterval(() => {
341
+ // Match Android: emit progress during loading, buffering, and playing.
342
+ this.progressTimer.start(
343
+ (interval ?? 0) * 1000,
344
+ () => {
309
345
  const state = this.state.state
310
- // Match Android: emit progress during loading, buffering, and playing
311
- if (
312
- state === 'playing' ||
313
- state === 'loading' ||
314
- state === 'buffering'
315
- ) {
316
- const progress = this.getProgress()
317
- const event: PlaybackProgressUpdatedEvent = {
318
- ...progress,
319
- track: this.currentIndex || 0
320
- }
321
- this.onPlaybackProgressUpdated(event)
322
- }
323
- }, interval * 1000)
324
- }
346
+ return (
347
+ state === 'playing' || state === 'loading' || state === 'buffering'
348
+ )
349
+ },
350
+ () => {
351
+ const progress = this.getProgress()
352
+ this.onPlaybackProgressUpdated({
353
+ ...progress,
354
+ track: this.queue.currentIndex || 0
355
+ })
356
+ this.remoteCommands.updateProgress()
357
+ }
358
+ )
325
359
  }
326
360
 
327
361
  protected clearUpdateEventInterval() {
328
- if (this.progressUpdateEventInterval) {
329
- clearInterval(this.progressUpdateEventInterval)
330
- }
362
+ this.progressTimer.stop()
363
+ }
364
+
365
+ setPlaybackIntervalEnabled(enabled: boolean): void {
366
+ this.intervalTimer.start(
367
+ enabled ? 1000 : 0,
368
+ () => this.state.state === 'playing',
369
+ () => this.onPlaybackInterval()
370
+ )
331
371
  }
332
372
 
333
- protected onPlaylistEnded() {
334
- super.onPlaylistEnded()
373
+ protected onQueueEnded() {
374
+ super.onQueueEnded()
335
375
  this.onPlaybackQueueEnded({
336
- track: this.currentIndex ?? 0,
376
+ track: this.queue.currentIndex ?? 0,
337
377
  position: this.element?.currentTime ?? 0
338
378
  })
339
379
  }
@@ -344,9 +384,8 @@ export class NativeAudioBrowser
344
384
  }
345
385
 
346
386
  navigateTrack(track: Track): void {
347
- const url = track.url
348
387
  // Execute async navigation logic without blocking
349
- void this.navigateTrackAsync(track, url)
388
+ void this.navigateTrackAsync(track)
350
389
  }
351
390
 
352
391
  /**
@@ -356,7 +395,9 @@ export class NativeAudioBrowser
356
395
  * @returns true if the handler intercepted, false if defaultBehavior ran
357
396
  */
358
397
  private async handleLoad(
359
- track: Track, queue: Track[], startIndex: number,
398
+ track: Track,
399
+ queue: Track[],
400
+ startIndex: number,
360
401
  defaultBehavior: () => void
361
402
  ): Promise<boolean> {
362
403
  const handler = this.configuration.handleTrackLoad
@@ -417,7 +458,12 @@ export class NativeAudioBrowser
417
458
  }
418
459
 
419
460
  await this.handleLoad(track, result.tracks, result.startIndex, () => {
461
+ // setQueue keeps the current play/pause state, so start playback
462
+ // explicitly — selecting a track is an intent to play (matches the
463
+ // skip-to-existing-queue-track path). Without this the first track of a
464
+ // freshly expanded queue loads but stays paused.
420
465
  this.setQueue(result.tracks, result.startIndex)
466
+ this.play()
421
467
  })
422
468
  return true
423
469
  }
@@ -426,55 +472,57 @@ export class NativeAudioBrowser
426
472
  * Async implementation of track navigation with queue expansion support.
427
473
  * Matches Android's MediaSessionCallback behavior.
428
474
  */
429
- private async navigateTrackAsync(
430
- track: Track,
431
- url: string | undefined
432
- ): Promise<void> {
475
+ private async navigateTrackAsync(track: Track): Promise<void> {
433
476
  try {
434
- // Handle contextual URL (playable track with queue context)
435
- if (url && BrowserPathHelper.isContextual(url)) {
436
- const parentPath = BrowserPathHelper.stripTrackId(url)
437
- const trackId = BrowserPathHelper.extractTrackId(url)
438
-
439
- // Optimization: skip to track if already in current queue
440
- if (trackId && await this.trySkipToExistingQueueTrack(trackId, parentPath)) {
477
+ const nav = classifyTrackNavigation(track)
478
+ switch (nav.kind) {
479
+ case 'contextual':
480
+ // Optimization: skip to the track if it's already in the queue.
481
+ if (
482
+ nav.trackId &&
483
+ (await this.trySkipToExistingQueueTrack(
484
+ nav.trackId,
485
+ nav.parentPath
486
+ ))
487
+ ) {
488
+ return
489
+ }
490
+ // Otherwise expand the queue from the contextual URL, falling back to
491
+ // loading the single track if expansion yields nothing.
492
+ if (await this.expandQueueAndPlay(track)) return
493
+ await this.playSingleTrack(track)
441
494
  return
442
- }
443
495
 
444
- // Expand queue from contextual URL
445
- if (await this.expandQueueAndPlay(track)) {
496
+ case 'browse':
497
+ this.browserManager.navigateTrack(track).catch((error: unknown) => {
498
+ console.error('Failed to navigate to track:', error)
499
+ })
446
500
  return
447
- }
448
-
449
- // Fallback: load single track if expansion fails
450
- await this.handleLoad(track, [track], 0, () => this.load(track))
451
- return
452
- }
453
501
 
454
- // Handle browsable track (has URL but not contextual)
455
- if (url) {
456
- this.browserManager.navigateTrack(track).catch((error: unknown) => {
457
- console.error('Failed to navigate to track:', error)
458
- })
459
- return
460
- }
502
+ case 'playable':
503
+ await this.playSingleTrack(track)
504
+ return
461
505
 
462
- // Handle playable track (has src but no URL)
463
- if (track.src) {
464
- await this.handleLoad(track, [track], 0, () => this.load(track))
465
- return
506
+ case 'invalid':
507
+ throw new Error("Track must have either 'url' or 'src' property")
466
508
  }
467
-
468
- throw new Error("Track must have either 'url' or 'src' property")
469
509
  } catch (error) {
470
510
  const message = error instanceof Error ? error.message : 'Unknown error'
471
511
  this.navigationErrorManager.setNavigationError('unknown-error', message)
472
512
  }
473
513
  }
474
514
 
515
+ /** Loads a single track as its own queue and starts playback. */
516
+ private async playSingleTrack(track: Track): Promise<void> {
517
+ await this.handleLoad(track, [track], 0, () => {
518
+ this.load(track)
519
+ this.play()
520
+ })
521
+ }
522
+
475
523
  async onSearch(query: string): Promise<Track[]> {
476
524
  // Wrap query string in SearchParams (matches Android's search(query: String) overload)
477
- return this.searchManager.search({ query })
525
+ return this.searchManager.search({ query, reference: 'unknown' })
478
526
  }
479
527
 
480
528
  getContent(): ResolvedTrack | undefined {
@@ -493,13 +541,24 @@ export class NativeAudioBrowser
493
541
  this.browserManager.notifyContentChanged(path)
494
542
  }
495
543
 
544
+ invalidateAllContent(): void {
545
+ this.browserManager.invalidateAllContent()
546
+ }
547
+
496
548
  setFavorites(favorites: string[]): void {
497
549
  this.favoriteManager.setFavorites(favorites)
498
550
  }
499
551
 
500
552
  // MARK: Player init and config
501
- async setupPlayer(options: PartialSetupPlayerOptions): Promise<void> {
553
+ async setupPlayer(options: NativeSetupPlayerOptions): Promise<void> {
502
554
  await super.setupPlayer(options)
555
+ // Apply the launch options and initial state bundled in setup — same
556
+ // atomic contract as the native platforms.
557
+ if (options.options) this.updateOptions(options.options)
558
+ if (options.repeatMode !== undefined) this.setRepeatMode(options.repeatMode)
559
+ if (options.playWhenReady !== undefined) {
560
+ this.setPlayWhenReady(options.playWhenReady)
561
+ }
503
562
  }
504
563
 
505
564
  updateOptions(options: NativeUpdateOptions): void {
@@ -516,7 +575,7 @@ export class NativeAudioBrowser
516
575
  }
517
576
  }
518
577
 
519
- getOptions(): UpdateOptions {
578
+ getOptions(): Options {
520
579
  return this.optionsManager.getOptions()
521
580
  }
522
581
 
@@ -529,8 +588,25 @@ export class NativeAudioBrowser
529
588
  * Mirrors Android's MediaFactory.getMediaRequestConfig behavior.
530
589
  */
531
590
  private async resolveMediaUrl(src: string): Promise<string> {
532
- const mediaConfig = this.browserManager.configuration.media
533
- return RequestConfigBuilder.resolveMediaUrl(src, mediaConfig)
591
+ const { request, media } = this.browserManager.configuration
592
+ return RequestConfigBuilder.resolveMediaUrl(src, request, media)
593
+ }
594
+
595
+ /**
596
+ * Reload from the queue's own entry, whose `src` is still unresolved —
597
+ * `current` holds the resolved track, and re-feeding it into `load()` would
598
+ * re-resolve the resolved URL (double-applying a `transform`) and replace
599
+ * the queue entry with it.
600
+ */
601
+ protected override reloadCurrent(): void {
602
+ const index = this.queue.currentIndex
603
+ const sourceTrack =
604
+ index !== undefined ? this.queue.getTrack(index) : undefined
605
+ if (sourceTrack) {
606
+ this.load(sourceTrack)
607
+ } else {
608
+ super.reloadCurrent()
609
+ }
534
610
  }
535
611
 
536
612
  load(track: Track, callback?: (track: Track) => void): void {
@@ -541,22 +617,22 @@ export class NativeAudioBrowser
541
617
 
542
618
  // Match Android: load() modifies the queue.
543
619
  // If queue is empty, add the track. If queue has items, replace at currentIndex.
544
- if (this.playlist.length === 0) {
545
- this.playlist = [track]
546
- this._currentIndex = 0
547
- this.onPlaybackQueueChanged(this.playlist)
620
+ if (this.queue.length === 0) {
621
+ this.queue.setTracks([track])
622
+ this.queue.currentIndex = 0
623
+ this.emitQueueChanged()
548
624
  } else if (
549
- this.currentIndex !== undefined &&
550
- this.playlist[this.currentIndex] !== track
625
+ this.queue.currentIndex !== undefined &&
626
+ this.queue.getTrack(this.queue.currentIndex) !== track
551
627
  ) {
552
- this.playlist[this.currentIndex] = track
553
- this.onPlaybackQueueChanged(this.playlist)
628
+ this.queue.replaceTrack(this.queue.currentIndex, track)
629
+ this.emitQueueChanged()
554
630
  }
555
631
 
556
632
  const lastTrack = this.current
557
633
  const lastPosition = element.currentTime
558
- const lastIndex = this.lastIndex
559
- const currentIndex = this.currentIndex
634
+ const lastIndex = this.queue.lastIndex
635
+ const currentIndex = this.queue.currentIndex
560
636
 
561
637
  // Set loading flag early so seekTo() calls during async URL resolution
562
638
  // are captured as pending seeks rather than silently dropped
@@ -587,7 +663,7 @@ export class NativeAudioBrowser
587
663
  // Update now playing metadata
588
664
  const nowPlaying = this.getNowPlaying()
589
665
  if (nowPlaying) {
590
- this.onNowPlayingChanged(nowPlaying)
666
+ this.publishNowPlaying(nowPlaying)
591
667
  }
592
668
 
593
669
  // Call the provided callback if any
@@ -599,12 +675,20 @@ export class NativeAudioBrowser
599
675
 
600
676
  // Execute async load without blocking, with error handling
601
677
  doLoad().catch((error: unknown) => {
678
+ // Only the active load may surface a resolution failure.
679
+ if (loadId !== this.currentLoadId) return
602
680
  this._loadInProgress = false
603
681
  this._pendingSeek = undefined
604
682
  console.error('Error loading track:', error)
605
683
  const message =
606
684
  error instanceof Error ? error.message : 'Failed to load track'
607
- const playbackError = { code: 'load-error', message }
685
+ // Track resolution failed before playback was ever attempted, so nothing
686
+ // is known about the stream itself.
687
+ const playbackError: PlaybackError = {
688
+ kind: 'unknown',
689
+ code: 'load-error',
690
+ message
691
+ }
608
692
  this.state = { state: 'error', error: playbackError }
609
693
  })
610
694
  }
@@ -613,15 +697,89 @@ export class NativeAudioBrowser
613
697
  super.togglePlayback()
614
698
  }
615
699
 
616
- setPlayWhenReady(pwr: boolean): void {
617
- const didChange = pwr !== this._playWhenReady
618
- super.playWhenReady = pwr
700
+ /**
701
+ * Copies before emitting: the queue mutates in place, and handing out the
702
+ * live array defeats React's reference-equality change detection.
703
+ */
704
+ private emitQueueChanged(): void {
705
+ this.onPlaybackQueueChanged([...this.queue.tracks])
706
+ }
707
+
708
+ // Queue mutations must reach onPlaybackQueueChanged (the contract covers
709
+ // added/removed/reordered; Android emits via onTimelineChanged).
710
+ override add(tracks: Track[], insertBeforeIndex?: number): void {
711
+ super.add(tracks, insertBeforeIndex)
712
+ this.emitQueueChanged()
713
+ }
714
+
715
+ override remove(indexes: number[]): void {
716
+ super.remove(indexes)
717
+ this.emitQueueChanged()
718
+ }
719
+
720
+ override move(fromIndex: number, toIndex: number): void {
721
+ super.move(fromIndex, toIndex)
722
+ this.emitQueueChanged()
723
+ }
724
+
725
+ override removeUpcomingTracks(): void {
726
+ super.removeUpcomingTracks()
727
+ this.emitQueueChanged()
728
+ }
729
+
730
+ override reset(): void {
731
+ super.reset()
732
+ this.emitQueueChanged()
733
+ }
734
+
735
+ // Override playWhenReady to emit events (mirrors the state override): the
736
+ // base transport methods (play/pause/stop, the queue-end intent clear)
737
+ // assign through this accessor, so the change event and MediaSession sync
738
+ // fire for every writer — not only setPlayWhenReady().
739
+ public override get playWhenReady(): boolean {
740
+ return super.playWhenReady
741
+ }
619
742
 
743
+ public override set playWhenReady(pwr: boolean) {
744
+ const didChange = pwr !== super.playWhenReady
745
+ super.playWhenReady = pwr
620
746
  if (didChange) {
621
- this.onPlaybackPlayWhenReadyChanged({
622
- playWhenReady: this._playWhenReady
623
- })
747
+ this.onPlaybackPlayWhenReadyChanged({ playWhenReady: pwr })
748
+ this.refreshPlayingState()
749
+ this.remoteCommands.syncPlaybackState()
750
+ }
751
+ }
752
+
753
+ setPlayWhenReady(pwr: boolean): void {
754
+ if (!pwr) {
755
+ if (this.element) {
756
+ // pause() halts first and its override then clears a fading sleep
757
+ // timer — restoring the volume before the halt would let full-volume
758
+ // audio slip out (VolumeFader's invariant).
759
+ this.pause()
760
+ } else {
761
+ this.clearSleepTimerIfFading()
762
+ this.playWhenReady = false
763
+ }
764
+ return
624
765
  }
766
+ // Mirror native: raising the intent restarts playback from terminal
767
+ // states (reload/replay via play()) and resumes a settled paused/ready
768
+ // player. While loading/buffering the flag alone is correct — load()'s
769
+ // auto-play starts playback once the source is ready.
770
+ const { state } = this.state
771
+ if (
772
+ this.current !== undefined &&
773
+ (state === 'ended' ||
774
+ state === 'stopped' ||
775
+ state === 'error' ||
776
+ state === 'paused' ||
777
+ state === 'ready')
778
+ ) {
779
+ this.play()
780
+ return
781
+ }
782
+ this.playWhenReady = true
625
783
  }
626
784
 
627
785
  getPlayWhenReady(): boolean {
@@ -633,7 +791,7 @@ export class NativeAudioBrowser
633
791
  }
634
792
 
635
793
  getPlayingState(): PlayingState {
636
- return this.getPlayingStateFromPlayback(this.state)
794
+ return derivePlayingState(this._playWhenReady, this.state.state)
637
795
  }
638
796
 
639
797
  getRepeatMode(): RepeatModeType {
@@ -641,7 +799,7 @@ export class NativeAudioBrowser
641
799
  }
642
800
 
643
801
  setRepeatMode(mode: RepeatModeType): void {
644
- const didChange = this.repeatMode !== mode
802
+ const didChange = this.queue.repeatMode !== mode
645
803
  super.setRepeatMode(mode)
646
804
  this.optionsManager.setRepeatMode(mode)
647
805
 
@@ -677,11 +835,35 @@ export class NativeAudioBrowser
677
835
  return null
678
836
  }
679
837
 
680
- setSleepTimer(seconds: number): void {
681
- this.sleepTimer.sleepAfter(seconds)
838
+ setSleepTimer(seconds: number, fadeDuration?: number): void {
839
+ this.sleepTimer.sleepAfter(seconds, fadeDuration)
682
840
  this.onSleepTimerChanged(this.getSleepTimer())
683
841
  }
684
842
 
843
+ /**
844
+ * An explicit pause intent during the sleep fade is the timer's goal
845
+ * arriving early: clear the timer (which restores the pre-fade volume).
846
+ * Called after the halt lands so the restore never precedes it. Mirrors
847
+ * the native playWhenReady hooks.
848
+ */
849
+ private clearSleepTimerIfFading(): void {
850
+ if (this.sleepFader.isActive) this.clearSleepTimer()
851
+ }
852
+
853
+ override pause(): void {
854
+ super.pause()
855
+ this.clearSleepTimerIfFading()
856
+ }
857
+
858
+ override stop(): void {
859
+ // Invalidate any in-flight load: its post-await continuation would call
860
+ // super.load(), whose first line re-arms the player (_isStopped = false)
861
+ // and revives the state out of Stopped.
862
+ this.currentLoadId++
863
+ super.stop()
864
+ this.clearSleepTimerIfFading()
865
+ }
866
+
685
867
  setSleepTimerToEndOfTrack(): void {
686
868
  this.sleepTimer.setToEndOfTrack()
687
869
  this.onSleepTimerChanged(this.getSleepTimer())
@@ -701,9 +883,9 @@ export class NativeAudioBrowser
701
883
  protected onTrackEnded(): void {
702
884
  // Check if sleep timer is set to end on track completion
703
885
  if (this.sleepTimer.sleepWhenPlayedToEnd) {
704
- console.log('Sleep timer triggered on track end, stopping playback')
886
+ console.log('Sleep timer triggered on track end, pausing playback')
705
887
  this.sleepTimer.clear()
706
- this.stop()
888
+ this.pause()
707
889
  this.onSleepTimerChanged(null)
708
890
  return
709
891
  }
@@ -713,49 +895,43 @@ export class NativeAudioBrowser
713
895
  }
714
896
 
715
897
  // MARK: Queue management
716
- setQueue(
717
- tracks: Track[],
718
- startIndex?: number,
719
- startPositionMs?: number
720
- ): void {
898
+ setQueue(tracks: Track[], startIndex?: number, startPosition?: number): void {
721
899
  this.stop()
722
900
  // Clear stale references from previous queue
723
901
  this.current = undefined
724
- this._currentIndex = undefined
725
902
  // Hydrate favorites and transform artwork URLs on all tracks in the queue
726
- const artworkConfig = this.browserManager.configuration.artwork
727
- this.playlist = tracks.map((track) => {
728
- try {
729
- const hydratedTrack = this.favoriteManager.hydrateFavorite(track)
730
- return RequestConfigBuilder.transformTrackArtwork(
731
- hydratedTrack,
732
- artworkConfig
733
- )
734
- } catch (error) {
735
- console.error('Failed to transform track:', error)
736
- return track // Use original track as fallback
737
- }
738
- })
739
- this.onPlaybackQueueChanged(this.playlist)
740
-
741
- // Regenerate shuffle order when queue is set
742
- if (super.getShuffleEnabled()) {
743
- super.setShuffleEnabled(true) // Regenerates shuffle order
744
- }
903
+ const { request, artwork } = this.browserManager.configuration
904
+ this.queue.setTracks(
905
+ tracks.map((track) => {
906
+ try {
907
+ const hydratedTrack = this.favoriteManager.hydrateFavorite(track)
908
+ return RequestConfigBuilder.transformTrackArtwork(
909
+ hydratedTrack,
910
+ request,
911
+ artwork
912
+ )
913
+ } catch (error) {
914
+ console.error('Failed to transform track:', error)
915
+ return track // Use original track as fallback
916
+ }
917
+ })
918
+ )
919
+ this.emitQueueChanged()
745
920
 
746
- if (startIndex !== undefined && this.playlist[startIndex]) {
747
- this.skip(startIndex, startPositionMs)
921
+ if (startIndex !== undefined && this.queue.getTrack(startIndex)) {
922
+ this.skip(startIndex, startPosition)
748
923
  }
749
924
  }
750
925
 
751
926
  getQueue(): Track[] {
752
- return this.playlist
927
+ // Copy — see emitQueueChanged.
928
+ return [...this.queue.tracks]
753
929
  }
754
930
 
755
931
  getActiveTrackIndex(): number | undefined {
756
932
  this.requireElement()
757
933
  this.requirePlayer()
758
- return this.currentIndex
934
+ return this.queue.currentIndex
759
935
  }
760
936
 
761
937
  getActiveTrack(): Track | undefined {
@@ -780,8 +956,8 @@ export class NativeAudioBrowser
780
956
  favorited
781
957
  }
782
958
 
783
- // Replace the track in the playlist
784
- this.playlist[index] = updatedTrack
959
+ // Replace the track in the queue
960
+ this.queue.replaceTrack(index, updatedTrack)
785
961
 
786
962
  // Emit favorite changed event
787
963
  this.onFavoriteChanged({ track: updatedTrack, favorited })
@@ -796,7 +972,7 @@ export class NativeAudioBrowser
796
972
  })
797
973
 
798
974
  // Emit queue changed so useQueue() hook updates
799
- this.onPlaybackQueueChanged(this.playlist)
975
+ this.emitQueueChanged()
800
976
  }
801
977
 
802
978
  toggleActiveTrackFavorited(): void {
@@ -820,6 +996,26 @@ export class NativeAudioBrowser
820
996
  return this.nowPlayingManager.getNowPlaying(track, duration)
821
997
  }
822
998
 
999
+ private nowPlayingFlashRevert: ReturnType<typeof setTimeout> | undefined
1000
+
1001
+ flashNowPlaying(update: NowPlayingUpdate, durationMs: number): void {
1002
+ // Web approximation: an override + timer is sufficient here — the
1003
+ // background-timer and formatter-priority concerns are native-only.
1004
+ this.updateNowPlaying(update)
1005
+ if (this.nowPlayingFlashRevert) clearTimeout(this.nowPlayingFlashRevert)
1006
+ this.nowPlayingFlashRevert = setTimeout(() => {
1007
+ this.nowPlayingFlashRevert = undefined
1008
+ this.updateNowPlaying(undefined)
1009
+ }, durationMs)
1010
+ }
1011
+
1012
+ clearNowPlayingFlash(): void {
1013
+ if (!this.nowPlayingFlashRevert) return
1014
+ clearTimeout(this.nowPlayingFlashRevert)
1015
+ this.nowPlayingFlashRevert = undefined
1016
+ this.updateNowPlaying(undefined)
1017
+ }
1018
+
823
1019
  // MARK: Network connectivity
824
1020
  getOnline(): boolean {
825
1021
  return this._online
@@ -873,12 +1069,27 @@ export class NativeAudioBrowser
873
1069
  // No-op on web - browsers can't set system volume
874
1070
  }
875
1071
 
876
- // MARK: iOS output (not applicable on web)
877
- getIosOutput(): IosOutput | undefined {
1072
+ // MARK: Gate (no-op — web has no external browse surfaces)
1073
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
1074
+ setGate(_gate: NativeGate | undefined, _hasResolver: boolean): void {}
1075
+
1076
+ clearGate(): void {}
1077
+
1078
+ // MARK: Car connection (not applicable on web)
1079
+ isCarConnected(): boolean {
1080
+ return false
1081
+ }
1082
+
1083
+ // MARK: audio output (not applicable on web)
1084
+ getOutput(): Output | undefined {
878
1085
  return undefined
879
1086
  }
880
1087
 
881
- openIosOutputPicker(): void {
1088
+ openOutputPicker(): void {
882
1089
  // No-op on web
883
1090
  }
1091
+
1092
+ supportsOutputSwitcher(): boolean {
1093
+ return false
1094
+ }
884
1095
  }