Continue linting fixes [#287] (#332)

* make use of ===, if branches, let/const, string templates, var names consistent style.
This commit is contained in:
Brandon Liu
2024-01-29 17:41:12 +08:00
committed by GitHub
parent 3b61cc8b49
commit a6cbc1961e
6 changed files with 181 additions and 195 deletions

View File

@@ -17,17 +17,17 @@ export const leafletRasterLayer = (source: PMTiles, options: any) => {
}; };
if (!loaded) { if (!loaded) {
source.getHeader().then((header) => { source.getHeader().then((header) => {
if (header.tileType == TileType.Mvt) { if (header.tileType === TileType.Mvt) {
console.error( console.error(
"Error: archive contains MVT vector tiles, but leafletRasterLayer is for displaying raster tiles. See https://github.com/protomaps/PMTiles/tree/main/js for details." "Error: archive contains MVT vector tiles, but leafletRasterLayer is for displaying raster tiles. See https://github.com/protomaps/PMTiles/tree/main/js for details."
); );
} else if (header.tileType == 2) { } else if (header.tileType === 2) {
mimeType = "image/png"; mimeType = "image/png";
} else if (header.tileType == 3) { } else if (header.tileType === 3) {
mimeType = "image/jpeg"; mimeType = "image/jpeg";
} else if (header.tileType == 4) { } else if (header.tileType === 4) {
mimeType = "image/webp"; mimeType = "image/webp";
} else if (header.tileType == 5) { } else if (header.tileType === 5) {
mimeType = "image/avif"; mimeType = "image/avif";
} }
}); });
@@ -115,7 +115,7 @@ export class Protocol {
params: RequestParameters, params: RequestParameters,
callback: ResponseCallback callback: ResponseCallback
): Cancelable => { ): Cancelable => {
if (params.type == "json") { if (params.type === "json") {
const pmtilesUrl = params.url.substr(10); const pmtilesUrl = params.url.substr(10);
let instance = this.tiles.get(pmtilesUrl); let instance = this.tiles.get(pmtilesUrl);
if (!instance) { if (!instance) {
@@ -127,7 +127,7 @@ export class Protocol {
.getHeader() .getHeader()
.then((h) => { .then((h) => {
const tilejson = { const tilejson = {
tiles: [params.url + "/{z}/{x}/{y}"], tiles: [`${params.url}/{z}/{x}/{y}`],
minzoom: h.minZoom, minzoom: h.minZoom,
maxzoom: h.maxZoom, maxzoom: h.maxZoom,
bounds: [h.minLon, h.minLat, h.maxLon, h.maxLat], bounds: [h.minLon, h.minLat, h.maxLon, h.maxLat],
@@ -141,14 +141,11 @@ export class Protocol {
return { return {
cancel: () => {}, cancel: () => {},
}; };
} else { }
const re = new RegExp(/pmtiles:\/\/(.+)\/(\d+)\/(\d+)\/(\d+)/); const re = new RegExp(/pmtiles:\/\/(.+)\/(\d+)\/(\d+)\/(\d+)/);
const result = params.url.match(re); const result = params.url.match(re);
if (!result) { if (!result) {
throw new Error("Invalid PMTiles protocol URL"); throw new Error("Invalid PMTiles protocol URL");
return {
cancel: () => {},
};
} }
const pmtilesUrl = result[1]; const pmtilesUrl = result[1];
@@ -168,8 +165,8 @@ export class Protocol {
}; };
instance.getHeader().then((header) => { instance.getHeader().then((header) => {
instance! instance
.getZxy(+z, +x, +y, signal) ?.getZxy(+z, +x, +y, signal)
.then((resp) => { .then((resp) => {
if (resp) { if (resp) {
callback( callback(
@@ -179,7 +176,7 @@ export class Protocol {
resp.expires resp.expires
); );
} else { } else {
if (header.tileType == TileType.Mvt) { if (header.tileType === TileType.Mvt) {
callback(null, new Uint8Array(), null, null); callback(null, new Uint8Array(), null, null);
} else { } else {
callback(null, null, null, null); callback(null, null, null, null);
@@ -195,6 +192,5 @@ export class Protocol {
return { return {
cancel: cancel, cancel: cancel,
}; };
}
}; };
} }

View File

@@ -13,9 +13,8 @@ function toNum(low: number, high: number): number {
function readVarintRemainder(l: number, p: BufferPosition): number { function readVarintRemainder(l: number, p: BufferPosition): number {
const buf = p.buf; const buf = p.buf;
let h, b; let b = buf[p.pos++];
b = buf[p.pos++]; let h = (b & 0x70) >> 4;
h = (b & 0x70) >> 4;
if (b < 0x80) return toNum(l, h); if (b < 0x80) return toNum(l, h);
b = buf[p.pos++]; b = buf[p.pos++];
h |= (b & 0x7f) << 3; h |= (b & 0x7f) << 3;
@@ -37,10 +36,8 @@ function readVarintRemainder(l: number, p: BufferPosition): number {
export function readVarint(p: BufferPosition): number { export function readVarint(p: BufferPosition): number {
const buf = p.buf; const buf = p.buf;
let val, b; let b = buf[p.pos++];
let val = b & 0x7f;
b = buf[p.pos++];
val = b & 0x7f;
if (b < 0x80) return val; if (b < 0x80) return val;
b = buf[p.pos++]; b = buf[p.pos++];
val |= (b & 0x7f) << 7; val |= (b & 0x7f) << 7;
@@ -58,8 +55,8 @@ export function readVarint(p: BufferPosition): number {
} }
function rotate(n: number, xy: number[], rx: number, ry: number): void { function rotate(n: number, xy: number[], rx: number, ry: number): void {
if (ry == 0) { if (ry === 0) {
if (rx == 1) { if (rx === 1) {
xy[0] = n - 1 - xy[0]; xy[0] = n - 1 - xy[0];
xy[1] = n - 1 - xy[1]; xy[1] = n - 1 - xy[1];
} }
@@ -70,7 +67,7 @@ function rotate(n: number, xy: number[], rx: number, ry: number): void {
} }
function idOnLevel(z: number, pos: number): [number, number, number] { function idOnLevel(z: number, pos: number): [number, number, number] {
const n = Math.pow(2, z); const n = 2 ** z;
let rx = pos; let rx = pos;
let ry = pos; let ry = pos;
let t = pos; let t = pos;
@@ -99,12 +96,12 @@ export function zxyToTileId(z: number, x: number, y: number): number {
if (z > 26) { if (z > 26) {
throw Error("Tile zoom level exceeds max safe number limit (26)"); throw Error("Tile zoom level exceeds max safe number limit (26)");
} }
if (x > Math.pow(2, z) - 1 || y > Math.pow(2, z) - 1) { if (x > 2 ** z - 1 || y > 2 ** z - 1) {
throw Error("tile x/y outside zoom level bounds"); throw Error("tile x/y outside zoom level bounds");
} }
const acc = tzValues[z]; const acc = tzValues[z];
const n = Math.pow(2, z); const n = 2 ** z;
let rx = 0; let rx = 0;
let ry = 0; let ry = 0;
let d = 0; let d = 0;
@@ -161,20 +158,19 @@ async function defaultDecompress(
): Promise<ArrayBuffer> { ): Promise<ArrayBuffer> {
if (compression === Compression.None || compression === Compression.Unknown) { if (compression === Compression.None || compression === Compression.Unknown) {
return buf; return buf;
} else if (compression === Compression.Gzip) { }
if (typeof (globalThis as any).DecompressionStream == "undefined") { if (compression === Compression.Gzip) {
if (typeof (globalThis as any).DecompressionStream === "undefined") {
return decompressSync(new Uint8Array(buf)); return decompressSync(new Uint8Array(buf));
} else { }
const stream = new Response(buf).body!; const stream = new Response(buf).body!;
const 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();
} }
} else {
throw Error("Compression method not supported"); throw Error("Compression method not supported");
} }
}
export enum TileType { export enum TileType {
Unknown = 0, Unknown = 0,
@@ -310,10 +306,7 @@ export class FetchSource implements Source {
} }
const requestHeaders = new Headers(this.customHeaders); const requestHeaders = new Headers(this.customHeaders);
requestHeaders.set( requestHeaders.set("Range", `bytes=${offset}-${offset + length - 1}`);
"Range",
"bytes=" + offset + "-" + (offset + length - 1)
);
let resp = await fetch(this.url, { let resp = await fetch(this.url, {
signal: signal, signal: signal,
@@ -333,12 +326,12 @@ export class FetchSource implements Source {
const actualLength = +contentRange.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-" + (actualLength - 1) }, headers: { range: `bytes=0-${actualLength - 1}` },
}); });
} }
if (resp.status >= 300) { if (resp.status >= 300) {
throw Error("Bad response code: " + resp.status); throw Error(`Bad response code: ${resp.status}`);
} }
const contentLength = resp.headers.get("Content-Length"); const contentLength = resp.headers.get("Content-Length");
@@ -365,7 +358,7 @@ export class FetchSource implements Source {
export function getUint64(v: DataView, offset: number): number { export function getUint64(v: DataView, offset: number): number {
const wh = v.getUint32(offset + 4, true); const wh = v.getUint32(offset + 4, true);
const wl = v.getUint32(offset + 0, true); const wl = v.getUint32(offset + 0, true);
return wh * Math.pow(2, 32) + wl; return wh * 2 ** 32 + wl;
} }
export function bytesToHeader(bytes: ArrayBuffer, etag?: string): Header { export function bytesToHeader(bytes: ArrayBuffer, etag?: string): Header {
@@ -447,7 +440,8 @@ function detectVersion(a: ArrayBuffer): number {
"PMTiles spec version 2 has been deprecated; please see github.com/protomaps/PMTiles for tools to upgrade" "PMTiles spec version 2 has been deprecated; please see github.com/protomaps/PMTiles for tools to upgrade"
); );
return 2; return 2;
} else if (v.getUint16(2, true) === 1) { }
if (v.getUint16(2, true) === 1) {
console.warn( console.warn(
"PMTiles spec version 1 has been deprecated; please see github.com/protomaps/PMTiles for tools to upgrade" "PMTiles spec version 1 has been deprecated; please see github.com/protomaps/PMTiles for tools to upgrade"
); );
@@ -496,10 +490,9 @@ async function getHeaderAndRoot(
const headerData = resp.data.slice(0, HEADER_SIZE_BYTES); const headerData = resp.data.slice(0, HEADER_SIZE_BYTES);
let respEtag = resp.etag; let respEtag = resp.etag;
if (currentEtag && resp.etag != currentEtag) { 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()
); );
respEtag = undefined; respEtag = undefined;
} }
@@ -513,14 +506,9 @@ async function getHeaderAndRoot(
header.rootDirectoryOffset, header.rootDirectoryOffset,
header.rootDirectoryOffset + header.rootDirectoryLength header.rootDirectoryOffset + header.rootDirectoryLength
); );
const dirKey = const dirKey = `${source.getKey()}|${header.etag || ""}|${
source.getKey() + header.rootDirectoryOffset
"|" + }|${header.rootDirectoryLength}`;
(header.etag || "") +
"|" +
header.rootDirectoryOffset +
"|" +
header.rootDirectoryLength;
const rootDir = deserializeIndex( const rootDir = deserializeIndex(
await decompress(rootDirData, header.internalCompression) await decompress(rootDirData, header.internalCompression)
@@ -581,7 +569,7 @@ export class ResolvedValueCache {
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++;
const data = this.cache.get(cacheKey)!.data; const data = this.cache.get(cacheKey)?.data;
return data as Header; return data as Header;
} }
@@ -612,11 +600,12 @@ export class ResolvedValueCache {
length: number, length: number,
header: Header header: Header
): Promise<Entry[]> { ): Promise<Entry[]> {
const cacheKey = const cacheKey = `${source.getKey()}|${
source.getKey() + "|" + (header.etag || "") + "|" + offset + "|" + length; header.etag || ""
}|${offset}|${length}`;
if (this.cache.has(cacheKey)) { if (this.cache.has(cacheKey)) {
this.cache.get(cacheKey)!.lastUsed = this.counter++; this.cache.get(cacheKey)!.lastUsed = this.counter++;
const data = this.cache.get(cacheKey)!.data; const data = this.cache.get(cacheKey)?.data;
return data as Entry[]; return data as Entry[];
} }
@@ -642,11 +631,12 @@ export class ResolvedValueCache {
length: number, length: number,
header: Header header: Header
): Promise<ArrayBuffer> { ): Promise<ArrayBuffer> {
const cacheKey = const cacheKey = `${source.getKey()}|${
source.getKey() + "|" + (header.etag || "") + "|" + offset + "|" + length; header.etag || ""
}|${offset}|${length}`;
if (this.cache.has(cacheKey)) { if (this.cache.has(cacheKey)) {
this.cache.get(cacheKey)!.lastUsed = this.counter++; this.cache.get(cacheKey)!.lastUsed = this.counter++;
const data = await this.cache.get(cacheKey)!.data; const data = await this.cache.get(cacheKey)?.data;
return data as ArrayBuffer; return data as ArrayBuffer;
} }
@@ -716,7 +706,7 @@ export class SharedPromiseCache {
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++;
const data = await this.cache.get(cacheKey)!.data; const data = await this.cache.get(cacheKey)?.data;
return data as Header; return data as Header;
} }
@@ -746,11 +736,12 @@ export class SharedPromiseCache {
length: number, length: number,
header: Header header: Header
): Promise<Entry[]> { ): Promise<Entry[]> {
const cacheKey = const cacheKey = `${source.getKey()}|${
source.getKey() + "|" + (header.etag || "") + "|" + offset + "|" + length; header.etag || ""
}|${offset}|${length}`;
if (this.cache.has(cacheKey)) { if (this.cache.has(cacheKey)) {
this.cache.get(cacheKey)!.lastUsed = this.counter++; this.cache.get(cacheKey)!.lastUsed = this.counter++;
const data = await this.cache.get(cacheKey)!.data; const data = await this.cache.get(cacheKey)?.data;
return data as Entry[]; return data as Entry[];
} }
@@ -775,11 +766,12 @@ export class SharedPromiseCache {
length: number, length: number,
header: Header header: Header
): Promise<ArrayBuffer> { ): Promise<ArrayBuffer> {
const cacheKey = const cacheKey = `${source.getKey()}|${
source.getKey() + "|" + (header.etag || "") + "|" + offset + "|" + length; header.etag || ""
}|${offset}|${length}`;
if (this.cache.has(cacheKey)) { if (this.cache.has(cacheKey)) {
this.cache.get(cacheKey)!.lastUsed = this.counter++; this.cache.get(cacheKey)!.lastUsed = this.counter++;
const data = await this.cache.get(cacheKey)!.data; const data = await this.cache.get(cacheKey)?.data;
return data as ArrayBuffer; return data as ArrayBuffer;
} }
@@ -899,10 +891,9 @@ export class PMTiles {
cacheControl: resp.cacheControl, cacheControl: resp.cacheControl,
expires: resp.expires, expires: resp.expires,
}; };
} else { }
dO = header.leafDirectoryOffset + entry.offset; dO = header.leafDirectoryOffset + entry.offset;
dL = 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
// with empty data, but filled in cache control / expires headers // with empty data, but filled in cache control / expires headers
@@ -924,9 +915,8 @@ export class PMTiles {
if (e instanceof EtagMismatch) { if (e instanceof EtagMismatch) {
this.cache.invalidate(this.source, e.message); this.cache.invalidate(this.source, e.message);
return await this.getZxyAttempt(z, x, y, signal); return await this.getZxyAttempt(z, x, y, signal);
} else {
throw e;
} }
throw e;
} }
} }
@@ -955,9 +945,8 @@ export class PMTiles {
if (e instanceof EtagMismatch) { if (e instanceof EtagMismatch) {
this.cache.invalidate(this.source, e.message); this.cache.invalidate(this.source, e.message);
return await this.getMetadataAttempt(); return await this.getMetadataAttempt();
} else { }
throw e; throw e;
} }
} }
} }
}

View File

@@ -22,7 +22,8 @@
"test": "tsx test/index.test.ts", "test": "tsx test/index.test.ts",
"tsc": "tsc --noEmit --watch", "tsc": "tsc --noEmit --watch",
"prettier": "prettier --write *.ts test/*.ts", "prettier": "prettier --write *.ts test/*.ts",
"prettier-check": "prettier --check *.ts test/*.ts" "prettier-check": "prettier --check *.ts test/*.ts",
"biome": "biome check adapters.ts index.ts v2.ts test"
}, },
"homepage": "https://github.com/protomaps/pmtiles", "homepage": "https://github.com/protomaps/pmtiles",
"author": "Brandon Liu", "author": "Brandon Liu",

View File

@@ -14,22 +14,22 @@ import {
test("stub data", () => { test("stub data", () => {
const 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, isDir: false },
{ {
z: 14, z: 14,
x: 16383, x: 16383,
y: 16383, y: 16383,
offset: 999999, offset: 999999,
length: 999, length: 999,
is_dir: false, isDir: false,
}, },
]) ])
); );
var zRaw = dataview.getUint8(17 + 0); const zRaw = dataview.getUint8(17 + 0);
var x = getUint24(dataview, 17 + 1); const x = getUint24(dataview, 17 + 1);
var y = getUint24(dataview, 17 + 4); const y = getUint24(dataview, 17 + 4);
var offset = getUint48(dataview, 17 + 7); const offset = getUint48(dataview, 17 + 7);
var length = dataview.getUint32(17 + 13, true); const length = dataview.getUint32(17 + 13, true);
assert.strictEqual(zRaw, 14); assert.strictEqual(zRaw, 14);
assert.strictEqual(x, 16383); assert.strictEqual(x, 16383);
assert.strictEqual(y, 16383); assert.strictEqual(y, 16383);
@@ -38,24 +38,24 @@ test("stub data", () => {
test("get entry", () => { test("get entry", () => {
const 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, isDir: false },
{ {
z: 14, z: 14,
x: 16383, x: 16383,
y: 16383, y: 16383,
offset: 999999, offset: 999999,
length: 999, length: 999,
is_dir: false, isDir: false,
}, },
]) ])
); );
const 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);
assert.strictEqual(entry!.offset, 999999); assert.strictEqual(entry?.offset, 999999);
assert.strictEqual(entry!.length, 999); assert.strictEqual(entry?.length, 999);
assert.strictEqual(entry!.is_dir, false); assert.strictEqual(entry?.isDir, false);
assert.strictEqual(queryLeafdir(view, 14, 16383, 16383), null); assert.strictEqual(queryLeafdir(view, 14, 16383, 16383), null);
}); });
@@ -68,17 +68,17 @@ test("get leafdir", () => {
y: 16383, y: 16383,
offset: 999999, offset: 999999,
length: 999, length: 999,
is_dir: true, isDir: true,
}, },
]) ])
); );
const 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);
assert.strictEqual(entry!.offset, 999999); assert.strictEqual(entry?.offset, 999999);
assert.strictEqual(entry!.length, 999); assert.strictEqual(entry?.length, 999);
assert.strictEqual(entry!.is_dir, true); assert.strictEqual(entry?.isDir, true);
assert.strictEqual(queryTile(view, 14, 16383, 16383), null); assert.strictEqual(queryTile(view, 14, 16383, 16383), null);
}); });
@@ -91,14 +91,14 @@ test("derive the leaf level", () => {
y: 3, y: 3,
offset: 0, offset: 0,
length: 0, length: 0,
is_dir: true, isDir: true,
}, },
]) ])
); );
let leaf = deriveLeaf(view, { z: 7, x: 6, y: 6 }); let leaf = deriveLeaf(view, { z: 7, x: 6, y: 6 });
assert.strictEqual(leaf!.z, 6); assert.strictEqual(leaf?.z, 6);
assert.strictEqual(leaf!.x, 3); assert.strictEqual(leaf?.x, 3);
assert.strictEqual(leaf!.y, 3); assert.strictEqual(leaf?.y, 3);
view = new DataView( view = new DataView(
createDirectory([ createDirectory([
{ {
@@ -107,7 +107,7 @@ test("derive the leaf level", () => {
y: 3, y: 3,
offset: 0, offset: 0,
length: 0, length: 0,
is_dir: false, isDir: false,
}, },
]) ])
); );
@@ -124,7 +124,7 @@ test("convert spec v1 directory to spec v2 directory", () => {
y: 3, y: 3,
offset: 3, offset: 3,
length: 3, length: 3,
is_dir: true, isDir: true,
}, },
{ {
z: 6, z: 6,
@@ -132,7 +132,7 @@ test("convert spec v1 directory to spec v2 directory", () => {
y: 2, y: 2,
offset: 2, offset: 2,
length: 2, length: 2,
is_dir: false, isDir: false,
}, },
{ {
z: 6, z: 6,
@@ -140,21 +140,21 @@ test("convert spec v1 directory to spec v2 directory", () => {
y: 1, y: 1,
offset: 1, offset: 1,
length: 1, length: 1,
is_dir: false, isDir: false,
}, },
]) ])
); );
let entry = queryLeafdir(view, 7, 3, 3); let entry = queryLeafdir(view, 7, 3, 3);
assert.strictEqual(entry!.offset, 3); assert.strictEqual(entry?.offset, 3);
entry = queryTile(view, 6, 2, 2); entry = queryTile(view, 6, 2, 2);
assert.strictEqual(entry!.offset, 2); assert.strictEqual(entry?.offset, 2);
entry = queryTile(view, 6, 2, 1); entry = queryTile(view, 6, 2, 1);
assert.strictEqual(entry!.offset, 1); assert.strictEqual(entry?.offset, 1);
entry = parseEntry(view, 0); entry = parseEntry(view, 0);
assert.strictEqual(entry!.offset, 1); assert.strictEqual(entry?.offset, 1);
entry = parseEntry(view, 1); entry = parseEntry(view, 1);
assert.strictEqual(entry!.offset, 2); assert.strictEqual(entry?.offset, 2);
entry = parseEntry(view, 2); entry = parseEntry(view, 2);
assert.strictEqual(entry!.offset, 3); assert.strictEqual(entry?.offset, 3);
}); });

