mirror of
https://github.com/jkingsman/Remote-Terminal-for-MeshCore.git
synced 2026-03-28 17:43:05 +01:00
Deal with reconciliation conflict from colliding WS fetches
This commit is contained in:
@@ -195,8 +195,12 @@ export function useConversationMessages(
|
||||
}
|
||||
|
||||
const messagesWithPendingAck = data.map((msg) => applyPendingAck(msg));
|
||||
setMessages(messagesWithPendingAck);
|
||||
syncSeenContent(messagesWithPendingAck);
|
||||
const merged = messageCache.reconcile(messagesRef.current, messagesWithPendingAck);
|
||||
const nextMessages = merged ?? messagesRef.current;
|
||||
if (merged) {
|
||||
setMessages(merged);
|
||||
}
|
||||
syncSeenContent(nextMessages);
|
||||
setHasOlderMessages(messagesWithPendingAck.length >= MESSAGE_PAGE_SIZE);
|
||||
} catch (err) {
|
||||
if (isAbortError(err)) {
|
||||
|
||||
@@ -101,6 +101,40 @@ describe('useConversationMessages ACK ordering', () => {
|
||||
expect(result.current.messages[0].paths).toEqual(paths);
|
||||
});
|
||||
|
||||
it('preserves a WebSocket-arrived message when latest fetch resolves afterward', async () => {
|
||||
const deferred = createDeferred<Message[]>();
|
||||
mockGetMessages.mockReturnValueOnce(deferred.promise);
|
||||
|
||||
const { result } = renderHook(() => useConversationMessages(createConversation()));
|
||||
await waitFor(() => expect(mockGetMessages).toHaveBeenCalledTimes(1));
|
||||
|
||||
act(() => {
|
||||
const added = result.current.addMessageIfNew(
|
||||
createMessage({
|
||||
id: 99,
|
||||
text: 'ws-arrived',
|
||||
sender_timestamp: 1700000099,
|
||||
received_at: 1700000099,
|
||||
})
|
||||
);
|
||||
expect(added).toBe(true);
|
||||
});
|
||||
|
||||
deferred.resolve([
|
||||
createMessage({
|
||||
id: 42,
|
||||
text: 'rest-fetched',
|
||||
sender_timestamp: 1700000000,
|
||||
received_at: 1700000001,
|
||||
}),
|
||||
]);
|
||||
|
||||
await waitFor(() => expect(result.current.messagesLoading).toBe(false));
|
||||
expect(result.current.messages).toHaveLength(2);
|
||||
expect(result.current.messages.some((msg) => msg.text === 'rest-fetched')).toBe(true);
|
||||
expect(result.current.messages.some((msg) => msg.text === 'ws-arrived')).toBe(true);
|
||||
});
|
||||
|
||||
it('keeps highest ACK state when out-of-order ACK updates arrive', async () => {
|
||||
mockGetMessages.mockResolvedValueOnce([]);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user