Add a typescript linter.

This commit is contained in:
Luke Curley 2023-05-22 15:54:30 -07:00
parent 5410a3767f
commit a2371dada6
20 changed files with 5303 additions and 345 deletions

View File

@ -9,5 +9,14 @@ module.exports = {
"@typescript-eslint/ban-ts-comment": "off",
"@typescript-eslint/no-non-null-assertion": "off",
"@typescript-eslint/no-explicit-any": "off",
"no-unused-vars": "off", // note you must disable the base rule as it can report incorrect errors
"@typescript-eslint/no-unused-vars": [
"warn", // or "error"
{
"argsIgnorePattern": "^_",
"varsIgnorePattern": "^_",
"caughtErrorsIgnorePattern": "^_"
}
],
}
};

4253
web/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -4,17 +4,21 @@
"scripts": {
"serve": "parcel serve --https --cert ../cert/localhost.crt --key ../cert/localhost.key --port 4444 --open",
"build": "parcel build",
"check": "tsc --noEmit"
"check": "tsc --noEmit",
"lint": "eslint ."
},
"devDependencies": {
"@parcel/transformer-inline-string": "2.8.3",
"@parcel/validator-typescript": "^2.6.0",
"@types/audioworklet": "^0.0.41",
"@types/dom-webcodecs": "^0.1.6",
"@typescript-eslint/eslint-plugin": "^5.59.7",
"@typescript-eslint/parser": "^5.59.7",
"eslint": "^8.41.0",
"parcel": "^2.8.0",
"typescript": ">=3.0.0"
"typescript": "^5.0.4"
},
"dependencies": {
"mp4box": "^0.5.2"
}
}
}

View File

@ -69,7 +69,7 @@ export class Encoder {
dts: frame.timestamp,
});
const stream = this.container.createSingleSampleMoof(sample);
const _stream = this.container.createSingleSampleMoof(sample);
}
onVideo(frame: EncodedVideoChunk, metadata?: EncodedVideoChunkMetadata) {
@ -99,6 +99,6 @@ export class Encoder {
dts: frame.timestamp,
});
const stream = this.container.createSingleSampleMoof(sample);
const _stream = this.container.createSingleSampleMoof(sample);
}
}

View File

@ -1,4 +1,5 @@
export default class Broadcaster {
constructor() {
// TODO
}
}

View File

@ -5,7 +5,7 @@ import Transport from "./transport"
import fingerprintHex from 'bundle-text:../fingerprint.hex';
// Convert the hex to binary.
let fingerprint = [];
const fingerprint = [];
for (let c = 0; c < fingerprintHex.length - 1; c += 2) {
fingerprint.push(parseInt(fingerprintHex.substring(c, c + 2), 16));
}

View File

