Initial commit
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
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
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user