From 941c04878ab24d57c15b08d11f4e9c27960de849 Mon Sep 17 00:00:00 2001 From: Miguel Angel Date: Wed, 30 Jul 2025 14:03:09 -0400 Subject: [PATCH 1/3] feat: refactor FormButton component to utilize Web Workers --- src/components/renderer/form-button.vue | 61 +++++++++++++++++++++---- src/workers/worker.js | 19 ++++++++ 2 files changed, 70 insertions(+), 10 deletions(-) create mode 100644 src/workers/worker.js diff --git a/src/components/renderer/form-button.vue b/src/components/renderer/form-button.vue index aa3116351..4afae959b 100644 --- a/src/components/renderer/form-button.vue +++ b/src/components/renderer/form-button.vue @@ -10,7 +10,7 @@ :disabled="showSpinner" > - {{ showSpinner ? (!loadingLabel ? 'Loading...': loadingLabel) : label }} + {{ showSpinner ? (!loadingLabel ? "Loading..." : loadingLabel) : label }} @@ -19,17 +19,31 @@ import Mustache from 'mustache'; import { mapActions, mapState } from "vuex"; import { getValidPath } from '@/mixins'; +import Worker from "@/workers/worker.js?worker&inline"; export default { mixins: [getValidPath], - props: ['variant', 'label', 'event', 'eventData', 'name', 'fieldValue', 'value', 'tooltip', 'transientData', 'loading', 'loadingLabel', 'handler'], + props: [ + "variant", + "label", + "event", + "eventData", + "name", + "fieldValue", + "value", + "tooltip", + "transientData", + "loading", + "loadingLabel", + "handler" + ], data() { return { showSpinner: false }; }, computed: { - ...mapState('globalErrorsModule', ['valid']), + ...mapState("globalErrorsModule", ["valid"]), classList() { let variant = this.variant || 'primary'; return { @@ -106,15 +120,42 @@ export default { async runHandler() { if (this.handler) { try { - const data = this.getScreenDataReference(null, (screen, name, value) => { - // Enable the data reference to be updated by the handler - screen.$set(screen.vdata, name, value); + const data = this.getScreenDataReference( + null, + (screen, name, value) => { + // Enable the data reference to be updated by the handler + screen.$set(screen.vdata, name, value); + } + ); + + const rawData = data[Symbol.for("__v_raw")]; + + const worker = new Worker(); + console.log("rawData ==> ", rawData); + worker.postMessage({ + fn: this.handler, + data: rawData, }); - await new Function(['toRaw'], this.handler).apply(data, [(item) => { - return item[Symbol.for('__v_raw')]; - }]); + + worker.onmessage = (e) => { + console.log("Received:", e.data); + if (e.data.error) { + console.error("Worker error:", e.data.error); + } else if (e.data.result) { + console.log("Worker result:", e.data.result); + + // Update the data with the result + Object.keys(e.data.result).forEach(key => { + rawData[key] = e.data.result[key]; + }); + } + }; + + // await new Function(['toRaw'], this.handler).apply(data, [(item) => { + // return item[Symbol.for('__v_raw')]; + // }]); } catch (error) { - console.error('❌ There is an error in the button handler', error); + console.error("❌ There is an error in the button handler", error); } } } diff --git a/src/workers/worker.js b/src/workers/worker.js new file mode 100644 index 000000000..d00b7791d --- /dev/null +++ b/src/workers/worker.js @@ -0,0 +1,19 @@ +// worker.js +self.onmessage = function (e) { + console.log("Worker received:", e.data); + + const { fn, data } = e.data; + + try { + // Execute the handler as a function with data as the context + const func = new Function("data", fn); + // const func = new Function('data', `return (${fn})(data)`) + const result = func(data); + console.log("result ==> ", result); + + self.postMessage({ result }); + } catch (error) { + console.error("Error executing handler:", error); + self.postMessage({ error: error.message }); + } +}; From ee134c43a1065ba4208df1d44699e44ac4bca438 Mon Sep 17 00:00:00 2001 From: Miguel Angel Date: Thu, 31 Jul 2025 14:12:25 -0400 Subject: [PATCH 2/3] fix: remove console logs for cleaner code --- src/components/renderer/form-button.vue | 7 ------- src/workers/worker.js | 3 --- 2 files changed, 10 deletions(-) diff --git a/src/components/renderer/form-button.vue b/src/components/renderer/form-button.vue index 4afae959b..86a67fbb0 100644 --- a/src/components/renderer/form-button.vue +++ b/src/components/renderer/form-button.vue @@ -131,18 +131,15 @@ export default { const rawData = data[Symbol.for("__v_raw")]; const worker = new Worker(); - console.log("rawData ==> ", rawData); worker.postMessage({ fn: this.handler, data: rawData, }); worker.onmessage = (e) => { - console.log("Received:", e.data); if (e.data.error) { console.error("Worker error:", e.data.error); } else if (e.data.result) { - console.log("Worker result:", e.data.result); // Update the data with the result Object.keys(e.data.result).forEach(key => { @@ -150,10 +147,6 @@ export default { }); } }; - - // await new Function(['toRaw'], this.handler).apply(data, [(item) => { - // return item[Symbol.for('__v_raw')]; - // }]); } catch (error) { console.error("❌ There is an error in the button handler", error); } diff --git a/src/workers/worker.js b/src/workers/worker.js index d00b7791d..a985bb771 100644 --- a/src/workers/worker.js +++ b/src/workers/worker.js @@ -1,7 +1,5 @@ // worker.js self.onmessage = function (e) { - console.log("Worker received:", e.data); - const { fn, data } = e.data; try { @@ -9,7 +7,6 @@ self.onmessage = function (e) { const func = new Function("data", fn); // const func = new Function('data', `return (${fn})(data)`) const result = func(data); - console.log("result ==> ", result); self.postMessage({ result }); } catch (error) { From 852462b6cbb72f7fa479cec1153a2e17ee852dc1 Mon Sep 17 00:00:00 2001 From: Miguel Angel Date: Fri, 1 Aug 2025 09:52:42 -0400 Subject: [PATCH 3/3] test: update button click handler fixture to return reactive data updates --- tests/e2e/fixtures/button_click_handler.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/e2e/fixtures/button_click_handler.json b/tests/e2e/fixtures/button_click_handler.json index 504cac5a5..6bb22c4a4 100644 --- a/tests/e2e/fixtures/button_click_handler.json +++ b/tests/e2e/fixtures/button_click_handler.json @@ -690,7 +690,7 @@ "name": "button_with_handler", "fieldValue": null, "tooltip": {}, - "handler": "this.form_input_2=\"value changed by handler\";" + "handler": "return {\n form_input_2: \"value changed by handler\",\n}" }, "inspector": [ { @@ -1392,7 +1392,7 @@ "name": "record_list_button_with_handler", "fieldValue": null, "tooltip": {}, - "handler": "this.form_input_1=\"value changed by handler\";console.log('handler executed')" + "handler": "console.log('handler executed');\nreturn {\n form_input_1: \"value changed by handler\",\n}" }, "inspector": [ { @@ -1818,4 +1818,4 @@ ], "screen_categories": [], "scripts": [] -} \ No newline at end of file +}