diff --git a/build.sh b/build.sh index 1c50fee..198f028 100755 --- a/build.sh +++ b/build.sh @@ -48,6 +48,49 @@ for path in kernel_extension_dir.glob("*.js"): if not patched_files: raise SystemExit("No Pyodide dynamic import bundle entry was patched") PY -find content/ -type f -exec cat {} \; | sha256sum | cut -d' ' -f1 > content-hash.txt +python3 - <<'PY' +import hashlib +from pathlib import Path + +paths = [] +for root in [ + Path("content"), + Path("pyodide-custom-recipes"), + Path("repl"), + Path("tskit-launcher/src"), + Path("tskit-launcher/style"), +]: + if root.exists(): + paths.extend(path for path in root.rglob("*") if path.is_file()) + +for path in [ + Path("build.sh"), + Path("build_pyodide_world.sh"), + Path("jupyter-lite.json"), + Path("requirements.txt"), + Path("tskit-launcher/package.json"), + Path("tskit-launcher/package-lock.json"), + Path("dist/jupyter-lite.json"), + Path("dist/static/pyodide/pyodide-lock.json"), + Path("dist/static/pyodide/pyodide.asm.mjs"), + Path("dist/static/pyodide/pyodide.asm.wasm"), + Path("dist/static/pyodide/python_stdlib.zip"), +]: + if path.exists(): + paths.append(path) + +pyodide_dir = Path("dist/static/pyodide") +if pyodide_dir.exists(): + paths.extend(pyodide_dir.glob("pyodide*.mjs")) + +digest = hashlib.sha256() +for path in sorted(set(paths)): + digest.update(path.as_posix().encode()) + digest.update(b"\0") + digest.update(path.read_bytes()) + digest.update(b"\0") + +Path("content-hash.txt").write_text(digest.hexdigest() + "\n") +PY HASH=$(cat content-hash.txt) echo "{\"contentHash\":\"$HASH\",\"lastUpdated\":\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\"}" > dist/lab/content-config.json diff --git a/content-hash.txt b/content-hash.txt index 617c1c4..53eee71 100644 --- a/content-hash.txt +++ b/content-hash.txt @@ -1 +1 @@ -8c5267c94cf95d2e4d7cb4f23f84b32ced8dfcbad49614942200e9679ddecb78 +5401e341378a031ff0d1bc35f51696710a091d23df4fa6592bb2ed4805641c21 diff --git a/tskit-launcher/src/index.ts b/tskit-launcher/src/index.ts index 80112ce..ce85df6 100644 --- a/tskit-launcher/src/index.ts +++ b/tskit-launcher/src/index.ts @@ -25,7 +25,7 @@ class CustomLauncher extends Widget implements ILauncher { private readonly STORAGE_KEY = 'tskit-launcher-content-hash'; private readonly AUTO_RESET_KEY = 'tskit-launcher-auto-reset-content-hash'; private readonly UI_STATE_VERSION_KEY = 'tskit-launcher-ui-state-version'; - private readonly UI_STATE_VERSION = 'pyodide-2026-0'; + private readonly UI_STATE_VERSION = 'pyodide-2026-0-native-import'; private readonly CONFIG_URL = './content-config.json'; constructor() { @@ -204,8 +204,7 @@ class CustomLauncher extends Widget implements ILauncher { sessionStorage.setItem(this.AUTO_RESET_KEY, resetMarker); - this.clearJupyterLiteLocalStorage(); - await this.deleteIndexedDBDatabases(['JupyterLite Storage']); + await this.clearJupyterLiteState(); this.storeCurrentHash(); localStorage.setItem(this.UI_STATE_VERSION_KEY, this.UI_STATE_VERSION); window.location.reload();