Files
cozsweet-frontend-nextjs/src/stores/chat/chat-state.ts
T
admin 1f3980d461 chore(chat): refactor chat init into separate quota and history actors
Split `chatInitActor` into `loadQuotaActor` (guest quota fetch) and `loadHistoryActor` (local → network → save sync), and add `quotaLoaded` / `historyLoaded` state flags so the UI can display loading status during the new local-first history hydration flow. Also drop the now-unused `ChatInit` event and pipe Next.js stdout/stderr to a persistent log file in the post-receive hook for easier troubleshooting.
2026-06-15 16:21:40 +08:00

67 lines
2.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* Chat 状态机:State 形状 + 初始值
*
* 注:GuestChatQuota 仍位于 chat-machine.ts(属于业务常量,与上下文配对紧密)。
*
* 历史:
* - `isGuest: boolean` 字段已**删**(由 chat-screen 派生自 `auth.loginStatus === "guest"`
* - `guestRemainingQuota` / `guestTotalQuota` default **改 0**
* - 游客:chat-screen 派 `ChatInit` → readInitData 调 ChatStorage → onDone 条件赋
* - 非游客:**永不被赋值**(业务事实"非游客无消息限制")—— 0 - 1 = max(0, -1) = 0 天然 no-op
* - 0 同时表示"未初始化"和"已耗尽" —— UI 用 `if (isGuest && ...)` 天然过滤
*
* 新增 `wsConnected: boolean`**仅** userSession 期间 true):
* - **WS 已连** → 消息发送走 WS,**不**消耗次数
* - **WS 未连** → 消息发送走 HTTP,消耗次数
* - `ChatWebSocketConnected` 事件 → true
* - `userSession.exit` → falseWS actor cleanup 时**也**会跑 exit
*/
import type { UiMessage } from "@/models/chat/ui-message";
export interface ChatState {
messages: UiMessage[];
isReplyingAI: boolean;
/**
* WebSocket 连接状态(**仅** userSession 期间 true
* - 决定消息发送**路径**WS / HTTP)和**是否消耗**次数
* - true:走 WS**不**消耗次数
* - false:走 HTTP,消耗次数
*/
wsConnected: boolean;
/** 游客剩余配额(次/天)—— **仅**游客业务展示用
* - default 0 = "未初始化" / "已耗尽"(同码,靠 `isGuest` 区分)
* - 非游客:永不被赋值(业务事实"无消息限制")
*/
guestRemainingQuota: number;
/** 游客总配额(仅游客展示用) */
guestTotalQuota: number;
quotaExceededTrigger: number;
isLoadingMore: boolean;
hasMore: boolean;
historyOffset: number;
/** 游客配额加载完成标**志****仅** guestSession 期间) —— default false
* - guestSession.initializing **走** always barrier`quotaLoaded && historyLoaded` **才**进** ready
* - userSession **永不为** true**不**调 loadQuota)—— OK**不**影响 barrier
*/
quotaLoaded: boolean;
/** history 加**载**完成标**志**initial load —— local → network → save 跑**完**
* - guestSession.initializing / userSession.initializing 走 always barrier
* - **不**被 `loadMoreHistoryActor` 设**置****翻**页**是**另**一**码**事**
*/
historyLoaded: boolean;
}
export const initialState: ChatState = {
messages: [],
isReplyingAI: false,
wsConnected: false,
guestRemainingQuota: 0,
guestTotalQuota: 0,
quotaExceededTrigger: 0,
isLoadingMore: false,
hasMore: true,
historyOffset: 0,
quotaLoaded: false,
historyLoaded: false,
};