From a9a9a6f71fc77be894e4db081e2c4c3796378f6e Mon Sep 17 00:00:00 2001 From: Red-Asuka Date: Mon, 6 Jan 2025 11:43:49 +0800 Subject: [PATCH] feat(core): add script execution functionality with uvm integration --- packages/core/package.json | 3 ++ packages/core/src/utils/index.ts | 1 + packages/core/src/utils/sandbox.ts | 49 +++++++++++++++++++ packages/types/base.ts | 4 ++ .../ui/src/components/script/TabFunction.vue | 32 ++++++++++-- pnpm-lock.yaml | 16 ++++++ 6 files changed, 100 insertions(+), 5 deletions(-) create mode 100644 packages/core/src/utils/sandbox.ts diff --git a/packages/core/package.json b/packages/core/package.json index 261e3cfa5..a31beca4b 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -9,10 +9,13 @@ "test:dev": "vitest" }, "dependencies": { + "buffer": "^6.0.3", "uuid": "^11.0.3", + "uvm": "^4.0.0", "vitest": "^2.1.4" }, "devDependencies": { + "@types/mqttx": "workspace:^", "@types/uuid": "^10.0.0", "@vitest/coverage-istanbul": "^2.1.4", "typescript": "~5.6.3" diff --git a/packages/core/src/utils/index.ts b/packages/core/src/utils/index.ts index 9a99b4c54..cc3182052 100644 --- a/packages/core/src/utils/index.ts +++ b/packages/core/src/utils/index.ts @@ -1 +1,2 @@ export * from './getMessageId' +export * from './sandbox' diff --git a/packages/core/src/utils/sandbox.ts b/packages/core/src/utils/sandbox.ts new file mode 100644 index 000000000..3805a5eb6 --- /dev/null +++ b/packages/core/src/utils/sandbox.ts @@ -0,0 +1,49 @@ +import type { MessageType } from 'mqttx' +// eslint-disable-next-line unicorn/prefer-node-protocol +import { Buffer } from 'buffer' +// @ts-expect-error uvm is not defined +import uvm from 'uvm' + +export function executeScript(opts: { + script: string + payload: string + messageType: MessageType + index?: number +}): Promise { + return new Promise((resolve, reject) => { + uvm.spawn( + { + bootCode: ` + bridge.on('runScript', function ({ script, payload, messageType, index }) { + try { + function execute(callback) { + return callback(payload, messageType, index); + }; + bridge.dispatch( + 'scriptResult', + Function('execute', 'payload', 'messageType', 'index', script)(execute, payload, messageType, index) + ); + } catch (error) { + bridge.dispatch('scriptError', error.message); + } + }); + `, + bootTimeout: 1000, + dispatchTimeout: 1000, + }, + (err: any, context: any) => { + if (err) reject(err) + + context.on('scriptResult', (result: any) => { + resolve(Buffer.from(result?.toString() ?? '')) + }) + + context.on('scriptError', (error?: string) => { + reject(new Error(error)) + }) + + context.dispatch('runScript', opts) + }, + ) + }) +} diff --git a/packages/types/base.ts b/packages/types/base.ts index 84e0d1b2c..93def56f1 100644 --- a/packages/types/base.ts +++ b/packages/types/base.ts @@ -13,6 +13,10 @@ export type Protocol = 'mqtt' | 'mqtts' export type QoS = 0 | 1 | 2 +export type PayloadType = 'Plaintext' | 'Base64' | 'JSON' | 'Hex' | 'CBOR' | 'MsgPack' + +export type MessageType = 'all' | 'received' | 'publish' + export type Lang = 'en' | 'zh' | 'ja' | 'hu' | 'tr' export type Theme = 'light' | 'dark' | 'night' diff --git a/packages/ui/src/components/script/TabFunction.vue b/packages/ui/src/components/script/TabFunction.vue index ebb496e73..3552ef685 100644 --- a/packages/ui/src/components/script/TabFunction.vue +++ b/packages/ui/src/components/script/TabFunction.vue @@ -1,5 +1,6 @@