Session Cache Implementation
Nucleic-Session: B2346642-3353-4BD5-9DE2-A8B77BD66C98 Co-authored-by: Nucleic <[email protected]>
This commit is contained in:
@@ -647,6 +647,48 @@ final class RemoteStore: ObservableObject {
|
||||
return bySeq.values.sorted { $0.seq < $1.seq }
|
||||
}
|
||||
|
||||
// MARK: - Offline cache (SessionCache)
|
||||
|
||||
/// Debounced write of the live session list to disk, so a read-only history survives a
|
||||
/// disconnect / relaunch.
|
||||
private func persistSummaries(_ list: [WireSessionSummary]) {
|
||||
summaryPersistTask?.cancel()
|
||||
summaryPersistTask = Task { [list] in
|
||||
try? await Task.sleep(nanoseconds: 2_000_000_000)
|
||||
guard !Task.isCancelled else { return }
|
||||
await SessionCache.saveSummaries(list)
|
||||
}
|
||||
}
|
||||
|
||||
/// Seed the open transcript from disk so a cached session's history shows instantly — even fully
|
||||
/// offline. A live snapshot/backfill merges on top by seq (dedup), so this never double-counts.
|
||||
private func loadCachedTranscript(_ sessionID: SessionID) {
|
||||
Task { [weak self] in
|
||||
let cached = await SessionCache.loadEvents(sessionID)
|
||||
guard let self, self.openSessionID == sessionID, !cached.isEmpty else { return }
|
||||
self.openEvents = Self.mergedEvents(cached, self.openEvents)
|
||||
}
|
||||
}
|
||||
|
||||
/// Debounced write of the open transcript, called after each batch of events lands.
|
||||
private func persistOpenTranscript() {
|
||||
guard !demoMode, let id = openSessionID, !openEvents.isEmpty else { return }
|
||||
let events = openEvents
|
||||
transcriptPersistTask?.cancel()
|
||||
transcriptPersistTask = Task { [events, id] in
|
||||
try? await Task.sleep(nanoseconds: 1_500_000_000)
|
||||
guard !Task.isCancelled else { return }
|
||||
await SessionCache.saveEvents(events, for: id)
|
||||
}
|
||||
}
|
||||
|
||||
/// Flush the open transcript to disk immediately (on close), cancelling any pending debounce.
|
||||
private func flushOpenTranscript(_ id: SessionID, _ events: [AgentEvent]) {
|
||||
transcriptPersistTask?.cancel()
|
||||
guard !demoMode, !events.isEmpty else { return }
|
||||
Task { await SessionCache.saveEvents(events, for: id) }
|
||||
}
|
||||
|
||||
/// The flat sessions list: every connected Mac's sessions, deduped by id (ids are globally
|
||||
/// unique). Views handle sorting/grouping.
|
||||
private func aggregatedSessions() -> [WireSessionSummary] {
|
||||
|
||||
Reference in New Issue
Block a user