@ -26,11 +26,11 @@ export class InitParser {
push(data: Uint8Array) {
// Make a copy of the atom because mp4box only accepts an ArrayBuffer unfortunately
let box = new Uint8Array(data.byteLength);
const box = new Uint8Array(data.byteLength);
box.set(data)
// and for some reason we need to modify the underlying ArrayBuffer with fileStart
let buffer = box.buffer as MP4.ArrayBuffer
const buffer = box.buffer as MP4.ArrayBuffer
buffer.fileStart = this.offset
// Parse the data

View File

@ -121,10 +121,10 @@ declare module "mp4box" {
mapUint8Array(length: number): Uint8Array;
readInt32Array(length: number, littleEndian: boolean): Int32Array;
readInt16Array(length: number, littleEndian: boolean): Int16Array;
readInt8(length: number): Int8Array;
readInt8Array(length: number): Int8Array;
readUint32Array(length: number, littleEndian: boolean): Uint32Array;
readUint16Array(length: number, littleEndian: boolean): Uint16Array;
readUint8(length: number): Uint8Array;
readUint8Array(length: number): Uint8Array;
readFloat64Array(length: number, littleEndian: boolean): Float64Array;
readFloat32Array(length: number, littleEndian: boolean): Float32Array;

View File

@ -8,7 +8,7 @@ export default class Audio {
render?: number; // non-zero if requestAnimationFrame has been called
last?: number; // the timestamp of the last rendered frame, in microseconds
constructor(config: Message.Config) {
constructor(_config: Message.Config) {
this.queue = []
}
@ -47,7 +47,7 @@ export default class Audio {
}
while (this.queue.length) {
let frame = this.queue[0];
const frame = this.queue[0];
if (ring.size() + frame.numberOfFrames > ring.capacity) {
// Buffer is full
break

View File

@ -16,8 +16,8 @@ export default class Decoder {
}
async receiveInit(msg: Message.Init) {
let stream = new Stream.Reader(msg.reader, msg.buffer);
while (1) {
const stream = new Stream.Reader(msg.reader, msg.buffer);
for (;;) {
const data = await stream.read()
if (!data) break
@ -29,14 +29,14 @@ export default class Decoder {
async receiveSegment(msg: Message.Segment) {
// Wait for the init segment to be fully received and parsed
const info = await this.init.info
const init = await this.init.info
const input = MP4.New();
input.onSamples = this.onSamples.bind(this);
input.onReady = (info: any) => {
input.onReady = (track: any) => {
// Extract all of the tracks, because we don't know if it's audio or video.
for (let track of info.tracks) {
input.setExtractionOptions(track.id, track, { nbSamples: 1 });
for (const i of init.tracks) {
input.setExtractionOptions(track.id, i, { nbSamples: 1 });
}
input.start();
@ -45,7 +45,7 @@ export default class Decoder {
// MP4box requires us to reparse the init segment unfortunately
let offset = 0;
for (let raw of this.init.raw) {
for (const raw of this.init.raw) {
raw.fileStart = offset
offset = input.appendBuffer(raw)
}
@ -61,11 +61,11 @@ export default class Decoder {
const atom = await stream.bytes(size)
// Make a copy of the atom because mp4box only accepts an ArrayBuffer unfortunately
let box = new Uint8Array(atom.byteLength);
const box = new Uint8Array(atom.byteLength);
box.set(atom)
// and for some reason we need to modify the underlying ArrayBuffer with offset
let buffer = box.buffer as MP4.ArrayBuffer
const buffer = box.buffer as MP4.ArrayBuffer
buffer.fileStart = offset
// Parse the data
@ -79,7 +79,7 @@ export default class Decoder {
if (!decoder) {
// We need a sample to initalize the video decoder, because of mp4box limitations.
let sample = samples[0];
const sample = samples[0];
if (isVideoTrack(track)) {
// Configure the decoder using the AVC box for H.264
@ -124,7 +124,7 @@ export default class Decoder {
this.decoders.set(track_id, decoder)
}
for (let sample of samples) {
for (const sample of samples) {
// Convert to microseconds
const timestamp = 1000 * 1000 * sample.dts / sample.timescale
const duration = 1000 * 1000 * sample.duration / sample.timescale

View File

@ -45,7 +45,7 @@ export default class Player {
return worker
}
private async setupWorklet(config: Config): Promise<AudioWorkletNode> {
private async setupWorklet(_config: Config): Promise<AudioWorkletNode> {
// Load the worklet source code.
const url = new URL('worklet.ts', import.meta.url)
await this.context.audioWorklet.addModule(url)

View File

@ -37,7 +37,7 @@ export class Ring {
this.state = new Int32Array(buffer.state)
this.channels = []
for (let channel of buffer.channels) {
for (const channel of buffer.channels) {
this.channels.push(new Float32Array(channel))
}
@ -46,8 +46,8 @@ export class Ring {
// Write samples for single audio frame, returning the total number written.
write(frame: AudioData): number {
let readPos = Atomics.load(this.state, STATE.READ_POS)
let writePos = Atomics.load(this.state, STATE.WRITE_POS)
const readPos = Atomics.load(this.state, STATE.READ_POS)
const writePos = Atomics.load(this.state, STATE.WRITE_POS)
const startPos = writePos
let endPos = writePos + frame.numberOfFrames;
@ -60,8 +60,8 @@ export class Ring {
}
}
let startIndex = startPos % this.capacity;
let endIndex = endPos % this.capacity;
const startIndex = startPos % this.capacity;
const endIndex = endPos % this.capacity;
// Loop over each channel
for (let i = 0; i < this.channels.length; i += 1) {
@ -102,10 +102,10 @@ export class Ring {
}
read(dst: Float32Array[]): number {
let readPos = Atomics.load(this.state, STATE.READ_POS)
let writePos = Atomics.load(this.state, STATE.WRITE_POS)
const readPos = Atomics.load(this.state, STATE.READ_POS)
const writePos = Atomics.load(this.state, STATE.WRITE_POS)
let startPos = readPos;
const startPos = readPos;
let endPos = startPos + dst[0].length;
if (endPos > writePos) {
@ -116,8 +116,8 @@ export class Ring {
}
}
let startIndex = startPos % this.capacity;
let endIndex = endPos % this.capacity;
const startIndex = startPos % this.capacity;
const endIndex = endPos % this.capacity;
// Loop over each channel
for (let i = 0; i < dst.length; i += 1) {
@ -147,8 +147,8 @@ export class Ring {
size() {
// TODO is this thread safe?
let readPos = Atomics.load(this.state, STATE.READ_POS)
let writePos = Atomics.load(this.state, STATE.WRITE_POS)
const readPos = Atomics.load(this.state, STATE.READ_POS)
const writePos = Atomics.load(this.state, STATE.WRITE_POS)
return writePos - readPos
}

View File

@ -89,7 +89,7 @@ export default class Video {
frame.close()
}
play(play: Message.Play) {
play(_play: Message.Play) {
// Queue up to render the next frame.
if (!this.render) {
this.render = self.requestAnimationFrame(this.draw.bind(this))

View File

@ -10,7 +10,7 @@ class Renderer extends AudioWorkletProcessor {
ring?: Ring;
base: number;
constructor(params: AudioWorkletNodeOptions) {
constructor(_params: AudioWorkletNodeOptions) {
// The super constructor call is required.
super();
@ -29,7 +29,7 @@ class Renderer extends AudioWorkletProcessor {
}
// Inputs and outputs in groups of 128 samples.
process(inputs: Float32Array[][], outputs: Float32Array[][], parameters: Record<string, Float32Array>): boolean {
process(inputs: Float32Array[][], outputs: Float32Array[][], _parameters: Record<string, Float32Array>): boolean {
if (!this.ring) {
// Paused
return true

View File

@ -28,7 +28,7 @@ export default class Reader {
async readAll(): Promise<Uint8Array> {
const r = this.reader.getReader()
while (1) {
for (;;) {
const result = await r.read()
if (result.done) {
break
@ -164,18 +164,22 @@ export default class Reader {
const size = (first & 0xc0) >> 6
switch (size) {
case 0:
const v0 = await this.uint8()
return BigInt(v0) & 0x3fn
case 1:
const v1 = await this.uint16()
return BigInt(v1) & 0x3fffn
case 2:
const v2 = await this.uint32()
return BigInt(v2) & 0x3fffffffn
case 3:
const v3 = await this.uint64()
return v3 & 0x3fffffffffffffffn
case 0: {
const v = await this.uint8()
return BigInt(v) & 0x3fn
}
case 1: {
const v = await this.uint16()
return BigInt(v) & 0x3fffn
}
case 2: {
const v = await this.uint32()
return BigInt(v) & 0x3fffffffn
}
case 3: {
const v = await this.uint64()
return v & 0x3fffffffffffffffn
}
default:
throw "impossible"
}
@ -183,7 +187,7 @@ export default class Reader {
async done(): Promise<boolean> {
try {
const peek = await this.peek(1)
await this.peek(1)
return false
} catch (err) {
return true // Assume EOF

View File

@ -29,7 +29,7 @@ export default class Transport {
// Helper function to make creating a promise easier
private async connect(config: Config): Promise<WebTransport> {
let options: WebTransportOptions = {};
const options: WebTransportOptions = {};
if (config.fingerprint) {
options.serverCertificateHashes = [ config.fingerprint ]
}

View File

@ -1,5 +1,6 @@
export interface Init {}
export interface Segment {}
// TODO fill in required fields
export type Init = any
export type Segment = any
export interface Debug {
max_bitrate: number

View File

@ -29,7 +29,7 @@ interface WebTransport {
readonly incomingUnidirectionalStreams: ReadableStream;
}
declare var WebTransport: {
declare const WebTransport: {
prototype: WebTransport;
new(url: string, options?: WebTransportOptions): WebTransport;
};
@ -71,7 +71,7 @@ interface WebTransportError extends DOMException {
readonly streamErrorCode: number;
}
declare var WebTransportError: {
declare const WebTransportError: {
prototype: WebTransportError;
new(init?: WebTransportErrorInit): WebTransportError;
};

View File

@ -2,11 +2,11 @@ export default class Deferred<T> {
promise: Promise<T>
resolve: (value: T | PromiseLike<T>) => void
reject: (value: T | PromiseLike<T>) => void
constructor() {
// Set initial values so TS stops being annoying.
this.resolve = (value: T | PromiseLike<T>) => {};
this.reject = (value: T | PromiseLike<T>) => {};
this.resolve = (_value: T | PromiseLike<T>) => { /* noop */ };
this.reject = (_value: T | PromiseLike<T>) => { /* noop */ };
this.promise = new Promise((resolve, reject) => {
this.resolve = resolve

File diff suppressed because it is too large Load Diff