Files
Aislo/B03_FileInput/B03_FileInput_State.ts
2026-07-10 18:12:17 +09:00

91 lines
2.6 KiB
TypeScript

export type B03AnalysisStatus = "pending" | "in_progress" | "completed" | "failed";
export interface B03StoredFileState {
slot: string;
fileName: string;
fileSize: number;
status: "completed" | "failed";
}
export interface B03ProjectState {
projectId: string;
uploadedAt: number;
files: B03StoredFileState[];
analysisStatus: B03AnalysisStatus;
analysisProgress: number;
lastCheckedAt: number;
}
function key(projectId: string): string {
return `b03_project_state_${projectId}`;
}
export function loadB03ProjectState(projectId: string): B03ProjectState | null {
const raw = localStorage.getItem(key(projectId));
if (!raw) return null;
try {
return JSON.parse(raw) as B03ProjectState;
} catch {
localStorage.removeItem(key(projectId));
return null;
}
}
export function saveB03UploadedFile(
projectId: string,
file: { slot: string; fileName: string; fileSize: number },
): B03ProjectState {
const current = loadB03ProjectState(projectId);
const nextFiles = (current?.files ?? []).filter((item) => item.slot !== file.slot);
nextFiles.push({ ...file, status: "completed" });
const next: B03ProjectState = {
projectId,
uploadedAt: current?.uploadedAt ?? Date.now(),
files: nextFiles,
analysisStatus: "pending",
analysisProgress: 0,
lastCheckedAt: Date.now(),
};
localStorage.setItem(key(projectId), JSON.stringify(next));
return next;
}
export function updateB03AnalysisState(
projectId: string,
status: B03AnalysisStatus,
progress: number,
): B03ProjectState {
const current = loadB03ProjectState(projectId);
const next: B03ProjectState = {
projectId,
uploadedAt: current?.uploadedAt ?? Date.now(),
files: current?.files ?? [],
analysisStatus: status,
analysisProgress: progress,
lastCheckedAt: Date.now(),
};
localStorage.setItem(key(projectId), JSON.stringify(next));
return next;
}
export function restoreB03ProjectState(options: {
projectId: string;
label: string;
container: HTMLElement;
poll: (projectId: string) => Promise<boolean>;
onComplete: () => void;
}): void {
const state = loadB03ProjectState(options.projectId);
if (!state) return;
options.container.replaceChildren();
const message = document.createElement("span");
message.textContent = `${options.label}: ${state.analysisProgress}%`;
options.container.append(message);
options.container.classList.add("is-visible");
if (state.analysisStatus === "in_progress" || state.analysisStatus === "pending") {
void options.poll(options.projectId).then((completed) => {
if (completed) options.onComplete();
});
}
}