diff --git a/app/package.json b/app/package.json index 2d7e34b2e..550b407cb 100644 --- a/app/package.json +++ b/app/package.json @@ -90,7 +90,7 @@ }, "homepage": "./", "scripts": { - "start": "cross-env ELECTRON_START_URL=http://localhost:5000 electron .", + "start": "cross-env ELECTRON_START_URL=http://localhost:5000 ELECTRON_DEBUG=1 DEVMODE=1 electron .", "start:local": "cross-env electron .", "dist": "electron-builder", "build": "cd ../packages/api && yarn build && cd ../web && yarn build && cd ../../app && yarn dist", diff --git a/app/src/electron.js b/app/src/electron.js index 72b6b6e2c..affffaf11 100644 --- a/app/src/electron.js +++ b/app/src/electron.js @@ -101,25 +101,25 @@ function buildMenu() { { label: 'dbgate.org', click() { - require('electron').shell.openExternal('https://dbgate.org'); + electron.shell.openExternal('https://dbgate.org'); }, }, { label: 'DbGate on GitHub', click() { - require('electron').shell.openExternal('https://github.com/dbgate/dbgate'); + electron.shell.openExternal('https://github.com/dbgate/dbgate'); }, }, { label: 'DbGate on docker hub', click() { - require('electron').shell.openExternal('https://hub.docker.com/r/dbgate/dbgate'); + electron.shell.openExternal('https://hub.docker.com/r/dbgate/dbgate'); }, }, { label: 'Report problem or feature request', click() { - require('electron').shell.openExternal('https://github.com/dbgate/dbgate/issues/new'); + electron.shell.openExternal('https://github.com/dbgate/dbgate/issues/new'); }, }, commandItem('tabs.changelog'), @@ -182,6 +182,7 @@ function createWindow() { // enableRemoteModule: true, }, }); + mainWindow.webContents.openDevTools(); // require('@electron/remote/main').enable(mainWindow.webContents); if (store.get('winIsMaximized')) { mainWindow.maximize(); @@ -190,7 +191,7 @@ function createWindow() { mainMenu = buildMenu(); mainWindow.setMenu(mainMenu); - function loadMainWindow(initArgs) { + function loadMainWindow() { const startUrl = process.env.ELECTRON_START_URL || url.format({ @@ -198,18 +199,18 @@ function createWindow() { protocol: 'file:', slashes: true, }); - mainWindow.webContents.on('did-finish-load', function () { - mainWindow.webContents.executeJavaScript( - `runInit=()=>{ - try{ - dbgate_initializeElectron(${JSON.stringify(initArgs)}); - }catch(e){ - setTimeout(runInit,100) - } - }; - runInit()` - ); - }); + // mainWindow.webContents.on('did-finish-load', function () { + // mainWindow.webContents.executeJavaScript( + // `runInit=()=>{ + // try{ + // dbgate_initializeElectron(${JSON.stringify(initArgs)}); + // }catch(e){ + // setTimeout(runInit,100) + // } + // }; + // runInit()` + // ); + // }); mainWindow.on('close', () => { store.set('winBounds', mainWindow.getBounds()); store.set('winIsMaximized', mainWindow.isMaximized()); @@ -220,27 +221,35 @@ function createWindow() { } } - if (process.env.ELECTRON_START_URL) { - loadMainWindow({}); - } else { - const apiProcess = fork(path.join(__dirname, '../packages/api/dist/bundle.js'), [ - '--dynport', - '--is-electron-bundle', - '--native-modules', - path.join(__dirname, 'nativeModules'), - // '../../../src/nativeModules' - ]); - apiProcess.on('message', msg => { - if (msg.msgtype == 'listening') { - const { port, authorization } = msg; + const api = require(path.join( + __dirname, + process.env.ELECTRON_DEBUG ? '../../packages/api' : '../packages/api/dist/bundle.js' + )); + api.getMainModule().useAllControllers(null, electron); - loadMainWindow({ - port, - authorization, - }); - } - }); - } + loadMainWindow(); + + // if (process.env.ELECTRON_START_URL) { + // loadMainWindow({}); + // } else { + // const apiProcess = fork(path.join(__dirname, '../packages/api/dist/bundle.js'), [ + // '--dynport', + // '--is-electron-bundle', + // '--native-modules', + // path.join(__dirname, 'nativeModules'), + // // '../../../src/nativeModules' + // ]); + // apiProcess.on('message', msg => { + // if (msg.msgtype == 'listening') { + // const { port, authorization } = msg; + + // loadMainWindow({ + // port, + // authorization, + // }); + // } + // }); + // } // and load the index.html of the app. // mainWindow.loadURL('http://localhost:3000'); diff --git a/packages/api/package.json b/packages/api/package.json index 153c977d6..5e29b9aac 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -39,6 +39,7 @@ "fs-reverse": "^0.0.3", "get-port": "^5.1.1", "http": "^0.0.0", + "is-electron": "^2.2.1", "js-yaml": "^4.1.0", "json-stable-stringify": "^1.0.1", "line-reader": "^0.4.0", diff --git a/packages/api/src/index.js b/packages/api/src/index.js index 9da36f975..3e5c1ba39 100644 --- a/packages/api/src/index.js +++ b/packages/api/src/index.js @@ -8,12 +8,14 @@ if (processArgs.startProcess) { const proc = require('./proc'); const module = proc[processArgs.startProcess]; module.start(); -} else if (!module['parent'] && !processArgs.checkParent) { - const main = require('./main'); - - main.start(); } +// else if (!module['parent'] && !processArgs.checkParent) { +// const main = require('./main'); + +// main.start(); +// } + module.exports = { ...shell, getMainModule: () => require('./main'), diff --git a/packages/api/src/main.js b/packages/api/src/main.js index 858139b74..c3534cf56 100644 --- a/packages/api/src/main.js +++ b/packages/api/src/main.js @@ -102,20 +102,7 @@ function start() { }) ); - useController(app, '/connections', connections); - useController(app, '/server-connections', serverConnections); - useController(app, '/database-connections', databaseConnections); - useController(app, '/metadata', metadata); - useController(app, '/sessions', sessions); - useController(app, '/runners', runners); - useController(app, '/jsldata', jsldata); - useController(app, '/config', config); - useController(app, '/archive', archive); - useController(app, '/uploads', uploads); - useController(app, '/plugins', plugins); - useController(app, '/files', files); - useController(app, '/scheduler', scheduler); - useController(app, '/query-history', queryHistory); + useAllControllers(app, null); // if (process.env.PAGES_DIRECTORY) { // app.use('/pages', express.static(process.env.PAGES_DIRECTORY)); @@ -158,4 +145,21 @@ function start() { } } -module.exports = { start }; +function useAllControllers(app, electron) { + useController(app, electron, '/connections', connections); + useController(app, electron, '/server-connections', serverConnections); + useController(app, electron, '/database-connections', databaseConnections); + useController(app, electron, '/metadata', metadata); + useController(app, electron, '/sessions', sessions); + useController(app, electron, '/runners', runners); + useController(app, electron, '/jsldata', jsldata); + useController(app, electron, '/config', config); + useController(app, electron, '/archive', archive); + useController(app, electron, '/uploads', uploads); + useController(app, electron, '/plugins', plugins); + useController(app, electron, '/files', files); + useController(app, electron, '/scheduler', scheduler); + useController(app, electron, '/query-history', queryHistory); +} + +module.exports = { start, useAllControllers }; diff --git a/packages/api/src/utility/platformInfo.js b/packages/api/src/utility/platformInfo.js index 2025dc72b..e50f00f9c 100644 --- a/packages/api/src/utility/platformInfo.js +++ b/packages/api/src/utility/platformInfo.js @@ -2,6 +2,7 @@ const fs = require('fs'); const os = require('os'); const path = require('path'); const processArgs = require('./processArgs'); +const isElectron = require('is-electron'); const platform = process.env.OS_OVERRIDE ? process.env.OS_OVERRIDE : process.platform; const isWindows = platform === 'win32'; @@ -28,6 +29,7 @@ const platformInfo = { isLinux, isDocker, isElectronBundle, + isElectron: isElectron(), isDevMode, isNpmDist, isSnap: process.env.ELECTRON_SNAP == 'true', diff --git a/packages/api/src/utility/useController.js b/packages/api/src/utility/useController.js index e8c85566a..a1f4c0d74 100644 --- a/packages/api/src/utility/useController.js +++ b/packages/api/src/utility/useController.js @@ -4,7 +4,7 @@ const express = require('express'); /** * @param {string} route */ -module.exports = function useController(app, route, controller) { +module.exports = function useController(app, electron, route, controller) { const router = express.Router(); if (controller._init) { @@ -23,6 +23,21 @@ module.exports = function useController(app, route, controller) { const meta = controller[`${key}_meta`]; if (!meta) continue; + const routeAction = `/${_.kebabCase(key)}`; + + if (electron) { + if (meta === true) { + const handler = `${route.substring(1)}-${_.kebabCase(key)}`; + console.log('REGISTERING HANDLER', handler); + electron.ipcMain.handle(handler, async (event, args) => { + const data = await controller[key](args); + return data; + }); + } + + continue; + } + let method = 'post'; let raw = false; let rawParams = false; @@ -36,11 +51,10 @@ module.exports = function useController(app, route, controller) { rawParams = meta.rawParams; } - const route = `/${_.kebabCase(key)}`; if (raw) { - router[method](route, controller[key]); + router[method](routeAction, controller[key]); } else { - router[method](route, async (req, res) => { + router[method](routeAction, async (req, res) => { // if (controller._init && !controller._init_called) { // await controller._init(); // controller._init_called = true; @@ -58,5 +72,7 @@ module.exports = function useController(app, route, controller) { } } - app.use(route, router); + if (app) { + app.use(route, router); + } }; diff --git a/packages/web/src/App.svelte b/packages/web/src/App.svelte index b62e17da2..b77d962c6 100644 --- a/packages/web/src/App.svelte +++ b/packages/web/src/App.svelte @@ -11,7 +11,7 @@ import { setAppLoaded } from './utility/appLoadManager'; import ErrorHandler from './utility/ErrorHandler.svelte'; import OpenTabsOnStartup from './utility/OpenTabsOnStartup.svelte'; - import { shouldWaitForElectronInitialize } from './utility/getElectron'; + // import { shouldWaitForElectronInitialize } from './utility/getElectron'; import { subscribeConnectionPingers } from './utility/connectionsPinger'; import { subscribePermissionCompiler } from './utility/hasPermission'; import { apiCall } from './utility/api'; @@ -19,10 +19,10 @@ let loadedApi = false; async function loadApi() { - if (shouldWaitForElectronInitialize()) { - setTimeout(loadApi, 100); - return; - } + // if (shouldWaitForElectronInitialize()) { + // setTimeout(loadApi, 100); + // return; + // } try { // console.log('************** LOADING API'); diff --git a/packages/web/src/utility/api.ts b/packages/web/src/utility/api.ts index b9ddc9d9b..e9e20e52a 100644 --- a/packages/web/src/utility/api.ts +++ b/packages/web/src/utility/api.ts @@ -1,6 +1,7 @@ import resolveApi, { resolveApiHeaders } from './resolveApi'; import { writable } from 'svelte/store'; import { cacheClean } from './cache'; +import getElectron from './getElectron'; // import socket from './socket'; let eventSource; @@ -13,37 +14,53 @@ function wantEventSource() { } export async function apiCall(route: string, args: {} = undefined) { - const resp = await fetch(`${resolveApi()}/${route}`, { - method: 'POST', - cache: 'no-cache', - headers: { - 'Content-Type': 'application/json', - ...resolveApiHeaders(), - }, - body: JSON.stringify(args), - }); - return resp.json(); + const electron = getElectron(); + if (electron) { + const resp = await electron.invoke(route.replace('/', '-'), args); + return resp; + } else { + const resp = await fetch(`${resolveApi()}/${route}`, { + method: 'POST', + cache: 'no-cache', + headers: { + 'Content-Type': 'application/json', + ...resolveApiHeaders(), + }, + body: JSON.stringify(args), + }); + return resp.json(); + } } const apiHandlers = new WeakMap(); export function apiOn(event: string, handler: Function) { - wantEventSource(); - if (!apiHandlers.has(handler)) { - const handlerProxy = e => { - // console.log('RECEIVED', e.type, JSON.parse(e.data)); - handler(JSON.parse(e.data)); - }; - apiHandlers.set(handler, handlerProxy); - } + const electron = getElectron(); + if (electron) { + electron.addEventListener(event, handler); + } else { + wantEventSource(); + if (!apiHandlers.has(handler)) { + const handlerProxy = e => { + // console.log('RECEIVED', e.type, JSON.parse(e.data)); + handler(JSON.parse(e.data)); + }; + apiHandlers.set(handler, handlerProxy); + } - eventSource.addEventListener(event, apiHandlers.get(handler)); + eventSource.addEventListener(event, apiHandlers.get(handler)); + } } export function apiOff(event: string, handler: Function) { - wantEventSource(); - if (apiHandlers.has(handler)) { - eventSource.removeEventListener(event, apiHandlers.get(handler)); + const electron = getElectron(); + if (electron) { + electron.removeEventListener(event, handler); + } else { + wantEventSource(); + if (apiHandlers.has(handler)) { + eventSource.removeEventListener(event, apiHandlers.get(handler)); + } } } diff --git a/packages/web/src/utility/getElectron.ts b/packages/web/src/utility/getElectron.ts index 5909aedba..1f907de2b 100644 --- a/packages/web/src/utility/getElectron.ts +++ b/packages/web/src/utility/getElectron.ts @@ -1,11 +1,11 @@ class ElectronApi { - public port?: number; - public authorization?: string; + // public port?: number; + // public authorization?: string; private ipcRenderer = getIpcRenderer(); - constructor(args) { - this.port = args.port; - this.authorization = args.authorization; + constructor() { + // this.port = args.port; + // this.authorization = args.authorization; } send(msg, args = null) { @@ -30,18 +30,29 @@ class ElectronApi { async openExternal(url) { await this.ipcRenderer.invoke('openExternal', url); } -} -let apiInstance = null; + async invoke(route, args) { + const res = await this.ipcRenderer.invoke(route, args); + return res; + } -function initializeElectron(args) { - apiInstance = new ElectronApi(args); - if (window['dbgate_recreateSocket']) { - window['dbgate_recreateSocket'](); + addEventListener(channel: string, listener: Function) { + this.ipcRenderer.on(channel, listener); + } + + removeEventListener(channel: string, listener: Function) { + this.ipcRenderer.removeEventListener(channel, listener); } } -window['dbgate_initializeElectron'] = initializeElectron; +// function initializeElectron(args) { +// apiInstance = new ElectronApi(args); +// if (window['dbgate_recreateSocket']) { +// window['dbgate_recreateSocket'](); +// } +// } + +// window['dbgate_initializeElectron'] = initializeElectron; function getIpcRenderer() { if (window['require']) { @@ -51,14 +62,16 @@ function getIpcRenderer() { return null; } -export function shouldWaitForElectronInitialize() { - return !!getIpcRenderer() && !apiInstance; -} +// export function shouldWaitForElectronInitialize() { +// return !!getIpcRenderer() && !apiInstance; +// } export function isElectronAvailable() { return !!getIpcRenderer(); } +const apiInstance = isElectronAvailable() ? new ElectronApi() : null; + export default function getElectron(): ElectronApi { return apiInstance; // try { diff --git a/yarn.lock b/yarn.lock index 8534c684d..b4913e90a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5316,6 +5316,11 @@ is-descriptor@^1.0.0, is-descriptor@^1.0.2: is-data-descriptor "^1.0.0" kind-of "^6.0.2" +is-electron@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/is-electron/-/is-electron-2.2.1.tgz#751b1dd8a74907422faa5c35aaa0cf66d98086e9" + integrity sha512-r8EEQQsqT+Gn0aXFx7lTFygYQhILLCB+wn0WCDL5LZRINeLH/Rvw1j2oKodELLXYNImQ3CRlVsY8wW4cGOsyuw== + is-extendable@^0.1.0, is-extendable@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89"