import { Activity, AlertTriangle, Archive, ArrowRight, Box, Braces, Check, CircleStop, CloudUpload, Cpu, Download, FileCode2, Package, Play, RadioTower, RefreshCw, RotateCcw, Search, Server, SquareTerminal, X, Zap, } from "lucide-react"; import { ReactNode, useState } from "react"; import { BackendCapability, BackendRuntime, BackendWitPackage, witPackageDownloadUrl, } from "../api"; import { EventTone, RuntimeEvent, Service, ServiceStatus, STATUS_META, formatDuration, serviceKey, } from "../console-model"; function PageHeading({ eyebrow, title, description, actions, }: { eyebrow: string; title: string; description: string; actions?: ReactNode; }) { return (
{eyebrow}

{title}

{description}

{actions &&
{actions}
}
); } export function Overview({ services, filteredServices, events, running, faulted, totalCalls, deploymentCount, runtime, selectedService, onSelect, onDeploy, onInvoke, onStatus, onActivate, onViewAll, onRefresh, onRuntimeAction, runtimeAction, deploymentAction, }: { services: Service[]; filteredServices: Service[]; events: RuntimeEvent[]; running: number; faulted: number; totalCalls: number; deploymentCount: number; runtime: BackendRuntime | null; selectedService: Service | null; onSelect: (service: Service) => void; onDeploy: () => void; onInvoke: (service: Service) => void; onStatus: (service: Service, status: ServiceStatus) => void; onActivate: (service: Service) => void; onViewAll: () => void; onRefresh: () => void; onRuntimeAction: (action: "start" | "stop" | "restart") => void; runtimeAction: "start" | "stop" | "restart" | null; deploymentAction: string | null; }) { const errorCount = services.reduce((sum, service) => sum + service.errors, 0); const latencies = services .map((service) => service.latencyMs) .filter((latency): latency is number => latency !== null); const latestLatency = latencies.length ? Math.max(...latencies) : null; return ( <> } />
} label="服务版本" value={services.length.toString()} note={`${deploymentCount} 个对外服务`} tone="cyan" /> } label="运行实例" value={running.toString()} note={`${services.length - running} 个未运行`} tone="green" /> } label="累计调用" value={totalCalls.toLocaleString("zh-CN")} note="持久化统计" tone="amber" /> } label="异常" value={(faulted + errorCount).toString()} note={faulted + errorCount ? "需要检查" : "无异常"} tone="coral" />
Wasmeld Runtime {runtime?.status === "running" ? "Engine 已启用 fuel 与 epoch interruption" : "Engine 与所有 Actor 已释放"}
{runtime?.status === "stopped" ? ( ) : ( <> )}

服务状态

已注册版本及当前 Actor 状态

