| 337 | * This also works around browser and storage-specific edge cases. |
| 338 | */ |
| 339 | export class FetchSource implements Source { |
| 340 | url: string; |
| 341 | |
| 342 | /** |
| 343 | * A [Headers](https://developer.mozilla.org/en-US/docs/Web/API/Headers) object, specfying custom [Headers](https://developer.mozilla.org/en-US/docs/Web/API/Headers) set for all requests to the remote archive. |
| 344 | * |
| 345 | * This should be used instead of maplibre's [transformRequest](https://maplibre.org/maplibre-gl-js/docs/API/classes/Map/#example) for PMTiles archives. |
| 346 | */ |
| 347 | customHeaders: Headers; |
| 348 | credentials: "same-origin" | "include" | undefined; |
| 349 | /** @hidden */ |
| 350 | mustReload: boolean; |
| 351 | /** @hidden */ |
| 352 | chromeWindowsNoCache: boolean; |
| 353 | |
| 354 | constructor( |
| 355 | url: string, |
| 356 | customHeaders: Headers = new Headers(), |
| 357 | credentials: "same-origin" | "include" | undefined = undefined |
| 358 | ) { |
| 359 | this.url = url; |
| 360 | this.customHeaders = customHeaders; |
| 361 | this.credentials = credentials; |
| 362 | this.mustReload = false; |
| 363 | let userAgent = ""; |
| 364 | if ("navigator" in globalThis) { |
| 365 | //biome-ignore lint: cf workers |
| 366 | userAgent = (globalThis as any).navigator?.userAgent ?? ""; |
| 367 | } |
| 368 | const isWindows = userAgent.indexOf("Windows") > -1; |
| 369 | const isChromiumBased = /Chrome|Chromium|Edg|OPR|Brave/.test(userAgent); |
| 370 | this.chromeWindowsNoCache = false; |
| 371 | if (isWindows && isChromiumBased) { |
| 372 | this.chromeWindowsNoCache = true; |
| 373 | } |
| 374 | } |
| 375 | |
| 376 | getKey() { |
| 377 | return this.url; |
| 378 | } |
| 379 | |
| 380 | /** |
| 381 | * Mutate the custom [Headers](https://developer.mozilla.org/en-US/docs/Web/API/Headers) set for all requests to the remote archive. |
| 382 | */ |
| 383 | setHeaders(customHeaders: Headers) { |
| 384 | this.customHeaders = customHeaders; |
| 385 | } |
| 386 | |
| 387 | async getBytes( |
| 388 | offset: number, |
| 389 | length: number, |
| 390 | passedSignal?: AbortSignal, |
| 391 | etag?: string |
| 392 | ): Promise<RangeResponse> { |
| 393 | let controller: AbortController | undefined; |
| 394 | let signal: AbortSignal | undefined; |
| 395 | if (passedSignal) { |
| 396 | signal = passedSignal; |
nothing calls this directly
no outgoing calls
no test coverage detected
searching dependent graphs…