- B06 [>] · 단계 판 B07~B09 = moveStage 한 단계(설계 확정) · progress = GET /design/save/progress 1 s 물음 · B03 · B04 로 = moveStage 잠금 길(떠남 확인은 잠금 풀린 뒤) - 낡음 확인 창 · 화면 side.update() 걷음 — 배수유역은 서버 [확정] 관 차례가 한 번만 셈 · 진행 이름 「배수유역 다시 셈」(basins) - 서버 _run_steps step() 진행을 메모리(B06_Section_Router_DesignSave_Progress) · 차례 목록 = N · 끝에 비움 - 노선 바뀐 채 [>] = 물음(잠금판 위 · z 1050 > 900) → 다시 세운 페이지 둘째 확정을 저장 줄 밖에서 기다림 → 잠금판이 다시 마운트를 넘어 이어져 이동 · 120 s 넘으면 머묾 - saveSharedDesign 이 참 · 거짓을 돌려줌 · 확정 이동은 부른 쪽(moveStage) - 낡은 시험 고침 — 512_2(확인 창 → 잠금판 한 단계 · 서버 basins) · 298_3 · 272 · b06_save_channels · b06_save_recompute(글 약속 새 길) - helper_ts_stub_loader .css = 빈 모듈 — 520-3 ui_template_progress.css import 로 451 · 384_4 · 416 등 helper 시험이 깨짐(브레인 승인) - 새 시험 test_520_4_save_progress(n/N · 배수유역 자리) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
92 lines
4.2 KiB
JavaScript
92 lines
4.2 KiB
JavaScript
/* 진짜 TS 를 CommonJS 로 트랜스파일해 부르는 공용 불러오기 + 가짜 모듈 끼워 넣기(507-4 · 새 시험부터 이걸 씀).
|
|
* 옛 헬퍼 198 벌이 저마다 베낀 `loadTs`(+ `STUBS`) 한 벌 — 진짜 모듈이 새 export · import 를 늘리면 헬퍼마다 낡아
|
|
* 깨졌음(482). 여기만 고치면 되게 모음.
|
|
*
|
|
* const { makeLoader, memoryStorage } = require("./helper_ts_stub_loader.cjs");
|
|
* const STUBS = {}; // 끝이 이 이름으로 끝나는 import 를 가짜로(헬퍼가 나중에 채움)
|
|
* const { load, loadTs } = makeLoader({ root: ROOT, stubs: STUBS, ui: () => anyModule() });
|
|
* const store = load("B06_Section", "B06_Section_Section_Store.ts");
|
|
*
|
|
* 풀이 순서(기본): 카탈로그 · STUBS · @config(가짜 주소) · @ui(`ui` 쪽 값 · 기본 showToast) · .css · .json · @util · 상대 경로 · 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");
|
|
|
|
function memoryStorage() {
|
|
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;
|
|
},
|
|
};
|
|
}
|
|
|
|
/* 옵션 — 옮겨 온 옛 헬퍼가 저마다 달리 쓰던 것(헬퍼 동작 그대로).
|
|
* requireFor(full, file) 풀이 함수를 헬퍼가 직접 지음(기본 풀이 대신) · 인자 없으면 진짜 require
|
|
* interop esModuleInterop 로 트랜스파일
|
|
* cache:false 같은 파일을 부를 때마다 새로 읽음(기본은 한 번만)
|
|
* fileStub(full) 파일 경로로 통째 대신할 값(없으면 undefined)
|
|
* target 트랜스파일 대상(기본 ES2020)
|
|
* rewrite(js) 트랜스파일한 글 손봄(`import.meta` 처럼 CommonJS 가 못 읽는 것) */
|
|
function makeLoader({
|
|
root,
|
|
stubs = {},
|
|
ui = () => ({ showToast: () => undefined }),
|
|
requireFor,
|
|
interop = false,
|
|
cache: useCache = true,
|
|
fileStub,
|
|
target = ts.ScriptTarget.ES2020,
|
|
rewrite = (js) => js,
|
|
}) {
|
|
const cache = new Map();
|
|
function defaultRequire(full) {
|
|
return (request) => {
|
|
if (CATALOG.isCatalogRequest(request)) return CATALOG;
|
|
const key = Object.keys(stubs).find((name) => request.endsWith(name));
|
|
if (key) return stubs[key];
|
|
if (request.startsWith("@config/")) return { API_BASE_URL: "http://fake" };
|
|
if (request.startsWith("@ui/")) return ui();
|
|
if (request.endsWith(".css")) return {};
|
|
if (request.endsWith(".json")) return require(path.join(path.dirname(full), request));
|
|
if (request.startsWith("@util/"))
|
|
return loadTs(path.join(root, "common_util", `${request.slice(6)}.ts`));
|
|
if (request.startsWith(".")) return loadTs(path.join(path.dirname(full), `${request}.ts`));
|
|
return require(request);
|
|
};
|
|
}
|
|
function loadTs(file) {
|
|
const full = path.resolve(file);
|
|
if (useCache && cache.has(full)) return cache.get(full);
|
|
const stub = fileStub && fileStub(full);
|
|
if (stub) return stub;
|
|
if (full.endsWith(".css")) return {}; // 화면 글꼴 import(ui_template_progress.css 등) — 트랜스파일 못 함
|
|
if (full.endsWith(".json")) {
|
|
const data = JSON.parse(fs.readFileSync(full, "utf8"));
|
|
if (useCache) cache.set(full, data);
|
|
return data;
|
|
}
|
|
const compilerOptions = { module: ts.ModuleKind.CommonJS, target };
|
|
if (interop) compilerOptions.esModuleInterop = true;
|
|
const js = rewrite(
|
|
ts.transpileModule(fs.readFileSync(full, "utf8"), { compilerOptions }).outputText,
|
|
);
|
|
const box = { exports: {} };
|
|
if (useCache) cache.set(full, box.exports);
|
|
const localRequire = requireFor ? requireFor(full, file) : defaultRequire(full);
|
|
new Function("exports", "module", "require", js)(box.exports, box, localRequire);
|
|
if (useCache) cache.set(full, box.exports);
|
|
return box.exports;
|
|
}
|
|
return { loadTs, load: (...parts) => loadTs(path.join(root, ...parts)) };
|
|
}
|
|
|
|
module.exports = { makeLoader, memoryStorage };
|