Files
Aislo/resources/tester/helper_323_9_save_redraw.cjs
T
eomsangdonandClaude Opus 5.5 da3dfc1ca8 feat(종단보기): 346-2 덧 2 B05 종단 보기 · 3D 측점선도 갈아끼운 상세로 — 보일 때만 · 숨었으면 다시 보일 때 · 횡단 보기 없이도
- design_view_profile_sections: 노선마다 상세 갈아끼움을 듣고 종단도 · 표 · 3D 측점선 다시(보일 때만 · 숨으면 flushSwap 이 다시 보일 때) · 가게 stations 도 들어 횡단 보기를 안 열어도 갈아끼움(먼저 부른 쪽만 · 다음은 「같은 목록」)
- design_view_profile: 받는 줄만(보임 · 떠날 때 끊음 · 다시 보일 때 flushSwap)
- 갈아끼움 알림판 B06_Section_Swap_Bus(가져오기 없음 · 돌고 도는 가져오기 막음) — 조정창 값 · 암 경계 옮김을 어느 보기가 갈아끼웠든 한 번 · 횡단 보기는 알림으로 다시 그림
- 시험: 종단 보기 보임 7 → 8 · 숨음 = 안 그림 · 다시 보임 = 6 · 3D 측점선 같은 차례 · 옛 시험 둘(342-1 화면 선 = listedBase · 323-9 열쇠 모듈 진짜로) 맞춤

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QfHKQs7J3hQELKMWQMUJEy
2026-10-16 12:28:11 +09:00

138 lines
5.3 KiB
JavaScript

/* PLAN 323-9 ① — B06 [저장] 뒤 카드 = 서버 새 상세. 진짜 `design_save.ts`(저장 차례) ·
* `B06_Section_UI_Page_Persist.ts`(횡단 뒤처리) · `B06_Section_Section_Store.ts`(상세 캐시)를 Node 로 돌림.
* 서버 창구만 가짜 — 상세는 저장 전(옛 자리) · 저장 뒤(새 자리) 두 벌.
*/
const fs = require("fs");
const path = require("path");
const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript"));
const CATALOG = require("./helper_322_catalog_module.cjs"); // 구조물 표(322-1)
const ROOT = path.join(__dirname, "..", "..");
const memory = () => {
const map = new Map();
return {
getItem: (key) => (map.has(key) ? map.get(key) : null),
setItem: (key, value) => map.set(key, String(value)),
removeItem: (key) => map.delete(key),
key: (index) => [...map.keys()][index] ?? null,
get length() {
return map.size;
},
};
};
globalThis.window = { sessionStorage: memory(), localStorage: memory() };
globalThis.sessionStorage = globalThis.window.sessionStorage;
const calls = [];
let server = "옛 자리 4+5";
const detail = () => ({ cross_sections: [], longitudinal: { stations: [] }, tag: server });
const B06 = path.join(ROOT, "B06_Section");
const STUBS = {
"@ui/ui_template_elements": {
showToast: (_text, kind) => calls.push(`toast:${kind}`),
showLoadingOverlay: () => calls.push("overlay:on"),
hideLoadingOverlay: () => calls.push("overlay:off"),
},
// 노선 저장(346-3) — 이 시험은 노선이 그대로인 [저장]만 봄
[path.join(ROOT, "B05_Profile", "B05_Profile_UI_RouteEdit_Apply.ts")]: {
pendingRouteSave: async () => null,
},
[path.join(B06, "B06_Section_Api_Fetch.ts")]: {
fetchSectionDetail: async () => (calls.push(`fetch:${server}`), detail()),
saveSections: async () => calls.push("cross:save"),
confirmSections: async () => calls.push("cross:confirm"),
},
};
const cache = new Map();
function loadTs(file) {
const full = path.resolve(file);
if (STUBS[full]) return STUBS[full];
if (cache.has(full)) return cache.get(full);
const js = ts.transpileModule(fs.readFileSync(full, "utf8"), {
compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2020 },
}).outputText;
const box = { exports: {} };
cache.set(full, box.exports);
const localRequire = (request) => {
if (STUBS[request]) return STUBS[request];
if (CATALOG.isCatalogRequest(request)) return CATALOG;
if (request.endsWith(".json")) return require(path.join(path.dirname(full), request));
if (request.endsWith(".css")) return {};
if (request.startsWith(".")) return loadTs(path.join(path.dirname(full), `${request}.ts`));
if (request.startsWith("@")) return new Proxy({}, { get: () => () => undefined });
return require(request);
};
new Function("exports", "module", "require", js)(box.exports, box, localRequire);
cache.set(full, box.exports);
return box.exports;
}
// 측점 열쇠 한 벌(344-3 · 346-2)은 진짜로 — 빈 대역은 열쇠 목록을 못 냄
STUBS["@util/common_util_station_key"] = loadTs(
path.join(ROOT, "common_util", "common_util_station_key.ts"),
);
const { saveDesign, savingDesign } = loadTs(
path.join(ROOT, "A00_Common", "design", "design_save.ts"),
);
const { crossSaveParts } = loadTs(path.join(B06, "B06_Section_UI_Page_Persist.ts"));
const { loadSectionDetail } = loadTs(path.join(B06, "B06_Section_Section_Store.ts"));
(async () => {
const P = "p1";
const R = 7;
// 횡단 보기 = 바뀜 신호마다 `refreshDetailForStructures` 와 같은 차례(최신만 · 저장 도중 안 그림)
let shown = null;
let seq = 0;
const refresh = async () => {
const mine = ++seq;
if (savingDesign(P)) return calls.push("refresh:skip");
const got = await loadSectionDetail(P, R);
if (mine === seq) shown = got.tag;
};
await refresh(); // 저장 전 화면(캐시 = 옛 서버)
const before = shown;
const ctx = {
projectId: P,
routeId: () => R,
detail: () => null,
context: () => null,
standardValues: () => undefined,
flushCulvertOptions: async () => undefined,
patchSources: () =>
Object.fromEntries(
["rockOffsets", "cutSlopeRatios", "stationWidths", "inletStructures", "basinAdjustments"]
.concat(["revetAdjusts", "extraCounts", "extraSpans", "fordAdjusts", "boxAdjusts"])
.concat(["linkFlags"])
.map((key) => [key, new Map()]),
),
reconcileDesigns: async () => undefined,
redraw: refresh,
};
const parts = crossSaveParts(ctx);
calls.length = 0;
const savingSeen = [];
const ok = await saveDesign({
projectId: P,
routeId: () => R,
steps: {
// 관 · 구조물 초안이 정본으로 나가며 가게가 바뀜 → 바뀜 신호(저장 도중)
structures: async () => {
server = "새 자리 4+8 · 47+0";
savingSeen.push(savingDesign(P));
await refresh();
},
...parts.steps,
},
cross: (confirm) => parts.cross(confirm),
done: async () => {
savingSeen.push(savingDesign(P));
await parts.done(false);
},
failed: (error) => calls.push(`failed:${error}`),
});
process.stdout.write(
JSON.stringify({ ok, before, after: shown, savingSeen, calls, savingIdle: savingDesign(P) }),
);
})();