react-native-queue-player 1.2.0 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (362) hide show
  1. package/QueuePlayer.podspec +14 -9
  2. package/README.md +3 -3
  3. package/android/consumer-rules.pro +1 -1
  4. package/android/src/main/cpp/airplay2_control.c +4 -4
  5. package/android/src/main/cpp/airplay2_control.h +4 -4
  6. package/android/src/main/cpp/airplay2_jni.cpp +3 -19
  7. package/android/src/main/cpp/airplay2_pair.c +7 -7
  8. package/android/src/main/cpp/airplay2_pair.h +2 -2
  9. package/android/src/main/cpp/airplay2_rtsp.c +8 -8
  10. package/android/src/main/cpp/airplay2_session.c +2 -2
  11. package/android/src/main/cpp/airplay_jni.cpp +8 -69
  12. package/android/src/main/java/com/margelo/nitro/queueplayer/AirPlayEngine.kt +7 -16
  13. package/android/src/main/java/com/margelo/nitro/queueplayer/CacheMimeTypes.kt +1 -1
  14. package/android/src/main/java/com/margelo/nitro/queueplayer/CastManager.kt +2 -14
  15. package/android/src/main/java/com/margelo/nitro/queueplayer/CellularTransportMonitor.kt +77 -0
  16. package/android/src/main/java/com/margelo/nitro/queueplayer/CrossfadeEngine.kt +187 -52
  17. package/android/src/main/java/com/margelo/nitro/queueplayer/Equalizer.kt +27 -7
  18. package/android/src/main/java/com/margelo/nitro/queueplayer/EqualizerEngine.kt +33 -12
  19. package/android/src/main/java/com/margelo/nitro/queueplayer/EqualizerLegacyEngine.kt +31 -8
  20. package/android/src/main/java/com/margelo/nitro/queueplayer/FFTProcessorTee.kt +45 -30
  21. package/android/src/main/java/com/margelo/nitro/queueplayer/FifoCacheEvictor.kt +111 -15
  22. package/android/src/main/java/com/margelo/nitro/queueplayer/GaplessEngine.kt +60 -33
  23. package/android/src/main/java/com/margelo/nitro/queueplayer/HeadlessJsMediaService.kt +1 -1
  24. package/android/src/main/java/com/margelo/nitro/queueplayer/IEqualizerEngine.kt +3 -1
  25. package/android/src/main/java/com/margelo/nitro/queueplayer/LookaheadCache.kt +111 -29
  26. package/android/src/main/java/com/margelo/nitro/queueplayer/LookaheadCacheWriter.kt +78 -30
  27. package/android/src/main/java/com/margelo/nitro/queueplayer/MediaItemBuilder.kt +6 -6
  28. package/android/src/main/java/com/margelo/nitro/queueplayer/MediaResponseCheck.kt +156 -0
  29. package/android/src/main/java/com/margelo/nitro/queueplayer/MediaValidatingDataSource.kt +165 -0
  30. package/android/src/main/java/com/margelo/nitro/queueplayer/MimeCapturingDataSource.kt +18 -9
  31. package/android/src/main/java/com/margelo/nitro/queueplayer/NowPlayingFormatExtractor.kt +48 -1
  32. package/android/src/main/java/com/margelo/nitro/queueplayer/PitchCorrection.kt +3 -2
  33. package/android/src/main/java/com/margelo/nitro/queueplayer/PlaybackEngine.kt +71 -76
  34. package/android/src/main/java/com/margelo/nitro/queueplayer/PlaybackErrorMapping.kt +13 -5
  35. package/android/src/main/java/com/margelo/nitro/queueplayer/PlaybackModeStateMachine.kt +2 -2
  36. package/android/src/main/java/com/margelo/nitro/queueplayer/PlaybackService.kt +68 -46
  37. package/android/src/main/java/com/margelo/nitro/queueplayer/PlaybackServiceCallback.kt +6 -5
  38. package/android/src/main/java/com/margelo/nitro/queueplayer/QueueMutationArithmetic.kt +5 -6
  39. package/android/src/main/java/com/margelo/nitro/queueplayer/QueueSkipArithmetic.kt +11 -8
  40. package/android/src/main/java/com/margelo/nitro/queueplayer/ReplayGainAudioProcessor.kt +26 -6
  41. package/android/src/main/java/com/margelo/nitro/queueplayer/ReplayGainData.kt +22 -3
  42. package/android/src/main/java/com/margelo/nitro/queueplayer/ReplayGainExtractor.kt +38 -12
  43. package/android/src/main/java/com/margelo/nitro/queueplayer/ReplayGainGain.kt +17 -13
  44. package/android/src/main/java/com/margelo/nitro/queueplayer/SuppliedReplayGain.kt +66 -0
  45. package/android/src/main/java/com/margelo/nitro/queueplayer/TrackPlayer.kt +985 -276
  46. package/android/src/main/java/com/margelo/nitro/queueplayer/Visualizer.kt +4 -8
  47. package/android/src/main/java/com/margelo/nitro/queueplayer/cast/CastBackend.kt +4 -3
  48. package/android/src/main/java/com/margelo/nitro/queueplayer/cast/CastSession.kt +5 -4
  49. package/android/src/main/java/com/margelo/nitro/queueplayer/cast/airplay/AirPlay2JNI.kt +0 -2
  50. package/android/src/main/java/com/margelo/nitro/queueplayer/cast/airplay/AirPlay2Session.kt +4 -2
  51. package/android/src/main/java/com/margelo/nitro/queueplayer/cast/airplay/AirPlayBackend.kt +16 -9
  52. package/android/src/main/java/com/margelo/nitro/queueplayer/cast/airplay/AirPlayMetadataSync.kt +1 -1
  53. package/android/src/main/java/com/margelo/nitro/queueplayer/cast/airplay/AirPlayRenderersFactory.kt +6 -14
  54. package/android/src/main/java/com/margelo/nitro/queueplayer/cast/airplay/AirplayJNI.kt +1 -13
  55. package/android/src/main/java/com/margelo/nitro/queueplayer/cast/airplay/MulticastLockHolder.kt +1 -1
  56. package/android/src/main/java/com/margelo/nitro/queueplayer/cast/chromecast/ChromecastBackend.kt +3 -3
  57. package/android/src/main/java/com/margelo/nitro/queueplayer/cast/http/LocalMediaServer.kt +11 -35
  58. package/android/src/main/java/com/margelo/nitro/queueplayer/cast/http/MediaServerHandle.kt +0 -5
  59. package/android/src/main/java/com/margelo/nitro/queueplayer/cast/http/MediaTokenRegistry.kt +0 -6
  60. package/android/src/main/java/com/margelo/nitro/queueplayer/cast/net/LocalAddressMonitor.kt +32 -33
  61. package/android/src/test/java/androidx/media3/session/{MediaSessionControllerRequestTestSeam.kt → MediaSessionControllerRequestTestSupport.kt} +1 -1
  62. package/android/src/test/java/com/margelo/nitro/queueplayer/AvrcpMetadataTest.kt +12 -0
  63. package/android/src/test/java/com/margelo/nitro/queueplayer/CrossfadeEngineFocusLossTest.kt +115 -0
  64. package/android/src/test/java/com/margelo/nitro/queueplayer/CrossfadeEngineLifecycleTest.kt +45 -0
  65. package/android/src/test/java/com/margelo/nitro/queueplayer/EngineEndSignalOrderTest.kt +70 -0
  66. package/android/src/test/java/com/margelo/nitro/queueplayer/EqualizerEngineTest.kt +17 -0
  67. package/android/src/test/java/com/margelo/nitro/queueplayer/EqualizerKtTest.kt +0 -6
  68. package/android/src/test/java/com/margelo/nitro/queueplayer/EqualizerLegacyEngineTest.kt +17 -0
  69. package/android/src/test/java/com/margelo/nitro/queueplayer/FFTProcessorTeeTest.kt +15 -0
  70. package/android/src/test/java/com/margelo/nitro/queueplayer/FifoCacheEvictorTest.kt +135 -4
  71. package/android/src/test/java/com/margelo/nitro/queueplayer/GaplessEngineLifecycleTest.kt +1 -0
  72. package/android/src/test/java/com/margelo/nitro/queueplayer/GaplessEngineReplayGainTest.kt +36 -2
  73. package/android/src/test/java/com/margelo/nitro/queueplayer/LookaheadCacheTest.kt +84 -18
  74. package/android/src/test/java/com/margelo/nitro/queueplayer/LookaheadCacheWriterCancelTest.kt +85 -0
  75. package/android/src/test/java/com/margelo/nitro/queueplayer/LookaheadCacheWriterTest.kt +112 -1
  76. package/android/src/test/java/com/margelo/nitro/queueplayer/MediaItemBuilderTest.kt +5 -3
  77. package/android/src/test/java/com/margelo/nitro/queueplayer/MediaResponseCheckTest.kt +163 -0
  78. package/android/src/test/java/com/margelo/nitro/queueplayer/MediaValidatingDataSourceTest.kt +189 -0
  79. package/android/src/test/java/com/margelo/nitro/queueplayer/NowPlayingFormatExtractorTest.kt +45 -0
  80. package/android/src/test/java/com/margelo/nitro/queueplayer/PitchAwareAudioProcessorChainTest.kt +1 -1
  81. package/android/src/test/java/com/margelo/nitro/queueplayer/PlaybackServiceCallbackSearchTest.kt +47 -0
  82. package/android/src/test/java/com/margelo/nitro/queueplayer/PlaybackServiceCallbackTest.kt +53 -29
  83. package/android/src/test/java/com/margelo/nitro/queueplayer/PlaybackServiceLifecycleTest.kt +8 -8
  84. package/android/src/test/java/com/margelo/nitro/queueplayer/QueueSkipArithmeticTest.kt +33 -1
  85. package/android/src/test/java/com/margelo/nitro/queueplayer/ReplayGainAudioProcessorTest.kt +128 -5
  86. package/android/src/test/java/com/margelo/nitro/queueplayer/ReplayGainExtractorTest.kt +209 -14
  87. package/android/src/test/java/com/margelo/nitro/queueplayer/ReplayGainGainTest.kt +150 -10
  88. package/android/src/test/java/com/margelo/nitro/queueplayer/ReplayGainMergeTest.kt +258 -0
  89. package/android/src/test/java/com/margelo/nitro/queueplayer/RobolectricServiceBindHelper.kt +2 -2
  90. package/android/src/test/java/com/margelo/nitro/queueplayer/SessionCommandForwardingPlayerTest.kt +2 -2
  91. package/android/src/test/java/com/margelo/nitro/queueplayer/ShadowDynamicsProcessingRejectingEnable.kt +19 -0
  92. package/android/src/test/java/com/margelo/nitro/queueplayer/ShadowEqualizer.kt +1 -1
  93. package/android/src/test/java/com/margelo/nitro/queueplayer/ShadowEqualizerRejectingBandWrites.kt +27 -0
  94. package/android/src/test/java/com/margelo/nitro/queueplayer/SuppliedReplayGainTest.kt +61 -0
  95. package/android/src/test/java/com/margelo/nitro/queueplayer/TrackPlayerAirPlayMetadataWiringTest.kt +4 -4
  96. package/android/src/test/java/com/margelo/nitro/queueplayer/TrackPlayerAudioFocusTest.kt +1 -1
  97. package/android/src/test/java/com/margelo/nitro/queueplayer/TrackPlayerCastCommandRoutingTest.kt +2 -1
  98. package/android/src/test/java/com/margelo/nitro/queueplayer/TrackPlayerCastStateTest.kt +2 -1
  99. package/android/src/test/java/com/margelo/nitro/queueplayer/TrackPlayerEventsTest.kt +122 -38
  100. package/android/src/test/java/com/margelo/nitro/queueplayer/TrackPlayerLifecycleTest.kt +291 -27
  101. package/android/src/test/java/com/margelo/nitro/queueplayer/TrackPlayerLookaheadConfigTest.kt +277 -38
  102. package/android/src/test/java/com/margelo/nitro/queueplayer/TrackPlayerMutationTest.kt +5 -3
  103. package/android/src/test/java/com/margelo/nitro/queueplayer/TrackPlayerProgressThrottleTest.kt +2 -1
  104. package/android/src/test/java/com/margelo/nitro/queueplayer/TrackPlayerQueueChangeTest.kt +85 -3
  105. package/android/src/test/java/com/margelo/nitro/queueplayer/TrackPlayerQueueTest.kt +11 -7
  106. package/android/src/test/java/com/margelo/nitro/queueplayer/TrackPlayerReadersTest.kt +2 -1
  107. package/android/src/test/java/com/margelo/nitro/queueplayer/TrackPlayerSkipCapabilityTest.kt +90 -4
  108. package/android/src/test/java/com/margelo/nitro/queueplayer/TrackPlayerSkipTest.kt +8 -26
  109. package/android/src/test/java/com/margelo/nitro/queueplayer/TrackPlayerTransportTest.kt +3 -3
  110. package/android/src/test/java/com/margelo/nitro/queueplayer/VisualizerKtTest.kt +0 -4
  111. package/android/src/test/java/com/margelo/nitro/queueplayer/cast/FakeRemotePlayer.kt +2 -2
  112. package/android/src/test/java/com/margelo/nitro/queueplayer/cast/net/LocalAddressMonitorTest.kt +173 -0
  113. package/android/src/test/java/com/margelo/nitro/queueplayer/cast/net/ShadowConnectivityManagerRecordingRequests.kt +27 -0
  114. package/app.plugin.js +17 -1
  115. package/ios/AVPlayerItemQueueItemId.swift +26 -12
  116. package/ios/AVQueueBuilder.swift +120 -85
  117. package/ios/ArtworkLoader.swift +0 -7
  118. package/ios/ArtworkResolver.swift +22 -4
  119. package/ios/AssetReplayGainReader.swift +118 -0
  120. package/ios/AudioSession.swift +67 -16
  121. package/ios/AudioTapProvider.swift +284 -149
  122. package/ios/CarPlayBridge.swift +0 -12
  123. package/ios/CarPlayCoordinator.swift +18 -2
  124. package/ios/CarPlaySceneDelegate.swift +2 -2
  125. package/ios/Cast/AirPlayRouteState.swift +9 -8
  126. package/ios/Cast/Core/CastEventBridge.swift +66 -26
  127. package/ios/Cast/Core/CastNowPlayingController.swift +38 -16
  128. package/ios/Cast/Core/CastSession.swift +2 -2
  129. package/ios/Cast/Core/CastTransportRouter.swift +21 -9
  130. package/ios/Cast/Core/LocalMediaServer.swift +41 -52
  131. package/ios/Cast/Core/LocalNetworkPermissionProbe.swift +32 -11
  132. package/ios/Cast/Core/MediaServerHandle.swift +0 -4
  133. package/ios/Cast/Core/MediaTokenRegistry.swift +0 -6
  134. package/ios/CastManager.swift +1 -1
  135. package/ios/CrossfadeEngine.swift +672 -226
  136. package/ios/EQTap.swift +20 -17
  137. package/ios/Equalizer.swift +1 -1
  138. package/ios/FLACStreamInfo.swift +65 -0
  139. package/ios/GaplessEngine.swift +57 -30
  140. package/ios/InputGuards.swift +35 -5
  141. package/ios/LookaheadCache.swift +229 -58
  142. package/ios/LookaheadCachePrefetcher.swift +48 -36
  143. package/ios/MediaResponseCheck.swift +122 -0
  144. package/ios/MediaServer/MediaHTTPConnection.swift +691 -0
  145. package/ios/NetworkRecoveryPolicy.swift +32 -0
  146. package/ios/NowPlayingFormatExtractor.swift +25 -18
  147. package/ios/NowPlayingInfo.swift +84 -48
  148. package/ios/OutputRouteMonitor.swift +16 -3
  149. package/ios/PendingBrowseRequests.swift +1 -1
  150. package/ios/PlaceholderArtwork.swift +9 -5
  151. package/ios/PlaybackEngine.swift +165 -76
  152. package/ios/PlaybackErrorMapping.swift +3 -3
  153. package/ios/PlaybackModeStateMachine.swift +2 -2
  154. package/ios/PlaybackNetworkMonitor.swift +73 -0
  155. package/ios/PlayerStateDerivation.swift +6 -6
  156. package/ios/QueueMutationArithmetic.swift +25 -0
  157. package/ios/QueueSkipArithmetic.swift +5 -3
  158. package/ios/QueueWindowArithmetic.swift +152 -0
  159. package/ios/ReadThroughServer.swift +283 -0
  160. package/ios/RemoteCommands.swift +44 -4
  161. package/ios/ReplayGainData.swift +22 -3
  162. package/ios/ReplayGainExtractor.swift +70 -27
  163. package/ios/Siri/VoiceDonation.swift +14 -9
  164. package/ios/StreamingBitrateProbe.swift +22 -68
  165. package/ios/SuppliedReplayGain.swift +83 -0
  166. package/ios/Tests/AVQueueBuilderTests.swift +158 -221
  167. package/ios/Tests/ActiveItemEngineStub.swift +44 -0
  168. package/ios/Tests/AssetReplayGainReaderTests.swift +228 -0
  169. package/ios/Tests/AudioTapProviderDispatchTargetTests.swift +158 -0
  170. package/ios/Tests/AudioTapProviderReplayGainTests.swift +122 -10
  171. package/ios/Tests/BitrateReresolveBudgetTests.swift +71 -0
  172. package/ios/Tests/CastMediaItemTranslationTests.swift +72 -0
  173. package/ios/Tests/CastNowPlayingControllerTests.swift +1 -1
  174. package/ios/Tests/CrossfadeAdvanceWithoutFadeTests.swift +120 -0
  175. package/ios/Tests/CrossfadeEngineIncomingMixTests.swift +122 -0
  176. package/ios/Tests/CrossfadeEngineTests.swift +164 -0
  177. package/ios/Tests/CrossfadeMixReapplyTests.swift +66 -0
  178. package/ios/Tests/CrossfadePlaybackIntentTests.swift +81 -0
  179. package/ios/Tests/EngineSwapTests.swift +91 -0
  180. package/ios/Tests/EqualizerAudioMixProviderTests.swift +46 -0
  181. package/ios/Tests/EqualizerHybridTests.swift +5 -2
  182. package/ios/Tests/FLACStreamInfoTests.swift +88 -0
  183. package/ios/Tests/GaplessEngineLifecycleTests.swift +4 -4
  184. package/ios/Tests/InputGuardsTests.swift +41 -0
  185. package/ios/Tests/InterruptionIntentTests.swift +77 -0
  186. package/ios/Tests/LookaheadCacheCellularAccessTests.swift +185 -0
  187. package/ios/Tests/LookaheadCachePrefetcherTests.swift +53 -30
  188. package/ios/Tests/LookaheadCacheRuntimeConfigTests.swift +160 -1
  189. package/ios/Tests/LookaheadCacheTests.swift +44 -18
  190. package/ios/Tests/MediaHTTPConnectionTests.swift +79 -0
  191. package/ios/Tests/MediaResponseCheckTests.swift +128 -0
  192. package/ios/Tests/MutationDeferralTests.swift +220 -0
  193. package/ios/Tests/NowPlayingInfoTests.swift +86 -99
  194. package/ios/Tests/NowPlayingSnapshotTests.swift +127 -0
  195. package/ios/Tests/OriginRestartStitcherTests.swift +60 -0
  196. package/ios/Tests/PlaybackNetworkMonitorTests.swift +95 -0
  197. package/ios/Tests/PlayerFixtures.swift +48 -0
  198. package/ios/Tests/PlayerStateDerivationTests.swift +10 -10
  199. package/ios/Tests/QueueMutationGenerationTests.swift +141 -0
  200. package/ios/Tests/QueueRebuildPrefixTests.swift +317 -0
  201. package/ios/Tests/QueueStateTests.swift +3 -1
  202. package/ios/Tests/QueueWindowArithmeticTests.swift +56 -0
  203. package/ios/Tests/QueueWindowSliceTests.swift +162 -0
  204. package/ios/Tests/ReadThroughRoutingLifecycleTests.swift +63 -0
  205. package/ios/Tests/ReadThroughServerTests.swift +345 -0
  206. package/ios/Tests/RemoteCommandsTests.swift +28 -0
  207. package/ios/Tests/ReplayGainExtractorTests.swift +216 -6
  208. package/ios/Tests/ReplayGainMergeTests.swift +230 -0
  209. package/ios/Tests/RetryRecoveryTests.swift +418 -0
  210. package/ios/Tests/SkipCapabilityTests.swift +233 -8
  211. package/ios/Tests/SkipIndexTests.swift +32 -2
  212. package/ios/Tests/SleepTimerPauseIntentTests.swift +43 -0
  213. package/ios/Tests/StallRecoveryTests.swift +97 -0
  214. package/ios/Tests/StreamingBitrateProbeTests.swift +17 -20
  215. package/ios/Tests/TopUpWindowGateTests.swift +441 -0
  216. package/ios/Tests/TrackPlayer+TestHops.swift +14 -0
  217. package/ios/Tests/TrackPlayerCallOrderTests.swift +93 -0
  218. package/ios/Tests/TrackPlayerConfigureTeardownTests.swift +86 -0
  219. package/ios/Tests/TrackPlayerEndVerdictTests.swift +206 -0
  220. package/ios/Tests/TrackPlayerSeekTests.swift +137 -0
  221. package/ios/Tests/TrackPlayerThreadingTests.swift +127 -0
  222. package/ios/Tests/TrackSourceClassifierTests.swift +33 -7
  223. package/ios/Tests/VoiceVocabularyOptInTests.swift +38 -0
  224. package/ios/TrackPlayer+Automotive.swift +101 -0
  225. package/ios/TrackPlayer+Cache.swift +232 -0
  226. package/ios/TrackPlayer+Config.swift +291 -0
  227. package/ios/TrackPlayer+EngineDelegate.swift +209 -0
  228. package/ios/TrackPlayer+EventsAPI.swift +111 -0
  229. package/ios/TrackPlayer+EventsDispatch.swift +1042 -0
  230. package/ios/TrackPlayer+EventsWiring.swift +173 -0
  231. package/ios/TrackPlayer+Lifecycle.swift +982 -0
  232. package/ios/TrackPlayer+NowPlayingFormat.swift +258 -0
  233. package/ios/TrackPlayer+Queue.swift +951 -0
  234. package/ios/TrackPlayer+Recovery.swift +213 -0
  235. package/ios/TrackPlayer+Skip.swift +465 -0
  236. package/ios/TrackPlayer+SleepTimer.swift +175 -0
  237. package/ios/TrackPlayer+State.swift +108 -0
  238. package/ios/TrackPlayer+Threading.swift +135 -0
  239. package/ios/TrackPlayer+Transport.swift +272 -0
  240. package/ios/TrackPlayer+Window.swift +227 -0
  241. package/ios/TrackPlayer.swift +331 -4619
  242. package/ios/Visualizer.swift +6 -5
  243. package/ios/tests-harness/Podfile +1 -1
  244. package/ios/tests-harness/TestHost.xcodeproj/project.pbxproj +19 -11
  245. package/ios/tests-harness/scripts/seed-xcodeproj.rb +2 -2
  246. package/lib/module/hooks/useActiveTrack.js +29 -22
  247. package/lib/module/hooks/useActiveTrack.js.map +1 -1
  248. package/lib/module/hooks/useCast.js +8 -26
  249. package/lib/module/hooks/useCast.js.map +1 -1
  250. package/lib/module/hooks/useEqualizer.js +19 -12
  251. package/lib/module/hooks/useEqualizer.js.map +1 -1
  252. package/lib/module/hooks/useLookaheadCache.js +3 -7
  253. package/lib/module/hooks/useLookaheadCache.js.map +1 -1
  254. package/lib/module/hooks/useQueue.js +66 -19
  255. package/lib/module/hooks/useQueue.js.map +1 -1
  256. package/lib/module/index.js +6 -3
  257. package/lib/module/index.js.map +1 -1
  258. package/lib/module/queueDelta.js +41 -0
  259. package/lib/module/queueDelta.js.map +1 -0
  260. package/lib/module/types.js +28 -5
  261. package/lib/module/types.js.map +1 -1
  262. package/lib/typescript/TrackPlayer.nitro.d.ts +53 -28
  263. package/lib/typescript/TrackPlayer.nitro.d.ts.map +1 -1
  264. package/lib/typescript/hooks/useActiveTrack.d.ts +5 -7
  265. package/lib/typescript/hooks/useActiveTrack.d.ts.map +1 -1
  266. package/lib/typescript/hooks/useCast.d.ts +6 -1
  267. package/lib/typescript/hooks/useCast.d.ts.map +1 -1
  268. package/lib/typescript/hooks/useEqualizer.d.ts +2 -1
  269. package/lib/typescript/hooks/useEqualizer.d.ts.map +1 -1
  270. package/lib/typescript/hooks/useLookaheadCache.d.ts.map +1 -1
  271. package/lib/typescript/hooks/useQueue.d.ts +4 -4
  272. package/lib/typescript/hooks/useQueue.d.ts.map +1 -1
  273. package/lib/typescript/index.d.ts +2 -1
  274. package/lib/typescript/index.d.ts.map +1 -1
  275. package/lib/typescript/queueDelta.d.ts +10 -0
  276. package/lib/typescript/queueDelta.d.ts.map +1 -0
  277. package/lib/typescript/types.d.ts +168 -12
  278. package/lib/typescript/types.d.ts.map +1 -1
  279. package/nitrogen/generated/android/c++/JFunc_void_QueueChangeDelta_double_QueueChangeReason.hpp +85 -0
  280. package/nitrogen/generated/android/c++/JHybridTrackPlayerSpec.cpp +45 -19
  281. package/nitrogen/generated/android/c++/JHybridTrackPlayerSpec.hpp +3 -3
  282. package/nitrogen/generated/android/c++/JLookaheadCacheConfig.hpp +8 -4
  283. package/nitrogen/generated/android/c++/JPlayerConfig.hpp +5 -1
  284. package/nitrogen/generated/android/c++/JQueueChangeDelta.hpp +128 -0
  285. package/nitrogen/generated/android/c++/JTrackItem.hpp +19 -3
  286. package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_std__shared_ptr_Promise_std__shared_ptr_Promise_std__vector_BrowseItem______std__string.kt +0 -2
  287. package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_std__shared_ptr_Promise_std__shared_ptr_Promise_std__vector_TrackItem______MediaSearchRequest.kt +0 -2
  288. package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_std__shared_ptr_Promise_std__shared_ptr_Promise_std__vector_TrackItem______std__string.kt +0 -2
  289. package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void.kt +0 -2
  290. package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void_AudioRoute.kt +0 -2
  291. package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void_BufferState.kt +0 -2
  292. package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void_CacheStatus.kt +0 -2
  293. package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void_CastDiscoveryState.kt +0 -2
  294. package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void_CastLocalNetworkPermissionEvent.kt +0 -2
  295. package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void_CastRoute.kt +0 -2
  296. package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void_CastSessionDiedEvent.kt +0 -2
  297. package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void_PlaybackError.kt +0 -2
  298. package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void_PlayerProgress.kt +0 -2
  299. package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void_PlayerState_StateChangeReason.kt +0 -2
  300. package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/{Func_void_std__vector_TrackItem__double_QueueChangeReason.kt → Func_void_QueueChangeDelta_double_QueueChangeReason.kt} +14 -16
  301. package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void_ServiceReadyReason.kt +0 -2
  302. package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void_SkipCapability.kt +0 -2
  303. package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void_SleepTimerState.kt +0 -2
  304. package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void_VisualizerErrorReason.kt +0 -2
  305. package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void_VisualizerFrame.kt +0 -2
  306. package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void_bool.kt +0 -2
  307. package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void_double_double.kt +0 -2
  308. package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void_std__optional_TrackItem__double_TrackChangeReason_std__optional_double_.kt +0 -2
  309. package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void_std__optional_std__variant_nitro__NullType__NowPlayingFormat__.kt +0 -2
  310. package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void_std__vector_CastReceiver_.kt +0 -2
  311. package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/Func_void_std__vector_EqualizerBand_.kt +0 -2
  312. package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/HybridCastManagerSpec.kt +2 -0
  313. package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/HybridEqualizerSpec.kt +2 -0
  314. package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/HybridTrackPlayerSpec.kt +6 -4
  315. package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/HybridVisualizerSpec.kt +2 -0
  316. package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/LookaheadCacheConfig.kt +9 -4
  317. package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/PlayerConfig.kt +7 -2
  318. package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/QueueChangeDelta.kt +86 -0
  319. package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/TrackItem.kt +24 -4
  320. package/nitrogen/generated/android/queueplayerOnLoad.cpp +2 -2
  321. package/nitrogen/generated/ios/QueuePlayer-Swift-Cxx-Bridge.cpp +16 -16
  322. package/nitrogen/generated/ios/QueuePlayer-Swift-Cxx-Bridge.hpp +80 -65
  323. package/nitrogen/generated/ios/QueuePlayer-Swift-Cxx-Umbrella.hpp +3 -0
  324. package/nitrogen/generated/ios/c++/HybridTrackPlayerSpecSwift.hpp +6 -3
  325. package/nitrogen/generated/ios/swift/Func_void_CacheStatus.swift +5 -5
  326. package/nitrogen/generated/ios/swift/Func_void_QueueChangeDelta_double_QueueChangeReason.swift +46 -0
  327. package/nitrogen/generated/ios/swift/HybridTrackPlayerSpec.swift +3 -3
  328. package/nitrogen/generated/ios/swift/HybridTrackPlayerSpec_cxx.swift +32 -24
  329. package/nitrogen/generated/ios/swift/LookaheadCacheConfig.swift +20 -2
  330. package/nitrogen/generated/ios/swift/PlayerConfig.swift +19 -1
  331. package/nitrogen/generated/ios/swift/QueueChangeDelta.swift +82 -0
  332. package/nitrogen/generated/ios/swift/TrackItem.swift +73 -1
  333. package/nitrogen/generated/shared/c++/HybridTrackPlayerSpec.hpp +6 -3
  334. package/nitrogen/generated/shared/c++/LookaheadCacheConfig.hpp +7 -3
  335. package/nitrogen/generated/shared/c++/PlayerConfig.hpp +5 -1
  336. package/nitrogen/generated/shared/c++/QueueChangeDelta.hpp +113 -0
  337. package/nitrogen/generated/shared/c++/TrackItem.hpp +18 -2
  338. package/package.json +8 -8
  339. package/src/TrackPlayer.nitro.ts +53 -27
  340. package/src/hooks/useActiveTrack.ts +29 -22
  341. package/src/hooks/useCast.ts +14 -15
  342. package/src/hooks/useEqualizer.ts +19 -12
  343. package/src/hooks/useLookaheadCache.ts +3 -7
  344. package/src/hooks/useQueue.ts +66 -17
  345. package/src/index.ts +13 -3
  346. package/src/queueDelta.ts +41 -0
  347. package/src/types.ts +169 -12
  348. package/android/src/main/java/com/margelo/nitro/queueplayer/PendingIntentBuffer.kt +0 -82
  349. package/android/src/main/java/com/margelo/nitro/queueplayer/cast/http/LocalMediaServerLifecycle.kt +0 -15
  350. package/android/src/test/java/com/margelo/nitro/queueplayer/PendingIntentBufferTest.kt +0 -192
  351. package/android/src/test/java/com/margelo/nitro/queueplayer/PlaybackEngineInterfaceTest.kt +0 -135
  352. package/android/src/test/java/com/margelo/nitro/queueplayer/SmokeTest.kt +0 -27
  353. package/ios/Cast/Core/LocalAddressMonitor.swift +0 -110
  354. package/ios/Cast/Core/MediaHTTPConnection.swift +0 -349
  355. package/ios/MetadataReader.swift +0 -555
  356. package/ios/Tests/CrossfadeEngineStubTests.swift +0 -43
  357. package/ios/Tests/MetadataReaderTests.swift +0 -603
  358. package/ios/Tests/PlaybackEngineProtocolTests.swift +0 -92
  359. package/ios/Tests/VoiceDonationTests.swift +0 -26
  360. package/nitrogen/generated/android/c++/JFunc_void_std__vector_TrackItem__double_QueueChangeReason.hpp +0 -101
  361. package/nitrogen/generated/ios/swift/Func_void_std__vector_TrackItem__double_QueueChangeReason.swift +0 -46
  362. /package/ios/{Cast/Core → MediaServer}/MimeTypes.swift +0 -0
