react-native-audio-browser 0.2.0-next.2 → 0.2.0-next.21

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 (660) hide show
  1. package/README.md +35 -21
  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 +389 -164
  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 +48 -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 +24 -5
  11. package/android/src/main/java/com/audiobrowser/browser/InertStyleDiagnostic.kt +267 -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 +56 -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 +108 -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 +87 -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 +38 -0
  51. package/android/src/test/java/com/audiobrowser/browser/InertStyleDiagnosticTest.kt +277 -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 +147 -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 +154 -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 +41 -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/Browser/BrowserConfig.swift +102 -5
  76. package/ios/Browser/BrowserManager+URLResolution.swift +18 -14
  77. package/ios/Browser/BrowserManager.swift +230 -205
  78. package/ios/Browser/BrowserPathHelper.swift +44 -44
  79. package/ios/Browser/InertStyleDiagnostic.swift +279 -0
  80. package/ios/Browser/JsonModels.swift +264 -106
  81. package/ios/Browser/SearchDrillIn.swift +7 -7
  82. package/ios/Browser/SectionPresentation.swift +64 -0
  83. package/ios/Browser/SectionScope.swift +58 -24
  84. package/ios/Browser/StyleResolver.swift +58 -0
  85. package/ios/Browser/TabBarEntries.swift +9 -3
  86. package/ios/Browser/TrackIdTemplate.swift +37 -0
  87. package/ios/CarPlay/CarPlayArtworkResolver.swift +8 -7
  88. package/ios/CarPlay/CarPlayController.swift +227 -85
  89. package/ios/CarPlay/CarPlayImageLoader.swift +42 -20
  90. package/ios/CarPlay/CarPlayListItemFactory.swift +289 -84
  91. package/ios/CarPlay/CarPlayNowPlayingManager.swift +15 -12
  92. package/ios/CarPlay/RNABMediaAddHandler.swift +6 -6
  93. package/ios/CarPlay/RNABMediaAffinityHandler.swift +2 -2
  94. package/ios/CarPlay/RNABMediaIntentHandler.swift +16 -16
  95. package/ios/Extension/Capability+RemoteCommand.swift +1 -1
  96. package/ios/Extension/PlayerCapabilities+Favorite.swift +1 -15
  97. package/ios/Extension/ResolvedTrack+Copying.swift +13 -15
  98. package/ios/Extension/Section+Copying.swift +29 -0
  99. package/ios/Extension/String+IcyCharset.swift +21 -0
  100. package/ios/Extension/TimedMetadata+AVFoundation.swift +6 -4
  101. package/ios/Extension/Track+Copying.swift +8 -12
  102. package/ios/Extension/Track+Identity.swift +18 -0
  103. package/ios/Extension/UIApplication+ActiveScene.swift +27 -0
  104. package/ios/Http/HttpClient.swift +8 -2
  105. package/ios/HybridAudioBrowser.swift +253 -100
  106. package/ios/Model/NitroTypeStubs.swift +125 -23
  107. package/ios/Model/PlayerUpdateOptions.swift +7 -0
  108. package/ios/Model/RemoteCommand.swift +18 -0
  109. package/ios/Model/TrackPlayerError.swift +2 -2
  110. package/ios/Option/SessionCategories.swift +3 -2
  111. package/ios/Player/MediaIntentCriteria.swift +17 -9
  112. package/ios/Player/MediaLoader.swift +33 -9
  113. package/ios/Player/NowPlayingUpdater.swift +54 -6
  114. package/ios/Player/PlaybackCoordinator.swift +13 -6
  115. package/ios/Player/PlaybackErrorHandler.swift +4 -4
  116. package/ios/Player/PlaybackTimer.swift +8 -2
  117. package/ios/Player/QueueManager.swift +46 -13
  118. package/ios/Player/RetryManager.swift +80 -18
  119. package/ios/Player/SeekCompletionHandler.swift +3 -1
  120. package/ios/Player/ShuffleOrder.swift +33 -0
  121. package/ios/Player/SleepTimerHandling.swift +13 -0
  122. package/ios/RemoteCommand/RemoteCommandCallbacks.swift +47 -0
  123. package/ios/RemoteCommand/RemoteCommandController.swift +62 -24
  124. package/ios/Tests/BrowserPathHelperTests.swift +50 -20
  125. package/ios/Tests/CarPlayArtworkResolverTests.swift +24 -41
  126. package/ios/Tests/InertStyleDiagnosticTests.swift +200 -0
  127. package/ios/Tests/JsonModelsTests.swift +150 -1
  128. package/ios/Tests/LRUCacheTests.swift +111 -0
  129. package/ios/Tests/LoadSeekCoordinatorTests.swift +3 -1
  130. package/ios/Tests/MediaIntentCriteriaTests.swift +2 -2
  131. package/ios/Tests/PlaybackCoordinatorTests.swift +1 -1
  132. package/ios/Tests/PlaybackErrorHandlerTests.swift +3 -1
  133. package/ios/Tests/PlaybackStateStoreTests.swift +4 -3
  134. package/ios/Tests/PlayerTimeObserverTests.swift +37 -0
  135. package/ios/Tests/QueueManagerTests.swift +122 -10
  136. package/ios/Tests/RemoteCommandControllerTests.swift +172 -0
  137. package/ios/Tests/RemoteCommandTests.swift +67 -0
  138. package/ios/Tests/ResolvedTrackCopyingTests.swift +39 -35
  139. package/ios/Tests/RetryManagerTests.swift +89 -0
  140. package/ios/Tests/SearchDrillInTests.swift +16 -16
  141. package/ios/Tests/SectionPresentationTests.swift +90 -0
  142. package/ios/Tests/SectionScopeTests.swift +87 -55
  143. package/ios/Tests/StyleResolverTests.swift +127 -0
  144. package/ios/Tests/Support/TestTypes.swift +8 -1
  145. package/ios/Tests/TabBarEntriesTests.swift +19 -19
  146. package/ios/Tests/TimedMetadataAVFoundationTests.swift +42 -0
  147. package/ios/Tests/TrackIdTemplateTests.swift +67 -0
  148. package/ios/Tests/TrackIdentityTests.swift +20 -0
  149. package/ios/Tests/TrackSelectorTests.swift +168 -33
  150. package/ios/TrackPlayer.swift +63 -35
  151. package/ios/TrackPlayerCallbacks.swift +5 -38
  152. package/ios/TrackSelector.swift +45 -30
  153. package/ios/Util/ArtworkImageFetcher.swift +16 -1
  154. package/ios/Util/LRUCache.swift +4 -1
  155. package/ios/Util/NetworkMonitor.swift +43 -26
  156. package/ios/Util/SFSymbolRenderer.swift +24 -2
  157. package/ios/Util/SVGProcessor.swift +9 -2
  158. package/lib/commonjs/AudioBrowser.js +8 -8
  159. package/lib/commonjs/AudioBrowser.js.map +1 -1
  160. package/lib/commonjs/CLAUDE.md +52 -0
  161. package/lib/commonjs/features/browser-config.js +12 -8
  162. package/lib/commonjs/features/browser-config.js.map +1 -1
  163. package/lib/commonjs/features/browser.js +11 -3
  164. package/lib/commonjs/features/browser.js.map +1 -1
  165. package/lib/commonjs/features/carConnection.js +1 -1
  166. package/lib/commonjs/features/equalizer.js +1 -1
  167. package/lib/commonjs/features/errors.js +3 -3
  168. package/lib/commonjs/features/favorites.js +14 -11
  169. package/lib/commonjs/features/favorites.js.map +1 -1
  170. package/lib/commonjs/features/gate.js +16 -1
  171. package/lib/commonjs/features/gate.js.map +1 -1
  172. package/lib/commonjs/features/metadata.js +20 -3
  173. package/lib/commonjs/features/metadata.js.map +1 -1
  174. package/lib/commonjs/features/network.js +1 -1
  175. package/lib/commonjs/features/nowPlaying.js +1 -1
  176. package/lib/commonjs/features/output.js +1 -1
  177. package/lib/commonjs/features/playback/controls.js +4 -2
  178. package/lib/commonjs/features/playback/controls.js.map +1 -1
  179. package/lib/commonjs/features/playback/playWhenReady.js +1 -1
  180. package/lib/commonjs/features/playback/playing.js +1 -1
  181. package/lib/commonjs/features/playback/progress.js +3 -2
  182. package/lib/commonjs/features/playback/progress.js.map +1 -1
  183. package/lib/commonjs/features/playback/rate.js +8 -1
  184. package/lib/commonjs/features/playback/rate.js.map +1 -1
  185. package/lib/commonjs/features/playback/state.js +3 -4
  186. package/lib/commonjs/features/playback/state.js.map +1 -1
  187. package/lib/commonjs/features/playback/trackPlaybackTime.js +0 -6
  188. package/lib/commonjs/features/playback/trackPlaybackTime.js.map +1 -1
  189. package/lib/commonjs/features/playback/volume.js +1 -1
  190. package/lib/commonjs/features/player/options.js +48 -34
  191. package/lib/commonjs/features/player/options.js.map +1 -1
  192. package/lib/commonjs/features/player/setup.js +18 -9
  193. package/lib/commonjs/features/player/setup.js.map +1 -1
  194. package/lib/commonjs/features/player/validateOptions.js +23 -0
  195. package/lib/commonjs/features/player/validateOptions.js.map +1 -0
  196. package/lib/commonjs/features/queue/activeTrack.js +15 -4
  197. package/lib/commonjs/features/queue/activeTrack.js.map +1 -1
  198. package/lib/commonjs/features/queue/queue.js +13 -6
  199. package/lib/commonjs/features/queue/queue.js.map +1 -1
  200. package/lib/commonjs/features/queue/repeatMode.js +1 -1
  201. package/lib/commonjs/features/queue/shuffle.js +1 -1
  202. package/lib/commonjs/features/remoteControls.js +13 -92
  203. package/lib/commonjs/features/remoteControls.js.map +1 -1
  204. package/lib/commonjs/features/sleepTimer.js +13 -1
  205. package/lib/commonjs/features/sleepTimer.js.map +1 -1
  206. package/lib/commonjs/test-utils/reactNativeStub.js +65 -0
  207. package/lib/commonjs/test-utils/reactNativeStub.js.map +1 -0
  208. package/lib/commonjs/utils/LazyNativeEmitter.js +28 -14
  209. package/lib/commonjs/utils/LazyNativeEmitter.js.map +1 -1
  210. package/lib/commonjs/utils/NativeUpdatedValue.js +31 -13
  211. package/lib/commonjs/utils/NativeUpdatedValue.js.map +1 -1
  212. package/lib/commonjs/utils/getTrackIdentity.js +24 -0
  213. package/lib/commonjs/utils/getTrackIdentity.js.map +1 -0
  214. package/lib/commonjs/utils/useNativeValueRefreshedBy.js +33 -0
  215. package/lib/commonjs/utils/useNativeValueRefreshedBy.js.map +1 -0
  216. package/lib/commonjs/web/NativeAudioBrowser.js +200 -75
  217. package/lib/commonjs/web/NativeAudioBrowser.js.map +1 -1
  218. package/lib/commonjs/web/TrackPlayer/LoadAttempt.js +37 -0
  219. package/lib/commonjs/web/TrackPlayer/LoadAttempt.js.map +1 -0
  220. package/lib/commonjs/web/TrackPlayer/PlaybackStateMachine.js +18 -2
  221. package/lib/commonjs/web/TrackPlayer/PlaybackStateMachine.js.map +1 -1
  222. package/lib/commonjs/web/TrackPlayer/Player.js +254 -39
  223. package/lib/commonjs/web/TrackPlayer/Player.js.map +1 -1
  224. package/lib/commonjs/web/TrackPlayer/QueueManager.js +14 -0
  225. package/lib/commonjs/web/TrackPlayer/QueueManager.js.map +1 -1
  226. package/lib/commonjs/web/TrackPlayer/QueuePlayer.js +33 -12
  227. package/lib/commonjs/web/TrackPlayer/QueuePlayer.js.map +1 -1
  228. package/lib/commonjs/web/browser/BrowserManager.js +175 -100
  229. package/lib/commonjs/web/browser/BrowserManager.js.map +1 -1
  230. package/lib/commonjs/web/browser/FavoriteManager.js +30 -21
  231. package/lib/commonjs/web/browser/FavoriteManager.js.map +1 -1
  232. package/lib/commonjs/web/browser/SearchManager.js +18 -23
  233. package/lib/commonjs/web/browser/SearchManager.js.map +1 -1
  234. package/lib/commonjs/web/browser/assertBrowsePageShape.js +2 -2
  235. package/lib/commonjs/web/browser/assertBrowsePageShape.js.map +1 -1
  236. package/lib/commonjs/web/browser/classifyTrackNavigation.js +9 -9
  237. package/lib/commonjs/web/browser/classifyTrackNavigation.js.map +1 -1
  238. package/lib/commonjs/web/browser/sections.js +89 -0
  239. package/lib/commonjs/web/browser/sections.js.map +1 -0
  240. package/lib/commonjs/web/http/RequestConfigBuilder.js +110 -27
  241. package/lib/commonjs/web/http/RequestConfigBuilder.js.map +1 -1
  242. package/lib/commonjs/web/http/followMediaRedirect.js +219 -0
  243. package/lib/commonjs/web/http/followMediaRedirect.js.map +1 -0
  244. package/lib/commonjs/web/player/NowPlayingManager.js +4 -3
  245. package/lib/commonjs/web/player/NowPlayingManager.js.map +1 -1
  246. package/lib/commonjs/web/util/BrowserPathHelper.js +56 -11
  247. package/lib/commonjs/web/util/BrowserPathHelper.js.map +1 -1
  248. package/lib/module/AudioBrowser.js +2 -1
  249. package/lib/module/AudioBrowser.js.map +1 -1
  250. package/lib/module/CLAUDE.md +52 -0
  251. package/lib/module/features/browser-config.js +12 -8
  252. package/lib/module/features/browser-config.js.map +1 -1
  253. package/lib/module/features/browser.js +11 -3
  254. package/lib/module/features/browser.js.map +1 -1
  255. package/lib/module/features/carConnection.js +1 -1
  256. package/lib/module/features/equalizer.js +1 -1
  257. package/lib/module/features/errors.js +3 -3
  258. package/lib/module/features/favorites.js +14 -11
  259. package/lib/module/features/favorites.js.map +1 -1
  260. package/lib/module/features/gate.js +16 -1
  261. package/lib/module/features/gate.js.map +1 -1
  262. package/lib/module/features/metadata.js +20 -3
  263. package/lib/module/features/metadata.js.map +1 -1
  264. package/lib/module/features/network.js +1 -1
  265. package/lib/module/features/nowPlaying.js +1 -1
  266. package/lib/module/features/output.js +1 -1
  267. package/lib/module/features/playback/controls.js +4 -2
  268. package/lib/module/features/playback/controls.js.map +1 -1
  269. package/lib/module/features/playback/playWhenReady.js +1 -1
  270. package/lib/module/features/playback/playing.js +1 -1
  271. package/lib/module/features/playback/progress.js +3 -2
  272. package/lib/module/features/playback/progress.js.map +1 -1
  273. package/lib/module/features/playback/rate.js +8 -1
  274. package/lib/module/features/playback/rate.js.map +1 -1
  275. package/lib/module/features/playback/state.js +3 -4
  276. package/lib/module/features/playback/state.js.map +1 -1
  277. package/lib/module/features/playback/trackPlaybackTime.js +0 -5
  278. package/lib/module/features/playback/trackPlaybackTime.js.map +1 -1
  279. package/lib/module/features/playback/volume.js +1 -1
  280. package/lib/module/features/player/options.js +47 -32
  281. package/lib/module/features/player/options.js.map +1 -1
  282. package/lib/module/features/player/setup.js +17 -8
  283. package/lib/module/features/player/setup.js.map +1 -1
  284. package/lib/module/features/player/validateOptions.js +19 -0
  285. package/lib/module/features/player/validateOptions.js.map +1 -0
  286. package/lib/module/features/queue/activeTrack.js +15 -4
  287. package/lib/module/features/queue/activeTrack.js.map +1 -1
  288. package/lib/module/features/queue/queue.js +13 -6
  289. package/lib/module/features/queue/queue.js.map +1 -1
  290. package/lib/module/features/queue/repeatMode.js +1 -1
  291. package/lib/module/features/queue/shuffle.js +1 -1
  292. package/lib/module/features/remoteControls.js +13 -92
  293. package/lib/module/features/remoteControls.js.map +1 -1
  294. package/lib/module/features/sleepTimer.js +13 -1
  295. package/lib/module/features/sleepTimer.js.map +1 -1
  296. package/lib/module/test-utils/reactNativeStub.js +58 -0
  297. package/lib/module/test-utils/reactNativeStub.js.map +1 -0
  298. package/lib/module/utils/LazyNativeEmitter.js +28 -14
  299. package/lib/module/utils/LazyNativeEmitter.js.map +1 -1
  300. package/lib/module/utils/NativeUpdatedValue.js +31 -13
  301. package/lib/module/utils/NativeUpdatedValue.js.map +1 -1
  302. package/lib/module/utils/getTrackIdentity.js +20 -0
  303. package/lib/module/utils/getTrackIdentity.js.map +1 -0
  304. package/lib/module/utils/useNativeValueRefreshedBy.js +29 -0
  305. package/lib/module/utils/useNativeValueRefreshedBy.js.map +1 -0
  306. package/lib/module/web/NativeAudioBrowser.js +200 -75
  307. package/lib/module/web/NativeAudioBrowser.js.map +1 -1
  308. package/lib/module/web/TrackPlayer/LoadAttempt.js +32 -0
  309. package/lib/module/web/TrackPlayer/LoadAttempt.js.map +1 -0
  310. package/lib/module/web/TrackPlayer/PlaybackStateMachine.js +18 -2
  311. package/lib/module/web/TrackPlayer/PlaybackStateMachine.js.map +1 -1
  312. package/lib/module/web/TrackPlayer/Player.js +254 -39
  313. package/lib/module/web/TrackPlayer/Player.js.map +1 -1
  314. package/lib/module/web/TrackPlayer/QueueManager.js +14 -0
  315. package/lib/module/web/TrackPlayer/QueueManager.js.map +1 -1
  316. package/lib/module/web/TrackPlayer/QueuePlayer.js +33 -12
  317. package/lib/module/web/TrackPlayer/QueuePlayer.js.map +1 -1
  318. package/lib/module/web/browser/BrowserManager.js +175 -100
  319. package/lib/module/web/browser/BrowserManager.js.map +1 -1
  320. package/lib/module/web/browser/FavoriteManager.js +31 -21
  321. package/lib/module/web/browser/FavoriteManager.js.map +1 -1
  322. package/lib/module/web/browser/SearchManager.js +18 -23
  323. package/lib/module/web/browser/SearchManager.js.map +1 -1
  324. package/lib/module/web/browser/assertBrowsePageShape.js +2 -2
  325. package/lib/module/web/browser/assertBrowsePageShape.js.map +1 -1
  326. package/lib/module/web/browser/classifyTrackNavigation.js +9 -9
  327. package/lib/module/web/browser/classifyTrackNavigation.js.map +1 -1
  328. package/lib/module/web/browser/sections.js +83 -0
  329. package/lib/module/web/browser/sections.js.map +1 -0
  330. package/lib/module/web/http/RequestConfigBuilder.js +110 -27
  331. package/lib/module/web/http/RequestConfigBuilder.js.map +1 -1
  332. package/lib/module/web/http/followMediaRedirect.js +215 -0
  333. package/lib/module/web/http/followMediaRedirect.js.map +1 -0
  334. package/lib/module/web/player/NowPlayingManager.js +4 -3
  335. package/lib/module/web/player/NowPlayingManager.js.map +1 -1
  336. package/lib/module/web/util/BrowserPathHelper.js +56 -11
  337. package/lib/module/web/util/BrowserPathHelper.js.map +1 -1
  338. package/lib/typescript/package.json +1 -0
  339. package/lib/typescript/src/AudioBrowser.d.ts +1 -1
  340. package/lib/typescript/src/AudioBrowser.d.ts.map +1 -1
  341. package/lib/typescript/src/features/browser-config.d.ts.map +1 -1
  342. package/lib/typescript/src/features/browser.d.ts +10 -2
  343. package/lib/typescript/src/features/browser.d.ts.map +1 -1
  344. package/lib/typescript/src/features/carConnection.d.ts +1 -1
  345. package/lib/typescript/src/features/equalizer.d.ts +1 -1
  346. package/lib/typescript/src/features/errors.d.ts +3 -3
  347. package/lib/typescript/src/features/favorites.d.ts +14 -11
  348. package/lib/typescript/src/features/favorites.d.ts.map +1 -1
  349. package/lib/typescript/src/features/gate.d.ts +18 -2
  350. package/lib/typescript/src/features/gate.d.ts.map +1 -1
  351. package/lib/typescript/src/features/metadata.d.ts +20 -3
  352. package/lib/typescript/src/features/metadata.d.ts.map +1 -1
  353. package/lib/typescript/src/features/network.d.ts +1 -1
  354. package/lib/typescript/src/features/nowPlaying.d.ts +1 -1
  355. package/lib/typescript/src/features/output.d.ts +1 -1
  356. package/lib/typescript/src/features/playback/controls.d.ts +4 -2
  357. package/lib/typescript/src/features/playback/controls.d.ts.map +1 -1
  358. package/lib/typescript/src/features/playback/playWhenReady.d.ts +1 -1
  359. package/lib/typescript/src/features/playback/playing.d.ts +1 -1
  360. package/lib/typescript/src/features/playback/progress.d.ts +1 -1
  361. package/lib/typescript/src/features/playback/progress.d.ts.map +1 -1
  362. package/lib/typescript/src/features/playback/rate.d.ts +8 -1
  363. package/lib/typescript/src/features/playback/rate.d.ts.map +1 -1
  364. package/lib/typescript/src/features/playback/state.d.ts +3 -4
  365. package/lib/typescript/src/features/playback/state.d.ts.map +1 -1
  366. package/lib/typescript/src/features/playback/trackPlaybackTime.d.ts +1 -1
  367. package/lib/typescript/src/features/playback/trackPlaybackTime.d.ts.map +1 -1
  368. package/lib/typescript/src/features/playback/volume.d.ts +1 -1
  369. package/lib/typescript/src/features/player/options.d.ts +108 -56
  370. package/lib/typescript/src/features/player/options.d.ts.map +1 -1
  371. package/lib/typescript/src/features/player/setup.d.ts +14 -4
  372. package/lib/typescript/src/features/player/setup.d.ts.map +1 -1
  373. package/lib/typescript/src/features/player/validateOptions.d.ts +2 -0
  374. package/lib/typescript/src/features/player/validateOptions.d.ts.map +1 -0
  375. package/lib/typescript/src/features/queue/activeTrack.d.ts +9 -2
  376. package/lib/typescript/src/features/queue/activeTrack.d.ts.map +1 -1
  377. package/lib/typescript/src/features/queue/queue.d.ts +7 -4
  378. package/lib/typescript/src/features/queue/queue.d.ts.map +1 -1
  379. package/lib/typescript/src/features/queue/repeatMode.d.ts +1 -1
  380. package/lib/typescript/src/features/queue/shuffle.d.ts +1 -1
  381. package/lib/typescript/src/features/remoteControls.d.ts +23 -22
  382. package/lib/typescript/src/features/remoteControls.d.ts.map +1 -1
  383. package/lib/typescript/src/features/sleepTimer.d.ts +1 -1
  384. package/lib/typescript/src/features/sleepTimer.d.ts.map +1 -1
  385. package/lib/typescript/src/test-utils/reactNativeStub.d.ts +36 -0
  386. package/lib/typescript/src/test-utils/reactNativeStub.d.ts.map +1 -0
  387. package/lib/typescript/src/types/browser-native.d.ts +3 -2
  388. package/lib/typescript/src/types/browser-native.d.ts.map +1 -1
  389. package/lib/typescript/src/types/browser-nodes.d.ts +380 -126
  390. package/lib/typescript/src/types/browser-nodes.d.ts.map +1 -1
  391. package/lib/typescript/src/types/browser.d.ts +82 -57
  392. package/lib/typescript/src/types/browser.d.ts.map +1 -1
  393. package/lib/typescript/src/utils/LazyNativeEmitter.d.ts +19 -16
  394. package/lib/typescript/src/utils/LazyNativeEmitter.d.ts.map +1 -1
  395. package/lib/typescript/src/utils/NativeUpdatedValue.d.ts +24 -19
  396. package/lib/typescript/src/utils/NativeUpdatedValue.d.ts.map +1 -1
  397. package/lib/typescript/src/utils/getTrackIdentity.d.ts +18 -0
  398. package/lib/typescript/src/utils/getTrackIdentity.d.ts.map +1 -0
  399. package/lib/typescript/src/utils/useNativeValueRefreshedBy.d.ts +21 -0
  400. package/lib/typescript/src/utils/useNativeValueRefreshedBy.d.ts.map +1 -0
  401. package/nitrogen/generated/android/AudioBrowser+autolinking.cmake +1 -2
  402. package/nitrogen/generated/android/AudioBrowserOnLoad.cpp +2 -0
  403. package/nitrogen/generated/android/c++/JAndroidOptions.hpp +10 -10
  404. package/nitrogen/generated/android/c++/{JFavoritesMatchMode.hpp → JArtworkRendering.hpp} +15 -15
  405. package/nitrogen/generated/android/c++/JArtworkRequestConfig.hpp +8 -3
  406. package/nitrogen/generated/android/c++/JBrowseResult.hpp +16 -4
  407. package/nitrogen/generated/android/c++/JCarPlayPlayingIndicatorLocation.hpp +58 -0
  408. package/nitrogen/generated/android/c++/JCardImage.hpp +58 -0
  409. package/nitrogen/generated/android/c++/JFavoriteChangedEvent.hpp +8 -3
  410. package/nitrogen/generated/android/c++/JFormatNowPlayingParams.hpp +8 -3
  411. package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_RequestConfig___Track.hpp +8 -3
  412. package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__optional_NowPlayingUpdate____FormatNowPlayingParams.hpp +8 -3
  413. package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__optional_std__string____Track.hpp +8 -3
  414. package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__shared_ptr_Promise_RequestConfig_____Track.hpp +8 -3
  415. package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__shared_ptr_Promise_std__vector_Track______SearchParams.hpp +8 -2
  416. package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__shared_ptr_Promise_void_____TrackLoadEvent.hpp +8 -2
  417. package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__string__.hpp +102 -0
  418. package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__variant_ResolvedTrack__BrowseError__std__shared_ptr_Promise_std__variant_ResolvedTrack__BrowseError_______BrowserSourceCallbackParam.hpp +16 -4
  419. package/nitrogen/generated/android/c++/JFunc_void_FavoriteChangedEvent.hpp +8 -3
  420. package/nitrogen/generated/android/c++/JFunc_void_Options.hpp +7 -10
  421. package/nitrogen/generated/android/c++/JFunc_void_PlaybackActiveTrackChangedEvent.hpp +8 -3
  422. package/nitrogen/generated/android/c++/JFunc_void_std__optional_ResolvedTrack_.hpp +15 -3
  423. package/nitrogen/generated/android/c++/JFunc_void_std__vector_Track_.hpp +8 -2
  424. package/nitrogen/generated/android/c++/JGridTile.hpp +61 -0
  425. package/nitrogen/generated/android/c++/JHybridAudioBrowserSpec.cpp +45 -25
  426. package/nitrogen/generated/android/c++/JHybridAudioBrowserSpec.hpp +1 -1
  427. package/nitrogen/generated/android/c++/JIOSOptions.hpp +9 -3
  428. package/nitrogen/generated/android/c++/JImageShape.hpp +58 -0
  429. package/nitrogen/generated/android/c++/JMediaRequestConfig.hpp +8 -3
  430. package/nitrogen/generated/android/c++/JNativeBrowserConfiguration.hpp +36 -11
  431. package/nitrogen/generated/android/c++/JNativeRouteEntry.hpp +14 -2
  432. package/nitrogen/generated/android/c++/JNativeSetupPlayerOptions.hpp +15 -12
  433. package/nitrogen/generated/android/c++/JNativeUpdateOptions.hpp +7 -10
  434. package/nitrogen/generated/android/c++/JNitroAndroidUpdateOptions.hpp +10 -10
  435. package/nitrogen/generated/android/c++/JNitroIOSUpdateOptions.hpp +9 -3
  436. package/nitrogen/generated/android/c++/JOptions.hpp +7 -10
  437. package/nitrogen/generated/android/c++/JPlaybackActiveTrackChangedEvent.hpp +8 -3
  438. package/nitrogen/generated/android/c++/JPlayerCapabilities.hpp +5 -11
  439. package/nitrogen/generated/android/c++/{JNotificationButton.hpp → JRemoteButton.hpp} +19 -19
  440. package/nitrogen/generated/android/c++/JRemoteButtonLayout.hpp +86 -0
  441. package/nitrogen/generated/android/c++/JResolvedTrack.hpp +57 -49
  442. package/nitrogen/generated/android/c++/JSection.hpp +116 -0
  443. package/nitrogen/generated/android/c++/JSectionStyle.hpp +96 -0
  444. package/nitrogen/generated/android/c++/JStyleDisplay.hpp +58 -0
  445. package/nitrogen/generated/android/c++/JTrack.hpp +25 -46
  446. package/nitrogen/generated/android/c++/JTrackLoadEvent.hpp +8 -2
  447. package/nitrogen/generated/android/c++/JTrackStyle.hpp +46 -18
  448. package/nitrogen/generated/android/c++/JVariant_NullType_RemoteButtonLayout.cpp +26 -0
  449. package/nitrogen/generated/android/c++/JVariant_NullType_RemoteButtonLayout.hpp +75 -0
  450. package/nitrogen/generated/android/c++/JVariant_ResolvedTrack_BrowseError_Promise_BrowseResult_.hpp +16 -4
  451. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/AndroidOptions.kt +3 -3
  452. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/{FavoritesMatchMode.kt → ArtworkRendering.kt} +5 -5
  453. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/CarPlayPlayingIndicatorLocation.kt +23 -0
  454. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/CardImage.kt +23 -0
  455. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_std__shared_ptr_Promise_std__string__.kt +80 -0
  456. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/GridTile.kt +24 -0
  457. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/HybridAudioBrowserSpec.kt +1 -1
  458. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/IOSOptions.kt +6 -3
  459. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/ImageShape.kt +23 -0
  460. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NativeBrowserConfiguration.kt +8 -5
  461. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NitroAndroidUpdateOptions.kt +3 -3
  462. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NitroIOSUpdateOptions.kt +6 -3
  463. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/PlayerCapabilities.kt +2 -2
  464. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/{NotificationButton.kt → RemoteButton.kt} +3 -3
  465. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/RemoteButtonLayout.kt +44 -0
  466. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/ResolvedTrack.kt +12 -15
  467. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/{FavoriteConfig.kt → Section.kt} +15 -6
  468. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/SectionStyle.kt +59 -0
  469. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/StyleDisplay.kt +23 -0
  470. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Track.kt +6 -12
  471. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/TrackStyle.kt +35 -5
  472. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/{Variant_NullType_NotificationButtonLayout.kt → Variant_NullType_RemoteButtonLayout.kt} +9 -9
  473. package/nitrogen/generated/ios/AudioBrowser-Swift-Cxx-Bridge.cpp +9 -0
  474. package/nitrogen/generated/ios/AudioBrowser-Swift-Cxx-Bridge.hpp +244 -133
  475. package/nitrogen/generated/ios/AudioBrowser-Swift-Cxx-Umbrella.hpp +31 -16
  476. package/nitrogen/generated/ios/c++/HybridAudioBrowserSpecSwift.hpp +33 -18
  477. package/nitrogen/generated/ios/swift/AndroidOptions.swift +12 -12
  478. package/nitrogen/generated/ios/swift/ArtworkRendering.swift +40 -0
  479. package/nitrogen/generated/ios/swift/CarPlayPlayingIndicatorLocation.swift +40 -0
  480. package/nitrogen/generated/ios/swift/CardImage.swift +40 -0
  481. package/nitrogen/generated/ios/swift/Func_std__shared_ptr_Promise_std__string__.swift +54 -0
  482. package/nitrogen/generated/ios/swift/GridTile.swift +44 -0
  483. package/nitrogen/generated/ios/swift/HybridAudioBrowserSpec.swift +1 -1
  484. package/nitrogen/generated/ios/swift/HybridAudioBrowserSpec_cxx.swift +2 -2
  485. package/nitrogen/generated/ios/swift/IOSOptions.swift +7 -2
  486. package/nitrogen/generated/ios/swift/ImageShape.swift +40 -0
  487. package/nitrogen/generated/ios/swift/NativeBrowserConfiguration.swift +52 -5
  488. package/nitrogen/generated/ios/swift/NitroAndroidUpdateOptions.swift +12 -12
  489. package/nitrogen/generated/ios/swift/NitroIOSUpdateOptions.swift +12 -1
  490. package/nitrogen/generated/ios/swift/PlayerCapabilities.swift +8 -27
  491. package/nitrogen/generated/ios/swift/{NotificationButton.swift → RemoteButton.swift} +6 -6
  492. package/nitrogen/generated/ios/swift/RemoteButtonLayout.swift +57 -0
  493. package/nitrogen/generated/ios/swift/ResolvedTrack.swift +62 -73
  494. package/nitrogen/generated/ios/swift/Section.swift +82 -0
  495. package/nitrogen/generated/ios/swift/SectionStyle.swift +133 -0
  496. package/nitrogen/generated/ios/swift/StyleDisplay.swift +40 -0
  497. package/nitrogen/generated/ios/swift/Track.swift +28 -63
  498. package/nitrogen/generated/ios/swift/TrackStyle.swift +86 -22
  499. package/nitrogen/generated/ios/swift/{Variant_NullType_NotificationButtonLayout.swift → Variant_NullType_RemoteButtonLayout.swift} +3 -3
  500. package/nitrogen/generated/shared/c++/AndroidOptions.hpp +8 -8
  501. package/nitrogen/generated/shared/c++/{FavoritesMatchMode.hpp → ArtworkRendering.hpp} +17 -17
  502. package/nitrogen/generated/shared/c++/CarPlayPlayingIndicatorLocation.hpp +76 -0
  503. package/nitrogen/generated/shared/c++/CardImage.hpp +76 -0
  504. package/nitrogen/generated/shared/c++/GridTile.hpp +80 -0
  505. package/nitrogen/generated/shared/c++/HybridAudioBrowserSpec.cpp +1 -1
  506. package/nitrogen/generated/shared/c++/HybridAudioBrowserSpec.hpp +1 -1
  507. package/nitrogen/generated/shared/c++/IOSOptions.hpp +9 -2
  508. package/nitrogen/generated/shared/c++/ImageShape.hpp +76 -0
  509. package/nitrogen/generated/shared/c++/NativeBrowserConfiguration.hpp +10 -6
  510. package/nitrogen/generated/shared/c++/NitroAndroidUpdateOptions.hpp +8 -8
  511. package/nitrogen/generated/shared/c++/NitroIOSUpdateOptions.hpp +9 -2
  512. package/nitrogen/generated/shared/c++/PlayerCapabilities.hpp +6 -9
  513. package/nitrogen/generated/shared/c++/{NotificationButton.hpp → RemoteButton.hpp} +19 -19
  514. package/nitrogen/generated/shared/c++/RemoteButtonLayout.hpp +94 -0
  515. package/nitrogen/generated/shared/c++/ResolvedTrack.hpp +33 -37
  516. package/nitrogen/generated/shared/c++/Section.hpp +102 -0
  517. package/nitrogen/generated/shared/c++/SectionStyle.hpp +126 -0
  518. package/nitrogen/generated/shared/c++/StyleDisplay.hpp +76 -0
  519. package/nitrogen/generated/shared/c++/Track.hpp +18 -30
  520. package/nitrogen/generated/shared/c++/TrackStyle.hpp +73 -34
  521. package/package.json +24 -11
  522. package/src/AudioBrowser.ts +2 -1
  523. package/src/CLAUDE.md +52 -0
  524. package/src/features/battery.test.ts +79 -0
  525. package/src/features/browser-config.test.ts +21 -6
  526. package/src/features/browser-config.ts +12 -8
  527. package/src/features/browser.test.ts +1 -1
  528. package/src/features/browser.ts +11 -3
  529. package/src/features/carConnection.ts +1 -1
  530. package/src/features/equalizer.ts +1 -1
  531. package/src/features/errors.ts +3 -3
  532. package/src/features/favorites.ts +14 -11
  533. package/src/features/gate.ts +16 -1
  534. package/src/features/hook-wiring.test.ts +302 -0
  535. package/src/features/metadata.ts +20 -3
  536. package/src/features/network.ts +1 -1
  537. package/src/features/nowPlaying.ts +1 -1
  538. package/src/features/output.ts +1 -1
  539. package/src/features/playback/controls.ts +4 -2
  540. package/src/features/playback/playWhenReady.ts +1 -1
  541. package/src/features/playback/playing.ts +1 -1
  542. package/src/features/playback/progress.test.ts +169 -0
  543. package/src/features/playback/progress.ts +3 -2
  544. package/src/features/playback/rate.ts +8 -1
  545. package/src/features/playback/state.ts +3 -4
  546. package/src/features/playback/trackPlaybackTime.test.ts +16 -6
  547. package/src/features/playback/trackPlaybackTime.ts +1 -6
  548. package/src/features/playback/volume.ts +1 -1
  549. package/src/features/player/options.ts +126 -76
  550. package/src/features/player/setup.test.ts +24 -7
  551. package/src/features/player/setup.ts +22 -10
  552. package/src/features/player/validateOptions.ts +21 -0
  553. package/src/features/queue/activeTrack.ts +15 -4
  554. package/src/features/queue/queue.ts +13 -6
  555. package/src/features/queue/repeatMode.ts +1 -1
  556. package/src/features/queue/shuffle.ts +1 -1
  557. package/src/features/remoteControls.ts +13 -92
  558. package/src/features/sleepTimer.test.ts +172 -0
  559. package/src/features/sleepTimer.ts +9 -1
  560. package/src/nitro-stub-drift.test.ts +277 -0
  561. package/src/public-surface.test.ts +147 -0
  562. package/src/specs/audio-browser.nitro.ts +5 -4
  563. package/src/style-resolution.test.ts +210 -0
  564. package/src/test-utils/reactNativeStub.ts +60 -0
  565. package/src/types/browser-native.ts +7 -3
  566. package/src/types/browser-nodes.ts +396 -134
  567. package/src/types/browser.ts +85 -59
  568. package/src/utils/LazyNativeEmitter.ts +28 -15
  569. package/src/utils/NativeUpdatedValue.ts +29 -13
  570. package/src/utils/getTrackIdentity.ts +20 -0
  571. package/src/utils/useDebug.test.ts +182 -0
  572. package/src/utils/useNativeUpdatedValue.test.ts +103 -0
  573. package/src/utils/useNativeValueRefreshedBy.ts +38 -0
  574. package/src/web/NativeAudioBrowser.playWhenReady.test.ts +232 -2
  575. package/src/web/NativeAudioBrowser.ts +239 -82
  576. package/src/web/TrackPlayer/LoadAttempt.ts +29 -0
  577. package/src/web/TrackPlayer/PlaybackStateMachine.test.ts +60 -13
  578. package/src/web/TrackPlayer/PlaybackStateMachine.ts +22 -6
  579. package/src/web/TrackPlayer/Player.dispatch.test.ts +5 -3
  580. package/src/web/TrackPlayer/Player.load.test.ts +137 -1
  581. package/src/web/TrackPlayer/Player.ts +284 -37
  582. package/src/web/TrackPlayer/QueueManager.test.ts +29 -0
  583. package/src/web/TrackPlayer/QueueManager.ts +14 -0
  584. package/src/web/TrackPlayer/QueuePlayer.ts +33 -14
  585. package/src/web/__tests__/lifecycle.test.ts +345 -0
  586. package/src/web/__tests__/lifecycleHarness.ts +351 -0
  587. package/src/web/__tests__/loadEdgeCases.test.ts +246 -0
  588. package/src/web/__tests__/loadSupersession.test.ts +175 -0
  589. package/src/web/__tests__/retry.test.ts +169 -0
  590. package/src/web/browser/BrowserManager.ts +209 -111
  591. package/src/web/browser/FavoriteManager.test.ts +84 -0
  592. package/src/web/browser/FavoriteManager.ts +28 -23
  593. package/src/web/browser/SearchManager.test.ts +75 -0
  594. package/src/web/browser/SearchManager.ts +25 -28
  595. package/src/web/browser/__tests__/artwork-resolution.test.ts +117 -0
  596. package/src/web/browser/__tests__/layer-resolver.test.ts +35 -0
  597. package/src/web/browser/__tests__/search-artwork.test.ts +46 -0
  598. package/src/web/browser/__tests__/search-navigation.test.ts +76 -0
  599. package/src/web/browser/assertBrowsePageShape.test.ts +1 -1
  600. package/src/web/browser/assertBrowsePageShape.ts +5 -3
  601. package/src/web/browser/classifyTrackNavigation.test.ts +10 -8
  602. package/src/web/browser/classifyTrackNavigation.ts +9 -9
  603. package/src/web/browser/parseSearchResponse.test.ts +8 -2
  604. package/src/web/browser/sections.test.ts +91 -0
  605. package/src/web/browser/sections.ts +72 -0
  606. package/src/web/http/RequestConfigBuilder.test.ts +241 -1
  607. package/src/web/http/RequestConfigBuilder.ts +140 -33
  608. package/src/web/http/followMediaRedirect.test.ts +289 -0
  609. package/src/web/http/followMediaRedirect.ts +253 -0
  610. package/src/web/player/NowPlayingManager.ts +4 -3
  611. package/src/web/util/BrowserPathHelper.test.ts +52 -0
  612. package/src/web/util/BrowserPathHelper.ts +61 -13
  613. package/website/guide/android-auto.md +114 -0
  614. package/website/guide/android-certificates.md +409 -0
  615. package/website/guide/artwork.md +255 -0
  616. package/website/guide/audio-output.md +135 -0
  617. package/website/guide/automotive.md +86 -0
  618. package/website/guide/basic-usage.md +151 -0
  619. package/website/guide/battery.md +115 -0
  620. package/website/guide/browser.md +581 -0
  621. package/website/guide/carplay.md +620 -0
  622. package/website/guide/configuration.md +173 -0
  623. package/website/guide/equalizer.md +231 -0
  624. package/website/guide/errors.md +310 -0
  625. package/website/guide/favorites.md +154 -0
  626. package/website/guide/gate.md +143 -0
  627. package/website/guide/getting-started.md +46 -0
  628. package/website/guide/hooks.md +238 -0
  629. package/website/guide/live-streams.md +125 -0
  630. package/website/guide/metadata.md +239 -0
  631. package/website/guide/migrating-from-track-player.md +244 -0
  632. package/website/guide/native-callback-fetch.md +127 -0
  633. package/website/guide/network.md +86 -0
  634. package/website/guide/now-playing.md +175 -0
  635. package/website/guide/playback.md +328 -0
  636. package/website/guide/queue.md +300 -0
  637. package/website/guide/remote-controls.md +256 -0
  638. package/website/guide/search.md +255 -0
  639. package/website/guide/sleep-timer.md +268 -0
  640. package/website/guide/track.md +247 -0
  641. package/ios/CarPlay/ImageRowItem+CarPlay.swift +0 -19
  642. package/ios/Model/MediaURL.swift +0 -67
  643. package/nitrogen/generated/android/c++/JFavoriteConfig.hpp +0 -58
  644. package/nitrogen/generated/android/c++/JImageRowItem.hpp +0 -105
  645. package/nitrogen/generated/android/c++/JNotificationButtonLayout.hpp +0 -94
  646. package/nitrogen/generated/android/c++/JVariant_Boolean_FavoriteConfig.cpp +0 -26
  647. package/nitrogen/generated/android/c++/JVariant_Boolean_FavoriteConfig.hpp +0 -71
  648. package/nitrogen/generated/android/c++/JVariant_NullType_NotificationButtonLayout.cpp +0 -26
  649. package/nitrogen/generated/android/c++/JVariant_NullType_NotificationButtonLayout.hpp +0 -75
  650. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/ImageRowItem.kt +0 -68
  651. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NotificationButtonLayout.kt +0 -50
  652. package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Variant_Boolean_FavoriteConfig.kt +0 -53
  653. package/nitrogen/generated/ios/swift/FavoriteConfig.swift +0 -29
  654. package/nitrogen/generated/ios/swift/FavoritesMatchMode.swift +0 -40
  655. package/nitrogen/generated/ios/swift/ImageRowItem.swift +0 -195
  656. package/nitrogen/generated/ios/swift/NotificationButtonLayout.swift +0 -92
  657. package/nitrogen/generated/ios/swift/Variant_Bool_FavoriteConfig.swift +0 -18
  658. package/nitrogen/generated/shared/c++/FavoriteConfig.hpp +0 -84
  659. package/nitrogen/generated/shared/c++/ImageRowItem.hpp +0 -129
  660. package/nitrogen/generated/shared/c++/NotificationButtonLayout.hpp +0 -102
