mirror of
https://github.com/tcsenpai/Spin.git
synced 2025-06-03 18:00:18 +00:00
Initial commit
This commit is contained in:
commit
7a7f027796
8
.gitignore
vendored
Normal file
8
.gitignore
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
|
||||
.DS_Store
|
||||
|
||||
node_modules/.bin/
|
||||
|
||||
node_modules/
|
||||
|
||||
spin.zip
|
202
README.md
Normal file
202
README.md
Normal file
@ -0,0 +1,202 @@
|
||||
# Spin - The multithreading manager for Electron
|
||||
|
||||
## Pre-alpha version
|
||||
|
||||
### Introduction
|
||||
|
||||
Spin is a template that allows you to start a simple Electron application with included a boilerplate code that contains methods for managing multithreading processes in a simple way.
|
||||
|
||||
Some of the methods are related to code execution, others allows also to customize the page HTML in the children processes.
|
||||
|
||||
### Architecture
|
||||
|
||||
The project makes an extensive use of the worker_threads npm module, available in all the modern npm versions.
|
||||
|
||||
The majority of the code is in main.js, enclosed in a SECTION comment tag and commented. In the included worker example script, you can easily examine and apply Spin methods to your project.
|
||||
|
||||
### Examples
|
||||
|
||||
in main.js, after creating a window, you can add something like:
|
||||
|
||||
```javascript
|
||||
start_subroutine("process", "./process.js", { })
|
||||
```
|
||||
|
||||
Now the code in process.js will be executed and a listener will be added to
|
||||
monitor messages from process.js .
|
||||
|
||||
In process.js you can write whatever you like but you have to include Spin code as provided in the example worker script.
|
||||
|
||||
You can use a code like this to communicate from process.js to the main process:
|
||||
|
||||
```javascript
|
||||
let message_id = getHTML("id_in_html")
|
||||
print("Sent message: " + message_id)
|
||||
```
|
||||
|
||||
This way you are using the included code to get the html of an element with the specified HTML id field. The response is managed by the parse_message method that is triggered each time a message from main is received.
|
||||
|
||||
As you already know your message_id, you can use the check_response method to determine which is the response of the main process:
|
||||
|
||||
```javascript
|
||||
let response = check_response(message_id, callback_method);
|
||||
```
|
||||
|
||||
Take into account that callback_method can be any method ( with or without parameters ) that you want to define. The only requirement is accepting a first parameter with the message id as check_response will pass it to the method. Having the response stored into messages_awaiting, you can do something like this:
|
||||
|
||||
```javascript
|
||||
function callback_method(message_id) {
|
||||
print("[*] I am printing the result: " + messages_awaiting[message_id]);
|
||||
}
|
||||
```
|
||||
As a living example, the send_message method uses check_response with a method that prints the result to the console, to ensure that the message has been properly received.
|
||||
|
||||
On another hand, you can write your own methods to send and receive messages
|
||||
to and from the main process.
|
||||
|
||||
To do this, follow the instructions in the next paragraph.
|
||||
|
||||
### Adding your handlers
|
||||
|
||||
The main.js code contains a method called parseMessage, which is called when the message from the worker is received. You are free to edit or add a condition like:
|
||||
|
||||
```javascript
|
||||
else if (type == "your_customized_type") {
|
||||
// Do something
|
||||
return true, "Your customized response"
|
||||
}
|
||||
```
|
||||
|
||||
As you can see, the only required part is the return value defined as a boolean plus the message (it can be false plus error message too, of course).
|
||||
|
||||
As a last step, you can use your customized handle in your worker code, for example doing the following:
|
||||
|
||||
```javascript
|
||||
function myFunction() {
|
||||
let payload = {
|
||||
"type": 'your_customized_type',
|
||||
"your_field": 'your_field_content',
|
||||
"another_field": 'another_content'
|
||||
}
|
||||
let msg_id = send_message(payload)
|
||||
return msg_id
|
||||
}
|
||||
```
|
||||
|
||||
Then you can use that function in the same way as a built-in Spin function:
|
||||
|
||||
```javascript
|
||||
let msg_id = myFunction()
|
||||
let status
|
||||
let response
|
||||
[status, response] = waitForResponse(msg_id, 1000)
|
||||
```
|
||||
|
||||
### Managing the messages from the main process
|
||||
|
||||
As you can easily see, the worker process contains the start() method which is called when the script is started. You can play with this but remember to keep the included code to be executed as soon as possible:
|
||||
|
||||
```javascript
|
||||
function start () {
|
||||
// NOTE Handling messages from the main process
|
||||
parentPort.on('message', (message) => {
|
||||
// NOTE Handle responses
|
||||
let j_message = JSON.parse(message.toString('utf8'))
|
||||
parse_message(j_message)
|
||||
});
|
||||
```
|
||||
|
||||
The parse_message(message) function is called every time the main process
|
||||
send a message to the worker. By default, the method parses the message and if type is "response", it looks for the message id field in the message. If the message id is found in the waiting queue dictionary:
|
||||
|
||||
```javascript
|
||||
messages_awaiting[id]
|
||||
```
|
||||
|
||||
And its response value is null:
|
||||
|
||||
```javascript
|
||||
messages_awaiting[id].response==null
|
||||
```
|
||||
|
||||
The method assign to the response field of the waiting queue dictionary the message contained in the message from main process:
|
||||
|
||||
```javascript
|
||||
messages_awaiting[id].response = JSON.stringify(message)
|
||||
```
|
||||
|
||||
The above code is already included and is reported just to illustrate the mechanism behind what happens.
|
||||
|
||||
From your code, you can then check in any way you want the response field of the message you sent to the main process as described above or do whatever you want playing with parse_message method as for example adding different types of messages.
|
||||
|
||||
In main.js, of course, you will need to insert a code corresponding to your custom handler, as:
|
||||
|
||||
```javascript
|
||||
subroutine["routine_name"].postMessage(JSON.stringify({
|
||||
"type": "your_type",
|
||||
"your_field": "your_content"
|
||||
}))
|
||||
```
|
||||
|
||||
For example in a specific method, or on a specific condition.
|
||||
|
||||
### Proof of Concept
|
||||
|
||||
To better illustrate how this codebase works, let's make an example.
|
||||
By using the following methods in your worker file (e.g. worker_template.js) inside the start() method:
|
||||
|
||||
```javascript
|
||||
setHTML("editable", "<h2>2D Engine test</h2>")
|
||||
setBackgroundStyle("backgroundColor", "red")
|
||||
setBackgroundStyle("width", "90%")
|
||||
setBackgroundStyle("height", "75vh")
|
||||
setBackgroundStyle( "border", "1px solid navy")
|
||||
setStyle("background", "margin", "auto")
|
||||
```
|
||||
|
||||
You will obtain:
|
||||
|
||||

