From ed0ca708fdd0ee4f56d741b5b5af0fcdbb0d914a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adri=C3=A1n=20Bueno?= Date: Thu, 1 Aug 2024 13:21:02 +0200 Subject: [PATCH] feat: keep callback --- .../platform_www/cdv-electron-main.js | 43 +++++++++++++++++++ .../platform_www/cdv-electron-preload.js | 24 +++++++++-- cordova-js-src/exec.js | 5 ++- .../src/electron/index.js | 24 +++++++++++ .../cordova-plugin-sample/www/sample.js | 12 ++++++ 5 files changed, 104 insertions(+), 4 deletions(-) diff --git a/bin/templates/platform_www/cdv-electron-main.js b/bin/templates/platform_www/cdv-electron-main.js index 81e6b3e..db4baf8 100644 --- a/bin/templates/platform_www/cdv-electron-main.js +++ b/bin/templates/platform_www/cdv-electron-main.js @@ -176,5 +176,48 @@ ipcMain.handle('cdv-plugin-exec', async (_, serviceName, action, ...args) => { } }); +function cdvPluginExec$Reply (event, request, error, data, keepCallback) { + event.reply('cdv-plugin-exec$', { + id: request.id, + serviceName: request.serviceName, + action: request.action, + data, + error, + keepCallback + }); +} + +ipcMain.on('cdv-plugin-exec$', (event, request) => { + const { serviceName, action, args } = request; + + if (!cordova || !cordova.services || !cordova.services[serviceName]) { + const error = new Error(`The requested plugin service "${serviceName}" does not exist have native support.`); + return cdvPluginExec$Reply(event, request, error); + } + + const plugin = require(cordova.services[serviceName]); + + if (!plugin[action]) { + const error = new Error(`The action "${action}" for the requested plugin service "${serviceName}" does not exist.`); + return cdvPluginExec$Reply(event, request, error); + } + + function successCallback (data, keepCallback) { + cdvPluginExec$Reply(event, request, null, data, keepCallback); + } + + function errorCallback (error) { + cdvPluginExec$Reply(event, request, error); + } + + try { + plugin[action](successCallback, errorCallback, args); + } catch (e) { + console.error(e); + const error = new Error(`An error occured executing action "${action}" for the requested plugin service "${serviceName}".`); + cdvPluginExec$Reply(event, request, error); + } +}); + // In this file you can include the rest of your app's specific main process // code. You can also put them in separate files and require them here. diff --git a/bin/templates/platform_www/cdv-electron-preload.js b/bin/templates/platform_www/cdv-electron-preload.js index ac00ab2..549c717 100644 --- a/bin/templates/platform_www/cdv-electron-preload.js +++ b/bin/templates/platform_www/cdv-electron-preload.js @@ -28,8 +28,26 @@ contextBridge.exposeInMainWorld('_cdvElectronIpc', { error ); }, - + exec$: (success, error, serviceName, action, args) => { + const id = Date.now() + Math.random(); + const listener = (event, response) => { + if (id !== response.id) { + return; + } + if (response.error) { + ipcRenderer.removeListener('cdv-plugin-exec$', listener); + error(response.error); + return; + } + if (!response.keepCallback) { + ipcRenderer.removeListener('cdv-plugin-exec$', listener); + } + success(response.data); + }; + ipcRenderer.on('cdv-plugin-exec$', listener); + ipcRenderer.send('cdv-plugin-exec$', { id, serviceName, action, args }); + }, hasService: (serviceName) => cordova && - cordova.services && - cordova.services[serviceName] + cordova.services && + cordova.services[serviceName] }); diff --git a/cordova-js-src/exec.js b/cordova-js-src/exec.js index 5537d10..1566494 100644 --- a/cordova-js-src/exec.js +++ b/cordova-js-src/exec.js @@ -41,7 +41,10 @@ const execProxy = require('cordova/exec/proxy'); module.exports = function (success, fail, service, action, args) { if (window._cdvElectronIpc.hasService(service)) { // Electron based plugin support - window._cdvElectronIpc.exec(success, fail, service, action, args); + const f = action.endsWith('$') + ? window._cdvElectronIpc.exec$ + : window._cdvElectronIpc.exec; + f(success, fail, service, action, args); } else { // Fall back for browser based plugin support... const proxy = execProxy.get(service, action); diff --git a/tests/spec/fixtures/test-app-with-electron-plugin/plugins/cordova-plugin-sample/src/electron/index.js b/tests/spec/fixtures/test-app-with-electron-plugin/plugins/cordova-plugin-sample/src/electron/index.js index 2ada429..d4171e4 100644 --- a/tests/spec/fixtures/test-app-with-electron-plugin/plugins/cordova-plugin-sample/src/electron/index.js +++ b/tests/spec/fixtures/test-app-with-electron-plugin/plugins/cordova-plugin-sample/src/electron/index.js @@ -33,5 +33,29 @@ module.exports = { } catch (e) { console.log(e); } + }, + countdown$: (successCallback, errorCallback, args) => { + if (!args || !args.length || typeof args[0] != "number") { + errorCallback("NUMERIC_ARG_NEEDED"); + return; + } + + let num = args[0]; + + if (num <= 0) { + successCallback(0, false); + } + + successCallback(num, true); + + const interval = setInterval(() => { + num--; + if (num > 0) { + successCallback(num, true); + } else { + clearInterval(interval); + successCallback(num, false); + } + }, 1000); } }; diff --git a/tests/spec/fixtures/test-app-with-electron-plugin/plugins/cordova-plugin-sample/www/sample.js b/tests/spec/fixtures/test-app-with-electron-plugin/plugins/cordova-plugin-sample/www/sample.js index 80dc845..baf0b22 100644 --- a/tests/spec/fixtures/test-app-with-electron-plugin/plugins/cordova-plugin-sample/www/sample.js +++ b/tests/spec/fixtures/test-app-with-electron-plugin/plugins/cordova-plugin-sample/www/sample.js @@ -58,4 +58,16 @@ Sample.prototype.getInfo = function (successCallback, errorCallback) { exec(successCallback, errorCallback, 'Sample', 'getSampleInfo', []); }; +/** + * Count down + * + * @param {Function} successCallback The function to call when the heading data is available + * @param {Function} errorCallback The function to call when there is an error getting the heading data. + * @param {Function} num Number to start the countdown from + */ +Sample.prototype.countdown = function (successCallback, errorCallback, num) { + argscheck.checkArgs("fF", "Sample.countDown", arguments); + exec(successCallback, errorCallback, "Sample", "countdown$", [num]); +}; + module.exports = new Sample();