/******************************************************************************** * Copyright (c) 2026 CrossBreeze, EclipseSource and others. * * This program and the accompanying materials are made available under the * terms of the MIT License which is available in the project root. * * SPDX-License-Identifier: MIT ********************************************************************************/ import { type DataServerDiagnosticsProtocol, type HostDiagnosticsProtocol, type StartProfilingArgs } from '@hydranium/protocol'; import { CommandContribution, MessageService, type Command, type CommandRegistry } from '@theia/core'; import { type interfaces } from '@theia/core/shared/inversify'; import { OutputChannelManager, type OutputChannel } from '@theia/output/lib/browser/output-channel'; /** * Per-product branding for {@link MemoryDiagnosticsContribution}. Bound by the * adopter so the command ids, palette category, and output channel carry the * product name. The framework supplies the behaviour; only these strings vary. */ export interface MemoryDiagnosticsOptions { /** Prefix for the registered command ids: `.dumpServerState`. */ readonly commandIdPrefix: string; /** Command-palette category. */ readonly category: string; /** Output channel the full snapshots are appended to (View > Output). */ readonly channelName: string; } export declare const MemoryDiagnosticsOptions: unique symbol; /** * The server-process diagnostics the commands call. Equals * {@link DataServerDiagnosticsProtocol} (`dumpServerState` / `writeHeapSnapshot` * / `dumpPodMemory`); the adopter binds its data-server frontend proxy (which * exposes those methods after connecting) to this symbol. Kept as a distinct * symbol so the contribution stays decoupled from any concrete frontend type. */ export type MemoryDiagnosticsService = DataServerDiagnosticsProtocol; export declare const MemoryDiagnosticsService: unique symbol; /** * Optional host (parent) process diagnostics — the Theia backend itself, reached * by an ordinary in-process RPC service ({@link HostDiagnosticsProtocol}), NOT * the data-server socket. When bound, the contribution adds the "Dump Backend * State" and "Write Heap Snapshot (Backend)" commands; left unbound, those two * commands are simply not registered. `@hydranium/data-client-theia`'s * `bindHostDiagnostics` binds the frontend proxy. */ export type HostMemoryDiagnosticsService = HostDiagnosticsProtocol; export declare const HostMemoryDiagnosticsService: unique symbol; /** * What a `report` call captured, as a code rather than a prose fragment. The * sentences it appears in are authored once per code, because a fragment * substituted into a sentence is itself translatable text and a translator * given the sentence alone cannot inflect around a hole. */ export type DiagnosticsSubject = 'server-state' | 'pod-memory' | 'latency' | 'backend-state' | 'profile'; /** Which process a heap snapshot is taken of; a code, for the reason {@link DiagnosticsSubject} is one. */ export type HeapSnapshotTarget = 'server' | 'backend'; /** * Memory-diagnostics commands, one per layer reachable from the frontend. Full * multi-line snapshots are appended to the configured output channel; a one-line * summary is toasted. * - "Dump Server State" - the data-server process (heap/rss/event-loop/CPU/documents), via RPC. * - "Dump Pod Memory" - cgroup current/peak/limit + process-tree RSS (the figure that OOMs a pod), via RPC. * - "Dump Frontend State" - the browser tab's JS heap (Chrome `performance.memory`), client-side. * - "Write Heap Snapshot" - a V8 heap snapshot of the data-server process, via RPC. * - "Start/Stop Profiling" - a windowed CPU/allocation/GC/event-loop sampled profile of the data-server, via RPC. * - "Record Performance Profile" - the same, wrapped over a fixed window (start, wait, stop, report). * - "Dump RPC/LSP Latency" - per-method latency/throughput collected on the server, via RPC. * * Generic: the adopter binds {@link MemoryDiagnosticsOptions} (branding) and * {@link MemoryDiagnosticsService} (its connected data-server frontend) and adds * this class as a `CommandContribution` — see {@link bindMemoryDiagnostics}. */ export declare class MemoryDiagnosticsContribution implements CommandContribution { protected readonly diagnostics: MemoryDiagnosticsService; protected readonly options: MemoryDiagnosticsOptions; protected readonly messageService: MessageService; protected readonly channels: OutputChannelManager; protected readonly hostDiagnostics?: HostMemoryDiagnosticsService; /** Dimensions the profiling commands capture — the server samples only what is named. */ protected readonly profileDimensions: StartProfilingArgs; /** Window length for the "Record Performance Profile" command. */ protected readonly recordDurationMs: number; /** * Label of the stop-profiling command, and of the action its start toast * offers. One field for both: two literals naming one command can be * localized apart, leaving a button or an instruction that names a command * the user cannot find. */ protected readonly stopProfilingLabel: string; registerCommands(registry: CommandRegistry): void; /** * Takes an object rather than positional arguments so that `label` — the one * user-facing member — is addressable by name. A lint rule guarding the * localization of labels has only syntax to work with, and a selector for an * argument position would equally catch `id`, which must stay a bare literal. */ protected command(spec: { id: string; label: string; category: string; }): Command; /** The record window as whole seconds, for the label and the toast that must agree on it. */ protected recordDurationSeconds(): number; /** Run a snapshot call, append the full result to the channel, toast the first matching summary line. */ protected report(subject: DiagnosticsSubject, produce: () => Promise, summaryKeys: string[]): Promise; protected writeSnapshot(target: HeapSnapshotTarget, produce: (label: string) => Promise): Promise; /** Begin an open-ended capture; the toast's stop action ends it and reports. */ protected startProfiling(): Promise; /** End the capture and report it. Shared, so the toast action and the command cannot diverge in behaviour. */ protected stopProfiling(): Promise; /** One authored sentence for both start paths; identical literals in two places drift apart under translation. */ protected startProfilingFailedMessage(detail: string): string; /** Capture a fixed-length window: start, wait, stop, and report the result. */ protected recordProfile(): Promise; /** Isolated so tests can drive the record window without a real timer. */ protected delay(ms: number): Promise; protected dumpFrontendState(): Promise; protected channel(): OutputChannel; /** Pull the first line starting with one of `keys` for a one-line toast; full text is in the channel. */ protected summarize(snapshot: string, subject: DiagnosticsSubject, keys: string[]): string; /** * The captured-with-detail toast. The detail is a machine-formatted figure, * so it is safe as a substitution parameter; the subject is not, hence one * authored sentence per subject. */ protected capturedDetailMessage(subject: DiagnosticsSubject, detail: string): string; /** The captured-without-detail toast; the channel name is adopter branding, not translatable text. */ protected capturedChannelMessage(subject: DiagnosticsSubject): string; /** The failed-to-dump toast; the detail is a technical error string, safe as a parameter. */ protected dumpFailedMessage(subject: DiagnosticsSubject, detail: string): string; protected writingSnapshotMessage(target: HeapSnapshotTarget): string; protected wroteSnapshotMessage(target: HeapSnapshotTarget, filePath: string): string; protected writeSnapshotFailedMessage(target: HeapSnapshotTarget, detail: string): string; protected errorMessage(error: unknown): string; } /** * Bind {@link MemoryDiagnosticsContribution} as a `CommandContribution` with the * given branding. The adopter still binds {@link MemoryDiagnosticsService} to its * connected data-server frontend separately (the framework cannot — the concrete * frontend is adopter-defined). Call from a Theia frontend `ContainerModule`. */ export declare function bindMemoryDiagnostics(bind: interfaces.Bind, options: MemoryDiagnosticsOptions): void; //# sourceMappingURL=memory-diagnostics-contribution.d.ts.map