/**
* Small shared UI primitives for the inspector: JSON dump, badges, buttons,
* relative time. Deliberately minimal — this is an internal devtool.
*/
import { useState } from 'react';
export function JsonView({ data, empty }: { data: unknown; empty?: string }) {
const [open, setOpen] = useState(false);
if (data === undefined || data === null) {
return
{empty ?? 'no data'}
;
}
const text = JSON.stringify(data, null, 2);
const long = text.length > 500;
return (
long && setOpen((v) => !v)}
title={long ? 'click to expand / collapse' : undefined}
>
{long && !open ? `${text.slice(0, 500)}\n… (${text.length} chars, click to expand)` : text}
);
}
export function Badge({
children,
tone = 'neutral',
}: {
children: React.ReactNode;
tone?: 'neutral' | 'green' | 'amber' | 'red' | 'sky' | 'violet';
}) {
const tones: Record = {
neutral: 'bg-neutral-800 text-neutral-300',
green: 'bg-emerald-900/60 text-emerald-300',
amber: 'bg-amber-900/60 text-amber-300',
red: 'bg-red-900/60 text-red-300',
sky: 'bg-sky-900/60 text-sky-300',
violet: 'bg-violet-900/60 text-violet-300',
};
return (
{children}
);
}
export function ActionButton({
children,
onClick,
danger,
disabled,
}: {
children: React.ReactNode;
onClick: () => void | Promise;
danger?: boolean;
disabled?: boolean;
}) {
return (
);
}
export function relTime(epochMs: number | undefined): string {
if (epochMs === undefined) return '';
const diff = Date.now() - epochMs;
if (diff < 60_000) return `${Math.max(0, Math.round(diff / 1000))}s ago`;
if (diff < 3_600_000) return `${Math.round(diff / 60_000)}m ago`;
if (diff < 86_400_000) return `${Math.round(diff / 3_600_000)}h ago`;
return new Date(epochMs).toLocaleDateString();
}
/** Render an unknown thrown value as display text (never "[object Object]"). */
export function errorMessage(error: unknown): string {
if (error instanceof Error) return error.message;
if (typeof error === 'string') return error;
if (error === null || typeof error !== 'object') return String(error);
return JSON.stringify(error) ?? 'unknown error';
}
export function ErrorLine({ error }: { error: unknown }) {
if (error === null || error === undefined) return null;
const msg = errorMessage(error);
return {msg}
;
}