// // Swiftfin is subject to the terms of the Mozilla Public // License, v2.0. If a copy of the MPL was not distributed with this // file, you can obtain one at https://mozilla.org/MPL/2.0/. // // Copyright (c) 2025 Jellyfin & Jellyfin Contributors // import Combine import Foundation /// Observable object property wrapper that allows observing /// another `Publisher`. @propertyWrapper final class ObservedPublisher: ObservableObject { @Published private(set) var wrappedValue: Value var projectedValue: AnyPublisher { $wrappedValue .eraseToAnyPublisher() } private var cancellables = Set() init( wrappedValue: Value, observing publisher: P ) where P.Output == Value, P.Failure == Never { self.wrappedValue = wrappedValue publisher .receive(on: DispatchQueue.main) .sink { [weak self] newValue in self?.wrappedValue = newValue } .store(in: &cancellables) } static subscript( _enclosingInstance instance: T, wrapped wrappedKeyPath: KeyPath, storage storageKeyPath: KeyPath> ) -> Value where T.ObjectWillChangePublisher == ObservableObjectPublisher { let wrapper = instance[keyPath: storageKeyPath] wrapper.objectWillChange .sink { [weak instance] _ in instance?.objectWillChange.send() } .store(in: &wrapper.cancellables) return wrapper.wrappedValue } }