diff --git a/eleventy.config.js b/eleventy.config.js index 3083b2a..a27ff48 100644 --- a/eleventy.config.js +++ b/eleventy.config.js @@ -14,7 +14,7 @@ module.exports = eleventyConfig => { async ({ dir, results, runMode, outputMode }) => { await Promise.all([ esbuild.build({ - entryPoints: [`src/style.css`, `src/interface.ts`, `src/embed.ts`], + entryPoints: ["src/style.css", "src/interface.ts", "src/embed.ts"], outdir: output, format: "esm", bundle: true, @@ -24,7 +24,7 @@ module.exports = eleventyConfig => { //write: serve, }), esbuild.build({ - entryPoints: [`src/audio-worklet/audio-worklet.ts`], + entryPoints: ["src/audio-worklet/audio-worklet.ts"], outdir: output, format: "esm", bundle: true, diff --git a/src/audio-worklet/audio-worklet.ts b/src/audio-worklet/audio-worklet.ts index 6526785..6cfa26a 100644 --- a/src/audio-worklet/audio-worklet.ts +++ b/src/audio-worklet/audio-worklet.ts @@ -11,7 +11,7 @@ declare abstract class AudioWorkletProcessor { numberOfOutputs?: number; outputChannelCount: number[]; parameterData?: Record; - processorOptions?: any; + processorOptions?: unknown; }); abstract process( _inputs: Float32Array[][], @@ -24,15 +24,14 @@ declare function registerProcessor( processorCtor: Newable, ): void; -function safeStringify(value: any, quoteString?: boolean) { +function safeStringify(value: unknown, quoteString?: boolean) { if (!quoteString && typeof value === "string") { return value; - } else { - return JSON.stringify(value); } + return JSON.stringify(value); } -function getErrorMessage(err: any, time: number) { +function getErrorMessage(err: unknown, time: number) { if ( err instanceof Error && typeof err.lineNumber === "number" && @@ -44,21 +43,19 @@ function getErrorMessage(err: any, time: number) { return `${message} (at line ${err.lineNumber - 3}, character ${ err.columnNumber }, t=${time})`; - } else { - return `${message} (at line ${err.lineNumber - 3}, character ${err.columnNumber})`; - } - } else { - if (time !== undefined) { - return `Thrown: ${safeStringify(err, true)} (at t=${time})`; - } else { - return `Thrown: ${safeStringify(err, true)}`; } + return `${message} (at line ${err.lineNumber - 3}, character ${err.columnNumber})`; } + if (time !== undefined) { + return `Thrown: ${safeStringify(err, true)} (at t=${time})`; + } + return `Thrown: ${safeStringify(err, true)}`; } // replace Proxy so that they can be detected from the bytebeat code // this is completely undetectable by the bytebeat code const proxies = new WeakSet(); +// biome-ignore lint/suspicious/noGlobalAssign: required monkeypatch Proxy = Object.getPrototypeOf(Proxy).constructor = new Proxy(Proxy, { construct(target, args) { // @ts-expect-error @@ -66,7 +63,7 @@ Proxy = Object.getPrototypeOf(Proxy).constructor = new Proxy(Proxy, { proxies.add(newProxy); return newProxy; }, -}) +}); class BytebeatProcessor extends AudioWorkletProcessor { audioSample = 0; @@ -104,7 +101,7 @@ class BytebeatProcessor extends AudioWorkletProcessor { const data = e.data; // set vars - for (let v of ["songData", "sampleRateDivisor", "playSpeed"]) { + for (const v of ["songData", "sampleRateDivisor", "playSpeed"]) { if (data[v] !== undefined) { this[v] = data[v]; } @@ -222,7 +219,7 @@ class BytebeatProcessor extends AudioWorkletProcessor { this.port.postMessage({ updateUrl: true, errorMessage: null }); } updateSampleRatio() { - let flooredTimeOffset = isNaN(this.sampleRatio) + const flooredTimeOffset = isNaN(this.sampleRatio) ? 0 : this.lastFlooredTime - Math.floor(this.sampleRatio * this.audioSample); // TODO: this is the only use of global sampleRate, can it be removed? @@ -287,12 +284,11 @@ class BytebeatProcessor extends AudioWorkletProcessor { // @ts-expect-error if (proxies.has(v)) { return NaN; - } else { - // this does not cast BigInt, which matches the behaviour of - // placing it directly into a typed array - // @ts-expect-error - return +v; } + // this does not cast BigInt, which matches the behaviour of + // placing it directly into a typed array + // @ts-expect-error + return +v; } catch (err) { return NaN; } diff --git a/src/audio-worklet/clean-globals.ts b/src/audio-worklet/clean-globals.ts index 7e86e8e..c19ab18 100644 --- a/src/audio-worklet/clean-globals.ts +++ b/src/audio-worklet/clean-globals.ts @@ -23,7 +23,7 @@ export function freezeExistingGlobals() { // @ts-expect-error Object.getOwnPropertyNames(globalThis).forEach((k: string & keyof typeof globalThis) => { if (k !== "sampleRate") { - let t = typeof globalThis[k]; + const t = typeof globalThis[k]; if ((t === "object" || t === "function") && k !== "globalThis") { if (t === "function" && Object.hasOwnProperty.call(globalThis[k], "prototype")) { // @ts-expect-error diff --git a/src/audio-worklet/transform-code.ts b/src/audio-worklet/transform-code.ts index e260b43..e7511f3 100644 --- a/src/audio-worklet/transform-code.ts +++ b/src/audio-worklet/transform-code.ts @@ -9,19 +9,19 @@ function constEval(expression: string): string { let hadStart = false; const withoutStart = expression.replace( /^eval\s*\(\s*unescape\s*\(\s*escape/, - () => ((hadStart = true), ""), + () => {hadStart = true; return ""}, ); if (hadStart) { let hadEnd = false; const withoutEnd = withoutStart.replace( /\.replace\(\/u\(\.\.\)\/g,([`"'])\$1%\1\)\)\)$/, - () => ((hadEnd = true), ""), + () => {hadEnd = true; return ""}, ); if (hadEnd) { let hadParens = false; const content = withoutEnd.replace( /^\s*\((?.*)\)\s*$/s, - (_, content) => ((hadParens = true), content), + (_, content) => {hadParens = true; return content}, ); const part4 = content .trim() diff --git a/src/code-editor/codemirror.ts b/src/code-editor/codemirror.ts index b92c0c9..0d28042 100644 --- a/src/code-editor/codemirror.ts +++ b/src/code-editor/codemirror.ts @@ -37,7 +37,9 @@ function createCodemirror(inputListener?: () => void) { javascript(), syntaxHighlighting(classHighlighter), EditorView.updateListener.of(v => { - if (v.docChanged && inputListener) inputListener(); + if (v.docChanged && inputListener) { + inputListener(); + } }), ], }), diff --git a/src/code-editor/textarea.ts b/src/code-editor/textarea.ts index 623e550..2c1fd8c 100644 --- a/src/code-editor/textarea.ts +++ b/src/code-editor/textarea.ts @@ -13,19 +13,20 @@ export function initTextarea(editCallback: () => void, textarea: HTMLTextAreaEle const { selectionStart, selectionEnd } = textarea; if (e.shiftKey) { // remove indentation on all selected lines - let lines = textarea.value.split("\n"); + const lines = textarea.value.split("\n"); - let getLine = (char: number) => { + function getLine(char: number) { let line = 0; for (let c = 0; ; line++) { c += lines[line].length; - if (c > char) + if (c > char) { break; + } } return line; }; - let startLine = getLine(selectionStart); - let endLine = getLine(selectionEnd); + const startLine = getLine(selectionStart); + const endLine = getLine(selectionEnd); let newSelectionStart = selectionStart; let newSelectionEnd = selectionEnd; for (let i = startLine; i <= endLine; i++) { diff --git a/src/embed.ts b/src/embed.ts index 8346af5..341bf2f 100644 --- a/src/embed.ts +++ b/src/embed.ts @@ -39,11 +39,11 @@ window.addEventListener( e => { console.info("recieved message", e); if (isPlainObject(e.data)) { - const data: { [index: string]: any } = e.data; + const data: { [index: string]: unknown } = e.data; // show/hide elements if (isPlainObject(data["show"])) { for (const [name, fn, ...ids] of nameids) { - const show: { [index: string]: any } = data["show"]; + const show: { [index: string]: unknown } = data["show"]; if (show[name] !== undefined) { if (show[name]) { fn(true); diff --git a/src/interface.ts b/src/interface.ts index 0f14531..6b4f812 100644 --- a/src/interface.ts +++ b/src/interface.ts @@ -1,4 +1,4 @@ -import { sign0, f32ToRound10, isPlainObject, Song, SongMode, StrongPartial } from "./common.ts"; +import { sign0, f32ToRound10, isPlainObject, type Song, type SongMode, type StrongPartial } from "./common.ts"; import elements from "./elements.ts"; // this shouldn't need to load when useUrlData is false, // but if it was loaded conditionally then it can't inline diff --git a/src/library/load.ts b/src/library/load.ts index 64ec447..3ab25e2 100644 --- a/src/library/load.ts +++ b/src/library/load.ts @@ -1,4 +1,4 @@ -import { library, Entry, InlineEntry } from "./library.ts"; +import { library, type Entry, type InlineEntry } from "./library.ts"; import { setSong } from "../interface.ts"; function stripEntryToSong(entry: Entry) { @@ -55,7 +55,7 @@ function createEntryElem(entry: Entry) { for (const elem of songElems) { const songData = elem.dataset["songData"] ? JSON.parse(elem.dataset["songData"]) : {}; - const onclick = elem.dataset.hasOwnProperty("codeFile") + const onclick = Object.hasOwn(elem.dataset, "codeFile") ? () => fetch(`/library/${elem.dataset["codeFile"]}`) .then(response => response.text()) @@ -79,7 +79,7 @@ function createEntryElem(entry: Entry) { if (entry.author) { const authorListElem = document.createElement("span"); let authors = entry.author; - if (!(authors instanceof Array)) { + if (!Array.isArray(authors)) { authors = [authors]; } @@ -232,7 +232,7 @@ function createEntryElem(entry: Entry) { } if (entry.children) { - let childrenElem = document.createElement("ul"); + const childrenElem = document.createElement("ul"); for (const child of entry.children) { childrenElem.append(createEntryElem(child)); } diff --git a/src/url/mod.ts b/src/url/mod.ts index 563bb20..db774a2 100644 --- a/src/url/mod.ts +++ b/src/url/mod.ts @@ -36,7 +36,7 @@ export async function fromUrlData(hash: string): Promise { } else { // add "00" to shift over float bytes and set first 4 bits to 0100 data = Uint8Array.from( - atob("00" + hash.substring(2, 8)), + atob(`00${hash.substring(2, 8)}`), // @ts-ignore c => c.charCodeAt(), ); @@ -76,7 +76,8 @@ export async function fromUrlData(hash: string): Promise { ); return { code, sampleRate, mode }; - } else if (v === "v") { + } + if (v === "v") { // #v4, #v3b64 const dataString = atob(hash.substring(hash[2] === "4" ? 3 : 6)); @@ -90,7 +91,7 @@ export async function fromUrlData(hash: string): Promise { const songDataString = new TextDecoder().decode(inflateSync(dataBuffer)); let { code, sampleRate, mode } = JSON.parse(songDataString); - code = code + ""; + code += ""; sampleRate = Math.fround(sampleRate ?? 8000); mode = mode ?? "Bytebeat"; if (sampleRate < 2 || sampleRate >= 2 ** 24) { @@ -104,14 +105,12 @@ export async function fromUrlData(hash: string): Promise { } return { code, sampleRate, mode }; - } else { - console.error("Unrecognized url data"); - return; } } catch (err) { console.error("Couldn't load data from url:", err); return; } + console.error("Unrecognized url data"); } //version 6 breaks markdown and probably other things