Erweiterung um preload und typen
This commit is contained in:
parent
b1f264424c
commit
56c16a6ab8
@ -1,6 +1,7 @@
|
|||||||
{
|
{
|
||||||
"appId": "com.nwaschk.api-tool",
|
"appId": "com.nwaschk.api-tool",
|
||||||
"files": ["dist-electron", "dist-svelte"],
|
"files": ["dist-electron", "dist-svelte"],
|
||||||
|
"extraResources": ["dist-electron/preload.cjs"],
|
||||||
"icon": "./desktopIcon.png",
|
"icon": "./desktopIcon.png",
|
||||||
"mac": {
|
"mac": {
|
||||||
"target": "dmg"
|
"target": "dmg"
|
||||||
|
|||||||
@ -1,17 +1,24 @@
|
|||||||
import {app, BrowserWindow} from 'electron';
|
import {app, BrowserWindow} from 'electron';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
|
import {getPreloadPath, inDevelopment} from './utils.js';
|
||||||
|
import {ipcMain} from 'electron/main';
|
||||||
import {ProdressConnection} from './pdr2com/connection.js';
|
import {ProdressConnection} from './pdr2com/connection.js';
|
||||||
|
|
||||||
const APPLICATION_PATH = path.join(app.getAppPath(), '/dist-svelte/index.html');
|
const APPLICATION_PATH = path.join(app.getAppPath(), '/dist-svelte/index.html');
|
||||||
|
|
||||||
app.on('ready', async () => {
|
app.on('ready', async () => {
|
||||||
const mainWindow = new BrowserWindow({}); //@todo
|
const mainWindow = new BrowserWindow({
|
||||||
if (process.env.NODE_ENV === 'development') {
|
webPreferences: {
|
||||||
|
preload: getPreloadPath(),
|
||||||
|
},
|
||||||
|
}); //@todo
|
||||||
|
if (inDevelopment()) {
|
||||||
mainWindow.loadURL('http://localhost:5123/');
|
mainWindow.loadURL('http://localhost:5123/');
|
||||||
} else {
|
} else {
|
||||||
mainWindow.loadFile(APPLICATION_PATH);
|
mainWindow.loadFile(APPLICATION_PATH);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ipcMain.handle('ping', () => {
|
||||||
const req = new ProdressConnection(
|
const req = new ProdressConnection(
|
||||||
{
|
{
|
||||||
port: 4788,
|
port: 4788,
|
||||||
@ -26,25 +33,6 @@ app.on('ready', async () => {
|
|||||||
['line2', 'string'],
|
['line2', 'string'],
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
const res = await req.handleRequest();
|
return 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);
|
|
||||||
// }
|
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import {RequestLeser as ProdressListener, type R2AnfrageBlaupause} from '@prodress/pdr2com';
|
import {RequestLeser as ProdressListener, type R2AnfrageBlaupause} from '@prodress/pdr2com';
|
||||||
import {type ResponseTupel, type ResponseObject, ProdressRequest, type RequestTupel} from './wrapper.js';
|
import {type ResponseTupel, type ResponseObject, ProdressRequest, type RequestTupel} from './wrapper.js';
|
||||||
import {Socket} from 'node:net';
|
import {Socket} from 'node:net';
|
||||||
|
import {stringifyError} from '../utils.js';
|
||||||
|
|
||||||
export interface ProdressHeader {
|
export interface ProdressHeader {
|
||||||
port?: number;
|
port?: number;
|
||||||
@ -10,20 +11,9 @@ export interface ProdressHeader {
|
|||||||
action: string;
|
action: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
// @todo move to nyi utils file
|
/**
|
||||||
function stringifyError(error: Error): string {
|
* Initializes a TCP Socket, sends a ProdressRequest and listens to this Socket for one Response
|
||||||
const {message, stack} = error;
|
*/
|
||||||
|
|
||||||
return JSON.stringify(
|
|
||||||
{
|
|
||||||
message,
|
|
||||||
stack,
|
|
||||||
},
|
|
||||||
null,
|
|
||||||
2,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export class ProdressConnection {
|
export class ProdressConnection {
|
||||||
public static readonly TIMEOUT = 30_000;
|
public static readonly TIMEOUT = 30_000;
|
||||||
|
|
||||||
@ -35,6 +25,11 @@ export class ProdressConnection {
|
|||||||
private requestTupelList: RequestTupel[];
|
private requestTupelList: RequestTupel[];
|
||||||
private responseTupelList: ResponseTupel[];
|
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[]) {
|
public constructor(header: ProdressHeader, requestTupelList: RequestTupel[], responseTupelList: ResponseTupel[]) {
|
||||||
this.port = header.port ?? 4788;
|
this.port = header.port ?? 4788;
|
||||||
this.host = header.host ?? 'localhost';
|
this.host = header.host ?? 'localhost';
|
||||||
@ -45,8 +40,12 @@ export class ProdressConnection {
|
|||||||
this.responseTupelList = responseTupelList;
|
this.responseTupelList = responseTupelList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handels the request- and response-flow
|
||||||
|
*/
|
||||||
public async handleRequest(): Promise<string> {
|
public async handleRequest(): Promise<string> {
|
||||||
let response: 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) => {
|
const responseAsPromise = new Promise<string>((resolve) => {
|
||||||
this.socket.once('finished', () => {
|
this.socket.once('finished', () => {
|
||||||
if (!this.socket.destroyed) {
|
if (!this.socket.destroyed) {
|
||||||
@ -59,6 +58,7 @@ export class ProdressConnection {
|
|||||||
this.socket.setTimeout(ProdressConnection.TIMEOUT);
|
this.socket.setTimeout(ProdressConnection.TIMEOUT);
|
||||||
this.socket.connect(this.port, this.host);
|
this.socket.connect(this.port, this.host);
|
||||||
|
|
||||||
|
// Sends the writes and sends the request when the connecting is established
|
||||||
this.socket.once('connect', () => {
|
this.socket.once('connect', () => {
|
||||||
try {
|
try {
|
||||||
this.request.writeEntries(this.requestTupelList);
|
this.request.writeEntries(this.requestTupelList);
|
||||||
@ -81,11 +81,14 @@ export class ProdressConnection {
|
|||||||
this.finished();
|
this.finished();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Starts writing data from the buffer to the listener-instance and emits the "dataRecieved" event
|
||||||
this.socket.on('data', (data: Buffer) => {
|
this.socket.on('data', (data: Buffer) => {
|
||||||
this.listener.verarbeiteDaten(data);
|
this.listener.verarbeiteDaten(data);
|
||||||
this.socket.emit('dataRecieved');
|
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 () => {
|
this.socket.once('dataRecieved', async () => {
|
||||||
try {
|
try {
|
||||||
const incomingResponse = await this.listener.leseRequest();
|
const incomingResponse = await this.listener.leseRequest();
|
||||||
@ -97,9 +100,13 @@ export class ProdressConnection {
|
|||||||
this.finished();
|
this.finished();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return responseAsPromise;
|
return responseAsPromise;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Emits a custom "finished" event
|
||||||
|
*/
|
||||||
private finished(): void {
|
private finished(): void {
|
||||||
this.socket.emit('finished');
|
this.socket.emit('finished');
|
||||||
}
|
}
|
||||||
@ -112,8 +119,7 @@ export class ProdressConnection {
|
|||||||
private readResponse(responseInstance: R2AnfrageBlaupause): ResponseObject {
|
private readResponse(responseInstance: R2AnfrageBlaupause): ResponseObject {
|
||||||
const response: ResponseObject = {};
|
const response: ResponseObject = {};
|
||||||
|
|
||||||
for (const tupel of this.responseTupelList) {
|
for (const [key, type] of this.responseTupelList) {
|
||||||
const [key, type] = tupel;
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 'string':
|
case 'string':
|
||||||
response[key] = responseInstance.nächsterText();
|
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",
|
"moduleResolution": "NodeNext",
|
||||||
"esModuleInterop": true,
|
"esModuleInterop": true,
|
||||||
"outDir": "../../dist-electron",
|
"outDir": "../../dist-electron",
|
||||||
"skipLibCheck": true
|
"skipLibCheck": true,
|
||||||
//"types": ["../../types"]
|
"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>
|
<main>
|
||||||
<p>Hallo Welt</p>
|
<p>Hallo Welt</p>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<a href="https://svelte.dev" target="_blank" rel="noreferrer">
|
<a href="https://svelte.dev" target="_blank" rel="noreferrer">
|
||||||
<img src={svelteLogo} class="logo svelte" alt="Svelte Logo" />
|
<img src={svelteLogo} class="logo svelte" alt="Svelte Logo" />
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
{
|
{
|
||||||
"extends": "@tsconfig/svelte/tsconfig.json",
|
"extends": "@tsconfig/svelte/tsconfig.json",
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
|
"types": ["./types"],
|
||||||
"target": "ESNext",
|
"target": "ESNext",
|
||||||
"useDefineForClassFields": true,
|
"useDefineForClassFields": true,
|
||||||
"module": "ESNext",
|
"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