Toggle stricter compilation rules in tsconfig

Now the whole codebase needs to be fixed. Every file.
This commit is contained in:
2024-04-19 22:25:04 +02:00
parent 75481e19f0
commit d3ac9f19a2
11 changed files with 150 additions and 114 deletions

2
global.d.ts vendored
View File

@ -1 +1,3 @@
/// <reference types="vite-plugin-pwa/client" />

View File

@ -11,7 +11,7 @@ import * as Ziffers from './Ziffers';
import * as Filters from './Time/Filters';
import * as LFO from './LFO';
import * as Probability from './Probabilities';
import * as OSC from './OSC';
import * as OSC from './IO/OSC';
import * as Randomness from './Randomness';
import * as Counter from './Counter';
import * as Sound from './Sound';

View File

@ -1,14 +1,46 @@
import { OscilloscopeConfig } from "../../DOM/Visuals/Oscilloscope";
import { ShapeObject, createConicGradient, createLinearGradient, createRadialGradient, drawBackground, drawBox, drawBall, drawBalloid, drawDonut, drawEquilateral, drawImage, drawPie, drawSmiley, drawStar, drawStroke, drawText, drawTriangular } from "../DOM/Visuals/CanvasVisuals";
import { createConicGradient, createLinearGradient, createRadialGradient, drawBackground, drawBox, drawBall, drawBalloid, drawDonut, drawEquilateral, drawImage, drawPie, drawSmiley, drawStar, drawStroke, drawText, drawTriangular } from "../../DOM/Visuals/CanvasVisuals";
import { Editor } from "../../main";
export type ShapeObject = {
x: number;
y: number;
x1: number;
y1: number;
x2: number;
y2: number;
radius: number;
width: number;
height: number;
fillStyle: string;
secondary: string;
strokeStyle: string;
rotation: number;
points: number;
outerRadius: number;
eyeSize: number;
happiness: number;
slices: number;
gap: number;
font: string;
fontSize: number;
text: string;
filter: string;
url: string;
curve: number;
curves: number;
stroke: string;
eaten: number;
hole: number;
};
export const loadHydra = (app: Editor) => (): void => {
app.ensureHydraLoaded()
}
export const w = (app: Editor) => (): number => {
const canvas: HTMLCanvasElement = app.interface.feedback as HTMLCanvasElement;
const canvas: HTMLCanvasElement = app.interface["feedback"] as HTMLCanvasElement;
return canvas.clientWidth;
};
@ -17,7 +49,7 @@ export const pulseLocation = (app: Editor) => (): number => {
};
export const clear = (app: Editor) => (): boolean => {
const canvas: HTMLCanvasElement = app.interface.feedback as HTMLCanvasElement;
const canvas: HTMLCanvasElement = app.interface["feedback"] as HTMLCanvasElement;
const ctx = canvas.getContext("2d")!;
ctx.clearRect(0, 0, canvas.width, canvas.height);
return true;
@ -25,7 +57,7 @@ export const clear = (app: Editor) => (): boolean => {
export const h = (app: Editor) => (): number => {
const canvas: HTMLCanvasElement = app.interface.feedback as HTMLCanvasElement;
const canvas: HTMLCanvasElement = app.interface["feedback"] as HTMLCanvasElement;
return canvas.clientHeight;
};
@ -38,28 +70,28 @@ export const wc = (app: Editor) => (): number => {
};
export const background = (app: Editor) => (color: string | number, ...gb: number[]): boolean => {
drawBackground(app.interface.feedback as HTMLCanvasElement, color, ...gb);
drawBackground(app.interface["feedback"] as HTMLCanvasElement, color, ...gb);
return true;
};
export const bg = background;
export const linearGradient = (app: Editor) => (x1: number, y1: number, x2: number, y2: number, ...stops: (number | string)[]): CanvasGradient => {
return createLinearGradient(app.interface.feedback as HTMLCanvasElement, x1, y1, x2, y2, ...stops);
return createLinearGradient(app.interface["feedback"] as HTMLCanvasElement, x1, y1, x2, y2, ...stops);
};
export const radialGradient = (app: Editor) => (x1: number, y1: number, r1: number, x2: number, y2: number, r2: number, ...stops: (number | string)[]) => {
return createRadialGradient(app.interface.feedback as HTMLCanvasElement, x1, y1, r1, x2, y2, r2, ...stops);
return createRadialGradient(app.interface["feedback"] as HTMLCanvasElement, x1, y1, r1, x2, y2, r2, ...stops);
};
export const conicGradient = (app: Editor) => (x: number, y: number, angle: number, ...stops: (number | string)[]) => {
return createConicGradient(app.interface.feedback as HTMLCanvasElement, x, y, angle, ...stops);
return createConicGradient(app.interface["feedback"] as HTMLCanvasElement, x, y, angle, ...stops);
};
export const draw = (app: Editor) => (func: Function): boolean => {
if (typeof func === "string") {
drawText(app.interface.feedback as HTMLCanvasElement, func, 24, 0, "Arial", wc(app)(), hc(app)(), "white", "none");
drawText(app.interface["feedback"] as HTMLCanvasElement, func, 24, 0, "Arial", wc(app)(), hc(app)(), "white", "none");
} else {
const canvas: HTMLCanvasElement = app.interface.feedback as HTMLCanvasElement;
const canvas: HTMLCanvasElement = app.interface["feedback"] as HTMLCanvasElement;
const ctx = canvas.getContext("2d")!;
func(ctx);
}
@ -84,7 +116,7 @@ export const balloid = (app: Editor) => (
radius = curves.radius || hc(app)() / 2;
curves = curves.curves || 6;
}
drawBalloid(app.interface.feedback as HTMLCanvasElement, curves, radius, curve, fillStyle, secondary, x, y);
drawBalloid(app.interface["feedback"] as HTMLCanvasElement, curves, radius, curve, fillStyle, secondary, x, y);
return true;
};
@ -102,7 +134,7 @@ export const equilateral = (app: Editor) => (
rotation = radius.rotation || 0;
radius = radius.radius || hc(app)() / 3;
}
drawEquilateral(app.interface.feedback as HTMLCanvasElement, radius, fillStyle, rotation, x, y);
drawEquilateral(app.interface["feedback"] as HTMLCanvasElement, radius, fillStyle, rotation, x, y);
return true;
};
@ -122,7 +154,7 @@ export const triangular = (app: Editor) => (
height = width.height || hc(app)() / 3;
width = width.width || hc(app)() / 3;
}
drawTriangular(app.interface.feedback as HTMLCanvasElement, width, height, fillStyle, rotation, x, y);
drawTriangular(app.interface['feedback'] as HTMLCanvasElement, width, height, fillStyle, rotation, x, y);
return true;
};
export const pointy = triangular;
@ -139,7 +171,7 @@ export const ball = (app: Editor) => (
y = radius.y || hc(app)();
radius = radius.radius || hc(app)() / 3;
}
drawBall(app.interface.feedback as HTMLCanvasElement, radius, fillStyle, x, y);
drawBall(app.interface['feedback'] as HTMLCanvasElement, radius, fillStyle, x, y);
return true;
};
export const circle = ball;
@ -168,7 +200,7 @@ export const donut = (app: Editor) => (
stroke = slices.stroke || "black";
slices = slices.slices || 3;
}
drawDonut(app.interface.feedback as HTMLCanvasElement, slices, eaten, radius, hole, fillStyle, secondary, stroke, rotation, x, y);
drawDonut(app.interface['feedback'] as HTMLCanvasElement, slices, eaten, radius, hole, fillStyle, secondary, stroke, rotation, x, y);
return true;
};
@ -194,7 +226,7 @@ export const pie = (app: Editor) => (
eaten = slices.eaten || 0;
slices = slices.slices || 3;
}
drawPie(app.interface.feedback as HTMLCanvasElement, slices, eaten, radius, fillStyle, secondary, stroke, rotation, x, y);
drawPie(app.interface['feedback'] as HTMLCanvasElement, slices, eaten, radius, fillStyle, secondary, stroke, rotation, x, y);
return true;
};
@ -216,7 +248,7 @@ export const star = (app: Editor) => (
outerRadius = points.outerRadius || radius / 100;
points = points.points || 5;
}
drawStar(app.interface.feedback as HTMLCanvasElement, points, radius, fillStyle, rotation, outerRadius, x, y);
drawStar(app.interface['feedback'] as HTMLCanvasElement, points, radius, fillStyle, rotation, outerRadius, x, y);
return true;
};
@ -238,7 +270,7 @@ export const stroke = (app: Editor) => (
rotation = width.rotation || 0;
width = width.width || 1;
}
drawStroke(app.interface.feedback as HTMLCanvasElement, width, strokeStyle, rotation, x1, y1, x2, y2);
drawStroke(app.interface['feedback'] as HTMLCanvasElement, width, strokeStyle, rotation, x1, y1, x2, y2);
return true;
};
@ -258,7 +290,7 @@ export const box = (app: Editor) => (
height = width.height || wc(app)() / 4;
width = width.width || wc(app)() / 4;
}
drawBox(app.interface.feedback as HTMLCanvasElement, width, height, fillStyle, rotation, x, y);
drawBox(app.interface['feedback'] as HTMLCanvasElement, width, height, fillStyle, rotation, x, y);
return true;
};
@ -280,7 +312,7 @@ export const smiley = (app: Editor) => (
radius = happiness.radius || hc(app)() / 3;
happiness = happiness.happiness || 0;
}
drawSmiley(app.interface.feedback as HTMLCanvasElement, happiness, radius, eyeSize, fillStyle, rotation, x, y);
drawSmiley(app.interface['feedback'] as HTMLCanvasElement, happiness, radius, eyeSize, fillStyle, rotation, x, y);
return true;
};
@ -304,7 +336,7 @@ export const text = (app: Editor) => (
filter = text.filter || "none";
text = text.text || "";
}
drawText(app.interface.feedback as HTMLCanvasElement, text, fontSize, rotation, font, x, y, fillStyle, filter);
drawText(app.interface['feedback'] as HTMLCanvasElement, text, fontSize, rotation, font, x, y, fillStyle, filter);
return true;
};
@ -327,7 +359,7 @@ export const image = (app: Editor) => (
filter = url.filter || "none";
url = url.url || "";
}
drawImage(app.interface.feedback as HTMLCanvasElement, url, width, height, rotation, x, y, filter);
drawImage(app.interface['feedback'] as HTMLCanvasElement, url, width, height, rotation, x, y, filter);
return true;
};

