react-native-audio-browser 0.2.0-next.3 → 0.2.0-next.30

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 (989) hide show
  1. package/README.md +36 -22
  2. package/android/build.gradle +35 -12
  3. package/android/gradle.properties +2 -2
  4. package/android/src/main/AndroidManifest.xml +3 -1
  5. package/android/src/main/java/com/audiobrowser/AudioBrowser.kt +541 -278
  6. package/android/src/main/java/com/audiobrowser/AudioBrowserLifecycleModule.kt +38 -0
  7. package/android/src/main/java/com/audiobrowser/AudioBrowserPackage.kt +18 -2
  8. package/android/src/main/java/com/audiobrowser/ServiceBinding.kt +52 -0
  9. package/android/src/main/java/com/audiobrowser/browser/BrowserManager.kt +315 -213
  10. package/android/src/main/java/com/audiobrowser/browser/BrowserUrlResolution.kt +27 -9
  11. package/android/src/main/java/com/audiobrowser/browser/InertStyleDiagnostic.kt +288 -0
  12. package/android/src/main/java/com/audiobrowser/browser/JsonModels.kt +97 -58
  13. package/android/src/main/java/com/audiobrowser/browser/SectionScope.kt +70 -29
  14. package/android/src/main/java/com/audiobrowser/browser/StyleResolver.kt +60 -0
  15. package/android/src/main/java/com/audiobrowser/extension/ResolvedTrackExt.kt +20 -7
  16. package/android/src/main/java/com/audiobrowser/extension/TappedTrack.kt +20 -0
  17. package/android/src/main/java/com/audiobrowser/extension/TrackIdentity.kt +15 -0
  18. package/android/src/main/java/com/audiobrowser/http/HttpClient.kt +20 -3
  19. package/android/src/main/java/com/audiobrowser/model/IcyTitle.kt +24 -0
  20. package/android/src/main/java/com/audiobrowser/model/PlaybackMetadata.kt +10 -6
  21. package/android/src/main/java/com/audiobrowser/model/PlayerUpdateOptions.kt +12 -12
  22. package/android/src/main/java/com/audiobrowser/player/CapabilityControls.kt +111 -58
  23. package/android/src/main/java/com/audiobrowser/player/CrossOriginHeaderStripper.kt +77 -0
  24. package/android/src/main/java/com/audiobrowser/player/MediaFactory.kt +28 -10
  25. package/android/src/main/java/com/audiobrowser/player/MediaSessionCallback.kt +509 -230
  26. package/android/src/main/java/com/audiobrowser/player/MediaSessionCommandManager.kt +218 -252
  27. package/android/src/main/java/com/audiobrowser/player/NowPlayingUpdater.kt +21 -25
  28. package/android/src/main/java/com/audiobrowser/player/PlaybackStateStore.kt +113 -78
  29. package/android/src/main/java/com/audiobrowser/player/Player.kt +81 -38
  30. package/android/src/main/java/com/audiobrowser/player/PlayerCapabilitiesExt.kt +2 -15
  31. package/android/src/main/java/com/audiobrowser/player/PlayerListener.kt +1 -1
  32. package/android/src/main/java/com/audiobrowser/player/RetryLoadErrorHandlingPolicy.kt +2 -1
  33. package/android/src/main/java/com/audiobrowser/player/ShuffleOrderLedBy.kt +30 -0
  34. package/android/src/main/java/com/audiobrowser/tls/AiaCertChaser.kt +67 -11
  35. package/android/src/main/java/com/audiobrowser/tls/AiaChasingExtendedTrustManager.kt +168 -0
  36. package/android/src/main/java/com/audiobrowser/tls/AiaChasingTrustManager.kt +58 -14
  37. package/android/src/main/java/com/audiobrowser/tls/AiaTls.kt +35 -7
  38. package/android/src/main/java/com/audiobrowser/tls/CachingCertificateFetcher.kt +278 -59
  39. package/android/src/main/java/com/audiobrowser/util/ArtworkVariant.kt +7 -9
  40. package/android/src/main/java/com/audiobrowser/util/BrowserPathHelper.kt +62 -40
  41. package/android/src/main/java/com/audiobrowser/util/MediaExtrasBuilder.kt +28 -23
  42. package/android/src/main/java/com/audiobrowser/util/StyleWire.kt +110 -0
  43. package/android/src/main/java/com/audiobrowser/util/TrackFactory.kt +56 -52
  44. package/android/src/main/res/values/strings.xml +25 -5
  45. package/android/src/test/java/com/audiobrowser/ServiceBindingTest.kt +100 -0
  46. package/android/src/test/java/com/audiobrowser/TestFixtures.kt +119 -33
  47. package/android/src/test/java/com/audiobrowser/browser/BrowserManagerFavoritesTest.kt +153 -0
  48. package/android/src/test/java/com/audiobrowser/browser/BrowserManagerLayerResolutionTest.kt +15 -0
  49. package/android/src/test/java/com/audiobrowser/browser/BrowserManagerTest.kt +346 -8
  50. package/android/src/test/java/com/audiobrowser/browser/BrowserUrlResolutionTest.kt +40 -2
  51. package/android/src/test/java/com/audiobrowser/browser/InertStyleDiagnosticTest.kt +301 -0
  52. package/android/src/test/java/com/audiobrowser/browser/JsonArtworkTest.kt +3 -2
  53. package/android/src/test/java/com/audiobrowser/browser/JsonStyleTest.kt +168 -0
  54. package/android/src/test/java/com/audiobrowser/browser/SectionScopeTest.kt +128 -55
  55. package/android/src/test/java/com/audiobrowser/browser/StyleResolverTest.kt +160 -0
  56. package/android/src/test/java/com/audiobrowser/extension/TappedTrackTest.kt +43 -0
  57. package/android/src/test/java/com/audiobrowser/extension/TrackIdentityTest.kt +41 -0
  58. package/android/src/test/java/com/audiobrowser/model/IcyTitleTest.kt +49 -0
  59. package/android/src/test/java/com/audiobrowser/player/BrowseTilesTest.kt +385 -0
  60. package/android/src/test/java/com/audiobrowser/player/CapabilityControlsTest.kt +101 -58
  61. package/android/src/test/java/com/audiobrowser/player/CrossOriginHeaderStripperTest.kt +94 -0
  62. package/android/src/test/java/com/audiobrowser/player/MediaSessionSlotMappingTest.kt +45 -0
  63. package/android/src/test/java/com/audiobrowser/player/NowPlayingUpdaterTest.kt +42 -2
  64. package/android/src/test/java/com/audiobrowser/player/PlaybackErrorClassifierTest.kt +3 -4
  65. package/android/src/test/java/com/audiobrowser/player/PlaybackStateStoreTrackJsonTest.kt +55 -0
  66. package/android/src/test/java/com/audiobrowser/player/RetryLoadErrorHandlingPolicyTest.kt +3 -3
  67. package/android/src/test/java/com/audiobrowser/player/ShuffleOrderLedByTest.kt +79 -0
  68. package/android/src/test/java/com/audiobrowser/tls/AiaCertChaserTest.kt +197 -7
  69. package/android/src/test/java/com/audiobrowser/tls/AiaChasingTrustManagerTest.kt +325 -4
  70. package/android/src/test/java/com/audiobrowser/tls/CachingCertificateFetcherCallSiteTest.kt +322 -0
  71. package/android/src/test/java/com/audiobrowser/tls/CachingCertificateFetcherTest.kt +83 -0
  72. package/android/src/test/java/com/audiobrowser/util/BrowserPathHelperTest.kt +55 -16
  73. package/android/src/test/java/com/audiobrowser/util/MediaExtrasBuilderTest.kt +162 -0
  74. package/android/src/test/java/com/audiobrowser/util/TrackFactoryMediaIdTest.kt +7 -7
  75. package/ios/AVPlayerEngine.swift +330 -0
  76. package/ios/AVPlayerEngineCallbacks.swift +15 -0
  77. package/ios/Browser/BrowseGate.swift +58 -0
  78. package/ios/Browser/BrowserConfig.swift +117 -78
  79. package/ios/Browser/BrowserManager.swift +209 -603
  80. package/ios/Browser/BrowserPathHelper.swift +50 -46
  81. package/ios/Browser/InertStyleDiagnostic.swift +296 -0
  82. package/ios/Browser/JsonModels.swift +264 -106
  83. package/ios/Browser/NavigationErrorState.swift +41 -0
  84. package/ios/Browser/PageResolver.swift +227 -0
  85. package/ios/Browser/RequestLayer.swift +90 -0
  86. package/ios/Browser/{BrowserManager+URLResolution.swift → RequestPipeline.swift} +193 -121
  87. package/ios/Browser/SearchDrillIn.swift +7 -7
  88. package/ios/Browser/SectionScope.swift +58 -24
  89. package/ios/Browser/StyleResolver.swift +58 -0
  90. package/ios/Browser/TabBarEntries.swift +9 -3
  91. package/ios/Browser/TrackIdTemplate.swift +37 -0
  92. package/ios/CarPlay/CPInterfaceController+Safe.swift +100 -43
  93. package/ios/CarPlay/CarPlayArtworkResolver.swift +36 -83
  94. package/ios/CarPlay/CarPlayController.swift +42 -1296
  95. package/ios/CarPlay/CarPlayImageLoader.swift +78 -97
  96. package/ios/CarPlay/CarPlayListItemFactory.swift +303 -92
  97. package/ios/CarPlay/CarPlayNowPlayingManager.swift +129 -136
  98. package/ios/CarPlay/CarPlaySession+Navigator.swift +114 -0
  99. package/ios/CarPlay/CarPlaySession+PageLoader.swift +92 -0
  100. package/ios/CarPlay/CarPlaySession+Refresher.swift +43 -0
  101. package/ios/CarPlay/CarPlaySession+TabBar.swift +193 -0
  102. package/ios/CarPlay/CarPlaySession.swift +209 -0
  103. package/ios/CarPlay/CarPlayTemplates.swift +63 -0
  104. package/ios/CarPlay/HybridAudioBrowser+IntentFavorite.swift +20 -0
  105. package/ios/{Player → CarPlay}/MediaIntentCriteria.swift +17 -9
  106. package/ios/CarPlay/MediaIntentPlayback.swift +74 -0
  107. package/ios/CarPlay/RNABMediaAddHandler.swift +8 -24
  108. package/ios/CarPlay/RNABMediaAffinityHandler.swift +7 -23
  109. package/ios/CarPlay/RNABMediaIntentHandler.swift +18 -19
  110. package/ios/CarPlay/SectionPresentation.swift +77 -0
  111. package/ios/CarPlay/TopTemplateReplacer.swift +96 -0
  112. package/ios/Extension/Capability+RemoteCommand.swift +1 -1
  113. package/ios/Extension/NavigationError+Conversion.swift +14 -4
  114. package/ios/Extension/PlayerCapabilities+Favorite.swift +1 -15
  115. package/ios/Extension/ResolvedTrack+Copying.swift +13 -15
  116. package/ios/Extension/Section+Copying.swift +29 -0
  117. package/ios/Extension/String+IcyCharset.swift +21 -0
  118. package/ios/Extension/TimedMetadata+AVFoundation.swift +6 -4
  119. package/ios/Extension/Track+Copying.swift +8 -12
  120. package/ios/Extension/Track+Identity.swift +18 -0
  121. package/ios/Extension/UIApplication+ActiveScene.swift +27 -0
  122. package/ios/Extension/UIImage+Adaptive.swift +12 -0
  123. package/ios/Extension/URLError+Connectivity.swift +15 -0
  124. package/ios/Http/HttpClient.swift +66 -142
  125. package/ios/HybridAudioBrowser+Browser.swift +153 -0
  126. package/ios/HybridAudioBrowser+Options.swift +144 -0
  127. package/ios/HybridAudioBrowser+Player.swift +397 -0
  128. package/ios/HybridAudioBrowser+PlayerCallbacks.swift +190 -0
  129. package/ios/HybridAudioBrowser+Stubs.swift +46 -0
  130. package/ios/HybridAudioBrowser.swift +153 -1610
  131. package/ios/Model/NitroTypeStubs.swift +146 -24
  132. package/ios/Model/PlayerUpdateOptions.swift +8 -1
  133. package/ios/Model/RemoteCommand.swift +18 -0
  134. package/ios/Model/TrackPlayerError.swift +2 -2
  135. package/ios/NowPlayingInfo/NowPlayingInfoController.swift +18 -53
  136. package/ios/Observer/ItemObserver.swift +90 -0
  137. package/ios/Observer/PlayerObserver.swift +59 -0
  138. package/ios/Option/SessionCategories.swift +42 -92
  139. package/ios/Player/AudioSessionController.swift +177 -0
  140. package/ios/Player/DeferredSeek.swift +70 -0
  141. package/ios/Player/ErrorStatus.swift +27 -0
  142. package/ios/Player/MediaLoader.swift +62 -35
  143. package/ios/Player/NowPlayingUpdater.swift +197 -50
  144. package/ios/Player/PlaybackFailure.swift +125 -0
  145. package/ios/Player/PlaybackPersistence.swift +73 -0
  146. package/ios/Player/PlaybackTimer.swift +8 -2
  147. package/ios/Player/Player.swift +1078 -0
  148. package/ios/Player/{PlaybackCoordinatorCallbacks.swift → PlayerCallbacks.swift} +3 -4
  149. package/ios/Player/PlayerEngine.swift +87 -0
  150. package/ios/Player/PlayerStatusTypes.swift +2 -6
  151. package/ios/Player/QueueManager.swift +93 -67
  152. package/ios/Player/RetryLoop.swift +261 -0
  153. package/ios/Player/ShuffleOrder.swift +33 -0
  154. package/ios/Player/SleepTimerManager.swift +1 -1
  155. package/ios/RemoteCommand/RemoteCommandCallbacks.swift +46 -0
  156. package/ios/RemoteCommand/RemoteCommandController.swift +87 -331
  157. package/ios/Tests/BrowserPathHelperTests.swift +56 -15
  158. package/ios/Tests/CarPlayArtworkResolverTests.swift +60 -373
  159. package/ios/Tests/DeferredSeekTests.swift +70 -0
  160. package/ios/Tests/EmitterTests.swift +29 -0
  161. package/ios/Tests/GenerationMemoTests.swift +121 -0
  162. package/ios/Tests/InertStyleDiagnosticTests.swift +209 -0
  163. package/ios/Tests/JsonModelsTests.swift +164 -1
  164. package/ios/Tests/LRUCacheTests.swift +110 -0
  165. package/ios/Tests/MediaIntentCriteriaTests.swift +2 -2
  166. package/ios/Tests/MediaLoaderTests.swift +12 -48
  167. package/ios/Tests/ObserverTests.swift +88 -0
  168. package/ios/Tests/PlaybackErrorTests.swift +76 -0
  169. package/ios/Tests/PlaybackFailureTests.swift +189 -0
  170. package/ios/Tests/PlaybackPersistenceTests.swift +93 -0
  171. package/ios/Tests/PlayerPolicyTests.swift +420 -0
  172. package/ios/Tests/{PlaybackCoordinatorTests.swift → PlayerTests.swift} +300 -248
  173. package/ios/Tests/PlayingStateTests.swift +42 -0
  174. package/ios/Tests/QueueManagerTests.swift +196 -115
  175. package/ios/Tests/ReadyValueTests.swift +73 -0
  176. package/ios/Tests/RemoteCommandControllerTests.swift +152 -0
  177. package/ios/Tests/RemoteCommandTests.swift +65 -0
  178. package/ios/Tests/RequestLayerTests.swift +112 -0
  179. package/ios/Tests/ResolvedTrackCopyingTests.swift +39 -35
  180. package/ios/Tests/RetryLoopTests.swift +270 -0
  181. package/ios/Tests/SearchDrillInTests.swift +16 -16
  182. package/ios/Tests/SectionPresentationTests.swift +98 -0
  183. package/ios/Tests/SectionScopeTests.swift +87 -55
  184. package/ios/Tests/StyleResolverTests.swift +132 -0
  185. package/ios/Tests/Support/TestTypes.swift +108 -104
  186. package/ios/Tests/TabBarEntriesTests.swift +19 -19
  187. package/ios/Tests/TimedMetadataAVFoundationTests.swift +42 -0
  188. package/ios/Tests/TopTemplateReplacerTests.swift +172 -0
  189. package/ios/Tests/TrackIdTemplateTests.swift +67 -0
  190. package/ios/Tests/TrackIdentityTests.swift +20 -0
  191. package/ios/Tests/TrackSelectorTests.swift +168 -33
  192. package/ios/Tests/URLErrorConnectivityTests.swift +20 -0
  193. package/ios/TrackSelector.swift +46 -31
  194. package/ios/Util/ArtworkImageFetcher.swift +58 -1
  195. package/ios/Util/Emitter.swift +42 -0
  196. package/ios/Util/GenerationMemo.swift +36 -0
  197. package/ios/Util/LRUCache.swift +23 -159
  198. package/ios/Util/NetworkMonitor.swift +43 -26
  199. package/ios/Util/ReadyValue.swift +56 -0
  200. package/ios/Util/SFSymbolRenderer.swift +59 -31
  201. package/ios/Util/SVGProcessor.swift +9 -12
  202. package/lib/commonjs/AudioBrowser.js +8 -8
  203. package/lib/commonjs/AudioBrowser.js.map +1 -1
  204. package/lib/commonjs/CLAUDE.md +52 -0
  205. package/lib/commonjs/features/browser-config.js +12 -8
  206. package/lib/commonjs/features/browser-config.js.map +1 -1
  207. package/lib/commonjs/features/browser.js +11 -3
  208. package/lib/commonjs/features/browser.js.map +1 -1
  209. package/lib/commonjs/features/carConnection.js +1 -1
  210. package/lib/commonjs/features/equalizer.js +1 -1
  211. package/lib/commonjs/features/errors.js +3 -3
  212. package/lib/commonjs/features/favorites.js +14 -11
  213. package/lib/commonjs/features/favorites.js.map +1 -1
  214. package/lib/commonjs/features/gate.js +16 -1
  215. package/lib/commonjs/features/gate.js.map +1 -1
  216. package/lib/commonjs/features/metadata.js +20 -3
  217. package/lib/commonjs/features/metadata.js.map +1 -1
  218. package/lib/commonjs/features/network.js +1 -1
  219. package/lib/commonjs/features/nowPlaying.js +1 -1
  220. package/lib/commonjs/features/output.js +1 -1
  221. package/lib/commonjs/features/playback/controls.js +4 -2
  222. package/lib/commonjs/features/playback/controls.js.map +1 -1
  223. package/lib/commonjs/features/playback/playWhenReady.js +1 -1
  224. package/lib/commonjs/features/playback/playing.js +1 -1
  225. package/lib/commonjs/features/playback/progress.js +3 -2
  226. package/lib/commonjs/features/playback/progress.js.map +1 -1
  227. package/lib/commonjs/features/playback/rate.js +8 -1
  228. package/lib/commonjs/features/playback/rate.js.map +1 -1
  229. package/lib/commonjs/features/playback/state.js +3 -4
  230. package/lib/commonjs/features/playback/state.js.map +1 -1
  231. package/lib/commonjs/features/playback/trackPlaybackTime.js +0 -6
  232. package/lib/commonjs/features/playback/trackPlaybackTime.js.map +1 -1
  233. package/lib/commonjs/features/playback/volume.js +1 -1
  234. package/lib/commonjs/features/player/options.js +48 -34
  235. package/lib/commonjs/features/player/options.js.map +1 -1
  236. package/lib/commonjs/features/player/setup.js +18 -9
  237. package/lib/commonjs/features/player/setup.js.map +1 -1
  238. package/lib/commonjs/features/player/validateOptions.js +23 -0
  239. package/lib/commonjs/features/player/validateOptions.js.map +1 -0
  240. package/lib/commonjs/features/queue/activeTrack.js +15 -4
  241. package/lib/commonjs/features/queue/activeTrack.js.map +1 -1
  242. package/lib/commonjs/features/queue/queue.js +13 -6
  243. package/lib/commonjs/features/queue/queue.js.map +1 -1
  244. package/lib/commonjs/features/queue/repeatMode.js +1 -1
  245. package/lib/commonjs/features/queue/shuffle.js +1 -1
  246. package/lib/commonjs/features/remoteControls.js +13 -92
  247. package/lib/commonjs/features/remoteControls.js.map +1 -1
  248. package/lib/commonjs/features/sleepTimer.js +13 -1
  249. package/lib/commonjs/features/sleepTimer.js.map +1 -1
  250. package/lib/commonjs/test-utils/reactNativeStub.js +65 -0
  251. package/lib/commonjs/test-utils/reactNativeStub.js.map +1 -0
  252. package/lib/commonjs/utils/LazyNativeEmitter.js +28 -14
  253. package/lib/commonjs/utils/LazyNativeEmitter.js.map +1 -1
  254. package/lib/commonjs/utils/NativeUpdatedValue.js +31 -13
  255. package/lib/commonjs/utils/NativeUpdatedValue.js.map +1 -1
  256. package/lib/commonjs/utils/getTrackIdentity.js +24 -0
  257. package/lib/commonjs/utils/getTrackIdentity.js.map +1 -0
  258. package/lib/commonjs/utils/useNativeValueRefreshedBy.js +33 -0
  259. package/lib/commonjs/utils/useNativeValueRefreshedBy.js.map +1 -0
  260. package/lib/commonjs/web/NativeAudioBrowser.js +201 -76
  261. package/lib/commonjs/web/NativeAudioBrowser.js.map +1 -1
  262. package/lib/commonjs/web/TrackPlayer/LoadAttempt.js +37 -0
  263. package/lib/commonjs/web/TrackPlayer/LoadAttempt.js.map +1 -0
  264. package/lib/commonjs/web/TrackPlayer/PlaybackStateMachine.js +18 -2
  265. package/lib/commonjs/web/TrackPlayer/PlaybackStateMachine.js.map +1 -1
  266. package/lib/commonjs/web/TrackPlayer/Player.js +254 -39
  267. package/lib/commonjs/web/TrackPlayer/Player.js.map +1 -1
  268. package/lib/commonjs/web/TrackPlayer/PlayingStateFactory.js +1 -1
  269. package/lib/commonjs/web/TrackPlayer/QueueManager.js +14 -0
  270. package/lib/commonjs/web/TrackPlayer/QueueManager.js.map +1 -1
  271. package/lib/commonjs/web/TrackPlayer/QueuePlayer.js +33 -12
  272. package/lib/commonjs/web/TrackPlayer/QueuePlayer.js.map +1 -1
  273. package/lib/commonjs/web/browser/BrowserManager.js +175 -100
  274. package/lib/commonjs/web/browser/BrowserManager.js.map +1 -1
  275. package/lib/commonjs/web/browser/FavoriteManager.js +30 -21
  276. package/lib/commonjs/web/browser/FavoriteManager.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 +18 -23
  280. package/lib/commonjs/web/browser/SearchManager.js.map +1 -1
  281. package/lib/commonjs/web/browser/assertBrowsePageShape.js +2 -2
  282. package/lib/commonjs/web/browser/assertBrowsePageShape.js.map +1 -1
  283. package/lib/commonjs/web/browser/classifyTrackNavigation.js +9 -9
  284. package/lib/commonjs/web/browser/classifyTrackNavigation.js.map +1 -1
  285. package/lib/commonjs/web/browser/sections.js +89 -0
  286. package/lib/commonjs/web/browser/sections.js.map +1 -0
  287. package/lib/commonjs/web/http/RequestConfigBuilder.js +110 -27
  288. package/lib/commonjs/web/http/RequestConfigBuilder.js.map +1 -1
  289. package/lib/commonjs/web/http/followMediaRedirect.js +219 -0
  290. package/lib/commonjs/web/http/followMediaRedirect.js.map +1 -0
  291. package/lib/commonjs/web/player/NowPlayingManager.js +4 -3
  292. package/lib/commonjs/web/player/NowPlayingManager.js.map +1 -1
  293. package/lib/commonjs/web/util/BrowserPathHelper.js +62 -11
  294. package/lib/commonjs/web/util/BrowserPathHelper.js.map +1 -1
  295. package/lib/module/AudioBrowser.js +2 -1
  296. package/lib/module/AudioBrowser.js.map +1 -1
  297. package/lib/module/CLAUDE.md +52 -0
  298. package/lib/module/features/browser-config.js +12 -8
  299. package/lib/module/features/browser-config.js.map +1 -1
  300. package/lib/module/features/browser.js +11 -3
  301. package/lib/module/features/browser.js.map +1 -1
  302. package/lib/module/features/carConnection.js +1 -1
  303. package/lib/module/features/equalizer.js +1 -1
  304. package/lib/module/features/errors.js +3 -3
  305. package/lib/module/features/favorites.js +14 -11
  306. package/lib/module/features/favorites.js.map +1 -1
  307. package/lib/module/features/gate.js +16 -1
  308. package/lib/module/features/gate.js.map +1 -1
  309. package/lib/module/features/metadata.js +20 -3
  310. package/lib/module/features/metadata.js.map +1 -1
  311. package/lib/module/features/network.js +1 -1
  312. package/lib/module/features/nowPlaying.js +1 -1
  313. package/lib/module/features/output.js +1 -1
  314. package/lib/module/features/playback/controls.js +4 -2
  315. package/lib/module/features/playback/controls.js.map +1 -1
  316. package/lib/module/features/playback/playWhenReady.js +1 -1
  317. package/lib/module/features/playback/playing.js +1 -1
  318. package/lib/module/features/playback/progress.js +3 -2
  319. package/lib/module/features/playback/progress.js.map +1 -1
  320. package/lib/module/features/playback/rate.js +8 -1
  321. package/lib/module/features/playback/rate.js.map +1 -1
  322. package/lib/module/features/playback/state.js +3 -4
  323. package/lib/module/features/playback/state.js.map +1 -1
  324. package/lib/module/features/playback/trackPlaybackTime.js +0 -5
  325. package/lib/module/features/playback/trackPlaybackTime.js.map +1 -1
  326. package/lib/module/features/playback/volume.js +1 -1
  327. package/lib/module/features/player/options.js +47 -32
  328. package/lib/module/features/player/options.js.map +1 -1
  329. package/lib/module/features/player/setup.js +17 -8
  330. package/lib/module/features/player/setup.js.map +1 -1
  331. package/lib/module/features/player/validateOptions.js +19 -0
  332. package/lib/module/features/player/validateOptions.js.map +1 -0
  333. package/lib/module/features/queue/activeTrack.js +15 -4
  334. package/lib/module/features/queue/activeTrack.js.map +1 -1
  335. package/lib/module/features/queue/queue.js +13 -6
  336. package/lib/module/features/queue/queue.js.map +1 -1
  337. package/lib/module/features/queue/repeatMode.js +1 -1
  338. package/lib/module/features/queue/shuffle.js +1 -1
  339. package/lib/module/features/remoteControls.js +13 -92
  340. package/lib/module/features/remoteControls.js.map +1 -1
  341. package/lib/module/features/sleepTimer.js +13 -1
  342. package/lib/module/features/sleepTimer.js.map +1 -1
  343. package/lib/module/test-utils/reactNativeStub.js +58 -0
  344. package/lib/module/test-utils/reactNativeStub.js.map +1 -0
  345. package/lib/module/utils/LazyNativeEmitter.js +28 -14
  346. package/lib/module/utils/LazyNativeEmitter.js.map +1 -1
  347. package/lib/module/utils/NativeUpdatedValue.js +31 -13
  348. package/lib/module/utils/NativeUpdatedValue.js.map +1 -1
  349. package/lib/module/utils/getTrackIdentity.js +20 -0
  350. package/lib/module/utils/getTrackIdentity.js.map +1 -0
  351. package/lib/module/utils/useNativeValueRefreshedBy.js +29 -0
  352. package/lib/module/utils/useNativeValueRefreshedBy.js.map +1 -0
  353. package/lib/module/web/NativeAudioBrowser.js +201 -76
  354. package/lib/module/web/NativeAudioBrowser.js.map +1 -1
  355. package/lib/module/web/TrackPlayer/LoadAttempt.js +32 -0
  356. package/lib/module/web/TrackPlayer/LoadAttempt.js.map +1 -0
  357. package/lib/module/web/TrackPlayer/PlaybackStateMachine.js +18 -2
  358. package/lib/module/web/TrackPlayer/PlaybackStateMachine.js.map +1 -1
  359. package/lib/module/web/TrackPlayer/Player.js +254 -39
  360. package/lib/module/web/TrackPlayer/Player.js.map +1 -1
  361. package/lib/module/web/TrackPlayer/PlayingStateFactory.js +1 -1
  362. package/lib/module/web/TrackPlayer/QueueManager.js +14 -0
  363. package/lib/module/web/TrackPlayer/QueueManager.js.map +1 -1
  364. package/lib/module/web/TrackPlayer/QueuePlayer.js +33 -12
  365. package/lib/module/web/TrackPlayer/QueuePlayer.js.map +1 -1
  366. package/lib/module/web/browser/BrowserManager.js +175 -100
  367. package/lib/module/web/browser/BrowserManager.js.map +1 -1
  368. package/lib/module/web/browser/FavoriteManager.js +31 -21
  369. package/lib/module/web/browser/FavoriteManager.js.map +1 -1
  370. package/lib/module/web/browser/NavigationErrorManager.js +3 -1
  371. package/lib/module/web/browser/NavigationErrorManager.js.map +1 -1
  372. package/lib/module/web/browser/SearchManager.js +18 -23
  373. package/lib/module/web/browser/SearchManager.js.map +1 -1
  374. package/lib/module/web/browser/assertBrowsePageShape.js +2 -2
  375. package/lib/module/web/browser/assertBrowsePageShape.js.map +1 -1
  376. package/lib/module/web/browser/classifyTrackNavigation.js +9 -9
  377. package/lib/module/web/browser/classifyTrackNavigation.js.map +1 -1
  378. package/lib/module/web/browser/sections.js +83 -0
  379. package/lib/module/web/browser/sections.js.map +1 -0
  380. package/lib/module/web/http/RequestConfigBuilder.js +110 -27
  381. package/lib/module/web/http/RequestConfigBuilder.js.map +1 -1
  382. package/lib/module/web/http/followMediaRedirect.js +215 -0
  383. package/lib/module/web/http/followMediaRedirect.js.map +1 -0
  384. package/lib/module/web/player/NowPlayingManager.js +4 -3
  385. package/lib/module/web/player/NowPlayingManager.js.map +1 -1
  386. package/lib/module/web/util/BrowserPathHelper.js +62 -11
  387. package/lib/module/web/util/BrowserPathHelper.js.map +1 -1
  388. package/lib/typescript/package.json +1 -0
  389. package/lib/typescript/src/AudioBrowser.d.ts +1 -1
  390. package/lib/typescript/src/AudioBrowser.d.ts.map +1 -1
  391. package/lib/typescript/src/features/browser-config.d.ts.map +1 -1
  392. package/lib/typescript/src/features/browser.d.ts +10 -2
  393. package/lib/typescript/src/features/browser.d.ts.map +1 -1
  394. package/lib/typescript/src/features/carConnection.d.ts +1 -1
  395. package/lib/typescript/src/features/equalizer.d.ts +1 -1
  396. package/lib/typescript/src/features/errors.d.ts +3 -3
  397. package/lib/typescript/src/features/favorites.d.ts +14 -11
  398. package/lib/typescript/src/features/favorites.d.ts.map +1 -1
  399. package/lib/typescript/src/features/gate.d.ts +18 -2
  400. package/lib/typescript/src/features/gate.d.ts.map +1 -1
  401. package/lib/typescript/src/features/metadata.d.ts +20 -3
  402. package/lib/typescript/src/features/metadata.d.ts.map +1 -1
  403. package/lib/typescript/src/features/network.d.ts +1 -1
  404. package/lib/typescript/src/features/nowPlaying.d.ts +1 -1
  405. package/lib/typescript/src/features/output.d.ts +1 -1
  406. package/lib/typescript/src/features/playback/controls.d.ts +4 -2
  407. package/lib/typescript/src/features/playback/controls.d.ts.map +1 -1
  408. package/lib/typescript/src/features/playback/playWhenReady.d.ts +1 -1
  409. package/lib/typescript/src/features/playback/playing.d.ts +1 -1
  410. package/lib/typescript/src/features/playback/progress.d.ts +1 -1
  411. package/lib/typescript/src/features/playback/progress.d.ts.map +1 -1
  412. package/lib/typescript/src/features/playback/rate.d.ts +8 -1
  413. package/lib/typescript/src/features/playback/rate.d.ts.map +1 -1
  414. package/lib/typescript/src/features/playback/state.d.ts +3 -4
  415. package/lib/typescript/src/features/playback/state.d.ts.map +1 -1
  416. package/lib/typescript/src/features/playback/trackPlaybackTime.d.ts +1 -1
  417. package/lib/typescript/src/features/playback/trackPlaybackTime.d.ts.map +1 -1
  418. package/lib/typescript/src/features/playback/volume.d.ts +1 -1
  419. package/lib/typescript/src/features/player/options.d.ts +108 -56
  420. package/lib/typescript/src/features/player/options.d.ts.map +1 -1
  421. package/lib/typescript/src/features/player/setup.d.ts +14 -4
  422. package/lib/typescript/src/features/player/setup.d.ts.map +1 -1
  423. package/lib/typescript/src/features/player/validateOptions.d.ts +2 -0
  424. package/lib/typescript/src/features/player/validateOptions.d.ts.map +1 -0
  425. package/lib/typescript/src/features/queue/activeTrack.d.ts +9 -2
  426. package/lib/typescript/src/features/queue/activeTrack.d.ts.map +1 -1
  427. package/lib/typescript/src/features/queue/queue.d.ts +7 -4
  428. package/lib/typescript/src/features/queue/queue.d.ts.map +1 -1
  429. package/lib/typescript/src/features/queue/repeatMode.d.ts +1 -1
  430. package/lib/typescript/src/features/queue/shuffle.d.ts +1 -1
  431. package/lib/typescript/src/features/remoteControls.d.ts +23 -22
  432. package/lib/typescript/src/features/remoteControls.d.ts.map +1 -1
  433. package/lib/typescript/src/features/sleepTimer.d.ts +1 -1
  434. package/lib/typescript/src/features/sleepTimer.d.ts.map +1 -1
  435. package/lib/typescript/src/test-utils/reactNativeStub.d.ts +36 -0
  436. package/lib/typescript/src/test-utils/reactNativeStub.d.ts.map +1 -0
  437. package/lib/typescript/src/types/browser-native.d.ts +3 -2
  438. package/lib/typescript/src/types/browser-native.d.ts.map +1 -1
  439. package/lib/typescript/src/types/browser-nodes.d.ts +387 -126
  440. package/lib/typescript/src/types/browser-nodes.d.ts.map +1 -1
  441. package/lib/typescript/src/types/browser.d.ts +93 -61
  442. package/lib/typescript/src/types/browser.d.ts.map +1 -1
  443. package/lib/typescript/src/utils/LazyNativeEmitter.d.ts +19 -16
  444. package/lib/typescript/src/utils/LazyNativeEmitter.d.ts.map +1 -1
  445. package/lib/typescript/src/utils/NativeUpdatedValue.d.ts +24 -19
  446. package/lib/typescript/src/utils/NativeUpdatedValue.d.ts.map +1 -1
  447. package/lib/typescript/src/utils/getTrackIdentity.d.ts +18 -0
  448. package/lib/typescript/src/utils/getTrackIdentity.d.ts.map +1 -0
  449. package/lib/typescript/src/utils/resolveAssetSource.d.ts +1 -2
  450. package/lib/typescript/src/utils/resolveAssetSource.d.ts.map +1 -1
  451. package/lib/typescript/src/utils/useNativeValueRefreshedBy.d.ts +21 -0
  452. package/lib/typescript/src/utils/useNativeValueRefreshedBy.d.ts.map +1 -0
  453. package/nitrogen/generated/android/AudioBrowser+autolinking.cmake +1 -2
  454. package/nitrogen/generated/android/AudioBrowserOnLoad.cpp +4 -2
  455. package/nitrogen/generated/android/c++/JAndroidAudioContentType.hpp +2 -2
  456. package/nitrogen/generated/android/c++/JAndroidAudioOffloadSettings.hpp +2 -2
  457. package/nitrogen/generated/android/c++/JAndroidOptions.hpp +12 -12
  458. package/nitrogen/generated/android/c++/JAndroidPlayerWakeMode.hpp +2 -2
  459. package/nitrogen/generated/android/c++/JAppKilledPlaybackBehavior.hpp +2 -2
  460. package/nitrogen/generated/android/c++/JArtworkRendering.hpp +58 -0
  461. package/nitrogen/generated/android/c++/JArtworkRequestConfig.hpp +10 -5
  462. package/nitrogen/generated/android/c++/JArtworkVariants.hpp +2 -2
  463. package/nitrogen/generated/android/c++/JBatteryOptimizationStatus.hpp +2 -2
  464. package/nitrogen/generated/android/c++/JBatteryOptimizationStatusChangedEvent.hpp +2 -2
  465. package/nitrogen/generated/android/c++/JBatteryWarningPendingChangedEvent.hpp +2 -2
  466. package/nitrogen/generated/android/c++/JBrowseError.hpp +2 -2
  467. package/nitrogen/generated/android/c++/JBrowseResult.hpp +19 -7
  468. package/nitrogen/generated/android/c++/JBrowserSourceCallbackParam.hpp +2 -2
  469. package/nitrogen/generated/android/c++/JCarPlayNowPlayingButton.hpp +2 -2
  470. package/nitrogen/generated/android/c++/JCarPlayPlayingIndicatorLocation.hpp +58 -0
  471. package/nitrogen/generated/android/c++/JCarPlaySiriListButtonPosition.hpp +2 -2
  472. package/nitrogen/generated/android/c++/JCardImage.hpp +58 -0
  473. package/nitrogen/generated/android/c++/JChapterMetadata.hpp +2 -2
  474. package/nitrogen/generated/android/c++/JEqualizerSettings.hpp +10 -10
  475. package/nitrogen/generated/android/c++/JFavoriteChangedEvent.hpp +10 -5
  476. package/nitrogen/generated/android/c++/JFormatNavigationErrorParams.hpp +11 -5
  477. package/nitrogen/generated/android/c++/JFormatNowPlayingParams.hpp +10 -5
  478. package/nitrogen/generated/android/c++/JFormattedNavigationError.hpp +2 -2
  479. package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_RequestConfig___MediaTransformParams.hpp +2 -2
  480. package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_RequestConfig___RequestConfig_std__optional_std__unordered_map_std__string__std__string__.hpp +9 -9
  481. package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_RequestConfig___Track.hpp +10 -5
  482. package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__optional_FormattedNavigationError____FormatNavigationErrorParams.hpp +4 -2
  483. package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__optional_NowPlayingUpdate____FormatNowPlayingParams.hpp +10 -5
  484. package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__optional_std__string____Track.hpp +10 -5
  485. package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__shared_ptr_Promise_GateDecision_____NativeGateRequest.hpp +2 -2
  486. package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__shared_ptr_Promise_RequestConfig_____MediaTransformParams.hpp +2 -2
  487. package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__shared_ptr_Promise_RequestConfig_____RequestConfig_std__optional_std__unordered_map_std__string__std__string__.hpp +9 -9
  488. package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__shared_ptr_Promise_RequestConfig_____Track.hpp +10 -5
  489. package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__shared_ptr_Promise_TransformableRequestConfig____.hpp +2 -2
  490. package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__shared_ptr_Promise_std__vector_Track______SearchParams.hpp +18 -12
  491. package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__shared_ptr_Promise_void_____TrackLoadEvent.hpp +10 -4
  492. package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__string__.hpp +102 -0
  493. package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__variant_ResolvedTrack__BrowseError__std__shared_ptr_Promise_std__variant_ResolvedTrack__BrowseError_______BrowserSourceCallbackParam.hpp +18 -6
  494. package/nitrogen/generated/android/c++/JFunc_void.hpp +2 -2
  495. package/nitrogen/generated/android/c++/JFunc_void_BatteryOptimizationStatusChangedEvent.hpp +2 -2
  496. package/nitrogen/generated/android/c++/JFunc_void_BatteryWarningPendingChangedEvent.hpp +2 -2
  497. package/nitrogen/generated/android/c++/JFunc_void_EqualizerSettings.hpp +2 -2
  498. package/nitrogen/generated/android/c++/JFunc_void_FavoriteChangedEvent.hpp +10 -5
  499. package/nitrogen/generated/android/c++/JFunc_void_GateEvent.hpp +2 -2
  500. package/nitrogen/generated/android/c++/JFunc_void_NavigationErrorEvent.hpp +2 -2
  501. package/nitrogen/generated/android/c++/JFunc_void_NowPlayingMetadata.hpp +2 -2
  502. package/nitrogen/generated/android/c++/JFunc_void_Options.hpp +9 -12
  503. package/nitrogen/generated/android/c++/JFunc_void_Output.hpp +2 -2
  504. package/nitrogen/generated/android/c++/JFunc_void_Playback.hpp +2 -2
  505. package/nitrogen/generated/android/c++/JFunc_void_PlaybackActiveTrackChangedEvent.hpp +10 -5
  506. package/nitrogen/generated/android/c++/JFunc_void_PlaybackErrorEvent.hpp +2 -2
  507. package/nitrogen/generated/android/c++/JFunc_void_PlaybackPlayWhenReadyChangedEvent.hpp +2 -2
  508. package/nitrogen/generated/android/c++/JFunc_void_PlaybackProgressUpdatedEvent.hpp +2 -2
  509. package/nitrogen/generated/android/c++/JFunc_void_PlaybackQueueEndedEvent.hpp +2 -2
  510. package/nitrogen/generated/android/c++/JFunc_void_PlayingState.hpp +2 -2
  511. package/nitrogen/generated/android/c++/JFunc_void_RemoteJumpBackwardEvent.hpp +2 -2
  512. package/nitrogen/generated/android/c++/JFunc_void_RemoteJumpForwardEvent.hpp +2 -2
  513. package/nitrogen/generated/android/c++/JFunc_void_RemotePlayIdEvent.hpp +2 -2
  514. package/nitrogen/generated/android/c++/JFunc_void_RemotePlaySearchEvent.hpp +2 -2
  515. package/nitrogen/generated/android/c++/JFunc_void_RemoteSeekEvent.hpp +2 -2
  516. package/nitrogen/generated/android/c++/JFunc_void_RemoteSkipEvent.hpp +2 -2
  517. package/nitrogen/generated/android/c++/JFunc_void_RepeatModeChangedEvent.hpp +2 -2
  518. package/nitrogen/generated/android/c++/JFunc_void_TimedMetadata.hpp +2 -2
  519. package/nitrogen/generated/android/c++/JFunc_void_TrackMetadata.hpp +2 -2
  520. package/nitrogen/generated/android/c++/JFunc_void_bool.hpp +2 -2
  521. package/nitrogen/generated/android/c++/JFunc_void_double.hpp +2 -2
  522. package/nitrogen/generated/android/c++/JFunc_void_std__optional_FormattedNavigationError_.hpp +2 -2
  523. package/nitrogen/generated/android/c++/JFunc_void_std__optional_ResolvedTrack_.hpp +17 -5
  524. package/nitrogen/generated/android/c++/JFunc_void_std__optional_std__variant_nitro__NullType__SleepTimerTime__SleepTimerEndOfTrack__.hpp +2 -2
  525. package/nitrogen/generated/android/c++/JFunc_void_std__string.hpp +2 -2
  526. package/nitrogen/generated/android/c++/JFunc_void_std__vector_ChapterMetadata_.hpp +16 -16
  527. package/nitrogen/generated/android/c++/JFunc_void_std__vector_Track_.hpp +24 -18
  528. package/nitrogen/generated/android/c++/JGate.hpp +2 -2
  529. package/nitrogen/generated/android/c++/JGateDecision.hpp +2 -2
  530. package/nitrogen/generated/android/c++/JGateEvent.hpp +2 -2
  531. package/nitrogen/generated/android/c++/JGateReason.hpp +2 -2
  532. package/nitrogen/generated/android/c++/JGridTile.hpp +64 -0
  533. package/nitrogen/generated/android/c++/JHttpMethod.hpp +2 -2
  534. package/nitrogen/generated/android/c++/JHybridAudioBrowserSpec.cpp +77 -53
  535. package/nitrogen/generated/android/c++/JHybridAudioBrowserSpec.hpp +3 -3
  536. package/nitrogen/generated/android/c++/JIOSCategory.hpp +2 -2
  537. package/nitrogen/generated/android/c++/JIOSCategoryMode.hpp +2 -2
  538. package/nitrogen/generated/android/c++/JIOSCategoryOptions.hpp +2 -2
  539. package/nitrogen/generated/android/c++/JIOSCategoryPolicy.hpp +2 -2
  540. package/nitrogen/generated/android/c++/JIOSOptions.hpp +17 -11
  541. package/nitrogen/generated/android/c++/JImageContext.hpp +2 -2
  542. package/nitrogen/generated/android/c++/JImageQueryParams.hpp +2 -2
  543. package/nitrogen/generated/android/c++/JImageShape.hpp +58 -0
  544. package/nitrogen/generated/android/c++/JImageSource.hpp +2 -2
  545. package/nitrogen/generated/android/c++/JMediaReference.hpp +2 -2
  546. package/nitrogen/generated/android/c++/JMediaRequestConfig.hpp +10 -5
  547. package/nitrogen/generated/android/c++/JMediaTransformParams.hpp +2 -2
  548. package/nitrogen/generated/android/c++/JNativeAndroidSetupOptions.hpp +2 -2
  549. package/nitrogen/generated/android/c++/JNativeBrowserConfiguration.hpp +48 -21
  550. package/nitrogen/generated/android/c++/JNativeGateRequest.hpp +2 -2
  551. package/nitrogen/generated/android/c++/JNativeIOSSetupOptions.hpp +10 -10
  552. package/nitrogen/generated/android/c++/JNativeRouteEntry.hpp +16 -4
  553. package/nitrogen/generated/android/c++/JNativeSetupPlayerOptions.hpp +17 -14
  554. package/nitrogen/generated/android/c++/JNativeUpdateOptions.hpp +9 -12
  555. package/nitrogen/generated/android/c++/JNavigationError.hpp +2 -2
  556. package/nitrogen/generated/android/c++/JNavigationErrorEvent.hpp +2 -2
  557. package/nitrogen/generated/android/c++/JNavigationErrorKind.hpp +58 -0
  558. package/nitrogen/generated/android/c++/JNavigationErrorType.hpp +2 -2
  559. package/nitrogen/generated/android/c++/JNitroAndroidUpdateOptions.hpp +12 -12
  560. package/nitrogen/generated/android/c++/JNitroIOSUpdateOptions.hpp +17 -11
  561. package/nitrogen/generated/android/c++/JNowPlayingMetadata.hpp +2 -2
  562. package/nitrogen/generated/android/c++/JNowPlayingUpdate.hpp +2 -2
  563. package/nitrogen/generated/android/c++/JOptions.hpp +9 -12
  564. package/nitrogen/generated/android/c++/JOutput.hpp +2 -2
  565. package/nitrogen/generated/android/c++/JOutputType.hpp +2 -2
  566. package/nitrogen/generated/android/c++/JPlayback.hpp +2 -2
  567. package/nitrogen/generated/android/c++/JPlaybackActiveTrackChangedEvent.hpp +10 -5
  568. package/nitrogen/generated/android/c++/JPlaybackError.hpp +2 -2
  569. package/nitrogen/generated/android/c++/JPlaybackErrorEvent.hpp +2 -2
  570. package/nitrogen/generated/android/c++/JPlaybackErrorKind.hpp +2 -2
  571. package/nitrogen/generated/android/c++/JPlaybackPlayWhenReadyChangedEvent.hpp +2 -2
  572. package/nitrogen/generated/android/c++/JPlaybackProgressUpdatedEvent.hpp +2 -2
  573. package/nitrogen/generated/android/c++/JPlaybackQueueEndedEvent.hpp +2 -2
  574. package/nitrogen/generated/android/c++/JPlaybackState.hpp +2 -2
  575. package/nitrogen/generated/android/c++/JPlayerCapabilities.hpp +7 -13
  576. package/nitrogen/generated/android/c++/JPlayingState.hpp +2 -2
  577. package/nitrogen/generated/android/c++/JProgress.hpp +2 -2
  578. package/nitrogen/generated/android/c++/{JNotificationButton.hpp → JRemoteButton.hpp} +19 -19
  579. package/nitrogen/generated/android/c++/JRemoteButtonLayout.hpp +86 -0
  580. package/nitrogen/generated/android/c++/JRemoteJumpBackwardEvent.hpp +2 -2
  581. package/nitrogen/generated/android/c++/JRemoteJumpForwardEvent.hpp +2 -2
  582. package/nitrogen/generated/android/c++/JRemotePlayIdEvent.hpp +2 -2
  583. package/nitrogen/generated/android/c++/JRemotePlaySearchEvent.hpp +2 -2
  584. package/nitrogen/generated/android/c++/JRemoteSeekEvent.hpp +2 -2
  585. package/nitrogen/generated/android/c++/JRemoteSkipEvent.hpp +2 -2
  586. package/nitrogen/generated/android/c++/JRepeatMode.hpp +2 -2
  587. package/nitrogen/generated/android/c++/JRepeatModeChangedEvent.hpp +2 -2
  588. package/nitrogen/generated/android/c++/JRequestConfig.hpp +2 -2
  589. package/nitrogen/generated/android/c++/JResolvedTrack.hpp +67 -59
  590. package/nitrogen/generated/android/c++/JRetryConfig.hpp +2 -2
  591. package/nitrogen/generated/android/c++/JSearchMode.hpp +2 -2
  592. package/nitrogen/generated/android/c++/JSearchParams.hpp +2 -2
  593. package/nitrogen/generated/android/c++/JSection.hpp +116 -0
  594. package/nitrogen/generated/android/c++/JSectionStyle.hpp +96 -0
  595. package/nitrogen/generated/android/c++/JSleepTimer.hpp +4 -4
  596. package/nitrogen/generated/android/c++/JSleepTimerEndOfTrack.hpp +2 -2
  597. package/nitrogen/generated/android/c++/JSleepTimerTime.hpp +2 -2
  598. package/nitrogen/generated/android/c++/JStallReason.hpp +2 -2
  599. package/nitrogen/generated/android/c++/JStyleDisplay.hpp +58 -0
  600. package/nitrogen/generated/android/c++/JTimedMetadata.hpp +2 -2
  601. package/nitrogen/generated/android/c++/JTrack.hpp +27 -48
  602. package/nitrogen/generated/android/c++/JTrackLoadEvent.hpp +18 -12
  603. package/nitrogen/generated/android/c++/JTrackMetadata.hpp +2 -2
  604. package/nitrogen/generated/android/c++/JTrackRequest.hpp +2 -2
  605. package/nitrogen/generated/android/c++/JTrackStyle.hpp +47 -19
  606. package/nitrogen/generated/android/c++/JTransformableRequestConfig.hpp +2 -2
  607. package/nitrogen/generated/android/c++/JVariant_Boolean_AndroidAudioOffloadSettings.hpp +3 -3
  608. package/nitrogen/generated/android/c++/JVariant_Boolean_RetryConfig.hpp +3 -3
  609. package/nitrogen/generated/android/c++/JVariant_NullType_Double.hpp +3 -3
  610. package/nitrogen/generated/android/c++/JVariant_NullType_RemoteButtonLayout.cpp +26 -0
  611. package/nitrogen/generated/android/c++/JVariant_NullType_RemoteButtonLayout.hpp +75 -0
  612. package/nitrogen/generated/android/c++/JVariant_ResolvedTrack_BrowseError_Promise_BrowseResult_.hpp +20 -8
  613. package/nitrogen/generated/android/c++/JVariant_String_ArtworkVariants.hpp +3 -3
  614. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/AndroidAudioOffloadSettings.kt +15 -0
  615. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/AndroidOptions.kt +20 -3
  616. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/{FavoritesMatchMode.kt → ArtworkRendering.kt} +5 -5
  617. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/ArtworkRequestConfig.kt +37 -0
  618. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/ArtworkVariants.kt +15 -0
  619. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/BatteryOptimizationStatusChangedEvent.kt +13 -0
  620. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/BatteryWarningPendingChangedEvent.kt +13 -0
  621. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/BrowseError.kt +13 -0
  622. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/BrowseResult.kt +16 -7
  623. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/BrowserSourceCallbackParam.kt +15 -0
  624. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/CarPlayPlayingIndicatorLocation.kt +23 -0
  625. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/CardImage.kt +23 -0
  626. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/ChapterMetadata.kt +19 -0
  627. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/EqualizerSettings.kt +27 -0
  628. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/FavoriteChangedEvent.kt +15 -0
  629. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/FormatNavigationErrorParams.kt +25 -3
  630. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/FormatNowPlayingParams.kt +21 -0
  631. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/FormattedNavigationError.kt +15 -0
  632. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_std__shared_ptr_Promise_RequestConfig___MediaTransformParams.kt +0 -2
  633. 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 +0 -2
  634. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_std__shared_ptr_Promise_RequestConfig___Track.kt +0 -2
  635. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_std__shared_ptr_Promise_std__optional_FormattedNavigationError____FormatNavigationErrorParams.kt +0 -2
  636. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_std__shared_ptr_Promise_std__optional_NowPlayingUpdate____FormatNowPlayingParams.kt +0 -2
  637. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_std__shared_ptr_Promise_std__optional_std__string____Track.kt +0 -2
  638. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_std__shared_ptr_Promise_std__shared_ptr_Promise_GateDecision_____NativeGateRequest.kt +0 -2
  639. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_std__shared_ptr_Promise_std__shared_ptr_Promise_RequestConfig_____MediaTransformParams.kt +0 -2
  640. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_std__shared_ptr_Promise_std__shared_ptr_Promise_RequestConfig_____RequestConfig_std__optional_std__unordered_map_std__string__std__string__.kt +0 -2
  641. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_std__shared_ptr_Promise_std__shared_ptr_Promise_RequestConfig_____Track.kt +0 -2
  642. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_std__shared_ptr_Promise_std__shared_ptr_Promise_TransformableRequestConfig____.kt +0 -2
  643. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_std__shared_ptr_Promise_std__shared_ptr_Promise_std__vector_Track______SearchParams.kt +0 -2
  644. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_std__shared_ptr_Promise_std__shared_ptr_Promise_void_____TrackLoadEvent.kt +0 -2
  645. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_std__shared_ptr_Promise_std__string__.kt +78 -0
  646. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_std__shared_ptr_Promise_std__variant_ResolvedTrack__BrowseError__std__shared_ptr_Promise_std__variant_ResolvedTrack__BrowseError_______BrowserSourceCallbackParam.kt +0 -2
  647. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void.kt +0 -2
  648. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_BatteryOptimizationStatusChangedEvent.kt +0 -2
  649. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_BatteryWarningPendingChangedEvent.kt +0 -2
  650. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_EqualizerSettings.kt +0 -2
  651. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_FavoriteChangedEvent.kt +0 -2
  652. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_GateEvent.kt +0 -2
  653. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_NavigationErrorEvent.kt +0 -2
  654. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_NowPlayingMetadata.kt +0 -2
  655. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_Options.kt +0 -2
  656. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_Output.kt +0 -2
  657. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_Playback.kt +0 -2
  658. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_PlaybackActiveTrackChangedEvent.kt +0 -2
  659. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_PlaybackErrorEvent.kt +0 -2
  660. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_PlaybackPlayWhenReadyChangedEvent.kt +0 -2
  661. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_PlaybackProgressUpdatedEvent.kt +0 -2
  662. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_PlaybackQueueEndedEvent.kt +0 -2
  663. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_PlayingState.kt +0 -2
  664. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_RemoteJumpBackwardEvent.kt +0 -2
  665. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_RemoteJumpForwardEvent.kt +0 -2
  666. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_RemotePlayIdEvent.kt +0 -2
  667. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_RemotePlaySearchEvent.kt +0 -2
  668. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_RemoteSeekEvent.kt +0 -2
  669. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_RemoteSkipEvent.kt +0 -2
  670. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_RepeatModeChangedEvent.kt +0 -2
  671. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_TimedMetadata.kt +0 -2
  672. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_TrackMetadata.kt +0 -2
  673. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_bool.kt +0 -2
  674. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_double.kt +0 -2
  675. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_std__optional_FormattedNavigationError_.kt +0 -2
  676. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_std__optional_ResolvedTrack_.kt +0 -2
  677. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_std__optional_std__variant_nitro__NullType__SleepTimerTime__SleepTimerEndOfTrack__.kt +0 -2
  678. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_std__string.kt +0 -2
  679. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_std__vector_ChapterMetadata_.kt +0 -2
  680. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_std__vector_Track_.kt +0 -2
  681. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Gate.kt +15 -0
  682. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/GateDecision.kt +15 -0
  683. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/GateEvent.kt +13 -0
  684. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/GridTile.kt +25 -0
  685. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/HybridAudioBrowserSpec.kt +3 -1
  686. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/IOSOptions.kt +25 -3
  687. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/ImageContext.kt +15 -0
  688. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/ImageQueryParams.kt +15 -0
  689. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/ImageShape.kt +23 -0
  690. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/ImageSource.kt +19 -0
  691. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/MediaRequestConfig.kt +35 -0
  692. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/MediaTransformParams.kt +15 -0
  693. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NativeAndroidSetupOptions.kt +31 -0
  694. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NativeBrowserConfiguration.kt +51 -5
  695. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NativeGateRequest.kt +17 -0
  696. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NativeIOSSetupOptions.kt +21 -0
  697. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NativeRouteEntry.kt +27 -0
  698. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NativeSetupPlayerOptions.kt +29 -0
  699. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NativeUpdateOptions.kt +23 -0
  700. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NavigationError.kt +19 -0
  701. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NavigationErrorEvent.kt +13 -0
  702. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NavigationErrorKind.kt +23 -0
  703. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NitroAndroidUpdateOptions.kt +20 -3
  704. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NitroIOSUpdateOptions.kt +25 -3
  705. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NowPlayingMetadata.kt +29 -0
  706. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NowPlayingUpdate.kt +17 -0
  707. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Options.kt +23 -0
  708. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Output.kt +17 -0
  709. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Playback.kt +15 -0
  710. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/PlaybackActiveTrackChangedEvent.kt +21 -0
  711. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/PlaybackError.kt +21 -0
  712. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/PlaybackErrorEvent.kt +13 -0
  713. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/PlaybackPlayWhenReadyChangedEvent.kt +13 -0
  714. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/PlaybackProgressUpdatedEvent.kt +19 -0
  715. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/PlaybackQueueEndedEvent.kt +15 -0
  716. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/PlayerCapabilities.kt +37 -2
  717. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/PlayingState.kt +15 -0
  718. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Progress.kt +17 -0
  719. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/{NotificationButton.kt → RemoteButton.kt} +3 -3
  720. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/RemoteButtonLayout.kt +61 -0
  721. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/RemoteJumpBackwardEvent.kt +13 -0
  722. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/RemoteJumpForwardEvent.kt +13 -0
  723. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/RemotePlayIdEvent.kt +15 -0
  724. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/RemotePlaySearchEvent.kt +13 -0
  725. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/RemoteSeekEvent.kt +13 -0
  726. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/RemoteSkipEvent.kt +13 -0
  727. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/RepeatModeChangedEvent.kt +13 -0
  728. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/RequestConfig.kt +27 -0
  729. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/ResolvedTrack.kt +67 -15
  730. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/RetryConfig.kt +17 -0
  731. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/SearchParams.kt +27 -0
  732. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Section.kt +66 -0
  733. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/SectionStyle.kt +86 -0
  734. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/SleepTimer.kt +18 -8
  735. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/SleepTimerEndOfTrack.kt +13 -0
  736. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/SleepTimerTime.kt +13 -0
  737. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/StyleDisplay.kt +23 -0
  738. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/TimedMetadata.kt +21 -0
  739. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Track.kt +55 -12
  740. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/TrackLoadEvent.kt +17 -0
  741. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/TrackMetadata.kt +43 -0
  742. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/TrackRequest.kt +17 -0
  743. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/TrackStyle.kt +58 -5
  744. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/TransformableRequestConfig.kt +31 -0
  745. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Variant_Boolean_AndroidAudioOffloadSettings.kt +16 -7
  746. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Variant_Boolean_RetryConfig.kt +16 -7
  747. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Variant_NullType_Double.kt +16 -7
  748. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/{Variant_NullType_NotificationButtonLayout.kt → Variant_NullType_RemoteButtonLayout.kt} +24 -15
  749. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Variant_ResolvedTrack_BrowseError_Promise_BrowseResult_.kt +18 -8
  750. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Variant_String_ArtworkVariants.kt +16 -7
  751. package/nitrogen/generated/ios/AudioBrowser+autolinking.rb +2 -0
  752. package/nitrogen/generated/ios/AudioBrowser-Swift-Cxx-Bridge.cpp +38 -29
  753. package/nitrogen/generated/ios/AudioBrowser-Swift-Cxx-Bridge.hpp +779 -665
  754. package/nitrogen/generated/ios/AudioBrowser-Swift-Cxx-Umbrella.hpp +34 -16
  755. package/nitrogen/generated/ios/c++/HybridAudioBrowserSpecSwift.hpp +36 -18
  756. package/nitrogen/generated/ios/swift/AndroidOptions.swift +12 -12
  757. package/nitrogen/generated/ios/swift/ArtworkRendering.swift +40 -0
  758. package/nitrogen/generated/ios/swift/BrowseResult.swift +12 -0
  759. package/nitrogen/generated/ios/swift/CarPlayPlayingIndicatorLocation.swift +40 -0
  760. package/nitrogen/generated/ios/swift/CardImage.swift +40 -0
  761. package/nitrogen/generated/ios/swift/FormatNavigationErrorParams.swift +7 -2
  762. package/nitrogen/generated/ios/swift/Func_std__shared_ptr_Promise_std__string__.swift +54 -0
  763. package/nitrogen/generated/ios/swift/GridTile.swift +48 -0
  764. package/nitrogen/generated/ios/swift/HybridAudioBrowserSpec.swift +1 -1
  765. package/nitrogen/generated/ios/swift/HybridAudioBrowserSpec_cxx.swift +2 -2
  766. package/nitrogen/generated/ios/swift/IOSOptions.swift +7 -2
  767. package/nitrogen/generated/ios/swift/ImageShape.swift +40 -0
  768. package/nitrogen/generated/ios/swift/NativeBrowserConfiguration.swift +52 -5
  769. package/nitrogen/generated/ios/swift/NavigationErrorKind.swift +40 -0
  770. package/nitrogen/generated/ios/swift/NitroAndroidUpdateOptions.swift +12 -12
  771. package/nitrogen/generated/ios/swift/NitroIOSUpdateOptions.swift +12 -1
  772. package/nitrogen/generated/ios/swift/PlayerCapabilities.swift +8 -27
  773. package/nitrogen/generated/ios/swift/{NotificationButton.swift → RemoteButton.swift} +6 -6
  774. package/nitrogen/generated/ios/swift/RemoteButtonLayout.swift +57 -0
  775. package/nitrogen/generated/ios/swift/ResolvedTrack.swift +62 -73
  776. package/nitrogen/generated/ios/swift/Section.swift +82 -0
  777. package/nitrogen/generated/ios/swift/SectionStyle.swift +133 -0
  778. package/nitrogen/generated/ios/swift/SleepTimer.swift +13 -0
  779. package/nitrogen/generated/ios/swift/StyleDisplay.swift +40 -0
  780. package/nitrogen/generated/ios/swift/Track.swift +28 -63
  781. package/nitrogen/generated/ios/swift/TrackStyle.swift +86 -22
  782. package/nitrogen/generated/ios/swift/Variant_Bool_AndroidAudioOffloadSettings.swift +12 -0
  783. package/nitrogen/generated/ios/swift/Variant_Bool_RetryConfig.swift +12 -0
  784. package/nitrogen/generated/ios/swift/Variant_NullType_Double.swift +12 -0
  785. package/nitrogen/generated/ios/swift/Variant_NullType_RemoteButtonLayout.swift +30 -0
  786. package/nitrogen/generated/ios/swift/Variant_ResolvedTrack_BrowseError_Promise_BrowseResult_.swift +13 -0
  787. package/nitrogen/generated/ios/swift/Variant_String_ArtworkVariants.swift +12 -0
  788. package/nitrogen/generated/shared/c++/AndroidOptions.hpp +8 -8
  789. package/nitrogen/generated/shared/c++/{FavoritesMatchMode.hpp → ArtworkRendering.hpp} +17 -17
  790. package/nitrogen/generated/shared/c++/CarPlayPlayingIndicatorLocation.hpp +76 -0
  791. package/nitrogen/generated/shared/c++/CardImage.hpp +76 -0
  792. package/nitrogen/generated/shared/c++/FormatNavigationErrorParams.hpp +9 -2
  793. package/nitrogen/generated/shared/c++/GridTile.hpp +84 -0
  794. package/nitrogen/generated/shared/c++/HybridAudioBrowserSpec.cpp +1 -1
  795. package/nitrogen/generated/shared/c++/HybridAudioBrowserSpec.hpp +1 -1
  796. package/nitrogen/generated/shared/c++/IOSOptions.hpp +9 -2
  797. package/nitrogen/generated/shared/c++/ImageShape.hpp +76 -0
  798. package/nitrogen/generated/shared/c++/NativeBrowserConfiguration.hpp +10 -6
  799. package/nitrogen/generated/shared/c++/NavigationErrorKind.hpp +76 -0
  800. package/nitrogen/generated/shared/c++/NitroAndroidUpdateOptions.hpp +8 -8
  801. package/nitrogen/generated/shared/c++/NitroIOSUpdateOptions.hpp +9 -2
  802. package/nitrogen/generated/shared/c++/PlayerCapabilities.hpp +6 -9
  803. package/nitrogen/generated/shared/c++/{NotificationButton.hpp → RemoteButton.hpp} +19 -19
  804. package/nitrogen/generated/shared/c++/RemoteButtonLayout.hpp +94 -0
  805. package/nitrogen/generated/shared/c++/ResolvedTrack.hpp +33 -37
  806. package/nitrogen/generated/shared/c++/Section.hpp +102 -0
  807. package/nitrogen/generated/shared/c++/SectionStyle.hpp +126 -0
  808. package/nitrogen/generated/shared/c++/StyleDisplay.hpp +76 -0
  809. package/nitrogen/generated/shared/c++/Track.hpp +18 -30
  810. package/nitrogen/generated/shared/c++/TrackStyle.hpp +73 -34
  811. package/package.json +24 -11
  812. package/src/AudioBrowser.ts +2 -1
  813. package/src/CLAUDE.md +52 -0
  814. package/src/features/battery.test.ts +79 -0
  815. package/src/features/browser-config.test.ts +21 -6
  816. package/src/features/browser-config.ts +12 -8
  817. package/src/features/browser.test.ts +1 -1
  818. package/src/features/browser.ts +11 -3
  819. package/src/features/carConnection.ts +1 -1
  820. package/src/features/equalizer.ts +1 -1
  821. package/src/features/errors.ts +3 -3
  822. package/src/features/favorites.ts +14 -11
  823. package/src/features/gate.ts +16 -1
  824. package/src/features/hook-wiring.test.ts +302 -0
  825. package/src/features/metadata.ts +20 -3
  826. package/src/features/network.ts +1 -1
  827. package/src/features/nowPlaying.ts +1 -1
  828. package/src/features/output.ts +1 -1
  829. package/src/features/playback/controls.ts +4 -2
  830. package/src/features/playback/playWhenReady.ts +1 -1
  831. package/src/features/playback/playing.ts +1 -1
  832. package/src/features/playback/progress.test.ts +169 -0
  833. package/src/features/playback/progress.ts +3 -2
  834. package/src/features/playback/rate.ts +8 -1
  835. package/src/features/playback/state.ts +3 -4
  836. package/src/features/playback/trackPlaybackTime.test.ts +16 -6
  837. package/src/features/playback/trackPlaybackTime.ts +1 -6
  838. package/src/features/playback/volume.ts +1 -1
  839. package/src/features/player/options.ts +126 -76
  840. package/src/features/player/setup.test.ts +24 -7
  841. package/src/features/player/setup.ts +22 -10
  842. package/src/features/player/validateOptions.ts +21 -0
  843. package/src/features/queue/activeTrack.ts +15 -4
  844. package/src/features/queue/queue.ts +13 -6
  845. package/src/features/queue/repeatMode.ts +1 -1
  846. package/src/features/queue/shuffle.ts +1 -1
  847. package/src/features/remoteControls.ts +13 -92
  848. package/src/features/sleepTimer.test.ts +172 -0
  849. package/src/features/sleepTimer.ts +9 -1
  850. package/src/nitro-stub-drift.test.ts +277 -0
  851. package/src/public-surface.test.ts +147 -0
  852. package/src/specs/audio-browser.nitro.ts +5 -4
  853. package/src/style-resolution.test.ts +210 -0
  854. package/src/test-utils/reactNativeStub.ts +60 -0
  855. package/src/types/browser-native.ts +7 -3
  856. package/src/types/browser-nodes.ts +403 -134
  857. package/src/types/browser.ts +97 -63
  858. package/src/utils/LazyNativeEmitter.ts +28 -15
  859. package/src/utils/NativeUpdatedValue.ts +29 -13
  860. package/src/utils/getTrackIdentity.ts +20 -0
  861. package/src/utils/useDebug.test.ts +182 -0
  862. package/src/utils/useNativeUpdatedValue.test.ts +103 -0
  863. package/src/utils/useNativeValueRefreshedBy.ts +38 -0
  864. package/src/web/NativeAudioBrowser.playWhenReady.test.ts +232 -2
  865. package/src/web/NativeAudioBrowser.ts +240 -83
  866. package/src/web/TrackPlayer/LoadAttempt.ts +29 -0
  867. package/src/web/TrackPlayer/PlaybackStateMachine.test.ts +60 -13
  868. package/src/web/TrackPlayer/PlaybackStateMachine.ts +22 -6
  869. package/src/web/TrackPlayer/Player.dispatch.test.ts +5 -3
  870. package/src/web/TrackPlayer/Player.load.test.ts +137 -1
  871. package/src/web/TrackPlayer/Player.ts +284 -37
  872. package/src/web/TrackPlayer/PlayingStateFactory.test.ts +1 -1
  873. package/src/web/TrackPlayer/PlayingStateFactory.ts +1 -1
  874. package/src/web/TrackPlayer/QueueManager.test.ts +29 -0
  875. package/src/web/TrackPlayer/QueueManager.ts +14 -0
  876. package/src/web/TrackPlayer/QueuePlayer.ts +33 -14
  877. package/src/web/__tests__/lifecycle.test.ts +345 -0
  878. package/src/web/__tests__/lifecycleHarness.ts +351 -0
  879. package/src/web/__tests__/loadEdgeCases.test.ts +246 -0
  880. package/src/web/__tests__/loadSupersession.test.ts +175 -0
  881. package/src/web/__tests__/retry.test.ts +169 -0
  882. package/src/web/browser/BrowserManager.ts +209 -111
  883. package/src/web/browser/FavoriteManager.test.ts +84 -0
  884. package/src/web/browser/FavoriteManager.ts +28 -23
  885. package/src/web/browser/NavigationErrorManager.ts +3 -1
  886. package/src/web/browser/SearchManager.test.ts +75 -0
  887. package/src/web/browser/SearchManager.ts +25 -28
  888. package/src/web/browser/__tests__/artwork-resolution.test.ts +117 -0
  889. package/src/web/browser/__tests__/layer-resolver.test.ts +35 -0
  890. package/src/web/browser/__tests__/search-artwork.test.ts +46 -0
  891. package/src/web/browser/__tests__/search-navigation.test.ts +76 -0
  892. package/src/web/browser/assertBrowsePageShape.test.ts +1 -1
  893. package/src/web/browser/assertBrowsePageShape.ts +5 -3
  894. package/src/web/browser/classifyTrackNavigation.test.ts +10 -8
  895. package/src/web/browser/classifyTrackNavigation.ts +9 -9
  896. package/src/web/browser/parseSearchResponse.test.ts +8 -2
  897. package/src/web/browser/sections.test.ts +91 -0
  898. package/src/web/browser/sections.ts +72 -0
  899. package/src/web/http/RequestConfigBuilder.test.ts +241 -1
  900. package/src/web/http/RequestConfigBuilder.ts +140 -33
  901. package/src/web/http/followMediaRedirect.test.ts +289 -0
  902. package/src/web/http/followMediaRedirect.ts +253 -0
  903. package/src/web/player/NowPlayingManager.ts +4 -3
  904. package/src/web/util/BrowserPathHelper.test.ts +68 -0
  905. package/src/web/util/BrowserPathHelper.ts +70 -13
  906. package/website/guide/android-auto.md +114 -0
  907. package/website/guide/android-certificates.md +409 -0
  908. package/website/guide/artwork.md +255 -0
  909. package/website/guide/audio-output.md +135 -0
  910. package/website/guide/automotive.md +86 -0
  911. package/website/guide/basic-usage.md +151 -0
  912. package/website/guide/battery.md +115 -0
  913. package/website/guide/browser.md +587 -0
  914. package/website/guide/carplay.md +650 -0
  915. package/website/guide/configuration.md +173 -0
  916. package/website/guide/equalizer.md +231 -0
  917. package/website/guide/errors.md +310 -0
  918. package/website/guide/favorites.md +154 -0
  919. package/website/guide/gate.md +143 -0
  920. package/website/guide/getting-started.md +46 -0
  921. package/website/guide/hooks.md +238 -0
  922. package/website/guide/live-streams.md +125 -0
  923. package/website/guide/metadata.md +239 -0
  924. package/website/guide/migrating-from-track-player.md +244 -0
  925. package/website/guide/native-callback-fetch.md +127 -0
  926. package/website/guide/network.md +86 -0
  927. package/website/guide/now-playing.md +175 -0
  928. package/website/guide/playback.md +328 -0
  929. package/website/guide/queue.md +300 -0
  930. package/website/guide/remote-controls.md +256 -0
  931. package/website/guide/search.md +255 -0
  932. package/website/guide/sleep-timer.md +268 -0
  933. package/website/guide/track.md +247 -0
  934. package/ios/Bridge.h +0 -8
  935. package/ios/Browser/MediaResolveComposer.swift +0 -114
  936. package/ios/CarPlay/ImageRowItem+CarPlay.swift +0 -19
  937. package/ios/Model/MediaURL.swift +0 -67
  938. package/ios/NowPlayingInfo/MediaItemProperty.swift +0 -78
  939. package/ios/NowPlayingInfo/NowPlayingInfoKeyValue.swift +0 -6
  940. package/ios/NowPlayingInfo/NowPlayingInfoProperty.swift +0 -220
  941. package/ios/Observer/PlayerItemNotificationObserver.swift +0 -119
  942. package/ios/Observer/PlayerItemPropertyObserver.swift +0 -133
  943. package/ios/Observer/PlayerStateObserver.swift +0 -50
  944. package/ios/Observer/PlayerTimeObserver.swift +0 -55
  945. package/ios/Option/PitchAlgorithms.swift +0 -17
  946. package/ios/Option/TimeEventFrequency.swift +0 -18
  947. package/ios/Player/LoadSeekCoordinator.swift +0 -99
  948. package/ios/Player/MediaLoaderDelegate.swift +0 -11
  949. package/ios/Player/PlaybackCoordinator.swift +0 -754
  950. package/ios/Player/PlaybackEffectHandler.swift +0 -54
  951. package/ios/Player/PlaybackErrorHandler.swift +0 -175
  952. package/ios/Player/PlaybackStateStore.swift +0 -27
  953. package/ios/Player/PlayingStateManager.swift +0 -33
  954. package/ios/Player/RetryManager.swift +0 -322
  955. package/ios/Player/SeekCompletionHandler.swift +0 -3
  956. package/ios/Player/SleepTimerHandling.swift +0 -15
  957. package/ios/Support/RNTrackPlayer-Bridging-Header.h +0 -7
  958. package/ios/Tests/LoadSeekCoordinatorTests.swift +0 -325
  959. package/ios/Tests/MediaResolveTests.swift +0 -126
  960. package/ios/Tests/OnceValueTests.swift +0 -79
  961. package/ios/Tests/PlaybackErrorHandlerTests.swift +0 -547
  962. package/ios/Tests/PlaybackStateStoreTests.swift +0 -48
  963. package/ios/Tests/PlayingStateManagerTests.swift +0 -57
  964. package/ios/Tests/RetryManagerTests.swift +0 -89
  965. package/ios/TrackPlayer.swift +0 -1014
  966. package/ios/TrackPlayerCallbacks.swift +0 -86
  967. package/ios/Util/MetadataAdapter.swift +0 -131
  968. package/ios/Util/OnceValue.swift +0 -104
  969. package/nitrogen/generated/android/c++/JFavoriteConfig.hpp +0 -58
  970. package/nitrogen/generated/android/c++/JFavoritesMatchMode.hpp +0 -58
  971. package/nitrogen/generated/android/c++/JImageRowItem.hpp +0 -105
  972. package/nitrogen/generated/android/c++/JNotificationButtonLayout.hpp +0 -94
  973. package/nitrogen/generated/android/c++/JVariant_Boolean_FavoriteConfig.cpp +0 -26
  974. package/nitrogen/generated/android/c++/JVariant_Boolean_FavoriteConfig.hpp +0 -71
  975. package/nitrogen/generated/android/c++/JVariant_NullType_NotificationButtonLayout.cpp +0 -26
  976. package/nitrogen/generated/android/c++/JVariant_NullType_NotificationButtonLayout.hpp +0 -75
  977. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/FavoriteConfig.kt +0 -38
  978. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/ImageRowItem.kt +0 -68
  979. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NotificationButtonLayout.kt +0 -50
  980. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Variant_Boolean_FavoriteConfig.kt +0 -53
  981. package/nitrogen/generated/ios/swift/FavoriteConfig.swift +0 -29
  982. package/nitrogen/generated/ios/swift/FavoritesMatchMode.swift +0 -40
  983. package/nitrogen/generated/ios/swift/ImageRowItem.swift +0 -195
  984. package/nitrogen/generated/ios/swift/NotificationButtonLayout.swift +0 -92
  985. package/nitrogen/generated/ios/swift/Variant_Bool_FavoriteConfig.swift +0 -18
  986. package/nitrogen/generated/ios/swift/Variant_NullType_NotificationButtonLayout.swift +0 -18
  987. package/nitrogen/generated/shared/c++/FavoriteConfig.hpp +0 -84
  988. package/nitrogen/generated/shared/c++/ImageRowItem.hpp +0 -129
  989. package/nitrogen/generated/shared/c++/NotificationButtonLayout.hpp +0 -102
