/**
 * Merges an array of request objects by combining requests
 * that share the same `id`, reducing the total number of requests.
 *
 * If multiple requests have the same `id`, their `tileIds` arrays are merged
 * into a single request entry in the output array.
 *
 * @example
 * ```js
 * const requests = [
 *   { id: "A", tileIds: ["1", "2"] },
 *   { id: "B", tileIds: ["3"] },
 *   { id: "A", tileids: ["4", "5"] },
 * ];
 *
 * const bundled = bundleRequests(requests);
 * console.log(bundled);
 * // [
 * //   { id: "A", tileIds: ["1", "2", "4", "5"] },
 * //   { id: "B", tileIds: ["3"] },
 * // ]
 * ```
 *
 * @template {{ id: string, tileIds: ReadonlyArray<string> }} T
 * @param {Array<T>} requests - The list of requests to bundle
 * @returns {Array<T>} - A new array with merged requests
 */
export function bundleRequestsById<T extends {
    id: string;
    tileIds: ReadonlyArray<string>;
}>(requests: Array<T>): Array<T>;
/**
 * Groups request objects by `server`, merging their `tileIds` and structuring tileset-related
 * data into `body`.
 *
 * **Note:** The first request for each `server` sets the `options` for all grouped requests.
 * Each tileset in `body` also inherits these `options`. A tileset is only added to `body`
 * if the request includes `options`.
 *
 * Trevor (2025-02-20): This follows the original "server bundling" logic. It’s unclear if `body` is
 * actually used in practice. Omitting requests without `options` might be an unintended
 * behavior, but we're maintaining it for now.
 *
 * @example
 * ```js
 * const requests = [
 *   { server: "A", tileIds: ["tileset1.1", "tileset2.2"], options: { foo: "bar" } },
 *   { server: "B", tileIds: ["tileset3.3"], options: { baz: "qux" } },
 *   { server: "A", tileIds: ["tileset1.4"] },
 * ];
 *
 * const bundled = bundleRequestsByServer(requests);
 * console.log(bundled);
 * // [
 * //   {
 * //     server: "A",
 * //     tileIds: ["tileset1.1", "tileset2.2", "tileset1.4"],
 * //     options: { foo: "bar" },
 * //     body: [
 * //       { tilesetUid: "tileset1", tileIds: ["1"], options: { foo: "bar" } },
 * //       { tilesetUid: "tileset2", tileIds: ["2"], options: { foo: "bar" } }
 * //     ]
 * //   },
 * //   {
 * //     server: "B",
 * //     tileIds: ["tileset3.3"],
 * //     options: { baz: "qux" },
 * //     body: [
 * //       { tilesetUid: "tileset3", tileIds: ["3"], options: { baz: "qux" } }
 * //     ]
 * //   }
 * // ]
 * ```
 *
 * @template {{ tileIds: ReadonlyArray<string>, server: string, options?: Record<string, any> }} T
 * @param {Array<T>} requests - The list of requests to bundle
 * @returns {Array<T & { body: ReadonlyArray<ServerTilesetBody> }> }>} - A new array with merged requests per server
 */
export function bundleRequestsByServer<T extends {
    tileIds: ReadonlyArray<string>;
    server: string;
    options?: Record<string, any>;
}>(requests: Array<T>): Array<T & {
    body: ReadonlyArray<{
        tilesetUid: string;
        tileIds: Array<string>;
        options: Record<string, any>;
    }>;
}>;
/**
 * Calculate the element within this tile containing the given
 * position.
 *
 * Returns the tile position and position within the tile for
 * the given element.
 *
 * @param {TilesetInfo} tilesetInfo - The information about this tileset
 * @param {number} maxDim - The maximum width of the dataset (only used for tilesets without resolutions)
 * @param {number} dataStartPos - The position where the data begins
 * @param {number} zoomLevel - The (integer) current zoomLevel
 * @param {number} position -The position (in absolute coordinates) to caculate the tile and position in tile for
 *
 * @returns {Array<number>}
 */
