- 새 Section_Canon — 정본 설계 사본 · 세션 글 풂 한 번(상세 가게 · 묶음 cross 입력 같이 봄) - 갈아끼움 · 되돌림은 세션 상세 안 씀(메모리만) · 받을 때만 씀 - 묶음 cross 입력이 세션 글을 따로 안 풂(storedText 지움) - 새 test_384_7_section_canon · test_365_1 세션 = 정본 기대값 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014utrjfoW831Vc5wJUd13kL
67 lines
3.1 KiB
TypeScript
67 lines
3.1 KiB
TypeScript
/* =============================================================================
|
|
* B06_Section_Section_Canon.ts
|
|
* 세션 상세(`section-detail`) = **저장 정본만**(387-7) — 서버에서 받은 그대로 한 벌 · 갈아끼움 · 되돌림 ·
|
|
* 다시 셈 결과는 안 씀(메모리 캐시 몫). 세션 글은 **한 번만** 풂 — 상세 가게(`_Section_Store`)와 계산 묶음
|
|
* cross 입력(`design_pipeline_cross`)이 이 파일을 함께 봄(예전에는 둘이 따로 1.5 MB 를 풂).
|
|
* 가벼운 자리 — 상세 가게의 화면 줄기를 안 끌고 묶음 입력이 부름.
|
|
* ========================================================================== */
|
|
|
|
import { readState } from "../A00_Common/b_page_state";
|
|
import type { CrossSection, SectionDetailResponse } from "./B06_Section_Api_Fetch";
|
|
|
|
/** 정본 측점 설계 — 받을 때 뜬 사본(다시 셈 · 초안 얹기가 고치는 캐시 객체와 따로). */
|
|
export type CanonRow = { chainage_m: number; design: CrossSection["design"] };
|
|
|
|
const canon = new Map<string, CanonRow[]>();
|
|
/** 묶음이 먼저 푼 세션 상세 — 상세 가게가 처음 읽을 때 가져감(다시 안 풂). */
|
|
const parsed = new Map<string, SectionDetailResponse>();
|
|
const keyOf = (projectId: string, routeId: number): string => `${projectId}:${routeId}`;
|
|
|
|
/** 서버에서 받은(또는 세션에서 푼) 정본의 설계 사본을 떠 둠. */
|
|
export function keepCanon(projectId: string, routeId: number, detail: SectionDetailResponse): void {
|
|
const key = keyOf(projectId, routeId);
|
|
parsed.delete(key);
|
|
canon.set(
|
|
key,
|
|
detail.cross_sections.map(({ chainage_m, design }) => ({
|
|
chainage_m,
|
|
design: design ? { ...design } : design,
|
|
})),
|
|
);
|
|
}
|
|
|
|
/** 새로고침 — 세션 상세(묶음이 먼저 풀었으면 그 객체) · 정본 사본도 뜸. */
|
|
export function sessionDetail(projectId: string, routeId: number): SectionDetailResponse | null {
|
|
const key = keyOf(projectId, routeId);
|
|
const ready = parsed.get(key);
|
|
if (ready) {
|
|
parsed.delete(key);
|
|
return ready;
|
|
}
|
|
const stored = readState<SectionDetailResponse>("section-detail", projectId, routeId);
|
|
if (stored) keepCanon(projectId, routeId, stored);
|
|
return stored;
|
|
}
|
|
|
|
/** 정본 측점 설계(묶음 cross 입력 · 365-5) — 아직 안 읽었으면 세션에서 한 번(상세 가게가 그 객체를 이어 씀). */
|
|
export function savedDesigns(projectId: string, routeId: number): CanonRow[] | null {
|
|
const key = keyOf(projectId, routeId);
|
|
if (!canon.has(key)) {
|
|
const stored = readState<SectionDetailResponse>("section-detail", projectId, routeId);
|
|
if (!stored) return null;
|
|
keepCanon(projectId, routeId, stored);
|
|
parsed.set(key, stored);
|
|
}
|
|
return canon.get(key) ?? null;
|
|
}
|
|
|
|
/** 정본이 바뀜(새로 받을 것) — 사본을 버림. 노선을 안 주면 그 프로젝트 전부. */
|
|
export function forgetCanon(projectId: string, routeId?: number): void {
|
|
for (const map of [canon, parsed])
|
|
for (const key of [...map.keys()])
|
|
if (
|
|
routeId === undefined ? key.startsWith(`${projectId}:`) : key === keyOf(projectId, routeId)
|
|
)
|
|
map.delete(key);
|
|
}
|