Releases: fastmon-dev/beacon-inspector
Releases · fastmon-dev/beacon-inspector
Release list
Release 2026.7.9
Add - overlay auto-hide and click-to-dismiss
- The on-page overlay can now hide itself after a set time. A new "Auto-hide
after" select in the popup's Options section offers 3, 5, 10 or 20 seconds, or
"never" (the default, permanent - unchanged behaviour). The timer is armed the
first time the bar shows for a pageview; a soft navigation or new pageview
shows it again and restarts the countdown. Stored inchrome.storage.local
(fm_overlay_ttl) and applied live viastorage.onChanged, like the other
overlay options. - Click the overlay to dismiss it for the current pageview (the bar is now
click-through-disabled and shows a pointer cursor). A soft-nav / new pageview
brings it back. Changing an overlay option (toggle, position, timeout) also
undoes a prior auto-hide or click-dismissal so the change is visible at once.
Add - smoxy page-cache verdict (S-Cache) per pageview
- Documents served behind smoxy now show their page-cache verdict. The
DevTools network listener additionally captures the response headers of
documentrequests; whenS-Cacheis present (orServer: smoxy), the
verdict is stored keyed by document URL (host + path, query ignored - the
tracker strips queries fromu) and matched to pageviews by closest
navigation timestamp, so a reload keeps each pageview's own HIT/MISS. - Shown as a
smoxy HIT|MISS|…badge in the pageview list and an
S-Cache line in the detail head (withS-Cache-Reasonwhen present),
color-coded like the popup's cache statuses (HIT good · MISS poor ·
EXPIRED/STALE/REVALIDATED warn · BYPASS purple). On a HIT the cache
Agefollows in parens (HIT (5min)) - Age is only meaningful when
the object actually came from the cache, and like every header here it is
optional (absent header, no parens). Entirely optional overall: pages not
behind smoxy render exactly as before. Works for tracked and basic-RUM
fallback pageviews alike. - Opt-in. The whole smoxy feature sits behind a popup toggle ("smoxy
s-cache",chrome.storage.localkeyfm_smoxy, default off): it gates
the panel's DevTools capture and display, the service worker's webRequest
storage, and the overlay cell - applied live, and switching it off sweeps
every stored verdict. While a smoxy verdict is shown, the CDN cache
row/cell is suppressed in popup and overlay: smoxy IS the page cache in
front of the origin here, showing both would be redundant. The popup's
toggles (overlay + smoxy) now live in a collapsed "Options"<details>
section, keeping the popup compact until expanded; the UI labels the
header lower-case ("s-cache"). - Popup and on-page overlay show the verdict too - without DevTools open.
NewwebRequestpermission (+<all_urls>host permissions, no new install
warning beyond the existing all-sites one): the service worker observes the
top-level document response and keeps onlyServer/S-Cache/
S-Cache-Reason/Ageper tab (doc:<tabId>in session storage; a
non-smoxy document clears the entry, tab close reclaims it). The popup adds
a "smoxy page cache" row to its cache section; the overlay (tap-relay.js)
pulls the verdict from the SW at document_start (__fmDocGet, with retries
for the async write) and renders asmoxy HIT (5min)|MISScell next to
CDN/Origin - the overlay now also appears on smoxy pages without fastmon.
Bodies are never read on this path; PRIVACY.md documents the header
observation. - Overlay polish. The vitals cells are always rendered (
n/auntil
measured) so the bar keeps a stable width instead of jumping as values pop
in. Basic-RUM fallback snapshots now feed the overlay too (display-only
__fm_rum__event from rum-tap.js; the records still reach the service
worker exactly once), so TTFB/LCP/CLS fill in on pages without fastmon. The
"fastmon" brand text is gone; instead the fastmon logo appears - and
ONLY when a real collector beacon proved fastmon runs on the page, so the
logo doubles as the "fastmon detected" indicator (RUM-fallback/smoxy-only
overlays carry no branding). The asset is the white logo mark without the
dark tile (logos/logo-dark.svg minus its background rect) - the tiled icon
read as a dark blob on the dark overlay bar - inlined as an SVG data URI:
chrome.runtime.getURL()would requireweb_accessible_resources, which
lets any page probe for the extension.
Add - overlay position option
- The on-page overlay's corner is now configurable: top-left, top-right,
bottom-right (default), or bottom-left, via a select in the popup's Options
section (chrome.storage.localkeyfm_overlay_pos). tap-relay.js applies
the corner live throughstorage.onChanged- no reload needed. Invalid
stored values fall back to bottom-right.
Fix - "Unchecked runtime.lastError: No tab with id: …"
- Fire-and-forget
chrome.runtime.sendMessagecalls in tap-relay.js and
rum-tap.js now pass a callback that readsruntime.lastError(marking it
checked). Without one, Chrome logs the error whenever the implicit response
cannot be delivered back to the sending tab - which happens routinely,
because the terminal beacon/snapshot fires duringpagehideand the tab is
gone a moment later. The service worker's__fmDocGetsendResponseis
guarded the same way (the asking document can vanish while the storage read
is in flight). chrome.action.setIcon/setTitleswitched from promise+.catchto the
callback form readinglastError- the promise variant still produced
"Unchecked runtime.lastError" logs on some Chrome versions when the tab id
was already gone. And tap-relay's smoxy pull no longer messages from
prerendered documents (it waits forprerenderingchange): discarded
prerenders were a steady source of vanishing synthetic tab ids.- Note: "Uncaught (in promise) TypeError: Failed to fetch" entries in the
extension error list are the PAGE's own failed fetches, attributed to us
because tap-main.js wrapswindow.fetch- known and deliberately not
silenced (see 2026.7.6 / 2026.7.7).
Add - basic-RUM fallback for pages without the fastmon snippet
- Pages without a fastmon snippet now show basic RUM data plus Server-Timing
instead of an empty panel. A new ISOLATED-world content script
(rum-tap.js) measures a minimal picture straight from the browser's
Performance APIs - navigation timing (TTFB/DNS/TCP/response/DOM-interactive/
load/transfer size/protocol/nav type), FCP/first-paint, LCP, session-window
CLS, a web-vitals-style INP estimate, connection info, and the navigation
entry's Server-Timing - and ships snapshots through the same
service-worker path as real beacons. Snapshots are shaped like collector
beacons (same wire keys, syntheticrum-…pvid, lifecycle
init → loaded → update → hidden → terminated), so vitals scorecards, the
field table, charts, compare, and overview render them unchanged. - Fallback pageviews are clearly marked: a
basic RUMbadge in the list and
a hint banner in the detail explain that the values are measured locally
by the inspector, not by tracker beacons. The popup shows the same fallback
summary (CWV + cache status + Server-Timing) with a matching hint; the
toolbar icon stays gray (it still signals "fastmon active" only). - Real beacons always win: fastmon presence is detected via the in-page
tap's event, collection stops immediately, and if fallback snapshots were
already emitted, a one-shot rum-drop retracts the fallback pageview and
popup summary. As a belt-and-braces, the panel also drops a still-open
fallback pageview when a real beacon for the same document arrives via the
network path (e.g. the pixel fallback). - Everything stays local (
chrome.storage.session); PRIVACY.md documents the
Performance-API read. Tests cover ingest, merge, banner/badge, supersede, and
the rum-drop retraction.
Release 2026.7.8
Add - localized store listing (EN/DE)
- The extension name, store summary, and toolbar tooltip are now localized in
English and German via_localesand manifest__MSG__placeholders, with
enas the default locale. This lets the Chrome Web Store serve the listing
(name + short description) in the user's language and unlocks per-language
detailed descriptions in the dashboard. The runtime UI keeps its own bundled
catalog (i18n.js); the two are independent. The toolbar tooltip now follows
the browser language viachrome.i18n.getMessage. Both the local
npm run buildand the release zips include_locales.
Release 2026.7.7
Revert
- Drop the no-op
.catchadded to thefetchwrapper in 2026.7.6. It only
silenced bare fire-and-forget rejections; for the commonawait/.then
patterns the rejection propagates to a promise in the page's own code that the
wrapper cannot reach, so it did not remove the "Failed to fetch" console
entries and only suppressed fire-and-forget warnings page-wide. The wrapper is
a transparent passthrough again: a page's own failed fetch is the page's, and
we only appear in its stack because we wrapfetch.
Release 2026.7.6
Fix - do not surface page fetch failures as extension errors
- The MAIN-world
fetchwrapper now attaches a no-op rejection handler to the
promise it returns, so a page's fire-and-forgetfetchthat fails no longer
logs an "Uncaught (in promise)" pinned ontap-main.js. Handlers on a promise
are independent, so the page's own.then/.catchare unaffected. Note: this
silences unhandled fire-and-forget fetch-rejection warnings page-wide (the
failed request is still visible in the Network panel).
Release 2026.7.5
Change
- The DevTools panel tab is now just "fastmon" (was "fastmon Beacons").
- Keep
package.jsonversionin sync with the manifest (both2026.7.5); it
had been left at0.1.0.
Release 2026.7.4
Add - JS error hint in the popup and overlay
- When the page's beacons report JS errors (
errc), it is now flagged: the
popup shows a red "N JS error(s) on this page" line, and the on-page overlay
adds a redERR Ncell. Nothing is shown when the page is error-free.
Add - per-browser unpacked builds (Firefox)
npm run buildemits clean per-browser builds underbuild/:build/chrome
(MV3 service worker) andbuild/firefox(event-page background), plus a loadable
.zipfor each. Firefox does not run an MV3 background service worker, so it
cannot load the Chrome-targeted committed manifest directly; load
build/firefox/manifest.json(or the zip) viaabout:debugging. The committed
manifest stays Chrome-clean; the release ships the same per-browser zips. The
build has no dependencies (own stored-zip writer). Documented in both READMEs.
Release 2026.7.3
Add - toolbar icon state, value popup, and optional on-page overlay
- The toolbar icon reflects fastmon activity per tab, no DevTools needed:
grayed out on pages with no fastmon beacons, full-color where a beacon fired,
reset on navigation. Uses the collector beacons the in-page tap already
relays, so no new permissions. - Clicking the icon opens an overview popup of the current page: Core Web
Vitals (LCP and CLS always shown, INP/FCP/TTFB when present, rated by the
web.dev thresholds), CDN/origin cache status derived from Server-Timing, the
Server-Timing phase durations, and a link to app.fastmon.eu. It reads a small
per-tab summary the service worker keeps, so it works even while the DevTools
panel is draining beacons. - Optional on-page overlay (off by default, toggled from the popup): a flat
bottom-right chip showing TTFB / LCP / CLS plus CDN/origin cache status, live.
INP is omitted because it only finalises late (on hidden/navigate). - Cache-status colors: HIT green, MISS red, BYPASS purple, EXPIRED/STALE
amber.
Fix
- Swallow the async "No tab with id" rejection from
chrome.action.setIcon/
setTitlewhen a tab closes between the triggering event and the icon update.
Release 2026.7.2
Add - German localization (EN/DE) with a language selector
- The whole UI is now localized in English and German. Toolbar, status,
hints, overview, charts, and all field labels and group titles are translated;
Core Web Vitals names and lifecycle wire values stay canonical. German terms
follow the dashboard's wording. - A toolbar language selector (Auto / English / Deutsch) lets you override
the language, stored inlocalStorage. Auto follows the browser language. This
is needed because the DevTools UI language is not exposed to extensions, so a
self-managed catalog (i18n.js, both locales bundled) replaceschrome.i18n/
_locales, which could only follow the browser. - The DevTools panel tab is now titled "fastmon Beacons".
Add - toolbar icon popup
- Clicking the extension's toolbar icon opens a small popup that points to
the panel ("Open DevTools (F12), then the fastmon Beacons tab"), localized
EN/DE. Extensions cannot open DevTools programmatically, so this is a guide,
not a shortcut. Adds anactionwith a tooltip andpopup.html.
Fix - manifest background and per-browser packaging
- Drop
background.scriptsfrom the committed manifest so Chrome no longer
warns "'background.scripts' requires manifest version of 2 or lower". Chrome
uses the MV3service_worker. - The release workflow now builds two zips,
beacon-inspector-chrome-*and
beacon-inspector-firefox-*. The Firefox manifest is rewritten to an
event-page background (background.scripts), since Firefox does not run MV3
background service workers.
Release 2026.7.1
Add — first public release
- DevTools panel (Chrome/Chromium/Edge ≥116, Firefox ≥128) that
live-captures the inspected page's fastmon collector beacons, groups them by
pageview (pvid), and shows how the data evolves across beacon versions
and lifecycle states (init→loaded→hidden/frozen/terminated/
softnav/*_update). - Reliable terminal-beacon capture. Terminal beacons are sent via
navigator.sendBeacon, whose body neither the DevTools/HAR API nor
chrome.webRequestexposes forpingrequests. A MAIN-world content script
wrapssendBeaconin the page, relays each payload to the service worker via
a synchronousCustomEvent, and the SW parks it inchrome.storage.session
(keyed by tab id) for the panel to drain — so the closing beacon is no longer
lost and pageviews finalise instead of stalling atloaded/live. - Merged-state-first view. The detail pane shows the current merged state by
default; a "show versions" toggle expands the per-beacon-version diff
(yellow = changed vs. the previous version). Core Web Vitals are rated
good / needs-improvement / poor by the web.dev thresholds. - Session overview dashboard, compare mode, soft-navigation
detection, inline charts (lifecycle timeline, navigation waterfall, vitals
subparts), a field search, and Markdown export (raw or anonymised for
pasting into an AI assistant). - Wire-contract drift guard (
tests/decode-map.test.js) that checks the
decode map against the collector'sCompactBeaconmodel when the backend
source is available (FASTMON_COLLECTOR_PY), and skips gracefully otherwise.