View File

@ -12,7 +12,9 @@ export const themeName = (app: Editor) => (): string => {
export const randomTheme = (app: Editor) => (): void => {
let theme_names = getThemes()();
let selected_theme = theme_names[Math.floor(Math.random() * theme_names.length)];
app.readTheme(selected_theme);
if (selected_theme) {
app.readTheme(selected_theme);
}
};
export const nextTheme = (app: Editor) => (): void => {
@ -21,7 +23,7 @@ export const nextTheme = (app: Editor) => (): void => {
let current_theme_idx = theme_names.indexOf(current_theme);
let next_theme_idx = (current_theme_idx + 1) % theme_names.length;
let next_theme = theme_names[next_theme_idx];
app.readTheme(next_theme);
app.readTheme(next_theme!);
app.api.log(next_theme);
};

View File

@ -2,10 +2,10 @@ import { getAllScaleNotes } from 'zifferjs';
import {
MidiCCEvent,
MidiNoteEvent,
} from "../IO/MidiConnection";
import { MidiEvent, MidiParams } from "../Classes/MidiEvent";
import { UserAPI } from './API';
import { Editor } from '../main';
} from "../../IO/MidiConnection";
import { MidiEvent, MidiParams } from "../../Classes/MidiEvent";
import { UserAPI } from '../API';
import { Editor } from '../../main';
interface ControlChange {
channel: number;
@ -136,9 +136,9 @@ export const last_note = (api: UserAPI) => (channel?: number): number => {
export const ccIn = (api: UserAPI) => (control: number, channel?: number): number => {
if (channel) {
if (api.MidiConnection.lastCCInChannel[channel]) {
return api.MidiConnection.lastCCInChannel[channel][control];
return api.MidiConnection.lastCCInChannel[channel]?.[control] ?? 0;
} else return 0;
} else return api.MidiConnection.lastCC[control] || 0;
} else return api.MidiConnection.lastCC[control] ?? 0;
};
export const has_cc = (api: UserAPI) => (channel?: number): boolean => {

View File

@ -1,6 +1,6 @@
import { sendToServer, type OSCMessage } from "../IO/OSC";
import { Editor } from "../main";
import { oscMessages } from "../IO/OSC";
import { sendToServer, type OSCMessage } from "../../IO/OSC";
import { Editor } from "../../main";
import { oscMessages } from "../../IO/OSC";
export const osc = (app: Editor) => (address: string, port: number, ...args: any[]): void => {
/**

View File

@ -10,7 +10,7 @@ const _euclidean_cycle = (
function startsDescent(list: number[], i: number): boolean {
const length = list.length;
const nextIndex = (i + 1) % length;
return list[i] > list[nextIndex] ? true : false;
return list[i]! > list[nextIndex]!? true : false;
}
if (pulses >= length) return [true];
const resList = Array.from(
@ -61,7 +61,7 @@ export const beat = (app: Editor) => (n: number | number[] = 1, nudge: number =
export const bar = (app: Editor) => (n: number | number[] = 1, nudge: number = 0): boolean => {
const nArray = Array.isArray(n) ? n : [n];
const barLength = app.clock.time_signature[1] * app.clock.ppqn;
const barLength = (app.clock.time_signature?.[1] ?? 4) * app.clock.ppqn;
const nudgeInPulses = Math.floor(nudge * barLength);
const results: boolean[] = nArray.map(
(value) =>
@ -111,7 +111,7 @@ export const flipbar = (app: Editor) => (chunk: number = 1): boolean => {
export const onbar = (app: Editor) => (
bars: number[] | number,
n: number = app.clock.time_signature[0],
n: number = app.clock.time_signature[0] || 4,
): boolean => {
let current_bar = (app.clock.time_position.bar % n) + 1;
return typeof bars === "number"
@ -161,7 +161,8 @@ export const euclid = () => (iterator: number, pulses: number, length: number, r
/**
* Returns a Euclidean cycle of size length, with n pulses, rotated or not.
*/
return _euclidean_cycle(pulses, length, rotate)[iterator % length];
const cycle = _euclidean_cycle(pulses, length, rotate);
return cycle && cycle[iterator % length] === true;
};
export const ec = euclid;
@ -192,7 +193,7 @@ export const bin = () => (iterator: number, n: number): boolean => {
*/
let convert: string = n.toString(2);
let tobin: boolean[] = convert.split("").map((x: string) => x === "1");
return tobin[iterator % tobin.length];
return tobin[iterator % tobin.length] || false;
};
export const binrhythm = (app: Editor) => (div: number, n: number): boolean => {

View File

@ -1,35 +1,3 @@
export type ShapeObject = {
x: number;
y: number;
x1: number;
y1: number;
x2: number;
y2: number;
radius: number;
width: number;
height: number;
fillStyle: string;
secondary: string;
strokeStyle: string;
rotation: number;
points: number;
outerRadius: number;
eyeSize: number;
happiness: number;
slices: number;
gap: number;
font: string;
fontSize: number;
text: string;
filter: string;
url: string;
curve: number;
curves: number;
stroke: string;
eaten: number;
hole: number;
};
export const drawBackground = (
canvas: HTMLCanvasElement,
color: string | number,
@ -60,7 +28,7 @@ export const createLinearGradient = (
let color = stops[i + 1];
if (typeof color === "number")
color = `rgb(${color},${stops[i + 2]},${stops[i + 3]})`;
gradient.addColorStop(stops[i] as number, color);
gradient.addColorStop(stops[i] as number, color as string);
}
return gradient;
};
@ -91,7 +59,7 @@ export const createRadialGradient = (
let color = stops[i + 1];
if (typeof color === "number")
color = `rgb(${color},${stops[i + 2]},${stops[i + 3]})`;
gradient.addColorStop(stops[i] as number, color);
gradient.addColorStop(stops[i] as number, color as string);
}
return gradient;
};
@ -116,7 +84,7 @@ export const createConicGradient = (
let color = stops[i + 1];
if (typeof color === "number")
color = `rgb(${color},${stops[i + 2]},${stops[i + 3]})`;
gradient.addColorStop(stops[i] as number, color);
gradient.addColorStop(stops[i] as number, color as string);
}
return gradient;
};
@ -221,10 +189,11 @@ export const drawBalloid = (
ctx.beginPath();
ctx.fillStyle = secondary;
// Form the shape from points with straight lines and fill it
ctx.moveTo(points[0][0], points[0][1]);
for (let point of points) ctx.lineTo(point[0], point[1]);
if (points[0]) {
ctx.moveTo(points[0][0] as number, points[0][1] as number);
for (let point of points) ctx.lineTo(point[0] as number, point[1] as number);
}
// Close and fill
ctx.closePath();
ctx.fill();
}

View File

@ -104,7 +104,13 @@ export class MidiConnection {
this.currentOutputIndex >= 0 &&
this.currentOutputIndex < this.midiOutputs.length
) {
return this.midiOutputs[this.currentOutputIndex].name;
const output = this.midiOutputs[this.currentOutputIndex];
if (output) {
return output.name;
} else {
console.error("MIDI output is undefined.");
return null;
}
} else {
console.error("No MIDI output selected or available.");
return null;
@ -253,7 +259,7 @@ export class MidiConnection {
this.midiClockInput = this.midiInputs[clockInputIndex];
this.registerMidiInputListener(clockInputIndex);
this.settings.midi_clock_input =
this.midiClockInput.name || undefined;
this.midiClockInput?.name ?? undefined;
}
});
@ -277,7 +283,7 @@ export class MidiConnection {
this.currentInputIndex = parseInt(value);
this.registerMidiInputListener(this.currentInputIndex);
this.settings.default_midi_input =
this.midiInputs[this.currentInputIndex].name || undefined;
this.midiInputs[this.currentInputIndex]?.name || undefined;
}
});
}

