Skip to content

Commit

Permalink
Return Type Improvements
Browse files Browse the repository at this point in the history
Added some more established function return types, and looked into additional type checking capabilities for the `DataTransferItem` type.

BenjaminAster/Better-TypeScript#3

Had the Service Worker TypeScript-ready again, but realized that would be a bit too much to change all at once, and I didn't want to implement too many things to where it would break something unexpectedly again.
  • Loading branch information
Offroaders123 committed May 21, 2023
1 parent 298fc6e commit fa85c53
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 38 deletions.
12 changes: 9 additions & 3 deletions public/service-worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@

var self = /** @type { ServiceWorkerGlobalScope } */ (/** @type { unknown } */ (globalThis));

const version = "Dovetail v1.6.0";
const NAME = "Dovetail";
const VERSION = "v1.6.1";
const CACHE_NAME = /** @type { const } */ (`${NAME} ${VERSION}`);

self.addEventListener("activate",event => {
event.waitUntil(removeOutdatedVersions());
Expand All @@ -15,12 +17,14 @@ self.addEventListener("fetch",event => {

/**
* Clears out old versions of the app from Cache Storage.
*
* @returns { Promise<void> }
*/
async function removeOutdatedVersions(){
const keys = await caches.keys();

await Promise.all(keys.map(async key => {
const isOutdatedVersion = key.startsWith("Dovetail ") && key !== version;
const isOutdatedVersion = key.startsWith(NAME) && key !== CACHE_NAME;

if (isOutdatedVersion){
await caches.delete(key);
Expand All @@ -36,6 +40,7 @@ async function removeOutdatedVersions(){
* If it hasn't been cached yet, it will fetch the network for a response, cache a clone, then return the response.
*
* @param { Request } request
* @returns { Promise<Response> }
*/
async function matchRequest(request){
let response = await caches.match(request);
Expand All @@ -52,8 +57,9 @@ async function matchRequest(request){
*
* @param { Request } request
* @param { Response } response
* @return { Promise<void> }
*/
async function cacheRequest(request,response){
const cache = await caches.open(version);
const cache = await caches.open(CACHE_NAME);
await cache.put(request,response.clone());
}
47 changes: 18 additions & 29 deletions src/app.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import "./compression-polyfill.js";
import { read, write, parse, stringify, Name, Endian, Compression, BedrockLevel, Int32, NBTData, NBTDataOptions, CompressionFormat } from "nbtify";
import { read, write, parse, stringify, Name, Endian, Compression, BedrockLevel, NBTData, NBTDataOptions, RootTag, Int32, CompressionFormat } from "nbtify";

if (window.isSecureContext){
await navigator.serviceWorker.register("./service-worker.js");
Expand Down Expand Up @@ -37,11 +37,12 @@ document.addEventListener("drop",async event => {
event.preventDefault();
if (event.dataTransfer === null) return;

const items = [...event.dataTransfer.items].filter(item => item.kind === "file");
const items = [...event.dataTransfer.items]
.filter((item): item is Omit<DataTransferItem,"getAsFile"> & { getAsFile(): File; } => item.kind === "file");
if (items.length === 0) return;

const [item] = items;
const file = item.getAsFile()!;
const file = item.getAsFile();
await openFile(file);
});

Expand Down Expand Up @@ -76,18 +77,10 @@ formatOpener.addEventListener("click",() => {
formatDialog.showModal();
});

// const demo = await fetch("../NBTify/test/nbt/ridiculous.nbt")
// .then(response => response.blob())
// .then(blob => new File([blob],"ridiculous.nbt"));

// await openFile(demo);

// formatOpener.click();

/**
* Attempts to read an NBT file, then open it in the editor.
*/
export async function openFile(file: File){
export async function openFile(file: File): Promise<void> {
saver.disabled = true;
formatOpener.disabled = true;
editor.disabled = true;
Expand Down Expand Up @@ -118,7 +111,7 @@ export interface FormatOptionsCollection extends HTMLFormControlsCollection {
/**
* Updates the Format Options dialog to match the NBT file's metadata.
*/
export function openOptions({ name, endian, compression, bedrockLevel }: NBTData){
export function openOptions({ name, endian, compression, bedrockLevel }: NBTData): NBTDataOptions {
const elements = formatForm.elements as FormatOptionsCollection;

if (name !== null){
Expand All @@ -134,23 +127,21 @@ export function openOptions({ name, endian, compression, bedrockLevel }: NBTData
elements.compression.value = (compression === null) ? "none" : compression;
elements.bedrockLevel.value = (bedrockLevel === null) ? "" : `${bedrockLevel}`;

const options: NBTDataOptions = { name, endian, compression, bedrockLevel };
return options;
return { name, endian, compression, bedrockLevel };
}

/**
* Attempts to create an NBTData object from a File object.
*/
export async function readFile(file: File){
export async function readFile<T extends RootTag = any>(file: File): Promise<NBTData<T> | null> {
const buffer = await file.arrayBuffer();
try {
const nbt = await read(buffer);
return nbt;
} catch (error: any){
if ((error as Error).message.includes("unread bytes remaining")){
return await read(buffer);
} catch (error: unknown){
if (error instanceof Error && error.message.includes("unread bytes remaining")){
const reattempt = confirm(`${error}\n\nEncountered extra data at the end of the file. Would you like to try opening it again without 'strict mode' enabled? The trailing data will be lost when re-saving your file again.`);
if (!reattempt) return null;
return read(buffer,{ strict: false });
return read<T>(buffer,{ strict: false });
} else {
alert(error);
return null;
Expand All @@ -161,22 +152,21 @@ export async function readFile(file: File){
/**
* Turns the values from the Format Options dialog into the NBT file's metadata.
*/
export function saveOptions(){
export function saveOptions(): NBTDataOptions {
const elements = formatForm.elements as FormatOptionsCollection;

const name: Name = (elements.disableName.checked) ? null : elements.name.value;
const endian: Endian = elements.endian.value as Endian;
const compression: Compression = (elements.compression.value === "none") ? null : elements.compression.value as CompressionFormat;
const bedrockLevel: BedrockLevel = (elements.bedrockLevel.value === "") ? null : new Int32(parseInt(elements.bedrockLevel.value));

const options: NBTDataOptions = { name, endian, compression, bedrockLevel };
return options;
return { name, endian, compression, bedrockLevel };
}

/**
* Shows the save file picker to the user.
*/
export function saveFile(file: File){
export function saveFile(file: File): void {
const anchor = document.createElement("a");
const blob = URL.createObjectURL(file);

Expand All @@ -190,7 +180,7 @@ export function saveFile(file: File){
/**
* Shows the file share menu to the user.
*/
export async function shareFile(file: File){
export async function shareFile(file: File): Promise<void> {
try {
await navigator.share({ files: [file] });
} catch (error){
Expand All @@ -201,8 +191,7 @@ export async function shareFile(file: File){
/**
* Creates a File object from an NBTData object.
*/
export async function writeFile(nbt: NBTData){
export async function writeFile(nbt: NBTData): Promise<File> {
const data = await write(nbt);
const file = new File([data],name);
return file;
return new File([data],name);
}
14 changes: 8 additions & 6 deletions src/compression-polyfill.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
export const usePolyfill: boolean = (() => {
/**
* Specifies whether the Compression Streams API must be polyfilled to run in the current browser.
*/
const usePolyfill: boolean = (() => {
try {
new CompressionStream("deflate-raw");
new DecompressionStream("deflate-raw");
Expand All @@ -9,14 +12,13 @@ export const usePolyfill: boolean = (() => {
})();

if (usePolyfill){
const {
makeCompressionStream,
makeDecompressionStream
} = await import("compression-streams-polyfill/ponyfill");
const { makeCompressionStream, makeDecompressionStream } = await import("compression-streams-polyfill/ponyfill");

const CompressionStream = makeCompressionStream(TransformStream);
const DecompressionStream = makeDecompressionStream(TransformStream);

globalThis.CompressionStream = CompressionStream as typeof globalThis.CompressionStream;
globalThis.DecompressionStream = DecompressionStream as typeof globalThis.DecompressionStream;
}
}

export default usePolyfill;

0 comments on commit fa85c53

Please sign in to comment.