• Prepares data table slice for virtualization with formatting, row metadata computation, and cache keys. Stages: (1) formats display values, (2) computes virtualization indexes and cache keys, (3) returns result.

    Parameters

    • message: DataTablePreparationMessage

      Worker message with table data, viewport, and column visibility.

    • activeTasks: Set<string>

      Set tracking active task IDs.

    Returns void

    Void; posts progress and result messages.

    export function handleDataTablePreparation(
    message: DataTablePreparationMessage,
    activeTasks: Set<string>,
    ): void {
    const { taskId, data, viewport, columnVisibility } = message.payload;

    activeTasks.add(taskId);

    console.debug(
    `[Worker] 📊 Starting data table preparation for task ${taskId} (${data.length} items, viewport: ${viewport.startIndex}-${viewport.endIndex})`,
    );

    const startTime = performance.now();

    try {
    const progressMsg1: DataTablePreparationProgressMessage = {
    type: "DATA_TABLE_PREPARATION_PROGRESS",
    payload: {
    taskId,
    stage: "formatting",
    progress: 25,
    message: `Formatting ${viewport.endIndex - viewport.startIndex} rows`,
    },
    };
    globalThis.postMessage(progressMsg1);

    if (!activeTasks.has(taskId)) {
    console.warn(
    `[Worker] ⚠️ Data table preparation task ${taskId} was cancelled before formatting`,
    );
    globalThis.postMessage({
    type: "DATA_TABLE_CANCELLED",
    payload: {
    taskId,
    stage: "formatting",
    },
    });
    return;
    }

    const formattingStartTime = performance.now();

    const slice = data.slice(viewport.startIndex, viewport.endIndex);

    const preparedData = prepareTableSlice(
    slice,
    0,
    slice.length,
    columnVisibility,
    );

    const formattingTimeMs = performance.now() - formattingStartTime;

    if (!activeTasks.has(taskId)) {
    console.warn(
    `[Worker] ⚠️ Data table preparation task ${taskId} was cancelled before metadata computation`,
    );
    globalThis.postMessage({
    type: "DATA_TABLE_CANCELLED",
    payload: {
    taskId,
    stage: "metadata",
    },
    });
    return;
    }

    const metadataStartTime = performance.now();

    const progressMsg2: DataTablePreparationProgressMessage = {
    type: "DATA_TABLE_PREPARATION_PROGRESS",
    payload: {
    taskId,
    stage: "computing-metadata",
    progress: 75,
    message: `Computing row metadata`,
    },
    };
    globalThis.postMessage(progressMsg2);

    // Compute virtualization indexes and cache keys for efficient rendering
    const cumulativeHeights: number[] = [];
    let cumulativeHeight = 0;
    for (const row of preparedData) {
    cumulativeHeight += row.rowHeight;
    cumulativeHeights.push(cumulativeHeight);
    }

    const totalRowHeights = cumulativeHeights.at(-1) || 0;

    const metadataComputationTimeMs = performance.now() - metadataStartTime;
    const totalTimeMs = performance.now() - startTime;

    if (!activeTasks.has(taskId)) {
    console.warn(
    `[Worker] ⚠️ Data table preparation task ${taskId} was cancelled before completion`,
    );
    globalThis.postMessage({
    type: "DATA_TABLE_CANCELLED",
    payload: {
    taskId,
    stage: "completion",
    },
    });
    return;
    }

    const resultMsg: DataTablePreparationResultMessage = {
    type: "DATA_TABLE_PREPARATION_RESULT",
    payload: {
    taskId,
    preparedData,
    indexInfo: {
    startIndex: viewport.startIndex,
    endIndex: viewport.endIndex,
    totalCount: data.length,
    },
    timing: {
    formattingTimeMs,
    metadataComputationTimeMs,
    totalTimeMs,
    },
    },
    };

    console.info(
    `[Worker] ✅ Data table preparation task ${taskId} completed (${slice.length} rows, avg height: ${(totalRowHeights / slice.length).toFixed(1)}px, ${totalTimeMs.toFixed(2)}ms)`,
    );

    globalThis.postMessage(resultMsg);
    } catch (error) {
    console.error(
    `[Worker] ❌ Error in data table preparation task ${taskId}:`,
    error,
    );
    globalThis.postMessage({
    type: "ERROR",
    payload: {
    taskId,
    error: getErrorDetails(error),
    },
    });
    } finally {
    activeTasks.delete(taskId);
    }
    }