export function calculateTileAndPosInTile(tilesetInfo: TilesetInfo, maxDim: number, dataStartPos: number, zoomLevel: number, position: number): Array<number>;
/** @type {number} */
export let requestsInFlight: number;
/** @type {string | null} */
export let authHeader: string | null;
export function setTileProxyAuthHeader(newHeader: string): void;
export function getTileProxyAuthHeader(): string | null;
/**
 * Retrieve a set of tiles from the server.
 *
 * @type {(request: TilesRequest, pubSub: PubSub) => Promise<Record<string, TileData>>}
 */
export const fetchTilesDebounced: (request: TilesRequest, pubSub: PubSub) => Promise<Record<string, TileData>>;
export function calculateZoomLevelFromResolutions(resolutions: Array<string>, scale: Scale): number;
export function calculateResolution(tilesetInfo: TilesetInfo, zoomLevel: number): number;
export function calculateZoomLevel(scale: Scale, minX: number, maxX: number, binsPerTile: number): number;
export function calculateTiles(zoomLevel: number, scale: Scale, minX: number, _maxX: number, maxZoom: number, maxDim: number): Array<number>;
export function calculateTileWidth(tilesetInfo: TilesetInfo, zoomLevel: number, binsPerTile: number): number;
export function calculateTilesFromResolution(resolution: number, scale: Scale, minX: number, maxX: number, pixelsPerTile?: number | undefined): number[];
export function tileDataToPixData(tile: {
    mirrored?: boolean;
    isMirrored?: boolean;
    tileData: {
        dense: Float32Array;
        tilePos: readonly [a: number, b?: number];
        shape: readonly [number, number];
    };
}, valueScaleType: "log" | "linear", valueScaleDomain: [min: number, max: number], pseudocount: number, colorScale: ReadonlyArray<readonly [r: number, g: number, b: number, a: number]>, finished: (x: null | {
    pixData: Uint8ClampedArray;
}) => void, ignoreUpperRight: boolean | undefined, ignoreLowerLeft: boolean | undefined, zeroValueColor: [r: number, g: number, b: number, a: number], selectedRowsOptions: Partial<SelectedRowsOptions>): void;
export function trackInfo(server: string, tilesetUid: string, doneCb: (info: Record<string, TilesetInfo>) => void, errorCb: (error: string) => void, pubSub: import("pub-sub-es").PubSub): void;
export default api;
export type WithResolvers<T, U> = {
    value: T;
    resolve: (value: U) => void;
    reject: (err: unknown) => void;
};
export type TileData = CompletedTileData<TileResponse>;
import type { TilesetInfo } from '../types';
import type { TilesRequest } from '../types';
import type { PubSub } from 'pub-sub-es';
import type { Scale } from '../types';
import type { SelectedRowsOptions } from './worker';
declare namespace api {
    export { calculateResolution };
    export { calculateTileAndPosInTile };
    export { calculateTiles };
    export { calculateTilesFromResolution };
    export { calculateTileWidth };
    export { calculateZoomLevel };
    export { calculateZoomLevelFromResolutions };
    export { fetchTilesDebounced };
    export { json };
    export { text };
    export { tileDataToPixData };
    export { trackInfo };
}
import type { TileResponse } from './worker';
import type { CompletedTileData } from './worker';
/**
 * Send a JSON request and mark it so that we can tell how many are in flight
 *
 * @template T
 * @param {string} url
 * @param {(err: Error | undefined, value: T | undefined) => void} callback
 * @param {import("pub-sub-es").PubSub} pubSub
 */
declare function json<T>(url: string, callback: (err: Error | undefined, value: T | undefined) => void, pubSub: import("pub-sub-es").PubSub): Promise<T>;
/**
 * Send a text request and mark it so that we can tell how many are in flight
 *
 * @param {string | URL} url
 * @param {(err: Error | undefined, value: string | undefined) => void} callback
 * @param {import("pub-sub-es").PubSub} pubSub
 */
declare function text(url: string | URL, callback: (err: Error | undefined, value: string | undefined) => void, pubSub: import("pub-sub-es").PubSub): Promise<string>;
