All files / js trace.js

0% Statements 0/65
0% Branches 0/1
0% Functions 0/1
0% Lines 0/65

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66                                                                                                                                   
// trace.js — Cell-level tracing functions for display debugging
// Extracted from display.js / headless.js to avoid duplication.

const _env = typeof process !== 'undefined' ? process.env : {};

export function parseTraceCellSpec(raw) {
    const text = String(raw || '').trim();
    if (!text) return null;
    const m = text.match(/^(\d+)\s*,\s*(\d+)$/);
    if (!m) return null;
    return { col: Number(m[1]), row: Number(m[2]) };
}

export function parseTraceStepSpec(raw) {
    const text = String(raw || '').trim();
    if (!text) return null;
    const m = text.match(/^(\d+)(?:\s*-\s*(\d+))?$/);
    if (!m) return null;
    const from = Number(m[1]);
    const to = Number(m[2] || m[1]);
    if (!Number.isInteger(from) || !Number.isInteger(to)) return null;
    return { from: Math.min(from, to), to: Math.max(from, to) };
}

export const TRACE_CELL_SPEC = parseTraceCellSpec(_env.WEBHACK_TRACE_CELL);
export const TRACE_CELL_STEPS = parseTraceStepSpec(_env.WEBHACK_TRACE_CELL_STEPS);
export const TRACE_CELL_STACK = _env.WEBHACK_TRACE_CELL_STACK === '1';

export function traceStepForDisplay(_display) {
    return null;
}

export function formatTraceChar(ch) {
    if (ch === ' ') return 'space';
    return JSON.stringify(ch);
}

export function traceCaller() {
    if (!TRACE_CELL_STACK) return '';
    const stack = String(new Error().stack || '').split('\n').slice(3);
    for (const line of stack) {
        if (!line.includes('/js/display.js')
            && !line.includes('/js/terminal.js')
            && !line.includes('/js/trace.js')) {
            return line.trim().replace(/^at\s+/, '');
        }
    }
    return stack[0] ? stack[0].trim().replace(/^at\s+/, '') : '';
}

export function maybeTraceCellWrite(display, col, row, prev, next, kind = 'write') {
    if (!TRACE_CELL_SPEC) return;
    if (TRACE_CELL_SPEC.col !== col || TRACE_CELL_SPEC.row !== row) return;
    const step = traceStepForDisplay(display);
    if (TRACE_CELL_STEPS && (step === null || step < TRACE_CELL_STEPS.from || step > TRACE_CELL_STEPS.to)) return;
    const caller = traceCaller();
    const callerPart = caller ? ` caller=${caller}` : '';
    console.error(
        `^celltrace[kind=${kind} step=${step === null ? '?' : step}`
        + ` cell=${col},${row}`
        + ` prev=${formatTraceChar(prev.ch)}/${prev.color}/${prev.attr}`
        + ` next=${formatTraceChar(next.ch)}/${next.color}/${next.attr}`
        + `${callerPart}]`
    );
}