Erweiterung um preload und typen
This commit is contained in:
parent
b1f264424c
commit
56c16a6ab8
@ -1,6 +1,7 @@
|
||||
{
|
||||
"appId": "com.nwaschk.api-tool",
|
||||
"files": ["dist-electron", "dist-svelte"],
|
||||
"extraResources": ["dist-electron/preload.cjs"],
|
||||
"icon": "./desktopIcon.png",
|
||||
"mac": {
|
||||
"target": "dmg"
|
||||
|
||||
@ -1,17 +1,24 @@
|
||||
import {app, BrowserWindow} from 'electron';
|
||||
import path from 'path';
|
||||
import {getPreloadPath, inDevelopment} from './utils.js';
|
||||
import {ipcMain} from 'electron/main';
|
||||
import {ProdressConnection} from './pdr2com/connection.js';
|
||||
|
||||
const APPLICATION_PATH = path.join(app.getAppPath(), '/dist-svelte/index.html');
|
||||
|
||||
app.on('ready', async () => {
|
||||
const mainWindow = new BrowserWindow({}); //@todo
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
const mainWindow = new BrowserWindow({
|
||||
webPreferences: {
|
||||
preload: getPreloadPath(),
|
||||
},
|
||||
}); //@todo
|
||||
if (inDevelopment()) {
|
||||
mainWindow.loadURL('http://localhost:5123/');
|
||||
} else {
|
||||
mainWindow.loadFile(APPLICATION_PATH);
|
||||
}
|
||||
|
||||
ipcMain.handle('ping', () => {
|
||||
const req = new ProdressConnection(
|
||||
{
|
||||
port: 4788,
|
||||
@ -26,25 +33,6 @@ app.on('ready', async () => {
|
||||
['line2', 'string'],
|
||||
],
|
||||
);
|
||||
const res = await req.handleRequest();
|
||||
console.log(res);
|
||||
// try {
|
||||
// const socket = new Socket();
|
||||
// socket.connect(4788, 'localhost');
|
||||
//
|
||||
// const test = new ProdressRequest('db', 'handler', 'aktion');
|
||||
// test.schreibeText('HalloWelt 2355435');
|
||||
// socket.on('connect', () => {
|
||||
// console.log('verbunden');
|
||||
// test.sende(socket);
|
||||
// });
|
||||
// const r2reader = new RequestLeser();
|
||||
// socket.on('data', (data: Buffer) => {
|
||||
// r2reader.verarbeiteDaten(data);
|
||||
// });
|
||||
// const r2request = await r2reader.leseRequest();
|
||||
// console.log(r2request.nächsterText());
|
||||
// } catch (error) {
|
||||
// console.error(error);
|
||||
// }
|
||||
return req.handleRequest();
|
||||
});
|
||||
});
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import {RequestLeser as ProdressListener, type R2AnfrageBlaupause} from '@prodress/pdr2com';
|
||||
import {type ResponseTupel, type ResponseObject, ProdressRequest, type RequestTupel} from './wrapper.js';
|
||||
import {Socket} from 'node:net';
|
||||
import {stringifyError} from '../utils.js';
|
||||
|
||||
export interface ProdressHeader {
|
||||
port?: number;
|
||||
@ -10,20 +11,9 @@ export interface ProdressHeader {
|
||||
action: string;
|
||||
}
|
||||
|
||||
// @todo move to nyi utils file
|
||||
function stringifyError(error: Error): string {
|
||||
const {message, stack} = error;
|
||||
|
||||
return JSON.stringify(
|
||||
{
|
||||
message,
|
||||
stack,
|
||||
},
|
||||
null,
|
||||
2,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes a TCP Socket, sends a ProdressRequest and listens to this Socket for one Response
|
||||
*/
|
||||
export class ProdressConnection {
|
||||
public static readonly TIMEOUT = 30_000;
|
||||
|
||||
@ -35,6 +25,11 @@ export class ProdressConnection {
|
||||
private requestTupelList: RequestTupel[];
|
||||
private responseTupelList: ResponseTupel[];
|
||||
|
||||
/**
|
||||
* @param header Headerdata to initialize the the TCP Socket and the ProdressRequest
|
||||
* @param requestTupelList Requestdata as list of tupel
|
||||
* @param responseTupelList Expected Responsedata as list of tupel
|
||||
*/
|
||||
public constructor(header: ProdressHeader, requestTupelList: RequestTupel[], responseTupelList: ResponseTupel[]) {
|
||||
this.port = header.port ?? 4788;
|
||||
this.host = header.host ?? 'localhost';
|
||||
@ -45,8 +40,12 @@ export class ProdressConnection {
|
||||
this.responseTupelList = responseTupelList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handels the request- and response-flow
|
||||
*/
|
||||
public async handleRequest(): Promise<string> {
|
||||
let response: string = '';
|
||||
// Wraps a Promise around the reponse which resolves when the "finished" event is emitted and destroys the socekt
|
||||
const responseAsPromise = new Promise<string>((resolve) => {
|
||||
this.socket.once('finished', () => {
|
||||
if (!this.socket.destroyed) {
|
||||
@ -59,6 +58,7 @@ export class ProdressConnection {
|
||||
this.socket.setTimeout(ProdressConnection.TIMEOUT);
|
||||
this.socket.connect(this.port, this.host);
|
||||
|
||||
// Sends the writes and sends the request when the connecting is established
|
||||
this.socket.once('connect', () => {
|
||||
try {
|
||||
this.request.writeEntries(this.requestTupelList);
|
||||
@ -81,11 +81,14 @@ export class ProdressConnection {
|
||||
this.finished();
|
||||
});
|
||||
|
||||
// Starts writing data from the buffer to the listener-instance and emits the "dataRecieved" event
|
||||
this.socket.on('data', (data: Buffer) => {
|
||||
this.listener.verarbeiteDaten(data);
|
||||
this.socket.emit('dataRecieved');
|
||||
});
|
||||
|
||||
// Since we only expect one response the "dataRecieved" event triggers only once
|
||||
// Reads the data until finished and writes the response afterwards
|
||||
this.socket.once('dataRecieved', async () => {
|
||||
try {
|
||||
const incomingResponse = await this.listener.leseRequest();
|
||||
@ -97,9 +100,13 @@ export class ProdressConnection {
|
||||
this.finished();
|
||||
}
|
||||
});
|
||||
|
||||
return responseAsPromise;
|
||||
}
|
||||
|
||||
/**
|
||||
* Emits a custom "finished" event
|
||||
*/
|
||||
private finished(): void {
|
||||
this.socket.emit('finished');
|
||||
}
|
||||
@ -112,8 +119,7 @@ export class ProdressConnection {
|
||||
private readResponse(responseInstance: R2AnfrageBlaupause): ResponseObject {
|
||||
const response: ResponseObject = {};
|
||||
|
||||
for (const tupel of this.responseTupelList) {
|
||||
const [key, type] = tupel;
|
||||
for (const [key, type] of this.responseTupelList) {
|
||||
switch (type) {
|
||||
case 'string':
|
||||
response[key] = responseInstance.nächsterText();
|
||||
|
||||
5
src/electron/preload.cts
Normal file
5
src/electron/preload.cts
Normal file
@ -0,0 +1,5 @@
|
||||
const electron: typeof Electron = require('electron');
|
||||
|
||||
electron.contextBridge.exposeInMainWorld('electron', {
|
||||
ping: () => electron.ipcRenderer.invoke('ping'),
|
||||
} satisfies Window['electron']);
|
||||
@ -6,7 +6,7 @@
|
||||
"moduleResolution": "NodeNext",
|
||||
"esModuleInterop": true,
|
||||
"outDir": "../../dist-electron",
|
||||
"skipLibCheck": true
|
||||
//"types": ["../../types"]
|
||||
"skipLibCheck": true,
|
||||
"types": ["../../types"]
|
||||
}
|
||||
}
|
||||
|
||||
36
src/electron/utils.ts
Normal file
36
src/electron/utils.ts
Normal file
@ -0,0 +1,36 @@
|
||||
import path from 'path';
|
||||
import {app} from 'electron';
|
||||
|
||||
/**
|
||||
* @returns true, when the application is starded in develpoment mode
|
||||
*/
|
||||
export function inDevelopment(): boolean {
|
||||
return process.env.NODE_ENV === 'development';
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an error into a stringified object
|
||||
* @param error
|
||||
* @returns an indented JSON srting
|
||||
*/
|
||||
export function stringifyError(error: Error): string {
|
||||
const {message, stack} = error;
|
||||
|
||||
return JSON.stringify(
|
||||
{
|
||||
message,
|
||||
stack,
|
||||
},
|
||||
null,
|
||||
2,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* resolves the path of the preload script, based on in which state the application is starded
|
||||
* @returns the path to the preload script
|
||||
*/
|
||||
export function getPreloadPath(): string {
|
||||
const preloadScript = '/dist-electron/preload.cjs';
|
||||
return path.join(app.getAppPath(), inDevelopment() ? '.' : '..', preloadScript);
|
||||
}
|
||||
@ -5,6 +5,7 @@
|
||||
|
||||
<main>
|
||||
<p>Hallo Welt</p>
|
||||
|
||||
<div>
|
||||
<a href="https://svelte.dev" target="_blank" rel="noreferrer">
|
||||
<img src={svelteLogo} class="logo svelte" alt="Svelte Logo" />
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
{
|
||||
"extends": "@tsconfig/svelte/tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"types": ["./types"],
|
||||
"target": "ESNext",
|
||||
"useDefineForClassFields": true,
|
||||
"module": "ESNext",
|
||||
|
||||
8
types.d.ts
vendored
Normal file
8
types.d.ts
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
/**
|
||||
* Extends the Main "Window" Interface
|
||||
*/
|
||||
interface Window {
|
||||
electron: {
|
||||
ping: () => Promise<string>;
|
||||
};
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user