import { writable, get } from "svelte/store"; import type { BreadcrumbEntry, NodeDetail } from "./types.js"; const STORAGE_KEY = "filelib.browser"; interface PersistedState { expanded: string[]; currentNodeId: string | null; tab: string | null; selectedFilePath: string | null; } function loadPersisted(): PersistedState { try { const raw = sessionStorage.getItem(STORAGE_KEY); if (raw) return JSON.parse(raw) as PersistedState; } catch { /* ignore */ } return { expanded: [], currentNodeId: null, tab: null, selectedFilePath: null }; } function savePersisted(): void { try { const state: PersistedState = { expanded: [...get(expanded)], currentNodeId: get(currentNode)?.id ?? null, tab: get(activeTab), selectedFilePath: get(selectedFilePath), }; sessionStorage.setItem(STORAGE_KEY, JSON.stringify(state)); } catch { /* sessionStorage 不可用时静默忽略 */ } } const persisted = loadPersisted(); /** 树展开集合 / 当前选中节点 / 面包屑 / 树刷新计数。 */ export const expanded = writable>(new Set(persisted.expanded)); export const currentNode = writable(null); export const breadcrumb = writable([]); export const treeVersion = writable(0); /** 刷新后需要恢复的节点 ID;LibraryView onMount 消费后清空。 */ export const restoreNodeId = persisted.currentNodeId; /** 刷新后需要恢复的 tab;NodeDetailPanel 消费。 */ export const restoreTab = persisted.tab; /** 右侧预览栏:当前选中文件路径(项目内);切换节点时清空。 */ export const selectedFilePath = writable(persisted.selectedFilePath); /** 文件列表刷新计数(编辑器保存/删除后 bump,列表随之重载)。 */ export const filesVersion = writable(0); /** 当前激活的 tab(由 NodeDetailPanel 写入,持久化用)。 */ export const activeTab = writable(persisted.tab); // 订阅需要持久化的 store,变化时写 sessionStorage。 expanded.subscribe(() => savePersisted()); currentNode.subscribe(() => savePersisted()); selectedFilePath.subscribe(() => savePersisted()); activeTab.subscribe(() => savePersisted()); export function bumpTree(): void { treeVersion.update((v) => v + 1); } export function bumpFiles(): void { filesVersion.update((v) => v + 1); } export function clearSelectedFile(): void { selectedFilePath.set(null); } export function toggleExpanded(id: string): void { expanded.update((set) => { const next = new Set(set); if (next.has(id)) next.delete(id); else next.add(id); return next; }); }