@@ -14,6 +14,7 @@ import NitroModules
14
14
  /// hops to main and builds a Nitro ArrayBuffer.
15
15
  final class Visualizer: HybridVisualizerSpec {
16
16
 
17
+ private static let currentLock = NSLock()
17
18
  /// The most recently constructed Visualizer instance. Held for
18
19
  /// JS-reload teardown parity with Android — a fresh construction
19
20
  /// tears the prior instance's subscriptions + consumer
@@ -23,7 +24,6 @@ final class Visualizer: HybridVisualizerSpec {
23
24
  /// Acquire `currentLock` when reading or writing [current] —
24
25
  /// `init()` runs on the JS bridge while a prior instance may be
25
26
  /// mid-dispatch on the render thread.
26
- private static let currentLock = NSLock()
27
27
  private static var _current: Visualizer?
28
28
  static var current: Visualizer? {
29
29
  get {
@@ -52,8 +52,9 @@ final class Visualizer: HybridVisualizerSpec {
52
52
  let disposed: DisposedFlag
53
53
  }
54
54
 
55
- /// Thread-safe one-way "disposed" latch shared by a subscription and the
56
- /// emit blocks it has already enqueued onto the main queue.
55
+ /// Thread-safe "disposed" flag shared by a subscription and the emit blocks
56
+ /// it has already enqueued onto the main queue. `mark()` sets it; nothing
57
+ /// clears it.
57
58
  private final class DisposedFlag {
58
59
  private let lock = NSLock()
59
60
  private var value = false
@@ -65,12 +66,12 @@ final class Visualizer: HybridVisualizerSpec {
65
66
  private var subscriptions: [Subscription] = []
66
67
  private var nextId: Int = 1
67
68
 
69
+ private let assetLock = NSLock()
68
70
  /// Snapshot of the active asset — set from the audio-tap provider's
69
71
  /// `audioMix(for:)` path so `subscribe` can report `hls-source` for
70
72
  /// HLS streams without poking the TrackPlayer Hybrid. Held under its
71
73
  /// own lock so the render-thread-hot `subsLock` covers only the
72
74
  /// subscription array; main-thread asset writes never block render.
73
- private let assetLock = NSLock()
74
75
  private var activeAsset: AVAsset?
75
76
 
76
77
  private let provider: AudioTapProvider
@@ -176,7 +177,7 @@ final class Visualizer: HybridVisualizerSpec {
176
177
  // throttle (default 16ms) caps the emit rate, which puts a
177
178
  // natural ceiling on main-queue accumulation.
178
179
  DispatchQueue.main.async {
179
- // Drop frames queued before dispose — the disposer sets this latch
180
+ // Drop frames queued before dispose — the disposer sets this flag
180
181
  // before removing the subscription, so anything already on the main
181
182
  // queue short-circuits here rather than firing onFrame post-dispose.
182
183
  if disposed.isSet { return }
@@ -17,7 +17,7 @@
17
17
 
18
18
  require_relative '../../node_modules/react-native/scripts/react_native_pods'
19
19
 
20
- platform :ios, '15.1'
20
+ platform :ios, '16.0'
21
21
 
22
22
  prepare_react_native_project!
23
23
 
@@ -208,23 +208,29 @@
208
208
  );
209
209
  inputPaths = (
210
210
  "${PODS_ROOT}/Target Support Files/Pods-TestHost/Pods-TestHost-resources.sh",
211
+ "${PODS_CONFIGURATION_BUILD_DIR}/GTMSessionFetcher/GTMSessionFetcher_Core_Privacy.bundle",
212
+ "${PODS_CONFIGURATION_BUILD_DIR}/GTMSessionFetcher/GTMSessionFetcher_Full_Privacy.bundle",
211
213
  "${PODS_CONFIGURATION_BUILD_DIR}/QueuePlayer/QueuePlayer.bundle",
212
214
  "${PODS_CONFIGURATION_BUILD_DIR}/React-Core/React-Core_privacy.bundle",
213
215
  "${PODS_CONFIGURATION_BUILD_DIR}/React-cxxreact/React-cxxreact_privacy.bundle",
214
- "${PODS_ROOT}/google-cast-sdk/GoogleCastSDK-ios-4.8.4_static_xcframework/GoogleCast.xcframework/ios-arm64/GoogleCast.framework/GoogleCastCoreResources.bundle",
215
- "${PODS_ROOT}/google-cast-sdk/GoogleCastSDK-ios-4.8.4_static_xcframework/GoogleCast.xcframework/ios-arm64/GoogleCast.framework/GoogleCastUIResources.bundle",
216
- "${PODS_ROOT}/google-cast-sdk/GoogleCastSDK-ios-4.8.4_static_xcframework/GoogleCast.xcframework/ios-arm64/GoogleCast.framework/GoogleCastOptionalUIResources.bundle",
217
- "${PODS_ROOT}/google-cast-sdk/GoogleCastSDK-ios-4.8.4_static_xcframework/GoogleCast.xcframework/ios-arm64/GoogleCast.framework/MaterialDialogs.bundle",
218
- "${PODS_ROOT}/google-cast-sdk/GoogleCastSDK-ios-4.8.4_static_xcframework/GoogleCast.xcframework/ios-arm64/GoogleCast.framework/GoogleSansBold.bundle",
219
- "${PODS_ROOT}/google-cast-sdk/GoogleCastSDK-ios-4.8.4_static_xcframework/GoogleCast.xcframework/ios-arm64/GoogleCast.framework/GoogleSansMedium.bundle",
220
- "${PODS_ROOT}/google-cast-sdk/GoogleCastSDK-ios-4.8.4_static_xcframework/GoogleCast.xcframework/ios-arm64/GoogleCast.framework/GoogleSansRegular.bundle",
216
+ "${PODS_CONFIGURATION_BUILD_DIR}/React-timing/React-timing_privacy.bundle",
217
+ "${PODS_ROOT}/google-cast-sdk/GoogleCastSDK-ios-4.8.6_static_xcframework/GoogleCast.xcframework/ios-arm64/GoogleCast.framework/GoogleCastCoreResources.bundle",
218
+ "${PODS_ROOT}/google-cast-sdk/GoogleCastSDK-ios-4.8.6_static_xcframework/GoogleCast.xcframework/ios-arm64/GoogleCast.framework/GoogleCastUIResources.bundle",
219
+ "${PODS_ROOT}/google-cast-sdk/GoogleCastSDK-ios-4.8.6_static_xcframework/GoogleCast.xcframework/ios-arm64/GoogleCast.framework/GoogleCastOptionalUIResources.bundle",
220
+ "${PODS_ROOT}/google-cast-sdk/GoogleCastSDK-ios-4.8.6_static_xcframework/GoogleCast.xcframework/ios-arm64/GoogleCast.framework/MaterialDialogs.bundle",
221
+ "${PODS_ROOT}/google-cast-sdk/GoogleCastSDK-ios-4.8.6_static_xcframework/GoogleCast.xcframework/ios-arm64/GoogleCast.framework/GoogleSansBold.bundle",
222
+ "${PODS_ROOT}/google-cast-sdk/GoogleCastSDK-ios-4.8.6_static_xcframework/GoogleCast.xcframework/ios-arm64/GoogleCast.framework/GoogleSansMedium.bundle",
223
+ "${PODS_ROOT}/google-cast-sdk/GoogleCastSDK-ios-4.8.6_static_xcframework/GoogleCast.xcframework/ios-arm64/GoogleCast.framework/GoogleSansRegular.bundle",
221
224
  "${PODS_CONFIGURATION_BUILD_DIR}/google-cast-sdk/GoogleCast.bundle",
222
225
  );
223
226
  name = "[CP] Copy Pods Resources";
224
227
  outputPaths = (
228
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/GTMSessionFetcher_Core_Privacy.bundle",
229
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/GTMSessionFetcher_Full_Privacy.bundle",
225
230
  "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/QueuePlayer.bundle",
226
231
  "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/React-Core_privacy.bundle",
227
232
  "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/React-cxxreact_privacy.bundle",
233
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/React-timing_privacy.bundle",
228
234
  "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/GoogleCastCoreResources.bundle",
229
235
  "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/GoogleCastUIResources.bundle",
230
236
  "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/GoogleCastOptionalUIResources.bundle",
@@ -264,7 +270,7 @@
264
270
  CURRENT_PROJECT_VERSION = 1;
265
271
  GENERATE_INFOPLIST_FILE = NO;
266
272
  INFOPLIST_FILE = TestHost/Info.plist;
267
- IPHONEOS_DEPLOYMENT_TARGET = 15.1;
273
+ IPHONEOS_DEPLOYMENT_TARGET = 16.0;
268
274
  LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
269
275
  MARKETING_VERSION = 1.0;
270
276
  PRODUCT_BUNDLE_IDENTIFIER = org.ghenry22.RNQueuePlayer.TestHost;
@@ -327,7 +333,7 @@
327
333
  GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
328
334
  GCC_WARN_UNUSED_FUNCTION = YES;
329
335
  GCC_WARN_UNUSED_VARIABLE = YES;
330
- IPHONEOS_DEPLOYMENT_TARGET = 15.1;
336
+ IPHONEOS_DEPLOYMENT_TARGET = 16.0;
331
337
  MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
332
338
  MTL_FAST_MATH = YES;
333
339
  ONLY_ACTIVE_ARCH = YES;
@@ -339,6 +345,7 @@
339
345
  "$(inherited)",
340
346
  "-DRCT_REMOVE_LEGACY_ARCH=1",
341
347
  );
348
+ PODFILE_DIR = "$(SRCROOT)";
342
349
  PRODUCT_NAME = "$(TARGET_NAME)";
343
350
  REACT_NATIVE_PATH = "${PODS_ROOT}/../../../node_modules/react-native";
344
351
  SDKROOT = iphoneos;
@@ -398,7 +405,7 @@
398
405
  GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
399
406
  GCC_WARN_UNUSED_FUNCTION = YES;
400
407
  GCC_WARN_UNUSED_VARIABLE = YES;
401
- IPHONEOS_DEPLOYMENT_TARGET = 15.1;
408
+ IPHONEOS_DEPLOYMENT_TARGET = 16.0;
402
409
  MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
403
410
  MTL_FAST_MATH = YES;
404
411
  ONLY_ACTIVE_ARCH = YES;
@@ -410,6 +417,7 @@
410
417
  "$(inherited)",
411
418
  "-DRCT_REMOVE_LEGACY_ARCH=1",
412
419
  );
420
+ PODFILE_DIR = "$(SRCROOT)";
413
421
  PRODUCT_NAME = "$(TARGET_NAME)";
414
422
  REACT_NATIVE_PATH = "${PODS_ROOT}/../../../node_modules/react-native";
415
423
  SDKROOT = iphoneos;
@@ -433,7 +441,7 @@
433
441
  CURRENT_PROJECT_VERSION = 1;
434
442
  GENERATE_INFOPLIST_FILE = NO;
435
443
  INFOPLIST_FILE = TestHost/Info.plist;
436
- IPHONEOS_DEPLOYMENT_TARGET = 15.1;
444
+ IPHONEOS_DEPLOYMENT_TARGET = 16.0;
437
445
  LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
438
446
  MARKETING_VERSION = 1.0;
439
447
  PRODUCT_BUNDLE_IDENTIFIER = org.ghenry22.RNQueuePlayer.TestHost;
@@ -41,7 +41,7 @@ end
41
41
 
42
42
  project = Xcodeproj::Project.new(PROJECT_PATH)
43
43
 
44
- target = project.new_target(:application, 'TestHost', :ios, '15.1', nil, :swift)
44
+ target = project.new_target(:application, 'TestHost', :ios, '16.0', nil, :swift)
45
45
 
46
46
  host_group = project.new_group('TestHost', 'TestHost')
47
47
  app_ref = host_group.new_reference('App.swift')
@@ -64,7 +64,7 @@ project.build_configurations.each do |config|
64
64
  'GCC_C_LANGUAGE_STANDARD' => 'gnu17',
65
65
  'GCC_DYNAMIC_NO_PIC' => 'NO',
66
66
  'GCC_NO_COMMON_BLOCKS' => 'YES',
67
- 'IPHONEOS_DEPLOYMENT_TARGET' => '15.1',
67
+ 'IPHONEOS_DEPLOYMENT_TARGET' => '16.0',
68
68
  'MTL_FAST_MATH' => 'YES',
69
69
  'ONLY_ACTIVE_ARCH' => 'YES',
70
70
  'SDKROOT' => 'iphoneos',
@@ -11,39 +11,46 @@ const INITIAL = {
11
11
  /**
12
12
  * Subscribes to native `onTrackChange` updates.
13
13
  *
14
- * The first-render seed reads `getQueue()` and `getCurrentTrackIndex()`
15
- * separately the pair is not atomic against a concurrent queue
16
- * mutation on either platform, so the seed can briefly observe the
17
- * new list with the old index (or vice versa). Self-healing: the
18
- * next `onTrackChange` event delivers a consistent
19
- * `(track, index, reason)` triple. Consumers needing an atomic
20
- * snapshot should wait for the first listener fire.
14
+ * Renders empty for the first frame, then fills in: the seed reads
15
+ * `getQueue()`, which resolves asynchronously, and pairs it with a separately
16
+ * read index so it can briefly observe a new list against an old index. Any
17
+ * `onTrackChange` that arrives first wins and the seed is dropped, since the
18
+ * event delivers a consistent `(track, index, reason)` triple.
21
19
  */
22
20
  export function useActiveTrack() {
23
- const [snapshot, setSnapshot] = useState(() => {
24
- try {
25
- const player = getTrackPlayer();
26
- const queue = player.getQueue();
27
- const index = player.getCurrentTrackIndex();
28
- return {
29
- track: index >= 0 && index < queue.length ? queue[index] : undefined,
30
- index,
31
- reason: 'queue-replaced'
32
- };
33
- } catch {
34
- return INITIAL;
35
- }
36
- });
21
+ const [snapshot, setSnapshot] = useState(INITIAL);
37
22
  useEffect(() => {
38
23
  const player = getTrackPlayer();
24
+ let seeded = false;
25
+ // A seed still in flight when this effect is cleaned up (a StrictMode
26
+ // remount, an unmount) must not land on a later mount's state.
27
+ let disposed = false;
28
+ void (async () => {
29
+ try {
30
+ const queue = await player.getQueue();
31
+ const index = player.getCurrentTrackIndex();
32
+ if (disposed || seeded) return;
33
+ setSnapshot({
34
+ track: index >= 0 && index < queue.length ? queue[index] : undefined,
35
+ index,
36
+ reason: 'queue-replaced'
37
+ });
38
+ } catch {
39
+ // Player not configured yet; the first event seeds instead.
40
+ }
41
+ })();
39
42
  const dispose = player.onTrackChange((track, index, reason) => {
43
+ seeded = true;
40
44
  setSnapshot({
41
45
  track,
42
46
  index,
43
47
  reason
44
48
  });
45
49
  });
46
- return dispose;
50
+ return () => {
51
+ disposed = true;
52
+ dispose();
53
+ };
47
54
  }, []);
48
55
  return snapshot;
49
56
  }
@@ -1 +1 @@
1
- {"version":3,"names":["useEffect","useState","getTrackPlayer","INITIAL","track","undefined","index","reason","useActiveTrack","snapshot","setSnapshot","player","queue","getQueue","getCurrentTrackIndex","length","dispose","onTrackChange"],"sourceRoot":"../../../src","sources":["hooks/useActiveTrack.ts"],"mappings":";;AAAA,SAASA,SAAS,EAAEC,QAAQ,QAAQ,OAAO;AAC3C,SAASC,cAAc,QAAQ,eAAY;AAW3C,MAAMC,OAA4B,GAAG;EACnCC,KAAK,EAAEC,SAAS;EAChBC,KAAK,EAAE,CAAC,CAAC;EACTC,MAAM,EAAE;AACV,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,cAAcA,CAAA,EAAwB;EACpD,MAAM,CAACC,QAAQ,EAAEC,WAAW,CAAC,GAAGT,QAAQ,CAAsB,MAAM;IAClE,IAAI;MACF,MAAMU,MAAM,GAAGT,cAAc,CAAC,CAAC;MAC/B,MAAMU,KAAK,GAAGD,MAAM,CAACE,QAAQ,CAAC,CAAC;MAC/B,MAAMP,KAAK,GAAGK,MAAM,CAACG,oBAAoB,CAAC,CAAC;MAC3C,OAAO;QACLV,KAAK,EAAEE,KAAK,IAAI,CAAC,IAAIA,KAAK,GAAGM,KAAK,CAACG,MAAM,GAAGH,KAAK,CAACN,KAAK,CAAC,GAAGD,SAAS;QACpEC,KAAK;QACLC,MAAM,EAAE;MACV,CAAC;IACH,CAAC,CAAC,MAAM;MACN,OAAOJ,OAAO;IAChB;EACF,CAAC,CAAC;EAEFH,SAAS,CAAC,MAAM;IACd,MAAMW,MAAM,GAAGT,cAAc,CAAC,CAAC;IAC/B,MAAMc,OAAO,GAAGL,MAAM,CAACM,aAAa,CAAC,CAACb,KAAK,EAAEE,KAAK,EAAEC,MAAM,KAAK;MAC7DG,WAAW,CAAC;QAAEN,KAAK;QAAEE,KAAK;QAAEC;MAAO,CAAC,CAAC;IACvC,CAAC,CAAC;IACF,OAAOS,OAAO;EAChB,CAAC,EAAE,EAAE,CAAC;EAEN,OAAOP,QAAQ;AACjB","ignoreList":[]}
1
+ {"version":3,"names":["useEffect","useState","getTrackPlayer","INITIAL","track","undefined","index","reason","useActiveTrack","snapshot","setSnapshot","player","seeded","disposed","queue","getQueue","getCurrentTrackIndex","length","dispose","onTrackChange"],"sourceRoot":"../../../src","sources":["hooks/useActiveTrack.ts"],"mappings":";;AAAA,SAASA,SAAS,EAAEC,QAAQ,QAAQ,OAAO;AAC3C,SAASC,cAAc,QAAQ,eAAY;AAW3C,MAAMC,OAA4B,GAAG;EACnCC,KAAK,EAAEC,SAAS;EAChBC,KAAK,EAAE,CAAC,CAAC;EACTC,MAAM,EAAE;AACV,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,cAAcA,CAAA,EAAwB;EACpD,MAAM,CAACC,QAAQ,EAAEC,WAAW,CAAC,GAAGT,QAAQ,CAAsBE,OAAO,CAAC;EAEtEH,SAAS,CAAC,MAAM;IACd,MAAMW,MAAM,GAAGT,cAAc,CAAC,CAAC;IAC/B,IAAIU,MAAM,GAAG,KAAK;IAClB;IACA;IACA,IAAIC,QAAQ,GAAG,KAAK;IACpB,KAAK,CAAC,YAAY;MAChB,IAAI;QACF,MAAMC,KAAK,GAAG,MAAMH,MAAM,CAACI,QAAQ,CAAC,CAAC;QACrC,MAAMT,KAAK,GAAGK,MAAM,CAACK,oBAAoB,CAAC,CAAC;QAC3C,IAAIH,QAAQ,IAAID,MAAM,EAAE;QACxBF,WAAW,CAAC;UACVN,KAAK,EAAEE,KAAK,IAAI,CAAC,IAAIA,KAAK,GAAGQ,KAAK,CAACG,MAAM,GAAGH,KAAK,CAACR,KAAK,CAAC,GAAGD,SAAS;UACpEC,KAAK;UACLC,MAAM,EAAE;QACV,CAAC,CAAC;MACJ,CAAC,CAAC,MAAM;QACN;MAAA;IAEJ,CAAC,EAAE,CAAC;IACJ,MAAMW,OAAO,GAAGP,MAAM,CAACQ,aAAa,CAAC,CAACf,KAAK,EAAEE,KAAK,EAAEC,MAAM,KAAK;MAC7DK,MAAM,GAAG,IAAI;MACbF,WAAW,CAAC;QAAEN,KAAK;QAAEE,KAAK;QAAEC;MAAO,CAAC,CAAC;IACvC,CAAC,CAAC;IACF,OAAO,MAAM;MACXM,QAAQ,GAAG,IAAI;MACfK,OAAO,CAAC,CAAC;IACX,CAAC;EACH,CAAC,EAAE,EAAE,CAAC;EAEN,OAAOT,QAAQ;AACjB","ignoreList":[]}
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
 
3
3
  import { useEffect, useState } from 'react';
4
- import { addDiscoveryStateListener, addLocalNetworkPermissionListener, addReceiversListener, addRouteListener, addSessionDiedListener, getCurrentRoute, getReceivers, getSupportedProtocols, isCastAvailable, isDiscovering, localRoute } from "../cast/index.js";
4
+ import { addDiscoveryStateListener, addLocalNetworkPermissionListener, addReceiversListener, addRouteListener, addSessionDiedListener, getCurrentRoute, getLocalNetworkPermissionState, getReceivers, getSupportedProtocols, isCastAvailable, isDiscovering, localRoute } from "../cast/index.js";
5
5
  const INITIAL = {
6
6
  supportedProtocols: [],
7
7
  isAvailable: false,
@@ -33,7 +33,7 @@ export function useCast() {
33
33
  route: getCurrentRoute(),
34
34
  isDiscovering: isDiscovering(),
35
35
  lastSessionDied: null,
36
- permission: 'undetermined'
36
+ permission: getLocalNetworkPermissionState()
37
37
  };
38
38
  } catch {
39
39
  return INITIAL;
@@ -42,39 +42,25 @@ export function useCast() {
42
42
  useEffect(() => {
43
43
  if (!isCastAvailable()) return;
44
44
 
45
- // Each `addXxxListener` synchronously replays the current value on
46
- // subscribe. The initial `useState` initializer already captured
47
- // every initial value; skipping the first replay per stream avoids
48
- // five back-to-back `setSnapshot` calls on mount.
49
- let firstRoute = true;
50
- let firstReceivers = true;
51
- let firstDiscovery = true;
52
- let firstPermission = true;
45
+ // Each `addXxxListener` replays the current value synchronously on
46
+ // subscribe, and every delivery is applied: a replay that equals the
47
+ // `useState` seed costs one batched render, while a replay that differs
48
+ // is a change that landed between the render and this effect — dropping
49
+ // it would leave the snapshot on the stale seed (on Android the
50
+ // permission replay is the only delivery there ever is).
53
51
  const routeSub = addRouteListener(route => {
54
- if (firstRoute) {
55
- firstRoute = false;
56
- return;
57
- }
58
52
  setSnapshot(prev => ({
59
53
  ...prev,
60
54
  route
61
55
  }));
62
56
  });
63
57
  const receiversSub = addReceiversListener(receivers => {
64
- if (firstReceivers) {
65
- firstReceivers = false;
66
- return;
67
- }
68
58
  setSnapshot(prev => ({
69
59
  ...prev,
70
60
  receivers
71
61
  }));
72
62
  });
73
63
  const discoverySub = addDiscoveryStateListener(state => {
74
- if (firstDiscovery) {
75
- firstDiscovery = false;
76
- return;
77
- }
78
64
  setSnapshot(prev => ({
79
65
  ...prev,
80
66
  isDiscovering: state.isDiscovering
@@ -85,10 +71,6 @@ export function useCast() {
85
71
  lastSessionDied: event
86
72
  })));
87
73
  const permissionSub = addLocalNetworkPermissionListener(event => {
88
- if (firstPermission) {
89
- firstPermission = false;
90
- return;
91
- }
92
74
  setSnapshot(prev => ({
93
75
  ...prev,
94
76
  permission: event.state
@@ -1 +1 @@
1
- {"version":3,"names":["useEffect","useState","addDiscoveryStateListener","addLocalNetworkPermissionListener","addReceiversListener","addRouteListener","addSessionDiedListener","getCurrentRoute","getReceivers","getSupportedProtocols","isCastAvailable","isDiscovering","localRoute","INITIAL","supportedProtocols","isAvailable","receivers","route","lastSessionDied","permission","useCast","snapshot","setSnapshot","protocols","length","firstRoute","firstReceivers","firstDiscovery","firstPermission","routeSub","prev","receiversSub","discoverySub","state","deathSub","event","permissionSub","remove"],"sourceRoot":"../../../src","sources":["hooks/useCast.ts"],"mappings":";;AAAA,SAASA,SAAS,EAAEC,QAAQ,QAAQ,OAAO;AAC3C,SACEC,yBAAyB,EACzBC,iCAAiC,EACjCC,oBAAoB,EACpBC,gBAAgB,EAChBC,sBAAsB,EACtBC,eAAe,EACfC,YAAY,EACZC,qBAAqB,EACrBC,eAAe,EACfC,aAAa,EACbC,UAAU,QAML,kBAAS;AAsBhB,MAAMC,OAAqB,GAAG;EAC5BC,kBAAkB,EAAE,EAAE;EACtBC,WAAW,EAAE,KAAK;EAClBC,SAAS,EAAE,EAAE;EACbC,KAAK,EAAEL,UAAU,CAAC,CAAC;EACnBD,aAAa,EAAE,KAAK;EACpBO,eAAe,EAAE,IAAI;EACrBC,UAAU,EAAE;AACd,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,OAAOA,CAAA,EAAiB;EACtC,MAAM,CAACC,QAAQ,EAAEC,WAAW,CAAC,GAAGrB,QAAQ,CAAe,MAAM;IAC3D,IAAI;MACF,MAAMsB,SAAS,GAAGd,qBAAqB,CAAC,CAAC;MACzC,OAAO;QACLK,kBAAkB,EAAES,SAAS;QAC7BR,WAAW,EAAEQ,SAAS,CAACC,MAAM,GAAG,CAAC;QACjCR,SAAS,EAAER,YAAY,CAAC,CAAC;QACzBS,KAAK,EAAEV,eAAe,CAAC,CAAC;QACxBI,aAAa,EAAEA,aAAa,CAAC,CAAC;QAC9BO,eAAe,EAAE,IAAI;QACrBC,UAAU,EAAE;MACd,CAAC;IACH,CAAC,CAAC,MAAM;MACN,OAAON,OAAO;IAChB;EACF,CAAC,CAAC;EAEFb,SAAS,CAAC,MAAM;IACd,IAAI,CAACU,eAAe,CAAC,CAAC,EAAE;;IAExB;IACA;IACA;IACA;IACA,IAAIe,UAAU,GAAG,IAAI;IACrB,IAAIC,cAAc,GAAG,IAAI;IACzB,IAAIC,cAAc,GAAG,IAAI;IACzB,IAAIC,eAAe,GAAG,IAAI;IAE1B,MAAMC,QAAQ,GAAGxB,gBAAgB,CAAEY,KAAK,IAAK;MAC3C,IAAIQ,UAAU,EAAE;QAAEA,UAAU,GAAG,KAAK;QAAE;MAAQ;MAC9CH,WAAW,CAAEQ,IAAI,KAAM;QAAE,GAAGA,IAAI;QAAEb;MAAM,CAAC,CAAC,CAAC;IAC7C,CAAC,CAAC;IACF,MAAMc,YAAY,GAAG3B,oBAAoB,CAAEY,SAAS,IAAK;MACvD,IAAIU,cAAc,EAAE;QAAEA,cAAc,GAAG,KAAK;QAAE;MAAQ;MACtDJ,WAAW,CAAEQ,IAAI,KAAM;QAAE,GAAGA,IAAI;QAAEd;MAAU,CAAC,CAAC,CAAC;IACjD,CAAC,CAAC;IACF,MAAMgB,YAAY,GAAG9B,yBAAyB,CAAE+B,KAAK,IAAK;MACxD,IAAIN,cAAc,EAAE;QAAEA,cAAc,GAAG,KAAK;QAAE;MAAQ;MACtDL,WAAW,CAAEQ,IAAI,KAAM;QAAE,GAAGA,IAAI;QAAEnB,aAAa,EAAEsB,KAAK,CAACtB;MAAc,CAAC,CAAC,CAAC;IAC1E,CAAC,CAAC;IACF,MAAMuB,QAAQ,GAAG5B,sBAAsB,CAAE6B,KAAK,IAC5Cb,WAAW,CAAEQ,IAAI,KAAM;MAAE,GAAGA,IAAI;MAAEZ,eAAe,EAAEiB;IAAM,CAAC,CAAC,CAC7D,CAAC;IACD,MAAMC,aAAa,GAAGjC,iCAAiC,CAAEgC,KAAK,IAAK;MACjE,IAAIP,eAAe,EAAE;QAAEA,eAAe,GAAG,KAAK;QAAE;MAAQ;MACxDN,WAAW,CAAEQ,IAAI,KAAM;QAAE,GAAGA,IAAI;QAAEX,UAAU,EAAEgB,KAAK,CAACF;MAAM,CAAC,CAAC,CAAC;IAC/D,CAAC,CAAC;IAEF,OAAO,MAAM;MACXJ,QAAQ,CAACQ,MAAM,CAAC,CAAC;MACjBN,YAAY,CAACM,MAAM,CAAC,CAAC;MACrBL,YAAY,CAACK,MAAM,CAAC,CAAC;MACrBH,QAAQ,CAACG,MAAM,CAAC,CAAC;MACjBD,aAAa,CAACC,MAAM,CAAC,CAAC;IACxB,CAAC;EACH,CAAC,EAAE,EAAE,CAAC;EAEN,OAAOhB,QAAQ;AACjB","ignoreList":[]}
1
+ {"version":3,"names":["useEffect","useState","addDiscoveryStateListener","addLocalNetworkPermissionListener","addReceiversListener","addRouteListener","addSessionDiedListener","getCurrentRoute","getLocalNetworkPermissionState","getReceivers","getSupportedProtocols","isCastAvailable","isDiscovering","localRoute","INITIAL","supportedProtocols","isAvailable","receivers","route","lastSessionDied","permission","useCast","snapshot","setSnapshot","protocols","length","routeSub","prev","receiversSub","discoverySub","state","deathSub","event","permissionSub","remove"],"sourceRoot":"../../../src","sources":["hooks/useCast.ts"],"mappings":";;AAAA,SAASA,SAAS,EAAEC,QAAQ,QAAQ,OAAO;AAC3C,SACEC,yBAAyB,EACzBC,iCAAiC,EACjCC,oBAAoB,EACpBC,gBAAgB,EAChBC,sBAAsB,EACtBC,eAAe,EACfC,8BAA8B,EAC9BC,YAAY,EACZC,qBAAqB,EACrBC,eAAe,EACfC,aAAa,EACbC,UAAU,QAML,kBAAS;AA2BhB,MAAMC,OAAqB,GAAG;EAC5BC,kBAAkB,EAAE,EAAE;EACtBC,WAAW,EAAE,KAAK;EAClBC,SAAS,EAAE,EAAE;EACbC,KAAK,EAAEL,UAAU,CAAC,CAAC;EACnBD,aAAa,EAAE,KAAK;EACpBO,eAAe,EAAE,IAAI;EACrBC,UAAU,EAAE;AACd,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,OAAOA,CAAA,EAAiB;EACtC,MAAM,CAACC,QAAQ,EAAEC,WAAW,CAAC,GAAGtB,QAAQ,CAAe,MAAM;IAC3D,IAAI;MACF,MAAMuB,SAAS,GAAGd,qBAAqB,CAAC,CAAC;MACzC,OAAO;QACLK,kBAAkB,EAAES,SAAS;QAC7BR,WAAW,EAAEQ,SAAS,CAACC,MAAM,GAAG,CAAC;QACjCR,SAAS,EAAER,YAAY,CAAC,CAAC;QACzBS,KAAK,EAAEX,eAAe,CAAC,CAAC;QACxBK,aAAa,EAAEA,aAAa,CAAC,CAAC;QAC9BO,eAAe,EAAE,IAAI;QACrBC,UAAU,EAAEZ,8BAA8B,CAAC;MAC7C,CAAC;IACH,CAAC,CAAC,MAAM;MACN,OAAOM,OAAO;IAChB;EACF,CAAC,CAAC;EAEFd,SAAS,CAAC,MAAM;IACd,IAAI,CAACW,eAAe,CAAC,CAAC,EAAE;;IAExB;IACA;IACA;IACA;IACA;IACA;IACA,MAAMe,QAAQ,GAAGrB,gBAAgB,CAAEa,KAAK,IAAK;MAC3CK,WAAW,CAAEI,IAAI,KAAM;QAAE,GAAGA,IAAI;QAAET;MAAM,CAAC,CAAC,CAAC;IAC7C,CAAC,CAAC;IACF,MAAMU,YAAY,GAAGxB,oBAAoB,CAAEa,SAAS,IAAK;MACvDM,WAAW,CAAEI,IAAI,KAAM;QAAE,GAAGA,IAAI;QAAEV;MAAU,CAAC,CAAC,CAAC;IACjD,CAAC,CAAC;IACF,MAAMY,YAAY,GAAG3B,yBAAyB,CAAE4B,KAAK,IAAK;MACxDP,WAAW,CAAEI,IAAI,KAAM;QAAE,GAAGA,IAAI;QAAEf,aAAa,EAAEkB,KAAK,CAAClB;MAAc,CAAC,CAAC,CAAC;IAC1E,CAAC,CAAC;IACF,MAAMmB,QAAQ,GAAGzB,sBAAsB,CAAE0B,KAAK,IAC5CT,WAAW,CAAEI,IAAI,KAAM;MAAE,GAAGA,IAAI;MAAER,eAAe,EAAEa;IAAM,CAAC,CAAC,CAC7D,CAAC;IACD,MAAMC,aAAa,GAAG9B,iCAAiC,CAAE6B,KAAK,IAAK;MACjET,WAAW,CAAEI,IAAI,KAAM;QAAE,GAAGA,IAAI;QAAEP,UAAU,EAAEY,KAAK,CAACF;MAAM,CAAC,CAAC,CAAC;IAC/D,CAAC,CAAC;IAEF,OAAO,MAAM;MACXJ,QAAQ,CAACQ,MAAM,CAAC,CAAC;MACjBN,YAAY,CAACM,MAAM,CAAC,CAAC;MACrBL,YAAY,CAACK,MAAM,CAAC,CAAC;MACrBH,QAAQ,CAACG,MAAM,CAAC,CAAC;MACjBD,aAAa,CAACC,MAAM,CAAC,CAAC;IACxB,CAAC;EACH,CAAC,EAAE,EAAE,CAAC;EAEN,OAAOZ,QAAQ;AACjB","ignoreList":[]}
@@ -3,7 +3,8 @@
3
3
  import { useCallback, useEffect, useState } from 'react';
4
4
  import { getEqualizer } from "../clients.js";
5
5
  /**
6
- * Subscribes to Equalizer band-change events and exposes imperative setters.
6
+ * Subscribes to Equalizer band-change and enabled-change events and
7
+ * exposes imperative setters.
7
8
  * Initial state is pulled synchronously on mount so consumers don't flash
8
9
  * empty bands.
9
10
  */
@@ -31,20 +32,27 @@ export function useEqualizer() {
31
32
  });
32
33
  useEffect(() => {
33
34
  const eq = getEqualizer();
34
- const dispose = eq.onBandChange(updated => {
35
+ const disposeBands = eq.onBandChange(updated => {
35
36
  setBands(updated);
36
37
  });
37
- return dispose;
38
+ const disposeEnabled = eq.onEnabledChange(next => {
39
+ setEnabledState(next);
40
+ });
41
+ return () => {
42
+ disposeBands();
43
+ disposeEnabled();
44
+ };
38
45
  }, []);
39
46
  const setEnabled = useCallback(async next => {
40
47
  const eq = getEqualizer();
41
48
  await eq.setEnabled(next);
42
- // Read back rather than echoing the requested value: the native
43
- // side may reject (or coerce) the change in a future build, and
44
- // mirroring its actual state keeps JS aligned without a separate
45
- // `onEnabledChange` event. Fall back to the requested value when
46
- // the read-back throws (today's behaviour against the
47
- // unimplemented native matches the seed's try/catch on init).
49
+ // `isEnabled()` is the authority on what the native side committed,
50
+ // so read it back rather than echoing the request. `onEnabledChange`
51
+ // has already delivered the same value both platforms emit it
52
+ // synchronously inside `setEnabled`'s promise body which makes this
53
+ // a redundant write on the happy path and the only correction if a
54
+ // future native build stops emitting. Fall back to the requested
55
+ // value when the read-back throws, matching the seed's try/catch.
48
56
  try {
49
57
  setEnabledState(eq.isEnabled());
50
58
  } catch {
@@ -61,9 +69,8 @@ export function useEqualizer() {
61
69
  await getEqualizer().applyPreset(name);
62
70
  }, []);
63
71
 
64
- // TODO: wire onPresetsChange when added to Equalizer.nitro.ts
65
- // until then, save/delete refresh the local presets list with a
66
- // manual sync re-fetch.
72
+ // The spec carries no presets-changed event, so save and delete
73
+ // re-read `getPresets()` themselves to refresh the local list.
67
74
  const saveCustomPreset = useCallback(async name => {
68
75
  await getEqualizer().saveCustomPreset(name);
69
76
  setPresets(getEqualizer().getPresets());
@@ -1 +1 @@
1
- {"version":3,"names":["useCallback","useEffect","useState","getEqualizer","useEqualizer","enabled","setEnabledState","isEnabled","bands","setBands","getBands","presets","setPresets","getPresets","eq","dispose","onBandChange","updated","setEnabled","next","setBandGain","index","gainDb","setAllBandGains","gains","applyPreset","name","saveCustomPreset","deleteCustomPreset","reset"],"sourceRoot":"../../../src","sources":["hooks/useEqualizer.ts"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["useCallback","useEffect","useState","getEqualizer","useEqualizer","enabled","setEnabledState","isEnabled","bands","setBands","getBands","presets","setPresets","getPresets","eq","disposeBands","onBandChange","updated","disposeEnabled","onEnabledChange","next","setEnabled","setBandGain","index","gainDb","setAllBandGains","gains","applyPreset","name","saveCustomPreset","deleteCustomPreset","reset"],"sourceRoot":"../../../src","sources":["hooks/useEqualizer.ts"],"mappings":"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","ignoreList":[]}
@@ -20,13 +20,9 @@ const INITIAL = {
20
20
  * and drop the lookahead count).
21
21
  */
22
22
  export function useLookaheadCache() {
23
- const [status, setStatus] = useState(() => {
24
- try {
25
- return getTrackPlayer().getLookaheadCacheStatus();
26
- } catch {
27
- return INITIAL;
28
- }
29
- });
23
+ // Seeded by the listener's own first fire, which delivers current status on
24
+ // registration — no getter call, so this survives the getter being async.
25
+ const [status, setStatus] = useState(INITIAL);
30
26
  useEffect(() => {
31
27
  const player = getTrackPlayer();
32
28
  const dispose = player.onCacheStatusChange(next => {
@@ -1 +1 @@
1
- {"version":3,"names":["useCallback","useEffect","useState","getTrackPlayer","INITIAL","enabled","currentSizeMb","maxSizeMb","tracksFullyCached","currentlyCaching","useLookaheadCache","status","setStatus","getLookaheadCacheStatus","player","dispose","onCacheStatusChange","next","setConfig","config","setLookaheadCache","clear","clearLookaheadCache"],"sourceRoot":"../../../src","sources":["hooks/useLookaheadCache.ts"],"mappings":";;AAAA,SAASA,WAAW,EAAEC,SAAS,EAAEC,QAAQ,QAAQ,OAAO;AACxD,SAASC,cAAc,QAAQ,eAAY;AAS3C;AACA;AACA;AACA;AACA,MAAMC,OAAoB,GAAG;EAC3BC,OAAO,EAAE,KAAK;EACdC,aAAa,EAAE,CAAC;EAChBC,SAAS,EAAE,GAAG;EACdC,iBAAiB,EAAE,CAAC;EACpBC,gBAAgB,EAAE;AACpB,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,iBAAiBA,CAAA,EAA4B;EAC3D,MAAM,CAACC,MAAM,EAAEC,SAAS,CAAC,GAAGV,QAAQ,CAAc,MAAM;IACtD,IAAI;MACF,OAAOC,cAAc,CAAC,CAAC,CAACU,uBAAuB,CAAC,CAAC;IACnD,CAAC,CAAC,MAAM;MACN,OAAOT,OAAO;IAChB;EACF,CAAC,CAAC;EAEFH,SAAS,CAAC,MAAM;IACd,MAAMa,MAAM,GAAGX,cAAc,CAAC,CAAC;IAC/B,MAAMY,OAAO,GAAGD,MAAM,CAACE,mBAAmB,CAAEC,IAAI,IAAK;MACnDL,SAAS,CAACK,IAAI,CAAC;IACjB,CAAC,CAAC;IACF,OAAOF,OAAO;EAChB,CAAC,EAAE,EAAE,CAAC;EAEN,MAAMG,SAAS,GAAGlB,WAAW,CAAC,MAAOmB,MAA4B,IAAK;IACpE,MAAMhB,cAAc,CAAC,CAAC,CAACiB,iBAAiB,CAACD,MAAM,CAAC;EAClD,CAAC,EAAE,EAAE,CAAC;EAEN,MAAME,KAAK,GAAGrB,WAAW,CAAC,YAAY;IACpC,MAAMG,cAAc,CAAC,CAAC,CAACmB,mBAAmB,CAAC,CAAC;EAC9C,CAAC,EAAE,EAAE,CAAC;EAEN,OAAO;IAAEX,MAAM;IAAEO,SAAS;IAAEG;EAAM,CAAC;AACrC","ignoreList":[]}
1
+ {"version":3,"names":["useCallback","useEffect","useState","getTrackPlayer","INITIAL","enabled","currentSizeMb","maxSizeMb","tracksFullyCached","currentlyCaching","useLookaheadCache","status","setStatus","player","dispose","onCacheStatusChange","next","setConfig","config","setLookaheadCache","clear","clearLookaheadCache"],"sourceRoot":"../../../src","sources":["hooks/useLookaheadCache.ts"],"mappings":";;AAAA,SAASA,WAAW,EAAEC,SAAS,EAAEC,QAAQ,QAAQ,OAAO;AACxD,SAASC,cAAc,QAAQ,eAAY;AAS3C;AACA;AACA;AACA;AACA,MAAMC,OAAoB,GAAG;EAC3BC,OAAO,EAAE,KAAK;EACdC,aAAa,EAAE,CAAC;EAChBC,SAAS,EAAE,GAAG;EACdC,iBAAiB,EAAE,CAAC;EACpBC,gBAAgB,EAAE;AACpB,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,iBAAiBA,CAAA,EAA4B;EAC3D;EACA;EACA,MAAM,CAACC,MAAM,EAAEC,SAAS,CAAC,GAAGV,QAAQ,CAAcE,OAAO,CAAC;EAE1DH,SAAS,CAAC,MAAM;IACd,MAAMY,MAAM,GAAGV,cAAc,CAAC,CAAC;IAC/B,MAAMW,OAAO,GAAGD,MAAM,CAACE,mBAAmB,CAAEC,IAAI,IAAK;MACnDJ,SAAS,CAACI,IAAI,CAAC;IACjB,CAAC,CAAC;IACF,OAAOF,OAAO;EAChB,CAAC,EAAE,EAAE,CAAC;EAEN,MAAMG,SAAS,GAAGjB,WAAW,CAAC,MAAOkB,MAA4B,IAAK;IACpE,MAAMf,cAAc,CAAC,CAAC,CAACgB,iBAAiB,CAACD,MAAM,CAAC;EAClD,CAAC,EAAE,EAAE,CAAC;EAEN,MAAME,KAAK,GAAGpB,WAAW,CAAC,YAAY;IACpC,MAAMG,cAAc,CAAC,CAAC,CAACkB,mBAAmB,CAAC,CAAC;EAC9C,CAAC,EAAE,EAAE,CAAC;EAEN,OAAO;IAAEV,MAAM;IAAEM,SAAS;IAAEG;EAAM,CAAC;AACrC","ignoreList":[]}
@@ -2,6 +2,7 @@
2
2
 
3
3
  import { useEffect, useState } from 'react';
4
4
  import { getTrackPlayer } from "../clients.js";
5
+ import { applyQueueDelta } from "../queueDelta.js";
5
6
  const INITIAL = {
6
7
  queue: [],
7
8
  currentIndex: -1
@@ -13,30 +14,75 @@ const INITIAL = {
13
14
  * `onTrackChange` so `currentIndex` stays live on auto-advance / skip,
14
15
  * which move the active position without changing the queue contents.
15
16
  *
16
- * The first-render seed reads `getQueue()` + `getCurrentTrackIndex()`
17
- * separately the pair is not atomic against a concurrent mutation, so
18
- * it can briefly skew. Self-healing: the first `onQueueChange` /
19
- * `onTrackChange` fire delivers a consistent snapshot.
17
+ * Renders empty for the first frame, then fills in: the seed reads
18
+ * `getQueue()`, which resolves asynchronously. A mutation landing in that gap
19
+ * is not lost: a delta that arrives before the seed lands cannot be applied —
20
+ * there is nothing correct to apply it to — so the queue is re-read instead.
20
21
  */
21
22
  export function useQueue() {
22
- const [snapshot, setSnapshot] = useState(() => {
23
- try {
24
- const player = getTrackPlayer();
25
- return {
26
- queue: player.getQueue(),
27
- currentIndex: player.getCurrentTrackIndex()
28
- };
29
- } catch {
30
- return INITIAL;
31
- }
32
- });
23
+ const [snapshot, setSnapshot] = useState(INITIAL);
33
24
  useEffect(() => {
34
25
  const player = getTrackPlayer();
35
- const offQueue = player.onQueueChange((queue, currentIndex) => {
36
- setSnapshot({
37
- queue,
38
- currentIndex
26
+ let disposed = false;
27
+ // `haveBase` is what makes a delta applicable: without a queue to apply it
28
+ // to, applying one silently produces a wrong mirror — and for `shuffle`, an
29
+ // array of holes. `seenEvent` separately stops a slow seed overwriting
30
+ // newer state.
31
+ let haveBase = false;
32
+ let seenEvent = false;
33
+ let revision = 0;
34
+ // Guards against two overlapping re-reads resolving out of order.
35
+ let readTicket = 0;
36
+ const reread = () => {
37
+ const ticket = ++readTicket;
38
+ // Until this read lands there is no base a delta can be applied to:
39
+ // an event arriving meanwhile re-reads too, and the ticket keeps the
40
+ // last read's answer.
41
+ haveBase = false;
42
+ void player.getQueue().then(queue => {
43
+ if (disposed || ticket !== readTicket) return;
44
+ haveBase = true;
45
+ // Re-read the index too: the queue just came from a fresh read, and
46
+ // the index captured when the event fired may already be stale.
47
+ setSnapshot({
48
+ queue,
49
+ currentIndex: player.getCurrentTrackIndex()
50
+ });
51
+ }).catch(() => {
52
+ // Player not configured yet; a later event re-reads.
39
53
  });
54
+ };
55
+ void (async () => {
56
+ try {
57
+ const ticket = ++readTicket;
58
+ const queue = await player.getQueue();
59
+ const currentIndex = player.getCurrentTrackIndex();
60
+ if (disposed || seenEvent || ticket !== readTicket) return;
61
+ haveBase = true;
62
+ setSnapshot({
63
+ queue,
64
+ currentIndex
65
+ });
66
+ } catch {
67
+ // Player not configured yet; the first event re-reads instead.
68
+ }
69
+ })();
70
+
71
+ // A delta only makes sense against the copy it was computed from, so a
72
+ // missed event — or one that beats the seed — is recovered by re-reading
73
+ // rather than patched over.
74
+ const offQueue = player.onQueueChange((delta, currentIndex, reason) => {
75
+ seenEvent = true;
76
+ const missed = revision !== 0 && delta.revision !== revision + 1;
77
+ revision = delta.revision;
78
+ if (!haveBase || missed) {
79
+ reread();
80
+ return;
81
+ }
82
+ setSnapshot(prev => ({
83
+ queue: applyQueueDelta(prev.queue, delta, reason),
84
+ currentIndex
85
+ }));
40
86
  });
41
87
  // Keep `currentIndex` live when the active track changes without a
42
88
  // queue-content change (auto-advance, skip). Preserves the queue from
@@ -48,6 +94,7 @@ export function useQueue() {
48
94
  }));
49
95
  });
50
96
  return () => {
97
+ disposed = true;
51
98
  offQueue();
52
99
  offTrack();
53
100
  };
@@ -1 +1 @@
1
- {"version":3,"names":["useEffect","useState","getTrackPlayer","INITIAL","queue","currentIndex","useQueue","snapshot","setSnapshot","player","getQueue","getCurrentTrackIndex","offQueue","onQueueChange","offTrack","onTrackChange","_track","index","prev"],"sourceRoot":"../../../src","sources":["hooks/useQueue.ts"],"mappings":";;AAAA,SAASA,SAAS,EAAEC,QAAQ,QAAQ,OAAO;AAC3C,SAASC,cAAc,QAAQ,eAAY;AAU3C,MAAMC,OAAsB,GAAG;EAAEC,KAAK,EAAE,EAAE;EAAEC,YAAY,EAAE,CAAC;AAAE,CAAC;;AAE9D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,QAAQA,CAAA,EAAkB;EACxC,MAAM,CAACC,QAAQ,EAAEC,WAAW,CAAC,GAAGP,QAAQ,CAAgB,MAAM;IAC5D,IAAI;MACF,MAAMQ,MAAM,GAAGP,cAAc,CAAC,CAAC;MAC/B,OAAO;QACLE,KAAK,EAAEK,MAAM,CAACC,QAAQ,CAAC,CAAC;QACxBL,YAAY,EAAEI,MAAM,CAACE,oBAAoB,CAAC;MAC5C,CAAC;IACH,CAAC,CAAC,MAAM;MACN,OAAOR,OAAO;IAChB;EACF,CAAC,CAAC;EAEFH,SAAS,CAAC,MAAM;IACd,MAAMS,MAAM,GAAGP,cAAc,CAAC,CAAC;IAC/B,MAAMU,QAAQ,GAAGH,MAAM,CAACI,aAAa,CAAC,CAACT,KAAK,EAAEC,YAAY,KAAK;MAC7DG,WAAW,CAAC;QAAEJ,KAAK;QAAEC;MAAa,CAAC,CAAC;IACtC,CAAC,CAAC;IACF;IACA;IACA;IACA,MAAMS,QAAQ,GAAGL,MAAM,CAACM,aAAa,CAAC,CAACC,MAAM,EAAEC,KAAK,KAAK;MACvDT,WAAW,CAAEU,IAAI,KAAM;QAAEd,KAAK,EAAEc,IAAI,CAACd,KAAK;QAAEC,YAAY,EAAEY;MAAM,CAAC,CAAC,CAAC;IACrE,CAAC,CAAC;IACF,OAAO,MAAM;MACXL,QAAQ,CAAC,CAAC;MACVE,QAAQ,CAAC,CAAC;IACZ,CAAC;EACH,CAAC,EAAE,EAAE,CAAC;EAEN,OAAOP,QAAQ;AACjB","ignoreList":[]}
1
+ {"version":3,"names":["useEffect","useState","getTrackPlayer","applyQueueDelta","INITIAL","queue","currentIndex","useQueue","snapshot","setSnapshot","player","disposed","haveBase","seenEvent","revision","readTicket","reread","ticket","getQueue","then","getCurrentTrackIndex","catch","offQueue","onQueueChange","delta","reason","missed","prev","offTrack","onTrackChange","_track","index"],"sourceRoot":"../../../src","sources":["hooks/useQueue.ts"],"mappings":"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","ignoreList":[]}
@@ -27,11 +27,14 @@ export { SectionIcon } from "./types.js";
27
27
  // `getEqualizer()` API for consumers building EQ UIs.
28
28
  export { EQ_BAND_COUNT, EQ_BAND_FREQUENCIES_HZ, EQ_FLAT_PRESET_NAME, EQ_GAIN_MAX_DB, EQ_GAIN_MIN_DB, clampGain, gainsFromBands, gainsFromMap, isBuiltinPreset, nearestBandIndex } from "./equalizer.js";
29
29
 
30
+ // Pure helper for applying an onQueueChange delta to a queue copy.
31
+ export { applyQueueDelta } from "./queueDelta.js";
32
+
30
33
  // React hooks — thin observers over the HybridObject event surface.
31
34
  export * from "./hooks/index.js";
32
35
 
33
- // Cast — Promise-based wrappers + listener subscriptions around the
34
- // `CastManager` HybridObject. Consumers can either reach in via
35
- // `getCastManager()` directly or import from `react-native-queue-player/cast`.
36
+ // Cast — `Cast.*`: thin functions over the `CastManager` HybridObject
37
+ // (optional-argument shapes, `CastSubscription` handles, `CastErrorCodes`,
38
+ // `localRoute()`); `getCastManager()` returns the HybridObject itself.
36
39
  export * as Cast from "./cast/index.js";
37
40
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["getCastManager","getEqualizer","getTrackPlayer","getVisualizer","registerPlaybackService","unregisterPlaybackService","crossfadeDurationBounds","SectionIcon","EQ_BAND_COUNT","EQ_BAND_FREQUENCIES_HZ","EQ_FLAT_PRESET_NAME","EQ_GAIN_MAX_DB","EQ_GAIN_MIN_DB","clampGain","gainsFromBands","gainsFromMap","isBuiltinPreset","nearestBandIndex","Cast"],"sourceRoot":"../../src","sources":["index.ts"],"mappings":";;AAAA;;AAMA;;AAwEA;AACA;AACA;AACA,SAASA,cAAc,EAAEC,YAAY,EAAEC,cAAc,EAAEC,aAAa,QAAQ,cAAW;;AAEvF;AACA;AACA;AACA,SACEC,uBAAuB,EACvBC,yBAAyB,QACpB,sBAAmB;AAM1B;AACA;AACA,SAASC,uBAAuB,QAAQ,YAAS;;AAEjD;AACA;AACA;AACA,SAASC,WAAW,QAAQ,YAAS;;AAErC;AACA;AACA;AACA,SACEC,aAAa,EACbC,sBAAsB,EACtBC,mBAAmB,EACnBC,cAAc,EACdC,cAAc,EACdC,SAAS,EACTC,cAAc,EACdC,YAAY,EACZC,eAAe,EACfC,gBAAgB,QACX,gBAAa;;AAEpB;AACA,cAAc,kBAAS;;AAEvB;AACA;AACA;AACA,OAAO,KAAKC,IAAI,MAAM,iBAAQ","ignoreList":[]}
1
+ {"version":3,"names":["getCastManager","getEqualizer","getTrackPlayer","getVisualizer","registerPlaybackService","unregisterPlaybackService","crossfadeDurationBounds","SectionIcon","EQ_BAND_COUNT","EQ_BAND_FREQUENCIES_HZ","EQ_FLAT_PRESET_NAME","EQ_GAIN_MAX_DB","EQ_GAIN_MIN_DB","clampGain","gainsFromBands","gainsFromMap","isBuiltinPreset","nearestBandIndex","applyQueueDelta","Cast"],"sourceRoot":"../../src","sources":["index.ts"],"mappings":";;AAAA;;AAMA;;AA+EA;AACA;AACA;AACA,SAASA,cAAc,EAAEC,YAAY,EAAEC,cAAc,EAAEC,aAAa,QAAQ,cAAW;;AAEvF;AACA;AACA;AACA,SACEC,uBAAuB,EACvBC,yBAAyB,QACpB,sBAAmB;AAM1B;AACA;AACA,SAASC,uBAAuB,QAAQ,YAAS;;AAEjD;AACA;AACA;AACA,SAASC,WAAW,QAAQ,YAAS;;AAErC;AACA;AACA;AACA,SACEC,aAAa,EACbC,sBAAsB,EACtBC,mBAAmB,EACnBC,cAAc,EACdC,cAAc,EACdC,SAAS,EACTC,cAAc,EACdC,YAAY,EACZC,eAAe,EACfC,gBAAgB,QACX,gBAAa;;AAEpB;AACA,SAASC,eAAe,QAAQ,iBAAc;;AAE9C;AACA,cAAc,kBAAS;;AAEvB;AACA;AACA;AACA,OAAO,KAAKC,IAAI,MAAM,iBAAQ","ignoreList":[]}