mirror of
https://github.com/permissionlesstech/bitchat.git
synced 2026-07-25 02:25:20 +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,9 +38,23 @@ private final class MockChatLifecycleContext: ChatLifecycleContext {
|
||||
var nostrKeyMapping: [PeerID: String] = [:]
|
||||
private(set) var ownerLevelReadPasses: [PeerID] = []
|
||||
private(set) var managerReadMarks: [PeerID] = []
|
||||
private(set) var privateStoreSyncCount = 0
|
||||
private(set) var systemMessages: [String] = []
|
||||
|
||||
// Conversation store intents
|
||||
@discardableResult
|
||||
func appendPrivateMessage(_ message: BitchatMessage, to peerID: PeerID) -> Bool {
|
||||
var chat = privateChats[peerID] ?? []
|
||||
guard !chat.contains(where: { $0.id == message.id }) else { return false }
|
||||
let index = chat.firstIndex(where: { $0.timestamp > message.timestamp }) ?? chat.count
|
||||
chat.insert(message, at: index)
|
||||
privateChats[peerID] = chat
|
||||
return true
|
||||
}
|
||||
|
||||
func markPrivateChatRead(_ peerID: PeerID) {
|
||||
unreadPrivateMessages.remove(peerID)
|
||||
}
|
||||
|
||||
@discardableResult
|
||||
func markReadReceiptSent(_ messageID: String) -> Bool {
|
||||
sentReadReceipts.insert(messageID).inserted
|
||||
@@ -61,7 +75,6 @@ private final class MockChatLifecycleContext: ChatLifecycleContext {
|
||||
work()
|
||||
}
|
||||
|
||||
func synchronizePrivateConversationStore() { privateStoreSyncCount += 1 }
|
||||
func addSystemMessage(_ content: String) { systemMessages.append(content) }
|
||||
|
||||
// Peers & sessions
|
||||
@@ -234,7 +247,6 @@ struct ChatLifecycleCoordinatorContextTests {
|
||||
coordinator.markPrivateMessagesAsRead(from: convKey)
|
||||
|
||||
#expect(context.managerReadMarks == [convKey])
|
||||
#expect(context.privateStoreSyncCount == 1)
|
||||
// Only the peer's own un-acked, non-relay message gets a READ.
|
||||
#expect(context.geoReadReceipts.map(\.messageID) == ["m1"])
|
||||
#expect(context.geoReadReceipts.first?.recipientHex == recipientHex)
|
||||
|
||||
Reference in New Issue
Block a user