()
| 50 | }; |
| 51 | |
| 52 | export const createStreamingHost = (): StreamingHost => ({ |
| 53 | resolveCandidatesForTrack: async (track: Track) => { |
| 54 | const provider = getActiveStreamingProvider(); |
| 55 | |
| 56 | if (!provider) { |
| 57 | Logger.streaming.warn('No streaming provider available'); |
| 58 | return { |
| 59 | success: false, |
| 60 | error: 'No streaming provider available', |
| 61 | }; |
| 62 | } |
| 63 | |
| 64 | try { |
| 65 | // Temporarily provide both methods to avoid breaking existing providers until we have autoupdate for plugins |
| 66 | const candidates = provider.searchForTrackV2 |
| 67 | ? await provider.searchForTrackV2(track) |
| 68 | : await provider.searchForTrack( |
| 69 | track.artists[0]?.name ?? 'Unknown Artist', |
| 70 | track.title, |
| 71 | track.album?.title, |
| 72 | ); |
| 73 | |
| 74 | return { |
| 75 | success: true, |
| 76 | candidates, |
| 77 | }; |
| 78 | } catch (error) { |
| 79 | Logger.streaming.error( |
| 80 | `resolveCandidatesForTrack error: ${resolveErrorMessage(error)}`, |
| 81 | ); |
| 82 | const message = error instanceof Error ? error.message : 'Unknown error'; |
| 83 | return { |
| 84 | success: false, |
| 85 | error: `Failed to resolve candidates: ${message}`, |
| 86 | }; |
| 87 | } |
| 88 | }, |
| 89 | |
| 90 | resolveStreamForCandidate: async (candidate: StreamCandidate) => { |
| 91 | const provider = getActiveStreamingProvider(); |
| 92 | |
| 93 | if (!provider) { |
| 94 | Logger.streaming.warn('No provider for stream resolution'); |
| 95 | return undefined; |
| 96 | } |
| 97 | |
| 98 | if (candidate.failed) { |
| 99 | Logger.streaming.warn('Candidate already marked as failed'); |
| 100 | return candidate; |
| 101 | } |
| 102 | |
| 103 | if (candidate.stream && !isStreamExpired(candidate)) { |
| 104 | return candidate; |
| 105 | } |
| 106 | |
| 107 | const retries = |
| 108 | (useSettingsStore |
| 109 | .getState() |
no test coverage detected