Architecture
IIFE Build and Registration
The widget is built as an IIFE bundle via Vite/Rollup: see
vite.config.lib.ts.Library entry:
src/index.tsFormat:
iifeOutput file:
dist/index.iife.jsReact is externalised and exposed via globals (
React,ReactDOM).
During initialization,
src/index.tsregisters the widget definition with the global Octopus host:It uses
makeWidgetDefto create the widget descriptor, then callsO.registerWidget(...).A small IIFE polls
globalThis.Octopusto register as soon as the frontend host is available.
This packaging allows octopus-frontend to load the widget bundle directly and have it auto-register at runtime.
Runtime Data Flow
The clock face remains client-driven:
src/ClockWidget.tsxmaintains asetIntervalloop that refreshes once per second.For IANA timezone entries, date/time formatting uses
Intl.DateTimeFormat.For sidereal entries (
LST,LST@<longitude>), local sidereal time is computed in-widget from UTC time and longitude.To enrich IANA cards with sunrise/sunset, the widget issues two GraphQL queries (using the Octopus host Apollo client):
locationsByTimezoneresolves configured IANA timezones to location records containing latitude/longitude.For each resolvable IANA zone,
solarCycleis queried with{ latitude, longitude, timezone, date }to fetch sunrise/sunset (dawn/dusk available for future use).
The location map and solar responses are cached in-memory per instance. A polling cadence derived from the dashboard refresh rate keeps the solar data fresh without spamming the backend.
Solar timestamps are normalised to
HH:mmlocal time before rendering, avoiding confusion when upstream APIs omit offsets.Sidereal (
LST) cards do not render sunrise/sunset chips because those are solar events, not sidereal ones.
Importing in octopus-frontend
Publish the package (or otherwise make
dist/index.iife.jsavailable) and include it in the frontend.When the script runs, it auto-registers the widget with the Octopus host; no explicit bootstrapping is needed beyond loading the bundle.