refactor(chat): remove partial state cloning

This commit is contained in:
murashit 2026-07-17 06:11:03 +09:00
parent edf2b70902
commit bf8c87046b
3 changed files with 3 additions and 69 deletions

View file

@ -1,6 +1,4 @@
import { type ChatAction, type ChatState, chatReducer, createChatState } from "./root-reducer";
import type { ChatThreadStreamActiveSegment, ChatThreadStreamState } from "./thread-stream";
import { cloneDisclosureUiState } from "./ui-state";
export interface ChatStateStore {
getState(): ChatState;
@ -9,7 +7,7 @@ export interface ChatStateStore {
}
export function createChatStateStore(initialState: ChatState = createChatState()): ChatStateStore {
let current = cloneChatState(initialState);
let current = initialState;
const listeners = new Set<() => void>();
return {
getState: () => current,
@ -28,63 +26,3 @@ export function createChatStateStore(initialState: ChatState = createChatState()
},
};
}
function cloneChatState(state: ChatState): ChatState {
return {
connection: {
...state.connection,
availableModels: [...state.connection.availableModels],
availableSkills: [...state.connection.availableSkills],
availablePermissionProfiles: state.connection.availablePermissionProfiles.map((profile) => ({ ...profile })),
},
threadList: {
listedThreads: [...state.threadList.listedThreads],
},
panelThread:
state.panelThread.kind === "active" ? { kind: "active", thread: { ...state.panelThread.thread } } : { ...state.panelThread },
runtime: { ...state.runtime },
turn: { lifecycle: state.turn.lifecycle },
threadStream: cloneThreadStreamState(state.threadStream),
pendingSubmission: state.pendingSubmission ? { ...state.pendingSubmission, item: { ...state.pendingSubmission.item } } : null,
requests: {
approvals: [...state.requests.approvals],
pendingUserInputs: [...state.requests.pendingUserInputs],
pendingMcpElicitations: [...state.requests.pendingMcpElicitations],
userInputDrafts: new Map(state.requests.userInputDrafts),
mcpElicitationDrafts: new Map(state.requests.mcpElicitationDrafts),
},
composer: {
...state.composer,
suggestions: [...state.composer.suggestions],
},
ui: {
toolbarPanel: state.ui.toolbarPanel,
archiveConfirmThreadId: state.ui.archiveConfirmThreadId,
rename: { ...state.ui.rename },
goalEditor: { ...state.ui.goalEditor },
threadStreamActionMenu: { ...state.ui.threadStreamActionMenu },
disclosures: cloneDisclosureUiState(state.ui.disclosures),
},
};
}
function cloneThreadStreamState(state: ChatThreadStreamState): ChatThreadStreamState {
return {
stableItems: [...state.stableItems],
activeSegment: cloneActiveSegment(state.activeSegment),
turnDiffs: new Map(state.turnDiffs),
historyCursor: state.historyCursor,
loadingHistory: state.loadingHistory,
reportedLogs: new Set(state.reportedLogs),
};
}
function cloneActiveSegment(segment: ChatThreadStreamActiveSegment | null): ChatThreadStreamActiveSegment | null {
if (!segment) return null;
return {
turnId: segment.turnId,
items: [...segment.items],
indexById: new Map(segment.indexById),
indexBySourceItemId: new Map(segment.indexBySourceItemId),
};
}

View file

@ -10,7 +10,7 @@ import { threadStreamIsTurnInitiator } from "../../domain/thread-stream/semantic
import { completeReasoningItems, upsertThreadStreamItemById } from "../../domain/thread-stream/updates";
import { definedPatch, patchObject } from "./patch";
export interface ChatThreadStreamActiveSegment {
interface ChatThreadStreamActiveSegment {
readonly turnId: string | null;
readonly items: readonly ThreadStreamItem[];
readonly indexById: ReadonlyMap<string, number>;

View file

@ -51,7 +51,7 @@ const CHAT_DISCLOSURE_BUCKETS = [
type ChatDisclosureBucket = (typeof CHAT_DISCLOSURE_BUCKETS)[number];
export type ChatDisclosureUiState = Readonly<Record<ChatDisclosureBucket, ReadonlySet<string>>>;
type ChatDisclosureUiState = Readonly<Record<ChatDisclosureBucket, ReadonlySet<string>>>;
export interface ChatUiState {
readonly toolbarPanel: "history" | "chat-actions" | "status-panel" | null;
@ -149,10 +149,6 @@ export function reduceUiSlice(state: ChatUiState, action: UiAction): ChatUiState
}
}
export function cloneDisclosureUiState(state: ChatDisclosureUiState): ChatDisclosureUiState {
return disclosureUiStateFrom((bucket) => new Set(state[bucket]));
}
export function maybeClearGoalObjectiveExpansion(
state: ChatUiState,
currentGoal: ThreadGoal | null,