feat(messages): stream history one-message-per-WS-frame instead of 50-row batch
- backend: add streamMany generator (paginated, yields one record at a time) + messagesService.streamMessages + WS 'stream_messages' handler emitting 'message_snapshot' per message, 'message_snapshot_end' with nextCursor - frontend: useMessagesStream hook accumulates snapshots into SWR list, SSR getMessages seeds first paint, WsHook gains sendText - add stream-many.test.ts locking the one-at-a-time + cursor contract
This commit is contained in:
@@ -32,6 +32,7 @@ import {
|
||||
useMessageSearch,
|
||||
useMessages,
|
||||
useMessagesHasMore,
|
||||
useMessagesStream,
|
||||
useMessagesWsSync,
|
||||
} from "@/hooks";
|
||||
import { aiTone } from "@/lib/ai-status";
|
||||
@@ -49,9 +50,14 @@ import { useWebSocket } from "@/lib/ws/context";
|
||||
export function MessagesView({
|
||||
initialGuilds,
|
||||
initialGuildId,
|
||||
initialMessages,
|
||||
}: {
|
||||
initialGuilds?: Guild[];
|
||||
initialGuildId?: string | null;
|
||||
initialMessages?: {
|
||||
data: MessageRecord[];
|
||||
nextCursor: string | null;
|
||||
} | null;
|
||||
}) {
|
||||
const ws = useWebSocket();
|
||||
const [guildId, setGuildId] = useState<string | null>(
|
||||
@@ -69,7 +75,15 @@ export function MessagesView({
|
||||
data: messages,
|
||||
isLoading,
|
||||
error,
|
||||
} = useMessages(guildId ?? "", channelId ?? undefined);
|
||||
} = useMessages(
|
||||
guildId ?? "",
|
||||
channelId ?? undefined,
|
||||
initialMessages ?? undefined,
|
||||
);
|
||||
// Stream history one message per WS frame (replaces the 50-row batched fetch).
|
||||
// Drives snapshots into the SWR list above as they arrive; falls back to the
|
||||
// SSR `initialMessages` seed if WS is unavailable.
|
||||
useMessagesStream(ws, guildId ?? "", channelId ?? undefined);
|
||||
// Cursor to the next (older) page + whether more history exists.
|
||||
const { data: pageInfo } = useMessagesHasMore(
|
||||
guildId ?? "",
|
||||
|
||||
Reference in New Issue
Block a user