This commit is contained in:
mark committed 2026-09-19 13:10:34 -04:00
1 parent ea1afaf833
commit e0db317146
12 files changed
+444 -56

No files matched your search

+69
View File
@@ -0,0 +1,69 @@
"""Stamping for the service worker.
The dev server stamps sw.js on every request; the deploy stamps it once into
the uploaded copy. Both import this, because a digest computed two different
ways is a worker that thinks its caches are current when they are not.
"""
from __future__ import annotations
import hashlib
import json
import os
WORKER = "sw.js"
VERSION_LINE = "const VERSION = 'dev';"
LIBRARY_VERSION_LINE = "const LIBRARY_VERSION = 'dev';"
LIBRARY_LINE = "const LIBRARY = [];"
CHUNK = 1 << 20
def walk(roots):
found = {}
for root in roots:
for dirpath, _dirs, names in os.walk(root):
for name in sorted(names):
path = os.path.join(dirpath, name)
rel = os.path.relpath(path, root).replace(os.sep, "/")
found.setdefault(rel, path)
return found
def digest(files):
# Contents, not size and mtime: a checkout, a rebuild and a rsync all move
# mtimes without changing a byte, and each one of those would otherwise
# throw away every cache on every device for nothing.
out = hashlib.sha256()
for rel in sorted(files):
out.update(rel.encode("utf-8") + b"\0")
with open(files[rel], "rb") as fh:
for chunk in iter(lambda: fh.read(CHUNK), b""):
out.update(chunk)
out.update(b"\0")
return out.hexdigest()[:12]
def page_url(rel):
if rel == "index.html":
return "./"
return "./" + (rel[:-len(".html")] if rel.endswith(".html") else rel)
def stamp_worker(roots):
chrome = walk(roots[:1])
library = {rel: path for rel, path in walk(roots).items() if rel not in chrome}
src = chrome.pop(WORKER, None)
if src is None:
return None
with open(src, encoding="utf-8") as fh:
body = fh.read()
for line, value in (
(VERSION_LINE, "const VERSION = '%s';" % digest(chrome)),
(LIBRARY_VERSION_LINE, "const LIBRARY_VERSION = '%s';" % digest(library)),
(LIBRARY_LINE, "const LIBRARY = %s;"
% json.dumps(sorted(page_url(rel) for rel in library), indent=2)),
):
if line not in body:
raise RuntimeError("%s: expected to find %r to stamp" % (WORKER, line))
body = body.replace(line, value, 1)
return body.encode("utf-8")