mirror of
https://github.com/permissionlesstech/bitchat.git
synced 2026-07-26 06:25:19 +00:00
Cut private message path over to ConversationStore
All private-message mutations now flow through store intents: coordinators, PrivateChatManager (its @Published dicts deleted - now read-only views over the store), outbound sends, delivery status, and chat migration. The O(1) store dedup replaces the full-scan duplicate check; insertion order is maintained by the store so sanitizeChat's re-sort is a documented no-op. Both bootstrapper Combine bridges and the Task.yield store synchronization are deleted. ChatViewModel.privateChats/unreadPrivateMessages become get-only derived views (measured: naive rebuild equals a change-invalidated cache within noise, so the simpler form stays). Feature models still read the legacy store, fed by a coalescing LegacyConversationStoreBridge (one mirror per burst, marked for step-5 deletion). pipeline.privateIngest: 9.6k -> 14.7k msg/s (+53%). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -38,11 +38,34 @@ private final class MockChatPeerIdentityContext: ChatPeerIdentityContext {
|
||||
func notifyUIChanged() { notifyUIChangedCount += 1 }
|
||||
func addSystemMessage(_ content: String) { systemMessages.append(content) }
|
||||
|
||||
// Conversation store intents (mirror `ConversationStore` migrate
|
||||
// semantics: dedup by ID, timestamp order, unread carried, old chat
|
||||
// removed) while recording calls for assertions.
|
||||
private(set) var migratedChats: [(from: PeerID, to: PeerID)] = []
|
||||
|
||||
func markPrivateChatRead(_ peerID: PeerID) {
|
||||
unreadPrivateMessages.remove(peerID)
|
||||
}
|
||||
|
||||
func migratePrivateChat(from oldPeerID: PeerID, to newPeerID: PeerID) {
|
||||
migratedChats.append((oldPeerID, newPeerID))
|
||||
guard oldPeerID != newPeerID, let source = privateChats[oldPeerID] else { return }
|
||||
var destination = privateChats[newPeerID] ?? []
|
||||
for message in source where !destination.contains(where: { $0.id == message.id }) {
|
||||
let index = destination.firstIndex(where: { $0.timestamp > message.timestamp }) ?? destination.count
|
||||
destination.insert(message, at: index)
|
||||
}
|
||||
privateChats[newPeerID] = destination
|
||||
privateChats.removeValue(forKey: oldPeerID)
|
||||
if unreadPrivateMessages.remove(oldPeerID) != nil {
|
||||
unreadPrivateMessages.insert(newPeerID)
|
||||
}
|
||||
}
|
||||
|
||||
// Private chat session lifecycle
|
||||
private(set) var consolidatedPeers: [(peerID: PeerID, peerNickname: String)] = []
|
||||
private(set) var syncedReadReceiptPeers: [PeerID] = []
|
||||
private(set) var begunChatSessions: [PeerID] = []
|
||||
private(set) var privateStoreSyncCount = 0
|
||||
private(set) var selectionStoreSyncCount = 0
|
||||
private(set) var markedReadPeers: [PeerID] = []
|
||||
|
||||
@@ -60,7 +83,6 @@ private final class MockChatPeerIdentityContext: ChatPeerIdentityContext {
|
||||
begunChatSessions.append(peerID)
|
||||
}
|
||||
|
||||
func synchronizePrivateConversationStore() { privateStoreSyncCount += 1 }
|
||||
func synchronizeConversationSelectionStore() { selectionStoreSyncCount += 1 }
|
||||
func markPrivateMessagesAsRead(from peerID: PeerID) { markedReadPeers.append(peerID) }
|
||||
|
||||
@@ -261,7 +283,6 @@ struct ChatPeerIdentityCoordinatorContextTests {
|
||||
#expect(context.storedFingerprints.map(\.fingerprint) == ["fp-alice"])
|
||||
#expect(context.selectedPrivateChatFingerprint == "fp-alice")
|
||||
#expect(context.begunChatSessions == [peerID])
|
||||
#expect(context.privateStoreSyncCount == 1)
|
||||
#expect(context.selectionStoreSyncCount == 1)
|
||||
#expect(context.markedReadPeers == [peerID])
|
||||
|
||||
|
||||
Reference in New Issue
Block a user