/** * Devtools Event Types * * These types represent the telemetry data captured from the Convex sync protocol */ export type JSONValue = null | boolean | number | string | JSONValue[] | { [key: string]: JSONValue; }; export interface TraceEvent { name: string; atMs: number; attributes?: Record; } export interface TraceSpan { id: string; parentId: string | null; name: string; kind: string; startMs: number; endMs: number; durationMs: number; status: "ok" | "error"; attributes?: Record; events?: TraceEvent[]; } export interface UdfTrace { version: number; requestId?: string; rootSpanId: string; generatedAtMs: number; spans: TraceSpan[]; summary: { spanCount: number; eventCount: number; totalDurationMs: number; }; } export type EventType = "query" | "mutation" | "action" | "subscription" | "log" | "auth"; export type EventStatus = "pending" | "success" | "error"; export type SubscriptionStatus = "added" | "updated" | "removed"; /** * Base event interface */ export interface BaseEvent { id: string; timestamp: number; type: EventType; } /** * Query execution event (captured from AddQuery + QueryUpdated/QueryFailed) */ export interface QueryEvent extends BaseEvent { type: "query"; queryId: number; udfPath: string; args: JSONValue[]; componentPath?: string; status: EventStatus; result?: JSONValue; error?: string; logLines?: string[]; /** * Backend/network round-trip time measured when the WS frame is received. */ duration?: number; /** * Simulated client-side delivery delay applied by devtools latency settings. */ simulatedDelayMs?: number; /** * End-to-end perceived latency = duration + simulatedDelayMs. */ endToEndDurationMs?: number; /** ID of the mutation that likely triggered this query update */ triggeredBy?: string; trace?: UdfTrace; } /** * Mutation execution event (captured from MutationRequest + MutationResponse) */ export interface MutationEvent extends BaseEvent { type: "mutation"; requestId: number; udfPath: string; args: JSONValue[]; componentPath?: string; status: EventStatus; result?: JSONValue; error?: string; logLines?: string[]; /** * Backend/network round-trip time measured when the WS frame is received. */ duration?: number; /** * Simulated client-side delivery delay applied by devtools latency settings. */ simulatedDelayMs?: number; /** * End-to-end perceived latency = duration + simulatedDelayMs. */ endToEndDurationMs?: number; trace?: UdfTrace; } /** * Action execution event (captured from ActionRequest + ActionResponse) */ export interface ActionEvent extends BaseEvent { type: "action"; requestId: number; udfPath: string; args: JSONValue[]; componentPath?: string; status: EventStatus; result?: JSONValue; error?: string; logLines?: string[]; /** * Backend/network round-trip time measured when the WS frame is received. */ duration?: number; /** * Simulated client-side delivery delay applied by devtools latency settings. */ simulatedDelayMs?: number; /** * End-to-end perceived latency = duration + simulatedDelayMs. */ endToEndDurationMs?: number; trace?: UdfTrace; } /** * Subscription event (captured from ModifyQuerySet) */ export interface SubscriptionEvent extends BaseEvent { type: "subscription"; queryId: number; udfPath: string; args: JSONValue[]; componentPath?: string; status: SubscriptionStatus; updateCount?: number; } /** * Log event (extracted from logLines in responses) */ export interface LogEvent extends BaseEvent { type: "log"; level: "log" | "info" | "warn" | "error"; message: string; relatedEventId?: string; } /** * Authentication protocol event (Connect / Authenticate / AuthError / Authenticated) */ export interface AuthEvent extends BaseEvent { type: "auth"; direction: "client" | "server"; messageType: string; status: EventStatus; tokenType?: string; error?: string; details?: JSONValue; } export type DevToolsEvent = QueryEvent | MutationEvent | ActionEvent | SubscriptionEvent | LogEvent | AuthEvent; /** * Active subscription tracking */ export interface ActiveSubscription { queryId: number; udfPath: string; args: JSONValue[]; componentPath?: string; addedAt: number; updateCount: number; lastUpdate: number; currentValue?: JSONValue; previousValue?: JSONValue; status: "active" | "error"; error?: string; } /** * Performance metrics */ export interface PerformanceMetrics { totalQueries: number; totalMutations: number; totalActions: number; avgQueryDuration: number; avgMutationDuration: number; avgActionDuration: number; p50QueryDuration: number; p50MutationDuration: number; p50ActionDuration: number; p90QueryDuration: number; p90MutationDuration: number; p90ActionDuration: number; p95QueryDuration: number; p95MutationDuration: number; p95ActionDuration: number; p99QueryDuration: number; p99MutationDuration: number; p99ActionDuration: number; slowestOperations: Array<{ type: "query" | "mutation" | "action"; eventId: string; udfPath: string; duration: number; timestamp: number; }>; }