Files
Aislo/resources/tester/helper_290_1_project_purge.cjs
T
eomsangdonandClaude Opus 5.5 0bf50a1837 feat(common): 다른 프로젝트 열면 그 밖 프로젝트 캐시 지움 · 저장 안 한 고침은 확인창 (290-1)
- b_project_switch.enterProject — 공용 goToWorkflowStage 에서 부름 · 탭마다 들어온 표식이 다를 때만
- 다른 프로젝트 세션 칸(초안 · 결과 · 옛 키 · 키 마디에 번호가 든 페이지 칸) + 3D 보관함 지움 · 지금 프로젝트 · 계정 취향 그대로
- 다른 프로젝트에 저장 안 한 고침이 있으면 확인창(지우고 열기 / 남기기) · 남기기 = 그 초안만 둠
- showConfirmDialog 취소 단추 글 받는 칸(기본 「취소」)
- 시험 test_290_1(진짜 TS · 가짜 저장소)

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

91 lines
3.2 KiB
JavaScript

/* 290-1 다른 프로젝트 열면 그 밖 프로젝트 캐시 지움 — 진짜 TS(b_page_state · b_project_switch)를
* 가짜 저장소 위에서 돌려 JSON 으로 냄(공용 storage · 브라우저 안 씀). */
const fs = require("fs");
const path = require("path");
const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript"));
const ROOT = path.join(__dirname, "..", "..");
const load = (rel, requireStub) => {
const js = ts.transpileModule(fs.readFileSync(path.join(ROOT, rel), "utf8"), {
compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2020 },
}).outputText;
const exports = {};
new Function("exports", "require", "window", js)(exports, requireStub, global.window);
return exports;
};
function fakeStorage() {
const map = new Map();
return {
get length() {
return map.size;
},
key: (i) => [...map.keys()][i] ?? null,
getItem: (k) => (map.has(k) ? map.get(k) : null),
setItem: (k, v) => map.set(k, String(v)),
removeItem: (k) => map.delete(k),
dump: () => Object.fromEntries(map),
};
}
global.window = { sessionStorage: fakeStorage(), localStorage: fakeStorage() };
const pageState = load("A00_Common/b_page_state.ts", () => ({}));
const asked = [];
const purged = [];
let answer = true;
const sw = load("A00_Common/b_project_switch.ts", (id) => {
if (id.includes("b_page_state")) return pageState;
if (id.includes("b_asset_cache")) return { purgeOtherProjects: async (p) => purged.push(p) };
return {
showConfirmDialog: async (msg, ok, cancel) => (asked.push([msg, ok, cancel]), answer),
};
});
const A = "aaaa1111";
const B = "bbbb2222";
const C = "cccc3333";
const SEED = {
[`aislo:draft:structures:${A}`]: '[{"id":1}]',
[`aislo:draft:crossw:${A}:12`]: '{"10":1}',
[`b06:culvertopt:${A}:12`]: '{"x":1}', // 옛 키(초안)
[`aislo:result:latest:${A}`]: '{"r":1}',
[`aislo:draft:structures:${B}`]: '[{"id":2}]',
[`aislo:result:section-detail:${B}:7`]: '{"d":1}',
[`aislo:result:latest:${C}`]: '{"r":3}',
[`aislo:draft:pipes:${C}`]: "{}", // 빈 초안 = 고침 없음
[`b09:page-cache:${C}`]: "1", // 등록표 밖 페이지 칸
"aislo.otp-pending": "x", // 프로젝트와 무관
};
const seed = (extra = {}) => {
global.window.sessionStorage = fakeStorage();
Object.entries({ ...SEED, ...extra }).forEach(([k, v]) =>
global.window.sessionStorage.setItem(k, v),
);
asked.length = 0;
purged.length = 0;
};
const keys = () => Object.keys(global.window.sessionStorage.dump()).sort();
const nameOf = async (id) => `이름-${id}`;
global.window.localStorage.setItem(`aislo:pref:routeedit-view:${A}`, "{}");
(async () => {
const out = {};
seed();
answer = true;
await sw.enterProject(B, nameOf);
out.drop = { keys: keys(), asked: [...asked], purged: [...purged] };
seed();
answer = false;
await sw.enterProject(B, nameOf);
out.keep = { keys: keys(), asked: asked.length };
seed({ "aislo:entered-project": B });
await sw.enterProject(B, nameOf);
out.same = { keys: keys(), asked: asked.length, purged: purged.length };
out.pref = global.window.localStorage.getItem(`aislo:pref:routeedit-view:${A}`);
out.plan = sw.planProjectPurge(SEED, B).draftProjects;
process.stdout.write(JSON.stringify(out));
})();