apply automated linting fixes (#331)

This commit is contained in:
Brandon Liu
2024-01-29 16:04:41 +08:00
committed by GitHub
parent 5e41bd65ef
commit 3b61cc8b49
8 changed files with 413 additions and 255 deletions

View File

@@ -2,13 +2,13 @@ declare const L: any;
declare const window: any; declare const window: any;
declare const document: any; declare const document: any;
import { PMTiles, Source, TileType } from "./index"; import { PMTiles, TileType } from "./index";
export const leafletRasterLayer = (source: PMTiles, options: any) => { export const leafletRasterLayer = (source: PMTiles, options: any) => {
let loaded = false; let loaded = false;
let mimeType: string = ""; let mimeType = "";
const cls = L.GridLayer.extend({ const cls = L.GridLayer.extend({
createTile: function (coord: any, done: any) { createTile: (coord: any, done: any) => {
const el: any = document.createElement("img"); const el: any = document.createElement("img");
const controller = new AbortController(); const controller = new AbortController();
const signal = controller.signal; const signal = controller.signal;
@@ -116,11 +116,11 @@ export class Protocol {
callback: ResponseCallback callback: ResponseCallback
): Cancelable => { ): Cancelable => {
if (params.type == "json") { if (params.type == "json") {
const pmtiles_url = params.url.substr(10); const pmtilesUrl = params.url.substr(10);
let instance = this.tiles.get(pmtiles_url); let instance = this.tiles.get(pmtilesUrl);
if (!instance) { if (!instance) {
instance = new PMTiles(pmtiles_url); instance = new PMTiles(pmtilesUrl);
this.tiles.set(pmtiles_url, instance); this.tiles.set(pmtilesUrl, instance);
} }
instance instance
@@ -150,12 +150,12 @@ export class Protocol {
cancel: () => {}, cancel: () => {},
}; };
} }
const pmtiles_url = result[1]; const pmtilesUrl = result[1];
let instance = this.tiles.get(pmtiles_url); let instance = this.tiles.get(pmtilesUrl);
if (!instance) { if (!instance) {
instance = new PMTiles(pmtiles_url); instance = new PMTiles(pmtilesUrl);
this.tiles.set(pmtiles_url, instance); this.tiles.set(pmtilesUrl, instance);
} }
const z = result[2]; const z = result[2];
const x = result[3]; const x = result[3];
@@ -163,7 +163,7 @@ export class Protocol {
const controller = new AbortController(); const controller = new AbortController();
const signal = controller.signal; const signal = controller.signal;
let cancel = () => { const cancel = () => {
controller.abort(); controller.abort();
}; };

20
js/biome.json Normal file
View File

@@ -0,0 +1,20 @@
{
"javascript": {
"formatter": {
"trailingComma": "es5"
}
},
"formatter": {
"indentStyle": "space"
},
"linter": {
"rules": {
"style": {
"useNamingConvention": {}
},
"nursery": {
"noUnusedImports": {}
}
}
}
}

View File

@@ -122,14 +122,14 @@ export function zxyToTileId(z: number, x: number, y: number): number {
export function tileIdToZxy(i: number): [number, number, number] { export function tileIdToZxy(i: number): [number, number, number] {
let acc = 0; let acc = 0;
let z = 0; const z = 0;
for (let z = 0; z < 27; z++) { for (let z = 0; z < 27; z++) {
const num_tiles = (0x1 << z) * (0x1 << z); const numTiles = (0x1 << z) * (0x1 << z);
if (acc + num_tiles > i) { if (acc + numTiles > i) {
return idOnLevel(z, i - acc); return idOnLevel(z, i - acc);
} }
acc += num_tiles; acc += numTiles;
} }
throw Error("Tile zoom level exceeds max safe number limit (26)"); throw Error("Tile zoom level exceeds max safe number limit (26)");
@@ -165,8 +165,8 @@ async function defaultDecompress(
if (typeof (globalThis as any).DecompressionStream == "undefined") { if (typeof (globalThis as any).DecompressionStream == "undefined") {
return decompressSync(new Uint8Array(buf)); return decompressSync(new Uint8Array(buf));
} else { } else {
let stream = new Response(buf).body!; const stream = new Response(buf).body!;
let result: ReadableStream<Uint8Array> = stream.pipeThrough( const result: ReadableStream<Uint8Array> = stream.pipeThrough(
new (globalThis as any).DecompressionStream("gzip") new (globalThis as any).DecompressionStream("gzip")
); );
return new Response(result).arrayBuffer(); return new Response(result).arrayBuffer();
@@ -326,14 +326,14 @@ export class FetchSource implements Source {
if (resp.status === 416 && offset === 0) { if (resp.status === 416 && offset === 0) {
// some HTTP servers don't accept ranges beyond the end of the resource. // some HTTP servers don't accept ranges beyond the end of the resource.
// Retry with the exact length // Retry with the exact length
const content_range = resp.headers.get("Content-Range"); const contentRange = resp.headers.get("Content-Range");
if (!content_range || !content_range.startsWith("bytes */")) { if (!contentRange || !contentRange.startsWith("bytes */")) {
throw Error("Missing content-length on 416 response"); throw Error("Missing content-length on 416 response");
} }
const actual_length = +content_range.substr(8); const actualLength = +contentRange.substr(8);
resp = await fetch(this.url, { resp = await fetch(this.url, {
signal: signal, signal: signal,
headers: { Range: "bytes=0-" + (actual_length - 1) }, headers: { Range: "bytes=0-" + (actualLength - 1) },
}); });
} }
@@ -341,11 +341,11 @@ export class FetchSource implements Source {
throw Error("Bad response code: " + resp.status); throw Error("Bad response code: " + resp.status);
} }
const content_length = resp.headers.get("Content-Length"); const contentLength = resp.headers.get("Content-Length");
// some well-behaved backends, e.g. DigitalOcean CDN, respond with 200 instead of 206 // some well-behaved backends, e.g. DigitalOcean CDN, respond with 200 instead of 206
// but we also need to detect no support for Byte Serving which is returning the whole file // but we also need to detect no support for Byte Serving which is returning the whole file
if (resp.status === 200 && (!content_length || +content_length > length)) { if (resp.status === 200 && (!contentLength || +contentLength > length)) {
if (controller) controller.abort(); if (controller) controller.abort();
throw Error( throw Error(
"Server returned no content-length header or content-length exceeding request. Check that your storage backend supports HTTP Byte Serving." "Server returned no content-length header or content-length exceeding request. Check that your storage backend supports HTTP Byte Serving."
@@ -370,15 +370,15 @@ export function getUint64(v: DataView, offset: number): number {
export function bytesToHeader(bytes: ArrayBuffer, etag?: string): Header { export function bytesToHeader(bytes: ArrayBuffer, etag?: string): Header {
const v = new DataView(bytes); const v = new DataView(bytes);
const spec_version = v.getUint8(7); const specVersion = v.getUint8(7);
if (spec_version > 3) { if (specVersion > 3) {
throw Error( throw Error(
`Archive is spec version ${spec_version} but this library supports up to spec version 3` `Archive is spec version ${specVersion} but this library supports up to spec version 3`
); );
} }
return { return {
specVersion: spec_version, specVersion: specVersion,
rootDirectoryOffset: getUint64(v, 8), rootDirectoryOffset: getUint64(v, 8),
rootDirectoryLength: getUint64(v, 16), rootDirectoryLength: getUint64(v, 16),
jsonMetadataOffset: getUint64(v, 24), jsonMetadataOffset: getUint64(v, 24),
@@ -459,7 +459,7 @@ function detectVersion(a: ArrayBuffer): number {
export class EtagMismatch extends Error {} export class EtagMismatch extends Error {}
export interface Cache { export interface Cache {
getHeader: (source: Source, current_etag?: string) => Promise<Header>; getHeader: (source: Source, currentEtag?: string) => Promise<Header>;
getDirectory: ( getDirectory: (
source: Source, source: Source,
offset: number, offset: number,
@@ -472,14 +472,14 @@ export interface Cache {
length: number, length: number,
header: Header header: Header
) => Promise<ArrayBuffer>; ) => Promise<ArrayBuffer>;
invalidate: (source: Source, current_etag: string) => Promise<void>; invalidate: (source: Source, currentEtag: string) => Promise<void>;
} }
async function getHeaderAndRoot( async function getHeaderAndRoot(
source: Source, source: Source,
decompress: DecompressFunc, decompress: DecompressFunc,
prefetch: boolean, prefetch: boolean,
current_etag?: string currentEtag?: string
): Promise<[Header, [string, number, Entry[] | ArrayBuffer]?]> { ): Promise<[Header, [string, number, Entry[] | ArrayBuffer]?]> {
const resp = await source.getBytes(0, 16384); const resp = await source.getBytes(0, 16384);
@@ -495,16 +495,16 @@ async function getHeaderAndRoot(
const headerData = resp.data.slice(0, HEADER_SIZE_BYTES); const headerData = resp.data.slice(0, HEADER_SIZE_BYTES);
let resp_etag = resp.etag; let respEtag = resp.etag;
if (current_etag && resp.etag != current_etag) { if (currentEtag && resp.etag != currentEtag) {
console.warn( console.warn(
"ETag conflict detected; your HTTP server might not support content-based ETag headers. ETags disabled for " + "ETag conflict detected; your HTTP server might not support content-based ETag headers. ETags disabled for " +
source.getKey() source.getKey()
); );
resp_etag = undefined; respEtag = undefined;
} }
const header = bytesToHeader(headerData, resp_etag); const header = bytesToHeader(headerData, respEtag);
// optimistically set the root directory // optimistically set the root directory
// TODO check root bounds // TODO check root bounds
@@ -577,7 +577,7 @@ export class ResolvedValueCache {
this.decompress = decompress; this.decompress = decompress;
} }
async getHeader(source: Source, current_etag?: string): Promise<Header> { async getHeader(source: Source, currentEtag?: string): Promise<Header> {
const cacheKey = source.getKey(); const cacheKey = source.getKey();
if (this.cache.has(cacheKey)) { if (this.cache.has(cacheKey)) {
this.cache.get(cacheKey)!.lastUsed = this.counter++; this.cache.get(cacheKey)!.lastUsed = this.counter++;
@@ -589,7 +589,7 @@ export class ResolvedValueCache {
source, source,
this.decompress, this.decompress,
this.prefetch, this.prefetch,
current_etag currentEtag
); );
if (res[1]) { if (res[1]) {
this.cache.set(res[1][0], { this.cache.set(res[1][0], {
@@ -666,9 +666,9 @@ export class ResolvedValueCache {
if (this.cache.size > this.maxCacheEntries) { if (this.cache.size > this.maxCacheEntries) {
let minUsed = Infinity; let minUsed = Infinity;
let minKey = undefined; let minKey = undefined;
this.cache.forEach((cache_value: ResolvedValue, key: string) => { this.cache.forEach((cacheValue: ResolvedValue, key: string) => {
if (cache_value.lastUsed < minUsed) { if (cacheValue.lastUsed < minUsed) {
minUsed = cache_value.lastUsed; minUsed = cacheValue.lastUsed;
minKey = key; minKey = key;
} }
}); });
@@ -678,9 +678,9 @@ export class ResolvedValueCache {
} }
} }
async invalidate(source: Source, current_etag: string) { async invalidate(source: Source, currentEtag: string) {
this.cache.delete(source.getKey()); this.cache.delete(source.getKey());
await this.getHeader(source, current_etag); await this.getHeader(source, currentEtag);
} }
} }
@@ -712,7 +712,7 @@ export class SharedPromiseCache {
this.decompress = decompress; this.decompress = decompress;
} }
async getHeader(source: Source, current_etag?: string): Promise<Header> { async getHeader(source: Source, currentEtag?: string): Promise<Header> {
const cacheKey = source.getKey(); const cacheKey = source.getKey();
if (this.cache.has(cacheKey)) { if (this.cache.has(cacheKey)) {
this.cache.get(cacheKey)!.lastUsed = this.counter++; this.cache.get(cacheKey)!.lastUsed = this.counter++;
@@ -721,7 +721,7 @@ export class SharedPromiseCache {
} }
const p = new Promise<Header>((resolve, reject) => { const p = new Promise<Header>((resolve, reject) => {
getHeaderAndRoot(source, this.decompress, this.prefetch, current_etag) getHeaderAndRoot(source, this.decompress, this.prefetch, currentEtag)
.then((res) => { .then((res) => {
if (res[1]) { if (res[1]) {
this.cache.set(res[1][0], { this.cache.set(res[1][0], {
@@ -807,23 +807,21 @@ export class SharedPromiseCache {
if (this.cache.size >= this.maxCacheEntries) { if (this.cache.size >= this.maxCacheEntries) {
let minUsed = Infinity; let minUsed = Infinity;
let minKey = undefined; let minKey = undefined;
this.cache.forEach( this.cache.forEach((cacheValue: SharedPromiseCacheValue, key: string) => {
(cache_value: SharedPromiseCacheValue, key: string) => { if (cacheValue.lastUsed < minUsed) {
if (cache_value.lastUsed < minUsed) { minUsed = cacheValue.lastUsed;
minUsed = cache_value.lastUsed;
minKey = key; minKey = key;
} }
} });
);
if (minKey) { if (minKey) {
this.cache.delete(minKey); this.cache.delete(minKey);
} }
} }
} }
async invalidate(source: Source, current_etag: string) { async invalidate(source: Source, currentEtag: string) {
this.cache.delete(source.getKey()); this.cache.delete(source.getKey());
await this.getHeader(source, current_etag); await this.getHeader(source, currentEtag);
} }
} }
@@ -864,7 +862,7 @@ export class PMTiles {
y: number, y: number,
signal?: AbortSignal signal?: AbortSignal
): Promise<RangeResponse | undefined> { ): Promise<RangeResponse | undefined> {
const tile_id = zxyToTileId(z, x, y); const tileId = zxyToTileId(z, x, y);
const header = await this.cache.getHeader(this.source); const header = await this.cache.getHeader(this.source);
// V2 COMPATIBILITY // V2 COMPATIBILITY
@@ -876,16 +874,16 @@ export class PMTiles {
return undefined; return undefined;
} }
let d_o = header.rootDirectoryOffset; let dO = header.rootDirectoryOffset;
let d_l = header.rootDirectoryLength; let dL = header.rootDirectoryLength;
for (let depth = 0; depth <= 3; depth++) { for (let depth = 0; depth <= 3; depth++) {
const directory = await this.cache.getDirectory( const directory = await this.cache.getDirectory(
this.source, this.source,
d_o, dO,
d_l, dL,
header header
); );
const entry = findTile(directory, tile_id); const entry = findTile(directory, tileId);
if (entry) { if (entry) {
if (entry.runLength > 0) { if (entry.runLength > 0) {
const resp = await this.source.getBytes( const resp = await this.source.getBytes(
@@ -902,8 +900,8 @@ export class PMTiles {
expires: resp.expires, expires: resp.expires,
}; };
} else { } else {
d_o = header.leafDirectoryOffset + entry.offset; dO = header.leafDirectoryOffset + entry.offset;
d_l = entry.length; dL = entry.length;
} }
} else { } else {
// TODO: We should in fact return a valid RangeResponse // TODO: We should in fact return a valid RangeResponse

314
js/package-lock.json generated
View File

@@ -12,14 +12,169 @@
"fflate": "^0.8.0" "fflate": "^0.8.0"
}, },
"devDependencies": { "devDependencies": {
"@biomejs/biome": "^1.5.3",
"@types/node": "^18.11.9", "@types/node": "^18.11.9",
"esbuild": "^0.15.11", "esbuild": "^0.15.11",
"esbuild-runner": "^2.2.1",
"prettier": "^2.8.4", "prettier": "^2.8.4",
"tsx": "^4.7.0", "tsx": "^4.7.0",
"typescript": "^4.5.5" "typescript": "^4.5.5"
} }
}, },
"node_modules/@biomejs/biome": {
"version": "1.5.3",
"resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-1.5.3.tgz",
"integrity": "sha512-yvZCa/g3akwTaAQ7PCwPWDCkZs3Qa5ONg/fgOUT9e6wAWsPftCjLQFPXBeGxPK30yZSSpgEmRCfpGTmVbUjGgg==",
"dev": true,
"hasInstallScript": true,
"bin": {
"biome": "bin/biome"
},
"engines": {
"node": ">=14.*"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/biome"
},
"optionalDependencies": {
"@biomejs/cli-darwin-arm64": "1.5.3",
"@biomejs/cli-darwin-x64": "1.5.3",
"@biomejs/cli-linux-arm64": "1.5.3",
"@biomejs/cli-linux-arm64-musl": "1.5.3",
"@biomejs/cli-linux-x64": "1.5.3",
"@biomejs/cli-linux-x64-musl": "1.5.3",
"@biomejs/cli-win32-arm64": "1.5.3",
"@biomejs/cli-win32-x64": "1.5.3"
}
},
"node_modules/@biomejs/cli-darwin-arm64": {
"version": "1.5.3",
"resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-1.5.3.tgz",
"integrity": "sha512-ImU7mh1HghEDyqNmxEZBoMPr8SxekkZuYcs+gynKlNW+TALQs7swkERiBLkG9NR0K1B3/2uVzlvYowXrmlW8hw==",
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">=14.*"
}
},
"node_modules/@biomejs/cli-darwin-x64": {
"version": "1.5.3",
"resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-1.5.3.tgz",
"integrity": "sha512-vCdASqYnlpq/swErH7FD6nrFz0czFtK4k/iLgj0/+VmZVjineFPgevOb+Sr9vz0tk0GfdQO60bSpI74zU8M9Dw==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">=14.*"
}
},
"node_modules/@biomejs/cli-linux-arm64": {
"version": "1.5.3",
"resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-1.5.3.tgz",
"integrity": "sha512-cupBQv0sNF1OKqBfx7EDWMSsKwRrBUZfjXawT4s6hKV6ALq7p0QzWlxr/sDmbKMLOaLQtw2Qgu/77N9rm+f9Rg==",
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=14.*"
}
},
"node_modules/@biomejs/cli-linux-arm64-musl": {
"version": "1.5.3",
"resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-1.5.3.tgz",
"integrity": "sha512-DYuMizUYUBYfS0IHGjDrOP1RGipqWfMGEvNEJ398zdtmCKLXaUvTimiox5dvx4X15mBK5M2m8wgWUgOP1giUpQ==",
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=14.*"
}
},
"node_modules/@biomejs/cli-linux-x64": {
"version": "1.5.3",
"resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-1.5.3.tgz",
"integrity": "sha512-YQrSArQvcv4FYsk7Q91Yv4uuu5F8hJyORVcv3zsjCLGkjIjx2RhjYLpTL733SNL7v33GmOlZY0eFR1ko38tuUw==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=14.*"
}
},
"node_modules/@biomejs/cli-linux-x64-musl": {
"version": "1.5.3",
"resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-1.5.3.tgz",
"integrity": "sha512-UUHiAnlDqr2Y/LpvshBFhUYMWkl2/Jn+bi3U6jKuav0qWbbBKU/ByHgR4+NBxpKBYoCtWxhnmatfH1bpPIuZMw==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=14.*"
}
},
"node_modules/@biomejs/cli-win32-arm64": {
"version": "1.5.3",
"resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-1.5.3.tgz",
"integrity": "sha512-HxatYH7vf/kX9nrD+pDYuV2GI9GV8EFo6cfKkahAecTuZLPxryHx1WEfJthp5eNsE0+09STGkKIKjirP0ufaZA==",
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=14.*"
}
},
"node_modules/@biomejs/cli-win32-x64": {
"version": "1.5.3",
"resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-1.5.3.tgz",
"integrity": "sha512-fMvbSouZEASU7mZH8SIJSANDm5OqsjgtVXlbUqxwed6BP7uuHRSs396Aqwh2+VoW8fwTpp6ybIUoC9FrzB0kyA==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=14.*"
}
},
"node_modules/@esbuild/aix-ppc64": { "node_modules/@esbuild/aix-ppc64": {
"version": "0.19.12", "version": "0.19.12",
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz",
@@ -394,12 +549,6 @@
"integrity": "sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg==", "integrity": "sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg==",
"dev": true "dev": true
}, },
"node_modules/buffer-from": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
"dev": true
},
"node_modules/esbuild": { "node_modules/esbuild": {
"version": "0.15.15", "version": "0.15.15",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.15.15.tgz", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.15.15.tgz",
@@ -693,22 +842,6 @@
"node": ">=12" "node": ">=12"
} }
}, },
"node_modules/esbuild-runner": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/esbuild-runner/-/esbuild-runner-2.2.1.tgz",
"integrity": "sha512-VP0VfJJZiZ3cKzdOH59ZceDxx/GzBKra7tiGM8MfFMLv6CR1/cpsvtQ3IsJI3pz7HyeYxtbPyecj3fHwR+3XcQ==",
"dev": true,
"dependencies": {
"source-map-support": "0.5.19",
"tslib": "2.3.1"
},
"bin": {
"esr": "bin/esr.js"
},
"peerDependencies": {
"esbuild": "*"
}
},
"node_modules/esbuild-sunos-64": { "node_modules/esbuild-sunos-64": {
"version": "0.15.15", "version": "0.15.15",
"resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.15.15.tgz", "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.15.15.tgz",
@@ -828,31 +961,6 @@
"url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1"
} }
}, },
"node_modules/source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/source-map-support": {
"version": "0.5.19",
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz",
"integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==",
"dev": true,
"dependencies": {
"buffer-from": "^1.0.0",
"source-map": "^0.6.0"
}
},
"node_modules/tslib": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==",
"dev": true
},
"node_modules/tsx": { "node_modules/tsx": {
"version": "4.7.0", "version": "4.7.0",
"resolved": "https://registry.npmjs.org/tsx/-/tsx-4.7.0.tgz", "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.7.0.tgz",
@@ -957,6 +1065,78 @@
} }
}, },
"dependencies": { "dependencies": {
"@biomejs/biome": {
"version": "1.5.3",
"resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-1.5.3.tgz",
"integrity": "sha512-yvZCa/g3akwTaAQ7PCwPWDCkZs3Qa5ONg/fgOUT9e6wAWsPftCjLQFPXBeGxPK30yZSSpgEmRCfpGTmVbUjGgg==",
"dev": true,
"requires": {
"@biomejs/cli-darwin-arm64": "1.5.3",
"@biomejs/cli-darwin-x64": "1.5.3",
"@biomejs/cli-linux-arm64": "1.5.3",
"@biomejs/cli-linux-arm64-musl": "1.5.3",
"@biomejs/cli-linux-x64": "1.5.3",
"@biomejs/cli-linux-x64-musl": "1.5.3",
"@biomejs/cli-win32-arm64": "1.5.3",
"@biomejs/cli-win32-x64": "1.5.3"
}
},
"@biomejs/cli-darwin-arm64": {
"version": "1.5.3",
"resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-1.5.3.tgz",
"integrity": "sha512-ImU7mh1HghEDyqNmxEZBoMPr8SxekkZuYcs+gynKlNW+TALQs7swkERiBLkG9NR0K1B3/2uVzlvYowXrmlW8hw==",
"dev": true,
"optional": true
},
"@biomejs/cli-darwin-x64": {
"version": "1.5.3",
"resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-1.5.3.tgz",
"integrity": "sha512-vCdASqYnlpq/swErH7FD6nrFz0czFtK4k/iLgj0/+VmZVjineFPgevOb+Sr9vz0tk0GfdQO60bSpI74zU8M9Dw==",
"dev": true,
"optional": true
},
"@biomejs/cli-linux-arm64": {
"version": "1.5.3",
"resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-1.5.3.tgz",
"integrity": "sha512-cupBQv0sNF1OKqBfx7EDWMSsKwRrBUZfjXawT4s6hKV6ALq7p0QzWlxr/sDmbKMLOaLQtw2Qgu/77N9rm+f9Rg==",
"dev": true,
"optional": true
},
"@biomejs/cli-linux-arm64-musl": {
"version": "1.5.3",
"resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-1.5.3.tgz",
"integrity": "sha512-DYuMizUYUBYfS0IHGjDrOP1RGipqWfMGEvNEJ398zdtmCKLXaUvTimiox5dvx4X15mBK5M2m8wgWUgOP1giUpQ==",
"dev": true,
"optional": true
},
"@biomejs/cli-linux-x64": {
"version": "1.5.3",
"resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-1.5.3.tgz",
"integrity": "sha512-YQrSArQvcv4FYsk7Q91Yv4uuu5F8hJyORVcv3zsjCLGkjIjx2RhjYLpTL733SNL7v33GmOlZY0eFR1ko38tuUw==",
"dev": true,
"optional": true
},
"@biomejs/cli-linux-x64-musl": {
"version": "1.5.3",
"resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-1.5.3.tgz",
"integrity": "sha512-UUHiAnlDqr2Y/LpvshBFhUYMWkl2/Jn+bi3U6jKuav0qWbbBKU/ByHgR4+NBxpKBYoCtWxhnmatfH1bpPIuZMw==",
"dev": true,
"optional": true
},
"@biomejs/cli-win32-arm64": {
"version": "1.5.3",
"resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-1.5.3.tgz",
"integrity": "sha512-HxatYH7vf/kX9nrD+pDYuV2GI9GV8EFo6cfKkahAecTuZLPxryHx1WEfJthp5eNsE0+09STGkKIKjirP0ufaZA==",
"dev": true,
"optional": true
},
"@biomejs/cli-win32-x64": {
"version": "1.5.3",
"resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-1.5.3.tgz",
"integrity": "sha512-fMvbSouZEASU7mZH8SIJSANDm5OqsjgtVXlbUqxwed6BP7uuHRSs396Aqwh2+VoW8fwTpp6ybIUoC9FrzB0kyA==",
"dev": true,
"optional": true
},
"@esbuild/aix-ppc64": { "@esbuild/aix-ppc64": {
"version": "0.19.12", "version": "0.19.12",
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz",
@@ -1124,12 +1304,6 @@
"integrity": "sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg==", "integrity": "sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg==",
"dev": true "dev": true
}, },
"buffer-from": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
"dev": true
},
"esbuild": { "esbuild": {
"version": "0.15.15", "version": "0.15.15",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.15.15.tgz", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.15.15.tgz",
@@ -1272,16 +1446,6 @@
"dev": true, "dev": true,
"optional": true "optional": true
}, },
"esbuild-runner": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/esbuild-runner/-/esbuild-runner-2.2.1.tgz",
"integrity": "sha512-VP0VfJJZiZ3cKzdOH59ZceDxx/GzBKra7tiGM8MfFMLv6CR1/cpsvtQ3IsJI3pz7HyeYxtbPyecj3fHwR+3XcQ==",
"dev": true,
"requires": {
"source-map-support": "0.5.19",
"tslib": "2.3.1"
}
},
"esbuild-sunos-64": { "esbuild-sunos-64": {
"version": "0.15.15", "version": "0.15.15",
"resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.15.15.tgz", "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.15.15.tgz",
@@ -1343,28 +1507,6 @@
"integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==",
"dev": true "dev": true
}, },
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"dev": true
},
"source-map-support": {
"version": "0.5.19",
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz",
"integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==",
"dev": true,
"requires": {
"buffer-from": "^1.0.0",
"source-map": "^0.6.0"
}
},
"tslib": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==",
"dev": true
},
"tsx": { "tsx": {
"version": "4.7.0", "version": "4.7.0",
"resolved": "https://registry.npmjs.org/tsx/-/tsx-4.7.0.tgz", "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.7.0.tgz",

View File

@@ -28,6 +28,7 @@
"author": "Brandon Liu", "author": "Brandon Liu",
"license": "BSD-3-Clause", "license": "BSD-3-Clause",
"devDependencies": { "devDependencies": {
"@biomejs/biome": "^1.5.3",
"@types/node": "^18.11.9", "@types/node": "^18.11.9",
"esbuild": "^0.15.11", "esbuild": "^0.15.11",
"prettier": "^2.8.4", "prettier": "^2.8.4",

View File

@@ -1,20 +1,18 @@
import { test } from "node:test";
import assert from "node:assert"; import assert from "node:assert";
import { test } from "node:test";
import { import {
unshift, createDirectory,
deriveLeaf,
getUint24, getUint24,
getUint48, getUint48,
deriveLeaf, parseEntry,
queryLeafdir, queryLeafdir,
queryTile, queryTile,
parseEntry,
EntryV2,
createDirectory,
} from "../v2"; } from "../v2";
test("stub data", () => { test("stub data", () => {
let dataview = new DataView( const dataview = new DataView(
createDirectory([ createDirectory([
{ z: 5, x: 1000, y: 2000, offset: 1000, length: 2000, is_dir: false }, { z: 5, x: 1000, y: 2000, offset: 1000, length: 2000, is_dir: false },
{ {
@@ -27,18 +25,18 @@ test("stub data", () => {
}, },
]) ])
); );
var z_raw = dataview.getUint8(17 + 0); var zRaw = dataview.getUint8(17 + 0);
var x = getUint24(dataview, 17 + 1); var x = getUint24(dataview, 17 + 1);
var y = getUint24(dataview, 17 + 4); var y = getUint24(dataview, 17 + 4);
var offset = getUint48(dataview, 17 + 7); var offset = getUint48(dataview, 17 + 7);
var length = dataview.getUint32(17 + 13, true); var length = dataview.getUint32(17 + 13, true);
assert.strictEqual(z_raw, 14); assert.strictEqual(zRaw, 14);
assert.strictEqual(x, 16383); assert.strictEqual(x, 16383);
assert.strictEqual(y, 16383); assert.strictEqual(y, 16383);
}); });
test("get entry", () => { test("get entry", () => {
let view = new DataView( const view = new DataView(
createDirectory([ createDirectory([
{ z: 5, x: 1000, y: 2000, offset: 1000, length: 2000, is_dir: false }, { z: 5, x: 1000, y: 2000, offset: 1000, length: 2000, is_dir: false },
{ {
@@ -51,7 +49,7 @@ test("get entry", () => {
}, },
]) ])
); );
let entry = queryTile(view, 14, 16383, 16383); const entry = queryTile(view, 14, 16383, 16383);
assert.strictEqual(entry!.z, 14); assert.strictEqual(entry!.z, 14);
assert.strictEqual(entry!.x, 16383); assert.strictEqual(entry!.x, 16383);
assert.strictEqual(entry!.y, 16383); assert.strictEqual(entry!.y, 16383);
@@ -62,7 +60,7 @@ test("get entry", () => {
}); });
test("get leafdir", () => { test("get leafdir", () => {
let view = new DataView( const view = new DataView(
createDirectory([ createDirectory([
{ {
z: 14, z: 14,
@@ -74,7 +72,7 @@ test("get leafdir", () => {
}, },
]) ])
); );
let entry = queryLeafdir(view, 14, 16383, 16383); const entry = queryLeafdir(view, 14, 16383, 16383);
assert.strictEqual(entry!.z, 14); assert.strictEqual(entry!.z, 14);
assert.strictEqual(entry!.x, 16383); assert.strictEqual(entry!.x, 16383);
assert.strictEqual(entry!.y, 16383); assert.strictEqual(entry!.y, 16383);
@@ -118,7 +116,7 @@ test("derive the leaf level", () => {
}); });
test("convert spec v1 directory to spec v2 directory", () => { test("convert spec v1 directory to spec v2 directory", () => {
let view = new DataView( const view = new DataView(
createDirectory([ createDirectory([
{ {
z: 7, z: 7,

View File

@@ -1,20 +1,19 @@
import { test } from "node:test";
import assert from "node:assert";
import fs from "fs"; import fs from "fs";
import assert from "node:assert";
import { test } from "node:test";
import { import {
Entry,
zxyToTileId,
tileIdToZxy,
findTile,
readVarint,
SharedPromiseCache,
BufferPosition, BufferPosition,
Source, Entry,
RangeResponse,
EtagMismatch,
PMTiles, PMTiles,
RangeResponse,
SharedPromiseCache,
Source,
findTile,
getUint64, getUint64,
readVarint,
tileIdToZxy,
zxyToTileId,
} from "../index"; } from "../index";
test("varint", () => { test("varint", () => {

166
js/v2.ts
View File

@@ -1,12 +1,12 @@
import { decompressSync } from "fflate";
import { import {
Source,
Header,
Cache, Cache,
RangeResponse,
Compression, Compression,
Header,
RangeResponse,
Source,
TileType, TileType,
} from "./index"; } from "./index";
import { decompressSync } from "fflate";
export const shift = (n: number, shift: number) => { export const shift = (n: number, shift: number) => {
return n * Math.pow(2, shift); return n * Math.pow(2, shift);
@@ -60,14 +60,14 @@ export const queryLeafdir = (
x: number, x: number,
y: number y: number
): EntryV2 | null => { ): EntryV2 | null => {
const offset_len = queryView(view, z | 0x80, x, y); const offsetLen = queryView(view, z | 0x80, x, y);
if (offset_len) { if (offsetLen) {
return { return {
z: z, z: z,
x: x, x: x,
y: y, y: y,
offset: offset_len[0], offset: offsetLen[0],
length: offset_len[1], length: offsetLen[1],
is_dir: true, is_dir: true,
}; };
} }
@@ -75,14 +75,14 @@ export const queryLeafdir = (
}; };
export const queryTile = (view: DataView, z: number, x: number, y: number) => { export const queryTile = (view: DataView, z: number, x: number, y: number) => {
const offset_len = queryView(view, z, x, y); const offsetLen = queryView(view, z, x, y);
if (offset_len) { if (offsetLen) {
return { return {
z: z, z: z,
x: x, x: x,
y: y, y: y,
offset: offset_len[0], offset: offsetLen[0],
length: offset_len[1], length: offsetLen[1],
is_dir: false, is_dir: false,
}; };
} }
@@ -128,15 +128,15 @@ const entrySort = (a: EntryV2, b: EntryV2): number => {
}; };
export const parseEntry = (dataview: DataView, i: number): EntryV2 => { export const parseEntry = (dataview: DataView, i: number): EntryV2 => {
const z_raw = dataview.getUint8(i * 17); const zRaw = dataview.getUint8(i * 17);
const z = z_raw & 127; const z = zRaw & 127;
return { return {
z: z, z: z,
x: getUint24(dataview, i * 17 + 1), x: getUint24(dataview, i * 17 + 1),
y: getUint24(dataview, i * 17 + 4), y: getUint24(dataview, i * 17 + 4),
offset: getUint48(dataview, i * 17 + 7), offset: getUint48(dataview, i * 17 + 7),
length: dataview.getUint32(i * 17 + 13, true), length: dataview.getUint32(i * 17 + 13, true),
is_dir: z_raw >> 7 === 1, is_dir: zRaw >> 7 === 1,
}; };
}; };
@@ -188,11 +188,11 @@ export const deriveLeaf = (view: DataView, tile: Zxy): Zxy | null => {
const numEntries = view.byteLength / 17; const numEntries = view.byteLength / 17;
const entry = parseEntry(view, numEntries - 1); const entry = parseEntry(view, numEntries - 1);
if (entry.is_dir) { if (entry.is_dir) {
const leaf_level = entry.z; const leafLevel = entry.z;
const level_diff = tile.z - leaf_level; const levelDiff = tile.z - leafLevel;
const leaf_x = Math.trunc(tile.x / (1 << level_diff)); const leafX = Math.trunc(tile.x / (1 << levelDiff));
const leaf_y = Math.trunc(tile.y / (1 << level_diff)); const leafY = Math.trunc(tile.y / (1 << levelDiff));
return { z: leaf_level, x: leaf_x, y: leaf_y }; return { z: leafLevel, x: leafX, y: leafY };
} }
return null; return null;
}; };
@@ -202,57 +202,57 @@ async function getHeader(source: Source): Promise<Header> {
const dataview = new DataView(resp.data); const dataview = new DataView(resp.data);
const json_size = dataview.getUint32(4, true); const jsonSize = dataview.getUint32(4, true);
const root_entries = dataview.getUint16(8, true); const rootEntries = dataview.getUint16(8, true);
const dec = new TextDecoder("utf-8"); const dec = new TextDecoder("utf-8");
const json_metadata = JSON.parse( const jsonMetadata = JSON.parse(
dec.decode(new DataView(resp.data, 10, json_size)) dec.decode(new DataView(resp.data, 10, jsonSize))
); );
let tile_compression = Compression.Unknown; let tileCompression = Compression.Unknown;
if (json_metadata.compression === "gzip") { if (jsonMetadata.compression === "gzip") {
tile_compression = Compression.Gzip; tileCompression = Compression.Gzip;
} }
let minzoom = 0; let minzoom = 0;
if ("minzoom" in json_metadata) { if ("minzoom" in jsonMetadata) {
minzoom = +json_metadata.minzoom; minzoom = +jsonMetadata.minzoom;
} }
let maxzoom = 0; let maxzoom = 0;
if ("maxzoom" in json_metadata) { if ("maxzoom" in jsonMetadata) {
maxzoom = +json_metadata.maxzoom; maxzoom = +jsonMetadata.maxzoom;
} }
let center_lon = 0; let centerLon = 0;
let center_lat = 0; let centerLat = 0;
let center_zoom = 0; let centerZoom = 0;
let min_lon = -180.0; let minLon = -180.0;
let min_lat = -85.0; let minLat = -85.0;
let max_lon = 180.0; let maxLon = 180.0;
let max_lat = 85.0; let maxLat = 85.0;
if (json_metadata.bounds) { if (jsonMetadata.bounds) {
const split = json_metadata.bounds.split(","); const split = jsonMetadata.bounds.split(",");
min_lon = +split[0]; minLon = +split[0];
min_lat = +split[1]; minLat = +split[1];
max_lon = +split[2]; maxLon = +split[2];
max_lat = +split[3]; maxLat = +split[3];
} }
if (json_metadata.center) { if (jsonMetadata.center) {
const split = json_metadata.center.split(","); const split = jsonMetadata.center.split(",");
center_lon = +split[0]; centerLon = +split[0];
center_lat = +split[1]; centerLat = +split[1];
center_zoom = +split[2]; centerZoom = +split[2];
} }
const header = { const header = {
specVersion: dataview.getUint16(2, true), specVersion: dataview.getUint16(2, true),
rootDirectoryOffset: 10 + json_size, rootDirectoryOffset: 10 + jsonSize,
rootDirectoryLength: root_entries * 17, rootDirectoryLength: rootEntries * 17,
jsonMetadataOffset: 10, jsonMetadataOffset: 10,
jsonMetadataLength: json_size, jsonMetadataLength: jsonSize,
leafDirectoryOffset: 0, leafDirectoryOffset: 0,
leafDirectoryLength: undefined, leafDirectoryLength: undefined,
tileDataOffset: 0, tileDataOffset: 0,
@@ -262,17 +262,17 @@ async function getHeader(source: Source): Promise<Header> {
numTileContents: 0, numTileContents: 0,
clustered: false, clustered: false,
internalCompression: Compression.None, internalCompression: Compression.None,
tileCompression: tile_compression, tileCompression: tileCompression,
tileType: TileType.Mvt, tileType: TileType.Mvt,
minZoom: minzoom, minZoom: minzoom,
maxZoom: maxzoom, maxZoom: maxzoom,
minLon: min_lon, minLon: minLon,
minLat: min_lat, minLat: minLat,
maxLon: max_lon, maxLon: maxLon,
maxLat: max_lat, maxLat: maxLat,
centerZoom: center_zoom, centerZoom: centerZoom,
centerLon: center_lon, centerLon: centerLon,
centerLat: center_lat, centerLat: centerLat,
etag: resp.etag, etag: resp.etag,
}; };
return header; return header;
@@ -287,65 +287,65 @@ async function getZxy(
y: number, y: number,
signal?: AbortSignal signal?: AbortSignal
): Promise<RangeResponse | undefined> { ): Promise<RangeResponse | undefined> {
let root_dir = await cache.getArrayBuffer( let rootDir = await cache.getArrayBuffer(
source, source,
header.rootDirectoryOffset, header.rootDirectoryOffset,
header.rootDirectoryLength, header.rootDirectoryLength,
header header
); );
if (header.specVersion === 1) { if (header.specVersion === 1) {
root_dir = sortDir(root_dir); rootDir = sortDir(rootDir);
} }
const entry = queryTile(new DataView(root_dir), z, x, y); const entry = queryTile(new DataView(rootDir), z, x, y);
if (entry) { if (entry) {
const resp = await source.getBytes(entry.offset, entry.length, signal); const resp = await source.getBytes(entry.offset, entry.length, signal);
let tile_data = resp.data; let tileData = resp.data;
const view = new DataView(tile_data); const view = new DataView(tileData);
if (view.getUint8(0) == 0x1f && view.getUint8(1) == 0x8b) { if (view.getUint8(0) == 0x1f && view.getUint8(1) == 0x8b) {
tile_data = decompressSync(new Uint8Array(tile_data)); tileData = decompressSync(new Uint8Array(tileData));
} }
return { return {
data: tile_data, data: tileData,
}; };
} }
const leafcoords = deriveLeaf(new DataView(root_dir), { z: z, x: x, y: y }); const leafcoords = deriveLeaf(new DataView(rootDir), { z: z, x: x, y: y });
if (leafcoords) { if (leafcoords) {
const leafdir_entry = queryLeafdir( const leafdirEntry = queryLeafdir(
new DataView(root_dir), new DataView(rootDir),
leafcoords.z, leafcoords.z,
leafcoords.x, leafcoords.x,
leafcoords.y leafcoords.y
); );
if (leafdir_entry) { if (leafdirEntry) {
let leaf_dir = await cache.getArrayBuffer( let leafDir = await cache.getArrayBuffer(
source, source,
leafdir_entry.offset, leafdirEntry.offset,
leafdir_entry.length, leafdirEntry.length,
header header
); );
if (header.specVersion === 1) { if (header.specVersion === 1) {
leaf_dir = sortDir(leaf_dir); leafDir = sortDir(leafDir);
} }
const tile_entry = queryTile(new DataView(leaf_dir), z, x, y); const tileEntry = queryTile(new DataView(leafDir), z, x, y);
if (tile_entry) { if (tileEntry) {
const resp = await source.getBytes( const resp = await source.getBytes(
tile_entry.offset, tileEntry.offset,
tile_entry.length, tileEntry.length,
signal signal
); );
let tile_data = resp.data; let tileData = resp.data;
const view = new DataView(tile_data); const view = new DataView(tileData);
if (view.getUint8(0) == 0x1f && view.getUint8(1) == 0x8b) { if (view.getUint8(0) == 0x1f && view.getUint8(1) == 0x8b) {
tile_data = decompressSync(new Uint8Array(tile_data)); tileData = decompressSync(new Uint8Array(tileData));
} }
return { return {
data: tile_data, data: tileData,
}; };
} }
} }