From 4e896244d12a645593d482a0fe34eb305d050909 Mon Sep 17 00:00:00 2001 From: Fabio Di Stasio Date: Tue, 4 Apr 2023 17:59:54 +0200 Subject: [PATCH] refactor: improved typings --- CONTRIBUTING.md | 100 ------------------------------ package.json | 16 +---- src/main/libs/Sender.ts | 48 +++++++------- src/main/libs/Server.ts | 36 ++++++----- src/main/main.ts | 4 +- src/main/workers/clientProcess.ts | 7 +-- src/main/workers/serverProcess.ts | 5 +- 7 files changed, 54 insertions(+), 162 deletions(-) delete mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index 1f79c54..0000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,100 +0,0 @@ -# Contributors Guide - -Antares SQL is an application based on [Electron.js](https://www.electronjs.org/) that uses [Vue.js](https://vuejs.org/) and [Spectre.css](https://picturepan2.github.io/spectre/) as frontend frameworks. -For the build process it takes advantage of [electron-builder](https://www.electron.build/). -This application uses [Pinia🍍](https://pinia.vuejs.org/) as application state manager and [electron-store](https://github.com/sindresorhus/electron-store) to save the various settings on disc. -This guide aims to provide useful information and guidelines to everyone wants to contribute with this open-source project. -For every other question related to this project please [contact me](https://github.com/Fabio286). - -## Project Structure - -The main files of the application are located inside `src` folder and are groupped in three subfolders. - -### `common` - -This folder contains small libraries, classes and objects. The purpose of `common` folder is to group together utilities used by **renderer** and **main** processes. -Noteworthy is the `customizations` folder that contains clients related customizations. Those settings are merged with `default.js` that lists every option. -Client related customizations are stored on Pinia and can be accessed by `customizations` property of current workspace object, or importing `common/customizations`. - -An use case of customizations object can be the following: - -```js -computed: { - defaultEngine () { - if (this.workspace.customizations.engines) - return this.workspace.engines.find(engine => engine.isDefault).name; - return ''; - } -} -``` - -In this case the computed property `defaultEngine` returns the default engine for MySQL client, or an empty string with PostgreSQL that doesn't have engines. -Customization properties are also useful **if some features are ready for one client but not others**. - -### `main` - -Inside this folder are located all files required by main process. -`ipc-handlers` subfolder includes all IPC handlers for events sent from renderer process. -`libs` subfolder includes classes related to clients and **query and connection logics**. -**Everything above client's class level should be "client agnostic"** with a neutral and uniformed api interface - -### `renderer` - -In this folder is located the structure of Vue frontend application. - -## Build - -The command to build Antares SQL locally is `npm run build`. - -## Conventions - -### Electron - -- **kebab-case** for IPC event names. - -### Vue - -- **PascalCase** for file names (with .vue extension) and including components inside others (``). -- "**Base**" prefix for [base component names](https://vuejs.org/v2/style-guide/#Base-component-names-strongly-recommended). -- "**The**" prefix for [single-instance component names](https://vuejs.org/v2/style-guide/#Single-instance-component-names-strongly-recommended). -- [Tightly coupled component names](https://vuejs.org/v2/style-guide/#Tightly-coupled-component-names-strongly-recommended). -- [Order of words in component names](https://vuejs.org/v2/style-guide/#Order-of-words-in-component-names-strongly-recommended). -- **kebab-case** in templates for property and event names. - -### Code Style - -The project includes [ESlint](https://eslint.org/) and [StyleLint](https://stylelint.io/) config files with style rules. I recommend to set the lint on-save option in your code editor. -Alternatively you can launch following commands to lint the project. - -Check if all the style rules have been followed: - -```console -npm run lint -``` - -Apply style rules globally if possible: - -```console -npm run lint:fix -``` - -### Other recommendations - -Please, use if possible **template literals** to compose strings and **avoid unnecessary dependencies**. - -### Commits - -The commit style adopted for this project is [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/). -Basicly it's important to have **single scoped commits with a prefix** that follows this style because Antares SQL uses [standard-version](https://github.com/conventional-changelog/standard-version) to generate new releases and [CHANGELOG.md](https://github.com/Fabio286/antares/blob/master/CHANGELOG.md) file to track all notable changes. -For Visual Studio Code users may be useful [Conventional Commits](https://marketplace.visualstudio.com/items?itemName=vivaxy.vscode-conventional-commits) extension. - -## Debug - -**Debug mode**: - -```console -npm run debug -``` - -After running the debug mode Antares will listen on port 9222 (main process) for a debugger. -On **Visual Studio Code** just launch "*Electron: Main*" configurations after running Antares in debug mode. diff --git a/package.json b/package.json index efd91e3..c79aac0 100644 --- a/package.json +++ b/package.json @@ -87,26 +87,12 @@ "artifactName": "${productName}-${version}-portable.exe" }, "appx": { - "displayName": "Antares SQL", + "displayName": "Mizar TCP Tester", "backgroundColor": "transparent", "showNameOnTiles": true, "identityName": "62514FabioDiStasio.AntaresSQLClient", "publisher": "CN=1A2729ED-865C-41D2-9038-39AE2A63AA52", "applicationId": "FabioDiStasio.AntaresSQLClient" - }, - "dmg": { - "contents": [ - { - "x": 130, - "y": 220 - }, - { - "x": 410, - "y": 220, - "type": "link", - "path": "/Applications" - } - ] } }, "dependencies": { diff --git a/src/main/libs/Sender.ts b/src/main/libs/Sender.ts index aac1e80..48da7ac 100644 --- a/src/main/libs/Sender.ts +++ b/src/main/libs/Sender.ts @@ -3,6 +3,18 @@ import { ClientHost, ClientMessage } from 'common/interfaces'; import * as ElectronStore from 'electron-store'; const persistentStore = new ElectronStore({ name: 'client' }); +interface SenderParams { + closeOnEcho: boolean; + persistentConnection: boolean; + nMsgs: number; + tMin: number; + tMax: number; + nClients: number; + trace: boolean; + alertReset: boolean; + loop: boolean; +} + class Sender { process: NodeJS.Process; closeOnEcho: boolean; @@ -17,15 +29,14 @@ class Sender { nConnected: number; nClosed: number; nTryConnect: number; - nReceived: any[]; + nReceived: number[]; nSent: number; timeStart: Date; hosts: ClientHost[]; messages: ClientMessage[]; - nHostClients: any[]; - nHostBytes: any[]; - nHostMsgs: any[]; - storagePath: string; + nHostClients: number[]; + nHostBytes: number[]; + nHostMsgs: number[]; loop: boolean; /** @@ -55,7 +66,6 @@ class Sender { this.nHostClients = []; this.nHostBytes = []; this.nHostMsgs = []; - this.storagePath = ''; } /** @@ -74,7 +84,7 @@ class Sender { * @param {*} params * @memberof Sender */ - setParams (params: any) { + setParams (params: SenderParams) { this.closeOnEcho = params.closeOnEcho; this.persistentConnection = params.persistentConnection; this.nMsgs = params.nMsgs; @@ -86,16 +96,6 @@ class Sender { this.loop = params.loop; } - /** - * Setta il percorso della cartella storage - * - * @param {string} storagePath - * @memberof Sender - */ - setStoragePath (storagePath: string) { - this.storagePath = storagePath; - } - /** * Carica i messaggi in memoria * @@ -188,7 +188,7 @@ class Sender { const msg = this.randMsg(); - client.write(msg, (err: any) => { + client.write(msg, (err: Error) => { if (err) this.sendLog(`Socket #${clientId} su ${params.host}:${params.port}:\nErrore messaggio: ${err}`, 'red'); else { @@ -208,7 +208,7 @@ class Sender { this.sendLog(`Socket #${clientId} su ${params.host}:${params.port}:\n${err}`, 'red'); } - client.on('connect', (err: any) => { + client.on('connect', (err: Error) => { this.nTryConnect++; if (err) this.sendLog(`Errore connessione #${clientId} su ${params.host}:${params.port}:\n${err}`, 'red'); @@ -236,7 +236,7 @@ class Sender { } }); - client.on('error', (err: any) => { + client.on('error', (err: Error & { code: string }) => { switch (err.code) { case 'ECONNRESET': if (this.alertReset) @@ -281,7 +281,7 @@ class Sender { this.sendLog(`Socket #${clientId} su ${params.host}:${params.port}:\n${err}`, 'red'); } - client.on('connect', (err: any) => { + client.on('connect', (err: Error) => { this.nTryConnect++; if (err) this.sendLog(`Errore connessione #${clientId} su ${params.host}:${params.port}:\n${err}`, 'red'); @@ -305,7 +305,7 @@ class Sender { if (this.trace) this.sendLog(`Socket #${clientId} su ${params.host}:${params.port} chiuso`); }); - client.on('error', (err: any) => { + client.on('error', (err: Error & { code: string }) => { switch (err.code) { case 'ECONNRESET': if (this.alertReset) @@ -350,7 +350,7 @@ class Sender { const msg = this.randMsg(); - client.write(msg, (err: any) => { + client.write(msg, (err: Error) => { if (err) this.sendLog(`Socket #${clientId} su ${params.host}:${params.port}:\nErrore messaggio: ${err}`, 'red'); else { @@ -417,4 +417,4 @@ class Sender { } } } -export { Sender }; +export { Sender, SenderParams }; diff --git a/src/main/libs/Server.ts b/src/main/libs/Server.ts index bba2d3a..9e20f88 100644 --- a/src/main/libs/Server.ts +++ b/src/main/libs/Server.ts @@ -1,15 +1,21 @@ import { ServerPort } from 'common/interfaces'; import * as net from 'net'; +interface ServerParams { + trace: boolean; + echo: boolean; + alertReset: boolean; + } + class Server { process: NodeJS.Process; trace: boolean; echo: boolean; alertReset: boolean; ports: ServerPort[]; - server: any[]; - nBytes: any[]; - nMsgs: any[]; + server: net.Server[]; + nBytes: number[]; + nMsgs: number[]; constructor (process: NodeJS.Process) { this.process = process; @@ -28,7 +34,7 @@ class Server { * @param {*} ports * @memberof Server */ - setPorts (ports: any) { + setPorts (ports: ServerPort[]) { this.ports = ports; } @@ -47,7 +53,7 @@ class Server { this.process.send(log); } - startServer (params: any) { + startServer (params: ServerParams) { this.trace = params.trace; this.echo = params.echo; this.alertReset = params.alertReset; @@ -59,10 +65,10 @@ class Server { this.nBytes[i] = 0; this.nMsgs[i] = 0; - this.server[i].on('connection', (socket: any) => { + this.server[i].on('connection', (socket: net.Socket) => { if (this.trace) this.sendLog(`Client connesso su porta ${port}`); - socket.on('data', (msg: any) => { + socket.on('data', (msg: Buffer) => { const msgString = msg.toString(); if (this.echo) socket.write(msg); this.nBytes[i] += msg.length; @@ -75,7 +81,7 @@ class Server { if (this.trace) this.sendLog(`Client disconnesso su porta ${port}`); }); - socket.on('error', (err: any) => { + socket.on('error', (err: Error & { code: string }) => { switch (err.code) { case 'ECONNRESET': if (this.alertReset) @@ -89,7 +95,7 @@ class Server { }); });// <- server - this.server[i].on('error', (err: any) => { + this.server[i].on('error', (err: Error) => { this.sendLog(`Errore server su porta ${port}: \n${err}`, 'red'); }); @@ -102,7 +108,7 @@ class Server { stopServer (callback: () => void) { (async () => { for (let i = 0; i < this.server.length; i++) { - await this.server[i].close(function () { + this.server[i].close(() => { this.server[i].unref(); }); } @@ -111,16 +117,16 @@ class Server { } getReports () { - const reportList: any[] = []; + const reportList: {port: number; sockets: number; data: number; messages: number}[] = []; for (let i = 0; i < this.server.length; i++) { const report = { - port: this.server[i].address().port, - sockets: null as any, + port: (this.server[i].address() as net.AddressInfo).port, + sockets: null as number, data: this.nBytes[i], messages: this.nMsgs[i] }; - this.server[i].getConnections((err: any, nSockets: any) => { + this.server[i].getConnections((err: Error, nSockets: number) => { if (err) this.sendLog(`Errore report: \n${err}`, 'red'); report.sockets = nSockets; reportList.push(report); @@ -143,4 +149,4 @@ class Server { } } } -export { Server }; +export { Server, ServerParams }; diff --git a/src/main/main.ts b/src/main/main.ts index b005f6b..b6e5e00 100644 --- a/src/main/main.ts +++ b/src/main/main.ts @@ -1,5 +1,5 @@ -import { app, BrowserWindow, nativeImage, ipcMain, Menu } from 'electron'; -import * as fs from 'fs'; +import { app, BrowserWindow, /* nativeImage, */ ipcMain, Menu } from 'electron'; +// import * as fs from 'fs'; import * as path from 'path'; import * as Store from 'electron-store'; import { ChildProcess, fork, Serializable } from 'child_process'; diff --git a/src/main/workers/clientProcess.ts b/src/main/workers/clientProcess.ts index b72a08f..72a13ef 100644 --- a/src/main/workers/clientProcess.ts +++ b/src/main/workers/clientProcess.ts @@ -1,14 +1,14 @@ -import { Sender } from '../libs/Sender'; +import { ClientHost } from 'common/interfaces'; +import { Sender, SenderParams } from '../libs/Sender'; const Sends = new Sender(process); let clientTimer: NodeJS.Timer; -process.on('message', (message: any) => { +process.on('message', (message: { event: string; hosts: ClientHost[]; params: SenderParams}) => { switch (message.event) { case 'start': Sends.setHosts(message.hosts); Sends.setParams(message.params); - Sends.setStoragePath(message.storagePath); Sends.startFullTest(() => { const response = { @@ -31,7 +31,6 @@ process.on('message', (message: any) => { case 'startStep': Sends.setHosts(message.hosts); Sends.setParams(message.params); - Sends.setStoragePath(message.storagePath); Sends.connectClients(() => { const response = { diff --git a/src/main/workers/serverProcess.ts b/src/main/workers/serverProcess.ts index 206b1ae..78cc62c 100644 --- a/src/main/workers/serverProcess.ts +++ b/src/main/workers/serverProcess.ts @@ -1,9 +1,10 @@ -import { Server } from '../libs/Server'; +import { ServerPort } from 'common/interfaces'; +import { Server, ServerParams } from '../libs/Server'; const myServer = new Server(process); let serverTimer: NodeJS.Timer; -process.on('message', (message: {event: string; ports: string; params: any}) => { +process.on('message', (message: {event: string; ports: ServerPort[]; params: ServerParams}) => { switch (message.event) { case 'start': myServer.setPorts(message.ports);