@@ -1,14 +1,16 @@
1
1
  import type { Track, ResolvedTrack } from '../../types'
2
+ import { getTrackIdentity } from '../../utils/getTrackIdentity'
2
3
 
3
4
  /**
4
- * Manages favorite state for tracks.
5
+ * Manages favorite state for tracks, keyed by track identity (`id` when set,
6
+ * falling back to `src` — see getTrackIdentity / ADR 0008).
5
7
  * Matches Android's favorite hydration behavior.
6
8
  */
7
9
  export class FavoriteManager {
8
10
  private favorites = new Set<string>()
9
11
 
10
12
  /**
11
- * Sets the favorites cache from an array of track src values.
13
+ * Sets the favorites cache from an array of track identities.
12
14
  * This is typically called when favorites are loaded from storage.
13
15
  */
14
16
  setFavorites(favorites: string[]): void {
@@ -16,24 +18,27 @@ export class FavoriteManager {
16
18
  }
17
19
 
18
20
  /**
19
- * Checks if a track is favorited based on its src.
21
+ * Checks if a track is favorited based on its identity.
20
22
  */
21
- isFavorited(src: string): boolean {
22
- return this.favorites.has(src)
23
+ isFavorited(track: Track): boolean {
24
+ const identity = getTrackIdentity(track)
25
+ return identity !== undefined && this.favorites.has(identity)
23
26
  }
24
27
 
25
28
  /**
26
- * Adds a track src to the favorites cache.
29
+ * Adds a track to the favorites cache under its identity.
27
30
  */
28
- addFavorite(src: string): void {
29
- this.favorites.add(src)
31
+ addFavorite(track: Track): void {
32
+ const identity = getTrackIdentity(track)
33
+ if (identity !== undefined) this.favorites.add(identity)
30
34
  }
31
35
 
32
36
  /**
33
- * Removes a track src from the favorites cache.
37
+ * Removes a track from the favorites cache under its identity.
34
38
  */
35
- removeFavorite(src: string): void {
36
- this.favorites.delete(src)
39
+ removeFavorite(track: Track): void {
40
+ const identity = getTrackIdentity(track)
41
+ if (identity !== undefined) this.favorites.delete(identity)
37
42
  }
38
43
 
39
44
  /**
@@ -48,8 +53,7 @@ export class FavoriteManager {
48
53
  if (track.favorited !== undefined && track.favorited !== null) return track
49
54
  if (this.favorites.size === 0) return track
50
55
 
51
- const isFavorited = track.src ? this.favorites.has(track.src) : false
52
- if (!isFavorited) return track
56
+ if (!this.isFavorited(track)) return track
53
57
 
54
58
  return {
55
59
  ...track,
@@ -58,22 +62,23 @@ export class FavoriteManager {
58
62
  }
59
63
 
60
64
  /**
61
- * Hydrates favorites on all children of a ResolvedTrack.
62
- * Matches Android's hydrateChildren behavior.
65
+ * Hydrates favorites on all tracks of a resolved page.
66
+ * Matches Android's hydrateChildren behavior. Pages reach hydration
67
+ * normalized (ADR 0010), so `sections` is the only structure to walk.
63
68
  *
64
- * @param resolvedTrack ResolvedTrack with children to hydrate
65
- * @returns ResolvedTrack with favorited properties set on children
69
+ * @param resolvedTrack Resolved page to hydrate
70
+ * @returns Resolved page with favorited properties set on its tracks
66
71
  */
67
72
  hydrateChildren(resolvedTrack: ResolvedTrack): ResolvedTrack {
68
- const children = resolvedTrack.children
69
- if (!children) return resolvedTrack
73
+ const { sections } = resolvedTrack
74
+ if (!sections) return resolvedTrack
70
75
 
71
- const hydratedChildren = children.map((track) =>
72
- this.hydrateFavorite(track)
73
- )
74
76
  return {
75
77
  ...resolvedTrack,
76
- children: hydratedChildren
78
+ sections: sections.map((section) => ({
79
+ ...section,
80
+ children: section.children.map((track) => this.hydrateFavorite(track))
81
+ }))
77
82
  }
78
83
  }
79
84
  }
@@ -5,6 +5,7 @@ import type {
5
5
  NavigationErrorEvent
6
6
  } from '../../features'
7
7
  import type { NativeBrowserConfiguration } from '../../types/browser-native'
8
+ import { BrowserPathHelper } from '../util/BrowserPathHelper'
8
9
 
9
10
  const ERROR_TITLES: Record<NavigationErrorType, string> = {
10
11
  'network-error': 'Network Error',
@@ -91,7 +92,8 @@ export class NavigationErrorManager {
91
92
  const customFormatted = this.formatCallback({
92
93
  error: navError,
93
94
  defaultFormatted,
94
- path
95
+ path,
96
+ kind: BrowserPathHelper.navigationErrorKind(path)
95
97
  })
96
98
  this._formattedNavigationError = customFormatted || defaultFormatted
97
99
  } catch (error) {
@@ -0,0 +1,75 @@
1
+ import { describe, it, expect, vi } from 'vitest'
2
+ import type { NativeBrowserConfiguration } from '../../types/browser-native'
3
+ import type { HttpClient } from '../http/HttpClient'
4
+ import { BrowserManager } from './BrowserManager'
5
+ import { FavoriteManager } from './FavoriteManager'
6
+ import { NavigationErrorManager } from './NavigationErrorManager'
7
+ import { SearchManager } from './SearchManager'
8
+
9
+ /**
10
+ * Builds a SearchManager over a BrowserManager whose HTTP client answers every
11
+ * request with `respond` — a resolved body or a rejection.
12
+ */
13
+ function makeSearchManager(
14
+ respond: () => Promise<unknown>,
15
+ route: NonNullable<NativeBrowserConfiguration['routes']>[number] = {
16
+ path: '__search__',
17
+ searchConfig: { baseUrl: 'https://api.example.com' }
18
+ }
19
+ ): SearchManager {
20
+ const httpClient = {
21
+ executeRequest: vi.fn().mockImplementation(respond)
22
+ } as unknown as HttpClient
23
+ const browserManager = new BrowserManager(
24
+ httpClient,
25
+ new FavoriteManager(),
26
+ new NavigationErrorManager()
27
+ )
28
+ browserManager.configuration = { routes: [route] }
29
+ return new SearchManager(browserManager)
30
+ }
31
+
32
+ const httpError = (): Error => {
33
+ const error = new Error('HTTP 500: Internal Server Error') as Error & {
34
+ code: string
35
+ statusCode: number
36
+ }
37
+ error.code = 'http-error'
38
+ error.statusCode = 500
39
+ return error
40
+ }
41
+
42
+ describe('SearchManager', () => {
43
+ it('rejects when the search request fails', async () => {
44
+ const manager = makeSearchManager(() => Promise.reject(httpError()))
45
+ await expect(
46
+ manager.search({ query: 'jazz', reference: 'unknown' })
47
+ ).rejects.toThrow('HTTP 500: Internal Server Error')
48
+ })
49
+
50
+ it('resolves [] when the search found nothing', async () => {
51
+ const manager = makeSearchManager(() => Promise.resolve({ children: [] }))
52
+ await expect(
53
+ manager.search({ query: 'jazz', reference: 'unknown' })
54
+ ).resolves.toEqual([])
55
+ })
56
+
57
+ it('resolves the matching tracks', async () => {
58
+ const manager = makeSearchManager(() =>
59
+ Promise.resolve({ children: [{ title: 'Jazz FM', src: 'https://s/1' }] })
60
+ )
61
+ await expect(
62
+ manager.search({ query: 'jazz', reference: 'unknown' })
63
+ ).resolves.toEqual([{ title: 'Jazz FM', src: 'https://s/1' }])
64
+ })
65
+
66
+ it('propagates a rejecting search callback', async () => {
67
+ const manager = makeSearchManager(() => Promise.resolve([]), {
68
+ path: '__search__',
69
+ searchCallback: () => Promise.reject(new Error('callback exploded'))
70
+ })
71
+ await expect(
72
+ manager.search({ query: 'jazz', reference: 'unknown' })
73
+ ).rejects.toThrow('callback exploded')
74
+ })
75
+ })
@@ -15,7 +15,9 @@ export class SearchManager {
15
15
  * Matches Android's BrowserManager.search(params: SearchParams) behavior.
16
16
  *
17
17
  * @param params Search parameters (query is required, other fields optional)
18
- * @returns Array of matching tracks
18
+ * @returns Array of matching tracks — empty only when the source found none
19
+ * @throws The failure itself: an `Error` carrying a `NavigationErrorType`
20
+ * `code` from `HttpClient`, or whatever a `searchCallback` rejected with
19
21
  */
20
22
  async search(params: SearchParams): Promise<Track[]> {
21
23
  // Find __search__ route entry
@@ -48,36 +50,31 @@ export class SearchManager {
48
50
 
49
51
  // Delegate to the shared layered fetch (request → search) on BrowserManager
50
52
  // so the ladder lives in one place.
51
- try {
52
- results = await this.browserManager.fetchSearchResults(
53
- searchRoute.searchConfig,
54
- searchQueryParams
55
- )
56
- } catch (error) {
57
- console.error('Search failed:', error)
58
- return []
59
- }
53
+ results = await this.browserManager.fetchSearchResults(
54
+ searchRoute.searchConfig,
55
+ searchQueryParams
56
+ )
60
57
  }
61
58
 
62
59
  // Transform artwork URLs on search results using async method with full Track access
63
- const { request: requestConfig, artwork: artworkConfig } =
64
- this.browserManager.configuration
65
- if (artworkConfig) {
66
- results = await Promise.all(
67
- results.map(async (track) => {
68
- const artworkSource =
69
- await RequestConfigBuilder.resolveArtworkSourceAsync(
70
- track,
71
- requestConfig,
72
- artworkConfig
73
- )
74
- if (artworkSource && !track.artworkSource) {
75
- return { ...track, artworkSource }
76
- }
77
- return track
78
- })
79
- )
80
- }
60
+ // Gated per track inside the resolver, as on Android — a result carrying a
61
+ // plain `artwork` URL resolves even with no `artwork` config.
62
+ const requestConfig = await this.browserManager.resolvedRequestConfig()
63
+ const artworkConfig = this.browserManager.configuration.artwork
64
+ results = await Promise.all(
65
+ results.map(async (track) => {
66
+ const artworkSource =
67
+ await RequestConfigBuilder.resolveArtworkSourceAsync(
68
+ track,
69
+ requestConfig,
70
+ artworkConfig
71
+ )
72
+ if (artworkSource && !track.artworkSource) {
73
+ return { ...track, artworkSource }
74
+ }
75
+ return track
76
+ })
77
+ )
81
78
 
82
79
  return results
83
80
  }
@@ -0,0 +1,117 @@
1
+ import { describe, it, expect, vi } from 'vitest'
2
+ import type { HttpClient } from '../../http/HttpClient'
3
+ import { BrowserManager } from '../BrowserManager'
4
+ import { FavoriteManager } from '../FavoriteManager'
5
+ import { NavigationErrorManager } from '../NavigationErrorManager'
6
+
7
+ function makeManager(): BrowserManager {
8
+ const httpClient = {
9
+ executeRequest: vi.fn().mockRejectedValue(new Error('no network in test'))
10
+ } as unknown as HttpClient
11
+ return new BrowserManager(
12
+ httpClient,
13
+ new FavoriteManager(),
14
+ new NavigationErrorManager()
15
+ )
16
+ }
17
+
18
+ /**
19
+ * Who gets an `artworkSource`, and on whose say-so.
20
+ *
21
+ * Android gates this per *track* — `resolveArtworkUrl` returns early only when
22
+ * `artworkConfig == null && track.artwork == null`, so a track carrying a plain
23
+ * URL resolves to `{ uri }` with no `artwork` block configured at all. Web used
24
+ * to gate a level up, bailing out of the whole page when `configuration.artwork`
25
+ * was unset, which left every child's `artworkSource` undefined in any app that
26
+ * never declared one — the example app among them.
27
+ */
28
+ describe('artwork resolution without an artwork config', () => {
29
+ it('populates artworkSource for a child carrying a plain artwork url', async () => {
30
+ const manager = makeManager()
31
+ manager.configuration = {
32
+ path: '/',
33
+ routes: [
34
+ {
35
+ path: '/library',
36
+ browseStatic: {
37
+ path: '/library',
38
+ title: 'Library',
39
+ sections: [
40
+ {
41
+ title: 'Collections',
42
+ children: [
43
+ {
44
+ title: 'Cratediggers',
45
+ path: '/collection/cratediggers',
46
+ artwork: 'https://cdn.example.com/cratediggers.jpg'
47
+ }
48
+ ]
49
+ }
50
+ ]
51
+ }
52
+ }
53
+ ]
54
+ }
55
+
56
+ await manager.navigatePath('/library')
57
+
58
+ const tile = manager.content?.sections?.[0]?.children[0]
59
+ expect(tile?.artworkSource?.uri).toBe(
60
+ 'https://cdn.example.com/cratediggers.jpg'
61
+ )
62
+ })
63
+
64
+ it('leaves artworkSource undefined for a child with no artwork', async () => {
65
+ const manager = makeManager()
66
+ manager.configuration = {
67
+ path: '/',
68
+ routes: [
69
+ {
70
+ path: '/library',
71
+ browseStatic: {
72
+ path: '/library',
73
+ title: 'Library',
74
+ sections: [
75
+ {
76
+ title: 'Collections',
77
+ children: [{ title: 'Bare', path: '/collection/bare' }]
78
+ }
79
+ ]
80
+ }
81
+ }
82
+ ]
83
+ }
84
+
85
+ await manager.navigatePath('/library')
86
+
87
+ const tile = manager.content?.sections?.[0]?.children[0]
88
+ expect(tile?.artworkSource).toBeUndefined()
89
+ })
90
+
91
+ it('treats an empty artwork string as no artwork, as Android does', async () => {
92
+ const manager = makeManager()
93
+ manager.configuration = {
94
+ path: '/',
95
+ routes: [
96
+ {
97
+ path: '/library',
98
+ browseStatic: {
99
+ path: '/library',
100
+ title: 'Library',
101
+ sections: [
102
+ {
103
+ title: 'Collections',
104
+ children: [{ title: 'Empty', path: '/x', artwork: '' }]
105
+ }
106
+ ]
107
+ }
108
+ }
109
+ ]
110
+ }
111
+
112
+ await manager.navigatePath('/library')
113
+
114
+ const tile = manager.content?.sections?.[0]?.children[0]
115
+ expect(tile?.artworkSource).toBeUndefined()
116
+ })
117
+ })
@@ -66,4 +66,39 @@ describe('BrowserManager layer resolver', () => {
66
66
  await expect(manager.navigatePath('/a')).resolves.not.toThrow()
67
67
  expect(calls).toBe(1)
68
68
  })
69
+
70
+ /**
71
+ * The media and artwork paths sit outside browse and so must reach the
72
+ * request layer through this accessor. Reading `configuration.request`
73
+ * instead hands a resolver-only config no baseUrl and no headers — on
74
+ * exactly the requests that carry a credential. Android's
75
+ * `resolvedRequestConfig()` exists for the same reason.
76
+ */
77
+ it('exposes the resolver result to consumers outside the browse path', async () => {
78
+ const manager = makeManager()
79
+ manager.configuration = {
80
+ path: '/',
81
+ requestResolver: async () => ({
82
+ baseUrl: 'https://api.example.com',
83
+ headers: { Authorization: 'Bearer token' }
84
+ })
85
+ }
86
+
87
+ expect(await manager.resolvedRequestConfig()).toEqual({
88
+ baseUrl: 'https://api.example.com',
89
+ headers: { Authorization: 'Bearer token' }
90
+ })
91
+ })
92
+
93
+ it('falls back to the static request config when no resolver is set', async () => {
94
+ const manager = makeManager()
95
+ manager.configuration = {
96
+ path: '/',
97
+ request: { baseUrl: 'https://static.example.com' }
98
+ }
99
+
100
+ expect(await manager.resolvedRequestConfig()).toEqual({
101
+ baseUrl: 'https://static.example.com'
102
+ })
103
+ })
69
104
  })
@@ -0,0 +1,46 @@
1
+ import { describe, it, expect, vi } from 'vitest'
2
+ import type { HttpClient } from '../../http/HttpClient'
3
+ import { BrowserManager } from '../BrowserManager'
4
+ import { FavoriteManager } from '../FavoriteManager'
5
+ import { NavigationErrorManager } from '../NavigationErrorManager'
6
+ import { SearchManager } from '../SearchManager'
7
+
8
+ /**
9
+ * Search-result artwork reaches the request layer through
10
+ * `resolvedRequestConfig()`, as content and media artwork do. Reading
11
+ * `configuration.request` handed a resolver-only config no baseUrl and no
12
+ * headers, so a relative artwork path on a search result never resolved.
13
+ */
14
+ describe('search result artwork', () => {
15
+ it('applies a resolver-only request layer', async () => {
16
+ const httpClient = {
17
+ executeRequest: vi
18
+ .fn()
19
+ .mockResolvedValue([
20
+ { title: 'Hit', src: '/hit.mp3', artwork: '/art/hit.jpg' }
21
+ ])
22
+ } as unknown as HttpClient
23
+ const manager = new BrowserManager(
24
+ httpClient,
25
+ new FavoriteManager(),
26
+ new NavigationErrorManager()
27
+ )
28
+ manager.configuration = {
29
+ path: '/',
30
+ requestResolver: async () => ({
31
+ baseUrl: 'https://api.example.com',
32
+ headers: { Authorization: 'Bearer t' }
33
+ }),
34
+ artwork: {},
35
+ routes: [{ path: '__search__', searchConfig: { path: '/search' } }]
36
+ }
37
+
38
+ const [hit] = await new SearchManager(manager).search({
39
+ query: 'hit',
40
+ reference: 'unknown'
41
+ })
42
+
43
+ expect(hit?.artworkSource?.uri).toBe('https://api.example.com/art/hit.jpg')
44
+ expect(hit?.artworkSource?.headers).toEqual({ Authorization: 'Bearer t' })
45
+ })
46
+ })
@@ -0,0 +1,76 @@
1
+ import { describe, it, expect, vi } from 'vitest'
2
+ import type { FormattedNavigationError } from '../../../features'
3
+ import type { HttpClient } from '../../http/HttpClient'
4
+ import { BrowserManager } from '../BrowserManager'
5
+ import { FavoriteManager } from '../FavoriteManager'
6
+ import { NavigationErrorManager } from '../NavigationErrorManager'
7
+
8
+ /**
9
+ * A BrowserManager whose only route is a `searchConfig`, with its HTTP client
10
+ * answering every request with `respond`.
11
+ */
12
+ function makeManager(respond: () => Promise<unknown>): {
13
+ manager: BrowserManager
14
+ errors: NavigationErrorManager
15
+ formattedPaths: string[]
16
+ } {
17
+ const httpClient = {
18
+ executeRequest: vi.fn().mockImplementation(respond)
19
+ } as unknown as HttpClient
20
+ const errors = new NavigationErrorManager()
21
+ const manager = new BrowserManager(httpClient, new FavoriteManager(), errors)
22
+ const formattedPaths: string[] = []
23
+ manager.configuration = {
24
+ routes: [
25
+ {
26
+ path: '__search__',
27
+ searchConfig: { baseUrl: 'https://api.example.com' }
28
+ }
29
+ ],
30
+ formatNavigationError: ({ path }): FormattedNavigationError => {
31
+ formattedPaths.push(path)
32
+ return { title: 'Search unavailable' }
33
+ }
34
+ }
35
+ return { manager, errors, formattedPaths }
36
+ }
37
+
38
+ const httpError = (): Error => {
39
+ const error = new Error('HTTP 500: Internal Server Error') as Error & {
40
+ code: string
41
+ statusCode: number
42
+ }
43
+ error.code = 'http-error'
44
+ error.statusCode = 500
45
+ return error
46
+ }
47
+
48
+ describe('navigating to a search path', () => {
49
+ it('surfaces a navigation error when the search fails', async () => {
50
+ const { manager, errors, formattedPaths } = makeManager(() =>
51
+ Promise.reject(httpError())
52
+ )
53
+
54
+ await manager.navigatePath('/__search?q=jazz')
55
+
56
+ expect(errors.getNavigationError()).toEqual({
57
+ code: 'http-error',
58
+ message: 'HTTP 500: Internal Server Error',
59
+ statusCode: 500,
60
+ statusCodeSuccess: undefined
61
+ })
62
+ expect(formattedPaths).toEqual(['/__search?q=jazz'])
63
+ expect(manager.content).toBeUndefined()
64
+ })
65
+
66
+ it('resolves an empty page without an error when the search found nothing', async () => {
67
+ const { manager, errors } = makeManager(() =>
68
+ Promise.resolve({ children: [] })
69
+ )
70
+
71
+ await manager.navigatePath('/__search?q=jazz')
72
+
73
+ expect(errors.getNavigationError()).toBeUndefined()
74
+ expect(manager.content?.sections).toEqual([{ children: [] }])
75
+ })
76
+ })
@@ -3,7 +3,7 @@ import { assertBrowsePageShape } from './assertBrowsePageShape'
3
3
 
4
4
  describe('assertBrowsePageShape', () => {
5
5
  it('passes a page object through unchanged', () => {
6
- const page = { url: '/x', title: 'X', children: [] }
6
+ const page = { path: '/x', title: 'X', children: [] }
7
7
  expect(assertBrowsePageShape(page, '/x')).toBe(page)
8
8
  })
9
9
 
@@ -13,14 +13,16 @@ export function assertBrowsePageShape(
13
13
  if (Array.isArray(response)) {
14
14
  throw new Error(
15
15
  `Browse endpoint for "${path}" returned a JSON array; expected a ` +
16
- `page object { title, children?: Track[] }. Wrap the rows in a ` +
17
- `\`children\` array.`
16
+ `page object { title, sections?: Section[], children?: Track[] }. ` +
17
+ `Wrap the rows in a \`children\` array (one untitled section) or ` +
18
+ `group them into \`sections\`.`
18
19
  )
19
20
  }
20
21
  if (response === null || typeof response !== 'object') {
21
22
  throw new Error(
22
23
  `Browse endpoint for "${path}" returned ${JSON.stringify(response)}; ` +
23
- `expected a page object { title, children?: Track[] }.`
24
+ `expected a page object { title, sections?: Section[], ` +
25
+ `children?: Track[] }.`
24
26
  )
25
27
  }
26
28
  return response as ResolvedTrack
@@ -5,10 +5,10 @@ import { classifyTrackNavigation } from './classifyTrackNavigation'
5
5
  const track = (fields: Partial<Track>): Track => fields as Track
6
6
 
7
7
  describe('classifyTrackNavigation', () => {
8
- it('classifies a contextual url, exposing parent path and track id', () => {
8
+ it('classifies a contextual path, exposing parent path and track id', () => {
9
9
  expect(
10
10
  classifyTrackNavigation(
11
- track({ url: '/library/radio?__trackId=song.mp3' })
11
+ track({ path: '/library/radio?__trackId=song.mp3' })
12
12
  )
13
13
  ).toEqual({
14
14
  kind: 'contextual',
@@ -17,25 +17,27 @@ describe('classifyTrackNavigation', () => {
17
17
  })
18
18
  })
19
19
 
20
- it('classifies a non-contextual url as a browse navigation', () => {
21
- expect(classifyTrackNavigation(track({ url: '/library/radio' }))).toEqual({
20
+ it('classifies a non-contextual path as a browse navigation', () => {
21
+ expect(classifyTrackNavigation(track({ path: '/library/radio' }))).toEqual({
22
22
  kind: 'browse'
23
23
  })
24
24
  })
25
25
 
26
- it('classifies a track with src but no url as playable', () => {
26
+ it('classifies a track with src but no path as playable', () => {
27
27
  expect(classifyTrackNavigation(track({ src: 'song.mp3' }))).toEqual({
28
28
  kind: 'playable'
29
29
  })
30
30
  })
31
31
 
32
- it('prefers browse over playable when a url is present', () => {
32
+ it('prefers browse over playable when a path is present', () => {
33
33
  expect(
34
- classifyTrackNavigation(track({ url: '/library/radio', src: 'song.mp3' }))
34
+ classifyTrackNavigation(
35
+ track({ path: '/library/radio', src: 'song.mp3' })
36
+ )
35
37
  ).toEqual({ kind: 'browse' })
36
38
  })
37
39
 
38
- it('classifies a track with neither url nor src as invalid', () => {
40
+ it('classifies a track with neither path nor src as invalid', () => {
39
41
  expect(classifyTrackNavigation(track({}))).toEqual({ kind: 'invalid' })
40
42
  })
41
43
  })
@@ -4,10 +4,10 @@ import { BrowserPathHelper } from '../util/BrowserPathHelper'
4
4
  /**
5
5
  * How a selected track should be navigated, decided purely from its shape:
6
6
  * - `contextual` — a playable track carrying its parent queue context in a
7
- * contextual URL (`{parentPath}?__trackId={src}`); expand/skip within that queue.
8
- * - `browse` — a browsable track (has a `url` that isn't contextual); drill in.
9
- * - `playable` — a bare playable track (`src`, no `url`); load and play it alone.
10
- * - `invalid` — neither `url` nor `src`; nothing to do.
7
+ * contextual path (`{parentPath}?__trackId={src}`); expand/skip within that queue.
8
+ * - `browse` — a browsable track (has a `path` that isn't contextual); drill in.
9
+ * - `playable` — a bare playable track (`src`, no `path`); load and play it alone.
10
+ * - `invalid` — neither `path` nor `src`; nothing to do.
11
11
  */
12
12
  export type TrackNavigation =
13
13
  | { kind: 'contextual'; parentPath: string; trackId: string | undefined }
@@ -21,15 +21,15 @@ export type TrackNavigation =
21
21
  * caller; this only decides which action applies.
22
22
  */
23
23
  export function classifyTrackNavigation(track: Track): TrackNavigation {
24
- const url = track.url
25
- if (url && BrowserPathHelper.isContextual(url)) {
24
+ const path = track.path
25
+ if (path && BrowserPathHelper.isContextual(path)) {
26
26
  return {
27
27
  kind: 'contextual',
28
- parentPath: BrowserPathHelper.stripTrackId(url),
29
- trackId: BrowserPathHelper.extractTrackId(url)
28
+ parentPath: BrowserPathHelper.stripTrackId(path),
29
+ trackId: BrowserPathHelper.extractTrackId(path)
30
30
  }
31
31
  }
32
- if (url) return { kind: 'browse' }
32
+ if (path) return { kind: 'browse' }
33
33
  if (track.src) return { kind: 'playable' }
34
34
  return { kind: 'invalid' }
35
35
  }