@molecule/app-status-dashboard-http
Provider bond · status-dashboard · App (browser) · v1.0.2 · Apache-2.0
HTTP status dashboard provider
npm install @molecule/app-status-dashboard-httpnpm · Source on GitHub · Implements @molecule/app-status-dashboard
How it works
@molecule/app-status-dashboard-http is a provider bond on the app (browser) side: it implements the status-dashboard core interface (@molecule/app-status-dashboard) with a concrete vendor or library behind it.
Your code calls the core; you wire this provider once at startup. Swapping vendors later is one line in that wiring, not a rewrite.
import { setProvider } from '@molecule/app-status-dashboard'
import { createProvider } from '@molecule/app-status-dashboard-http'
setProvider(createProvider({ baseUrl: '/api' }))
// Now GET /api/status, /api/status/incidents?status=&limit=,
// /api/status/uptime?serviceId= back the dashboard.Works with: @molecule/app-i18n
Reference
HTTP status dashboard provider for molecule.dev.
Implements StatusDashboardProvider from @molecule/app-status-dashboard by
fetching status data from the backend over plain HTTP, with automatic polling.
Pairs with @molecule/api-resource-status-page, which serves the expected
endpoints: GET /status, GET /status/incidents, and GET /status/uptime.
Auto-generated, AI-first package reference for the molecule.dev ecosystem. It is written to be read by coding agents as much as by people, and is generated from this package's source — edit
src/index.tsJSDoc, not this file.
Quick Start
import { setProvider } from '@molecule/app-status-dashboard'
import { createProvider } from '@molecule/app-status-dashboard-http'
setProvider(createProvider({ baseUrl: '/api' }))
// Now GET /api/status, /api/status/incidents?status=&limit=,
// /api/status/uptime?serviceId= back the dashboard.
Type
provider
Installation
npm install @molecule/app-status-dashboard-http @molecule/app-i18n @molecule/app-status-dashboard
API
Interfaces
HttpStatusDashboardConfig
Configuration for http status dashboard provider.
interface HttpStatusDashboardConfig {
/** Base URL for API requests. Defaults to '' (same origin). */
baseUrl?: string
/** Custom headers to include in requests. */
headers?: Record<string, string>
}
Classes
HttpStatusDashboardProvider
HTTP-based implementation of StatusDashboardProvider. Fetches system status,
incidents, and uptime data from backend API endpoints via standard HTTP requests.
class HttpStatusDashboardProvider implements StatusDashboardProvider {
readonly name = 'http'
private config: HttpStatusDashboardConfig
private pollingTimers: Set<ReturnType<typeof setInterval>> = new Set()
constructor(config: HttpStatusDashboardConfig = {}) {
this.config = config
}
/**
* Fetches the current system status from the API.
* @param config - Status dashboard configuration including API base URL and headers.
* @returns The current system status including services and active incidents.
*/
async fetchStatus(config: StatusDashboardConfig): Promise<SystemStatus> {
const url = `${config.apiBaseUrl ?? this.config.baseUrl ?? ''}/status`
const response = await fetch(url, { headers: { ...this.config.headers, ...config.headers } })
if (!response.ok) {
throw new Error(
t(
'statusDashboard.error.fetchFailed',
{ status: response.status },
{
defaultValue: 'Failed to fetch status: HTTP {{status}}',
},
),
)
}
return (await response.json()) as SystemStatus
}
/**
* Fetches recent incidents from the API with optional filtering.
* @param config - Status dashboard configuration including API base URL and headers.
* @param options - Optional filters for incident status and result limit.
* @param options.status - Filter incidents by status.
* @param options.limit - Maximum number of incidents to return.
* @returns An array of status incidents, or an empty array if the request fails.
*/
async fetchIncidents(
config: StatusDashboardConfig,
options?: { status?: IncidentStatus; limit?: number },
): Promise<StatusIncident[]> {
const params = new URLSearchParams()
if (options?.status) params.set('status', options.status)
if (options?.limit) params.set('limit', String(options.limit))
const qs = params.toString()
const url = `${config.apiBaseUrl ?? this.config.baseUrl ?? ''}/status/incidents${qs ? `?${qs}` : ''}`
const response = await fetch(url, { headers: { ...this.config.headers, ...config.headers } })
if (!response.ok) return []
const data = (await response.json()) as { incidents?: StatusIncident[] }
return data.incidents ?? []
}
/**
* Fetches uptime data for all services or a specific service.
* @param config - Status dashboard configuration including API base URL and headers.
* @param serviceId - Optional service ID to filter uptime data.
* @returns An array of service uptime records, or an empty array if the request fails.
*/
async fetchUptime(config: StatusDashboardConfig, serviceId?: string): Promise<ServiceUptime[]> {
const params = new URLSearchParams()
if (serviceId) params.set('serviceId', serviceId)
const qs = params.toString()
const url = `${config.apiBaseUrl ?? this.config.baseUrl ?? ''}/status/uptime${qs ? `?${qs}` : ''}`
const response = await fetch(url, { headers: { ...this.config.headers, ...config.headers } })
if (!response.ok) return []
const data = (await response.json()) as { uptime?: ServiceUptime[] }
return data.uptime ?? []
}
/**
* Starts polling for status updates at the configured interval.
* Fetches immediately and then at regular intervals.
* @param config - Status dashboard configuration including poll interval.
* @param onUpdate - Callback invoked with the latest system status on each successful poll.
* @returns A stop function that cancels this polling subscription.
*/
startPolling(
config: StatusDashboardConfig,
onUpdate: (status: SystemStatus) => void,
): () => void {
const intervalMs = config.pollIntervalMs ?? 30000
const timer = setInterval(async () => {
try {
const status = await this.fetchStatus(config)
onUpdate(status)
} catch (_error) {
// Best-effort poll — network blips are transient; the next interval will retry.
}
}, intervalMs)
this.pollingTimers.add(timer)
// Fetch immediately
this.fetchStatus(config)
.then(onUpdate)
.catch((_error) => {
// Best-effort immediate fetch — the polling interval will retry shortly.
})
return () => {
clearInterval(timer)
this.pollingTimers.delete(timer)
}
}
/**
* Stops all active polling timers.
*/
stopPolling(): void {
for (const timer of this.pollingTimers) {
clearInterval(timer)
}
this.pollingTimers.clear()
}
}
Functions
createProvider(config)
Creates an HttpStatusDashboardProvider instance with optional configuration.
function createProvider(config?: HttpStatusDashboardConfig): HttpStatusDashboardProvider
config— HTTP-specific status dashboard configuration (base URL, headers).
Returns: An HttpStatusDashboardProvider that communicates with the backend via HTTP.
Constants
provider
Pre-instantiated provider singleton.
const provider: HttpStatusDashboardProvider
Core Interface
Implements @molecule/app-status-dashboard interface.
Bond Wiring
Setup function to register this provider with the core interface:
import { setProvider } from '@molecule/app-status-dashboard'
import { provider } from '@molecule/app-status-dashboard-http'
export function setupStatusDashboardHttp(): void {
setProvider(provider)
}
Injection Notes
Requirements
Peer dependencies:
@molecule/app-status-dashboard^1.0.1@molecule/app-i18n^1.0.1
Runtime Dependencies
-
@molecule/app-i18n -
@molecule/app-status-dashboard -
The backend must serve the three endpoints (
/status,/status/incidents,/status/uptime) relative tobaseUrl— responses areSystemStatus,{ incidents: StatusIncident[] }, and{ uptime: ServiceUptime[] }respectively.@molecule/api-resource-status-pageprovides them. -
Error semantics differ per method:
fetchStatus()throws on non-2xx;fetchIncidents()/fetchUptime()return[]on ANY failure — an empty incidents list can mean "endpoint missing", not "all clear". Verify/statusworks first. -
Polling defaults to every 30 s (
pollIntervalMs), fetches immediately, and swallows per-tick errors (next tick retries). Keep the stop function returned bystartPolling()and call it on unmount;stopPolling()cancels everything. -
Per-call
config.apiBaseUrl/headersoverride/merge over the constructor'sbaseUrl/headers.
E2E Tests
Integration checklist — drive the real status page in the live preview (no mocks), adapt each item to this app's actual screens, and check every box off one by one. A box you can't check is an integration bug to fix — not a skip:
- Every monitored service returned by
fetchStatusrenders as its own tile/row showing the service name and a status indicator, grouped bygroupNamewhen present — no service silently missing from the page. - Each status indicator reflects that service's real
ServiceStatus: anoperationalservice shows the up/green treatment,downshows the down/red treatment, anddegraded/unknowneach show their own distinct state — never one uniform color regardless of status. - The overall system-status banner is DERIVED from the tiles, not
hardcoded: with all services operational it reads operational; flip one
service to
downin the data and the banner flips to down/degraded on the next fetch — it never stays green while a tile is red. - Metric values render as real numbers with units — service latency as
e.g.
142 msand eachUptimeWindowas a percentage (e.g.99.98%) for the selected window (1h/24h/7d/30d/90d) — not0,NaN, or a placeholder. - Active incidents render with title, severity, and status; when there are none the page shows an all-clear/empty state, not a blank or broken incidents area.
- Polling updates the tiles without a manual reload: with
startPollingrunning, change the underlying status and confirm the affected tile AND the overall banner update on the next poll; navigating away calls the returned stop function so polls don't pile up. - Loading and failure are observable: a loading indicator shows while
fetchStatusis in flight, and a fetch error surfaces a visible message (fromstate.error) — never a blank page or a stale dashboard shown as fresh.