{selectedService && (
当前选中 {selectedService.id} @{selectedService.revision}
{!selectedService.active && ( )}
)} ); } function Metric({ icon, label, value, note, tone, }: { icon: ReactNode; label: string; value: string; note: string; tone: string; }) { return (
{icon}
{label} {value}
{note}
); } function RuntimeStat({ label, value, detail }: { label: string; value: string; detail: string }) { return (
{label} {value} {detail}
); } function DetailValue({ label, value }: { label: string; value: string }) { return (
{label} {value}
); } function StatusBadge({ status }: { status: ServiceStatus }) { const meta = STATUS_META[status]; return ( {meta.label} ); } function CapabilitySummary({ capabilities }: { capabilities: BackendCapability[] }) { if (capabilities.length === 0) { return ; } const [first, ...remaining] = capabilities; return ( capability.interface).join("\n")} > {first.package}/{first.name} @{first.version} {remaining.length > 0 && +{remaining.length}} ); } function ServiceTable({ services, selectedKey, onSelect, onInvoke, onStatus, onActivate, canActivate, deploymentAction, compact = false, }: { services: Service[]; selectedKey?: string; onSelect: (service: Service) => void; onInvoke: (service: Service) => void; onStatus: (service: Service, status: ServiceStatus) => void; onActivate: (service: Service) => void; canActivate: boolean; deploymentAction: string | null; compact?: boolean; }) { if (services.length === 0) { return (
没有匹配的服务 调整搜索关键词或状态筛选。
); } return (
{!compact && } {!compact && } {services.map((service) => ( {!compact && } {!compact && ( )} ))}
服务 状态制品Host 能力调用 延迟 操作
{service.artifact} {service.calls.toLocaleString("zh-CN")} {service.latencyMs ? `${service.latencyMs} ms` : "—"}
{service.status === "running" ? ( <> ) : ( )}
); } function EventList({ events }: { events: RuntimeEvent[] }) { const icons: Record = { success: , warning: , danger: , neutral: , }; return (
{events.map((event) => (
{icons[event.tone]}
{event.title} {event.detail}
))}
); } export function ServicesView({ services, statusFilter, onFilter, onDeploy, onInvoke, onSelect, onStatus, onActivate, canActivate, deploymentAction, }: { services: Service[]; statusFilter: "all" | ServiceStatus; onFilter: (status: "all" | ServiceStatus) => void; onDeploy: () => void; onInvoke: (service: Service) => void; onSelect: (service: Service) => void; onStatus: (service: Service, status: ServiceStatus) => void; onActivate: (service: Service) => void; canActivate: boolean; deploymentAction: string | null; }) { return ( <> 注册组件 } />
{[ ["all", "全部"], ["running", "运行中"], ["stopped", "已停止"], ["faulted", "故障"], ].map(([value, label]) => ( ))}
{services.length} 个版本
); } export function WitPackagesView({ apiBase, packages, onPublish, }: { apiBase: string; packages: BackendWitPackage[]; onPublish: () => void; }) { function downloadPackage(packageMetadata: BackendWitPackage) { const anchor = document.createElement("a"); anchor.href = witPackageDownloadUrl(apiBase, packageMetadata); anchor.download = `${packageMetadata.name.replace(":", "-")}-${packageMetadata.version}.wasm`; document.body.append(anchor); anchor.click(); anchor.remove(); } return ( <> 发布 WIT 包 } />
发布后不可覆盖;包名、版本与依赖由制品自动解析。 {packages.length} 个包版本
{packages.length === 0 ? (
没有匹配的 WIT 包 发布二进制 WIT Package,或调整搜索关键词。
) : (
{packages.map((packageMetadata) => { const dependencies = packageMetadata.dependencies .map((dependency) => `${dependency.name}@${dependency.version}`) .join(", "); return ( ); })}
Package 依赖 SHA-256 操作
{packageMetadata.name} {packageMetadata.version}
{dependencies || "无直接依赖"} {packageMetadata.sha256}
)}
); } export function InstancesView({ services, onInvoke, onStatus, onRefresh, }: { services: Service[]; onInvoke: (service: Service) => void; onStatus: (service: Service, status: ServiceStatus) => void; onRefresh: () => void; }) { const instances = services.filter( (service) => service.status === "running" || service.status === "faulted", ); return ( <> } />
{instances.length === 0 ? (
暂无运行实例 0 ACTIVE ACTORS
) : ( instances.map((service) => (
{service.id}@{service.revision} actor/{service.id}-01
{service.updatedAt}
)) )}
); } export function ActivityView({ events, services, }: { events: RuntimeEvent[]; services: Service[]; }) { const calls = services.reduce((sum, service) => sum + service.calls, 0); const errors = services.reduce((sum, service) => sum + service.errors, 0); const latencies = services .map((service) => service.latencyMs) .filter((latency): latency is number => latency !== null); const averageLatency = latencies.length ? latencies.reduce((sum, latency) => sum + latency, 0) / latencies.length : null; function exportEvents() { const blob = new Blob([JSON.stringify(events, null, 2)], { type: "application/json", }); const url = URL.createObjectURL(blob); const anchor = document.createElement("a"); anchor.href = url; anchor.download = "wasmeld-events.json"; anchor.click(); URL.revokeObjectURL(url); } return ( <> 导出记录 } />
时间范围 当前进程
成功率 {calls ? `${(((calls - errors) / calls) * 100).toFixed(2)}%` : "—"}
平均延迟 {averageLatency === null ? "—" : `${averageLatency.toFixed(1)} ms`}
记录数 {events.length}
); } export function SettingsView({ endpoint, onSaveEndpoint, }: { endpoint: string; onSaveEndpoint: (value: string) => void; }) { const [value, setValue] = useState(endpoint); return ( <>
{ event.preventDefault(); onSaveEndpoint(value); }} >

控制端连接

管理 API 的本地访问地址。

setValue(event.target.value)} /> 连接状态将在顶部工具栏显示。
); }