Skip to content

Commit 8753c63

Browse files
Initial setup for electron socket (#1)
Description This PR intends to create an initial setup for electron-socket project. What is included: - Renaming the project pointing lichtblick projects and references - Change version on package.json - Update needed dependencies - Solve lint issues --------- Co-authored-by: Luiz Bezerra <[email protected]>
1 parent ef8613b commit 8753c63

23 files changed

+798
-462
lines changed

.eslintrc.yaml

+6-3
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,18 @@ ignorePatterns:
55
- dist
66

77
extends:
8-
- plugin:@foxglove/base
9-
- plugin:@foxglove/jest
8+
- plugin:@lichtblick/base
9+
- plugin:@lichtblick/jest
1010

1111
overrides:
1212
- files: ["*.ts", "*.tsx"]
1313
extends:
14-
- plugin:@foxglove/typescript
14+
- plugin:@lichtblick/typescript
1515
parserOptions:
1616
project: [./tsconfig.json, ./tsconfig.dts.json]
1717
- files: ["example/**"]
1818
parserOptions:
1919
project: ./example/tsconfig.json
20+
21+
rules:
22+
"@lichtblick/no-boolean-parameters": off

.vscode/settings.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// -*- jsonc -*-
22
{
33
"editor.codeActionsOnSave": {
4-
"source.fixAll.eslint": true
4+
"source.fixAll.eslint": "explicit"
55
},
66
"editor.formatOnSave": true,
77
"editor.defaultFormatter": "esbenp.prettier-vscode",

README.md

+6-10
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
# @foxglove/electron-socket
1+
# @lichtblick/electron-socket
22

33
Networking sockets for Electron apps
44

5-
[![npm version](https://img.shields.io/npm/v/@foxglove/electron-socket.svg?style=flat)](https://www.npmjs.com/package/@foxglove/electron-socket)
5+
[![npm version](https://img.shields.io/npm/v/@lichtblick/electron-socket.svg?style=flat)](https://www.npmjs.com/package/@lichtblick/electron-socket)
66

77
## Introduction
88

@@ -12,14 +12,14 @@ Raw sockets are not supported in browser contexts, even in Electron apps. To ove
1212

1313
```ts
1414
// preload.ts ////////////////////////////////////////////////////////////////
15-
import { PreloaderSockets } from "@foxglove/electron-socket/preloader";
15+
import { PreloaderSockets } from "@lichtblick/electron-socket/preloader";
1616

1717
PreloaderSockets.Create();
1818
```
1919

2020
```ts
2121
// renderer.ts ///////////////////////////////////////////////////////////////
22-
import { Sockets } from "@foxglove/electron-socket/renderer";
22+
import { Sockets } from "@lichtblick/electron-socket/renderer";
2323

2424
async function main() {
2525
const net = await Sockets.Create();
@@ -40,7 +40,7 @@ main();
4040

4141
## License
4242

43-
@foxglove/electron-socket is licensed under the [MIT License](https://opensource.org/licenses/MIT).
43+
@lichtblick/electron-socket is licensed under the [MIT License](https://opensource.org/licenses/MIT).
4444

4545
## Development
4646

@@ -52,8 +52,4 @@ A small example Electron app is provided in the [example](example) directory, wh
5252

5353
1. Run `yarn version --[major|minor|patch]` to bump version
5454
2. Run `git push && git push --tags` to push new tag
55-
3. GitHub Actions will take care of the rest
56-
57-
## Stay in touch
58-
59-
Join our [Slack channel](https://foxglove.dev/slack) to ask questions, share feedback, and stay up to date on what our team is working on.
55+
3. GitHub Actions will take care of the rest

example/preload.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { PreloaderSockets } from "@foxglove/electron-socket/preloader";
1+
import { PreloaderSockets } from "@lichtblick/electron-socket/preloader";
22

33
async function main() {
44
// Change this delay to test initializing the preloader after the renderer

example/renderer.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Sockets } from "@foxglove/electron-socket/renderer";
1+
import { Sockets } from "@lichtblick/electron-socket/renderer";
22

33
async function main() {
44
// Change this delay to test initializing the renderer after the preloader

example/tsconfig.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
{
2-
"extends": "@foxglove/tsconfig/base",
2+
"extends": "@lichtblick/tsconfig/base",
33
"include": ["./**/*.ts"],
44
"compilerOptions": {
55
"lib": ["dom", "es2020"],
66
"module": "commonjs",
77
"rootDir": "..",
88
"outDir": "dist",
99
"paths": {
10-
"@foxglove/electron-socket/*": ["../src/*"]
10+
"@lichtblick/electron-socket/*": ["../src/*"]
1111
}
1212
}
1313
}

example/webpack.config.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ const resolve: ResolveOptions = {
1212
".js": [".ts", ".js"],
1313
},
1414
alias: {
15-
"@foxglove/electron-socket": path.resolve(__dirname, "../src"),
15+
"@lichtblick/electron-socket": path.resolve(__dirname, "../src"),
1616
},
1717
};
1818

package.json

+13-13
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
{
2-
"name": "@foxglove/electron-socket",
2+
"name": "@lichtblick/electron-socket",
33
"private": false,
4-
"version": "2.1.1",
4+
"version": "1.0.0",
55
"description": "Networking sockets for Electron apps",
66
"license": "MIT",
77
"repository": {
88
"type": "git",
9-
"url": "https://github.com/foxglove/electron-socket.git"
9+
"url": "https://github.com/Lichtblick-Suite/electron-socket.git"
1010
},
1111
"author": {
12-
"name": "Foxglove",
13-
"email": "[email protected]"
12+
"name": "Lichtblick",
13+
"email": "[email protected]"
1414
},
15-
"homepage": "https://github.com/foxglove/electron-socket",
15+
"homepage": "https://github.com/lichtblick-suite",
1616
"type": "module",
1717
"exports": {
1818
"./preloader": "./dist/preloader/index.js",
@@ -41,12 +41,12 @@
4141
"electron": ">=12"
4242
},
4343
"devDependencies": {
44-
"@foxglove/eslint-plugin": "0.21.0",
45-
"@foxglove/tsconfig": "^1.1.0",
44+
"@lichtblick/eslint-plugin": "1.0.1",
45+
"@lichtblick/tsconfig": "1.0.0",
4646
"@types/dns-packet": "5.2.2",
4747
"@types/jest": "^27.0.1",
48-
"@typescript-eslint/eslint-plugin": "5.56.0",
49-
"@typescript-eslint/parser": "5.56.0",
48+
"@typescript-eslint/eslint-plugin": "6.10.0",
49+
"@typescript-eslint/parser": "6.10.0",
5050
"clean-webpack-plugin": "^4.0.0",
5151
"cross-env": "^7.0.3",
5252
"electron": "^23.2.0",
@@ -56,11 +56,11 @@
5656
"eslint-plugin-es": "^4.1.0",
5757
"eslint-plugin-filenames": "^1.3.2",
5858
"eslint-plugin-import": "2.27.5",
59-
"eslint-plugin-jest": "27.2.1",
60-
"eslint-plugin-prettier": "4.2.1",
59+
"eslint-plugin-jest": "27.6.3",
60+
"eslint-plugin-prettier": "5.1.3",
6161
"html-webpack-plugin": "^5.5.0",
6262
"jest": "27.0.6",
63-
"prettier": "2.8.6",
63+
"prettier": "3.3.2",
6464
"ts-jest": "27.0.5",
6565
"ts-loader": "^9.4.2",
6666
"ts-node": "^10.9.1",

src/preloader/HttpServerElectron.ts

+65-36
Original file line numberDiff line numberDiff line change
@@ -6,62 +6,91 @@ import { TcpAddress } from "../shared/TcpTypes.js";
66

77
export class HttpServerElectron {
88
readonly id: number;
9-
private _server: http.Server;
10-
private _messagePort: MessagePort;
11-
private _nextRequestId = 0;
12-
private _requests = new Map<number, (response: HttpResponse) => Promise<void>>();
13-
private _api = new Map<string, RpcHandler>([
14-
["address", (callId) => this._apiResponse([callId, this.address()])],
9+
#server: http.Server;
10+
#messagePort: MessagePort;
11+
#nextRequestId = 0;
12+
#requests = new Map<number, (response: HttpResponse) => Promise<void>>();
13+
#api = new Map<string, RpcHandler>([
14+
[
15+
"address",
16+
(callId) => {
17+
this.#apiResponse([callId, this.address()]);
18+
},
19+
],
1520
[
1621
"listen",
1722
(callId, args) => {
1823
const port = args[0] as number | undefined;
1924
const hostname = args[1] as string | undefined;
2025
const backlog = args[2] as number | undefined;
2126
this.listen(port, hostname, backlog)
22-
.then(() => this._apiResponse([callId, undefined]))
23-
.catch((err: Error) => this._apiResponse([callId, String(err.stack ?? err)]));
27+
.then(() => {
28+
this.#apiResponse([callId, undefined]);
29+
})
30+
.catch((err: Error) => {
31+
this.#apiResponse([callId, String(err.stack ?? err)]);
32+
});
2433
},
2534
],
2635
[
2736
"response",
2837
(callId, args) => {
2938
const requestId = args[0] as number;
3039
const response = args[1] as HttpResponse;
31-
const handler = this._requests.get(requestId);
40+
const handler = this.#requests.get(requestId);
3241
if (handler == undefined) {
33-
this._apiResponse([callId, `unknown requestId ${requestId}`]);
42+
this.#apiResponse([callId, `unknown requestId ${requestId}`]);
3443
return;
3544
}
36-
this._requests.delete(requestId);
45+
this.#requests.delete(requestId);
3746
handler(response)
38-
.then(() => this._apiResponse([callId, undefined]))
39-
.catch((err: Error) => this._apiResponse([callId, String(err.stack ?? err)]));
47+
.then(() => {
48+
this.#apiResponse([callId, undefined]);
49+
})
50+
.catch((err: Error) => {
51+
this.#apiResponse([callId, String(err.stack ?? err)]);
52+
});
53+
},
54+
],
55+
[
56+
"close",
57+
(callId) => {
58+
//eslint-disable-next-line @typescript-eslint/no-confusing-void-expression
59+
this.#apiResponse([callId, this.close()]);
60+
},
61+
],
62+
[
63+
"dispose",
64+
(callId) => {
65+
//eslint-disable-next-line @typescript-eslint/no-confusing-void-expression
66+
this.#apiResponse([callId, this.dispose()]);
4067
},
4168
],
42-
["close", (callId) => this._apiResponse([callId, this.close()])],
43-
["dispose", (callId) => this._apiResponse([callId, this.dispose()])],
4469
]);
4570

4671
constructor(id: number, messagePort: MessagePort) {
4772
this.id = id;
48-
this._server = http.createServer(this._handleRequest);
49-
this._messagePort = messagePort;
73+
this.#server = http.createServer(this.#handleRequest);
74+
this.#messagePort = messagePort;
5075

51-
this._server.on("close", () => this._emit("close"));
52-
this._server.on("error", (err) => this._emit("error", String(err.stack ?? err)));
76+
this.#server.on("close", () => {
77+
this.#emit("close");
78+
});
79+
this.#server.on("error", (err) => {
80+
this.#emit("error", String(err.stack ?? err));
81+
});
5382

5483
messagePort.onmessage = (ev: MessageEvent<RpcCall>) => {
5584
const [methodName, callId] = ev.data;
5685
const args = ev.data.slice(2);
57-
const handler = this._api.get(methodName);
86+
const handler = this.#api.get(methodName);
5887
handler?.(callId, args);
5988
};
6089
messagePort.start();
6190
}
6291

6392
address(): TcpAddress | undefined {
64-
const addr = this._server.address();
93+
const addr = this.#server.address();
6594
if (addr == undefined || typeof addr === "string") {
6695
// Address will only be a string for an IPC (named pipe) server, which
6796
// should never happen here
@@ -71,45 +100,45 @@ export class HttpServerElectron {
71100
}
72101

73102
async listen(port?: number, hostname?: string, backlog?: number): Promise<void> {
74-
return await new Promise((resolve, reject) => {
75-
this._server.listen(port, hostname, backlog, () => {
76-
this._server.removeListener("error", reject);
103+
await new Promise<void>((resolve, reject) => {
104+
this.#server.listen(port, hostname, backlog, () => {
105+
this.#server.removeListener("error", reject);
77106
resolve();
78107
});
79108
});
80109
}
81110

82111
close(): void {
83-
this._server.close();
112+
this.#server.close();
84113
}
85114

86115
dispose(): void {
87-
this._server.removeAllListeners();
116+
this.#server.removeAllListeners();
88117
this.close();
89-
this._messagePort.close();
118+
this.#messagePort.close();
90119
}
91120

92-
private _apiResponse(message: RpcResponse, transfer?: Transferable[]): void {
121+
#apiResponse(message: RpcResponse, transfer?: Transferable[]): void {
93122
if (transfer != undefined) {
94-
this._messagePort.postMessage(message, transfer);
123+
this.#messagePort.postMessage(message, transfer);
95124
} else {
96-
this._messagePort.postMessage(message);
125+
this.#messagePort.postMessage(message);
97126
}
98127
}
99128

100-
private _emit(eventName: string, ...args: Cloneable[]): void {
129+
#emit(eventName: string, ...args: Cloneable[]): void {
101130
const msg = [eventName, ...args];
102-
this._messagePort.postMessage(msg);
131+
this.#messagePort.postMessage(msg);
103132
}
104133

105-
private _handleRequest = (req: http.IncomingMessage, res: http.ServerResponse): void => {
134+
#handleRequest = (req: http.IncomingMessage, res: http.ServerResponse): void => {
106135
const chunks: Uint8Array[] = [];
107136
req.on("data", (chunk: Uint8Array) => chunks.push(chunk));
108137
req.on("end", () => {
109138
const body = Buffer.concat(chunks).toString();
110139

111-
const requestId = this._nextRequestId++;
112-
this._requests.set(requestId, async (out): Promise<void> => {
140+
const requestId = this.#nextRequestId++;
141+
this.#requests.set(requestId, async (out): Promise<void> => {
113142
res.shouldKeepAlive = out.shouldKeepAlive ?? res.shouldKeepAlive;
114143
res.statusCode = out.statusCode;
115144
res.statusMessage = out.statusMessage ?? "";
@@ -147,7 +176,7 @@ export class HttpServerElectron {
147176
remotePort: req.socket.remotePort,
148177
},
149178
};
150-
this._emit("request", requestId, request);
179+
this.#emit("request", requestId, request);
151180
});
152181
};
153182
}

0 commit comments

Comments
 (0)