MCPcopy Index your code
hub / github.com/ChatLab/ChatLab / detectConflictsInMessages

Function detectConflictsInMessages

packages/core/src/merger/algorithms.ts:118–186  ·  view source on GitHub ↗
(
  allMessages: Array<{ msg: MergerMessage; source: string; platform: string }>
)

Source from the content-addressed store, hash-verified

116// ==================== Conflict detection ====================
117
118export function detectConflictsInMessages(
119 allMessages: Array<{ msg: MergerMessage; source: string; platform: string }>
120): ConflictCheckResult {
121 const collidingIds = getCollidingPlatformIdsFromMessages(allMessages)
122 const conflicts: MergeConflict[] = []
123
124 const timeGroups = new Map<number, Array<{ msg: MergerMessage; source: string; platform: string }>>()
125 for (const item of allMessages) {
126 const ts = item.msg.timestamp
127 if (!timeGroups.has(ts)) timeGroups.set(ts, [])
128 timeGroups.get(ts)!.push(item)
129 }
130
131 for (const [ts, items] of timeGroups) {
132 if (items.length < 2) continue
133
134 const senderGroups = new Map<string, typeof items>()
135 for (const item of items) {
136 const sender = normalizePlatformId(item.msg.senderPlatformId, item.platform || 'unknown', collidingIds)
137 if (!senderGroups.has(sender)) senderGroups.set(sender, [])
138 senderGroups.get(sender)!.push(item)
139 }
140
141 for (const [sender, senderItems] of senderGroups) {
142 if (senderItems.length < 2) continue
143 const sources = new Set(senderItems.map((it) => it.source))
144 if (sources.size < 2) continue
145
146 const contentGroups = new Map<string, typeof senderItems>()
147 for (const item of senderItems) {
148 const c = item.msg.content || ''
149 if (!contentGroups.has(c)) contentGroups.set(c, [])
150 contentGroups.get(c)!.push(item)
151 }
152
153 if (contentGroups.size > 1) {
154 const entries = Array.from(contentGroups.entries())
155 for (let i = 0; i < entries.length - 1; i++) {
156 for (let j = i + 1; j < entries.length; j++) {
157 const [c1, items1] = entries[i]
158 const [c2, items2] = entries[j]
159 const item1 = items1[0]
160 const item2 = items2.find((it) => it.source !== item1.source)
161 if (!item2) continue
162 if (isImageOnlyMessage(c1) && isImageOnlyMessage(c2)) continue
163
164 conflicts.push({
165 id: `conflict_${ts}_${sender}_${conflicts.length}`,
166 timestamp: ts,
167 sender: getDisplayName(item1.msg) || sender,
168 contentLength1: c1.length,
169 contentLength2: c2.length,
170 content1: c1,
171 content2: c2,
172 })
173 }
174 }
175 }

Callers 2

algorithms.test.tsFile · 0.90

Calls 8

normalizePlatformIdFunction · 0.85
isImageOnlyMessageFunction · 0.85
getMessageKeyFunction · 0.85
setMethod · 0.80
getDisplayNameFunction · 0.70
getMethod · 0.65
addMethod · 0.45

Tested by

no test coverage detected