@siemsiem/tonpleun 0.1.1 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/GEN.d.ts +1 -0
- package/dist/GEN.js +12 -0
- package/dist/GEN.js.map +1 -0
- package/dist/client.d.ts +1 -0
- package/dist/client.js +49 -0
- package/dist/client.js.map +1 -0
- package/dist/client2.d.ts +1 -0
- package/dist/client2.js +26 -0
- package/dist/client2.js.map +1 -0
- package/dist/clientLib.d.ts +11 -0
- package/dist/clientLib.js +172 -0
- package/dist/clientLib.js.map +1 -0
- package/dist/helpers.d.ts +5 -0
- package/dist/helpers.js +17 -0
- package/dist/helpers.js.map +1 -0
- package/dist/server.d.ts +1 -0
- package/dist/server.js +145 -0
- package/dist/server.js.map +1 -0
- package/dist/test3.d.ts +1 -0
- package/dist/test3.js +16 -0
- package/dist/test3.js.map +1 -0
- package/dist/types.d.ts +77 -0
- package/dist/types.js +25 -0
- package/dist/types.js.map +1 -0
- package/dist/v1/client.d.ts +1 -0
- package/dist/v1/client.js +17 -0
- package/dist/v1/client.js.map +1 -0
- package/dist/v1/lib.d.ts +28 -0
- package/dist/v1/lib.js +191 -0
- package/dist/v1/lib.js.map +1 -0
- package/dist/v1/main.d.ts +1 -0
- package/dist/v1/main.js +195 -0
- package/dist/v1/main.js.map +1 -0
- package/dist/v1/test2.d.ts +1 -0
- package/dist/v1/test2.js +13 -0
- package/dist/v1/test2.js.map +1 -0
- package/package.json +10 -3
- package/src/GEN.ts +11 -0
- package/src/client.ts +1 -1
- package/src/client2.ts +4 -1
- package/src/clientLib.ts +40 -7
- package/src/server.ts +29 -3
- package/src/test3.ts +11 -0
- package/src/types.ts +11 -2
- package/tsconfig.json +0 -39
- package/webui/clientLib.js +0 -186
- package/webui/index.html +0 -22
- package/webui/main.js +0 -22
package/src/server.ts
CHANGED
|
@@ -1,17 +1,43 @@
|
|
|
1
1
|
import { log, successPacketBuilder, WsSend } from './helpers.js';
|
|
2
2
|
import { WebSocketServer, WebSocket } from 'ws';
|
|
3
|
-
import { requestType, stringPacketOptions, type
|
|
3
|
+
import { InitResponsePacket, requestType, stringPacketOptions, type namedFakeType, type getServicePacket, type getServicePacketClient, type GetServiceResponsePacketToClient, type InitPacket, type packet, type registerConfigPacket, type RegisterServicePacket, type setConfigPacket } from './types.js';
|
|
4
4
|
|
|
5
5
|
function mapToObject(map: Map<any, any>) {
|
|
6
6
|
return Object.fromEntries([...map.entries()].map(([kMaxLength, v]): any => [kMaxLength, v instanceof Map ? mapToObject(v) : v]))
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
+
const VERSION = {
|
|
10
|
+
MAJOR: 1,
|
|
11
|
+
MINOR: 1,
|
|
12
|
+
PATCH: 2
|
|
13
|
+
}
|
|
14
|
+
|
|
9
15
|
let clients: Record<string, WebSocket> = {};
|
|
10
|
-
let services = new Map<string, Map<string,
|
|
16
|
+
let services = new Map<string, Map<string, namedFakeType[]>>();
|
|
11
17
|
let configs = new Map<string, Map<string, registerConfigPacket>>();
|
|
12
18
|
let localServices = new Map<string, (...args: any[]) => any>();
|
|
13
19
|
localServices.set('getServices', (...args: any[]) => { return mapToObject(services) })
|
|
14
20
|
localServices.set('getConfigs', (...args: any[]) => { return mapToObject(configs) })
|
|
21
|
+
localServices.set('genHelper', (...args: any[]) => {
|
|
22
|
+
let output = '/* Dit bestand is automatisch gegenereerd door Tonpleun. Wijzigingen hierin worden overschreven. */\n\n';
|
|
23
|
+
output += `import { getService } from './clientLib.js';\n\n`;
|
|
24
|
+
|
|
25
|
+
services.forEach((serviceMap, clientId) => {
|
|
26
|
+
output += `// Services for client: ${clientId}\n`;
|
|
27
|
+
serviceMap.forEach((argTypes, serviceId) => {
|
|
28
|
+
output += `// ${serviceId}\n`;
|
|
29
|
+
output += `export async function ${serviceId}(`;
|
|
30
|
+
output += argTypes.map((type, _) => `${type.name}: ${type.type}`).join(', ');
|
|
31
|
+
output += `): Promise<any> {\n`;
|
|
32
|
+
output += ` return await getService('${serviceId}', '${clientId}', [${argTypes.map((arg, _) => `${arg.name}`).join(', ')}]);\n`;
|
|
33
|
+
output += `}\n\n`;
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
output += `// Tonpleun versie: ${VERSION.MAJOR}.${VERSION.MINOR}.${VERSION.PATCH}\n`;
|
|
38
|
+
output += `// Genereer dit bestand opnieuw met de genHelper service indien services zijn gewijzigd.\n`;
|
|
39
|
+
return output;
|
|
40
|
+
});
|
|
15
41
|
// Map a unique connectionId to the original requester WebSocket
|
|
16
42
|
const connectionMap = new Map<string, WebSocket>();
|
|
17
43
|
const wsServer = new WebSocketServer({ host: '0.0.0.0', port: 8765 });
|
|
@@ -31,7 +57,7 @@ wsServer.on('connection', (ws, req) => {
|
|
|
31
57
|
// initialize per-client config store to avoid undefined access
|
|
32
58
|
configs.set(id, new Map())
|
|
33
59
|
log(id, 'ws init gedaan, client id gegeven. ip: ', req.socket.remoteAddress);
|
|
34
|
-
WsSend(ws,
|
|
60
|
+
WsSend(ws, { type: requestType.Init, data: { versionMajor: VERSION.MAJOR, versionMinor: VERSION.MINOR, versionPatch: VERSION.MINOR } as InitResponsePacket } as packet);
|
|
35
61
|
break;
|
|
36
62
|
case requestType.RegisterService:
|
|
37
63
|
data = jsonData.data as RegisterServicePacket;
|
package/src/test3.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { getService, initializeClient, SetConfigItem, genHelper } from './clientLib.js'
|
|
2
|
+
import { echo } from './GEN.js';
|
|
3
|
+
import assert from 'node:assert/strict';
|
|
4
|
+
|
|
5
|
+
async function main() {
|
|
6
|
+
await initializeClient('Client3');
|
|
7
|
+
echo('Hello from Client3').then((result) => {
|
|
8
|
+
assert.equal(result, 'pindakaas');
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
main();
|
package/src/types.ts
CHANGED
|
@@ -10,6 +10,10 @@ export enum requestType {
|
|
|
10
10
|
}
|
|
11
11
|
export enum stringPacketOptions { Error, initSuccess, registerServiceSuccess, getServiceSuccess, registerConfigSuccess, setConfigSuccess };
|
|
12
12
|
export type fakeTypeType = "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function";
|
|
13
|
+
export type namedFakeType = {
|
|
14
|
+
name: string,
|
|
15
|
+
type: fakeTypeType
|
|
16
|
+
};
|
|
13
17
|
export type packet = {
|
|
14
18
|
type: requestType,
|
|
15
19
|
data: any,
|
|
@@ -18,6 +22,12 @@ export type packet = {
|
|
|
18
22
|
export type InitPacket = {
|
|
19
23
|
ClientId: string,
|
|
20
24
|
}
|
|
25
|
+
// requestType.Init response
|
|
26
|
+
export type InitResponsePacket = {
|
|
27
|
+
versionMajor: number,
|
|
28
|
+
versionMinor: number,
|
|
29
|
+
versionPatch: number,
|
|
30
|
+
}
|
|
21
31
|
// requestType.Success en requestType.Error
|
|
22
32
|
export type StringPacket = {
|
|
23
33
|
msg: string,
|
|
@@ -26,7 +36,7 @@ export type StringPacket = {
|
|
|
26
36
|
// requestType.RegisterService
|
|
27
37
|
export type RegisterServicePacket = {
|
|
28
38
|
ServiceId: string,
|
|
29
|
-
args:
|
|
39
|
+
args: namedFakeType[]
|
|
30
40
|
}
|
|
31
41
|
// requestType.GetService ( client1 -> server)
|
|
32
42
|
export type getServicePacket = {
|
|
@@ -35,7 +45,6 @@ export type getServicePacket = {
|
|
|
35
45
|
connectionId: string,
|
|
36
46
|
args: any[],
|
|
37
47
|
}
|
|
38
|
-
export type args = fakeTypeType[];
|
|
39
48
|
// requestType.getService (server -> client2)
|
|
40
49
|
export type getServicePacketClient = {
|
|
41
50
|
ServiceId: string,
|
package/tsconfig.json
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
// Visit https://aka.ms/tsconfig to read more about this file
|
|
3
|
-
"compilerOptions": {
|
|
4
|
-
// File Layout
|
|
5
|
-
"rootDir": "./src",
|
|
6
|
-
"outDir": "./dist",
|
|
7
|
-
// Environment Settings
|
|
8
|
-
// See also https://aka.ms/tsconfig/module
|
|
9
|
-
"module": "nodenext",
|
|
10
|
-
"target": "esnext",
|
|
11
|
-
"types": [],
|
|
12
|
-
// For nodejs:
|
|
13
|
-
// "lib": ["esnext"],
|
|
14
|
-
// "types": ["node"],
|
|
15
|
-
// and npm install -D @types/node
|
|
16
|
-
// Other Outputs
|
|
17
|
-
"sourceMap": true,
|
|
18
|
-
"declaration": true,
|
|
19
|
-
"declarationMap": true,
|
|
20
|
-
// Stricter Typechecking Options
|
|
21
|
-
"noUncheckedIndexedAccess": true,
|
|
22
|
-
"exactOptionalPropertyTypes": true,
|
|
23
|
-
// Style Options
|
|
24
|
-
// "noImplicitReturns": true,
|
|
25
|
-
// "noImplicitOverride": true,
|
|
26
|
-
// "noUnusedLocals": true,
|
|
27
|
-
// "noUnusedParameters": true,
|
|
28
|
-
// "noFallthroughCasesInSwitch": true,
|
|
29
|
-
// "noPropertyAccessFromIndexSignature": true,
|
|
30
|
-
// Recommended Options
|
|
31
|
-
"strict": true,
|
|
32
|
-
"jsx": "react-jsx",
|
|
33
|
-
"verbatimModuleSyntax": true,
|
|
34
|
-
"isolatedModules": true,
|
|
35
|
-
"noUncheckedSideEffectImports": true,
|
|
36
|
-
"moduleDetection": "force",
|
|
37
|
-
"skipLibCheck": true,
|
|
38
|
-
}
|
|
39
|
-
}
|
package/webui/clientLib.js
DELETED
|
@@ -1,186 +0,0 @@
|
|
|
1
|
-
// Browser versie
|
|
2
|
-
|
|
3
|
-
var requestType;
|
|
4
|
-
(function (requestType) {
|
|
5
|
-
requestType[requestType["Init"] = 0] = "Init";
|
|
6
|
-
requestType[requestType["Success"] = 1] = "Success";
|
|
7
|
-
requestType[requestType["Error"] = 2] = "Error";
|
|
8
|
-
requestType[requestType["RegisterService"] = 3] = "RegisterService";
|
|
9
|
-
requestType[requestType["GetServiceResponse"] = 4] = "GetServiceResponse";
|
|
10
|
-
requestType[requestType["GetService"] = 5] = "GetService";
|
|
11
|
-
requestType[requestType["RegisterConifg"] = 6] = "RegisterConifg";
|
|
12
|
-
requestType[requestType["SetConfig"] = 7] = "SetConfig";
|
|
13
|
-
})(requestType || (requestType = {}));
|
|
14
|
-
|
|
15
|
-
var stringPacketOptions;
|
|
16
|
-
(function (stringPacketOptions) {
|
|
17
|
-
stringPacketOptions[stringPacketOptions["Error"] = 0] = "Error";
|
|
18
|
-
stringPacketOptions[stringPacketOptions["initSuccess"] = 1] = "initSuccess";
|
|
19
|
-
stringPacketOptions[stringPacketOptions["registerServiceSuccess"] = 2] = "registerServiceSuccess";
|
|
20
|
-
stringPacketOptions[stringPacketOptions["getServiceSuccess"] = 3] = "getServiceSuccess";
|
|
21
|
-
stringPacketOptions[stringPacketOptions["registerConfigSuccess"] = 4] = "registerConfigSuccess";
|
|
22
|
-
stringPacketOptions[stringPacketOptions["setConfigSuccess"] = 5] = "setConfigSuccess";
|
|
23
|
-
})(stringPacketOptions || (stringPacketOptions = {}));
|
|
24
|
-
|
|
25
|
-
const url = "ws://localhost:8765";
|
|
26
|
-
export let ws;
|
|
27
|
-
const serviceCallbacks = new Map();
|
|
28
|
-
const localConfigs = new Map();
|
|
29
|
-
|
|
30
|
-
export async function awaitServiceMessage(expectedFor) {
|
|
31
|
-
return new Promise((resolve) => {
|
|
32
|
-
const handler = (event) => {
|
|
33
|
-
try {
|
|
34
|
-
const rawPacket = JSON.parse(event.data);
|
|
35
|
-
if (rawPacket.type === requestType.Success) {
|
|
36
|
-
const data = rawPacket.data;
|
|
37
|
-
if (data.for === expectedFor) {
|
|
38
|
-
ws.removeEventListener('message', handler);
|
|
39
|
-
resolve(data);
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
} catch (e) {
|
|
43
|
-
// ignore malformed packets
|
|
44
|
-
}
|
|
45
|
-
};
|
|
46
|
-
ws.addEventListener('message', handler);
|
|
47
|
-
});
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
function WsSend(ws, data) {
|
|
51
|
-
if (ws && ws.readyState === WebSocket.OPEN) {
|
|
52
|
-
ws.send(JSON.stringify(data));
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
export async function registerService(ServiceId, args, callback) {
|
|
57
|
-
WsSend(ws, { type: requestType.RegisterService, data: { ServiceId, args } });
|
|
58
|
-
serviceCallbacks.set(ServiceId, callback);
|
|
59
|
-
return await awaitServiceMessage(stringPacketOptions.registerServiceSuccess);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
export async function registerConfigItem(name, description, value, idthing) {
|
|
63
|
-
WsSend(ws, {
|
|
64
|
-
type: requestType.RegisterConifg,
|
|
65
|
-
data: {
|
|
66
|
-
name: name,
|
|
67
|
-
description: description,
|
|
68
|
-
defaultValue: value,
|
|
69
|
-
type: typeof value,
|
|
70
|
-
id: idthing
|
|
71
|
-
}
|
|
72
|
-
});
|
|
73
|
-
return await awaitServiceMessage(stringPacketOptions.registerConfigSuccess).then((msg) => {
|
|
74
|
-
localConfigs.set(idthing, {
|
|
75
|
-
name,
|
|
76
|
-
id: idthing,
|
|
77
|
-
description,
|
|
78
|
-
type: typeof value,
|
|
79
|
-
defaultValue: value
|
|
80
|
-
});
|
|
81
|
-
return msg;
|
|
82
|
-
});
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
export async function SetConfigItem(idthing, newValue, clientId) {
|
|
86
|
-
WsSend(ws, {
|
|
87
|
-
type: requestType.SetConfig,
|
|
88
|
-
data: {
|
|
89
|
-
ClientId: clientId,
|
|
90
|
-
id: idthing,
|
|
91
|
-
newValue: newValue
|
|
92
|
-
}
|
|
93
|
-
});
|
|
94
|
-
return await awaitServiceMessage(stringPacketOptions.setConfigSuccess).then((msg) => {
|
|
95
|
-
const existing = localConfigs.get(idthing);
|
|
96
|
-
if (existing) {
|
|
97
|
-
localConfigs.set(idthing, { ...existing, value: newValue });
|
|
98
|
-
}
|
|
99
|
-
return msg;
|
|
100
|
-
});
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
export async function getService(ServiceId, ClientId, inputs) {
|
|
104
|
-
const connectionId =
|
|
105
|
-
(typeof crypto !== 'undefined' && crypto.randomUUID)
|
|
106
|
-
? crypto.randomUUID()
|
|
107
|
-
: `${Date.now()}-${Math.random().toString(16).slice(2)}`;
|
|
108
|
-
|
|
109
|
-
WsSend(ws, { type: requestType.GetService, data: { ClientId, ServiceId, args: inputs, connectionId } });
|
|
110
|
-
|
|
111
|
-
return new Promise((resolve) => {
|
|
112
|
-
const handler = (event) => {
|
|
113
|
-
try {
|
|
114
|
-
const rawPacket = JSON.parse(event.data);
|
|
115
|
-
if (rawPacket.type === requestType.GetServiceResponse) {
|
|
116
|
-
const data = rawPacket.data;
|
|
117
|
-
if (data.serviceId === ServiceId && data.connectionId === connectionId) {
|
|
118
|
-
ws.removeEventListener('message', handler);
|
|
119
|
-
resolve(data.result);
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
} catch (e) {
|
|
123
|
-
// ignore malformed packets
|
|
124
|
-
}
|
|
125
|
-
};
|
|
126
|
-
ws.addEventListener('message', handler);
|
|
127
|
-
});
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
export async function initializeClient(ClientId) {
|
|
131
|
-
ws = new WebSocket(url);
|
|
132
|
-
|
|
133
|
-
ws.addEventListener('open', () => {
|
|
134
|
-
console.log('Verbonden met tonpleun server.');
|
|
135
|
-
WsSend(ws, { type: requestType.Init, data: { ClientId } });
|
|
136
|
-
});
|
|
137
|
-
|
|
138
|
-
ws.addEventListener('close', () => {
|
|
139
|
-
console.log('Verbinding met tonpleun server gesloten.');
|
|
140
|
-
});
|
|
141
|
-
|
|
142
|
-
ws.addEventListener('error', (event) => {
|
|
143
|
-
console.error('Fout opgetreden:', event);
|
|
144
|
-
try { ws.close(); } catch { }
|
|
145
|
-
});
|
|
146
|
-
|
|
147
|
-
ws.addEventListener('message', async (event) => {
|
|
148
|
-
try {
|
|
149
|
-
const rawPacket = JSON.parse(event.data);
|
|
150
|
-
if (rawPacket.type === requestType.GetService) {
|
|
151
|
-
const serviceData = rawPacket.data;
|
|
152
|
-
const callback = serviceCallbacks.get(serviceData.ServiceId);
|
|
153
|
-
if (callback) {
|
|
154
|
-
try {
|
|
155
|
-
const result = await Promise.resolve(callback(...serviceData.args));
|
|
156
|
-
WsSend(ws, {
|
|
157
|
-
type: requestType.GetServiceResponse,
|
|
158
|
-
data: {
|
|
159
|
-
result,
|
|
160
|
-
ServiceId: serviceData.ServiceId,
|
|
161
|
-
connectionId: serviceData.connectionId,
|
|
162
|
-
}
|
|
163
|
-
});
|
|
164
|
-
} catch (error) {
|
|
165
|
-
console.error(`Fout bij uitvoeren van service ${serviceData.ServiceId}:`, error);
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
} else if (rawPacket.type === requestType.SetConfig) {
|
|
169
|
-
const cfg = rawPacket.data;
|
|
170
|
-
const existing = localConfigs.get(cfg.id);
|
|
171
|
-
if (existing) {
|
|
172
|
-
localConfigs.set(cfg.id, { ...existing, value: cfg.newValue });
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
} catch (e) {
|
|
176
|
-
// ignore malformed packets
|
|
177
|
-
}
|
|
178
|
-
});
|
|
179
|
-
|
|
180
|
-
return await awaitServiceMessage(stringPacketOptions.initSuccess);
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
export function getConfigValue(id) {
|
|
184
|
-
const item = localConfigs.get(id);
|
|
185
|
-
return item ? (item.value ?? item.defaultValue) : undefined;
|
|
186
|
-
}
|
package/webui/index.html
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
<html lang="en">
|
|
2
|
-
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="UTF-8">
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
-
<title>Tonpleun webui</title>
|
|
7
|
-
<script type="module" src="main.js"></script>
|
|
8
|
-
</head>
|
|
9
|
-
|
|
10
|
-
<body id="out">
|
|
11
|
-
<div id="buttonList">
|
|
12
|
-
</div>
|
|
13
|
-
<div id="container"></div>
|
|
14
|
-
<script>function onchangeOfthing(newValue) {
|
|
15
|
-
const container = document.getElementById('container');
|
|
16
|
-
const localdata = window.dataMap.get(newValue);
|
|
17
|
-
container.innerText = JSON.stringify(localdata);
|
|
18
|
-
}</script>
|
|
19
|
-
|
|
20
|
-
</body>
|
|
21
|
-
|
|
22
|
-
</html>
|
package/webui/main.js
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { getService, initializeClient } from "./clientLib.js";
|
|
2
|
-
async function main() {
|
|
3
|
-
await initializeClient('webUI');
|
|
4
|
-
getData();
|
|
5
|
-
setInterval(getData, 1000);
|
|
6
|
-
}
|
|
7
|
-
async function getData() {
|
|
8
|
-
const data = await getService('getConfigs', 'tonpleun', []);
|
|
9
|
-
console.log('data update')
|
|
10
|
-
window.tonpleunData = data;
|
|
11
|
-
update(window.tonpleunData);
|
|
12
|
-
|
|
13
|
-
}
|
|
14
|
-
function update(data) {
|
|
15
|
-
window.dataMap = new Map(Object.entries(data));
|
|
16
|
-
document.getElementById('buttonList').innerHTML = '';
|
|
17
|
-
window.dataMap.forEach((dinges, name) => {
|
|
18
|
-
console.log(name, dinges);
|
|
19
|
-
document.getElementById('buttonList').innerHTML += '<button onclick="onchangeOfthing(\'' + name + '\')">' + name + '</button>';
|
|
20
|
-
});
|
|
21
|
-
}
|
|
22
|
-
main();
|