View File

@@ -64,8 +64,8 @@ test("a lot of tiles", () => {
}); });
test("tile extremes", () => { test("tile extremes", () => {
for (var z = 0; z < 27; z++) { for (let z = 0; z < 27; z++) {
const dim = Math.pow(2, z) - 1; const dim = 2 ** z - 1;
const tl = tileIdToZxy(zxyToTileId(z, 0, 0)); const tl = tileIdToZxy(zxyToTileId(z, 0, 0));
assert.deepEqual([z, 0, 0], tl); assert.deepEqual([z, 0, 0], tl);
const tr = tileIdToZxy(zxyToTileId(z, dim, 0)); const tr = tileIdToZxy(zxyToTileId(z, dim, 0));
@@ -100,9 +100,9 @@ test("tile search for first entry == id", () => {
const entries: Entry[] = [ const entries: Entry[] = [
{ tileId: 100, offset: 1, length: 1, runLength: 1 }, { tileId: 100, offset: 1, length: 1, runLength: 1 },
]; ];
const entry = findTile(entries, 100)!; const entry = findTile(entries, 100);
assert.strictEqual(entry.offset, 1); assert.strictEqual(entry?.offset, 1);
assert.strictEqual(entry.length, 1); assert.strictEqual(entry?.length, 1);
assert.strictEqual(findTile(entries, 101), null); assert.strictEqual(findTile(entries, 101), null);
}); });
@@ -111,32 +111,32 @@ test("tile search with runlength", () => {
{ tileId: 3, offset: 3, length: 1, runLength: 2 }, { tileId: 3, offset: 3, length: 1, runLength: 2 },
{ tileId: 5, offset: 5, length: 1, runLength: 2 }, { tileId: 5, offset: 5, length: 1, runLength: 2 },
]; ];
const entry = findTile(entries, 4)!; const entry = findTile(entries, 4);
assert.strictEqual(entry.offset, 3); assert.strictEqual(entry?.offset, 3);
}); });
test("tile search with multiple tile entries", () => { test("tile search with multiple tile entries", () => {
let entries: Entry[] = [{ tileId: 100, offset: 1, length: 1, runLength: 2 }]; let entries: Entry[] = [{ tileId: 100, offset: 1, length: 1, runLength: 2 }];
let entry = findTile(entries, 101)!; let entry = findTile(entries, 101);
assert.strictEqual(entry.offset, 1); assert.strictEqual(entry?.offset, 1);
assert.strictEqual(entry.length, 1); assert.strictEqual(entry?.length, 1);
entries = [ entries = [
{ tileId: 100, offset: 1, length: 1, runLength: 1 }, { tileId: 100, offset: 1, length: 1, runLength: 1 },
{ tileId: 150, offset: 2, length: 2, runLength: 2 }, { tileId: 150, offset: 2, length: 2, runLength: 2 },
]; ];
entry = findTile(entries, 151)!; entry = findTile(entries, 151);
assert.strictEqual(entry.offset, 2); assert.strictEqual(entry?.offset, 2);
assert.strictEqual(entry.length, 2); assert.strictEqual(entry?.length, 2);
entries = [ entries = [
{ tileId: 50, offset: 1, length: 1, runLength: 2 }, { tileId: 50, offset: 1, length: 1, runLength: 2 },
{ tileId: 100, offset: 2, length: 2, runLength: 1 }, { tileId: 100, offset: 2, length: 2, runLength: 1 },
{ tileId: 150, offset: 3, length: 3, runLength: 1 }, { tileId: 150, offset: 3, length: 3, runLength: 1 },
]; ];
entry = findTile(entries, 51)!; entry = findTile(entries, 51);
assert.strictEqual(entry.offset, 1); assert.strictEqual(entry?.offset, 1);
assert.strictEqual(entry.length, 1); assert.strictEqual(entry?.length, 1);
}); });
test("leaf search", () => { test("leaf search", () => {
@@ -144,8 +144,8 @@ test("leaf search", () => {
{ tileId: 100, offset: 1, length: 1, runLength: 0 }, { tileId: 100, offset: 1, length: 1, runLength: 0 },
]; ];
const entry = findTile(entries, 150); const entry = findTile(entries, 150);
assert.strictEqual(entry!.offset, 1); assert.strictEqual(entry?.offset, 1);
assert.strictEqual(entry!.length, 1); assert.strictEqual(entry?.length, 1);
}); });
// inefficient method only for testing // inefficient method only for testing

