npm package: @ricsam/quickjs-console
Description: Console API implementation for QuickJS runtime
Author: Richard Samuelsson
Latest version: 0.2.18

# @ricsam/quickjs-console

Console API with logging, timing, counting, and grouping for QuickJS.

> **Note**: This is a low-level package. For most use cases, use [`@ricsam/quickjs-runtime`](../runtime) with `createRuntime()` instead.

## Installation

```bash
bun add @ricsam/quickjs-console
```

## Setup

Uses a single `onEntry` callback that receives structured `ConsoleEntry` objects:

```typescript
import { setupConsole, type ConsoleEntry } from "@ricsam/quickjs-console";

const handle = setupConsole(context, {
  onEntry: (entry: ConsoleEntry) => {
    switch (entry.type) {
      case "output":
        console.log(`[${entry.level}]`, ...entry.args);
        break;
      case "time":
        console.log(`${entry.label}: ${entry.duration}ms`);
        break;
      case "count":
        console.log(`${entry.label}: ${entry.count}`);
        break;
      case "group":
        console.group(entry.label);
        break;
      case "groupEnd":
        console.groupEnd();
        break;
      // ... handle other entry types
    }
  },
});

// Access console state
handle.getTimers();    // Map<string, number> - active timers
handle.getCounters();  // Map<string, number> - counter values
handle.getGroupDepth(); // number - current nesting level
handle.reset();        // Clear all state
```

## Simple Console Handler

For basic use cases where you just want to route output to console methods:

```typescript
import { setupConsole, simpleConsoleHandler } from "@ricsam/quickjs-console";

const handle = setupConsole(
  context,
  simpleConsoleHandler({
    log: (...args) => console.log("[sandbox]", ...args),
    warn: (...args) => console.warn("[sandbox]", ...args),
    error: (...args) => console.error("[sandbox]", ...args),
    info: (...args) => console.info("[sandbox]", ...args),
    debug: (...args) => console.debug("[sandbox]", ...args),
  })
);
```

## Injected Globals

- `console.log`, `console.warn`, `console.error`, `console.debug`, `console.info`
- `console.trace`, `console.dir`, `console.table`
- `console.time`, `console.timeEnd`, `console.timeLog`
- `console.count`, `console.countReset`
- `console.group`, `console.groupCollapsed`, `console.groupEnd`
- `console.assert`, `console.clear`

## Usage in QuickJS

```javascript
// Basic logging
console.log("Hello", { name: "World" });
console.warn("Warning message");
console.error("Error occurred");

// Timing
console.time("operation");
// ... do work ...
console.timeLog("operation", "checkpoint");
// ... more work ...
console.timeEnd("operation"); // Logs: "operation: 123ms"

// Counting
console.count("clicks");     // clicks: 1
console.count("clicks");     // clicks: 2
console.countReset("clicks");
console.count("clicks");     // clicks: 1

// Grouping
console.group("User Info");
console.log("Name: John");
console.log("Age: 30");
console.groupEnd();

// Assertions
console.assert(1 === 1, "Math works");      // No output
console.assert(1 === 2, "Math is broken");  // Logs assertion failure
```

## ConsoleEntry Types

```typescript
type ConsoleEntry =
  | { type: "output"; level: "log" | "warn" | "error" | "info" | "debug"; args: unknown[]; groupDepth: number }
  | { type: "dir"; value: unknown; groupDepth: number }
  | { type: "table"; data: unknown; columns?: string[]; groupDepth: number }
  | { type: "time"; label: string; duration: number; groupDepth: number }
  | { type: "timeLog"; label: string; duration: number; args: unknown[]; groupDepth: number }
  | { type: "count"; label: string; count: number; groupDepth: number }
  | { type: "countReset"; label: string; groupDepth: number }
  | { type: "assert"; args: unknown[]; groupDepth: number }
  | { type: "group"; label: string; collapsed: boolean; groupDepth: number }
  | { type: "groupEnd"; groupDepth: number }
  | { type: "clear" }
  | { type: "trace"; args: unknown[]; stack: string; groupDepth: number };
```

Each entry includes `groupDepth` (except `clear`) which indicates the current nesting level of console groups, allowing proper indentation rendering without tracking state yourself.

## Entry Types Reference

| Entry Type | Description | Key Properties |
|------------|-------------|----------------|
| `output` | Standard logging (log, warn, error, info, debug) | `level`, `args` |
| `dir` | Object inspection | `value` |
| `table` | Tabular data display | `data`, `columns?` |
| `time` | Timer completion (timeEnd) | `label`, `duration` |
| `timeLog` | Timer checkpoint | `label`, `duration`, `args` |
| `count` | Counter increment | `label`, `count` |
| `countReset` | Counter reset | `label` |
| `assert` | Failed assertion | `args` |
| `group` | Group start | `label`, `collapsed` |
| `groupEnd` | Group end | - |
| `clear` | Console clear | - |
| `trace` | Stack trace | `args`, `stack` |