```ts
/**
 * Labels regions in a grid based on connected components of equal values.
 * @param grid - A non-empty list of rows, each row a non-empty list of whole numbers.
 */
export function labelValueRegions(grid: number[][]): any {
    if (!Array.isArray(grid) || grid.length === 0) {
        throw new Error("Invalid grid: must be a non-empty array of arrays.");
    }

    const rowCount = grid.length;
    const colCount = grid[0].length;

    for (let row of grid) {
        if (!Array.isArray(row) || row.length !== colCount) {
            throw new Error("Invalid grid: each row must be a non-empty array of the same length as the first row.");
        }
        for (let value of row) {
            if (!Number.isInteger(value)) {
                throw new Error("Invalid grid: all elements must be whole numbers.");
            }
        }
    }

    const map = grid.map(row => row.slice());
    const sizes: number[] = [];
    const values: number[] = [];
    let regionCount = 0;

    function dfs(r: number, c: number, value: number, region: number): void {
        if (r < 0 || r >= rowCount || c < 0 || c >= colCount || map[r][c] !== value) return;
        map[r][c] = region;
        sizes[region - 1]++;
        dfs(r + 1, c, value, region);
        dfs(r - 1, c, value, region);
        dfs(r, c + 1, value, region);
        dfs(r, c - 1, value, region);
    }

    for (let r = 0; r < rowCount; r++) {
        for (let c = 0; c < colCount; c++) {
            if (map[r][c] !== value) {
                regionCount++;
                sizes.push(0);
                values.push(grid[r][c]);
                dfs(r, c, grid[r][c], regionCount);
            }
        }
    }

    return { map, sizes, values };
}
```