@justai/cuts 0.2.0 → 0.3.1

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/Base.astro +36 -5
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@justai/cuts",
3
- "version": "0.2.0",
3
+ "version": "0.3.1",
4
4
  "description": "A persona's named parts \u2014 the page shell that holds them, and the cuts themselves.",
5
5
  "license": "UNLICENSED",
6
6
  "repository": {
package/src/Base.astro CHANGED
@@ -6,7 +6,13 @@
6
6
  * of which 132 were IDENTICAL. The 22 that differed were all identity — the host, the theme colour,
7
7
  * the favicon, the analytics property — plus two real ones, both preserved here as contract rather
8
8
  * than flattened: --on-accent (cleanmylink and howlong have light accents where white text fails
9
- * contrast) and a head slot (time self-hosts Geist).
9
+ * contrast) and the DEV service-worker kill, which came from the one persona that had it.
10
+ *
11
+ * NO head slot, and the docstring claimed one for a while before anyone checked. time self-hosts
12
+ * Geist through `import "@fontsource-variable/geist"` in its OWN layout frontmatter — a build-time
13
+ * CSS import that Astro bundles, not a tag that needs injecting here. The claim was removed rather
14
+ * than the slot added: building a feature to make a comment true is the wrong direction, and an
15
+ * unused extension point is the thing that rots.
10
16
  *
11
17
  * WHAT IT DELIBERATELY DOES NOT OWN.
12
18
  *
@@ -127,9 +133,26 @@ const localePath = (l: string) => (l === defaultLocale ? "/" : `/${l}/`);
127
133
  <!-- PWA: Workbox service worker (precache + offline) + installable manifest -->
128
134
  <link rel="manifest" href="/manifest.webmanifest" />
129
135
  <link rel="apple-touch-icon" href="/icon-192.png" />
130
- <script is:inline>
131
- if ("serviceWorker" in navigator) addEventListener("load", () => navigator.serviceWorker.register("/sw.js"));
132
- </script>
136
+ {import.meta.env.DEV ? (
137
+ <script is:inline>
138
+ {/* DEV: no service worker. Kill any stale one — from an earlier prod or preview build — and
139
+ purge its caches, so a local edit is never masked by something a previous build cached.
140
+ If a SW currently controls the page, reload once (guarded by sessionStorage so it cannot
141
+ loop) to get a clean, uncontrolled load.
142
+
143
+ This came from `time`, which was the only persona that had it. It is in the package
144
+ rather than behind a prop because a stale service worker hiding your own changes is not
145
+ a preference — the other ten had the bug and had simply not noticed it yet. Migration
146
+ found it; the fleet's best version wins over the fleet's most common one. */}
147
+ if ("serviceWorker" in navigator) navigator.serviceWorker.getRegistrations().then((rs) => rs.forEach((r) => r.unregister()));
148
+ if (window.caches) caches.keys().then((ks) => ks.forEach((k) => caches.delete(k)));
149
+ if (navigator.serviceWorker && navigator.serviceWorker.controller && !sessionStorage.getItem("__swkill")) { sessionStorage.setItem("__swkill", "1"); location.reload(); }
150
+ </script>
151
+ ) : (
152
+ <script is:inline>
153
+ if ("serviceWorker" in navigator) addEventListener("load", () => navigator.serviceWorker.register("/sw.js"));
154
+ </script>
155
+ )}
133
156
  <!-- Google Analytics 4 — anonymous (ad signals + personalization OFF), lazy-loaded after idle.
134
157
  analytics_storage granted: direct user counting (cookieless modeling needs high traffic to
135
158
  surface, so it shows nothing at low/launch volume).
@@ -146,7 +169,15 @@ const localePath = (l: string) => (l === defaultLocale ? "/" : `/${l}/`);
146
169
  // EEA + UK + CH: deny analytics until the visitor consents (the banner below grants it).
147
170
  gtag("consent", "default", { region: ["AT","BE","BG","HR","CY","CZ","DK","EE","FI","FR","DE","GR","HU","IE","IT","LV","LT","LU","MT","NL","PL","PT","RO","SK","SI","ES","SE","IS","LI","NO","GB","CH"], ad_storage: "denied", ad_user_data: "denied", ad_personalization: "denied", analytics_storage: "denied" });
148
171
  try { var cc0 = localStorage.getItem("consent"); if (cc0) gtag("consent", "update", { analytics_storage: cc0 }); } catch (e) {}
149
- gtag("config", gaId, { cookie_expires: 60 * 60 * 24 * 60, /* two months — matches the GA data retention; the cookie must not outlive the data it labels (foundations/15) */ allow_google_signals: false, allow_ad_personalization_signals: false });
172
+ // page_title is PINNED to the title as it is at load, before anything can touch it. Only one
173
+ // persona mutates document.title today — time shows a live clock in the tab — and without this
174
+ // its analytics reports "13:32 · Amsterdam" as the page name instead of the page. For every
175
+ // other persona it captures the same string the title already has, so it costs nothing and
176
+ // removes a trap the next persona that animates its tab would otherwise walk into.
177
+ //
178
+ // Found by migration: it existed only in time, and the extraction dropped it silently. Nothing
179
+ // errored — the analytics would simply have been wrong from that day on.
180
+ gtag("config", gaId, { cookie_expires: 60 * 60 * 24 * 60, page_title: document.title, /* two months — matches the GA data retention; the cookie must not outlive the data it labels (foundations/15) */ allow_google_signals: false, allow_ad_personalization_signals: false });
150
181
  addEventListener("load", function () {
151
182
  (window.requestIdleCallback || function (f) { setTimeout(f, 1200); })(function () {
152
183
  var s = document.createElement("script");