fix sequential awaits and add an eslint rule to catch future ones

This commit is contained in:
Egor 2025-09-11 13:57:24 -07:00
parent 0fe74f0093
commit 3697ff694e
6 changed files with 67 additions and 24 deletions

View file

@ -6,7 +6,10 @@ import reactHooks from 'eslint-plugin-react-hooks';
import react from 'eslint-plugin-react';
import importPlugin from 'eslint-plugin-import';
import sonarjs from 'eslint-plugin-sonarjs';
// @ts-ignore - No types available
import noComments from 'eslint-plugin-no-comments';
// @ts-ignore - No types available
import promise from 'eslint-plugin-promise';
const config = [
js.configs.recommended,
@ -53,6 +56,7 @@ const config = [
import: importPlugin,
sonarjs: sonarjs,
'no-comments': noComments,
promise: promise,
},
settings: {
react: {
@ -155,6 +159,19 @@ const config = [
'sonarjs/cognitive-complexity': ['warn', 25],
// Promise rules to prevent sequential awaits (no warnings, only errors)
'promise/prefer-await-to-then': 'error', // Enforce async/await
'promise/prefer-await-to-callbacks': 'off', // Too aggressive for Electron APIs
'promise/no-nesting': 'error', // No nested promises
'promise/no-promise-in-callback': 'off', // Common in Electron
'promise/no-callback-in-promise': 'off', // Common in Electron
'promise/avoid-new': 'off', // Sometimes needed for wrapping APIs
'promise/no-new-statics': 'error',
'promise/no-return-wrap': 'error',
'promise/param-names': 'error',
'promise/catch-or-return': 'off', // Too strict for some patterns
'promise/no-native': 'off',
'no-comments/disallowComments': 'error',
},
},
@ -187,6 +204,7 @@ const config = [
'@typescript-eslint/return-await': 'off',
'@typescript-eslint/no-unused-vars': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-require-imports': 'off',
},
},
{

View file

@ -52,6 +52,7 @@
"eslint": "^9.35.0",
"eslint-plugin-import": "^2.32.0",
"eslint-plugin-no-comments": "^1.1.10",
"eslint-plugin-promise": "^7.2.1",
"eslint-plugin-react": "^7.37.5",
"eslint-plugin-react-hooks": "^5.2.0",
"eslint-plugin-sonarjs": "^3.0.5",

View file

@ -17,11 +17,12 @@ if (process.argv[1] === '--version') {
process.exit(0);
})();
} else {
const isCliMode = process.argv.includes('--cli');
(async () => {
const isCliMode = process.argv.includes('--cli');
if (isCliMode) {
import('./cli')
.then(async (cliModule) => {
if (isCliMode) {
try {
const cliModule = await import('./cli');
const args = process.argv.slice(process.argv.indexOf('--cli') + 1);
try {
await cliModule.handleCliMode(args);
@ -30,18 +31,19 @@ if (process.argv[1] === '--version') {
console.error('CLI mode error:', error);
process.exit(1);
}
})
.catch((error) => {
} catch (error) {
// eslint-disable-next-line no-console
console.error('Failed to load CLI module:', error);
process.exit(1);
});
} else {
import('./gui').then((guiModule) => {
guiModule.initializeApp().catch((error: unknown) => {
}
} else {
try {
const guiModule = await import('./gui');
await guiModule.initializeApp();
} catch (error: unknown) {
// eslint-disable-next-line no-console
console.error('Failed to initialize Gerbil:', error);
});
});
}
}
}
})();
}

View file

@ -45,12 +45,21 @@ async function detectBackendSupportFromPath(koboldBinaryPath: string) {
}
};
support.rocm = await hasKoboldCppLib('koboldcpp_hipblas');
support.vulkan = await hasKoboldCppLib('koboldcpp_vulkan');
support.clblast = await hasKoboldCppLib('koboldcpp_clblast');
support.noavx2 = await hasKoboldCppLib('koboldcpp_noavx2');
support.failsafe = await hasKoboldCppLib('koboldcpp_failsafe');
support.cuda = await hasKoboldCppLib('koboldcpp_cublas');
const [rocm, vulkan, clblast, noavx2, failsafe, cuda] = await Promise.all([
hasKoboldCppLib('koboldcpp_hipblas'),
hasKoboldCppLib('koboldcpp_vulkan'),
hasKoboldCppLib('koboldcpp_clblast'),
hasKoboldCppLib('koboldcpp_noavx2'),
hasKoboldCppLib('koboldcpp_failsafe'),
hasKoboldCppLib('koboldcpp_cublas'),
]);
support.rocm = rocm;
support.vulkan = vulkan;
support.clblast = clblast;
support.noavx2 = noavx2;
support.failsafe = failsafe;
support.cuda = cuda;
} catch (error) {
logError('Error detecting backend support:', error as Error);
}

View file

@ -480,11 +480,12 @@ export async function stopFrontend() {
if (sillyTavernProcess) {
promises.push(
terminateProcess(sillyTavernProcess, {
logError: (message, error) => logError(message, error),
}).then(() => {
(async () => {
await terminateProcess(sillyTavernProcess, {
logError: (message, error) => logError(message, error),
});
sillyTavernProcess = null;
})
})()
);
}

View file

@ -584,7 +584,7 @@ __metadata:
languageName: node
linkType: hard
"@eslint-community/eslint-utils@npm:^4.7.0, @eslint-community/eslint-utils@npm:^4.8.0":
"@eslint-community/eslint-utils@npm:^4.4.0, @eslint-community/eslint-utils@npm:^4.7.0, @eslint-community/eslint-utils@npm:^4.8.0":
version: 4.9.0
resolution: "@eslint-community/eslint-utils@npm:4.9.0"
dependencies:
@ -3074,6 +3074,17 @@ __metadata:
languageName: node
linkType: hard
"eslint-plugin-promise@npm:^7.2.1":
version: 7.2.1
resolution: "eslint-plugin-promise@npm:7.2.1"
dependencies:
"@eslint-community/eslint-utils": "npm:^4.4.0"
peerDependencies:
eslint: ^7.0.0 || ^8.0.0 || ^9.0.0
checksum: 10c0/d494982faeeafbd2aa5fae9cbceca546169a8399000f72d5d940fa5c4ba554612903bcafbb8033647179e5d21ccf1d621b433d089695f7f47ce3d9fcf4cd0abf
languageName: node
linkType: hard
"eslint-plugin-react-hooks@npm:^5.2.0":
version: 5.2.0
resolution: "eslint-plugin-react-hooks@npm:5.2.0"
@ -3643,6 +3654,7 @@ __metadata:
eslint: "npm:^9.35.0"
eslint-plugin-import: "npm:^2.32.0"
eslint-plugin-no-comments: "npm:^1.1.10"
eslint-plugin-promise: "npm:^7.2.1"
eslint-plugin-react: "npm:^7.37.5"
eslint-plugin-react-hooks: "npm:^5.2.0"
eslint-plugin-sonarjs: "npm:^3.0.5"