diff --git a/common_util/common_util_node_bundle.py b/common_util/common_util_node_bundle.py index d8de92f8f..f91d05255 100644 --- a/common_util/common_util_node_bundle.py +++ b/common_util/common_util_node_bundle.py @@ -13,6 +13,7 @@ import logging import os import subprocess import tempfile +import time from pathlib import Path from typing import Any @@ -48,15 +49,34 @@ def node_env() -> dict[str, str]: return env +# 「낡지 않음」 판정 기억 — 묶음마다 (묶음 mtime_ns, 잰 때). 같은 묶음이면 `RECHECK_S` 안에는 +# TS 330여 개를 다시 stat 하지 않는다(R24 · 부름마다 수십 ms). 낡음은 기억하지 않는다. +RECHECK_S = 30.0 +_FRESH: dict[str, tuple[int, float]] = {} + + def bundle_stale(bundle: Path) -> bool: """번들이 없거나 TS 원본보다 오래됐으면 참. 번들이 낡으면 서버와 화면이 **다른 값**을 만든다 — 이 판정이 그것을 막는 유일한 장치다. 개발 중에는 `npm run build`를 따로 돌리지 않으므로 여기서 스스로 갱신한다. + 「낡지 않음」은 `RECHECK_S` 동안 기억 — TS 를 고치면 늦어도 그만큼 뒤에 다시 짓는다. """ if not bundle.is_file(): return True - built_at = bundle.stat().st_mtime + stamp = bundle.stat().st_mtime_ns + remembered = _FRESH.get(str(bundle)) + if remembered and remembered[0] == stamp and time.monotonic() - remembered[1] < RECHECK_S: + return False + if _sources_newer(bundle.stat().st_mtime): + _FRESH.pop(str(bundle), None) + return True + _FRESH[str(bundle)] = (stamp, time.monotonic()) + return False + + +def _sources_newer(built_at: float) -> bool: + """묶음이 끌어가는 TS · 자료 중 하나라도 `built_at` 보다 새로우면 참.""" for directory in SOURCE_DIRS: for path in (ROOT / directory).rglob("*.ts"): if "node_modules" not in path.parts and path.stat().st_mtime > built_at: