/* PLAN 445-2 헬퍼 — 노선 저장 뒤 [저장] · [확정]마다 노선 저장이 다시 돌던 것. * ① 편집기가 떠나면(페이지 다시 세움 · 평면 판 접힘) 등록부에서 풀림 → `pendingRouteSave` = 가게 초안(저장 뒤 null) * ② 고정(잠금)만 바꾼 걸음은 노선이 안 바뀜(`lineChanged`) · [초기화] 판정(`isDirty`)은 그대로. * TS 를 그 자리에서 트랜스파일 · 가게 · 서버 창구는 가짜. 짝 = `test_445_2_route_pending.py`. */ const fs = require("fs"); const path = require("path"); const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript")); const ROOT = path.join(__dirname, "..", ".."); const B05 = (name) => path.join(ROOT, "B05_Profile", `${name}.ts`); const anything = () => new Proxy({}, { get: (_target, key) => (key === "__esModule" ? false : () => undefined) }); function load(file, stubs) { const js = ts.transpileModule(fs.readFileSync(file, "utf8"), { compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2020 }, }).outputText; const box = { exports: {} }; new Function("exports", "module", "require", js)(box.exports, box, (spec) => spec in stubs ? stubs[spec] : anything(), ); return box.exports; } const store = new Map(); const apply = load(B05("B05_Profile_UI_RouteEdit_Apply"), { "../A00_Common/design/design_store": { useDesignStore: () => ({ get: (key) => store.get(key) ?? null, set: (k, v) => store.set(k, v), }), }, }); const history = load(B05("B05_Profile_UI_RouteEdit_History"), { "./B05_Profile_UI_Profile_History": { onPageHistory: () => () => undefined }, }); (async () => { const out = {}; const P = "p445"; let dirty = true; // 옛 편집기 = 교점을 끈 채 남음 const params = (changed) => ({ projectId: P, nodes: () => ({ planned: [ [0, 0], [10, 0], [20, 5], ], curveOn: [false, true, false], curveRadius: [null, 30, null], }), changed, terrain: () => null, snap: () => ({ stationSnap: false, stationSnapStep: null }), initial: { current: () => null, keep: () => undefined }, onApplied: () => undefined, }); const unbind = apply.bindRouteApply(params(() => dirty)); out.boundPending = !!(await apply.pendingRouteSave(P)); unbind(); // 편집기가 떠남(저장 뒤 페이지 다시 세움) out.afterUnbind = !!(await apply.pendingRouteSave(P)); // 가게 초안 없음 = null // 새 편집기가 선 뒤 옛 편집기가 늦게 풀려도 새 것은 남음 const unbindOld = apply.bindRouteApply(params(() => true)); apply.bindRouteApply(params(() => false)); unbindOld(); out.newKept = await apply.pendingRouteSave(P); // 새 편집기 = 안 바뀜 → null(옛 것이면 true) // 고정만 바꾼 걸음 const snap = (lock) => ({ planned: [ [0, 0], [10, 0], [20, 5], ], curveOn: [false, true, false], curveRadius: [null, 30, null], curveLock: [null, null, null], curveArc: [null, null, null], apexLock: [true, lock, true], picked: 1, }); const h = history.createRouteEditHistory(snap(false)); h.commit(snap(true)); out.lockOnly = { isDirty: h.isDirty(), lineChanged: history.lineChanged(h) }; const moved = snap(false); moved.planned[1] = [10, 3]; h.commit(moved); out.moved = { lineChanged: history.lineChanged(h) }; process.stdout.write(JSON.stringify(out)); })().catch((error) => { process.stderr.write(String(error?.stack ?? error)); process.exit(1); });