mirror of
https://github.com/pewdiepie-archdaemon/odysseus.git
synced 2026-10-11 01:12:20 +02:00
refactor(email): move emailLibrary.js into static/js/emailLibrary/
The email library was 11,375 lines in one file, the second-largest JS module in the repo. `static/js/emailLibrary/` already held four extracted helpers, so the package existed; the bulk of the code just was not in it. The implementation moves to `emailLibrary/index.js` and the old path becomes a re-export wrapper. Five call sites import that path, four of them dynamically with a `?v=` string, and `sw.js` caches URLs verbatim, so a wrapper is what makes the move need no coordinated edit to any of them. The test side is the part worth reviewing. 58 tests read `static/js/emailLibrary.js` as text. Pointing them at `emailLibrary/index.js` would buy one move and break again on the next one, which is exactly what happened to the stylesheet tests (they now go through `tests/helpers/stylesheets.py`). So the same shape: `tests/helpers/js_modules.py` reads the whole package, and assertions stop caring which module a function sits in. `tests/test_email_library_module_graph_js.py` is new. This frontend has no module-graph validation, and a package fails in ways a single file cannot: a wrapper that drops an export is `undefined` at call time rather than an error at load time, and a module that reads a `const` across an import cycle throws only when that module is entered first. It pins the wrapper's surface against the entry module's, evaluates every module on its own in a browser, and requires both import paths to hand out one instance. It also caught a live gap while being written: `emailLibrary/replyRecipients.js` is imported by `emailInbox.js`, an app shell module, and was never in the `sw.js` precache.
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
"""Read a split JS subpackage the way the module graph does.
|
||||
|
||||
``static/js/emailLibrary.js`` is a re-export wrapper; the implementation lives
|
||||
in ``static/js/emailLibrary/``. A test that asserts on email-library behaviour
|
||||
has to look at every module in that package, because reading one file ties the
|
||||
test to whichever module a function happens to sit in today — it goes red the
|
||||
next time something moves without any behaviour changing.
|
||||
|
||||
That is the mistake the stylesheet split made, which is why
|
||||
``tests/helpers/stylesheets.py`` exists. This is the same helper for JS.
|
||||
|
||||
Order is deterministic: the entry module first, then the rest alphabetically.
|
||||
Tests that assert "A appears before B" are asserting about one module's source,
|
||||
not about the package, so the concatenation order only has to be stable.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
_STATIC_JS = Path(__file__).resolve().parents[2] / "static" / "js"
|
||||
|
||||
EMAIL_LIBRARY_WRAPPER = _STATIC_JS / "emailLibrary.js"
|
||||
EMAIL_LIBRARY_PACKAGE = _STATIC_JS / "emailLibrary"
|
||||
EMAIL_LIBRARY_ENTRY = EMAIL_LIBRARY_PACKAGE / "index.js"
|
||||
|
||||
|
||||
def _package_paths(package: Path, entry: Path) -> list[Path]:
|
||||
if not entry.is_file():
|
||||
raise AssertionError(f"missing package entry module: {entry}")
|
||||
rest = sorted(p for p in package.glob("*.js") if p != entry)
|
||||
return [entry, *rest]
|
||||
|
||||
|
||||
def email_library_paths(include_wrapper: bool = False) -> list[Path]:
|
||||
"""Every module of the email-library package, entry module first.
|
||||
|
||||
``include_wrapper`` adds the compatibility file at the old top-level path.
|
||||
Leave it off for assertions about implementation code: the wrapper holds
|
||||
only an ``export … from`` list.
|
||||
"""
|
||||
paths = _package_paths(EMAIL_LIBRARY_PACKAGE, EMAIL_LIBRARY_ENTRY)
|
||||
return [EMAIL_LIBRARY_WRAPPER, *paths] if include_wrapper else paths
|
||||
|
||||
|
||||
def email_library_source(include_wrapper: bool = False) -> str:
|
||||
"""The whole email-library package as one string."""
|
||||
return "\n".join(
|
||||
p.read_text(encoding="utf-8") for p in email_library_paths(include_wrapper)
|
||||
)
|
||||
Reference in New Issue
Block a user