nvrsion: Add shortened 8-char device resolution text to Approval.swift, refactor Session Sync Repair files, and update SyncClient.swift and RemoteStore.swift.
Nucleic-Promote: 1 Co-authored-by: Nucleic <[email protected]>
This commit is contained in:
@@ -35,7 +35,20 @@ final class HostConnection {
|
||||
|
||||
/// The session RemoteStore currently has open on this host, if any — so snapshot/events are only
|
||||
/// forwarded (and deduped) for the transcript on screen. Set by RemoteStore on open/close.
|
||||
var openSessionID: SessionID?
|
||||
/// Changing which session is open resets the per-session cursor + dedup set (they only make
|
||||
/// sense within one transcript).
|
||||
var openSessionID: SessionID? {
|
||||
didSet {
|
||||
guard openSessionID != oldValue else { return }
|
||||
openMaxSeq = nil
|
||||
seenSeq = []
|
||||
}
|
||||
}
|
||||
|
||||
/// The highest event `seq` delivered for the open session — the warm-resubscribe cursor. On a
|
||||
/// reconnect we re-subscribe `sinceSeq: openMaxSeq` so the host replays only what we missed
|
||||
/// instead of cold-resetting to the 200-event tail (which would truncate a long transcript).
|
||||
private var openMaxSeq: UInt64?
|
||||
|
||||
// MARK: Callbacks up to RemoteStore (aggregate concerns)
|
||||
|
||||
@@ -440,7 +453,9 @@ final class HostConnection {
|
||||
callbacks.didUpdate()
|
||||
send(.listSessions)
|
||||
send(.listDashboard)
|
||||
if let id = openSessionID { send(.subscribe(Subscribe(sessionID: id, sinceSeq: nil, verbosity: .full))) }
|
||||
// Warm-resubscribe from what we already have, so a reconnect on a long transcript replays
|
||||
// only the gap rather than snapping back to the host's 200-event tail.
|
||||
if let id = openSessionID { send(.subscribe(Subscribe(sessionID: id, sinceSeq: openMaxSeq, verbosity: .full))) }
|
||||
case .sessionList(let list):
|
||||
sessions = list
|
||||
callbacks.didUpdate()
|
||||
@@ -461,12 +476,17 @@ final class HostConnection {
|
||||
callbacks.didUpdate()
|
||||
case .snapshot(let snapshot):
|
||||
guard snapshot.summary.sessionID == openSessionID else { break }
|
||||
seenSeq = Set(snapshot.recentEvents.map(\.seq))
|
||||
// A snapshot may be a fresh open (tail window) or a warm-resubscribe delta; either way
|
||||
// union its seqs into the dedup set and advance the cursor. RemoteStore merges the events
|
||||
// into the transcript rather than replacing, so an existing transcript isn't truncated.
|
||||
seenSeq.formUnion(snapshot.recentEvents.map(\.seq))
|
||||
if let maxSeq = snapshot.recentEvents.map(\.seq).max() { openMaxSeq = max(openMaxSeq ?? 0, maxSeq) }
|
||||
callbacks.openSnapshot(snapshot)
|
||||
case .events(let batch):
|
||||
guard batch.sessionID == openSessionID else { break }
|
||||
let fresh = batch.events.filter { !seenSeq.contains($0.seq) }
|
||||
for e in fresh { seenSeq.insert(e.seq) }
|
||||
if let maxSeq = batch.events.map(\.seq).max() { openMaxSeq = max(openMaxSeq ?? 0, maxSeq) }
|
||||
if !fresh.isEmpty { callbacks.openEvents(EventBatch(sessionID: batch.sessionID, events: fresh)) }
|
||||
case .approvalRequested(let req):
|
||||
let title = sessions.first { $0.sessionID == req.sessionID }?.title ?? "Approval"
|
||||
|
||||
Reference in New Issue
Block a user