import { useAppStore } from "../../../store/useAppStore"; /** dispatchFrame 处理的单个下行帧(信封形状,与 lib/ws.ts 导出的 dispatchFrame 签名一致)。 */ export interface FrameEvent { type: string; sessionId?: string; data: unknown; } /** toRecord(ev.data) 解析后的帧 payload(与 lib/wsParse.ts#toRecord 的返回形状一致)。 */ export type FramePayload = Record | null; /** dispatchFrame 入口处取到的 store 快照类型,按参数传给各帧处理组。 */ export type StoreState = ReturnType; /** 一帧所属的会话 id:payload 里带的优先(结构化流帧在回合边界由 loop 注入), * 其次帧壳的;两者都没有时返回 undefined,调用方据此落回「当前激活会话」。 * * 裁决 16.4.5 后这里返回的 id 决定**写进哪个会话的消息桶**(而不是决定丢弃)。 */ export function frameSessionId(ev: FrameEvent, r: FramePayload): string | undefined { if (r && typeof r.sessionId === "string" && r.sessionId) return r.sessionId; return ev.sessionId || undefined; } /** 这帧是不是屏幕上这个会话的?只用于**单槽全局状态**的判定(忙态 / 上下文 / * 思考累积器)—— 消息内容本身按各自的会话桶写入,不再受此限制。 * * 激活会话尚未解析(列表没加载出来,仍是 "")时返回 true,沿用旧行为:不因为 * 会话 id 还没对上就把主人正看着的流丢掉。 */ export function frameIsActive( sessionId: string | undefined, activeSessionId: string ): boolean { if (!sessionId || !activeSessionId) return true; return sessionId === activeSessionId; }