Merge nucleic/plucky-opal-weasel into dev
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
import Foundation
|
||||
import NucleicProtocol
|
||||
|
||||
/// The on-device snapshot of the phone's mesh-cast ledger (`CastLedger`) — the activity feed,
|
||||
/// mesh messages, and runner-presence cards it has received, plus (implicitly) the cursors a
|
||||
/// reconnect subscribes with. Like `SessionCache`, a *projection cache*, never canonical: a
|
||||
/// live host always supersedes it; it exists so a relaunch renders the feed instantly and
|
||||
/// resubscribes O(gap) instead of re-pulling every channel from zero.
|
||||
///
|
||||
/// One JSON file under Application Support (`NucleicCastCache/casts.json`) — the ledger's
|
||||
/// per-channel retention already bounds it. Reads/writes hop onto a utility `Task.detached`.
|
||||
enum CastCache {
|
||||
private static var root: URL? {
|
||||
guard let base = try? FileManager.default.url(
|
||||
for: .applicationSupportDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
|
||||
else { return nil }
|
||||
return base.appendingPathComponent("NucleicCastCache", isDirectory: true)
|
||||
}
|
||||
private static var castsURL: URL? { root?.appendingPathComponent("casts.json") }
|
||||
|
||||
/// Load the persisted ledger — called once at launch, before any host connects. The ledger's
|
||||
/// init re-applies retention, so a policy change between builds re-caps on load.
|
||||
static func loadLedger() -> CastLedger {
|
||||
guard let url = castsURL, let data = try? Data(contentsOf: url),
|
||||
let casts = try? JSONDecoder().decode([WireCast].self, from: data)
|
||||
else { return CastLedger() }
|
||||
return CastLedger(casts: casts)
|
||||
}
|
||||
|
||||
/// Persist the ledger's snapshot. Off the main actor; callers debounce bursts.
|
||||
static func save(_ ledger: CastLedger) async {
|
||||
let casts = ledger.allCasts
|
||||
await Task.detached(priority: .utility) {
|
||||
guard let root, let url = castsURL else { return }
|
||||
try? FileManager.default.createDirectory(at: root, withIntermediateDirectories: true)
|
||||
if let data = try? JSONEncoder().encode(casts) {
|
||||
try? data.write(to: url, options: .atomic)
|
||||
}
|
||||
}.value
|
||||
}
|
||||
|
||||
/// Drop the cache — on full unpair (no Mac left whose casts this device should hold).
|
||||
static func clear() {
|
||||
guard let root else { return }
|
||||
try? FileManager.default.removeItem(at: root)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user