import LRU from '@jbrowse/quick-lru'; import { CacheSemantics, ChunkResponse } from './cacheSemantics.ts'; import AggregatingFetcher from './aggregatingFetcher.ts'; /** * smart cache that fetches chunks of remote files. * caches chunks in an LRU cache, and aggregates upstream fetches */ export default class HttpRangeFetcher { chunkSize: number; aggregator: AggregatingFetcher; chunkCache: LRU>; cacheSemantics: CacheSemantics; stats: LRU; constructor({ fetch, size, chunkSize, aggregationTime, minimumTTL, maxFetchSize, maxExtraFetch, }: { fetch?: (key: string, start: number, end: number) => Promise<{ headers: Headers; buffer: Uint8Array; }>; size?: number; chunkSize?: number; aggregationTime?: number; minimumTTL?: number; maxFetchSize?: number; maxExtraFetch?: number; }); getRange(key: string, position: number, length: number, options?: {}): Promise<{ headers: {}; buffer: Uint8Array; } | { headers: { 'content-length': number; 'content-range': string; 'x-resource-length': string | undefined; append(name: string, value: string): void; delete(name: string): void; get(name: string): string | null; getSetCookie(): string[]; has(name: string): boolean; set(name: string, value: string): void; forEach(callbackfn: (value: string, key: string, parent: Headers) => void, thisArg?: any): void; }; buffer: Uint8Array; }>; _makeBuffer(chunkResponses: { buffer: Uint8Array; }[], chunksOffset: number, length: number): Uint8Array; /** * Fetches the first few bytes of the remote file (if necessary) and uses * the returned headers to populate a `fs`-like stat object. * * Currently, this attempts to set `size`, `mtime`, and `mtimeMs`, if * the information is available from HTTP headers. * * @param {string} key * @returns {Promise} for a stats object */ stat(key: string): Promise<{ size: number; mtime: Date; }>; _headersToStats(chunkResponse: ChunkResponse): { mtimeMs: number; mtime: Date; size: number; }; _makeHeaders(originalHeaders: Headers, newStart: number, newEnd: number): { 'content-length': number; 'content-range': string; 'x-resource-length': string | undefined; append(name: string, value: string): void; delete(name: string): void; get(name: string): string | null; getSetCookie(): string[]; has(name: string): boolean; set(name: string, value: string): void; forEach(callbackfn: (value: string, key: string, parent: Headers) => void, thisArg?: any): void; }; _getChunk(key: string, chunkNumber: number, requestOptions?: { signal?: AbortSignal; }): Promise; _recordStatsIfNecessary(key: string, chunk: ChunkResponse): void; _uncacheIfSame(key: string, cachedPromise: Promise): void; /** * Throw away all cached data, resetting the cache. */ reset(): void; }