Skip to content

Releases: fastmon-dev/beacon-inspector

Release 2026.7.9

Choose a tag to compare

@github-actions github-actions released this 21 Jul 20:12
2026.7.9
eb2564f

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 in chrome.storage.local
    (fm_overlay_ttl) and applied live via storage.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
    document requests; when S-Cache is present (or Server: smoxy), the
    verdict is stored keyed by document URL (host + path, query ignored - the
    tracker strips queries from u) 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 (with S-Cache-Reason when present),
    color-coded like the popup's cache statuses (HIT good · MISS poor ·
    EXPIRED/STALE/REVALIDATED warn · BYPASS purple). On a HIT the cache
    Age follows 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.local key fm_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.
    New webRequest permission (+ <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 only Server / S-Cache /
    S-Cache-Reason / Age per 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 a smoxy HIT (5min)|MISS cell 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/a until
    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 require web_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.local key fm_overlay_pos). tap-relay.js applies
    the corner live through storage.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.sendMessage calls in tap-relay.js and
    rum-tap.js now pass a callback that reads runtime.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 during pagehide and the tab is
    gone a moment later. The service worker's __fmDocGet sendResponse is
    guarded the same way (the asking document can vanish while the storage read
    is in flight).
  • chrome.action.setIcon/setTitle switched from promise+.catch to the
    callback form reading lastError - 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 for prerenderingchange): 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 wraps window.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, synthetic rum-… 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 RUM badge 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

Choose a tag to compare

@github-actions github-actions released this 17 Jul 15:03
2026.7.8
da0ef98

Add - localized store listing (EN/DE)

  • The extension name, store summary, and toolbar tooltip are now localized in
    English and German
    via _locales and manifest __MSG__ placeholders, with
    en as 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 via chrome.i18n.getMessage. Both the local
    npm run build and the release zips include _locales.

Release 2026.7.7

Choose a tag to compare

@github-actions github-actions released this 17 Jul 13:16
2026.7.7
4022980

Revert

  • Drop the no-op .catch added to the fetch wrapper in 2026.7.6. It only
    silenced bare fire-and-forget rejections; for the common await / .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 wrap fetch.

Release 2026.7.6

Choose a tag to compare

@github-actions github-actions released this 17 Jul 13:04
2026.7.6
8edea32

Fix - do not surface page fetch failures as extension errors

  • The MAIN-world fetch wrapper now attaches a no-op rejection handler to the
    promise it returns
    , so a page's fire-and-forget fetch that fails no longer
    logs an "Uncaught (in promise)" pinned on tap-main.js. Handlers on a promise
    are independent, so the page's own .then/.catch are 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

Choose a tag to compare

@github-actions github-actions released this 17 Jul 12:33
2026.7.5
a80a9ef

Change

  • The DevTools panel tab is now just "fastmon" (was "fastmon Beacons").
  • Keep package.json version in sync with the manifest (both 2026.7.5); it
    had been left at 0.1.0.

Release 2026.7.4

Choose a tag to compare

@github-actions github-actions released this 17 Jul 12:24
2026.7.4
a4d7cff

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 red ERR N cell. Nothing is shown when the page is error-free.

Add - per-browser unpacked builds (Firefox)

  • npm run build emits clean per-browser builds under build/: build/chrome
    (MV3 service worker) and build/firefox (event-page background), plus a loadable
    .zip for 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) via about: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

Choose a tag to compare

@github-actions github-actions released this 17 Jul 11:55
2026.7.3
6a389e7

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 /
    setTitle when a tab closes between the triggering event and the icon update.

Release 2026.7.2

Choose a tag to compare

@github-actions github-actions released this 17 Jul 10:54
2026.7.2
2288afd

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 in localStorage. 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) replaces chrome.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 an action with a tooltip and popup.html.

Fix - manifest background and per-browser packaging

  • Drop background.scripts from the committed manifest so Chrome no longer
    warns "'background.scripts' requires manifest version of 2 or lower". Chrome
    uses the MV3 service_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

Choose a tag to compare

@github-actions github-actions released this 17 Jul 09:08
2026.7.1
4ecd5f9

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 (initloadedhidden/frozen/terminated /
    softnav / *_update).
  • Reliable terminal-beacon capture. Terminal beacons are sent via
    navigator.sendBeacon, whose body neither the DevTools/HAR API nor
    chrome.webRequest exposes for ping requests. A MAIN-world content script
    wraps sendBeacon in the page, relays each payload to the service worker via
    a synchronous CustomEvent, and the SW parks it in chrome.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 at loaded / 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's CompactBeacon model when the backend
    source is available (FASTMON_COLLECTOR_PY), and skips gracefully otherwise.