View File

@@ -9,11 +9,11 @@ import {
} from "./index"; } from "./index";
export const shift = (n: number, shift: number) => { export const shift = (n: number, shift: number) => {
return n * Math.pow(2, shift); return n * 2 ** shift;
}; };
export const unshift = (n: number, shift: number) => { export const unshift = (n: number, shift: number) => {
return Math.floor(n / Math.pow(2, shift)); return Math.floor(n / 2 ** shift);
}; };
export const getUint24 = (view: DataView, pos: number) => { export const getUint24 = (view: DataView, pos: number) => {
@@ -36,7 +36,7 @@ export interface EntryV2 {
y: number; y: number;
offset: number; offset: number;
length: number; length: number;
is_dir: boolean; isDir: boolean;
} }
const compare = ( const compare = (
@@ -46,11 +46,11 @@ const compare = (
view: DataView, view: DataView,
i: number i: number
) => { ) => {
if (tz != view.getUint8(i)) return tz - view.getUint8(i); if (tz !== view.getUint8(i)) return tz - view.getUint8(i);
const x = getUint24(view, i + 1); const x = getUint24(view, i + 1);
if (tx != x) return tx - x; if (tx !== x) return tx - x;
const y = getUint24(view, i + 4); const y = getUint24(view, i + 4);
if (ty != y) return ty - y; if (ty !== y) return ty - y;
return 0; return 0;
}; };
@@ -68,7 +68,7 @@ export const queryLeafdir = (
y: y, y: y,
offset: offsetLen[0], offset: offsetLen[0],
length: offsetLen[1], length: offsetLen[1],
is_dir: true, isDir: true,
}; };
} }
return null; return null;
@@ -83,7 +83,7 @@ export const queryTile = (view: DataView, z: number, x: number, y: number) => {
y: y, y: y,
offset: offsetLen[0], offset: offsetLen[0],
length: offsetLen[1], length: offsetLen[1],
is_dir: false, isDir: false,
}; };
} }
return null; return null;
@@ -112,10 +112,10 @@ const queryView = (
}; };
const entrySort = (a: EntryV2, b: EntryV2): number => { const entrySort = (a: EntryV2, b: EntryV2): number => {
if (a.is_dir && !b.is_dir) { if (a.isDir && !b.isDir) {
return 1; return 1;
} }
if (!a.is_dir && b.is_dir) { if (!a.isDir && b.isDir) {
return -1; return -1;
} }
if (a.z !== b.z) { if (a.z !== b.z) {
@@ -136,7 +136,7 @@ export const parseEntry = (dataview: DataView, i: number): EntryV2 => {
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: zRaw >> 7 === 1, isDir: zRaw >> 7 === 1,
}; };
}; };
@@ -157,7 +157,7 @@ export const createDirectory = (entries: EntryV2[]): ArrayBuffer => {
for (let i = 0; i < entries.length; i++) { for (let i = 0; i < entries.length; i++) {
const entry = entries[i]; const entry = entries[i];
let z = entry.z; let z = entry.z;
if (entry.is_dir) z = z | 0x80; if (entry.isDir) z = z | 0x80;
arr[i * 17] = z; arr[i * 17] = z;
arr[i * 17 + 1] = entry.x & 0xff; arr[i * 17 + 1] = entry.x & 0xff;
@@ -187,7 +187,7 @@ export const deriveLeaf = (view: DataView, tile: Zxy): Zxy | null => {
if (view.byteLength < 17) return null; if (view.byteLength < 17) return 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.isDir) {
const leafLevel = entry.z; const leafLevel = entry.z;
const levelDiff = tile.z - leafLevel; const levelDiff = tile.z - leafLevel;
const leafX = Math.trunc(tile.x / (1 << levelDiff)); const leafX = Math.trunc(tile.x / (1 << levelDiff));
@@ -303,7 +303,7 @@ async function getZxy(
let tileData = resp.data; let tileData = resp.data;
const view = new DataView(tileData); const view = new DataView(tileData);
if (view.getUint8(0) == 0x1f && view.getUint8(1) == 0x8b) { if (view.getUint8(0) === 0x1f && view.getUint8(1) === 0x8b) {
tileData = decompressSync(new Uint8Array(tileData)); tileData = decompressSync(new Uint8Array(tileData));
} }
@@ -341,7 +341,7 @@ async function getZxy(
let tileData = resp.data; let tileData = resp.data;
const view = new DataView(tileData); const view = new DataView(tileData);
if (view.getUint8(0) == 0x1f && view.getUint8(1) == 0x8b) { if (view.getUint8(0) === 0x1f && view.getUint8(1) === 0x8b) {
tileData = decompressSync(new Uint8Array(tileData)); tileData = decompressSync(new Uint8Array(tileData));
} }
return { return {