import type { Metadata } from "next"; import Link from "next/link"; import { EventRow } from "@/components/event-row"; import { BreakingRail } from "@/components/rail"; import { Empty, PageHeader, Panel, Sparkline, Stat } from "@/components/ui"; import { api } from "@/lib/api"; import { fmtInt, GROUP_LABELS, relTime, CHANNELS } from "@/lib/format"; export const dynamic = "force-dynamic"; export const metadata: Metadata = { title: "Pulse", description: "What is changing on the Internet right now: global activity, breaking events, fastest-rising entities, cyber incidents, AI developments, market and government events, infrastructure incidents, silent changes." }; /** Real-time summary of the Internet (spec §39). */ export default async function PulsePage() { const p = await api.pulse(); if (!p) return Pulse is warming up.; const activity = p.activity ?? []; const evSeries = activity.map((a) => Number(a.events)); const chSeries = activity.map((a) => Number(a.changes)); const groups = Object.entries(p.by_group_24h ?? {}).sort((a, b) => b[1] - a[1]); const maxG = Math.max(1, ...groups.map(([, n]) => n)); const deskLabel = (d: string): string => CHANNELS.find((c) => c.key === d)?.label ?? d; return ( <>
c.state === "breaking").length} / ${p.breaking.filter((c) => c.state === "developing").length}`} tone="hot" />
Events
Raw changes

The gap between raw changes and events is the noise WebSensor filtered out: timestamps, navigation churn, cookie banners, advertising, cosmetic edits.

{(p.desks ?? []).filter((d) => d.items.length).map((d) => ( desk →}> {d.items.map((e) => ( ))} ))}
live →}> {p.infrastructure.length ? p.infrastructure.map((e) => ) : No outage, incident or maintenance signal in the last 6 h.} all →}> {p.silent_changes.length ? p.silent_changes.map((e) => ) : No silent change in the last 24 h.}
); }