withcache 0.5.0__tar.gz → 0.5.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: withcache
3
- Version: 0.5.0
3
+ Version: 0.5.1
4
4
  Summary: Operator-curated, URL-keyed artifact cache for a small lab (CUDA/ROCm/DOCA/firmware)
5
5
  Project-URL: Homepage, https://github.com/safl/withcache
6
6
  Author-email: "Simon A. F. Lund" <safl@safl.dk>
@@ -2,7 +2,7 @@
2
2
  .name = .withcache_shim,
3
3
  // Zig requires a literal here; keep it in lockstep with the project's
4
4
  // single source (src/withcache/__init__.py) via `make bump` / `make version-check`.
5
- .version = "0.5.0",
5
+ .version = "0.5.1",
6
6
  .fingerprint = 0xd7d96c5ed212ccaa,
7
7
  .minimum_zig_version = "0.16.0",
8
8
  .paths = .{
@@ -12,6 +12,6 @@ All modules are stdlib-only and self-contained.
12
12
 
13
13
  from .client import blob_url, cache_base, is_cached, serve_url
14
14
 
15
- __version__ = "0.5.0"
15
+ __version__ = "0.5.1"
16
16
 
17
17
  __all__ = ["__version__", "blob_url", "cache_base", "is_cached", "serve_url"]
@@ -1011,6 +1011,42 @@ class Handler(http.server.BaseHTTPRequestHandler):
1011
1011
  hx-swap="innerHTML">
1012
1012
  {self.render_dash()}
1013
1013
  </div>
1014
+
1015
+ <!-- Tab activation. Applies an ``active-tab`` class to the
1016
+ ``section.tab`` whose id matches the URL hash (defaulting to
1017
+ the first section when no hash is set) and to the
1018
+ corresponding ``nav.tabs a``. Runs on initial load, on every
1019
+ click into a tab link (so the operator gets immediate
1020
+ feedback before the next htmx tick), and on every
1021
+ ``htmx:afterSettle`` so the class survives the 1 Hz
1022
+ innerHTML replacement of ``#dash``. Without this the
1023
+ previous ``:target``-based CSS would snap the operator back
1024
+ to the first tab within a second of any click. -->
1025
+ <script>
1026
+ (function () {{
1027
+ function applyActiveTab() {{
1028
+ var hash = (window.location.hash || '').replace(/^#/, '');
1029
+ var sections = document.querySelectorAll('#dash section.tab');
1030
+ if (!sections.length) return;
1031
+ var ids = Array.prototype.map.call(sections, function (s) {{ return s.id; }});
1032
+ if (ids.indexOf(hash) === -1) hash = ids[0];
1033
+ sections.forEach(function (s) {{
1034
+ s.classList.toggle('active-tab', s.id === hash);
1035
+ }});
1036
+ document.querySelectorAll('#dash nav.tabs a').forEach(function (a) {{
1037
+ var target = (a.getAttribute('href') || '').replace(/^#/, '');
1038
+ a.classList.toggle('active-tab', target === hash);
1039
+ }});
1040
+ }}
1041
+ window.addEventListener('hashchange', applyActiveTab);
1042
+ document.body.addEventListener('htmx:afterSettle', applyActiveTab);
1043
+ document.addEventListener('click', function (ev) {{
1044
+ var a = ev.target.closest && ev.target.closest('#dash nav.tabs a');
1045
+ if (a) setTimeout(applyActiveTab, 0);
1046
+ }});
1047
+ applyActiveTab();
1048
+ }})();
1049
+ </script>
1014
1050
  </main></body></html>"""
1015
1051
 
1016
1052
  def render_dash(self) -> str:
@@ -1024,13 +1060,20 @@ class Handler(http.server.BaseHTTPRequestHandler):
1024
1060
  used += f" / {human_size(self.store.max_bytes)}"
1025
1061
  full = "" if self.store.has_capacity() else " &middot; <strong>cache full</strong>"
1026
1062
 
1027
- # Tabs are pure-CSS via :target. The URL hash names the active
1028
- # section; htmx innerHTML-replacement of #dash leaves the hash
1029
- # alone, so the operator's tab choice survives every refresh.
1030
- # ``body:not(:has(section:target))`` selects the default tab
1031
- # when no hash is present; :has() lands cleanly on Chrome 105+,
1032
- # Firefox 121+, Safari 15.4+, which is the whole modern web by
1033
- # the time this ships in 2026.
1063
+ # Tabs are driven by an ``active-tab`` class applied to one
1064
+ # ``section.tab`` (and matching ``nav.tabs a``). A tiny script
1065
+ # at the bottom of the dash watches the URL hash, the htmx
1066
+ # post-swap event, and click events on the tab links so the
1067
+ # class survives every 1 Hz innerHTML replacement.
1068
+ #
1069
+ # An earlier pure-CSS attempt used ``:target`` + ``:has()``.
1070
+ # That works on a static page, but when htmx swaps the
1071
+ # ``#dash`` innerHTML each second the freshly-inserted
1072
+ # ``section.tab`` elements do not always get re-matched by
1073
+ # ``:target`` (the browser keeps the URL hash but the
1074
+ # newly-inserted node is not the one ``:target`` resolved to
1075
+ # at hash-change time). The visible symptom was the tab
1076
+ # snapping back to Streams within a second of every click.
1034
1077
  tab_style = """
1035
1078
  <style>
1036
1079
  nav.tabs { margin: 1rem 0 .25rem; border-bottom: 1px solid var(--pico-muted-border-color); }
@@ -1042,22 +1085,13 @@ class Handler(http.server.BaseHTTPRequestHandler):
1042
1085
  margin-bottom: -1px; font-size: .9rem;
1043
1086
  }
1044
1087
  nav.tabs a:hover { color: var(--pico-color); }
1045
- section.tab { display: none; padding-top: .75rem; }
1046
- section.tab:target { display: block; }
1047
- body:not(:has(section.tab:target)) section.tab#tab-streams { display: block; }
1048
- body:has(#tab-streams:target) nav.tabs a[href="#tab-streams"],
1049
- body:has(#tab-downloads:target) nav.tabs a[href="#tab-downloads"],
1050
- body:has(#tab-misses:target) nav.tabs a[href="#tab-misses"],
1051
- body:has(#tab-cached:target) nav.tabs a[href="#tab-cached"] {
1052
- color: var(--pico-color);
1053
- border-bottom-color: var(--pico-primary, #0172ad);
1054
- font-weight: 600;
1055
- }
1056
- body:not(:has(section.tab:target)) nav.tabs a[href="#tab-streams"] {
1088
+ nav.tabs a.active-tab {
1057
1089
  color: var(--pico-color);
1058
1090
  border-bottom-color: var(--pico-primary, #0172ad);
1059
1091
  font-weight: 600;
1060
1092
  }
1093
+ section.tab { display: none; padding-top: .75rem; }
1094
+ section.tab.active-tab { display: block; }
1061
1095
  </style>
1062
1096
  """
1063
1097
 
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes