import Foundation // Deliberately separate from launch: no configuration, application, player or state APIs. enum SourceCheck { enum Status: String, Sendable, CaseIterable { case available, unavailable, failed var json: String { "{\"version\":1,\"provider\":\"zokoanime\",\"track\":\"sub\",\"status\":\"\(rawValue)\"}" } } static func run( mediaID: String, episode: Int, timeout: Duration = .seconds(15), resolve: @escaping @Sendable (String, Int) async throws -> ResolvedSource = { try await ZokoResolver.resolve(mediaID: $0, episode: $1, enrichTitle: false) }, validate: @escaping @Sendable (ResolvedSource) async throws -> Void = { try await MiruroTransport.checkZokoRoot($0) } ) async -> Status { await withTaskGroup(of: Status.self) { group in group.addTask { let source: ResolvedSource do { try Task.checkCancellation() source = try await resolve(mediaID, episode) try Task.checkCancellation() } catch ZokoError.unavailable { return Task.isCancelled ? .failed : .unavailable } catch { return .failed } do { try await validate(source) try Task.checkCancellation() return .available } catch { // A manifest 404, protection page or other resource failure is // not evidence of the provider's explicit missing-episode page. return .failed } } group.addTask { try? await Task.sleep(for: timeout) return .failed } let result = await group.next() ?? .failed group.cancelAll() return result } } }