Files
Aislo/B06_Section/B06_Section_UI_Page_Link_Session.ts
T

104 lines
3.6 KiB
TypeScript

/* =============================================================================
* B06_Section_UI_Page_Link_Session.ts
* 연동 기슭막이 옵션(연동 해제·종단경사 반영)의 **세션 보관** — 측점 제어기
* (`_UI_Page_Station_Controls.ts`)에서 700줄 제한으로 분리했다(2026-08-25).
* 두 플래그는 한 세션 항목에 같이 담아 확정 전 리로드에도 살아남는다.
*
* 측점별 조작값을 담는 **한 겹 맵**도 여기서 낸다(`createSessionMap`, 2026-09-02) —
* 반폭·기슭막이 4축·유입 형식·집수정·추가 벽 수·단별 구간값이 같은 모양(읽기 → 항목
* 검증 → 담기 / 쓰기 → 통째 직렬화)이라 제어기마다 짝을 두던 것을 하나로 모았다.
* ========================================================================== */
/** 세션에 담기는 측점별 조작값 한 겹 맵. */
export interface SessionMap<V> {
values: Map<string, V>;
/** 세션값 읽기 — 맵을 비우고 다시 채운다. */
load: () => void;
/** 맵을 통째로 세션에 쓴다. */
persist: () => void;
}
/**
* 세션 보관 맵을 만든다. `accept` 가 항목마다 값을 검증·정규화해 돌려주고,
* `undefined` 를 내면 그 항목은 버린다(손상값·옛 형식 정리 자리).
*/
export function createSessionMap<V>(
sessionKey: () => string | null,
accept: (value: unknown) => V | undefined,
): SessionMap<V> {
const values = new Map<string, V>();
return {
values,
load(): void {
values.clear();
const key = sessionKey();
if (!key) return;
try {
const raw = window.sessionStorage.getItem(key);
if (!raw) return;
const parsed = JSON.parse(raw) as Record<string, unknown>;
Object.entries(parsed).forEach(([entry, value]) => {
const taken = accept(value);
if (taken !== undefined) values.set(entry, taken);
});
} catch {
/* 손상된 세션 값은 무시 — 정본·기본값으로 재시작. */
}
},
persist(): void {
const key = sessionKey();
if (!key) return;
try {
window.sessionStorage.setItem(key, JSON.stringify(Object.fromEntries(values)));
} catch {
/* 세션 저장 실패는 무시(용량 초과 등) — 값은 메모리에 유지된다. */
}
},
};
}
export interface LinkFlagMaps {
detached: Map<string, boolean>;
followGrade: Map<string, boolean>;
load: () => void;
persist: () => void;
}
export function createLinkFlagSession(sessionKey: () => string | null): LinkFlagMaps {
const detached = new Map<string, boolean>();
const followGrade = new Map<string, boolean>();
return {
detached,
followGrade,
load(): void {
detached.clear();
followGrade.clear();
const key = sessionKey();
if (!key) return;
try {
const raw = window.sessionStorage.getItem(key);
if (!raw) return;
const parsed = JSON.parse(raw) as {
detached?: Record<string, boolean>;
grade?: Record<string, boolean>;
};
Object.entries(parsed.detached ?? {}).forEach(([at, value]) => detached.set(at, !!value));
Object.entries(parsed.grade ?? {}).forEach(([at, value]) => followGrade.set(at, !!value));
} catch {
/* 손상된 세션 값은 무시 — 정본·기본값으로 재시작. */
}
},
persist(): void {
const key = sessionKey();
if (!key) return;
window.sessionStorage.setItem(
key,
JSON.stringify({
detached: Object.fromEntries(detached),
grade: Object.fromEntries(followGrade),
}),
);
},
};
}