66 lines
2.1 KiB
Swift
66 lines
2.1 KiB
Swift
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
|
|
}
|
|
}
|