@@ -1,6 +1,229 @@
1
1
  import type { CarPlaySiriListButtonPosition, HttpMethod } from './browser'
2
2
 
3
- export type TrackStyle = 'list' | 'grid'
3
+ /**
4
+ * How a holder's *children* lay out — CSS's inner display type, honored
5
+ * literally (`display: 'grid'` in CSS describes the children, not the
6
+ * element).
7
+ *
8
+ * - `'list'` (default) — full-width rows on every surface.
9
+ * - `'grid'` — artwork tiles; wraps unless {@link SectionStyle.gridWrap}
10
+ * is `false`. Tiles presume artwork: an artwork-less child renders a
11
+ * placeholder tile plus its title. On CarPlay a *wrapping* grid needs
12
+ * iOS 26+ and renders a list before that; a single-line grid renders
13
+ * on every OS.
14
+ */
15
+ export type StyleDisplay = 'list' | 'grid'
16
+
17
+ /**
18
+ * How a track's artwork is rendered.
19
+ *
20
+ * - `'original'` (default) — drawn as-is.
21
+ * - `'stencil'` — treated as a monochrome glyph and tinted to the
22
+ * surface's appearance (black in light mode, white in dark). For
23
+ * monochrome logos and icons; full-color artwork should stay
24
+ * `'original'`.
25
+ */
26
+ export type ArtworkRendering = 'original' | 'stencil'
27
+
28
+ /**
29
+ * The shape a grid tile's artwork is cropped to.
30
+ *
31
+ * - `'rounded-rectangle'` (default) — the standard tile crop.
32
+ * - `'circular'` — the standard presentation for *people* (artists, hosts,
33
+ * DJs). Shape encodes the kind of item, so mixed grids legitimately
34
+ * render circular artists next to rounded albums.
35
+ *
36
+ * Named after Apple's `imageShape` parameter (a platform passthrough), and
37
+ * deliberately without a grid prefix: every tile presentation that takes a
38
+ * shape reads the same property.
39
+ */
40
+ export type ImageShape = 'circular' | 'rounded-rectangle'
41
+
42
+ /**
43
+ * The kind of tile a grid renders.
44
+ *
45
+ * - `'plain'` (default) — artwork tiles with a title.
46
+ * - `'card'` — a larger card with title/subtitle and a
47
+ * {@link TrackStyle.cardTint} color; its image mode is
48
+ * {@link TrackStyle.cardImage}. Cards have no shape.
49
+ * - `'condensed'` — a denser cell carrying title + subtitle; takes
50
+ * {@link TrackStyle.imageShape} and {@link TrackStyle.accessorySymbol}
51
+ * like a plain tile.
52
+ *
53
+ * Element families are mutually exclusive within a container, so this is
54
+ * a container property — hence the enum, and the `grid` prefix.
55
+ */
56
+ export type GridTile = 'plain' | 'card' | 'condensed'
57
+
58
+ /**
59
+ * How a card tile uses its image.
60
+ *
61
+ * - `'normal'` (default) — image above the labels;
62
+ * {@link TrackStyle.cardTint} colors a gradient behind the labels.
63
+ * - `'background'` — the image fills the card full-height with the labels
64
+ * overlaid; `cardTint` becomes the color behind them. Selects the larger
65
+ * artwork target size.
66
+ *
67
+ * An enum rather than a boolean: it names the card's image mode and
68
+ * leaves room for future modes.
69
+ */
70
+ export type CardImage = 'normal' | 'background'
71
+
72
+ /**
73
+ * The style declaration block a {@link Track} may carry: *inherited item
74
+ * properties* (resolved `track ?? section ?? page ?? default`, per
75
+ * property — they travel with the track) plus the *positional*
76
+ * {@link TrackStyle.display} (each holder's own children; never
77
+ * inherited).
78
+ *
79
+ * Rules governing every property:
80
+ *
81
+ * - **Declarations are aspirational.** Each surface renders the
82
+ * properties it understands and ignores the rest — inert, never an
83
+ * error.
84
+ * - **Presentation only.** No style property affects queue scope,
85
+ * playback, or navigation: rendering may truncate what is visible, it
86
+ * never changes what plays. (This is why {@link Track.disabled} is NOT
87
+ * here — it carries behavior, so it lives on Track as a content fact.)
88
+ * - **The inheritance boundary**: a handle's block styles the handle; a
89
+ * page's block is inherited by the page's descendants; nothing
90
+ * inherits across resolution.
91
+ */
92
+ export interface TrackStyle {
93
+ /**
94
+ * How this entity's *children* lay out. The meaning is uniform at
95
+ * every position; only the children differ:
96
+ *
97
+ * - On a {@link Section}: the section's children.
98
+ * - On a resolved page ({@link ResolvedTrack.style}): the declaration
99
+ * for the whole page — a section overrides it for its own children.
100
+ * - On a browsable {@link Track} (the handle): the *advertised*
101
+ * layout of the page it opens. Android Auto decides a page's
102
+ * layout before resolving it, so it is the one reader that acts
103
+ * on the handle's declaration. Declared or it doesn't exist: no
104
+ * value → nothing advertised. The resolved page is the truth.
105
+ * - On a track rendered *playable* (`src` wins the rendering): inert —
106
+ * playables open no page.
107
+ *
108
+ * Never *item*-inherited — each holder speaks only for its own
109
+ * children. Between containers it resolves by scope override, not
110
+ * inheritance: the page declares for its whole scope, a section
111
+ * overrides for its own children.
112
+ *
113
+ * @default 'list'
114
+ *
115
+ * @see https://developer.android.com/training/cars/media/create-media-browser/content-styles
116
+ */
117
+ display?: StyleDisplay
118
+
119
+ /**
120
+ * Inherited (`track ?? section ?? page`): how this item's artwork is
121
+ * rendered — `'stencil'` tints a monochrome glyph to the surface's
122
+ * light/dark appearance.
123
+ *
124
+ * @default 'original'
125
+ *
126
+ * @platform carplay
127
+ */
128
+ artworkRendering?: ArtworkRendering
129
+
130
+ /**
131
+ * Inherited (`track ?? section ?? page`): the shape a grid tile's
132
+ * artwork is cropped to — `'circular'` for people, the default
133
+ * `'rounded-rectangle'` for everything else. Shape follows the item
134
+ * wherever it travels: a circular artist stays circular in whatever
135
+ * grid renders it next. Inert where the presentation has no shape
136
+ * (list rows, pre-26 CarPlay, Android Auto).
137
+ *
138
+ * @default 'rounded-rectangle'
139
+ *
140
+ * @platform carplay
141
+ */
142
+ imageShape?: ImageShape
143
+
144
+ /**
145
+ * Inherited (`track ?? section ?? page`): an SF Symbol name drawn as
146
+ * the item's accessory wherever the current presentation supports one —
147
+ * the trailing edge of a list row, leading the title on an iOS 26 grid
148
+ * tile (placement is the platform's choice per surface). A resolved
149
+ * symbol replaces the derived accessory (the disclosure chevron a
150
+ * browsable row gets); `'none'` clears an inherited value, restoring
151
+ * the derived behavior — inheritance has no other escape, and no SF
152
+ * Symbol is named `none`, so the sentinel is collision-free. Inert off
153
+ * CarPlay.
154
+ *
155
+ * @platform carplay
156
+ */
157
+ accessorySymbol?: string
158
+
159
+ /**
160
+ * Inherited (`track ?? section ?? page`): the card treatment's tint
161
+ * color (hex, e.g. `'#1e3a8a'`) — a gradient behind the labels, or the
162
+ * color behind them when {@link TrackStyle.cardImage} is
163
+ * `'background'`. Card-prefixed: inert unless the container renders
164
+ * `gridTile: 'card'`.
165
+ *
166
+ * @platform carplay
167
+ */
168
+ cardTint?: string
169
+
170
+ /**
171
+ * Inherited (`track ?? section ?? page`): how a card tile uses its
172
+ * image — see {@link CardImage}. Uniform via the section value,
173
+ * mixable per card. Inert unless the container renders
174
+ * `gridTile: 'card'`.
175
+ *
176
+ * @default 'normal'
177
+ *
178
+ * @platform carplay
179
+ */
180
+ cardImage?: CardImage
181
+ }
182
+
183
+ /**
184
+ * A {@link Section}'s (or resolved page's) style declaration block: the
185
+ * *container* properties below, plus — via `extends` — a section-wide
186
+ * value for every inherited {@link TrackStyle} item property (and the
187
+ * section's own positional `display`).
188
+ *
189
+ * Container properties resolve by scope override, not inheritance: the
190
+ * page declares for its whole scope, a section overrides for its own
191
+ * children (`section ?? page ?? default`) — they never flow to items.
192
+ */
193
+ export interface SectionStyle extends TrackStyle {
194
+ /**
195
+ * Whether grid tiles wrap to multiple lines. `false` renders exactly
196
+ * one line — the teaser shelf: a preview of a larger collection,
197
+ * typically paired with {@link Section.path} as the "view all" target.
198
+ *
199
+ * Rendered by CarPlay (a single line of tiles). Android Auto has no
200
+ * single-line tile container — its grid wraps, showing more, never
201
+ * less. Phone UIs typically honor `false` as a horizontal scroller.
202
+ *
203
+ * Inert unless {@link TrackStyle.display} is `'grid'`.
204
+ *
205
+ * @default true
206
+ *
207
+ * @platform carplay
208
+ *
209
+ * @see https://developer.apple.com/documentation/carplay/cplistimagerowitem
210
+ */
211
+ gridWrap?: boolean
212
+
213
+ /**
214
+ * The kind of tile this container's grid renders — see
215
+ * {@link GridTile}. A container property (element families are
216
+ * container-homogeneous), resolved by scope override
217
+ * (`section ?? page`), never per item. Inert unless
218
+ * {@link TrackStyle.display} is `'grid'`, and on CarPlay before
219
+ * iOS 26 (where the treatment drops and the layout survives).
220
+ *
221
+ * @default 'plain'
222
+ *
223
+ * @platform carplay
224
+ */
225
+ gridTile?: GridTile
226
+ }
4
227
 
