import Foundation public struct ProjectAutosavePolicy: Equatable, Sendable { public static let `default` = ProjectAutosavePolicy() public var minimumVersionInterval: TimeInterval public var versionLabel: String public init( minimumVersionInterval: TimeInterval = 300, versionLabel: String = "Autosave checkpoint" ) { self.minimumVersionInterval = minimumVersionInterval self.versionLabel = versionLabel } } public struct ProjectAutosaveResult: Equatable, Sendable { public var project: SongProject public var didCreateVersion: Bool public init(project: SongProject, didCreateVersion: Bool) { self.project = project self.didCreateVersion = didCreateVersion } } public actor ProjectAutosaveService { private let store: any ProjectStore private let policy: ProjectAutosavePolicy public init(store: any ProjectStore, policy: ProjectAutosavePolicy = .default) { self.store = store self.policy = policy } public func autosave(_ project: SongProject, at savedAt: Date = Date()) async throws -> ProjectAutosaveResult { var autosavedProject = project var didCreateVersion = false if shouldCreateAutosaveVersion(for: autosavedProject, at: savedAt) { _ = autosavedProject.createVersion(label: policy.versionLabel, createdAt: savedAt) didCreateVersion = true } autosavedProject.updatedAt = savedAt try await store.save(autosavedProject) return ProjectAutosaveResult(project: autosavedProject, didCreateVersion: didCreateVersion) } private func shouldCreateAutosaveVersion(for project: SongProject, at savedAt: Date) -> Bool { let currentSnapshot = SongProjectSnapshot(project: project) guard let latestVersion = project.versions.last else { return true } guard latestVersion.snapshot != currentSnapshot else { return false } return savedAt.timeIntervalSince(latestVersion.createdAt) >= policy.minimumVersionInterval } }