Main now has #1282, which pauses periodic layer polling in a hidden page
with its own catch-up and listener cleanup, so this PR drops its duplicate
lifecycle.js change and test in favor of main's.
Review fixes:
- data.js passes panelAwareVisibility(document) (new in app/embed.js) as
the lifecycle's visibility target, so an inline panel whose host reports
it hidden keeps polling. The HUD's 250 ms readout follows the same
document.hidden && !isEmbeddedInline() rule as tools.js.
- Tests: embed.test.mjs (layers poll in an inline panel reported hidden,
pause without the flag) and hudPageVisibility.test.mjs (HUD readout).
Both use mock timers and clean up in finally.
- changelog.d/1344-inline-panel-visibility.md and a note in
docs/CURRENT-STATE.md.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Knip, configured with the application, package exports, scripts, QA
harnesses, workers, tools and tests as entry points, reports exports
that no module imports. Each was checked by hand against string-based
and namespace imports.
- Symbols that are still used inside their own module lose only the
`export` keyword (176 constants and helpers).
- Unused re-exports are removed from barrel modules (flight, military,
vessel, CCTV, directions, transit history, local ADS-B and street-level
policy modules).
- Declarations that nothing uses at all are deleted, among them
AIS_WATCHDOG_STATUSES, applyFilter, isRadioCountryCode, compactText,
DENSITY_STOPS, the unused CCTV endpoint constants, and the SDR band
constants.
- Default exports that nothing imports are removed. The ones in
src/data/earthquakes.js, src/data/telegeographySubmarineCables.js,
src/data/wind.js and src/data/bhoteKoshiLocator.js each constructed a
layer instance at import time that nothing used; those instances are
no longer created.
Every export of a package.json entry stays, as does TOMTOM_CREDIT,
which the traffic layer reads from the credits namespace it is given.
Embed-mode documents now keep the server's framing protection unless
GEV_EMBED_FRAME_ANCESTORS names the pages that may frame them (or * for any
page). The MCP Apps panel loads the app into its own page and needs no
framing. View answers are posted to the origin that sent the view rather
than to any origin.
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
A view's follow may ask for cockpit view, which the app enters after it
follows the aircraft; links cannot carry it and open the app following.
Applying a view no longer flies the camera when the followed entity is
already there, since the flight ended the follow; it flies only while
waiting for the entity. The panel applies its first view again only
when it asks for cockpit view.
Drop the render restarts added while chasing the black overlays; keep
the full render-error report and stop the timer after an error, as
Cesium does. Correct comments the investigation outran, share the
panel_request name, and document the host differences the panel works
around.
Cesium stops drawing after a render error and prints worker failures as
[object Object]. An inline panel now logs the error's details and starts
drawing again, up to three times.
Claude reports a panel on screen as hidden, which stopped the app's
render loop and the browser's animation frames, so no map was drawn. An
inline panel no longer suspends rendering when hidden, and draws from a
timer while animation frames stop arriving.
Hosts such as Claude do not let a panel frame other sites, so the panel
now loads the app's page, styles and scripts into itself in inline embed
mode, and declares the app and map providers as resource and connect
domains. The dev server answers panel origins with CORS.
?embed=1 shows the globe alone: clean view with the HUD, panels, welcome and
setup prompts hidden, and provider attribution kept. The page that frames it
sends views with postMessage; the app applies each through its own actions
and reports every step. Annotations in any link are drawn once it restores.
Only embed-mode documents may be framed; every other page keeps
X-Frame-Options DENY and frame-ancestors 'none', and
GEV_EMBED_FRAME_ANCESTORS can restrict who frames them.