|
||||
|
||||
### Recommendations
|
||||
|
||||
- Adding custom handlers requires paying attention to existing ones and to code organization. It is very easy to implement too many custom handlers and to ending up making the code's complexity explode
|
||||
- This codebase is intended as a simple example of implementing the Spin methods and is not intended to be used directly in production environments
|
||||
- Please pay especially attention to security, for example sanitizing or filtering (or avoiding) unsupervised code execution through exec or through cross executed javascript
|
||||
- Once again, before using this in production environments remove all the methods that you don't need and double check security
|
||||
- This codebase is still in development
|
||||
|
||||
### Credits
|
||||
|
||||
Coded by TheCookingSenpai
|
||||
|
||||
### License
|
||||
|
||||
Distributed under the CreativeCommons CC-BY-SA 4.0 License
|
||||
|
||||
https://creativecommons.org/licenses/by-sa/4.0/
|
||||
|
||||
You are free to:
|
||||
Share — copy and redistribute the material in any medium or format
|
||||
Adapt — remix, transform, and build upon the material
|
||||
for any purpose, even commercially.
|
||||
This license is acceptable for Free Cultural Works.
|
||||
The licensor cannot revoke these freedoms as long as you follow the license terms.
|
||||
|
||||
Under the following terms:
|
||||
|
||||
- Attribution — You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use.
|
||||
|
||||
- SharehareAlike — If you remix, transform, or build upon the material, you must distribute your contributions under the same license as the original.
|
||||
|
||||
- No additional restrictions — You may not apply legal terms or technological measures that legally restrict others from doing anything the license permits.
|
||||
|
||||
Notices:
|
||||
|
||||
You do not have to comply with the license for elements of the material in the public domain or where your use is permitted by an applicable exception or limitation.
|
||||
|
||||
No warranties are given.
|
||||
|
||||
The license may not give you all of the permissions necessary for your intended use.
|
||||
|
||||
For example, other rights such as publicity, privacy, or moral rights may limit how you use the material.
|
23
index.html
Normal file
23
index.html
Normal file
@ -0,0 +1,23 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" href="style.css">
|
||||
<meta charset="UTF-8">
|
||||
<!-- !! IMPORTANT !! -->
|
||||
<!-- Content-Security-Policy no longer required. Will show warning in devtools. Can be ignored -->
|
||||
<!-- <meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline'"> -->
|
||||
<title>Spin Engine Demo</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Spin Engine Demo</h1>
|
||||
<div id="editable">
|
||||
|
||||
</div>
|
||||
|
||||
<!-- JS -->
|
||||
<script>
|
||||
// All the scripts are originated from main, but you can add any other script here
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
192
main.js
Normal file
192
main.js
Normal file
@ -0,0 +1,192 @@
|
||||
// NOTE Loading modules (app and BrowserWindow) for main and rederer
|
||||
const {app, BrowserWindow} = require('electron')
|
||||
const { Worker } = require('worker_threads')
|
||||
|
||||
// SECTION Subroutine management
|
||||
|
||||
// NOTE Loading subprocesses and starting the listeners
|
||||
subroutines = {}
|
||||
|
||||
function start_subroutine(name, path, data) {
|
||||
if (name in subroutines) {
|
||||
console.log("[x] Subroutine already exists")
|
||||
alert("Error launching the subroutine: subroutine already exists")
|
||||
return
|
||||
}
|
||||
subroutines[name] = new Worker(path, { workerData: data });
|
||||
subroutines[name].on('message', (message) => {
|
||||
// On message load it
|
||||
let j_message = JSON.parse(message.toString('utf8'))
|
||||
console.log("[*] Message from " + name)
|
||||
console.log(j_message)
|
||||
// Extract the message id
|
||||
let msg_id = j_message.id
|
||||
console.log("ID: " + msg_id)
|
||||
var result;
|
||||
var message;
|
||||
// Send it to the parser
|
||||
var packed = parseMessage(j_message, name)
|
||||
result = packed[0]
|
||||
message = packed[1]
|
||||
console.log(result)
|
||||
console.log(message)
|
||||
// Manage errors
|
||||
if (result == "error") {
|
||||
console.log("[x] Error in " + name + ".js")
|
||||
alert("Error in the subroutine " + name + " at " + path + ": " + message)
|
||||
}
|
||||
else {
|
||||
console.log("[+] Message from " + name + " parsed")
|
||||
}
|
||||
// Send the response back solving promises if any
|
||||
solved = null
|
||||
if (message.toString().includes("Promise")) {
|
||||
// In case of promise, solve it and send it
|
||||
message.then((value) => {
|
||||
console.log("Promise resolved: " + value)
|
||||
let payload = '{ "type": "response", "id": "' + msg_id + '", "result": "' + result + '", "message": "' + value + '"}'
|
||||
console.log("[*] Sending response: " + JSON.stringify(payload))
|
||||
subroutines[name].postMessage(JSON.stringify(payload))
|
||||
})
|
||||
} else {
|
||||
// In case of normal message, send it
|
||||
let payload = '{ "type": "response", "id": "' + msg_id + '", "result": "' + result + '", "message": "' + message + '"}'
|
||||
console.log("[*] Sending response: " + JSON.stringify(payload))
|
||||
subroutines[name].postMessage(JSON.stringify(payload))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// NOTE Parsing the response
|
||||
function parseMessage (j_response, sender) {
|
||||
// Schema being like:
|
||||
/*
|
||||
{
|
||||
"type": "render|info|error",
|
||||
[...] (properties of the above)
|
||||
}
|
||||
*/
|
||||
console.log("Parsing message from " + sender + ": " + JSON.stringify(j_response))
|
||||
let type = j_response.type
|
||||
let id = j_response.id
|
||||
if (type == "error") {
|
||||
console.log("[x] Error in " + sender + ".js")
|
||||
console.log(j_response.message)
|
||||
return ["error", j_response.message]
|
||||
}
|
||||
// NOTE Rendering an element (overwriting it if exists)
|
||||
else if (type == "render") {
|
||||
let element = j_response.element
|
||||
console.log("[*] Rendering")
|
||||
// Loading element to replace
|
||||
console.log("Element: " + element)
|
||||
// Normalizing and loading the HTML to insert
|
||||
let newHTML = j_response.html.replace("'", '"')
|
||||
console.log("HTML: " + newHTML)
|
||||
// Executing the rendering command
|
||||
let renderCmd = "document.getElementById('" + j_response.element + "').innerHTML += '" + newHTML + "'"
|
||||
console.log(renderCmd)
|
||||
mainWindow.webContents.executeJavaScript(renderCmd)
|
||||
console.log("[+] Rendered")
|
||||
return ["ok", "Rendered"]
|
||||
}
|
||||
// NOTE Changing style of an existing element
|
||||
else if (type == "style") {
|
||||
let element = j_response.element
|
||||
let property = j_response.property
|
||||
let value = j_response.value
|
||||
console.log("[*] Styling")
|
||||
// Loading element to replace
|
||||
console.log("Element: " + element)
|
||||
// Normalizing and loading the HTML to insert
|
||||
let newProperty = j_response.property.replace("'", '"')
|
||||
console.log("Property: " + newProperty)
|
||||
// Executing the rendering command
|
||||
let renderCmd = "document.getElementById('" + element + "').style." + property + "='" + value + "'"
|
||||
console.log(renderCmd)
|
||||
mainWindow.webContents.executeJavaScript(renderCmd)
|
||||
console.log("[+] Styled")
|
||||
return ["ok", "Styled"]
|
||||
}
|
||||
// NOTE Executing a js command
|
||||
// REVIEW Remember to sanitize it
|
||||
else if (j_response.type == "exec") {
|
||||
let command = j_response.command
|
||||
console.log("[*] Executing")
|
||||
console.log(command)
|
||||
mainWindow.webContents.executeJavaScript(command + ";")
|
||||
console.log("[+] Executed")
|
||||
return ["ok", "Executed"]
|
||||
}
|
||||
// NOTE Getting an existing element
|
||||
else if (type == "get") {
|
||||
let element = j_response.element
|
||||
console.log("[*] Getting " + element + " for renderer")
|
||||
let cmd = "document.getElementById('" + element + "');"
|
||||
console.log(cmd)
|
||||
let response = mainWindow.webContents.executeJavaScript("document.getElementById('" + element + "').innerHTML;")
|
||||
console.log("[+] Got " + element + " for renderer")
|
||||
console.log('[>] Returning ' + response)
|
||||
return ["ok", response]
|
||||
|
||||
|
||||
}
|
||||
else if (type == "info") {
|
||||
console.log("[i] Info from " + sender)
|
||||
console.log(j_response.message)
|
||||
return ["ok", "Info"]
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// !SECTION Subroutine management
|
||||
|
||||
// Keep a global reference of the window object, if you don't, the window will
|
||||
// be closed automatically when the JavaScript object is garbage collected.
|
||||
let mainWindow
|
||||
// Create a new BrowserWindow when `app` is ready
|
||||
// NOTE This is just a definition which will be executed later
|
||||
function createWindow () {
|
||||
|
||||
mainWindow = new BrowserWindow({
|
||||
width: 1280, height: 720,
|
||||
webPreferences: {
|
||||
// --- !! IMPORTANT !! ---
|
||||
// Disable 'contextIsolation' to allow 'nodeIntegration'
|
||||
// 'contextIsolation' defaults to "true" as from Electron v12
|
||||
contextIsolation: false,
|
||||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
// NOTE Load index.html into the new BrowserWindow
|
||||
mainWindow.loadFile('index.html')
|
||||
|
||||
// Open DevTools - Remove for PRODUCTION!
|
||||
//mainWindow.webContents.openDevTools();
|
||||
|
||||
// NOTE Listen for window being closed
|
||||
mainWindow.on('closed', () => {
|
||||
mainWindow = null
|
||||
})
|
||||
|
||||
// NOTE Once the window is loaded, start the subroutines
|
||||
// INFO: graphics subroutine is responsible for the loading of the graphics
|
||||
start_subroutine("template", "./worker_template.js", { })
|
||||
|
||||
}
|
||||
|
||||
// NOTE Listener for app ready that will execute the createWindow function
|
||||
app.on('ready', createWindow)
|
||||
|
||||
// NOTE Quit when all windows are closed - (Not macOS - Darwin)
|
||||
app.on('window-all-closed', () => {
|
||||
// also on mac
|
||||
app.quit()
|
||||
})
|
||||
|
||||
// NOTE When app icon is clicked and app is running, (macOS) recreate the BrowserWindow
|
||||
app.on('activate', () => {
|
||||
if (mainWindow === null) createWindow()
|
||||
})
|
2169
package-lock.json
generated
Normal file
2169
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
42
package.json
Normal file
42
package.json
Normal file
@ -0,0 +1,42 @@
|
||||
{
|
||||
"appId": "com.electron.yourapp",
|
||||
"name": "yourapp",
|
||||
"version": "1.0.0",
|
||||
"description": "Your description",
|
||||
"main": "main.js",
|
||||
"files": [],
|
||||
"mac": {
|
||||
"target": "dmg",
|
||||
"icon": "path/to.icns",
|
||||
"category": "public.app-category.category"
|
||||
},
|
||||
"win": {
|
||||
"target": "nsis",
|
||||
"icon": "path/to.ico",
|
||||
"requestedExecutionLevel": "highestAvailable"
|
||||
},
|
||||
"linux": {
|
||||
"target": "AppImage",
|
||||
"icon": "path/to.png"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "electron .",
|
||||
"watch": "nodemon --exec electron .",
|
||||
"reset": "git reset --hard"
|
||||
},
|
||||
"keywords": [
|
||||
"Electron",
|
||||
"Spin",
|
||||
"other keywords"
|
||||
],
|
||||
"author": "You",
|
||||
"license": "License type",
|
||||
"devDependencies": {
|
||||
"electron": "latest",
|
||||
"nodemon": "^2.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"fs": "^0.0.1-security",
|
||||
"observable-slim": "^0.1.6"
|
||||
}
|
||||
}
|
191
worker_template.js
Normal file
191
worker_template.js
Normal file
@ -0,0 +1,191 @@
|
||||
const fs = require('fs');
|
||||
const { parentPort } = require('worker_threads')
|
||||
|
||||
|
||||
// NOTE Is possible to load data from the main process
|
||||
// someVariable = workerData.someProperty
|
||||
|
||||
// SECTION Utilities
|
||||
|
||||
// NOTE Waiting list for the responses
|
||||
let messages_awaiting = {}
|
||||
let ready_responses = {}
|
||||
|
||||
// NOTE Allow generating a message id
|
||||
String.prototype.hashCode = function() {
|
||||
var hash = 0,
|
||||
i, chr;
|
||||
if (this.length === 0) return hash;
|
||||
for (i = 0; i < this.length; i++) {
|
||||
chr = this.charCodeAt(i);
|
||||
hash = ((hash << 5) - hash) + chr;
|
||||
hash |= 0; // Convert to 32bit integer
|
||||
}
|
||||
return Math.abs(hash).toString();
|
||||
}
|
||||
|
||||
// NOTE Sending messages to the main process
|
||||
function send_message(message, callback=null) {
|
||||
// Adding the message id to the message
|
||||
let _message = JSON.stringify(message)
|
||||
let msg_id = _message.hashCode()
|
||||
message["id"] = msg_id
|
||||
let string_message = JSON.stringify(message)
|
||||
// Creating a waiting structure for the response
|
||||
messages_awaiting[msg_id] = {
|
||||
"message": string_message,
|
||||
"timestamp": Date.now(),
|
||||
"response": null
|
||||
}
|
||||
// Sending as a string
|
||||
parentPort.postMessage(string_message)
|
||||
// Allowing the calling function to wait for the response
|
||||
if(callback) {
|
||||
check_response(msg_id, callback)
|
||||
} else {
|
||||
check_response(msg_id, react_to_response)
|
||||
}
|
||||
return msg_id
|
||||
}
|
||||
|
||||
// NOTE Parsing the messages from the main process
|
||||
function parse_message(message_str) {
|
||||
let message = JSON.parse(JSON.parse(message_str))
|
||||
console.log("Parsing: " + message_str)
|
||||
let type = message["type"]
|
||||
// Handle responses
|
||||
if (type == "response") {
|
||||
// Extracting the message id
|
||||
let id = message.id
|
||||
// Checking if the message is in the awaiting list
|
||||
if (messages_awaiting[id]) {
|
||||
// Updating the response if it is empty
|
||||
if (messages_awaiting[id].response == null) {
|
||||
messages_awaiting[id].response = JSON.stringify(message)
|
||||
console.log("[*] Response received for message " + id + ": " + messages_awaiting[id].response)
|
||||
// Setting the ready flag
|
||||
ready_responses[id].ready = true
|
||||
return
|
||||
}
|
||||
else {
|
||||
console.log("[!] Response already received: " + id)
|
||||
return
|
||||
}
|
||||
}
|
||||
else {
|
||||
console.log("[!] Message not found: " + id)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
console.log("[!] Unknown message type: " + type)
|
||||
console.log(message)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE Checking if the response is ready and calling the callback function
|
||||
function check_response(message_id, callback) {
|
||||
try {
|
||||
// Recalled response
|
||||
if(ready_responses[message_id].ready) {
|
||||
callback(message_id)
|
||||
return messages_awaiting[message_id].response
|
||||
}
|
||||
}
|
||||
catch(err) {
|
||||
// Setting a listener for the response readiness
|
||||
ready_responses[message_id] = new Proxy( {ready: false}, {
|
||||
set (target, prop, val) {
|
||||
console.log("[*] Response ready for message " + message_id)
|
||||
target[prop] = val;
|
||||
callback(message_id)
|
||||
return messages_awaiting[message_id].response
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// !SECTION Utilities
|
||||
|
||||
// SECTION Methods to operate on the page background
|
||||
// REVIEW Remove the methods you won't use, as those are just examples
|
||||
|
||||
function setBackgroundStyle(property, value) {
|
||||
let payload = {
|
||||
"type": "style",
|
||||
"element": "background",
|
||||
"property": property,
|
||||
"value": value
|
||||
}
|
||||
let msg_id = send_message(payload)
|
||||
return msg_id
|
||||
}
|
||||
|
||||
|
||||
// !SECTION Background methods
|
||||
|
||||
// SECTION General low level method
|
||||
// REVIEW Remove the methods you won't use, as those are just examples
|
||||
|
||||
function setStyle(element, property, value) {
|
||||
let cmd = property + ": " + value + ";"
|
||||
let payload = {
|
||||
"type": "style",
|
||||
"element": element,
|
||||
"property": property,
|
||||
"value": value
|
||||
}
|
||||
let msg_id = send_message(payload)
|
||||
return msg_id
|
||||
}
|
||||
|
||||
function setHTML(element, html) {
|
||||
let payload = {
|
||||
"type": "render",
|
||||
"element": element,
|
||||
"html": html
|
||||
}
|
||||
let msg_id = send_message(payload)
|
||||
return msg_id
|
||||
}
|
||||
|
||||
|
||||
function getHTML(element) {
|
||||
let payload = {
|
||||
"type": "get",
|
||||
"element": element
|
||||
}
|
||||
let message_id = send_message(payload)
|
||||
return message_id
|
||||
}
|
||||
|
||||
// !SECTION General low level method
|
||||
|
||||
// ANCHOR Example of reacting to a response
|
||||
function react_to_response(message_id) {
|
||||
console.log("[reacted] Message id: " + message_id)
|
||||
let response = messages_awaiting[message_id].response
|
||||
console.log("[reacted] Response: " + response)
|
||||
}
|
||||
|
||||
// ANCHOR Main process
|
||||
// INFO Note that the main process is sync, so you can't use async/await here
|
||||
function start () {
|
||||
console.log("[*] Starting worker")
|
||||
|
||||
// NOTE Handling messages from the main process
|
||||
parentPort.on('message', (message) => {
|
||||
console.log('[+] Message from parent:', message);
|
||||
parse_message(message)
|
||||
});
|
||||
|
||||
// INFO You can write whatever you want here
|
||||
// NOTE Examples
|
||||
let msg_id = setHTML("editable", "<h2>Hello world!</h2>")
|
||||
console.log("[-] Waiting for response " + msg_id)
|
||||
|
||||
}
|
||||
|
||||
// ANCHOR Entry pont
|
||||
// REVIEW Remember to execute the included start() code if you change this
|
||||
start()
|
Loading…
x
Reference in New Issue
Block a user