5
228
  /**
6
229
  * Image source for React Native's `<Image>` component.
@@ -37,12 +260,6 @@ export interface TrackRequest {
37
260
  query?: Record<string, string>
38
261
  }
39
262
 
40
- // export interface BrowserSection {
41
- // title: string
42
- // style?: BrowserItemStyle
43
- // children: Track
44
- // }
45
-
46
263
  /**
47
264
  * Artwork URLs for a track that ships a different image per appearance.
48
265
  *
@@ -67,66 +284,77 @@ export interface ArtworkVariants {
67
284
  /** A single artwork URL, or one per appearance. */
68
285
  export type TrackArtwork = string | ArtworkVariants
69
286
 
70
- export interface ImageRowItem {
287
+ /**
288
+ * A titled, styled group of Tracks within a resolved page — the unit of
289
+ * queue scope. Tapping a playable child queues the section it sits in,
290
+ * identically on every platform and screen width: rendering may truncate
291
+ * what is visible, it never changes what plays.
292
+ */
293
+ export interface Section {
294
+ /** Header text. Absent = headerless group. */
295
+ title?: string
71
296
  /**
72
- * Opaque, stable identifier for this item's track. Round-tripped like
73
- * `Track.id` when the thumbnail is played (see `src`).
297
+ * Presentation, separated from content. Each surface renders the
298
+ * declared layout's nearest supported form; on CarPlay
299
+ * a wrapping grid requires iOS 26+ and renders a list before that,
300
+ * since CarPlay's only earlier tile container truncates at a width the
301
+ * system doesn't report. Use the artwork `resolve` hook to supply
302
+ * fallback art for tile layouts.
74
303
  */
75
- id?: string
76
- /** Navigation path. Tapping this thumbnail navigates to this URL. */
77
- url?: string
304
+ style?: SectionStyle
78
305
  /**
79
- * Direct audio source. When present, tapping this thumbnail plays it
80
- * immediately (same selection path as a playable list row) instead of
81
- * navigating. Takes precedence over `url`.
306
+ * Navigation target for the section's "view all" affordance — the
307
+ * fuller page this section is a teaser for. Absent = a self-contained
308
+ * section: the header is a plain label, not a link.
309
+ *
310
+ * The surface picks the form (ADR 0010), and each carries the copy
311
+ * itself — a `path` never adds words to the section:
312
+ *
313
+ * - **CarPlay** — a tile section's row draws a disclosure chevron and
314
+ * the whole row navigates. A list section renders no affordance:
315
+ * CarPlay has no "see all" idiom for one, and an invented row would
316
+ * spend an item from the template's cap.
317
+ * - **Android Auto** — no header is tappable at any display, so the
318
+ * section gets an appended browsable row, titled by the global
319
+ * `viewMoreTitle` browser option ("View more" by default).
82
320
  */
83
- src?: string
84
- /** Artwork URL for the thumbnail image. */
85
- artwork?: string
86
- /** Output only — populated by the artwork transform pipeline. */
87
- readonly artworkSource?: ImageSource
88
- /** Title of this item. Shown as the thumbnail caption; used for identification and accessibility. */
89
- title: string
90
- /** Now-playing secondary line when played via `src` (mirrors `Track.artist`). */
91
- artist?: string
92
- /** Now-playing album line when played via `src` (mirrors `Track.album`). */
93
- album?: string
94
- /** Navigation target of the album line when played via `src` (mirrors `Track.albumUrl`). */
95
- albumUrl?: string
96
- /** Live stream indicator when played via `src` (mirrors `Track.live`). */
97
- live?: boolean
98
- /** Per-item media-request override when played via `src` (mirrors `Track.request`). */
99
- request?: TrackRequest
321
+ path?: string
322
+ /** The section's tracks. */
323
+ children: Track[]
100
324
  }
101
325
 
326
+ /**
327
+ * The one node type of the browse tree — every tab, folder, station,
328
+ * episode, and queue item is a Track. What a Track *is* follows from which
329
+ * address fields it carries: a {@link path} makes it **browsable** (it opens
330
+ * as a page), a {@link src} makes it **playable** (it can be loaded into the
331
+ * player); at least one of the two is required. The remaining fields are
332
+ * display metadata ({@link title}, {@link artist}, {@link artwork}, …) and
333
+ * content state ({@link favorited}, {@link live}, {@link disabled}).
334
+ */
102
335
  export interface Track {
103
336
  /**
104
337
  * Opaque, stable identifier for this track.
105
338
  *
339
+ * A track's **identity** is `id` when set (non-blank), falling back to
340
+ * `src`. That single rule drives every comparison the library makes:
341
+ * favorites matching (`setFavorites`), the CarPlay / Android Auto
342
+ * "now playing" row indicator, section scoping and skip-in-place, and the
343
+ * contextual queue re-expansion. Two tracks refer to the same item iff
344
+ * their identities are equal — so set `id` consistently on every surface,
345
+ * or on none.
346
+ *
106
347
  * The library never parses or derives anything from this value — it is
107
- * round-tripped verbatim through `setQueue`, `getActiveTrack`, the queue, and
108
- * `onActiveTrackChanged`, so consumers can recognise which item became active
109
- * after an external transport change (lock screen / CarPlay / Android Auto /
110
- * Bluetooth next-previous) without parsing the playable `src`.
111
- *
112
- * When present on a playable track it is also the track's *identity* on car
113
- * browse surfaces: CarPlay's and Android Auto's "now playing" row indicator
114
- * match the active track to browse rows by `id` (falling back to exact `src`
115
- * equality for tracks without one). Assign ids when your playable `src`
116
- * strings for the same item can differ between browse rows and loaded tracks
117
- * (absolute vs relative URLs, volatile query params) — otherwise the
118
- * indicator never matches.
119
- *
120
- * It is also handed to the per-track `MediaRequestConfig.resolve` and
121
- * `ArtworkRequestConfig.resolve` hooks, so requests can be built from a stable
122
- * id (e.g. supply tracks with only an `id` and synthesise `src` in `resolve`).
123
- *
124
- * Optional: consumers whose `url`/`src` strings are already stable across
125
- * surfaces can ignore it.
126
- *
127
- * Note: an Android Auto item selected directly from the browse tree that the
128
- * consumer never queued is identified only by `url`/`src`, so `id` may be
129
- * undefined on that specific path.
348
+ * round-tripped verbatim through `setQueue`, `getActiveTrack`, the queue,
349
+ * `onActiveTrackChanged`, and `onFavoriteChanged`, and handed to the
350
+ * per-track `MediaRequestConfig.resolve` / `ArtworkRequestConfig.resolve`
351
+ * hooks so requests can be built from the stable id.
352
+ *
353
+ * Optional: consumers whose `src` strings are identical wherever the same
354
+ * item appears can ignore it — their identity is the `src`. Assign ids when
355
+ * `src` strings for the same item can differ between surfaces (absolute vs
356
+ * relative URLs, volatile query params), or when favorites are stored as an
357
+ * identifier that isn't the playable URL.
130
358
  */
131
359
  id?: string
132
360
 
@@ -134,9 +362,13 @@ export interface Track {
134
362
  * Navigation path. When present, this track is a container (tab, album, playlist, folder)
135
363
  * that can be navigated into to view its contents.
136
364
  *
137
- * At least one of `url` or `src` must be defined.
365
+ * At least one of `path` or `src` must be defined. When both are set, current
366
+ * surfaces treat the track as playable — `src` wins the rendering, and the
367
+ * browse pipeline replaces a playable track's `path` with its contextual
368
+ * path — so a consumer-supplied `path` on a playable track is not reachable
369
+ * today.
138
370
  */
139
- url?: string
371
+ path?: string
140
372
 
141
373
  /**
142
374
  * Direct audio source identifier. When present, this track can be played directly.
@@ -145,7 +377,7 @@ export interface Track {
145
377
  * any string (file path, custom identifier, etc.) that will be passed to
146
378
  * MediaRequestConfig.resolve to transform it into the actual media request.
147
379
  *
148
- * At least one of `url` or `src` must be defined.
380
+ * At least one of `path` or `src` must be defined.
149
381
  */
150
382
  src?: string
151
383
 
@@ -159,7 +391,8 @@ export interface Track {
159
391
  * Pass an {@link ArtworkVariants} pair to supply genuinely different images
160
392
  * per appearance — a logo that changes colour, say. For a monochrome glyph
161
393
  * that only needs recolouring, prefer a single URL plus
162
- * {@link Track.artworkCarPlayTinted}, which is one fetch instead of two.
394
+ * `style: { artworkRendering: 'stencil' }`, which is one fetch instead
395
+ * of two.
163
396
  *
164
397
  * **iOS:** supports {@link https://developer.apple.com/sf-symbols/ | SF Symbols}
165
398
  * with the `sf:` prefix and optional color params:
@@ -189,23 +422,6 @@ export interface Track {
189
422
  /** Per-track media-request override; merged last (request → media → track.request). */
190
423
  request?: TrackRequest
191
424
 
192
- /**
193
- * Whether this artwork should be tinted based on CarPlay's current appearance (light/dark mode).
194
- *
195
- * When `true`, the artwork is treated as a monochrome icon and tinted:
196
- * - Light mode: tinted black for visibility on light backgrounds
197
- * - Dark mode: tinted white for visibility on dark backgrounds
198
- *
199
- * This is useful for SVG or PNG icons that need to adapt to CarPlay's light/dark themes.
200
- * Full-color artwork (album covers, logos) should not use this.
201
- *
202
- * **iOS CarPlay only** - Android Auto is dark-only, so content providers should
203
- * provide appropriately colored icons directly (e.g., white icons).
204
- *
205
- * @default false
206
- */
207
- artworkCarPlayTinted?: boolean
208
-
209
425
  // type?: TrackType
210
426
  /** Primary line shown for this item, in both browse lists and now-playing. */
211
427
  title: string
@@ -231,9 +447,9 @@ export interface Track {
231
447
 
232
448
  /**
233
449
  * Browse path the {@link album} line navigates to (same path namespace as
234
- * {@link url}). On CarPlay, when the active track has an `albumUrl`, its
450
+ * {@link path}). On CarPlay, when the active track has an `albumPath`, its
235
451
  * album line on the Now Playing screen becomes tappable and navigates the
236
- * browse stack there. See also `resolveAlbumUrl` in the browser
452
+ * browse stack there. See also `resolveAlbumPath` in the browser
237
453
  * configuration for a dynamic fallback.
238
454
  *
239
455
  * Requires {@link album} to be set: CarPlay renders the tappable line from
@@ -241,10 +457,28 @@ export interface Track {
241
457
  *
242
458
  * @platform ios
243
459
  */
244
- albumUrl?: string
460
+ albumPath?: string
245
461
 
462
+ /**
463
+ * Album name, shown on now-playing surfaces that have an album slot
464
+ * (CarPlay, Android Auto, Bluetooth metadata — the iOS lock screen has
465
+ * none). With {@link albumPath} set, CarPlay renders it as a tappable
466
+ * line that navigates there.
467
+ */
246
468
  album?: string
469
+
470
+ /**
471
+ * Longer free-form text about the item, passed to the platform's
472
+ * description metadata slot where one exists. Not shown on browse rows
473
+ * (those render {@link title} / {@link subtitle}) or the lock screen.
474
+ */
247
475
  description?: string
476
+
477
+ /**
478
+ * Genre name, passed to the platform's genre metadata slot where one
479
+ * exists. Catalog metadata only — the library never matches search or
480
+ * browse against it.
481
+ */
248
482
  genre?: string
249
483
 
250
484
  /**
@@ -255,30 +489,31 @@ export interface Track {
255
489
  duration?: number
256
490
 
257
491
  /**
258
- * Display style for this item in Android Auto/AAOS.
259
- * - 'list': Display as a list row
260
- * - 'grid': Display as a grid tile
261
- *
262
- * On Android: when `artwork` is an `android.resource://` URI
263
- * (e.g., `android.resource://com.myapp/drawable/ic_folder`), the library
264
- * automatically uses 'category' styling which adds margins around the icon
265
- * and enables system tinting for vector drawables.
266
- *
267
- * @see https://developer.android.com/training/cars/media#default-content-style
492
+ * The track's style declaration block: inherited item properties (a
493
+ * per-item override of section/page values — they travel with the
494
+ * track), plus the positional {@link TrackStyle.display} — on a
495
+ * browsable track, the advertised layout of the page it opens, read
496
+ * by Android Auto, which picks a page's layout before resolving it.
268
497
  */
269
498
  style?: TrackStyle
270
499
 
271
500
  /**
272
- * Display style for this item's children in Android Auto/AAOS.
273
- * Only applies to browsable items (containers/folders).
274
- * - 'list': Display children as list rows
275
- * - 'grid': Display children as grid tiles
501
+ * Unavailable — a content-state fact beside `favorited` and `live`,
502
+ * with full behavioral weight (content facts may carry behavior; style
503
+ * never does): a disabled track never plays — tap refused, queue
504
+ * expansion excludes it, voice search won't match it.
505
+ *
506
+ * Rendering ladder, never a trap: **grayed + inert** where the surface
507
+ * can draw it (CarPlay) → **hidden** where it can't (Android Auto) —
508
+ * never a normal-looking dead control. Hiding is behavior-safe because
509
+ * the track is inert everywhere regardless; the cost is losing the
510
+ * "Available at 9 PM" tease on surfaces that hide, so put the reason
511
+ * in the title for the ones that gray. Applied at page (re-)serve,
512
+ * like style.
276
513
  *
277
- * Must be set on the item when it appears as a child in a parent's list.
278
- * Android Auto reads the extras at that point to determine how to display
279
- * the folder's contents when navigated into.
514
+ * @default false
280
515
  */
281
- childrenStyle?: TrackStyle
516
+ disabled?: boolean
282
517
 
283
518
  /**
284
519
  * Whether this track is favorited. When the `favorite` capability is enabled,
@@ -287,40 +522,46 @@ export interface Track {
287
522
  favorited?: boolean
288
523
 
289
524
  /**
290
- * Group title for section headers in Android Auto/AAOS.
291
- * Items with the same groupTitle are displayed under a shared section header.
292
- * Items must be contiguous to form a single group.
293
- */
294
- groupTitle?: string
295
-
296
- /**
297
- * Whether this track is a live stream. When true, displays a "live" indicator
298
- * in iOS now playing interfaces.
525
+ * Declares this track a live broadcast rather than a file. The players
526
+ * detect *transport* liveness (sliding windows, buffering) themselves;
527
+ * this declaration drives the semantic decisions they can't infer:
528
+ *
529
+ * - **End of stream** (iOS): a live track "ending" is judged a dropped
530
+ * broadcast and recovered by rejoining the edge, never a queue advance.
531
+ * - **Stall recovery** (iOS): a live track that runs dry reconnects at
532
+ * the edge; a non-live one resumes its existing connection.
533
+ * - **`seekToLiveEdge()`** (all platforms): the call only acts on a
534
+ * track declared live — without the declaration it is a no-op.
535
+ * - **Persistence** (iOS): no position is stored, so a cold-start resume
536
+ * rejoins the current broadcast instead of seeking a stale timestamp.
537
+ * - **Now-playing** (iOS): the live indicator and live-style
538
+ * (non-scrubbing) progress UI.
539
+ *
540
+ * The iOS-heavy list is deliberate, not a gap: on Android, ExoPlayer's
541
+ * own classification already covers these — a dropped live connection
542
+ * surfaces as a load error (never end-of-stream), and persistence keys
543
+ * off its detected liveness — so the declaration's only Android reader
544
+ * is the `seekToLiveEdge()` gate. Android Auto has no live badge.
545
+ *
546
+ * Omitting it never breaks playback — it silently breaks these judgment
547
+ * calls. Declare it on every live track.
299
548
  */
300
549
  live?: boolean
301
550
 
302
551
  /**
303
- * When present, renders this track as a horizontal row of tappable artwork
304
- * thumbnails instead of a standard list item.
305
- *
306
- * - Track.title → row header text
307
- * - Track.url → navigated when header is tapped (optional)
308
- * - Each ImageRowItem → one thumbnail in the horizontal row; a thumbnail
309
- * with `src` plays immediately on tap, otherwise its `url` is navigated
310
- *
311
- * On CarPlay: maps to CPListImageRowItem. Limits visible images by display
312
- * width (~4-5). Excess silently truncated. A row whose track has no `url`
313
- * is a pure preview: its header is not tappable.
314
- *
315
- * On Android Auto: there is no image-row rendering, so the row expands into
316
- * its items as grid-styled rows (artwork tiles where the host honors the
317
- * per-item content-style hint, list rows otherwise) grouped under the
318
- * track's title, followed by the track itself as a browsable "view all"
319
- * link when it has a `url`.
320
- *
321
- * On app side: consumable by React Native UI for horizontal thumbnail layouts.
552
+ * Byte encoding of this track's ICY `StreamTitle` when it is not UTF-8, as
553
+ * an IANA label (`'windows-1251'`, `'windows-874'`, …). Some Shoutcast /
554
+ * Icecast stations send titles in a legacy code page; ICY declares no
555
+ * encoding, so the player's UTF-8 decode fails and falls back to Latin-1,
556
+ * showing mojibake. With this set, a title that came out Latin-1 shaped
557
+ * (every char at or below U+00FF, some at or above U+0080) is re-decoded
558
+ * through ISO-8859-1 with the given charset; this also repairs stations
559
+ * that UTF-8 encoded their legacy bytes. A title already in another script
560
+ * or pure ASCII is left alone. Applies to ICY only: ID3 and HLS timed
561
+ * metadata declare their own encoding and are never touched. A label the
562
+ * platform cannot decode with is ignored.
322
563
  */
323
- imageRow?: ImageRowItem[]
564
+ icyCharset?: string
324
565
  }
325
566
 
326
567
  /**
@@ -333,22 +574,43 @@ export interface Track {
333
574
  * ```ts
334
575
  * // navigate() is fire-and-forget (returns void); read the resolved page
335
576
  * // from getContent() / useContent() / onContentChanged.
336
- * navigate('albums/abbey-road');
577
+ * navigate('/albums/abbey-road');
337
578
  * const resolved = getContent();
338
- * console.log(resolved?.url); // "albums/abbey-road"
579
+ * console.log(resolved?.path); // "/albums/abbey-road"
339
580
  * console.log(resolved?.title); // "Abbey Road"
340
- * console.log(resolved?.children); // Array of tracks in this album
581
+ * console.log(resolved?.sections); // the album's tracks, as sections
341
582
  * ```
342
583
  */
343
584
  export interface ResolvedTrack extends Track {
344
585
  /**
345
- * URL path for this resolved track. Always present since you navigated to this location.
586
+ * Browse path of this resolved track. Always present since you navigated to this location.
587
+ */
588
+ path: string
589
+
590
+ /**
591
+ * A page is a Track that is also the container of its sections, so its
592
+ * block widens to {@link SectionStyle}: the declaration for the whole
593
+ * page. Item properties set here are inherited by every item on the
594
+ * page unless a section or track declares its own; the container
595
+ * property (`gridWrap`) and the positional `display` are the page-wide
596
+ * values a section overrides for its own children.
597
+ */
598
+ style?: SectionStyle
599
+
600
+ /**
601
+ * The page's sections — the canonical resolved shape. Every resolved page
602
+ * with content carries `sections`; a page authored with plain `children`
603
+ * resolves to a single untitled section.
346
604
  */
347
- url: string
605
+ sections?: Section[]
348
606
 
349
607
  /**
350
- * Immediate children of this track. Present for container tracks (albums, playlists, folders).
351
- * Undefined for leaf tracks (individual songs without children).
608
+ * Authoring sugar for a flat page: equivalent to declaring one untitled,
609
+ * style-less section holding these tracks (which therefore takes the
610
+ * page block's scope-wide values, like any undeclared section). Accepted
611
+ * anywhere a page is authored (static routes, browse callbacks, JSON
612
+ * payloads); never populated on a *resolved* page — read `sections`
613
+ * instead.
352
614
  */
353
615
  children?: Track[]
354
616