tricu

An interpreted language for exploring Tree Calculus
Log | Files | Refs | README | LICENSE

bundle-assets.py (2316B)


      1 #!/usr/bin/env python3
      2 """Bundle production entrypoints while preserving their import.meta.url bases."""
      3 import argparse
      4 import json
      5 from pathlib import Path
      6 import shutil
      7 import subprocess
      8 
      9 ENTRIES = ['dist/app.js', 'dist/wasm-worker.js', 'dist/local-module-worker.js',
     10            'dist/zig-helpers.js', 'runtime/zig/site-session.mjs',
     11            'runtime/haskell/client.mjs', 'runtime/haskell/worker.mjs']
     12 
     13 
     14 def bundle(root, probe):
     15     root = root.resolve()
     16     support = root / 'nix-support'
     17     support.mkdir(exist_ok=True)
     18     shutil.copyfile(root / 'runtime/haskell/pins.mjs', support / 'haskell-pins.mjs')
     19     shutil.copyfile(probe, root / 'dist/probe-api.js')
     20     graphs = {}
     21     for entry in [*ENTRIES, 'dist/probe-api.js']:
     22         output = 'bundled/' + entry
     23         subprocess.run(['esbuild', entry, '--bundle', '--format=esm',
     24                         '--platform=browser', '--target=es2020',
     25                         '--legal-comments=inline', '--outfile=' + output,
     26                         '--metafile=graph.json'], cwd=root, check=True)
     27         graph = json.loads((root / 'graph.json').read_text())
     28         # Computed URL imports retain explicit lazy runtime boundaries. All
     29         # statically resolved imports must be contained in their entrypoint.
     30         assert all(not row['imports'] for row in graph['outputs'].values())
     31         graphs[entry] = graph
     32     (support / 'bundle-graphs.json').write_text(json.dumps(graphs, indent=2) + '\n')
     33     (root / 'graph.json').unlink()
     34     for name in ['dist', 'runtime']:
     35         for path in (root / name).rglob('*'):
     36             if path.suffix in ['.js', '.mjs']:
     37                 path.unlink()
     38     for entry in ENTRIES:
     39         shutil.move(root / 'bundled' / entry, root / entry)
     40     shutil.move(root / 'bundled/dist/probe-api.js', support / 'probe-api.js')
     41     shutil.rmtree(root / 'bundled')
     42     # Empty module directories would otherwise imply unshipped entrypoints.
     43     for path in sorted((root / 'runtime').rglob('*'), reverse=True):
     44         if path.is_dir() and not any(path.iterdir()):
     45             path.rmdir()
     46 
     47 
     48 if __name__ == '__main__':
     49     parser = argparse.ArgumentParser(description=__doc__)
     50     parser.add_argument('root', type=Path)
     51     parser.add_argument('probe', type=Path)
     52     args = parser.parse_args()
     53     bundle(args.root, args.probe)