View File

@ -125,7 +125,7 @@ export class Editor {
this.initializeElements();
this.initializeButtonGroups();
this.setCanvas(this.interface.feedback as HTMLCanvasElement);
this.setCanvas(this.interface["feedback"] as HTMLCanvasElement);
// this.loadHydraSynthAsync();
// ================================================================================
@ -193,10 +193,10 @@ export class Editor {
// ================================================================================
installEditor(this);
runOscilloscope(this.interface.feedback as HTMLCanvasElement, this);
runOscilloscope(this.interface['feedback'] as HTMLCanvasElement, this);
// First evaluation of the init file
tryEvaluate(this, this.universes[this.selected_universe.toString()].init);
tryEvaluate(this, this.universes[this.selected_universe.toString()]!.init);
// Changing to global when opening
this.changeModeFromInterface("global");
@ -234,8 +234,8 @@ export class Editor {
*/
const universe = this.universes[this.selected_universe.toString()];
return type === "locals"
? universe[type][this.local_index]
: universe[type as keyof Universe];
? universe![type][this.local_index]
: universe![type as keyof Universe];
}
get note_buffer() {
@ -313,10 +313,10 @@ export class Editor {
const tab = tabs[i] as HTMLElement;
tab.classList.add("bg-foreground");
for (let j = 0; j < tabs.length; j++) {
if (j != i) tabs[j].classList.remove("bg-foreground");
if (j !== i && tabs[j]) tabs[j]!.classList.remove("bg-foreground");
}
let tab_id = tab.id.split("-")[1];
this.local_index = parseInt(tab_id);
this.local_index = parseInt(tab_id as string);
this.updateEditorView();
}
@ -327,10 +327,10 @@ export class Editor {
* @param mode - The mode to change to. Can be one of "global", "local", "init", or "notes".
*/
const interface_buttons: HTMLElement[] = [
this.interface.local_button,
this.interface.global_button,
this.interface.init_button,
this.interface.note_button,
(this.interface['local_button'] as HTMLElement),
(this.interface['global_button'] as HTMLElement),
(this.interface['init_button'] as HTMLElement),
(this.interface['note_button'] as HTMLElement),
];
let changeColor = (button: HTMLElement) => {
@ -341,16 +341,16 @@ export class Editor {
button.classList.remove("text-foreground_selection");
}
});
button.children[0].classList.remove("text-white");
button.children[0].classList.add("text-foreground_selection");
button.children[0]!.classList.remove("text-white");
button.children[0]!.classList.add("text-foreground_selection");
button.classList.add("text-foreground_selection");
button.classList.add("fill-foreground_selection");
};
switch (mode) {
case "local":
if (this.interface.local_script_tabs.classList.contains("hidden")) {
this.interface.local_script_tabs.classList.remove("hidden");
if (this.interface['local_script_tabs']!.classList.contains("hidden")) {
this.interface['local_script_tabs']!.classList.remove("hidden");
}
this.editor_mode = "local";
this.local_index = 0;
@ -459,8 +459,10 @@ export class Editor {
unfocusPlayButtons() {
document.querySelectorAll('[id^="play-button-"]').forEach((button) => {
button.children[0].classList.remove("fill-foreground_selection");
button.children[0].classList.remove("animate-pulse");
if (button.children[0]) {
button.children[0].classList.remove("fill-foreground_selection");
button.children[0].classList.remove("animate-pulse");
}
});
}
@ -585,7 +587,7 @@ export class Editor {
*/
// @ts-ignore
this.hydra_backend = new Hydra({
canvas: this.interface.hydra_canvas as HTMLCanvasElement,
canvas: this.interface["hydra_canvas"] as HTMLCanvasElement,
detectAudio: false,
enableStreamCapture: false,
});
@ -612,9 +614,9 @@ export class Editor {
function hexToRgb(hex: string): { r: number, g: number, b: number } | null {
let result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
return result ? {
r: parseInt(result[1], 16),
g: parseInt(result[2], 16),
b: parseInt(result[3], 16)
r: parseInt(result[1] || '0', 16),
g: parseInt(result[2] || '0', 16),
b: parseInt(result[3] || '0', 16)
} : null;
};
for (const [key, value] of Object.entries(selected_theme)) {
@ -628,8 +630,8 @@ export class Editor {
getColorScheme(theme_name: string): { [key: string]: string } {
// Check if the theme exists in colors.json
let themes: Record<string, { [key: string]: any }> = colors;
return themes[theme_name];
let themes: Record<string, { [key: string]: string }> = colors;
return themes[theme_name] || {};
}
readTheme(theme_name: string): void {

View File

@ -2,9 +2,30 @@
"compilerOptions": {
"target": "ES2020",
"module": "ESNext",
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"lib": [
"ES2020",
"DOM",
"DOM.Iterable"
],
"skipLibCheck": true,
// Strict mode (9)
"strict": true,
"alwaysStrict": true,
"noImplicitAny": true,
"noImplicitThis": true,
"strictNullChecks": true,
"strictBindCallApply": true,
"strictFunctionTypes": true,
"strictPropertyInitialization": true,
"useUnknownInCatchVariables": true,
// No unused code (4)
"noUnusedLocals": true,
"noUnusedParameters": true,
"allowUnusedLabels": false,
"allowUnreachableCode": false,
// No implicit code (2)
"noImplicitOverride": true,
"noImplicitReturns": true,
/* Bundler mode */
"moduleResolution": "bundler",
"esModuleInterop": true,
@ -12,14 +33,15 @@
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
/* Linting */
"strict": true,
"forceConsistentCasingInFileNames": true,
"useDefineForClassFields": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true
// Others (5)
"noUncheckedIndexedAccess": true,
"noPropertyAccessFromIndexSignature": true,
"noFallthroughCasesInSwitch": true,
"exactOptionalPropertyTypes": true,
"forceConsistentCasingInFileNames": true
},
"include": ["src", "../definitions/"]
"include": [
"src",
"../definitions/"
]
}