refactor(chat): remove commented-out code in guestSession
This commit is contained in:
@@ -53,10 +53,7 @@ export const loadQuotaActor = fromPromise<{
|
|||||||
remaining: number;
|
remaining: number;
|
||||||
total: number;
|
total: number;
|
||||||
}>(async () => {
|
}>(async () => {
|
||||||
log.debug("[chat-machine] loadQuotaActor ENTRY");
|
return readGuestQuota();
|
||||||
const result = await readGuestQuota();
|
|
||||||
log.debug("[chat-machine] loadQuotaActor DONE", result);
|
|
||||||
return result;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// ============================================================
|
// ============================================================
|
||||||
@@ -76,16 +73,7 @@ export const loadHistoryActor = fromPromise<{
|
|||||||
localCount: number;
|
localCount: number;
|
||||||
networkCount: number;
|
networkCount: number;
|
||||||
}>(async () => {
|
}>(async () => {
|
||||||
log.debug("[chat-machine] loadHistoryActor ENTRY");
|
return readAndSyncHistory();
|
||||||
const result = await readAndSyncHistory();
|
|
||||||
log.debug("[chat-machine] loadHistoryActor DONE", {
|
|
||||||
finalCount: result.messages.length,
|
|
||||||
localCount: result.localCount,
|
|
||||||
networkCount: result.networkCount,
|
|
||||||
hasMore: result.hasMore,
|
|
||||||
localOverwritten: result.localOverwritten,
|
|
||||||
});
|
|
||||||
return result;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// ============================================================
|
// ============================================================
|
||||||
@@ -100,83 +88,30 @@ export const loadHistoryActor = fromPromise<{
|
|||||||
export const sendMessageHttpActor = fromPromise<
|
export const sendMessageHttpActor = fromPromise<
|
||||||
{ reply: UiMessage },
|
{ reply: UiMessage },
|
||||||
{ content: string }
|
{ content: string }
|
||||||
>(async ({ input, self }) => {
|
>(async ({ input }) => {
|
||||||
log.debug("[chat-machine] sendMessageHttpActor ENTRY", {
|
|
||||||
contentLength: input.content.length,
|
|
||||||
contentPreview: input.content.slice(0, 50),
|
|
||||||
selfId: self.id,
|
|
||||||
selfPath: "<actor path>",
|
|
||||||
});
|
|
||||||
log.debug("[chat-machine] sendMessageHttpActor calling chatRepo.sendMessage");
|
|
||||||
const result = await chatRepo.sendMessage(input.content);
|
const result = await chatRepo.sendMessage(input.content);
|
||||||
log.debug("[chat-machine] sendMessageHttpActor chatRepo.sendMessage DONE", {
|
|
||||||
success: result.success,
|
|
||||||
error: result.success ? null : Result.isErr(result) ? result.error : null,
|
|
||||||
});
|
|
||||||
if (Result.isErr(result)) {
|
if (Result.isErr(result)) {
|
||||||
log.error("[chat-machine] sendMessageHttpActor result isErr, throwing");
|
log.error("[chat-machine] sendMessageHttpActor failed", { error: result.error });
|
||||||
throw result.error;
|
throw result.error;
|
||||||
}
|
}
|
||||||
|
return { reply: sendResponseToUiMessage(result.data) };
|
||||||
// 一次发送 = 一次返回 —— 直接转 reply → UiMessage
|
|
||||||
log.debug("[chat-machine] sendMessageHttpActor converting reply to UiMessage", {
|
|
||||||
replyLength: result.data.reply.length,
|
|
||||||
replyPreview: result.data.reply.slice(0, 50),
|
|
||||||
messageId: result.data.messageId,
|
|
||||||
timestamp: result.data.timestamp,
|
|
||||||
});
|
|
||||||
|
|
||||||
const reply = sendResponseToUiMessage(result.data);
|
|
||||||
log.debug("[chat-machine] sendMessageHttpActor done", {
|
|
||||||
replyContentLength: reply.content.length,
|
|
||||||
});
|
|
||||||
return { reply };
|
|
||||||
});
|
});
|
||||||
|
|
||||||
/** 翻历史(pagination)—— 不走 local-first,纯 server fetch */
|
/** 翻历史(pagination)—— 不走 local-first,纯 server fetch */
|
||||||
export const loadMoreHistoryActor = fromPromise<
|
export const loadMoreHistoryActor = fromPromise<
|
||||||
{ messages: UiMessage[]; hasMore: boolean; newOffset: number },
|
{ messages: UiMessage[]; hasMore: boolean; newOffset: number },
|
||||||
{ offset: number }
|
{ offset: number }
|
||||||
>(async ({ input, self }) => {
|
>(async ({ input }) => {
|
||||||
log.debug("[chat-machine] loadMoreHistoryActor ENTRY", {
|
|
||||||
inputOffset: input.offset,
|
|
||||||
pageSize: PAGE_SIZE,
|
|
||||||
selfPath: "<actor path>",
|
|
||||||
});
|
|
||||||
log.debug("[chat-machine] loadMoreHistoryActor calling chatRepo.getHistory", {
|
|
||||||
pageSize: PAGE_SIZE,
|
|
||||||
offset: input.offset,
|
|
||||||
});
|
|
||||||
const result = await chatRepo.getHistory(PAGE_SIZE, input.offset);
|
const result = await chatRepo.getHistory(PAGE_SIZE, input.offset);
|
||||||
log.debug("[chat-machine] loadMoreHistoryActor chatRepo.getHistory DONE", {
|
|
||||||
success: result.success,
|
|
||||||
error: result.success ? null : Result.isErr(result) ? result.error : null,
|
|
||||||
responseType: result.success ? typeof result.data : "err",
|
|
||||||
});
|
|
||||||
if (Result.isErr(result)) {
|
if (Result.isErr(result)) {
|
||||||
log.error("[chat-machine] loadMoreHistoryActor result isErr, throwing", {
|
log.error("[chat-machine] loadMoreHistoryActor failed", { error: result.error });
|
||||||
error: result.error,
|
|
||||||
});
|
|
||||||
throw result.error;
|
throw result.error;
|
||||||
}
|
}
|
||||||
log.debug("[chat-machine] loadMoreHistoryActor result data", {
|
|
||||||
rawMessagesCount: result.data.messages.length,
|
|
||||||
});
|
|
||||||
const page = localMessagesToUi(result.data.messages);
|
const page = localMessagesToUi(result.data.messages);
|
||||||
log.debug("[chat-machine] loadMoreHistoryActor AFTER UiMessage mapping", {
|
|
||||||
uiMessagesCount: page.length,
|
|
||||||
});
|
|
||||||
const hasMore = page.length >= PAGE_SIZE;
|
|
||||||
const newOffset = input.offset + page.length;
|
|
||||||
log.debug("[chat-machine] loadMoreHistoryActor result", {
|
|
||||||
pageSize: page.length,
|
|
||||||
hasMore,
|
|
||||||
newOffset,
|
|
||||||
});
|
|
||||||
return {
|
return {
|
||||||
messages: page,
|
messages: page,
|
||||||
hasMore,
|
hasMore: page.length >= PAGE_SIZE,
|
||||||
newOffset,
|
newOffset: input.offset + page.length,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -196,40 +131,14 @@ export const loadMoreHistoryActor = fromPromise<
|
|||||||
*/
|
*/
|
||||||
export const chatWebSocketActor = fromCallback<ChatEvent, { token: string }>(
|
export const chatWebSocketActor = fromCallback<ChatEvent, { token: string }>(
|
||||||
({ sendBack, input }) => {
|
({ sendBack, input }) => {
|
||||||
log.debug("[chat-machine] chatWebSocketActor ENTRY", {
|
|
||||||
hasToken: !!input.token,
|
|
||||||
tokenLength: input.token?.length ?? 0,
|
|
||||||
tokenPrefix: input.token?.slice(0, 10) ?? "EMPTY",
|
|
||||||
selfPath: "<actor path>",
|
|
||||||
});
|
|
||||||
log.debug("[chat-machine] chatWebSocketActor creating ChatWebSocket instance");
|
|
||||||
const ws = createChatWebSocket(input.token);
|
const ws = createChatWebSocket(input.token);
|
||||||
log.debug("[chat-machine] chatWebSocketActor createChatWebSocket DONE", {
|
|
||||||
wsType: ws.constructor.name,
|
|
||||||
});
|
|
||||||
|
|
||||||
// 写入 module-level 共享引用 —— sendMessageWsActor 借此调 ws.sendMessage()
|
|
||||||
activeChatWebSocket = ws;
|
activeChatWebSocket = ws;
|
||||||
log.debug("[chat-machine] chatWebSocketActor activeChatWebSocket SET", {
|
|
||||||
isConnected: ws.isConnected,
|
|
||||||
});
|
|
||||||
|
|
||||||
ws.onConnected = (userId) => {
|
ws.onConnected = (userId) => {
|
||||||
log.debug("[chat-machine] WS onConnected", {
|
log.debug("[chat-machine] WS connected", { userId });
|
||||||
userId,
|
|
||||||
userIdPrefix: userId?.slice(0, 8) ?? "EMPTY",
|
|
||||||
});
|
|
||||||
sendBack({ type: "ChatWebSocketConnected", userId });
|
sendBack({ type: "ChatWebSocketConnected", userId });
|
||||||
};
|
};
|
||||||
ws.onSentence = (p) => {
|
ws.onSentence = (p) => {
|
||||||
log.debug("[chat-machine] WS onSentence", {
|
|
||||||
index: p.index,
|
|
||||||
total: p.total,
|
|
||||||
done: p.done,
|
|
||||||
textLength: p.text.length,
|
|
||||||
textPreview: p.text.slice(0, 50),
|
|
||||||
textSuffix: p.text.slice(-20),
|
|
||||||
});
|
|
||||||
sendBack({
|
sendBack({
|
||||||
type: "ChatAISentenceReceived",
|
type: "ChatAISentenceReceived",
|
||||||
index: p.index,
|
index: p.index,
|
||||||
@@ -239,23 +148,14 @@ export const chatWebSocketActor = fromCallback<ChatEvent, { token: string }>(
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
ws.onError = (msg) => {
|
ws.onError = (msg) => {
|
||||||
log.error("[chat-machine] WS onError", {
|
log.error("[chat-machine] WS error", { errorMessage: msg });
|
||||||
errorMessage: msg,
|
|
||||||
errorLength: msg?.length ?? 0,
|
|
||||||
});
|
|
||||||
sendBack({ type: "ChatWebSocketError", errorMessage: msg });
|
sendBack({ type: "ChatWebSocketError", errorMessage: msg });
|
||||||
};
|
};
|
||||||
log.debug("[chat-machine] chatWebSocketActor calling ws.connect()");
|
|
||||||
ws.connect();
|
ws.connect();
|
||||||
log.debug("[chat-machine] chatWebSocketActor ws.connect() called");
|
|
||||||
return () => {
|
return () => {
|
||||||
log.debug(
|
log.debug("[chat-machine] chatWebSocketActor cleanup");
|
||||||
"[chat-machine] chatWebSocketActor CLEANUP (parent state exit / logout / cross-transition / unmount)",
|
|
||||||
);
|
|
||||||
// 清空 module-level 引用 —— 严格用 `=== ws` 判等,避免覆盖更新的实例
|
|
||||||
if (activeChatWebSocket === ws) {
|
if (activeChatWebSocket === ws) {
|
||||||
activeChatWebSocket = null;
|
activeChatWebSocket = null;
|
||||||
log.debug("[chat-machine] chatWebSocketActor activeChatWebSocket CLEARED");
|
|
||||||
}
|
}
|
||||||
ws.disconnect();
|
ws.disconnect();
|
||||||
};
|
};
|
||||||
@@ -283,28 +183,16 @@ export const chatWebSocketActor = fromCallback<ChatEvent, { token: string }>(
|
|||||||
*/
|
*/
|
||||||
export const sendMessageWsActor = fromPromise<void, { content: string }>(
|
export const sendMessageWsActor = fromPromise<void, { content: string }>(
|
||||||
async ({ input }) => {
|
async ({ input }) => {
|
||||||
log.debug("[chat-machine] sendMessageWsActor ENTRY", {
|
|
||||||
contentLength: input.content.length,
|
|
||||||
contentPreview: input.content.slice(0, 50),
|
|
||||||
});
|
|
||||||
const ws = getActiveChatWebSocket();
|
const ws = getActiveChatWebSocket();
|
||||||
if (!ws) {
|
if (!ws) {
|
||||||
log.error("[chat-machine] sendMessageWsActor no activeChatWebSocket");
|
log.error("[chat-machine] sendMessageWsActor no active WebSocket");
|
||||||
throw new Error("[chat-machine] sendMessageWs: no active WebSocket (actor not running)");
|
throw new Error("[chat-machine] sendMessageWs: no active WebSocket (actor not running)");
|
||||||
}
|
}
|
||||||
log.debug("[chat-machine] sendMessageWsActor calling ws.sendMessage", {
|
|
||||||
isConnected: ws.isConnected,
|
|
||||||
});
|
|
||||||
const ok = ws.sendMessage(input.content);
|
const ok = ws.sendMessage(input.content);
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
log.error(
|
log.error("[chat-machine] sendMessageWsActor WebSocket not OPEN");
|
||||||
"[chat-machine] sendMessageWsActor ws.sendMessage returned false (not OPEN)",
|
|
||||||
);
|
|
||||||
throw new Error("[chat-machine] sendMessageWs: WebSocket not OPEN");
|
throw new Error("[chat-machine] sendMessageWs: WebSocket not OPEN");
|
||||||
}
|
}
|
||||||
log.debug(
|
|
||||||
"[chat-machine] sendMessageWsActor ws.sendMessage OK, awaiting AI sentence stream",
|
|
||||||
);
|
|
||||||
// resolve 不返值 —— AI reply 由 chatWebSocketActor 的 ChatAISentenceReceived 流回
|
// resolve 不返值 —— AI reply 由 chatWebSocketActor 的 ChatAISentenceReceived 流回
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -219,9 +219,6 @@ export const chatMachine = setup({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
// ========================================================================
|
|
||||||
// guestSession(游客会话 —— 不连 WS,2 个 init 任务并行)
|
|
||||||
// ========================================================================
|
|
||||||
guestSession: {
|
guestSession: {
|
||||||
on: {
|
on: {
|
||||||
ChatLogout: "#chat.idle",
|
ChatLogout: "#chat.idle",
|
||||||
@@ -342,13 +339,9 @@ export const chatMachine = setup({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
// 删除 loadingMore(游客无翻页)
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
// ========================================================================
|
|
||||||
// userSession(非游客会话 —— WS 父级 + history 子级)
|
|
||||||
// ========================================================================
|
|
||||||
userSession: {
|
userSession: {
|
||||||
// 父级 on:把 WS / AI 流句 事件从 ready.on 上提到 userSession.on
|
// 父级 on:把 WS / AI 流句 事件从 ready.on 上提到 userSession.on
|
||||||
// —— 任何 child state(initializing / ready / sendingViaWs / sendingViaHttp / loadingMore)
|
// —— 任何 child state(initializing / ready / sendingViaWs / sendingViaHttp / loadingMore)
|
||||||
@@ -360,7 +353,6 @@ export const chatMachine = setup({
|
|||||||
// —— XState v5: child handler 替换 parent;复制 action
|
// —— XState v5: child handler 替换 parent;复制 action
|
||||||
on: {
|
on: {
|
||||||
ChatLogout: "#chat.idle",
|
ChatLogout: "#chat.idle",
|
||||||
ChatGuestLogin: "#chat.guestSession",
|
|
||||||
ChatNonGuestLogin: {
|
ChatNonGuestLogin: {
|
||||||
target: "#chat.userSession",
|
target: "#chat.userSession",
|
||||||
reenter: true,
|
reenter: true,
|
||||||
|
|||||||
Reference in New Issue
Block a user