UNPKG

@playcanvas/splat-transform

Version:

Library and CLI tool for 3D Gaussian splat format conversion and transformation

271 lines (270 loc) 10.6 kB
/** * Verbosity level controlling which messages reach the renderer. * * - `quiet` - errors and warnings only. * - `normal` - tasks, bars, info, warn, error (default). * - `verbose` - normal + debug messages. */ type Verbosity = 'quiet' | 'normal' | 'verbose'; /** Severity tag for free-form messages (ordered descending by severity). */ type MessageKind = 'error' | 'warn' | 'info' | 'debug'; /** * Semantic event delivered to a {@link Renderer}. Renderers can filter, format * and display these as they wish. * * `scopeStart` / `scopeEnd` represent the open/close of a {@link Group}. * They carry optional `index` / `total` fields when the scope is part of a * numbered series, which renderers can use to switch to a `[N/T] name` style. * * `barStart` / `barTick` / `barEnd` represent a determinate progress bar. * The bar's `name` is repeated on every event so the renderer can keep its * label stable across in-place updates while tracking progress via `current` * and `total`. * * `output` is the pipeable channel: each event represents a single logical * unit of output (typically one line - or a multi-line block treated as a * unit) that the renderer is expected to terminate with a newline. Callers * should not include a trailing `\n` themselves. */ type LogEvent = { kind: 'scopeStart'; depth: number; name: string; index?: number; total?: number; } | { kind: 'scopeEnd'; depth: number; name: string; durationMs: number; failed?: boolean; index?: number; total?: number; } | { kind: 'barStart'; depth: number; name: string; total: number; } | { kind: 'barTick'; depth: number; name: string; current: number; total: number; } | { kind: 'barEnd'; depth: number; name: string; durationMs: number; current: number; total: number; failed?: boolean; } | { kind: 'message'; depth: number; level: MessageKind; text: string; } | { kind: 'output'; text: string; }; /** * Renderer interface. Receives the full stream of semantic lifecycle * events ({@link LogEvent}) and decides how to display them. The core * does not filter scope/bar events by verbosity, so renderers see a * faithful record of every scope open/close and bar progress update - * embedders consuming the event stream can rely on this for progress * UIs that must close themselves on completion. Visibility decisions * (e.g. hiding successful `scopeEnd` footers at non-`verbose` * verbosity) are the renderer's responsibility; {@link logger.getVerbosity} * is available to consult. * * `message` events for `info`, `warn` and `debug` are gated by verbosity * at the façade (see {@link LoggerCore.isLevelVisible}) before reaching * the renderer; `error` is always delivered. */ interface Renderer { /** * Handle a log event. * @param event - The event to render. */ handle(event: LogEvent): void; } /** * Determinate progress bar handle. Closed explicitly via `end()`, or * implicitly when an enclosing {@link Group}'s `end()` (or a * {@link Logger.unwindAll}) pops it as part of cleanup. * * Carries a `[Symbol.dispose]` slot directly (rather than extending the * built-in `Disposable` lib type) so the published `.d.ts` stays free of * any reference to the `Disposable` interface. `Symbol.dispose` itself is * still a TS 5.2+ / `esnext.disposable` (or `es2024.disposable`) lib * symbol, so consumers compiling against these declarations need that * lib enabled (or `skipLibCheck: true`). Callers on TS 5.2+ / Node 20+ * can adopt `using bar = logger.bar(...)` because `using` only requires * the `[Symbol.dispose]` shape structurally. */ interface Bar { /** * Advance the bar by `n` ticks. * @param n - Number of ticks to advance (default 1). */ tick(n?: number): void; /** * Set the bar's absolute progress. Clamped to `[0, total]`. Suppresses * a `barTick` event when the value is unchanged. * @param current - Absolute progress value. */ update(current: number): void; /** * Close the bar and emit final timing. */ end(): void; /** Dispose hook so `using` syntax closes the bar on scope exit. */ [Symbol.dispose](): void; } /** * Named, timed scope returned from {@link Logger.group}. Manages the scope's * lifecycle only - free-form messages, nested groups and bars are emitted via * the global `logger` (they auto-indent under whatever is on top of the * active-scope stack). * * Open scopes with `logger.group(name)` and close them with `sub.end()` after * the body. Embedders that catch their own exceptions (rather than letting * them propagate to a `logger.error()` call) should call * {@link Logger.unwindAll} from their catch to close any scopes/bars left * dangling on the stack. * * Carries a `[Symbol.dispose]` slot directly (rather than extending the * built-in `Disposable` lib type) so the published `.d.ts` stays free of * any reference to the `Disposable` interface. `Symbol.dispose` itself is * still a TS 5.2+ / `esnext.disposable` (or `es2024.disposable`) lib * symbol, so consumers compiling against these declarations need that * lib enabled (or `skipLibCheck: true`). Callers on TS 5.2+ / Node 20+ * can adopt `using g = logger.group(...)` because `using` only requires * the `[Symbol.dispose]` shape structurally. */ interface Group { /** * Close the group, popping anything still open above it on the stack * (defensively handles forgotten inner scopes) and emit the timing event. */ end(): void; /** Dispose hook so `using` syntax closes the group on scope exit. */ [Symbol.dispose](): void; } declare const verbosityRank: Record<Verbosity, number>; /** * Public logger surface. * * Open named, timed scopes with {@link Logger.group}. Pass `{ index, total }` * to render the group as part of a numbered series. Indeterminate progress is * reported with {@link Logger.bar}. Free-form messages route through `info` / * `warn` / `error` / `debug`, indented under whatever is on top of the * active-scope stack. * * Both `group` and `bar` are pure-push operations: opening a new scope simply * places it on top of the stack without auto-closing siblings, so call order * directly determines nesting. Close scopes with `handle.end()` after the * body. Callers that route failures through {@link Logger.error} get scope * cleanup for free; embedders that swallow exceptions should call * {@link Logger.unwindAll} from their catch to close every still-open scope. */ declare const logger: { /** * Open a named, timed scope. Returns a {@link Group} handle. Call `end()` * to close it. Group children indent automatically based on call depth. * * Pass `{ index, total }` to render the group as part of a numbered * series (e.g. `[2/5] name`). Both fields must be supplied together. * * @param name - The group name. * @param options - Optional configuration. * @param options.index - 1-based position in the numbered series. * @param options.total - Total length of the numbered series. * @returns A handle for closing the group and writing nested log entries. */ group(name: string, options?: { index?: number; total?: number; }): Group; /** * Open a labelled progress bar nested directly under whatever scope is * currently on top of the active-scope stack. Renders as a single line * at child indent. * * Like {@link Logger.group}, this is a pure-push operation: it does not * close any sibling already on the stack. Close with `bar.end()`, or let * an enclosing group's `end()` / {@link Logger.unwindAll} pop it. * * @param name - The bar's label. * @param total - Expected number of ticks (or absolute total when using * {@link Bar.update}). * @returns A handle for advancing and closing the bar. */ bar(name: string, total: number): Bar; /** * Emit an info message indented under the innermost active scope. * @param args - Message parts (joined with a space). */ info(...args: any[]): void; /** * Emit a warning indented under the innermost active scope. * @param args - Message parts. */ warn(...args: any[]): void; /** * Emit an error message. Always shown, regardless of verbosity. Triggers * an automatic unwind of all open scopes, marking each as failed. * @param args - Message parts. */ error(...args: any[]): void; /** * Emit a debug message. Shown only at `verbose` verbosity. * @param args - Message parts. */ debug(...args: any[]): void; /** * Emit a logical unit of pipeable output (typically one line, or a * multi-line block treated as a single unit). The renderer terminates * each unit with a newline, so callers should not include a trailing * `\n`. Always shown, regardless of verbosity. * @param text - The text to emit (without a trailing newline). */ output(text: string): void; /** * Replace the active renderer. Embedders install their own renderer here * to consume `LogEvent`s; the default renderer is a no-op. Renderers * receive every scope/bar lifecycle event regardless of verbosity, so * progress UIs can rely on `scopeStart`/`scopeEnd` and `barStart`/`barEnd` * to manage their state. * @param r - The renderer to install. */ setRenderer(r: Renderer): void; /** * Set verbosity: `quiet` (errors and warnings), `normal` (default), * `verbose` (includes debug). * @param v - The verbosity level. */ setVerbosity(v: Verbosity): void; /** * Close every open scope and bar, optionally marking them as failed. * Use this from an embedder's catch when an exception is being swallowed * (rather than rethrown into a `logger.error()` call), to prevent * dangling scopes from corrupting subsequent output. * @param failed - When true, mark every closed scope as having failed. */ unwindAll(failed?: boolean): void; /** * Get the current verbosity level. * @returns The active verbosity level. */ getVerbosity(): Verbosity; }; /** * Public type alias for the logger object. Embedders can type-hint against * this to inject a configured logger. */ type Logger = typeof logger; export { logger, verbosityRank }; export type { Bar, Group, LogEvent, Logger, MessageKind, Renderer, Verbosity };