Files
Dermot Duffy c02c692f68 feat: Add experimental rewrite of go2rtc live provider (MSE/WebRTC/MP4/MJPEG) (#2580)
- Closes #2556
- Closes #2450

**Key intended features:**
 - go2rtc compatible
- 100% test coverage to significantly improve ability to test, maintain
and work around browser weirdnesses (e.g. Safari).
 - Written from the ground up in the style of the rest of the project.

**To use:**
 - Change `live_provider` from `go2rtc` to `go2rtc-experimental`.
2026-07-14 14:22:41 -07:00

118 lines
3.5 KiB
JavaScript

import path from 'node:path';
import { fileURLToPath } from 'node:url';
import { FlatCompat } from '@eslint/eslintrc';
import js from '@eslint/js';
import tsParser from '@typescript-eslint/parser';
import { defineConfig } from 'eslint/config';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const compat = new FlatCompat({
baseDirectory: __dirname,
recommendedConfig: js.configs.recommended,
allConfig: js.configs.all,
});
// Local rule: ban the em-dash character (U+2014) anywhere, including comments and
// strings. The codebase uses a colon or a double hyphen `--` instead. The regex uses
// the unicode escape so the character never appears literally in this file.
const noEmDash = {
meta: {
type: 'problem',
docs: { description: 'Disallow the em-dash character; use ":" or "--" instead.' },
messages: {
emDash: 'Em-dash character is not allowed; use ":" or "--" instead.',
},
},
create(context) {
const sourceCode = context.sourceCode ?? context.getSourceCode();
return {
Program(node) {
const text = sourceCode.getText();
const re = /\u2014/g;
let match;
while ((match = re.exec(text)) !== null) {
context.report({
node,
loc: {
start: sourceCode.getLocFromIndex(match.index),
end: sourceCode.getLocFromIndex(match.index + 1),
},
messageId: 'emDash',
});
}
},
};
},
};
export default defineConfig([
{
extends: compat.extends('plugin:@typescript-eslint/recommended', 'prettier'),
languageOptions: {
parser: tsParser,
ecmaVersion: 2020,
sourceType: 'module',
},
plugins: {
local: { rules: { 'no-em-dash': noEmDash } },
},
rules: {
curly: 'error',
'local/no-em-dash': 'error',
'@typescript-eslint/consistent-type-definitions': ['error', 'interface'],
'@typescript-eslint/consistent-type-imports': [
'error',
{ fixStyle: 'separate-type-imports' },
],
'@typescript-eslint/no-explicit-any': 'error',
'@typescript-eslint/no-non-null-assertion': 'error',
'@typescript-eslint/parameter-properties': 'error',
},
},
// Timers must go through the Timer class (src/utils/timer.ts).
{
files: ['src/**/*.ts'],
rules: {
'no-restricted-syntax': [
'error',
{
selector:
'CallExpression > Identifier.callee[name=/^(setTimeout|setInterval)$/]',
message:
'Use the Timer class (src/utils/timer.ts) instead of setTimeout/setInterval.',
},
{
selector: 'MemberExpression[property.name=/^(setTimeout|setInterval)$/]',
message:
'Use the Timer class (src/utils/timer.ts) instead of window.setTimeout/setInterval.',
},
],
},
},
// A fire-and-forget promise must be marked with `void` to show it is deliberate.
// To know which calls return a promise, this rule needs type information, so the
// `project` option below runs the TypeScript type-checker over source while linting.
// That makes linting source slower. Tests are excluded: they leave promises unawaited
// freely.
{
files: ['src/**/*.ts'],
languageOptions: {
parser: tsParser,
parserOptions: {
projectService: true,
tsconfigRootDir: __dirname,
},
},
rules: {
'@typescript-eslint/no-floating-promises': 'error',
},
},
]);